【问题标题】:How to print the gradients during training in Tensorflow?如何在 Tensorflow 训练期间打印梯度?
【发布时间】:2018-03-04 19:48:18
【问题描述】:

为了调试 Tensorflow 模型,我需要查看渐变是否发生了变化,或者其中是否有任何 nan。简单地在 Tensorflow 中打印一个变量是行不通的,因为你看到的只是:

 <tf.Variable 'Model/embedding:0' shape=(8182, 100) dtype=float32_ref>

我尝试使用tf.Print 类但无法使其工作,我想知道它是否可以以这种方式实际使用。在我的模型中,我有一个训练循环,可以打印每个时期的损失值:

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 的训练循环中在内打印梯度变量?

【问题讨论】:

    标签: python variables tensorflow machine-learning tensorflow-gradient


    【解决方案1】:

    根据我的经验,在 tensorflow 中查看梯度流的最佳方法不是使用 tf.Print,而是使用 tensorboard。这是我在another problem 中使用的示例代码,其中梯度是学习的关键问题:

    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 中清晰可见。

    【讨论】:

    • 如何在一个迭代器(又名grads_and_vars)中获取所有梯度和变量?
    猜你喜欢
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2021-09-07
    • 1970-01-01
    相关资源
    最近更新 更多