如何针对特定数据集提高 CNN 模型的性能?在训练和测试数据集上获得低准确度

How to improve the performance of CNN Model for a specific Dataset? Getting Low Accuracy on both training and Testing Dataset

我们得到了一项任务,我们应该在其中实现我们自己的神经网络,以及另外两个已经开发的神经网络。我已经这样做了,但是,这不是作业的要求,但我仍然想知道 steps/procedure 我可以遵循什么来提高模型的准确性?

作为一个整体,我对深度学习和机器学习还比较陌生,所以不太了解。

给定的数据集总共包含 15 class 个(飞机、椅子等),我们在训练数据集中为每个 class 提供了大约 15 张图像。测试数据集每个 class.

有 10 张图像

我的代码的完整 github 存储库可以在这里找到(Jupyter Notebook 文件):https://github.com/hassanashas/Deep-Learning-Models

我先用自己的 CNN 试了一下(用 Youtube 教程做了一个)。 代码如下,

X_train = X_train/255.0
model = Sequential()

model.add(Conv2D(64, (3, 3), input_shape = X_train.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))

model.add(Dense(16)) # added 16 because it model.fit gave error on 15 
model.add(Activation('softmax'))

为了模型的编译,

from tensorflow.keras.optimizers import SGD

model.compile(loss='sparse_categorical_crossentropy', 
             optimizer=SGD(learning_rate=0.01), 
             metrics=['accuracy'])

我使用了稀疏分类交叉熵,因为我的“y”标签是整数值,运行从 1 到 15。

我运行这个模型用下面的方法,

model_fit = model.fit(X_train, y_train, batch_size=32, epochs=30, validation_split=0.1)

它在 training dataset 上给了我 0.2030 的准确度,在 testing dataset 上只有 0.0733(两者都是数据集存在于 github 存储库中)

然后,我尝试了 AlexNet CNN(按照 Youtube 教程获取其代码)

我 运行 AlexNet 在同一个数据集上进行了 15 个 epoch。它将训练数据集的准确性提高到 0.3317,但是测试数据集的准确性甚至比我自己的 CNN 还差,仅为 0.06

之后,我再次按照 Youtube 教程尝试了 VGG16 CNN

我 运行 Google Colab 上的代码 10 Epochs。在第 8 轮 training dataset 上,它成功地提高了 100% 的准确率。但是这个模型在测试数据集上给出了所有三个模型中最差的精度,只有 0.0533

我无法理解所有这些模型的这种对比行为。我尝试了不同的 epoch 值、损失函数等,但当前的相对给出了最好的结果。当我 运行 在 100 个 epochs 上我自己的 CNN 能够达到 100% 的准确率(但是,它在测试数据集上的结果很差)

我可以做些什么来提高这些模型的性能?具体来说,为了提高深度学习模型的效率,人们应该始终尝试遵循哪些关键事项?我在 Whosebug 上查找了多个类似的问题,但几乎所有问题都在处理由 tensorflow 提供的数据集,如 mnist 数据集等,但我没有从中找到太多帮助。

免责声明:我自己玩CNN也有几年了,所以只能传递一些笼统的意见和建议。

首先,我想谈谈你们目前取得的成果。您训练的前两个网络似乎至少从训练数据中学到了一些东西,因为它们比随机猜测表现得更好。

然而:测试数据的表现表明网络没有学到任何东西有意义因为这些数字表明网络与(或仅略好于)随机猜测。

第三个网络:训练数据准确率高,测试数据准确率低,说明你的网络过拟合了。这意味着网络已经记住了训练数据,但没有学到任何有意义的模式。

继续训练已经开始过度拟合的网络是没有意义的。所以一旦连续几个epoch训练准确率上升,测试准确率下降,就可以停止训练了。

增加数据集大小

神经网络依赖大量良好的训练数据来学习模式。您的数据集包含 15 classes,每个 15 张图像,这是非常少的训练数据。

当然,如果你能获得额外的高质量训练数据来扩展你的数据集,那就太好了,但这并不总是可行的。因此,一种不同的方法是人为地扩展您的数据集。您可以通过对原始训练数据应用一系列转换来轻松做到这一点。想一想:镜像、旋转、缩放和裁剪。

切记不要随便应用这些转换,它们必须有意义!例如,如果你想让网络识别一把椅子,你是否也想让它识别倒置的椅子?或者用于检测路标:镜像它们是没有意义的,因为文本、数字和图形在现实生活中永远不会出现镜像。

根据您所拥有的 classes 的简要描述(飞机和椅子等等...),我认为水平镜像可能是最初应用的最佳转换。这将使您的训练数据集大小翻倍。

此外,请记住,人工膨胀的数据集永远不如包含所有真实真实图像的相同大小的数据集好。镜像包含与其原始图像相同的大部分信息,我们只希望它能延迟网络过度拟合,并希望它能学习重要的模式。

降低学习率

这有点旁注,但请尝试降低学习率。您的网络似乎只在几个非常快的时代就过拟合了。显然,降低学习率不会对抗过度拟合,但它会发生得更慢。这意味着你可以在过度拟合发生之前找到一个整体性能更好的 epoch。

请注意,较低的学习率永远不会神奇地使性能不佳的网络变好。这只是找到一组性能稍好一点的参数的方法。

随机化训练数据顺序

在训练期间,训练数据分批呈现给网络。这通常在所有迭代中以固定顺序发生。这可能会导致网络中出现某些偏差。

首先,确保训练数据至少被打乱一次。你不想一个一个地呈现 classes,例如首先是所有平面图像,然后是所有椅子,等等......这可能会导致网络忘记第一个 class 的大部分内容每个纪元结束。

此外,重新调整时期之间的训练数据。这将再次避免由于训练数据顺序而导致的潜在小偏差。

改进网络设计

您设计了一个只有两个卷积层和两个全连接层的卷积神经网络。也许这个模型太浅了,无法学会区分不同的 classes。

知道卷积层倾向于首先提取小的视觉特征,然后倾向于将这些特征组合成更高层次的模式。所以也许添加第三个卷积层可以帮助网络识别更有意义的模式。

显然,网络设计是您必须尝试的事情,让网络过于深入或复杂也是一个需要提防的陷阱!