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

报错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.所以说看懂原理和代码还是远远不够的,复现起来还是有很多细节需要注意的,确实是纸上学来终觉浅,绝知此事要躬行

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Attention is all you

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值