arrayfire - 在ArrayFire中实现卷积神经网络反向传播(梯度计算)

标签 arrayfire

我修改了 http://www.deeplearningbook.org/contents/convnets.html 中的方程 9.12将 MxN 卷积核居中。

这给出了以下梯度表达式(暂时相信它),假设有 1 个输入和 1 个输出 channel (为了简化):

dK(krow, kcol) = sum(G(row, col) * V(row+krow-M/2, col+kcol-N/2); row, col)

为了阅读上面的内容,dK 在 krow、kcol 处的单个元素等于 G 乘以移位的 V 的乘积的所有行和列的总和。注意 G 和 V 具有相同的维度。我们将定义超出 V 的结果为零。

例如,在一维中,如果 G 为 [a b c d],V 为 [w x y z],M 为 3,则第一个和为 dot(G, [0 w x y]),第二个和为 dot(G ,[w x y z]),第三个和是点(G,[x y z 0])。

ArrayFire有移位操作,但它是循环移位,而不是零插入移位。此外,内核大小 MxN 通常很小,例如 7x7,因此似乎更优化的实现仅在 G 和 V 中读取一次,并在内核上累积。

对于该一维示例,我们将读入 a 和 w,x 并从 [a*0 aw ax] 开始。然后我们读入 b,y 并添加 [bw bx by]。然后读入c,z并添加[cx cy cz]。然后读入d,最后加上[dy dz d*0]。

在 ArrayFire 中是否有直接计算 dK 的方法?我忍不住认为这是某种卷积,但我一直无法理解卷积会是什么样子。

最佳答案

啊,原来如此。对于 3x3 dK 数组,我使用 unwrap 将 MxN 输入数组转换为两个 MxN 列向量。然后我对两个列向量的移位子集进行 9 点积。不,这不起作用,因为移位是二维的。

因此,我需要创建大小为 1 x (MxN) 和 (MxN) x 9 的中间数组,其中后者的每一列都是原始窗口的移位 MxN 窗口,其填充边框大小为 0,并且然后进行矩阵乘法。

嗯,这需要太多的内存(有时)。所以最终的解决方案是对输出 3x3 执行 gfor,并且对于每个循环,对一次展开的 G 和重复展开的 V 进行点积。

同意吗?

关于arrayfire - 在ArrayFire中实现卷积神经网络反向传播(梯度计算),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36392677/

相关文章:

c++ - 如何在 arrayfire 中使用翻转和转置来避免 memcpy?

c++ - ArrayFire中统一后端的使用

rust - 如何将 Arrayfire 数组转换为 Rust Vec?

c++ - 由于头文件中的语法错误导致编译错误

rust - 使用Arrayfire设置索引值

c++ - 手电筒 (arrayfire) 中的 torch.squeeze 和 torch.unsqueeze 等价物

c++ - 交替错误: “Invalid dimension for argument 0”

search - ArrayFire帧搜索算法崩溃

c++ - ArrayFire:具有从主函数调用的 OpenCL 内核的函数