Эта страница переведена с помощью Cloud Translation API.
Switch to English

Обучение и оценка с помощью встроенных методов

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Настроить

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

Введение

В этом руководстве рассматриваются модели обучения, оценки и прогнозирования (вывода) при использовании встроенных API-интерфейсов для обучения и проверки (например, model.fit() , model.evaluate() , model.predict() ).

Если вы заинтересованы в использовании fit() при указании собственной функции шага обучения, см. Руководство «Настройка того, что происходит в fit() » .

Если вы заинтересованы в написании собственных циклов обучения и оценки с нуля, см. Руководство «Написание цикла обучения с нуля» .

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

Это руководство не распространяется на распределенное обучение. Информацию о распределенном обучении см. В нашем руководстве по обучению с использованием нескольких GPU и распределенному обучению .

Обзор API: первый сквозной пример

При передаче данных во встроенные циклы обучения модели вы должны использовать либо массивы NumPy (если ваши данные небольшие и умещаются в памяти), либо объекты tf.data Dataset . В следующих нескольких абзацах мы будем использовать набор данных MNIST в качестве массивов NumPy, чтобы продемонстрировать, как использовать оптимизаторы, потери и метрики.

Давайте рассмотрим следующую модель (здесь мы встроили функциональный API, но это также может быть последовательная модель или модель с подклассом):

inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, activation="softmax", name="predictions")(x)

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

Вот как выглядит типичный сквозной рабочий процесс, состоящий из:

  • Тренировка
  • Проверка удерживающего набора, созданного на основе исходных обучающих данных
  • Оценка на тестовых данных

В этом примере мы будем использовать данные MNIST.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Preprocess the data (these are NumPy arrays)
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255

y_train = y_train.astype("float32")
y_test = y_test.astype("float32")

# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]

Уточняем конфигурацию обучения (оптимизатор, убыток, метрики):

model.compile(
    optimizer=keras.optimizers.RMSprop(),  # Optimizer
    # Loss function to minimize
    loss=keras.losses.SparseCategoricalCrossentropy(),
    # List of metrics to monitor
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

Мы вызываем fit() , которая будет обучать модель, разделяя данные на «пакеты» размером «batch_size» и многократно повторяя весь набор данных в течение заданного количества «эпох».

print("Fit model on training data")
history = model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=2,
    # We pass some validation for
    # monitoring validation loss and metrics
    # at the end of each epoch
    validation_data=(x_val, y_val),
)
Fit model on training data
Epoch 1/2
782/782 [==============================] - 2s 2ms/step - loss: 0.3425 - sparse_categorical_accuracy: 0.9034 - val_loss: 0.1827 - val_sparse_categorical_accuracy: 0.9478
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1618 - sparse_categorical_accuracy: 0.9513 - val_loss: 0.1282 - val_sparse_categorical_accuracy: 0.9651

Возвращенный объект «история» содержит запись значений потерь и значений показателей во время обучения:

history.history
{'loss': [0.3424801528453827, 0.16180744767189026],
 'sparse_categorical_accuracy': [0.903439998626709, 0.9512799978256226],
 'val_loss': [0.18268445134162903, 0.12816601991653442],
 'val_sparse_categorical_accuracy': [0.9477999806404114, 0.9650999903678894]}

Мы оцениваем модель на тестовых данных с помощью evaluate() :

# Evaluate the model on the test data using `evaluate`
print("Evaluate on test data")
results = model.evaluate(x_test, y_test, batch_size=128)
print("test loss, test acc:", results)

# Generate predictions (probabilities -- the output of the last layer)
# on new data using `predict`
print("Generate predictions for 3 samples")
predictions = model.predict(x_test[:3])
print("predictions shape:", predictions.shape)
Evaluate on test data
79/79 [==============================] - 0s 1ms/step - loss: 0.1310 - sparse_categorical_accuracy: 0.9637
test loss, test acc: [0.1309928148984909, 0.963699996471405]
Generate predictions for 3 samples
predictions shape: (3, 10)

Теперь давайте подробно рассмотрим каждую часть этого рабочего процесса.

Метод compile() : указание потерь, показателей и оптимизатора

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

Вы передаете их модели в качестве аргументов методу compile() :

model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

Аргумент metrics должен быть списком - ваша модель может иметь любое количество метрик.

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

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

model.compile(
    optimizer="rmsprop",
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
)

Для последующего повторного использования давайте поместим определение нашей модели и этап компиляции в функции; мы будем вызывать их несколько раз в разных примерах в этом руководстве.

