Обратное распространение градиента через пропускаемые соединения ResNet


22

Мне любопытно, как градиенты распространяются обратно через нейронную сеть с помощью модулей ResNet / пропуска соединений. Я видел пару вопросов о ResNet (например, Нейронная сеть с пропускаемыми соединениями ), но этот вопрос специально задает о обратном распространении градиентов во время обучения.

Основная архитектура здесь:

введите описание изображения здесь

Я прочитал эту статью, Изучение остаточных сетей для распознавания изображений , и в Разделе 2 они рассказывают о том, как одна из целей ResNet состоит в том, чтобы обеспечить более короткий / более четкий путь для градиента для обратного распространения к базовому слою.

Может кто-нибудь объяснить, как градиент течет через этот тип сети? Я не совсем понимаю, как операция добавления и отсутствие параметризованного слоя после добавления обеспечивает лучшее распространение градиента. Имеет ли это какое-то отношение к тому, как градиент не изменяется при прохождении через оператор добавления и как-то перераспределяется без умножения?

Кроме того, я могу понять, как облегчается проблема исчезающего градиента, если градиент не должен течь через весовые слои, но если нет градиентного потока через веса, то как они обновляются после обратного прохода?


Просто идиотский вопрос: почему мы передаем x как пропущенное соединение и не вычисляем обратное (F (x)), чтобы получить x в конце. Является ли это причиной вычислительной сложности?
Яш Кумар Атри

Я не понял вашу точку зрения the gradient doesn't need to flow through the weight layers, не могли бы вы объяснить это?
ана

Ответы:


13

Add отправляет градиент обратно одинаково на оба входа. Вы можете убедиться в этом, запустив следующее в tenorflow:

import tensorflow as tf

graph = tf.Graph()
with graph.as_default():
    x1_tf = tf.Variable(1.5, name='x1')
    x2_tf = tf.Variable(3.5, name='x2')
    out_tf = x1_tf + x2_tf

    grads_tf = tf.gradients(ys=[out_tf], xs=[x1_tf, x2_tf])
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        fd = {
            out_tf: 10.0
        }
        print(sess.run(grads_tf, feed_dict=fd))

Выход:

[1.0, 1.0]

Итак, градиент будет:

  • передается обратно на предыдущие слои без изменений через соединение с пропуском слоев, а также
  • передается в блок с весами и используется для обновления этих весов

Изменить: возникает вопрос: «что такое операция в точке, где соединение шоссе и блок нейронной сети снова соединяются вместе, внизу рисунка 2?»

Там ответ: они суммируются. Вы можете увидеть это из формулы на рисунке 2:

outputF(x)+x

Это говорит о том, что:

  • значения в автобусе (x
  • xF(x)
  • чтобы дать вывод из остаточного блока, который я пометил здесь как output

Изменить 2:

Переписываем несколько разными словами:

  • в прямом направлении входные данные передаются по шине
    • в точках вдоль шины остаточные блоки могут научиться добавлять / удалять значения к вектору шины
  • в обратном направлении градиенты стекают обратно по шине
    • по пути градиенты обновляют остаточные блоки, которые они проходят мимо
    • остаточные блоки сами тоже немного изменят градиенты

Остаточные блоки изменяют градиенты, текущие в обратном направлении, но нет функций «сдавливания» или «активации», через которые проходят градиенты. Функции «раздавливания» / «активации» - вот что вызывает проблему разрыва / исчезновения градиента, поэтому, удаляя их из самой шины, мы значительно смягчаем эту проблему.

Редактировать 3: Лично я представляю реснет в моей голове, как на следующей диаграмме. Он топологически идентичен рисунку 2, но, возможно, более четко показывает, как шина протекает прямо через сеть, в то время как остаточные блоки просто отбирают значения из нее и добавляют / удаляют некоторый маленький вектор по отношению к шине:

введите описание изображения здесь


1
если градиент также пропускается через блоки веса (как в обычных сетях), то откуда выгода от перезапуска? Конечно, он позволяет градиенту пропускать непосредственно к базовому входу, но как это дает увеличение производительности, когда другой путь все еще обучается как обычно?
Симон

3
Понимаю. Таким образом, один градиент пропускает прямо обратно к x, другой распространяется через веса обратно к x. они суммируются, когда достигают x из-за разделения x на 2 пути? если так, то не меняется ли градиент, когда он возвращается через эти слои?
Симон

1
Градиенты текут вниз по стеку без изменений. Однако каждый блок вносит свои собственные изменения градиента в стек после применения обновлений весов и генерации своего собственного набора градиентов. Каждый блок имеет как вход, так и выход, и градиенты будут вытекать из входа обратно в градиентную "магистраль".
Хью Перкинс

1
@RonakAgrawal добавила редактирование, показывающее сумму операций из рисунка 2, и объяснение этого
Хью Перкинс

1
добавил второе редактирование, немного перефразируя мое объяснение :)
Хью Перкинс,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.