Обзор Keras

Смотрите на TensorFlow.org Запустите в Google Colab Изучайте код на GitHub Скачайте ноутбук

Это руководство даст вам основы для начала работы с Keras. Чтение займет 10 минут.

Импортируйте tf.keras

tf.keras является реализацией TensorFlow спецификации Keras API. Это высокоуровневый API для построения и обучения моделей включающий первоклассную поддержку для TensorFlow-специфичной функциональности, такой как eager execution, конвейеры tf.data, и Estimators. tf.keras делает использование TensorFlow проще не жертвуя при этом гибкостью и производительностью.

Для начала, импортируйте tf.keras как часть установки вашей TensorFlow:

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

from tensorflow import keras

tf.keras может выполнять любой Keras-совместимый код, но имейте ввиду:

Постройте простую модель

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

В Keras, вы собираете слои (layers) для построения моделей (models). Модель это (обычно) граф слоев. Наиболее распространенным видом модели является стек слоев: модель tf.keras.Sequential.

Построение простой полносвязной сети (т.е. многослойного перцептрона):

from tensorflow.keras import layers

model = tf.keras.Sequential()
# Добавим полносвязный слой с 64 узлами к модели:
model.add(layers.Dense(64, activation='relu'))
# Добавим другой слой:
model.add(layers.Dense(64, activation='relu'))
# Добавим слой softmax с 10 выходами:
model.add(layers.Dense(10, activation='softmax'))

Вы можете найти короткий, но полный пример того, как использовать последовательные (Sequential) модели здесь.

Чтобы узнать о построении более сложных чем последовательные (Sequential), см:

Настройте слои

Доступно много разновидностей слоев tf.keras.layers. Большинство из них используют общий конструктор аргументов:

  • activation: Установка функции активации для слоя. В этом параметре указывается имя встроенной функции или вызываемый объект. У параметра нет значения по умолчанию.
  • kernel_initializer И bias_initializer: Схемы инициализации создающие веса слоя (ядро и сдвиг). В этом параметре может быть имя или вызываемый объект. По умолчанию используется инициализатор "Glorot uniform".
  • kernel_regularizer и bias_regularizer: Схемы регуляризации добавляемые к весам слоя (ядро и сдвиг), такие как L1 или L2 регуляризации. По умолчанию регуляризация не устанавливается.

Следующие примеры слоев tf.keras.layers.Dense используют аргументы конструктора:

# Создать слой с сигмоидой:
layers.Dense(64, activation='sigmoid')
# Или:
layers.Dense(64, activation=tf.keras.activations.sigmoid)

# Линейный слой с регуляризацией L1 с коэфициентом 0.01 примененной к матрице ядра:
layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))

# Линейный слой с регуляризацией L2 с коэффициентом 0.01 примененной к вектору сдвига:
layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))

# Линейный слой с ядром инициализированным случайной ортогональной матрицей:
layers.Dense(64, kernel_initializer='orthogonal')

# Линейный слой с вектором сдвига инициализированным значениями 2.0:
layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))
<tensorflow.python.keras.layers.core.Dense at 0x7f93564ea898>

Обучение и оценка

Настройка обучения

После того как модель сконструирована, настройте процесс ее обучения вызовом метода compile:

model = tf.keras.Sequential([
# Добавляем полносвязный слой с 64 узлами к модели:
layers.Dense(64, activation='relu', input_shape=(32,)),
# Добавляем другой слой:
layers.Dense(64, activation='relu'),
# Добавляем слой softmax с 10 выходами:
layers.Dense(10, activation='softmax')])

model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

