前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「深度学习一遍过」必修10:pytorch 框架的使用

「深度学习一遍过」必修10:pytorch 框架的使用

作者头像
荣仔_最靓的仔
发布2022-01-10 13:50:52
5740
发布2022-01-10 13:50:52
举报
文章被收录于专栏:一些有趣的Python案例

本专栏用于记录关于深度学习的笔记,不光方便自己复习与查阅,同时也希望能给您解决一些关于深度学习的相关问题,并提供一些微不足道的人工神经网络模型设计思路。 专栏地址:「深度学习一遍过」必修篇

目录

1 Tensor生成

2 Tensor基本操作

形状查看

形状更改

增加维度

压缩维度

3 Tensor其他操作

4 Pytorch网络定义与优化

4.1 基础网络定义接口

4.2 网络结构定义与前向传播

4.3 优化器定义

4.4 优化器使用流程

4.5 Tensor 的自动微分 autograd

5 pytorch数据与模型接口

5.1 数据接口

5.2 计算机视觉数据集与模型读取

5.3 数据增强接口

5.4 模型保存

1 Tensor生成

类似于

,可以使用

进行计算。

代码语言:javascript
复制
import torch

构造一个默认

型的

张量

代码语言:javascript
复制
torch.Tensor(5, 3)

构造一个

矩阵,不初始

代码语言:javascript
复制
torch.empty(5, 3)

构造一个随机初始化的矩阵

代码语言:javascript
复制
torch.rand(5, 3)

构造一个矩阵全为

,而且数据类型是

代码语言:javascript
复制
torch.zeros(5, 3, dtype=torch.long)
代码语言:javascript
复制
torch.long

基于已经存在的

创建一个

代码语言:javascript
复制
x = torch.zeros(5, 3, dtype=torch.long)
代码语言:javascript
复制
x.new_ones(5, 3, dtype=torch.double)

构造一个张量,为

,从数据中推断数据类型

代码语言:javascript
复制
torch.tensor([5.5, 3])

2 Tensor基本操作

在张量做加减乘除等运算时,需要保证张量的形状一致,往往需要对某些张量进行更改

代码语言:javascript
复制
import torch

构造一个默认

型的

张量

代码语言:javascript
复制
x = torch.Tensor(5, 3)
x

形状查看

代码语言:javascript
复制
x.size()
代码语言:javascript
复制
x.shape
代码语言:javascript
复制
x.dim()   # dim维度

形状更改

展为

矩阵,共享内存

代码语言:javascript
复制
x.view(3,5)

展为

维向量

代码语言:javascript
复制
x.view(-1)

增加维度

代码语言:javascript
复制
torch.unsqueeze(x,1)

压缩维度

代码语言:javascript
复制
torch.squeeze(x,1)

3 Tensor其他操作

拼接与拆分,基本数学操作:对多个分支的张量加以融合或拆分

代码语言:javascript
复制
torch.cat()   #拼接 
torch.stack() #堆叠 
torch.chunk() #分块 
torch.split() #切分
代码语言:javascript
复制
z = x + y     # torch加法
代码语言:javascript
复制
z = torch.add(x, y)     # torch加法 
代码语言:javascript
复制
y.add_(x)     # 下划线版本,in-place加法,原地运算,结果存在y中

4 Pytorch网络定义与优化

4.1 基础网络定义接口

通过

包来构建网络, 包含

:纯函数,不包含可学习参数,如激活函数,池化层

的核心数据结构,可以是一个

或者一个网络,其中

自动提取可学习参数,适用于卷积层,全连接层等

4.2 网络结构定义与前向传播

通过

包来构建网络

代码语言:javascript
复制
import torch 
import torch.nn as nn 
import torch.nn.functional as F 

class Net(nn.Module): 
    def __init__(self): 
        super(Net, self).__init__() #继承Net类,并进行初始化 
        self.conv1 = nn.Conv2d(1, 6, 5) #继承nn.Module的需要实例化 
        self.conv2 = nn.Conv2d(6, 16, 5) 
        self.fc1 = nn.Linear(16 * 5 * 5, 120) 
        self.fc2 = nn.Linear(120, 84) 
        self.fc3 = nn.Linear(84, 10) 
        
    def forward(self, x): #前向传播函数 
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) #relu,max_pool2d,不需要实例化 
        x = F.max_pool2d(F.relu(self.conv2(x)), 2) 
        x = x.view(-1, self.num_flat_features(x)) 
        x = F.relu(self.fc1(x)) 
        x = F.relu(self.fc2(x)) 
        x = self.fc3(x) 
        return x

需要实例化,可以与

配合使用,

不行,

不需要实例化。

不需要传入

不行。

层状态自动切换,

可以实现,

不行。

代码语言:javascript
复制
import torch.nn as nn

# 创建一个Model类, 这个模型的功能就是给输入的数加上1
class Model(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input):
        output = input + 1
        print(output)

model = Model()         # 实例化
input = torch.tensor(1) # 输入为1
model(input)            # 输出为0

都是和输入共享内存的,

的好处是不用输入形状参数,直接指定维度,在这之后的都被拉平。

则是更加灵活.

4.3 优化器定义

通过

包来构建(优化目标与方法定义)

代码语言:javascript
复制
import torch.optim as 

optim criterion = nn.CrossEntropyLoss() #交叉熵损失 
optimizer_ft = optim.SGD(modelclc.parameters(), lr=0.1, momentum=0.9) #SGD优化方法 
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=100, gamma=0.1) #学习率

4.4 优化器使用流程

三个步骤:清空梯度、反向传播、更新参数

代码语言:javascript
复制
for input, target in dataset: 
    optimizer.zero_grad() #清空梯度 
    
    output = model(input) #自动执行forward函数 
    loss = loss_fn(output, target) #计算损失 
    
    loss.backward() #反向传播 
    optimizer.step() #更新参数

前向计算

代码语言:javascript
复制
out = net(img) #自动执行forward函数 
loss = criterion(out,label) #计算损失

反向传播

代码语言:javascript
复制
loss.backward()   #反向传播 
optimizer.step() #更新参数

4.5 Tensor 的自动微分 autograd

互相连接并构建一个非循环图,它保存完整计算过程。

完成自动求导的步骤:

的属性

设置为

,开始跟踪针对

的所有操作。

  1. 完成计算后调用

自动计算所有梯度。

  1. 将该张量的梯度将累积到

属性中。

是输入叶子结点,

需要进行参数更新。

代码语言:javascript
复制
import torch 
import numpy as np 

x=torch.Tensor([2]) #定义输入张量x 
#初始化权重参数W,偏移量b、并设置require_grad为True, 为自动求导 
w=torch.randn(1,requires_grad=True) 
b=torch.randn(1,requires_grad=True) 
y=torch.mul(w,x) 
z=torch.add(y,b) #等价于y+b 
z.backward() #标量进行反向传播,向量则需要构建梯度矩阵 

print("x,w,b,y,z的require_grad属性分别为:{},{},{},{},{}".format(x.requires_grad, w.requires_grad,b.requires_grad,y.requires_grad,z.requires_grad)) 

如何取消求导?

  1. 调用

修改

,它将其与计算历史记录分离

  1. 调用

停止

模块的工作

代码语言:javascript
复制
# 推理案例 
torch.no_grad() #停止autograd模块的工作,加速和节省显存 
image = Image.open(imagepath) 
imgblob = data_transforms(img).unsqueeze(0) #填充数据维度 
imgblob = Variable(imgblob) 
predict = F.softmax(net(imgblob)) 
index = np.argmax(predict.detach().numpy())

5 pytorch数据与模型接口

5.1 数据接口

通过

包来构建数据集

读取数据的

个必须实现的函数:

  1. __init__:相关参数定义
  2. __len __:获取数据集样本总数
  3. __getitem __:读取每个样本及标签
代码语言:javascript
复制
class TestDataset(torch.utils.data.Dataset):
    #继承Dataset 
    def __init__(self): 
        self.Data=np.asarray([[1,2],[3,4],[2,1],[3,4],[4,5]])#数据 
        self.Label=np.asarray([0,1,0,1,2])#标签 
        
    def __getitem__(self, index): 
        data=torch.from_numpy(self.Data[index]) #把numpy转换为Tensor 
        label=torch.tensor(self.Label[index]) 
        return data,label 
    
    def __len__(self): 
        return len(self.Data)
代码语言:javascript
复制
# 使用index取数据 
Test=TestDataset() 
print(Test[2]) #结果是(tensor([2, 1]), tensor(0)) 
print(Test.__len__()) #结果是5

使用

迭代器提取数据(实现批量读取,打乱数据等)

代码语言:javascript
复制
# 获得数据指针 
test_loader = data.DataLoader(Test, batch_size=2,shuffle=False, num_workers=2)  
  • batch_size:batch大小
  • shuffle=False:是否打乱
  • num_workers=2:加载数据线程数

参数:

  • 当加载

的时间

数据训练的时间,

每次训练完都可以直接从

中取到

的数据 无需额外的等待,不需要多余的

,即使增加

也不会影响训练速度

  • 当加载

的时间

数据训练的时间,

每次训练完都需要等待

完成数据的载入,若增加

, 即使

还未就绪,

也可以取其他

的数据来训练

5.2 计算机视觉数据集与模型读取

通过

包来读取已有的数据集和模型

等,

代码语言:javascript
复制
# 数据集读取
import torchvision.dataset as dataset 
data_dir = './data/'
data = datasets.ImageFolder('./data',data_transform) 
dataloader = data.DataLoader(data)

