![](/img/trans.png)
[英]50% validation accuracy in binary classification with any CNN model (including VGG16)
[英]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.