tensorflow python - Comprendre les histogrammes de TensorBoard(poids)




understand weights (2)

Il semble que le réseau n'a rien appris dans les couches un à trois. La dernière couche change, ce qui signifie qu'il peut y avoir quelque chose qui ne va pas avec les dégradés (si vous les manipulez manuellement), vous êtes contraint d'apprendre à la dernière couche en optimisant seulement ses poids ou la dernière couche vraiment ' mange 'toutes les erreurs. Il se pourrait aussi que seuls les biais soient appris. Le réseau semble toutefois apprendre quelque chose, mais il pourrait ne pas utiliser tout son potentiel. Plus de contexte serait nécessaire ici, mais jouer avec le taux d'apprentissage (par exemple en utilisant un plus petit) pourrait valoir la peine.

En général, les histogrammes affichent le nombre d'occurrences d'une valeur par rapport aux autres valeurs. Simplement parlant, si les valeurs possibles sont dans une plage de 0..9 et que vous voyez une pointe de 10 sur la valeur 0 , cela signifie que 10 entrées prennent la valeur 0 ; en revanche, si l'histogramme montre un plateau de 1 pour toutes les valeurs de 0..9 , cela signifie que pour 10 entrées, chaque valeur possible 0..9 se produit exactement une fois. Vous pouvez également utiliser des histogrammes pour visualiser les distributions de probabilité lorsque vous normalisez toutes les valeurs d'histogramme par leur somme totale; Si vous faites cela, vous obtiendrez intuitivement la vraisemblance avec laquelle une certaine valeur (sur l'axe des x) apparaîtra (par rapport aux autres entrées).

Maintenant pour layer1/weights , le plateau signifie que:

  • la plupart des poids sont dans la gamme de -0.15 à 0.15
  • il est (pour la plupart) également probable qu'un poids ait l'une de ces valeurs, c'est-à-dire qu'il soit (presque) uniformément réparti

Dit différemment, presque le même nombre de poids ont les valeurs -0.15 , 0.0 , 0.15 et tout le -0.15 . Certains poids ont des valeurs légèrement plus petites ou plus élevées. Bref, on dirait simplement que les poids ont été initialisés en utilisant une distribution uniforme avec une moyenne nulle et une plage de valeurs -0.15..0.15 ... donner ou prendre. Si vous utilisez effectivement une initialisation uniforme, cela est typique lorsque le réseau n'a pas encore été formé.

En comparaison, layer1/activations forme une courbe en forme de cloche (gaussienne): Les valeurs sont centrées autour d'une valeur spécifique, dans ce cas 0 , mais elles peuvent aussi être plus grandes ou plus petites (aussi probable, puisqu'elle est symétrique) . La plupart des valeurs semblent proches de la moyenne de 0 , mais les valeurs vont de -0.8 à 0.8 . Je suppose que la layer1/activations est prise comme la distribution sur toutes les sorties de couche dans un lot. Vous pouvez voir que les valeurs changent au fil du temps.

L'histogramme de la couche 4 ne me dit rien de spécifique. De la forme, cela montre juste que certaines valeurs de poids autour de -0.1 , 0.05 et 0.25 ont tendance à se produire avec une probabilité plus élevée; une raison pourrait être que différentes parties de chaque neurone recueillent la même information et sont fondamentalement redondantes. Cela peut signifier que vous pourriez réellement utiliser un plus petit réseau ou que votre réseau a le potentiel d'apprendre plus de caractéristiques distinctives afin d'empêcher le surajustement. Ce ne sont que des suppositions.

De plus, comme indiqué dans les commentaires ci-dessous, ajoutez des unités de biais. En les excluant, vous forcez votre réseau à trouver une solution potentiellement invalide.

Il est vraiment simple de voir et de comprendre les valeurs scalaires dans TensorBoard. Cependant, il n'est pas clair comment comprendre les graphiques d'histogramme.

Par exemple, ce sont les histogrammes de mes poids de réseau.

(Après avoir réparé un bug grâce à Sunside) Quelle est la meilleure façon de les interpréter? Les poids de couche 1 semblent plutôt plats, qu'est-ce que cela signifie?

J'ai ajouté le code de construction du réseau ici.

X = tf.placeholder(tf.float32, [None, input_size], name="input_x")
x_image = tf.reshape(X, [-1, 6, 10, 1])
tf.summary.image('input', x_image, 4)

# First layer of weights
with tf.name_scope("layer1"):
    W1 = tf.get_variable("W1", shape=[input_size, hidden_layer_neurons],
                         initializer=tf.contrib.layers.xavier_initializer())
    layer1 = tf.matmul(X, W1)
    layer1_act = tf.nn.tanh(layer1)
    tf.summary.histogram("weights", W1)
    tf.summary.histogram("layer", layer1)
    tf.summary.histogram("activations", layer1_act)

