Рубрики
Без рубрики

Отзывы о обратной обработке интуитивно объяснено – волшебный соус за нейронные сети!

Напоминание: код для этой серии учебных пособий можно найти на GitHub. Как и с другими сообщениями, de … с меткой MachineLearning, Python, учебник.

Напоминание: код для этой серии учебных пособий можно найти на Github Отказ

Как и с другими сообщениями, dev.to Иногда форматирует математику неправильно. Чтобы увидеть оригинальный пост с математикой, правильно оказанным отправиться на оригинальный пост Действительно

Это может быть самое важное пост в сериале, а также самые упущенные, как по той же причине – именно здесь математика получает Интересно Действительно Важно справиться с ним при взгляде на глубокие алгоритмы обучения – хотя позже вам, возможно, никогда не придется реализовать его вручную, благодаря силе глубокой структуры обучения, понимая, что это решающий При отладке вашей модели.

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

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

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

Зачем обратно для изучения весов?

Сначала он имеет смысл понимать, почему мы используем BackProp для вычисления производных в первую очередь. Нет лучших альтернатив?

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

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

Если бы мы проходили через сеть вперед, и рассмотрим вес от первого слоя, нам придется рассмотреть, как подталкивает, влияет на немедленные выходы – то есть 2-й слой, а затем то, как это подталкивает в 2-м слое, распространяется на 3-й слой и т. Д. Для 2-го уровня, которым мы должны были пересчитать все более поздние расчеты слоя, что дорого, поскольку частичные производные более поздних слоев используются снова. И снова, для весов в 3-м слое и так далее.

Поставить математику формально:

∂ J ∂ W [ 1 ] = ∂ A [ 1 ] ∂ W [ 1 ] ∂ A [ 2 ] ∂ A [ 1 ] [ ∂ A [ 3 ] ∂ A [ 2 ] . . . ∂ A [ L ] ∂ A [ L − 1 ] ∗ ∂ J ∂ A [ L ] ] \ frac {\ partial {j}} {\ partial {w ^ {[1]}}} = \ frac {\ partial {a ^ {[1]}}} {\ partial {w ^ {[1]}} } \ frac {\ partial {a ^ {[2]}}} {\ partial {a ^ {[1]}}}} [\ partial {A ^ {[3]}}} {\ partial {A ^ {[2]}}} … \ frac {\ partial {a ^ {[l]}}} {\ partial {a ^ {[l-1]}}} * \ frac {\ partial {j}} {\ partial {a ^ {[l] }}}] ∂ W [ 1 ] ∂ J ​ = ∂ W [ 1 ] ∂ A [ 1 ] ​ ∂ A [ 1 ] ∂ A [ 2 ] ​ [ ∂ A [ 2 ] ∂ A [ 3 ] ​ . . . ∂ A [ L − 1 ] ∂ A [ L ] ​ ∗ ∂ A [ L ] ∂ J ​ ]

∂ J ∂ W [ 2 ] = ∂ A [ 2 ] ∂ W [ 2 ] [ ∂ A [ 3 ] ∂ A [ 2 ] . . . ∂ A [ L ] ∂ A [ L − 1 ] ∂ J ∂ A [ L ] ] \ frac {\ partial {j}} {\ partial {w ^ {[2]}}} = \ frac {\ partial {a ^ {[2]}}} {\ partial {w ^ {[2]}} } [\ frac {\ partial {a ^ {[3]}}} {\ partial {a ^ {[2]}}} … \ frac {\ partial {a ^ {[l]}}}} {\ частичный {a ^ {[l-1]}}} \ frac {\ partial {j}} {\ partial {a ^ {[l]}}}] ∂ W [ 2 ] ∂ J ​ = ∂ W [ 2 ] ∂ A [ 2 ] ​ [ ∂ A [ 2 ] ∂ A [ 3 ] ​ . . . ∂ A [ L − 1 ] ∂ A [ L ] ​ ∂ A [ L ] ∂ J ​ ]

Обратите внимание, как термин в квадратных скобках (эффект пульсации «подтяжки» от 3-го уровня внутрь) одинаково для обоих уравнений. Так что, если мы вычислили термин Первый Затем вычисляли вес для первого и второго слоя?

В целом, при вычислении весов в слоях 1 … л 1 … л 1 Отказ . . л Мы будем повторно использовать те же вычисления с участием частичных производных из слоя л + 1 l + 1. l + 1 далее.

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