tf.keras.Model.compile принимает три важных аргумента:

  • optimizer: Этот объект определяет процедуру обучения. Передайте в него экземпляры оптимизатора из модуля tf.keras.optimizers, такие как tf.keras.optimizers.Adam или tf.keras.optimizers.SGD. Если вы просто хотите использовать значения по умолчанию, вы также можете указать оптимизаторы ключевыми словами, такими как 'adam' или 'sgd'.
  • loss: Это функция которая минимизируется в процессе обучения. Среди распространенных вариантов mean square error (mse), categorical_crossentropy, и binary_crossentropy. Функции потерь указываются по имени или по передаче вызываемого объекта из модуля tf.keras.losses.
  • metrics: Используются для мониторинга обучения. Это строковые имена или вызываемые объекты из модуля tf.keras.metrics.
  • Кроме того, чтобы быть уверенным, что модель обучается и оценивается eagerly, проверьте что вы передали компилятору параметр run_eagerly=True

Далее посмотрим несколько примеров конфигурации модели для обучения:

# Сконфигурируем модель для регрессии со среднеквадратичной ошибкой.
model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
              loss='mse',       # срееднеквадратичная ошибка
              metrics=['mae'])  # средняя абсолютная ошибка

# Сконфигурируем модель для категориальной классификации.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.01),
              loss=tf.keras.losses.CategoricalCrossentropy(),
              metrics=[tf.keras.metrics.CategoricalAccuracy()])

Обучение на данных NumPy

Для небольших датасетов используйте помещающиеся в память массивы NumPy для обучения и оценки модели. Модель "обучается" на тренировочных даннных используя метод fit:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.fit(data, labels, epochs=10, batch_size=32)
Train on 1000 samples
Epoch 1/10
1000/1000 [==============================] - 1s 745us/sample - loss: 210.3580 - categorical_accuracy: 0.1170
Epoch 2/10
1000/1000 [==============================] - 0s 89us/sample - loss: 844.6599 - categorical_accuracy: 0.0980
Epoch 3/10
1000/1000 [==============================] - 0s 89us/sample - loss: 1728.6746 - categorical_accuracy: 0.0940
Epoch 4/10
1000/1000 [==============================] - 0s 90us/sample - loss: 2856.4144 - categorical_accuracy: 0.1000
Epoch 5/10
1000/1000 [==============================] - 0s 88us/sample - loss: 4405.2240 - categorical_accuracy: 0.0890
Epoch 6/10
1000/1000 [==============================] - 0s 88us/sample - loss: 6004.5073 - categorical_accuracy: 0.1000
Epoch 7/10
1000/1000 [==============================] - 0s 88us/sample - loss: 7630.2912 - categorical_accuracy: 0.1130
Epoch 8/10
1000/1000 [==============================] - 0s 87us/sample - loss: 10247.0097 - categorical_accuracy: 0.0960
Epoch 9/10
1000/1000 [==============================] - 0s 89us/sample - loss: 12596.5057 - categorical_accuracy: 0.0970
Epoch 10/10
1000/1000 [==============================] - 0s 90us/sample - loss: 14518.4998 - categorical_accuracy: 0.1140

<tensorflow.python.keras.callbacks.History at 0x7f935420cac8>

tf.keras.Model.fit принимает три важных аргумента:

  • epochs: Обучение разбито на эпохи. Эпоха это одна итерация по всем входным данным (это делается небольшими партиями).
  • batch_size: При передаче данных NumPy, модель разбивает данные на меньшие блоки (batches) и итерирует по этим блокам во время обучения. Это число указывает размер каждого блока данных. Помните, что последний блок может быть меньшего размера если общее число записей не делится на размер партии.
  • validation_data: При прототипировании модели вы хотите легко отслеживать её производительность на валидационных данных. Передача с этим аргументом кортежа входных данных и меток позволяет модели отопражать значения функции потерь и метрики в режиме вывода для передаваемых данных в конце каждой эпохи.

Вот пример использования validation_data:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

val_data = np.random.random((100, 32))
val_labels = np.random.random((100, 10))

model.fit(data, labels, epochs=10, batch_size=32,
          validation_data=(val_data, val_labels))
