CNN - точность модели колеблется около 50% - PullRequest
0 голосов
/ 06 апреля 2020

Я использую CNN для прогнозирования клинической значимости медицинских изображений. У меня есть несбалансированный набор train_data из 196 изображений с 149 True и 47 False. Чтобы сбалансировать набор данных, я использовал увеличение данных для пересчета ложных данных. Полученный набор данных включал 3817 образцов с примерно 50/50 для каждого класса. Однако когда я использовал этот набор данных для обучения модели, я всегда получал точность около 50%. Я также попытался использовать тот же набор данных для предварительно обученной модели VGG19 (не включая верхние слои), и все работало как обычно (точность 80-90%). Я понятия не имею, что случилось с построением модели с нуля.

Код

from keras import models
from keras import layers
from keras.utils import np_utils, generic_utils
from keras.utils import to_categorical
from keras.preprocessing.image import ImageDataGenerator
from keras.applications import VGG19
from sklearn.model_selection import KFold
from keras.optimizers import adam
import pickle
import numpy as np

### CNN model and training ###
base_model = VGG19(weights=None, include_top=False, input_shape=(224,224,3))

# Define the K-fold Cross Validator
kfold = KFold(n_splits=5, shuffle=True)
acc_per_fold = []       # Define per-fold score containers
loss_per_fold = []      # Define per-fold score containers
fold_no = 1
for train, val in kfold.split(xtrain, ytrain):
    X_train = xtrain[train]
    X_val = xtrain[val]
    X_train = X_train.astype('float32')
    X_val = X_val.astype('float32')
    y_train = ytrain[train]
    y_val = ytrain[val]


 ### Model architecture
    model = models.Sequential()
    model.add(base_model)
    model.add(layers.Conv2D(64,(3,3), activation = 'relu', padding = 'same'))                                               
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))
    model.add(layers.Flatten())
    model.add(layers.Dense(256, activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(256, activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(2, activation='softmax'))
    model.summary()

    ### Compile the model
    opt = adam(lr=0.0001)
    model.compile(loss='binary_crossentropy',
                  optimizer=opt,
                  metrics=['accuracy'])
    print('------------------------------------------------------------------------')
    print(f'Training for fold {fold_no} ...')

    Epochs_no = 20
    BS = 64
    CB = CSVLogger('/headnode2/mngu6638/mproject/VGG19_model_save/VGG19B_Test1_Fold'+str(fold_no)+'_CB.csv',separator = ',', append=False)

    # Train the model
    history = model.fit(X_train, y_train, epochs=Epochs_no, batch_size=BS,validation_data=(X_val,y_val), callbacks = [CB], verbose=1)

Я использовал модель VGG19 с добавлением 1 свертки + слой MaxPooling. Вес был установлен на «Нет», чтобы модель работала с нуля.

Результаты за 1 эпоху, но 20 эпох имеют одинаковую точность

64/3053 [..............................] - ETA: 50:49 - loss: 0.6931 - acc: 0.5156
128/3053 [>.............................] - ETA: 48:52 - loss: 0.6931 - acc: 0.5234
192/3053 [>.............................] - ETA: 47:20 - loss: 0.6930 - acc: 0.5312
256/3053 [=>............................] - ETA: 45:58 - loss: 0.6931 - acc: 0.5234
320/3053 [==>...........................] - ETA: 44:50 - loss: 0.6931 - acc: 0.5156
384/3053 [==>...........................] - ETA: 43:35 - loss: 0.6931 - acc: 0.4948
448/3053 [===>..........................] - ETA: 42:33 - loss: 0.6931 - acc: 0.4911
512/3053 [====>.........................] - ETA: 41:29 - loss: 0.6931 - acc: 0.4941
576/3053 [====>.........................] - ETA: 40:26 - loss: 0.6931 - acc: 0.4948
640/3053 [=====>........................] - ETA: 39:26 - loss: 0.6931 - acc: 0.4922
704/3053 [=====>........................] - ETA: 38:21 - loss: 0.6931 - acc: 0.4986
768/3053 [======>.......................] - ETA: 37:16 - loss: 0.6931 - acc: 0.5052
832/3053 [=======>......................] - ETA: 36:15 - loss: 0.6931 - acc: 0.5012
896/3053 [=======>......................] - ETA: 35:14 - loss: 0.6931 - acc: 0.5000
960/3053 [========>.....................] - ETA: 34:11 - loss: 0.6931 - acc: 0.4990
1024/3053 [=========>....................] - ETA: 33:09 - loss: 0.6931 - acc: 0.4990
.
.
.
2560/3053 [========================>.....] - ETA: 7:03 - loss: 0.6931 - acc: 0.4994
2624/3053 [========================>.....] - ETA: 6:09 - loss: 0.6931 - acc: 0.4998 
2688/3053 [=========================>....] - ETA: 5:15 - loss: 0.6931 - acc: 0.4968
2752/3053 [==========================>...] - ETA: 4:20 - loss: 0.6931 - acc: 0.4976
2816/3053 [==========================>...] - ETA: 3:26 - loss: 0.6931 - acc: 0.4980
2880/3053 [===========================>..] - ETA: 2:30 - loss: 0.6931 - acc: 0.4964
2944/3053 [===========================>..] - ETA: 1:35 - loss: 0.6931 - acc: 0.4971
3008/3053 [============================>.] - ETA: 39s - loss: 0.6931 - acc: 0.4985
3053/3053 [==============================] - 2879s 943ms/step - loss: 0.6931 - acc: 0.5000 val_loss:0.6931 - val_acc: 0.5131

Сначала я подумал, что это может быть связано с входными данными; Тем не менее, я использовал тот же набор данных для модели с использованием предварительно обученных весов, и все работало нормально. Я также пытался снизить скорость обучения с 10e-4 до 10e-6, но я получил одинаковые результаты для всех сгибов. Может ли кто-нибудь, пожалуйста, есть предложения по решению этой проблемы. Большое спасибо.

...