type
status
date
slug
summary
tags
category
icon
password
comment
每个部分都是参考b站小土堆写的,我觉着这个up主讲的蛮好的,手把手教学,b站点击量也很高,适合入门~ 感觉pytorch中文文档删减好多内容,好多还是得对照原版: 官方pytorch参考英文文档:https://pytorch.org/docs/stable/index.html 官方pytorch参考中文文档:https://pytorch-cn.readthedocs.io/zh/latest/ 2024.11.17 完结撒花~完成了一周速通pytorch基础的工作,接下来就上手实战了!
写在最前面:
如果不知道某个数据的数据类型,可以选择使用
print(type())
来打印一下数据的数据类型,这样应该可以快速debug~Pytorch工具学习一、pytorch常识Part 1:环境配置1. 安装anaconda2. pytorch安装(在你想要安装pytorch的虚拟环境下)Part 2:好用的python命令1. dir()2. help()3. 章节总结Part 3:Dataset类的使用1. 不区分标签文件夹代码示例2. 用txt文件存储标签代码示例(包含split用法)Part 4:Tensorboard使用SummaryWriter类的使用Part 5:Transforms的使用1. transforms.Compose2. transforms.Resize3. transforms.CenterCrop 和 transforms.RandomCrop4. transforms.ToTensor5. transforms.Normalize6. transforms.RandomHorizontalFlip 和 transforms.RandomVerticalFlip7. transforms.RandomRotation8. transforms.ColorJitter9. transforms.Grayscale10. transforms.RandomResizedCrop11. transforms.LambdaPart 6:torchvision中的数据集使用Part 7:Dataloader的使用1. 基本使用2. DataLoader 参数详解3. 实际应用示例二、神经网络搭建Part 1:神经网络基本骨架——nn.Module的使用1. nn.Module2. container 常见使用3. 容器的区别对比Part 2:花点时间说卷积操作1. 什么是卷积操作?2. 卷积的步骤3. 卷积的超参数4. 卷积的数学实现5. 示例6. 特点与优势7. 在 PyTorch 中实现卷积Part 3:神经网络——卷积层1. 卷积层的基本原理2. 卷积层的参数3. 输出特征图的大小4. 卷积层的参数总量5. PyTorch 中的卷积层6. 代码示例7. 卷积层的优点Part 4:神经网络——池化层池化层的常见类型PyTorch 中的常用池化函数参数详解注意事项Part 5:神经网络——非线性激活非线性激活(Non-linear Activation)简介非线性激活的常见类型常见激活函数的选择注意事项Part 6:神经网络小结1. 线性层(Linear Layer)2. 卷积层(Convolution Layer)3. 归一化层(Normalization Layer)4. Dropout 层5. 嵌入层(Embedding Layer)6. 循环层(Recurrent Layers)7. Flatten 层8. 池化层(Pooling Layer)9. 非线性激活层总结Part 7:损失函数与反向传播1. 损失函数与反向传播介绍2. 常用损失函数及 PyTorch 实现3. 损失函数选择指南4. 反向传播与优化示例Part 8:优化器及其简介1. 优化器及其原理2. 常见的优化器3. 优化器选择指南4. PyTorch 优化器完整示例Part 9:现有网络模型的使用与修改1. 常见模型分类2. 模型加载与使用3. 常见模型的使用4. 修改现有网络的方法5. 检测与分割模型的使用6. 保存与加载模型总结Part 10:如何在网络中添加层1. 修改现有模型结构2. 使用子类化 nn.Module 添加层3. 在 Forward 方法中动态添加层4. 使用 add_module 动态插入新层Part 11:如何保存模型和加载模型1. 保存网络模型2. 加载网络模型3. 保存和加载模型时的注意事项4. 使用 Checkpoint 保存和加载5. 保存和加载到 GPU/CPU6. 总结三、模型训练与验证完整套路Part 1:完整模型训练套路模型完整训练流程1. 准备数据2. 定义模型3. 选择损失函数4. 选择优化器5. 训练循环6. 模型评估7. 保存模型8. 迁移学习和微调(可选)9. 完整代码示例Part 2:完整模型验证套路1. 准备验证数据2. 加载模型3. 切换到评估模式4. 禁用梯度计算5. 执行验证6. 可视化验证结果(可选)7. 保存验证结果8. 完整验证流程代码9. 总结四、如何利用GPU进行训练1. 检查 GPU 是否可用2. 将模型转移到 GPU3. 将数据转移到 GPU4. 定义损失函数和优化器5. 使用 GPU 进行训练6. 评估模型时使用 GPU7. 保存和加载模型(支持 GPU)8. 多 GPU 训练(可选)9. 完整流程总结
Pytorch工具学习
一、pytorch常识
Part 1:环境配置
1. 安装anaconda
- anaconda安装地址如下,根据自己的操作系统下载对应版本即可
- 安装成功以后打开Anaconda Prompt可以看到命令行最前方出现
(base)
证明成功
2. pytorch安装(在你想要安装pytorch的虚拟环境下)
- pytorch安装地址:https://pytorch.org/
- 选择你适合的版本,博主本人是mac没法用gpu所以cuda就全部失效,只能用default了
- 尽量选择stable版本,这样比较稳定。如果你是windows或者linux就需要去检查你的gpu型号,可以采用在命令行输入命令:
nvidia-smi
来查看你的gpu型号,然后查看cuda支持的gpu型号,选择好以后复制在Run this Command一栏后方的命令,上图显示的是pip3 install torch torchvision torchaudio
,这个命令每个人操作系统型号不同因此命令不同。 - 如果没有独立显卡或者不支持你的gpu,那么在Compute Platform就选择None
- 复制到命令行,在虚拟环境中(即看一下命令行前面是base还是你的环境名称,如果是base就conda activate一下)执行即可
- 更多有关环境配置问题可以自行上网查找,此处不再赘述
Part 2:好用的python命令
1. dir()
dir()
是查看某个包的内容以及某个类的内容的命令
- 在命令行中:
2. help()
help()
是查看某个函数的使用方法
- 在命令行中:
3. 章节总结
- python文件中想要执行上面的内容,就需要借助print
Part 3:Dataset类的使用
1. 不区分标签文件夹代码示例
2. 用txt文件存储标签代码示例(包含split用法)
Part 4:Tensorboard使用
SummaryWriter
类的使用
- 这一部分主要有两个核心函数,一个是
add_image()
,一个是add_scalar()
,接下来分别介绍两个函数的用法
add_scalar()
函数- 运行完上面程序后,然后会发现在对应目录文件夹下出现一个logs文件夹,里面有一个文件是你无法直接打开的,下面介绍如何打开这个文件在终端中,进入logs的上一级文件夹,比如该项目中就对应Part3 ,随后执行
tensorboard --logdir logs
- 如果报错可能有以下几种解决办法:
- 先看一下主机名是不是含有汉字了
- 如果没有可以尝试
pip install --upgrade tensorboard
更新一下版本 - 将命令中的logs改为绝对路径,具体方法自行百度即可
- 还可以指定打开的端口,比如:
tensorboard --logdir logs --port 6007
- 这里注意,现在显示的是页面中有两幅图,
y = x
y = 2x
,如果不更换writer.add_scalar("y = 2x", 2 * i, i)
中的title,就会导致后续的图像也会在同一个title下的图像中绘制,比如我现在如果执行writer.add_scalar("y = 2x", 3 * i, i)
,就会发现y = 2x,y = 3x
出现在同一个图像中,会造成视觉混淆,如果出现不妨停止程序,然后更新一下title再重新绘制就可以了(不过好像现在修复了?我和up主用的不是一个版本,现在不会出现这个问题,好像会直接覆盖掉原来的)
add_image()
函数- 同样在tensorboard中查看,命令和上面的相同,结果如下:
Part 5:Transforms的使用
torchvision.transforms
是 PyTorch 中一个用于数据预处理和增强的模块,尤其在图像处理任务中广泛应用。其主要作用是对输入数据(如图像)进行变换,以便适配模型的输入格式,同时提高模型的鲁棒性。
- 主要应用
- 数据预处理: 例如,调整图像大小、裁剪、归一化等,使数据满足模型的输入要求。
- 数据增强: 通过对图像进行随机变换(如旋转、翻转等),增加数据的多样性,提高模型的泛化能力。
- 管道式操作: 通过
transforms.Compose
将多个变换组合在一起,实现预处理和增强的流水线。
1. transforms.Compose
- 作用: 用于将多个变换组合成一个顺序流水线,方便对数据进行一系列预处理和增强操作。
- 参数: 接收一个列表,列表中的每个元素是一个单独的变换。
- 示例:
解释: 这里的流水线依次调整图像大小、转换为张量、并对像素值标准化。
2. transforms.Resize
- 作用: 调整图像大小。
- 参数:
size
: 目标大小,若为元组(height, width)
则指定高和宽;若为单一值,则将较短边调整到此值,保持长宽比。interpolation
(可选): 指定插值方式(如双线性插值、最近邻插值等),默认是InterpolationMode.BILINEAR
。
- 示例:
解释: 将图像调整为固定大小的 128x128 像素。
3. transforms.CenterCrop
和 transforms.RandomCrop
- 作用:
CenterCrop
:从图像中心裁剪出指定大小的区域。RandomCrop
:从图像中随机裁剪指定大小的区域。
- 参数:
size
: 裁剪区域的大小,接受整数或元组(height, width)
。
- 示例:
4. transforms.ToTensor
- 作用: 将 PIL 图像或 numpy 数组转换为 PyTorch 张量,并将像素值归一化到
[0, 1]
。
- 参数: 无。
- 示例:
解释: 将形状为
(height, width, channels)
的图像转换为 (channels, height, width)
的张量,并归一化。5. transforms.Normalize
- 作用: 对张量进行标准化处理,使每个通道的值服从指定的均值和标准差。
- 参数:
mean
: 各通道的均值。std
: 各通道的标准差。
- 示例:
解释: 每个通道的像素值会减去均值,再除以标准差,实现标准化。
6. transforms.RandomHorizontalFlip
和 transforms.RandomVerticalFlip
- 作用: 随机水平或垂直翻转图像。
- 参数:
p
: 翻转的概率,默认值为 0.5。
- 示例:
解释: 在训练过程中以 50% 的概率随机翻转图像,用于数据增强。
7. transforms.RandomRotation
- 作用: 随机旋转图像。
- 参数:
degrees
: 旋转角度范围,支持单值或范围(min, max)
。
- 示例:
解释: 随机将图像旋转 -45° 到 +45°。
8. transforms.ColorJitter
- 作用: 随机调整图像的亮度、对比度、饱和度和色调。
- 参数:
brightness
: 亮度因子范围(0 无亮度,1 原始亮度)。contrast
: 对比度因子范围。saturation
: 饱和度因子范围。hue
: 色调变化范围。
- 示例:
解释: 随机改变图像的视觉属性,模拟不同的拍摄条件。
9. transforms.Grayscale
- 作用: 将图像转换为灰度图。
- 参数:
num_output_channels
: 指定输出的通道数,默认为 1。
- 示例:
解释: 将彩色图像转换为灰度图,输出单通道。
10. transforms.RandomResizedCrop
- 作用: 随机裁剪并调整图像大小。
- 参数:
size
: 输出图像的大小(height, width)
。scale
: 裁剪区域相对于原始图像面积的比例范围(默认[0.08, 1.0]
)。ratio
: 裁剪区域的宽高比范围(默认[3/4, 4/3]
)。
- 示例:
解释: 随机裁剪一部分图像,并调整为指定大小,常用于数据增强。
11. transforms.Lambda
- 作用: 自定义变换操作。
- 参数:
lambda_function
: 自定义的函数。
- 示例:
解释: 定义一个将像素值除以 255 的自定义操作,用于手动归一化数据。
示例1:
示例2:
示例3:
示例4:
Part 6:torchvision中的数据集使用
- 去到网址:https://pytorch.org/vision/stable/,选择你想要的数据集,然后点击进去就有使用方法了,此处我们仅举一个例子
Part 7:Dataloader的使用
DataLoader
是 PyTorch 中用于批量加载数据的工具,通常与Dataset
配合使用。它提供了高效的数据加载方式,支持多线程、多批次加载以及数据打乱等功能,非常适合深度学习的训练和测试流程。
1. 基本使用
2. DataLoader
参数详解
以下是
DataLoader
中常用参数的解释:dataset
- 数据集对象,需实现 PyTorch 的
Dataset
接口(如torchvision.datasets
提供的内置数据集或自定义Dataset
)。 - 作用:指定数据加载的来源。
batch_size
- 每个批次加载的样本数量,默认为 1。
- 作用:指定训练或测试时的批量大小。
- 示例:
batch_size=32
表示每次加载 32 个样本。
shuffle
- 是否在每个 epoch 开始时打乱数据,默认为
False
。 - 作用:打乱数据有助于防止模型依赖样本顺序,尤其在训练过程中。
- 示例:
shuffle=True
表示数据在每个 epoch 之前会被打乱。
num_workers
- 用于加载数据的子进程数,默认为
0
(单线程加载)。 - 作用:通过多线程加载数据,提高数据预处理的效率。
- 示例:
num_workers=4
使用 4 个线程并行加载数据。- 注意:Windows 用户需在
if __name__ == "__main__"
保护下运行代码。
drop_last
- 是否丢弃最后一个不足
batch_size
的批次,默认为False
。 - 作用:当样本总数不能被
batch_size
整除时,选择是否丢弃最后一个小批次。 - 示例:
drop_last=True
表示丢弃最后的小批次。
pin_memory
- 是否将数据加载到 GPU 的固定内存中,默认为
False
。 - 作用:当使用 GPU 训练时,设置为
True
可加速数据传输。 - 示例:
pin_memory=True
启用固定内存加速。
collate_fn
- 自定义的批次处理函数,默认为
None
。 - 作用:控制如何将多个样本合并成一个批次(常用于处理变长数据,如 NLP)。
- 示例:
- 可传入自定义函数以处理不同长度的文本序列。
sampler
- 自定义采样器,用于指定样本的采样顺序,默认为
None
。 - 作用:覆盖
shuffle
参数,控制数据加载顺序。 - 示例:
- 可使用
torch.utils.data.RandomSampler
或torch.utils.data.SequentialSampler
。
worker_init_fn
- 子进程初始化函数。
- 作用:当
num_workers > 0
时,用于自定义每个子进程的初始化逻辑。 - 示例:
- 常用于设置随机种子等。
3. 实际应用示例
1. 使用
shuffle
和 batch_size
输出示例:
2. 使用
num_workers
加速数据加载注意:
num_workers > 0
时,子进程的初始化开销可能增加训练开始的延迟。
- Windows 系统需在
if __name__ == "__main__"
中运行代码以避免多进程冲突。
3. 使用自定义
collate_fn
用于处理变长数据,例如文本序列。
4. 使用
pin_memory
当训练时使用 GPU,设置
pin_memory=True
可以加速 CPU 到 GPU 的数据传输。二、神经网络搭建
Part 1:神经网络基本骨架——nn.Module的使用
torch.nn
中的container
与nn.Module
torch.nn
模块是 PyTorch 中构建神经网络的核心模块,其中的 container 和nn.Module
是用于组织和管理网络层、模块的重要工具。以下是container
的常见用法以及nn.Module
的详细介绍。
1. nn.Module
- 简介
nn.Module
是 PyTorch 中所有神经网络模型的基类,它不仅仅是一个简单的类,而是提供了深度学习中常用功能的封装,如参数管理、子模块嵌套、前向传播定义等。
- 核心功能
- 参数管理: 自动注册和管理子模块的参数(如权重、偏置等)。
- 模块嵌套: 可以嵌套其他子模块,方便构建复杂模型。
- 前向传播: 通过重载
forward
方法定义前向计算逻辑。 - 设备管理: 提供方便的方法将模型和参数转移到 GPU 或 CPU。
- 常见方法和属性
__init__
- 构造函数,用于定义子模块和初始化操作。
forward
- 前向传播逻辑。
parameters
- 返回模型的所有参数。
children
- 返回所有直接子模块的迭代器。
named_parameters
和named_children
- 返回带名字的参数或子模块。
to
- 将模块和参数移动到指定设备(如 GPU)。
state_dict
和load_state_dict
- 保存和加载模型参数。
- 使用示例
输出:
2. container
常见使用
torch.nn
中的 container 是一些特殊模块,用于组织、管理和简化子模块的组合与连接,尤其适合构建复杂网络。
- 常见 container
nn.Sequential
nn.ModuleList
nn.ModuleDict
2.1
nn.Sequential
简介
- 按顺序组织多个子模块,前向传播时会依次调用子模块。
- 适合顺序执行的网络,如多层感知机(MLP)。
用法
动态添加子模块
2.2
nn.ModuleList
简介
- 是子模块的有序容器,但不会定义网络的前向传播逻辑,需要手动实现
forward
。
- 适合需要灵活控制子模块调用顺序的场景。
用法
2.3
nn.ModuleDict
简介
- 子模块的字典容器,可以通过键值对的方式存储子模块。
- 适合需要根据名称动态选择子模块的场景。
用法
3. 容器的区别对比
容器 | 特点 | 适用场景 |
nn.Sequential | 顺序执行所有子模块,自动定义前向传播逻辑。 | 网络层固定、执行顺序简单的模型(如 MLP)。 |
nn.ModuleList | 仅存储子模块,需要手动定义前向传播逻辑。 | 子模块顺序灵活或需要动态调整的网络。 |
nn.ModuleDict | 使用键值对管理子模块,可根据键动态调用指定模块。 | 模块需要通过名称选择或动态调用的模型。 |
Part 2:花点时间说卷积操作
卷积操作详解
卷积操作是深度学习中卷积神经网络
(Convolutional Neural Network, CNN)
的核心概念。它通过使用滤波器(或称卷积核)对输入图像进行局部特征提取,广泛用于图像处理和计算机视觉任务。1. 什么是卷积操作?
- 卷积操作的本质是通过一个滤波器(卷积核)在输入矩阵上滑动,计算滤波器与输入局部区域的逐元素乘积并求和,从而生成输出特征图。
- 公式
- :输入图像在位置 的像素值。
- :卷积核在位置 的权重。
- :输出特征图在位置 的值。
离散卷积的一般公式为:
2. 卷积的步骤
输入:
- 输入张量 ,大小为 (高度和宽度)。
- 卷积核(滤波器),大小为 (通常为 、 等)。
步骤:
- 选择区域: 在输入图像中选择一个与卷积核大小相同的局部区域。
- 逐元素乘积: 计算输入区域和卷积核对应元素的乘积。
- 求和: 将乘积的结果求和,得到该区域对应的输出值。
- 移动卷积核: 按指定的步幅滑动卷积核,重复上述操作。
3. 卷积的超参数
1) 卷积核大小
(Kernel Size)
- 表示滤波器的高度和宽度,通常为奇数(通常为 、 等)。
- 决定了感受野
(receptive field)
的大小。
2) 步幅
(Stride)
- 滑动窗口的步进距离。
- 默认值为 1,即每次滑动一个像素。
- 步幅较大时,输出特征图尺寸会减小。
3) 填充
(Padding)
- 在输入边界周围填充额外的像素值,通常为零填充
(Zero Padding)
。
- 目的:控制输出特征图的大小。
- 常用的填充方式:
valid
(无填充): 输出比输入小。same
(填充): 输出大小与输入相同。
4) 输出通道数
(Out Channels)
- 决定了输出特征图的通道数,对应卷积层的卷积核个数。
4. 卷积的数学实现
- 1D 卷积
用于时间序列数据或简单的信号处理。
- 2D 卷积
用于图像处理(二维平面)。
- 3D 卷积
用于体积数据(如视频)。
5. 示例
2D 卷积操作示例
假设:
- 输入图像大小 :
- 卷积核大小 :
- 步幅 ,无填充。
步骤:
- 将卷积核放置在输入图像的左上角,取局部区域:
与卷积核逐元素相乘并求和:
结果存储为输出特征图的左上角值。
- 按步幅滑动卷积核,重复计算,最终得到输出特征图。
输出特征图大小公式
- 输出特征图的大小由以下公式决定:
6. 特点与优势
- 局部感受野:
- 卷积操作只关注局部区域,降低了计算复杂度。
- 有利于提取局部特征(如边缘、纹理等)。
- 权重共享:
- 同一个卷积核在不同位置共享参数,减少参数数量,缓解过拟合。
- 平移不变性:
- 卷积对输入图像的平移具有鲁棒性,能够捕获相同特征的不同位置。
7. 在 PyTorch 中实现卷积
使用
torch.nn.Conv2d
实现卷积操作。代码示例1:
代码示例2:
输出结果:
Part 3:神经网络——卷积层
卷积层详细介绍
卷积层
(Convolutional Layer)
是卷积神经网络(CNN)
的核心构建模块,主要功能是通过局部感受野和权重共享的方式提取输入数据的特征,如边缘、纹理、形状等。卷积层通过卷积操作将输入特征映射为输出特征图,同时保留输入数据的空间结构。1. 卷积层的基本原理
核心操作
- 对输入数据进行卷积操作,提取局部特征。
- 卷积核(或滤波器)在输入上滑动,逐元素计算内积并求和,生成输出特征图。
输入与输出
- 输入:一个或多个通道的张量(例如,RGB 图像有 3 个通道)。
- 卷积核:一组权重矩阵,每个卷积核用于提取特定类型的特征。
- 输出:多个特征图,每个特征图对应一个卷积核的输出。
2. 卷积层的参数
卷积层主要包含以下几个关键参数:
2.1 卷积核
(Filters 或 Kernels)
- 定义: 卷积核是一个权重矩阵,大小为 (高度和宽度),用于在输入特征图上滑动,提取特定特征。
- 数量: 卷积核的数量等于输出通道数。
- 初始化: 卷积核的权重是需要学习的参数,通过反向传播优化。
2.2 输入通道数(In Channels)
- 定义: 输入特征图的通道数。例如,RGB 图像的输入通道数为 3。
- 作用: 卷积核会在每个通道上进行单独的卷积操作,然后对结果求和,生成一个输出特征图。
2.3 输出通道数(Out Channels)
- 定义: 输出特征图的通道数,等于卷积核的数量。
- 作用: 每个卷积核生成一个对应的输出通道。
2.4 卷积核大小(Kernel Size)
- 定义: 卷积核的高度 和宽度 ,通常为奇数(如 、)。
- 作用: 决定卷积操作的感受野大小。
2.5 步幅(Stride)
- 定义: 卷积核在输入特征图上滑动的步长。
- 默认值: 通常为 1。
- 作用: 控制输出特征图的大小。步幅越大,输出特征图越小。
2.6 填充(Padding)
- 定义: 在输入特征图的边缘填充额外的像素值,通常为零填充(Zero Padding)。
- 作用:
- 增大输入特征图的尺寸,避免卷积后输出特征图尺寸过小。
- 保持输入和输出的空间维度一致(
padding="same"
)。
2.7 偏置(Bias)
- 定义: 每个输出通道的偏置参数。
- 作用: 增加模型的表达能力。
3. 输出特征图的大小
卷积层的输出特征图大小由以下公式计算:
公式
参数含义
- :输入特征图的高度和宽度。
- :输出特征图的高度和宽度。
- :卷积核的高度和宽度。
- :步幅。
- :填充大小。
4. 卷积层的参数总量
卷积层的参数数量由以下公式计算:
示例
- 输入通道数:3(RGB 图像)。
- 输出通道数:64。
- 卷积核大小:。
计算:
5. PyTorch 中的卷积层
在 PyTorch 中,卷积层通过
torch.nn.Conv2d
实现。类定义
6. 代码示例
1. 定义卷积层
输出:
2. 计算输出大小
输出:
3. 前向传播
输出:
7. 卷积层的优点
- 权重共享: 减少参数数量,降低计算复杂度。
- 局部连接: 关注局部区域,适合处理高维数据。
- 平移不变性: 提取的特征对输入的平移具有鲁棒性。
Part 4:神经网络——池化层
池化层(Pooling Layer)简介
池化层是一种用于降维的操作,常见于卷积神经网络(CNN)中。它的主要功能是通过对特征图进行下采样来减小数据的尺寸,同时保留特征图中的主要信息。池化可以降低计算复杂度、减少过拟合并提升模型的鲁棒性。
池化层通过某种规则(如取最大值或平均值)对输入特征图的某个区域进行处理,生成一个更小的特征图。池化操作与卷积操作类似,也依赖滑动窗口的思想,但不涉及可学习参数。
池化层的常见类型
- 最大池化(Max Pooling)
- 从每个池化窗口中取最大值作为结果。
- 常用于提取显著特征,对边缘和轮廓检测非常有效。
- 平均池化(Average Pooling)
- 计算池化窗口内所有值的平均值作为结果。
- 常用于降噪和平滑特征图。
- 全局池化(Global Pooling)
- 全局平均池化
(Global Average Pooling, GAP)
:将整个特征图的平均值作为输出。 - 全局最大池化
(Global Max Pooling)
:将整个特征图的最大值作为输出。
PyTorch 中的常用池化函数
PyTorch 提供了一组函数来实现不同类型的池化操作,主要包括 1D、2D 和 3D 池化。
1. 最大池化
- 函数名称:
torch.nn.MaxPool1d
torch.nn.MaxPool2d
torch.nn.MaxPool3d
- 主要参数:
kernel_size
:池化窗口的大小。stride
:窗口的滑动步幅(默认为与kernel_size
相同)。padding
:在输入张量周围添加的填充。dilation
:池化窗口的扩张倍数。return_indices
(仅 2D 和 3D 支持):是否返回最大值的索引,用于反池化操作。
- 使用示例:
2. 平均池化
- 函数名称:
torch.nn.AvgPool1d
torch.nn.AvgPool2d
torch.nn.AvgPool3d
- 主要参数:
- 与最大池化基本相同,但不支持
return_indices
。
- 使用示例:
3. 自适应池化(Adaptive Pooling)
自适应池化用于将输入张量缩放到指定的输出大小。
- 函数名称:
torch.nn.AdaptiveMaxPool1d
torch.nn.AdaptiveMaxPool2d
torch.nn.AdaptiveMaxPool3d
torch.nn.AdaptiveAvgPool1d
torch.nn.AdaptiveAvgPool2d
torch.nn.AdaptiveAvgPool3d
- 主要参数:
output_size
:指定输出特征图的大小,张量会根据输入尺寸动态调整池化窗口和步幅。
- 使用示例:
参数详解
- kernel_size:
- 定义池化窗口的尺寸。例如,
kernel_size=2
意味着窗口大小为 (2D 池化)。
- stride:
- 定义池化窗口移动的步长。
- 若未指定,默认值等于
kernel_size
。
- padding:
- 指定输入特征图在边界处填充的大小,用于控制输出尺寸。
- dilation:
- 扩张池化窗口,使窗口间隔加大。
- return_indices:
- 仅用于最大池化,当设置为
True
时返回最大值的位置索引,可用于后续的反池化操作。
- output_size(仅自适应池化):
- 明确指定池化后的输出尺寸,适合处理变长输入。
注意事项
- 池化的边界处理: 当特征图尺寸与池化窗口不整除时,PyTorch 默认舍弃超出部分的元素。
- 例如:输入大小为 ,
kernel_size=2
,stride=2
,则输出大小为 。
- 自适应池化与普通池化的区别:
- 自适应池化根据目标尺寸自动调整窗口和步幅。
- 普通池化需要用户明确指定
kernel_size
和stride
。
池化层在减少计算量的同时也带来信息丢失,因此在设计模型时需要结合具体任务来选择合适的池化方式和参数。
Part 5:神经网络——非线性激活
非线性激活(Non-linear Activation)
简介
非线性激活函数是神经网络的关键组件,其作用是引入非线性,使模型能够学习和表示复杂的模式和特征。没有非线性激活,神经网络无论深度多深,最终都等价于一个线性变换,限制了网络的表达能力。
非线性激活的常见类型
在 PyTorch 中,非线性激活函数可以通过
torch.nn
模块中的类(如 nn.ReLU
)或 torch
模块中的函数(如 torch.relu
)来实现。下面是一些常用的激活函数:1. ReLU(Rectified Linear Unit)
- 定义:
- 特点:
- 简单、高效,适用于大多数深度学习任务。
- 有助于缓解梯度消失问题。
- 对于负输入,输出恒为零,可能导致神经元“死亡”(Dead Neuron)。
- PyTorch 实现:
2. Leaky ReLU
- 定义:
其中 是一个小的正数(默认 0.01)。
- 特点:
- 允许负输入有非零输出,缓解 ReLU 的“死亡神经元”问题。
- PyTorch 实现:
- 参数:
negative_slope
:控制负输入的线性斜率。
3. PReLU(Parametric ReLU)
- 定义: 类似于 Leaky ReLU,但负输入的斜率 是可学习的参数。
- 特点:
- 灵活性更强,可以通过训练自动调整激活函数的负区间斜率。
- PyTorch 实现:
- 参数:
num_parameters
:控制是否为每个通道使用单独的斜率。
4. Sigmoid
- 定义:
- 特点:
- 将输出映射到 (0, 1),常用于二分类任务的输出层。
- 容易导致梯度消失问题,尤其是在深层网络中。
- PyTorch 实现:
5. Tanh(双曲正切)
- 定义:
- 特点:
- 输出范围为 (-1, 1)。
- 与 Sigmoid 类似,但在值接近 0 时梯度更大,性能略优。
- PyTorch 实现:
6. Softmax
- 定义:
其中 是输入的第 个元素。
- 特点:
- 将输出转化为概率分布,常用于多分类任务的输出层。
- PyTorch 实现:
- 参数:
dim
:指定 Softmax 操作的维度。
7. ELU(Exponential Linear Unit)
- 定义:
- 特点:
- 负值区域更平滑,缓解了 ReLU 的死神经元问题。
- 带有可调整的 参数。
- PyTorch 实现:
- 参数:
alpha
:负输入区域的缩放参数。
8. GELU(Gaussian Error Linear Unit)
- 定义:
其中 是标准正态分布的累积分布函数。
- 特点:
- 在 Transformer 等现代架构中表现优异。
- 比 ReLU 更平滑,训练稳定性更强。
- PyTorch 实现:
9. Swish
- 定义:
- 特点:
- 提出了较高的表达能力,适用于深层网络。
- 常见于 Google 的 EfficientNet 等模型。
- PyTorch 实现:
常见激活函数的选择
激活函数 | 优点 | 缺点 | 常用场景 |
ReLU | 简单高效,减少梯度消失 | 死神经元问题 | 卷积网络、一般任务 |
Leaky ReLU | 缓解死神经元问题 | 需手动调整参数 | 深层网络 |
Sigmoid | 输出范围在 (0, 1) | 梯度消失 | 输出层(二分类) |
Tanh | 输出范围在 (-1, 1) | 梯度消失 | 特征归一化 |
Softmax | 概率分布 | 需与交叉熵结合 | 多分类任务 |
ELU | 平滑负值 | 计算量较大 | 深度学习任务 |
GELU | 平滑激活,现代网络优选 | 计算复杂 | Transformer 等 |
注意事项
- 选择合适的激活函数:
- 根据任务需求和网络架构选择合适的激活函数。
- 比如分类任务的输出层,常用 Sigmoid 或 Softmax。
- 避免梯度消失或爆炸:
- 深层网络中,ReLU、Leaky ReLU、GELU 等常用于缓解梯度消失问题。
- 考虑计算效率:
- 激活函数的复杂性可能影响训练和推理速度。
- 激活函数的位置:
- 通常放在每一层的线性变换(如卷积或全连接层)之后。
Part 6:神经网络小结
1. 线性层(Linear Layer)
定义:
线性层实现一个线性变换:
其中 是权重矩阵, 是偏置项。
常用函数:
torch.nn.Linear(in_features, out_features, bias=True)
参数:
in_features
:输入特征的数量(每个样本的特征维度)。
out_features
:输出特征的数量(神经元的个数)。
bias
:是否添加偏置项 (默认True
)。
示例:
2. 卷积层(Convolution Layer)
定义:
卷积层通过滑动窗口提取局部特征。
常用函数:
torch.nn.Conv1d
torch.nn.Conv2d
torch.nn.Conv3d
参数:
in_channels
:输入通道数(如彩色图像的通道数为 3)。
out_channels
:输出通道数(卷积核个数)。
kernel_size
:卷积核的尺寸。
stride
:步幅(窗口移动的步长)。
padding
:填充大小,常见值为 0(无填充)或same
(输出尺寸与输入相同)。
dilation
:扩张率,控制卷积核之间的间隔。
示例:
3. 归一化层(Normalization Layer)
类型与功能:
归一化层用于稳定训练,常见类型包括:
- 批归一化(Batch Normalization)
- 层归一化(Layer Normalization)
批归一化(BatchNorm)
torch.nn.BatchNorm1d
torch.nn.BatchNorm2d
torch.nn.BatchNorm3d
参数:
num_features
:输入通道数。
eps
:防止除零的小值。
momentum
:更新移动平均值时的动量。
示例:
层归一化(LayerNorm)
torch.nn.LayerNorm
参数:
normalized_shape
:需要归一化的最后几个维度的大小。
示例:
4. Dropout 层
定义:
Dropout 是一种正则化方法,通过随机丢弃部分神经元来减少过拟合。
常用函数:
torch.nn.Dropout
torch.nn.Dropout2d
torch.nn.Dropout3d
参数:
p
:丢弃的概率(默认 0.5)。
示例:
5. 嵌入层(Embedding Layer)
定义:
嵌入层将离散的索引映射为连续的向量表示,常用于自然语言处理。
常用函数:
torch.nn.Embedding
参数:
num_embeddings
:词汇表大小(索引的数量)。
embedding_dim
:嵌入向量的维度。
示例:
6. 循环层(Recurrent Layers)
类型与功能:
- RNN(
torch.nn.RNN
):最基本的循环层。
- LSTM(
torch.nn.LSTM
):长短时记忆网络,解决 RNN 的梯度消失问题。
- GRU(
torch.nn.GRU
):门控循环单元,简化版 LSTM。
参数:
input_size
:输入特征的维度。
hidden_size
:隐藏状态的维度。
num_layers
:层数(默认为 1)。
bidirectional
:是否双向(默认False
)。
示例:
7. Flatten 层
定义:
将高维张量展平为一维。
常用函数:
torch.nn.Flatten
参数:
start_dim
和end_dim
:指定展平的起止维度。
示例:
8. 池化层(Pooling Layer)
池化层用于降维,常见于卷积网络中。常用函数包括:
- 最大池化:
nn.MaxPool1d
、nn.MaxPool2d
、nn.MaxPool3d
- 平均池化:
nn.AvgPool1d
、nn.AvgPool2d
、nn.AvgPool3d
- 自适应池化:
nn.AdaptiveMaxPool2d
、nn.AdaptiveAvgPool2d
示例:
9. 非线性激活层
激活函数引入非线性,已在前面详细介绍。常用的 PyTorch 激活函数包括:
nn.ReLU
nn.LeakyReLU
nn.Sigmoid
nn.Tanh
总结
层类型 | 主要功能 | 常用函数 | 关键参数 |
线性层 | 线性变换 | nn.Linear | in_features , out_features |
卷积层 | 提取局部特征 | nn.Conv2d | in_channels , out_channels |
归一化层 | 稳定训练 | nn.BatchNorm2d | num_features , momentum |
Dropout 层 | 防止过拟合 | nn.Dropout | p |
嵌入层 | 离散索引到连续向量 | nn.Embedding | num_embeddings , embedding_dim |
循环层 | 序列建模 | nn.LSTM | input_size , hidden_size |
池化层 | 降维 | nn.MaxPool2d | kernel_size , stride |
激活层 | 引入非线性 | nn.ReLU | 无 |
Flatten | 层展平张量 | nn.Flattenstart_dim | start_dim end_dim |
Part 7:损失函数与反向传播
1. 损失函数与反向传播介绍
- 损失函数的作用
损失函数(Loss Function)是衡量模型预测值与真实值之间差异的指标,用于指导模型优化。在神经网络中,损失函数的输出是一个标量,表示模型在当前参数下的误差大小。通过反向传播算法,根据损失函数计算梯度,从而更新模型的参数。
- 反向传播(Backpropagation)
- 前向传播:将输入通过网络计算输出和损失。
- 计算损失:用损失函数计算预测值和目标值之间的差异。
- 反向传播:计算损失相对于每个参数的梯度。
- 参数更新:通过优化算法(如 SGD、Adam)更新参数。
loss.backward()
: 计算损失函数对参数的梯度。optimizer.step()
: 使用优化器更新参数。
反向传播是一种基于链式法则(Chain Rule)的算法,用于高效地计算神经网络中每个参数的梯度。流程如下:
在 PyTorch 中,反向传播由以下方法自动实现:
2. 常用损失函数及 PyTorch 实现
- 均方误差损失(Mean Squared Error, MSE)
- 定义:
- 常用于:回归任务。
- PyTorch 实现:
- 参数:
reduction
:指定如何对损失进行归约(默认'mean'
)。可选:'mean'
:返回平均值。'sum'
:返回总和。'none'
:返回逐项损失。
其中 是目标值, 是预测值。
- 交叉熵损失(Cross-Entropy Loss)
- 定义:
- 常用于:分类任务。
- PyTorch 实现:
- 参数:
weight
:类别权重,用于处理类别不平衡问题。ignore_index
:忽略指定的类别索引。reduction
:同上。
是目标类别的 one-hot 编码, 是预测的概率。
- 二分类交叉熵(Binary Cross-Entropy, BCE)
- 定义:
- 常用于:二分类任务。
- PyTorch 实现:
- 参数:
weight
:每个样本的权重。reduction
:同上。- 注意:
输入需要经过 Sigmoid 激活。若未经过 Sigmoid,可使用
nn.BCEWithLogitsLoss
,该版本包含 Sigmoid 操作。
- 平滑 L1 损失(Smooth L1 Loss)
- 定义:
- 常用于:回归任务,特别是鲁棒性更强的场景(对异常值不敏感)。
- PyTorch 实现:
- 参数:
beta
(仅在新版支持):控制从 L2 损失切换到 L1 损失的点。reduction
:同上。
- KL 散度损失(Kullback-Leibler Divergence, KLDiv)
- 定义:
- 常用于:概率分布之间的差异度量。
- PyTorch 实现:
- 参数:
reduction
:同上。
是目标分布, 是预测分布。
- 自定义损失函数
- 定义:在 PyTorch 中,可以自定义损失函数,继承
nn.Module
并实现forward
方法。 - 示例:
3. 损失函数选择指南
任务类型 | 常用损失函数 |
回归任务 | MSELoss , SmoothL1Loss |
二分类任务 | BCELoss , BCEWithLogitsLoss |
多分类任务 | CrossEntropyLoss |
概率分布 | KLDivLoss |
自定义场景 | 自定义损失函数 |
4. 反向传播与优化示例
以下是完整的反向传播与优化过程示例:
PyTorch 的自动微分特性(
autograd
)使得反向传播过程高效且便捷,无需手动计算梯度。Part 8:优化器及其简介
1. 优化器及其原理
优化器在神经网络中负责更新参数,以最小化损失函数值。通过迭代调整参数,优化器帮助模型更接近目标值。不同的优化器使用不同的方法计算梯度并更新参数。
2. 常见的优化器
- 随机梯度下降(SGD)
- 原理:
- :参数
- :学习率
- :损失函数对参数的梯度
- 改进版本:
- 动量(Momentum): 引入动量缓解震荡问题,提高收敛速度:
- 带 Nesterov 动量: 对动量优化的进一步改进,进行“预更新”。
- PyTorch 实现:
- 参数:
lr
:学习率momentum
:动量因子(默认 0)weight_decay
:权重衰减(L2 正则化,默认 0)nesterov
:是否使用 Nesterov 动量(默认 False)
随机梯度下降使用当前批次的数据计算梯度,并基于梯度更新参数:
其中:
其中 是动量因子。
- 自适应梯度算法(Adagrad)
- 原理:
- 适用场景:
- PyTorch 实现:
- 参数:
lr
:学习率lr_decay
:学习率衰减(默认 0)weight_decay
:权重衰减(L2 正则化,默认 0)
Adagrad 会对每个参数单独适应学习率,较频繁更新的参数拥有较低的学习率:
其中 GG 是梯度平方累积矩阵, 是防止除零的小值。
适合稀疏特征场景,但在训练后期学习率可能会变得极小。
- RMSprop
- 原理:
- 适用场景:
- PyTorch 实现:
- 参数:
lr
:学习率alpha
:梯度平方的移动平均因子(默认 0.99)eps
:防止除零的小值(默认 1e-8)weight_decay
:权重衰减(默认 0)momentum
:动量因子(默认 0)
RMSprop 是对 Adagrad 的改进,通过对梯度平方的指数加权移动平均解决学习率衰减过快的问题:
其中 是梯度平方的移动平均。
适用于非平稳目标(如 RNN 任务)。
- Adam(Adaptive Moment Estimation)
- 原理:
- 动量方法记录梯度的一阶动量(均值)。
- RMSprop 记录梯度的二阶动量(方差)。
- 优点:
- 收敛速度快
- 默认参数设置对大多数任务效果良好
- PyTorch 实现:
- 参数:
lr
:学习率betas
:一阶和二阶动量的指数衰减率(默认(0.9, 0.999)
)eps
:防止除零的小值(默认 1e-8)weight_decay
:权重衰减(默认 0)
Adam 结合了 Momentum 和 RMSprop:
- AdamW
- 原理:
- PyTorch 实现:
- 参数:
AdamW 是 Adam 的改进版,将 L2 正则化(权重衰减)独立于动量更新计算,从而提高收敛性。
与 Adam 相同,区别在于权重衰减的实现方式。
- Adadelta
- 原理:
- PyTorch 实现:
- 参数:
lr
:学习率(默认 1.0)rho
:平方梯度移动平均因子(默认 0.9)eps
:防止除零的小值(默认 1e-6)weight_decay
:权重衰减(默认 0)
Adadelta 是对 Adagrad 的改进,不直接累积所有梯度平方,而是计算一个窗口内的移动平均值,从而克服学习率过小的问题。
- Nadam
- 原理:
- PyTorch 实现:
Nadam 是 Adam 的变体,结合了 Nesterov 动量的思想。
PyTorch 没有直接提供 Nadam,可以通过第三方库实现或自定义实现。
- LBFGS(Limited-memory BFGS)
- 原理:
- PyTorch 实现:
- 参数:
lr
:学习率max_iter
:每次调用step()
的最大迭代次数(默认 20)tolerance_grad
:梯度收敛容差tolerance_change
:参数收敛容差
LBFGS 是一种拟牛顿优化算法,适合小型数据集和高精度优化场景。
3. 优化器选择指南
优化器 | 特点 | 常用场景 |
SGD | 简单高效,但可能收敛慢 | 一般任务 |
SGD + Momentum | 提升收敛速度 | 深层网络 |
Adagrad | 对稀疏特征友好 | NLP 或稀疏特征场景 |
RMSprop | 稳定性强,适合非平稳目标 | RNN 等序列任务 |
Adam | 默认首选优化器,表现稳定 | 各类任务 |
AdamW | Adam 的改进版,适合正则化模型 | 深度学习任务 |
Adadelta | 不需要手动设置学习率 | 动态学习率场景 |
LBFGS | 高精度优化,但计算开销较大 | 小数据集 |
4. PyTorch 优化器完整示例
Part 9:现有网络模型的使用与修改
torchvision.models
模块介绍torchvision.models
是 PyTorch 提供的一个子模块,包含了预训练的图像分类模型、目标检测模型、语义分割模型和实例分割模型。这些模型在大型数据集(如 ImageNet、COCO)上预训练,并可用于迁移学习或直接推理。1. 常见模型分类
1.1 图像分类模型
- 用途:对输入图像进行类别预测。
- 常见模型:
- ResNet(
resnet18
,resnet50
等) - VGG(
vgg16
,vgg19
等) - Inception(
inception_v3
) - MobileNet(
mobilenet_v2
,mobilenet_v3
) - EfficientNet(
efficientnet_b0
,efficientnet_b7
) - Vision Transformer(
vit_b_16
)
1.2 目标检测模型
- 用途:在图像中识别目标位置并分类。
- 常见模型:
- Faster R-CNN(
fasterrcnn_resnet50_fpn
) - RetinaNet(
retinanet_resnet50_fpn
)
1.3 语义分割模型
- 用途:为每个像素分配类别标签。
- 常见模型:
- DeepLabV3(
deeplabv3_resnet50
) - FCN(
fcn_resnet50
)
1.4 实例分割模型
- 用途:结合目标检测和语义分割,为每个实例生成分割掩码。
- 常见模型:
- Mask R-CNN(
maskrcnn_resnet50_fpn
)
2. 模型加载与使用
2.1 加载预训练模型
torchvision.models
提供了方便的接口加载模型。可以选择加载预训练权重,也可以从随机初始化开始。示例:
注意:
- 从 PyTorch 1.12 开始,
pretrained=True
被替换为:
2.2 模型推理
模型输入通常是尺寸为
(batch_size, channels, height, width)
的 4D 张量,且需归一化(如 ImageNet 权重对应的标准化)。完整示例:
3. 常见模型的使用
3.1 ResNet(Residual Network)
- 特点:通过残差连接解决梯度消失问题,适合深层网络。
- 加载:
3.2 VGG
- 特点:多层卷积网络,具有较大的参数量。
- 加载:
3.3 EfficientNet
- 特点:参数效率高,性能强大。
- 加载:
4. 修改现有网络的方法
在实际任务中,我们通常需要对现有的模型进行修改以适应特定任务。
4.1 修改分类层
在迁移学习中,最常见的需求是修改分类模型的最后一层以适应新的类别数。
示例:修改 ResNet 的分类头:
示例:修改 VGG 的分类头:
4.2 冻结部分网络层
在迁移学习中,可以冻结预训练模型的某些层以保留其特征提取能力,仅训练最后几层。
示例:
4.3 添加自定义层
可以在预训练模型前后添加自定义的模块。
示例:在 ResNet 后添加一个新层:
5. 检测与分割模型的使用
5.1 目标检测(Faster R-CNN)
5.2 语义分割(DeepLabV3)
6. 保存与加载模型
保存模型
加载模型
总结
torchvision.models
提供了丰富的预训练模型资源,适用于图像分类、目标检测和分割任务。通过加载预训练模型并进行适当修改(如修改分类头、冻结层等),可以快速实现迁移学习。结合 PyTorch 的灵活性,我们还可以自由构建和扩展模型以满足特定需求。Part 10:如何在网络中添加层
在 PyTorch 中,可以通过以下几种方式在现有网络中添加新的层:
1. 修改现有模型结构
直接将模型的子模块提取为一个
nn.Sequential
,并插入新的层。示例:在 ResNet 的中间部分插入一个新层
2. 使用子类化 nn.Module
添加层
如果需要更复杂的调整,可以通过继承
nn.Module
构建一个新模型。示例:在 VGG 模型后添加一个 Dropout 层
3. 在 Forward 方法中动态添加层
如果新添加的层需要在特定逻辑下动态执行,可以直接在
forward
方法中实现。示例:在前向传播中添加一个新层
4. 使用 add_module
动态插入新层
通过
add_module
方法,可以动态插入新的层到现有模型的子模块中。示例:在 Sequential 模块中插入新层
注意事项
- 层的输入输出维度要匹配: 在插入新层时,需要确保新层的输入输出维度与上下文相符。可以通过打印中间层的张量形状进行调试。
- 迁移学习时的冻结层: 如果在预训练模型中添加新层,通常需要冻结原有层的参数以保留其特征提取能力。
- 重新初始化新层的参数: 如果添加了新层,需确保这些层的参数被合理初始化。PyTorch 的默认初始化通常够用,但可以手动调整:
Part 11:如何保存模型和加载模型
在 PyTorch 中,保存和加载模型是非常常见的操作。以下是详细的步骤和注意事项:
1. 保存网络模型
1.1 保存模型的参数(推荐方式)
最常用的方法是只保存模型的参数(
state_dict
),而不是整个模型结构。这样可以在加载时灵活地重新定义模型结构。示例:
- 保存内容:模型的权重和偏置等参数信息。
- 保存文件名:建议使用
.pth
或.pt
作为文件扩展名。
1.2 保存整个模型(包含结构和参数)
这种方法保存了模型的结构和参数,但加载时依赖于代码的版本。如果模型很复杂,推荐保存参数后手动定义模型结构。
示例:
2. 加载网络模型
2.1 加载模型参数(推荐方式)
在加载模型参数时,需要手动定义与保存时相同结构的模型,然后加载参数。
完整流程:
2.2 加载整个模型
如果保存了整个模型,可以直接加载模型而无需重新定义结构。
示例:
3. 保存和加载模型时的注意事项
3.1 模型训练和推理模式
- 模型在保存时不区分训练模式和推理模式(
train()
或eval()
)。
- 在加载模型后需要手动切换模式:
3.2 迁移学习或微调时的加载
如果要加载预训练模型并进行微调,可以只加载部分参数或忽略某些层。
示例:加载部分参数:
3.3 保存和加载优化器状态
在训练过程中,优化器的状态也需要保存和加载,以便恢复训练。
保存优化器状态:
加载优化器状态:
4. 使用 Checkpoint 保存和加载
4.1 保存 Checkpoint
Checkpoint 是保存训练中模型和优化器的状态,便于恢复训练。
示例:
4.2 加载 Checkpoint
加载 Checkpoint 可以恢复模型、优化器和训练进度。
示例:
5. 保存和加载到 GPU/CPU
5.1 保存时指定设备
模型保存时不依赖设备信息。如果需要加载到指定设备,可以根据需求调整。
5.2 加载到 CPU
即使模型原本在 GPU 上训练,也可以加载到 CPU:
5.3 加载到 GPU
如果要将模型加载到 GPU:
6. 总结
操作 | 方法 | 推荐场景 |
保存模型参数 | torch.save(model.state_dict(), ...) | 推荐,用于参数重载或迁移学习 |
保存整个模型 | torch.save(model, ...) | 简单模型,版本兼容性较低 |
保存优化器状态 | torch.save(optimizer.state_dict(), ...) | 恢复训练 |
加载模型参数 | model.load_state_dict(torch.load(...)) | 推荐,需要重新定义模型结构 |
加载整个模型 | torch.load(...) | 简单模型 |
使用 Checkpoint | 保存 state_dict 和训练状态 | 恢复训练 |
保存和加载模型时,推荐保存
state_dict
,这是一种灵活、可靠的方法,可以适应多种场景。结合优化器和训练状态的保存,可以实现高效的模型恢复和迁移学习。三、模型训练与验证完整套路
Part 1:完整模型训练套路
模型完整训练流程
训练一个深度学习模型通常包括以下步骤:
- 准备数据
- 定义模型
- 选择损失函数
- 选择优化器
- 训练循环
- 前向传播
- 计算损失
- 反向传播
- 更新权重
- 评估模型性能
- 保存模型
以下是完整的流程,配以 PyTorch 的代码示例和详细说明。
1. 准备数据
数据是模型训练的基础,需先加载并预处理数据。
步骤:
- 加载数据:使用
torchvision.datasets
或自定义数据集。
- 预处理数据:标准化、裁剪、数据增强。
- 构建数据加载器:使用
torch.utils.data.DataLoader
。
示例:
2. 定义模型
选择适合任务的模型,可以是内置模型(如 ResNet)或自定义模型。
示例:自定义一个简单的全连接网络:
3. 选择损失函数
根据任务选择合适的损失函数。
- 回归任务:
nn.MSELoss
- 二分类任务:
nn.BCELoss
或nn.BCEWithLogitsLoss
- 多分类任务:
nn.CrossEntropyLoss
示例:多分类任务:
4. 选择优化器
根据任务和模型,选择优化器并设置超参数。
示例:SGD 优化器:
5. 训练循环
训练循环是训练的核心部分,包含以下步骤:
- 切换模型到训练模式。
- 遍历数据集:批量加载训练数据。
- 前向传播:将数据输入模型,获取输出。
- 计算损失:比较预测值和真实值。
- 反向传播:计算梯度。
- 更新参数:用优化器更新模型参数。
- 记录与监控:保存中间结果以监控性能。
完整训练代码:
6. 模型评估
评估模型性能,通常在验证集或测试集上进行。评估时需切换模型到推理模式(
model.eval()
),并禁用梯度计算(torch.no_grad()
)。完整测试代码:
7. 保存模型
保存训练好的模型,便于后续加载和推理。
保存模型参数:
加载模型参数:
8. 迁移学习和微调(可选)
对于复杂任务,可以使用预训练模型并进行微调。
加载预训练模型并修改最后一层:
9. 完整代码示例
将以上步骤整合成完整代码:
Part 2:完整模型验证套路
1. 准备验证数据
模型验证需要一个与训练数据分离的验证数据集。在实际任务中,验证数据可以通过以下方式获取:
- 拆分数据集:从训练数据中划分出一部分作为验证集。
- 独立数据集:使用独立的验证集。
步骤:
- 加载验证数据。
- 数据预处理:确保与训练数据的处理方式一致。
示例代码:
2. 加载模型
验证时,需要加载已训练好的模型。
两种方法:
- 加载模型结构和参数:
- 定义与训练相同的模型结构。
- 加载参数。
- 加载整个模型:
- 如果在训练时保存了整个模型,直接加载。
示例代码:
3. 切换到评估模式
验证时,必须将模型切换到评估模式以关闭 Dropout 和 BatchNorm 的随机性。
代码:
4. 禁用梯度计算
验证阶段不需要更新模型参数,因此可以禁用梯度计算以节省内存和计算资源。
代码:
5. 执行验证
- 遍历验证集,计算每个批次的预测结果。
- 累积评价指标(如准确率、损失、F1 分数等)。
- 打印或记录验证结果。
完整验证代码:
6. 可视化验证结果(可选)
为了更直观地理解模型性能,可以对结果进行可视化,比如:
- 绘制混淆矩阵。
- 显示错误分类的样本。
混淆矩阵示例:
错误分类样本示例:
7. 保存验证结果
可以将验证的指标(如损失、准确率)和预测结果保存到文件中以供后续分析。
示例:
8. 完整验证流程代码
9. 总结
验证过程包括加载数据、加载模型、切换模式、计算指标和记录结果。完整的流程中可以加入混淆矩阵、错误分类可视化等分析步骤,以更全面地理解模型性能。
四、如何利用GPU进行训练
1. 检查 GPU 是否可用
在代码中,首先需要检查是否有可用的 GPU 设备,并动态切换到 GPU 或 CPU。
代码:
- 如果有 GPU,
device
将是cuda
,否则为cpu
。
- 训练代码中需将模型和数据移动到该设备。
2. 将模型转移到 GPU
在 PyTorch 中,模型和数据需要显式地转移到 GPU。
代码:
3. 将数据转移到 GPU
训练数据的张量也需要转移到 GPU。
代码:
4. 定义损失函数和优化器
损失函数和优化器可以保持不变,无需额外修改。它们会自动识别模型参数所在的设备。
代码:
5. 使用 GPU 进行训练
完整的训练过程包括以下步骤:
- 将数据和模型移动到 GPU。
- 在每个 epoch 和 batch 中进行前向传播、计算损失、反向传播和更新参数。
- 使用 GPU 加速的张量操作。
完整训练代码:
6. 评估模型时使用 GPU
在评估(验证或测试)时,也可以使用 GPU 加速。评估时需要关闭梯度计算。
评估代码:
7. 保存和加载模型(支持 GPU)
保存模型:
保存模型的参数后,无需关心设备信息。
代码:
加载模型到 GPU 或 CPU:
加载模型时可以指定目标设备:
- 加载到 GPU:
- 加载到 CPU:
8. 多 GPU 训练(可选)
对于多 GPU 训练,可以使用
torch.nn.DataParallel
或 torch.nn.parallel.DistributedDataParallel
。示例:使用 DataParallel:
9. 完整流程总结
- 检查 GPU:通过
torch.cuda.is_available()
检查是否支持 GPU。
- 将模型转移到 GPU:使用
model.to(device)
。
- 将数据转移到 GPU:使用
tensor.to(device)
。
- 定义损失函数和优化器:无需修改,直接使用。
- 训练和评估:在训练和验证循环中,将输入数据转移到 GPU,并确保模型运行在 GPU 上。
- 保存和加载模型:保存和加载时可以指定目标设备。
- 作者:小H狂炫香菜
- 链接:https://hjwvip.top/technology/pytorch-learning
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。