Tensorflow CNN测试数据拆分和数组大小调整问题

时间:2018-10-17 18:28:12

标签: python tensorflow machine-learning

我试图自己弄清楚事情,而不是退一步来实际在这里创建帐户,但是作为一个自学成才的初学者,我已经有了这段代码。

除了在一切正常的情况下优化网络体系结构之外,我还有两个主要问题:

  • 每次我尝试为测试批次创建一个新的数据集时,我遇到的'xTensor不是Tensor'错误都可以通过它运行会话,这与迭代器的工作原理完全一样。我正在加载目录名称为标签的自定义数据,没有手动创建的训练和测试目录。我可能缺少正确的tf方法。

  • 我无法解决当前遇到的第一个错误: 'ValueError:在feed_dict {y = batch_y}时,无法为张量为'(?,1)'的张量'Placeholder_1:0'提供形状(100,)的值。我已经尝试了一些发布在SO上的解决方案,但无法使其正常工作。

我要粘贴整个内容,############是在会话最底部触发区域的问题。

import tensorflow as tf
import numpy as np
import os

# load custom imageset directory
data_path = r"..\datasets\images\flowers"

# setup hypervariables for labels and images format
n_classes = 5
img_width = 64
img_length = 64
channels = 3

# setup hypervariables for network
learning_rate = 0.0001
epochs = 2
batch_size = 100
drop_rate = 0.6

imagepaths = list()
labels = list()
label = 0
classes = sorted(os.walk(data_path).__next__()[1])
# List each sub-directory (the classes)
for c in classes:
    c_dir = os.path.join(data_path, c)
    walk = os.walk(c_dir).__next__()

    # Add each image to the training set
    for sample in walk[2]:
        imagepaths.append(os.path.join(c_dir, sample))
        labels.append(label)
    label += 1

total_input = len(labels)
# Convert to Tensor
imagepaths = tf.convert_to_tensor(imagepaths, dtype=tf.string)
labels = tf.convert_to_tensor(labels, dtype=tf.int32)
# Build a TF Queue, shuffle data
dataset = tf.data.Dataset.from_tensor_slices((imagepaths, labels))

# read, decode, resize and normalize images on RGB range
def parse(imagepath, label):
    image = tf.read_file(imagepath)
    image = tf.image.decode_jpeg(image, channels=channels)
    image = tf.image.resize_images(image, [img_length, img_width])
    image = image * 1.0/255
    return image, label

dataset = dataset.map(parse)
dataset = dataset.shuffle(buffer_size=batch_size*10)
dataset = dataset.batch(batch_size)
iterator = dataset.make_one_shot_iterator()
next_batch = iterator.get_next()

# hypervariables for layers' output size
K = 16
L = 32
M = 200

x = tf.placeholder(tf.float32, [None, 4326])
x_shaped = tf.reshape(x, [-1, img_length, img_width, 3])
y = tf.placeholder(tf.float32, [None, 1])

# weight, bias with stride size and activation method after convolution for layer 1
W1 = tf.Variable(tf.truncated_normal([5, 5, 3, K], stddev=0.03))
b1 = tf.Variable(tf.truncated_normal([K], stddev=0.01))
stride = 1
y1 = tf.nn.relu(tf.nn.conv2d(x_shaped, W1, strides=[1, stride, stride, 1], padding='SAME') + b1)

# weight, bias with stride size and activation method after convolution for layer 2
W2 = tf.Variable(tf.truncated_normal([5, 5, K, L], stddev=0.03))
b2 = tf.Variable(tf.truncated_normal([L], stddev=0.01))
stride = 2  # output is 14x14
y2 = tf.nn.relu(tf.nn.conv2d(y1, W2, strides=[1, stride, stride, 1], padding='SAME') + b2)

yflat = tf.reshape(y2, [-1, 7 * 7 * L])

W3 = tf.Variable(tf.truncated_normal([7 * 7 * L, M], stddev=0.1))
b3 = tf.Variable(tf.truncated_normal([M], stddev=0.01))
y3 = tf.nn.relu(tf.matmul(yflat, W3) + b3)

W4 = tf.Variable(tf.truncated_normal([M, 10], stddev=0.1))
b4 = tf.Variable(tf.truncated_normal([10], stddev=0.01))
ylogits = tf.matmul(y3, W4) + b4
y_ = tf.nn.softmax(ylogits)

# add cross entropy for back prop
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=ylogits, labels=y_))

# add an optimiser for back prop
optimiser = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cross_entropy)

# define an accuracy assessment operation
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

with tf.Session() as sess:

    sess.run(tf.global_variables_initializer())
    ########## temporary solution for test_x, test_y
    test_x, test_y = sess.run(next_batch)
    total_batch = int(total_input / batch_size)
    # define the iterator for the network
    for epoch in range(epochs):
        avg_cost = 0
        for i in range(total_batch):
            batch_x, batch_y = sess.run(next_batch)
            ########## ValueError: Cannot feed value of shape (100,) for Tensor 'Placeholder_1:0' -> y: batch_y
            _, c = sess.run([optimiser, cross_entropy], feed_dict={x_shaped: batch_x, y: batch_y}) 
            avg_cost += c / total_batch

        test_acc = sess.run(accuracy,feed_dict={x: test_x, y: test_y})
        print("Epoch:", (epoch + 1), "cost =", "{:.3f}".format(avg_cost), " test accuracy: {:.3f}".format(test_acc))
        summary = sess.run(merged, feed_dict={x: test_x, y: test_y})

    print("\nTraining complete!")
    print(sess.run(accuracy, feed_dict={x: test_x, y: test_y}))

1 个答案:

答案 0 :(得分:0)

您确定这部分是

_, c = sess.run([optimiser, cross_entropy], feed_dict={x_shaped: batch_x, y: batch_y}) 

不必是:

_, c = sess.run([optimiser, cross_entropy], feed_dict={x: batch_x, y: batch_y}) 

此外,您的批量大小为100,数据在数组的右边,形状不完整。 你有什么(虚拟的例子)

np.zeros((100,)).shape
>>> (100,)

此处100匹配“?”形状为((?,1)'的形状,可以很容易地添加它,并且经常发生numpy不这样做的情况。请参见以下代码:

 np.expand_dims(np.zeros((100,)), axis=-1).shape
 >>> (100, 1)

axis -1代表最后一个轴,您基本上告诉numpy在最后添加一个尺寸。这不会影响数据本身,但会影响数组的形状。因此您的代码应为:

_, c = sess.run([optimiser, cross_entropy], feed_dict={x_shaped: batch_x, y:np.expand_dims(batch_y, axis=-1)})