Ручной алгоритм обратного распространения + реализация кода

искусственный интеллект глубокое обучение алгоритм Нейронные сети

Оригинальная ссылка:CHAPTER 2 How the backpropagation algorithm works

Ссылки на статьи серии «Нейронные сети и машинное обучение»

Обзор обратного распространения

Алгоритм обратного распространения впервые был упомянут в 1970-х годах, но его важность не была признана до знаменитой статьи 1986 года Дэвида Румелхарта, Джеффри Хинтона и Рональда Уильямса.

Ядром обратного распространения является функция стоимости парыCо любом весеwи предвзятостьbчастная производная от\partial{C}/\partial{w}выражение.

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

Два предположения о функции стоимости

  1. Функция стоимости может быть записана как в каждой обучающей выборкеxфункция стоимости наC_xсреднее значениеC=\frac{1}{n}\sum_{x} C_x.

  2. Функция стоимости может быть записана как функция выхода нейронной сети.

Причина предположения 1 заключается в том, что обратное распространение фактически вычисляется на отдельной обучающей выборке.\partial{C_x}/\partial{w}и\partial{C_x}/\partial{b}. затем получено усреднением по всем обучающим выборкам\partial{C}/\partial{w}и\partial{C}/\partial{w}.

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

Определение символа

W_{jk}^{l}Отl-1первоеkнейроны кlпервоеjвеса каждого нейрона.

b_j^lпервыйlпервоеjсмещение каждого нейрона.

a_j^lпервыйlпервоеjзначение активации нейрона.

\sigmaявляется функцией активации.

Векторизуйте вышеуказанные символы

W^{l}- весовая матрица, перваяjРядkЭлементы столбцаW_{jk}^{l}.

Например, весовая матрица между вторым и третьим слоями имеет вид

w^3 = { \left[      \begin{matrix}        w_{11}^3 & w_{12}^3 & w_{13}^3 & w_{14}^3\\        w_{21}^3 & w_{22}^3 & w_{23}^3 & w_{24}^3       \end{matrix} \right] }

b^l— вектор смещения. первоеjЭлементы строкиb_j^l.

Например, вектор смещения для второго слоя равен

b^2 = { \left[      \begin{matrix}        b_{1}^2  \\        \\        b_{2}^2\\        \\        b_{3}^2\\        \\        b_{4}^2       \end{matrix}       \right] }

С этими представлениямиlпервоеjзначение активации нейронаa_j^lкакl-1Значения активации слоев связаны уравнением

a^{l}_j = \sigma \left( \sum_k w^{l}_{jk} a^{l-1}_k + b^l_j \right)

Векторизуйте приведенную выше формулу

a^{l} = \sigma(w^l a^{l-1}+b^l)

Например, вектор активации третьего слоя равен

{ \left[  \begin{matrix}    a_{1}^3  \\    \\    a_{2}^3 \\   \end{matrix}   \right] }   =\sigma\left(   { \left[    \begin{matrix}      w_{11}^3 & w_{12}^3 & w_{13}^3 & w_{14}^3\\      w_{21}^3 & w_{22}^3 & w_{23}^3 & w_{24}^3     \end{matrix}     \right] }     { \left[     \begin{matrix}       a_{1}^2  \\       \\       a_{2}^2 \\       \\       a_{3}^2  \\       \\       a_{4}^2 \\      \end{matrix}      \right] }+      { \left[       \begin{matrix}         b_{1}^3  \\         \\         b_{2}^3 \\         \\        \end{matrix}        \right] }\right)

a^{l}— вектор активации. первоеjЭлементы строкиa_j^l.

определение

z^l \equiv w^l a^{l-1}+b^l

ноa^l =\sigma(z^l)

z^lозначает первыйlВзвешенный ввод в слой. первоеjэлементыz_j^l.

z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

z_j^lпервыйlпервоеjвзвешенный вход для каждого нейрона.

Ядром обратного распространения является функция стоимости парыCо любом весеwи предвзятостьbчастная производная от\partial{C}/\partial{w}выражение. Для расчета этих значений введем промежуточную величину\delta_j^l, указывая на то, что вlпервоеjошибка нейрона.

определение

\delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

\delta^lвектор ошибки,\delta^lПервыйjэлементы\delta_j^l.

Четыре фундаментальных уравнения обратного распространения

\nabla_aоператор градиента,\nabla_a CРезультатом является вектор, элементами которого являются частные производные\partial C / \partial a^L_j.

