课程传送门:B站,刘二大人,pytorch深度学习实践
这里贴一个作者: GDUT 小胖鱼,博客对课程的理解和代码都比较详细,可以搭配课程观看,链接:Pytorch_GDUT 小胖鱼的博客-优快云博客
1.线性回归实现Minist数据集分类问题
可配合这篇博客进行理解:Pytorch实现多分类问题 样例解释 通俗易懂 新手必看,写的很详细,对代码部分也进行了详细分析。
网络模型结构图:
添加注释的详细代码:
import torch
from torchvision import transforms #针对图像处理的工具
from torch.utils.data import DataLoader
from torchvision import datasets
import torch.nn.functional as F #为了使用函数relu()
import torch.optim as optim #构建优化器
#prepare dataset(dataset and dataloader)
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307, ),(0.3081, ))])
#torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作,
#transforms.ToTensor() 将给定图像转为Tensor,
#transforms.Normalize(mean,std) 归一化处理
train_dataset = datasets.MNIST(root='../dataset/minist/',train=True,download=True,transform = transform)
#定义好transform之后放到数据集里边,将来读取样本的时候拿到的数据会直接用transform进行处理
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/minist/',train=False,download=True,transform = transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)
#desigen model using class(继承自nn.module)
class Net(torch.nn.Module):
def __init__(self):
super(Net,self).__init__()
#super() 是调用Net的父类(超类)Module的一种方法,在Net中可以通过super()方法来调用父类Module的方法。
self.l1 = torch.nn.Linear(784,512) #输入784,输出512
self.l2 = torch.nn.Linear(512,256)
self.l3 = torch.nn.Linear(256,128)
self.l4 = torch.nn.Linear(128,64)
self.l5 = torch.nn.Linear(64,10)
def forward(self, x):
x = x.view(-1,784) ##ninist数据集每张图片大小为28*28=784,将1*28*28图像三阶张量变成一阶向量
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = F.relu(self.l4(x))
return self.l5(x)
#使用交叉熵损失注意神经网络最后一层无需做激活,因为将其变分布的softmax激活包含在交叉熵损失中
model = Net()
#构建损失和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) #momentum为冲量加快权值收敛
#训练循环
def train(epoch):
running_loss = 0.0
for batch_idx,data in enumerate(train_loader,0):
inputs, target = data
#优化器优化之前要清零
optimizer.zero_grad()
#forward + backward + update
outputs = model(inputs)
loss = criterion(outputs,target)
loss.backward()
optimizer.step()
running_loss += loss.item() ##取loss要用item()把值拿出来,不然会构建计算图
if batch_idx % 300 == 299: #每300输出一次
print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
running_loss = 0.0
def test():
correct = 0
total = 0
with torch.no_grad(): #test不需要计算梯度
for data in test_loader:
images,labels=data
outputs=model(images)
_,predicted = torch.max(outputs.data, dim=1) #把每行最大值下标拿出来,dim=1表示沿列,沿着列(横着)找最大值
total += labels.size(0) #labels大小为(N,1),size中第0个元素就是N,即样本个数
correct += (predicted == labels).sum().item() #得到预则值与labels相同的个数,求和
print('Accuracy on testset: %d %%' % (100*correct/total))
if __name__=='__main__':
for epoch in range(10): #训练10轮,一轮训练,一轮测试
train(epoch)
#if epoch % 10 = 9 #加上这句可以每10轮测试一次
test()
运行结果:
2.CNN实现Minist数据集分类问题
可配合这篇博客进行理解:看了上百篇文章,我希望用我方式让大家通俗理解CNN
网络模型结构图:
添加注释的详细代码(可配合上述博客进行理解):
(代码与模型结构图不太一致,图中先relu再池化,代码先池化再relu)
import torch
from torchvision import transforms #针对图像处理的工具
from torch.utils.data import DataLoader
from torchvision import datasets
import torch.nn.functional as F #为了使用函数relu()
import torch.optim as optim #构建优化器
#prepare dataset(dataset and dataloader)
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307, ),(0.3081, ))])
#torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作,
#transforms.ToTensor() 将给定图像转为Tensor,
#transforms.Normalize(mean,std) 归一化处理
train_dataset = datasets.MNIST(root='../dataset/minist/',train=True,download=False,transform = transform)
#定义好transform之后放到数据集里边,将来读取样本的时候拿到的数据会直接用transform进行处理
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/minist/',train=False,download=False,transform = transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)
#desigen model using class(继承自nn.module)
class Net(torch.nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1 = torch.nn.Conv2d(1,10,kernel_size=5) #输入通道1,输出通道10。(1,28,28)经过5*5卷积-->(10,24,24)
self.conv2 = torch.nn.Conv2d(10,20,kernel_size=5) #输入通道10,输出通道20.
self.pooling = torch.nn.MaxPool2d(2) #最大池化filter:2*2
self.fc = torch.nn.Linear(320,10) #经过两层卷积和池化之后,转化为(20,4,4)一共320元素,将320个元素变成一个向量,经过一个全连接层映射成10
#若有时不知道该处向量元素个数,可利用模型计算,然后输出一下维度即可
def forward(self, x):
batch_size = x.size(0)
x = F.relu(self.pooling(self.conv1(x)))
x = F.relu(self.pooling(self.conv2(x)))
x = x.view(batch_size,-1) #将x由多维变成一个向量
x = self.fc(x)
return x
#使用torch.nn.Sequential定义模型实测也可行(李沐-动手学习深度学习)
#model = torch.nn.Sequential(
# torch.nn.Conv2d(1,10,kernel_size=5),torch.nn.MaxPool2d(2),torch.nn.ReLU(),
# torch.nn.Conv2d(10,20,kernel_size=5),torch.nn.MaxPool2d(2),torch.nn.ReLU(),
# torch.nn.Flatten(),
# torch.nn.Linear(320,10)
#)
model = Net()
####
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)#把模型的参数权重缓存等放到cuda里边
###
#构建损失和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) #momentum为冲量加快权值收敛
#训练循环
def train(epoch):
running_loss = 0.0
for batch_idx,data in enumerate(train_loader,0):
inputs, target = data
###把这两个迁移到device上
inputs,target = inputs.to(device),target.to(device)
###
#优化器优化之前要清零
optimizer.zero_grad()
#forward + backward + update
outputs = model(inputs)
loss = criterion(outputs,target)
loss.backward()
optimizer.step()
running_loss += loss.item() ##取loss要用item()把值拿出来,不然会构建计算图
if batch_idx % 300 == 299: #每300输出一次
print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
running_loss = 0.0
def test():
correct = 0
total = 0
with torch.no_grad(): #test不需要计算梯度
for data in test_loader:
inputs,target=data
###把这两个迁移到device上
inputs,target = inputs.to(device),target.to(device)
###
outputs=model(inputs)
_,predicted = torch.max(outputs.data, dim=1) #把每行最大值下标拿出来,dim=1表示沿列,沿着列(横着)找最大值
total += target.size(0) #labels大小为(N,1),size中第0个元素就是N,即样本个数
correct += (predicted == target).sum().item() #得到预则值与labels相同的个数,求和
print('Accuracy on testset: %d %% [%d/%d]' % (100*correct/total,correct, total))
if __name__=='__main__':
for epoch in range(10): #训练10轮,一轮训练,一轮测试
train(epoch)
#if epoch % 10 = 9 #加上这句可以每10轮测试一次
test()
运行结果:
要暑期实践了,剩下的Residual和RNN有空再敲吧