PyTorch 教程-数据增强过程
在之前,我们看到了模型准确性的显著增加。我们的模型被有效地训练以对训练数据进行分类。然而,它在验证数据上的泛化效果不好,存在过拟合的问题。现在,让我们讨论另一种改进模型训练过程的技术,即数据增强。这是一种通过在训练过程中为模型创建新数据的方法。
应用变换后,新创建的图像被称为增强图像,因为它们本质上允许我们通过向其添加新数据来增强数据集。数据增强技术很有用,因为它允许我们的模型从许多不同的角度查看数据集中的每个图像。这使得我们的模型能够更准确地提取相关特征,并从每个训练图像中获取更多的特征相关数据。
现在,我们最大的问题是如何使用增强来减少过拟合。过拟合发生在模型过于拟合训练集时。
我们无需开始收集新图像并将其添加到我们的数据集中。我们可以使用数据增强,对现有数据集进行轻微的更改,如加深阴影、翻转、缩放、旋转或平移。我们的模型将将它们解释为不同的图像。这不仅可以减少过拟合,还可以防止网络学习无关模式,并提高整体性能。我们有以下步骤来执行数据增强:
👉点击领取:最全Python资料合集
步骤 1:
transform_train=transforms.Compose([transforms.Resize((32,32)),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])
步骤 2:
transform_train=transforms.Compose([transforms.Resize((32,32)),transform.RandomHorizontalFlip(),transform.RandomRotation(),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])
transform_train=transforms.Compose([transforms.Resize((32,32)),transform.RandomHorizontalFlip(),transform.RandomRotation(),transform.RandomAffine(0,shear=10,scale=(0.8,1.2)),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])
在 RandomAffine() 中,第一个参数是旋转,我们将其设置为零以禁用旋转,第二个参数是剪切变换,最后一个参数是缩放变换,使用一个元组定义缩放的范围,我们将范围定义为 0.8 到 1.2,将图像缩放到其大小的 80% 到 120%。
步骤 3:
transform_train=transforms.Compose([transforms.Resize((32,32)),transform.RandomHorizontalFlip(),transform.RandomRotation(10),transform.RandomAffine(0,shear=10,scale=(0.8,1.2)),transform.ColorJitter(brightness=0.2,contrast=0.2,saturation=0.2)transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])
步骤 4:
training_dataset=datasets.CIFAR10(root='./data',train=True,download=True,transform=transform_train)
完整代码:
import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn.functional as funcimport PIL.ImageOpsfrom torch import nnfrom torchvision import datasets,transformsimport requestsfrom PIL import Imagedevice=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")transform_train=transforms.Compose([transforms.Resize((32,32)),transforms.RandomHorizontalFlip(),transforms.RandomRotation(10),transforms.RandomAffine(0,shear=10,scale=(0.8,1.2)),transforms.ColorJitter(brightness=0.2,contrast=0.2,saturation=0.2),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])transform1=transforms.Compose([transforms.Resize((32,32)),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])training_dataset=datasets.CIFAR10(root='./data',train=True,download=True,transform=transform_train)validation_dataset=datasets.CIFAR10(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)def im_convert(tensor):image=tensor.cpu().clone().detach().numpy()image=image.transpose(1,2,0)print(image.shape)image=image*(np.array((0.5,0.5,0.5))+np.array((0.5,0.5,0.5)))image=image.clip(0,1)return imageclasses=('plane','car','bird','cat','dear','dog','frog','horse','ship','truck')dataiter=iter(training_loader)images,labels=dataiter.next()fig=plt.figure(figsize=(25,4))for idx in np.arange(20):ax=fig.add_subplot(2,10,idx+1)plt.imshow(im_convert(images[idx]))ax.set_title(classes[labels[idx].item()])class LeNet(nn.Module):def __init__(self):super().__init__()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)self.fully1=nn.Linear(4*4*64,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=func.relu(self.conv3(x))x=func.max_pool2d(x,2,2)x=x.view(-1,4*4*64) #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.001)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()))url='https://akm-img-a-in.tosshub.com/indiatoday/images/story/201810/white_stork.jpeg?B2LINO47jclcIb3QCW.Bj9nto934Lox4'response=requests.get(url,stream=True)img=Image.open(response.raw)img=transform1(img)image1=img.to(device).unsqueeze(0)output=model(image1)_,pred=torch.max(output,1)print(classes[pred.item()])dataiter=iter(validation_loader)images,labels=dataiter.next()images_=images.to(device)labels=labels.to(device)output=model(images_)_,preds=torch.max(output,1)fig=plt.figure(figsize=(25,4))for idx in np.arange(20):ax=fig.add_subplot(2,10,idx+1,xticks=[],yticks=[])plt.imshow(im_convert(images[idx]))ax.set_title("{}({})".format(str(classes[preds[idx].item()]),str(classes[labels[idx].item()]),color=("green" if classes[preds[idx]]==classes[labels[idx]] else "red")))plt.show()
热门推荐