首页 > 解决方案 > CNN准确率没有提高

问题描述

我有一个图像数据集(脑电图谱图),如下所示 在此处输入图像描述

图像尺寸为 669X1026。我正在使用以下代码对频谱图进行二进制分类。

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K

# dimensions of our images.
img_width, img_height = 669, 1026

train_data_dir = '/home/spectrograms/train'
validation_data_dir = '/home/spectrograms/test'
nb_train_samples = 791
nb_validation_samples = 198
epochs = 100
batch_size = 3



if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height,3)

model = Sequential()
model.add(Conv2D(128, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(16))
model.add(Activation('relu'))
# model.add(Dropout(0.5))

model.add(Dense(1))
model.add(Activation('sigmoid'))

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

model.summary()

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0,
    zoom_range=0,
    horizontal_flip=False)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

model.save_weights('CNN_model.h5')

但我无法获得大于 0.53 的训练准确度。我只有有限数量的数据(790 个训练样本和 198 个测试样本)。因此,增加输入图像的数量不是一种选择。我还能做些什么来提高准确性?

标签: tensorflowkerasdeep-learningconv-neural-network

解决方案


你的代码

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0,
    zoom_range=0,
    horizontal_flip=False)

没有做任何图像增强,只是重新调用。不确定哪种类型的增强可能会有所帮助。看起来你的图像真的不依赖于颜色。它可能无助于准确性,但您可以通过将图像转换为灰度来减少计算费用。通过使用 Keras 回调 ReduceLROnPlateau 和 EarlyStopping,您可能会得到一些改进。文档在这里。我为这些回调建议的代码如下所示

rlronp=tf.keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.5, patience=1,
    verbose=1, mode="auto", min_delta=0.0001, cooldown=0, min_lr=0)
estop=tf.keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0,patience=4,
    verbose=1, mode="auto", baseline=None, restore_best_weights=True)
callbacks=[rlronp, estop]

您可以尝试使用迁移学习。这些模型中的大多数都是在 imagenet 数据集上训练的,该数据集与您使用的图像类型不同,但可能值得一试。我建议您使用 Mobilenet 模型。代码如下所示

base_model=tf.keras.applications.mobilenet.MobileNet( include_top=False, 
           input_shape=input_shape, pooling='max', weights='imagenet',dropout=.4) 
x=base_model.output
x = Dense(64,activation='relu')(x)
x=Dropout(.3, seed=123)(x)
output=Dense(1, activation='sigmoid')(x)
model=Model(inputs=base_model.input, outputs=output)        
model.compile(Adamax(lr=.001), loss='binary_crossentropy', metrics=['accuracy']) 

使用上面在 model.fit 中引用的回调您可能会收到警告,Mobilenet 已使用 224 X 224 X 3 的图像形状进行训练,但它仍应加载 imagenet 权重并正常工作。


推荐阅读