conv3x3s1_winograd64_transform_kernel_neon5的非NEON实现
这里面的变换的理论依据,我还是没有搞清楚,先闷着头继续看了,希望高人能指点一二,谢谢!
函数:void conv3x3s1_winograd64_transform_kernel_neon5(const Mat& kernel, Mat& kernel_tm, int inch, int outch)
处理流程:
- 用于winograd计算的kernel数据weight_3x3_winograd64_data分配data, 大小为outCh*inCh*64.定义了一个局部变量ktm。
- 遍历所有outCh和所有inCh,进行如下的矩阵运算:
- 计算tmp[8][3],公式如下,
,其中,k0、k1和k2是原始kernel当前outCh和inCh对应的第1、2和3行的向量。T标识转置。
- 计算kernel_tm0,kernel_tm0是扩展后的kernel当前outCh和inCh对应的8x8的矩阵,公式如下:
与1)整合在一起,即
- 局部变量kernel_tm2,我们当前只考虑非NEON的情况,大小为(outch/4 + outch%4)*64*(4*4*(inch/4) + 4*(inch%4))即(outch/4 + outch%4)*64*(4*inch)。使用weight_3x3_winograd64_data(数据内存大小为outCh*inCh*64)来填充kernel_tm2,填充的规则如下:
- 使用weight_3x3_winograd64_data的OutChannel为x的数据 来填充 局部变量kernel_tm2的channel为x/4(即4的倍数的channel),填充如下:
。总共填充了个元素。???不明白原理
- 对剩下的outCh%4进行赋值,填充如下:
其中,x为0到outCh%4.
- 把kernel_tm2赋给weight_3x3_winograd64_data。
- 返回
我不知道,???这些变换的依据是什么?ktm这个矩阵的值是如何得到的?希望有高人指点一二,非常感谢!!!