Что мне делать, если моя нейронная сеть не учится?

148

Я тренирую нейронную сеть, но потери от тренировок не уменьшаются. Как я могу это исправить?

Я не спрашиваю о переоснащении или регуляризации. Я спрашиваю, как решить проблему, когда производительность моей сети не улучшается на тренировочном наборе .


Этот вопрос намеренно носит общий характер, поэтому другие вопросы о том, как обучить нейронную сеть, могут быть закрыты как дубликат этого, с отношением: «если вы даете человеку рыбу, вы кормите его в течение дня, но если вы учите человек ловить рыбу, вы можете кормить его до конца своей жизни. " См. Эту мета-ветку для обсуждения: как лучше ответить на вопросы «моя нейронная сеть не работает, пожалуйста, исправьте» вопросы?

Если ваша нейронная сеть плохо обобщается, см .: Что мне делать, если моя нейронная сеть плохо обобщается?

Sycorax
источник
1
Вот случай, когда NN не может прогрессировать. youtu.be/iakFfOmanJU?t=144
Джошуа
4
Блог Иванова « Причины, по которым ваша нейронная сеть не работает », особенно разделы II, III и IV, может оказаться полезным.
user5228

Ответы:

187

Модульное тестирование - твой друг

Среди писателей есть поговорка: «Все письма переписывают», то есть большая часть написания пересматривается. Для программистов (или, по крайней мере, исследователей данных) выражение можно перефразировать как «Все кодирование отлаживается».

Каждый раз, когда вы пишете код, вы должны убедиться, что он работает как задумано. Лучший метод проверки правильности, который я когда-либо нашел, - разбить ваш код на маленькие сегменты и убедиться, что каждый сегмент работает. Это можно сделать, сравнив вывод сегмента с тем, что, как вы знаете, является правильным ответом. Это называется модульным тестированием . Написание хороших модульных тестов является ключевым моментом для того, чтобы стать хорошим статистиком / специалистом по данным / специалистом по машинному обучению / практиком нейронных сетей. Там просто нет замены.

Вы должны проверить, что ваш код не содержит ошибок, прежде чем вы сможете настроить производительность сети! В противном случае, вы также можете переставить шезлонги на RMS Titanic .

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

  1. Нейронные сети не являются «готовыми» алгоритмами, как случайный лес или логистическая регрессия. Даже для простых сетей с прямой связью пользователь в основном принимает решения о том, как сеть будет настроена, подключена, инициализирована и оптимизирована. Это означает написание кода, а написание кода означает отладку.

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

В этой публикации среднего уровня « Как проводить модульное тестирование кода машинного обучения » Чейз Робертс более подробно рассматривается модульное тестирование для моделей машинного обучения. Я взял этот пример с ошибочным кодом из статьи:

def make_convnet(input_image):
    net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
    net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool2')
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool3')
    net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
    return net

Вы видите ошибку? Многие из различных операций фактически не используются, потому что предыдущие результаты перезаписываются новыми переменными. Использование этого блока кода в сети все еще будет тренироваться, а весы будут обновляться, и потери могут даже уменьшиться - но код определенно не выполняет то, что предполагалось. (Автор также не согласен с использованием одинарных или двойных кавычек, но это чисто стилистически.)

Наиболее распространенные ошибки программирования, относящиеся к нейронным сетям:

  • Переменные создаются, но никогда не используются (обычно из-за ошибок копирования-вставки);
  • Выражения для градиентных обновлений неверны;
  • Обновления веса не применяются;
  • Функции потерь не измеряются по правильной шкале (например, потеря кросс-энтропии может быть выражена через вероятность или логиты)
  • Потеря не подходит для задачи (например, использование категориальной кросс-энтропийной потери для регрессионной задачи).

Ползти, прежде чем идти; Иди, прежде чем бежать

