Я заметил, что во время тренировок вводится частое явление NAN
.
Часто кажется, что это происходит из-за того, что веса во внутреннем продукте / полностью связанных или сверточных слоях взрываются.
Это происходит потому, что вычисление градиента резко увеличивается? Или это из-за инициализации веса (если да, то почему инициализация веса имеет такой эффект)? Или это, вероятно, вызвано характером входных данных?
Общий вопрос здесь прост: какова наиболее частая причина возникновения NAN во время обучения? А во-вторых, какие есть методы борьбы с этим (и почему они работают)?
caffe
связан с ним.Ответы:
Хороший вопрос.
Я сталкивался с этим явлением несколько раз. Вот мои наблюдения:
Градиент взорвать
Причина: большие градиенты сбивают процесс обучения с пути.
Чего следует ожидать: глядя на журнал выполнения, вы должны смотреть на значения потерь на итерацию. Вы заметите, что потери начинают значительно расти от итерации к итерации, в конечном итоге потеря будет слишком большой, чтобы ее можно было представить переменной с плавающей запятой, и она станет
nan
.Что вы можете сделать: Уменьшите
base_lr
(в solver.prototxt) на порядок (как минимум). Если у вас несколько слоев потерь, вы должны проверить журнал, чтобы увидеть, какой слой отвечает за увеличение градиента, и уменьшитьloss_weight
(в train_val.prototxt) для этого конкретного слоя, а не для общегоbase_lr
.Плохая политика скорости обучения и параметры
Причина: caffe не может вычислить допустимую скорость обучения и получает
'inf'
или'nan'
вместо этого эта недопустимая скорость умножает все обновления и, таким образом, делает недействительными все параметры.Чего следует ожидать: глядя в журнал выполнения, вы должны увидеть, что сама скорость обучения составляет
'nan'
, например:Что вы можете сделать: исправить все параметры, влияющие на скорость обучения, в вашем
'solver.prototxt'
файле.Например, если вы используете
lr_policy: "poly"
и забыли определитьmax_iter
параметр, вы получитеlr = nan
...Подробнее о скорости обучения в кафе см. В этой ветке .
Неисправная функция потери
Причина: Иногда при вычислении потерь в слоях потерь
nan
появляется s. Например,InfogainLoss
слой подачи с ненормализованными значениями , с использованием настраиваемого слоя потерь с ошибками и т. Д.Чего следует ожидать: глядя в журнал выполнения, вы, вероятно, не заметите ничего необычного: потери постепенно уменьшаются, и внезапно
nan
появляется значок.Что вы можете сделать: посмотрите, сможете ли вы воспроизвести ошибку, добавить распечатку к слою потерь и отладить ошибку.
Например: однажды я использовал потерю, которая нормализовала штраф на частоту появления меток в пакете. Так уж получилось, что если одна из обучающих меток вообще не появилась в партии - вычисляемые потери производили
nan
s. В этом случае достаточно было работать с достаточно большими партиями (по количеству этикеток в наборе), чтобы избежать этой ошибки.Неправильный ввод
Причина: у вас есть вход
nan
в него!Чего и следовало ожидать: как только процесс обучения "попадает" в этот ошибочный ввод, становится выходом
nan
. Глядя на журнал выполнения, вы, вероятно, не заметите ничего необычного: потери постепенно уменьшаются, и вдругnan
появляется значок.Что вы можете сделать: пересоберите свои входные наборы данных (lmdb / leveldn / hdf5 ...), убедитесь, что у вас нет плохих файлов изображений в вашем наборе для обучения / проверки. Для отладки вы можете построить простую сеть, которая считывает входной слой, имеет фиктивную потерю поверх нее и проходит через все входы: если один из них неисправен, эта фиктивная сеть также должна работать
nan
.шаг больше, чем размер ядра в
"Pooling"
слоеПо какой-то причине выбор
stride
>kernel_size
для объединения может привести кnan
s. Например:результаты с
nan
s вy
.Нестабильности в
"BatchNorm"
Сообщалось, что при некоторых настройках
"BatchNorm"
слой может выводитьnan
s из-за числовой нестабильности.Эта проблема возникла в bvlc / caffe, и PR № 5136 пытается ее исправить.
Недавно я узнал о
debug_info
флаге: установкаdebug_info: true
в'solver.prototxt'
заставит Caffe печать войти больше отладочной информации ( в том числе градиентные величин и значений активации) во время тренировки: Эта информация может помочь в пятнистость градиентные раздутия и другие проблемы в процессе обучения .источник
В моем случае причиной было отсутствие смещения в слоях свертки / деконволюции.
Решение: добавьте следующее к параметрам сверточного слоя.
bias_filler {тип: "постоянное" значение: 0}
источник
Этот ответ не касается причины
nan
s, а скорее предлагает способ ее отладки. У вас может быть этот слой Python:class checkFiniteLayer(caffe.Layer): def setup(self, bottom, top): self.prefix = self.param_str def reshape(self, bottom, top): pass def forward(self, bottom, top): for i in xrange(len(bottom)): isbad = np.sum(1-np.isfinite(bottom[i].data[...])) if isbad>0: raise Exception("checkFiniteLayer: %s forward pass bottom %d has %.2f%% non-finite elements" % (self.prefix,i,100*float(isbad)/bottom[i].count)) def backward(self, top, propagate_down, bottom): for i in xrange(len(top)): if not propagate_down[i]: continue isf = np.sum(1-np.isfinite(top[i].diff[...])) if isf>0: raise Exception("checkFiniteLayer: %s backward pass top %d has %.2f%% non-finite elements" % (self.prefix,i,100*float(isf)/top[i].count))
Добавление этого слоя в
train_val.prototxt
определенные моменты, которые вы подозреваете, может вызвать проблемы:источник
Learning_rate высока и должна быть уменьшена Точность в коде RNN была nan, с выбором низкого значения для скорости обучения, которую он исправляет
источник
Я пытался создать автоэнкодер с разреженным кодом и имел в нем несколько слоев, чтобы добиться разреженности. Во время работы в сети я наткнулся на NaN. При удалении некоторых слоев (в моем случае мне действительно пришлось удалить 1) я обнаружил, что NaN исчезли. Итак, я полагаю, что слишком большая разреженность также может привести к NaN (могли быть вызваны вычисления 0/0 !?)
источник
nan
s, и фиксированной конфигурации? какой тип слоев? какие параметры?