Выпуск NaN с Адам решателем
Я тренирую сети с помощью решателя Адама и столкнулся с проблемой, что оптимизация в какой-то момент достигает «нан», но до этого момента потери, похоже, неплохо уменьшаются. Это происходит только для некоторых конкретных конфигураций и после нескольких тысяч итераций. Например, сеть с размером пакета 5 будет иметь проблемы, в то время как с размером пакета один это работает. Итак, я начал отлаживать свой код:
1) Первое, что мне пришло в голову, это проверить входные данные, когда сеть достигнет «nan», но они выглядят разумно (правильно обозначенная правдоподобная истина и ввод с нормальным диапазоном значений)
2) Во время поиска я обнаружилtf.verify_tensor_all_finite(..)
и я поместил это по всему моему коду, чтобы увидеть, какой тензор сначала становится 'nan'. Я мог бы сузить проблему до следующих строк:
kernel = tf.verify_tensor_all_finite(kernel, 'kernel')
in_tensor = tf.verify_tensor_all_finite(in_tensor, 'in_tensor')
tmp_result = tf.nn.conv2d_transpose(value=in_tensor, filter=kernel, output_shape=output_shape,
strides=strides, padding='SAME')
tmp_result = tf.verify_tensor_all_finite(tmp_result, 'convres')
Который выдает ошибку, которая гласит:
InvalidArgumentError (see above for traceback): convres : Tensor had NaN values
[[Node: upconv_logits5_fs/VerifyFinite_2/CheckNumerics = CheckNumerics[T=DT_FLOAT, _class=["loc:@upconv_logits5_fs/conv2d_transpose"], message="convres", _device="/job:localhost/replica:0/task:0/gpu:0"](upconv_logits5_fs/conv2d_transpose)]]
[[Node: Adam/update/_2794 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_154_Adam/update", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
Теперь я не уверен, что здесь произошло.
Я предполагаю, что во время прямого прохода все прошло хорошо, потому что скалярная потеря не вызвала ошибку, а также ядро и ввод были по-прежнему действительными числами. Кажется, что какой-то узел обновления Адама изменяет значение моегоupconv_logits5_fs
в сторону нан. Эта транспонированная операция свертки является самой последней в моей сети и, следовательно, первой, которая будет обновлена.
Я работаю сtf.nn.softmax_cross_entropy_with_logits()
потеря и положитьtf.verify_tensor_all_finite()
на всех входах и выходах, но они не вызывают ошибок. Единственный вывод, который я могу сделать, состоит в том, что с решателем Адама может возникнуть численная проблема.
Ваша помощь очень ценится.
РЕДАКТИРОВАТЬ: Я смог решить мою проблему путем увеличения решателейэпсилон параметр от 1e-8 до 1e-4. Казалось, что некоторые из моих параметров имеют тенденцию иметь очень небольшую или нулевую дисперсию, и это привело кtf.sqrt(0.0 + epsilon)
, что вызвало численные проблемы.