\odotоператор поэлементного произведения,{(s \odot t)}_j = s_j t_j,Например

\left[\begin{array}{c} 1 \\ 2 \end{array}\right]   \odot \left[\begin{array}{c} 3 \\ 4\end{array} \right] = \left[ \begin{array}{c} 1 * 3 \\ 2 * 4 \end{array} \right] = \left[ \begin{array}{c} 3 \\ 8 \end{array} \right].

Алгоритм обратного распространения

Как мы сказали выше, алгоритм обратного распространения вычисляет градиент функции стоимости для обучающей выборки,C=C_x. на практике , обычно используя комбинацию алгоритмов обратного распространения и обучения, таких как стохастический градиентный спуск, мы будем Обучающие выборки вычисляют соответствующие градиенты. В частности, для мини-партии размера m на этой мини-партии выполняется следующий алгоритм. Примените алгоритм обучения градиентного спуска на основе данных:

Схематический код комбинации алгоритма обратного распространения ошибки и алгоритма мини-пакетного стохастического градиентного спуска, полный код см.network.py

def backprop(self, x, y):
        """Return a tuple ``(nabla_b, nabla_w)`` representing the
        gradient for the cost function C_x.  ``nabla_b`` and
        ``nabla_w`` are layer-by-layer lists of numpy arrays, similar
        to ``self.biases`` and ``self.weights``."""
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        # feedforward
        activation = x
        activations = [x] # list to store all the activations, layer by layer
        zs = [] # list to store all the z vectors, layer by layer
        for b, w in zip(self.biases, self.weights):
            z = np.dot(w, activation)+b
            zs.append(z)
            activation = sigmoid(z)
            activations.append(activation)
        # backward pass
        delta = self.cost_derivative(activations[-1], y) * \
            sigmoid_prime(zs[-1])
        nabla_b[-1] = delta
        nabla_w[-1] = np.dot(delta, activations[-2].transpose())
        # Note that the variable l in the loop below is used a little
        # differently to the notation in Chapter 2 of the book.  Here,
        # l = 1 means the last layer of neurons, l = 2 is the
        # second-last layer, and so on.  It's a renumbering of the
        # scheme in the book, used here to take advantage of the fact
        # that Python can use negative indices in lists.
        for l in range(2, self.num_layers):
            z = zs[-l]
            sp = sigmoid_prime(z)
            delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
            nabla_b[-l] = delta
            nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
        return (nabla_b, nabla_w)

def cost_derivative(self, output_activations, y):
        """Return the vector of partial derivatives \partial C_x /
        \partial a for the output activations."""
        return (output_activations-y)

def sigmoid_prime(z):
    """Derivative of the sigmoid function."""
    return sigmoid(z)*(1-sigmoid(z))

Доказательство четырех фундаментальных уравнений

Теперь мы докажем эти четыре основных уравнения (BP)-(BP4). Все это является следствием цепного правила многомерного исчисления.

доказывать\delta^L = \nabla_a C \odot \sigma'(z^L)

Исходя из уравнения (BP1), это дает ошибку\delta^lвыражение. По определению

\delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

Согласно двум предположениям о функции стоимости 2 «Функция стоимости может быть записана как функция выхода нейронной сети», применение цепного метода показывает, что можно получить частную производную выхода нейронной сети первый{\partial C}/{\partial a^L_k}Затем возьмите частную производную взвешенного выхода{\partial a^L_k} /  {\partial z^L_j}.

\delta^L_j = \sum_k \frac{\partial C}{\partial a^L_k } \frac{\partial a^L_k}{\partial z^L_j},

Кажется, что приведенная выше формула очень сложна, но из-заkвыходное значение активации нейронаa_k^lзависит только от индексаk=jвремяjвходные веса нейроновz_j^l. все когдаk\neq {j}Время\partial a^L_k / \partial z^L_jИсчезнувший. В результате мы можем упростить предыдущую формулу как

\delta^L_j = \frac{\partial C}{\partial a^L_j} \frac{\partial a^L_j}{\partial z^L_j}.

Также из-заa^L_j = \sigma(z^L_j)так\frac{\partial a^L_j}{\partial z^L_j}можно записать как\sigma'(z^L_j), уравнение становится

\delta^L_j = \frac{\partial C}{\partial a^L_j} \sigma'(z^L_j)