Кроме того: Связывание этого к другим областям информатики как способ взглянуть на основные принципы, это пример более общего принципа Динамическое программирование снизу вверх Отказ

Получение алгоритма обратной обработки

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

Полезно переформулировать советы, данные в обучении по почте градиентного происхождения:

  • Частичная производная интуиция : Думаю о y х \ frac {\ partial {y}} {\ partial {x}} х y свободно, как количественно, сколько у y y изменится, если вы дали ценность х х х немного “подталкиваю” в точке.
  • Разбиение вычислений – Мы можем использовать Правило цепи Чтобы помочь нам в наших вычислениях – вместо того, чтобы пытаться вычислить производное в одном палам, мы распадаем вычисление на более мелкие промежуточные шаги.
  • Вычислить правило цепочки – При думании о том, какие промежуточные значения включают в наше выражение правила цепочки, подумайте о немедленных выходах уравнений, связанных с х х х – какие другие значения напрямую влияют, когда мы немного подталкиваем х х х ?
  • Один элемент за раз – вместо того, чтобы беспокоиться о всей матрице A A А вместо этого мы посмотрим на элемент А Я J A_ {IJ} А Я J Отказ Одно уравнение мы будем ссылаться на время и время снова:

C i j = ∑ k A i k B k j ⟺ C = A . B C_ {ij} = \ sum_k a_ {ik} b_ {kj} \ iff. B C i j ​ = ∑ k ​ A i k ​ B k j ​ ⟺ C = A . B

Полезный совет при попытке перейти от одного элемента в матрицу – искать суммирование по повторным индексам (здесь это было K) – это говорит о матрице умножении.

Другое полезное уравнение – это элемент-мудрый продукт двух матриц:

