Советы по написанию чистого кода в Tensorflow 2

Советы по написанию чистого кода в Tensorflow 2

20 июля 2025 г.

Обзор контента

  • Обзор
  • Настраивать
  • Рекомендации для идиоматического тензора 2
  • Refactor Your Code в более мелкие модули
  • Регулируйте скорость обучения по умолчанию для некоторых tf.keras.optimizersers
  • Используйте слои tf.modules и keras для управления переменными
  • Объединить tf.data.datasets и tf.function
  • Используйте петли обучения кераса
  • Настройте обучение и напишите свой собственный цикл
  • Воспользуйтесь преимуществами функции с потоком управления Python
  • Метрики и убытки в новом стиле
  • Отладка
  • Не держите TF.tensors в ваших объектах
  • Ресурсы и дальнейшее чтение

Обзор

Это руководство содержит список лучших практик для написания кода с использованием Tensorflow 2 (TF2), он написан для пользователей, которые недавно перешли с TensorFlow 1 (TF1). Сммигрировать раздел руководстваДля получения дополнительной информации о миграции вашего кода TF1 на TF2.

Настраивать

Импорт TensorFlow и другие зависимости для примеров в этом руководстве.

import tensorflow as tf
import tensorflow_datasets as tfds

2023-10-04 01:22:53.526066: E tensorflow/compiler/xla/stream_executor/cuda/cuda_dnn.cc:9342] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2023-10-04 01:22:53.526110: E tensorflow/compiler/xla/stream_executor/cuda/cuda_fft.cc:609] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2023-10-04 01:22:53.526158: E tensorflow/compiler/xla/stream_executor/cuda/cuda_blas.cc:1518] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered

Рекомендации для идиоматического тензора 2

Refactor Your Code в более мелкие модули

Хорошая практика - реформировать ваш код в более мелкие функции, которые называются по мере необходимости. Для достижения наилучшей производительности, вы должны попытаться украсить самые большие блоки вычислений, которые вы можете вtf.function(Обратите внимание, что вложенные функции Python, вызванныеtf.functionне требуют их собственных отдельных украшений, если вы не хотите использовать разныеjit_compileНастройки дляtf.function) В зависимости от вашего варианта использования, это может быть несколько учебных этапов или даже ваш цикл обучения. Для вывода используют варианты использования, это может быть единственная модель вперед.

Отрегулируйте скорость обучения по умолчанию для некоторыхtf.keras.optimizerс

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

Нет изменений дляoptimizers.SGDВoptimizers.Adam, илиoptimizers.RMSpropПолем

Следующие ставки обучения по умолчанию изменились:

  • optimizers.Adagradот0.01к0.001
  • optimizers.Adadeltaот1.0к0.001
  • optimizers.Adamaxот0.002к0.001
  • optimizers.Nadamот0.002к0.001

Использоватьtf.ModuleСлои S и Keras для управления переменными

tf.Moduleпесокtf.keras.layers.LayerS предлагает удобноеvariablesиtrainable_variablesсвойства, которые рекурсивно собирают все зависимые переменные. Это позволяет легко управлять переменными локально, где они используются.

Керас слои/модели наследуют отtf.train.Checkpointableи интегрированы с@tf.function, что позволяет напрямую контрольно -пропускную точку или экспорта сохранения моделей из объектов Keras. Вам не обязательно нужно использовать керас 'Model.fitAPI, чтобы воспользоваться этими интеграциями.

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

Комбинироватьtf.data.Datasetпесокtf.function

АНаборы данных TensorFlowупаковка (tfds) содержит утилиты для загрузки предопределенных наборов данных какtf.data.Datasetобъекты Для этого примера вы можете загрузить набор данных MNIST, используяtfds:

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']

2023-10-04 01:22:57.406511: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2211] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.
Skipping registering GPU devices...

Затем подготовьте данные для обучения:

  • Повторно масштабируйте каждое изображение.
  • Пойфрайте порядок примеров.
  • Соберите партии изображений и ярлыков.

BUFFER_SIZE = 10 # Use a much larger value for real code
BATCH_SIZE = 64
NUM_EPOCHS = 5


def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255

  return image, label

Чтобы сохранить пример коротким, обрежьте набор данных, чтобы вернуть только 5 партий:

train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
test_data = mnist_test.map(scale).batch(BATCH_SIZE)

