Qual è il ruolo di "Flatten" in Keras?


108

Sto cercando di capire il ruolo della Flattenfunzione in Keras. Di seguito è riportato il mio codice, che è una semplice rete a due strati. Accetta dati bidimensionali di forma (3, 2) e genera dati monodimensionali di 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

Questo stampa che yha forma (1, 4). Tuttavia, se rimuovo la Flattenlinea, viene stampata la yforma (1, 3, 4).

Non lo capisco. Dalla mia comprensione delle reti neurali, la model.add(Dense(16, input_shape=(3, 2)))funzione sta creando uno strato nascosto completamente connesso, con 16 nodi. Ciascuno di questi nodi è collegato a ciascuno degli elementi di input 3x2. Pertanto, i 16 nodi all'uscita di questo primo strato sono già "piatti". Quindi, la forma di output del primo livello dovrebbe essere (1, 16). Quindi, il secondo livello lo prende come input e fornisce dati di forma (1, 4).

Quindi, se l'output del primo strato è già "piatto" e di forma (1, 16), perché devo appiattirlo ulteriormente?

Risposte:


123

Se leggi la voce della documentazione di Keras per Dense, vedrai che questa chiamata:

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

risulterebbe in una Denserete con 3 ingressi e 16 uscite che verrebbero applicate indipendentemente per ciascuno dei 5 passaggi. Quindi, se D(x)trasforma un vettore tridimensionale in un vettore 16-d, ciò che otterrai come output dal tuo livello sarebbe una sequenza di vettori: [D(x[0,:]), D(x[1,:]),..., D(x[4,:])]con forma (5, 16). Per avere il comportamento che specifichi puoi prima Flatteninserire il tuo input in un vettore 15-d e poi applicare 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: come alcune persone hanno faticato a capire, ecco un'immagine esplicativa:

inserisci qui la descrizione dell'immagine


Grazie per la tua spiegazione. Giusto per chiarire: con Dense(16, input_shape=(5,3), ogni neurone in uscita dall'insieme di 16 (e, per tutti e 5 gli insiemi di questi neuroni), sarà connesso a tutti (3 x 5 = 15) i neuroni in ingresso? Oppure ogni neurone nel primo set di 16 sarà connesso solo ai 3 neuroni nel primo set di 5 neuroni di input, e quindi ogni neurone nel secondo set di 16 sarà connesso solo ai 3 neuroni nel secondo set di 5 input neuroni, ecc .... sono confuso su quale sia!
Karnivaurus

1
Hai uno strato denso che ottiene 3 neuroni e l'output 16 che viene applicato a ciascuno dei 5 set di 3 neuroni.
Marcin Możejko

1
Ah ok. Quello che sto cercando di fare è prendere un elenco di 5 pixel di colore come input e voglio che passino attraverso un livello completamente connesso. Quindi input_shape=(5,3)significa che ci sono 5 pixel e ogni pixel ha tre canali (R, G, B). Ma secondo quello che stai dicendo, ogni canale verrebbe elaborato individualmente, mentre io voglio che tutti e tre i canali vengano elaborati da tutti i neuroni nel primo strato. Quindi applicare lo Flattenstrato immediatamente all'inizio mi darebbe quello che voglio?
Karnivaurus

8
Un piccolo disegno con e senza Flattenpuò aiutare a capire.
Xvolks

2
Ok, ragazzi, vi ho fornito un'immagine. Ora puoi eliminare i tuoi voti negativi.
Marcin Możejko


35

lettura breve:

Appiattire un tensore significa rimuovere tutte le dimensioni tranne una. Questo è esattamente ciò che fa il livello Flatten.

lettura lunga:

Se prendiamo in considerazione il modello originale (con il layer Flatten) creato possiamo ottenere il seguente riepilogo del modello:

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

Per questo riepilogo, si spera che l'immagine successiva fornisca un po 'più di senso sulle dimensioni di input e output per ogni livello.

La forma di output per il livello Appiattisci come puoi leggere è (None, 48). Ecco il suggerimento. Dovresti leggerlo (1, 48)o (2, 48)o ... o (16, 48)... o (32, 48), ...

Infatti, None in quella posizione si intende qualsiasi dimensione del lotto. Per gli input da richiamare, la prima dimensione indica la dimensione del batch e la seconda indica il numero di funzioni di input.

Il ruolo del livello Flatten in Keras è semplicissimo:

Un'operazione di appiattimento su un tensore rimodella il tensore in modo che abbia la forma che è uguale al numero di elementi contenuti nel tensore esclusa la dimensione del lotto .

inserisci qui la descrizione dell'immagine


Nota: ho utilizzato il model.summary()metodo per fornire la forma di output ei dettagli dei parametri.


1
Diagramma molto perspicace.
Shrey Joshi

1
Grazie per il diagramma. Mi dà un'immagine chiara.
Sultan Ahmed Sagor

0

Flatten rende esplicito come serializzare un tensore multidimensionale (tipicamente quello di input). Ciò consente la mappatura tra il tensore di input (appiattito) e il primo layer nascosto. Se il primo strato nascosto è "denso", ogni elemento del tensore di input (serializzato) sarà connesso con ogni elemento dell'array nascosto. Se non si utilizza Flatten, il modo in cui il tensore di input viene mappato sul primo livello nascosto sarebbe ambiguo.


0

Mi sono imbattuto di recente in questo, sicuramente mi ha aiutato a capire: https://www.cs.ryerson.ca/~aharley/vis/conv/

Quindi c'è un input, un Conv2D, MaxPooling2D ecc., I livelli Flatten sono alla fine e mostrano esattamente come si formano e come vanno a definire le classificazioni finali (0-9).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.