Куча советов и приемов для обучения глубоких нейронных сетей

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

А теперь давайте перейдем к делу ...

1). Прежде чем вы начнете строить свою сетевую архитектуру, первое, что вам нужно сделать, это проверить ваши входные данные в сети, если вход (x) соответствует метке (y). В случае плотного прогнозирования убедитесь, что метка наземной истинности (y) правильно закодирована для меток индексов (или одноразового кодирования). В противном случае обучение не сработает.

2). Решите, использовать ли предварительно обученную модель или обучать сеть с нуля?

  • Если ваш набор данных в вашей проблемной области похож на набор данных ImageNet, используйте предварительно обученную модель для этого набора данных. Наиболее широко используемыми предварительно обученными моделями являются VGG net, ResNet, DenseNet или Xception и т. Д. Существуют многоуровневые архитектуры, например, VGG (19 и 16 уровней), ResNet (152, 101, 50 слоев или меньше), DenseNet (201, 169 и 121 слой). Примечание: не пытайтесь искать гиперпараметры, используя больше сетей слоев (например, сеть слоев VGG-19, ResNet-152 или DenseNet-201, потому что это требует больших вычислительных ресурсов), вместо этого используйте сети с меньшим количеством слоев (например, слои VGG-16, ResNet-50 или DenseNet-121). Выберите одну предварительно обученную модель, которая, по вашему мнению, дает наилучшую производительность с вашими гиперпараметрами (скажем, уровни ResNet-50). После получения оптимальных гиперпараметров просто выберите ту же сеть, но с большим количеством слоев (скажем, ResNet-101 или ResNet-152), чтобы повысить точность.
  • Выполните точную настройку нескольких слоев или обучите классификатор только в том случае, если у вас небольшой набор данных, и вы также можете попытаться вставить выпадающие слои после сверточных слоев, которые вы собираетесь настроить, потому что это может помочь в борьбе с переобучением в вашей сети.
  • Если ваш набор данных не похож на набор данных ImageNet, вы можете подумать о создании и обучении вашей сети с нуля.

3). Всегда используйте уровни нормализации в своей сети. Если вы тренируете сеть с большим размером пакета (скажем, 10 или более), используйте слой BatchNormalization. В противном случае, если вы тренируетесь с небольшим размером пакета (скажем, 1), используйте вместо него слой InstanceNormalization. Обратите внимание, что основные авторы обнаружили, что BatchNormalization дает улучшение производительности, если они увеличивают размер пакета, и снижает производительность, когда размер пакета маленький. Однако InstanceNormalization дает небольшое улучшение производительности, если используется небольшой размер пакета. Или вы также можете попробовать GroupNormalization.

4). Используйте SpatialDropout после конкатенации объектов, если у вас есть два или более сверточных слоя (скажем Li), работающих с одним и тем же входом (скажем F ). Поскольку эти сверточные слои работают с одним и тем же входом, выходные функции, вероятно, будут коррелированы. Таким образом, SpatialDropout удаляет эти коррелированные функции и предотвращает переоснащение в сети. Примечание: чаще всего используется на нижних уровнях, а не на более высоких.

5). Чтобы определить пропускную способность вашей сети, попробуйте переоснастить вашу сеть с помощью небольшого набора обучающих примеров (примечание Андрея Карпати). Если он не подходит, увеличьте емкость вашей сети. После переобучения используйте методы регуляризации, такие как L1, L2, Dropout или другие методы для борьбы с переобучением.

6). Другой метод регуляризации - ограничение или ограничение веса вашей сети. Это также может помочь предотвратить проблему градиентного взрыва в вашей сети, поскольку веса всегда ограничены. В отличие от регуляризации L2, где вы штрафываете большие веса в своей функции потерь, это ограничение напрямую регулирует ваши веса. Вы можете легко установить ограничение веса в Keras:

7). Среднее вычитание из данных иногда дает действительно худшую производительность, особенно вычитание из полутоновых изображений (я лично столкнулся с этой проблемой в области сегментации переднего плана).

8). Всегда перемешивайте данные тренировки как перед тренировкой, так и во время тренировки, если вы не пользуетесь временными данными. Это может помочь улучшить производительность вашей сети.

9). Если ваша проблемная область связана с плотным прогнозированием (например, семантическая сегментация), я рекомендую вам использовать Расширенные остаточные сети в качестве предварительно обученной модели, поскольку она оптимизирован для плотного прогнозирования.

10). Для сбора контекстной информации об объектах используйте модуль объединения многомасштабных функций. Это может еще больше помочь повысить точность, и эта идея успешно используется в семантической сегментации или сегментации переднего плана.

11). Отключите недействительные метки (или неоднозначные области) из ваших вычислений потерь или точности, если таковые имеются. Это может помочь вашей сети более уверенно делать прогнозы.

12). Применяйте веса классов во время обучения, если у вас очень проблема с несбалансированными данными. Другими словами, придавайте больший вес редкому классу, но меньший вес главному классу. Веса классов можно легко вычислить с помощью sklearn. Или попробуйте передискретизировать свой обучающий набор, используя методы OverSampling и UnderSampling. Это также может помочь повысить точность вашего прогноза.

13). Выберите подходящий оптимизатор. Существует множество популярных адаптивных оптимизаторов, таких как Adam, Adagrad, Adadelta или RMSprop и т. Д. SGD + Momentum широко используется в различных проблемных областях. Следует учитывать две вещи: F во-первых, если вы заботитесь о быстрой сходимости, используйте адаптивные оптимизаторы, такие как Adam, но он может каким-то образом застрять в локальных минимумах и обеспечить плохое обобщение (рисунок ниже). Во-вторых, SGD + импульс можно достичь для нахождения глобальных минимумов, но он зависит от надежных инициализаций, и для схождения может потребоваться больше времени, чем у других адаптивных оптимизаторов (рисунок ниже). Я рекомендую вам использовать SGD + импульс, поскольку он имеет тенденцию достигать лучших оптимумов.

14). Есть три начальных точки скорости обучения, с которыми можно поиграть (т. е. 1e-1, 1e-3 и 1e-6). Если вы настраиваете предварительно обученную модель, учитывайте, что низкая скорость обучения составляет менее 1e-3 (скажем, 1e-4). Если вы тренируете свою сеть с нуля, рассмотрите скорость обучения больше или равную 1e-3. Вы можете попробовать эти отправные точки и настроить их, чтобы увидеть, какая из них работает лучше всего, выберите ту. Еще одна вещь, которую вы можете рассмотреть, чтобы замедлить скорость обучения по мере продвижения обучения, используя Планировщики скорости обучения. Это также может помочь улучшить производительность сети.

15). Помимо Графика скорости обучения, который снижает скорость обучения с течением времени, есть еще один способ, которым мы можем снизить скорость обучения на некоторые факторы (скажем, на 10). если потеря проверки перестает улучшаться в некоторые эпохи (скажем, 5), и остановить процесс обучения, если потеря проверки перестает улучшаться в некоторые эпохи ( скажем 10). Это легко сделать с помощью ReduceLROnPlateau с EarlyStopping в Keras.

16). Если вы работаете в области плотного прогнозирования, такой как сегментация переднего плана или семантическая сегментация, вы должны использовать пропускать соединения, поскольку границы объектов или полезная информация теряются из-за операций максимального объединения. или ступенчатые извилины. Это также может помочь вашей сети легко изучить отображение функций из пространства функций в пространство изображений, и это может помочь облегчить проблему исчезновения градиента в сети.

17). Больше данных - лучше умного алгоритма! Всегда используйте расширения данных, такие как горизонтальное отражение, вращение, масштабирование-обрезка и т. Д. Это может помочь повысить точность за счет больших полей.

18). У вас должен быть высокоскоростной графический процессор для обучения, но это немного дорого. Если вы хотите использовать бесплатный облачный GPU, я рекомендую использовать Google Colab. Если вы не знаете, с чего начать, посмотрите мой предыдущий пост или попробуйте различные облачные платформы GPU, такие как Floydhub или Paperspace и т. Д.

19). Используйте Max-pooling перед ReLU, чтобы сохранить некоторые вычисления. Поскольку для ReLU пороговые значения равны нулю: f(x)=max(0,x) и Максимальное количество пулов, только максимальное количество активаций: f(x)=max(x1,x2,...,xi), используйте Conv > MaxPool > ReLU, а не Conv > ReLU > MaxPool.

Например. Предположим, что у нас было две активации с Conv (т.е. 0,5 и -0,5):

  • so MaxPool > ReLU = max(0, max(0.5,-0.5)) = 0.5
  • и ReLU > MaxPool = max(max(0,0.5), max(0,-0.5)) = 0.5

Видеть? результат этих двух операций по-прежнему 0.5. В этом случае использование MaxPool > ReLU может сэкономить нам одну max операцию.

20). Рассмотрите возможность использования операции Свертка с разделением по глубине, которая является быстрой и значительно сокращает количество параметров по сравнению с обычной операцией свертки.

21). И последнее, но не менее важное: не сдавайтесь 💪. Поверьте, вы справитесь! Если вы все еще не достигли желаемой высокой точности, настройте гиперпараметры, сетевую архитектуру или обучающие данные, пока не получите желаемую точность 👏.

Заключительные слова…

Если вам понравился этот пост, не стесняйтесь хлопать в ладоши или поделиться им со всем миром. Если у вас есть вопросы, пишите в комментариях ниже. Вы можете связаться со мной в LinkedIn или подписаться на меня в Twitter. Хорошего дня.