TensorBoard(ウェイト)ヒストグラムについて


120

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)

4
最後のレイヤーでアクティベーションをまったく使用していないことに気づきました。たぶんtf.nn.softmax(tf.matmul(layer3_act, W4))
2017

@sunsideありがとう。ヒストグラムはデバッグにも非常に役立ちます。写真を更新しました。
Sung Kim

1
@SungKim実装を参照として使用していますが、バイアスをどのように追加しますか?このような?B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())and layer1_bias = tf.add(layer1, B1)およびtf.summary.histogram("bias", layer1_bias)
Gert Kommer 2017

1
@SungKimにまだログディレクトリがある場合、それをAughie Boardsにアップロードできますか?ヒストグラムをインタラクティブなダッシュボードで見るのは素晴らしいことです
Agost Biro

@SungKimを定義してコードを修正し、input_size実行して結果を確認できるようにしますtensorboard
Mario

回答:


131

ネットワークはレイヤ1〜3で何も学習していないようです。最後のレイヤーは変更されるため、グラデーションに何らかの問題がある可能性があります(手動で変更している場合)、重みのみを最適化することによって、または最後のレイヤーを本当に最適化することで、学習を最後のレイヤーに制限しています 'すべてのエラーを食い尽くす。また、バイアスのみが学習される場合もあります。ネットワークは何かを学んでいるように見えますが、その潜在能力を最大限に活用しているとは限りません。ここではより多くのコンテキストが必要になりますが、学習率をいじって(たとえば、より小さなものを使用して)試してみる価値があるかもしれません。

一般に、ヒストグラムは、他の値と比較した値の出現回数を表示します。簡単に言えば、可能な値がの範囲内に0..9あり10、値にスパイクが見られる場合0、これは10個の入力が値を想定していることを意味します0。対照的に、ヒストグラムが1のすべての値のプラトーを示している場合0..9、これは、10個の入力に対して、可能な各値0..9正確に発生することを意味します一回。また、ヒストグラムを使用して、すべてのヒストグラム値を合計で正規化するときに確率分布を視覚化することもできます。これを行うと、(他の入力と比較して)特定の値(x軸上)が表示される可能性が直感的に得られます。

ここでlayer1/weights、高原とは次のことを意味します。

  • ほとんどの重みは-0.15から0.15の範囲です
  • 重みがこれらの値のいずれかを(ほとんど)等しくする可能性があります。つまり、(ほぼ)均一に分布しています

重みのほぼ同じ数が値を持って、違ったと述べ-0.150.00.15との間のすべてを。値がわずかに小さいまたは大きい重みがあります。つまり、これは単純に、平均値と値の範囲が0である均一分布を使用して重みが初期化されているように見え-0.15..0.15ます。実際に統一された初期化を使用する場合、これはネットワークがまだトレーニングされていない場合の典型的な例です。

比較すると、layer1/activationsベルカーブ(ガウス)のような形を形成します。値は特定の値(この場合は)を中心にしていますが、0それよりも大きいまたは小さいこともあります(対称であるため、そうなる可能性が高いです)。ほとんどの値はの平均付近に表示されます0が、値の範囲は-0.80.8です。私は仮定するlayer1/activationsバッチ内のすべてのレイヤの出力上分布とします。値が時間とともに変化することがわかります。

レイヤー4のヒストグラムでは、具体的なことは何もわかりません。形状から、それだけでいくつかの重量は約値ことを示しています-0.10.05そして0.25より高い確率で発生する傾向があります。その理由、各ニューロンの異なる部分が実際に同じ情報を取得し、基本的に冗長であることです。これは、実際には小規模なネットワークを使用できること、またはネットワークが過剰適合を防ぐために、より特徴的な機能を学習する可能性があることを意味します。ただし、これらは単なる仮定です。

また、以下のコメントですでに述べたように、バイアス単位を追加してください。それらを除外することで、ネットワークをおそらく無効なソリューションに強制的に制限できます。


5
バイアスがないことは非常に悪い考えです。これは、(非常に高次元の)点群に線を引こうとするのに似ていますが、値0を通過する必要があります。それはうまくいくかもしれず、あなたにいくつかの解決策を与えるでしょうが、それは悪いか単に間違っているものである可能性があります。
2017

1
残念ながらヒストグラムからはあまりわかりません。(ただし、私の回答を更新しました。)
2017

1
もう少し長く訓練する必要があります。特に最初の結果を考えると、layer4/Qpredそれははるかに良くなる可能性があるように見えます。ウエイトは変わらないですが…生意気なのですが、今はわかりません。それは本当に正しい分布であるかもしれませんが、まったく変化がないことを考えると、私はそれを信じることは難しいと思います。
2017

1
@sunsideバイアスよりもネットワークの重みの更新を優先する方法はありますか?バイアスだけでなく、最後の層はすべてのエラーを吸収するようです。バイアスのみが更新され、重みヒストグラムが比較的変更されないままである、同様の問題が発生しています。
ママフォク2017

2
アクティベーション前
Tosha
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.