Estoy tratando de entender el papel de la función Flatten
en Keras. A continuación está mi código, que es una simple red de dos capas. Toma datos bidimensionales de forma (3, 2), y emite datos unidimensionales de forma (1, 4):
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
Esto imprime que y
tiene forma (1, 4). Sin embargo, si elimino la línea Flatten
, entonces se imprime que y
tiene forma (1, 3, 4).
No lo entiendo. Según mis conocimientos de redes neuronales, la función model.add(Dense(16, input_shape=(3, 2)))
crea una capa oculta totalmente conectada, con 16 nodos. Cada uno de estos nodos está conectado a cada uno de los 3x2 elementos de entrada. Por lo tanto, los 16 nodos en la salida de esta primera capa son ya "plana". Por lo tanto, la forma de salida de la primera capa debe ser (1, 16). Entonces, la segunda capa toma esto como entrada, y emite datos de forma (1, 4).
Entonces, si la salida de la primera capa ya es "plana" y de forma (1, 16), ¿por qué necesito aplanarla más?
si lees la documentación de Dense
aquí lo verás:
Dense(16, input_shape=(5,3))
daría como resultado una red Dense
con 3 entradas y 16 salidas que se aplicarían independientemente para cada uno de los 5 pasos. Así que si D(x)
transforma un vector de 3 dimensiones en un vector de 16 lo que obtendrás como salida de tu capa sería una secuencia de vectores: [D(x[0,:], D(x[1,:],..., D(x[4,:]]
con forma (5, 16)
. Para tener el comportamiento que especifica, primero puede Aplanar
su entrada a un vector de 15 d y luego aplicar Densidad
:
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: Como a algunos les costó entenderlo - aquí tienes una imagen explicativa:
lectura corta: Aplanar un tensor significa eliminar todas las dimensiones excepto una. Esto es exactamente lo que hace la capa Aplanar.
lectura larga:
Si tomamos en consideración el modelo original (con la capa Flatten) creado podemos obtener el siguiente resumen del modelo:
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
Para este resumen la siguiente imagen espero que proporcione un poco más de sentido sobre los tamaños de entrada y salida para cada capa.
La forma de salida para la capa Flatten como se puede leer es (None, 48)
. Aquí está la punta. Usted debe leer (1, 48)
o (2, 48)
o ... o (16, 48)
... o (32, 48)
, ...
De hecho, Ninguno
en esa posición significa cualquier tamaño de lote. En el caso de las entradas a recordar, la primera dimensión significa el tamaño del lote y la segunda el número de características de entrada.
El papel de la capa Flatten en Keras es super simple:
Una operación de aplanamiento en un tensor remodela el tensor para que tenga la forma que es igual al número de elementos contenidos en el tensor sin incluir la dimensión del lote.
Nota: He utilizado el método model.summary()
para proporcionar la forma de salida y los detalles de los parámetros.