C i j = A i j B i j ⟺ C = A ∗ B C_ {ij} {ij} b_ {ij} \ iff * b C i j ​ = A i j ​ B i j ​ ⟺ C = A ∗ B

  • Урочно проверьте размеры – Проверьте размеры матриц все совпадения (производная матрица должна иметь одинаковые размеры, что и оригинальная матрица, и все матрицы умножаются вместе, должны иметь размеры, которые выравниваются.

Обратнопропасывать через слой L:

Давайте сломаем наклейку в меньшие вычисления, что из одного конкретного слоя l l l . Давайте предположим, что мы вычислили ∂. J A [ л ] \ frac {\ partial {j}} {\ partial {a ^ {[l]}}} A [ л ] ∂. J – в общем алгоритме это распространяется назад от слоя л + 1 l + 1. l + 1 .

Нам нужно вычислить относительные частичные производные для этого слоя, чтобы иметь смысл напомнить себе о уравнениях из переднего прохода:

Z [ l ] = W [ l ] . A [ l − 1 ] + b [ l ] K ^ {[l]} ^ {[l]}. A ^ {[l-1]} + b ^ {[l] } Z [ l ] = W [ l ] . A [ l − 1 ] + b [ l ]

A [ l ] = g ( Z [ l ] ) A ^ {[l]} (z ^ {[l]}) A [ l ] = g ( Z [ l ] )

Сначала давайте рассмотрим, как вычислить J Z [ л ] \ frac {\ partial {j}} {\ partial {z ^ {[l]}}} ∂. Z [ л ] ∂. J . Рассмотреть один элемент Z Я j [ л ] Z ^ {[l]} _ {ij} Z Я j [ l ] – Поскольку мы применяем функцию активации g ( x ) g (x) g ( x ) индивидуально к каждому элементу в матрице, оттуда в Z. [ l ] i J Z ^ {[l]} {ij} Z [ l ] i J повлияет только на соответствующий активированный выход – A [ l ] i J A ^ {[l]} {ij} A [ l ] i j . Величина подталкивания А Я J A_ {IJ} А Я J по определению производной функции g ( x ) g (x) g ( x ) по стоимости Z Я J Z_ {ij} Z Я j . Итак, у нас есть:

d A [ l ] i j d Z [ l ] i j = g ′ ( Z i j [ l ] ) \ frac {da ^ {[l]} {ij}} {dz ^ {[l]} {ij}} ‘(z ^ {[l]} _ {ij}) d Z [ l ] i j d A [ l ] i j ​ = g ′ ( Z i j [ l ] ​ )

Мы можем применить правило цепи:

∂ J ∂ Z [ l ] i j = ∂ J ∂ A [ l ] i j ∗ g ′ ( Z i j [ l ] ) \ frac {\ partial {j}} {\ partial {z ^ {[l]} {ij}}} = \ frac {\ partial {j}} {\ partial {a ^ {[l]} {ij}} } * g ‘(z ^ {[l]} _ {ij}) ∂ Z [ l ] i j ∂ J ​ = ∂ A [ l ] i j ∂ J ​ ∗ g ′ ( Z i j [ l ] ​ )

Это просто элемент-мудрый продукт двух матриц – поскольку мы умножим соответствующие индексы i J _ {IJ} i j обеих матриц вместе. Таким образом, у нас есть наше уравнение:

∂ J ∂ Z [ l ] = ∂ J ∂ A [ l ] ∗ g ′ ( Z [ L ] ) \ frac {\ partial {j}} {\ partial {z ^ {[l]}}} = \ frac {\ partial {j}} {\ partial {a ^ {[l]}}} * g ‘(z ^ {[L]}) ∂ Z [ l ] ∂ J ​ = ∂ A [ l ] ∂ J ​ ∗ g ′ ( Z [ L ] )

Как чек здравомыслия, J A [ л ] \ frac {\ partial {j}} {\ partial {a ^ {[l]}}} A [ л ] ∂. J имеет те же размеры, что и A [ л ] A ^ {[l]} A [ л ] который имеет размеры n l n_l. n l х м м м , что такое же, как г ( Z [ Л ] ) g ‘(z ^ {[l]}) g ( Z [ Л ] ) Так как он применяет функциональный элемент-мудрый Так что сохраняет размеры Z [ Л ] Z ^ {[l]} Z [ L ] . Таким образом, размеры J Z [ л ] \ frac {\ partial {j}} {\ partial {z ^ {[l]}}} ∂. Z [ л ] ∂. J Сделайте матч с Z [ Л ] Z ^ {[l]} Z [ L ] .

Бриллиант! Далее давайте посмотрим на эффект подтягивания веса W j k [ л ] W ^ {[l]} _ {jk} W j k [ l ] . Чтобы упростить концептуализацию, давайте переписаним матрицы в терминах на индивидуальном уровне нейрона:

z l j = ∑ k = 1 n W j k [ l ] a k l − 1 + b j [ l ] z ^ {l} j =} ^ {n} w ^ {[l]} _ {jk} a ^ {l-1} _k + b ^ {[l]} _ j z l j = ∑ k = 1 n W j k [ l ] ​ a k l − 1 ​ + b j [ l ] ​

Это подталкивает W [ l ] j к W ^ {[l]} {jk} W [ l ] J к влияет на взвешенный вклад нейрона z [ l ] J z ^ {[l]} {j} z [ l ] J Во всех примерах в учебном наборе – мы возьмем средний градиент в примерах. Величина подталкивания к значению нейрона z [ l ] J z ^ {[l]} {j} z [ l ] J это – А [ л 1 ] к A ^ {[L-1]} {k} А [ л 1 Несомненно к раз подтолкнуть W [ l ] j к W ^ {[l]} {jk} W [ l ] j к С Варенье [ l ] j к W ^ {[l]} {jk} W [ l ] j к умножается на А k [ л 1 ] A ^ {[L-1]} _ {k} А k [ л 1 Несомненно в уравнении выше.

Также рассмотрим подталку в B [ l ] J b ^ {[l]} {j} b [ l ] J , величина соответствующего подталкивания к z [ l ] J z ^ {[l]} {j} z [ l ] J будет то же самое, и просто как с W j k [ л ] W ^ {[l]} _ {jk} W j k [ l ] Мы будем в среднем эффект подталкивания через примеры. Итак, у нас есть:

∂ J ∂ W [ l ] j k = 1 m ∑ i = 1 m ∂ J ∂ z l j ∗ ∂ z l j ∂ W [ l ] j k = 1 m ∑ i = 1 m ∂ J ∂ z l j ∗ a l − 1 k \ frac {\ partial {j}} {\ partial {w ^ {[l]} {jk}}} = \ frac {1} {m}} ^ {m} \ frac {\ partial {j}} {\ частичный {z ^ {l} {j}}}} * \ frac {\ partial {z ^ {l} {j}}} {\ partial {w ^ {[l]} {jk}}} = \ frac {1 } {m}} ^ {m} \ frac {\ partial {j}} {\ partial {z ^ {l} {j}}} * a ^ {l-1} {k} ∂ W [ l ] j k ∂ J ​ = m 1 ​ ∑ i = 1 m ∂ z l j ∂ J ​ ∗ ∂ W [ l ] j k ∂ z l j ​ = m 1 ​ ∑ i = 1 m ∂ z l j ∂ J ​ ∗ a l − 1 k

