理解张量板(权重)直方图

要查看和理解 TensorBoard 中的标量值非常简单。然而,如何理解直方图还不清楚。

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

enter image description here

(多亏 Sunside 修复了一个 bug) enter image description here 什么是最好的方法来解释这些? 第一层的权重看起来大部分是平的,这意味着什么?

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

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)
55793 次浏览

看起来网络还没有在第一层到第三层学到任何东西。最后一层确实发生了变化,这意味着要么是渐变出了问题(如果你手动修改的话) ,要么是通过优化权重将学习限制在最后一层,要么是最后一层真的“吞噬”了所有的错误。也可能只有偏见是后天习得的。不过,该网络似乎学到了一些东西,但它可能没有充分发挥其潜力。这里需要更多的上下文,但是玩玩学习速率(例如使用较小的速率)可能值得一试。

通常,直方图显示一个值相对于其他值出现的次数。简单地说,如果可能的值在 0..9的范围内,你看到值 0上有一个数值 10的峰值,这意味着10个输入假设值 0; 相反,如果直方图显示所有值 0..9的平台 1,这意味着对于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是作为一个批处理中所有层输出的分布。您可以看到这些值随着时间的推移而变化。

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

另外,正如下面的评论中已经说明的那样,请增加偏见单位。通过省略它们,您将强制地将您的网络限制为一个可能无效的解决方案。

在这里,我将通过给出一个最小的例子来间接地解释这个情节。下面的代码生成一个简单的张量板直方图图形。

from datetime import datetime
import tensorflow as tf
filename = datetime.now().strftime("%Y%m%d-%H%M%S")
fw = tf.summary.create_file_writer(f'logs/fit/{filename}')
with fw.as_default():
for i in range(10):
t = tf.random.uniform((2, 2), 1000)
tf.summary.histogram(
"train/hist",
t,
step=i
)
print(t)

我们看到,生成一个最大范围为1000的2x2矩阵将产生0-1000的值。这张量看起来像什么,我把它们的对数放在这里。

enter image description here

 tf.Tensor(
[[398.65747  939.9828  ]
[942.4269    59.790222]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[869.5309  980.9699 ]
[149.97845 454.524  ]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[967.5063   100.77594 ]
[ 47.620544 482.77008 ]], shape=(2, 2), dtype=float32)

我们登录了张量板10次。在图的右侧,生成一个时间线来指示时间步骤。直方图的深度表示哪些值是新的。较亮的/正面的值是较新的,较暗的/远的值是较旧的。

值被收集到桶中,桶由这些三角形结构表示。X 轴表示束所在的值的范围。