Hice una red neuronal convolucional y quería comprobar que mis gradientes se calculan correctamente utilizando la comprobación numérica de gradiente. La pregunta es, ¿qué tan cerca está lo suficientemente cerca?
Mi función de verificación solo escupe la derivada calculada, la derivada aproximada numéricamente, la diferencia entre los dos y si los dos valores tienen o no el mismo signo (uno es positivo y el otro negativo es un gran no-no) para cada uno peso.
La principal preocupación que tengo es que para todas las capas completamente conectadas y todas las capas convolucionales, excepto la primera, las diferencias se ven similares: los primeros 9-13 caracteres de los dos números coincidirán. Eso suena bastante bien, ¿verdad? Pero para los pesos de la primera capa convolucional, a veces obtengo hasta 12 decimales para que coincidan, pero también puede ser tan bajo como solo 3. ¿Es eso suficiente o podría haber un posible error?
Una cosa buena a tener en cuenta es que el signo de los dos valores siempre coincide, lo que es bueno, por lo que la red siempre hará movimientos en la dirección correcta, incluso si la magnitud del movimiento es un poco diferente. Pero esa es la pregunta ... ¿hay alguna posibilidad de que esté apagado?
flatten
método.Teoría de antecedentes que es útil
Un pequeño hecho que puede usar para ayudar a comprender si una derivada numérica se calcula correctamente o no es el resto Cauchy de la expansión de Taylor. Es decir,
Esto es útil, porque probablemente haya aproximado su primera derivada por
con un poco de (normalmente uso , pero estoy seguro de que algún día me encontraré con un caso en el que no es apropiado).h 10−4
Después de un poco de álgebra, podemos usar el resto de Cauchy para ver que nuestra aproximación numérica en teoría debería estar dentro de de .hf′′(ξ),ξ∈[x−h,x+h] f′(x)
De hecho, puedes vincularlo con , donde y ... que es equivalente a , .h(f′′(ξ1)−f′′(ξ2)) ξ1∈[x−h,x] ξ2∈[x,x+h] h2f′′′(ξ) ξ∈[x−h,x+h]
Problemas en la práctica
De acuerdo, tenemos una buena teoría que limita el error de la derivada numérica. Pero hay dos agujeros en tratar directamente de usar esos resultados:
1.) No sabemos (y probablemente no queremos pasar el tiempo aproximándolo)f′′′(x)
2.) como , sufre de inestabilidad numéricah→0 f(x+h)−f(x−h)2h
Entonces, usando lo que sabemos de la forma en que verifico mis derivadas analíticas (que podría no ser la mejor manera) es escribir la función de derivada numérica como una función de . Si no puedo decir si la diferencia entre las derivadas numéricas y analíticas se debe a un error de codificación o simplemente a una aproximación numérica, puedo reducir y ver si mi derivada numérica se acerca a mi derivada analítica antes de sufrir inestabilidad numérica (cuando esto sucede, sus aproximaciones numéricas serán menos consistentes a medida que haga más pequeña). Tenga en cuenta que el término debería desaparecer cuadráticamente, por lo que si mi error es aproximadamente conh h h f′′′(ξ) 0.01 h=10−4 , debe estar alrededor de con suponiendo que la inestabilidad numérica aún no haya comenzado .0.0001 h=10−5
Desafortunadamente, no hay una guía dura y rápida para determinar siempre estas cosas; depende mucho de cuán estable sea la función (y me refiero a ambos en términos de estabilidad numérica y derivados más altos). Pero en mi experiencia, nunca he visto un caso en el que el error de no fuera definitivamente a 0 (es decir, usar dio prácticamente la misma respuesta que ) para cuando la inestabilidad numérica de entró en acción.h2f′′′(ξ) h=10−4 h=10−5 h→0
fuente
Consulte este tutorial http://cs231n.github.io/neural-networks-3/#ensemble . La sección "Verificación de degradado" es muy detallada y útil.
Como sugiere gung, incluyo los puntos principales de este enlace:
Utilice aproximación, donde .f(w+h)−f(w−h)2h h∼10−5
Monitoree la fracción de , donde es el gradiente analítico y es el gradiente numéricamente aproximado. Por lo general, el rango preferido de esta fracción debería ser .|f′a(w)−f′n(w)|max(|f′a(w)|,|f′n(w)|) f′a(w) f′n(w) <10−2
Use doble precisión en lugar de flotación.
Mente de torcedura (s) en las funciones de activación, por ejemplo, cuando uno usa ReLU. Cuando hay torceduras, uno necesita monitorear los valores de y . Si estos dos valores están en dos lados de un pliegue, uno debería excluir esta verificación de gradiente.x=0 x−h x+h
Use pocos puntos de datos.
No verifique el gradiente en la etapa inicial del proceso de capacitación.
Primero verifique el modelo sin regularización y luego con él.
Apague el abandono y el abandono invertido al hacer la verificación de gradiente.
Solo verifique al azar algunas dimensiones.
fuente