【问题标题】:Why can't my CNN learn?为什么我的 CNN 无法学习?
【发布时间】:2016-09-10 18:39:06
【问题描述】:

我是深度学习的新手。我刚刚用 Tensorflow 实现了一个 CNN,并在 CIFAR-10(一个对象识别基准,其中图像属于 10 个不同的类别)上进行了尝试。

在训练过程中,训练损失一开始下降得非常快(从 100000 到 3),但之后一直停留在 2.30 左右(大约是 log(1/10) )。由于我使用交叉熵作为损失函数,因此 2.30 的损失意味着我的模型的准确率约为 10% ---- 与随机猜测完全相同(我检查了模型的实际输出,实际上几乎都在 10% 左右每个班级)。

我尝试增加模型的大小以尝试是否是因为我的模型不够“强大”而无法过拟合。但事实证明,无论我如何增加或减少模型大小,训练损失总是会在 2.30 左右停止减少。

我非常有信心我正确地实现了它,因为我的模型适用于更简单的任务,例如 MNIST(手写数字识别)。所以我真的想知道问题可能是什么。非常感谢。

conv1:带relu的卷积层

pooling1:最大池化层

fc1:带relu的全连接层

输出:带有 softmax 的全连接层

代码:

nn = NeuralNetwork(optimizer=Adam(0.001), log_dir='logs')
nn.add(Input('input', [32, 32, 3], ))
nn.add(Convolution2D(name='conv1', filter_height=3, filter_width=3, 
                     n_output_channels=256, activation_fn='relu'))
nn.add(Pooling2D('pooling1', mode='max', pool_shape=(3, 3), padding='SAME'))
nn.add(Convolution2D(name='conv2', filter_height=3, filter_width=3, 
                     n_output_channels=128, activation_fn='relu'))
nn.add(Pooling2D('pooling2', mode='max', pool_shape=(3, 3), padding='SAME'))
nn.add(FullyConnected('fc1', 384, activation_fn='relu',
                      weight_init=truncated_normal(), bias_init=constant(0.1)))
nn.add(FullyConnected('fc2', 192, activation_fn='relu', 
                      weight_init=truncated_normal(), bias_init=constant(0.1)))
nn.add(Output(loss_fn='sparse_softmax_cross_entropy', output_fn='softmax',
              name='output', target_shape=[], target_dtype=tf.int64, 
              output_shape=10))
nn.build()

编辑:

正如我所提到的。我试图通过添加更多层来增加模型的复杂性,并且几乎尝试了教程中的那个,除了我没有规范层(conv1、pooling1、conv2、pooling2、fc1、fc2、softmax)和像白化等预处理。为简单起见,我认为这可能不会严重影响我的表现,从 86% 到 10%。

我认为可能有帮助的另一个线索是,我发现层 fc1 的输出非常稀疏(几乎 99% 的元素都是零)。由于我使用 ReLU 作为激活函数,这意味着 fc1 中的单元大多是死的。我有什么可以用它做的吗?

【问题讨论】:

  • 您是否检查过两次标签,可能在洗牌数据时出现问题?
  • MNIST 具有更简单的功能,因此一个卷积层就足够了,要开始学习像 CIFAR-10 这样的真实图像数据集,您至少需要添加另一个卷积层。即conv2和pool2。按照这个例子:github.com/tensorflow/tensorflow/blob/master/tensorflow/models/…
  • 是的,但我也尝试过使用两个卷积层和两个池化层。仍然停留在 2.3 左右
  • 您是否对更复杂的模型进行了很多超参数优化?也许如果您发布代码的最小版本,它会有所帮助。我几乎看不懂你图中的张量形状,但它看起来像 [?, 32, 32, 3] => CONV1/POOL1 => [?, 16, 16, 128] => CONV2/POOL2 => [? , 8, 8, 64]。如果我没看错,那不太可能运作良好。第一次卷积后网络的“宽度”非常宽,然后急剧变窄,第二次卷积丢弃了许多个特征。 [?, 32, 32, 3] => [?, 16, 16, 64] => [?, 8, 8, 128] 会更好。
  • 感谢您发布代码。我不确定它到底做了什么——看起来它正在使用一些非标准功能(可能是您创建的基础设施?)我建议使用 5x5 内核。 (3x3 内核可以工作 - VGGNet 是一个很好的例子,但当然这是一个更深的网络架构。)根据我之前的评论,请考虑避免网络宽度的急剧变化。

标签: computer-vision neural-network tensorflow deep-learning


【解决方案1】:

您可能只是严重低估了在此任务中获得合理结果所需的架构。您描述的模型(输入->conv1->pooling1->fc1->output)对于 MNIST 来说可能已经足够了,但这并不意味着它在涉及真实彩色图像的图像分类任务上可以取得比随机结果更好的结果。

现实情况是,您需要为人们提供实际代码以提供更具体的建议,但根据您描述的模型,我至少建议您查看其他一些可以解决此问题的模型。例如,Tensorflow 带有一个example CNN,它可以在 CIFAR-10 上达到约 86% 的准确度,但这个模型更复杂。即使有额外的卷积和全连接层、归一化和输入预处理(白化、数据增强等)以及调整的超参数,仍然需要在强大的 GPU 上进行数小时的训练才能获得良好的结果。

无论如何,长话短说,我认为您应该查看示例模型以了解所需的架构类型。很容易低估识别随机彩色图像中的对象与黑白数字集相比要复杂得多。

【讨论】:

  • 感谢您的回答,但正如我所提到的。我试图通过添加更多层来增加模型的复杂性,几乎尝试了教程中的那个,除了我没有标准层(conv1、pooling1、conv2、pooling2、fc1、fc2、softmax ) 和像美白等预处理,为了简单起见,我认为这可能不会严重影响我的性能,从 86% 到 10%,可能吗?
  • 您对更复杂的模型尝试了哪些超参数优化?即使 NN 架构中的微小差异也可能需要大量的超参数优化,以实现比随机精度更好的精度。
  • 嗨,@Aenimated,我已经发布了我的代码。顺便说一句,它与一开始的版本略有不同,因为我把它变得更复杂了,但仍然没有太大的进步。
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 2017-01-30
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
相关资源
最近更新 更多