web-dev-qa-db-fra.com

Quel est l'initialiseur de noyau par défaut dans tf.layers.conv2d et tf.layers.dense?

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?

51
daniszw

Bonne question! C'est tout un truc à découvrir!

  • Comme vous pouvez le constater, cela n’est pas documenté dans tf.layers.conv2d
  • Si vous regardez la définition de la fonction vous voyez que la fonction appelle 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 aussi None, nous utilisons un nouveau glorot_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 est sqrt(6 / (fan_in + fan_out))fan_in est le nombre d'unités d'entrée dans le tenseur de poids et fan_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!

82
rmeertens

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), )
0
xtluo