问题1 pooling层尺寸不一致
pooling层输出尺寸的计算公式如下:
当不能整除(输入或卷积核为奇数)时,pytorch默认是floor
,而caffe默认是ceil
,因此会出现onnx2caffe转换后输出尺寸比pytorch大1的情况。
解决办法:Slice层切割pooling层的输出
-
如果训练端发现该问题,可以pytorch的pooling设置为
ceil_mode=True
-
如果部署端发现该问题,不想重新修改模型retrain,则需要手动修改prototxt
- 首先,不能采用将padding置为0的方式,虽然能获得相同的size,但计算方式会发生变化,实测也是会出现掉点的。具体可以看下图;
- 从上图可以看到,可以将caffe ceil模式输出的结果的最后一行和最后一列切掉,从而获得与pytorch相同的输出;
- 最后,其实也可以修改caffe端pooling层为
floor
模式,但在当前情景下,caffe只是作为中转,还要转换到nnie模型,可能还会出现不匹配的情况,故这里不适用。 -
代价:无效输出增多
由于slice分割了pooling层的输出,故每次slice都会产生一个无用的tensor输出(最后一行/列),nnie每个模型seg的最大输出个数为16(hi_nnie.h中定义了
#define SVP_NNIE_MAX_OUTPUT_NUM 16
),故如果有些模型slice加的多,还得将这些无用输出合并成一个。 -
问题2 不支持relu6
-
解决办法:多个op组合进行替代
relu6即在relu的基础上,将最大值钳制到6,图像如下:
-
caffe和nnie没有现成的op支持,如非用relu6不可,可以用几个caffe支持的op组合进行代替,公式如下:
- 阈值判断用
threshold
,乘和偏置作可以用power
,tensor相加的操作可以用eltwise
,具体组合方式见下图
衍生问题:Power 层shift=1.0
无法正常加1