Tensorflow.keras.Sequential.fit: примеры (PYTHON)

TensorFlow Keras Sequential.fit: практическое применение и примеры
Раздел: Машинное обучение, Нейронные сети
tensorflow.keras.Sequential.fit(x: array-like, y: array-like, batch_size: int = 32, epochs: int = 1, ...): History

Основные сведения о методе fit

Метод fit класса Sequential в TensorFlow Keras предназначен для обучения модели на предоставленных данных. Его применяют после компиляции модели для настройки весов сети посредством минимизации функции потерь. Основная задача метода - организация процесса обучения, включая разбиение данных на батчи, вычисление градиентов и обновление параметров модели.

Аргументы метода:

  • x: входные данные (тензор, список тензоров, NumPy массив, генератор или tf.data.Dataset).
  • y: целевые значения (структура аналогичная x).
  • batch_size: количество образцов на один шаг градиентного спуска (целое число или None).
  • epochs: количество эпох обучения (целое число).
  • verbose: уровень детализации вывода (0 - нет вывода, 1 - прогресс-бар, 2 - одна строка на эпоху).
  • callbacks: список экземпляров классов Callback для выполнения во время обучения.
  • validation_split: доля данных, используемая для валидации (число от 0 до 1).
  • validation_data: данные для оценки потерь и метрик на каждой эпохе.
  • shuffle: перемешивание данных перед каждой эпохой (логическое значение).
  • class_weight: словарь весов классов для компенсации дисбаланса.
  • sample_weight: массив весов для каждого образца, влияющих на функцию потерь.
  • initial_epoch: эпоха, с которой начинается обучение (полезно при возобновлении обучения).
  • steps_per_epoch: количество шагов (батчей) до завершения эпохи.
  • validation_steps: количество шагов валидации, если validation_data является генератором.
  • validation_batch_size: размер батча для валидации.
  • validation_freq: периодичность проведения валидации в эпохах.
  • max_queue_size: максимальный размер очереди для генератора.
  • workers: максимальное количество процессов для генератора.
  • use_multiprocessing: использование многопроцессорной обработки для генератора.

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

Базовые примеры использования

Простой пример обучения модели на данных NumPy.

import numpy as np
import tensorflow as tf

# Создание синтетических данных
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))

# Создание модели
model = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(20,)),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Обучение модели
history = model.fit(x_train, y_train, epochs=10, batch_size=32, verbose=1)

print(history.history.keys())
Epoch 1/10
32/32 [==============================] - 0s 2ms/step - loss: 0.7012 - accuracy: 0.5030
...
Epoch 10/10
32/32 [==============================] - 0s 1ms/step - loss: 0.6910 - accuracy: 0.5310
dict_keys(['loss', 'accuracy'])

Пример с валидационными данными и обратными вызовами.

from sklearn.model_selection import train_test_split
from tensorflow.keras.callbacks import EarlyStopping

x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.2)

early_stopping = EarlyStopping(monitor='val_loss', patience=3)

history = model.fit(
    x_train, y_train,
    validation_data=(x_val, y_val),
    epochs=50,
    batch_size=16,
    callbacks=[early_stopping],
    verbose=2
)

print(f'Обучение остановлено на эпохе: {len(history.history["loss"])}')
Epoch 1/50
50/50 - 0s - loss: 0.6912 - accuracy: 0.5212 - val_loss: 0.6943 - val_accuracy: 0.5050
...
Epoch 15/50
50/50 - 0s - loss: 0.6901 - accuracy: 0.5312 - val_loss: 0.6950 - val_accuracy: 0.5050
Обучение остановлено на эпохе: 15

Похожие функции в Python

model.fit_generator: В более ранних версиях Keras (до TensorFlow 2.1) существовал отдельный метод для работы с генераторами данных. Сейчас метод fit поддерживает генераторы напрямую, поэтому fit_generator считается устаревшим.

model.train_on_batch: Выполняет один шаг градиентного обновления на одном батче данных. Этот метод полезен при необходимости тонкого контроля над процессом обучения, например, при реализации пользовательских циклов обучения или при работе с нестандартными потерями. Метод возвращает потери и значения метрик для данного батча.

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

