2016-01-31 9 views
8

HowTo mnistチュートリアルに従うことで、テンソルフローのサマリーライターを扱う方法を学ぼうとしています。このチュートリアルでは、損失関数のスカラサマリーを追加します。私は、正則化項を構築することにより、珍しいで損失関数を書いた、と私は、この例外を取得:私が構築する場合テンソルフロースカラーサマリータグ名例外

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) 

ようregularizationTermは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() 

答えて

20

TL; DR:

問題は何か他のものに関連している場合は、ここで私は、問題を特定し、私の単純な例です問題は、tf.scalar_summary()に引数の形ではありません名。

私はこの問題は、この行から生じる、形状関連の問題であると思う:

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

これは、その形状のための糖衣構文である後続+=演算子(1長さのベクトルである変数を定義しますtf.add())とtf.add()lossを計算すると、tf.add()broadcastsベクトルになるためスカラー引数がベクトル形式の結果を生成します。最後に、tf.scalar_summary()は、その2つの引数がブロードキャスト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') 

...またはtf.scalar_summary()に文字列の(長さ1の)ベクトルを渡す:

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

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

を置き換えることができます!私はscalar_summary引数とスカラーを定義するための構文との間の形状関係を理解し​​ていませんでした。 – MrCartoonology

+0

ありがとう! '[]と' [1] 'が違っていることに気付かなかった。なぜ私はtfがクラッシュするのだろう... – Pinocchio

0

これに関連する問題であるのでサイズ1のテンソルの形状の場合は、tf.squeezeを使用して、テンソルの形状からサイズ1の寸法を特に取り除くことができます。あなたのケースでは

、あなたはこれらの両方働い

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