Panduan ini mengasumsikan Anda telah membaca panduan model dan lapisan .
Di TensorFlow.js ada dua cara untuk melatih model pembelajaran mesin:
- menggunakan Layers API dengan
LayersModel.fit()
atauLayersModel.fitDataset()
. - menggunakan API Inti dengan
Optimizer.minimize()
.
Pertama, kita akan melihat Layers API, yang merupakan API tingkat tinggi untuk membangun dan melatih model. Kemudian, kami akan menunjukkan cara melatih model yang sama menggunakan Core API.
Perkenalan
Model pembelajaran mesin adalah fungsi dengan parameter yang dapat dipelajari yang memetakan masukan ke keluaran yang diinginkan. Parameter optimal diperoleh dengan melatih model pada data.
Pelatihan melibatkan beberapa langkah:
- Mendapatkan sekumpulan data ke model.
- Meminta model untuk membuat prediksi.
- Membandingkan prediksi tersebut dengan nilai "sebenarnya".
- Memutuskan seberapa besar perubahan setiap parameter sehingga model dapat membuat prediksi yang lebih baik di masa mendatang untuk batch tersebut.
Model yang terlatih akan memberikan pemetaan yang akurat dari masukan hingga keluaran yang diinginkan.
Parameter model
Mari kita definisikan model 2 lapis sederhana menggunakan Layers API:
const model = tf.sequential({
layers: [
tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
tf.layers.dense({units: 10, activation: 'softmax'}),
]
});
Di balik terpalnya, model memiliki parameter (sering disebut sebagai bobot ) yang dapat dipelajari dengan melatih data. Mari kita cetak nama bobot yang terkait dengan model ini dan bentuknya:
model.weights.forEach(w => {
console.log(w.name, w.shape);
});
Kami mendapatkan output berikut:
> dense_Dense1/kernel [784, 32]
> dense_Dense1/bias [32]
> dense_Dense2/kernel [32, 10]
> dense_Dense2/bias [10]
Total ada 4 bobot, 2 per lapisan padat. Hal ini diharapkan karena lapisan padat mewakili fungsi yang memetakan tensor masukan x
ke tensor keluaran y
melalui persamaan y = Ax + b
dengan A
(kernel) dan b
(bias) adalah parameter lapisan padat.
CATATAN: Secara default, lapisan padat menyertakan bias, namun Anda dapat mengecualikannya dengan menentukan
{useBias: false}
dalam opsi saat membuat lapisan padat.
model.summary()
adalah metode yang berguna jika Anda ingin mendapatkan gambaran umum model Anda dan melihat jumlah total parameter:
Lapisan (tipe) | Bentuk keluaran | Parameter # |
padat_Padat1 (Padat) | [batal,32] | 25120 |
padat_Padat2 (Padat) | [batal,10] | 330 |
Jumlah parameter: 25450 Param yang dapat dilatih: 25450 Param yang tidak dapat dilatih: 0 |
Setiap bobot dalam model didukung oleh objek Variable
. Di TensorFlow.js, Variable
adalah Tensor
floating-point dengan satu metode tambahan assign()
yang digunakan untuk memperbarui nilainya. Layers API secara otomatis menginisialisasi bobot menggunakan praktik terbaik. Demi demonstrasi, kita dapat menimpa bobot dengan memanggil assign()
pada variabel yang mendasarinya:
model.weights.forEach(w => {
const newVals = tf.randomNormal(w.shape);
// w.val is an instance of tf.Variable
w.val.assign(newVals);
});
Pengoptimal, kerugian dan metrik
Sebelum Anda melakukan pelatihan apa pun, Anda perlu memutuskan tiga hal:
- Pengoptimal . Tugas pengoptimal adalah memutuskan seberapa besar perubahan setiap parameter dalam model, berdasarkan prediksi model saat ini. Saat menggunakan Layers API, Anda dapat memberikan pengidentifikasi string pengoptimal yang ada (seperti
'sgd'
atau'adam'
), atau instance kelasOptimizer
. - Fungsi kerugian . Suatu tujuan yang akan coba diminimalkan oleh model. Tujuannya adalah memberikan satu angka untuk mengetahui "seberapa salah" prediksi model tersebut. Kerugian dihitung pada setiap kumpulan data sehingga model dapat memperbarui bobotnya. Saat menggunakan Layers API, Anda dapat memberikan pengidentifikasi string dari fungsi kerugian yang ada (seperti
'categoricalCrossentropy'
), atau fungsi apa pun yang mengambil nilai prediksi dan nilai sebenarnya serta mengembalikan kerugian. Lihat daftar kerugian yang ada di dokumen API kami. - Daftar metrik. Mirip dengan kerugian, metrik menghitung satu angka, yang merangkum seberapa baik kinerja model kita. Metrik biasanya dihitung pada seluruh data pada akhir setiap zaman. Paling tidak, kami ingin memantau bahwa kerugian kami akan berkurang seiring berjalannya waktu. Namun, kita sering kali menginginkan metrik yang lebih ramah manusia seperti akurasi. Saat menggunakan Layers API, Anda dapat memberikan pengidentifikasi string dari metrik yang ada (seperti
'accuracy'
), atau fungsi apa pun yang mengambil nilai prediksi dan nilai sebenarnya serta mengembalikan skor. Lihat daftar metrik yang tersedia di dokumen API kami.
Ketika Anda sudah memutuskan, kompilasi LayersModel
dengan memanggil model.compile()
dengan opsi yang disediakan:
model.compile({
optimizer: 'sgd',
loss: 'categoricalCrossentropy',
metrics: ['accuracy']
});
Selama kompilasi, model akan melakukan beberapa validasi untuk memastikan bahwa opsi yang Anda pilih kompatibel satu sama lain.
Pelatihan
Ada dua cara untuk melatih LayersModel
:
- Menggunakan
model.fit()
dan menyediakan data sebagai satu tensor besar. - Menggunakan
model.fitDataset()
dan menyediakan data melalui objekDataset
.
model.fit()
Jika kumpulan data Anda cocok dengan memori utama, dan tersedia sebagai tensor tunggal, Anda dapat melatih model dengan memanggil metode 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);
});
Di balik terpal, model.fit()
dapat melakukan banyak hal untuk kita:
- Membagi data menjadi kumpulan pelatihan dan validasi, dan menggunakan kumpulan validasi untuk mengukur kemajuan selama pelatihan.
- Mengacak data tetapi hanya setelah pemisahan. Agar aman, Anda harus mengacak data terlebih dahulu sebelum meneruskannya ke
fit()
. - Membagi tensor data besar menjadi tensor lebih kecil dengan ukuran
batchSize.
- Memanggil
optimizer.minimize()
sambil menghitung hilangnya model sehubungan dengan kumpulan data. - Itu dapat memberi tahu Anda tentang awal dan akhir setiap zaman atau batch. Dalam kasus kami, kami diberi tahu di akhir setiap batch menggunakan opsi
callbacks.onBatchEnd
. Opsi lainnya meliputi:onTrainBegin
,onTrainEnd
,onEpochBegin
,onEpochEnd
danonBatchBegin
. - Ini menghasilkan thread utama untuk memastikan bahwa tugas-tugas yang diantri di loop peristiwa JS dapat ditangani tepat waktu.
Untuk info lebih lanjut, lihat dokumentasi fit()
. Perhatikan bahwa jika Anda memilih untuk menggunakan Core API, Anda harus mengimplementasikan logika ini sendiri.
model.fitDataset()
Jika data Anda tidak muat seluruhnya di memori, atau sedang dialirkan, Anda bisa melatih model dengan memanggil fitDataset()
, yang menggunakan objek Dataset
. Berikut adalah kode pelatihan yang sama tetapi dengan kumpulan data yang menggabungkan fungsi generator:
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);
});
Untuk informasi selengkapnya tentang kumpulan data, lihat dokumentasi model.fitDataset()
.
Memprediksi data baru
Setelah model dilatih, Anda dapat memanggil model.predict()
untuk membuat prediksi pada data yang tidak terlihat:
// Predict 3 random samples.
const prediction = model.predict(tf.randomNormal([3, 784]));
prediction.print();
API Inti
Sebelumnya, kami telah menyebutkan bahwa ada dua cara untuk melatih model pembelajaran mesin di TensorFlow.js.
Aturan umumnya adalah mencoba menggunakan Layers API terlebih dahulu, karena ini dimodelkan setelah Keras API yang diadopsi dengan baik. Layers API juga menawarkan berbagai solusi siap pakai seperti inisialisasi bobot, serialisasi model, pelatihan pemantauan, portabilitas, dan pemeriksaan keamanan.
Anda mungkin ingin menggunakan Core API kapan pun:
- Anda memerlukan fleksibilitas atau kontrol maksimum.
- Dan Anda tidak memerlukan serialisasi, atau dapat mengimplementasikan logika serialisasi Anda sendiri.
Untuk informasi selengkapnya tentang API ini, baca bagian "API Inti" di panduan Model dan Lapisan .
Model yang sama seperti di atas yang ditulis menggunakan Core API terlihat seperti ini:
// 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);
}
Selain Layers API, Data API juga bekerja secara lancar dengan Core API. Mari kita gunakan kembali kumpulan data yang telah kita definisikan sebelumnya di bagian model.fitDataset() , yang melakukan pengacakan dan pengelompokan untuk kita:
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);
Mari kita latih modelnya:
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);
}
Kode di atas adalah resep standar saat melatih model dengan Core API:
- Ulangi jumlah zaman.
- Di dalam setiap zaman, ulangi kumpulan data Anda. Saat menggunakan
Dataset
,dataset.forEachAsync()
adalah cara mudah untuk mengulang batch Anda. - Untuk setiap batch, panggil
optimizer.minimize(f)
, yang mengeksekusif
dan meminimalkan outputnya dengan menghitung gradien sehubungan dengan empat variabel yang kita definisikan sebelumnya. -
f
menghitung kerugiannya. Ini memanggil salah satu fungsi kerugian yang telah ditentukan sebelumnya menggunakan prediksi model dan nilai sebenarnya.