我一直在犹豫要问这个问题,因为一般来说我更喜欢问非常具体的问题,而不是“这是一段代码,哪里出错了?”。但是,我已经了解了这方面的知识,并且已经花了很长时间以各种方式进行故障排除,此时我真的可以使用一些外部帮助。
所以我试图在TensorFlow中使用CNN进行相对简单的图像分类,因为我对机器学习还不熟悉。我原来的尝试涉及5类图像(32x32有3个颜色通道),我使用大约10K,但我有一个几十万的数据集。我写了一个模型和诸如此类的东西,让它训练,但准确度总是在19-24%左右,这几乎是随机猜测的准确性。
我试着隔离我能做的一切。我查看了数据的每一步,以确保没有任何不匹配或丢失,并调整各种参数,如学习率,批量大小,时代数等,但没有任何东西使准确率下降。
最终我完全改变了数据,所以现在我使用的是狗和猫(仍然是32x32x3)的图像数据集,其中包含8k训练图像和2k eval图像。我还逐字复制并粘贴了在MNIST上表现良好的代码,并且为了使用新的数据集而改变了我需要的东西(我不打算使用被盗的代码,我只是想在我排除故障时隔离所有内容) 。而且仍然准确率保持在50%左右,最多达到60%左右,这基本上只是猜测。我的假设是有一些明显的,简单的解决方案,因此我将包含下面代码的内容,希望另一双眼睛能看到它(或者看一个更复杂的问题,如果有的话)。
import tensorflow as tf
import numpy as np
n_classes = 2
batch_size = 100
x = tf.placeholder('float', [None, 32,32])
y = tf.placeholder('float')
keep_rate = 0.8
keep_prob = tf.placeholder(tf.float32)
'''--- Generic layers ---'''
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
def maxpool2d(x):
return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1],
padding='SAME')
'''--- Network itself ---'''
def convolutional_neural_network(x):
weights = {'W_conv1':tf.Variable(tf.random_normal([5,5,1,32])),
'W_conv2':tf.Variable(tf.random_normal([5,5,32,64])),
'W_fc':tf.Variable(tf.random_normal([8*8*64,1024])),
'out':tf.Variable(tf.random_normal([1024, n_classes]))}
biases = {'b_conv1':tf.Variable(tf.random_normal([32])),
'b_conv2':tf.Variable(tf.random_normal([64])),
'b_fc':tf.Variable(tf.random_normal([1024])),
'out':tf.Variable(tf.random_normal([n_classes]))}
x = tf.reshape(x, shape=[-1, 32, 32, 1])
conv1 = tf.nn.relu(conv2d(x, weights['W_conv1']) + biases['b_conv1'])
conv1 = maxpool2d(conv1)
conv2 = tf.nn.relu(conv2d(conv1, weights['W_conv2']) + biases['b_conv2'])
conv2 = maxpool2d(conv2)
fc = tf.reshape(conv2,[-1, 8*8*64])
fc = tf.nn.relu(tf.matmul(fc, weights['W_fc'])+biases['b_fc'])
fc = tf.nn.dropout(fc, keep_rate)
output = tf.matmul(fc, weights['out'])+biases['out']
return output
def train_neural_network(x,train_data, train_labels, eval_images,
eval_lables):
prediction = convolutional_neural_network(x)
cost = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y))
optimizer = tf.train.AdamOptimizer().minimize(cost)
hm_epochs = 10
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
for epoch in range(hm_epochs):
epoch_loss = 0
for _ in range(int(len(train_data)/batch_size)):
epoch_x, epoch_y = train_data[_*batch_size:
(_+1)*batch_size], train_labels[_*batch_size:
(_+1)*batch_size]
_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x,
y: epoch_y})
epoch_loss += c
print('Epoch', epoch+1, 'completed out of',hm_epochs,'loss:',epoch_loss)
correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print('Accuracy:',accuracy.eval({x:eval_images, y:eval_lables}))
网络的结构只是2个卷积+池化层,然后是完全连接/密集层。我没有包含实际获取数据的代码部分,因为它有点麻烦,但是图像是嵌套的python列表,形成32x32(为简单起见,我将颜色扁平化为1个通道)。每个像素都在0-255整数范围内(我原来将它们标准化,没有区别)。标签是[1,0]或[0,1]。
我会感激任何帮助,即使它只是告诉我在这个问题上我是一个小丑。此外,我确定我遗漏了一些信息,所以如果需要澄清,我会添加它。
根据要求,这里是每个时期的损失:
Epoch 1 completed out of 10 loss: 329459839.0
Epoch 2 completed out of 10 loss: 165906787.75
Epoch 3 completed out of 10 loss: 110051434.0
Epoch 4 completed out of 10 loss: 76307372.1875
Epoch 5 completed out of 10 loss: 54765472.84375
Epoch 6 completed out of 10 loss: 44318552.59375
Epoch 7 completed out of 10 loss: 34356790.765625
Epoch 8 completed out of 10 loss: 27277588.34375
Epoch 9 completed out of 10 loss: 22176274.859375
Epoch 10 completed out of 10 loss: 18461464.671875
Accuracy: 0.605
这奇怪地高于正常情况,但通常情况类似。