Train on 1000 samples, validate on 100 samples
Epoch 1/10
1000/1000 [==============================] - 0s 192us/sample - loss: 18156.7571 - categorical_accuracy: 0.0930 - val_loss: 23463.1391 - val_categorical_accuracy: 0.0500
Epoch 2/10
1000/1000 [==============================] - 0s 99us/sample - loss: 20489.6666 - categorical_accuracy: 0.0970 - val_loss: 15680.4291 - val_categorical_accuracy: 0.0800
Epoch 3/10
1000/1000 [==============================] - 0s 99us/sample - loss: 23987.2277 - categorical_accuracy: 0.0930 - val_loss: 25098.6495 - val_categorical_accuracy: 0.1200
Epoch 4/10
1000/1000 [==============================] - 0s 100us/sample - loss: 28209.8688 - categorical_accuracy: 0.1010 - val_loss: 49399.7891 - val_categorical_accuracy: 0.0900
Epoch 5/10
1000/1000 [==============================] - 0s 103us/sample - loss: 31390.5183 - categorical_accuracy: 0.1000 - val_loss: 38560.5677 - val_categorical_accuracy: 0.1400
Epoch 6/10
1000/1000 [==============================] - 0s 101us/sample - loss: 35416.1291 - categorical_accuracy: 0.0880 - val_loss: 44403.6584 - val_categorical_accuracy: 0.1100
Epoch 7/10
1000/1000 [==============================] - 0s 104us/sample - loss: 39149.5079 - categorical_accuracy: 0.1280 - val_loss: 31191.3916 - val_categorical_accuracy: 0.1100
Epoch 8/10
1000/1000 [==============================] - 0s 99us/sample - loss: 45070.2486 - categorical_accuracy: 0.0860 - val_loss: 52098.1728 - val_categorical_accuracy: 0.1000
Epoch 9/10
1000/1000 [==============================] - 0s 102us/sample - loss: 49573.1952 - categorical_accuracy: 0.1030 - val_loss: 77907.8463 - val_categorical_accuracy: 0.1000
Epoch 10/10
1000/1000 [==============================] - 0s 102us/sample - loss: 53325.0839 - categorical_accuracy: 0.0970 - val_loss: 44146.9248 - val_categorical_accuracy: 0.0500

<tensorflow.python.keras.callbacks.History at 0x7f935408b198>

Обучение с использованием наборов данных tf.data

Используйте Datasets API для масштабирования больших баз данных или обучения на нескольких устройствах. Передайте экземпляр tf.data.Dataset в метод fit:

# Создает экземпляр учебного датасета:
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.fit(dataset, epochs=10)
Train for 32 steps
Epoch 1/10
32/32 [==============================] - 0s 9ms/step - loss: 58812.4480 - categorical_accuracy: 0.0870
Epoch 2/10
32/32 [==============================] - 0s 3ms/step - loss: 64410.5913 - categorical_accuracy: 0.1020
Epoch 3/10
32/32 [==============================] - 0s 3ms/step - loss: 73670.3043 - categorical_accuracy: 0.0820
Epoch 4/10
32/32 [==============================] - 0s 3ms/step - loss: 77134.9311 - categorical_accuracy: 0.1040
Epoch 5/10
32/32 [==============================] - 0s 3ms/step - loss: 81619.6878 - categorical_accuracy: 0.1050
Epoch 6/10
32/32 [==============================] - 0s 3ms/step - loss: 90435.1660 - categorical_accuracy: 0.1030
Epoch 7/10
32/32 [==============================] - 0s 3ms/step - loss: 98167.7955 - categorical_accuracy: 0.0970
Epoch 8/10
32/32 [==============================] - 0s 3ms/step - loss: 104775.1982 - categorical_accuracy: 0.0950
Epoch 9/10
32/32 [==============================] - 0s 3ms/step - loss: 112499.3215 - categorical_accuracy: 0.0960
Epoch 10/10
32/32 [==============================] - 0s 3ms/step - loss: 114244.1738 - categorical_accuracy: 0.1060

<tensorflow.python.keras.callbacks.History at 0x7f9354195390>

Поскольку Dataset выдает данные пакетами, этот кусок кода не требует аргумента batch_size.

Датасеты могут быть также использованы для валидации:

dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
val_dataset = val_dataset.batch(32)

