ValueError:无法为Tensor' Placeholder_1:0'提供形状值(64,),它具有形状'(?,10)'

时间:2017-04-28 09:23:27

标签: tensorflow lstm mnist

我是张量流的新手,我试图重现网站上发布的实验https://github.com/jiegzhan/image-classification-rnn

我的TensorFlow版本是1.0.1,所以我稍微修改了他的代码。我使用的代码如下。

import os
import sys
import json
import time
import tensorflow as tf
from tensorflow.contrib.rnn.python.ops import rnn, rnn_cell
from tensorflow.examples.tutorials.mnist import input_data

n_input = 28 # MNIST data input (img shape: 28*28)
n_steps = 28 # timesteps
n_hidden = 128 # hidden layer num of features
n_classes = 10 # MNIST total classes (0-9 digits)
#coding:utf-8
def rnn_model(x, weights, biases):
    """RNN (LSTM or GRU) model for image"""
    x = tf.transpose(x, [1, 0, 2])
    x = tf.reshape(x, [-1, n_input])
    x = tf.split(x, n_steps, 0)
    # Define a lstm cell with tensorflow
    #lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
    lstm_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0)
    # Get lstm cell output
    outputs, states = tf.contrib.rnn.static_rnn(lstm_cell, x, dtype=tf.float32)
    return tf.matmul(outputs[-1], weights) + biases

def train():
    """Train an image classifier"""
    """Step 0: load image data and training parameters"""
    mnist = input_data.read_data_sets("./data/", one_hot=False)# change one_hot to false by myself ---------
    #parameter_file = sys.argv[1]
    #params = json.loads(open(parameter_file).read())
    params = json.loads(open('parameters.json').read())

    """Step 1: build a rnn model for image"""
    x = tf.placeholder("float", [None, n_steps, n_input])
    y = tf.placeholder("float", [None, n_classes])
    #y = tf.placeholder("float", [n_classes,])

    weights = tf.Variable(tf.random_normal([n_hidden, n_classes]), name='weights')
    biases = tf.Variable(tf.random_normal([n_classes]), name='biases')

    pred = rnn_model(x, weights, biases)
    # Define loss and optimizer
    #you will get the dreaded 'No gradients provided for any variable' if you switch the args between y and pred
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pred))
    optimizer = tf.train.AdamOptimizer(learning_rate=params['learning_rate']).minimize(cost)

    # Evaluate model
    correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

    """Step 2: train the image classification model"""
    with tf.Session() as sess:
        #sess.run(tf.initialize_all_variables())# deprecated
        sess.run(tf.global_variables_initializer())
        step = 1

        """Step 2.0: create a directory for saving model files"""
        timestamp = str(int(time.time()))
        out_dir = os.path.abspath(os.path.join(os.path.curdir, "trained_model_" + timestamp))
        checkpoint_dir = os.path.abspath(os.path.join(out_dir, "checkpoints"))
        checkpoint_prefix = os.path.join(checkpoint_dir, "model")
        if not os.path.exists(checkpoint_dir):
            os.makedirs(checkpoint_dir)
        saver = tf.train.Saver(tf.all_variables())

        """Step 2.1: train the image classifier batch by batch"""
        while step * params['batch_size'] < params['training_iters']:
            batch_x, batch_y = mnist.train.next_batch(params['batch_size'])
            # Reshape data to get 28 seq of 28 elements
            print(batch_x)
            print(batch_y)
            batch_x = batch_x.reshape((params['batch_size'], n_steps, n_input))
            #batch_y = batch_y.reshape((-1, n_classes))

            sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})#**bug is here**

            """Step 2.2: save the model"""
            if step % params['display_step'] == 0:
                path = saver.save(sess, checkpoint_prefix, global_step=step)
                acc = sess.run(accuracy, feed_dict={x: batch_x, y: batch_y})
                loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y})
                print('Iter: {}, Loss: {:.6f}, Accuracy: {:.6f}'.format(step * params['batch_size'], loss, acc))
            step += 1
        print("The training is done")

        """Step 3: test the model"""
        test_len = 128
        test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
        test_label = mnist.test.labels[:test_len]
        print("Testing Accuracy:", sess.run(accuracy, feed_dict={x: test_data, y: test_label}))

if __name__ == '__main__':
    train()

警告:

WARNING:tensorflow:From D:/TensorFlow/image-classification-rnn-master/train.py:68: all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Please use tf.global_variables instead.
[[ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 ..., 
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]]
[7 3 4 6 1 8 1 0 9 8 0 3 1 2 7 0 2 9 6 0 1 6 7 1 9 7 6 5 5 8 8 3 4 4 8 7 3
 6 4 6 6 3 8 8 9 9 4 4 0 7 8 1 0 0 1 8 5 7 1 7 5 5 9 9]
Traceback (most recent call last):
  File "D:/TensorFlow/image-classification-rnn-master/train.py", line 98, in <module>
    train()
  File "D:/TensorFlow/image-classification-rnn-master/train.py", line 80, in train
    sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})
  File "C:\Users\***\AppData\Local\Programs\Python\Python35\lib\site-packages\tensorflow\python\client\session.py", line 767, in run
    run_metadata_ptr)
  File "C:\Users\***\AppData\Local\Programs\Python\Python35\lib\site-packages\tensorflow\python\client\session.py", line 944, in _run
    % (np_val.shape, subfeed_t.name, str(subfeed_t.get_shape())))
ValueError: Cannot feed value of shape (64,) for Tensor 'Placeholder_1:0', which has shape '(?, 10)'

Process finished with exit code 1

错误在这里:

sess.run(optimizer, feed_dict={x: batch_x, y: batch_y}) 

print(batch_y ) --> Tensor("ExpandDims:0", shape=(64, 1), dtype=uint8)

我试图在谷歌上找到一个相关的答案并得到一些相似的答案,但我无法让它们中的任何一个起作用。

有人帮忙吗?非常感谢!

1 个答案:

答案 0 :(得分:5)

问题是batch_y是一个包含标签(数字从0到9)的张量,指定了正确的类,而你的占位符

y = tf.placeholder(tf.float32, [None, n_classes])

每个示例都需要一个长度为n_classes的向量,用于指定每个类的预期概率。

在这个问题中,一次只有一个类是正确的,因此代替正确的标签n_classes - 长度向量,您可以将y作为标签,例如

y = tf.placeholder(tf.float32, [None])

然后您还必须将cost更改为

cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=pred))

sparse表示只有一个类是正确的,因此参数labels是一个大小为[batch_size]的张量,其数字代表每个示例的正确类。