小白带你去开启PyTorch神经网络工具箱

小白带你去开启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 运行效果

MNIST数据源展示

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工具。如果喜欢,请收藏关注支持。

猜你喜欢

转载自blog.csdn.net/keny88888/article/details/105785106