model.fit(dataset, epochs=10,
          validation_data=val_dataset)
Train for 32 steps, validate for 4 steps
Epoch 1/10
32/32 [==============================] - 0s 6ms/step - loss: 127322.8653 - categorical_accuracy: 0.1020 - val_loss: 115275.1406 - val_categorical_accuracy: 0.1000
Epoch 2/10
32/32 [==============================] - 0s 3ms/step - loss: 134345.5976 - categorical_accuracy: 0.0890 - val_loss: 197049.1953 - val_categorical_accuracy: 0.1000
Epoch 3/10
32/32 [==============================] - 0s 3ms/step - loss: 145004.1893 - categorical_accuracy: 0.0850 - val_loss: 98326.1465 - val_categorical_accuracy: 0.0800
Epoch 4/10
32/32 [==============================] - 0s 3ms/step - loss: 148997.6304 - categorical_accuracy: 0.0980 - val_loss: 181924.9961 - val_categorical_accuracy: 0.0800
Epoch 5/10
32/32 [==============================] - 0s 3ms/step - loss: 162229.2392 - categorical_accuracy: 0.0860 - val_loss: 136020.0371 - val_categorical_accuracy: 0.1000
Epoch 6/10
32/32 [==============================] - 0s 3ms/step - loss: 161981.5365 - categorical_accuracy: 0.1080 - val_loss: 202202.4023 - val_categorical_accuracy: 0.1000
Epoch 7/10
32/32 [==============================] - 0s 3ms/step - loss: 182517.2547 - categorical_accuracy: 0.1000 - val_loss: 282729.1953 - val_categorical_accuracy: 0.1000
Epoch 8/10
32/32 [==============================] - 0s 3ms/step - loss: 195815.6419 - categorical_accuracy: 0.0830 - val_loss: 199730.4180 - val_categorical_accuracy: 0.0900
Epoch 9/10
32/32 [==============================] - 0s 3ms/step - loss: 192467.3829 - categorical_accuracy: 0.1180 - val_loss: 175976.8008 - val_categorical_accuracy: 0.0500
Epoch 10/10
32/32 [==============================] - 0s 3ms/step - loss: 206873.8795 - categorical_accuracy: 0.0830 - val_loss: 134115.6465 - val_categorical_accuracy: 0.1200

<tensorflow.python.keras.callbacks.History at 0x7f9348753cf8>

Оценка и предсказание

Методы tf.keras.Model.evaluate и tf.keras.Model.predict могут использовать данные NumPy и tf.data.Dataset.

Вот так можно оценить потери в режиме вывода и метрики для предоставленных данных:

# С массивом Numpy
data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.evaluate(data, labels, batch_size=32)

# С датасетом
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.evaluate(dataset)
1000/1000 [==============================] - 0s 55us/sample - loss: 137957.9651 - categorical_accuracy: 0.1100
32/32 [==============================] - 0s 2ms/step - loss: 137723.3364 - categorical_accuracy: 0.1100

[137723.33642578125, 0.11]

А вот как предсказать вывод последнего уровня в режиме вывода для предоставленных данных, в виде массива NumPy:

result = model.predict(data, batch_size=32)
print(result.shape)
(1000, 10)

Полное руководство по обучению и оценке модели, включая описание написания пользовательских циклов обучения с нуля, см. в руководстве по обучению и оценке.

Построение сложных моделей

The Functional API

Модель tf.keras.Sequential это простой стек слоев с помощью которого нельзя представить произвольную модель. Используйте Keras functional API для построения сложных топологий моделей, таких как:

  • Модели с несколькими входами,
  • Модели с несколькими выходами,
  • Модели с общими слоями (один и тот же слой вызывается несколько раз),
  • Модели с непоследовательными потоками данных (напр. остаточные связи).

Построение модели с functional API работает следующим образом:

  1. Экземпляр слоя является вызываемым и возвращает тензор.
  2. Входные и выходные тензоры используются для определения экземпляра tf.keras.Model
  3. Эта модель обучается точно так же как и Sequential модель.

