Pytorch任务2——组件学习与实战

1.第一章

        跟着 DW的教程https://datawhalechina.github.io/thorough-pytorch/%E7%AC%AC%E4%B8%80%E7%AB%A0/index.html

安装Pytorch,由于之前安装过Ananconda,因此直接使用进行设置,创建虚拟环境,类似在这个环境下做一个沙盒来运行我们的程序,这几步进行顺利。

 

 

然后是 Step 4:换源 ,这个只是为了加速,建议不按照教程来,我试了几次总是出问题,直接跳过这一步!!!

由于我的电脑没有显卡,直接安装CPU版本,在PyTorch 官网上选择型号,他会在选择栏下面给一条命令,复制这命令去 Anaconda Prompt运行

(不用删除-c 后面的,完整不动地复制),然后等等就可以了!!!

最后是验证一下,输入如下命令,能够返回,OK

参考下面两个教程,在Pycharm里面也能运行torch效果如下:

参考了: 关于pycharm软件edit configurations及解释器(project interpreter)配置的问题_跳动的喵尾巴的博客-CSDN博客_editconfiguration怎么配置

            win10 安装 pytorch - 知乎 (zhihu.com)

BTW: 失败了好几次,试了DW教程提到的离线下载,但是失败了,教程 对于这种情况失败了后怎么处理,没给说明,这个有点不方便!

 

2.PyTorch基础知识

1.张量

       这部分主要学习了解张量(Tensor)以及在PyTorch中如何创建、怎么进行加减操作、索引操作,这些和Python的列表操作类似,

然后介绍的广播机制,是和之前不一样的,在线代里面,形状不同矩阵不能加减,但通过广播机制可以变成(整行整列进行复制)形状一样的然后进行加减操作。

 

 

2.自动求导

这部分主要学习了解PyTorch 的自动求梯度功能,利用 .backward()来自动计算所有的梯度,然后关于那个.grad属性我通过看教程还没太明白。Mark 一下,之后用到再看

 

3.并行计算简介

       这部分主要介绍了 PyTorch可以在编写完模型之后,让多个GPU来参与训练。但是目前只有部分NVIDIA的GPU才支持CUDA(所以我的AMD的电脑用不了CUDA >-<)

然后关于并行的方法是数据并行的方式(Data parallelism), 因为这种方式可以解决之前模式遇到的通讯问题。

这种方式先拆分数据,即同一个模型在不同GPU中训练一部分数据,然后将输出的结果汇总。

 

第三章:PyTorch的主要组成模块

 1.首先了解了进行深度学习的流程,先要设置好模型的结构和参数,然后再训练集训练,并在测试集验证模型效果。

       DL 样本量大,加载方式须设计,读入数据是按批的、需要“逐层”搭建、损失函数和优化器要能够保证反向

    传播能够在用户自行定义的模型结构上实现、误差反向传播的同时使用优化器调整网络参数,最后根据设定指标计算模型表现。

