Processing math: 100%

3 votos

Rendimiento inferior de SELUs: ¿Cómo restringir correctamente los pesos de capa en TF/Keras?

La promesa de SELUs y SNNs

Primero leí acerca del 'poder' de SELUs en una publicación de blog de aprendizaje automático. La promesa de una Red Neural de Auto-normalización (SNN) suena demasiado buena para ser verdad; su capacidad para auto-normalizarse y auto-regularizarse internamente promete un diseño más simple de redes profundas y teóricamente resuelve tanto los gradientes que mueren como los que explotan.

Sin embargo, en mi experiencia no puede superar a las DNNs de ReLU, y en el caso de las CNNs profundas no aprende nada en absoluto.

La arquitectura de la red

Tengo una CNN profunda para la clasificación de imágenes de Places 365 (que están transformadas a escala de grises) que involucra 12 capas Conv2D y 3 capas Dense FC y una capa de salida adicional Dense FC.

Cuando se utilizan ReLUs puede lograr un 40% de precisión top-1 y un 70% de precisión top-5 en el conjunto de validación... pero cuando se utilizan SELUs la precisión (tanto en entrenamiento como en validación) converge a 1365 lo que sugiere que la salida no tiene sentido. Además, cuando se usan SELUs en esta red, la pérdida de entropía cruzada también converge a una constante (alrededor de 6).

  • Cuando usé SELUs utilicé la inicialización de pesos correcta LeCun Normal y la inicialización de sesgos en cero.
  • Intenté entrenar la red con varias regularizaciones habilitadas y deshabilitadas, incluyendo: dropout alpha, decaimiento de pesos y normalización por lotes.
  • También probé el optimizador Adam con diversas tasas de aprendizaje y valores de épsilon, y también el optimizador Adadelta con tasas de aprendizaje que varían de 1.0 (el valor correspondiente al comportamiento del paper original de Adadelta) a 0.001 (el valor predeterminado en Keras).
  • Estoy seguro de que mi proceso de entrada no está roto de ninguna manera; Verifiqué que al transformar de RGB a Lab, la red recibe un canal de Luminosidad con valores en el rango [0,1] y los datos de entrada pueden mostrarse correctamente usando pyplot.
  • También verifiqué que el comportamiento es el mismo independientemente de si se usa float16 o float32, y el comportamiento también es el mismo con o sin Softmax en la capa final (y el parámetro correspondiente from_logits esté correctamente establecido para la función de pérdida).

Mi Hipótesis

Según el paper que introduce SNNs y SELUs, su Teorema 1 establece que "...las redes SELU son auto-normalizantes bajo condiciones moderadas en los pesos."

Pero antes del teorema y la prueba, afirman que "Para la inicialización de pesos, proponemos = 0 y = 1 para todas las unidades en la capa superior. ... Por supuesto, durante el aprendizaje, estas suposiciones sobre el vector de peso se violarán. Sin embargo, podemos demostrar la propiedad de auto-normalización incluso para vectores de peso que no están normalizados, por lo tanto, la propiedad de auto-normalización se puede mantener durante el aprendizaje y los cambios de peso." Lo cual suena contradictorio para mí, ya que no se menciona que se necesite mantener esas condiciones después de la inicialización.

Por lo tanto, mi hipótesis es que estas 'condiciones moderadas' son más importantes de lo insinuado en el paper, y la falta de restricciones en los pesos de la capa (y tal vez sesgos) está resultando en el rendimiento deficiente de SELUs en la práctica.

Entonces, mi pregunta es cómo impongo restricciones en los pesos de la capa de manera que = 0 y = 1 durante el entrenamiento? Sé que las capas Dense y Conv2D de Keras tienen un parámetro kernel_constraint pero no estoy seguro de qué clase de keras.constraints, si hay alguna, puede cumplir con esta propiedad. ¿Es algo que no se puede hacer solo con el parámetro de restricciones y requiere algún otro método?

Editar:

He implementado una restricción de centralización de pesos como sugiere Redefiniendo la Propiedad de Auto-normalización que ajusta la matriz de pesos para cada capa con ˆW=Wmean(W). La red SELU ya no converge a una precisión de 1365 lo cual es una mejora, sin embargo, no sé qué tan bien funcionará con el tiempo. Estoy ejecutando el entrenamiento durante la noche y regresaré en ~12 horas con el código de la restricción si tiene éxito.

2voto

Avelina Puntos 333

Después de 12 horas usando el método de restricción de peso que sugerí en la edición de mi pregunta, el modelo ha seguido aprendiendo usando SELUs. Además, la pérdida de validación ha disminuido de manera mucho más estable que cuando se usaban ReLUs, aunque la convergencia es ligeramente más lenta.

Aquí está el código de restricción en tensorflow y la forma correspondiente de usarlo en las capas.

class CentralizacionPesos( keras.constraints.Constraint ):
    def __call__( self, w ):
        return w - tf.math.reduce_mean( w )

...

Conv2D(
    64,
    3,
    activation = 'selu',
    kernel_initializer = 'lecun_normal',
    kernel_constraint = CentralizacionPesos()
)

Espero que esto responda cualquier pregunta que otros pudieran haber tenido con problemas para que SELU funcione bien.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X