我们可以使用winograd算法来加速卷积的计算。在“卷积神经网络的快速算法”论文中,我们得到以下公式:
例如,F(6x6,3x3)表示该卷积内核为3x3,out为6x6。如果g和d是浮点类型,那么我们可以轻松获得变换矩阵A G B:
static const float A[8*6] = {
1 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f,
1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f,
1 * 1.f, -1 * 1.f, 1 * 1.f, -1 * 1.f, 1 * 1.f, -1 * 1.f,
1 * 1.f, 2 * 1.f, 4 * 1.f, 8 * 1.f, 16 * 1.f, 32 * 1.f,
1 * 1.f, -2 * 1.f, 4 * 1.f, -8 * 1.f, 16 * 1.f, -32 * 1.f,
1 * 1.f, 0.5*1.f, 0.25*1.f, 0.125*1.f, 0.0625*1.f, 0.03125*1.f,
1 * 1.f, -0.5*1.f, 0.25*1.f, -0.125*1.f, 0.0625*1.f, -0.03125*1.f,
0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 1 * 1.f,
};
static const float G[8*3] = {
1.f, 0.f , 0.f ,
-2.f / 9 , -2.f / 9 , -2.f / 9,
-2.f / 9 , 2.f / 9 , -2.f / 9,
1.f / 90 , 1.f / 45 , 2.f / 45,
1.f / 90 , -1.f / 45 , 2.f / 45,
32.f / 45, 16.f / 45, 8.f / 45,
32.f / 45, -16.f / 45, 8.f / 45,
0.f , 0.f , 1.f ,
};
static const float B[8*8] = {
1 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f,
0 * 1.f, 1 * 1.f, -1 * 1.f, 0.5*1.f, -0.5*1.f, 2 * 1.f, -2 * 1.f, -1 * 1.f,
-5.25*1.f, 1 * 1.f, 1 * 1.f, 0.25*1.f, 0.25*1.f, 4 * 1.f, 4 * 1.f, 0 * 1.f,
0 * 1.f, -4.25*1.f, 4.25*1.f, -2.5*1.f, 2.5*1.f, -2.5*1.f, 2.5*1.f, 5.25*1.f,
5.25*1.f, -4.25*1.f, -4.25*1.f, -1.25*1.f, -1.25*1.f, -5 * 1.f, -5 * 1.f, 0 * 1.f,
0 * 1.f, 1 * 1.f, -1 * 1.f, 2 * 1.f, -2 * 1.f, 0.5*1.f, -0.5*1.f, -5.25*1.f,
-1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 1 * 1.f, 0 * 1.f,
0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 0 * 1.f, 1 * 1.f,
};
在这种情况下,所有类型的F(6x6,3x3)运算都为浮点型。
但是如果g和d是int类型的,我们希望所有F(6x6,3x3)运算的类型都是int。有人知道A G B变换矩阵的值是多少吗?或如何实现此定点winograd?非常感谢!