【问题标题】:Tensorflow: CNN is not learning at allTensorflow:CNN 根本没有学习
【发布时间】:2017-04-04 10:08:14
【问题描述】:

我刚刚创建了自己的 CNN,它从磁盘读取数据并尝试学习。 但是权重似乎根本没有学习,它们都是随机的。

偏见只改变了一点。我已经尝试使用灰度图像,但没有成功。我也厌倦了将我的数据集减少到只有 2 个在我看来应该有效的类。但是实测准确率低于50%(可能我计算的准确率是假的)

这里有一些代码:

x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, classes])
weights = {
    'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
    'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
    'wd1': tf.Variable(tf.random_normal([12*12*64, 1024])),
    'out': tf.Variable(tf.random_normal([1024, classes]))
}
biases = {
    'bc1': tf.Variable(tf.random_normal([32])),
    'bc2': tf.Variable(tf.random_normal([64])),
    'bd1': tf.Variable(tf.random_normal([1024])),
    'out': tf.Variable(tf.random_normal([classes]))
}

pred = model.conv_net(x, weights, biases, keep_prob, imgSize)

with tf.name_scope("cost"):
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
with tf.name_scope("optimizer"):
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
with tf.name_scope("accuracy"):
    correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    while(step < epochs):
         batch_x, batch_y = batch_creator(batch_size, train_x.shape[0], 'train')
         sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: dropout})
          if(step % display_step == 0):
                 batchv_x, batchv_y = batch_creator(batch_size, val_x.shape[0], 'val')
                 summary, loss, acc = sess.run([merged, cost,  accuracy], feed_dict={x: batchv_x, y: batchv_y})
                 train_writer.add_summary(summary, step)

我查看了创建的批次,看起来不错。 batch_x 是一个长度为 2304 个浮点值的数组,代表 48x48 图像 batch_y 是一个带有 one_hot 标签的数组:[0 0 ... 0 1 0 ... 0 0]

这是我的模型:

def conv2d(x, W, b, strides=1):
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x)

def maxpool2d(x, k=2):
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
                          padding='SAME')

def conv_net(x, weights, biases, dropout, imgSize):
    with tf.name_scope("Reshaping_data") as scope:
        x = tf.reshape(x, shape=[-1, imgSize, imgSize, 1], name="inp") #(?, 48, 48, 1)

    with tf.name_scope("Conv1") as scope:
        conv1 = conv2d(x, weights['wc1'], biases['bc1'])
        conv1 = maxpool2d(conv1, k=2) #(?, 24, 24, 32)

    with tf.name_scope("Conv2") as scope:
        conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
        conv2 = maxpool2d(conv2, k=2) #(?, 12, 12, 64)

    with tf.name_scope("FC1") as scope:
        fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]]) #(?, 9216)
        fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1']) #(?, 1024)
        fc1 = tf.nn.relu(fc1) #(?, 1024)

    out = tf.add(tf.matmul(fc1, weights['out']), biases['out'], name="out") #(?, 43)
    return out

感谢您的帮助!

PS:这是第二个卷积层的一些过滤器的样子(不管后面多少个 epoch)

【问题讨论】:

  • 您没有在会话中运行init 来初始化变量。您不会因此而收到错误消息吗?
  • 我正在运行初始化,我只是忘了复制和粘贴它。我编辑了我的问题。谢谢!
  • 啊,我明白了...不过,您只运行了一次优化器。通常,您需要对整个数据集进行多次训练(“epochs”),然后才能真正看到实现目标的任何进展。还是有一些隐式循环?
  • 它在循环中运行。我只是尽量去掉复制这里的代码
  • 而且(我知道这是基本的,但我只是在考虑常见的嫌疑人)我假设您正在确保 init 操作在循环,对吧?当然还有会话创建本身。据我所知,该模型对我来说看起来不错。当我遇到这类错误时,我发现通常是一些更简单的控制流错误。

标签: python tensorflow conv-neural-network


【解决方案1】:

我已经使用 cifar-10 数据库尝试了您的网络。

恐怕问题是由巨大的参数引起的,尤其是在fc1层。您可以尝试在卷积层中减少内核数,例如除以 2,并在池化层中使用 4 或 6 作为 k 以减少空间维度。然后你可以减少很多 fc1 层的权重。

当参数很多时,要注意权重初始化。使用tf.contrib.layers.xavier_initializer()tf.random_normal_initializer(stddev=np.sqrt(2.0 / n)) 以获得更好的初始化。

在减少参数和更好地初始化权重后,cifar-10 上的损失开始收敛。你可以用你自己的数据库试试这个。

【讨论】:

  • 非常感谢。我现在将 xavier init 添加到权重并显着减少了参数(8 个过滤器 conv1,16 个过滤器 conv2,两次都使用 4 个池。如果我运行它,我会得到这个 acc/costs imgur.com/a/Z4AA5。对于训练,我使用 80k 48x48 灰度图像以 70:30 分割进行验证。它们被分割为 43 个 one-Hot 类
  • 抱歉,在使用 cifar-10 进行训练时,我也使用了常数初始化 0.01 来处理偏差。如果你也试试这个怎么办?而且,如果我仍然对偏差使用随机初始化,那么训练不收敛的可能性很小(1/5)。并尝试使用学习率和批量大小。就我而言,我分别使用了 0.01(使用 AdamOptimizer)和 128。大约 100~500 次迭代,loss 明显减少。
  • 我使用了您的建议并与他们一起玩了一下,但没有成功。结果如下所示:imgur.com/a/HQBF6。我还在这里上传了我的完整代码:pastebin.com/vGj9bMf7。我使用的数据库可以在这里找到:benchmark.ini.rub.de/?section=gtsrb&subsection=dataset谢谢!
  • 如何拆分训练集和验证集?我想说的是,在拆分到训练和验证集之前,您是否已经对整个数据集进行了洗牌。如果不是,则网络在训练期间看不到验证集中的示例。还有一个建议,你不必训练这么长时间就能得到结果。也许 10K~30K 迭代就足够了。
  • 训练/测试数据的文件列表在使用 tensorflow 读取它们之前已经随机化。
猜你喜欢
  • 2019-05-21
  • 1970-01-01
  • 2017-03-02
  • 2017-07-01
  • 2020-07-09
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
相关资源
最近更新 更多