Широкие и глубокие нейронные сети и нейронные сети с экзотической проводкой - вот что сейчас важно для машинного обучения. Но эти сети не возникли полностью сформированными; их дизайнеры создавали их из небольших подразделений. Сначала создайте небольшую сеть с одним скрытым слоем и убедитесь, что она работает правильно. Затем постепенно добавляйте дополнительную сложность модели и проверяйте, что каждая из них также работает.

  • Слишком мало нейронов в слое может ограничить представление, которое изучает сеть, вызывая недопоставку. Слишком много нейронов может вызвать перенапряжение, потому что сеть «запомнит» данные обучения.

    Даже если вы можете доказать, что математически существует только небольшое количество нейронов, необходимых для моделирования проблемы, часто бывает так, что наличие «еще нескольких» нейронов облегчает оптимизатору поиск «хорошей» конфигурации. (Но я не думаю, что кто-то полностью понимает, почему это так.) Я привожу пример этого в контексте проблемы XOR: не нужны ли мои итерации для обучения NN для XOR с MSE <0,001 слишком высоким? ,

  • Выбор количества скрытых слоев позволяет сети изучать абстракцию из необработанных данных. Глубокое обучение в моде в наши дни, и сети с большим количеством уровней показали впечатляющие результаты. Но добавление слишком большого количества скрытых слоев может привести к перерасходу или усложнить оптимизацию сети.

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

Обучение нейронной сети похоже на взлом замков

Чтобы достичь современных или даже просто хороших результатов, вам необходимо настроить все части, настроенные для совместной работы . Настройка конфигурации нейронной сети, которая на самом деле запоминается, очень похожа на взлом блокировки: все части должны быть выстроены правильно. Точно так же, как недостаточно располагать один тумблер в нужном месте, так и недостаточно правильно настроить только архитектуру или только оптимизатор.

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

Это не полный список параметров конфигурации, которые не являются также параметрами регуляризации или числовой оптимизации.

Все эти темы являются активными областями исследований.

Невыпуклая оптимизация трудна

Целевая функция нейронной сети является выпуклой только тогда, когда нет скрытых единиц, все активации являются линейными, а матрица проектирования является полноценной - потому что эта конфигурация идентична обычной задаче регрессии.

Во всех остальных случаях задача оптимизации невыпуклая, а невыпуклая оптимизация трудна. Проблемы обучения нейронных сетей общеизвестны (см. Почему трудно обучать глубокие нейронные сети? ). Кроме того, нейронные сети имеют очень большое количество параметров, что ограничивает нас только методами первого порядка (см .: Почему метод Ньютона не широко используется в машинном обучении? ). Это очень активная область исследований.

  • Установка слишком высокой скорости обучения приведет к расхождению оптимизации, потому что вы перепрыгнете с одной стороны «каньона» на другую. Слишком малое значение этого параметра не позволит вам добиться реального прогресса и, возможно, позволит шуму, присущему SGD, превзойти ваши оценки градиента.

  • Ограничение градиента изменяет масштаб градиента, если оно превышает некоторый порог. Раньше я думал, что это был параметр «установил и забыл», обычно на уровне 1,0, но я обнаружил, что могу значительно улучшить языковую модель LSTM, установив ее на 0,25. Я не знаю, почему это так.

  • Планирование скорости обучения может снизить скорость обучения в течение обучения. По моему опыту, попытка использовать планирование очень похожа на регулярное выражение : она заменяет одну проблему («Как я могу продолжить обучение после определенной эпохи?») На две проблемы («Как я могу продолжить обучение после определенной эпохи» ? »и« Как выбрать хороший график? »). Другие люди настаивают на том, что планирование важно. Я позволю тебе решить.

  • Выбор хорошего размера мини-партии может косвенно влиять на процесс обучения, поскольку большая мини-партия будет иметь тенденцию иметь меньшую дисперсию ( ), чем меньшая мини-партия. Вы хотите, чтобы мини-пакет был достаточно большим, чтобы иметь представление о направлении градиента, но достаточно маленьким, чтобы SGD мог регулировать вашу сеть.

  • Существует несколько вариантов стохастического градиентного спуска, в которых используется импульс, адаптивные скорости обучения, обновления Нестерова и т. Д. Для улучшения ванильной SGD. Разработка лучшего оптимизатора - очень активная область исследований. Некоторые примеры:

  • Когда он впервые появился, оптимизатор Adam вызвал большой интерес. Но некоторые недавние исследования показали, что SGD с импульсом может превзойти методы адаптивного градиента для нейронных сетей. « Предельная ценность адаптивных градиентных методов в машинном обучении » Ашиа Уилсон, Ребекка Рулофс, Митчелл Стерн, Натан Сребро, Бенджамин Рехт

  • Но с другой стороны, в этой самой недавней статье предлагается новый адаптивный оптимизатор скорости обучения, который предположительно закрывает разрыв между методами адаптивной скорости и SGD с импульсом. « Устранение пробела в обобщении адаптивных градиентных методов в обучении глубоких нейронных сетей », Цзинхуэй Чен, Цюаньцюань Гу

    Обнаружено, что методы адаптивного градиента, которые принимают историческую информацию о градиенте для автоматической настройки скорости обучения, обобщают хуже, чем стохастический градиентный спуск (SGD) с импульсом в обучении глубоких нейронных сетей. Это оставляет, как закрыть разрыв обобщения адаптивных градиентных методов открытой проблемой. В этой работе мы покажем, что методы адаптивного градиента, такие как Адам, Амсград, иногда «чрезмерно адаптированы». Мы разрабатываем новый алгоритм, называемый частично адаптивным методом оценки импульса (Padam), который объединяет Адама / Амстердама с SGD для достижения лучшего из обоих миров. Эксперименты на стандартных тестах показывают, что Padam может поддерживать высокую скорость сходимости как Adam / Amsgrad, в то же время обобщая, а также SGD при обучении глубоких нейронных сетей.

