Точность CNN не улучшается

#tensorflow #keras #deep-learning #conv-neural-network

#tensorflow #keras #глубокое обучение #conv-нейронная сеть

Вопрос:

У меня есть набор данных изображений ( спектрограмм ЭЭГ ), как указано ниже введите описание изображения здесь

Размеры изображения составляют 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 тестовых выборок). Таким образом, увеличение количества входных изображений — это не вариант. Что еще я могу сделать, чтобы повысить точность?

Комментарии:

1. Это очень маленький объем данных. Вы можете немного усложнить свою модель, тогда вам также следует ее упорядочить. На самом деле я бы придерживался передачи обучения в этой задаче. Также, если вы можете, попробуйте немного увеличить размер пакета.

2. Можете ли вы объяснить, как я могу использовать здесь обучение передаче? Кроме того, существуют ли какие-либо алгоритмы или методы, которые полезны при работе с небольшим набором данных?

3. Я не уверен, содержит ли ‘imagenet’ такие вещи, как это, но попробовать стоит. Трудно работать с такими наборами данных. Возможно, может помочь увеличение с помощью opencv2 перед обучением.

4. Спасибо. Я постараюсь

5. Попробуйте поискать любую предварительно подготовленную модель с открытым исходным кодом, которая была обучена для аналогичной цели, подобной вашей, чтобы данные были похожими, тогда вы можете использовать ее для обучения передаче.

Ответ №1:

ваш код

 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]
 

Вы можете попробовать использовать transfer learning. Большинство этих моделей обучаются на наборе данных 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 и работать.