Предисловие

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

Например, для вопроса прогнозирования цен на жилье: 1) для оцифрованного представления входных данных вы можете использовать вектор, содержащий площадь дома, год дома и т. д., чтобы указать входные данные, 2) для выходных данных является фактическим цена сделки дома, 3) для входа в выход. Метод отображения может быть линейной регрессией, 4) Для критериев оценки метода отображения может использоваться критерий Abs, то есть абсолютное значение разницы между прогнозируемое значение и фактическое значение. Как только это содержимое определено, можно использовать метод оптимизации градиентного спуска для решения неизвестных в методе отображения, чтобы отображение достигло оптимального состояния. В работе будней инженеры не могут изменить метод градиентного спуска или вводить новшества. Есть некоторые исследования в этой области, но они все еще меньшинство. Тем не менее метод оптимизации градиентного спуска является важной частью машинного обучения. Полное понимание этой части поможет принять лучшее решение о четырех ключевых частях машинного обучения, например, при разработке карты. Необходимо обеспечить вычитаемость отображения, чтобы его можно было решить методом градиентного спуска.

Теория

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

Чтобы продемонстрировать, вот упрощенная функция, которая представляет стоимость.

Его графическое представление выглядит следующим образом: направление оси X представляет w₁, направление оси Y представляет стоимость.

Чтобы найти оптимальное значение w₁, позволяющее минимизировать затраты. Из рисунка легко увидеть, что минимальное значение стоимости будет при w₁=-1. Короче говоря, вы можете найти положение минимального значения, когда производная равна 0, используя функцию производной функции стоимости. Однако в реальной ситуации выражение стоимости очень сложное, включает сотни и тысячи переменных. Когда количество уравнений с нулевым прореживанием равно 0, сложность очень высока, а объем вычислений велик. Поэтому исследователи изобрели метод, который использует рассчитанное компьютером значение w₁, чтобы сделать стоимость минимально возможной.

Шаги

Возьмем случайное значение для w₁. Например, пусть w₁=0,5, в это время стоимость = 2 ⨉0,5² + 4 ⨉ 0,5 = 2,5. Мы знаем, что стоимость’ = 4 ⨉ w₁ + 4 , при которой стоимость’= 4 ⨉ 0,5 + 4 = 6 . Это значит, что если добавить чуть-чуть w₁, то стоимость увеличится чуть-чуть в 6 раз. В свою очередь, w₁ немного уменьшится, и немного уменьшится стоимость. Таким образом, есть способ постепенно снижать стоимость. так что вы можете получить значение w₁ для минимальной стоимости.

Здесь бит равен 0.5. Поскольку 0,5 намного больше небольшого числа, изменение стоимости строго не в шесть раз больше, чем 0,5, но это мало влияет на наши цели.

Первая итерация: на данный момент стоимость’= 4 ⨉ 0,5 + 4 = 6, w₁ = w₁–0,5 = 0,5–0,5 = 0, стоимость = 0

Вторая итерация: в это время стоимость’= 4 ⨉ 0 + 4 = 4, w₁ = w₁–0,5 = -0,5, стоимость = -1,5

Третья итерация: на данный момент стоимость’= 4 ⨉ -0,5 + 4 = 2, w₁ = w₁–0,5 = -1, стоимость=-2

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

Вычислительный модуль в Torch

В настоящее время многие библиотеки глубокого обучения имеют встроенные методы сопоставления, а также критерии оценки для методов сопоставления. Вычисление функции и часть производной имеют внутренние методы, которые можно вызывать напрямую. Здесь Факел, среда глубокого обучения, используется в качестве примера, чтобы привести несколько примеров использования. Большинство библиотек глубокого обучения спроектированы одинаково. Когда вы разберетесь в других библиотеках, вы сможете применить идеи здесь, но вам нужно обратить внимание на тонкие различия, такие как Torch vs PyTorch.

Поле в левой части рисунка выше — это модуль линейного преобразования, который преобразует два измерения в одно измерение. Изображение справа представляет собой блок квадрата разности критерия MSE, используемый для расчета эффекта этого отображения линейных преобразований. Кружок представляет переменную, красный кружок представляет известное число, x1, x2 представляют два элемента двумерного входного вектора, а y представляет значение цели 10. Зеленый кружок указывает на неизвестное число или переменный номер, в модуле. Кружки без цвета представляют некоторые промежуточные переменные. Квадраты представляют такие операции, как умножение, сложение, вычитание, возведение в квадрат и так далее.

Код, связанный с Torch, выглядит следующим образом.

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

require 'nn';
l = nn.Linear(2, 1)
l.weight[1][1] = 1
l.weight[1][2] = 5
l.bias[1] = 3
a = torch.Tensor(2)
a[1] = 2
a[2] = 3
res = l:forward(a) --res = 2 * 1 + 3 * 5 + 3 = 20, 
print(res)
--will print 
--20
--[torch.DoubleTensor of size 1]

crit = nn.MSECriterion()
targets = torch.Tensor(1)
targets[1] = 10
cost = crit:forward(res, targets)
print(cost) --cost = (20 - 10) * (20 - 10) = 100
--will print
--100

Обратная функция:

Предоставляется производная стоимости для каждой переменной, nn.Linear, nn.MSECriterion.

Принцип следующий:

По правилам цепочки производных в математике можно сделать вывод, что

require 'nn';

l = nn.Linear(2, 1)
l.weight[1][1] = 1
l.weight[1][2] = 5
l.bias[1] = 3
a = torch.Tensor(2)
a[1] = 2
a[2] = 3
res = l:forward(a) --res = 2 * 1 + 3 * 5 + 3 = 20, 
print(res)
--will print 
--20
--[torch.DoubleTensor of size 1]


crit = nn.MSECriterion()
targets = torch.Tensor(1)
targets[1] = 10
cost = crit:forward(res, targets)
print(cost) --cost = (20 - 10) * (20 - 10) = 100
--will print
--100

backward1 = crit:backward(res, targets) 
print(backward1) -- 2 * (20 - 10) = 20
--will print
--20
--[torch.DoubleTensor of size 1]

backward2 = l:backward(a, backward1) -- This is result of d(cost) / d(y') same to 2(y'-y)
print(l.gradWeight) -- dw1 = 20 * 2 = 40, dw2 = 20 * 3 = 60
--will print
--40  60
--[torch.DoubleTensor of size 1x2]

print(l.gradBias)  --db = 20
--will print
--20
--[torch.DoubleTensor of size 1]

ссылка

  1. [Видео]Лекция 4 | Введение в нейронные сети, обратное распространение и нейронные сети
  2. [Слайды]Лекция 4: Обратное распространение ошибки и нейронные сети
  3. Факел | Документация разработчика, определение собственного слоя