PyTorch 教程-调整PyTorch模型的超参数技术
在上一个主题中,我们对CIFAR数据集进行了Lenet模型的训练。我们发现我们的LeNet模型对大多数图像进行了正确的预测,同时我们还发现在准确率方面存在过拟合的问题。尽管我们的模型训练得不是很好,但它仍然能够预测大多数验证图像。
由于训练图像的深度变化和固有复杂性,CIFAR数据集将更难分类。
我们在处理的两个主要问题是准确性不够高,网络似乎过度拟合训练数据。第一个问题可以通过对LeNet模型代码进行各种修改来解决。我们将应用的修改是非常特定于每个特定深度学习任务的案例依赖的,以及对模型容量进行微调。这通常是一个非常具体的过程,对于每个特定的深度学习任务是独特的。
然而,微调我们的模型很重要,可以显著提高模型的性能。我们必须始终尝试并修改我们的模型,以查看这些修改如何提高我们模型的有效性。我们将应用以下修改:
- 第一次修改将专注于学习速率。Adam优化器计算单独的自适应学习率。为了实现最佳性能,仍然很重要指定合适的学习率。学习率太高通常会导致较低的准确性。当涉及到更复杂的数据集时,较低的学习率可以帮助神经网络更有效地学习。
注意: 学习率太小会显著减慢我们的训练性能。
通过分析和经验的帮助,我们得出结论,训练过程相当慢,从一个时期到下一个时期,训练和验证的准确性没有显着提高。
我们将学习率设置为0.001而不是0.0001。
criteron=nn.CrossEntropyLoss()
optimizer=torch.optim.Adam(model.parameters(),lr=0.001)
- 第二次修改非常有效。我们将简单地添加更多的卷积层。通过添加更多的卷积,我们的网络可以更有效地提取特征,并且还有助于提高准确性。
注意: 定义卷积层的常见架构是,每个层使前一层的输出深度翻倍。
在我们的第一个卷积层中,将有3个输入通道和与conv1相对应的16个输出通道的深度。然后将翻倍为32,然后为64,如下所示:
self.conv1=nn.Conv2d(3,16,5,1)
self.conv2=nn.Conv2d(16,32,5,1)
在我们从一个卷积层进入下一个卷积层时,输出的深度一直在不断增加。通过这样做,我们在内部增加了用于提取与前向输入相关的高度复杂信息的滤波器数量。卷积层用于使网络更加深入,从而提取更加复杂的特征。
因此,我们将添加另一个卷积层conv3:
self.conv3=nn.Conv2d(32,64,5,1)
向完全连接的层馈送的适当矢量将是五乘五,与以前相同,但是输出通道的数量将为64。
self.fully1=nn.Linear(5*5*64,500)
为了确保一致性,我们还将在forward的view方法中更改输出通道的数量:
xx=x.view(-1,5*5*64)
在初始化第三个卷积层之后,我们将在其上应用relu函数:
x=func.relu(self.conv3(x))
x=func.max_pool2d(x,2,2)
较大的卷积核意味着更多的参数。我们将使用较小的内核大小来消除过拟合。我们将使用大小为3的内核,这适用于我们的代码。以前在MNIST数据集中,我们在卷积层中没有使用任何填充,但是现在我们正在处理更复杂的数据集。通过在卷积层中包含填充以确保最大限度地提取特征,使图像的边缘像素保持不变是有意义的。我们将为所有卷积层设置填充为1:
self.conv1=nn.Conv2d(3,16,3,1, padding=1)
self.conv2=nn.Conv2d(16,32,3,1, padding=1)
self.conv3=nn.Conv2d(32,64,3,1, padding=1)
最终馈送到全连接层的矢量由图像大小决定,该图像在每个最大池层中都会减半。图像的大小将减小为:
因此,我们将将nn.Linear方法的初始化器更改为:
self.fully1=nn.Linear(4*4*64,500)
同样,我们将更改forward的view方法:
xx=x.view(-1,4*4*64)
现在,我们将对其进行训练,它将为我们提供以下预期输出: