小白带你去开启PyTorch神经网络工具箱
要想成功,你要想把自己变为神奇的工具箱
1.神经网络核心组件
神经网络看起来很复杂,节点多,层数多,参数多。组件包括
1) 层:神经网络的基本结构。
2)模型:层构成的网络。
3)loss函数:参数学习的目标函数,通过最小化损失函数来学习各种参数。
4)优化器:使损失函数最小,是优化器的工作。
1.1 神经网络组建关系图
学习网络一个循环过程,当损失值达到一个阀值或循环次数到达指定次数,循环结束
1.2 Pytorch工具介绍
实现神经网络实例
1.3 手写识别
1.3.1 源代码 Pytorchtest.py 在该目录建立data
源数据要用到Mnist数据,下载地址为http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz ,将文件解压到data目录下
import torch as t
import numpy as np
import torch
# 导入 PyTorch 内置的 mnist 数据
from torchvision.datasets import mnist
#导入预处理模块
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
#导入nn及优化器
import torch.nn.functional as F
import torch.optim as optim
from torch import nn
train_batch_size = 64
test_batch_size = 128
learning_rate = 0.01
num_epoches = 20
lr = 0.01
momentum = 0.5
#定义预处理函数,这些预处理依次放在Compose函数中。
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5], [0.5])])
#下载数据,并对数据进行预处理
train_dataset = mnist.MNIST('./data', train=True, transform=transform, download=True)
test_dataset = mnist.MNIST('./data', train=False, transform=transform)
#dataloader是一个可迭代对象,可以使用迭代器一样使用。
train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)
1.3.2 运行效果
2.网络实例化
2.1 MNIST下载后的目录为
要满足固定的目录格式,这里卡了很久
2.2 训练模型
学习的lr为0.1 如果想学的更好,也可以用0.01 optimizer.param_groups[0]['lr']*=0.1
# 开始训练
losses = []
acces = []
eval_losses = []
eval_acces = []
for epoch in range(num_epoches):
train_loss = 0
train_acc = 0
model.train()
#动态修改参数学习率
if epoch%5==0:
optimizer.param_groups[0]['lr']*=0.1
for img, label in train_loader:
img=img.to(device)
label = label.to(device)
img = img.view(img.size(0), -1)
# 前向传播
out = model(img)
loss = criterion(out, label)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 记录误差
train_loss += loss.item()
# 计算分类的准确率
_, pred = out.max(1)
num_correct = (pred == label).sum().item()
acc = num_correct / img.shape[0]
train_acc += acc
losses.append(train_loss / len(train_loader))
acces.append(train_acc / len(train_loader))
# 在测试集上检验效果
eval_loss = 0
eval_acc = 0
# 将模型改为预测模式
model.eval()
for img, label in test_loader:
img=img.to(device)
label = label.to(device)
img = img.view(img.size(0), -1)
out = model(img)
loss = criterion(out, label)
# 记录误差
eval_loss += loss.item()
# 记录准确率
_, pred = out.max(1)
num_correct = (pred == label).sum().item()
acc = num_correct / img.shape[0]
eval_acc += acc
eval_losses.append(eval_loss / len(test_loader))
eval_acces.append(eval_acc / len(test_loader))
print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
.format(epoch, train_loss / len(train_loader), train_acc / len(train_loader),
eval_loss / len(test_loader), eval_acc / len(test_loader)))
2.3 运行效果
训练的损失率一直在减低,测试损失率也是一直减低,训练的精确度一直升高,测试的精确度也是一直升高,训练效果不错。
epoch: 0, Train Loss: 1.0155, Train Acc: 0.7873, Test Loss: 0.5458, Test Acc: 0.9012
epoch: 1, Train Loss: 0.4740, Train Acc: 0.8998, Test Loss: 0.3478, Test Acc: 0.9240
epoch: 2, Train Loss: 0.3441, Train Acc: 0.9200, Test Loss: 0.2694, Test Acc: 0.9341
epoch: 3, Train Loss: 0.2769, Train Acc: 0.9330, Test Loss: 0.2236, Test Acc: 0.9446
epoch: 4, Train Loss: 0.2387, Train Acc: 0.9405, Test Loss: 0.1954, Test Acc: 0.9509
epoch: 5, Train Loss: 0.2185, Train Acc: 0.9466, Test Loss: 0.1932, Test Acc: 0.9512
epoch: 6, Train Loss: 0.2150, Train Acc: 0.9472, Test Loss: 0.1922, Test Acc: 0.9518
epoch: 7, Train Loss: 0.2129, Train Acc: 0.9475, Test Loss: 0.1867, Test Acc: 0.9531
epoch: 8, Train Loss: 0.2103, Train Acc: 0.9485, Test Loss: 0.1888, Test Acc: 0.9508
epoch: 9, Train Loss: 0.2085, Train Acc: 0.9481, Test Loss: 0.1869, Test Acc: 0.9509
epoch: 10, Train Loss: 0.2052, Train Acc: 0.9498, Test Loss: 0.1856, Test Acc: 0.9527
epoch: 11, Train Loss: 0.2055, Train Acc: 0.9493, Test Loss: 0.1836, Test Acc: 0.9534
epoch: 12, Train Loss: 0.2045, Train Acc: 0.9493, Test Loss: 0.1847, Test Acc: 0.9524
epoch: 13, Train Loss: 0.2054, Train Acc: 0.9486, Test Loss: 0.1826, Test Acc: 0.9527
epoch: 14, Train Loss: 0.2043, Train Acc: 0.9496, Test Loss: 0.1835, Test Acc: 0.9526
epoch: 15, Train Loss: 0.2036, Train Acc: 0.9498, Test Loss: 0.1849, Test Acc: 0.9529
epoch: 16, Train Loss: 0.2052, Train Acc: 0.9499, Test Loss: 0.1827, Test Acc: 0.9543
epoch: 17, Train Loss: 0.2053, Train Acc: 0.9494, Test Loss: 0.1834, Test Acc: 0.9539
epoch: 18, Train Loss: 0.2041, Train Acc: 0.9491, Test Loss: 0.1834, Test Acc: 0.9530
epoch: 19, Train Loss: 0.2048, Train Acc: 0.9491, Test Loss: 0.1840, Test Acc: 0.9525
2.4 可视化训练和测试损失率
精确度和损失率提供图标
plt.title('trainloss')
plt.plot(np.arange(len(losses)), losses)
plt.legend(['Train Loss'], loc='upper right')
plt.show()
plt.title('accs')
plt.plot(np.arange(len(acces)), acces)
plt.legend(['Train acces'], loc='upper right')
plt.show()
3.解说
from torch import nn nn实际就是torch
3.1 nn.Module
nn.Module是nn的一个核心数据结构,它可以是神经网络的某个层(Layer),也可以是包含多层的神经网络。在实际使用中,最常见的做法是继承nn.Module,生成自己的网络/层。所定义的Net类就采用这种方法(class Net(torch.nn.Module))。nn中已实现了绝大多数层,包括全连接层、损失层、激活层、卷积层、循环层等,这些层都是nn.Module的子类,能够自动检测到自己的Parameter,
并将其作为学习参数,且针对GPU运行进行了cuDNN优化
3.2 nn.functional
nn中的层,一类是继承了nn.Module,其命名一般为nn.Xxx(第一个是大写),
如nn.Linear、nn.Conv2d、nn.CrossEntropyLoss等。
另一类是nn.functional中的函数,
其名称一般为nn.funtional.xxx,如nn.funtional.linear、nn.funtional.conv2d、nn.funtional.cross_entropy等。
3.2.1 主要区别如下
- nn.Xxx继承于nn.Module,nn.Xxx需要先实例化并传入参数,然后以函数调用的方式调用实例化的对象并传入输入数据。它能够很好地与nn.Sequential结合使用,而nn.functional.xxx无法与nn.Sequential结合使用。
nn.Xxx不需要自己定义和管理weight、bias参数;而nn.functional.xxx需要自己定义weight、bias参数,每次调用的时候都需要手动传入weight、bias等参数,不利于代码复用。
Dropout操作在训练和测试阶段是有区别的,使用nn.Xxx方式定义Dropout,在调用model.eval()之后,自动实现状态的转换,而使用nn.functional.xxx却无此功能。
中使用激活层,我们采用F.relu来实现,即nn.functional.xxx方式。
4.优化器
PyTorch 优化器都封装在torch.optim里面,设计灵活,可以扩展和自己定义优化方法。所有的优化都集成optim.Optimizer来实现自己的优化步骤。最常用的是优化算法,梯度下降法和梯度下降化变种。SGD是最普通的优化器,是叫随机梯度下降法。
4.1 建立优化器
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)
4.2 前向传播和反向传播
# 前向传播
out = model(img)
loss = criterion(out, label)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
4.3.清空梯度
optimizer.zero_grad()
4.4 反向传播
loss.backward()
4.5 更新参数
optimizer.step()
4.6 动态修改学习率参数
optimizer.param_groups[0]['lr']*=0.1
5.多个优化器比较图
6.总结
小白带你去熟悉了神经网络的核心件 Torch ,即层,模型,损失函数和优化器。并且比较优化器的的损失率。开启PyTorch工具。如果喜欢,请收藏关注支持。