Assumerò per C1
, C2
ecc., Intendi i livelli convoluzionali, e per P1
, P2
intendi i livelli di pooling e i livelli FC
completamente collegati.
Possiamo calcolare la memoria richiesta per un passaggio in avanti come questo:
Un'immagine
Se stai lavorando con i valori float32, quindi seguendo il link fornito sopra da @Alexandru Burlacu hai:
Input
: 50x50x3 = 7.500 = 7.5K
C1
: 50x50x32 = 80.000 = 80 K.
P1
: 25x25x32 = 20.000 = 20K
C2
: 25x25x64 = 40.000 = 40 K.
P2
: 12x12x64 = 9.216 = 9.2K <- Questo è un problema (e la mia approssimazione è un'ipotesi molto ondulata qui). Invece di lavorare con 50, 25, '12 .5 ', avrebbe più senso lavorare con multipli di 32. Ho sentito che lavorare con multipli di 32 è anche più efficiente dal punto di vista della memoria. Il motivo per cui questa è una cattiva idea è che il pooling 2x2 non divide correttamente lo spazio, per quanto ne so. Sentiti libero di correggermi se sbaglio.
FC
: 1x500 = 500 = 0,5 K.
Output
: 1 x 10 = 10 = 0,01 K (quasi nulla)
Memoria totale: 7,5 K + 80 K + 20 K + 40 K + 0,5 K = 157,2 K * 4 byte = 628,8 KB
Questo è per un'immagine.
Minibatch
Se lavori con una dimensione di minibatch di 64, stai leggendo 64 di questi in memoria contemporaneamente ed eseguendo le operazioni tutte insieme, ridimensionando tutto in questo modo:
Input
: 64x50x50x3 = 480.000 = 480K = 0.48M
C1
: 64x50x50x32 = 5.120.000 = 5,12 milioni
P1
: 64x25x25x32 = 1.280.000 = 1,28 milioni
C2
: 64x25x25x64 = 2.560.000 = 2,56M
P2
: 64x12x12x64 = 589.824 = 590K = 0,59M
FC
: 64x500 = 32.000 = 32K = 0.032M
Output
: 1x10x64 = 640 = 0.64K = 0.00064M (non ci interessa, questo è minuscolo)
Memoria totale: 10 MB x 4 byte ~ 40 MB (sto dicendo approssimativo perché il sito Web dice anche un valore approssimativo)
EDIT: ho letto male il sito web, mi dispiace.
Secondo il sito Web, un passaggio all'indietro richiede circa il triplo, a causa della necessità di memorizzare:
le attivazioni e i gradienti associati per ciascun neurone - sono di uguali dimensioni;
i gradienti dei pesi (parametri) che hanno le stesse dimensioni dei parametri;
il valore della quantità di moto, se la stai usando;
una sorta di memoria varia (non capisco questa parte)
C1
sopra hai50x50x32
ma che sarebbero solo i valori per le mappe di attivazione del livello, che dire dei valori appresi (32x3x3
) all'interno del kernel stesso?