∂ J ∂ b [ l ] j = 1 m ∑ i = 1 m ∂ J ∂ z l j ∗ ∂ z l j ∂ b [ l ] j = 1 m ∑ i = 1 m ∂ J ∂ z j l \ frac {\ partial {j}} {\ partial {b ^ {[l]} {j}}} = \ frac {1} {m}} ^ {m}}} ^ {m} \ frac {\ partial {j}} {\ \ частичный {z ^ {l} {j}}}} * \ \ frac {\ partial {z ^ {l} {j}}} {\ partial {b ^ {[l]} {j}}} = \ frac {1 } {m}} ^ {m} \ frac {\ partial {j}} {\ partial {z ^ {l} _ {j}}} ∂ b [ l ] j ∂ J ​ = m 1 ​ ∑ i = 1 m ∂ z l j ∂ J ​ ∗ ∂ b [ l ] j ∂ z l j ​ = m 1 ​ ∑ i = 1 m ∂ z j l ​ ∂ J ​

Стоит отметить, что насколько похожи эти уравнения к логистическая регрессия – Просто вместо х х х У нас есть более общее А [ l 1 ] ^ {[L-1]} А [ л 1 ] Отказ Как мы упоминали на предыдущем посте, принципы для логистической регрессии просто масштабируются и обобщены для нейронной сети FeedForward.

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

∂ J ∂ W [ l ] j k = 1 m ∑ i = 1 m ∂ J ∂ Z [ l ] j i ∗ A [ l − 1 ] k i = 1 m ∑ ∗ i = 1 m ∂ J ∂ Z [ l ] ∗ j i ∗ A i k [ l − 1 ] T \ frac {\ partial {j}} {\ partial {w ^ {[l]} {jk}}} = \ frac {1} {m}} ^ {m} \ frac {\ partial {j}} {\ частичный {z ^ {[l]} {ji}}} * a ^ {[l-1]} {ki} = \ frac {1} {m}} ^ {m} \ frac {\ partial {j}} {\ partial {z ^ {[l]} * {ji}}} * a ^ {[l-1] t} _ {Ik} ∂ W [ l ] j k ∂ J ​ = m 1 ​ ∑ i = 1 m ∂ Z [ l ] j i ∂ J ​ ∗ A [ l − 1 ] k i = m 1 ​ ∑ ∗ i = 1 m ∂ Z [ l ] ∗ j i ∂ J ​ ∗ A i k [ l − 1 ] T ​

Это дает нам наши уравнения:

∂ J ∂ W j k [ l ] = 1 m ∂ J ∂ Z [ l ] . A [ l − 1 ] T \ frac {\ partial {j}} {\ partial {w ^ {[l]} _ {jk}}} = \ frac {1} {m} \ frac {\ partial {j}} {\ partial {z ^ ^ {[l]}}}. ^ {[l-1] t} ∂ W j k [ l ] ​ ∂ J ​ = m 1 ​ ∂ Z [ l ] ∂ J ​ . A [ l − 1 ] T

Как здравомыслие проверка: правая сторона умножает A n * l n * l n * л х м м м Матрица с м м м х n * л 1 n * {l-1} n * л 1 Матрица, давая n * л n * {l} n * л х n * л 1 n * {l-1} n * л 1 Матрица – поэтому размеры делают совпадение.

∂ J ∂ b [ l ] = 1 m ∑ i = 1 m ∂ J ∂ Z l \ frac {\ partial {j}} {\ partial {b ^ {[l]}}} = \ frac {1} {m}} ^ {m} \ frac {\ partial {j}} {\ partial {z ^ {l}}} ∂ b [ l ] ∂ J ​ = m 1 ​ ∑ i = 1 m ​ ∂ Z l ∂ J ​

