当前位置: 首页 > article >正文

Vision Transfomer系列第二节---复现过程的Bugs记录

目录

  • 报错cuda error
  • loss始终下不去, attention矩阵size变成[b,b]
  • loss还是下不去
  • loss还还是下不去
  • 训练正常验证报cuda out of memory
  • 全数据训练时loss还还还是下不去
  • 可视化时预测类别全乱套
  • 总结

报错cuda error

原因:class2label生成过程中,遍历文件夹时候文件集内有无关文件,导致class2label变成了{‘daisy’: 0, ‘dandelion’: 1, ‘roses’: 2, ‘sunflowers’: 3, ‘tulips’: 5}
解决方法:加个非文件夹过滤(见dataset.py)

flowers_path = os.path.join(dataset_path, flower)
if os.path.isdir(flowers_path):
'''''''

loss始终下不去, attention矩阵size变成[b,b]

原因:我的mha输入要求是,[n, b, dim],实际输入是[b, n, dim],导致注意力查询错误
解决方法:调整维度顺序 (见model.py)

input = input.permute(1, 0, 2) #注意输入的维度顺序
input = self.blocks(input)  # 自注意力

loss还是下不去

原因:使用view和reshape同时交换维度和改变形状,而不是提前使用transpose和permute交换维度.
前者可以改变数据形状[3,5,8]->[3,5,2,4],但是不能交换维度[3,8,5],如果用前者强制指定新维度会改变数据内容,而后者只交换维度参考.
所以建议view和reshape时候要慎重,先用transpose和permute交换好维度,在改变形状.
reshape相当于contiguous().view),建议用reshape就行了
transpose交换2个维度和permute交换多个维度,建议用permute就行了
解决方法:修改(见model.py)

# [b,n_h,tgt_len,d_h] -> [b,tgt_len,embed_dim]
output = output.permute(0, 2, 1, 3).contiguous().view(tgt_len, bsz, embed_dim)

loss还还是下不去

原因:nn.CrossEntropyLoss()已经内置softmax,预测输出无需外接sigmod激活
解决方法:预测输出无需外接sigmod激活

训练正常验证报cuda out of memory

相关的原始代码:

# 训练
loss = self.model.loss(**instance)
loss_sum += loss
loss.backward()
self.optimizer.step()
self.optimizer.zero_grad()

# 验证
self.model.eval()
loss, correct_num = self.model.predict(**instance)
loss_sum += loss

原因:经过测试,发现:
1.在验证时加上loss.backward()可以解决这个问题,训练删掉loss.backward()则训练会复现这个问题.
2.在验证时加上with torch.no_grad()也可以解决这个问题
3.每迭代一次,显存增加一些,直到爆表
后来发现根本原因在于loss_sum += loss有没有加loss.detach(),经过查看参考资料1和[2]
(https://blog.csdn.net/qq_43391414/article/details/120571920),明白loss本身是神经网络计算图的一部分,而loss_sum作为一个迭代之外的变量,每次的累加都被记录到计算图中,经测试loss_sum是一个迭代内变量则不会引发这个问题.
detach将新建一个脱离计算图的新变量(requires_grad=false),loss_sum也不会进入计算图中影响显存.
解决方法:loss_sum += loss.detach()

全数据训练时loss还还还是下不去

原因:norm很重要,重要的blocks不光中间需要,blocks的输入输出侧都需要!!!
解决方法:输出层加个norm,(因为我的每个block是’norm’, ‘self_attn’, ‘norm’, ‘ffn’)(见model.py)

def extract_feature(self, input):
    # backbone + neck
    # 位置编码
    input = input + self.pos_embed.to(input)
    # 注意力机制
    input = input.permute(1, 0, 2) #注意输入的维度顺序
    input = self.blocks(input)  # 自注意力
    input = self.norm(input)
    input = input.permute(1, 0, 2)
    return input

可视化时预测类别全乱套

原因:python每次读取文件夹的顺序是随机的,而我训练和测试要读两次文件夹确定类别和索引的关系,所以需要排序
解决方法:对文件夹排序(见dataset,py),或者直接训练时候就生成一个固定的class_label文件

flowers = os.listdir(dataset_path)
flowers = sorted(flowers) # 必须排序,否在每一次顺序不一样训练测试类别就会乱

总结

1.transfomer模型的训练收敛速度确实很慢,一个分类就需要训练好很多个epoch (花分类45epochs左右)
2.所以说看懂原理和代码还是远远不够的,复现起来还是有很多细节需要注意的,确实是纸上学来终觉浅,绝知此事要躬行


http://www.kler.cn/a/229187.html

相关文章:

  • 【Uniapp-Vue3】uni-api交互反馈showToast的使用方法
  • C语言结构体漫谈:从平凡中见不平凡
  • lwip单网卡多ip的实现
  • 【Flink系列】4. Flink运行时架构
  • docker 部署 MantisBT
  • 机器人传动力系统介绍
  • BUUCTF-Real-[ThinkPHP]IN SQL INJECTION
  • 【cmu15445c++入门】(6)c++的迭代器
  • Opencc4j 开源中文繁简体使用介绍
  • 记一次页面接口502问题:“502 Bad Gateway”
  • Windows安装Nginx
  • Python脚本之操作Elasticsearch【一】
  • Spring Boot整合MyBatis Plus实现基本CRUD与高级功能
  • 前端JavaScript篇之如何判断一个对象是否属于某个类?
  • 【Qt Design】界面介绍
  • fastjson 导致的OOM
  • 多个总体均值的比较(一)
  • 快速上手极狐GitLab设计管理功能
  • 读千脑智能笔记05_千脑智能理论
  • 算法——二分查找算法
  • day38WEB攻防-通用漏洞XSS跨站绕过修复http_onlyCSP标签符号
  • 深入探索 MySQL 8 中的 JSON 类型:功能与应用
  • 当前小程序跳转另一个小程序
  • 【高质量精品】2024美赛B题22页word版高质量半成品论文+多版保奖思路+数据+前四问思路代码等(后续会更新)
  • 数据类型完整版
  • Day4.