Técnica Jedi para reducir redes convolucionais - poda

Técnica Jedi para reducir redes convolucionais - poda

Antes de que de novo é a tarefa de detectar obxectos. A prioridade é a velocidade de operación cunha precisión aceptable. Tomas a arquitectura YOLOv3 e adestras aínda máis. A precisión (mAp75) é superior a 0.95. Pero a taxa de execución aínda é baixa. Merda.

Hoxe ignoraremos a cuantificación. E debaixo do corte miraremos Modelo de poda — recortar partes redundantes da rede para acelerar a inferencia sen perda de precisión. Está claro onde, canto e como cortar. Imos descubrir como facelo manualmente e onde podes automatizalo. Ao final hai un repositorio de keras.

Introdución

No meu anterior lugar de traballo, Macroscop en Perm, adquirei un hábito: supervisar sempre o tempo de execución dos algoritmos. E comprobe sempre o tempo de execución da rede a través dun filtro de adecuación. Normalmente, o estado da arte na produción non pasa este filtro, o que me levou a Poda.

A poda é un tema antigo que se tratou en Charlas de Stanford en 2017. A idea principal é reducir o tamaño da rede adestrada sen perder precisión eliminando varios nodos. Parece xenial, pero poucas veces escoito falar do seu uso. Probablemente, non haxa implementacións suficientes, non hai artigos en ruso ou simplemente todo o mundo o considera que pode podar o coñecemento e permanece en silencio.
Pero imos desmontar

Unha ollada á bioloxía

Encántame cando Deep Learning mira ideas que veñen da bioloxía. Eles, como a evolución, pódense confiar (sabías que ReLU é moi semellante a? función de activación neuronal no cerebro?)

O proceso de poda modelo tamén está preto da bioloxía. A resposta da rede aquí pódese comparar coa plasticidade do cerebro. Hai un par de exemplos interesantes no libro. Norman Doidge:

  1. O cerebro dunha muller que naceu con só unha metade reprogramouse para realizar as funcións da metade desaparecida.
  2. O mozo disparou a parte do seu cerebro responsable da visión. Co paso do tempo, outras partes do cerebro asumiron estas funcións. (non intentamos repetir)

Do mesmo xeito, pode cortar algunhas das circunvolucións débiles do seu modelo. Como último recurso, os paquetes restantes axudarán a substituír os cortados.

Gústache Transfer Learning ou estás aprendendo desde cero?

Opción número un. Usas Transfer Learning en Yolov3. Retina, Mask-RCNN ou U-Net. Pero a maioría das veces non necesitamos recoñecer 80 clases de obxectos como en COCO. Na miña práctica, todo está limitado aos graos 1-2. Pódese supoñer que aquí a arquitectura para 80 clases é redundante. Isto suxire que a arquitectura debe facerse máis pequena. Ademais, gustaríame facelo sen perder os pesos adestrados previamente existentes.

Opción número dous. Quizais tes moitos recursos de datos e informática, ou só necesites unha arquitectura superpersonalizada. Non importa. Pero estás aprendendo a rede desde cero. O procedemento habitual é mirar a estrutura de datos, seleccionar unha arquitectura EXCESIVA en potencia e impulsar os abandonos da reciclaxe. Vin 0.6 abandonos, Karl.

En ambos os casos, a rede pódese reducir. Motivado. Agora imos descubrir que tipo de poda de circuncisión é

Algoritmo xeral

Decidimos que podíamos eliminar os paquetes. Parece moi sinxelo:

Técnica Jedi para reducir redes convolucionais - poda

Eliminar calquera convolución é estresante para a rede, o que normalmente leva a un aumento do erro. Por unha banda, este aumento do erro é un indicador de como eliminamos correctamente as circunvolucións (por exemplo, un gran aumento indica que estamos a facer algo mal). Pero un pequeno aumento é bastante aceptable e adoita eliminarse mediante un adestramento adicional lixeiro posterior cun pequeno LR. Engade un paso de adestramento adicional:

Técnica Jedi para reducir redes convolucionais - poda

Agora temos que descubrir cando queremos deter o noso ciclo de Aprendizaxe<->Poda. Pode haber opcións exóticas aquí cando necesitemos reducir a rede a un determinado tamaño e velocidade (por exemplo, para dispositivos móbiles). Non obstante, a opción máis común é continuar o ciclo ata que o erro sexa superior ao aceptable. Engade unha condición:

Técnica Jedi para reducir redes convolucionais - poda

Entón, o algoritmo queda claro. Queda por descubrir como determinar as circunvolucións eliminadas.

Busca paquetes eliminados

Temos que eliminar algunhas circunvolucións. Correr adiante e "disparar" a calquera é unha mala idea, aínda que funcionará. Pero como tes cabeza, podes pensar e tentar seleccionar circunvolucións "débiles" para eliminalas. Hai varias opcións:

  1. Poda mínima de medida L1 ou de baixa amplitude. A idea de que as circunvolucións con pequenos pesos contribúen pouco á decisión final
  2. A menor medida L1 tendo en conta a media e a desviación típica. Complementamos cunha valoración da natureza da distribución.
  3. Enmascarando circunvolucións e excluíndo as que menos inflúen na precisión final. Determinación máis precisa de circunvolucións insignificantes, pero que consumen moito tempo e recursos.
  4. Outros

