Comprendre les histogrammes TensorBoard (poids)


120

Il est très 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.

entrez la description de l'image ici

(Après avoir corrigé un bug grâce à sunside) entrez la description de l'image ici Quelle est la meilleure façon de les interpréter? Les poids de la couche 1 semblent généralement 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)

4
Je viens de remarquer que vous n'utilisez pas du tout les activations sur la dernière couche. Vous vouliez probablement dire tf.nn.softmax(tf.matmul(layer3_act, W4)).
Sunside

@sunside Merci. Il s'avère que l'histogramme est également très utile pour le débogage. J'ai mis à jour les photos.
Sung Kim le

1
@SungKim J'utilise votre implémentation comme référence, mais comment ajouter le biais? Comme ça? B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())et layer1_bias = tf.add(layer1, B1)ettf.summary.histogram("bias", layer1_bias)
Gert Kommer

1
@SungKim si vous avez toujours le répertoire des journaux, pouvez-vous le télécharger sur Aughie Boards ? Ce serait formidable de voir les histogrammes dans un tableau de bord interactif
Agost Biro

@SungKim voudriez-vous corriger votre code en définissant input_sizeafin que nous puissions l'exécuter et voir le résultat danstensorboard
Mario

Réponses:


131

Il semble que le réseau n'ait rien appris dans les couches un à trois. La dernière couche change, ce qui signifie qu'il peut y avoir un problème avec les dégradés (si vous les trafiquez manuellement), vous contraignez l'apprentissage à la dernière couche en optimisant uniquement ses poids ou la dernière couche vraiment '' mange «toute erreur. Il se peut aussi que seuls les préjugés soient appris. Le réseau semble cependant apprendre quelque chose, mais il se peut qu'il n'utilise pas 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 le coup.

En général, les histogrammes affichent le nombre d'occurrences d'une valeur par rapport aux autres valeurs. Pour parler simplement, si les valeurs possibles sont dans une plage de 0..9et que vous voyez un pic de montant 10sur la valeur 0, cela signifie que 10 entrées prennent la valeur 0; en revanche, si l'histogramme montre un plateau de 1pour toutes les valeurs de 0..9, cela signifie que pour 10 entrées, chaque valeur possible 0..9apparaît 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 probabilité avec laquelle une certaine valeur (sur l'axe des x) apparaîtra (par rapport à d'autres entrées).

Maintenant layer1/weights, le plateau signifie que:

  • la plupart des poids sont compris entre -0,15 et 0,15
  • il est (généralement) également probable qu'un poids ait l'une de ces valeurs, c'est-à-dire qu'elles sont (presque) uniformément distribuées

Dit autrement, presque le même nombre de poids ont les valeurs -0.15, 0.0, 0.15et tout le reste. Certains poids ont des valeurs légèrement plus petites ou plus élevées. Donc, en bref, cela ressemble simplement à des 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/activationsforme une forme de courbe en cloche (gaussienne): les valeurs sont centrées autour d'une valeur spécifique, dans ce cas 0, mais elles peuvent également être plus grandes ou plus petites que cela (tout aussi probable, car 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 le layer1/activationsest considéré comme la distribution sur toutes les sorties de couche dans un lot. Vous pouvez voir que les valeurs changent avec le temps.

L'histogramme de la couche 4 ne me dit rien de spécifique. À partir de la forme, cela montre simplement que certaines valeurs de poids autour -0.1, 0.05et 0.25ont tendance à se produire avec une probabilité plus élevée; une raison pourrait être que différentes parties de chaque neurone captent en fait la même information et sont fondamentalement redondantes. Cela peut signifier que vous pouvez en fait utiliser un réseau plus petit ou que votre réseau a le potentiel d'apprendre plus de fonctionnalités distinctives afin d'éviter le surajustement. Ce ne sont cependant que des hypothèses.

De plus, comme déjà indiqué dans les commentaires ci-dessous, ajoutez des unités de biais. En les laissant de côté, vous contraignez avec force votre réseau à une solution éventuellement invalide.


5
Ne pas avoir de biais du tout peut être une très mauvaise idée - c'est vraiment comme essayer de tracer une ligne à travers un nuage de points (très dimensionnel), mais être forcé de passer par la valeur 0; cela pourrait fonctionner et vous donnera une solution, mais il y a de fortes chances que ce soit une mauvaise ou tout simplement une mauvaise solution.
sunside

1
Je ne peux malheureusement pas vous dire grand-chose de l'histogramme. (Mis à jour ma réponse cependant.)
sunside

1
Il devrait probablement s'entraîner un peu plus longtemps maintenant. Surtout compte tenu de vos premiers résultats, il layer4/Qpredsemble que cela pourrait être beaucoup mieux. Quant aux poids qui restent les mêmes ... Je trouve ça louche, mais je ne peux pas y donner un sens pour le moment. Peut-être que c'est vraiment la bonne distribution, mais étant donné qu'il n'y a pas du tout de changement, j'ai du mal à le croire.
Sunside

1
@sunside existe-t-il une méthode pour prioriser la mise à jour des pondérations du réseau par rapport aux biais? Comme les biais ainsi que la dernière couche semblent aspirer toute l'erreur. J'ai un problème similaire où seuls les biais sont mis à jour et l'histogramme de poids reste relativement inchangé.
mamafoku

2
Ne pas avoir de biais est acceptable si vous utilisez la norme de lot avant l'activation
Tosha
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.