La documentation officielle de l'API Tensorflow affirme que le paramètre kernel_initializer est défini par défaut sur None pour tf.layers.conv2d et tf.layers.dense.
Cependant, en lisant le tutoriel sur les couches ( https://www.tensorflow.org/tutorials/layers ), j'ai constaté que ce paramètre n'était pas défini dans le code. Par exemple:
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
L'exemple de code du didacticiel s'exécute sans erreur. Je pense donc que kernel_initializer
par défaut n'est pas None
. Alors, quel initialiseur est utilisé?
Dans un autre code, je n'ai pas défini le kernel_initializer
des couches conv2d et dense, et tout allait bien. Cependant, lorsque j'ai essayé de définir le kernel_initializer
sur tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)
, des erreurs NaN se sont produites. Qu'est-ce qui se passe ici? Quelqu'un peut-il aider?
Bonne question! C'est tout un truc à découvrir!
tf.layers.conv2d
variable_scope.get_variable
: Dans du code:
self.kernel = vs.get_variable('kernel',
shape=kernel_shape,
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
trainable=True,
dtype=self.dtype)
Étape suivante: Que fait la portée de la variable lorsque l’initialiseur est défini sur None?
Ici on dit:
Si initializer est
None
(valeur par défaut), l’initialiseur par défaut est transmis le constructeur est utilisé. Si celui-ci est aussiNone
, nous utilisons un nouveauglorot_uniform_initializer
.
Donc, la réponse est: il utilise le glorot_uniform_initializer
Pour être complet, la définition de cet initialiseur:
L’initialiseur d’uniforme Glorot, également appelé initialiseur d’uniforme Xavier . Il tire des échantillons d'une distribution uniforme dans [-limit, limit] où
limit
estsqrt(6 / (fan_in + fan_out))
oùfan_in
est le nombre d'unités d'entrée dans le tenseur de poids etfan_out
est le nombre d'unités de sortie dans le tenseur de poids . Référence: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
Edit: voici ce que j'ai trouvé dans le code et la documentation. Peut-être pourriez-vous vérifier que l'initialisation ressemble à ceci en exécutant eval sur les poids!
Selon ce cours par Andrew Ng et la documentation Xavier , si vous utilisez ReLU comme fonction d’activation, changez l’initialiseur de poids par défaut (qui est Xavier uniform) Xavier normal par:
y = tf.layers.conv2d(x, kernel_initializer=tf.contrib.layers.xavier_initializer(uniform=False), )