Published on

๐Ÿ“–STUDY ์›น ๋ธŒ๋ผ์šฐ์ € ์† ๋จธ์‹ ๋Ÿฌ๋‹ Tensorflow.js | ์›น์—์„œ์˜ ๋จธ์‹ ๋Ÿฌ๋‹

3๋…„์ „ ๋„์ปค ์ด๋ฏธ์ง€๋กœ aws์— ๋ชจ๋ธ์„ ์˜ฌ๋ฆฌ๊ณ  ์›น ์‚ฌ์ดํŠธ๋ฅผ ์šด์˜์„ ํ–ˆ์—ˆ๋Š”๋ฐ, ๋‹น์‹œ ๋‚ด ๊ถ๊ธˆ์ฆ์œผ๋กœ๋Š” ๊ทธ๋ƒฅ ๋กœ์ปฌ์—์„œ ๋Œ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•๋„ ์—†๋‚˜ ์‹ถ์–ด์„œ ์ฐพ์€ ์ฑ…์ด์—ˆ๋‹ค.
์‹œ๊ฐ„์ด ๋งŽ์ด ์ง€๋‚˜์„œ ์ด์ง ์ค€๋น„๋ฅผ ํ•˜๋ฉด์„œ ๊ทธ๊ฐ„ ์‚ฌ๋†“์€ ์ฑ…๋“ค์„ ๋งค์ผ ํ•˜๋‚˜์”ฉ ๊ณต๋ถ€ํ•˜๋Š” ์ƒ๊ฐ์œผ๋กœ ํฌ์ŠคํŒ…์„ ์‹œ์ž‘ํ•œ๋‹ค..!

๋”ฐ๋ผ์„œ ์ด ํฌ์ŠคํŒ…์€ ๋‚ด๊ฐ€ ์ฝ๊ณ  ์‹ค์Šตํ•˜๋ฉด์„œ ์ƒ๊ฐ๋“ค์„ ์ •๋ฆฌํ•œ ํฌ์ŠคํŠธ๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค.

์›น์—์„œ์˜ ๋จธ์‹ ๋Ÿฌ๋‹

์›น์—์„œ ๋ชจ๋ธ์„ ๋„์šฐ๋Š” ์ด์œ ๋Š” ๊ฒฐ๊ตญ์—” ์‚ฌ์šฉ์ž๋“ค(end user)์—๊ฒŒ ๋” ๋งŽ์ด ๋ชจ๋ธ์„ ํ™œ์šฉํ•˜๊ณ  ๊ทธ์— ๋Œ€ํ•œ ์ด์ต ์ฐฝ์ถœ์ด๋‹ค. ์ด๋ฅผ porting์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ํŒŒ์ด์ฌ์œผ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ๋ชจ๋ธ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋Œ€๋ถ€๋ถ„ ์šด์šฉํ•˜๋Š” ์›น์‚ฌ์ดํŠธ์—์„œ ํ˜ธํ™˜์€ ์‰ฝ์ง€ ์•Š์€ ์ผ๋กœ ์—ฌ๊ฒจ์ ธ ์™”๋‹ค.

  • ํŒŒ์ด์ฌ์œผ๋กœ ๊ตฌํ˜„ํ•œ ๋ชจ๋ธ์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” tfjs-converter ์„ ์ด์šฉํ•˜์—ฌ ๋ณ€ํ™˜ํ•œ๋‹ค.

Tensorflow.js๋Š” ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ์›น์—์„œ ๋จธ์‹ ๋Ÿฌ๋‹์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
ํŠน์ง•์œผ๋กœ๋Š” ์—ฐ์‚ฐ ๊ทธ๋ž˜ํ”„๋ฅผ ์ฆ‰์‹œ ์‹คํ–‰(eager execution)์œผ๋กœ ๊ตฌํ˜„ํ•˜์—ฌ, WebGL์„ ํ†ตํ•ด GPU๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

GPU๋ฅผ ์ด์šฉํ•˜์—ฌ ์—ฐ์‚ฐํ•˜์ง€๋งŒ, ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค. explicitํ•˜๊ฒŒ ๊ด€๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๊ณ , ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋‹ค. (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฌธ์ œ ํ•ด๊ฒฐ)

