Создание 3DCNN для прогнозирования результатов тестов МРТ-изображений - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь предсказать оценку (непрерывное число) на основе изображения МРТ, но получаемый мной результат является одинаковым числовым прогнозом для каждого изображения. Я попытался изменить свои оптимизаторы, размер модели, скорость обучения и активации, но без решения.

На данный момент я не уверен, может ли ошибка исходить из сети cnn или из-за того, что ошибка модель не предсказывает каждое изображение независимо.

Вот результат выполнения кода: https://i.stack.imgur.com/a3RAm.jpg

Вот код:

import os
import csv
import tensorflow as tf  # 2.0
import nibabel as nib
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
from keras.models import Model, Sequential
from keras.layers import Conv3D, MaxPooling3D, Dense, Dropout, Activation, Flatten 
from keras.layers import Input, concatenate
from keras import optimizers
from keras.utils import to_categorical
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
from augmentedvolumetricimagegenerator.generator import customImageDataGenerator
from keras.callbacks import EarlyStopping
import math
import random


# Administrative items
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# Where the file is located
path = r'PD_Classification/niiImagesSkullStripped/PD'
folder = os.listdir(path)

target_size = (96, 96, 96)  # 224, 256, 160

files = []
for i in range(len(folder)):
    if folder[i][0:9] == 'T1_MPRage':
        files.append(folder[i])
files = sorted(files)

csv_path = r'PD_Classification/nonImaging/PD_Classification_list.csv'

csv_read = pd.read_csv(csv_path)
date = csv_read['3T MRI']
updrs = csv_read['UPDRS\nTotal']

scores = []
nii = []
for i in range(len(files)):
    for j in range(len(updrs)):
        
        if isinstance(date[j], float) == True:
            continue
        
        numbers = date[j][6:] + date[j][0:2] + date[j][3:5]
        
        if '/' in numbers:
            continue
        
        elif files[i][20:28] == numbers:
            nii.append(files[i])
            scores.append(updrs[j])

print(len(scores), len(nii))

img = []
for i in range(len(nii)):
    image = np.array(nib.load(path + '/' + nii[i]).get_fdata())
    image = np.resize(image, target_size)
    image = np.expand_dims(image, axis=3)
    image /= 255.
    img.append(image)
img = np.asarray(img)

x = np.asarray(img)
y = np.asarray(scores)
x_split, x_test, y_split, y_test = train_test_split(x, y, test_size=.2)
x_train, x_val, y_train, y_val = train_test_split(x_split, y_split, test_size=.25)
print(x_train.shape, x_val.shape, x_test.shape, y_train.shape, y_val.shape, y_test.shape)

batch_size = 5

model = Sequential()

model.add(Conv3D(32, [3, 3, 3], padding='same', activation='relu',
                 input_shape=[96, 96, 96, 1]))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))

model.add(Conv3D(64, [3, 3, 3], padding='same', activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding='same'))

model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(1, activation='linear'))

opt = optimizers.Adam(lr=1e-4)
model.compile(loss='mean_squared_error', optimizer=opt, metrics=['accuracy'])

train_datagen = customImageDataGenerator(horizontal_flip=True)

val_datagen = customImageDataGenerator()

test_datagen = customImageDataGenerator()



training_set = train_datagen.flow(x_train, y_train, batch_size=batch_size)

validation_set = val_datagen.flow(x_val, y_val, batch_size=batch_size)

testing_set = test_datagen.flow(x_test, y_test, batch_size=batch_size, shuffle=False)



callbacks = EarlyStopping(monitor='val_loss', patience=30)

history = model.fit(
                    training_set,
                    steps_per_epoch = len(x_train)//batch_size,
                    epochs = 50,
                    callbacks = [callbacks],
                    validation_data = validation_set,
                    validation_steps = len(x_val)//batch_size
                    )
#score = model.predict(testing_set, steps=len(x_test)//batch_size)

def accuracy_score(y_pred, y_test):
    count = 0
    for i in range(len(y_test)):
        error = 5.
        if (y_pred[i] < y_test[i] + error) and (y_pred[i] > y_test[i] - error):
            count += 1
    accuracy = count/len(y_test)
    return accuracy


y_pred = model.predict(x_test, batch_size=batch_size)

for i in range(len(y_pred)):
    print('Predicted score:', y_pred[i], 'True score:', y_test[i])

accuracy_score(y_pred, y_test)

print(model.summary())

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.figure(1)
plt.plot(loss)
plt.plot(val_loss)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='best')
plt.title('Loss')
...