Следующий пример использует functional API для построения простой, полносвязной сети:

inputs = tf.keras.Input(shape=(32,))  # Возвращает входной плейсхолдер

# Экземпляр слоя вызывается на тензор и возвращает тензор.
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dense(64, activation='relu')(x)
predictions = layers.Dense(10, activation='softmax')(x)

Создайте экземпляр модели с данными входами и выходами.

model = tf.keras.Model(inputs=inputs, outputs=predictions)

# Шаг компиляции определяет конфигурацию обучения.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Обучение  за 5 эпох
model.fit(data, labels, batch_size=32, epochs=5)
Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 431us/sample - loss: 13.3398 - accuracy: 0.1030
Epoch 2/5
1000/1000 [==============================] - 0s 80us/sample - loss: 24.0782 - accuracy: 0.0960
Epoch 3/5
1000/1000 [==============================] - 0s 79us/sample - loss: 40.5977 - accuracy: 0.1120
Epoch 4/5
1000/1000 [==============================] - 0s 79us/sample - loss: 60.8738 - accuracy: 0.1040
Epoch 5/5
1000/1000 [==============================] - 0s 82us/sample - loss: 84.6479 - accuracy: 0.1130

<tensorflow.python.keras.callbacks.History at 0x7f93486440f0>

Сабклассинг моделей

Создайте полностью настраиваемую модель с помощью сабклассинга tf.keras.Model и определения вашего собственного прямого распространения. Создайте слои в методе __init__ и установите их как атрибуты экземпляра класса. Определите прямое распространение в методе call.

Сабклассинг модели особенно полезен когда включен eager execution, поскольку он позволяет написать прямое распространение императивно.

Примечание: если вам нужно чтобы ваша модель всегда выполнялась императивно, вы можете установить dynamic=True когда вызываете конструктор super.

Ключевой момент: Используйте правильный API для работы. Хоть сабклассинг модели обеспечивает гибкость, за нее приходится платить большей сложностью и большими возможностями для пользовательских ошибок. Если это возможно выбирайте functional API.

Следующий пример показывает сабклассированную tf.keras.Model использующую пользовательское прямое распространение, которое не обязательно выполнять императивно:

class MyModel(tf.keras.Model):

  def __init__(self, num_classes=10):
    super(MyModel, self).__init__(name='my_model')
    self.num_classes = num_classes
    # Определим свои слои тут.
    self.dense_1 = layers.Dense(32, activation='relu')
    self.dense_2 = layers.Dense(num_classes, activation='sigmoid')

  def call(self, inputs):
    # Определим тут свое прямое распространение,
    # с использованием ранее определенных слоев (в `__init__`).
    x = self.dense_1(inputs)
    return self.dense_2(x)

Создайте экземпляр класса новой модели:

model = MyModel(num_classes=10)

# Шаг компиляции определяет конфигурацию обучения.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Обучение за 5 эпох.
model.fit(data, labels, batch_size=32, epochs=5)
Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 394us/sample - loss: 11.5176 - accuracy: 0.1070
Epoch 2/5
1000/1000 [==============================] - 0s 78us/sample - loss: 11.4902 - accuracy: 0.1000
Epoch 3/5
1000/1000 [==============================] - 0s 79us/sample - loss: 11.4843 - accuracy: 0.1000
Epoch 4/5
1000/1000 [==============================] - 0s 81us/sample - loss: 11.4812 - accuracy: 0.1120
Epoch 5/5
1000/1000 [==============================] - 0s 79us/sample - loss: 11.4788 - accuracy: 0.0970

<tensorflow.python.keras.callbacks.History at 0x7f93484d7128>

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

Создайте пользовательский слой сабклассингом tf.keras.layers.Layer и реализацией следующих методов:

  • __init__: Опционально определите подслои которые будут использоваться в этом слое.
  • build: Создайте веса слоя. Добавьте веса при помощи метода add_weight.
  • call: Определите прямое распространение.
  • Опционально, слой может быть сериализован реализацией метода get_config и метода класса from_config.

