繁体   English   中英

CNN 中图像二进制分类的 50% 准确率

[英]50% accuracy in CNN on image binary classification

我有一组睁眼和闭眼的图像。
使用 keras 从当前目录收集数据,方式如下:

batch_size = 64
N_images = 84898 #total number of images
datagen = ImageDataGenerator(
    rescale=1./255)
data_iterator = datagen.flow_from_directory(
    './Eyes',
    shuffle = 'False',
    color_mode='grayscale',
    target_size=(h, w),
    batch_size=batch_size,
    class_mode = 'binary')

我有一个.csv 文件和每只眼睛的 state。

我已经构建了这个顺序 model:

num_filters = 8
filter_size = 3
pool_size = 2

model = Sequential([
  Conv2D(num_filters, filter_size, input_shape=(90, 90, 1)),
  MaxPooling2D(pool_size=pool_size),
  Flatten(),
  Dense(16, activation='relu'),
  Dense(2, activation='sigmoid'), # Two classes. one for "open" and another one for "closed"
])

Model 编译。

model.compile(
    'adam',
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

最后,我将所有数据与以下内容相匹配:

model.fit(
  train_images,
  to_categorical(train_labels),
  epochs=3,
  validation_data=(test_images, to_categorical(test_labels)),
)

结果在 50% 左右波动,我不明白为什么。

您当前的 model 基本上有一个卷积层。 也就是说,定义和拟合num_filters卷积滤波器(在本例中为 3 x 3 数组),以便当它们与图像进行卷积时,它们会产生尽可能区分类别的特征。 然后执行 maxpooling 以稍微减小 output CNN 特征的维度,然后再传递到 2 个密集层。

我首先要说一个卷积层几乎肯定是不够的,尤其是对于 3x3 过滤器。 基本上,使用单个卷积层,您可以获得的最有意义的信息是边缘或线条。 这些功能对于 function 逼近器(即您的全连接层)仅比原始像素强度值更有用,因为它们在 class 内和类之间仍然具有极高程度的可变性。 考虑将眼睛的图像向左移动 2 个像素会导致与 1 层 CNN 完全不同的值 output。 您希望 CNN 的输出在缩放、旋转、照明等方面保持不变。

实际上,这意味着您将需要更多的卷积层。 相对简单的 VGG 网络至少有 14 个卷积层,而现代基于残差层的网络通常有 100 多个卷积层。 尝试编写一个例程来依次定义更复杂的网络,直到您开始看到性能提升。

作为第二点,通常您不想在训练期间对最终层输出使用sigmoid()激活 function。 这会使梯度变平,并使反向传播损失的速度慢得多。 您实际上并不关心 output 值介于 0 和 1 之间,您只关心它们的相对大小。 常见的做法是使用交叉熵损失,它结合了对数 softmax function(梯度比正常 softmax 更稳定)和负对数似然损失,正如您已经完成的那样。 因此,由于 log softmax 部分将 output 值转换为所需范围,因此无需使用 sigmoid 激活 function。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM