我构建并测试了两个卷积神经网络模型(VGG-16 和 3层CNN
)来预测COVID-19的肺部CT扫描分类。
在分类之前,我通过k-means聚类
对图像进行了分割,以试图提高分类的性能。
分割后的图像如下所示。
我分别在分割后的图像和原始图像上训练并评估了VGG-16模型。最后,在分割后的图像上训练并评估了一个3层的CNN。以下是它们的训练/验证损失和准确率的结果。
对于简单的3层CNN模型,我可以清楚地看到模型训练得很好,并且一旦训练超过2个周期就开始过拟合。但是,我不明白为什么VGG模型的验证准确率看起来不像指数曲线,反而像是一条水平直线或波动的水平线。此外,简单的3层CNN模型似乎表现得更好。这是由于VGG模型中的梯度消失造成的吗?还是图像本身太简单,深层架构没有带来好处?我希望您能分享您对这种模型学习行为的知识。
这是VGG-16模型的代码:
# build modelimg_height = 256img_width = 256model = Sequential()model.add(Conv2D(input_shape=(img_height,img_width,1),filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Flatten())model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=1, activation="sigmoid"))opt = Adam(lr=0.001)model.compile(optimizer=opt, loss=keras.losses.binary_crossentropy, metrics=['accuracy'])
这是3层CNN的代码。
# build modelmodel2 = Sequential()model2.add(Conv2D(32, 3, padding='same', activation='relu',input_shape=(img_height, img_width, 1))) model2.add(MaxPool2D()) model2.add(Conv2D(64, 5, padding='same', activation='relu'))model2.add(MaxPool2D())model2.add(Flatten())model2.add(Dense(128, activation='relu'))model2.add(Dense(1, activation='sigmoid'))opt = Adam(lr=0.001)model2.compile(optimizer=opt, loss=keras.losses.binary_crossentropy, metrics=['accuracy'])
谢谢!
回答:
假设这是一个二分类问题,通过观察准确率可以看出模型只是在随机猜测(准确率约为0.5)。您3层模型在训练集上的结果要好得多,这表明您训练的时间不够长,尚未达到过拟合。此外,您似乎没有对神经网络进行适当的初始化。注意:在实施过程的开始阶段,过拟合表明训练过程正常进行。因此,在这个阶段这是件好事。因此,第一步应该是让模型过拟合。您似乎是从头开始训练的。在这种情况下,像VGG16这样的复杂模型可能需要几百个周期才能影响到第一个卷积层。
由于3层CNN似乎严重过拟合,我认为您的数据集相当小。因此,我建议从预训练模型(VGG16)开始,只重新训练最后两层。这应该能得到更好的结果。