Керас CNN высокая точность, но плохие прогнозы.Как улучшить это - PullRequest
1 голос
/ 20 сентября 2019

Я должен идентифицировать болезнь сетчатки с CNN.У меня 1400 изображений, по 700 в каждом классе.Мои классы (0 - нет PDR) и (1 - PDR).Я пытаюсь сделать модель, чтобы определить, есть ли заболевание сетчатки на уровне 4 или нет.

Я делаю последующие манипуляции с моими изображениями и изменяю их размеры до 256x256:

ImageCV[index] = cv2.addWeighted(ImageCV[index],4, cv2.GaussianBlur(ImageCV[index],(0,0), 256/30), -4, 128)

И он сделал следующее с моими imgs: https://imgur.com/X1p9G1c

Затем, когда я тренирую свою модель, я получаю очень высокую точность (например, 99 ....), но когда я пытаюсь предсказать некоторые тестовые изображения, это терпит неудачу ... например, я поместил 10 примеров PDR в тестовую папку и пытаетсяпредсказать их (все должно быть 1) .. это результат:

[[0.]]
[[0.]]
[[1.]]
[[0.]]
[[0.]]
[[0.]]
[[1.]]
[[0.]]
[[0.]]
[[0.]]

Это моя модель:

visible = Input(shape=(256,256,3))
conv1 = Conv2D(16, kernel_size=(3,3), activation='relu', strides=(1, 1))(visible)
conv2 = Conv2D(16, kernel_size=(3,3), activation='relu', strides=(1, 1))(conv1)
bat1 = BatchNormalization()(conv2)
conv3 = ZeroPadding2D(padding=(1, 1))(bat1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv3)

conv4 = Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(pool1)
conv5 = Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(conv4)
bat2 = BatchNormalization()(conv5)
pool2 = MaxPooling2D(pool_size=(1, 1))(bat2)

conv6 = Conv2D(64, kernel_size=(3,3), activation='relu',strides=(1, 1), padding='valid')(pool2)
conv7 = Conv2D(64, kernel_size=(3,3), activation='relu',strides=(1, 1), padding='valid')(conv6)
bat3 = BatchNormalization()(conv7)
conv7 = ZeroPadding2D(padding=(1, 1))(bat3)
pool3 = MaxPooling2D(pool_size=(1, 1))(conv7)

conv8 = Conv2D(128, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(pool3)
conv9 = Conv2D(128, kernel_size=(2,2), activation='relu', strides=(1, 1), padding='valid')(conv8)
bat4 = BatchNormalization()(conv9)
pool4 = MaxPooling2D(pool_size=(1, 1))(bat4)

flat = Flatten()(pool4)

output = Dense(1, activation='sigmoid')(flat)
model = Model(inputs=visible, outputs=output)

opt = optimizers.adam(lr=0.001, decay=0.0)

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


data, labels = ReadImages(TRAIN_DIR)

test, lt = ReadImages(TEST_DIR)

data = np.array(data)
labels = np.array(labels)
test = np.array(test)
lt = np.array(lt)

np.random.permutation(len(data))
np.random.permutation(len(labels))
np.random.permutation(len(test))
np.random.permutation(len(lt))

model.fit(data, labels, epochs=7, validation_data = (test,lt))

model.save('model.h5')

И это прогнозируемый .py

model = load_model('model.h5')

for filename in os.listdir(r'v/'):
    if filename.endswith(".jpg") or filename.endswith(".ppm") or filename.endswith(".jpeg"):
        ImageCV = cv2.resize(cv2.imread(os.path.join(TEST_DIR) + filename), (256,256))
        ImageCV = cv2.addWeighted(ImageCV,4, cv2.GaussianBlur(ImageCV,(0,0), 256/30), -4, 128)
        cv2.imshow('image', ImageCV)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        ImageCV = ImageCV.reshape(-1,256,256,3)
        print(model.predict(ImageCV))

Что я мог сделать, чтобы вообще улучшить свои прогнозы?Я очень ценю вашу помощь

ОБНОВЛЕНИЕ Ну, я пытался сделать все, что было сказано в ответах, но все еще не работает ... это мой код сейчас:

visible = Input(shape=(256,256,3))
conv1 = Conv2D(16, kernel_size=(3,3), activation='relu', strides=(1, 1))(visible)
conv2 = Conv2D(32, kernel_size=(3,3), activation='relu', strides=(1, 1))(conv1)
bat1 = BatchNormalization()(conv2)
conv3 = ZeroPadding2D(padding=(1, 1))(bat1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv3)
drop1 = Dropout(0.30)(pool1)

conv4 = Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(drop1)
conv5 = Conv2D(64, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(conv4)
bat2 = BatchNormalization()(conv5)
pool2 = MaxPooling2D(pool_size=(1, 1))(bat2)
drop1 = Dropout(0.30)(pool2)

conv6 = Conv2D(128, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(pool2)
conv7 = Conv2D(128, kernel_size=(2,2), activation='relu', strides=(1, 1), padding='valid')(conv6)
bat3 = BatchNormalization()(conv7)
pool3 = MaxPooling2D(pool_size=(1, 1))(bat3)
drop1 = Dropout(0.30)(pool3)

flat = Flatten()(pool3)
drop4 = Dropout(0.50)(flat)

output = Dense(1, activation='sigmoid')(drop4)
model = Model(inputs=visible, outputs=output)

opt = optimizers.adam(lr=0.001, decay=0.0)

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

data, labels = ReadImages(TRAIN_DIR)
test, lt = ReadImages(TEST_DIR)

data = np.array(data)
labels = np.array(labels)

perm = np.random.permutation(len(data))
data = data[perm]
labels = labels[perm]
#model.fit(data, labels, epochs=8, validation_data = (np.array(test), np.array(lt)))

aug = ImageDataGenerator(rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.15,
    horizontal_flip=True)

# train the network
model.fit_generator(aug.flow(data, labels, batch_size=32),
    validation_data=(np.array(test), np.array(lt)), steps_per_epoch=len(data) // 32,
    epochs=7)

И это возвращаемое значение:

Epoch 1/7
43/43 [==============================] - 1004s 23s/step - loss: 1.8090 - acc: 0.9724 - val_loss: 1.7871 - val_acc: 0.9861
Epoch 2/7
43/43 [==============================] - 1003s 23s/step - loss: 1.8449 - acc: 0.9801 - val_loss: 1.4828 - val_acc: 1.0000
Epoch 3/7
43/43 [==============================] - 1092s 25s/step - loss: 1.5704 - acc: 0.9920 - val_loss: 1.3985 - val_acc: 1.0000
Epoch 4/7
43/43 [==============================] - 1062s 25s/step - loss: 1.5219 - acc: 0.9898 - val_loss: 1.3167 - val_acc: 1.0000
Epoch 5/7
43/43 [==============================] - 990s 23s/step - loss: 2.5744 - acc: 0.9222 - val_loss: 2.9347 - val_acc: 0.9028
Epoch 6/7
43/43 [==============================] - 983s 23s/step - loss: 1.6053 - acc: 0.9840 - val_loss: 1.3299 - val_acc: 1.0000
Epoch 7/7
43/43 [==============================] - 974s 23s/step - loss: 1.6180 - acc: 0.9801 - val_loss: 1.5181 - val_acc: 0.9861

Я бы добавил отсевы, уменьшил бы слои модели, добавил увеличение данных и не работал вообще (все предсказания возвращали 0) ...

Пожалуйста, кто-нибудь может помочь в этом.

Ответы [ 3 ]

0 голосов
/ 20 сентября 2019

Ваша модель очень велика для размера вашего тренировочного набора, что приводит к переоснащению.Используйте меньше слоев

0 голосов
/ 22 сентября 2019

Вы переоснащены, то есть у вас проблема с высокой дисперсией.Попробуйте добавить немного мягких выпадений (0,2-0,3) в конце ваших сверточных блоков.Вы также можете добавить пару плотных слоев с уменьшающимися номерами единиц перед выходным слоем и поместить большее количество выпадающих слоев между ними (0,5 +).

Вам также следует реализовать дополнительное увеличение данных, такое как вращения, отражения, случайные значения.шум, случайная яркость и т. д. Ознакомьтесь с документацией Keras для класса ImageDataGenerator.

0 голосов
/ 20 сентября 2019

Кажется, у вас проблемы с переоснащением.У меня есть какая-то личная дилемма здесь, вне зависимости от того, является ли это не темой или нет, потому что подход, который можно дать, основывается на мнении, но здесь я иду: во-первых, если вам нужно упорядочить перегрузочную сеть, вы хотите использоватьdropout начиная с 0.25 и проверяя, улучшает ли это модель.Data augmentation является обязательным при работе с переоснащением вместе с batch normalization (который вы применяете).Если это по-прежнему не решает проблемы перегрузки, то вам следует попробовать поработать над сетевой архитектурой, чтобы настроить ее так, чтобы она лучше обобщалась.Вы проверили простой из входов, используемых для обучения и тестирования?

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

РЕДАКТИРОВАТЬ:Консенсус в отношении подхода к такого рода моделям состоит в том, чтобы сначала переобучить его с приличной точностью, а затем поработать над его обобщением, не теряя при этом точности.

...