我修改了http://www.deeplearningbook.org/contents/convnets.html中的等式9.12,使MxN卷积内核居中。
为渐变提供以下表达式(暂时取信),假设1个输入和1个输出通道(为了简化):
dK(krow, kcol) = sum(G(row, col) * V(row+krow-M/2, col+kcol-N/2); row, col)
为了阅读上述内容,kk中kK的单个元素,kcol等于G乘以V的乘积的所有行和列的总和。注意G和V具有相同的尺寸。我们将定义在V外部导致零。
例如,在一个维度中,如果G是[abcd],V是[wxyz],M是3,那么第一个和是点(G,[0 wxy]),第二个和是点(G ,[wxyz]),第三个和是点(G,[xyz 0])。
ArrayFire有一个移位操作,但它执行循环移位,而不是零插入移位。此外,内核大小MxN通常较小,例如7x7,因此看起来更优化的实现只会在G和V中读取一次,并在内核上累积。
对于那个1D例子,我们将读取a和w,x并以[a * 0 aw ax]开头。然后我们读入b,y并添加[bw bx by]。然后读入c,z并添加[cx cy cz]。然后读入d并最后添加[dy dz d * 0]。
有没有直接的方法来计算ArrayFire中的dK?我不禁想到这是某种卷积,但我无法绕过卷积的样子。
答案 0 :(得分:2)
所以我需要创建大小为1 x(MxN)和(MxN)x 9的中间数组,其中后者的每一列都是原始的移位MxN窗口,其填充边框的大小为1,并且然后做一个矩阵乘法。
嗯,这需要太多的内存(有时候。)所以最后的解决方案是对输出3x3做一个gfor,对于每个循环,做一个unwrapped-once G和unwrapped-repeated V的点积。同意?