def get_uncompiled_model():
    inputs = keras.Input(shape=(784,), name="digits")
    x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
    x = layers.Dense(64, activation="relu", name="dense_2")(x)
    outputs = layers.Dense(10, activation="softmax", name="predictions")(x)
    model = keras.Model(inputs=inputs, outputs=outputs)
    return model


def get_compiled_model():
    model = get_uncompiled_model()
    model.compile(
        optimizer="rmsprop",
        loss="sparse_categorical_crossentropy",
        metrics=["sparse_categorical_accuracy"],
    )
    return model

Доступно множество встроенных оптимизаторов, потерь и метрик.

В общем, вам не придется создавать с нуля свои собственные потери, метрики или оптимизаторы, потому что то, что вам нужно, скорее всего, уже является частью Keras API:

Оптимизаторы:

  • SGD() (с импульсом или без него)
  • RMSprop()
  • Adam()
  • и т.п.

Убытки:

  • MeanSquaredError()
  • KLDivergence()
  • CosineSimilarity()
  • и т.п.

Метрики:

  • AUC()
  • Precision()
  • Recall()
  • и т.п.

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

Есть два способа предоставить пользовательские потери с помощью Keras. В первом примере создается функция, которая принимает входные данные y_true и y_pred . В следующем примере показана функция потерь, которая вычисляет среднеквадратичную ошибку между реальными данными и прогнозами:

def custom_mean_squared_error(y_true, y_pred):
    return tf.math.reduce_mean(tf.square(y_true - y_pred))


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=custom_mean_squared_error)

# We need to one-hot encode the labels to use MSE
y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 1s 1ms/step - loss: 0.0168

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

Если вам нужна функция потерь, которая принимает параметры помимо y_true и y_pred , вы можете tf.keras.losses.Loss подкласс класса tf.keras.losses.Loss и реализовать следующие два метода:

  • __init__(self) : принять параметры для передачи во время вызова вашей функции потери
  • call(self, y_true, y_pred) : используйте цели (y_true) и прогнозы модели (y_pred) для вычисления потерь модели

Предположим, вы хотите использовать среднеквадратичную ошибку, но с добавленным термином, который деактивирует значения прогнозов далеко от 0,5 (мы предполагаем, что категориальные цели закодированы по очереди и принимают значения от 0 до 1). Это создает стимул для модели не быть слишком уверенной, что может помочь уменьшить переоснащение (мы не узнаем, сработает ли она, пока не попробуем!).

Вот как бы вы это сделали:

class CustomMSE(keras.losses.Loss):
    def __init__(self, regularization_factor=0.1, name="custom_mse"):
        super().__init__(name=name)
        self.regularization_factor = regularization_factor

    def call(self, y_true, y_pred):
        mse = tf.math.reduce_mean(tf.square(y_true - y_pred))
        reg = tf.math.reduce_mean(tf.square(0.5 - y_pred))
        return mse + reg * self.regularization_factor


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=CustomMSE())

y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 0.0390

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

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

Если вам нужна метрика, которая не является частью API, вы можете легко создать собственные метрики, tf.keras.metrics.Metric подкласс класса tf.keras.metrics.Metric . Вам потребуется реализовать 4 метода:

  • __init__(self) , в котором вы создадите переменные состояния для своей метрики.
  • update_state(self, y_true, y_pred, sample_weight=None) , который использует целевые значения y_true и прогнозы модели y_pred для обновления переменных состояния.
  • result(self) , который использует переменные состояния для вычисления окончательных результатов.
  • reset_states(self) , который повторно инициализирует состояние метрики.

Обновление состояния и вычисление результатов хранятся отдельно (в update_state() и result() соответственно), потому что в некоторых случаях вычисление результатов может быть очень дорогостоящим и будет выполняться только периодически.

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

class CategoricalTruePositives(keras.metrics.Metric):
    def __init__(self, name="categorical_true_positives", **kwargs):
        super(CategoricalTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name="ctp", initializer="zeros")

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
        values = tf.cast(y_true, "int32") == tf.cast(y_pred, "int32")
        values = tf.cast(values, "float32")
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, "float32")
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):
        # The state of the metric will be reset at the start of each epoch.
        self.true_positives.assign(0.0)


model = get_uncompiled_model()
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
Epoch 1/3
782/782 [==============================] - 1s 2ms/step - loss: 0.3429 - categorical_true_positives: 45146.0000
Epoch 2/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1560 - categorical_true_positives: 47637.0000
Epoch 3/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1155 - categorical_true_positives: 48237.0000

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