Ниже пример пользовательского слоя который осуществляет умножение матрицы (matmul) поданной на вход с матрицей ядра:

class MyLayer(layers.Layer):

  def __init__(self, output_dim, **kwargs):
    self.output_dim = output_dim
    super(MyLayer, self).__init__(**kwargs)

  def build(self, input_shape):
    # Создадим обучаемую весовую переменную для этого слоя.
    self.kernel = self.add_weight(name='kernel',
                                  shape=(input_shape[1], self.output_dim),
                                  initializer='uniform',
                                  trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.kernel)

  def get_config(self):
    base_config = super(MyLayer, self).get_config()
    base_config['output_dim'] = self.output_dim
    return base_config

  @classmethod
  def from_config(cls, config):
    return cls(**config)

Создайте модель с использованием вашего пользовательского слоя:

model = tf.keras.Sequential([
    MyLayer(10),
    layers.Activation('softmax')])

# Шаг компиляции определяет конфигурацию обучения
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Обучение за 5 эпох.
model.fit(data, labels, batch_size=32, epochs=5)
Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 273us/sample - loss: 11.5064 - accuracy: 0.0990
Epoch 2/5
1000/1000 [==============================] - 0s 64us/sample - loss: 11.5062 - accuracy: 0.0990
Epoch 3/5
1000/1000 [==============================] - 0s 63us/sample - loss: 11.5062 - accuracy: 0.0990
Epoch 4/5
1000/1000 [==============================] - 0s 66us/sample - loss: 11.5062 - accuracy: 0.0990
Epoch 5/5
1000/1000 [==============================] - 0s 65us/sample - loss: 11.5058 - accuracy: 0.0990

<tensorflow.python.keras.callbacks.History at 0x7f934839e2b0>

Узнайте больше о создании новых слоев и моделей с нуля с помощью сабклассинга в Руководстве написания слоев и моделей с нуля.

Колбеки

Колбек это объект переданный модели чтобы кастомизировать и расширить ее поведение во время обучения. Вы можете написать свой пользовательский колбек или использовать встроенный tf.keras.callbacks который включает:

Для использования tf.keras.callbacks.Callback, передайте ее методу модели fit:

callbacks = [
  # Остановить обучение если `val_loss` перестанет улучшаться в течение 2 эпох
  tf.keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
  # Записать логи TensorBoard в каталог `./logs`
  tf.keras.callbacks.TensorBoard(log_dir='./logs')
]
model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
          validation_data=(val_data, val_labels))
Train on 1000 samples, validate on 100 samples
Epoch 1/5
1000/1000 [==============================] - 0s 171us/sample - loss: 11.5062 - accuracy: 0.1000 - val_loss: 11.4793 - val_accuracy: 0.1500
Epoch 2/5
1000/1000 [==============================] - 0s 98us/sample - loss: 11.5055 - accuracy: 0.1000 - val_loss: 11.4794 - val_accuracy: 0.1500
Epoch 3/5
1000/1000 [==============================] - 0s 97us/sample - loss: 11.5056 - accuracy: 0.0990 - val_loss: 11.4783 - val_accuracy: 0.1500
Epoch 4/5
1000/1000 [==============================] - 0s 96us/sample - loss: 11.5050 - accuracy: 0.0990 - val_loss: 11.4781 - val_accuracy: 0.1500
Epoch 5/5
1000/1000 [==============================] - 0s 96us/sample - loss: 11.5044 - accuracy: 0.1000 - val_loss: 11.4782 - val_accuracy: 0.1400

<tensorflow.python.keras.callbacks.History at 0x7f9348283940>

Сохранение и восстановление

Сохранение только значений весов

Сохраните и загрузите веса модели с помощью tf.keras.Model.save_weights:

model = tf.keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(32,)),
layers.Dense(10, activation='softmax')])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
# Сохраним веса в файл TensorFlow Checkpoint
model.save_weights('./weights/my_model')

