Keras CNN 精度要么是静态的,要么对于图像分类来说太高了

Posted

技术标签:

【中文标题】Keras CNN 精度要么是静态的,要么对于图像分类来说太高了【英文标题】:Keras CNN accuracy is either static or way too high for image classification 【发布时间】:2021-01-31 16:12:44 【问题描述】:

我正在尝试实现一个卷积神经网络,它可以检测一个人是否戴眼镜。不幸的是,无论我使用哪种确切的设置来设置学习率、特定的优化器等,我都会得到非常奇怪的结果。对于大多数设置,我注意到我的模型的准确性在第二个 epoch 之后并没有改变并且卡在0.56(接近一个标签2700张图片与另一个标签2200张图片的比率)。在其他运行中,设置稍有不同,准确率突然飙升至 0.9 左右并不断增加。然而,在这两种情况下,模型每次都预测完全相同的分类(“戴眼镜”)(即使在训练/验证集中的图像上),始终具有 100% 的置信水平(每个标签正好是 1时间)。

我对神经网络进行图像分类的经验并不多,所以我不太确定如何解决这个问题。我尝试从我的数据集中打印一些值及其各自的标签,并且标签确实包含两个标签(0 和 1)。因此,我认为这可能是我的模型的问题,但我自己并不能真正弄清楚。我尝试了不同的优化器(主要是 Adam,SGD)、越来越小的学习率、不同的动量值、更少/更多的卷积层以及填充和 kernel_initializer 的不同参数、不同的批量大小......快速提高精度或静态精度。

我的代码如下:

#parameters
batch_size = 16
img_height = 180
img_width = 180
num_classes = 2
epochs = 10

#training data
train_db = tf.keras.preprocessing.image_dataset_from_directory(
  `D:\archive\faces\`,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width), color_mode = "grayscale",
  batch_size=batch_size)

#validation data
val_db = tf.keras.preprocessing.image_dataset_from_directory(
  `D:\archive\faces\`,
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width), color_mode = "grayscale",
  batch_size=batch_size)

#speeds up the model training
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_db = train_db.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_db = val_db.cache().prefetch(buffer_size=AUTOTUNE)

#establishing the model
model = Sequential([
layers.experimental.preprocessing.Rescaling(1./255),
layers.Conv2D(16, (3,3), activation='relu', input_shape=(img_width, img_height, 1), kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2, 2),
layers.Conv2D(32, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Flatten(),
layers.Dense(512, activation='relu', kernel_initializer='he_uniform'),
layers.Dense(1, activation='sigmoid')
])

#different optimizer options
opt = tf.keras.optimizers.SGD(learning_rate=0.001, momentum=0.9)
opt2 = tf.keras.optimizers.Adam(learning_rate=0.001)

#compiling the model
model.compile(
  optimizer=opt,
  loss=tf.losses.BinaryCrossentropy(),
  metrics='accuracy')

#training the model
model.fit(train_db,validation_data=val_db,epochs=epochs)

【问题讨论】:

【参考方案1】:

因为您使用的是 loss=tf.losses.BinaryCrossentropy(),所以在 image_dataset_from_directory 中,您需要为 train_db 和 val_db 添加 label_mode='binary'。对于 val_db 添加 shuffle=False

【讨论】:

我试图添加这个,不幸的是无济于事。似乎确实有所作为的是使用了更少量的数据(实际数据集的 10%),现在它实际上预测了 0 和 1 之间的值。 尝试在model.fit中添加batch_size=batch_size

以上是关于Keras CNN 精度要么是静态的,要么对于图像分类来说太高了的主要内容,如果未能解决你的问题,请参考以下文章

CNN——全连接层 dense/FC

使用 keras 顺序模型获得较差的分类精度

Keras:过拟合模型?

如何使用精度(而不是准确度)在 Keras 中优化 CNN

Cnn keras模型没有经过训练的参数表示和改进模型

如何在 Keras 中使用预训练的 CNN 实现连体网络?