我创建了一个用于分类杂草图像的CNN。图像是128 * 128,我的准确度非常糟糕。在18-32%之间,我有四个班级。其中三种是不同类型的杂草,最后一种是没有杂草。总共大约有1000张图片。我做错了什么,我的准确性是如此可怕(有时比猜测更糟)。我的图像缩小了很多吗? (原来是425 * 425),我的图层错了吗?是否有太少的图像需要训练? 我现在的设置有什么方法可以改善结果吗?我目前不熟悉tensorflow,所以这不一定是最优的。代码部分来自修改后的教程,以满足我的需求。
我的代码如下所示:
def parse_function(filename, label):
image_string = tf.read_file(filename)
image = tf.image.decode_png(image_string, channels=3)
#image_resized = tf.image.resize_image_with_crop_or_pad(image, 128, 128)
new_image = tf.image.resize_image_with_crop_or_pad(image, 128,128)
return new_image, label
# INIT weights
def init_weights(shape):
init_random_dist = tf.truncated_normal(shape, stddev=0.1)
return (tf.Variable(init_random_dist))
# INIT Bias
def init_bias(shape):
init_bias_vals = tf.constant(0.1, shape=shape)
return tf.Variable(init_bias_vals)
# CONV2D
def conv2d(x, W):
# x --> input tensor [batch, H, W, Channels]
# W --> [filter H, filter W, Channels IN, Channels OUT]
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
# Pooling
def max_pooling_2by2(x):
# x --> [batch, h, w, c]
return tf.nn.max_pool(
x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
#Convolutional layer
def convolutional_layer(input_x, shape):
W = init_weights(shape)
b = init_bias([shape[3]])
return tf.nn.relu(conv2d(input_x, W) + b)
# Normal (FULLY CONNTCTED)
def normal_full_layer(input_layer, size):
input_size = int(input_layer.get_shape()[1])
W = init_weights([input_size, size])
b = init_bias([size])
return tf.matmul(input_layer, W) + b
def main():
one_hot_encoded_labels_dummy = []
one_hot_encoded_test_labels_dummy = []
filenames_dummy, labels_dummy, test_filenames_dummy, test_labels_dummy = image_util.run_it()
for x in labels_dummy:
one_hot_encoded_labels_dummy.append(wd.one_hot_encoder(x))
for y in test_labels_dummy:
one_hot_encoded_test_labels_dummy.append(wd.one_hot_encoder(y))
filenames = tf.constant(filenames_dummy)
labels = tf.constant(one_hot_encoded_labels_dummy)
test_filenames = tf.constant(test_filenames_dummy)
test_lables = tf.constant(one_hot_encoded_test_labels_dummy)
dataset = tf.contrib.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(wd.parse_function)
test_dataset = tf.contrib.data.Dataset.from_tensor_slices((test_filenames,
test_lables))
test_dataset = test_dataset.map(wd.parse_function)
dataset = dataset.batch(5)
dataset = dataset.shuffle(len(filenames_dummy))
dataset = dataset.repeat()
test_dataset = test_dataset.batch(60)
test_dataset = test_dataset.repeat()
iterator = dataset.make_one_shot_iterator()
test_iterator = test_dataset.make_one_shot_iterator()
# PLACEHOLDERS
x = tf.placeholder(tf.float32, shape=[None, 128, 128, 3])
y_true = tf.placeholder(tf.float32, shape=[None, 4])
convo_1 = wd.convolutional_layer(x, shape=[5,5,3,128])
convo_1_pooling = wd.max_pooling_2by2(convo_1)
convo_2 = wd.convolutional_layer(convo_1_pooling, shape=[5,5,128, 128*2])
convo_2_pooling = wd.max_pooling_2by2(convo_2)
convo_2_flat = tf.reshape(convo_2_pooling, [-1,32*32*256])
full_layer_one = tf.nn.relu(wd.normal_full_layer(convo_2_flat, 1024))
# Dropout
hold_prob = tf.placeholder(tf.float32)
full_one_dropout = tf.nn.dropout(full_layer_one, keep_prob=hold_prob)
y_pred = wd.normal_full_layer(full_one_dropout, 4)
# LOSS function
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred))
# Optimizer
optimizer = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cross_entropy)
init = tf.global_variables_initializer()
steps = 1000
with tf.Session() as sess:
sess.run(init)
for i in range(steps):
value_x, value_y = iterator.get_next()
batch_x, batch_y = sess.run([value_x, value_y])
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred))
_, loss_val = sess.run([
optimizer, cross_entropy], feed_dict={
x: batch_x,
y_true: batch_y,
hold_prob: 0.5
})
print(loss_val, " is the loss")
if i % 10 == 0:
print("ON STEP {}".format(i))
print("Accuracy: ")
matches = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_true, 1))
accuracy = tf.reduce_mean(tf.cast(matches, tf.float32))
test_1, test_2 = test_iterator.get_next()
test_batch_x, test_batch_y = sess.run([test_1, test_2])
print(sess.run(
accuracy,
feed_dict={
x: test_batch_x,
y_true: test_batch_y,
hold_prob: 1.0
}))
main()