Consumo di memoria della CNN


10

Mi piacerebbe essere in grado di stimare se un modello proposto è abbastanza piccolo da essere addestrato su una GPU con una determinata quantità di memoria

Se ho una semplice architettura CNN come questa:

  • Input: 50x50x3
  • C1: 32 kernel 3x3, con imbottitura (immagino che in realtà siano 3x3x3 data la profondità di input?)
  • P1: 2x2 con passo 2
  • C2: 64 kernel 3x3, con imbottitura
  • P2: 2x2 con passo 2
  • FC: 500 neuroni
  • Output: softmax 10 classi
  • Dimensione del lotto mini di 64

Supponendo valori in virgola mobile a 32 bit, come si calcola il costo della memoria di ciascun livello della rete durante l'allenamento? e quindi la memoria totale richiesta per addestrare un tale modello?

Risposte:


7

Assumerò per C1, C2ecc., Intendi i livelli convoluzionali, e per P1, P2intendi i livelli di pooling e i livelli FCcompletamente 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)


Dobbiamo considerare anche la memoria richiesta per pesi / parametri? Ad esempio, per il tuo livello C1sopra hai 50x50x32ma che sarebbero solo i valori per le mappe di attivazione del livello, che dire dei valori appresi ( 32x3x3) all'interno del kernel stesso?
Simone,

Sì, secondo cs.stanford.edu/~quocle/tutorial2.pdf . L'algoritmo di backprop che utilizza SGD richiede i valori precedenti dei pesi. Ma con il pool massimo (stai facendo il pool massimo?), Non è necessario tenere traccia del gradiente rispetto a ciascuna connessione. È necessario tenere traccia della connessione da cui proviene il valore massimo e calcolare solo il gradiente per quel ramo.
StatsSorceress

@StatsSorceress, grazie per questa risposta ma una domanda mi è venuta in mente, cosa succede se la dimensione del livello di convoluzione è 11x11 anziché 3x3? e cosa succede se una ReLU seguita da uno strato convoluzionale?
Saeed Masoomi,

2

Forse questo link ti darà una spiegazione su come calcolare l'utilizzo della memoria di una rete neurale arbitraria. Di seguito nel link viene spiegato l'utilizzo della memoria del modello VGGNet. Fai clic qui e scorri un po 'verso il basso))


1

Durante l'addestramento di una convNet, la memoria totale richiesta include quanto segue:

  • Memoria per parametri
  • Memoria per l'output di strati intermedi
  • Memoria per il gradiente di ciascun parametro
  • Memoria aggiuntiva necessaria se si utilizza un ottimizzatore come Momentum, RMSprop, Adams ecc
  • Memoria varia per l'implementazione

Una buona approssimazione approssimativa è il numero di parametri x 3 x 4 (se si utilizza float a 32 bit) byte

Bene, ora è così che calcoli il numero di parametri:

  • Conv layer: (larghezza del kernel x altezza del kernel) x numero di canali x profondità + profondità (aggiungi profondità solo se c'è bias)
  • Livello FC: intorpidimento dell'input * intorpidimento dell'output + output (l'output viene aggiunto per includere il numero di bias)
  • Livello pool massimo: nessun parametro

Ora sommate semplicemente il numero di tutti i parametri e utilizzate la formula che ho citato.

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.