PyTorch实战(卷积神经网络模型的训练)

在最后一个主题中, 我们实现了CNN模型。现在, 我们的下一个任务是训练它。为了训练我们的CNN模型, 我们将涉及CUDA张量类型, 该类型将实现与CPU张量相同的功能, 但它们可用于计算。
有以下步骤来训练我们的CNN模型:
步骤1:
在培训部分的第一步, 我们将借助torch.device()指定设备。我们将检查CUDA;如果CUDA可用, 则我们使用Cuda, 否则我们将使用CPU。

device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

第2步:
下一步, 我们将模型分配给设备的方式如下:
model=LeNet.to(device)

第三步:
现在, 我们将定义损失函数。损失函数的定义方式与我们之前使用深度神经网络模型所定义的方式相同。
criteron=nn.CrossEntropyLoss()

之后, 我们将使用熟悉的优化器, 即Adam作为
optimizer=torch.optim.Adam(model.parameters(), lr=0.00001)

步骤4:
在下一步中, 我们将指定时期数。我们初始化历元数, 并使用绘图分析每个历元的损失。我们将初始化两个列表, 即loss_history和正确的历史记录。
epoch=12loss_history=[]correct_history=[]

步骤5:
我们将从迭代每个纪元开始, 并且对于每个纪元, 我们都必须迭代由培训加载者提供给我们的每个培训批次。每个训练批次在训练加载程序中的一列火车中包含一百张图像以及一百个标签, 如下所示:
for e in range(epochs):for input, labels in training_loader:

步骤6:
我们正在处理首先传递输入的卷积神经网络。我们将以四个维度传递图像, 因此无需将其展平。
正如我们将模型分配给设备一样, 我们也将输入和标签也分配给了设备。
input=input.to(device)labels=labels.to(device)

现在, 借助这些输入, 我们得到的输出为:
outputs=model(inputs)

步骤7:
下一步, 我们将以与之前在图像识别中相同的方式执行优化算法。
loss1=criteron(outputs, labels)optimizer.zero_grad()loss1.backward()optimizer.step()

步骤8:
为了跟踪每个时期的损失, 我们将初始化一个变量损失, 即running_loss。对于按批次计算的每个损失, 我们必须将每个批次的总和相加, 然后在每个时期计算最终损失。
loss+=loss1.item()

现在, 我们将整个时期的累积损失添加到损失清单中。为此, 我们在循环语句之后使用else语句。因此, 一旦for循环完成, 便会调用else语句。在此else语句中, 我们将打印在该特定时期为整个数据集计算的累积损失。
epoch_loss=loss/len(training_loader)loss_history.append(epoch_loss)

步骤11:
在下一步中, 我们将发现网络的准确性。我们将初始化正确的变量并将其值分配为零。我们将模型对每个训练图像的预测与图像的实际标签进行比较, 以显示在一个时期内有多少正确。
对于每个图像, 我们将采用最大得分值。在这种情况下, 将返回一个元组。它返回的第一个值是实际的最高值-最大分数, 该分数由模型针对这批图像中的每个单个图像得出。因此, 我们对第一个元组值不感兴趣, 第二个将对应于该模型做出的顶级预测, 我们称其为pred。它将返回该图像的最大值的索引。-
_, preds=torch.max(outputs, 1)

步骤12:
每个图像输出将是索引范围从0到9的值的集合, 以使MNIST数据集包含从0到9的类。由此可以看出, 出现最大值的预测对应于模型所做的预测。我们将模型所做的所有这些预测与图像的实际标签进行比较, 以查看它们中有多少是正确的。
correct+=torch.sum(preds==labels.data)

这将给出每批图像的正确预测数。我们将以与时间损失相同的方式定义时间损失的准确性, 并打印时间损失和准确性为
epoch_acc=correct.float()/len(training_loader)print('training_loss:{:.4f}, {:.4f}'.format(epoch_loss, epoch_acc.item()))

这将产生预期的结果:
PyTorch实战(卷积神经网络模型的训练)

文章图片
步骤13:
【PyTorch实战(卷积神经网络模型的训练)】现在, 我们将整个时期的准确性附加到我们的correct_history列表中, 为了更好地可视化, 我们将时期损失和准确性绘制为
plt.plot(loss_history, label='Running Loss History')plt.plot(correct_history, label='Running correct History')

PyTorch实战(卷积神经网络模型的训练)

文章图片
PyTorch实战(卷积神经网络模型的训练)

文章图片
完整的代码
import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn.functional as funcimport PIL.ImageOpsfrom torch import nnfrom torchvision import datasets, transforms device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")transform1=transforms.Compose([transforms.Resize((28, 28)), transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])training_dataset=datasets.MNIST(root='./data', train=True, download=True, transform=transform1)training_loader=torch.utils.data.DataLoader(dataset=training_dataset, batch_size=100, shuffle=True)class LeNet(nn.Module):def __init__(self):super().__init__()self.conv1=nn.Conv2d(1, 20, 5, 1)self.conv2=nn.Conv2d(20, 50, 5, 1)self.fully1=nn.Linear(4*4*50, 500)self.fully2=nn.Linear(500, 10)def forward(self, x):x=func.relu(self.conv1(x))x=func.max_pool2d(x, 2, 2)x=func.relu(self.conv2(x))x=func.max_pool2d(x, 2, 2)x=x.view(-1, 4*4*50) #Reshaping the output into desired shapex=func.relu(self.fully1(x)) #Applying relu activation function to our first fully connected layerx=self.fully2(x) #We will not apply activation function here because we are dealing with multiclass datasetreturn xmodel=LeNet().to(device)criteron=nn.CrossEntropyLoss()optimizer=torch.optim.Adam(model.parameters(), lr=0.00001) epochs=12loss_history=[]correct_history=[] for e in range(epochs):loss=0.0correct=0.0for e in range(epochs):loss=0.0correct=0.0for inputs, labels in training_loader:inputs=inputs.to(device)labels=labels.to(device)outputs=model(inputs)loss1=criteron(outputs, labels)optimizer.zero_grad()loss1.backward()optimizer.step()_, preds=torch.max(outputs, 1)loss+=loss1.item()correct+=torch.sum(preds==labels.data)else:epoch_loss=loss/len(training_loader)epoch_acc=correct.float()/len(training_loader)loss_history.append(epoch_loss)correct_history.append(epoch_acc)print('training_loss:{:.4f}, {:.4f}'.format(epoch_loss, epoch_acc.item()))plt.plot(loss_history, label='Running Loss History')plt.plot(correct_history, label='Running correct History')plt.show()

    推荐阅读