首页 > 其他分享 >PyTorch神经网络工具箱-新手笔记

PyTorch神经网络工具箱-新手笔记

时间:2023-08-17 11:03:30浏览次数:31  
标签:loss nn img 神经网络 PyTorch train eval 工具箱 model

训练模型

构建模型后,接下来就是训练模型。PyTorch训练模型的主要步骤包括加载和预处理数据集、损失计算、定义优化算法、反向传播、参数更新等主要步骤。

1)加载和预处理数据集:可以使用PyTorch的数据处理工具,如torch.utils和torchvision等。

2)定义损失函数:通过自定义的方法或使用PyTorch内置的损失函数定义,如回归使用nn.MSELoss(),分类使用nn.BCELoss等损失函数。

3)定义优化方法:PyTorch的优化方法都封装在torch.optim中,可以扩展为自定义的方法,都是继承了基类optim.Optimizer,并实现了自己的优化步骤。最常用的优化算法就是梯度下降法及其各种变种,大都使用梯度更新参数。

4)循环训练模型(假设模型实例化为model )

model.train() 将模型设置为训练模式

optimizer.zero_grad():梯度清零,默认情况下梯度值是累加的。

y_pre = model(x):预测值            

loss = loss_fun(y_prev, y_true):把预测值和真实值放入损失函数中。

loss.backward():自动求导,实现梯度的反向传播。

optimizer.step():更新参数

5)循环测试或验证模式

model.eval():设置为测试或验证模式,把所有的training属性设置为False

with.torch.no_grad():在不跟踪梯度的模式下计算损失值、预测值等。

6)可视化结果

注:model.train()与model.eval()的使用

1)如果模型中有批量归一化层(Batch Normalization, BN)和dropout层,需要在训练时添加model.train(),在测试时添加model.eval()。

2)model.train()是保证BN层用每一批数据的均值和方差,而model.eval()是保证BN层用全部训练数据的均值和方差。

3)对于dropout层,model.train()是随机取一部分网络连接来更新参数,model.eval()是利用所有网络的连接。

实现神经网络实例

实现手写数字数据集进行识别的实例。

PyTorch:1.5+版本,GPU或CPU,数据集MNIST

主要步骤如下:

1、下载训练和测试的数据集。

2、利用torchvision对数据进行预处理,调用torch.utils建立一个数据迭代器。

3、可视化源数据。

4、利用nn工具箱构建神经网络模型。

5、实例化模型,定义损失函数及优化器。

6、训练模型。

7、可视化结果。

PyTorch神经网络工具箱-新手笔记_数据集


# 准备数据
# 1) 导入必要的模块
import torch
import torchvision
import numpy as np
# 导入预处理模块
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
# 可视化源数据
import matplotlib.pyplot as plt
from torch.utils.tensorboard import SummaryWriter

# 2) 定义一些超参数
# 训练数据的批量大小
train_batch_size = 64
# 测试数据的批量大小
test_batch_size = 128
# 学习率
learning_rate = 0.01
# 遍历所有数据集的次数
num_epoches = 20
# 学习率
lr = 0.01
# 动量
momentum = 0.5

# 3) 下载数据并对数据进行预处理
# 定义预处理函数
# transforms.Compose可以把一些转换函数组合在一起,以列表的形式。
# Normalize([全局平均值], [方差])对张量进行归一化,图像是灰色,只有一个通道Normalize([0.5], [0.5])
# 假如有3个通道,应该是Normalize([m1, m2, m3], [n1, n2, n3])
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.5], [0.5])])
# 下载数据,并对数据进行预处理:   './':同一级   '../':上一级,下载训练数据集
train_dataset = torchvision.datasets.MNIST('./data/', train=True, transform=transform, download=True)
# 下载测试数据集
test_dataset = torchvision.datasets.MNIST('./data/', train=False, transform=transform, download=True)

# 得到一个生成器
# 将 训练数据集 打包 给后面的神经网络,批量处理,重新排序(shuffle):是
train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)
# 将 测试数据集 打包 给后面的神经网络,批量处理,重新排序(shuffle):否
test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)

