Терминологию проверьте здесь https://machinelearning.wtf/terms/inverted-dropout/

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

И Dropout, и Regularization — это на самом деле своего рода затухание веса, то есть ослабление влияния весов или параметров на все нейроны, которые теоретически могут включать в себя входной слой.

Как это работает

На каждой тренировочной итерации с отсевом вы отключаете (= устанавливаете в ноль) каждый нейрон слоя с вероятностью 1−keep_prob или сохраняете его с вероятностью keep_prob (здесь 50 %). ).

Отброшенные нейроны не участвуют в обучении как при прямом, так и при обратном распространении итерации.

Интуиция

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

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

Вы должны использовать отсев (случайное удаление узлов) только в обучении.

Выполнение

Применение

Предположим, у нас есть нейронная сеть, содержащая один скрытый слой L, и обучение выполняется на одной итерации (прямой или обратной). Чтобы исключить некоторые единицы на L (здесь только случайная матрица для демонстрации, каждая строка представляет активацию или производные одного тренировочного примера, 3 примера, 4 измерения):

L = randi(35, 3, 4); 

Мы определяем keep_prob, скажем, 0,85, что означает, что (1-keep_prob) будет исключено:

keep_prob = 0.85;

После запуска дропаута мы увидим что-то вроде:

L =
   24   15   13   11
    1   26   26   22
   30   28    7   13
sum(L): 63.000000
sum(L): 75.000000
sum(L): 78.000000
mask =
  0  1  1  1
  1  1  1  1
  1  1  0  1
sum(L): 45.882353
sum(L): 88.235294
sum(L): 83.529412
L =
         0   17.6471   15.2941   12.9412
    1.1765   30.5882   30.5882   25.8824
   35.2941   32.9412         0   15.2941

sum(L) – это сумма активаций каждого обучающего примера.

Полный код с матлабом:

L = randi(35, 3, 4);
keep_prob = 0.85;
L
printf("sum(L): %f\n", sum(L, 2));
L = dropout(L, keep_prob);
printf("sum(L): %f\n", sum(L, 2));

Алгоритм отсева

Предположим, у нас есть пара векторов признаков или активаций (матрица) X и предопределенный keep_prob. Наша цель — исключить (1-keep_prob) единиц каждого вектора.

С точки зрения логики мы можем определить маску, которая имеет точно такое же измерение, как X, и некоторые единицы измерения равны 0:

sz = size(X);
mask = rand(sz);
mask = mask < 0.8; % Element of mask will be set to 1 or 0 with probability 𝑘𝑒𝑒𝑝_𝑝𝑟𝑜𝑏

Результат должен быть

  0  1  1  1
  1  1  1  1
  1  1  0  1

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

Мы делаем поэлементное умножение на X:

X = X .* mask;

Важно

Размер элемента X (вход) был уменьшен на keep_prob от маски (процент элементов был исключен из-за маски), поэтому значение X (выход) также будет уменьшено, поэтому чтобы примерно компенсировать это, мы инвертируем изменение, разделив keep_prob, чтобы гарантировать, что значение X (выход) не будет затронуто больше всего.

Чтобы дать грубую компенсацию, мы масштабируем строки на:

X = X ./ keep_prob;

Полный код в матлабе:

function [X] = dropout(X, keep_prob)
% Dropout some units from X.
% (1 - keep_prob) of units will be dropped out.
sz = size(X);
mask = rand(sz);
mask = mask < 0.8; % Element of mask will be set to 1 or 0 with probability 𝑘𝑒𝑒𝑝_𝑝𝑟𝑜𝑏
X = X .* mask; 
% The element size of X (input) has been reduced by keep_prob from mask (a percentage of elements have been dropped out by mask),
% thus the value of X (output) is also gonna be reduced, so to compensate this roughly we shall invert the change by dividing
% keep_prob to make sure the value of X (output) won't be impacted mostly.
X = X ./ keep_prob;
endfunction

Проверьте общее количество здесь https://gist.github.com/XinyueZ/debcff1838abb8e00143d7ecf99283c9#file-ml_dropout_inverted_dropout-m-L23

Исключение иллюстраций

На самом деле это слишком туманно, чтобы объяснить отсев с математического уровня, поэтому лучше использовать две диаграммы, чтобы примерно объяснить его здесь, чего достаточно как разработчику прикладного направления ML.

Если предположить, что НС без отсева будет таким, то это очень знакомо.

Во время ОДНОЙ итерации мы знаем, что отсев — это случайное исключение (установленное в 0) некоторых юнитов между каждым слоем в соответствии с определенным соотношением (1-keep_prob), поэтому после отсева будет аналогичная ситуация.

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

Не удивляйтесь, ведь каждая итерация — это случайное уничтожение каких-то юнитов, поэтому, конечно, сеть изменится.

Однако интуитивно не обнаруживается, что сеть становится проще и в крайнем случае становится полностью линейной сетью (предполагая relu в качестве функции активации для каждого слоя).

Если сделать предположение, становится ясно, что

Предположим, мы отслеживаем один слой NN, а модель просто линейная:

Y = W * X+ b
Y = W * dropout(X) + b
=> Y = [(x1, x2, x3) .... (some "x"s)]*[W1, W2, W3….] + [b1, b2, b3...]

после выпадения некоторых юнитов

Y = W * X+ b
Y = W * dropout(X) + b
=> Y = [(x1, 0, 0) .... (some "x"s and "0"s)]*[W1, W2, W3….] + [b1, b2, b3...]

после высадки ВСЕХ юнитов

Y = W * X + b
Y = W * dropout(X) + b
=> Y = [(0, 0, 0) .... ("0"s)]*[W1, W2, W3….] + [b1, b2, b3...]
=> Y = b

Модель Y становится моделью только со смещением b.

У этой модели высокий уклон (недообучение), очень высокий, потому что он чрезвычайно прост.

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

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

Уведомление

  • Dropout — это метод регуляризации.
  • Вы используете отсев только во время обучения. Не используйте отсев (случайное удаление узлов) во время тестирования.
  • Применять отсев как при прямом, так и при обратном распространении.
  • Во время обучения разделите каждый выпадающий слой на keep_prob, чтобы сохранить одно и то же ожидаемое значение для активаций. Например, если значение keep_prob равно 0,5, то в среднем мы отключим половину узлов, поэтому выходные данные будут масштабироваться на 0,5, поскольку только оставшаяся половина вносит свой вклад в решение. Деление на 0,5 эквивалентно умножению на 2. Следовательно, результат теперь имеет такое же ожидаемое значение. Вы можете проверить, что это работает, даже если значение keep_prob отличается от 0,5.