Модели и слои

В машинном обучении модель — это функция с обучаемыми параметрами , которая сопоставляет входные данные с выходными данными. Оптимальные параметры получаются путем обучения модели на данных. Хорошо обученная модель обеспечит точное сопоставление входных данных с желаемыми выходными данными.

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

  1. используя Layers API, где вы строите модель с использованием слоев .
  2. использование Core API с операциями более низкого уровня, такими как tf.matMul() , tf.add() и т. д.

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

Создание моделей с помощью Layers API

Существует два способа создания модели с использованием Layers API: последовательная модель и функциональная модель. В следующих двух разделах каждый тип рассматривается более подробно.

Последовательная модель

Наиболее распространенным типом модели является Sequential модель, представляющая собой линейный набор слоев. Вы можете создать Sequential модель, передав список слоев функции sequential() :

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

Или через метод add() :

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

ВАЖНО: первому слою модели требуется inputShape . Обязательно исключите размер пакета при предоставлении inputShape . Например, если вы планируете передать тензоры модели формы [B, 784] , где B может быть любым размером пакета, при создании модели укажите inputShape как [784] .

Вы можете получить доступ к слоям модели через model.layers , а точнее model.inputLayers и model.outputLayers .

Функциональная модель

Другой способ создать LayersModel — использовать функцию tf.model() . Ключевое различие между tf.model() и tf.sequential() заключается в том, что tf.model() позволяет создавать произвольный граф слоев, если они не имеют циклов.

Вот фрагмент кода, который определяет ту же модель, что и выше, с использованием API tf.model() :

// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});

Мы вызываем apply() для каждого слоя, чтобы соединить его с выходными данными другого слоя. Результатом apply() в этом случае является SymbolicTensor , который действует как Tensor , но без каких-либо конкретных значений.

Обратите внимание, что в отличие от последовательной модели мы создаем SymbolicTensor с помощью tf.input() вместо предоставления inputShape первому слою.

apply() также может дать вам конкретный Tensor , если вы передадите ему конкретный Tensor :

const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]

Это может быть полезно при изолированном тестировании слоев и просмотре их результатов.

Как и в последовательной модели, вы можете получить доступ к слоям модели через model.layers , а точнее через model.inputLayers и model.outputLayers .

Валидация

И последовательная модель, и функциональная модель являются экземплярами класса LayersModel . Одним из основных преимуществ работы с LayersModel является проверка: она заставляет вас указать форму ввода и использовать ее позже для проверки ввода. LayersModel также выполняет автоматический вывод формы при прохождении данных через слои. Знание формы заранее позволяет модели автоматически создавать ее параметры и сообщать вам, несовместимы ли два последовательных слоя друг с другом.

Краткое описание модели

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

  • Имя и тип всех слоев модели.
  • Выходная форма для каждого слоя.
  • Количество весовых параметров каждого слоя.
  • Если модель имеет общую топологию (обсуждаемую ниже), входные данные получает каждый слой.
  • Общее количество обучаемых и необучаемых параметров модели.

Для модели, которую мы определили выше, мы получаем на консоли следующий вывод:

Слой (тип) Выходная форма Параметр #
плотный_Dense1 (Плотный) [ноль, 32] 25120
плотный_Dense2 (Плотный) [ноль, 10] 330
Всего параметров: 25450
Обучаемые параметры: 25450
Необучаемые параметры: 0

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

Сериализация

Одним из основных преимуществ использования LayersModel по сравнению с API более низкого уровня является возможность сохранять и загружать модель. LayersModel знает о:

  • архитектура модели, позволяющая воссоздать модель.
  • вес модели
  • конфигурация обучения (потери, оптимизатор, метрики).
  • состояние оптимизатора, позволяющее возобновить обучение.

Чтобы сохранить или загрузить модель, достаточно одной строки кода:

const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');

В приведенном выше примере модель сохраняется в локальном хранилище браузера. См. model.save() documentation и руководство по сохранению и загрузке , чтобы узнать, как сохранить на различных носителях (например, в файловом хранилище, IndexedDB , запустить загрузку браузера и т. д.).

Пользовательские слои

Слои — это строительные блоки модели. Если ваша модель выполняет пользовательские вычисления, вы можете определить собственный слой, который хорошо взаимодействует с остальными слоями. Ниже мы определяем пользовательский слой, который вычисляет сумму квадратов:

class SquaredSumLayer extends tf.layers.Layer {
 constructor() {
   super({});
 }
 // In this case, the output is a scalar.
 computeOutputShape(inputShape) { return []; }

 // call() is where we do the computation.
 call(input, kwargs) { return input.square().sum();}

 // Every layer needs a unique name.
 getClassName() { return 'SquaredSum'; }
}

Чтобы проверить это, мы можем вызвать метод apply() с конкретным тензором:

const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30

ВАЖНО: Если вы добавите пользовательский слой, вы потеряете возможность сериализовать модель.

Создание моделей с помощью Core API

В начале этого руководства мы упомянули, что существует два способа создания модели машинного обучения в TensorFlow.js.

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

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

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

Модели в Core API — это просто функции, которые принимают один или несколько Tensors и возвращают Tensor . Та же модель, что и выше, написанная с использованием 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).softmax();
}

Обратите внимание, что в Core API мы отвечаем за создание и инициализацию весов модели. Каждый вес поддерживается Variable , которая сигнализирует TensorFlow.js о том, что эти тензоры можно изучить. Вы можете создать Variable используя tf.variable() и передав существующий Tensor .

В этом руководстве вы ознакомились с различными способами создания модели с использованием слоев и основного API. Далее см. руководство по обучению моделей , чтобы узнать, как обучать модель.