20251031_三天速通PyTorch
入门内容 大同小异 稍显生硬 但内容丰富 快速浏览 学习强化
1
Ubuntu:https://www.php.cn/linux-373791.html
显卡驱动安装:https://www.imooc.com/article/303674
CUDA-cuDNN配置:https://www.imooc.com/article/303675
- 也可以从官网分开下载安装,cudnn需要放到已经安装好的cuda路径下
- cuDNN必须运行在CUDA之上,形成"显卡驱动 → CUDA → cuDNN"的依赖链
- 深度学习:cuDNN作为PyTorch、TensorFlow等框架的底层加速核心,调用CUDA实现GPU计算,显著提升模型训练效率。
- 通用计算:CUDA独立支持非深度学习任务(如金融建模、分子模拟),此时无需cuDNN。
Anaconda:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
PyTorch:https://pytorch.org/
py
torch.__version__
torch.version.cuda
5
分类 回归
张量Tensor
py
tensor.type()
# 全0 zeros 全1 ones 对角线eye 随机rand 分布采样normal 序列arange/等间隔序列linespace 打乱randperm
numpy.ndarray 与 tensor 操作很类似,两者之间可以转换;
Tensor属性
- torch.dtype
- torch.device
- torch.layout 内存布局 稠密/稀疏(torch.sparse_coo_tensor, coo类型表示了非零元素的坐标形式)
py
indeices = torch.tensor([[0,1,2],[0,1,2]])
values = torch.tensor([2,4,6], dtype=torch.float32)
# 稀疏张量:非0坐标 非0坐标值 待初始化张量的size
x = torch.sparse_coo_tensor(indeices, values, [4,4])
# 转稠密张量
x = x.to_dense()
稀疏 和 低秩
张量运算
- 乘法-哈达玛积(对应元素相乘)
a.mul(b) - 除法
a / b或a.div(b) - 矩阵乘法
torch.mm(a, b)、a.mm(b)、torch.matmul(a, b)、a.matmul(b)、a @ b
高维矩阵运算 只支持torch.matmul方式,且运算只作用在最后两个维度上,前面的维度需要保持一致;
- 幂运算:pow、
**、exp、sqrt - 对数运算:log、log2、log10
其他
- torch.randn:生成标准正态分布(均值为0,标准差为1)的随机数,适用于模拟噪声或自然现象。
- torch.rand:生成均匀分布(范围[0,1)的随机数,常用于概率计算或颜色通道值等场景。
- inplace原位操作:不使用临时变量
- 广播机制:张量参数可以自动扩展(右对齐)为相同大小
- 向下取整 向上取整 四舍五入 只取整数 只取小数 取余数
- 比较:
- eq:按元素判等
- equal:变量判等
- ge 按元素判断大于等于
- gt 按元素判断大于
- le 按元素判断小于等于
- lt 按元素判断小于
- ne 按元素判断不等于
- 其他
py
torch.sort()
torch.topk() # 沿指定维度返回最大k个数值及其索引
torch.kthvalue() # 沿指定维度返回第k小的数值及其索引
torch.isfinite() # 有界判定
torch.isinf() # 无界判定
torch.isnan()
# 三角函数
torch.acos()
torch.asin()
torch.cos()
torch.sin()
torch.cosh()
torch.sinh()
torch.abs()
torch.sign()
torch.sigmoid()
# 统计相关
torch.mean()
torch.sum()
torch.prod() # 计算所有元素的积
torch.max()
torch.min()
torch.argmax() # 返回最大值的索引
torch.argmin()
torch.std()
torch.var()
torch.median()
torch.mode() # 众数
torch.histc() # 直方图value
torch.bincount() # 统计频数 如统计分类频数
分布:
torch.distributions包含可参数化的概率分布和采样函数- 奖励函数
- pathwise derivative参数化技巧
- 定义了许多分布函数,如Uniform、Normal、Gamma、OneHotCategorical等
- KL Divergence 分布度量
- Transforms 分布转换
- Constraint 分布约束
随机抽样
- 定义随机种子:
torch.manual_seed(seed) - 定义随机数满足的分布:
torch.normal()
范数运算
- 度量某个向量空间(或矩阵)中的每个向量的长度或大小;
- 0范数 1范数 2范数 p范数 核范数
torch.dist(input, other, p=2)计算p范数(绝对值p次方,在开p次方根)torch.norm()计算2范数(欧式距离,平方在开根号)- 范数距离 对应元素差 再算范数
- 核范数:低秩 奇异值
通过范数约束 来实现 对模型参数的约束
矩阵分解
- LU分解:将矩阵A分解成L(下三角)矩阵和U(上三角)矩阵的乘积
- QR分解:将原矩阵分解成一个正交矩阵Q和一个上三角矩阵R的乘积
- EVD分解:特征值分解;PCA算法
- SVD分解:奇异值分解;LDA算法;
torch.svd()
特征值分解:将矩阵分解为由其特征值和特征向量表示的矩阵之积的方法(可能包含多组特征向量和特征值)
- 矩阵需要满秩,由线性无关的向量构成的方阵,这样的矩阵也称为非奇异矩阵
- 不满足就是奇异矩阵,使用的是SVD分解;
PCA算法:也叫主成分分析,将n维特征映射到k维尚,这k维是全新的正交特征,也被称为主成分,是在原n维特征基础上重新构造出来的k维特征
- 该算法优化目标:降维后同一维度的方差最大、不同维度之间的相关性为0
- 采用样本的协方差矩阵作为分解矩阵
这里主要是了解和记录,后续有应用,再具体学习
奇异值分解
- 一般应用在LDA算法中,分类鉴别/判别算法中;
- 思想也是降维,在投影空间中,有效区分不同的类别;
- 同类样本在空间中距离尽可能的小(同类的协方差矩阵)
- 不同类样本在空间中距离尽可能的大(不同类的协方差矩阵)
矩阵分解不等于特征降维,而是在特征降维的过程中用到了矩阵分解;协方差矩阵用来描述方差和相关性;
24
Tensor的裁剪运算
- 对张量中元素范围进行过滤;
- 常用于 梯度剪裁(gradient clipping),即在发生梯度离散或者梯度爆炸时对梯度的处理
- 如
a.clamp(2,10) - 可以产生一定的正则化效果以防止过拟合(限制、平滑了解空间),并使训练更稳定
Tensor的索引和数据筛选
torch.where(condition,x,y):按照条件从x和y中选出满足条件的元素组成新的tensortorch.gather(input, dim, index,out=None):在指定维度上按照索引赋值输出tensortorch.index_select(input, dim, index, out=None):按照指定索引输出tensortorch.masked_select(input, mask,out=None):按照mask输出tensor,输出为向量torch.take(input, indices):将输入看成1D-tensor,按照索引得到输出tensortorch.nonzero(input, out=None):输出非0元素的坐标
Tensor的组合、拼接
torch.cat(seq, dim=0, out=None)按照已经存在的维度进行拼接torch.stack(seq, dim-0, out=None)按照新的维度进行拼接torch.gather(input, dim, index, out=None)在指定维度上按照索引赋值 输出tensor
Tensor切片
torch.chunk(tensor, chunks, dim=0)按照某个维度平均分块(最后一个可能小于平均值)torch.split(tensor, split_size_or_sections, dim=0)在某个维度依照第二个参数给出的list或int进行分割tensor
Tensor变形
torch.reshape(input, shape)torch.t(input)2D 转置torch.transpose(input, dim0, dim1)交换维度torch.squeeze(input, dim=None, out=None)去除维度大小为1 的维度torch.unbind(tensor, dim=0)去除某个维度 返回一个元组,元素为相应维度变成1后的张量torch.unsqueeze(input, dim, out=None)在指定位置添加维度(大小1)torch.flip(input, dims)指定维度反转张量torch.rot90(input, k, dims)角度旋转,k是正数表示逆时针调整;
Tensor填充操作:
torch.full((2,3), 3.14)
Tensor的频谱操作
torch.fft(input, signal_ndim, normalized=False)傅里叶变换torch.ifft(input, signal_ndim, normalized=False)短时傅里叶变换torch.rfft(input, signal_ndim, normalized=False, onesided=True)快速傅里叶变换torch.irfft(input, signal_ndim, normalized=False, onesided=True)短时傅里叶反变换torch.stft(signa, frame_length, hop, ..)快速傅里叶反变换
31
模型的保存预加载
torch.savestorch.load(dir)
DP和DDP
使用to方法可以将Tensor在CPU和GPU之间相互移动;如tensor.to(torch.device("cuda"))
Tensor与Numpy相互转换
torch.from_numpy(ndarray)a.numpy()需要先转移到cpu上
Variable & Autograd
- 各维度的偏导 构成的梯度
- Variable is Tensor
- 每个tensor通过requires_grad来设置是否支持计算梯度(默认False),这通常用来冻结模型某些层的参数;
- 梯度计算链式法则:两个函数组合起来的复合函数,导致等于里面函数代入外函数值的导 乘以 里面函数的导数;
关于Autograd的几个概念
- 叶子张量leaf:计算图的叶节点,只有叶子结点的张量是有梯度的
- grad:tensor的梯度值,每次在计算 backward 时都需要将前一时刻的梯度归零,否则梯度值会一直累加
- grad_fn:tensor对应的梯度函数,叶子结点通常为None,只有结果节点的grad_fn才有效,用于指示梯度函数是哪种类型;
torch.autograd.backward(tensor, grad_tensors=None, retain_graph=None, create_graph=False)- tensor:用于计算梯度的tensor,
torch.autograd.backward(z) == z.backward() - grad_tensors:在计算矩阵梯度时有用,也是一个tensor,shape一般需要和tensor保持一致;
- retain_graph:通常调用一次backward之后,pytorch会自动把计算图销毁,所以想要对某个变量重复调用backward,就需要保留计算图,将该参数设置为True;
- create_graph:创建一个专门用于derivative微分的图,计算图会保留,可以方便计算更高阶微分
- tensor:用于计算梯度的tensor,
torch.autograd.grad(outputs, inputs,...): 计算和返回output关于inputs的梯度的和,output是因变量(即需要求导的那个函数),inputs是自变量
torch.autograd包中的其他函数
torch.autograd.enable_grad启动梯度计算的上下文管理器torch.autograd.no_grad启动的逆操作,即禁止
torch.autograd.Function
- 每一个原始的自动求导运算实际上是两个在Tensor上运行的函数,分别是forwad和bachward
- forward 进行前向计算 输入Tensor 输出Tensors
- backward接受输出的Tensor对于某个标量值的梯度,计算相对于该标量值的梯度
- 可以自定义继承该类,实现这两个函数,最后再利用apply方法执行相应的运算
py
# 一个线性函数的举例
import torch
class Line(torch.autograd.Function):
@staticmethod
def forward(ctx, w, x, b):
ctx.save_for_barckward(w,x,b)
return w * x + b
@staticmethod
def backward(ctx, grad_out): # 上一级梯度
w,x,b = ctx.saved_tensors
grad_w = grad_out * x
grad_x = grad_out * w
grad_b = grad_out
return grad_w, grad_x, grad_b
w = torch,rand(2,2,requires_grad=True)
x = torch,rand(2,2,requires_grad=True)
b = torch,rand(2,2,requires_grad=True)
out = Line.allpy(w,x,b)
out.backward(torch.ones(2,2))
print(w,x,b)
print(w.grad,x.grad,b.grad)
38
torch.nn是专为神经网络设计的模块化接口
nn构建在autograd之上,用来定义和运行神经网络
- nn.Parameter:定义可训练的参数
- nn.ParameterList & nn.ParameterDict
- nn.Linear 、 nn.conv2d等
- nn.functional
- 注意dropout层,在训练和推理时表现不同
- nn.Module
- 各种神经网络层的定义,继承于nn.Module
- 参数为parameter类型
- nn.Sequential
py
#
params = nn.ParameterList([nn.Parameter(torch.randn(10,10)) for i in range(10)])
params = nn.ParameterDict({
'left':nn.Parameter(torch.randn(5,10))
'right':nn.Parameter(torch.randn(5,10))
})
#
layer = nn.Linear(1,1)
layer.weight = nn.Parameter(torch.FloatTensor([[0]]))
layer.bias = nn.Parameter(torch.FloatTensor([0]))
#
linears = nn.ModuleList([nn.Linear(10,10) for i in range(10)])
choices = nn.ModuleDict({
"conv": nn.Conv2d(10,10,3),
"pool":nn.MaxPool2d(3)
})
nn.Module
model.parameters()获取已注册的可训练的参数(被optinizer更新),register_parameter或nn.Parameter初始化model.buffers()获取已注册的不可训练的参数,register_buffermodel.state_dict()模型的所有参数model.modules()模型中定义的模块forward()、to()
可视化工具 Visdom、tensorboardX
41
torchvision
- 独立的图像操作工具包
torchvision.datasets常用视觉数据集torchvision.models经典的预训练模型torchvision.transforms图像增强、转换操作torchvision.utils等
反向传播(Backpropagation,BP)算法:通过计算输出层金额承受与真实值之间的偏差来进行逐层调节参数;
过拟合 和 欠拟合;参数正则化;
神经网络基本组成模块
- 数据集和数据加载
- 网络结构
- 损失和优化器
- 测试与评估
- 推理部署
手写数字识别
k-折交叉验证
波士顿房价预测案例
- 这里例子 竟然没有做任何数据缩放;
py
# 都需要 Net类的声明代码
torch.save(net, "model/model.pkl")
torch.load("model/model.pkl")
# 需要进一步实例化Net类
torch.save(net.state_dict(), "model/model.pkl")
net.load_state_dict(torch.load("model/model.pkl"))
经典的手写数字识别;
48
分类任务评估:混淆矩阵
F.avg_pool2d
Anchor based vs Anchor Free目标检测
- YOLO、CornerNet、CenterNet
- 使用重叠率 判定是否是正样本
- PASCAL VOL数据集(这个数据集的格式很有代表性)
- COCO数据集
- MMDetection:Pytorch实现的深度学习目标检测开源工具箱
图像分割:提取图像中像素所表达的已知目标;
- Semantic Segmentation语义分割:UNet、SegNet
- Instance Segmentation实例分割(只分割感兴趣的目标,分割+检测)
- Panoptic Segmentation全景分割(前两者的结合)
空洞卷积、反卷积
分割任务的评价指标
- Pixel Acc 像素准确率
- MPA(平均像素准确率)
- MIoU 平均交并比
- FWIoU 频权交并比
参与统一损失计算的多个网络结构,可以使用 itertools.chain将待优化参数进行拼接;
NLP基础:
- Transformer
- BERT
- 语言模型是对语句的概率分布的建模