TensorBoardには、セッション時にテンソルのヒストグラムをプロットする機能がありました。トレーニング中のグラデーションのヒストグラムが必要です。
tf.gradients(yvars,xvars)
は、グラデーションのリストを返します。
ただし、tf.histogram_summary('name',Tensor)
はTensorのみを受け入れ、Tensorのリストは受け入れません。
とりあえず、回避策を作りました。すべてのテンソルを列ベクトルにフラット化して連結します。
for l in xrange(listlength): col_vec = tf.reshape(grads[l],[-1,1]) g = tf.concat(0,[g,col_vec]) grad_hist = tf.histogram_summary("name", g)
勾配のヒストグラムをプロットするより良い方法は何でしょうか?
これは一般的なことのようですので、TensorFlowに専用の機能を持たせたいと思います。
( この定足数の回答 に基づく)別の解決策は、すでに使用しているオプティマイザーから直接勾配にアクセスすることです。
optimizer = tf.train.AdamOptimizer(..)
grads = optimizer.compute_gradients(loss)
grad_summ_op = tf.summary.merge([tf.summary.histogram("%s-grad" % g[1].name, g[0]) for g in grads])
grad_vals = sess.run(fetches=grad_summ_op, feed_dict = feed_dict)
writer['train'].add_summary(grad_vals)
@ user728291 の提案に従って、次のようにoptimize_loss
関数を使用してテンソルボードでグラデーションを表示することができました。 optimize_loss の関数呼び出し構文は
optimize_loss(
loss,
global_step,
learning_rate,
optimizer,
gradient_noise_scale=None,
gradient_multipliers=None,
clip_gradients=None,
learning_rate_decay_fn=None,
update_ops=None,
variables=None,
name=None,
summaries=None,
colocate_gradients_with_ops=False,
increment_global_step=True
)
この関数はglobal_step
を必要とし、次に示すように他のいくつかのインポートに依存しています。
from tensorflow.python.ops import variable_scope
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import init_ops
global_step = variable_scope.get_variable( # this needs to be defined for tf.contrib.layers.optimize_loss()
"global_step", [],
trainable=False,
dtype=dtypes.int64,
initializer=init_ops.constant_initializer(0, dtype=dtypes.int64))
次に、通常のトレーニング操作を置き換えます
training_operation = optimizer.minimize(loss_operation)
と
training_operation = tf.contrib.layers.optimize_loss(
loss_operation, global_step, learning_rate=rate, optimizer='Adam',
summaries=["gradients"])
次に、要約のマージステートメントを作成します
summary = tf.summary.merge_all()
次に、各実行/エポックの最後にあるテンソルフローセッションで:
summary_writer = tf.summary.FileWriter(logdir_run_x, sess.graph)
summary_str = sess.run(summary, feed_dict=feed_dict)
summary_writer.add_summary(summary_str, i)
summary_writer.flush() # evidently this is needed sometimes or scalars will not show up on tensorboard.
ここで、logdir_run_x
は実行ごとに異なるディレクトリです。そうすることで、TensorBoardの実行時に、各実行を個別に確認できます。グラデーションはヒストグラムタブの下にあり、ラベルはOptimizeLoss
です。すべての重み、すべてのバイアス、およびbeta
パラメーターをヒストグラムとして表示します。
更新:tf slimを使用すると、別の方法も機能し、おそらくよりクリーンになります。
optimizer = tf.train.AdamOptimizer(learning_rate = rate)
training_operation = slim.learning.create_train_op(loss_operation, optimizer,summarize_gradients=True)
デフォルトではないsummarize_gradients=True
を設定すると、すべての重みの勾配の要約が得られます。これらはsummarize_grads
の下のTensorboardで表示できます