如何在 Tensorflow 训练期间打印梯度?
How to print the gradients during training in Tensorflow?
为了调试 Tensorflow 模型,我需要查看梯度是否发生变化或者其中是否有 nan。在 Tensorflow 中简单地打印一个变量是行不通的,因为你看到的只是:
<tf.Variable 'Model/embedding:0' shape=(8182, 100) dtype=float32_ref>
我尝试使用 tf.Print
class 但无法正常工作,我想知道它是否真的可以这样使用。在我的模型中,我有一个训练循环,它打印每个时期的损失值:
def run_epoch(session, model, eval_op=None, verbose=False):
costs = 0.0
iters = 0
state = session.run(model.initial_state)
fetches = {
"cost": model.cost,
"final_state": model.final_state,
}
if eval_op is not None:
fetches["eval_op"] = eval_op
for step in range(model.input.epoch_size):
feed_dict = {}
for i, (c, h) in enumerate(model.initial_state):
feed_dict[c] = state[i].c
feed_dict[h] = state[i].h
vals = session.run(fetches, feed_dict)
cost = vals["cost"]
state = vals["final_state"]
costs += cost
iters += model.input.num_steps
print("Loss:", costs)
return costs
将print(model.gradients[0][1])
插入到这个函数中是行不通的,所以我尝试在丢失打印后立即使用以下代码:
grads = model.gradients[0][1]
x = tf.Print(grads, [grads])
session.run(x)
但我收到以下错误信息:
ValueError: Fetch argument <tf.Tensor 'mul:0' shape=(8182, 100) dtype=float32> cannot be interpreted as a Tensor. (Tensor Tensor("mul:0", shape=(8182, 100), dtype=float32) is not an element of this graph.)
这是有道理的,因为 tf.Print
确实不是图表的一部分。因此,我尝试在实际图表中进行损失计算后使用 tf.Print
,但效果不佳,我仍然得到 Tensor("Train/Model/mul:0", shape=(8182, 100), dtype=float32)
.
如何在 Tensorflow 的训练循环中打印梯度变量?
根据我的经验,在 tensorflow 中查看梯度流的最佳方式不是使用 tf.Print
,而是使用 tensorboard。这是我在 中使用的示例代码,其中梯度是学习中的关键问题:
for g, v in grads_and_vars:
tf.summary.histogram(v.name, v)
tf.summary.histogram(v.name + '_grad', g)
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter('train_log_layer', tf.get_default_graph())
...
_, summary = sess.run([train_op, merged], feed_dict={I: 2*np.random.rand(1, 1)-1})
if i % 10 == 0:
writer.add_summary(summary, global_step=i)
这将向您展示渐变随时间的分布。顺便说一句,为了检查 NaN,tensorflow 中有一个专用函数:tf.is_nan
。通常,您不需要检查梯度是否为 NaN:当它发生时,变量也会爆炸,这将在 tensorboard 中清晰可见。
为了调试 Tensorflow 模型,我需要查看梯度是否发生变化或者其中是否有 nan。在 Tensorflow 中简单地打印一个变量是行不通的,因为你看到的只是:
<tf.Variable 'Model/embedding:0' shape=(8182, 100) dtype=float32_ref>
我尝试使用 tf.Print
class 但无法正常工作,我想知道它是否真的可以这样使用。在我的模型中,我有一个训练循环,它打印每个时期的损失值:
def run_epoch(session, model, eval_op=None, verbose=False):
costs = 0.0
iters = 0
state = session.run(model.initial_state)
fetches = {
"cost": model.cost,
"final_state": model.final_state,
}
if eval_op is not None:
fetches["eval_op"] = eval_op
for step in range(model.input.epoch_size):
feed_dict = {}
for i, (c, h) in enumerate(model.initial_state):
feed_dict[c] = state[i].c
feed_dict[h] = state[i].h
vals = session.run(fetches, feed_dict)
cost = vals["cost"]
state = vals["final_state"]
costs += cost
iters += model.input.num_steps
print("Loss:", costs)
return costs
将print(model.gradients[0][1])
插入到这个函数中是行不通的,所以我尝试在丢失打印后立即使用以下代码:
grads = model.gradients[0][1]
x = tf.Print(grads, [grads])
session.run(x)
但我收到以下错误信息:
ValueError: Fetch argument <tf.Tensor 'mul:0' shape=(8182, 100) dtype=float32> cannot be interpreted as a Tensor. (Tensor Tensor("mul:0", shape=(8182, 100), dtype=float32) is not an element of this graph.)
这是有道理的,因为 tf.Print
确实不是图表的一部分。因此,我尝试在实际图表中进行损失计算后使用 tf.Print
,但效果不佳,我仍然得到 Tensor("Train/Model/mul:0", shape=(8182, 100), dtype=float32)
.
如何在 Tensorflow 的训练循环中打印梯度变量?
根据我的经验,在 tensorflow 中查看梯度流的最佳方式不是使用 tf.Print
,而是使用 tensorboard。这是我在
for g, v in grads_and_vars:
tf.summary.histogram(v.name, v)
tf.summary.histogram(v.name + '_grad', g)
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter('train_log_layer', tf.get_default_graph())
...
_, summary = sess.run([train_op, merged], feed_dict={I: 2*np.random.rand(1, 1)-1})
if i % 10 == 0:
writer.add_summary(summary, global_step=i)
这将向您展示渐变随时间的分布。顺便说一句,为了检查 NaN,tensorflow 中有一个专用函数:tf.is_nan
。通常,您不需要检查梯度是否为 NaN:当它发生时,变量也会爆炸,这将在 tensorboard 中清晰可见。