Высокая тренировка и проверка точности, но плохие прогнозы - PullRequest
0 голосов
/ 08 апреля 2020

Я тренирую предварительно обученную модель, чтобы предсказать клиническую значимость медицинских изображений. Я получил хорошую подготовку и точность проверки (около 90%), но плохую точность тестирования (точность прогноза 50%). Набор данных, который я использовал для обучения модели, содержит 3000 образцов с метками «True» или «False». Этот набор данных несбалансирован, доля False в 3 раза больше, чем доля истинных выборок. Поэтому я устанавливаю class_weight при подгонке модели к соотношению 1: 3.

Это код

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='imagenet', 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.Dense(256, activation='relu'))
    model.add(layers.Dense(2, activation='softmax'))
    for layer in base_model.layers:
        layer.trainable = False
    model.summary()

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

    Epochs_no = 20
    BS = 64
    CB = CSVLogger('VGG19_Test1_Fold'+str(fold_no)+'_CB.csv',separator = ',', append=False)
    class_weights = {0:1, 1:3}

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

Сводка модели

Model: "sequential_1"
_________________________________________________________________ 
Layer (type)                 Output Shape              Param #
=================================================================
vgg19 (Model)                (None, 7, 7, 512)         20024384
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 5, 5, 64)          294976
_________________________________________________________________                                                       max_pooling2d_1 (MaxPooling2 (None, 2, 2, 64)          0
_________________________________________________________________
flatten_1 (Flatten)          (None, 256)               0
_________________________________________________________________
dense_1 (Dense)              (None, 256)               65792
_________________________________________________________________
dense_2 (Dense)              (None, 256)               65792
_________________________________________________________________ 
dense_3 (Dense)              (None, 2)                 514
=================================================================
Total params: 20,451,458
Trainable params: 427,074
Non-trainable params: 20,024,384
_________________________________________________________________

Мой тестовый набор данных был предварительно обработан тем же методом, что и данные обучения (повторная выборка, нормализация ...). Половина тестовых данных - True, а другая половина - False. Тем не менее, обученная модель предсказывает намного больше «Ложь», хотя я уже установил class_weight, поэтому модель должна уделять больше внимания меньшинству (истинному классу) в обучении.

Я не мог понять, почему модель не прошла тестирование, может, у кого-нибудь есть предложения по этой проблеме. Большое спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...