笔记_pytorch

本文介绍了PyTorch的基本概念和操作,包括张量的创建与转换、与NumPy的交互、损失函数的使用以及优化算法如SGD、RMSprop和Adam。此外,还讨论了激活函数如ReLU、LeakyReLU及其在神经网络中的作用。同时,提到了多GPU计算和内存管理的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pytorch 基础
PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序。 它主要由Facebook的人工智能研究小组开发。Uber的"Pyro"也是使用的这个库。
PyTorch是一个Python包,提供两个高级功能: * 具有强大的GPU加速的张量计算(如NumPy) * 包含自动求导系统的的深度神经网络

import torch
# 创建一个形状为(2,3)的空张量
torch.empty(2,3) 
# 创建一个形状为(2.3)的随机张量,每个值在[0,1]之间
torch.rand(2,3) 
# 创建一个0填充的矩阵,数据类型为long:
x = torch.zeros(5, 3, dtype=torch.long)
# 创建tensor并使用现有数据初始化:
x = torch.tensor([5.5, 3])
# NumPy 转换 torch
a = torch.ones(5)
b = a.numpy()
# numpy 转化为pytorch
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
# 与Numpy的reshape类似
x = torch.randn(4, 4)
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  #  size -1 从其他维度推断
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
# 查看向量大小 
print(x.size())
# 向量x和y的点积
x.dot(y)
对x按元素求正弦值
x.sin()
报错:
RuntimeError: expected scalar type Long but found Int
解决:
label=label.to(device).long()
optimizer=torch.optim.SGD(albertBertClassifier.parameters(),lr=0.01,momentum=0.9,weight_decay=1e-4)
momentum:
若当前的梯度方向与累积的历史梯度方向一致,则当前的梯度会被加强,从而这一步下降的幅度更大。若当前的梯度方向与累积的梯度方向不一致,则会减弱当前下降的梯度幅度。
动量的引入就是为了加快学习过程,特别是对于高曲率、小但一致的梯度,或者噪声比较大的梯度能够很好的加快学习过程。动量的主要思想是积累了之前梯度指数级衰减的移动平均(前面的指数加权平均)
weight_decay:
权衰量,用于防止过拟合
错误:
ImportError: No module named 'keras_contrib'
解决:
pip install git+https://www.github.com/keras-team/keras-contrib.git
# nn.MSELoss()
nn.MSELoss是一个比较简单的损失函数,它计算输出和目标间的均方误差
图像可以使用 Pillow, OpenCV
音频可以使用 scipy, librosa
文本可以使用原始Python和Cython来加载,或者使用 NLTK或 SpaCy 处理,中文建议使用lac

损失函数(Loss Function)
因为PyTorch是使用mini-batch来进行计算的,所以损失函数的计算出来的结果已经对mini-batch取了平均

 **nn.L1Loss:**
#输入x和目标y之间差的绝对值,要求 x 和 y 的维度要一样(可以是向量或者矩阵),得到的 loss 维度也是对应一样的
torch.nn.L1Loss(reduction='mean')
#reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。

**nn.NLLLoss:**
用于多分类的负对数似然损失函数

**nn.MSELoss:**
均方损失函数 ,输入x和目标y之间均方差
torch.nn.MSELoss(reduction='mean')
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。

**nn.CrossEntropyLoss:**
多分类用的交叉熵损失函数,LogSoftMax和NLLLoss集成到一个类中,会调用nn.NLLLoss函数,我们可以理解为CrossEntropyLoss()=log_softmax() + NLLLoss()
torch.nn.CrossEntropyLoss(weight=None,ignore_index=-100, reduction='mean')
weight (Tensor, optional) – 自定义的每个类别的权重. 必须是一个长度为 C 的 Tensor
ignore_index (int, optional) – 设置一个目标值, 该目标值会被忽略, 从而不会影响到 输入的梯度。
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。

**KL 散度损失 KLDivLoss:**
计算 input 和 target 之间的 KL 散度。KL 散度可用于衡量不同的连续分布之间的距离, 在连续的输出分布的空间上(离散采样)上进行直接回归时 很有效.
torch.nn.KLDivLoss(reduction='mean')
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。

**MarginRankingLoss:**
对于 mini-batch(小批量) 中每个实例的损失函数如下:
torch.nn.MarginRankingLoss(margin=0.0, reduction='mean')
margin:默认值0

**连接时序分类损失 CTCLoss:**
CTC连接时序分类损失,可以对没有对齐的数据进行自动对齐,主要用在没有事先对齐的序列化数据训练上。比如语音识别、ocr识别等等。
torch.nn.CTCLoss(blank=0, reduction='mean')
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。

**nn.BCELoss:**
计算 x 与 y 之间的二进制交叉熵。

梯度下降
几何上讲,梯度就是函数变化增加最快的地方,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向梯度减少最快,也就是更加容易找到函数的最小值。
优化算法
torch.optim.SGD
随机梯度下降算法,带有动量(momentum)的算法作为一个可选参数可以进行设置,样例如下:

#lr参数为学习率,对于SGD来说一般选择0.1 0.01.0.001,如何设置会在后面实战的章节中详细说明
##如果设置了momentum,就是带有动量的SGD,可以不设置
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)

torch.optim.RMSprop

可以减小某些维度梯度更新波动较大的情况,使其梯度下降的速度变得更快
optimizer = torch.optim.RMSprop(model.parameters(), lr=0.01, alpha=0.99)

torch.optim.Adam
Adam 优化算法的基本思想就是将 Momentum 和 RMSprop 结合起来形成的一种适用于不同深度学习结构的优化算法

# 这里的lr,betas,还有eps都是用默认值即可,所以Adam是一个使用起来最简单的优化方法
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=1e-2)
# weight_decay:防止过拟合L2,使得神经网络的梯度平缓

正则化
L1正则化
损失函数基础上加上权重参数的绝对值
L2正则化
损失函数基础上加上权重参数的平方和
激活函数
sigmoid 函数
在sigmoid函数中我们可以看到,其输出是在(0,1)这个开区间,它能够把输入的连续实值变换为0和1之间的输出,如果是非常大的负数,那么输出就是0;如果是非常大的正数输出就是1,起到了抑制的作用。

但是sigmod由于需要进行指数运算(这个对于计算机来说是比较慢,相比relu),再加上函数输出不是以0为中心的(这样会使权重更新效率降低),当输入稍微远离了坐标原点,函数的梯度就变得很小了(几乎为零)。在神经网络反向传播的过程中不利于权重的优化,这个问题叫做梯度饱和,也可以叫梯度弥散。这些不足,所以现在使用到sigmod基本很少了,基本上只有在做二元分类(0,1)时的输出层才会使用。
tanh 函数
tanh是双曲正切函数,输出区间是在(-1,1)之间,而且整个函数是以0为中心的
与sigmoid函数类似,当输入稍微远离了坐标原点,梯度还是会很小,但是好在tanh是以0为中心点,如果使用tanh作为激活函数,还能起到归一化(均值为0)的效果。

一般二分类问题中,隐藏层用tanh函数,输出层用sigmod函数,但是随着Relu的出现所有的隐藏层基本上都使用relu来作为激活函数了
ReLU 函数
Relu(Rectified Linear Units)修正线性单元

a=max(0,z) 导数大于0时1,小于0时0。
也就是说: z>0时,梯度始终为1,从而提高神经网络基于梯度算法的运算速度。然而当 z<0时,梯度一直为0。 ReLU函数只有线性关系(只需要判断输入是否大于0)不管是前向传播还是反向传播,都比sigmod和tanh要快很多,
当输入是负数的时候,ReLU是完全不被激活的,这就表明一旦输入到了负数,ReLU就会死掉。但是到了反向传播过程中,输入负数,梯度就会完全到0,这个和sigmod函数、tanh函数有一样的问题。 但是实际的运用中,该缺陷的影响不是很大。
Leaky Relu 函数
理论上来讲,Leaky ReLU有ReLU的所有优点,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。

ReLU目前仍是最常用的activation function,在隐藏层中推荐优先尝试!

如果需要指定多张显卡,比如0,1号显卡。

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'
---------------------------------------------------------
清除显存
torch.cuda.empty_cache()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值