2

MxN 畳み込みカーネルを中央に配置するために、 http: //www.deeplearningbook.org/contents/convnets.html の式 9.12 を変更しました。

1 つの入力チャネルと 1 つの出力チャネルを (単純化するために) 仮定すると、勾配の次の式が得られます (今のところは信じてください)。

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

上記を読むと、krow、kcol での dK の 1 つの要素は、G とシフトされた V の積のすべての行と列の合計に等しくなります。G と V は同じ次元を持つことに注意してください。V の外に出てゼロになるように定義します。

たとえば、1 つの次元で、G が [abcd]、V が [wxyz]、M が 3 の場合、最初の合計は dot (G, [0 wxy])、2 番目の合計は dot (G, [wxyz] です。 ])、3 番目の和は dot (G, [xyz 0]) です。

ArrayFire にはシフト操作がありますが、挿入ゼロのシフトではなく循環シフトを行います。また、カーネル サイズ MxN は通常小さい (たとえば 7x7) ため、より最適な実装では G と V を 1 回だけ読み取り、カーネル全体に累積するように思われます。

その 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 を計算する直接的な方法はありますか? これはある種の畳み込みだと思わざるを得ませんが、畳み込みがどのようになるかについて頭を悩ませることができませんでした。

4

1 に答える 1

2

そうそう。3x3 dK 配列の場合、unwrap を使用して MxN 入力配列を 2 つの MxN 列ベクトルに変換します。次に、2 つの列ベクトルのシフトされたサブセットの内積を 9 つ計算します。いいえ、シフトは 2 次元であるため、機能しません。

したがって、サイズが 1 x (MxN) および (MxN) x 9 の中間配列を作成する必要があります。後者の各列は、サイズ 1 のゼロのパッド境界を持つオリジナルのシフトされた MxN ウィンドウです。行列乗算。

うーん、それにはメモリが多すぎる場合があります (場合によっては)。したがって、最終的な解決策は、出力 3x3 に対して gfor を実行し、ループごとに、1 回アンラップされた G とアンラップされた繰り返し V のドット積を実行することです。

同意しましたか?

于 2016-04-05T17:52:46.960 に答える