【问题标题】:Tensorflow - Convolutonal neural network with custom data set DOES NOT LEARNTensorflow - 具有自定义数据集的卷积神经网络不学习
【发布时间】:2016-02-29 02:40:01
【问题描述】:

我正在尝试为自定义数据集制作卷积神经网络。分类器只有两个类。我能够正确读取输入图像,并且还为它们分配了两个相应类的 batch_labels。代码执行没有错误,但输出异常。 由于某种原因,准确率始终为 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))

当我打印 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]

准确度始终为 0.5,就好像权重根本没有更新一样。当我在每个训练步骤后打印权重时,它们保持不变。我想我有一些编码错误。会不会是网络一次又一次地在同一张图像上训练?但即便如此,权重也必须更新。我有 150 个训练示例,每个类有 75 个。 有人可以指出我正确的方向吗?

编辑: 这就是我初始化权重的方式

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)

【问题讨论】:

    标签: python machine-learning computer-vision tensorflow deep-learning


    【解决方案1】:

    您的网络存在一些设计缺陷。由于数学问题,自己计算交叉熵并在输出层上应用 softmax 并不是一个好主意。如果你对数学感兴趣,我可以添加这个,如果不坚持 Tensorflow 的解释和方法:tf.nn.softmax_cross_entropy_with_logits

    您是否已经尝试过许多不同的配置?根据图像的复杂性,更高或更低的内核大小和特征图数量可能是一个好主意。通常,如果您的图像相对同质,则会添加许多非常相似的信息,因此如果您有许多特征图,网络将难以收敛。由于您只有两个输出神经元,我假设图像不是很复杂?

    接下来是你的辍学。您始终使用 0.5 的 dropout,但通常,对于测试/验证(如您的准确性预测),您不使用 dropout。在大多数情况下,您仅将其用于培训。您可以创建一个占位符来指定您的辍学率并提供此sess.run

    这是我自己的一些例子:

    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
                                }
                             )
    

    这让 Tensorflow 可以计算我的方程为 accuracytopX 错误率,同时我输入测试数据输入 teX 和真实标签 teY 用于输出,保持概率 keep_prob 为 1.0对于辍学者。

    尽管如此,权重的初始化在深度神经网络中非常重要。即使您的设计足以解决您的问题(这也必须进行调查),如果您的权重未正确初始化,您的网络可能会拒绝学习、发散或收敛到 0。您没有在初始化中添加详细信息,因此您可能想要查找 Xavier 初始化This 是 Xavier 初始化的一个简单开始。

    最后,我可以鼓励您绘制一些权重、特征图、随时间变化的输出等等,以了解您的网络在做什么。通常这会很有帮助。

    【讨论】:

    • 谢谢!首先,是的,我想知道不使用 softmax 层背后的数学原理。其次,我没有使用 feed_dict,因为我的输入只有一个批次,它们是张量,而不是 numpy 数组。第三,是的,我尝试了许多配置,但都松了一口气。网络无论如何都拒绝学习。我相信这是一个编码缺陷。第四,我也尝试过没有辍学,但没有让我松一口气。第五,我也初始化了权重,这样就没有死神经元了。
    • 我已经编辑了这个问题,让您更好地了解这个问题。再次感谢!
    • 如何初始化权重,更重要的是如何初始化权重?
    • 我已经编辑了问题,显示了权重初始化。
    • 你的 init 太大了。你的图片有多大?对于 1000 个神经元,stddev
    猜你喜欢
    • 1970-01-01
    • 2017-12-17
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2018-06-22
    • 1970-01-01
    相关资源
    最近更新 更多