Propagación inversa de gradiente a través de conexiones de omisión de ResNet

22

Tengo curiosidad acerca de cómo los gradientes se propagan hacia atrás a través de una red neuronal utilizando módulos ResNet / conexiones de omisión. He visto un par de preguntas sobre ResNet (por ejemplo, red neuronal con conexiones de capa de salto ), pero esta pregunta específicamente sobre la propagación hacia atrás de gradientes durante el entrenamiento.

La arquitectura básica está aquí:

ingrese la descripción de la imagen aquí

Leí este documento, Estudio de redes residuales para el reconocimiento de imágenes , y en la Sección 2 hablan sobre cómo uno de los objetivos de ResNet es permitir una ruta más corta / más clara para que el gradiente se propague hacia atrás a la capa base.

¿Alguien puede explicar cómo fluye el gradiente a través de este tipo de red? No entiendo cómo la operación de adición, y la falta de una capa parametrizada después de la adición, permite una mejor propagación del gradiente. ¿Tiene algo que ver con cómo el gradiente no cambia cuando fluye a través de un operador de suma y de alguna manera se redistribuye sin multiplicación?

Además, puedo entender cómo se alivia el problema del gradiente de fuga si el gradiente no necesita fluir a través de las capas de peso, pero si no hay flujo de gradiente a través de los pesos, ¿cómo se actualizan después del paso hacia atrás?

Simon
fuente
Solo una pregunta idiota: ¿Por qué pasamos x como conexión de salto y no calcula inversa (F (x)) para obtener x al final? ¿Es causa de complejidad computacional?
Yash Kumar Atri
No entendí tu punto the gradient doesn't need to flow through the weight layers, ¿podrías explicar eso?
anu

Respuestas:

13

Agregar envía el gradiente de nuevo por igual a ambas entradas. Puede convencerse de esto ejecutando lo siguiente en tensorflow:

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))

Salida:

[1.0, 1.0]

Entonces, el gradiente será:

  • pasado de nuevo a las capas anteriores, sin cambios, a través de la conexión de salto de capa, y también
  • pasó al bloque con pesas, y se utiliza para actualizar esos pesos

Editar: hay una pregunta: "¿cuál es la operación en el punto donde la conexión de la autopista y el bloque de la red neuronal se unen nuevamente, en la parte inferior de la Figura 2?"

La respuesta es: se resumen. Puede ver esto en la fórmula de la Figura 2:

outputF(x)+x

Lo que esto dice es que:

  • x
  • xF(x)
  • output

Edición 2:

Reescribiendo en palabras ligeramente diferentes:

  • en la dirección hacia adelante, los datos de entrada fluyen por el bus
    • en puntos a lo largo del bus, los bloques residuales pueden aprender a agregar / eliminar valores al vector del bus
  • en la dirección hacia atrás, los gradientes fluyen de regreso por el autobús
    • En el camino, los gradientes actualizan los bloques residuales que pasan
    • los bloques residuales también modificarán ligeramente los gradientes

Los bloques residuales modifican los gradientes que fluyen hacia atrás, pero no hay funciones de 'aplastamiento' o 'activación' por las que fluyen los gradientes. Las funciones de 'aplastamiento' / 'activación' son las que causan el problema del gradiente de explosión / desaparición, por lo que al eliminarlas del bus mismo, mitigamos este problema considerablemente.

Edición 3: Personalmente, imagino un resnet en mi cabeza como el siguiente diagrama. Es topológicamente idéntico a la figura 2, pero muestra más claramente tal vez cómo el bus fluye directamente a través de la red, mientras que los bloques residuales simplemente tocan los valores de él y agregan / eliminan algún pequeño vector contra el bus:

ingrese la descripción de la imagen aquí

Hugh Perkins
fuente
1
si el gradiente también se pasa a través de los bloques de peso (al igual que en las redes normales), ¿de dónde proviene el beneficio de la red? claro, permite que el gradiente salte directamente a la entrada base, pero ¿cómo ofrece eso un aumento de rendimiento cuando la otra ruta todavía está entrenada de manera normal?
Simon
3
Veo. Entonces, un gradiente salta directamente a x, el otro se propaga a través de los pesos a x. ¿se resumen cuando alcanzan x debido a que x se ha dividido en 2 caminos? Si es así, ¿el gradiente todavía no cambia a medida que retrocede a través de estas capas?
Simon
1
Los gradientes fluyen por la pila, sin cambios. Sin embargo, cada bloque aporta sus propios cambios de gradiente en la pila, después de aplicar sus actualizaciones de peso y generar su propio conjunto de gradientes. Cada bloque tiene entrada y salida, y los gradientes fluirán fuera de la entrada, de regreso a la "autopista" de gradiente.
Hugh Perkins
1
@RonakAgrawal agregó una edición que muestra la suma de la operatoína de la Figura 2 y lo explica
Hugh Perkins,
1
agregó una segunda edición reformulando un poco mi explicación :)
Hugh Perkins