STEPS_PER_EPOCH = 5

train_data = train_data.take(STEPS_PER_EPOCH)
test_data = test_data.take(STEPS_PER_EPOCH)

image_batch, label_batch = next(iter(train_data))

2023-10-04 01:22:58.048011: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

Используйте обычную итерацию Python для итерации по поводу учебных данных, которые вписываются в память. В противном случае,tf.data.Datasetэто лучший способ трансляции обучающих данных с диска. Наборы данных естьиеры (не итераторы)и работайте так же, как и другие иеры Python в нетерпеливом исполнении. Вы можете в полной мере использовать функции предварительного получения/потоковой передачи Async Async, обернув свой код вtf.function, который заменяет итерацию Python на эквивалентные графические операции с использованием автографа.

@tf.function
def train(model, dataset, optimizer):
  for x, y in dataset:
    with tf.GradientTape() as tape:
      # training=True is only needed if there are layers with different
      # behavior during training versus inference (e.g. Dropout).
      prediction = model(x, training=True)
      loss = loss_fn(prediction, y)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

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

model.compile(optimizer=optimizer, loss=loss_fn)
model.fit(dataset)

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

Если вам не нужен низкоуровневый контроль вашего учебного процесса, используя встроенный керасfitВevaluate, иpredictметоды рекомендуются. Эти методы обеспечивают равномерный интерфейс для обучения модели независимо от реализации (последовательной, функциональной или подклассовой).

Преимущества этих методов включают:

  • Они принимают массивы Numpy, генераторы Python и,tf.data.DatasetsПолем
  • Они применяют регуляризацию, и автоматически потери активации.
  • Они поддерживаютtf.distributeгде код обучения остается прежнимНезависимо от конфигурации оборудованияПолем
  • Они поддерживают произвольные вызовы в качестве убытков и показателей.
  • Они поддерживают обратные вызовы, какtf.keras.callbacks.TensorBoardи пользовательские обратные вызовы.
  • Они работают, автоматически используя графики TensorFlow.

Вот пример обучения модели, используяDatasetПолем Для получения подробной информации о том, как это работает, проверьтеУчебные пособияПолем

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)

print("Loss {}, Accuracy {}".format(loss, acc))

Epoch 1/5
5/5 [==============================] - 2s 44ms/step - loss: 1.6644 - accuracy: 0.4906
Epoch 2/5
2023-10-04 01:22:59.569439: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 9ms/step - loss: 0.5173 - accuracy: 0.9062
Epoch 3/5
2023-10-04 01:23:00.062308: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 9ms/step - loss: 0.3418 - accuracy: 0.9469
Epoch 4/5
2023-10-04 01:23:00.384057: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 8ms/step - loss: 0.2707 - accuracy: 0.9781
Epoch 5/5
2023-10-04 01:23:00.766486: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 8ms/step - loss: 0.2195 - accuracy: 0.9812
2023-10-04 01:23:01.120149: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
5/5 [==============================] - 0s 4ms/step - loss: 1.6036 - accuracy: 0.6250
Loss 1.6036441326141357, Accuracy 0.625
2023-10-04 01:23:01.572685: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

Настройте обучение и напишите свой собственный цикл

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

Вы также можете реализовать много вещей какtf.keras.callbacks.CallbackПолем

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

Есть три шага к стандартной тренировочной петле:

  1. Итерация над генератором Python илиtf.data.DatasetЧтобы получить партии примеров.
  2. Использоватьtf.GradientTapeсобирать градиенты.
  3. Используйте один изtf.keras.optimizersЧтобы применить обновления веса к переменным модели.

Помнить:

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

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

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

for epoch in range(NUM_EPOCHS):
  for inputs, labels in train_data:
    train_step(inputs, labels)
  print("Finished epoch", epoch)

2023-10-04 01:23:02.652222: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 0
2023-10-04 01:23:02.957452: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 1
2023-10-04 01:23:03.632425: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 2
2023-10-04 01:23:03.877866: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Finished epoch 3
Finished epoch 4
2023-10-04 01:23:04.197488: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

Воспользоватьсяtf.functionс потоком управления Python

tf.functionобеспечивает способ преобразования данных управления, зависящего от данных, в эквиваленты графика, такие какtf.condиtf.while_loopПолем