# 可视化源数据
# 对数据集中的部分数据进行可视化
# enumerate()函数:用于将一个可遍历的数据对象(列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。
examples = enumerate(test_loader)
batch_idx, (example_data, example_targets) = next(examples)

for i in range(6):
    # 表示将整个图像窗口分为2行3列,当前位置为i+1
    plt.subplot(2, 3, i+1)
    # 自动调整子图参数,使之填充整个图像区域
    plt.tight_layout()
    # 用于绘制二维的灰度图像(或彩色图像,矩阵,热力图、地图等)。 cmap(color map,色图):gray,灰度图  interpolation:插值
    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')
    # 标题
    plt.title("Ground Truth: {}".format(example_targets[i]))
    # 用于设置x轴
    plt.xticks()
    # 用于设置y轴
    plt.yticks()
# 显示图像
plt.show()

# 构建模型
# 1) 构建网络:通过继承基类nn.Module来构建模型
class Net(nn.Module):
    # 使用nn.Sequential构建网络,Sequential()函数的功能是将网络的层组合到一起。
    # 把模型中需要用到的层放到构造函数__init__()中
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        # 初始化父类
        super(Net, self).__init__()
        # 展平(flatten)为向量
        self.flatten = nn.Flatten()

        # 第一层
        # 全连接层 + bn:batch normalization,批量归一化层
        self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1), nn.BatchNorm1d(n_hidden_1))

        # 第二层
        # 全连接层 + bn:batch normalization,批量归一化层
        self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2), nn.BatchNorm1d(n_hidden_2))

        # 输出层
        # 全连接层
        self.out = nn.Sequential(nn.Linear(n_hidden_2, out_dim))

    def forward(self, x):
        # 展平(flatten)为向量
        x = self.flatten(x)
        # 第一层激活函数ReLU(没有学习参数,使用nn.functional实现)
        x = F.relu(self.layer1(x))
        # 第二层激活函数ReLU(没有学习参数,使用nn.functional实现)
        x = F.relu(self.layer2(x))
        # 输出层激活函数softmax(没有学习参数,使用nn.functional实现)
        x = F.softmax(self.out(x), dim=1)
        return x

# 2) 实例化网络
# 检测是否有可用的GPU,有则使用,否则使用GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("*" * 10 + "device" + "*" * 10)
print(device)

# 实例化网络
model = Net(28 * 28, 300, 100, 10)
# 把网络放入device中
model.to(device)

# 定义损失函数和优化器
# 交叉熵损失函数
criterion = nn.CrossEntropyLoss()
# 优化器
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

# 训练模型
# 损失值
losses = []
# 准确率
acces = []
# 测试集损失值
eval_losses = []
# 测试集准确率
eval_acces = []
# 用于创建一个 tensorboard 文件
writer = SummaryWriter(log_dir='logs', comment='train-loss')