# Second layer of weights
with tf.name_scope("layer2"):
    W2 = tf.get_variable("W2", shape=[hidden_layer_neurons, hidden_layer_neurons],
                         initializer=tf.contrib.layers.xavier_initializer())
    layer2 = tf.matmul(layer1_act, W2)
    layer2_act = tf.nn.tanh(layer2)
    tf.summary.histogram("weights", W2)
    tf.summary.histogram("layer", layer2)
    tf.summary.histogram("activations", layer2_act)

# Third layer of weights
with tf.name_scope("layer3"):
    W3 = tf.get_variable("W3", shape=[hidden_layer_neurons, hidden_layer_neurons],
                         initializer=tf.contrib.layers.xavier_initializer())
    layer3 = tf.matmul(layer2_act, W3)
    layer3_act = tf.nn.tanh(layer3)

    tf.summary.histogram("weights", W3)
    tf.summary.histogram("layer", layer3)
    tf.summary.histogram("activations", layer3_act)

# Fourth layer of weights
with tf.name_scope("layer4"):
    W4 = tf.get_variable("W4", shape=[hidden_layer_neurons, output_size],
                         initializer=tf.contrib.layers.xavier_initializer())
    Qpred = tf.nn.softmax(tf.matmul(layer3_act, W4)) # Bug fixed: Qpred = tf.nn.softmax(tf.matmul(layer3, W4))
    tf.summary.histogram("weights", W4)
    tf.summary.histogram("Qpred", Qpred)

# We need to define the parts of the network needed for learning a policy
Y = tf.placeholder(tf.float32, [None, output_size], name="input_y")
advantages = tf.placeholder(tf.float32, name="reward_signal")

# Loss function
# Sum (Ai*logp(yi|xi))
log_lik = -Y * tf.log(Qpred)
loss = tf.reduce_mean(tf.reduce_sum(log_lik * advantages, axis=1))
tf.summary.scalar("Q", tf.reduce_mean(Qpred))
tf.summary.scalar("Y", tf.reduce_mean(Y))
tf.summary.scalar("log_likelihood", tf.reduce_mean(log_lik))
tf.summary.scalar("loss", loss)

# Learning
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)

De quoi parle cet avertissement?

Les processeurs modernes fournissent beaucoup d'instructions de bas niveau, outre l'arithmétique et la logique habituelles, connues sous le nom d'extensions, par exemple SSE2, SSE4, AVX, etc.

Advanced Vector Extensions ( AVX ) sont des extensions de l'architecture du jeu d'instructions x86 pour les microprocesseurs Intel et AMD proposés par Intel en mars 2008 et supportés par Intel avec le processeur Sandy Bridge au premier trimestre 2011 et plus tard par AMD avec le processeur Bulldozer au troisième trimestre 2011. AVX fournit de nouvelles fonctionnalités, de nouvelles instructions et un nouveau schéma de codage.

En particulier, AVX introduit des opérations FMA ( fusion multiple-accumulated ) qui accélèrent le calcul algébrique linéaire, à savoir le produit scalaire, la multiplication matricielle, la convolution, etc. Presque tous les entraînements mécaniques nécessitent une grande partie de ces opérations. plus rapide sur un processeur qui prend en charge AVX et FMA (jusqu'à 300%). L'avertissement indique que votre CPU supporte AVX (hourra!).

Je tiens à souligner ici: tout est sur le processeur seulement .

Pourquoi n'est-il pas utilisé alors?

Parce que la distribution par défaut tensorflow est construite sans extensions CPU , telles que SSE4.1, SSE4.2, AVX, AVX2, FMA, etc. Les builds par défaut (ceux de pip install tensorflow ) sont compatibles avec le plus de processeurs possible. Un autre argument est que même avec ces extensions, le CPU est beaucoup plus lent qu'un GPU, et on s'attend à ce que l'apprentissage de la machine à moyenne et grande échelle soit effectué sur un GPU.

Que devrais tu faire?

Si vous avez un GPU , vous ne devriez pas vous soucier de la prise en charge d'AVX, car les opérations les plus coûteuses seront envoyées sur un périphérique GPU (sauf si explicitement défini). Dans ce cas, vous pouvez simplement ignorer cet avertissement en

# Just disables the warning, doesn't enable AVX/FMA
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

... ou en réglant l' export TF_CPP_MIN_LOG_LEVEL=2 si vous utilisez Unix. Tensorflow fonctionne bien de toute façon, mais vous ne verrez pas ces avertissements agaçants.

Si vous n'avez pas de GPU et que vous souhaitez utiliser le processeur autant que possible, vous devez créer un tensorflow à partir de la source optimisée pour votre CPU avec AVX, AVX2 et FMA activés si votre CPU les prend en charge. Il a été discuté dans cette question et aussi ce problème GitHub . Tensorflow utilise un système de construction ad-hoc appelé bazel et construire ce n'est pas si trivial, mais c'est certainement faisable. Après cela, non seulement l'avertissement disparaîtra, mais les performances du tensorflow devraient également s'améliorer.







tensorflow histogram tensorboard