Выбор метода зависит от сложности задачи. fit подходит для большинства стандартных сценариев, train_on_batch - для более тонкой настройки, а пользовательские циклы - для исследовательских задач с нестандартными требованиями.

Типичные ошибки и их решение

1. Несоответствие форм входных данных и ожиданий модели.

# Модель ожидает форму (None, 20)
model = tf.keras.Sequential([tf.keras.layers.Dense(10, input_shape=(20,))])

# Данные имеют форму (1000, 10) - ошибка
x = np.random.random((1000, 10))
y = np.random.random((1000, 1))

history = model.fit(x, y, epochs=2)
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 20), found shape=(None, 10)

2. Пропуск компиляции модели перед вызовом fit.

model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(20,))])
# Забыли вызвать model.compile(...)
history = model.fit(x_train, y_train, epochs=2)
ValueError: You must compile your model before training/testing. Use `model.compile(optimizer, loss)`.

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

# Данные отсортированы по классам
x = np.vstack([np.zeros((500, 20)), np.ones((500, 20))])  # Первые 500 - класс 0
# y тоже отсортированы
history = model.fit(x, y, validation_split=0.2, shuffle=False, epochs=2)
# Валидационная выборка будет содержать только класс 1

4. Ошибки при работе с генераторами: бесконечные циклы, если не определен steps_per_epoch, или несоответствие выхода генератора ожидаемой структуре.

def faulty_generator():
    while True:
        # Возвращаем только x, забыв y
        yield np.random.random((32, 20))

history = model.fit(faulty_generator(), epochs=2, steps_per_epoch=10)
ValueError: Output of generator should be a tuple (x, y, sample_weight) or (x, y). Found: array(...)

Изменения в последних версиях

В TensorFlow 2.x метод fit претерпел значительные изменения по сравнению с Keras, встроенным в TensorFlow 1.x.

Интеграция с tf.data.Dataset: Метод теперь полностью поддерживает объекты tf.data.Dataset, что позволяет эффективно загружать и предобрабатывать большие наборы данных. Рекомендуется использовать именно этот способ для работы с данными.

Упрощение API: Метод fit_generator был объединен с fit. Теперь fit автоматически определяет тип входных данных (массивы NumPy, генераторы Python, tf.data.Dataset).

Поддержка распределенного обучения: Метод теперь прозрачно работает со стратегиями распределенного обучения (tf.distribute.Strategy), что позволяет легко масштабировать обучение на несколько GPU или машин.

Новые аргументы: Появились параметры validation_batch_size и validation_freq для более гибкой настройки процесса валидации.

Улучшенная обработка типов данных: Улучшена поддержка типов данных, включая смешанную точность (mixed precision) через tf.keras.mixed_precision.

Расширенные примеры

1. Использование tf.data.Dataset для эффективной загрузки данных.

Пример python
import tensorflow as tf

# Создание Dataset из тензоров
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(32).prefetch(tf.data.AUTOTUNE)

val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)).batch(32)

model = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(20,)),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

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

history = model.fit(
    train_dataset,
    epochs=10,
    validation_data=val_dataset,
    # steps_per_epoch и validation_steps не требуются,
    # так как Dataset сам определяет количество шагов
    verbose=1
)
print(f'Количество эпох в истории: {len(history.history["loss"])}')

2. Пользовательский генератор данных с дополнительной информацией (sample_weight).

Пример python
import numpy as np

def custom_generator(x, y, sample_weights, batch_size):
    num_samples = len(x)
    indices = np.arange(num_samples)
    np.random.shuffle(indices)
    
    for start in range(0, num_samples, batch_size):
        end = min(start + batch_size, num_samples)
        batch_indices = indices[start:end]
        
        batch_x = x[batch_indices]
        batch_y = y[batch_indices]
        batch_weights = sample_weights[batch_indices]
        
        # Возвращаем кортеж (x, y, sample_weight)
        yield batch_x, batch_y, batch_weights

# Создание искусственных весов
sample_weights = np.random.random((len(x_train),))

gen = custom_generator(x_train, y_train, sample_weights, batch_size=16)

history = model.fit(
    gen,
    epochs=5,
    steps_per_epoch=len(x_train) // 16,  # Важно указать
    verbose=0
)
print(f'Финальное значение потерь: {history.history["loss"][-1]:.4f}')

3. Обучение с частой валидацией (каждые N шагов) с использованием validation_freq в виде списка эпох.

Пример python
history = model.fit(
    x_train, y_train,
    validation_data=(x_val, y_val),
    epochs=20,
    batch_size=32,
    validation_freq=[5, 10, 15, 20],  # Валидация будет на эпохах 5, 10, 15, 20
    verbose=1
)
# Проверяем, на каких эпохах была валидация
if 'val_loss' in history.history:
    val_epochs = [i+1 for i, val in enumerate(history.history['val_loss']) if val is not None]
    print(f'Валидация проводилась на эпохах: {val_epochs}')

4. Возобновление обучения с определенной эпохи (initial_epoch).

Пример python
# Предположим, модель уже обучалась 5 эпох
initial_epoch = 5

history_continued = model.fit(
    x_train, y_train,
    epochs=15,  # Всего хотим 15 эпох
    initial_epoch=initial_epoch,  # Начинаем с эпохи 5
    batch_size=32,
    verbose=1
)
print(f'Общее количество эпох в истории после продолжения: {len(history_continued.history["loss"])}')

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

Пример python
# Допустим, у нас 90% класса 0 и 10% класса 1
class_weight = {0: 1., 1: 9.}  # Увеличиваем вес класса 1 в 9 раз

history = model.fit(
    x_train, y_train,
    epochs=10,
    batch_size=32,
    class_weight=class_weight,
    validation_data=(x_val, y_val),
    verbose=0
)
print(f'Потери на валидации: {history.history["val_loss"][-1]:.4f}')

Аналоги в других языках программирования

Концепция обучения нейронных сетей присутствует во многих фреймворках.

JavaScript (TensorFlow.js): Метод model.fit имеет схожий интерфейс.

// TensorFlow.js пример
const model = tf.sequential({
    layers: [
        tf.layers.dense({units: 64, inputShape: [20], activation: 'relu'}),
        tf.layers.dense({units: 1, activation: 'sigmoid'})
    ]
});

model.compile({
    optimizer: 'adam',
    loss: 'binaryCrossentropy',
    metrics: ['accuracy']
});

// Данные должны быть тензорами TensorFlow.js
const xs = tf.randomNormal([1000, 20]);
const ys = tf.randomUniform([1000, 1], 0, 2, 'int32');

const history = await model.fit(xs, ys, {
    epochs: 10,
    batchSize: 32,
    verbose: 1
});

Java (Deeplearning4j): Используется конструкция model.fit с объектом DataSetIterator.

// Deeplearning4j пример
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
    .list()
    .layer(new DenseLayer.Builder().nIn(20).nOut(64).activation(Activation.RELU).build())
    .layer(new OutputLayer.Builder(LossFunctions.LossFunction.XENT)
        .nIn(64).nOut(1).activation(Activation.SIGMOID).build())
    .build();

MultiLayerNetwork model = new MultiLayerNetwork(conf);
model.init();

// Создание итератора данных
DataSetIterator iterator = new ExistingDataSetIterator(datasets);

model.fit(iterator, 10); // 10 эпох

PyTorch (Python): Обучение реализуется через пользовательские циклы, что предоставляет большую гибкость.

import torch
import torch.nn as nn
import torch.optim as optim

# Определение модели
model = nn.Sequential(
    nn.Linear(20, 64),
    nn.ReLU(),
    nn.Linear(64, 1),
    nn.Sigmoid()
)

criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters())

# Пользовательский цикл обучения
for epoch in range(10):
    for batch_x, batch_y in dataloader:
        optimizer.zero_grad()
        outputs = model(batch_x)
        loss = criterion(outputs, batch_y)
        loss.backward()
        optimizer.step()
    print(f'Epoch {epoch+1}, Loss: {loss.item()}')

В отличие от Keras, PyTorch не предоставляет единого метода fit, требуя написания цикла обучения. Однако библиотеки-надстройки, такие как PyTorch Lightning или fast.ai, добавляют абстракции, подобные fit.

питон tensorflow.keras.Sequential.fit function comments

En
Tensorflow.keras.Sequential.fit Trains the model for a fixed number of epochs