- BrainTools - https://www.braintools.ru -
Привет, это моя первая статья на Хабре. И я хочу рассказать вам о проблеме, на решение которой когда-то давно у меня ушло довольно много времени.
Часто бывает, что при обучении [1] (или тестировании) модели нейронной сети (NN) функция потерь (loss) возвращает значение NaN (Not a Number). Это приводит к тому, что фаза обучения “срывается”. Обычно неясно, почему это происходит. Я расскажу вам о возможных причинах и рекомендациях по решению этой проблемы.
Существует две основные проблемы с градиентами на этапе обучения: исчезновение (vanishing) и взрыв (explosion) градиент. Первая описана в этих статьях:[1] [2] [2] [3]. Вторая будет рассмотрена здесь. Напомню, что при обратном распространении ошибки [4] оптимизатор распространяет градиенты от последнего слоя к первому (хорошо описано в книге Тарика Рашида «Создаем нейронную сеть»). С помощью глубокой NN значения градиентов можно значительно увеличить (или уменьшить). Поэтому абсолютные значения становятся inf или NaN. Итак, есть несколько рекомендаций:
Уменьшите начальную скорость обучения или/и используйте планировщик скорости обучения [5].
Нормирование градиентов (clip)
# loss.backprop()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm= C)
# optimizer.step()
Этот метод позволяет ограничить градиенты в диапазоне [-C..C].
3. Измените архитектуру текущей модели (количество слоев, голов, нейронов и т.д.) или используйте другую модель.
Некоторые слои могут выдавать NaN для определенных входных данных. Например, слой нормализации использует деление на норму вектора x
Но что, если заданный вектор x равен нулю, тогда и его норма. Это приводит к делению на ноль, следовательно, . Очевидное решение – добавить небольшое ненулевое число (например, 10e-7) в знаменатель.
В популярных фреймворках слои нормализации (обычно) уже используют это небольшое число, но лучше убедиться в этом, чтобы избежать такого случая.
Оптимизатор вычисляет производные функций потерь и слоев NN при обратном распространении. Рассмотрим слой standard-deviation-pooling, описанный здесь [6]. Стандартное отклонение некоторого вектора x:
Давайте продифференцируем эту функцию по х:
Поэтому нам нужно нарушить уравнение (*). Самое простое решение – добавить к небольшое число
.
Давайте разберемся с средней абсолютной ошибкой (mean absolute error – MAE).
Итак, как показано выше, если любое из предсказанных моделью значений равно целевому значению y^, производная функции потерь возвращает NaN. Вы можете заметить, что этот случай довольно редкий, но я думаю, что он все равно заслуживает вашего внимания [7] :-)
Мы рассмотрели несколько случаев, когда функция потерь становится NaN. В вашем пайплайне обучения вы можете проверять выход NN, градиенты и значение функции потерь, являются ли они NaN. Это позволит вашему алгоритму прервать цикл обучения и исправить ошибку.
Автор: kochetkover
Источник [8]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/14200
URLs in this post:
[1] обучении: http://www.braintools.ru/article/5125
[2] [1]: https://www.ultralytics.com/ru/glossary/vanishing-gradient
[3] [2]: https://habr.com/ru/articles/462381/
[4] ошибки: http://www.braintools.ru/article/4192
[5] планировщик скорости обучения: https://neptune.ai/blog/how-to-choose-a-learning-rate-scheduler
[6] здесь: https://arxiv.org/pdf/2105.04310v1.pdf
[7] внимания: http://www.braintools.ru/article/7595
[8] Источник: https://habr.com/ru/articles/900460/?utm_campaign=900460&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.