Наконец, нам просто нужно учитывать, как градиент распространяется на слой л 1 L-1 l 1 – Нам не нужно было рассмотреть это в конкретном случае логистической регрессии, так как был только один слой.

Опять же, интуиция о частичных производных как «нюг» поможет нам. Давайте рассмотрим один нейрон в слое л 1 L-1 l 1 для Я т h I ^ {th} Я т H Пример: А л 1 k A ^ {l-1} k А л 1 k . Оттуда в этом нейроне влияет на все взвешенные входы нейронов для этого примера в следующем слое, поэтому нам придется суммировать частичные производные по нейронам. Величина подталкивающего в взвешенном входе z J л z ^ {l} _j z J l будет оригинальный подталкивающий, умноженный на соответствующий вес W [ l ] j к W ^ {[l]} {jk} W [ l ] J к Отказ Действительно, уравнение:

∂ J ∂ a l − 1 k = ∑ j = 1 n ∗ l ∂ J ∂ z l j ∂ z l j ∂ a l − q j = ∑ ∗ j = 1 n l ∂ J ∂ z l ∗ j ∗ W j k [ l ] \ frac {\ partial {j}} {\ partial {a ^ {l-1} {k}}}} ^ {n * l} \ frac {\ partial {j}} {\ partial {z ^ {l} {j}}} \ frac {\ partial {z ^ {l} {j}}} {\ partial {a ^ {_} {j}}} =} ^ {n_l} \ frac {\ partial {j}} {\ partial {z ^ {l} * {j}}} * w ^ {[l]} _ {jk} ∂ a l − 1 k ∂ J ​ = ∑ j = 1 n ∗ l ∂ z l j ∂ J ​ ∂ a l − q j ∂ z l j ​ = ∑ ∗ j = 1 n l ​ ∂ z l ∗ j ∂ J ​ ∗ W j k [ l ] ​

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

∂ J ∂ A [ l − 1 ] k i = ∑ j = 1 n ∗ l W [ l ] j k ∂ J ∂ z [ l ] j i = ∑ ∗ j = 1 n ∗ l W [ l ] T ∗ k j ∂ J ∂ z j i [ l ] \ frac {\ partial {j}} {\ partial {a ^ {[l-1]} {ki}}} =} ^ {n * l} w ^ {[l]} {jk} _ \ frac {\ \ частичный {j}} {\ partial {z ^ {[l]} {yi}}} =} ^ {n * l} w ^ {[l] t} * {kj} _ \ frac {\ partial {j} } {\ partial {z ^ {[l]} _ {ji}}} ∂ A [ l − 1 ] k i ∂ J ​ = ∑ j = 1 n ∗ l W [ l ] j k ∂ z [ l ] j i ∂ J ​ ​ = ∑ ∗ j = 1 n ∗ l W [ l ] T ∗ k j ∂ z j i [ l ] ​ ∂ J ​ ​

Так как матричное умножение:

∂ J ∂ A [ l − 1 ] = W [ l ] T . ∂ J ∂ z [ l ] \ frac {\ partial {j}} {\ partial {a ^ {[l-1]}}} ^ {[l] t}. \ frac {\ partial {j}} {\ partial {z ^ {[l ]}}} ∂ A [ l − 1 ] ∂ J ​ = W [ l ] T . ∂ z [ l ] ∂ J ​

Опять как здравомыслие проверка: правая сторона умножает A n * л 1 n * {l-1} n * л 1 х n l n_l. n l Матрица с n l n_l. n l х м м м Матрица, давая n * л 1 n * {l-1} n * л 1 х м м м Матрица – поэтому размеры делают совпадение.

Теперь посмотрев на корпус общего слоя, давайте посмотрим на последний слой сети. Некоторые потенциальные активы конечного уровня:

  • Нет активации – для регрессии
  • Сигмоид – для бинарной классификации
  • Softmax – для многоклассных классификаций

Для регрессии и бинарной классификации, как мы показали ранее – J Z [ L ] = Y ^ Y \ frac {\ partial {j}} {\ partial {z ^ {[l]}}} = \ hat {y} – y ∂. Z [ Л ] ∂. J = Y ^ У

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