нормализация

Масштаб данных может иметь большое значение при обучении.

регуляризация

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

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

Эта тактика может точно определить, где какая-то регуляризация может быть плохо установлена. Некоторые примеры

Вести журнал экспериментов

Когда я настраиваю нейронную сеть, я не жестко программирую настройки параметров. Вместо этого я делаю это в файле конфигурации (например, JSON), который читается и используется для заполнения деталей конфигурации сети во время выполнения. Я храню все эти файлы конфигурации. Если я делаю какие-либо изменения параметров, я делаю новый файл конфигурации. Наконец, я добавляю в качестве комментариев все потери за эпоху для обучения и проверки.

Причина, по которой я так одержим сохранением старых результатов, заключается в том, что это позволяет очень легко вернуться и просмотреть предыдущие эксперименты. Это также препятствует ошибочному повторению того же тупикового эксперимента. Психологически это также позволяет вам оглянуться назад и наблюдать: «Ну, проект может быть не там, где я хочу, чтобы он был сегодня, но я делаю успехи по сравнению с тем, где я был недель назад».k

В качестве примера я хотел узнать о языковых моделях LSTM, поэтому я решил создать бота в Twitter, который будет писать новые твиты в ответ другим пользователям Twitter. Я работал над этим в свое свободное время, между аспирантурой и моей работой. Это заняло около года, и я перебрал около 150 различных моделей, прежде чем перейти к модели, которая сделала то, что я хотел: создать новый англоязычный текст, который (вроде бы) имеет смысл. (Одним из ключевых препятствий и одной из причин того, что потребовалось так много попыток, было то, что было недостаточно просто получить низкую потерю выборки, так как ранним моделям с малыми потерями удалось запомнить тренировочные данные, поэтому он просто воспроизводил германские текстовые блоки в ответ на подсказки - потребовалось некоторое изменение, чтобы сделать модель более спонтанной и при этом иметь низкие потери.)

