在二进制分类CNN中每个数据点使用多个图像

问题描述

我正在制作一个CNN模型,将MRI脑部扫描归类为阿尔茨海氏症和健康人群。

当前似乎过拟合了,我们在本书中尝试了很多技巧来解决此问题。

我现在想尝试的一种方法-但没有经验-在每个数据点使用大脑扫描的多个图像。

例如:

我以.nii格式下载大脑扫描并将其转换为一系列png文件。每个png文件在不同的时间点都进行相同的扫描。在我当前的模型中,每次脑部扫描我只删除了其中一张图像,所以使我的模型更易于使用。

我现在想尝试的是针对我的数据集中的每个样本使用多张图片-首先说5张图片

我将如何通过更改当前模型来实现这一目标?

我不想使用ImageDataGenerator的数据增强功能,我想使用存储在计算机上的现有文件

我将不胜感激,因为当前模型的训练精度约为80%,val精度为55%。

# Use ImageDataGenerator to create 3 lots of batches
train_batches = ImageDataGenerator(
    rescale=1/255).flow_from_directory(directory=train_path,target_size=(80,80),classes=['cn','ad'],batch_size=100,color_mode="rgb")
valid_batches = ImageDataGenerator(
    rescale=1/255).flow_from_directory(directory=valid_path,color_mode="rgb")
# test_batches = ImageDataGenerator(
#     rescale=1/255).flow_from_directory(directory=test_path,#         target_size=(224,224),batch_size=10,#             color_mode="rgb")

imgs,labels = next(train_batches)

# Test to see normalisation has occurred properly
print(imgs[1][8])

# Define method to plot MRIs
def plotimages(images_arr):
    fig,axes = plt.subplots(1,10,figsize=(20,20))
    axes = axes.flatten()
    for img,ax in zip( images_arr,axes):
        ax.imshow(img)
        ax.axis('off')
    plt.tight_layout()
    plt.show()

# Plot a sample of MRIs
plotimages(imgs)

# # Define the model
# # VGG16
# model = Sequential()
# model.add(Conv2D(input_shape=(160,160,3),filters=64,kernel_size=(3,padding="same",activation="relu"))
# model.add(Conv2D(filters=64,activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Conv2D(filters=128,activation="relu"))
# model.add(Conv2D(filters=128,2)))
# model.add(Conv2D(filters=256,activation="relu"))
# model.add(Conv2D(filters=256,2)))
# model.add(Conv2D(filters=512,activation="relu"))
# model.add(Conv2D(filters=512,2)))
# model.add(Flatten())
# model.add(Dense(units=1024,activation="relu"))
# model.add(Dense(units=128,activation="relu"))
# model.add(Dense(units=2,activation="softmax"))

# # Model from the paper
# model = Sequential([
#     Conv2D(filters=32,activation='relu',padding = 'same',input_shape=(160,3)),#     Conv2D(filters=32,padding='same'),#     MaxPool2D(pool_size=(2,strides=2),#     Flatten(),#     Dense(units=2,activation='softmax')
# ])

## Model from Dr Paul
# static_conv_layer=Conv2D(filters=16,kernel_size=(5,5),padding = 'same')
#
# model = Sequential([
#     Conv2D(filters=16,input_shape=(32,32,#     Dropout(0.1),#     static_conv_layer,activation='softmax')
# ])

# This model hits around 75% train acc,54% val acc
model = Sequential([
    Conv2D(filters=16,input_shape=(80,80,MaxPool2D(pool_size=(2,# Dropout(0.1),# Conv2D(filters=16,# MaxPool2D(pool_size=(2,Flatten(),Dense(units=2,activation='softmax')
])

# model = Sequential([
#     Conv2D(filters=32,activation='softmax')
# ])

## Basic model with dropouts
# model = Sequential([
#     Conv2D(filters=32,input_shape=(224,224,#     Conv2D(filters=64,#     Dropout(0.2),#     Conv2D(filters=128,#     Dropout(0.3),#     Dense(units=1,activation='sigmoid')
# ])

# Summarise each layer of the model
print(model.summary())

# Compile and train the model
model.compile(optimizer=Adam(),loss='binary_crossentropy',metrics=['accuracy'])
model.fit(x=train_batches,steps_per_epoch=len(train_batches),validation_data=valid_batches,validation_steps=len(valid_batches),epochs=20,verbose=1
)

解决方法

为了现在在模型中合并多个图像,可以为每个数据点拍摄多个图像,最简单的方法是将它们取平均值,然后尝试一下。但是,一种更好的方法是对多个图像应用降维。

首先,它将合并每个人的所有功能,并且,如果每个人的图像数量不同,那么这将简化您的培训。

最好先计算外部特征,然后将其插入模型。

为此,请首先考虑PCA。