Consumo de memória CNN

10

Eu gostaria de poder estimar se um modelo proposto é pequeno o suficiente para ser treinado em uma GPU com uma determinada quantidade de memória

Se eu tiver uma arquitetura CNN simples como esta:

  • Input: 50x50x3
  • C1: 32 núcleos 3x3, com preenchimento (acho que na realidade são 3x3x3, dada a profundidade de entrada?)
  • P1: 2x2 com passada 2
  • C2: 64 grãos 3x3, com estofamento
  • P2: 2x2 com passada 2
  • FC: 500 neurônios
  • Output: softmax 10 classes
  • Mini tamanho de lote de 64

Assumindo valores de ponto flutuante de 32 bits, como você calcula o custo da memória de cada camada da rede durante o treinamento? e então a memória total necessária para treinar esse modelo?

Simon
fonte

Respostas:

7

Assumirei por C1, C2etc, você quer dizer camadas convolucionais e por P1, P2você quer dizer camadas de pool e FCsignifica camadas totalmente conectadas.

Podemos calcular a memória necessária para um encaminhamento como este:

Uma imagem

Se você estiver trabalhando com valores float32, siga o link fornecido acima por @Alexandru Burlacu:

Input: 50x50x3 = 7.500 = 7,5K

C1: 50x50x32 = 80.000 = 80K

P1: 25x25x32 = 20.000 = 20K

C2: 25x25x64 = 40.000 = 40K

P2: 12x12x64 = 9,216 = 9,2K <- Esse é um problema (e minha aproximação é um palpite bastante ondulado aqui). Em vez de trabalhar com 50, 25, '12 .5 ', faria mais sentido trabalhar com múltiplos de 32. Ouvi dizer que trabalhar com múltiplos de 32 também é mais eficiente do ponto de vista da memória. A razão pela qual essa é uma má idéia é que o pool 2x2 não divide o espaço adequadamente, tanto quanto eu posso dizer. Sinta-se livre para me corrigir se eu estiver errado.

FC: 1x500 = 500 = 0,5K

Output: 1 x 10 = 10 = 0,01K (quase nada)

Memória total: 7,5K + 80K + 20K + 40K + 0,5K = 157,2K * 4 bytes = 628,8 KB

Isso é para uma imagem.

Minibatch

Se você estiver trabalhando com um tamanho de minibatch de 64, estará lendo 64 deles na memória de uma só vez e executando as operações juntas, dimensionando tudo da seguinte maneira:

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

C1: 64x50x50x32 = 5.120.000 = 5,12M

P1: 64x25x25x32 = 1.280.000 = 1,28M

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 (não nos importamos, isso é minúsculo)

Memória total: 10M x 4 bytes ~ 40MB (estou dizendo aproximado porque o site também indica um valor aproximado)

EDIT: Eu li mal o site, desculpe.

Segundo o site, um passe para trás exige aproximadamente o triplo disso, devido à necessidade de armazenar:

  • as ativações e gradientes associados a cada neurônio - são de tamanho igual;

  • os gradientes dos pesos (parâmetros) que são do mesmo tamanho que os parâmetros;

  • o valor do momento, se você estiver usando;

  • algum tipo de memória diversa (não entendo essa parte)

Estatísticas
fonte
Também precisamos considerar a memória necessária para pesos / parâmetros? Por exemplo, para a sua camada C1acima, você tem, 50x50x32mas esses seriam apenas os valores para os mapas de ativação da camada, e os valores aprendidos ( 32x3x3) dentro do próprio kernel?
Simon
Sim, de acordo com cs.stanford.edu/~quocle/tutorial2.pdf . O algoritmo backprop usando SGD precisa dos valores anteriores dos pesos. Mas com o pool máximo (você está executando o pool máximo?), Não é necessário acompanhar o gradiente em relação a cada conexão. Você precisa acompanhar de qual conexão o valor máximo veio e calcular apenas o gradiente para esse ramo.
StatsSorceress
@StatsSorceress, obrigado por esta resposta, mas uma pergunta apareceu em minha mente: o que aconteceria se o tamanho da camada de convolução fosse 11x11 em vez de 3x3? e o que acontecerá se uma ReLU seguida por uma camada convolucional?
saeed masoomi
2

Talvez este link lhe dê uma explicação sobre como calcular o uso de memória de uma rede neural arbitrária. Abaixo, no link, é explicado o uso de memória do modelo VGGNet. Clique aqui e role um pouco)))

Alexandru Burlacu
fonte
1

Ao treinar um convNet, a memória total necessária inclui o seguinte:

  • Memória para parâmetros
  • Memória para saída de camadas intermediárias
  • Memória para o gradiente de cada parâmetro
  • Memória extra necessária se você estiver usando otimizador como Momentum, RMSprop, Adams etc.
  • Memória diversa para implementação

Uma boa aproximação aproximada é o número de parâmetros x 3 x 4 (se você estiver usando flutuador de 32 bits) bytes

Bem, agora é assim que você calcula o número de parâmetros:

  • Camada de conv: (largura do kernel x altura do kernel) x número de canais x profundidade + profundidade (adicione profundidade apenas se houver viés)
  • Camada FC: número de entrada * número de saída + saída (a saída é adicionada para incluir o número de viés)
  • Camada máxima do pool: sem parâmetro

Agora basta somar o número de todos os parâmetros e usar a fórmula que eu mencionei.

Vijendra1125
fonte