Обработка потерь и показателей, не соответствующих стандартной подписи

Подавляющее большинство потерь и показателей можно вычислить на основе y_true и y_pred , где y_pred - это результат вашей модели. Но не все из них. Например, потеря регуляризации может потребовать только активации слоя (в этом случае нет целей), и эта активация может не быть выходом модели.

В таких случаях вы можете вызвать self.add_loss(loss_value) из метода вызова настраиваемого слоя. Потери, добавленные таким образом, добавляются к «основным» потерям во время обучения (переданным в compile() ). Вот простой пример, который добавляет регуляризацию активности (обратите внимание, что регуляризация активности встроена во все слои Keras - этот слой просто для предоставления конкретного примера):

class ActivityRegularizationLayer(layers.Layer):
    def call(self, inputs):
        self.add_loss(tf.reduce_sum(inputs) * 0.1)
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)

# The displayed loss will be much higher than before
# due to the regularization component.
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 2.4756

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

Вы можете сделать то же самое для регистрации значений метрики, используя add_metric() :

class MetricLoggingLayer(layers.Layer):
    def call(self, inputs):
        # The `aggregation` argument defines
        # how to aggregate the per-batch values
        # over each epoch:
        # in this case we simply average them.
        self.add_metric(
            keras.backend.std(inputs), name="std_of_activation", aggregation="mean"
        )
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert std logging as a layer.
x = MetricLoggingLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 0.3493 - std_of_activation: 0.9813

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

В функциональном API вы также можете вызвать model.add_loss(loss_tensor) или model.add_metric(metric_tensor, name, aggregation) .

Вот простой пример:

inputs = keras.Input(shape=(784,), name="digits")
x1 = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x2 = layers.Dense(64, activation="relu", name="dense_2")(x1)
outputs = layers.Dense(10, name="predictions")(x2)
model = keras.Model(inputs=inputs, outputs=outputs)

model.add_loss(tf.reduce_sum(x1) * 0.1)

model.add_metric(keras.backend.std(x1), name="std_of_activation", aggregation="mean")

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 2.5230 - std_of_activation: 0.0020

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

Обратите внимание, что когда вы передаете потери через add_loss() , становится возможным вызвать compile() без функции потерь, поскольку в модели уже есть потери, которые необходимо минимизировать.

Рассмотрим следующий уровень LogisticEndpoint : он принимает в качестве входных данных цели и логиты и отслеживает потери add_loss() через add_loss() . Он также отслеживает точность классификации с помощью add_metric() .

class LogisticEndpoint(keras.layers.Layer):
    def __init__(self, name=None):
        super(LogisticEndpoint, self).__init__(name=name)
        self.loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
        self.accuracy_fn = keras.metrics.BinaryAccuracy()

    def call(self, targets, logits, sample_weights=None):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        loss = self.loss_fn(targets, logits, sample_weights)
        self.add_loss(loss)

        # Log accuracy as a metric and add it
        # to the layer using `self.add_metric()`.
        acc = self.accuracy_fn(targets, logits, sample_weights)
        self.add_metric(acc, name="accuracy")

        # Return the inference-time prediction tensor (for `.predict()`).
        return tf.nn.softmax(logits)

Вы можете использовать его в модели с двумя входами (входные данные и цели), скомпилированной без аргумента loss , например:

import numpy as np

inputs = keras.Input(shape=(3,), name="inputs")
targets = keras.Input(shape=(10,), name="targets")
logits = keras.layers.Dense(10)(inputs)
predictions = LogisticEndpoint(name="predictions")(logits, targets)

model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")  # No loss argument!

data = {
    "inputs": np.random.random((3, 3)),
    "targets": np.random.random((3, 10)),
}
model.fit(data)
1/1 [==============================] - 0s 1ms/step - loss: 0.9344 - binary_accuracy: 0.0000e+00

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

Дополнительные сведения об обучении моделей с несколькими входами см. В разделе « Передача данных в модели с несколькими входами и несколькими выходами» .

Автоматическое разделение набора задержек проверки

В первом (x_val, y_val) примере, который вы видели, мы использовали аргумент validation_data для передачи кортежа массивов NumPy (x_val, y_val) в модель для оценки потерь при проверке и метрик проверки в конце каждой эпохи.

Вот еще один вариант: аргумент validation_split позволяет автоматически резервировать часть ваших обучающих данных для проверки. Значение аргумента представляет собой часть данных, которые должны быть зарезервированы для проверки, поэтому для него должно быть установлено число больше 0 и меньше 1. Например, validation_split=0.2 означает «использовать 20% данных для проверки», и validation_split=0.6 означает «использовать 60% данных для проверки».

