了解TensorBoard(权重)直方图


120

在TensorBoard中查看和理解标量值确实非常简单。但是,尚不清楚如何理解直方图。

例如,它们是我的网络权重的直方图。

在此处输入图片说明

(在通过sunside修复错误后) 在此处输入图片说明 解释这些的最佳方法是什么?第1层的权重看起来基本上是平坦的,这意味着什么?

我在这里添加了网络构建代码。

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
我只是注意到您根本没有在最后一层使用激活。你可能是说tf.nn.softmax(tf.matmul(layer3_act, W4))
sunside

@sunside谢谢。事实证明,直方图对于调试也非常有用。我更新了图片。
Sung Kim

1
@SungKim我使用您的实现作为参考,但是如何添加偏见?像这样?B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())layer1_bias = tf.add(layer1, B1)tf.summary.histogram("bias", layer1_bias)
格特Kommer

1
@SungKim如果您仍有日志目录,可以将其上传到Aughie Boards吗?非常
高兴

@SungKim是否会通过定义代码来修复代码,input_size以便我们可以运行它并在tensorboard
Mario

Answers:


131

看来网络没有在第一到第三层学到任何东西。最后一层确实发生了变化,这意味着渐变可能有问题(如果您手动进行了篡改),则只能通过优化权重或最后一层来限制学习到最后一层,吞噬所有的错误。也可能是只有偏见才被发现。虽然网络似乎在学习一些东西,但它可能没有充分利用其潜力。这里需要更多的上下文,但是尝试学习率(例如使用较小的上下文)可能值得一试。

通常,直方图显示一个值相对于其他值的出现次数。简而言之,如果可能的值在的范围内,0..9并且您看到数量的峰值10该值0,则表示有10个输入采用该值0;与此相反,如果直方图显示的高原1对的所有值0..9,就意味着对于10个输入,每个可能值0..9发生正好一次。当您通过直方图的总和对所有直方图值进行归一化时,也可以使用直方图来可视化概率分布。如果这样做,您将直观地获得某个值(在x轴上)出现的可能性(与其他输入相比)。

现在layer1/weights,高原意味着:

  • 大多数权重在-0.15到0.15的范围内
  • (几乎)权重具有这些值中的任何一个(即,它们(几乎)均匀分布)

换句话说,几乎相同数量的权重具有值-0.150.00.15以及两者之间的一切。有些权重的值会稍小或高一些。简而言之,这看起来只是权重已使用均值为零且取值范围为-0.15..0.15... 的均匀分布进行了初始化。如果确实使用统一初始化,则这在尚未训练网络时很典型。

相比之下,layer1/activations形成类似钟形曲线(高斯)的形状:在这种情况下0,值以特定值为中心,但也可能大于或小于该值(由于对称,因此也可能更大或更小)。大多数值似乎在的平均值附近0,但值的范围从-0.80.8。我假设layer1/activations将当作批次中所有层输出的分布。您可以看到这些值确实会随着时间而变化。

第4层直方图没有告诉我任何具体信息。从形状上,它只是显示周围一些重量值-0.10.05并且0.25倾向于以较高的概率发生;原因可能是,每个神经元的不同部分实际上接收相同的信息,并且基本上是多余的。这可能意味着您实际上可以使用较小的网络,或者您的网络有可能学习更多的区别功能,以防止过度拟合。这些只是假设。

同样,如下面的评论中所述,请添加偏差单位。通过将它们排除在外,您正在将网络强制约束到可能无效的解决方案。


5
完全没有偏见可能是一个非常糟糕的主意-就像在试图通过(非常高维的)点云画一条线,但被迫通过值0一样;它可能会起作用,并且会为您提供一些解决方案,但是很可能它是一个坏的或根本错误的解决方案。
赛德赛

1
我很难从直方图中告诉你很多。(虽然更新了我的答案。)
海边

1
现在应该训练更长一些。特别是考虑到您的第一个结果,layer4/Qpred它看起来可能会变得更好。至于权重保持不变...我觉得有点可疑,但我现在无法理解。可能确实是正确的分布,但是鉴于根本没有任何变化,我很难相信。
sunside

1
@sunside有什么方法可以优先于偏差优先更新网络权重?由于偏差以及最后一层似乎确实吸收了所有错误。我有一个类似的问题,其中仅更新偏差,并且权重直方图保持相对不变。
mamafoku

2
如果在激活之前使用批处理规范,则没有偏见是可以的
Tosha
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.