TensorBoardのスカラー値を見て理解するのは本当に簡単です。ただし、ヒストグラムグラフを理解する方法は明確ではありません。
たとえば、これらは私のネットワークの重みのヒストグラムです。
(サンサイドのおかげでバグを修正した後) これらを解釈する最良の方法は何ですか?レイヤー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)
ネットワークは、レイヤー1から3で何も学習していないようです。最後のレイヤーは変更されるため、グラデーションに何か問題がある可能性があることを意味します(手動でそれらを改ざんしている場合)、その重みまたは最後のレイヤーのみを最適化することにより、最後のレイヤーへの学習を制限していますすべてのエラーを食い尽くす。また、バイアスのみが学習される可能性もあります。ネットワークは何かを学習しているように見えますが、潜在能力をフルに活用していない可能性があります。ここではより多くのコンテキストが必要になりますが、学習率を試してみること(たとえば、より小さい学習率を使用すること)は一見の価値があります。
一般に、ヒストグラムは、ある値が他の値に相対して出現する回数を表示します。簡単に言えば、可能な値が0..9
の範囲にあり、値10
に0
のスパイクが見られる場合、これは10個の入力が0
の値をとることを意味します。対照的に、ヒストグラムが1
のすべての値に対して0..9
のプラトーを示す場合、10個の入力に対して、それぞれの可能な値0..9
が発生することを意味します正確に 1回。また、ヒストグラムを使用して、すべてのヒストグラム値を合計で正規化するときに確率分布を視覚化することもできます。これを行うと、特定の値(x軸上)が(他の入力と比較して)表示される可能性を直感的に取得できます。
layer1/weights
の場合、プラトーは次のことを意味します。
別の言い方をすれば、ほぼ同じ数の重みの値は-0.15
、0.0
、0.15
およびその間のすべてです。わずかに小さい値または高い値を持つ重みがいくつかあります。要するに、これは、平均がゼロで値の範囲が-0.15..0.15
... giveまたはtakeの一様分布を使用して重みが初期化されているように見えます。実際に均一な初期化を使用する場合、これはネットワークがまだ訓練されていないときの典型です。
比較すると、layer1/activations
はベル曲線(ガウス)のような形状を形成します:値は特定の値(この場合は0
)を中心にしていますが、それよりも大きい場合も小さい場合もあります(対称的であるため、同様にそうです)。ほとんどの値は0
の平均付近に表示されますが、値の範囲は-0.8
から0.8
です。 layer1/activations
は、バッチ内のすべてのレイヤー出力の分布として取得されると想定しています。値は時間とともに変化することがわかります。
レイヤー4ヒストグラムでは、具体的なことはわかりません。図形から、-0.1
、0.05
、および0.25
の周囲のいくつかの重み値がより高い確率で発生する傾向があることが示されています。理由could be、各ニューロンの異なる部分が実際に同じ情報を取得し、基本的に冗長であるためです。これは、実際には小規模なネットワークを使用できること、またはネットワークが過剰適合を防止するためにより明確な機能を学習する可能性があることを意味します。ただし、これらは単なる仮定です。
また、以下のコメントですでに述べたように、バイアス単位を追加してください。それらを除外することにより、無効なソリューションにネットワークを強制的に制約します。