1

MNISTのモデルをCNNで訓練しましたが、トレーニング後にモデルの精度をテストデータで確認すると、精度が向上することがわかります。ここにコードがあります。TensorFlow:テストセットを複数回評価するが精度が異なる

BATCH_SIZE = 50 
LR = 0.001    # learning rate 
mnist = input_data.read_data_sets('./mnist', one_hot=True) # they has been normalized to range (0,1) 
test_x = mnist.test.images[:2000] 
test_y = mnist.test.labels[:2000] 

def new_cnn(imageinput, inputshape): 
    weights = tf.Variable(tf.truncated_normal(inputshape, stddev = 0.1),name = 'weights') 
    biases = tf.Variable(tf.constant(0.05, shape = [inputshape[3]]),name = 'biases') 
    layer = tf.nn.conv2d(imageinput, weights, strides = [1, 1, 1, 1], padding = 'SAME') 
    layer = tf.nn.relu(layer) 
    return weights, layer 

tf_x = tf.placeholder(tf.float32, [None, 28 * 28]) 
image = tf.reshape(tf_x, [-1, 28, 28, 1])    # (batch, height, width, channel) 
tf_y = tf.placeholder(tf.int32, [None, 10])   # input y 

# CNN 
weights1, layer1 = new_cnn(image, [5, 5, 1, 32]) 
pool1 = tf.layers.max_pooling2d(
    layer1, 
    pool_size=2, 
    strides=2, 
)   # -> (14, 14, 32) 
weight2, layer2 = new_cnn(pool1, [5, 5, 32, 64]) # -> (14, 14, 64) 
pool2 = tf.layers.max_pooling2d(layer2, 2, 2) # -> (7, 7, 64) 
flat = tf.reshape(pool2, [-1, 7 * 7 * 64])   # -> (7*7*64,) 
hide = tf.layers.dense(flat, 1024, name = 'hide')    # hidden layer 
output = tf.layers.dense(hide, 10, name = 'output') 
loss = tf.losses.softmax_cross_entropy(onehot_labels=tf_y, logits=output)   # compute cost 
accuracy = tf.metrics.accuracy(labels=tf.argmax(tf_y, axis=1), predictions=tf.argmax(output, axis=1),)[1] 
train_op = tf.train.AdamOptimizer(LR).minimize(loss) 



sess = tf.Session() 
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()) # the local var is for accuracy 
sess.run(init_op)  # initialize var in graph 
saver = tf.train.Saver() 
for step in range(101): 
    b_x, b_y = mnist.train.next_batch(BATCH_SIZE) 
    _, loss_ = sess.run([train_op, loss], {tf_x: b_x, tf_y: b_y}) 
    if step % 50 == 0: 
     print(loss_) 
     accuracy_, loss2 = sess.run([accuracy, loss], {tf_x: test_x, tf_y: test_y }) 
     print('Step:', step, '| test accuracy: %f' % accuracy_) 

問題を単純化するために、私は100回のトレーニング反復のみを使用します。テストセットの最終精度は約0.655000です。

しかし、私は次のコードを実行すると:

for i in range(5): 
    accuracy2 = sess.run(accuracy, {tf_x: test_x, tf_y: test_y }) 
    print(sess.run(weight2[1,:,0,0])) # To show that the model parameters won't update 
    print(accuracy2) 

出力はこれは私が混乱します

[-0.06928255 -0.13498515 0.01266837 0.05656774 0.09438231] 
0.725875 
[-0.06928255 -0.13498515 0.01266837 0.05656774 0.09438231] 
0.7684 
[-0.06928255 -0.13498515 0.01266837 0.05656774 0.09438231] 
0.79675 
[-0.06928255 -0.13498515 0.01266837 0.05656774 0.09438231] 
0.817 
[-0.06928255 -0.13498515 0.01266837 0.05656774 0.09438231] 
0.832187 

ですが、誰かが間違っているものを私に伝えることができますか? ご理解いただきありがとうございます。

+0

[各推論の同じ予測](https://stackoverflow.com/questions/44952929/same-prediction-for-each-inference)の可能な複製 – user1735003

+0

完全なコードを含めてください。たとえば、wgat keep_probを使用していますか? – lejlot

+0

@lejlot申し訳ありませんが、私は冗長部分を削除します。 – DennngP

答えて

0

tf.metrics.accuracyあなたが思うほど些細なものではありません。そのドキュメントを見てみましょう:

accuracy機能が predictionslabelsと一致する頻度を計算するために使用される2つのローカル変数、total
countを作成します。この周波数は、最終的には として返され、accuracytotalcountを単に除算する等価演算です。

内部、is_correct動作 要素さもなければpredictionslabels一致と0.0の1.0に対応する要素とTensorを計算します。次いでupdate_opインクリメントweightsis_correctの積の減少和と total、それは weightsの減少和とcountをインクリメントします。データのストリーム上メトリックの推定に

、機能 は、これらの変数と 戻りaccuracyを更新update_op動作を生成します。

...

戻り値:

  • 精度:精度を表すTensortotalの値はcountによって 分割。
  • update_op:totalcountの変数 を適切にインクリメントし、値がaccuracyに一致する操作。それはあなたが2番目の項目、すなわちupdate_opを取るタプルを返し、こと

注意。連続してupdate_opを呼び出すと、データのストリーミングとして扱われます(これは、トレーニング中の各評価が今後の評価に影響するため)。実際、この実行中のメトリックはpretty counter-intuitiveです。

あなたのための解決策は、簡単な単純精度計算を使用することです。この行を

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(tf_y, axis=1), tf.argmax(output, axis=1)), tf.float32)) 

に変更してください。安定した精度の計算ができます。

関連する問題