Файл: 5 тарау. Кп абатты перцептрондар.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 22.11.2023

Просмотров: 130

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
2 или h5, и их соответствующий градиент также исчезает при выполнении обратного распространения. Таким образом, расчет выходного слоя не может чрезмерно зависеть от какого-либо одного элемента h1, …, h5.

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

      1. Реализация с нуля

Чтобы реализовать функцию отсева для одного слоя, мы должны взять столько выборок из случайной величины Бернулли (бинарной), сколько наш слой имеет размеры, где случайная переменная принимает значение 1 (сохранить) с вероятностью 1 - p и 0 (отбрасывать) с вероятностью p. Один из простых способов реализовать это - сначала отобрать выборки из равномерного распределения U [0, 1]. Затем мы можем оставить те узлы, для которых соответствующая выборка больше p, а остальные отбросить.

В следующем коде мы реализуем функцию dropout_layer, которая удаляет элементы во входном тензоре X с выпадением вероятности, изменяя масштаб остатка, как описано выше:

survivors by 1.0-dropout.

from d2l import mxnet as d2l

from mxnet import autograd, gluon, init, np, npx

from mxnet.gluon import nn

npx.set_np()

def dropout_layer(X, dropout):

assert 0 <= dropout <= 1

# In this case, all elements are dropped out

if dropout == 1:

return np.zeros_like(X)

# In this case, all elements are kept

if dropout == 0:

return X

mask = np.random.uniform(0, 1, X.shape) > dropout

return mask.astype(np.float32) * X / (1.0 - dropout)
Мы можем протестировать функцию dropout_layer на нескольких примерах. В следующих строках кода мы передаем наш ввод X через операцию выпадения с вероятностями 0, 0,5 и 1 соответственно.

X = np.arange(16).reshape(2, 8)

print(dropout_layer(X, 0))

print(dropout_layer(X, 0.5))

print(dropout_layer(X, 1))

[[ 0. 1. 2. 3. 4. 5. 6. 7.]

[ 8. 9. 10. 11. 12. 13. 14. 15.]]

[[ 0. 2. 4. 6. 8. 10. 12. 14.]

[ 0. 18. 20. 0. 0. 0. 28. 0.]]

[[0. 0. 0. 0. 0. 0. 0. 0.]

[0. 0. 0. 0. 0. 0. 0. 0.]]
Определение параметров модели

Опять же, мы работаем с набором данных Fashion-MNIST, представленным в разделе 3.5. Мы определяем MLP с двумя скрытыми слоями по 256 единиц каждый.

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

W1 = np.random.normal(scale=0.01, size=(num_inputs, num_hiddens1))

b1 = np.zeros(num_hiddens1)

W2 = np.random.normal(scale=0.01, size=(num_hiddens1, num_hiddens2))

b2 = np.zeros(num_hiddens2)

W3 = np.random.normal(scale=0.01, size=(num_hiddens2, num_outputs))


b3 = np.zeros(num_outputs)

params = [W1, b1, W2, b2, W3, b3]

for param in params:

param.attach_grad()
Определение модели

В приведенной ниже модели применяется выпадение вывода для каждого скрытого слоя (после функции активации). Мы можем установить вероятность выпадения для каждого слоя отдельно. Распространенной тенденцией является установка более низкой вероятности отсева ближе к входному слою. Ниже мы установили 0,2 и 0,5 для первого и второго скрытых слоев соответственно. Мы гарантируем, что отсев будет активен только во время тренировки.

dropout1, dropout2 = 0.2, 0.5

def net(X):

X = X.reshape(-1, num_inputs)

H1 = npx.relu(np.dot(X, W1) + b1)

# Use dropout only when training the model

if autograd.is_training():

# Add a dropout layer after the first fully connected layer

H1 = dropout_layer(H1, dropout1)

H2 = npx.relu(np.dot(H1, W2) + b2)

if autograd.is_training():

# Add a dropout layer after the second fully connected layer

H2 = dropout_layer(H2, dropout2)

return np.dot(H2, W3) + b3
Обучение и тестирование

Это похоже на обучение и тестирование MLP, описанное ранее.

num_epochs, lr, batch_size = 10, 0.5, 256

loss = gluon.loss.SoftmaxCrossEntropyLoss()

train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,

