В машинном обучении модель — это функция с обучаемыми параметрами , которая сопоставляет входные данные с выходными данными. Оптимальные параметры получаются путем обучения модели на данных. Хорошо обученная модель обеспечит точное сопоставление входных данных с желаемыми выходными данными.
В TensorFlow.js есть два способа создания модели машинного обучения:
- используя Layers API, где вы строите модель, используя слои .
- использование 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. Далее см. руководство по обучению моделей , чтобы узнать, как обучать модель.