Eğitim modelleri

Bu kılavuz , modeller ve katmanlar kılavuzunu zaten okuduğunuz varsayılmaktadır.

TensorFlow.js'de bir makine öğrenimi modelini eğitmenin iki yolu vardır:

  1. Layers API'sini LayersModel.fit() veya LayersModel.fitDataset() ile kullanma.
  2. Core API'yi Optimizer.minimize() ile kullanma.

İlk olarak, model oluşturmaya ve eğitmeye yönelik daha üst düzey bir API olan Katmanlar API'sine bakacağız. Daha sonra aynı modelin Core API kullanılarak nasıl eğitileceğini göstereceğiz.

giriiş

Makine öğrenimi modeli, bir girdiyi istenen çıktıyla eşleyen, öğrenilebilir parametrelere sahip bir işlevdir. Optimum parametreler, modelin veriler üzerinde eğitilmesiyle elde edilir.

Eğitim birkaç adımdan oluşur:

  • Modele bir grup veri alma.
  • Modelden bir tahmin yapmasını istemek.
  • Bu tahminin "gerçek" değerle karşılaştırılması.
  • Modelin o parti için gelecekte daha iyi bir tahmin yapabilmesi için her bir parametrenin ne kadar değiştirileceğine karar vermek.

İyi eğitilmiş bir model, girdiden istenen çıktıya doğru bir eşleme sağlayacaktır.

Modeli parametreleri

Katmanlar API'sini kullanarak basit bir 2 katmanlı model tanımlayalım:

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

Temel olarak modellerde, veriler üzerinde eğitim yapılarak öğrenilebilen parametreler (genellikle ağırlık olarak anılır) bulunur. Bu modele ait ağırlıkların isimlerini ve şekillerini yazdıralım:

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

Aşağıdaki çıktıyı alıyoruz:

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

Yoğun katman başına 2 adet olmak üzere toplam 4 ağırlık bulunmaktadır. Yoğun katmanlar, A (çekirdek) ve b (önyargı) yoğun katmanın parametreleri olduğu y = Ax + b denklemi aracılığıyla giriş tensörü x çıkış tensörü y eşleyen bir fonksiyonu temsil ettiğinden bu beklenen bir durumdur.

NOT: Varsayılan olarak yoğun katmanlar bir önyargı içerir, ancak yoğun bir katman oluştururken seçeneklerde {useBias: false} belirterek bunu hariç tutabilirsiniz.

model.summary() modelinize genel bir bakış sağlamak ve toplam parametre sayısını görmek istiyorsanız kullanışlı bir yöntemdir:

Katman (tür) Çıkış şekli Parametre #
yoğun_Dense1 (Yoğun) [boş,32] 25120
yoğun_Dense2 (Yoğun) [boş,10] 330
Toplam parametreler: 25450
Eğitilebilir parametreler: 25450
Eğitilemeyen parametreler: 0

Modeldeki her ağırlık bir Variable nesne tarafından arka uçta yer alır. TensorFlow.js'de bir Variable , değerlerini güncellemek için kullanılan ek bir assign() yöntemine sahip kayan noktalı bir Tensor . Layers API, en iyi uygulamaları kullanarak ağırlıkları otomatik olarak başlatır. Gösterim amacıyla, temel değişkenler üzerinde assign() çağırarak ağırlıkların üzerine yazabiliriz:

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

Optimize edici, kayıp ve metrik

Herhangi bir eğitime başlamadan önce üç şeye karar vermeniz gerekir:

  1. Bir optimize edici . Optimize edicinin görevi, mevcut model tahmini göz önüne alındığında, modeldeki her bir parametrenin ne kadar değiştirileceğine karar vermektir. Layers API'yi kullanırken, mevcut bir optimize edicinin dize tanımlayıcısını ( 'sgd' veya 'adam' gibi) ya da Optimizer sınıfının bir örneğini sağlayabilirsiniz.
  2. Bir kayıp fonksiyonu . Modelin en aza indirmeye çalışacağı bir amaç. Amacı, modelin tahmininin "ne kadar yanlış" olduğuna ilişkin tek bir sayı vermektir. Modelin ağırlıklarını güncelleyebilmesi için kayıp her veri kümesinde hesaplanır. Katmanlar API'sini kullanırken, mevcut bir kayıp işlevinin dize tanımlayıcısını ( 'categoricalCrossentropy' gibi) veya tahmin edilen ve gerçek değeri alan ve kayıp döndüren herhangi bir işlevi sağlayabilirsiniz. API belgelerimizde mevcut kayıpların listesine bakın.
  3. Metriklerin listesi. Kayıplara benzer şekilde ölçümler, modelimizin ne kadar iyi performans gösterdiğini özetleyen tek bir sayıyı hesaplar. Metrikler genellikle her dönemin sonunda tüm veriler üzerinden hesaplanır. En azından zararımızın zamanla azaldığını izlemek istiyoruz. Ancak çoğu zaman doğruluk gibi daha insan dostu bir ölçüm isteriz. Layers API'yi kullanırken, mevcut bir metriğin dize tanımlayıcısını ( 'accuracy' gibi) veya tahmin edilen ve gerçek değeri alan ve puan döndüren herhangi bir işlevi sağlayabilirsiniz. API belgelerimizde mevcut metriklerin listesine bakın.

Karar verdiğinizde, sağlanan seçeneklerle model.compile() öğesini çağırarak bir LayersModel derleyin:

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

Derleme sırasında model, seçtiğiniz seçeneklerin birbiriyle uyumlu olduğundan emin olmak için bazı doğrulamalar yapacaktır.

Eğitim

LayersModel eğitmenin iki yolu vardır:

  • model.fit() kullanmak ve verileri büyük bir tensör olarak sağlamak.
  • model.fitDataset() işlevini kullanmak ve verileri bir Dataset nesnesi aracılığıyla sağlamak.

model.fit()

Veri kümeniz ana belleğe sığıyorsa ve tek bir tensör olarak mevcutsa fit() yöntemini çağırarak bir modeli eğitebilirsiniz:

// 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);
 });

Aslında model.fit() bizim için çok şey yapabilir:

  • Verileri bir eğitim ve doğrulama kümesine böler ve eğitim sırasındaki ilerlemeyi ölçmek için doğrulama kümesini kullanır.
  • Verileri karıştırır, ancak yalnızca bölünmeden sonra. Güvende olmak için, verileri fit() öğesine aktarmadan önce önceden karıştırmalısınız.
  • Büyük veri tensörünü batchSize.
  • Veri kümesine göre modelin kaybını hesaplarken optimizer.minimize() öğesini çağırır.
  • Her dönemin veya partinin başlangıcında ve sonunda sizi bilgilendirebilir. Bizim durumumuzda, her partinin sonunda callbacks.onBatchEnd seçeneğini kullanarak bilgilendiriliriz. Diğer seçenekler şunlardır: onTrainBegin , onTrainEnd , onEpochBegin , onEpochEnd ve onBatchBegin .
  • JS olay döngüsünde sıralanan görevlerin zamanında ele alınabilmesini sağlamak için ana iş parçacığına teslim olur.

Daha fazla bilgi için fit() belgelerine bakın. Çekirdek API'yi kullanmayı seçerseniz bu mantığı kendiniz uygulamanız gerekeceğini unutmayın.

model.fitDataset()

Verileriniz belleğe tam olarak sığmıyorsa veya akışa alınıyorsa, bir Dataset nesnesi alan fitDataset() öğesini çağırarak bir modeli eğitebilirsiniz. İşte aynı eğitim kodu, ancak bir oluşturucu işlevini saran bir veri kümesiyle:

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);
});

Veri kümeleri hakkında daha fazla bilgi için model.fitDataset() belgelerine bakın.

Yeni verileri tahmin etmek

Model eğitildikten sonra görünmeyen veriler üzerinde tahminlerde bulunmak için model.predict() çağırabilirsiniz:

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

Çekirdek API

Daha önce TensorFlow.js'de makine öğrenimi modeli eğitmenin iki yolu olduğundan bahsetmiştik.

Genel kural, iyi benimsenmiş Keras API'sinden sonra modellendiğinden, önce Katmanlar API'sini kullanmaya çalışmaktır. Layers API ayrıca ağırlık başlatma, model serileştirme, izleme eğitimi, taşınabilirlik ve güvenlik kontrolü gibi çeşitli kullanıma hazır çözümler sunar.

Core API'yi aşağıdaki durumlarda kullanmak isteyebilirsiniz:

  • Maksimum esnekliğe veya kontrole ihtiyacınız var.
  • Ayrıca serileştirmeye ihtiyacınız yoktur veya kendi serileştirme mantığınızı uygulayabilirsiniz.

Bu API hakkında daha fazla bilgi için Modeller ve Katmanlar kılavuzundaki "Çekirdek API" bölümünü okuyun.

Yukarıda Core API kullanılarak yazılan modelin aynısı şuna benzer:

// 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'ye ek olarak Data API, Core API ile de sorunsuz bir şekilde çalışır. Karıştırma ve toplu işlemleri bizim için yapan model.fitDataset() bölümünde daha önce tanımladığımız veri kümesini yeniden kullanalım:

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);

Modeli eğitelim:

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);
}

Yukarıdaki kod, Core API ile bir model eğitilirken kullanılan standart tariftir:

  • Dönem sayısı üzerinde döngü yapın.
  • Her çağın içinde veri gruplarınız üzerinde döngü yapın. Bir Dataset kullanırken dataset.forEachAsync() toplu işleriniz üzerinde döngü oluşturmanın kolay bir yoludur.
  • Her grup için, f çalıştıran ve daha önce tanımladığımız dört değişkene göre gradyanları hesaplayarak çıktısını en aza indiren optimizer.minimize(f) çağrısını yapın.
  • f kaybı hesaplar. Modelin tahminini ve gerçek değeri kullanarak önceden tanımlanmış kayıp fonksiyonlarından birini çağırır.