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 模型示例
一个神经网络的典型训练过程如下:
-
定义包含一些可学习参数(或者叫权重)的神经网络,在输入数据集上迭代
-
通过网络处理输入
-
计算 loss (输出和正确答案的距离)
-
将梯度反向传播给网络的参数
- 更新网络的权重,一般使用一个简单的规则:
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>。在项目中,也可以表示为< anchor, positive 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():获取优化器当前状态信息字典
-
-

浙公网安备 33010602011771号