lambda batch_size: d2l.sgd(params, lr, batch_size))
      1. 1   2   3   4   5   6   7   8   9


Краткая реализация

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

net = nn.Sequential()

net.add(nn.Dense(256, activation="relu"),

# Add a dropout layer after the first fully connected layer

nn.Dropout(dropout1),

nn.Dense(256, activation="relu"),

# Add a dropout layer after the second fully connected layer

nn.Dropout(dropout2),

nn.Dense(10))

net.initialize(init.Normal(sigma=0.01))

Next, we train and test the model.

trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': lr})

d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
Резюме

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

  • Dropout заменяет активацию h случайной величиной с ожидаемым значением h.

  • Отсев используется только во время тренировки.

Упражнения

  1. Что произойдет, если вы измените вероятности отсева для первого и второго слоев? В частности, что произойдет, если вы поменяете местами оба слоя? Разработайте эксперимент, чтобы ответить на эти вопросы, количественно опишите свои результаты и обобщите качественные выводы.

  2. Увеличьте количество эпох и сравните результаты, полученные при использовании исключения, с результатами, полученными при его неиспользовании.

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

  4. Почему во время тестирования обычно не используется отсев из выборки?

  5. Используя модель в этом разделе в качестве примера, сравните эффекты использования отсева и снижения веса. Что произойдет, если одновременно использовать отсев и снижение веса? Аддитивны ли результаты? Есть уменьшенная отдача (или хуже)? Они отменяют друг друга?

  6. Что произойдет, если мы применим отсев к отдельным весам весовой матрицы, а не к активациям?

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


Обсуждение (см. https://discuss.d2l.ai/t/100)

    1. Прямое распространение, обратное распространение и вычислительные графы

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

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

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

      1. Прямое распространение

Прямое распространение (или прямой проход) относится к вычислению и хранению промежуточных переменных (включая выходные данные) для нейронной сети в порядке от входного уровня к выходному уровню. Теперь мы шаг за шагом проработаем механизм нейронной сети с одним скрытым слоем. Это может показаться утомительным, но, по вечным словам, фанка-виртуоза Джеймса Брауна, вы должны «заплатить цену, чтобы быть боссом».

Для простоты предположим, что входным примером является x ∈ Rd и что наш скрытый слой не включает член смещения. Здесь промежуточная переменная:

z = W (1) х, (5.7.1)

где W (1) ∈ Rh× d - весовой параметр скрытого слоя. После запуска промежуточной переменной z ∈ Rh через функцию активации ϕ мы получаем наш скрытый вектор активации длины h,

h = ϕ (z). (5.7.2)

Скрытая переменная h также является промежуточной переменной. Предполагая, что параметры выходного слоя имеют только вес W
(2) ∈ Rq × h, мы можем получить переменную выходного слоя с вектором длины q:

o = W(2) h. (5.7.3)

Предполагая, что функция потерь равна l, а метка примера - y, мы можем затем вычислить член потери для одного примера данных,

L = l (o, y). (5.7.4)

Согласно определению L2-регуляризации, учитывая гиперпараметр λ, член регуляризации равен

s = λ/2 (∥W (1)2F + ∥W (2)2F), (5.7.5)

где норма Фробениуса матрицы - это просто норма L2, применяемая после сглаживания матрицы в вектор. Наконец, регуляризованные потери модели на данном примере данных составляют:

J = L + s. (5.7.6)

Мы называем J целевой функцией по следующим соображениям.

      1. Вычислительный граф прямого распространения.

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

      1. Обратное распространение

Обратное распространение относится к методу расчета градиента параметров нейронной сети.

Короче говоря, метод проходит по сети в обратном порядке, от выходного до входного уровня, в соответствии с правилом цепочки из правил исчисления производных действительных функций. Алгоритм сохраняет любые промежуточные переменные (частные производные), необходимые при вычислении градиента по некоторым параметрам. Предположим, что у нас есть функции Y = f (X) и Z = g (Y), в которых вход и выход X, Y, Z являются тензорами произвольной формы. Используя цепное правило, мы можем вычислить производную Z по X через

∂Z/∂X = prod (∂Z/∂Y, ∂Y/∂X). (5.7.7)

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

Напомним, что параметрами простой сети с одним скрытым слоем, расчетный граф которой представлен на рис. 5.7.1, являются W