Datawhale AI 夏令营CV项目学习笔记
项目链接
Task1 跑通baseline
7月12日
开始学习,稍微修改baseline代码后跑通
并且尝试将baseline中的预训练模型更改为ResNet50,训练50个epoch,在leadboard的得分能有0.7(后来发现只用了前1000张图片训练,没有改)
7月15日
尝试使用预训练模型ResNet101,用前8000张的小批量数据集进行训练。(总共有50多万张)
训练9个epoch,本地acc达到66%,预测结果能达到0.8
过程中遇到的问题:
本地最后一个cell一直卡住,后来发现可能是显存不够导致的(之前没释放)(感谢群里老师同学的答疑)
当时的解决方法是把训练好的模型和参数(.pt文件)传到Kaggle上加载后再跑最后一个cell。在本地的话先释放之前的显存再跑应该也没问题,还没尝试。
Task2 从baseline入门深度学习
7月16日
-
深度学习的相关基础知识已经有所了解,因此这一阶段的主要学习任务是理解代码、改进模型
-
今天尝试解决上面最后一个cell在本地跑不通的问题。按照claude的指示释放内存后还是不行,最后发现只要把num_workers设置为0就可以了,下面是claude给出的原因分析:
-
您的观察很有洞察力。将
num_workers
设置为 0 解决了问题,这确实指向了一个与多进程数据加载相关的问题。让我们分析一下可能的原因:-
资源竞争:
当num_workers
大于 0 时,PyTorch 会创建多个工作进程来并行加载数据。这些进程可能会与主进程竞争系统资源(如 CPU、内存、磁盘 I/O),导致整体性能下降,甚至出现死锁。 -
内存使用增加:
每个工作进程都需要自己的内存空间。当num_workers=4
时,实际上可能会使用比单进程多 4 倍左右的内存,这可能超出了您系统的可用内存。 -
进程间通信开销:
工作进程需要将加载的数据传输回主进程,这涉及进程间通信,可能会在某些情况下成为瓶颈。 -
系统限制:
某些操作系统或环境可能对并发进程数量有限制,或者在处理多进程时存在问题。 -
数据加载方式:
如果您的FFDIDataset
类在初始化或__getitem__
方法中有复杂的操作(如大文件读取、复杂的预处理),多进程可能会放大这些操作的影响。 -
死锁或竞态条件:
多进程环境更容易出现同步问题,可能导致死锁或其他异常行为。 -
CUDA 相关问题:
如果您的代码涉及 CUDA 操作,多进程和 CUDA 的交互有时会导致意外行为。
-
-
解决方案和建议:
-
使用
num_workers=0
:
如您所发现,这是最直接的解决方案。虽然可能会稍微降低数据加载速度,但能确保稳定性。 -
渐进式增加:
如果需要并行加载,可以尝试从 1 开始逐步增加num_workers
,找到性能和稳定性的平衡点。 -
优化数据集类:
检查您的FFDIDataset
类,确保其实现是高效的,尤其是__getitem__
方法。 -
监控资源使用:
使用系统监控工具观察 CPU、内存、磁盘 I/O 的使用情况,找出可能的瓶颈。 -
考虑使用
prefetch_factor
:
如果决定使用多个工作进程,可以尝试调整prefetch_factor
参数来控制每个工作进程预加载的样本数。 -
检查 CUDA 使用:
确保在数据加载阶段没有不必要的 CUDA 操作。
-
-
总的来说,将
num_workers
设置为 0 是一个有效的解决方案,特别是在本地开发和调试阶段。在生产环境或需要更高性能的场景中,您可以根据具体情况和系统资源来逐步优化多进程数据加载。
-
-
尝试使用efficientNet-b2作为预训练模型,前4000张图片训练9个epoch,可在本地达到75%的准确率,预测结果达0.9
可见当前阶段提供的预测task是偏简单的,leaderboard成堆的0.99、0.98也可作证这一点;相对地,本地测试集的accuracy才能较为准确地反应模型的准确度和泛化能力。
供的预测task是偏简单的,leaderboard成堆的0.99、0.98也可作证这一点;相对地,本地测试集的accuracy才能较为准确地反应模型的准确度和泛化能力。
7月19日
炼了一个晚上的丹,完整数据集准确度达到0.98
Task3 数据增强
7月20日
Part1 数据增强基础
目的是通过人工的方式增加训练数据的多样性,从而提高模型的泛化能力,使其在未见过的数据上表现的更好
需要主语数据增强的变换操作需要和目标任务的实际场景相符,否则可能引入无关的噪音
之前使用过的数据增强方法:
- 图像大小调整
- 水平、纵向翻转增强
- 转换成张量
- 归一化
Part2 常见数据增强方法
torchvision
数据增强方法主要位于torchvision.transforms和torchvision.transforms.v2中
各种几何变换
颜色变换
自动增强
谨慎使用,可控性较差
Part3进阶数据增强方法
Mixup
将两个不同的图像及其标签按alpha比例混合
优点:
- 增加数据多样性
- 减少过拟合
- 提高泛化能力
Cutmix
将图片的一部分剪切并粘贴到另一个图像上来创建新的学习样本
数据增强实操
对比度变换
猜测提高图片的对比度可以一定程度上提升模型对于真实图像和fake图像在细节上的辨识能力
import torchvision.transforms.v2 as transforms_v2
# 在dataloader中添加
transforms_v2.RandomAutocontrast(p=0.5), # 添加随机对比度增强
进行小数据集的对比测试
前5000张图片,训练15个epoch,对比有无对比度随机变换的情况
有对比度增强,最高测试集acc为64.94
无对比度增强,才跑了4个epoch就到67.2了(\笑哭)
透视变换
考虑图片中可能有不同的人脸角度,猜测随机透视变换是有效的数据增强手段
import torchvision.transforms.v2 as v2
# 在dataloader中添加
v2.RandomPerspective(
distortion_scale=0.5,
p=0.2,
interpolation=v2.InterpolationMode.BILINEAR
), # 添加随机透视变换
采用4000张图片的小数据集训练15个epoch
有透视变换,最高acc86.05
无透视变化:最高acc83.67
可见对于这个任务透视变换可以作为一个有效的数据增强手段
随机裁剪
考虑到随机裁剪可能有助于模型关注人脸的不同部分,可以模拟不同的人脸区域检测结果,进行尝试
import torchvision.transforms.v2 as v2
# 在dataloader中添加
v2.RandomResizedCrop(size=(224, 224), scale=(0.8, 1.0)), # 添加随机裁剪
4000张图片15个epoch
有数据增强:最高acc76.75
无数据增强:最高acc79.22
好像没啥用…
结论
不是所有的数据增强手段都是有利于模型的,需要根据具体任务分析后检验。
对于这个任务,小数据集下的训练模型表现不是十分的稳定,同样的参数两次训练出来的结果也是有可能有比较大的不同的,因此可以探索一种更准确更高效的数据增强效果验证的手段。