Sycorax
источник
11
Там много полезных советов. Интересно, сколько ваших комментариев похоже на комментарии, которые я сделал (или видел, как другие), в отношении отладки оценки параметров или прогнозов для сложных моделей со схемами выборки MCMC. (Например, может показаться, что код работает, если он неправильно реализован.)
Glen_b
11
@Glen_b Я не думаю, что лучшие практики кодирования получают достаточный акцент в большинстве учебных программ по статистике и машинному обучению, поэтому я так подчеркивал этот момент. Я видел несколько сообщений NN, где OP оставил комментарий типа «о, я нашел ошибку, теперь она работает».
Sycorax
7
Я преподаю курс программирования для данных в Python, и мы фактически выполняем функции и модульное тестирование в первый день как основные понятия. Борьба хороший бой.
Мэтью Друри
8
+1 за «Все кодирование отлаживается». Я поражен тем, сколько плакатов на SO, кажется, считают, что кодирование - это простое упражнение, требующее небольших усилий; кто ожидает, что их код будет работать правильно при первом запуске; и кто, кажется, не может продолжать, когда это не так. Самое смешное, что они наполовину правы: кодирование является легко - но программирование трудно.
Боб Джарвис
41

Размещенные ответы великолепны, и я хотел добавить несколько «проверок здравомыслия», которые очень помогли мне в прошлом.

1) Тренируйте свою модель на одной точке данных. Если это работает, обучите его двум входам с разными выходами.

Это подтверждает несколько вещей. Во-первых, он быстро показывает, что ваша модель способна учиться, проверяя, может ли ваша модель соответствовать вашим данным. В моем случае я постоянно делаю глупые ошибки, делая Dense(1,activation='softmax')против Dense(1,activation='sigmoid')двоичных предсказаний, и первый дает результаты с мусором.

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

2) Обратите внимание на вашу первоначальную потерю.

Продолжая бинарный пример, если ваши данные равны 30% 0 и 70% 1, то ваши начальные ожидаемые потери составляют около . Это потому, что ваша модель должна начинаться со случайного угадывания.L=0.3ln(0.5)0.7ln(0.5)0.7

Много раз вы увидите первоначальную потерю чего-то смешного, например, 6,5. Концептуально это означает, что ваша продукция сильно насыщена, например, к 0. Например, , поэтому, если вы видите убыток, который больше 1, вероятно, ваш модель очень перекошена. Это обычно происходит, когда веса вашей нейронной сети не сбалансированы должным образом, особенно ближе к softmax / сигмоид. Так что это скажет вам, если ваша инициализация плохая.0.3ln(0.99)0.7ln(0.01)=3.2

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

3) Обобщите ваши выходные данные модели для отладки

В качестве примера представьте, что вы используете LSTM для прогнозирования на основе данных временных рядов. Возможно, в вашем примере вы заботитесь только о самом последнем прогнозе, поэтому ваш LSTM выдает одно значение, а не последовательность. Переключите LSTM для возврата прогнозов на каждом шаге (в керасе это так return_sequences=True). Затем вы можете посмотреть на выходы скрытого состояния после каждого шага и убедиться, что они действительно разные. Применение этого состоит в том, чтобы убедиться, что когда вы маскируете свои последовательности (т.е. заполняете их данными, чтобы сделать их равными по длине), LSTM правильно игнорирует ваши замаскированные данные. Без обобщения вашей модели вы никогда не найдете эту проблему .

4) Посмотрите на отдельные слои

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

5) Сначала создайте более простую модель

Вы решили, что лучший подход для решения вашей проблемы - это использование CNN в сочетании с детектором ограничивающего прямоугольника, который дополнительно обрабатывает кадрированные изображения, а затем использует LSTM для объединения всего. Инициализация вашей модели занимает всего 10 минут.

Вместо этого создайте пакет поддельных данных (той же формы) и разбейте вашу модель на компоненты. Затем сделайте фиктивные модели на месте каждого компонента (ваша «CNN» может быть просто 20x-шаговой сверткой 2x2, LSTM с двумя скрытыми единицами). Это поможет вам убедиться в правильности структуры вашей модели и отсутствии посторонних проблем. Некоторое время я боролся с такой моделью, и когда я попробовал более простую версию, я обнаружил, что один из слоев не маскировался должным образом из-за ошибки в keras. Вы можете легко (и быстро ) запросить внутренние слои модели и посмотреть, правильно ли вы настроили свой график.