В целом, хотя для любой функции активации выходного слоя вы можете получить J A [ L ] \ frac {\ partial {j}} {\ partial {a ^ {[l]}}} A [ Л ] ∂. J Из уравнения функции потерь напрямую, поскольку A [ L ] = Y ^ A ^ {[l]} = \ Hat {y} A [ L ] = Y ^ , а потом как в общем случае вы можете вычислить g ( Z [ Л ] ) g ‘(z ^ {[l]}) g ( Z [ L ] ) Для любой функции активации используется в выходном слое и перейти оттуда.

И там у вас есть! Вы успешно вывели обратное распространение для нейронной сети – нет среднего подвига!

Чтобы повторить, ключевые уравнения:

∂ J ∂ Z [ l ] = ∂ J ∂ A [ l ] ∗ g ′ ( Z [ L ] ) \ frac {\ partial {j}} {\ partial {z ^ {[l]}}} = \ frac {\ partial {j}} {\ partial {a ^ {[l]}}} * g ‘(z ^ {[L]}) ∂ Z [ l ] ∂ J ​ = ∂ A [ l ] ∂ J ​ ∗ g ′ ( Z [ L ] )

∂ J ∂ W [ l ] = 1 m ∂ J ∂ Z [ l ] . A [ l − 1 ] T \ frac {\ partial {j}} {\ partial {w ^ {[l]}}} = \ frac {1} {m} \ frac {\ partial {j}} {\ partial {z ^ {[l] }}}. ^ {[L-1] t} ∂ W [ l ] ∂ J ​ = m 1 ​ ∂ Z [ l ] ∂ J ​ . A [ l − 1 ] T

∂ J ∂ b [ l ] = 1 m ∑ i = 1 m ∂ J ∂ Z l \ frac {\ partial {j}} {\ partial {b ^ {[l]}}} = \ frac {1} {m}} ^ {m} \ frac {\ partial {j}} {\ partial {z ^ {l}}} ∂ b [ l ] ∂ J ​ = m 1 ​ ∑ i = 1 m ​ ∂ Z l ∂ J ​

∂ J ∂ A [ l − 1 ] = W [ l ] T . ∂ J ∂ Z [ l ] \ frac {\ partial {j}} {\ partial {a ^ {[l-1]}}} ^ {[l] t}. \ frac {\ partial {j}} {\ partial {z ^ {[l ]}}} ∂ A [ l − 1 ] ∂ J ​ = W [ l ] T . ∂ Z [ l ] ∂ J ​

Код:

Мы храним промежуточные результаты прохода вперед в кэше, то мы храним градиентов в другом словаре. Код для алгоритма backprop – это просто реализация уравнения, которое мы получили.

Примечание. Функция активации, используемая для промежуточного слоя, является RELU. Производное R е L U ( x ) RELU (X) R свидетельствовать L U ( x ) 1 если х > 0 х> 0. х > 0 Так как это линейно в этой области, и 0 В противном случае, поскольку график там плоский, как мы зажимаем все отрицательные значения до нуля. NB: технически на х = 0 х = 0 х = 0. Производное не определено, но на практике мы берем его на 0.

Как и прежде, сопроводительный код в ноутбук Отказ

def backpropagation(cache,Y,parameters):
    L = len(parameters)//2
    m = Y.shape[1]
    grads = {}
    grads["dZ" + str(L)]= cache["A" + str(L)] - Y
    grads["dW" + str(L)]= (1/m)*np.dot(grads["dZ" + str(L)],cache["A" + str(L-1)].T)
    grads["db" + str(L)]= (1/m)*np.sum(grads["dZ" + str(L)],axis=1,keepdims=True)
    for l in range(L-1,0,-1):
        grads["dA" + str(l)]= np.dot(parameters["W" + str(l+1)].T,grads["dZ" + str(l+1)])
        grads["dZ" + str(l)]= np.multiply(grads["dA" + str(l)], relu(cache["Z" + str(l)], deriv = True))
        grads["dW" + str(l)]= (1/m)*np.dot(grads["dZ" + str(l)],cache["A" + str(l-1)].T)
        grads["db" + str(l)]= (1/m)*np.sum(grads["dZ" + str(l)],axis=1,keepdims=True)
    return grads

Вывод

Давайте сделаем шаг назад здесь и просто ценю красота обратной обработки.

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

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

Оригинал: “https://dev.to/mukulrathi_/backpropagation-the-magic-sauce-behind-neural-networks-1f0g”