Способ вычисления проверки состоит в том, что перед любой перетасовкой берутся последние x% выборок массивов, полученных вызовом fit.

Обратите внимание, что вы можете использовать validation_split только при обучении с данными NumPy.

model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
625/625 [==============================] - 1s 2ms/step - loss: 0.3753 - sparse_categorical_accuracy: 0.8927 - val_loss: 0.2252 - val_sparse_categorical_accuracy: 0.9344

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

Обучение и оценка на основе наборов данных tf.data

В последних нескольких абзацах вы увидели, как обрабатывать потери, показатели и оптимизаторы, и вы увидели, как использовать аргументы validation_data и validation_split в соответствии, когда ваши данные передаются в виде массивов NumPy.

Давайте теперь рассмотрим случай, когда ваши данные поступают в виде объектаtf.data.Dataset .

API tf.data - это набор утилит в TensorFlow 2.0 для быстрой и масштабируемой загрузки и предварительной обработки данных.

Полное руководство по созданию Datasets см. В документации tf.data .

Вы можете передать экземпляр Dataset непосредственно в методы fit() , evaluate() и predict() :

model = get_compiled_model()

# First, let's create a training Dataset instance.
# For the sake of our example, we'll use the same MNIST data as before.
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Now we get a test dataset.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)

# Since the dataset already takes care of batching,
# we don't pass a `batch_size` argument.
model.fit(train_dataset, epochs=3)

# You can also evaluate or predict on a dataset.
print("Evaluate")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3404 - sparse_categorical_accuracy: 0.9048
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1596 - sparse_categorical_accuracy: 0.9529
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1165 - sparse_categorical_accuracy: 0.9658
Evaluate
157/157 [==============================] - 0s 1ms/step - loss: 0.1147 - sparse_categorical_accuracy: 0.9659

{'loss': 0.11471886932849884,
 'sparse_categorical_accuracy': 0.9659000039100647}

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

Если вы хотите запустить обучение только для определенного количества пакетов из этого набора данных, вы можете передать аргумент steps_per_epoch , который указывает, сколько шагов обучения модель должна выполнить с использованием этого набора данных, прежде чем перейти к следующей эпохе.

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

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Only use the 100 batches per epoch (that's 64 * 100 samples)
model.fit(train_dataset, epochs=3, steps_per_epoch=100)
Epoch 1/3
100/100 [==============================] - 0s 2ms/step - loss: 0.8448 - sparse_categorical_accuracy: 0.7734
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3912 - sparse_categorical_accuracy: 0.8922
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3399 - sparse_categorical_accuracy: 0.9011

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

Использование набора данных проверки

Вы можете передать экземпляр Dataset в качестве аргумента validation_data в fit() :

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
782/782 [==============================] - 2s 2ms/step - loss: 0.3384 - sparse_categorical_accuracy: 0.9032 - val_loss: 0.1752 - val_sparse_categorical_accuracy: 0.9518

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

В конце каждой эпохи модель будет перебирать набор данных валидации и вычислять потери валидации и метрики валидации.

Если вы хотите запустить проверку только для определенного количества пакетов из этого набора данных, вы можете передать аргумент validation_steps , который указывает, сколько шагов проверки модель должна выполнить с набором данных проверки, прежде чем прервать проверку и перейти к следующей эпохе:

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(
    train_dataset,
    epochs=1,
    # Only run validation using the first 10 batches of the dataset
    # using the `validation_steps` argument
    validation_data=val_dataset,
    validation_steps=10,
)
782/782 [==============================] - 2s 2ms/step - loss: 0.3503 - sparse_categorical_accuracy: 0.9021 - val_loss: 0.3226 - val_sparse_categorical_accuracy: 0.9156

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

Обратите внимание, что набор данных проверки будет сбрасываться после каждого использования (так что вы всегда будете оценивать одни и те же образцы от эпохи к эпохе).

Аргумент validation_split (создание удерживающего набора из обучающих данных) не поддерживается при обучении из объектов Dataset , поскольку эта функция требует возможности индексировать образцы наборов данных, что в целом невозможно с API Dataset .

Поддерживаются другие форматы ввода

Помимо массивов NumPy, активных тензоров и Datasets , можно обучить модель Keras, используя фреймы данных Pandas или генераторы Python, которые создают пакеты данных и меток.

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

В целом мы рекомендуем использовать:

  • Входные данные NumPy, если ваши данные маленькие и умещаются в памяти
  • Объекты наборов Dataset если у вас большие наборы данных и вам нужно проводить распределенное обучение
  • Sequence объектов, если у вас есть большие наборы данных, и вам нужно выполнить много пользовательской обработки на стороне Python, что невозможно сделать в TensorFlow (например, если вы полагаетесь на внешние библиотеки для загрузки или предварительной обработки данных).

Использование объекта keras.utils.Sequence качестве ввода

keras.utils.Sequence - это утилита, которую можно создать в подклассе для получения генератора Python с двумя важными свойствами:

  • Он хорошо работает с многопроцессорностью.
  • Его можно перемешать (например, при передаче shuffle=True в fit() ).

Sequence должна реализовывать два метода:

  • __getitem__
  • __len__

Метод __getitem__ должен возвращать полный пакет. Если вы хотите изменить свой набор данных между эпохами, вы можете реализовать on_epoch_end .

Вот небольшой пример:

from skimage.io import imread
from skimage.transform import resize
import numpy as np

# Here, `filenames` is list of path to the images
# and `labels` are the associated labels.

class CIFAR10Sequence(Sequence):
    def __init__(self, filenames, labels, batch_size):
        self.filenames, self.labels = filenames, labels
        self.batch_size = batch_size

    def __len__(self):
        return int(np.ceil(len(self.filenames) / float(self.batch_size)))

    def __getitem__(self, idx):
        batch_x = self.filenames[idx * self.batch_size:(idx + 1) * self.batch_size]
        batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]
        return np.array([
            resize(imread(filename), (200, 200))
               for filename in batch_x]), np.array(batch_y)