2.接下来 基于以上流程介绍Pytorch 实现:

  •   包导入和超参数的统一设置,GPU 没硬件,暂时跳过
  •   读入数据:Dataset定义好数据的格式和数据变换形式,DataLoader控制读入批次。
    •    要定义自己的Dataset类(继承pytorch的Dataset)实现灵活的数据读入
    •      读取使用了next和iter函数来完成,这部分需复习

 

  •  神经网络的构造:通过 Module 类(nn 模块里提供的一个模型构造类)来构造神经网络,如MLP:
    •  按照教程输入构造MLP
    • 这部分没太懂
    • 可以Module 来自定义层,从而可以反复调用:包括 1.不含模型参数的层。 2.含有模型参数的层(参数需要学习训练得到
      • 二维卷积层:将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。
      • 池化层:**每次对输入数据的一个固定形状窗口(⼜称池化窗口)中的元素计算输出,用 Max  或者 Average
      • LeNet 和 AlexNet 模型示例    

 

  一个神经网络的典型训练过程如下:

  1. 定义包含一些可学习参数(或者叫权重)的神经网络,在输入数据集上迭代

  2. 通过网络处理输入

  3. 计算 loss (输出和正确答案的距离)

  4. 将梯度反向传播给网络的参数

  5. 更新网络的权重,一般使用一个简单的规则:weight weight learning_rate gradient

 

  • 模型初始化

    •  初始权值选取得好可以使模型收敛速度提高,且准确率更精确!——使用 torch.nn.init 初始化

      # 查看随机初始化的conv参数
      conv.weight.data
      # 查看linear的参数
      linear.weight.data
      # 对conv进行kaiming初始化
      torch.nn.init.kaiming_normal_(conv.weight.data)
      conv.weight.data
      # 对linear进行常数初始化
      torch.nn.init.constant_(linear.weight.data, 0.3 )
      linear.weight.data
      
      #根据不同类型层,设定不同的权值初始化方法
      def initialize_weights( self ):
          for m  in self .modules():
              # 判断是否属于Conv2d
              if isinstance (m, nn.Conv2d):
                  torch.nn.init.xavier_normal_(m.weight.data)
                  # 判断是否有偏置
                  if m.bias  is not None :
                      torch.nn.init.constant_(m.bias.data, 0.3 )
              elif isinstance (m, nn.Linear):
                  torch.nn.init.normal_(m.weight.data,  0.1 )
                  if m.bias  is not None :
                      torch.nn.init.zeros_(m.bias.data)
              elif isinstance (m, nn.BatchNorm2d):
                  m.weight.data.fill_( 1 )       
                  m.bias.data.zeros_()    

        

  

 

  • 各种损失函数及其定义    < 参考: https://github.com/voyagebio/voyagebio.github.io/blob/main/datawhale_pytorch.md  >

二分类交叉熵损失函数 torch.nn.BCELoss计算二分类任务时的交叉熵(Cross Entropy)函数
交叉熵损失函数torch.nn.CrossEntropyLoss 计算交叉熵函数
L1损失函数torch.nn.L1Loss 计算输出y和真实标签target之间的差值的绝对值
MSE损失函数torch.nn.MSELoss 计算输出y和真实标签target之差的平方。
平滑L1损失函数torch.nn.SmoothL1Loss L1的平滑输出,其功能是减轻离群点带来的影响
目标泊松分布的负对数似然损失torch.nn.PoissonNLLLoss 泊松分布的负对数似然损失函数
KL散度torch.nn.KLDivLoss 用于连续分布的距离度量,并且对离散采用的连续输出空间分布进行回归通常很有用
torch.nn.MarginRankingLoss 计算两个向量之间的相似度,用于排序任务。该方法用于计算两组数据之间的差异
多标签边界损失函数torch.nn.MultiLabelMarginLoss 对于多标签分类问题计算损失函数
二分类损失函数torch.nn.SoftMarginLoss 计算二分类的 logistic 损失
多分类的折页损失torch.nn.MultiMarginLoss 计算多分类的折页损失
三元组损失torch.nn.TripletMarginLoss 三元组:这是一种数据的存储或者使用格式。<实体1,关系,实体2>。在项目中,也可以表示为< anchorpositive examples , negative examples>。在这个损失函数中,我们希望去anchor的距离更接近positive examples,而远离negative examples
torch.nn.HingeEmbeddingLoss 对输出的embedding结果做Hing损失计算
余弦相似度torch.nn.CosineEmbeddingLoss 对两个向量做余弦相似度。将余弦相似度作为一个距离的计算方式,如果两个向量的距离近,则损失函数值小,反之亦然。
torch.nn.CTCLoss 用于解决时序类数据的分类:计算连续时间序列和目标序列之间的损失。CTCLoss对输入和目标的可能排列的概率进行求和,产生一个损失值,这个损失值对每个输入节点来说是可分的
     

 

  • 训练和评估  

    • 首先应该设置模型的状态:如果是训练状态,那么模型的参数应该支持反向传播的修改;如果是验证/测试状态,则不应该修改模型参数。

      如下的两个操作二选一即可:   

      model.train()   # 训练状态
      model.eval()   # 验证/测试状态

      #读取DataLoader中的全部数据
      for data, label in train_loader:
      #之后将数据放到GPU上用于后续计算,此处以.cuda()为例
      data, label = data.cuda(), label.cuda()
      #开始用当前批次数据做训练时,应当先将优化器的梯度置零:
      optimizer.zero_grad()
      #之后将data送入模型中训练
      output = model(data)
      #根据预先定义的criterion计算损失函数
      loss = criterion(output, label)
      #将loss反向传播回网络
      loss.backward()
      #使用优化器更新模型参数
      optimizer.step()

      验证/测试的流程基本与训练过程一致,不同点在于:

      • 需要预先设置torch.no_grad,以及将model调至eval模式
      • 不需要将优化器的梯度置零
      • 不需要将loss反向回传到网络
      • 不需要更新optimizer

 

 

  • 优化器

    • 优化器是根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值,使得模型输出更加接近真实标签

    • 优化器的库torch.optim,在这里面提供了十种算法的优化器,其都是继承于 Optimizer,其包括三个属性:
      • defaults:存储的是优化器的超参数
      • state:参数的缓存
      • param_groups管理的参数组,是一个list,其中每个元素是一个字典
    • 包括的方法有:
      •   zero_grad():清空所管理参数的梯度
      •    step():执行一步梯度更新,参数更新
      •     add_param_group():添加参数组
      •     load_state_dict() :加载状态参数字典
      •           state_dict():获取优化器当前状态信息字典

 

posted @ 2022-05-16 22:50  longge2023  阅读(56)  评论(0)    收藏  举报