【问题标题】:CNN: challenge to recognize simple blocksCNN:识别简单块的挑战
【发布时间】:2017-09-14 14:07:49
【问题描述】:

我很想就以下挑战获得见解和观点。我正在尝试训练 CNN 对具有不同颜色的不同“块”的图像进行分类(请参见下面的示例)。图像是二维数组(例如 20 x 100 像素),其中白色编码为 0,蓝色编码为 1,绿色编码为 2。

我正在努力训练一个在这些类型的图像上性能良好的网络,尤其是在图像尺寸变大(例如 40 x 100)时,防止在验证集上出现过度拟合和性能非常差的情况,这让我有些吃惊。 .我试图理解/概念化识别这些类型的特征需要什么类型的 CNN 结构。

我在下面包含了我当前的网络结构 - 但这种结构往往具有混合性能,并且当图像大小增加时会失败或变得非常慢。我认为网络必须从上到下查看整个青色“块”才能做出准确的分类。

我很想就这样做的最佳方法提出想法。向网络添加更多层的最佳方法是什么?或者使用更大的卷积窗口?或者添加更多转化。过滤到每一层(例如从 64 到 96 等)?我觉得我在基本层面上做错了什么。

非常感谢您的想法和观点。

model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dropout(0.25))
model.add(Dense(1,activation="sigmoid"))  

opt = keras.optimizers.rmsprop(lr=0.001, decay=1e-5)
model.compile(loss='binary_crossentropy',optimizer=opt,metrics=['accuracy'])

【问题讨论】:

  • 只是为了正确理解您的挑战:您已经在数据中编码了结果(任何出现的绿色像素 = 正 (1))。为什么要训练神经网络而不是简单地检查图像中的绿色?
  • 为什么最后一张图片是负片?
  • 如果问题就像找到一个不同颜色的块一样简单,那么您可能只需要非常少的过滤器,例如 1 或 2,并且也只需很少的层。这个问题很简单,无需神经网络即可解决。
  • 感谢 cmets。这个例子是我试图解决的一个更复杂的图像识别问题的简化版本。我试图从一个程式化的简单示例开始。最后一个图像是负的,因为该块没有覆盖图表的整个垂直宽度,并且只有一个像素宽。我知道可以手动编码这些规则,但我想推动 CNN 自动提取这些特征。
  • 我尝试运行一个只有 2 层且过滤器很少(范围从 2 到 4)的网络 - 但不幸的是性能并不强。

标签: computer-vision keras conv-neural-network convolution


【解决方案1】:

所以只是向您展示您的设计中可能存在的两个问题和一些可能的解决方案:

  1. 您的网络的感受野太小:让我们根据来自给定层的过滤器看到的原始图片的大小来分析您的网络:

    model = Sequential()
    model.add(Conv2D(64, (3, 3), input_shape=input_shape)) # RF size = (3, 3)
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2))) # RF size = (4, 4)
    model.add(Dropout(0.25))
    
    model.add(Conv2D(64, (3, 3))) # RF size = (6, 6)
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2))) # RF size = (7, 7)
    model.add(Dropout(0.25))
    ...
    

    因此,从您的网络中获取信号的字段的最大尺寸远小于您的图片尺寸(其高度似乎为 10)。

    要克服这个问题 - 您可以增加第一层中的过滤器大小,使其高度等于图片的高度(所以基本上使用了相当于 1D 卷积的东西)。

  2. Flatten 是个坏主意: 当您使用 Flatten 时 - 您的网络实际上会考虑图像上不同图案的位置 - 例如它需要分别区分左侧的完整块和右侧的完整块,即使它们是相同的对象。克服这个问题的最佳选择是使用GlobalMaxPooling2D,它最适合检测图像上的模式(假设过滤器尺寸足够大)。

【讨论】:

    猜你喜欢
    • 2018-12-12
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多