Тренировочные модели

Это руководство предполагает , что вы уже читали модель и слои руководства.

В TensorFlow.js есть два способа обучения модели машинного обучения:

  1. с помощью слоев с API LayersModel.fit() или LayersModel.fitDataset() .
  2. используя Core API с Optimizer.minimize() .

Сначала мы рассмотрим Layers API, который представляет собой API более высокого уровня для создания и обучения моделей. Затем мы покажем, как обучить ту же модель с помощью Core API.

Вступление

Модель машинного обучения является функцией с изучаемыми параметрами, отображает входной до требуемого выхода. Оптимальные параметры получаются путем обучения модели на данных.

Обучение состоит из нескольких этапов:

  • Получение партии данных модели.
  • Просим модель сделать прогноз.
  • Сравнение этого прогноза с «истинным» значением.
  • Принятие решения о том, насколько изменить каждый параметр, чтобы модель могла лучше прогнозировать будущее для этой партии.

Хорошо обученная модель обеспечит точное сопоставление входных данных с желаемыми выходными данными.

Параметры модели

Давайте определим простую двухслойную модель с помощью Layers API:

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 на каждый плотный слой. Это , как ожидается , так как плотные слои представляют собой функцию , которая отображает входной тензор x на выходе тензор y с помощью уравнения y = Ax + b , где (ядро) и A b (смещения) являются параметрами плотного слоя.

Примечание: По умолчанию плотные слои включают смещение, но его можно исключить, указав {useBias: false} в настройках при создании плотного слоя.

model.summary() является полезным методом , если вы хотите , чтобы получить общее представление о вашей модели и увидеть общее количество параметров:

Слой (тип) Форма вывода Параметр #
плотный_плотный1 (плотный) [null, 32] 25120
плотный_плотный2 (плотный) [null, 10] 330
Всего параметров: 25450
Обучаемые параметры: 25450
Необучаемые параметры: 0

Каждый вес в модели бакэнд с помощью Variable объекта. В TensorFlow.js, А Variable является плавающей точкой Tensor с одним дополнительным методом assign() используется для обновления его значения. 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. Оптимизатор. Задача оптимизатора - решить, насколько изменить каждый параметр в модели с учетом текущего прогноза модели. При использовании слоев API, можно указать либо строку идентификатора существующего оптимизатора (например, 'sgd' или 'adam' ), или экземпляр Optimizer класса.
  2. Функция потерь. Цель, которую модель постарается минимизировать. Его цель - дать единое число, показывающее, насколько ошибочным был прогноз модели. Потери вычисляются для каждого пакета данных, чтобы модель могла обновлять свои веса. При использовании слоев API, можно указать либо строку идентификатор существующей функции потерь (например, 'categoricalCrossentropy' ), или любую функцию , которая принимает предсказанное и истинное значение и возвращает потерю. См список доступных потерь в наших API Docs.
  3. Список показателей. Подобно потерям, метрики вычисляют одно число, обобщающее, насколько хорошо работает наша модель. Метрики обычно рассчитываются на основе всех данных в конце каждой эпохи. По крайней мере, мы хотим следить за тем, чтобы наши убытки со временем уменьшались. Однако нам часто нужна более понятная для человека метрика, такая как точность. При использовании слоев API, можно указать либо строку идентификатора существующего метрики (например, 'accuracy' ), или какой - либо функции , которая принимает предсказанное и истинное значение и возвращает балл. См список доступных показателей в наших API Docs.

Когда вы решили, компилировать LayersModel по телефону model.compile() с предусмотренными опциями:

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() при вычислении потери модели по отношению к партии данных.
  • Он может уведомлять вас о начале и конце каждой эпохи или пакета. В нашем случае, мы уведомляются в конце каждой партии с использованием callbacks.onBatchEnd опции. Другие варианты включают в себя: onTrainBegin , onTrainEnd , onEpochBegin , onEpochEnd и onBatchBegin .
  • Он уступает основному потоку, чтобы гарантировать, что задачи, поставленные в очередь в цикле событий JS, могут быть обработаны своевременно.

Для получения дополнительной информации см документации по fit() . Обратите внимание: если вы решите использовать Core API, вам придется реализовать эту логику самостоятельно.

model.fitDataset ()

Если данные не помещаются полностью в памяти или время потоковых, вы можете тренировать модель по телефону fitDataset() , который принимает Dataset объект. Вот тот же обучающий код, но с набором данных, который включает функцию генератора:

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

Core API

Ранее мы упоминали, что есть два способа обучения модели машинного обучения в TensorFlow.js.

Общее практическое правило - сначала попытаться использовать Layers API, поскольку он смоделирован на основе хорошо принятого Keras API. Layers API также предлагает различные готовые решения, такие как инициализация веса, сериализация модели, обучение мониторингу, переносимость и проверка безопасности.

Вы можете использовать Core API всякий раз, когда:

  • Вам нужна максимальная гибкость или контроль.
  • И вам не нужна сериализация, или вы можете реализовать свою собственную логику сериализации.

Для получения дополнительной информации об этой 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:

  • Прокрутите количество эпох.
  • Внутри каждой эпохи перебирайте пакеты данных. При использовании Dataset , dataset.forEachAsync() представляет собой удобный способ петли над вашей партией.
  • Для каждой партии, вызов optimizer.minimize(f) , который выполняет f и сводит к минимуму его выход путем вычисления градиентов в отношении четырех переменных , определенных ранее.
  • f вычисляет потери. Он вызывает одну из предопределенных функций потерь, используя прогноз модели и истинное значение.