Дизайн архитектуры нейронной сети - программирование

Дизайн архитектуры нейронной сети

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

Я создал очень простой набор данных, состоящий из одной выпуклой области, как вы можете видеть ниже:

enter image description here

Все работает отлично, когда я использую архитектуру с L = 1 или L = 2 скрытых слоев (плюс выходной слой), но как только я добавляю третий скрытый слой (L = 3), моя производительность падает до слегка лучше шансов.

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

  • моя производительность в наборе обучения также составляет около 60% (тогда как переустановка обычно означает, что у вас очень низкая ошибка обучения и высокая ошибка теста),
  • и у меня очень много примеров данных (не смотрите на фигуру, что только игрушечная фигура, которую я uplaoded).

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

Вот изображение моего исполнения в зависимости от количества используемых слоев:

enter image description here

ДОБАВЛЕННАЯ ЧАСТЬ ИЗ КОММЕНТАРИЙ:

  • Я использую сигмоидные функции, принимающие значения от 0 до 1, L(s) = 1 / 1 + exp(-s)
  • Я использую раннюю остановку (после 40000 итераций backprop) как критерий, чтобы остановить обучение. Я знаю, что это не лучший способ остановиться, но я подумал, что это будет нормально для такой простой задачи классификации, если вы считаете, что это основная причина, по которой я не сходился. Я бы мог применить некоторые более качественные критерии.
4b9b3361

Ответ 1

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

Функции активации

Ваши нейроны активируются в соответствии с логистической сигмоидной функцией, f (x) = 1/(1 + e ^ -x):

sigmoid function

Эта функция активации используется часто, поскольку она имеет несколько приятных свойств. Одним из таких хороших свойств является то, что производная от f (x) выражаема в вычислительной форме, используя значение самой функции, поскольку f '(x) = f (x) (1 - f (x)). Эта функция имеет ненулевое значение для x вблизи нуля, но быстро переходит в ноль при | x | становится большим:

sigmoid first derivative

Градиентный спуск

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

delta_w(w) ~= w * f'(err(w)) * err(w)

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

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

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

Momentum

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

w_new = w_old - learning_rate * delta_w(w_old)

включают член импульса:

w_dir_new = mu * w_dir_old - learning_rate * delta_w(w_old)
w_new = w_old + w_dir_new

Интуитивно, вы хотите использовать информацию из прошлых производных, чтобы определить, хотите ли вы полностью следовать за новой производной (что вы можете сделать, установив mu = 0) или продолжить движение в направлении, в котором вы играли в предыдущем обновление, закаленное новой информацией о градиенте (путем установки mu > 0).

Вы можете получить еще лучше, чем это, используя "Ускоренный градиент Нестерова":

w_dir_new = mu * w_dir_old - learning_rate * delta_w(w_old + mu * w_dir_old)
w_new = w_old + w_dir_new

Я думаю, что идея заключается в том, что вместо вычисления производной по "старому" значению параметра w вычислите ее в качестве нового параметра для w, если вы перейдете туда и перейдете туда согласно стандартный импульсный член. Читайте больше в контексте нейронных сетей здесь (PDF).

Мешковина-Free

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

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

Подробнее об этом можно узнать, прочитав исследовательский документ (PDF) или просмотрев примерная реализация.

Другие

Существует много других методов оптимизации, которые могут быть полезны для этой задачи - сопряженный градиент (PDF - определенно стоит прочитать), < "Levenberg-Marquardt (PDF), L-BFGS - но из того, что я видел в исследовательской литературе, импульсы и методы, не содержащие гесса, являются наиболее распространенными.

Ответ 2

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