# for循环训练
for epoch in range(num_epoches):
    # 训练集损失值
    train_loss = 0
    # 训练集准确率
    train_acc = 0
    # 如果模型中有批量归一化层(Batch Normalization, BN)和dropout层,需要在训练时添加model.train()
    # model.train()是保证BN层用 每一批 数据的均值和方差。
    model.train()
    # 动态修改学习率:第0、5、10、15轮更新学习率
    if epoch % 5 == 0:
        # optimizer.param_groups:是一个list,其中的元素为字典。
        # optimizer.param_groups[0]:长度为7的字典,包括['params', 'lr', 'betas', 'eps', 'weight_decay', 'amsgrad', 'maximize']
        optimizer.param_groups[0]['lr'] *= 0.9

        # 输出动态修改后的学习率
        print("学习率:{:.6f}".format(optimizer.param_groups[0]['lr']))

    # 图片 和 标签 在训练生成器中
    for img, label in train_loader:
        # 把图片放到device中
        img = img.to(device)
        # 把标签放到device中
        label = label.to(device)

        # 训练集的图片放到神经网络中
        output = model(img)
        # 正向传播:计算loss
        loss = criterion(output, label)

        # 梯度清零:通过 autograd计算的梯度会自动累加到grad中
        optimizer.zero_grad()
        # 反向传播:自动计算梯度
        loss.backward()
        # 更新参数
        optimizer.step()

        # 求取训练集的损失,记录误差
        # .item()取出张量具体位置的元素的元素值,并且返回的是该位置元素值的高精度值(int类型)
        # 一般用在求loss或者accuracy时,使用.item()
        train_loss += loss.item()

        # add_scalar(名称,y轴值,x轴值):将一个标量(平均loss)添加到summary中
        # 保存loss的数据与epoch数值
        writer.add_scalar('Train', train_loss/len(train_loader), epoch)

        # 计算分类的准确率
        # torch.max()返回的是两个值,第一个值是具体的value,第二个值是value所在的index(索引值)。
        # _:不需要用到的变量,不关心。 只关心第二个值:变量所对应的索引值。
        # dim=1:取最大值,最后形成1列。  dim=0:取最大值,最后形成1行。
        _, pred = output.max(1)

        # pred == label:预测值与真实值相等返回1,不等返回0。 返回张量
        # .sum():张量求和,求出预测值与真实值相等的个数。
        # .item():返回int类型的元素值
        # num_correct:该批次的训练集中预测值与真实值相等的个数。
        num_correct = (pred == label).sum().item()

        # img.shape[0]:图片的高度(垂直尺寸,矩阵中的行数)
        # img.shape[1]:图片的宽度(水平尺寸,矩阵中的列数)
        # img.shape[2]:图片的通道数(图片的个数)
        acc = num_correct / img.shape[0]

        # 求取训练集的准确率
        train_acc += acc

    # append 向训练集列表末尾添加元素(损失率,准确率)
    losses.append(train_loss / len(train_loader))
    acces.append(train_acc / len(train_loader))

    # 在测试集上验证效果
    # 测试集的损失率
    eval_loss = 0
    # 测试集的准确率
    eval_acc = 0
    # 将模型改为预测模式,model.eval()是保证BN层用全部训练数据的均值和方差。
    # 把所有的training属性设置为False
    # net.eval()
    model.eval()

    # 把 图片 和 标签 在测试生成器中
    for img, label in test_loader:
        # 把图片放到 device 中
        img = img.to(device)
        # 把标签放到 device 中
        label = label.to(device)

        # 修改img的形状,行数:img.size(0),列数:根据输入数据和行数的变化而变化。
        # img.size():返回张量的shape属性值:行值×列值
        # img.size(0):返回张量的行数
        # img.size(1):返回张量的列数
        img = img.view(img.size(0), -1)

        # 把测试集的图像放入神经网络中
        output = model(img)

        # 正向传播:计算loss
        loss = criterion(output, label)

        # 求取测试集的损失,记录误差
        # .item()取出张量具体位置的元素的元素值,并且返回的是该位置元素值的高精度值(int类型)
        # 一般用在求loss或者accuracy时,使用.item()
        eval_loss += loss.item()

        # 计算分类的准确率
        # torch.max()返回的是两个值,第一个值是具体的value,第二个值是value所在的index(索引值)。
        # _:不需要用到的变量,不关心。 只关心第二个值:变量所对应的索引值。
        # dim=1:取最大值,最后形成1列。  dim=0:取最大值,最后形成1行。
        _, pred = output.max(1)

        # pred == label:预测值与真实值相等返回1,不等返回0。 返回张量
        # .sum():张量求和,求出预测值与真实值相等的个数。
        # .item():返回int类型的元素值
        # num_correct:该批次的训练集中预测值与真实值相等的个数。
        num_correct = (pred == label).sum().item()

        # img.shape[0]:图片的高度(垂直尺寸,矩阵中的行数)
        # img.shape[1]:图片的宽度(水平尺寸,矩阵中的列数)
        # img.shape[2]:图片的通道数(图片的个数)
        acc = num_correct / img.shape[0]

        # 求取测试集的准确率
        eval_acc += acc

    # append 向测试集列表末尾添加元素(损失率,准确率)
    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)))

# 设置标题
plt.title('train-loss')
# 用于画图,可以绘制点和线。plt.plot(x轴数据, y轴数据)
plt.plot(np.arange(len(losses)), losses)
# 设置标签名称与位置
plt.legend(['Train Loss'], loc='upper right')
plt.show()

运行结果:

PyTorch神经网络工具箱-新手笔记_预处理_02

PyTorch神经网络工具箱-新手笔记_预处理_03

PyTorch神经网络工具箱-新手笔记_数据集_04

PyTorch神经网络工具箱-新手笔记_数据_05

PyTorch神经网络工具箱-新手笔记_预处理_06

PyTorch神经网络工具箱-新手笔记_数据集_07

小结

本章介绍了神经网络的核心组件,即层、模型、损失函数及优化器。介绍了PyTorch如何使用包、模块等来搭建、训练、评估、优化神经网络。介绍了PyTorch的工具箱nn以及nn的一些常用类或模块等。最后通过一个手写数字识别的实例演示了这些模块的功能。









标签:loss,nn,img,神经网络,PyTorch,train,eval,工具箱,model
From: https://blog.51cto.com/u_16093693/7119445

相关文章

  • Matlab蛇群算法(SO)优化双向长短期记忆神经网络的数据分类预测,SO-BiLSTM分类预测,多输
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • Matlab麻雀算法(SSA)优化双向长短期记忆神经网络的数据分类预测,SSA-BiLSTM分类预测,多
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • Pytorch中使用Embedding报错'IndexError'的解决方法
    简介  Pytorch中nn.Embedding为针对词向量的层,其用来实现词与词向量的映射。其调用形式如下nn.Embedding(num_embeddings:int,embedding_dim:int,padding_idx:int|None=None,max_norm:float|None=None,norm_type:float=2.,scale_grad_by_freq:b......
  • 神经网络速查表
    转自网络。......
  • PyTorch神经网络工具箱-新手笔记
    神经网络核心组件利用PyTorch神经网路工具箱设计神经网络就像搭积木一样,可以极大简化构建模型的任务。神经网络核心组件如下:层:神经网络的基本结构,将输入张量转换为输出张量。模型:由层构成的网络。损失函数:参数学习的目标函数,通过最小化损失函数来学习各种参数。优化器:如在使损失值......
  • 神经网络算法如何用代码实现
    神经网络是一种模仿人类神经系统结构的机器学习算法,用于解决各种任务,如图像分类、自然语言处理等。以下是使用Python中的tensorflow库实现一个简单的神经网络的基本示例,以图像分类为例:importtensorflowastffromtensorflow.keras.datasetsimportmnistfromtensorflow.keras.......
  • Step-by-step to LSTM: 解析LSTM神经网络设计原理
    Ps:喂喂喂,你萌不要光收藏不点赞呀_(:з」∠)_emmmm...搞清楚LSTM中的每个公式的每个细节为什么是这样子设计吗?想知道simpleRNN是如何一步步的走向了LSTM吗?觉得LSTM的工作机制看不透?恭喜你打开了正确的文章!零、前置知识1:在上一篇文章《前馈到反馈:解析RNN》中,小夕从最简单的无......
  • NLP与神经网络
    在NLP中使用神经网络,是现在主流的做法。神经网络神经网络,全称人工神经网络(ArtificialNeuralNetwork),模拟生物神经网络的工作方式。特点:是一种由人工神经元(虚拟的数学模型)构成的计算系统。它具有学习、泛化和适应性等能力能够对输入数据进行自动识别、分类、聚类等任务。广泛应用于......
  • 杨立昆:挺过“神经网络寒冬”,人工智能实现大突破
    原创|文BFT机器人01“卷积网络之父”杨立昆谈人工智能今年GPT爆火以后,杨立昆化身“杠精”。从提出“GPT系统将很快被抛弃”的观点,到回怼特斯拉创始人马斯克“延缓大模型研究和开发是一种新的模糊主义,没有任何意义”,杨立昆的言论引发了激烈的讨论。在今年6月的智源大会上,杨立昆教......
  • 实践教程|源码级理解Pytorch中的Dataset和DataLoader
    前言 本文30分钟带你达到对Pytorch中的Dataset和DataLoader的源码级理解,并提供构建数据管道的3种常用方式的范例,扫除你构建数据管道的一切障碍。本文转载自算法美食屋作者|梁云1991仅用于学术分享,若侵权请联系删除欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最......