我正在尝试通过遵循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)]]
Run Code Online (Sandbox Code Playgroud)
丢失功能和添加摘要看起来像
loss = tf.add(modelError, regularizationTerm, name='loss')
tf.scalar_summary(loss.op.name, loss)
Run Code Online (Sandbox Code Playgroud)
如果我像这样建立正规化条款
regularizationTerm = tf.Variable(tf.zeros([1], dtype=np.float32), name='regterm')
regularizationTerm += tf.mul(2.0, regA)
regularizationTerm += tf.mul(3.0, regB)
Run Code Online (Sandbox Code Playgroud)
regA和regB是tf.Variables之前定义的,我得到了异常,而我是建立起来的
regularizationTerm = tf.add(tf.mul(2.0, regA), tf.mul(3.0, regB), name='regterm')
Run Code Online (Sandbox Code Playgroud)
然后它工作.所以我想我没有正确设置名称,当我做+ =我创建一个未命名的新张量?但为什么我不能把它添加到损失中,然后命名损失?这是我唯一要总结的事情吗?
是否有类似+ =的地方,我可以命名输出,或保留我正在修改的张量的名称?
如果问题与其他问题有关,这是我发现问题的简单示例:
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()
Run Code Online (Sandbox Code Playgroud)
mrr*_*rry 27
TL; DR:问题是参数的形状tf.scalar_summary(),而不是名称.
我认为问题是形状相关的问题,源于这一行:
regularizationTerm = tf.Variable(tf.zeros([1], dtype=np.float32), name='regterm')
Run Code Online (Sandbox Code Playgroud)
这定义了一个变量,其形状是长度为1的向量.后续+=运算符(它们是语法糖tf.add())和tf.add()计算loss将产生向量形状的结果,因为tf.add() 广播标量参数成为向量.最后,tf.scalar_summary()期望它的两个参数具有相同的形状 - 与广播不同add,tf.scalar_summary()不允许其输入的形状.该tags输入是一个标量字符串(的名称loss运算),而values输入是长度之一(的值的向量loss张量).因此,您会收到您报告的错误.
幸运的是,解决方案很简单!将regularizationTerm变量定义为标量,如下所示:
# Note that `[]` is the scalar shape.
regularizationTerm = tf.Variable(tf.zeros([], dtype=np.float32), name='regterm')
Run Code Online (Sandbox Code Playgroud)
...或将字符串向量(长度为1)传递给tf.scalar_summary():
# Wrap `loss.op.name` in a list to make it a vector.
tf.scalar_summary([loss.op.name], loss)
Run Code Online (Sandbox Code Playgroud)
小智 5
由于这是与尺寸为 1 的张量的形状有关的问题,因此您可以尝试使用 tf.squeezewhich 专门从张量的形状中删除尺寸为 1 的尺寸。
在你的情况下,你可以更换
tf.scalar_summary(loss.op.name, loss)
和
tf.scalar_summary(loss.op.name, tf.squeeze(loss))
| 归档时间: |
|
| 查看次数: |
12391 次 |
| 最近记录: |