Cada unha das opcións ten dereito á vida e ás súas propias características de implementación. Aquí consideramos a opción coa medida L1 máis pequena

Proceso manual para YOLOv3

A arquitectura orixinal contén bloques residuais. Pero por moi xeniais que sexan para as redes profundas, impediranos un pouco. A dificultade é que non pode eliminar conciliacións con índices diferentes nestas capas:

Técnica Jedi para reducir redes convolucionais - poda

Polo tanto, seleccionemos capas das que podemos eliminar libremente as conciliacións:

Técnica Jedi para reducir redes convolucionais - poda

Agora imos construír un ciclo de traballo:

  1. Cargando activacións
  2. Descubrir canto cortar
  3. Córtao
  4. Aprendizaxe de 10 épocas con LR=1e-4
  5. Probando

A descarga de circunvolucións é útil para estimar canta parte podemos eliminar nun determinado paso. Exemplos de descarga:

Técnica Jedi para reducir redes convolucionais - poda

Vemos que case en todas partes o 5% das circunvolucións teñen unha norma L1 moi baixa e podemos eliminalas. En cada paso repetíase esta descarga e facíase unha valoración de que capas e cantas se podían recortar.

Todo o proceso completouse en 4 pasos (números aquí e en todas partes para o RTX 2060 Super):

Paso mapa 75 Número de parámetros, millóns Tamaño da rede, mb Dende inicial, % Tempo de execución, ms Condición de circuncisión
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% de todo
2 0.9625 50 197 83 168 5% de todo
3 0.9633 39 155 64 155 15 % para capas con máis de 400 circunvolucións
4 0.9555 31 124 51 146 10 % para capas con máis de 100 circunvolucións

Engadiuse un efecto positivo ao paso 2: o tamaño do lote 4 encaixa na memoria, o que acelerou moito o proceso de formación adicional.
No paso 4, o proceso detívose porque nin sequera a formación adicional a longo prazo elevou mAp75 a valores antigos.
Como resultado, conseguimos acelerar a inferencia 15%, reduce o tamaño en 35% e non perder exactamente.

Automatización para arquitecturas máis sinxelas

Para arquitecturas de rede máis sinxelas (sen bloques adicionais, concaternados e residuais condicionais), é moi posible centrarse en procesar todas as capas convolucionais e automatizar o proceso de corte de circunvolucións.

Implementei esta opción aquí.
É sinxelo: só necesitas unha función de perda, un optimizador e xeradores de lotes:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

Se é necesario, pode cambiar os parámetros de configuración:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Ademais, implícase unha limitación baseada na desviación estándar. O obxectivo é limitar a parte que se elimina, excluíndo as circunvolucións con medidas L1 xa "suficientes":

Técnica Jedi para reducir redes convolucionais - poda

Así, permitimos eliminar só as circunvolucións débiles de distribucións semellantes á dereita e non afectar a eliminación de distribucións similares á esquerda:

Técnica Jedi para reducir redes convolucionais - poda

Cando a distribución se aproxima ao normal, o coeficiente pruning_standart_deviation_part pódese seleccionar entre:

Técnica Jedi para reducir redes convolucionais - poda
Recomendo unha suposición de 2 sigma. Ou pode ignorar esta función, deixando o valor < 1.0.

A saída é un gráfico do tamaño da rede, a perda e o tempo de execución da rede para toda a proba, normalizado a 1.0. Por exemplo, aquí o tamaño da rede reduciuse case 2 veces sen perda de calidade (pequena rede convolucional con 100k pesos):

Técnica Jedi para reducir redes convolucionais - poda

A velocidade de carreira está suxeita a flutuacións normais e permanece practicamente inalterada. Hai unha explicación para isto:

  1. O número de circunvolucións cambia de conveniente (32, 64, 128) a non o máis conveniente para tarxetas de vídeo: 27, 51, etc. Podería estar equivocado aquí, pero o máis probable é que teña un efecto.
  2. A arquitectura non é ampla, pero si consistente. Ao reducir o ancho, non afectamos á profundidade. Así, reducimos a carga, pero non cambiamos a velocidade.

Polo tanto, a mellora expresouse nunha redución da carga CUDA durante a execución nun 20-30%, pero non nunha redución no tempo de execución.

Resultados de

Reflexionemos. Consideramos 2 opcións para a poda: para YOLOv3 (cando tes que traballar coas túas mans) e para redes con arquitecturas máis sinxelas. Pódese ver que en ambos os casos é posible conseguir a redución do tamaño da rede e a aceleración sen perda de precisión. Resultados:

  • Reducindo o tamaño
  • Carreira de aceleración
  • Redución da carga CUDA
  • Como resultado, a compatibilidade co medio ambiente (Optimizamos o uso futuro dos recursos informáticos. Algún lugar é feliz Greta Thunberg)

Apéndice

  • Despois do paso de poda, pode engadir cuantización (por exemplo, con TensorRT)
  • Tensorflow ofrece capacidades para poda_de_baixo_magnitude. Obras.
  • repositorio Quero desenvolverme e estarei encantado de axudar

Fonte: www.habr.com

Engadir un comentario