6) Стандартизируйте свои версии предварительной обработки и пакета

В частности, нейронные сети чрезвычайно чувствительны к небольшим изменениям в ваших данных. Например, два популярных пакета загрузки изображений: cv2и PIL. Просто благодаря открытию JPEG оба этих пакета будут создавать немного разные изображения. Различия, как правило, очень малы, но из-за такого рода вещей вы время от времени будете наблюдать снижение производительности модели. Кроме того, это делает отладку кошмаром: во время обучения вы получаете балл проверки, а затем вы используете другой загрузчик и получаете разную точность для одного и того же набора данных.

Поэтому, если вы скачиваете чью-то модель с github, обратите пристальное внимание на их предварительную обработку. Какие загрузчики изображений они используют? Какие процедуры предварительной обработки изображений они используют? При изменении размера изображения какую интерполяцию они используют? Они сначала изменяют размер, а затем нормализуют изображение? Или наоборот? Каков порядок каналов для изображений RGB?

Самый безопасный способ стандартизации пакетов - это использовать requirements.txtфайл, в котором изложены все ваши пакеты, как и при настройке системы обучения, вплоть до keras==2.1.5номеров версий. Теоретически, использование Docker вместе с тем же графическим процессором, что и в вашей тренировочной системе, должно давать те же результаты.

Алекс Р.
источник
7
(+1) Проверка первоначальной потери - отличное предложение. Я сожалею, что я оставил это вне своего ответа.
Sycorax
7
Удостовериться, что ваша модель может подойти - отличная идея. Я настолько привык думать о переоснащении как о слабости, что никогда не думал явно (пока вы не упомянули об этом), что способность переоснащаться на самом деле является сильной стороной.
Джон Коулман
15

Не тренируйте нейронную сеть для начала!

Все ответы великолепны, но есть один момент, который следует упомянуть: есть ли чему поучиться из ваших данных? (что можно рассматривать как какое-то тестирование).

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

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

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

RUser4512
источник
5
Я согласен с этим ответом. Нейронные сети и другие формы ML "так жарко сейчас". Часто более простые формы регрессии упускаются из виду. Кроме того, когда дело доходит до объяснения вашей модели, кто-то придет и спросит "как влияет на результат?" и все, что вы сможете сделать, это пожать плечами. Обращайтесь к решениям по машинному обучению только тогда, когда более простые методы не сработали. xk
Инголифс
11

По своей сути, основной рабочий процесс для обучения модели NN / DNN более или менее всегда одинаков:

  1. определить архитектуру NN (сколько уровней, какие уровни, соединения между уровнями, функции активации и т. д.)

  2. читать данные из какого-либо источника (Интернет, база данных, набор локальных файлов и т. д.), просматривать несколько примеров (чтобы убедиться, что импорт прошел успешно) и выполнять очистку данных, если / когда это необходимо. Этот шаг не так тривиален, как обычно думают люди. Причина в том, что для DNN мы обычно имеем дело с гигантскими наборами данных, которые на несколько порядков больше, чем те, к которым мы привыкли, когда мы подгоняем более стандартные нелинейные параметрические статистические модели (теоретически NN принадлежат этому семейству).

  3. нормализовать или стандартизировать данные в некотором роде. Поскольку NN являются нелинейными моделями, нормализация данных может влиять не только на числовую стабильность, но также на время обучения и выходные данные NN (линейная функция, такая как нормализация, не коммутирует с нелинейной иерархической функцией).

  4. разделить данные в обучающем / проверочном / тестовом наборе или в несколько раз, если используется перекрестная проверка.

  5. обучать нейронную сеть, в то же время контролируя потери в проверочном наборе. Здесь вы можете насладиться душераздирающими удовольствиями от невыпуклой оптимизации, когда вы не знаете, существует ли какое-либо решение, существует ли несколько решений, что является наилучшим решением с точки зрения ошибки обобщения и насколько близко вы подошли к Это. Разумеется, сравнение между тренировочной потерей и кривой потерь при проверке направляет вас, но не стоит недооценивать жесткое отношение NN (и особенно DNN): они часто показывают (возможно, медленно) уменьшающиеся потери при обучении / проверке, даже если у вас есть наносящие вред ошибки в вашем коде.

  6. Проверьте точность на тестовом наборе и составьте несколько диагностических графиков / таблиц.

  7. Вернитесь к пункту 1, потому что результаты не очень хорошие. Повторите до тошноты .

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

