Мы собрали здесь некоторые полезные советы, основанные на нашем опыте работы с TensorFlow. Некоторые из них могут быть полезны для вас, а некоторые — нет. Всё зависит от вашего опыта и контекста.
Для более глубокого изучения темы вы можете обратиться к следующим источникам:
1. Используйте Adam в качестве оптимизатора. Adam — это очень эффективный оптимизатор. Он должен быть вашим первым выбором по сравнению с другими оптимизаторами, такими как градиентный спуск. При использовании Adam в TensorFlow не забудьте установить Saver после настройки AdamOptimizer, так как Adam имеет некоторые состояния, которые также необходимо восстановить (например, скорость обучения каждого веса).
2. Используйте ReLu в качестве функции активации. ReLU работает быстро, просто и эффективно. У него нет проблемы исчезающего градиента, которая может возникнуть при использовании сигмовидной функции.
3. Не используйте функцию активации на выходном слое. Если вы используете функцию активации в каждом слое, легко забыть отключить её на выходном уровне.
4. Добавьте смещение (bias) в каждый слой. Смещение важно для преобразования плоскости в наилучшее положение. Например, y = mx + b, где b — это смещение, которое перемещает линию, чтобы найти наилучшую позицию.
5. Используйте инициализацию variance-scaled. В TensorFlow это делается через интерфейс tf.contrib.layers.variance_scaling_initializer(). На наш взгляд, этот метод лучше других распространённых методов инициализации, таких как Gaussian, truncated normal и Xavier. Обычно методы инициализации на основе отклонения масштабируются в соответствии с количеством нейронов на входном и выходном уровнях (по умолчанию количество нейронов во входном слое в TensorFlow). Это помогает сигналам проходить глубже в сеть без дополнительных «хаков», таких как обрезка или пакетная нормализация. Xavier похож на этот метод, но он работает только тогда, когда все слои имеют одинаковое отклонение. Однако в CNN разные слои часто имеют разные формы, и использование одинакового отклонения для всех слоёв может привести к проблемам.
6. Нормализуйте входные данные. Во время обучения вычтите среднее значение входных данных и разделите его на стандартное отклонение. Чем меньше угол расширения и распространения сети, тем легче и быстрее она обучается. Сохраняйте входные данные с нулевым средним значением и большим стандартным отклонением, чтобы помочь этому процессу. Для всех тестовых данных также требуется эта процедура, поэтому убедитесь, что ваши тренировочные данные похожи на реальные данные.
7. Масштабируйте входные данные в пределах их динамического диапазона. Эта операция связана с нормализацией, но должна выполняться перед ней. Например, если диапазон изменения данных X составляет [0, 14 000 000], они могут быть обучены функциями tanh(x) или tanh(x/c), где c — константа, расширяющая кривую, чтобы соответствовать динамическим характеристикам данных, то есть наклону функции tanh. Особенно если у ваших входных данных нет верхнего и нижнего пределов, нейронная сеть может лучше обучаться в диапазоне [0, 1].
8. Не изменяйте скорость обучения. Скорость обучения обычно уменьшается в SGD и автоматически регулируется в ADAM. Если вы хотите немного изменить скорость обучения, например, уменьшить её после определённого периода обучения, кривая ошибки может внезапно немного упасть, а затем быстро восстановиться.
9. Если вы используете свёрточные слои с 64 или 128 ядрами, этого достаточно. Особенно для глубоких сетей, 128 ядер уже достаточно. Увеличение количества ядер не приведёт к улучшению результатов.
10. Используйте pooling для сохранения инвариантности перевода. Pooling помогает сети обрабатывать определённые части изображения одинаково. Например, максимальный пул может помочь CNN справляться с изображениями, повёрнутыми, смещёнными или изменёнными по размеру, сохраняя при этом устойчивость.
Если ваша модель не обучается (то есть потери или точность не уменьшаются во время обучения или результаты не соответствуют ожиданиям), попробуйте следующие советы:
1. Переобучение. Если ваша модель переобучена, потери будут стремиться к нулю или точность будет близка к 100% или 99,99%. Если модель не может переобучаться, это может указывать на серьёзные проблемы в структуре сети, хотя они могут быть не очевидны. Если модель переобучается на небольшом наборе данных, но всё ещё не сходится на большом наборе данных, попробуйте следующее:
* **Уменьшите скорость обучения.** Модель будет обучаться медленнее, но может достичь меньшего локального минимума, который она не могла достичь раньше из-за слишком большого шага.
* **Увеличьте скорость обучения.** Это может ускорить обучение модели и помочь ей выйти из локального минимума. Хотя модель может быстро сойтись, результаты могут быть стабильными, то есть результаты разных тренировок могут сильно отличаться. (Мы обнаружили, что 0,001 — хорошая начальная скорость для Adam.)
* **Уменьшите размер мини-пакета.** Уменьшение размера пакета до 1 позволяет увидеть мельчайшие изменения в параметрах модели. Вы можете использовать Tensorboard (или другие инструменты отладки/визуализации), чтобы определить, есть ли проблема с обновлением градиента.
* **Исключите batch normalization.** Когда вы уменьшаете размер пакета до 1, BN может помочь вам обнаружить проблемы с градиентом взрыва или исчезновения. Однажды мы столкнулись с моделью, которая не сходилась, и только после удаления BN мы обнаружили, что входные данные во втором раунде стали NaN. BN — это полезная функция, но она эффективна только тогда, когда вы уверены, что в вашей модели нет других проблем.
* **Увеличьте размер мини-пакета.** Увеличение размера пакета необходимо, поскольку больший размер пакета может уменьшить дисперсию обновления градиента и сделать каждое обновление градиента более точным. Другими словами, обновление градиента будет двигаться в правильном направлении. Однако мы не можем бесконечно увеличивать размер пакета, потому что физическая память компьютера ограничена. Мы обнаружили, что это более важно, чем два предыдущих совета (уменьшение размера партии и исключение BN).
* **Проверьте свои операции изменения формы.** Частые операции изменения формы (например, изменение размеров изображений X и Y) могут нарушить локальные пространственные особенности CNN, делая обучение практически невозможным, поскольку они должны изучать неправильную форму. Будьте особенно осторожны при выполнении нескольких операций изменения формы над изображениями/каналами и используйте numpy.stack() для правильного выравнивания.
* **Следите за изменениями функции потерь.** Если используется сложная функция в качестве целевой функции, рассмотрите возможность использования L1 или L2 ограничений для упрощения. Мы обнаружили, что L1 менее чувствителен к границам и менее подвержен влиянию зашумлённых тренировочных данных.
* **Визуализируйте обучение вашей модели как можно больше.** Если у вас есть инструменты визуализации, такие как matplotlib, OpenCV или Tensorboard, визуализируйте изменения масштаба, отсечения и т. д. в сети и убедитесь, что стратегии окрашивания для различных параметров согласованы.
Чтобы помочь вам понять приведённые выше советы, мы построили CNN и предоставили графики потерь, созданные с помощью TensorBoard.
Во-первых, модель вообще не обучалась:
Затем мы попытались обрезать значения, чтобы они не превышали фиксированных границ, и получили следующий результат:
Однако кривая потерь всё ещё недостаточно гладкая. Может быть, скорость обучения всё ещё слишком велика? Мы также попытались уменьшить скорость обучения и использовать один образец для обучения:
Можно видеть, что примерно после 300 и 3000 шагов... Этапы: изучение скорости изменения. Очевидно, что скорость обучения снижается слишком быстро. Поэтому необходимо увеличить интервал времени между каждым снижением скорости обучения, чтобы получить лучший результат:
Можно заметить, что на этапах 2000 и 5000 происходит снижение скорости обучения (decay), что приводит к улучшению результата, но он не идеален, и потери не снижаются до нуля.
Далее мы исключаем стратегию снижения скорости обучения LR, пропускаем входные данные через функцию tanh и сжимаем диапазон максимальных и минимальных значений входных данных до меньшего диапазона. Хотя очевидно, что эта операция может привести к некоторым ошибкам для значений меньше 1, мы не смогли достичь цели переобучения.
На практике мы обнаружили, что после удаления BN сеть выдаёт значения NaN уже через 1–2 итерации. Мы удалили BN и добавили ограничение на дисперсию параметров (variance scaling). Это привело к значительным изменениям в результатах. Модель наконец-то переобучилась для нескольких входных тренировочных образцов. Несмотря на то, что значение ошибки превысило 5, конечное значение ошибки уменьшилось на 4 порядка.
Кривая потерь на этом графике очень гладкая, и можно увидеть, что она переобучена на тестовых данных, а кривая потерь на обучающих данных только снизилась до 0,01. Это связано с тем, что не было применено снижение скорости обучения, поэтому потери не могли быть уменьшены. Затем мы снизили скорость обучения на порядок и получили лучшие результаты:
Результаты улучшились! Но что, если бы мы просто снижали скорость обучения без разделения тренировки на две части?
Если мы умножаем скорость обучения на коэффициент затухания 0,9995 для каждого шага, результаты не так хороши:
Это может быть связано со слишком быстрым затуханием. Поэтому мы изменили коэффициент затухания на 0,999995, и результаты стали немного лучше, но конечный результат в основном такой же, и потери больше не уменьшаются. Из этих экспериментов мы предполагаем, что это может быть связано с тем, что BN скрывает проблему взрыва градиента, вызванную плохой инициализацией параметров. Кроме того, для оптимизатора Adam снижение скорости обучения не приносит большой пользы, за исключением преднамеренного снижения в конце тренировки. При использовании BN сокращение весов только скрывает реальную проблему. Мы также можем использовать tanh для обработки входных данных с высокой дисперсией.
Мы надеемся, что эти советы помогут вам освоить некоторые основные методы построения глубоких нейронных сетей. Часто простые операции могут привести к огромным различиям.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )