代码是听完b站up主刘二大人的课程后敲下,每一行都做了注释笔记。
如果对原视频教程感兴趣,下方将供上连接,可以去刘老师的主页听课学习
《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibili
import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
# 准备数据
batch_size = 64 #说明mini—batch得大小
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
# 对输入PLT图像进行处理,在pytorch中我们希望将传入的图像最终转变为Tensor形式,并做一系列伴随的图片操作
# 上述操作中,我们将图片转换为tensor形式,然后将所有像素点进行均值为0.1307,方差为0.3081的归一化操作
train_dataset = datasets.MNIST(root='D:\\dataset\\MNIST', train=True, download=False, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_dataset = datasets.MNIST(root='D:\\dataset\\MNIST', train=False, download=False, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
#加载minist数据集
#设置网络
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()#继承父类
self.l1 = torch.nn.Linear(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): # 重写forward函数。在Modul类中由于存在__call__ 魔法函数,
#当给实例化加括号或者传入数据时,可以调用forward函数,并将数据传入forward函数中,实现向前传播的目的
x = x.view(-1, 784) # -1其实就是自动获取mini_batch
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) # 最后一层不做激活,不进行非线性变换
model = Net()# 实例化网络模型
# 损失函数与优化器
criterion = torch.nn.CrossEntropyLoss()# 采用交叉熵的方式,注意使用torch.nn.CrossEntropyLoss()前应该将网络最后一层设置为线性层
optimizer = optim.Adam(model.parameters(), lr=0.01)
# 这里采用Adam作为优化器,Adam YYDS!
# 定义训练模型函数
def train(epoch):
running_loss = 0.0
for batch_idx, data in enumerate(train_loader): # enumerate 表示将train_loader中储存的一个batch的数据进行编号索引,batch_idx为索引值
# 获得一个批次的数据和标签
inputs, target = data
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
running_loss += loss.item()# 累加所有loss,并在两行后取平均值作为一个阶段的损失计算
if batch_idx % 300 == 299: #当batch每计数300时
print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
running_loss = 0.0 # 归零loss
def test():
correct = 0
total = 0
with torch.no_grad(): # 在测试模型的时候并不需要跟踪计算梯度,这会浪费大量的内存构建计算图
for data in test_loader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, dim=1) # torch.max横向取最终10*1向量的最大值并返回索引下标
total += labels.size(0) # 返回该batch内的数据总量
correct += (predicted == labels).sum().item() # 将所有预测值等于正确值的情况加起来
print('accuracy on test set: %d %% ' % (100 * correct / total))# 计算准确率
if __name__ == '__main__':
for epoch in range(10):# 一共进行十轮epoch
train(epoch)
test()
最后在MINIST数据集的表现经过测试集验证达到97%的正确率