【问题标题】:tensorflow scalar summary tags name exceptiontensorflow 标量摘要标签名称异常
【发布时间】:2016-01-31 20:29:52
【问题描述】:

我正在尝试按照 HowTo mnist 教程学习如何使用 tensorflow 摘要编写器。该教程为损失函数添加了一个标量摘要。我通过建立一个正则化项以不寻常的方式编写了一个损失函数,我得到了这个异常:

W tensorflow/core/common_runtime/executor.cc:1027] 0x1e9ab70 Compute status: Invalid argument: tags and values not the same shape: [] != [1]
     [[Node: ScalarSummary = ScalarSummary[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"](ScalarSummary/tags, loss)]]

损失函数和添加摘要看起来像

loss = tf.add(modelError, regularizationTerm, name='loss')
tf.scalar_summary(loss.op.name, loss)

如果我像这样建立正则化术语

regularizationTerm = tf.Variable(tf.zeros([1], dtype=np.float32), name='regterm')
regularizationTerm +=  tf.mul(2.0, regA)
regularizationTerm +=  tf.mul(3.0, regB)

如果 regA 和 regB 是之前定义的 tf.Variables,我得到了异常,而我是像构建它一样

regularizationTerm = tf.add(tf.mul(2.0, regA), tf.mul(3.0, regB), name='regterm')

然后就可以了。所以我想我没有正确设置名称,当我执行 += 时,我创建了一个未命名的新张量?但是为什么我不能将它添加到损失中,然后命名损失?这是我唯一想总结的吗?

有没有像 += 这样的东西,我可以在其中命名输出,或者保留我正在修改的张量的名称?

如果问题与其他问题有关,这是我发现问题的简单示例:

import numpy as np
import tensorflow as tf

def main():
    x_input = tf.placeholder(tf.float32, shape=(None, 1))
    y_output = tf.placeholder(tf.float32, shape=(None, 1))

    hidden_weights = tf.Variable(tf.truncated_normal([1,10], stddev=0.1), name='weights')
    output_weights = tf.Variable(tf.truncated_normal([10,1], stddev=0.1), name='output')
    inference = tf.matmul(tf.matmul(x_input, hidden_weights), output_weights)
    regA = tf.reduce_sum(tf.pow(hidden_weights, 2))
    regB = tf.reduce_sum(tf.pow(output_weights, 2))
    modelError = tf.reduce_mean(tf.pow(tf.sub(inference,y_output),2), name='model-error')

    fail = True
    if fail:
        regularizationTerm = tf.Variable(tf.zeros([1], dtype=np.float32), name='regterm')
        regularizationTerm +=  tf.mul(2.0, regA)
        regularizationTerm +=  tf.mul(3.0, regB)
    else:
        regularizationTerm = tf.add(tf.mul(2.0, regA), tf.mul(3.0, regB), name='regterm')

    loss = tf.add(modelError, regularizationTerm, name='loss')
    tf.scalar_summary(loss.op.name, loss)
    optimizer = tf.train.GradientDescentOptimizer(0.05)
    global_step = tf.Variable(0, name='global_step', trainable=False)
    train_op = optimizer.minimize(loss, global_step=global_step)

    summary_op = tf.merge_all_summaries()

    saver = tf.train.Saver()

    sess = tf.Session()
    init = tf.initialize_all_variables()
    sess.run(init)

    summary_writer = tf.train.SummaryWriter('train_dir', 
                                            graph_def=sess.graph_def)

    feed_dict = {x_input:np.ones((30,1), dtype=np.float32),
                 y_output:np.ones((30,1), dtype=np.float32)}

    for step in xrange(1000):
        _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)
        if step % 100 == 0:
            print( "step=%d loss=%.2f" % (step, loss_value))
            summary_str = sess.run(summary_op, feed_dict=feed_dict)
            summary_writer.add_summary(summary_str, step)

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    由于这是与尺寸为 1 的张量的形状有关的问题,您可以尝试使用 tf.squeeze,它专门从张量的形状中删除尺寸为 1 的尺寸。

    在你的情况下,你可以替换

    tf.scalar_summary(loss.op.name, loss)

    tf.scalar_summary(loss.op.name, tf.squeeze(loss))

    【讨论】:

    • 简单胜于复杂!
    【解决方案2】:

    TL;DR:问题在于tf.scalar_summary() 的参数形式,而不是名称。

    我认为问题是与形状相关的问题,源于这一行:

    regularizationTerm = tf.Variable(tf.zeros([1], dtype=np.float32), name='regterm')
    

    这定义了一个变量,其形状是长度为 1 的向量。随后的 += 运算符(它们是 tf.add() 的语法糖)和计算 losstf.add() 将产生向量形状的结果,因为tf.add()broadcasts 标量参数成为向量。最后,tf.scalar_summary() 期望它的两个参数具有相同的形状——与广播 add 不同,tf.scalar_summary() 不允许其输入的形状。 tags 输入是标量字符串(loss 操作的名称),而 values 输入是长度为 1 的向量(loss 张量的值)。因此,您会收到您报告的错误。

    幸运的是,解决方案很简单!将regularizationTerm 变量定义为标量,如下所示:

    # Note that `[]` is the scalar shape.
    regularizationTerm = tf.Variable(tf.zeros([], dtype=np.float32), name='regterm')
    

    ...或将字符串向量(长度为 1)传递给tf.scalar_summary()

    # Wrap `loss.op.name` in a list to make it a vector.
    tf.scalar_summary([loss.op.name], loss)
    

    【讨论】:

    • 这两个都有效!我没有意识到 scalar_summary 参数或定义标量的语法之间的形状关系,谢谢!
    • 谢谢!没有意识到 [][1] 是不同的。我想知道为什么它会让 tf 崩溃......
    猜你喜欢
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 2018-06-29
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 2021-05-28
    相关资源
    最近更新 更多