Это в компонентной форме (BP1), а затем в соответствии с\nabla_aоператор градиента,\nabla_a CРезультатом является вектор, элементами которого являются частные производные\partial C / \partial a^L_j. Уравнения можно записать в векторной форме

\delta^L ={\nabla_a {C}} \odot {\sigma'(z^L_j)}

(BP1) доказано.

доказывать\delta^l = ((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l)

Докажите (BP2), что дает следующий уровень ошибок\delta^{l+1}ошибка в виде\delta^l. Для этого к\delta^l_j = \partial C / \partial z^l_jпереписать в виде\delta^{l+1}_k = \partial C / \partial z^{l+1}_k,\delta^{l+1}и\delta^lпройти черезz_k^{l+1}иz_j^lПодключить, применить тест цепи

в соответствии сz_k^{l+1}определение имеет

z^{l+1}_k = \sum_j w^{l+1}_{kj } a^l_j +b^{l+1}_k = \sum_j w^{l+1}_{kj} \sigma(z^l_j) +b^{l+1}_k

z_k^{l+1}правильноz_j^{l}Делаем частичное дифференцирование, получаем

\frac{\partial z^{l+1}_k}{\partial z^l_j} = w^{l+1}_{kj} \sigma'(z^l_j)

Обратите внимание, что хотяz^{l+1}иz^{l}Нейроны в двух слоях связаны сложным образом, но существует только одна связь между любой парой нейронов (не связанных в одном и том же слое) между двумя слоями, т. е.z_k^{l+1}иz_j^{l}только черезw_{kj}^{l+1}соединять. такz_k^{l+1}правильноz_j^{l}Результат частичного дифференцирования прост, простоw^{l+1}_{kj} \sigma'(z^l_j). довести этот результат до\delta_j^lсередина

\delta^l_j = \sum_k w^{l+1}_{kj }  \delta^{l+1}_k \sigma'(z^l_j)

Это именно то, что написано в компонентной форме (BP2).

записано в векторной форме

\delta^l = ((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l)

Пример

{ \left[  \begin{matrix}    \delta_{1}^l  \\    \\    \delta_{2}^l \\    \\    ...    \\   \delta_{j}^l   \end{matrix}   \right] }   = { \left[      \begin{matrix}        w_{11}^{l+1} & w_{21}^{l+1} & w_{31}^{l+1} & ... &w_{k1}^{l+1} \\        \\        w_{12}^{l+1} & w_{22}^{l+1} & w_{32}^{l+1} & ... & w_{k2}^{l+1} \\        \\        ...        \\        w_{j1}^{l+1} & w_{j2}^{l+1} & w_{j1}^{l+1} & ... & w_{kj}^{l+1}       \end{matrix}       \right] }    { \left[    \begin{matrix}      \delta_{1}^{l+1}  \\      \\      \delta_{2}^{l+1} \\      \\      \delta_{3}^{l+1} \\      \\      ...      \\     \delta_{k}^{l+1}     \end{matrix}     \right] }     \odot     { \left[     \begin{matrix}       \sigma'(z_1^l)  \\       \\       \sigma'(z_2^l) \\       \\       \sigma'(z_3^l) \\       \\       ...       \\      \sigma'(z_k^l)      \end{matrix}      \right] }

(BP2) доказано.

доказывать\frac{\partial C}{\partial b^l_j} =\delta^l_j.

в соответствии сz_j^lопределение

z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

и\delta_j^lопределение

\delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

следовательно

\frac{\partial C}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial b^l_j}

Также из-за

\frac{\partial z^l_j}{\partial b^l_j} = 1

так

\frac{\partial C}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial b^l_j} = \frac{\partial C}{\partial z^l_j}\cdot 1= \frac{\partial C}{\partial z^l_j}=\delta^l_j

который

\frac{\partial C}{\partial b^l_j} =\delta^l_j

записано в векторной форме

\frac{\partial C}{\partial b^l} =\delta^l

(BP3) доказано.

доказывать\frac{\partial C}{\partial w^l_{jk}} = a^{l-1}_k \delta^l_j

в соответствии сz_j^lопределение

z^l_j=\sum_k w^l_{jk} a^{l-1}_k+b^l_j

и\delta_j^lопределение

\delta^l_j \equiv \frac{\partial C}{\partial z^l_j}.

Также из-за

\frac{\partial z^l_j}{\partial w^l_{jk}} = a_k^{l-1}

так

\frac{\partial C}{\partial w^l_{jk}} = \frac{\partial C}{\partial z^l_j}\frac{\partial z^l_j}{\partial w^l_{jk}} = \delta^l_j a_k^{l-1}

векторизовать формулу

\frac{\partial C}{\partial w^l} = \delta^l (a^l)^T

Пример

\frac{\partial C}{\partial w^l} = { \left[  \begin{matrix}    \delta_{1}^l  \\    \\    \delta_{2}^l \\    \\    ...    \\   \delta_{j}^l   \end{matrix}   \right] }{ \left[      \begin{matrix}        a_{1}^{l-1} & a_{2}^{l-1} & ... &a_{k}^{l-1}       \end{matrix}       \right] }

(BP4) доказано.

Интуитивная схема:

На данный момент доказаны все четыре уравнения об обратном распространении.

Доказательство обратного распространения четырех уравнений другими учеными (он написал более кратко):CSDN: oio328Loio

Обратное распространение: общая картина

Как показано на рисунке выше, предположим, что у нас естьw_{jk}^lсделать небольшое возмущение\Delta w_{jk}^l, это возмущение в конечном итоге повлияет на функцию стоимости в нейронной сети.C, функция стоимости\Delta Cизменить и\Delta w_{jk}^lПодключить по следующей формуле

\Delta C \approx \frac{\partial C}{\partial w^l_{jk}} \Delta w^l_{jk}

Один путь, предположительно влияющий на функцию затрат, состоит в следующем.

\Delta C \approx \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}} \Delta w^l_{jk}

