предисловие
ПредыдущийВ этой статье представлены граф вычислений и реализация прямого распространения.В этой статье в основном будет представлен алгоритм обратного распространения, который очень важен для оптимизации модели, и реализация вычисления градиента в алгоритме обратного распространения. Поскольку вычисление градиента матрицы должно быть связано с вычислением градиента, в этой статье подробно рассматривается вычисление градиента и реализация нескольких общих операций. Пожалуйста, укажите на ошибки.
Прежде всего, если кратко подытожить, реализация процесса обратного распространения в основном заключается в выполнении двух задач:
- Реализовать расчет градиента выхода разных операций на вход
- Реализовать расчет градиента различных узлов путем расчета функции потерь в соответствии с цепным правилом.
Затем прикрепите кодовый адрес SimpleFlow:GitHub.com/pgirllab/simp…
текст
обратное распространение
Оптимизация модели, которую мы строим, обычно требует двух шагов: 1. Найдите градиент функции потерь для переменной 2. Выполните оптимизацию параметров (например, градиентный спуск) на основе информации о градиенте Итак, как использовать вычислительный график, который мы построили для вычислить функцию потерь для Что насчет градиентов других узлов на графике? пройти черезПравило цепи. Мы по-прежнему передаем выражение из предыдущей статьи
л
о
с
с
(
Икс
,
у
,
г
)
знак равно
г
(
Икс
+
у
)" role="презентация" style="позиция: относительная;">Соответствующая схема расчета для иллюстрации:
Мы помечаем вышеуказанные узлы операции буквами, и каждую операцию можно рассматривать как функцию, которая принимает один или два входа и имеет один или несколько выходов, тогда приведенное выше выражение
можно записать как
L o s s ( x , y , z ) = g ( z , f ( x , y ) )" role="presentation" style="text-align: center; position: relative;">Loss(x,y,z)=g(z,f(x,y)) L o s s ( x , y , z ) = g ( z , f ( x , y ) )
Тогда по цепному правилу можем получить
л
о
с
s" role="presentation" style="position: относительный;">правильно
х" роль="презентация" стиль="позиция: относительная;">
Производная от:
Предполагая, что узлы в графе вычислили свои собственные выходные значения, мы помещаем выходные значения узлов в узлы следующим образом:
Затем вычислите каждый пункт формулы цепного правила один раз, то есть от конца к началу на рисунке:
-
∂ л о с с ∂ г знак равно 1" роль="презентация" стиль="позиция: относительная;">
-
∂ г ∂ ф знак равно г знак равно 6" роль="презентация" стиль="позиция: относительная;">
(Конечно, это также может быть вычислено ∂ г ∂ г знак равно Икс + у знак равно 5" роль="презентация" стиль="позиция: относительная;">
). выяснить ∂ л о с с ∂ ф знак равно ∂ л о с с ∂ г ∂ г ∂ ф знак равно 1 × г знак равно 6" роль="презентация" стиль="позиция: относительная;">
-
∂ ф ∂ Икс знак равно 1" роль="презентация" стиль="позиция: относительная;">
(Можно также рассчитать ∂ ф ∂ у знак равно 1" роль="презентация" стиль="позиция: относительная;">
), то найти ∂ л о с с ∂ Икс знак равно ∂ л о с с ∂ г ∂ г ∂ ф ∂ ф ∂ Икс знак равно 1 × г × 1 знак равно 6" роль="презентация" стиль="позиция: относительная;">
Таким образом, градиент значения потерь к связанным с ним узлам может быть рассчитан по цепному правилу от задней части к передней. Что мы делаем дальше?функция потерьузел и вычислить его дляузелизградиентрассчитать.
Ниже представлен другой расчетный график:
здесь
х" роль="презентация" стиль="позиция: относительная;">Узел должен выводить на два разных узла, на данный момент нам нужно вычислить все из
g" role="presentation" style="позиция: относительная;">
прибыть
х" роль="презентация" стиль="позиция: относительная;">
Затем вычислите значение градиента каждого пути в соответствии с методом вычисления правила цепочки для выделенного пути выше и, наконец, просуммируйте градиенты различных путей. следовательно
л
о
с
s" role="presentation" style="position: относительный;">
правильно
х" роль="презентация" стиль="позиция: относительная;">
Градиент:
Расчет градиента
Благодаря введению обратного распространения выше мы уже знаем, как получается градиент значения потерь для определенного узла (конкретный метод реализации объясняется в следующем разделе), и ниже показано, как получить градиент для определенного узла, до тех пор, пока каждый Градиент на каждом узле рассчитывается и умножается в обратном направлении пути, чтобы получить градиент нужного узла. В этом разделе рассказывается, как рассчитать значение градиента значения потерь для определенного узла.
В этой части мы делаем именно такую вещь.Сначала нарисуем узел:
f" role="presentation" style="position: relative;">Узел можно рассматривать как функцию
г
знак равно
ф
(
Икс
,
у
)" role="презентация" style="позиция: относительная;">
, все, что нам нужно сделать, это спросить
∂
ф
(
Икс
,
у
)
∂
Икс
« role = «презентация» стиль = «позиция: относительная;»>
и
∂
ф
(
Икс
,
у
)
∂
у
« role = «презентация» стиль = «позиция: относительная;»>
.
Вычисление градиента для квадратных операций
Давайте сначала воспользуемся операцией возведения в квадрат (причина, по которой нам не нужно суммировать и произведение произведения на матрицу в качестве примера, потому что она включает в себя обработку размерности вывода матрицы, которая будет резюмирована позже, а операция возведения в квадрат не включать размер. Изменение относительно простое):
class Square(Operation):
''' Square operation. '''
# ...
def compute_gradient(self, grad=None):
''' Compute the gradient for square operation wrt input value.
:param grad: The gradient of other operation wrt the square output.
:type grad: ndarray.
'''
input_value = self.input_nodes[0].output_value
if grad is None:
grad = np.ones_like(self.output_value)
return grad*np.multiply(2.0, input_value)
вgrad
пара значений потерьSquare
Выходное значение градиента, которое показано на рисунке выше.
∂
л
о
с
с
∂
г
« role = «презентация» стиль = «позиция: относительная;»>стоимость его
shape
должно быть сSquare
выходное значениеshape
последовательный.
Вычисление матричного градиента для обратного распространения нейронной сети
Вычисление градиента матрицы является важной частью реализации алгоритма обратного распространения, но вывод матрицы при реализации обратного распространения нейронной сети все еще отличается от перечисленных во многих списках формул.
Вывод матрицы/вектора
Во-первых, давайте посмотрим на вывод матрицы.На самом деле вывод матрицы по существу является частной производной элементов в целевой матрице к элементам в переменной матрице.Что касается формы производной матрицы после деривация, это в основном ради формальной красоты.Удобно продолжать использовать после деривации. Так что не ведитесь на эти сложные формы вывода матриц. Загружено сюдаПеречислите PDF-версию правил формулы вывода матрицы, который может быть расширен шаг за шагом посредством векторного вывода скаляра (строка/столбец) до векторного вывода (строка/столбец) вектора (строка/столбец), а затем вывода матрицы в матрицу.
например скаляр
у" роль="презентация" стиль="позиция: относительная;">парная матрица
Икс
знак равно
[
Икс
11
Икс
12
Икс
двадцать один
Икс
двадцать два
]
« role = «презентация» стиль = «позиция: относительная;»>
Производная, у нас есть скаляр
у" роль="презентация" стиль="позиция: относительная;">
за
X" role="presentation" style="позиция: относительная;">
Получены все элементы частной производной и, наконец, получена производная матрица, форма матрицы такая же
X" role="presentation" style="позиция: относительная;">
такой же:
Вывод матрицы в обратном распространении нейронной сети
Причина, по которой вывод матрицы разделен на две части, заключается в том, что когда вывод матрицы реализуется, обнаруживается, что все еще существует разница в форме вывода матрицы и формуле вывода матрицы при выполнении обратного распространения. Так называемыйразницаэто,Когда мы выполняем вывод матрицы в нейронной сети, функция Loss (потери) фактически является выводом матрицы в узле, а функция потерь является скаляром, поэтому каждый раз, когда мы вычисляем градиент каждого узла в расчетном графе, он на самом деле является производной вычисленного скаляра (значение потерь) по отношению к матрице (выходное значение узла)То есть мы используем только один из выводов матрицы при выполнении обратного распространения, т.е.Вывод скаляра по матрице, То есть в виде примера выше. Дальнейший шаг — это фактически процесс взятия частной производной каждого элемента в матрице по функции потерь, С точки зрения непрофессионала, это вычисление степени влияния каждого элемента в матрице на рисунке на значение потерь. Следовательно, форма производной матрицы и форма вычисляемых таким образом переменных должны бытьпоследовательныйиз.
Интуитивно понятно, чтоПри расчете производной вектора/матрицы в расчетном графике вычисляется величина влияния элементов матрицы на величину потерь, а ее форма такая же, как и у матрицы.
Вычисление градиента для суммирования операций
Теперь мы возьмем градиентный расчет операции суммы в качестве примера, чтобы проиллюстрировать реализацию метода вывода матрицы в процессе обратного распространения ошибки.
Для операции суммы:
С
знак равно
А
+
б" роль="представление" стиль="позиция: относительная;">, в
А
знак равно
[
а
11
а
12
а
двадцать один
а
двадцать два
]
« role = «презентация» стиль = «позиция: относительная;»>
,
b
=
b
0
" role="presentation" style="position: relative;">
, но
С
знак равно
[
а
11
+
б
0
а
12
+
б
0
а
двадцать один
+
б
0
а
двадцать два
+
б
0
]
« role = «презентация» стиль = «позиция: относительная;»>
, стоимость потерь
L" role="presentation" style="позиция: относительная;">
правильно
C" role="presentation" style="позиция: относительная;">
Матрица градиента
г
знак равно
[
∂
л
∂
с
11
∂
л
∂
с
12
∂
л
∂
с
двадцать один
∂
л
∂
с
двадцать два
]
« role = «презентация» стиль = «позиция: относительная;»>
Ниже мы вычисляем
∂
л
∂
б
« role = «презентация» стиль = «позиция: относительная;»>, согласно тому, что мы сказали ранее, размер (форма) этого градиента должен быть таким же, как
б" роль="представление" стиль="позиция: относительная;">
То же самое, то есть скаляр, так как его вычислить? Мы разделим его на две части, чтобы разобраться с:
-
Рассчитайте сначала для С знак равно А + B" role="presentation" style="позиция: относительная;">
∂ л ∂ Б знак равно [ ∂ л с 11 ∂ с 11 ∂ б 0 ∂ л с 12 ∂ с 12 ∂ б 0 ∂ л с двадцать один ∂ с двадцать один ∂ б 0 ∂ л с двадцать два ∂ с двадцать два ∂ б 0 ] знак равно [ ∂ л с 11 × 1 ∂ л с 12 × 1 ∂ л с двадцать один × 1 ∂ л с двадцать два × 1 ] знак равно ∂ л ∂ С знак равно G" role="presentation" style="text-align: center; position: relative;">∂L∂B=⎡⎣∂Lc11∂c11∂b0∂Lc21∂c21∂b0∂Lc12∂c12∂b0∂Lc22∂ c22∂b0⎤⎦=[∂Lc11×1∂Lc21×1∂Lc12×1∂Lc22×1]=∂L∂C=G ∂ л ∂ Б знак равно [ ∂ л с 11 ∂ с 11 ∂ б 0 ∂ л с 12 ∂ с 12 ∂ б 0 ∂ л с двадцать один ∂ с двадцать один ∂ б 0 ∂ л с двадцать два ∂ с двадцать два ∂ б 0 ] знак равно [ ∂ л с 11 × 1 ∂ л с 12 × 1 ∂ л с двадцать один × 1 ∂ л с двадцать два × 1 ] знак равно ∂ л ∂ С знак равно г, ∂ л ∂ Б « role = «презентация» стиль = «позиция: относительная;»>
значение градиента , где Б знак равно [ б 0 б 0 б 0 б 0 ] « role = «презентация» стиль = «позиция: относительная;»>
через б" роль="представление" стиль="позиция: относительная;">
полученный путем трансляции
-
рассчитать L" role="presentation" style="позиция: относительная;">
правильно б" роль="представление" стиль="позиция: относительная;">
градиент ∂ л ∂ б « role = «презентация» стиль = «позиция: относительная;»>
. так как B" role="presentation" style="позиция: относительная;">
правда б" роль="представление" стиль="позиция: относительная;">
Широковещательная операция , хотя и в форме матрицы, по существу является б" роль="представление" стиль="позиция: относительная;">
Было изготовлено 4 экземпляра и затем эксплуатировалось, поэтому ∂ л ∂ Б « role = «презентация» стиль = «позиция: относительная;»>
Накопление каждого элемента в ∂ л ∂ б « role = «презентация» стиль = «позиция: относительная;»>
ценность.
Тогда значение градиента равно:
∂ л ∂ б знак равно ∑ я знак равно 1 2 ∑ Дж знак равно 1 2 ∂ л ∂ с я Дж " role="presentation" style="text-align: center; position: relative;">∂L∂b=∑i=12∑j=12∂L∂cij ∂ л ∂ б знак равно ∑ я знак равно 1 2 ∑ Дж знак равно 1 2 ∂ л ∂ с я Дж
Для этого примера б" роль="представление" стиль="позиция: относительная;">является скаляром, который может быть выражен как:
∂ л ∂ б знак равно [ 1 1 ] г [ 1 1 ] " role="presentation" style="text-align: center; position: relative;">∂L∂b=[11]G[11] ∂ л ∂ б знак равно [ 1 1 ] г [ 1 1 ]как б" роль="представление" стиль="позиция: относительная;">
∂ л ∂ б знак равно [ ∂ л ∂ с 11 + ∂ л ∂ с 12 ∂ л ∂ с двадцать один + ∂ л ∂ с двадцать два ] " role="presentation" style="text-align: center; position: relative;">∂L∂b=[∂L∂c11+∂L∂c12∂L∂c21+∂L∂c22] ∂ л ∂ б знак равно [ ∂ л ∂ с 11 + ∂ л ∂ с 12 ∂ л ∂ с двадцать один + ∂ л ∂ с двадцать два ]представляет собой вектор-столбец длины 2, например [ б 0 б 0 ] « role = «презентация» стиль = «позиция: относительная;»>
тебе надо G" role="presentation" style="позиция: относительная;">
Каждый столбец добавляется для получения и б" роль="представление" стиль="позиция: относительная;">
Градиентные векторы одинаковой формы:
Ниже приведена реализация Python вычисления градиента операции суммы:
class Add(object):
# ...
def compute_gradient(self, grad=None):
''' Compute the gradients for this operation wrt input values.
:param grad: The gradient of other operation wrt the addition output.
:type grad: number or a ndarray, default value is 1.0.
'''
x, y = [node.output_value for node in self.input_nodes]
if grad is None:
grad = np.ones_like(self.output_value)
grad_wrt_x = grad
while np.ndim(grad_wrt_x) > len(np.shape(x)):
grad_wrt_x = np.sum(grad_wrt_x, axis=0)
for axis, size in enumerate(np.shape(x)):
if size == 1:
grad_wrt_x = np.sum(grad_wrt_x, axis=axis, keepdims=True)
grad_wrt_y = grad
while np.ndim(grad_wrt_y) > len(np.shape(y)):
grad_wrt_y = np.sum(grad_wrt_y, axis=0)
for axis, size in enumerate(np.shape(y)):
if size == 1:
grad_wrt_y = np.sum(grad_wrt_y, axis=axis, keepdims=True)
return [grad_wrt_x, grad_wrt_y]
вgrad
Параметры находятся в приведенной выше формуле
G" role="presentation" style="позиция: относительная;">Его форма должна соответствовать выходному значению этого узла (
output_value
форма всегда).
Расчет матричного умножения градиента
В этой части в основном рассказывается, как использовать обратное распространение для поиска градиентов.Размерный анализчтобы помочь нам получить градиенты быстро. Начнем с примера операции умножения матриц:
C = A B" role="presentation" style="text-align: center; position: relative;">C=AB C = A Bв,
C" role="presentation" style="позиция: относительная;">да
М
×
K" role="presentation" style="позиция: относительная;">
матрица,
A" role="presentation" style="position: относительный;">
да
М
×
N" role="presentation" style="позиция: относительная;">
матрица,
B" role="presentation" style="позиция: относительная;">
да
Н
×
K" role="presentation" style="позиция: относительная;">
матрица.
стоимость потерь
L" role="presentation" style="позиция: относительная;">правильно
C" role="presentation" style="позиция: относительная;">
Градиент
Его форма и матрица
C" role="presentation" style="позиция: относительная;">то же
М
×
K" role="presentation" style="позиция: относительная;">
С помощью размерного анализа мы можем использовать наши знания о скалярном выводе, а затем немного обработать форму матрицы (левое умножение, правое умножение, транспонирование), чтобы получитьМинатополучить правильный градиент. Конечно, если вам нужно проанализировать производную каждого элемента, вы можете обратиться к этой статье.Суть операции обратного распространения с использованием матрицы в нейронной сети, ниже мы в основном используем размерный анализ для быстрого вычисления производной от матрицы к матрице узла умножения матриц при обратном распространении.
если мы хотим
∂
л
∂
Б
« role = «презентация» стиль = «позиция: относительная;»>, согласно цепному правилу скалярного вычисления, должно иметь:
известен из вектора
∂
л
∂
С
« role = «презентация» стиль = «позиция: относительная;»>форма
М
×
K" role="presentation" style="позиция: относительная;">
(и
C" role="presentation" style="позиция: относительная;">
одинаковая форма)
∂
л
∂
Б
« role = «презентация» стиль = «позиция: относительная;»>
форма
Н
×
K" role="presentation" style="позиция: относительная;">
(и
B" role="presentation" style="позиция: относительная;">
форма), поэтому
∂
С
∂
Б
« role = «презентация» стиль = «позиция: относительная;»>
должно быть
Н
×
M" role="presentation" style="позиция: относительная;">
Матрица , и формула для продукта выше написаны в обратном порядке, и порядок обратный.
Согласно нашим правилам скалярного вывода,
C" role="presentation" style="позиция: относительная;">за
B" role="presentation" style="позиция: относительная;">
Руководство должно быть
A" role="presentation" style="position: относительный;">
, но
A" role="presentation" style="position: относительный;">
Является
М
×
N" role="presentation" style="позиция: относительная;">
матрица, и теперь нам нужна
Н
×
M" role="presentation" style="позиция: относительная;">
матрица, то
A" role="presentation" style="position: относительный;">
Транспонируйте его, чтобы получить:
Точно так же его можно получить и с помощью размерного анализа.
L" role="presentation" style="позиция: относительная;">правильно
A" role="presentation" style="position: относительный;">
Градиент
г
Б
Т
« role = «презентация» стиль = «позиция: относительная;»>
Ниже приведена реализация Python вычисления градиента операции умножения матрицы:
class MatMul(Operation):
# ...
def compute_gradient(self, grad=None):
''' Compute and return the gradient for matrix multiplication.
:param grad: The gradient of other operation wrt the matmul output.
:type grad: number or a ndarray, default value is 1.0.
'''
# Get input values.
x, y = [node.output_value for node in self.input_nodes]
# Default gradient wrt the matmul output.
if grad is None:
grad = np.ones_like(self.output_value)
# Gradients wrt inputs.
dfdx = np.dot(grad, np.transpose(y))
dfdy = np.dot(np.transpose(x), grad)
return [dfdx, dfdy]
Вычисление градиента для других операций
Мы не будем здесь вводить вычисление градиента других операций одну за другой.Аналогично мы анализируем и понимаем градиент матрицы в обратном распространении на основе скалярного градиента и помещаем его в матричное правило.Суть деформации, другие градиенты также могут быть получены и реализовано.
В Simpleflow в настоящее время реализована градиентная реализация операций суммы, умножения, умножения матриц, квадрата, сигмоида, уменьшения суммы и журнала, см.:GitHub.com/pgirllab/simp…
Суммировать
В этой статье представлен принцип быстрого вычисления градиентов путем обратного распространения вычислительного графа, а также вычисления и реализации соответствующих градиентов каждого узла.При вычислении градиента каждого узла мы можем реализовать алгоритм обратного распространения для реализации функции потерь для всех узлов Вычисление градиента графа будет подведено в следующей статье, Вычисление градиента узлов в графе с помощью поиска в ширину и реализация оптимизатора градиентного спуска.