ResNet代码实现
步骤
引入库
import torch.nn as nn
import torch
import torch.nn.functional as F
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
Prepare dataset
batch_size = 64
transform=transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
])
train_dataset=datasets.MNIST(root="../dataset/mnist",
train=True,
download=False,
transform=transform)
train_loader=DataLoader(dataset=train_dataset,
batch_size=batch_size,
shuffle=True)
test_dataset=datasets.MNIST(root='../dataset/mnist/',
train=False,
download=False,
transform=transform)
test_loader=DataLoader(dataset=test_dataset,
shuffle=False)
Design model using Class
class residual(nn.Module):
#需要保证输出和输入通道数x一样
def __init__(self,channels):
super(residual,self).__init__()
self.channels=channels
#3*3卷积核,保证图像大小不变将padding设为1
#第一个卷积
self.conv1=nn.Conv2d(channels,channels,
kernel_size=3,padding=1)
#第二个卷积
self.conv2=nn.Conv2d(channels,channels,
kernel_size=3,padding=1)
def forward(self,x):
#激活
y=F.relu(self.conv1(x))
y=self.conv2(y)
#先求和 后激活
return F.relu(x+y)
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1=nn.Conv2d(1,16,kernel_size=5)
self.conv2 = nn.Conv2d(16, 32, kernel_size=5)
self.conv3 = nn.Conv2d(32, 64, kernel_size=1)
self.mp=nn.MaxPool2d(2)
self.residual1 = residual(16)
self.residual2 = residual(32)
self.residual3 = residual(64)
self.fc=nn.Linear(256,10)
def forward(self,x):
batch_size=x.size(0)
x=self.mp(F.relu(self.conv1(x)))
x=self.residual1(x)
x = self.mp(F.relu(self.conv2(x)))
x = self.residual2(x)
x = self.mp(F.relu(self.conv3(x)))
x = self.residual3(x)
x=x.view(batch_size,-1)
x=self.fc(x)
return x
net=Net()
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net.to(device)
Construct loss and optimizer
criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(net.parameters(),lr=0.01)
Training cycle
def train(epoch):
running_loss=0.0
for batch_idx,data in enumerate(train_loader,0):
inputs,targets=data
inputs,targets=inputs.to(device),targets.to(device)
optimizer.zero_grad()
#forward
y_pred=net(inputs)
#backward
loss=criterion(y_pred,targets)
loss.backward()
#update
optimizer.step()
running_loss+=loss.item()
if(batch_idx%300==299):
print("[%d,%d]loss:%.3f"%(epoch+1,batch_idx+1,running_loss/300))
running_loss=0.0
accuracy=[]
def test():
correct=0
total=0
with torch.no_grad():
for data in test_loader:
images,labels=data
images,labels = images.to(device), labels.to(device)
outputs=net(images)
_,predicted=torch.max(outputs.data,dim=1)
total+=labels.size(0)
correct+=(labels==predicted).sum().item()
print("accuracy on test set:%d %% [%d/%d]"%(100*correct/total,correct,total))
accuracy.append(100 * correct / total)
if __name__=="__main__":
for epoch in range(2):
train(epoch)
test()