const a = tf.tensor([1, 2, 3, 4], [2, 2]);
const b = tf.tensor([1, 2, 3, 4], [2, 2]);
const c = a.add(b);
a.dispose(); // a ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ
b.dispose(); // b ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ
c.dispose(); // c ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ

๋ชจ๋“  ๋ณ€์ˆ˜๋ฅผ ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ ํ•ด์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋น„ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์—, tf.tidy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

const a = tf.tensor([1, 2, 3, 4], [2, 2]);
const b = tf.tensor([1, 2, 3, 4], [2, 2]);
const c = tf.tidy(() => {
  const a = tf.tensor([1, 2, 3, 4], [2, 2]);
  const b = tf.tensor([1, 2, 3, 4], [2, 2]);
  return a.add(b);
});

์ƒํ™ฉ์— ๋”ฐ๋ผ tf.tidy ํ˜น์€ .dispose๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. ๋˜ํ•œ, tf.tidy๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ชจ๋ธ api๋Š” ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค.

  • Layers API: for ๋ชจ๋ธ ๊ตฌ์กฐ, Keras์™€ ์œ ์‚ฌํ•œ API๋กœ, ๋ชจ๋ธ์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
    • Sequential API: ๋ ˆ์ด์–ด๋ฅผ ์Œ“์•„๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ชจ๋ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
    • Functional API: ๋ ˆ์ด์–ด๋ฅผ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ชจ๋ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • Core API: for ์—ฐ์‚ฐ, ์ €์ˆ˜์ค€ API๋กœ, ํ…์„œ ์—ฐ์‚ฐ์„ ์ง์ ‘ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Layers API๋ฅผ ์ด์šฉํ•˜์—ฌ ์ปค์Šคํ…€ ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ serialization์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋ธ์„ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๋”ฐ๋ผ์„œ, ์ปค์Šคํ…€ ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” Core API๋ฅผ ์ด์šฉํ•˜์—ฌ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.


Terminology

  • Tensor: ๋ฐ์ดํ„ฐ์˜ ๋‹ค์ฐจ์› ๋ฐฐ์—ด์„ ์˜๋ฏธํ•œ๋‹ค. (numpy์—์„œ๋Š” ndarray๋กœ ํ‘œํ˜„)
  • Machine Learning vs Deep Learning: ์ด ๋‘˜์˜ ์ฐจ์ด๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•™์Šตํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์žˆ๋‹ค. ๋จธ์‹ ๋Ÿฌ๋‹์€ feature๋ฅผ ์ง์ ‘ ์ •์˜ํ•˜๊ณ , ๋”ฅ๋Ÿฌ๋‹์€ feature๋ฅผ ์Šค์Šค๋กœ ํ•™์Šตํ•œ๋‹ค.
  • Backpropagation: ๋”ฅ๋Ÿฌ๋‹์—์„œ ๊ฐ€์ค‘์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ์˜ค์ฐจ๋ฅผ ์—ญ์ „ํŒŒํ•˜์—ฌ ๊ฐ€์ค‘์น˜๋ฅผ ์กฐ์ •ํ•œ๋‹ค.
    • ์ง€๋„ํ•™์Šต์œผ๋กœ ์˜ˆ์ธก๊ฐ’๊ณผ ์‹ค์ œ๊ฐ’ ์˜ค์ฐจ์œจ ๊ณ„์‚ฐ
    • ์˜ˆ์ธก ๊ฒฐ๊ณผ๊ฐ€ ๊ธฐ์—ฌํ•˜๋Š” ์ •๋„์— ๋”ฐ๋ผ ๊ฐ ์—ฐ์‚ฐ ๋…ธ๋“œ์— ์˜ค์ฐจ์œจ ์ „ํŒŒ
    • ์˜ค์ฐจ์œจ ๊ธฐ๋ฐ˜์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐฑ์‹ 
  • rank: ํ…์„œ์˜ ์ฐจ์› ์ˆ˜
  • shape: ํ…์„œ์˜ ๊ฐ ์ฐจ์› ํฌ๊ธฐ
  • dtype: ํ…์„œ์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…
Authors