python - 图像中的不相关信息对CNN的学习过程有多大影响?

标签 python tensorflow keras neural-network neuroscience

我有一个 CNN,用于根据 MRI 数据检测阿尔茨海默病。 MRI 是 3D 1.5T 扫描,头骨非常明显(来自 ADNI1 第 3 年的预制数据集)。我一直在尝试适应头骨剥离但没有成功,因此决定在不进行头骨剥离的情况下运行我的模型。

结果让我相当困惑。从附图中可以看出,该模型没有正常的学习曲线。我尝试更改模型的参数,添加更多层和退出正则化,但我要么得到这个随机学习曲线,要么得到恒定的学习曲线(准确性和损失在整个时期内不会改变),而且准确性非常低并且仍然非常低(它是二元分类)。

AccuracyLoss

我想知道输入数据对模型的学习过程有多大影响。我了解到预处理对于神经网络并不总是必要的,因为网络会减去特征本身,但这些结果让我对此产生了疑问。所以我的问题是:不相关的数据(在我的例子中是头骨)对神经网络的学习过程有多大影响?

编辑:添加了我的模型

#hot-one labeling
Y = np.load('y_array.npy')
X = np.load('images_array.npy')
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
dummy_y = np_utils.to_categorical(encoded_Y)

#train-test split
X_train, X_test, y_train, y_test = train_test_split(X, dummy_y, test_size=0.2, random_state=1)
test_size=0.2, random_state=1)

print(X_train.shape , X_test.shape, y_train.shape, y_test.shape)
[out:] (718, 192, 192, 160) (180, 192, 192, 160) (718, 2) (180, 2)

batch_size = 64
epochs = 40
num_classes =2

AD_model = Sequential()
AD_model.add(Conv2D(64, kernel_size=(3, 3),activation='linear',input_shape=(192,192,160),padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))
AD_model.add(MaxPooling2D((2, 2),padding='same'))
AD_model.add(Conv2D(128, (3, 3), activation='linear',padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))
AD_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
AD_model.add(Conv2D(256, (3, 3), activation='linear',padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))                  
AD_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
AD_model.add(Flatten())
AD_model.add(Dense(256, activation='linear'))
AD_model.add(LeakyReLU(alpha=0.1))                  
AD_model.add(Dense(num_classes, activation='sigmoid'))

AD_model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['accuracy'])
AD_model.summary()

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 192, 192, 64)      92224     
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU)    (None, 192, 192, 64)      0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 96, 96, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 96, 96, 128)       73856     
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU)    (None, 96, 96, 128)       0         
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 48, 48, 128)       0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 48, 48, 256)       295168    
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU)    (None, 48, 48, 256)       0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 24, 24, 256)       0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 147456)            0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               37748992  
_________________________________________________________________
leaky_re_lu_4 (LeakyReLU)    (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 514       
=================================================================
Total params: 38,210,754
Trainable params: 38,210,754
Non-trainable params: 0

history = AD_model.fit(
    X_train, 
    y_train, 
    batch_size=batch_size,
    epochs=epochs,
    verbose=1,
    validation_data=(X_test, y_test))

最佳答案

您正在 3D 图像上使用 2D 卷积。这可能是性能不足的一个重要原因。您只需丢弃一个空间维度,使其表现得就像只是特征一样。

这里最明显的建议是制作 3D 卷积模型。

您还在两个类上使用“sigmoid”来解决看似明确的问题。

将模型制作为 3D

首先,将 X 设为 3D:

X = X.reshape((-1, 192, 192, 160, 1))

然后将您的模型制作为 3D:

AD_model = Sequential()
AD_model.add(Conv3D(64, kernel_size=3,input_shape=(192,192,160,1),padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))
AD_model.add(MaxPooling3D((2, 2, 2),padding='same'))
AD_model.add(Conv3D(128, 3, activation='linear',padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))
AD_model.add(MaxPooling3D((2, 2, 2),padding='same'))
AD_model.add(Conv3D(256, 3, activation='linear',padding='same'))
AD_model.add(LeakyReLU(alpha=0.1))                  
AD_model.add(MaxPooling3D((2, 2, 2),padding='same'))

#warning, maybe this gets too big and you might need to do more pooling steps 
AD_model.add(Flatten()) 

AD_model.add(Dense(256, activation='linear'))
AD_model.add(LeakyReLU(alpha=0.1))                  
AD_model.add(Dense(num_classes, activation='sigmoid'))

正确处理分类问题:

  • 如果您有 y_train.shape == (batch, 2),一个维度表示健康,另一个维度表示阿尔茨海默病,那么您需要 activation='softmax'损失='categorical_crossentropy'
  • 如果您有 y_train.shape == (batch, 1),值 0 是一个条件,1 是另一个条件,那么您需要 activation='sigmoid'loss = 'binary_crossentropy'

(测试此)为 ReLU 使用更好的内核初始化器

在使用 ReLU 的层上测试 kernel_initializer='he_uniform' 可能会很有趣。这可能有助于速度和收敛。 (不知道它是否适用于“leaky”relu,但可能值得尝试)

关于python - 图像中的不相关信息对CNN的学习过程有多大影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59562711/

相关文章:

python - 在 Tensorflow 2 中的每个纪元之后计算每个类的召回率

python - 用于关联字典列表和列表列表的 pythonian 单行代码

c++ - 使用 C++ 时如何加载自定义操作库?

tensorflow - 字节缓冲区的大小和形状不匹配(以前没有回答)

python - 通过 tensorflow 输出二维 boolean 掩码值

python - "Too early"在 Keras 中提前停止

tensorflow - Keras Batchnormalization,训练数据集的训练和评估结果不同

python - 需要一些有关 Python 代码的帮助

python - 如何在 PyQt 上的窗口上加载位图

python - SQLAlchemy 和原始 SQL : List as an input