5.3 数据增强接口

每一次训练时,需要输入同样大小的图片进行训练,一般使用裁剪

缩放操作。

torchvision 数据增强接口

通过

包的

进行数据预处理和增强:包括缩放,裁剪等数据增强函数,标准化等预处理函数

代码语言:javascript
复制
data_transforms = {
    'train': transforms.Compose([ 
        transforms.Scale(64),         # 缩放的图像大小:64*64
        transforms.RandomSizedCrop(48),      # 实际用于训练的图像大小:48*48,采用随机裁剪与缩放操作(此时Scale为冗余操作)
        transforms.RandomHorizontalFlip(), 
        transforms.ToTensor(), 
        transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5]) ]), 
    'val': transforms.Compose([ 
        transforms.Scale(64), 
        transforms.CenterCrop(48),       # 实际用于测试的图像大小:48*48,采用中心裁剪操作
        transforms.ToTensor(), 
        transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5]) ]), }

常见的数据预处理与增强相关的操作

CenterCrop,ColorJitter,FiveCrop,Grayscale,Pad,RandomAffine,RandomApply, RandomCrop,RandomGrayscale, RandomHorizontalFlip,RandomPerspective,RandomResizedCrop,RandomRotation, RandomSizedCrop, RandomVerticalFlip, Resize,Scale,TenCrop,GaussianBlur,RandomChoice,RandomOrder, LinearTransformation,Normalize,RandomErasing,ConvertImageDtype, ToPILImage,ToTensor,Lambda

通过

包的

接口,自定义数据增强函数

代码语言:javascript
复制
import torchvision.transforms.functional as TF 
import random 

def my_segmentation_transforms(image, segmentation): 
    if random.random() > 0.5: 
        angle = random.randint(-30, 30) 
        image = TF.rotate(image, angle) 
        segmentation = TF.rotate(segmentation, angle) 
        # more transforms ... 
        return image, segmentation

torchvision 模型接口

通过

包来读取已有的模型,

等)

代码语言:javascript
复制
# 模型读取、导出
import torchvision.models as models 
model = models.alexnet(pretrained=True).cuda() 
torch.save(model.state_dict(),'models/model.ckpt') 
dummy_input = torch.randn(10, 3, 224, 224).cuda() 
torch.onnx.export(model, dummy_input, "alexnet.proto", verbose=True)

5.4 模型保存

保存或加载整个模型

代码语言:javascript
复制
#保存 
torch.save(model, '\model.pkl’) 

#加载 
model = torch.load('\model.pkl’)

保存或加载模型参数

代码语言:javascript
复制
# 保存 
torch.save(model.state_dict(), '\parameter.pkl') 

# 加载 
model = TheModelClass(...) 
model.load_state_dict(torch.load('\parameter.pkl’))

_

是一个

字典对象,将每个图层映射到其参数

只有具有可学习参数的层(卷积层,线性层等)和已注册的缓冲区(

)才存在。

实例解析

保存方式一:模型结构+模型参数

代码语言:javascript
复制
import torch
import torchvision

# 保存模型
vgg16 = torchvision.models.vgg16(pretrained=False)
torch.save(vgg16, 'vgg16_method1.pth')
# 加载模型
model = torch.load('vgg16_method1.pth')
print(model)

保存方式二:模型参数(官方推荐)

代码语言:javascript
复制
import torch
import torchvision

# 保存模型
vgg16 = torchvision.models.vgg16(pretrained=False)
torch.save(vgg16.state_dict(), 'vgg16_method2.pth')
# 加载模型
model = torch.load('vgg16_method2.pth')
print(model)

若想通过保存的模型参数加载出原模型,可以执行如下代码:

代码语言:javascript
复制
import torch
import torchvision

vgg16 = torchvision.models.vgg16(pretrained=False)
vgg16.state_dict(torch.load('vgg16_method2.pth'))
print(vgg16)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 Tensor生成
  • 2 Tensor基本操作
    • 形状查看
      • 形状更改
        • 增加维度
          • 压缩维度
          • 3 Tensor其他操作
          • 4 Pytorch网络定义与优化
            • 4.1 基础网络定义接口
              • 4.2 网络结构定义与前向传播
                • 4.3 优化器定义
                  • 4.4 优化器使用流程
                    • 三个步骤:清空梯度、反向传播、更新参数
                      • 前向计算
                      • 反向传播
                  • 4.5 Tensor 的自动微分 autograd
                  • 5 pytorch数据与模型接口
                    • 5.1 数据接口
                      • 5.2 计算机视觉数据集与模型读取
                        • 5.3 数据增强接口
                          • torchvision 数据增强接口
                          • torchvision 模型接口
                        • 5.4 模型保存
                          • 实例解析
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档