简体   繁体   English

Tensorflow - 具有自定义数据集的Convolutonal神经网络不会学习

[英]Tensorflow - Convolutonal neural network with custom data set DOES NOT LEARN

I am trying to make a convolutional neural network for custom data set. 我正在尝试为自定义数据集创建卷积神经网络。 The classifier has only two classes. 分类器只有两个类。 I am able to read the input images properly and have also assigned them the batch_labels for the two corresponding classes . 我能够正确读取输入图像,并为两个相应的类分配了batch_labels。 The code executes without error, but the output is anomalous. 代码执行没有错误,但输出是异常的。 For some reason, the accuracy is always 50%. 出于某种原因,准确度始终为50%。

image=inputs()

image_batch=tf.train.batch([image],batch_size=150)
label_batch_pos=tf.train.batch([tf.constant([0,1])],batch_size=75) # label_batch for first class
label_batch_neg=tf.train.batch([tf.constant([1,0])],batch_size=75) # label_batch for second class
label_batch=tf.concat(0,[label_batch_pos,label_batch_neg])

W_conv1 = weight_variable([5, 5, 3, 32])
b_conv1 = bias_variable([32])

image_4d = tf.reshape(image, [-1,32,32,3])

h_conv1 = tf.nn.relu(conv2d(image_4d, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

W_fc1 = weight_variable([8 * 8 * 64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 8*8*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, 0.5)

W_fc2 = weight_variable([1024, 2])
b_fc2 = bias_variable([2])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
cross_entropy = -tf.reduce_sum(tf.cast(label_batch,tf.float32)*tf.log(y_conv+1e-9))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)


tf.train.start_queue_runners(sess=sess)
correct_prediction=tf.equal(tf.argmax(y_conv,1), tf.argmax(label_batch,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

for i in range(100):
 train_step.run(session=sess)
 print(sess.run(accuracy))

print(sess.run(correct_prediction))

When I print the correct_prediction tensor, I get the following output no matter what. 当我打印correct_prediction张量时, correct_prediction我得到以下输出。

[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False]

The accuracy is always 0.5, as if the weights are not being updated at all. 精度始终为0.5,就好像权重根本没有更新一样。 When I print weights after each training step, they remain unchanged. 当我在每个训练步骤后打印重量时,它们保持不变。 I think I have some coding error. 我想我有一些编码错误。 Could it be that the network is training on the same image again and again? 是不是网络一次又一次地训练同一个图像? But even so, the weights must update. 但即便如此,权重必须更新。 I have 150 training examples, with 75 belonging to each class. 我有150个训练样例,每个班级有75个。 Could someone please point me in the right direction ? 有人可以指点我正确的方向吗?

EDIT : This is how I initialize weights 编辑 :这是我初始化权重的方式

def weight_variable(shape,name):
  initial = tf.truncated_normal(shape, stddev=0.5)
  return tf.Variable(initial,name=name)

def bias_variable(shape,name):
  initial = tf.constant(1.0, shape=shape)
  return tf.Variable(initial,name=name)

Your network has some design flaws. 您的网络存在一些设计缺陷。 Because of mathematical issues it is not a good idea to calculate the cross entropy yourself and apply a softmax on the output layer. 由于数学问题,自己计算交叉熵并在输出层上应用softmax不是一个好主意。 If you are interested in the mathematics I could add this, if not stick to the Tensorflow explanation and method: tf.nn.softmax_cross_entropy_with_logits . 如果你对数学感兴趣我可以添加这个,如果不坚持Tensorflow解释和方法: tf.nn.softmax_cross_entropy_with_logits

Have you already tried many different configurations? 你有没有尝试过很多不同的配置? Depending on the complexity of your images a higher or lower kernel size and amount of feature maps might be a good idea. 根据图像的复杂程度,更高或更低的内核大小和特征映射的数量可能是个好主意。 Generally, if your images are relatively homogeneous, a lot of rather similar information is added up and therefore the network has it harder to converge if you have many feature maps. 通常,如果您的图像相对同质,则会添加许多相当类似的信息,因此如果您有许多要素图,则网络难以收敛。 Since you have only two output neurons I assume are images are not very complex? 既然你只有两个输出神经元我假设图像不是很复杂?

The next thing is your dropout. 接下来就是你的辍学生。 You are always using a dropout of 0.5 but normally, for test/validation (like your accuracy prediction) you do not use dropout. 您总是使用0.5的丢失,但通常,对于测试/验证(如您的准确度预测),您不使用dropout。 In most cases you only use it for training. 在大多数情况下,您只能将其用于培训。 You can create a placeholder specifying your dropout rate and feed this sess.run . 您可以创建一个占位符来指定您的辍学率并提供此sess.run

Here is some example of my own: 这是我自己的一些例子:

h_fc_drop = tf.nn.dropout(h_fc, keep_prob)

(...)

accu, top1, top3, top5 = sess.run([accuracy, te_top1, te_top3, te_top5],
                            feed_dict={
                                x: teX[i: i + batch_size],
                                y: teY[i: i + batch_size]
                                keep_prob: 1.0
                            }
                         )

This lets Tensorflow calculate my equations for accuracy and topX error rate, while I feed in the test data input teX and the real labels teY for the output with a keep probability keep_prob of 1.0 for the dropout. 这让Tensorflow计算我的方程式的accuracytopX错误率,同时我输入测试数据输入teX和输出的真实标签teY ,保持概率keep_prob为1.0用于丢失。

Despite this the initialization of your weights is really important in deep neural networks. 尽管如此,权重的初始化在深度神经网络中非常重要。 Even if your design is sufficient for your kind of problem (this also has to be investigated) your network could refuse to learn, diverge or converge to 0 if your weights are not initialized properly. 即使您的设计足以解决您的问题(这也需要进行调查),如果您的权重未正确初始化,您的网络可能会拒绝学习,分歧或收敛到0。 You did not add details to your initialization so you maybe want to look up Xavier initialization . 您没有向初始化添加详细信息,因此您可能希望查找Xavier初始化 This is an easy beginning for Xavier initialization. 是Xavier初始化的一个简单的开始。

Conclusively I can just encourage you to plot some weights, feature maps, the output over time and so on to get an idea of what your network is doing. 最后,我可以鼓励您绘制一些权重,功能图,随时间变化的输出等,以了解您的网络正在做什么。 Normally this helps a lot. 通常这会有很大帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM