2017-08-25 82 views
1

編程的新手段。碰到一個奇怪的問題。在Stackoverflow或Internet上找不到解決或提供避免錯誤的方法。當原始變量爲float32類型時,Tensorflow sess.run返回一個列表。 這些是控制線:tensorflow sess.run返回List而不是float32導致TypeError:不支持的操作數類型爲+ =:'float'和'list'

accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32)) 
accuracy_batch = sess.run([accuracy], feed_dict={images_pl: image, labels_pl: label}) 

這導致一種類型的錯誤的下游在這條線:

total_correct_preds += accuracy_batch 

隨着以下錯誤:

TypeError: unsupported operand type(s) for +=: 'float' and 'list' 

完整代碼在這裏:

import os 
    os.environ['TF_CPP_MIN_LOG_LEVEL']='2' 
    import numpy as np 
    import tensorflow as tf 
    from tensorflow.examples.tutorials.mnist import input_data 
    import time 

    learning_rate = 0.01 
    batch_size = 32 
    n_epochs = 10 

    mnist = input_data.read_data_sets('data/mnist', one_hot=True) 
    images_pl = tf.placeholder(tf.float32, shape=[1,784], name="images_pl") 
    labels_pl = tf.placeholder(tf.float32, shape=[1,10], name="labels_pl") 
    w = tf.Variable(tf.zeros([784, 10]), dtype=tf.float32, name="Weights") 
    b = tf.Variable(tf.zeros([1, 10]), dtype=tf.float32, name="Bias") 

    logits = tf.matmul(images_pl, w) + b 
    loss = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels_pl) 
    train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) 

    n_trainset = len(mnist.train.images) 
    n_testset = len(mnist.test.images) 

    # test the model 
    preds = tf.nn.softmax(logits) 
    correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(labels_pl, 1)) 
    # accuracy = tf.cast(correct_preds, tf.float32) 
    accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32)) # need numpy.count_nonzero(boolarr) :(
    print('accuracy dtype',accuracy.dtype) 

    with tf.Session() as sess: 
     start_time = time.time() 
     sess.run(tf.global_variables_initializer()) 
     sess.run(tf.local_variables_initializer()) 
     #n_batches = int(mnist.train.num_examples/batch_size) 
     for i in range(n_epochs): # train the model n_epochs times 
      total_loss = 0 
    #  for j in range(n_trainset): 
      for j in range(5): 
       image = np.reshape(mnist.train.images[j], [1,784]) 
       label = np.reshape(mnist.train.labels[j], [1,10]) 
       _, loss_curr = sess.run([train_op, loss], feed_dict={images_pl: image, labels_pl: label}) 
       total_loss += loss_curr 
       #print(loss_curr) 
      print('Average loss epoch {0}: {1}'.format(i, total_loss)) 

     print('Total time: {0} seconds'.format(time.time() - start_time)) 
     print('Optimization Finished!') # should be around 0.35 after 25 epochs 

     #n_batches = int(mnist.test.num_examples/batch_size) 
     total_correct_preds = 0.0 

     for k in range(10): 
      image = np.reshape(mnist.test.images[k], [1, 784]) 
      label = np.reshape(mnist.test.labels[k], [1, 10]) 
      accuracy_batch = sess.run([accuracy], feed_dict={images_pl: image, labels_pl: label}) 
      #print(accuracy_batch.dtype) 
      #accuracy_batch = tf.cast(accuracy_batch, tf.float32) 
      print(accuracy_batch) 
      print('accuracy_batch',accuracy_batch) 
      total_correct_preds += accuracy_batch 

     print('total_correct_preds',total_correct_preds) 

這很奇怪,因爲它遵循與在訓練部分中工作正常的total_loss/loss_curr結構相同的結構。 以下是完整的輸出日誌:

Extracting data/mnist/train-images-idx3-ubyte.gz 
.. 
Extracting data/mnist/t10k-labels-idx1-ubyte.gz 
('accuracy dtype', tf.float32) 
Average loss epoch 0: [ 11.81690311] 
Average loss epoch 1: [ 8.99989128] 
... 
Average loss epoch 9: [ 1.64795518] 
Total time: 0.04798579216 seconds 
Optimization Finished! 
[0.0] 
('accuracy_batch', [0.0]) 
Traceback (most recent call last): 
    File "CS20SI/Code/03_logistic_regression_mnist_starter.py", line 62, in <module> 
    total_correct_preds += accuracy_batch 
TypeError: unsupported operand type(s) for +=: 'float' and 'list' 

有人能幫助解釋爲什麼sess.run在當原始變量是D型float32的返回一個列表D型?

回答

0

sess.run接受圖表元素的列表並返回其值的列表。在你的情況下,圖表元素的列表是[accuracy],所以sess.run返回一個單個元素的列表。

爲了方便,你可以寫

(accuracy_batch,) = sess.run([accuracy], feed_dict={images_pl: image, labels_pl: label}) 

甚至

accuracy_batch, = sess.run([accuracy], feed_dict={images_pl: image, labels_pl: label}) 

Python會匹配sess.run和元組產生的名單,所以你會在accuracy_batch得到float32

您也可以通過單個圖形元素:

accuracy_batch = sess.run(accuracy, feed_dict={images_pl: image, labels_pl: label}) 
+0

感謝@velikodniy用於溶液和解釋。您提供的所有解決方案都可以工作。最後一個適合我最需要的! – Samit

相關問題