Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/js/guide/train_models.md
25118 views

ํ›ˆ๋ จ ๋ชจ๋ธ

์ด ๊ฐ€์ด๋“œ๋Š” ์ด๋ฏธ ๋ชจ๋ธ ๋ฐ ๋ ˆ์ด์–ด ๊ฐ€์ด๋“œ๋ฅผ ์ฝ์—ˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ์“ฐ์˜€์Šต๋‹ˆ๋‹ค.

TensorFlow.js์—๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. <a href="https://js.tensorflow.org/api/latest/#tf.Model.fit" data-md-type="link">LayersModel.fit()</a> ๋˜๋Š” <a href="https://js.tensorflow.org/api/latest/#tf.Model.fitDataset" data-md-type="link">LayersModel.fitDataset()</a>์™€ ํ•จ๊ป˜ Layers API ์‚ฌ์šฉํ•˜๊ธฐ

  2. <a href="https://js.tensorflow.org/api/latest/#tf.train.Optimizer.minimize" data-md-type="link">Optimizer.minimize()</a>์™€ ํ•จ๊ป˜ Core API ์‚ฌ์šฉํ•˜๊ธฐ

๋จผ์ € ๋ชจ๋ธ ๋นŒ๋“œ ๋ฐ ํ›ˆ๋ จ์„ ์œ„ํ•œ ์ƒ์œ„ ์ˆ˜์ค€ API ์ธ Layers API๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Core API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ™์€ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์†Œ๊ฐœ

๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์€ ์ž…๋ ฅ์„ ์›ํ•˜๋Š” ์ถœ๋ ฅ์— ๋งคํ•‘ํ•˜๋Š” ํ•™์Šต ๊ฐ€๋Šฅํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ตœ์ ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋ฐ์ดํ„ฐ์—์„œ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜์—ฌ ์–ป์Šต๋‹ˆ๋‹ค.

ํ›ˆ๋ จ์—๋Š” ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • ๋ชจ๋ธ์— ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜ ๊ฐ€์ ธ์˜ค๊ธฐ

  • ๋ชจ๋ธ์— ์˜ˆ์ธก๊ฐ’ ์š”์ฒญํ•˜๊ธฐ

  • ํ•ด๋‹น ์˜ˆ์ธก๊ฐ’์„ '์ฐธ'๊ฐ’๊ณผ ๋น„๊ตํ•˜๊ธฐ

  • ๋ชจ๋ธ์ด ํ–ฅํ›„ ํ•ด๋‹น ๋ฐฐ์น˜์— ๋Œ€ํ•ด ๋” ๋‚˜์€ ์˜ˆ์ธก๊ฐ’์„ ๋‚ด๋„๋ก ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋ณ€๊ฒฝ ๋ฒ”์œ„ ๊ฒฐ์ •ํ•˜๊ธฐ

์ž˜ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์€ ์ž…๋ ฅ์—์„œ ์›ํ•˜๋Š” ์ถœ๋ ฅ์œผ๋กœ ์ •ํ™•ํ•œ ๋งคํ•‘์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋ธ ๋งค๊ฐœ๋ณ€์ˆ˜

Layers API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ 2๋ ˆ์ด์–ด ๋ชจ๋ธ์„ ์ •์˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const model = tf.sequential({ layers: [ tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}), tf.layers.dense({units: 10, activation: 'softmax'}), ] });

๋‚ด๋ถ€์ ์œผ๋กœ ๋ชจ๋ธ์—๋Š” ๋ฐ์ดํ„ฐ ํ•™์Šต์„ ํ†ตํ•ด ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜(์ข…์ข… ๊ฐ€์ค‘์น˜ ๋ผ๊ณ  ํ•จ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ ๋ฐ ํ˜•์ƒ๊ณผ ๊ด€๋ จ๋œ ๊ฐ€์ค‘์น˜์˜ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•ด๋ด…๋‹ˆ๋‹ค.

model.weights.forEach(w => { console.log(w.name, w.shape); });

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

> dense_Dense1/kernel [784, 32] > dense_Dense1/bias [32] > dense_Dense2/kernel [32, 10] > dense_Dense2/bias [10]

์ด 4๊ฐœ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ์œผ๋ฉฐ ๋ฐ€์ง‘ ๋ ˆ์ด์–ด๋‹น 2๊ฐœ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์˜ˆ์ƒ๋˜๋Š” ์ด์œ ๋Š” ๋ฐ€์ง‘ ๋ ˆ์ด์–ด๋Š” ์ˆ˜์‹ y = Ax + b๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ ํ…์„œ x๋ฅผ ์ถœ๋ ฅ ํ…์„œ y๋กœ ๋งคํ•‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ A(์ปค๋„) ๋ฐ b(๋ฐ”์ด์–ด์Šค)๋Š” ๋ฐ€์ง‘ ๋ ˆ์ด์–ด์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ : ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ€์ง‘ ๋ ˆ์ด์–ด์—๋Š” ๋ฐ”์ด์–ด์Šค๊ฐ€ ํฌํ•จ๋˜์ง€๋งŒ, ๋ฐ€์ง‘ ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“ค ๋•Œ ์˜ต์…˜์—์„œ {useBias: false}๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋ฐ”์ด์–ด์Šค๋ฅผ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

model.summary()๋Š” ๋ชจ๋ธ์˜ ๊ฐœ์š”์™€ ์ด ๋งค๊ฐœ๋ณ€์ˆ˜ ์ˆ˜๋ฅผ ํ™•์ธํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•œ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

๋ ˆ์ด์–ด(์œ ํ˜•) ์ถœ๋ ฅ ํ˜•์ƒ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฒˆํ˜ธ
density_Dense1(๋ฐ€๋„) [null,32] 25120
density_Dense2(๋ฐ€๋„) [null,10] 330
์ด ๋งค๊ฐœ๋ณ€์ˆ˜: 25450
ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜: 25450
ํ›ˆ๋ จํ•  ์ˆ˜ ์—†๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜: 0

๋ชจ๋ธ์˜ ๊ฐ ๊ฐ€์ค‘์น˜๋Š” <a href="https://js.tensorflow.org/api/0.14.2/#class:Variable" data-md-type="link">Variable</a> ๊ฐ์ฒด์˜ ๋ฐฑ์—”๋“œ์ž…๋‹ˆ๋‹ค. TensorFlow.js์—์„œ Variable์€ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ•˜๋‚˜์˜ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ assign()์ด ์žˆ๋Š” ๋ถ€๋™ ์†Œ์ˆ˜์  Tensor์ž…๋‹ˆ๋‹ค. Layers API๋Š” ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ค‘์น˜๋ฅผ ์ž๋™์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด assign()์„ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ€์ค‘์น˜๋ฅผ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

model.weights.forEach(w => { const newVals = tf.randomNormal(w.shape); // w.val is an instance of tf.Variable w.val.assign(newVals); });

์˜ตํ‹ฐ๋งˆ์ด์ €, ์†์‹ค ๋ฐ ๋ฉ”ํŠธ๋ฆญ

ํ›ˆ๋ จ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๋‹ค์Œ ์„ธ ๊ฐ€์ง€๋ฅผ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์˜ตํ‹ฐ๋งˆ์ด์ €: ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ํ˜„์žฌ ๋ชจ๋ธ์˜ ์˜ˆ์ธก๊ฐ’์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ๋ชจ๋ธ์˜ ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์–ผ๋งˆ๋‚˜ ๋ณ€๊ฒฝํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. Layers API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ธฐ์กด ์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ๋ฌธ์ž์—ด ์‹๋ณ„์ž์ธ(์˜ˆ: 'sgd' ๋˜๋Š” 'adam' ) ๋˜๋Š” <a href="https://js.tensorflow.org/api/latest/#Training-Optimizers" data-md-type="link">Optimizer</a> ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ์†์‹ค ํ•จ์ˆ˜: ๋ชจ๋ธ์€ ์ตœ์†Œํ™”๋ฅผ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋ธ์˜ ์˜ˆ์ธก๊ฐ’์ด '์–ผ๋งˆ๋‚˜ ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€'์— ๋Œ€ํ•œ ๋‹จ์ผ ์ˆซ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†์‹ค์€ ๋ชจ๋ธ์ด ๊ฐ€์ค‘์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜์—์„œ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. Layers API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ธฐ์กด ์†์‹ค ํ•จ์ˆ˜์˜ ๋ฌธ์ž์—ด ์‹๋ณ„์ž(์˜ˆ: 'categoricalCrossentropy') ๋˜๋Š” ์˜ˆ์ธก๊ฐ’๊ณผ ์ฐธ๊ฐ’์„ ๊ฐ€์ ธ์™€ ์†์‹ค์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API ์„ค๋ช…์„œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์†์‹ค ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  3. ๋ฉ”ํŠธ๋ฆญ ๋ชฉ๋ก: ์†์‹ค๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋ฉ”ํŠธ๋ฆญ์€ ๋‹จ์ผ ์ˆซ์ž๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ์š”์•ฝํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”ํŠธ๋ฆญ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ epoch๊ฐ€ ๋๋‚  ๋•Œ ์ „์ฒด ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์†์‹ค์ด ๊ฐ์†Œํ•˜๊ณ  ์žˆ๋Š”์ง€ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค๋งŒ, ์ •ํ™•์„ฑ๊ณผ ๊ฐ™์€ ๋ณด๋‹ค ์ธ๊ฐ„ ์นœํ™”์ ์ธ ๋ฉ”ํŠธ๋ฆญ์„ ์›ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. Layers API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ธฐ์กด ๋ฉ”ํŠธ๋ฆญ์˜ ๋ฌธ์ž์—ด ์‹๋ณ„์ž(์˜ˆ: 'accuracy') ๋˜๋Š” ์˜ˆ์ธก๊ฐ’ ๋ฐ ์ฐธ๊ฐ’์„ ๊ฐ€์ ธ์™€ ์ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API ์„ค๋ช…์„œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”ํŠธ๋ฆญ ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฒฐ์ •ํ–ˆ์œผ๋ฉด ์ œ๊ณต๋œ ์˜ต์…˜์œผ๋กœ model.compile()์„ ํ˜ธ์ถœํ•˜์—ฌ LayersModel์„ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.

model.compile({ optimizer: 'sgd', loss: 'categoricalCrossentropy', metrics: ['accuracy'] });

์ปดํŒŒ์ผํ•˜๋Š” ๋™์•ˆ ๋ชจ๋ธ์€ ์„ ํƒํ•œ ์˜ต์…˜์ด ์„œ๋กœ ํ˜ธํ™˜๋˜๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ›ˆ๋ จ

LayersModel์„ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • model.fit()๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์˜ ํฐ ํ…์„œ๋กœ ์ œ๊ณตํ•˜๊ธฐ

  • model.fitDataset() ๋ฐ Dataset ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ œ๊ณตํ•˜๊ธฐ

model.fit()

๋ฐ์ดํ„ฐ์„ธํŠธ๊ฐ€ ์ฃผ ๋ฉ”๋ชจ๋ฆฌ์— ์ ํ•ฉํ•˜๊ฒŒ ๋งž๊ณ  ๋‹จ์ผ ํ…์„œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ๊ฒฝ์šฐ fit() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// Generate dummy data. const data = tf.randomNormal([100, 784]); const labels = tf.randomUniform([100, 10]); function onBatchEnd(batch, logs) { console.log('Accuracy', logs.acc); } // Train for 5 epochs with batch size of 32. model.fit(data, labels, { epochs: 5, batchSize: 32, callbacks: {onBatchEnd} }).then(info => { console.log('Final accuracy', info.history.acc); });

๋‚ด๋ถ€์ ์œผ๋กœ model.fit()๋Š” ๋งŽ์€ ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฅผ ํ›ˆ๋ จ ๋ฐ ๊ฒ€์ฆ ์„ธํŠธ๋กœ ๋ถ„ํ• ํ•˜๊ณ  ๊ฒ€์ฆ ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ›ˆ๋ จ ์ค‘ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ถ„ํ•  ํ›„์— ๋ฐ์ดํ„ฐ๋ฅผ ์…”ํ”Œํ•ฉ๋‹ˆ๋‹ค. ์•ˆ์ „์„ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ fit()๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์ „์— ๋ฏธ๋ฆฌ ์…”ํ”Œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํฐ ๋ฐ์ดํ„ฐ ํ…์„œ๋ฅผ batchSize. ํฌ๊ธฐ์˜ ๋” ์ž‘์€ ํ…์„œ๋กœ ๋ถ„ํ• ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜์™€ ๊ด€๋ จํ•˜์—ฌ ๋ชจ๋ธ ์†์‹ค์„ ๊ณ„์‚ฐํ•˜๋Š” ๋™์•ˆ optimizer.minimize()๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ epoch ๋˜๋Š” ๋ฐฐ์น˜์˜ ์‹œ์ž‘๊ณผ ๋์„ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ๋ชจ๋“  ๋ฐฐ์น˜๊ฐ€ ๋๋‚  ๋•Œ callbacks.onBatchEnd ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์•Œ๋ฆผ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ต์…˜์œผ๋กœ๋Š” onTrainBegin , onTrainEnd, onEpochBegin , onEpochEnd ๋ฐ onBatchBegin์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • JS ์ด๋ฒคํŠธ ๋ฃจํ”„์— ๋Œ€๊ธฐ ์ค‘์ธ ์ž‘์—…์„ ์ ์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฃผ ์Šค๋ ˆ๋“œ์— ์–‘๋ณดํ•ฉ๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ fit() ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. Core API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ์„ ํƒํ•œ ๊ฒฝ์šฐ ์ด ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

model.fitDataset()

๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์™„์ „ํžˆ ๋งž์ง€ ์•Š๊ฑฐ๋‚˜ ์ŠคํŠธ๋ฆฌ๋ฐ๋˜๋Š” ๊ฒฝ์šฐ Dataset ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” fitDataset()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ฐ™์€ ํ›ˆ๋ จ ์ฝ”๋“œ์ด์ง€๋งŒ ์ƒ์„ฑ๊ธฐ ํ•จ์ˆ˜๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๋ฐ์ดํ„ฐ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

function* data() { for (let i = 0; i < 100; i++) { // Generate one sample at a time. yield tf.randomNormal([784]); } } function* labels() { for (let i = 0; i < 100; i++) { // Generate one sample at a time. yield tf.randomUniform([10]); } } const xs = tf.data.generator(data); const ys = tf.data.generator(labels); // We zip the data and labels together, shuffle and batch 32 samples at a time. const ds = tf.data.zip({xs, ys}).shuffle(100 /* bufferSize */).batch(32); // Train the model for 5 epochs. model.fitDataset(ds, {epochs: 5}).then(info => { console.log('Accuracy', info.history.acc); });

๋ฐ์ดํ„ฐ์„ธํŠธ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ model.fitDataset() ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ์˜ˆ์ธกํ•˜๊ธฐ

ํ•œ๋ฒˆ ํ›ˆ๋ จ์„ ๊ฑฐ์น˜๋ฉด ๋ชจ๋ธ์ด model.predict()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ณด์ด์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์˜ ์˜ˆ์ธก๊ฐ’์„ ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// Predict 3 random samples. const prediction = model.predict(tf.randomNormal([3, 784])); prediction.print();

์ฐธ๊ณ : ๋ชจ๋ธ ๋ฐ ๋ ˆ์ด์–ด ๊ฐ€์ด๋“œ์—์„œ ์–ธ๊ธ‰๋˜์—ˆ๋“ฏ์ดLayersModel์€ ์ž…๋ ฅ์˜ ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ ์ฐจ์›์ด ๋ฐฐ์น˜ ํฌ๊ธฐ์ผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์˜ˆ์—์„œ ๋ฐฐ์น˜ ํฌ๊ธฐ๋Š” 3์ž…๋‹ˆ๋‹ค.

Core API

์•ž์„œ TensorFlow.js์—์„œ ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋จผ์ € ์ž˜ ์ฑ„ํƒ๋œ Keras API๋ฅผ ๋ชจ๋ธ๋กœ ํ•˜๋Š” Layers API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Layers API๋Š” ๊ฐ€์ค‘์น˜ ์ดˆ๊ธฐํ™”, ๋ชจ๋ธ ์ง๋ ฌํ™”, ๋ชจ๋‹ˆํ„ฐ๋ง ํ›ˆ๋ จ, ์ด์‹์„ฑ ๋ฐ ์•ˆ์ „ ๊ฒ€์‚ฌ์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๊ธฐ์„ฑ ์†”๋ฃจ์…˜๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ Core API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ตœ๋Œ€ํ•œ์˜ ์œ ์—ฐ์„ฑ ๋˜๋Š” ์ œ์–ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ทธ๋ฆฌ๊ณ  ์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ž์ฒด์ ์œผ๋กœ ์ง๋ ฌํ™” ๋…ผ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ชจ๋ธ ๋ฐ ๋ ˆ์ด์–ด ๊ฐ€์ด๋“œ์˜ 'Core API'์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

Core API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ ์œ„์™€ ๋™์ผํ•œ ๋ชจ๋ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// The weights and biases for the two dense layers. const w1 = tf.variable(tf.randomNormal([784, 32])); const b1 = tf.variable(tf.randomNormal([32])); const w2 = tf.variable(tf.randomNormal([32, 10])); const b2 = tf.variable(tf.randomNormal([10])); function model(x) { return x.matMul(w1).add(b1).relu().matMul(w2).add(b2); }

Layers API ์™ธ์—๋„ Data API๋Š” Core API์™€ ์›ํ™œํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์…”ํ”Œ ๋ฐ ์ผ๊ด„ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” model.fitDataset () ์„น์…˜์—์„œ ์ด์ „์— ์ •์˜ํ•œ ๋ฐ์ดํ„ฐ์„ธํŠธ๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const xs = tf.data.generator(data); const ys = tf.data.generator(labels); // Zip the data and labels together, shuffle and batch 32 samples at a time. const ds = tf.data.zip({xs, ys}).shuffle(100 /* bufferSize */).batch(32);

๋ชจ๋ธ์„ ํ›ˆ๋ จํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const optimizer = tf.train.sgd(0.1 /* learningRate */); // Train for 5 epochs. for (let epoch = 0; epoch < 5; epoch++) { await ds.forEachAsync(({xs, ys}) => { optimizer.minimize(() => { const predYs = model(xs); const loss = tf.losses.softmaxCrossEntropy(ys, predYs); loss.data().then(l => console.log('Loss', l)); return loss; }); }); console.log('Epoch', epoch); }

์œ„์˜ ์ฝ”๋“œ๋Š” Core API๋กœ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•  ๋•Œ ์“ฐ์ด๋Š” ํ‘œ์ค€ ๋ ˆ์‹œํ”ผ์ž…๋‹ˆ๋‹ค.

  • epoch ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ epoch ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. Dataset๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ <a href="https://js.tensorflow.org/api/0.15.1/#tf.data.Dataset.forEachAsync" data-md-type="link">dataset.forEachAsync()</a>๋Š” ๋ฐฐ์น˜๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  • ๊ฐ ๋ฐฐ์น˜์— ๋Œ€ํ•ด <a href="https://js.tensorflow.org/api/latest/#tf.train.Optimizer.minimize" data-md-type="link">optimizer.minimize(f)</a>๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด f๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์•ž์„œ ์ •์˜ํ•œ 4๊ฐœ์˜ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์ถœ๋ ฅ์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • f๋Š” ์†์‹ค์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋ธ์˜ ์˜ˆ์ธก๊ฐ’๊ณผ ์‹ค์ œ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ •์˜๋œ ์†์‹ค ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.