KerasのFlatten
関数の役割を理解しようとしています。下記は私のコードで、単純な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の入力要素に接続されています。したがって、この第1層の出力の16個のノードは、すでに"flat"である。したがって、第1層の出力形状は(1, 16)となる。そして第2層はこれを入力とし、(1, 4)のデータを出力する。
では、第1層の出力がすでに(1, 16)の形状でquot;flat"なのであれば、なぜさらに平坦化する必要があるのでしょうか?
ここのDense
のドキュメントを読めばわかるだろう:
Dense(16, input_shape=(5,3))
は3つの入力と16の出力を持つ Dense
ネットワークになり、5つのステップのそれぞれに独立して適用されます。D(x)が3次元のベクトルを16次元のベクトルに変換する場合、そのレイヤーの出力は一連のベクトルになります:D(x[0,:], D(x[1,:],..., D(x[4,:]]
, shape (5, 16)
。指定した振る舞いをするためには、まず入力を15次元のベクトルに Flatten
してから 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')
EDIT: 理解するのに苦労している人もいるようなので、ここに説明画像がある:
short read:</sub>; gt;テンソルを平坦化するとは、1次元を除くすべての次元を削除することです。これはまさにFlattenレイヤーが行うことです。
long read:</sub>;
作成された元のモデル(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)、
(2、48)、...、
(16、48)...、
(32、48)` ...、...と読むべきだ。
実際には、この位置の None
は任意のバッチサイズを意味する。想起する入力について、最初の次元はバッチサイズを意味し、2番目の次元は入力特徴の数を意味する。
KerasにおけるFlattenレイヤーの役割は非常にシンプルだ:
テンソルの平坦化操作は、テンソルに含まれる要素数に等しい形状を持つようにテンソルを再形成する。
注: 出力形状とパラメータの詳細を提供するために model.summary()
メソッドを使用しました。
これが、Matrixを1つの配列に変換するFlattenの動作です。