为什么我的Keras CNN不能用于糖尿病性视网膜病变检测

问题描述 投票:2回答:1

我必须做一个CNN来检测第4阶段的糖尿病性视网膜病变(它必须检测第4阶段是否存在DR,不需要检测其他水平)。输入将是这样的图像:https://imgur.com/DsU06Xv

为了更好地进行分类,我正在优化我的图像:https://imgur.com/X1p9G1c

所以,我有一个数据库,其中包含700个0级视网膜图像和700个4级视网膜图像。

问题是我尝试制作的所有模型都不起作用,通常这已成为过拟合的问题。

我已经尝试使用顺序模型,Functional API ..在这里我提出了一个问题,用户建议我使用VGG16 >>问题:https://datascience.stackexchange.com/questions/60706/how-do-i-handle-with-my-keras-cnn-overfitting

现在,我正在尝试使用VGG16,但仍然无法正常工作,我的所有预测都为0,而且我不知道该怎么做。.

这是我的火车。py:

import cv2
import os
import numpy as np

from keras.layers.core import Flatten, Dense, Dropout, Reshape
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras import regularizers
from keras.models import Model
from keras.layers import Input, ZeroPadding2D, Dropout
from keras import optimizers
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.utils import to_categorical 

from keras.applications.vgg16 import VGG16

# example of using a pre-trained model as a classifier
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.vgg16 import preprocess_input
from keras.applications.vgg16 import decode_predictions

TRAIN_DIR = 'train/'
TEST_DIR = 'test/'
v = 'v/'
BATCH_SIZE = 32
NUM_EPOCHS = 5

def ReadImages(Path):
    LabelList = list()
    ImageCV = list()
    classes = ["nonPdr", "pdr"]

    # Get all subdirectories
    FolderList = [f for f in os.listdir(Path) if not f.startswith('.')]

    # Loop over each directory
    for File in FolderList:
        for index, Image in enumerate(os.listdir(os.path.join(Path, File))):
            # Convert the path into a file
            ImageCV.append(cv2.resize(cv2.imread(os.path.join(Path, File) + os.path.sep + Image), (224,224)))
            #ImageCV[index]= np.array(ImageCV[index]) / 255.0
            LabelList.append(classes.index(os.path.splitext(File)[0])) 

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

    return ImageCV, LabelList

data, labels = ReadImages(TRAIN_DIR)
valid, vlabels = ReadImages(TEST_DIR)

vgg16_model = VGG16(weights="imagenet", include_top=True)

# (1) visualize layers
print("VGG16 model layers")
for i, layer in enumerate(vgg16_model.layers):
    print(i, layer.name, layer.output_shape)

# (2) remove the top layer
base_model = Model(input=vgg16_model.input, 
                   output=vgg16_model.get_layer("block5_pool").output)

# (3) attach a new top layer
base_out = base_model.output
base_out = Reshape((25088,))(base_out)
top_fc1 = Dropout(0.5)(base_out)
# output layer: (None, 5)
top_preds = Dense(1, activation="sigmoid")(top_fc1)

# (4) freeze weights until the last but one convolution layer (block4_pool)
for layer in base_model.layers[0:14]:
    layer.trainable = False

# (5) create new hybrid model
model = Model(input=base_model.input, output=top_preds)

# (6) compile and train the model
sgd = SGD(lr=1e-4, momentum=0.9)
model.compile(optimizer=sgd, loss="binary_crossentropy", metrics=["accuracy"])

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(data)

# fits the model on batches with real-time data augmentation:
model.fit_generator(datagen.flow(np.array(data), np.array(labels), batch_size=32), 
                    steps_per_epoch=len(np.array(data)) / 32, epochs=5)


#history = model.fit([data], [labels], nb_epoch=NUM_EPOCHS, 
#                    batch_size=BATCH_SIZE, validation_split=0.1)

# evaluate final model
#vlabels = model.predict(np.array(valid))

model.save('model.h5')

当我运行它时,返回的精度为〜1.0或0.99%,最小的损耗为〜0.01 ..

这是我的预测。py:

from keras.models import load_model
import cv2
import os
import json
import h5py
import numpy as np
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input

TEST_DIR = 'v/'

def fix_layer0(filename, batch_input_shape, dtype):
    with h5py.File(filename, 'r+') as f:
        model_config = json.loads(f.attrs['model_config'].decode('utf-8'))
        layer0 = model_config['config']['layers'][0]['config']
        layer0['batch_input_shape'] = batch_input_shape
        layer0['dtype'] = dtype
        f.attrs['model_config'] = json.dumps(model_config).encode('utf-8')

fix_layer0('model.h5', [None, 224, 224, 3], 'float32')

model = load_model('model.h5')

for filename in os.listdir(r'v/'):
    if filename.endswith(".jpg") or filename.endswith(".ppm") or filename.endswith(".jpeg") or filename.endswith(".png"):
        ImageCV = cv2.resize(cv2.imread(os.path.join(TEST_DIR) + filename), (224,224))

        x = image.img_to_array(ImageCV)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)
        print(np.argmax(model.predict(x)))

[当我运行它时,我所有的预测都是0 ..如果放下'np.argmax'并且仅运行model.predict,则返回以下结果:

[[0.03993018]]
[[0.9984968]]
[[1.]]
[[1.]]
[[0.]]
[[0.9999999]]
[[0.8691623]]
[[1.01611796e-07]]
[[1.]]
[[0.]]
[[1.]]
[[0.17786741]]

[考虑到前两个图像是0类,其他图像是1类(4级),结果不是0.99或1.0的精度。

我该怎么办?我真的非常感谢您的帮助!

python machine-learning keras neural-network conv-neural-network
1个回答
0
投票
  1. 您没有定义验证生成器。训练时,您使用训练集和验证集,并在验证损失没有改善时停止训练。

https://gist.github.com/fchollet/7eb39b44eb9e16e59632d25fb3119975

  1. 由于您网络的最后一层是S型,所以>

    top_preds = Dense(1,activation =“ sigmoid”)(top_fc1)

  2. 只有一个输出,它是从0到1的概率值。np.argmax在这里不相关。

[np.argmax用于最后一层使用softmax激活的两个输出,其概率之和为1,并选择具有较高概率的索引作为结果。

返回您使用sigmoid获得的结果,通常选择一个阈值来决定将其分类为0类还是1类。默认阈值为0.5。可以使用得出最佳阈值的概率来创建ROC曲线。

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html

使用阈值0.5,

prob = model.predict(x)
if prob < 0.5:
    output = 0
else:
    output = 1

[[0.03993018]] => < 0.5, class 0 correct
[[0.9984968]]  => > 0.5, class 1 incorrect
[[1.]]         => > 0.5, class 1 correct
[[1.]]         => > 0.5, class 1 correct
[[0.]]         => < 0.5, class 0 incorrect
[[0.9999999]]  => > 0.5, class 1 correct
[[0.8691623]]  => > 0.5, class 1 correct
[[1.01611796e-07]] => < 0.5, class 0 incorrect
[[1.]]             => > 0.5, class 1 correct
[[0.]]             => < 0.5, class 0 incorrect
[[1.]]             => > 0.5, class 1 correct
[[0.17786741]]     => < 0.5, class 0 incorrect

准确度= 7/12 = 58%

© www.soinside.com 2019 - 2024. All rights reserved.