我有两张打印物体的照片,第一张是2.5x2.5 cm^2的打印面积,第二张是同一个物体,但打印面积是5.0x5.0 cm^2。在将物体从背景中分离出来并均衡这两张图片的直方图之后,我试图在深度学习方法(CNN)中使用小补丁(64x64)来理解它们的模式并对它们进行分类。我尝试使用2.5x2.5cm^2打印对象中的64x64补丁来训练深度学习分类器,并使用5.0x5.0cm^2对象中的补丁测试它们。两个对象的数字图像的分辨率大致相同,这是从对象提取程序中定义的。以下是用于训练和测试CNN二进制分类器的64x64补丁的示例。
2.5x2.5cm^2对象的64x64修补程序
5x5cm^2对象的64x64修补程序
我要预测的类如下:
负类(第一次打印)
正类(复印、再版)
我发现:
-
2.5x2.5cm^2物体的补丁如果CNN接受相同大小(面积)物体的补丁训练,很容易分类。
-
如果CNN使用2.5x2.5cm^2物体的64x64补丁进行培训,并使用5x5cm^2物体的64x64补丁进行测试,则预测结果仅适用于一个等级(精度为50%)。
-
在这种情况下,一些多尺度和多分辨率描述符可以很好地工作,例如使用一袋视觉单词
-
在这种情况下,其他基线CNN也会失败,如Mobilenet、Densenet和Resnet。
-
我试图在我的数据扩充过程中包括缩放(就像一个答案所建议的那样)。它也不起作用:-(
这是我到目前为止试过的角膜模型
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=3, strides=1, padding='same',
input_shape=input_shape))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(filters=32, kernel_size=3, strides=2, padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(axis=-1, momentum=0.9, epsilon=0.001))
model.add(Conv2D(filters=64, kernel_size=3, strides=1, padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(axis=-1, momentum=0.9, epsilon=0.001))
model.add(Conv2D(filters=64, kernel_size=3, strides=2, padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(axis=-1, momentum=0.9, epsilon=0.001))
model.add(Conv2D(filters=96, kernel_size=3, strides=1, padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(axis=-1, momentum=0.9, epsilon=0.001))
model.add(Conv2D(filters=96, kernel_size=3, strides=2, padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(axis=-1, momentum=0.9, epsilon=0.001))
model.add(Flatten())
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(2, activation='softmax'))
return model
这是我正在使用的数据扩充
datagen = ImageDataGenerator(
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
vertical_flip=True,
zoom_range=0.2,
fill_mode='nearest')
datagen.fit(x_train)
datagen.fit(x_validation)
model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
steps_per_epoch=x_train.shape[0]
validation_data=datagen.flow(x_validation, y_validation, batch_size=batch_size),
epochs=nb_epoch, verbose=1, max_q_size=100,
validation_steps=x_validation.shape[0]
callbacks=[lr_reducer, early_stopper, csv_logger, model_checkpoint])
那么,对于CNN来说,在这种非常困难的情况下,有没有解决方案来提高准确性呢?我的意思是,CNN从数据中学习特性,正如你所看到的,来自同一个班级的培训和测试数据是不同的。那么,对于我来说,是否有可能执行任何数据扩充或CNN操作(我的CNN没有退学,也没有汇集,如你所见),以最小化或模拟培训数据中的测试数据?