Toybrick

标题: 分割模型 精度下降太多了 [打印本页]

作者: Zen    时间: 2020-6-10 17:47
标题: 分割模型 精度下降太多了
    分割模型作车道线检测,同样的条件(预处理一致,读取照片的接口一致(opencv)),在rknntoolkit-1.3.2得出来的效果与pytorch的差别很大,影响后续的判断了。并且rknn模型已经是未量化的模型,量化后效果更差。附图里面最左边是
未量化rknn模型的运行结果,右边两张是pytorch的结果。

    模型主要用到的 op 有 Conv2d、BatchNorm2d、relu、ConvTranspose2d 、dilated_conv2d 。是不是目前版本对
ConvTranspose2d 的实现还有点问题,导致精度下降太厉害了?


[attach]1177[/attach]


作者: jefferyzhang    时间: 2020-6-10 17:54
rknn默认是fp16,
pytorch、tf默认是fp32,
这里会有一点精度差异。最终你都得用混合量化来提高精度,建议你直接走混合量化开始做
作者: Zen    时间: 2020-6-11 09:22
fp16和fp32的差异很难差这么大的,nvdia的新一代安培架构都通过fp16来实现加速了。感觉问题像是哪层卷积的实现出现问题。
pytorch的半精度很方便,model.half().cuda()即可。尝试了一下,完全不会像rknn这样跑偏这么多的。这种情况下搞混合量化转模型,不会方向搞错了么......
图是左边fp16,中间差值图(被放大过了),右边是fp32.

感觉更像是某一些卷积的实现有问题的,你们有做过单独的评估吗,像upsample 的话用那种op 会相对好些的?整体op 有哪些掉精度太厉害的?

[attach]1179[/attach]



作者: jefferyzhang    时间: 2020-6-11 09:35
Zen 发表于 2020-6-11 09:22
fp16和fp32的差异很难差这么大的,nvdia的新一代安培架构都通过fp16来实现加速了。感觉问题像是哪层卷积的 ...

你第一层的图看起来还是很正常的呀,这层的图为啥没线?
如果方便的话,你可以把原始模型、转换脚本、测试脚本一起打包发云盘给我们,
我发给NPU部门调试
作者: jefferyzhang    时间: 2020-6-11 09:37
Zen 发表于 2020-6-11 09:22
fp16和fp32的差异很难差这么大的,nvdia的新一代安培架构都通过fp16来实现加速了。感觉问题像是哪层卷积的 ...

混合量化可以把某些层直接搞成fp32的,你直接在fp16调的话就把所有结果打印出来对比欧式距离,不要看这个后处理后的图,没啥意义。对比输出才知道结果是不是对的。

调试技巧的话就是把所有层dump出来,对比原始tf模型输出,看下哪层精度降低很多,或者算错了。具体看下我们trouble shoot那份文档
作者: Zen    时间: 2020-6-11 09:42
一楼的图 最左边是rknn的.
三楼的图 中间的那张是pytorch半精度和全精度图的差值(取绝对值)

嗯,我打包一下吧,提到redmine 对么?
作者: jefferyzhang    时间: 2020-6-11 10:00
Zen 发表于 2020-6-11 09:42
一楼的图 最左边是rknn的.
三楼的图 中间的那张是pytorch半精度和全精度图的差值(取绝对值)

你有redmine啊,那当然直接提交redmine咯,你们提交的bug比我们内部提交有用。。。
我们内部提交的bug他们都不一定有空看,客户提交的bug他们是必须要解决的。。
作者: Zen    时间: 2020-6-11 10:29
好,有个群问了没人回......就跑论坛看看了

多谢答复,#答复很快好评
作者: Zen    时间: 2020-6-11 15:13
自己解决了。你们的实现就是有问题的。

原版 :
self.conv3x1_2 = nn.Conv2d(chann, chann, (3, 1), stride=1, padding=(1*dilated,0), bias=True, dilation = (dilated, dilated))
self.conv1x3_2 = nn.Conv2d(chann, chann, (1, 3), stride=1, padding=(0,1*dilated), bias=True, dilation = (dilated, dilated))

修改完:
self.conv3x1_2 = nn.Conv2d(chann, chann, (3, 3), stride=1, padding=(1*dilated,1*dilated), bias=True, dilation = (dilated, dilated))
self.conv1x3_2 = nn.Conv2d(chann, chann, (3, 3), stride=1, padding=(1*dilated,1*dilated), bias=True, dilation = (dilated, dilated))

修改后将权重按逻辑位置放回,得到正确的结果。(与torch版本完全一致)

我猜测你们底层在实现不对称kernel的时候,会潜在补齐,更新为 对称的kernel ,如这里的 (1, 3), (3, 1)被更新为 (3, 3).
但是这里你们补齐的时候出现了问题,按逻辑上应该上 1 -》3 后 原数据应该放置于3的中间通道。但是不知道为什么你们在这一步上
的实现出bug了。而且我试了一下,把数据放在其他两个通道上都试运行一下,均无法跑出1楼图里的效果。你们可以自己看看具体是啥问题了。

作者: wujialiang    时间: 2020-6-29 12:17
Zen 发表于 2020-6-11 15:13
自己解决了。你们的实现就是有问题的。

原版 :

请问你是用什么模型做分割的?
作者: Zen    时间: 2020-7-8 18:05
wujialiang 发表于 2020-6-29 12:17
请问你是用什么模型做分割的?

普通的unet就可以了
细长型分割的用scnn、erfnet




欢迎光临 Toybrick (http://t.rock-chips.com/) Powered by Discuz! X3.3