Model pelatihan

Panduan ini mengasumsikan Anda sudah membaca model dan lapisan panduan.

Di TensorFlow.js ada dua cara untuk melatih model machine learning:

  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.

pengantar

Sebuah model pembelajaran mesin adalah fungsi dengan parameter dipelajari yang memetakan input ke output yang diinginkan. Parameter optimal diperoleh dengan melatih model pada data.

Pelatihan melibatkan beberapa langkah:

  • Mendapatkan bets data untuk model.
  • Meminta model untuk membuat prediksi.
  • Membandingkan prediksi itu dengan nilai "benar".
  • Memutuskan berapa banyak untuk mengubah setiap parameter sehingga model dapat membuat prediksi yang lebih baik di masa mendatang untuk batch tersebut.

Model yang terlatih dengan baik akan memberikan pemetaan yang akurat dari input hingga output yang diinginkan.

Parameter model

Mari kita definisikan model 2-layer 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 bawah tenda, model memiliki parameter (sering disebut sebagai bobot) yang bisa dipelajari dengan melatih pada data. Mari kita cetak nama-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]

Ada 4 bobot total, 2 per lapisan padat. Hal ini diharapkan karena lapisan padat merupakan fungsi yang memetakan input tensor x untuk output tensor y melalui persamaan y = Ax + b dimana A (kernel) dan b (bias) adalah parameter dari lapisan padat.

CATATAN: Secara default lapisan padat termasuk bias, tetapi Anda dapat mengecualikan itu dengan menentukan {useBias: false} dalam pilihan saat membuat lapisan padat.

model.summary() adalah metode yang berguna jika Anda ingin mendapatkan gambaran tentang model Anda dan melihat jumlah total parameter:

Lapisan (tipe) Bentuk keluaran Param #
padat_padat1 (padat) [null,32] 25120
padat_padat2 (padat) [null,10] 330
Jumlah parameter: 25450
Parameter yang dapat dilatih: 25450
Params yang tidak dapat dilatih: 0

Setiap berat badan dalam model ini backend oleh Variable objek. Dalam TensorFlow.js, sebuah Variable adalah floating-point Tensor dengan satu metode tambahan assign() digunakan untuk memperbarui nilai-nilainya. Layers API secara otomatis menginisialisasi bobot menggunakan praktik terbaik. Demi demonstrasi, kita bisa menimpa bobot dengan memanggil assign() pada variabel yang mendasari:

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. Sebuah optimizer. Tugas pengoptimal adalah memutuskan seberapa banyak perubahan setiap parameter dalam model, mengingat prediksi model saat ini. Bila menggunakan Layers API, Anda dapat menyediakan baik identifier string dari suatu optimizer yang ada (seperti 'sgd' atau 'adam' ), atau sebuah instance dari Optimizer kelas.
  2. Sebuah fungsi kerugian. Sebuah tujuan yang model akan mencoba untuk meminimalkan. Tujuannya adalah untuk memberikan satu angka untuk "seberapa salah" prediksi model itu. Kerugian dihitung pada setiap kumpulan data sehingga model dapat memperbarui bobotnya. Bila menggunakan Layers API, Anda dapat menyediakan baik identifier string fungsi kerugian yang ada (seperti 'categoricalCrossentropy' ), atau fungsi yang mengambil dan nilai sebenarnya diprediksi dan kembali kerugian. Lihat daftar kerugian yang tersedia di docs API kami.
  3. Daftar metrik. Mirip dengan kerugian, metrik menghitung satu angka, meringkas seberapa baik kinerja model kami. Metrik biasanya dihitung pada seluruh data pada akhir setiap zaman. Paling tidak, kami ingin memantau bahwa kerugian kami turun dari waktu ke waktu. Namun, kami sering menginginkan metrik yang lebih ramah manusia seperti akurasi. Bila menggunakan Layers API, Anda dapat menyediakan baik identifier string yang ada metrik (seperti 'accuracy' ), atau fungsi yang mengambil dan nilai sebenarnya diprediksi dan kembali skor. Lihat daftar metrik yang tersedia di docs API kami.

Ketika Anda telah memutuskan, menyusun LayersModel dengan memanggil model.compile() dengan pilihan 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 salah satu tensor besar.
  • Menggunakan model.fitDataset() dan menyediakan data melalui Dataset objek.

model.fit()

Jika cocok dataset Anda dalam memori utama, dan tersedia sebagai tensor tunggal, Anda dapat melatih model dengan memanggil fit() metode:

// 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 bawah tenda, model.fit() dapat melakukan banyak hal bagi kita:

  • Membagi data menjadi rangkaian pelatihan dan validasi, dan menggunakan set validasi untuk mengukur kemajuan selama pelatihan.
  • Mengacak data tetapi hanya setelah pemisahan. Untuk amannya, Anda harus pra-mengocok data sebelum diteruskan ke fit() .
  • Membagi tensor data yang besar menjadi tensor lebih kecil dari ukuran batchSize.
  • Panggilan optimizer.minimize() sedangkan komputasi hilangnya model sehubungan dengan batch data.
  • Itu dapat memberi tahu Anda di awal dan akhir setiap zaman atau batch. Dalam kasus kami, kami diberitahu pada akhir setiap bets menggunakan callbacks.onBatchEnd pilihan. Pilihan lainnya termasuk: onTrainBegin , onTrainEnd , onEpochBegin , onEpochEnd dan onBatchBegin .
  • Ini menghasilkan utas utama untuk memastikan bahwa tugas yang diantrekan di loop acara JS dapat ditangani tepat waktu.

Untuk info lebih lanjut, lihat dokumentasi dari fit() . Perhatikan bahwa jika Anda memilih untuk menggunakan Core API, Anda harus menerapkan logika ini sendiri.

model.fitDataset()

Jika data Anda tidak cocok seluruhnya dalam memori, atau sedang streaming, Anda dapat melatih model dengan memanggil fitDataset() , yang membutuhkan Dataset objek. Berikut adalah kode pelatihan yang sama tetapi dengan dataset yang membungkus 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 info lebih lanjut tentang dataset, lihat dokumentasi dari model.fitDataset() .

Memprediksi data baru

Setelah model telah dilatih, Anda dapat menghubungi model.predict() untuk membuat prediksi pada data tak 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 machine learning di TensorFlow.js.

Aturan umum adalah mencoba menggunakan Layers API terlebih dahulu, karena dimodelkan setelah API Keras 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 membutuhkan fleksibilitas atau kontrol maksimum.
  • Dan Anda tidak perlu serialisasi, atau dapat menerapkan logika serialisasi Anda sendiri.

Untuk informasi lebih lanjut tentang API ini, baca bagian "Inti API" di Model dan Layers panduan.

Model yang sama seperti yang ditulis di atas 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 dengan lancar dengan Core API. Mari kita menggunakan kembali dataset yang kita definisikan sebelumnya di model.fitDataset () bagian, yang tidak menyeret dan batching bagi 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 epoch.
  • Di dalam setiap zaman, ulangi kumpulan data Anda. Bila menggunakan Dataset , dataset.forEachAsync() adalah cara yang nyaman untuk loop atas batch Anda.
  • Untuk setiap batch, panggilan optimizer.minimize(f) , yang mengeksekusi f dan meminimalkan output dengan menghitung gradien sehubungan dengan empat variabel yang kita definisikan sebelumnya.
  • f menghitung kerugian. Ini memanggil salah satu fungsi kerugian yang telah ditentukan menggunakan prediksi model dan nilai sebenarnya.