Toybrick

分割模型 精度下降太多了

Zen

中级会员

积分
201
楼主
发表于 2020-6-10 17:47:56    查看: 35550|回复: 10 | [复制链接]    打印 | 只看该作者
    分割模型作车道线检测,同样的条件(预处理一致,读取照片的接口一致(opencv)),在rknntoolkit-1.3.2得出来的效果与pytorch的差别很大,影响后续的判断了。并且rknn模型已经是未量化的模型,量化后效果更差。附图里面最左边是
未量化rknn模型的运行结果,右边两张是pytorch的结果。

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




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

jefferyzhang

版主

积分
13580
沙发
发表于 2020-6-10 17:54:32 | 只看该作者
rknn默认是fp16,
pytorch、tf默认是fp32,
这里会有一点精度差异。最终你都得用混合量化来提高精度,建议你直接走混合量化开始做
回复

使用道具 举报

Zen

中级会员

积分
201
板凳
 楼主| 发表于 2020-6-11 09:22:28 | 只看该作者
fp16和fp32的差异很难差这么大的,nvdia的新一代安培架构都通过fp16来实现加速了。感觉问题像是哪层卷积的实现出现问题。
pytorch的半精度很方便,model.half().cuda()即可。尝试了一下,完全不会像rknn这样跑偏这么多的。这种情况下搞混合量化转模型,不会方向搞错了么......
图是左边fp16,中间差值图(被放大过了),右边是fp32.

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




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

jefferyzhang

版主

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

你第一层的图看起来还是很正常的呀,这层的图为啥没线?
如果方便的话,你可以把原始模型、转换脚本、测试脚本一起打包发云盘给我们,
我发给NPU部门调试
回复

使用道具 举报

jefferyzhang

版主

积分
13580
5#
发表于 2020-6-11 09:37:45 | 只看该作者
Zen 发表于 2020-6-11 09:22
fp16和fp32的差异很难差这么大的,nvdia的新一代安培架构都通过fp16来实现加速了。感觉问题像是哪层卷积的 ...

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

调试技巧的话就是把所有层dump出来,对比原始tf模型输出,看下哪层精度降低很多,或者算错了。具体看下我们trouble shoot那份文档
回复

使用道具 举报

Zen

中级会员

积分
201
6#
 楼主| 发表于 2020-6-11 09:42:32 | 只看该作者
一楼的图 最左边是rknn的.
三楼的图 中间的那张是pytorch半精度和全精度图的差值(取绝对值)

嗯,我打包一下吧,提到redmine 对么?
回复

使用道具 举报

jefferyzhang

版主

积分
13580
7#
发表于 2020-6-11 10:00:14 | 只看该作者
Zen 发表于 2020-6-11 09:42
一楼的图 最左边是rknn的.
三楼的图 中间的那张是pytorch半精度和全精度图的差值(取绝对值)

你有redmine啊,那当然直接提交redmine咯,你们提交的bug比我们内部提交有用。。。
我们内部提交的bug他们都不一定有空看,客户提交的bug他们是必须要解决的。。
回复

使用道具 举报

Zen

中级会员

积分
201
8#
 楼主| 发表于 2020-6-11 10:29:49 | 只看该作者
好,有个群问了没人回......就跑论坛看看了

多谢答复,#答复很快好评
回复

使用道具 举报

Zen

中级会员

积分
201
9#
 楼主| 发表于 2020-6-11 15:13:10 | 只看该作者
自己解决了。你们的实现就是有问题的。

原版 :
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

注册会员

积分
120
10#
发表于 2020-6-29 12:17:40 | 只看该作者
Zen 发表于 2020-6-11 15:13
自己解决了。你们的实现就是有问题的。

原版 :

请问你是用什么模型做分割的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表