大多数机器学习工作流程包含处理数据,建立模型,优化模型参数,和保存训练模型。
将使用FashionMNIST 数据集来训练一个神经网络,功能是预测一张输入图片是否属于其中【T-shirt/top, Trouser, Pullover, Dress, Coat, Sandal, Shirt, Sneaker, Bag, or Ankle boot】的一类。
处理数据
PyTorch 有两种处理数据的类:torch.utils.data.DataLoader 和torch.utils.data.Dataset。
Dataset存储有样本数据以及其对应的标签。而DataLoader包装着一个围绕着数据集的可迭代对象。
import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets from torchvision.transforms import ToTensor
Pytorch 提供了特定领域的库,如TorchText,TorchVision和TorchAudio,其中都包含有数据集。这里使用的是TorchVision数据集。
torchvison.datasets模块包含很多现实世界数据的数据集,如CIFAR,COCO等。这里使用的FashionMNIST数据集。
每个TorchVision数据集含有两个参数transform和target_transform分别修改样本数据和标签。
# Download training data from open datasets training_data=datasets.FashionMNIST(root='data',train=True,download=True,transform=ToTensor(),) #Download test data from open datasets test_data=datasets.FashionMNIST(root='data',train=False,download=True,transform=ToTensor(),)
将Dataset作为参数传递给DataLoader。DataLoader包装一个围绕数据集的可迭代对象,并其支持自动分批,取样,重新打乱和多进程处理数据加载。
batch_size=64 # Create data loaders train_dataloader=DataLoader(training_data,batch_size=batch_size) test_dataloader=DataLoader(test_data,baatch_size=batch_size) for X,y in test_dataloader: print(f'Shape of X [N, C, H, W]: {X.shape}') print(f'Shape of y:{y.shape} {y.dtype}') break
创建模型
为了定义Pytorch里的神经网络,定义一个类,继承nn.Module。并在__init__函数中定义神经网络的层和在forward函数中定义数据在模型中传递。为了加速在神经网络的操作,可以将模型放到GPU或MPS上。
# Create model device=('cuda' if torch.cuda.is_available() else 'cpu') print(f'using {device} divice') # define model class NeuralNetWork(nn.Module): def __init__(self): super().__init__() self.flattern=nn.Flatten() self.linear_relu_stack=nn.Sequential( nn.Linear(28*28,512), nn.ReLU(), nn.Linear(512,512), nn.ReLU(), nn.Linear(512,10) ) def forward(self,x): x=self.flattern(x) logits=self.linear_relu_stack(x) return logits model=NeuralNetWork().to(device) print(model)
优化模型参数
为了训练模型,需要一个损失函数和优化器。
loss_fn=nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=1e-3)
在单个训练循环中,模型在训练数据集上预言(将 训练数据分配传给模型),并通过向前传播预言的错误来调整模型的参数。
def train(dataloader,model,loss_fn,optimizer): size=len(dataloader.dataset) model.train() for batch,(X,y) in enumerate(dataloader): X,y=X.to(device),y.to(device) # compute prediction error pred=model(X) loss=loss_fn(pred,y) #backpropagation loss.backward() optimizer.step() optimizer.zero_grad() if batch%100==0: loss,current=loss.item(),(batch+1)*len(X) print(f'loss: {loss:>7f} [{current:>5d}/{size:>5d}]')
通过测试数据集来测试模型的性能。
def test(dataloader,model,loss_fn): size=len(dataloader.dataset) num_batches=len(dataloader) model.eval() test_loss,correct=0,0 with torch.no_grad(): for X,y in dataloader: X,y=X.to(device),y.to(device) pred=model(X) test_loss+=loss_fn(pred,y).item() correct+=(pred.argmax(1)==y).type(torch.float).sum().item() test_loss /=num_batches correct /=size print(f'Test Error: \n Accuracy:{(100*correct):>0.1f},Avg loss:{test_loss:>8f}\n')
为了更好的训练模型,让模型整体多执行几次。
epochs=5 for t in range(epochs): print(f'Epoch {t+1}\n') train(train_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print('Done!')
保存模型
一种通用方式去保存模型是序列化内部状态字典(含有模型参数)
torch.save(model.state_dict(),'model.pth') print('Saved Pytorch Model State to model.pth')
加载模型
加载模型包含重新创建一个模型架构和加载状态字典数据到模型里。
model=NeuralNetWork().to(device) model.load_state_dict(torch.load('model.pth'))
这个模型现在可以被用来进行预测。
classes=[ "T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot", ] model.eval() x,y=test_dataset[0][0],test_dataset[0][1] with torch.no_grad(): x=x.to(device) pred=model(x) predicted,actual=classes[pred[0].argmax(0)],classes[y] print(f'Predicted:"{predicted}",Actual:"{actual}"')
整体代码:
import torch from torch import nn from torch.utils.data import Dataset,DataLoader import torchvision.datasets from torchvision.transforms import ToTensor # working with data train_dataset=torchvision.datasets.FashionMNIST(root=r'data',train=True,transform=ToTensor(),download=False) test_dataset=torchvision.datasets.FashionMNIST(root=r'data',train=False,transform=ToTensor(),download=False) # img,label=train_dataset[0] # print(type(img)) # print(type(label)) batch_size=64 train_dataloader=DataLoader(dataset=train_dataset,batch_size=batch_size) test_dataloader=DataLoader(dataset=test_dataset,batch_size=batch_size) for X,y in test_dataloader: print(f'Shape of X [n,c,h,w]: {X.shape}') print(f'Shape of y: {y.shape} {y.dtype}') break # Create model device='cpu' # device=('cuda' if torch.cuda.is_available() else 'cpu') print(f'using {device} divice') # define model class NeuralNetWork(nn.Module): def __init__(self): super().__init__() self.flattern=nn.Flatten() self.linear_relu_stack=nn.Sequential( nn.Linear(28*28,512), nn.ReLU(), nn.Linear(512,512), nn.ReLU(), nn.Linear(512,10) ) def forward(self,x): x=self.flattern(x) logits=self.linear_relu_stack(x) return logits model=NeuralNetWork().to(device) print(model) # loss_fn=nn.CrossEntropyLoss() optimizer=torch.optim.SGD(model.parameters(),lr=0.06) def train(dataloader,model,loss_fn,optimizer): size=len(dataloader.dataset) model.train() for batch,(X,y) in enumerate(dataloader): X,y=X.to(device),y.to(device) # compute prediction error pred=model(X) loss=loss_fn(pred,y) #backpropagation loss.backward() optimizer.step() optimizer.zero_grad() if batch%100==0: loss,current=loss.item(),(batch+1)*len(X) print(f'loss: {loss:>7f} [{current:>5d}/{size:>5d}]') def test(dataloader,model,loss_fn): size=len(dataloader.dataset) num_batches=len(dataloader) model.eval() test_loss,correct=0,0 with torch.no_grad(): for X,y in dataloader: X,y=X.to(device),y.to(device) pred=model(X) test_loss+=loss_fn(pred,y).item() correct+=(pred.argmax(1)==y).type(torch.float).sum().item() test_loss /=num_batches correct /=size print(f'Test Error: \n Accuracy:{(100*correct):>0.1f},Avg loss:{test_loss:>8f}\n') epochs=5 for t in range(epochs): print(f'Epoch {t+1}\n') train(train_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print('Done!') # save models torch.save(model.state_dict(),'model.pth') print('Saved Pytorch Model State to model.pth') # loading models model=NeuralNetWork().to(device) model.load_state_dict(torch.load('model.pth')) classes=[ "T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot", ] model.eval() x,y=test_dataset[0][0],test_dataset[0][1] with torch.no_grad(): x=x.to(device) pred=model(x) predicted,actual=classes[pred[0].argmax(0)],classes[y] print(f'Predicted:"{predicted}",Actual:"{actual}"')
posted on
浙公网安备 33010602011771号