たたみ込みニューラルネットワーク(CNN)では、画像をたたみ込むときに、ドット積または要素ごとの乗算の合計を使用する演算ですか?


10

以下の例は、deeplearning.aiの講義から抜粋したもので、結果は要素ごとの(または「要素ごとの乗算」)の合計であることを示しています。赤い数字はフィルターの重みを表しています。

(11)+(10)+(11)+(00)+(11)+(10)+(01)+(00)+(11)=1+0+1+0+1+0+0+0+1=4

ここに画像の説明を入力してください

ただし、ほとんどのリソースでは、使用されているのはドット積であるとしています。

「…ニューロンの出力をとして表すことができます。ここで、はバイアス項です。つまり、bがバイアス項である場合、y = f(x * w)によって出力を計算できます。つまり、入力と重みのベクトルのドット積を実行し、バイアス項を追加してロジットを生成し、変換関数を適用することにより、出力を計算できます。」

ブドゥマ、ニキル; ロカスシオ、ニコラス。ディープラーニングの基礎:次世代のマシンインテリジェンスアルゴリズムの設計(p。8)。O'Reilly Media。キンドル版。

「5 * 5 * 3フィルターを取り、それを画像全体にスライドさせ、途中でフィルターと入力画像のチャンクの間の内積を取得します。取得されたすべての内積について、結果はスカラーです。」

https://medium.com/technologymadeeasy/the-best-explanation-of-convolutional-neural-networks-on-the-internet-fbb8b1ad5df8

「各ニューロンはいくつかの入力を受け取り、ドット積を実行し、オプションで非線形性に従います。」

http://cs231n.github.io/convolutional-networks/

「畳み込みの結果は、1つの大きな行列乗算np.dot(W_row、X_col)を実行することと同等になり、すべてのフィルターとすべての受容野の位置の間の内積を評価します。」

http://cs231n.github.io/convolutional-networks/

ただし、matricsのドット積の計算方法を調べたところ、ドット積は要素ごとの乗算の合計と同じではないようです。実際に使用される演算(要素ごとの乗算またはドット積?)と主な違いは何ですか?


1
ドット積は正確ではありません。Hadamard product選択した領域とたたみ込みカーネルの間の合計だと思います。
JP Zhang

そのドット積ですが、移動するマトリックス全体のパッチの合計を使用する代わりに、ドット積関数を使用できなかったため、すべての画像/マトリックスの周りでパッチ/ウィンドウを移動するさまざまなマトリックスをループ通過させる必要がある
Mr-Programs

回答:


13

CNNの特定のレイヤーには、通常3つの次元があります(高さ、幅、奥行きと呼びます)。畳み込みにより、新しい(または同じ)高さ、幅、奥行きの新しいレイヤーが作成されます。ただし、操作は高さ/幅と奥行きで異なる方法で実行され、これが混乱の原因だと思います。

最初に、入力行列の高さに対する畳み込み演算の様子を見てみましょう。このケースは、イメージに示されているとおりに実行され、2つの行列の要素ごとの乗算です

理論的には
二次元(離散)畳み込みは以下の式で計算されます。

C[メートル]=ΣあなたΣυ[メートル+あなた+υ]B[あなたυ]

CBCB

実際には
あなたは、パッケージの任意の数(私が使用しますと、上記の例をテストすることができscipyのダウンロードを):

import numpy as np
from scipy.signal import convolve2d

A = np.array([[1,1,1,0,0],[0,1,1,1,0],[0,0,1,1,1],[0,0,1,1,0],[0,1,1,0,0]])
B = np.array([[1,0,1],[0,1,0],[1,0,1]])
C = convolve2d(A, B, 'valid')
print(C)

上記のコードは以下を生成します:

[[4 3 4]
 [2 4 3]
 [2 3 4]]

これで、入力の深さの畳み込み演算は、同じ高さ/幅の各要素に同じ重みが乗算され、それらが合計されるため、実際にはドット積と見なすことができます。これは、1x1のたたみ込みの場合に最も明白です(通常、レイヤーのサイズを変更せずにレイヤーの深度を操作するために使用されます)。ただし、これは(数学的観点からの)2D畳み込みの一部ではなく、CNNで畳み込み層が行う処理です。


1:言われていること私が提供した情報源のほとんどは控えめに言っても誤解を招く説明があり、正しくないと思います。多くのソースがこの操作(これはCNNで最も重要な操作です)が間違っていることに気づいていませんでした。たたみ込みはスカラー間の積を合計し、2つのスカラー間の積はドット積とも呼ばれるという事実と関係があると思います
2:最初の参照は、たたみ込み層ではなく完全接続層を参照していると思います。その場合、FCレイヤーは前述のように内積を実行します。これを確認するための残りのコンテキストはありません。

tl; dr指定した画像は、操作の実行方法に関して100%正確ですが、これは全体像ではありません。CNNレイヤーには3つの次元があり、そのうち2つは図のように処理されます。私の提案は、たたみ込み層が入力の深さをどのように処理するかをチェックすることです(あなたが見ることができる最も単純なケースは1x1たたみ込みです)。


ご返信ありがとうございます。たたみ込み層が入力の深さをどのように処理するかを研究することについてのあなたの提案に従ってください-このリンクのたたみ込みデモのセクションを参照してください:cs231n.github.io/convolutional-networks。スプレッドシートで数値を計算しましたが、出力ボリュームに入る最終的な数値は、各フィルターと受容フィールドの要素ごとの乗算の合計(カラーボリュームごとに1つの数値になる)であり、次にバイアスとともに3つの数値が加算されます...
Ryan Chase

5
はい、私が指摘したかったのは、これは3次元に沿ったピクセルのベクトル(深さ、フィルターはそれをあなたが望むものと呼ぶ)と畳み込みカーネルのスカラー重みの間のドット積に等しいことです。
Djib2011

3

この演算は畳み込みと呼ばれ、要素ごとの乗算の合計を伴います。これは、MLの人々がテンソルと呼ぶ多次元行列のドット積と同じです。ループとして記述すると、次の擬似Pythonコードのようになります。

for i in 0:3:
  for j in 0:3:
    s = 0
    for k in 0:3:
      for l in 0:3:
        s += A[i+k,j+l]*C[k,l]
    Z[i,j] = s

ここで、Aは5x5入力行列、Cは3x3フィルター、Zは3x3出力行列です。

内積との微妙な違いは、通常、内積はベクトル全体にありますが、畳み込みでは、入力行列の移動サブセット(ウィンドウ)で内積を行うので、次のように記述して、最も内側の2つの入れ子を置き換えることができます。上記のコードのループ:

Z[i,j] = dot(A[i:i+2,j:j+2],C)

0

重要なのは、フィルターが画像の一部(「受容野」)を畳み込んでいるとき、フィルターの各数値(つまり、各重み)が最初にベクトル形式にフラット化されるということです。同様に、画像のピクセルもベクトル形式にフラット化されます。次に、ドット積が計算されます。これは、要素ごとの(要素ごとの)乗算の合計を求めるのとまったく同じです。

もちろん、以下の画像に示すように、これらのフラット化されたベクトルをマトリックス形式で結合することもできます。この場合、真の行列乗算を使用できますが、各畳み込みからのイメージピクセルの平坦化と重みフィルターも先駆けであることに注意することが重要です。

ここに画像の説明を入力してください

画像クレジット:PhDなしのTensorFlowとディープラーニング、パート1(Google Cloud Next '17)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.