ViT代码学习及实战

原理学习在这里

代码学习

后续再补充

手势识别实战

最好创建一个虚拟环境conda create -n vitpy38 python=3.8

注意数据集结构,与yolov5不同

dataset
-class1
--img
-class2
-class3

改datapath等参数

    parser.add_argument('--num_classes', type=int, default=14)我的类别是14

这里path如果不理解什么是root的话,要反复增删改减尝试呜呜呜

KeyError: 'pre_logits.fc.weight'权重格式不对

加载的预训练权重文件本来就没有这个key,所以在删除检索的时候检索不到,所以报错,

把删除的代码删了就好了。

靠了,好怪,原来是输入数据集文件夹排列不对,把所有图片都认为是train类了,在尝试花数据集后才恍然大悟

flower_photos

无权重

有权重

为什么花数据集只用10轮效果就已经很好,而手势数据集却不行?

我认为:花数据集大小是手势的大约3倍,且只有5类,而手势有14类,每类的数据集很小,所以效果差。

我的数据集只有14类,但是我的num_classes设置为14时,报错下面内容,我又发现我改为15时,正常运行File "/root/autodl-tmp/vit/utils.py", line 148, in train_one_epoch accu_loss.item() / (step + 1), RuntimeError: CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING=1 Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.

发现是因为有不显示的隐藏文件,删了就好了

手势识别

有权重50轮

有权重100轮,改进不大

改进点说明

  1. 优化器替换

    • 将 SGD 替换为 AdamW,更适合 Transformer 类模型。

    • 调整 weight_decay 为 0.05,增强正则化效果。

  2. 学习率调度

    • 添加了 5 个 epoch 的线性预热阶段,避免训练初期不稳定。

    • 保留了原有的余弦退火机制,并整合了预热逻辑。

组件 原始配置 改进配置
优化器 SGD(lr=args.lr, momentum=0.9) AdamW(lr=3e-4, weight_decay=0.05)
学习率曲线 纯余弦衰减 前5个epoch线性增长 + 后续余弦衰减
权重衰减 5e-5 0.05(增大正则化强度)
预热机制 内置在lambda函数中

有权重100轮batch_size=8+AdamW+退火

只提升了一点,效果依然不是很好,估计还是数据集太小了

下面是尝试过的失败记录