Одно распространенное место, где появляется зависимый от данных поток управления, находится в моделях последовательностей.tf.keras.layers.RNNЗавершает ячейку RNN, позволяя вам либо статически, либо динамически развернуть рецидив. В качестве примера вы можете переопределить динамику развертываться следующим образом.

class DynamicRNN(tf.keras.Model):

  def __init__(self, rnn_cell):
    super(DynamicRNN, self).__init__(self)
    self.cell = rnn_cell

  @tf.function(input_signature=[tf.TensorSpec(dtype=tf.float32, shape=[None, None, 3])])
  def call(self, input_data):

    # [batch, time, features] -> [time, batch, features]
    input_data = tf.transpose(input_data, [1, 0, 2])
    timesteps =  tf.shape(input_data)[0]
    batch_size = tf.shape(input_data)[1]
    outputs = tf.TensorArray(tf.float32, timesteps)
    state = self.cell.get_initial_state(batch_size = batch_size, dtype=tf.float32)
    for i in tf.range(timesteps):
      output, state = self.cell(input_data[i], state)
      outputs = outputs.write(i, output)
    return tf.transpose(outputs.stack(), [1, 0, 2]), state

lstm_cell = tf.keras.layers.LSTMCell(units = 13)

my_rnn = DynamicRNN(lstm_cell)
outputs, state = my_rnn(tf.random.normal(shape=[10,20,3]))
print(outputs.shape)

(10, 20, 13)

Читатьtf.functionРуководство для получения дополнительной информации.

Метрики и убытки в новом стиле

Метрики и потери - это оба объекта, которые работают с нетерпением и вtf.functionс

Объект потери является вызовом и ожидает (y_trueВy_pred) в качестве аргументов:

cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()

4.01815

Используйте метрики для сбора и отображения данных

Вы можете использоватьtf.metricsдля объединения данных иtf.summaryЧтобы зарегистрировать резюме и перенаправить его на писателя, используя диспетчер контекста. Резюме излучаются непосредственно писателю, что означает, что вы должны предоставитьstepзначение на звонках.

summary_writer = tf.summary.create_file_writer('/tmp/summaries')
with summary_writer.as_default():
  tf.summary.scalar('loss', 0.1, step=42)

Использоватьtf.metricsдля агрегирования данных перед тем, как записать их в качестве резюме. Метрики являются государственными; Они накапливают значения и возвращают кумулятивный результат, когда вы называетеresultМетод (напримерMean.result) Четкие накопленные значения сModel.reset_statesПолем

def train(model, optimizer, dataset, log_freq=10):
  avg_loss = tf.keras.metrics.Mean(name='loss', dtype=tf.float32)
  for images, labels in dataset:
    loss = train_step(model, optimizer, images, labels)
    avg_loss.update_state(loss)
    if tf.equal(optimizer.iterations % log_freq, 0):
      tf.summary.scalar('loss', avg_loss.result(), step=optimizer.iterations)
      avg_loss.reset_states()

def test(model, test_x, test_y, step_num):
  # training=False is only needed if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  loss = loss_fn(model(test_x, training=False), test_y)
  tf.summary.scalar('loss', loss, step=step_num)

train_summary_writer = tf.summary.create_file_writer('/tmp/summaries/train')
test_summary_writer = tf.summary.create_file_writer('/tmp/summaries/test')

with train_summary_writer.as_default():
  train(model, optimizer, dataset)

with test_summary_writer.as_default():
  test(model, test_x, test_y, optimizer.iterations)

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

tensorboard --logdir /tmp/summaries

Используйтеtf.summaryAPI для написания сводных данных для визуализации в Tensorboard. Для получения дополнительной информации прочитайтеtf.summaryгид.

# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  # Update the metrics
  loss_metric.update_state(total_loss)
  accuracy_metric.update_state(labels, predictions)


for epoch in range(NUM_EPOCHS):
  # Reset the metrics
  loss_metric.reset_states()
  accuracy_metric.reset_states()

  for inputs, labels in train_data:
    train_step(inputs, labels)
  # Get the metric results
  mean_loss=loss_metric.result()
  mean_accuracy = accuracy_metric.result()

  print('Epoch: ', epoch)
  print('  loss:     {:.3f}'.format(mean_loss))
  print('  accuracy: {:.3f}'.format(mean_accuracy))

2023-10-04 01:23:05.220607: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  0
  loss:     0.176
  accuracy: 0.994
