Melatih model

Panduan ini mengasumsikan Anda telah membaca panduan model dan lapisan .

Di TensorFlow.js ada dua cara untuk melatih model pembelajaran mesin:

  1. menggunakan Layers API dengan LayersModel.fit() atau LayersModel.fitDataset() .
  2. 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:

  1. 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 kelas Optimizer .
  2. 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 API Lapisan, 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.
  3. 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 objek Dataset .

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 dan onBatchBegin .
  • 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 mengeksekusi f 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.