Adam optimizer выходит из строя после партий 200k, потеря обучения растет

я видел очень странное поведение при обучении сети, где после пары итераций 100k (от 8 до 10 часов) обучения все ломается и потеря обучения растет:

Loss explodes

сами данные обучения рандомизированы и распределены по многим .tfrecord файлы, содержащие 1000 примеры каждый, а затем перетасовал снова на входном этапе и пакетировал в 200 примеры.

в фон

я разрабатываю сеть, которая одновременно выполняет четыре различные задачи регрессии, например, определение вероятности появления объекта на изображении и одновременное определение его ориентации. Сеть начинается с пары сверточных слоев, некоторые с остаточными соединениями, а затем разветвляется на четыре полностью Соединенных сегмента.

поскольку первая регрессия приводит к вероятности, я использую перекрестную энтропию для потери, в то время как другие используют классическое расстояние L2. Однако из-за их природы вероятность потери составляет порядка 0..1, в то время как потери ориентации могут быть намного больше, скажем 0..10. Я уже нормализовал как входные, так и выходные значения и использую отсечение

normalized = tf.clip_by_average_norm(inferred.sin_cos, clip_norm=2.)

в случаях, когда все может стать очень плохо.

я (успешно) использовал оптимизатор Adam для оптимизации тензора, содержащего все различные потери (а не reduce_suming их), как Итак:

reg_loss = tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
loss = tf.pack([loss_probability, sin_cos_mse, magnitude_mse, pos_mse, reg_loss])

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate,
                                   epsilon=self.params.adam_epsilon)
op_minimize = optimizer.minimize(loss, global_step=global_step)

чтобы отобразить результаты в TensorBoard, я на самом деле делаю

loss_sum = tf.reduce_sum(loss)

скаляр резюме.

Адам настроен на скорость обучения 1e-4 и Эпсилон 1e-4 (Я вижу такое же поведение со значением по умолчанию для epislon, и он ломается еще быстрее, когда я держу скорость обучения на 1e-3). Регуляризация также не влияет на это, она делает это последовательно в какой-то момент.

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

2 ответов


да. Это известная проблема Адама.

уравнения для Адама

t <- t + 1
lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)

m_t <- beta1 * m_{t-1} + (1 - beta1) * g
v_t <- beta2 * v_{t-1} + (1 - beta2) * g * g
variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)

здесь m - экспоненциальная скользящая средняя среднего градиента и v - экспоненциальная скользящая средняя квадратов градиентов. Проблема в том, что когда вы тренируетесь уже давно, и близки к оптимальному, то v может стать очень маленьким. Если затем внезапно градиенты снова начнут увеличиваться, он будет разделен на очень небольшое число и взрываются.

по умолчанию beta1=0.9 и beta2=0.999. Так что m изменения гораздо быстрее, чем v. Так что m может снова стать большим, пока v еще маленький и не может догнать.

чтобы устранить эту проблему, вы можете увеличить epsilon что это 10-8 по умолчанию. Таким образом, остановив задачу деления почти на 0. В зависимости от вашей сети, стоимостью epsilon на 0.1, 0.01 или 0.001 может быть хорошо.


Да, это может быть какой-то супер сложный случай нестабильных чисел/уравнений, но большая часть уверенности, что ваша скорость обучения просто высока, поскольку ваша потеря быстро уменьшается до 25K, а затем сильно колеблется на том же уровне. Попробуйте уменьшить его в 0,1 раза и посмотрите, что произойдет. Вы должны быть в состоянии достичь еще более низкой величины потерь.

продолжайте изучать! :)