Проверка базовой архитектуры

Это может быть источником проблем. Обычно я делаю эти предварительные проверки:

  • ищите простую архитектуру, которая хорошо работает для вашей проблемы (например, MobileNetV2 в случае классификации изображений) и применяйте подходящую инициализацию (на этом уровне обычно подходит случайная). Если это правильно работает с вашими данными, по крайней мере, вы знаете, что в наборе данных нет явных проблем. Если вы не можете найти простую, проверенную архитектуру, которая работает в вашем случае, подумайте о простой базовой линии . Например, наивный байесовский классификатор для классификации (или даже просто классификация всегда самого распространенного класса) или модель ARIMA для прогнозирования временных рядов

  • Сборка юнит-тестов. Пренебрежение этим (и использование кровавого Jupyter Notebook) обычно являются основными причинами проблем в коде NN, которые я просил проанализировать, особенно когда модель предполагается развернуть в рабочей среде. Поскольку наиболее часто задаваемый ответ уже охватывал модульные тесты, я просто добавлю, что существует библиотека, которая поддерживает разработку модульных тестов для NN (к сожалению, только в Tensorflow).

Обучающий набор

Дважды проверьте ваши входные данные. Посмотрите, например, перевернули ли вы учебный набор и ярлыки тестового набора (случалось со мной однажды -___-) или вы импортировали неправильный файл. Посмотрите на несколько входных сэмплов и связанные с ними метки и убедитесь, что они имеют смысл. Убедитесь, что нормализованные данные действительно нормализованы (посмотрите на их диапазон). Кроме того, реальные наборы данных являются грязными: для классификации может быть высокий уровень шума меток (выборки с неправильной меткой класса) или для прогноза многомерного временного ряда, некоторые компоненты временных рядов могут иметь много пропущенных данных ( Я видел цифры до 94% для некоторых входов).

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

Наконец, лучший способ проверить, есть ли у вас проблемы с тренировочным набором, - это использовать другой тренировочный набор. Если вы выполняете классификацию изображений, а не собранных изображений, используйте стандартный набор данных, такой как CIFAR10 или CIFAR100 (или ImageNet, если вы можете позволить себе обучаться этому). Эти наборы данных хорошо проверены: если ваши потери в обучении уменьшаются здесь, но не в исходном наборе данных, у вас могут быть проблемы в наборе данных.

Сделать золотые тесты

Есть два теста, которые я называю Золотые тесты, которые очень полезны для поиска проблем в NN, который не обучается:

  • уменьшите тренировочный набор до 1 или 2 образцов, и тренируйтесь на этом. NN должен немедленно перевооружиться на тренировочный набор, очень быстро достигнув точности 100% на тренировочном наборе, в то время как точность на проверочном / тестовом наборе достигнет 0%. Если этого не происходит, в вашем коде есть ошибка.

  • обратный тест: вы сохраняете полный тренировочный набор, но перемешиваете метки. Единственный способ, которым NN может учиться сейчас, - это запоминание тренировочного набора, что означает, что потеря тренировки будет уменьшаться очень медленно, тогда как потеря теста будет увеличиваться очень быстро. В частности, вы должны достичь случайной потери на тестовом наборе . Это означает, что если у вас есть 1000 классов, вы должны достичь точности 0,1%. Если вы не видите никакой разницы между потерей обучения до и после перестановки меток, это означает, что ваш код содержит ошибки (помните, что мы уже проверили метки набора обучения в предыдущем шаге).

Убедитесь, что ваша метрика обучения имеет смысл

Точность (потеря 0-1) - дерьмовый показатель, если у вас сильный дисбаланс классов. Попробуйте что-то более значимое, например, потерю кросс-энтропии: вы не просто хотите правильно классифицировать, но вы хотите классифицировать с высокой точностью.

Выведи большие пушки

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

  • попробуйте разные оптимизаторы: SGD тренируется медленнее, но это приводит к меньшей ошибке обобщения, в то время как Адам тренируется быстрее, но тестовые потери приводят к более высокому значению
  • попробуйте уменьшить размер партии
  • сначала увеличьте скорость обучения, а затем уменьшите ее или используйте циклическую скорость обучения
  • добавить слои
  • добавить скрытые юниты
  • постепенно удаляйте регуляризацию (возможно, переключите пакетную норму на несколько слоев). Потеря тренировки теперь должна уменьшиться, но потеря теста может увеличиться.
  • визуализировать распределение весов и уклонов для каждого слоя. Мне никогда не приходилось добираться сюда, но если вы используете BatchNorm, вы ожидаете примерно стандартных нормальных дистрибутивов. Посмотрите, увеличивается ли норма весов ненормально с эпохами.
  • если вы получаете какую-то ошибку во время обучения, Google эту ошибку . Однажды утром я потратил впустую, пытаясь исправить идеально работающую архитектуру, но обнаружил, что версия Keras, которую я установил, имела ошибочную поддержку нескольких графических процессоров, и мне пришлось обновить ее. Иногда мне приходилось делать обратное (понизить версию пакета).
  • обновите свое резюме и начните искать другую работу :-)
DeltaIV
источник
+1, но "кровавый ноутбук Юпитер"? Хотите прокомментировать это? :)
амеба
2
Вот почему я ненавижу ноутбуки Jupyter . TL; DR: скрытое состояние, различие - это боль, проблемы безопасности, и это поощряет плохие методы программирования, такие как неиспользование юнит-регрессионных / интеграционных тестов. Обучение NNs уже достаточно сложно, и люди не забывают об основах программирования.
DeltaIV
2
Возможно, я слишком негативен, но, честно говоря, мне было достаточно с людьми, клонирующими Jupyter Notebooks из GitHub, думая, что это будет считаться минутами, чтобы адаптировать код к их случаю использования, а затем придет ко мне с жалобой, что ничего не работает. Ради всего святого, возьмите настоящий IDE, такой как PyCharm или VisualStudio Code, и создайте хорошо структурированный код, а не готовьте Notebook! Особенно, если вы планируете отправлять модель в производство, это будет намного проще.
DeltaIV
2
Лол. «Блокнот Jupyter» и «модульное тестирование» не связаны между собой.
Sycorax
2
(+1) Это хорошая рецензия. Предложения для рандомизированных тестов - действительно отличные способы попасть в сети с ошибками.
Sycorax
6

Если модель не обучается, есть хороший шанс, что обратное распространение не работает. Но есть много вещей, которые могут пойти не так с моделью черного ящика, как нейронная сеть, есть много вещей, которые вам нужно проверить. Я думаю, что Sycorax и Alex оба дают очень хорошие исчерпывающие ответы. Просто хочу добавить, что один метод еще не обсуждался.

В Курсе машинного обучения Эндрю Нга он предлагает запустить проверку градиента в первые несколько итераций, чтобы убедиться, что обратное распространение работает правильно. По сути, идея состоит в том, чтобы вычислить производную, определив две точки с интервалом . Убедиться, что производная приблизительно соответствует вашему результату обратного распространения, должно помочь определить причину проблемы.ϵ

Энтони Лей
источник