2023-10-04 01:23:05.554495: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  1
  loss:     0.153
  accuracy: 0.991
2023-10-04 01:23:06.043597: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  2
  loss:     0.134
  accuracy: 0.994
2023-10-04 01:23:06.297768: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Epoch:  3
  loss:     0.108
  accuracy: 1.000
Epoch:  4
  loss:     0.095
  accuracy: 1.000
2023-10-04 01:23:06.678292: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

Керас метрических имен

Модели Keras последовательны в отношении обработки метрических имен. Когда вы передаете строку в списке метрик, этоточныйСтрока используется в качестве метрикиnameПолем Эти имена видны в объекте истории, возвращенномmodel.fitи в бревенчатыхkeras.callbacksПолем устанавливается на строку, которую вы прошли в метрическом списке.

model.compile(
    optimizer = tf.keras.optimizers.Adam(0.001),
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)

5/5 [==============================] - 1s 9ms/step - loss: 0.1077 - acc: 0.9937 - accuracy: 0.9937 - my_accuracy: 0.9937
2023-10-04 01:23:07.849601: W tensorflow/core/kernels/data/cache_dataset_ops.cc:854] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

history.history.keys()

dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])

Отладка

Используйте стремление к выполнению вашего кода пошаговым за шагом, чтобы осмотреть формы, типы данных и значения. Определенные API, какtf.functionВtf.kerasи т. д. предназначены для использования выполнения графика, для производительности и переносимости. При отладке используйтеtf.config.run_functions_eagerly(True)Чтобы использовать нетерпеливое выполнение в этом коде.

Например:

@tf.function
def f(x):
  if x > 0:
    import pdb
    pdb.set_trace()
    x = x + 1
  return x

tf.config.run_functions_eagerly(True)
f(tf.constant(1))

>>> f()
-> x = x + 1
(Pdb) l
  6     @tf.function
  7     def f(x):
  8       if x > 0:
  9         import pdb
 10         pdb.set_trace()
 11  ->     x = x + 1
 12       return x
 13
 14     tf.config.run_functions_eagerly(True)
 15     f(tf.constant(1))
[EOF]

Это также работает в моделях Keras и других API, которые поддерживают нетерпеливое исполнение:

class CustomModel(tf.keras.models.Model):

  @tf.function
  def call(self, input_data):
    if tf.reduce_mean(input_data) > 0:
      return input_data
    else:
      import pdb
      pdb.set_trace()
      return input_data // 2


tf.config.run_functions_eagerly(True)
model = CustomModel()
model(tf.constant([-2, -4]))

>>> call()
-> return input_data // 2
(Pdb) l
 10         if tf.reduce_mean(input_data) > 0:
 11           return input_data
 12         else:
 13           import pdb
 14           pdb.set_trace()
 15  ->       return input_data // 2
 16
 17
 18     tf.config.run_functions_eagerly(True)
 19     model = CustomModel()
 20     model(tf.constant([-2, -4]))

Примечания:

  • tf.keras.Modelметоды, такие какfitВevaluate, иpredictвыполнить какграфикисtf.functionпод капюшоном.
  • При использованииtf.keras.Model.compile, наборrun_eagerly = TrueЧтобы отключитьModelлогика от завершенияtf.functionПолем
  • Использоватьtf.data.experimental.enable_debug_modeЧтобы включить режим отладки дляtf.dataПолем ЧитатьAPI документыДля получения более подробной информации.

Не сохраняйтеtf.Tensorsв ваших объектах

Эти тензорные объекты могут быть созданы либо вtf.functionили в нетерпеливом контексте, и эти тензоры ведут себя по -разному. Всегда используйтеtf.TensorS только для промежуточных значений.

Чтобы отслеживать состояние, используйтеtf.VariableS, как они всегда используются из обоих контекстов. Читатьtf.VariableРуководство, чтобы узнать больше.

Ресурсы и дальнейшее чтение

  • Прочитайте TF2гидыиУчебные пособияЧтобы узнать больше о том, как использовать TF2.
  • Если вы ранее использовали tf1.x, настоятельно рекомендуется перенести свой код в TF2. ЧитатьРуководства по миграцииЧтобы узнать больше.

Первоначально опубликовано наTensorflowВеб -сайт, эта статья появляется здесь под новым заголовком и имеет лицензию в CC на 4.0. Образцы кода, разделенные по лицензии Apache 2.0.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE