Поширені причини нансу під час тренування


85

Я помітив, що під час тренувань NANвводяться часті випадки .

Часто здається, що це вводиться вагами у продувних шарах внутрішнього продукту / повністю з'єднаних або звивин.

Це відбувається тому, що обчислення градієнта роздувається? Або це через ініціалізацію ваги (якщо так, чому ініціалізація ваги має такий ефект)? Або це, ймовірно, спричинено характером вхідних даних?

Основне питання тут просто: Яка найпоширеніша причина виникнення НАН під час навчання? А по-друге, які існують методи боротьби з цим (і чому вони працюють)?


Ви викликаєте певні функції MATLAB? Це все ваш власний код?
Метью Ганн,

2
@MatthewGunn Я не думаю, що це питання є специфічним для matlab, а скоріше caffeпов'язане.
Шай,

Відповіді:


134

Хороше питання.
Я кілька разів стикався з цим явищем. Ось мої спостереження:


Градієнтний підрив

Причина: великі градієнти відхиляють процес навчання.

Що слід очікувати: Переглядаючи журнал виконання, слід дивитись на значення втрат за ітерацію. Ви помітите, що втрати починають значно зростати від ітерації до ітерації, врешті-решт втрата буде занадто великою, щоб бути представленою змінною з плаваючою комою, і вона стане nan.

Що ви можете зробити: Зменшіть base_lr(у розв'язувальному протоколі) на порядок (принаймні). Якщо у вас є кілька шарів втрат, слід перевірити журнал, щоб побачити, який шар відповідає за loss_weightвибух градієнта, і зменшити (у train_val.prototxt) для цього конкретного шару, замість загальногоbase_lr .


Погана політика та параметри навчання

Причина: caffe не може обчислити дійсну швидкість навчання і отримує'inf' або 'nan'замість цього, ця недійсна швидкість примножує всі оновлення і таким чином анулює всі параметри.

Що слід очікувати: Переглядаючи журнал виконання, ви побачите, що сам рівень навчання стає 'nan', наприклад:

... sgd_solver.cpp:106] Iteration 0, lr = -nan

Що ви можете зробити: виправити всі параметри, що впливають на швидкість навчання у вашому 'solver.prototxt'файлі.
Наприклад, якщо ви використовуєте, lr_policy: "poly"а ви забули визначити max_iterпараметр, у підсумку ви отримаєте lr = nan...
Більше інформації про швидкість навчання в caffe див. У цій темі .


Несправна функція втрати

Причина: Іноді обчислення збитків у шарах збитків призводить nanдо появи s. Наприклад, ГодуванняInfogainLoss шару з ненормованими значеннями , використання спеціального шару втрат з помилками тощо.

Що слід очікувати: Переглядаючи журнал виконання, ви, мабуть, не помітите нічого незвичного: втрати поступово зменшуються, і раптом nanз’являється a .

Що ви можете зробити: подивіться, чи можете ви відтворити помилку, додати роздруківку до шару втрат і налагодити помилку.

Наприклад: Одного разу я використав програш, який нормалізував покарання за частотою появи етикетки в партії. Так трапилося, що якщо одна з навчальних міток взагалі не відображалася в партії - обчислена втрата давала nans. У цьому випадку роботи з достатньо великими партіями (щодо кількості міток у наборі) було достатньо, щоб уникнути цієї помилки.


Помилка введення

Причина: вас є вхідні дані nan!

Що слід очікувати: як тільки процес навчання "потрапляє" на цей несправний вхід - вихід стаєnan . Переглядаючи журнал виконання, ви, мабуть, не помітите нічого незвичного: втрати поступово зменшуються, і раптом nanз'являється a .

Що ви можете зробити: заново побудуйте набори вхідних даних (lmdb / leveldn / hdf5 ...), переконайтесь, що у вас немає поганих файлів зображень у вашому навчальному / перевірочному наборі. Для налагодження ви можете створити просту мережу, яка зчитує вхідний рівень, має фіктивну втрату поверх нього і проходить через усі входи: якщо один з них несправний, ця фіктивна мережа також повинна створити nan.


крок більше "Pooling"шару, ніж розмір ядра

З якоїсь причини вибір stride> kernel_sizeдля об'єднання може призвести до nans. Наприклад:

layer {
  name: "faulty_pooling"
  type: "Pooling"
  bottom: "x"
  top: "y"
  pooling_param {
    pool: AVE
    stride: 5
    kernel: 3
  }
}

результати з nans вy .


Нестабільність у "BatchNorm"

Повідомлялося, що за деяких параметрів "BatchNorm"рівень може виводити nans через числові нестабільності.
Цю проблему порушено у bvlc / caffe, і PR # 5136 намагається її виправити.


Нещодавно я дізнався про debug_infoпрапорі: установка debug_info: trueв 'solver.prototxt'змусить Caffe друк увійти більше налагоджувальної інформації ( в тому числі градієнтні величин і значень активації) під час тренування: Ця інформація може допомогти в плямистість градієнтні роздуття та інші проблеми в процесі навчання .


Дякую, як інтерпретувати ці цифри? Що це за цифри? pastebin.com/DLYgXK5v, чому на виході шару є лише одне число !? як мають виглядати ці цифри, щоб хтось знав, що проблема є або її взагалі немає !?
Ріка

@Hossein це саме те, про що йдеться в цій публікації .
Шай

Дякую за цю відповідь. Я отримую втрату NAN для програми сегментації зображень, навченої втратою DICE (навіть після додавання невеликої константи епсилону / плавності). Мій набір даних містить кілька зображень, відповідні основні істини яких не містять жодної мітки переднього плану, і коли я вилучив ці зображення з тренувань, втрати стабілізувались. Я не впевнений, чому це?
Самра Іршад

@samrairshad ви пробували збільшити епсилон при втраті DICE?
Шай,

Так. Я відкрив пост під час переповнення стека і вставив еволюцію втрат протягом деяких епох. Ось посилання: stackoverflow.com/questions/62259112 / ...
Samra Irshad

5

У моєму випадку причиною було не встановлення упередженості в шарах згортки / деконволюції.

Рішення: додайте наступне до параметрів рівня згортки.

bias_filler {тип: "константне" значення: 0}


як би це виглядало в matconvnet? У мене щось на кшталт 'упереджень'. Init_bias * ones (1,4, одиночний)
h612

4

Ця відповідь не стосується причини nans, а, навпаки, пропонує спосіб допомогти її налагодити. Ви можете мати цей шар 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в певних місцях, які ви підозрюєте, може спричинити проблеми:

layer {
  type: "Python"
  name: "check_loss"
  bottom: "fc2"
  top: "fc2"  # "in-place" layer
  python_param {
    module: "/path/to/python/file/check_finite_layer.py" # must be in $PYTHONPATH
    layer: "checkFiniteLayer"
    param_str: "prefix-check_loss" # string for printouts
  }
}

1

Швидкість_навчання висока і повинна бути зменшена Точність у коді RNN була nn, з вибором низького значення для швидкості навчання, яку він виправляє


-1

Я намагався побудувати розріджений автокодер, і в ньому було кілька шарів, щоб викликати розрідженість. Під час запуску мережі я зіткнувся з NaN. Видаливши деякі шари (у моєму випадку мені фактично довелося видалити 1), я виявив, що NaN зник. Тож, гадаю, занадто розрідженість може призвести і до NaN (можливо, були використані деякі обчислення 0/0 !?)


ти можеш бути трохи конкретнішим? Ви можете надати детальну інформацію про конфігурацію, яка мала nans, та виправлену конфігурацію? який тип шарів? які параметри?
Шай,

1
@shai Я використовував декілька шарів InnerProduct (lr_mult 1, decay_mult 1, lr_mult 2, decay_mult 0, xavier, std: 0.01), за якими слідує ReLU (крім останнього). Я працював з MNIST, і якщо я добре пам’ятаю, архітектура була 784 -> 1000 -> 500 -> 250 -> 100 -> 30 (і фаза симетричного декодера); видалення шару 30 разом з його ReLU призвело до того, що NaN зник.
LKB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.