NaN с кросс-энтропией softmax в простой модели с фиктивными входами

1

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

import tensorflow as tf
from tensorflow.python import debug as tf_debug

def train_input_fn():
  pass


def model_fn(features, labels, mode, params):

  classes = 225
  enc = tf.ones((1,20,1024), dtype=tf.float16)
  labels = tf.ones((1,20), dtype=tf.int32)

  logits = tf.layers.dense(enc, classes)
  loss = tf.reduce_sum(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels)) / 20
  train_op = tf.train.AdamOptimizer(learning_rate=0.00001, beta1=0.9, beta2=0.999).minimize(loss)

  return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)


if __name__ == '__main__':

  model_directory = path/to/logdir
  hooks = [tf_debug.LocalCLIDebugHook(ui_type="readline")]

  classifier = tf.estimator.Estimator(
      model_fn=model_fn,
      model_dir=model_directory,
      params={},
  )

  classifier.train(input_fn=lambda: train_input_fn(), hooks = hooks)

После третьего или четвертого "запуска" с отладчиком tenorflow в новом каталоге модели я получаю "NaN-потерю во время обучения". Я уже пытался установить уровень обучения очень низко, но ничего не изменилось. Я использую tensorflow-gpu 1.8.

Теги:
tensorflow
cross-entropy

2 ответа

1
Лучший ответ

Я пробовал ваш код. Я получал NaN с первого шага.

И я проверил официальную документацию.

logits: Unscaled log probabilities of shape [d_0, d_1, ..., d_{r-1}, num_classes] and dtype float32 or float64.

Изменен enc = tf.ones((1,20,1024), dtype=tf.float16) до enc = tf.ones((1,20,1024), dtype=tf.float32) и он сработает!

  • 1
    Хотя в документации указано float32 или 64, у меня с float16 она работает нормально. Кажется, моя проблема связана с оптимизатором Adam, как указано в другом ответе. Тем не менее, спасибо за ваш проницательный ответ!
  • 0
    Float16 будет работать, но с внутренними изменениями по умолчанию, как вы упомянули Epsilon. Хотя, если у вас нет строгих ограничений памяти, я бы рекомендовал использовать float32 или float64, потому что могут быть другие операции, которые изначально ожидают, что ввод будет в этом формате.
0

Использование tf.float16 для переменных оптимизации Адама позволяет использовать более высокие значения эпсилона для численной стабильности. Когда я добавляю epsilon = 1e-04 (стандарт 1e-08) для оптимизатора Адама, он работает для меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню