2017-09-14 33 views
3

我很想获得关于以下挑战的见解和观点。我试图训练一个CNN来对具有不同“颜色块”的图像进行分类(请参见下面的示例)。图像是二维数组(例如20乘100像素),其中白色编码为0,蓝色编码为1,绿色编码为2.CNN:认识简单街区的挑战

我挣扎 - 有点令我惊讶 - 训练一个性能良好的网络这些类型的图像 - 特别是在图像尺寸变大时(例如40乘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

只是为了正确理解您的挑战:您已经在数据中编码了结果(任何发生的绿色像素=正面(1))。你为什么要训练一个神经网络,而不是简单地检查图像中的绿色? – petezurich

+1

为什么最后一张图片是否定的? –

+1

如果问题与以不同颜色查找一个块一样简单,那么您可能只需要非常少的过滤器(如1或2)以及几个图层。这个问题很简单,可以在没有神经网络的情况下解决。 –

回答

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,这是最好的检测图像上的模式(假设过滤器尺寸足够大)。