Kerasでの "Flatten"の役割は何ですか?


108

FlattenKeras における関数の役割を理解しようとしています。以下は、単純な2層ネットワークである私のコードです。形状(3、2)の2次元データを取り込み、形状(1、4)の1次元データを出力します。

model = Sequential()
model.add(Dense(16, input_shape=(3, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

x = np.array([[[1, 2], [3, 4], [5, 6]]])

y = model.predict(x)

print y.shape

これyは、形状(1、4)の出力です。ただし、Flatten線を削除すると、y形(1、3、4)のものが印刷されます。

分かりません。ニューラルネットワークについての私の理解から、このmodel.add(Dense(16, input_shape=(3, 2)))関数は、16ノードの完全に接続された非表示のレイヤーを作成しています。これらの各ノードは、3x2入力要素のそれぞれに接続されています。したがって、この最初のレイヤーの出力にある16個のノードはすでに「フラット」です。したがって、最初のレイヤーの出力形状は(1、16)になります。そして、第2層はこれを入力として、形状(1、4)のデータを出力する。

では、最初のレイヤーの出力がすでに「フラット」で形状(1、16)である場合、なぜさらにフラットにする必要があるのでしょうか。

回答:


122

のKerasドキュメントエントリを読むと、Dense次の呼び出しが表示されます。

Dense(16, input_shape=(5,3))

Dense5つのステップのそれぞれに個別に適用される3つの入力と16の出力を持つネットワークになります。したがって、D(x)3次元ベクトルを16次元ベクトルに変換する場合、レイヤーからの出力として得られるのは[D(x[0,:]), D(x[1,:]),..., D(x[4,:])]、Shapeを使用した一連のベクトルになります(5, 16)。指定した動作を実現するために、まずFlatten15-dベクトルへの入力を行い、次に適用することができますDense

model = Sequential()
model.add(Flatten(input_shape=(3, 2)))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

編集: 一部の人々が理解するのに苦労したように-ここに説明の画像があります:

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


ご説明ありがとうございます。ただ明確にするために:でDense(16, input_shape=(5,3)、各16のセットからニューロンを出力し(これらのニューロンの5つのセットすべて)、すべての(3 x 5 = 15)入力ニューロンに接続しますか?または、最初の16個のセットの各ニューロンは5個の入力ニューロンの最初のセットの3個のニューロンにのみ接続され、次に2番目の16個のセットの各ニューロンは5個の入力の2番目のセットの3個のニューロンにのみ接続されますニューロンなど...私はそれがどれなのか混乱しています!
Karnivaurus

1
3つのニューロンを取得する1つの高密度レイヤーがあり、3つのニューロンの5つのセットのそれぞれに適用される出力16があります。
MarcinMożejko2017

1
ああ。私がしようとしているのは、5つのカラーピクセルのリストを入力として受け取り、完全に接続されたレイヤーを通過させることです。つまりinput_shape=(5,3)、5つのピクセルがあり、各ピクセルには3つのチャネル(R、G、B)があります。しかし、あなたが言っていることに応じて、各チャネルは個別に処理されますが、私は3つすべてのチャネルが最初の層のすべてのニューロンによって処理されることを望みます。ではFlatten、最初にレイヤーをすぐに適用すると、必要なものが得られますか?
Karnivaurus 2017

8
少し描画した場合と描画しないFlatten場合が理解に役立つ場合があります。
Xvolks 2017

2
OK、みんな-私はあなたに画像を提供しました。これで、反対票を削除できます。
MarcinMożejko2017


35

短い読み:

テンソルの平坦化とは、1つを除いてすべての次元を削除することを意味します。これがまさにFlattenレイヤーが行うことです。

長い読み:

考慮して作成された(フラット化レイヤーを含む)元のモデルを使用すると、次のモデルの要約を取得できます。

Layer (type)                 Output Shape              Param #   
=================================================================
D16 (Dense)                  (None, 3, 16)             48        
_________________________________________________________________
A (Activation)               (None, 3, 16)             0         
_________________________________________________________________
F (Flatten)                  (None, 48)                0         
_________________________________________________________________
D4 (Dense)                   (None, 4)                 196       
=================================================================
Total params: 244
Trainable params: 244
Non-trainable params: 0

この要約では、次の画像で、各レイヤーの入力サイズと出力サイズの意味を理解できれば幸いです。

読み取れるFlattenレイヤーの出力形状は(None, 48)です。ここにヒントがあります。あなたはそれを読むべきです(1, 48)or (2, 48)または...または(16, 48) ... or(32, 48)、...

実際には、 Noneその位置にあるということは、任意のバッチサイズを意味します。入力を呼び出す場合、最初の次元はバッチサイズを意味し、2番目の次元は入力フィーチャの数を意味します。

の役割 フラット化レイヤーKerasは非常に簡単です:

テンソルの平坦化操作は、テンソルを再形成して、バッチディメンションを含まないテンソルに含まれる要素の数と等しい形状にします。

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


注:model.summary()メソッドを使用して、出力の形状とパラメーターの詳細を提供しました。


1
非常に洞察に富んだ図。
Shrey Joshi

1
図をありがとう。それは私に明確な絵を与えます。
スルタンアフメドサゴール

0

Flattenは、多次元テンソル(通常は入力テンソル)をシリアル化する方法を明示します。これにより、(平坦化された)入力テンソルと最初の非表示レイヤー間のマッピングが可能になります。最初の非表示層が「密」である場合、(シリアル化された)入力テンソルの各要素は非表示配列の各要素に接続されます。Flattenを使用しない場合、入力テンソルが最初の非表示レイヤーにマッピングされる方法があいまいになります。


0

私は最近これに遭遇しました、それは確かに私が理解するのに役立ちました: https //www.cs.ryerson.ca/~aharley/vis/conv/

したがって、入力、Conv2D、MaxPooling2Dなどがあり、フラット化レイヤーは最後にあり、それらがどのように形成され、最終的な分類(0〜9)を定義する方法を正確に示します。

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