CNN:识别简单块的挑战

时间:2017-09-14 14:07:49

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

我希望获得有关以下挑战的见解和观点。我正在尝试培训CNN来对具有独特"块"的图像进行分类。颜色不同(请参阅下面的例子)。图像是2D阵列(例如20乘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'])

enter image description here

1 个答案:

答案 0 :(得分: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,这对于检测图像上的模式最佳(假设过滤器大小足够大)。