手势识别模型训练

本周任务为通过提供的手势识别数据库训练对应的识别模型。训练代码使用的是SDK中给到的代码。代码基于的是yolo官方的训练代码。因为版本比较老,而且为了后续操作(模型转换等)作了针对性的优化,因此很多地方都需要深入理解才能够有针对性地对输入进行调整,以达到训练新模型的目标。

1. 预训练模型的问题

由于最初没有意识到代码经过了针对性修改的问题,对yolo模型的结构也不是很了解,甚至没有测试SDK自带的模型(只是用自带模型跑了个detect),因此走了很多弯路。

1.1 yolov5的版本问题

代码支持的是yolov5。但是yolov5内部也有很多版本,从release1到release7,模型支持的训练算法并不是通用的。从官网下载的.pt模型在SDK的代码里全部不能使用。release5之前(包括)的代码会报错:模型结构不对,缺少很多层的值,这一点在后面会详细记录。release5之后的模型会显示缺少SPPF类。在查阅资料后发现,该类是新添加的空间金字塔池化结构(Spatial Pyramid Pooling-Fast),旨在:1.避免图像缩放、裁减等操作导致的图像失真问题;2.解决CNN对图像特征重复提取的的问题。其大大提高了产生候选框 的速度,也节约了计算成本。当时直接在代码中添加SPPF类的代码,但是SDK中的代码不支持该该类,会报其他错误。因此只好尝试release5之前的模型。但是早期模型也会报错。

1.2 assertion error

代码中添加了对模型输出层的检测:

if c1 > 12:
   assert c1%32 == 0
   assert c2%32 == 0

目前推测的原因是要保证模型结构适用于后面的一些操作。这导致了低版本的模型也无法运行。只能运行SDK自带的预训练模型。

1.3 nc无法被检测到

解决了上述问题之后,还是会出现nc无法被检测到的问题:

nc = 1 if single_cls else int(data_dict['nc'])

nc是number of class,即训练需要分出的类的数量。debug发现data_dict中没有nc。最初想了很多办法都没有解决,后面找到了一个有效的方法:

 nc = 1 if single_cls else len(data_dict['names'])

即统计数据库描述文件中分类的数量。
但是后面了解了问题的本质之后,发现其实只需要在数据库描述文件中直接加一行nc的值就可以了。这样data_dict['nc']就能被检测到了。

解决上述问题后又出现了mlc的问题:

mlc = np.concatenate(dataset.labels, 0)[:, 0].max()  # max label class

最初给nc设置的值是1,并且将描述文件中其他name都注释掉了,仅仅保留person一个name,即希望先完成对人的检测的训练。但是这样会报错mlc>nc。经过研究后发现无论怎么调整代码都无法解决该问题。后面根据该条的注释max label class,猜测会不会是标签处理问题,便打开了一个标签,恍然大悟:

0 0.579790775 0.3148933 0.13299085 0.110474
19 0.549479 0.523438 0.526042 0.640625

原来每个标签都有两行,第一行对应的是手势的标签,第二行是person的标签。即每张图既标记了手势, 又标记了人体。因此数据库描述文件只能保留全部class name,且nc只能设为20。更改之后,报错消失。

1.4 模型结构问题

在解决上述问题后,还是会出现问题,报错模型缺少很多层的值(约70个)。在和老师讨论之后发现该问题没法解决,因为这涉及到很多代码的更改。于是只能使用SDK中给的预训练模型。但是用预训练模型还是会出现该问题。在继续搜寻了很多资料后发现,是模型加载的问题:

model.load_state_dict(state_dict, strict=True)

strict默认是True,这时候就需要严格按照模型中参数的Key值来加载参数,如果增删了模型的结构层,或者改变了原始层中的参数,加载就会报错。

相反地,如果设置strict为Flase,就可以只加载具有相同名称的参数层,对于修改的模型结构层进行随机赋值。这里需要注意的是,如果只是改变了原来层的参数,但是没有换名称,依然还是会报错。因为根据key值找到对应的层之后,进行赋值,发现参数不匹配。这时候可以将原来的层换个名称,再加载就不会报错了。

至此,训练代码成功运行。

附训练结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值