PyTorch 教程-卷积神经网络模型的验证
在训练部分,我们在MNIST数据集上训练了我们的CNN模型(无限数据集),并且似乎达到了合理的损失和准确性。如果模型能够将其所学到的内容推广到新数据,那么这将是其性能的真正证明。这将与我们在先前主题中所做的方式相同。
步骤1:
我们将使用我们在训练部分创建的训练数据集来创建验证集。这一次,我们将设置train=False:
validation_dataset=datasets.MNIST(root='./data',train=False,download=True,transform=transform1)
步骤2:
validation_loader=torch.utils.data.DataLoader(dataset=validation_dataset,batch_size=100,shuffle=False)
步骤3:
val_loss_history=[]val_correct_history=[]
步骤4:
在接下来的步骤中,我们将验证模型。该模型将在相同的epoch中验证。在我们完成通过整个训练集进行迭代以训练数据之后,我们现在将通过验证集进行迭代以测试数据。
val_loss=0.0val_correct=0.0
步骤5:
for val_input,val_labels in validation_loader:
👉点击领取:最全Python资料合集
步骤6:
我们正在处理卷积神经网络,将输入首先传递给它们。我们将专注于这些图像的四个维度。因此,无需将它们展平。
input=input.to(device)labels=input.to(device)
val_outputs=model(val_inputs)
步骤7:
val_loss1=criteron(val_outputs,val_labels)
with torch.no_grad():
它将临时将所有requires_grad标志设置为False。
步骤8:
_,val_preds=torch.max(val_outputs,1)val_loss+=val_loss1.item()val_correct+=torch.sum(val_preds==val_labels.data)
步骤9:
val_epoch_loss=val_loss/len(validation_loader)val_epoch_acc=val_correct.float()/len(validation_loader)val_loss_history.append(val_epoch_loss)val_correct_history.append(val_epoch_acc)
步骤10:
print('validation_loss:{:.4f},{:.4f}'.format(val_epoch_loss,val_epoch_acc.item()))
步骤11:
plt.plot(loss_history,label='Training Loss')plt.plot(val_loss_history,label='Validation Loss')plt.legend()plt.show()
plt.plot(correct_history,label='Training accuracy')plt.plot(val_correct_history,label='Validation accuracy')plt.legend()plt.show()
从上面的图表中可以清楚地看出,在CNN中发生了过拟合。为了减少这种过拟合,我们将介绍另一种名为Dropout Layer的快速技术。
步骤12:
在下一步中,我们将转到我们的LeNet类,并添加一种称为Dropout层的特定层类型,该层类型将减少我们数据的过拟合。该层类型称为Dropout层。此层本质上通过在训练过程中随机将输入单元的分数比例设置为0来工作,每次更新。
上图显示了标准神经网络,以及在应用了dropout后相同神经网络的情况。我们可以看到,有些节点已被关闭,并且不再沿着网络与信息通信。
我们将使用不止一个dropout层,这将在给定网络中用于获得所需的性能。我们将这些dropout层放在卷积层之间和全连接层之间。在完全连接的层之间,我们将dropout层放置在这些高参数层之间,因为这些高参数层更有可能过度拟合和记忆训练数据。因此,我们将在完全连接的层之间设置我们的dropout层。
self.dropout1=nn.dropout(0.5)
步骤13:
x=self.dropout1(x)
现在,我们将运行我们的程序,它将为我们提供更准确的结果:
完整代码
import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn.functional as funcimport PIL.ImageOpsfrom torch import nnfrom torchvision import datasets,transformsdevice=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)validation_dataset=datasets.MNIST(root='./data',train=False,download=True,transform=transform1)training_loader=torch.utils.data.DataLoader(dataset=training_dataset,batch_size=100,shuffle=True)validation_loader=torch.utils.data.DataLoader(dataset=validation_dataset,batch_size=100,shuffle=False)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.dropout1=nn.Dropout(0.5)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.dropout1(x)x=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=[]val_loss_history=[]val_correct_history=[]for e in range(epochs):loss=0.0correct=0.0val_loss=0.0val_correct=0.0for input,labels in training_loader:input=input.to(device)labels=labels.to(device)outputs=model(input)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:with torch.no_grad():for val_input,val_labels in validation_loader:val_input=val_input.to(device)val_labels=val_labels.to(device)val_outputs=model(val_input)val_loss1=criteron(val_outputs,val_labels)_,val_preds=torch.max(val_outputs,1)val_loss+=val_loss1.item()val_correct+=torch.sum(val_preds==val_labels.data)epoch_loss=loss/len(training_loader)epoch_acc=correct.float()/len(training_loader)loss_history.append(epoch_loss)correct_history.append(epoch_acc)val_epoch_loss=val_loss/len(validation_loader)val_epoch_acc=val_correct.float()/len(validation_loader)val_loss_history.append(val_epoch_loss)val_correct_history.append(val_epoch_acc)print('training_loss:{:.4f},{:.4f}'.format(epoch_loss,epoch_acc.item()))print('validation_loss:{:.4f},{:.4f}'.format(val_epoch_loss,val_epoch_acc.item()))plt.plot(loss_history,label='Training Loss')plt.plot(val_loss_history,label='Validation Loss')plt.legend()plt.show()plt.plot(correct_history,label='Training accuracy')plt.plot(val_correct_history,label='Validation accuracy')plt.legend()plt.show()
热门推荐