sequence = CIFAR10Sequence(filenames, labels, batch_size)
model.fit(sequence, epochs=10)

Использование взвешивания выборки и взвешивания классов

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

  • Вес класса
  • Вес образца

Вес класса

Это устанавливается путем передачи словаря в class_weight аргумент Model.fit() . Этот словарь сопоставляет индексы классов с весом, который следует использовать для выборок, принадлежащих этому классу.

Это можно использовать для балансировки классов без повторной выборки или для обучения модели, которая придает большее значение конкретному классу.

Например, если класс «0» в два раза меньше, чем класс «1» в ваших данных, вы можете использовать Model.fit(..., class_weight={0: 1., 1: 0.5}) .

Вот пример NumPy, в котором мы используем веса классов или выборочные веса, чтобы придать большее значение правильной классификации класса № 5 (который является цифрой «5» в наборе данных MNIST).

import numpy as np

class_weight = {
    0: 1.0,
    1: 1.0,
    2: 1.0,
    3: 1.0,
    4: 1.0,
    # Set weight "2" for class "5",
    # making this class 2x more important
    5: 2.0,
    6: 1.0,
    7: 1.0,
    8: 1.0,
    9: 1.0,
}

print("Fit with class weight")
model = get_compiled_model()
model.fit(x_train, y_train, class_weight=class_weight, batch_size=64, epochs=1)
Fit with class weight
782/782 [==============================] - 2s 2ms/step - loss: 0.3729 - sparse_categorical_accuracy: 0.9025

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

Вес образца

Для детального контроля или если вы не строите классификатор, вы можете использовать «выборочные веса».

  • При обучении на основе данных NumPy: sample_weight аргумент Model.fit() в Model.fit() .
  • При обучении из tf.data или любого другого типа итератора: (input_batch, label_batch, sample_weight_batch) Yield (input_batch, label_batch, sample_weight_batch) .

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

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

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

print("Fit with sample weight")
model = get_compiled_model()
model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=1)
Fit with sample weight
782/782 [==============================] - 2s 2ms/step - loss: 0.3837 - sparse_categorical_accuracy: 0.8984

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

Вот соответствующий пример Dataset :

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

# Create a Dataset that includes sample weights
# (3rd element in the return tuple).
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train, sample_weight))

# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model = get_compiled_model()
model.fit(train_dataset, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 0.3792 - sparse_categorical_accuracy: 0.9030

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

Передача данных в модели с множеством входов и выходов

В предыдущих примерах мы рассматривали модель с одним входом (тензор формы (764,) ) и одним выходом (тензор предсказания формы (10,) ). Но как насчет моделей с несколькими входами или выходами?

Рассмотрим следующую модель, которая имеет входное изображение формы (32, 32, 3) (это (height, width, channels) ) и входной (timesteps, features) формы (None, 10) (это (timesteps, features) ). Наша модель будет иметь два выхода, вычисляемых из комбинации этих входных данных: «оценка» (формы (1,) ) и распределение вероятностей по пяти классам (формы (5,) ).

image_input = keras.Input(shape=(32, 32, 3), name="img_input")
timeseries_input = keras.Input(shape=(None, 10), name="ts_input")

x1 = layers.Conv2D(3, 3)(image_input)
x1 = layers.GlobalMaxPooling2D()(x1)

x2 = layers.Conv1D(3, 3)(timeseries_input)
x2 = layers.GlobalMaxPooling1D()(x2)

x = layers.concatenate([x1, x2])

score_output = layers.Dense(1, name="score_output")(x)
class_output = layers.Dense(5, name="class_output")(x)

model = keras.Model(
    inputs=[image_input, timeseries_input], outputs=[score_output, class_output]
)

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

keras.utils.plot_model(model, "multi_input_and_output_model.png", show_shapes=True)

PNG

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

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

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

То же и для показателей:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
    metrics=[
        [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        [keras.metrics.CategoricalAccuracy()],
    ],
)

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

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
)

Мы рекомендуем использовать явные имена и словари, если у вас более двух выходов.

Можно присвоить разные веса разным потерям, зависящим от результата (например, в нашем примере можно было бы отдать loss_weights потере "оценки", присвоив 2- loss_weights значение потери класса), используя аргумент loss_weights :

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
    loss_weights={"score_output": 2.0, "class_output": 1.0},
)

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

# List loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[None, keras.losses.CategoricalCrossentropy()],
)

# Or dict loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={"class_output": keras.losses.CategoricalCrossentropy()},
)

Передача данных в модель с несколькими входами или несколькими выходами в fit работает аналогично указанию функции потерь при компиляции: вы можете передавать списки массивов NumPy (с отображением 1: 1 на выходы, получившие функцию потерь) или диктует отображение выходных имен в массивы NumPy .

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

# Generate dummy NumPy data
img_data = np.random.random_sample(size=(100, 32, 32, 3))
ts_data = np.random.random_sample(size=(100, 20, 10))
score_targets = np.random.random_sample(size=(100, 1))
class_targets = np.random.random_sample(size=(100, 5))

# Fit on lists
model.fit([img_data, ts_data], [score_targets, class_targets], batch_size=32, epochs=1)

# Alternatively, fit on dicts
model.fit(
    {"img_input": img_data, "ts_input": ts_data},
    {"score_output": score_targets, "class_output": class_targets},
    batch_size=32,
    epochs=1,
)
4/4 [==============================] - 0s 6ms/step - loss: 20.0184 - score_output_loss: 0.5383 - class_output_loss: 19.4800
4/4 [==============================] - 0s 4ms/step - loss: 17.7266 - score_output_loss: 0.3122 - class_output_loss: 17.4145

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

Вот пример использования Dataset : аналогично тому, что мы сделали для массивов NumPy, Dataset должен возвращать кортеж dicts.

train_dataset = tf.data.Dataset.from_tensor_slices(
    (
        {"img_input": img_data, "ts_input": ts_data},
        {"score_output": score_targets, "class_output": class_targets},
    )
)
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model.fit(train_dataset, epochs=1)
2/2 [==============================] - 0s 8ms/step - loss: 17.2156 - score_output_loss: 0.2522 - class_output_loss: 16.9634

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

Использование обратных вызовов

Обратные вызовы в Keras - это объекты, которые вызываются в разные моменты во время обучения (в начале эпохи, в конце пакета, в конце эпохи и т. Д.) И которые могут использоваться для реализации таких действий, как:

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

Обратные вызовы могут быть переданы в виде списка вашему вызову fit() :

model = get_compiled_model()

callbacks = [
    keras.callbacks.EarlyStopping(
        # Stop training when `val_loss` is no longer improving
        monitor="val_loss",
        # "no longer improving" being defined as "no better than 1e-2 less"
        min_delta=1e-2,
        # "no longer improving" being further defined as "for at least 2 epochs"
        patience=2,
        verbose=1,
    )
]
model.fit(
    x_train,
    y_train,
    epochs=20,
    batch_size=64,
    callbacks=callbacks,
    validation_split=0.2,
)
Epoch 1/20
625/625 [==============================] - 1s 2ms/step - loss: 0.3816 - sparse_categorical_accuracy: 0.8913 - val_loss: 0.2325 - val_sparse_categorical_accuracy: 0.9304
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1773 - sparse_categorical_accuracy: 0.9477 - val_loss: 0.2088 - val_sparse_categorical_accuracy: 0.9343
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1293 - sparse_categorical_accuracy: 0.9606 - val_loss: 0.1515 - val_sparse_categorical_accuracy: 0.9568
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1009 - sparse_categorical_accuracy: 0.9700 - val_loss: 0.1376 - val_sparse_categorical_accuracy: 0.9607
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0821 - sparse_categorical_accuracy: 0.9747 - val_loss: 0.1533 - val_sparse_categorical_accuracy: 0.9545
Epoch 6/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0704 - sparse_categorical_accuracy: 0.9794 - val_loss: 0.1319 - val_sparse_categorical_accuracy: 0.9616
Epoch 00006: early stopping

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

Доступно множество встроенных обратных вызовов

  • ModelCheckpoint : периодически сохраняйте модель.
  • EarlyStopping : остановите обучение, когда обучение больше не улучшает показатели проверки.
  • TensorBoard : периодически пишите логи модели, которые можно визуализировать в TensorBoard (подробнее в разделе «Визуализация»).
  • CSVLogger : передает данные о потерях и метриках в файл CSV.
  • и т.п.

См. Полный список в документации по обратным вызовам .

Написание собственного обратного вызова

Вы можете создать собственный обратный вызов, расширив базовый класс keras.callbacks.Callback . Обратный вызов имеет доступ к связанной с ним модели через свойство класса self.model .

Обязательно прочтите полное руководство по написанию пользовательских обратных вызовов .

Вот простой пример сохранения списка значений потерь для каждой партии во время обучения:

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs):
        self.per_batch_losses = []

    def on_batch_end(self, batch, logs):
        self.per_batch_losses.append(logs.get("loss"))

Модели контрольных точек

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

Самый простой способ добиться этого - использовать ModelCheckpoint вызов ModelCheckpoint :

model = get_compiled_model()

callbacks = [
    keras.callbacks.ModelCheckpoint(
        # Path where to save the model
        # The two parameters below mean that we will overwrite
        # the current checkpoint if and only if
        # the `val_loss` score has improved.
        # The saved model name will include the current epoch.
        filepath="mymodel_{epoch}",
        save_best_only=True,  # Only save a model if `val_loss` has improved.
        monitor="val_loss",
        verbose=1,
    )
]
model.fit(
    x_train, y_train, epochs=2, batch_size=64, callbacks=callbacks, validation_split=0.2
)
Epoch 1/2
608/625 [============================>.] - ETA: 0s - loss: 0.3797 - sparse_categorical_accuracy: 0.8940
Epoch 00001: val_loss improved from inf to 0.23986, saving model to mymodel_1
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
INFO:tensorflow:Assets written to: mymodel_1/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.3765 - sparse_categorical_accuracy: 0.8949 - val_loss: 0.2399 - val_sparse_categorical_accuracy: 0.9276
Epoch 2/2
606/625 [============================>.] - ETA: 0s - loss: 0.1758 - sparse_categorical_accuracy: 0.9474
Epoch 00002: val_loss improved from 0.23986 to 0.19765, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1751 - sparse_categorical_accuracy: 0.9477 - val_loss: 0.1976 - val_sparse_categorical_accuracy: 0.9409

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

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

import os

# Prepare a directory to store all the checkpoints.
checkpoint_dir = "./ckpt"
if not os.path.exists(checkpoint_dir):
    os.makedirs(checkpoint_dir)


def make_or_restore_model():
    # Either restore the latest model, or create a fresh one
    # if there is no checkpoint available.
    checkpoints = [checkpoint_dir + "/" + name for name in os.listdir(checkpoint_dir)]
    if checkpoints:
        latest_checkpoint = max(checkpoints, key=os.path.getctime)
        print("Restoring from", latest_checkpoint)
        return keras.models.load_model(latest_checkpoint)
    print("Creating a new model")
    return get_compiled_model()