# Восстановим состояние модели,
# для этого необходима модель с такой же архитектурой.
model.load_weights('./weights/my_model')
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f934853f518>

По умолчанию веса модели сохраняются в формате TensorFlow checkpoint. Веса могут быть также сохранены в формате Keras HDF5 (значение по умолчанию для универсальной реализации Keras):

# Сохранение весов в файл HDF5
model.save_weights('my_model.h5', save_format='h5')

# Восстановление состояния модели
model.load_weights('my_model.h5')

Сохранение только конфигурации модели

Конфигурация модели может быть сохранена - это сериализует архитектуру модели без всяких весов. Сохраненная конфигурация может восстановить и инициализировать ту же модель, даже без кода определяющего исходную модель. Keras поддерживает форматы сериализации JSON и YAML:

# Сериализация модели в формат JSON
json_string = model.to_json()
json_string
'{"class_name": "Sequential", "config": {"name": "sequential_3", "layers": [{"class_name": "Dense", "config": {"name": "dense_17", "trainable": true, "batch_input_shape": [null, 32], "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_18", "trainable": true, "dtype": "float32", "units": 10, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "keras_version": "2.2.4-tf", "backend": "tensorflow"}'
import json
import pprint
pprint.pprint(json.loads(json_string))
{'backend': 'tensorflow',
 'class_name': 'Sequential',
 'config': {'layers': [{'class_name': 'Dense',
                        'config': {'activation': 'relu',
                                   'activity_regularizer': None,
                                   'batch_input_shape': [None, 32],
                                   'bias_constraint': None,
                                   'bias_initializer': {'class_name': 'Zeros',
                                                        'config': {}},
                                   'bias_regularizer': None,
                                   'dtype': 'float32',
                                   'kernel_constraint': None,
                                   'kernel_initializer': {'class_name': 'GlorotUniform',
                                                          'config': {'seed': None}},
                                   'kernel_regularizer': None,
                                   'name': 'dense_17',
                                   'trainable': True,
                                   'units': 64,
                                   'use_bias': True}},
                       {'class_name': 'Dense',
                        'config': {'activation': 'softmax',
                                   'activity_regularizer': None,
                                   'bias_constraint': None,
                                   'bias_initializer': {'class_name': 'Zeros',
                                                        'config': {}},
                                   'bias_regularizer': None,
                                   'dtype': 'float32',
                                   'kernel_constraint': None,
                                   'kernel_initializer': {'class_name': 'GlorotUniform',
                                                          'config': {'seed': None}},
                                   'kernel_regularizer': None,
                                   'name': 'dense_18',
                                   'trainable': True,
                                   'units': 10,
                                   'use_bias': True}}],
            'name': 'sequential_3'},
 'keras_version': '2.2.4-tf'}

Восстановление модели (заново инициализированной) из JSON:

fresh_model = tf.keras.models.model_from_json(json_string)

Сериализация модели в формат YAML требует установки pyyaml перед тем как импортировать TensorFlow:

yaml_string = model.to_yaml()
print(yaml_string)
backend: tensorflow
class_name: Sequential
config:
  layers:
  - class_name: Dense
    config:
      activation: relu
      activity_regularizer: null
      batch_input_shape: !!python/tuple [null, 32]
      bias_constraint: null
      bias_initializer:
        class_name: Zeros
        config: {}
      bias_regularizer: null
      dtype: float32
      kernel_constraint: null
      kernel_initializer:
        class_name: GlorotUniform
        config: {seed: null}
      kernel_regularizer: null
      name: dense_17
      trainable: true
      units: 64
      use_bias: true
  - class_name: Dense
    config:
      activation: softmax
      activity_regularizer: null
      bias_constraint: null
      bias_initializer:
        class_name: Zeros
        config: {}
      bias_regularizer: null
      dtype: float32
      kernel_constraint: null
      kernel_initializer:
        class_name: GlorotUniform
        config: {seed: null}
      kernel_regularizer: null
      name: dense_18
      trainable: true
      units: 10
      use_bias: true
  name: sequential_3
keras_version: 2.2.4-tf

