我有一个 CNN,用于根据 MRI 数据检测阿尔茨海默病。 MRI 是 3D 1.5T 扫描,头骨非常明显(来自 ADNI1 第 3 年的预制数据集)。我一直在尝试适应头骨剥离但没有成功,因此决定在不进行头骨剥离的情况下运行我的模型。
结果让我相当困惑。从附图中可以看出,该模型没有正常的学习曲线。我尝试更改模型的参数,添加更多层和退出正则化,但我要么得到这个随机学习曲线,要么得到恒定的学习曲线(准确性和损失在整个时期内不会改变),而且准确性非常低并且仍然非常低(它是二元分类)。
,
我想知道输入数据对模型的学习过程有多大影响。我了解到预处理对于神经网络并不总是必要的,因为网络会减去特征本身,但这些结果让我对此产生了疑问。所以我的问题是:不相关的数据(在我的例子中是头骨)对神经网络的学习过程有多大影响?
编辑:添加了我的模型
#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/