model = make_or_restore_model()
callbacks = [
    # This callback saves a SavedModel every 100 batches.
    # We include the training loss in the saved model name.
    keras.callbacks.ModelCheckpoint(
        filepath=checkpoint_dir + "/ckpt-loss={loss:.2f}", save_freq=100
    )
]
model.fit(x_train, y_train, epochs=1, callbacks=callbacks)
Creating a new model
  94/1563 [>.............................] - ETA: 3s - loss: 0.9261 - sparse_categorical_accuracy: 0.7420INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.90/assets
 192/1563 [==>...........................] - ETA: 6s - loss: 0.6734 - sparse_categorical_accuracy: 0.8097INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.66/assets
 292/1563 [====>.........................] - ETA: 6s - loss: 0.5676 - sparse_categorical_accuracy: 0.8390INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.56/assets
 393/1563 [======>.......................] - ETA: 6s - loss: 0.5077 - sparse_categorical_accuracy: 0.8543INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.51/assets
 490/1563 [========>.....................] - ETA: 5s - loss: 0.4665 - sparse_categorical_accuracy: 0.8652INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.46/assets
 589/1563 [==========>...................] - ETA: 5s - loss: 0.4356 - sparse_categorical_accuracy: 0.8735INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.43/assets
 690/1563 [============>.................] - ETA: 4s - loss: 0.4077 - sparse_categorical_accuracy: 0.8813INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.41/assets
 791/1563 [==============>...............] - ETA: 4s - loss: 0.3883 - sparse_categorical_accuracy: 0.8873INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.39/assets
 892/1563 [================>.............] - ETA: 3s - loss: 0.3715 - sparse_categorical_accuracy: 0.8921INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
 992/1563 [==================>...........] - ETA: 3s - loss: 0.3569 - sparse_categorical_accuracy: 0.8964INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1092/1563 [===================>..........] - ETA: 2s - loss: 0.3444 - sparse_categorical_accuracy: 0.8994INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1194/1563 [=====================>........] - ETA: 2s - loss: 0.3315 - sparse_categorical_accuracy: 0.9025INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1293/1563 [=======================>......] - ETA: 1s - loss: 0.3217 - sparse_categorical_accuracy: 0.9056INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1383/1563 [=========================>....] - ETA: 1s - loss: 0.3145 - sparse_categorical_accuracy: 0.9077INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1478/1563 [===========================>..] - ETA: 0s - loss: 0.3057 - sparse_categorical_accuracy: 0.9102INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.30/assets
1563/1563 [==============================] - 9s 6ms/step - loss: 0.2996 - sparse_categorical_accuracy: 0.9119

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

Звоните и пишите свой callback для сохранения и восстановления моделей.

Полное руководство по сериализации и сохранению см. В руководстве по сохранению и сериализации моделей .

Использование расписаний скорости обучения

Распространенной схемой обучения моделей глубокого обучения является постепенное сокращение объема обучения по мере обучения. Это обычно известно как «снижение скорости обучения».

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

Передача расписания оптимизатору

Вы можете легко использовать статическое расписание спада скорости обучения, передав объект расписания в качестве аргумента learning_rate в оптимизаторе:

initial_learning_rate = 0.1
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)

optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)

Доступно несколько встроенных расписаний: ExponentialDecay , PiecewiseConstantDecay , PolynomialDecay и InverseTimeDecay .

Использование обратных вызовов для реализации динамического расписания скорости обучения

График скорости динамического обучения (например, уменьшение скорости обучения, когда потеря валидации больше не улучшается) не может быть достигнуто с этими объектами расписания, поскольку оптимизатор не имеет доступа к метрикам валидации.

Однако у обратных вызовов есть доступ ко всем метрикам, включая метрики проверки! Таким образом, вы можете достичь этого шаблона, используя обратный вызов, который изменяет текущую скорость обучения в оптимизаторе. Фактически, это даже встроенный ReduceLROnPlateau вызов ReduceLROnPlateau .

Визуализация потерь и показателей во время тренировки

Лучший способ следить за своей моделью во время обучения - использовать TensorBoard , приложение на основе браузера, которое вы можете запускать локально и которое предоставляет вам:

  • Живые графики потерь и метрики для обучения и оценки
  • (опционально) Визуализации гистограмм активации ваших слоев
  • (опционально) 3D-визуализация пространств вложения, изученных вашими слоями Embedding

Если вы установили TensorFlow с помощью pip, вы сможете запустить TensorBoard из командной строки:

tensorboard --logdir=/full_path_to_your_logs

Использование обратного вызова TensorBoard

Самый простой способ использовать TensorBoard с моделью Keras и методом подгонки - это TensorBoard вызов TensorBoard .

В простейшем случае просто укажите, где вы хотите, чтобы обратный вызов записывал журналы, и все готово:

keras.callbacks.TensorBoard(
    log_dir="/full_path_to_your_logs",
    histogram_freq=0,  # How often to log histogram visualizations
    embeddings_freq=0,  # How often to log embedding visualizations
    update_freq="epoch",
)  # How often to write logs (default: once per epoch)
<tensorflow.python.keras.callbacks.TensorBoard at 0x7f74ec5179e8>

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