Восстановление модели из YAML:

fresh_model = tf.keras.models.model_from_yaml(yaml_string)

Внимание: сабклассированные модели не сериализуемы, потому что их архитектура определяется кодом Python в теле метода call.

Сохранение всей модели в один файл

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

# Создадим простую модель
model = tf.keras.Sequential([
  layers.Dense(10, activation='softmax', input_shape=(32,)),
  layers.Dense(10, activation='softmax')
])
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(data, labels, batch_size=32, epochs=5)


# Сохраним всю модель в файл HDF5
model.save('my_model.h5')

# Пересоздадим в точности эту модель включая веса и оптимизатор.
model = tf.keras.models.load_model('my_model.h5')
Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 468us/sample - loss: 11.5273 - accuracy: 0.1040
Epoch 2/5
1000/1000 [==============================] - 0s 77us/sample - loss: 11.5528 - accuracy: 0.0970
Epoch 3/5
1000/1000 [==============================] - 0s 76us/sample - loss: 11.5795 - accuracy: 0.0970
Epoch 4/5
1000/1000 [==============================] - 0s 74us/sample - loss: 11.5981 - accuracy: 0.0930
Epoch 5/5
1000/1000 [==============================] - 0s 74us/sample - loss: 11.6182 - accuracy: 0.0890

Узнайте больше о сохранении и сериализации моделей Keras в руководстве по сохранению и сериализации моделей.

Eager execution

Eager execution это императивное программирование среда которая выполняет операции немедленно. Это не требуется для Keras, но поддерживается tf.keras и полезно для проверки вашей программы и отладки.

Все строящие модели API tf.keras совместимы eager execution. И хотя могут быть использованы Sequential и functional API, eager execution особенно полезно при сабклассировании модели и построении пользовательских слоев — эти API требуют от вас написание прямого распространения в виде кода (вместо API которые создают модели путем сборки существующих слоев).

См руководство eager execution для примеров использования моделей Keras с пользовательскими циклами обучения и tf.GradientTape. Вы можете также найти полный коротки пример тут.

Распределение

Множественные GPU

tf.keras модели можно запускать на множестве GPU с использованием tf.distribute.Strategy. Этот API обеспечивает распределенное обучение на нескольких GPU практически без изменений в существующем коде.

На данный момент, tf.distribute.MirroredStrategy единственная поддерживаемая стратегия распределения. MirroredStrategy выполняет репликацию в графах с синхронным обучением используя all-reduce на одной машине. Для использования distribute.Strategy , вложите инсталляцию оптимизатора, конструкцию и компиляцию модели в Strategy's .scope(), затем обучите модель.

Следующий пример распределяет tf.keras.Model между множеством GPU на одной машине.

Сперва определим модель внутри области распределенной стратегии:

strategy = tf.distribute.MirroredStrategy()

with strategy.scope():
  model = tf.keras.Sequential()
  model.add(layers.Dense(16, activation='relu', input_shape=(10,)))
  model.add(layers.Dense(1, activation='sigmoid'))

  optimizer = tf.keras.optimizers.SGD(0.2)

  model.compile(loss='binary_crossentropy', optimizer=optimizer)

model.summary()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_21 (Dense)             (None, 16)                176       
_________________________________________________________________
dense_22 (Dense)             (None, 1)                 17        
=================================================================
Total params: 193
Trainable params: 193
Non-trainable params: 0
_________________________________________________________________

Затем обучим модель на данных как обычно:

x = np.random.random((1024, 10))
y = np.random.randint(2, size=(1024, 1))
x = tf.cast(x, tf.float32)
dataset = tf.data.Dataset.from_tensor_slices((x, y))
dataset = dataset.shuffle(buffer_size=1024).batch(32)

model.fit(dataset, epochs=1)
Train for 32 steps
32/32 [==============================] - 2s 75ms/step - loss: 0.6988

<tensorflow.python.keras.callbacks.History at 0x7f9348090b38>

Для дополнительной информации см. полное руководство по распределенному обучению наа TensorFlow.