Consommation de mémoire CNN

10

J'aimerais pouvoir estimer si un modèle proposé est suffisamment petit pour être formé sur un GPU avec une quantité de mémoire donnée

Si j'ai une architecture CNN simple comme celle-ci:

  • Input: 50x50x3
  • C1: 32 noyaux 3x3, avec rembourrage (je suppose qu'ils sont en réalité 3x3x3 étant donné la profondeur d'entrée?)
  • P1: 2x2 avec foulée 2
  • C2: 64 noyaux 3x3, avec rembourrage
  • P2: 2x2 avec foulée 2
  • FC: 500 neurones
  • Output: softmax 10 classes
  • Mini lot de 64

En supposant des valeurs à virgule flottante 32 bits, comment calculez-vous le coût de la mémoire de chaque couche du réseau pendant la formation? puis la mémoire totale nécessaire pour former un tel modèle?

Simon
la source

Réponses:

7

Je suppose par C1, C2, etc., vous voulez dire des couches convolutifs, et par P1, P2vous couches de mise en commun moyennes, et des FCmoyens de couches entièrement connectées.

Nous pouvons calculer la mémoire requise pour une passe avant comme ceci:

Une image

Si vous travaillez avec des valeurs float32, alors en suivant le lien fourni ci-dessus par @Alexandru Burlacu, vous avez:

Input: 50x50x3 = 7500 = 7,5 K

C1: 50x50x32 = 80 000 = 80 K

P1: 25x25x32 = 20 000 = 20 K

C2: 25x25x64 = 40,000 = 40K

P2: 12x12x64 = 9,216 = 9.2K <- C'est un problème (et mon approximation est une supposition très ondulée ici). Au lieu de travailler avec 50, 25, '12 .5 ', il serait plus logique de travailler avec des multiples de 32. J'ai entendu dire que travailler avec des multiples de 32 était également plus efficace du point de vue de la mémoire. La raison pour laquelle c'est une mauvaise idée est que la mise en commun 2x2 ne divise pas correctement l'espace, pour autant que je sache. N'hésitez pas à me corriger si je me trompe.

FC: 1x500 = 500 = 0,5 K

Output: 1 x 10 = 10 = 0,01 K (presque rien)

Mémoire totale: 7,5 K + 80 K + 20 K + 40 K + 0,5 K = 157,2 K * 4 octets = 628,8 Ko

C'est pour une image.

Minibatch

Si vous travaillez avec une taille de mini-lot de 64, alors vous en lisez 64 en mémoire à la fois et effectuez les opérations ensemble, en augmentant tout comme ceci:

Input: 64x50x50x3 = 480 000 = 480 K = 0,48 M

C1: 64x50x50x32 = 5 120 000 = 5,12 M

P1: 64x25x25x32 = 1 280 000 = 1,28 M

C2: 64x25x25x64 = 2 560 000 = 2,56 M

P2: 64x12x12x64 = 589 824 = 590 K = 0,59 M

FC: 64x500 = 32 000 = 32 K = 0,032 M

Output: 1x10x64 = 640 = 0.64K = 0.00064M (peu nous importe, c'est minuscule)

Mémoire totale: 10 Mo x 4 octets ~ 40 Mo (je dis approximatif car le site Web indique également une valeur approximative)

EDIT: J'ai mal lu le site Web, désolé.

Selon le site Web, une passe en arrière nécessite environ le triple, en raison de la nécessité de stocker:

  • les activations et les gradients associés pour chaque neurone - ils sont de taille égale;

  • les gradients des poids (paramètres) qui ont la même taille que les paramètres;

  • la valeur de l'élan, si vous l'utilisez;

  • une sorte de mémoire divers (je ne comprends pas cette partie)

StatsSorcière
la source
Faut-il également prendre en compte la mémoire requise pour les poids / paramètres? Par exemple, pour votre couche C1ci-dessus, 50x50x32mais ce ne serait que les valeurs des cartes d'activation de couche, qu'en est-il des valeurs apprises ( 32x3x3) dans le noyau lui-même?
Simon
Oui, vous le faites, selon cs.stanford.edu/~quocle/tutorial2.pdf . L'algorithme backprop utilisant SGD a besoin des valeurs précédentes des poids. Mais avec la mise en commun maximale (faites-vous la mise en commun maximale?), Vous n'avez pas besoin de garder une trace du gradient par rapport à chaque connexion. Vous devez garder une trace de la connexion d'où provient la valeur maximale et calculer uniquement le gradient pour cette branche.
StatsSorceress
@StatsSorceress, merci pour cette réponse mais une question est apparue dans mon esprit, que se passe-t-il si la taille de la couche de convolution est de 11x11 au lieu de 3x3? et que se passe-t-il si une ReLU suivie d'une couche convolutionnelle?
saeed masoomi
2

Peut-être que ce lien vous donnera une explication sur la façon de calculer l'utilisation de la mémoire d'un réseau neuronal arbitraire. Ci-dessous dans le lien est expliqué l'utilisation de la mémoire du modèle VGGNet. Cliquez ici et faites défiler un peu))

Alexandru Burlacu
la source
1

Lors de la formation d'un convNet, la mémoire totale requise comprend les éléments suivants:

  • Mémoire pour les paramètres
  • Mémoire pour la sortie des couches intermédiaires
  • Mémoire pour le gradient de chaque paramètre
  • Mémoire supplémentaire nécessaire si vous utilisez un optimiseur comme Momentum, RMSprop, Adams, etc.
  • Mémoire divers pour l'implémentation

Une bonne approximation approximative est le nombre de paramètres x 3 x 4 (si vous utilisez un flottant 32 bits) octets

Eh bien, voici maintenant comment calculer le nombre de paramètres:

  • Couche conv: (largeur du noyau x hauteur du noyau) x nombre de canaux x profondeur + profondeur (ajouter de la profondeur uniquement si le biais est présent)
  • Couche FC: engourdie d'entrée * engourdie de sortie + sortie (la sortie est ajoutée pour inclure le nombre de biais)
  • Couche de pool max: aucun paramètre

Maintenant, additionnez simplement le nombre de tous les paramètres et utilisez la formule que j'ai mentionnée.

Vijendra1125
la source