tensorflow - guide - ¿Cuál es el inicializador de kernel predeterminado en tf.layers.conv2d y tf.layers.dense?
tensorflow playground (2)
El documento oficial de la API de Tensorflow afirma que el parámetro kernel_initializer está predeterminado en None para tf.layers.conv2d y tf.layers.dense.
Sin embargo, al leer el tutorial de capas ( https://www.tensorflow.org/tutorials/layers ), noté que este parámetro no está configurado en el código. Por ejemplo:
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
El código de ejemplo del tutorial se ejecuta sin ningún error, por lo que creo que el
kernel_initializer
predeterminado no es
None
.
Entonces, ¿qué inicializador se usa?
En otro código, no configuré el
kernel_initializer
de las capas conv2d y densa, y todo estuvo bien.
Sin embargo, cuando intenté configurar
kernel_initializer
en
tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)
, obtuve errores de NaN.
¿Que esta pasando aqui?
¿Alguien puede ayudar?
De acuerdo con este curso de Andrew Ng y la documentación de Xavier , si está utilizando ReLU como función de activación, mejor cambie el inicializador de pesos predeterminado (que es uniforme de Xavier ) a Xavier normal :
y = tf.layers.conv2d(x, kernel_initializer=tf.contrib.layers.xavier_initializer(uniform=False), )
Gran pregunta! ¡Es todo un truco descubrirlo!
-
Como puede ver, no está documentado en
tf.layers.conv2d
-
Si observa la definición de
la función
, verá que la función llama
variable_scope.get_variable
:
En codigo:
self.kernel = vs.get_variable(''kernel'',
shape=kernel_shape,
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
trainable=True,
dtype=self.dtype)
Siguiente paso: ¿qué hace el alcance variable cuando el inicializador es Ninguno?
Aquí dice:
Si initializer es
None
(el predeterminado), se usa el inicializador predeterminado pasado en el constructor. Si ese también esNone
, usamos un nuevoglorot_uniform_initializer
.
Entonces la respuesta es: usa el
glorot_uniform_initializer
Para completar la definición de este inicializador:
El inicializador uniforme Glorot, también llamado inicializador uniforme Xavier. Toma muestras de una distribución uniforme dentro de [-limit, limit] donde
limit
essqrt(6 / (fan_in + fan_out))
dondefan_in
es el número de unidades de entrada en el tensor de peso yfan_out
es el número de unidades de salida en el peso tensor. Referencia: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
Editar: esto es lo que encontré en el código y la documentación. ¡Quizás pueda verificar que la inicialización se vea así ejecutando eval en los pesos!