чтобы рассчитатьCВсе изменения в , нам нужно просуммировать все возможные пути, т.е.

\Delta C \approx \sum_{mnp\ldots q} \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}} \Delta w^l_{jk}

так как

\frac{\partial C}{\partial w^l_{jk}}=\frac{\Delta C}{\Delta w^l_{jk}}

Из приведенных выше трех уравнений видно, что

\frac{\partial C}{\partial w^l_{jk} } = \sum_{mnp\ldots q} \frac{\partial C}{\partial a^L_m}   \frac{\partial a^L_m}{\partial a^{L-1}_n}   \frac{\partial a^{L-1}_n}{\partial a^{L-2}_p} \ldots   \frac{\partial a^{l+1}_q}{\partial a^l_j}   \frac{\partial a^l_j}{\partial w^l_{jk}}

Приведенная выше формула выглядит сложной, и вот довольно хорошее интуитивное объяснение. Мы используем эту формулу для расчетаCО скорости изменения веса в сети. И что эта формула говорит нам, так это то, что связь между двумя нейронами на самом деле связана с коэффициентом скорости изменения, который является просто частной производной значения активации одного нейрона по отношению к значению активации других нейронов. Фактор скорости изменения пути является произведением многих факторов пути. общая скорость изменения\partial C / \partial w^l_{jk}представляет собой сумму факторов скорости изменения для всех возможных путей от начальных весов до конечного результата функции стоимости. Для определенного пути процесс поясняется следующим образом:

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

Если вы попытаетесь использовать приведенные выше идеи для доказательства обратного распространения, это будет намного сложнее, чем четыре уравнения обратного распространения в этой статье, потому что есть много мест, которые можно упростить в соответствии с приведенными выше идеями. Можно добавить один аккуратный шаг, объект частной производной приведенного выше уравнения выглядит примерно так:a_q^{l+1}значение активации. Хитрость заключается в том, чтобы вместо этого использовать взвешенный ввод, например.z_q^{l+1}, как промежуточная переменная. Если идея не пришла в голову, продолжайте использовать значение активацииa_q^{l+1}, доказательство, которое вы получите, будет немного сложнее, чем доказательство, приведенное выше.

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


использованная литература

[1] Michael Nielsen. CHAPTER 2 How the backpropagation algorithm works[DB/OL]. neuralnetworksanddeeplearning.com/chap2.html, 2018-06-21.

[2] Zhu Xiaohu. Zhang Freeman.Another Chinese Translation of Neural Networks and Deep Learning[DB/OL]. GitHub.com/Chapter Mandarin Edition/Можете ли вы…, 2018-06-21.

[3] oio328Loio, Обучение нейронной сети (3) Алгоритм обратного (BP) распространения (1) [DB/OL].blog.CSDN.net/HOHO1151191…, 2018-06-25.