Path: blob/master/site/es-419/tutorials/optimization/compression.ipynb
25118 views
Copyright 2022 The TensorFlow Compression Authors.
Compresión de modelo escalable
Descripción general
En estas anotaciones se muestra cómo comprimir un modelo con TensorFlow Compression.
En el ejemplo que se encuentra abajo, comprimimos los pesos de un clasificador MNIST a un tamaño mucho más pequeño que el de la representación de su punto flotante, a la vez, manteniendo la exactitud en la clasificación. Se hace con un proceso de dos pasos basado en la publicación Scalable Model Compression by Entropy Penalized Reparameterization (Compresión de modelo escalable por reparametrización con sanción por entropía):
Entrenamiento de un modelo "comprimible" con una sanción por entropía explícita durante el entrenamiento, que favorece la capacidad de compresión de los parámetros del modelo. El peso de la sanción habilita el control continuo de las compensaciones entre el tamaño del modelo comprimido y su exactitud.
Codificación del modelo comprimible en un modelo comprimido con un esquema de código que coincide con la sanción, es decir, que la sanción predice bien el tamaño del modelo. De este modo, se garantiza que el método no requiera de varias iteraciones de entrenamiento, compresión ni reentrenamiento del modelo para ajustarlo.
Este método está estrictamente centrado en el tamaño del modelo comprimido, no en la complejidad computacional. Se puede combinar con una técnica como la poda de modelos para reducir el tamaño y la complejidad.
Ejemplo de resultados de compresión en varios modelos:
Modelo (conjunto de datos) | Tamaño del modelo | Relación de comp. | Error de comp. principal (descomp.) |
---|---|---|---|
LeNet300-100 (MNIST) | 8.56 KB | 124x | 1.9% (1.6%) |
LeNet5-Caffe (MNIST) | 2.84 KB | 606x | 1.0% (0.7%) |
VGG-16 (CIFAR-10) | 101 KB | 590x | 10.0% (6.6%) |
ResNet-20-4 (CIFAR-10) | 128 KB | 134x | 8.8% (5.0%) |
ResNet-18 (ImageNet) | 1.97 MB | 24x | 30.0% (30.0%) |
ResNet-50 (ImageNet) | 5.49 MB | 19x | 26.0% (25.0%) |
Entre las aplicaciones se incluye:
Retransmisión/implementación de modelos para dispositivos con tecnología edge a gran escala, con ahorro de ancho de banda en tránsito.
Comunicación del estado del modelo global a los clientes en aprendizaje federado. La arquitectura del modelo (la cantidad de unidades ocultas, etc.) no cambia en cuanto al modelo inicial, y los clientes pueden seguir aprendiendo con el modelo comprimido.
Inferir sobre clientes con memoria extremadamente limitada. Durante la inferencia, los pesos de cada capa se pueden descomprimir secuencialmente y descartar inmediatamente después de que se calculan las activaciones.
Preparar
Instalar Tensorflow Compression con pip
.
Importar las dependencias de la librería.
Definición y entrenamiento de un clasificador MNIST básico
A fin de comprimir con efectividad las capas densas y convolucionales necesitamos definir las clases de capas personalizadas. Son análogas a las capas bajo tf.keras.layers
, pero las subclasificaremos más adelante para implementar efectivamente la reparametrización con sanción por entropía (EPR). Para este mismo objetivo, también agregamos un constructor de copia.
Primero, definimos una capa densa estándar:
De un modo similar, una capa convolucional 2D:
Antes de continuar con la compresión del modelo, verifiquemos que podamos entrenar bien a un clasificador regular.
Defina la arquitectura del modelo:
Cargue los datos de entrenamiento:
Finalmente, entrene el modelo:
¡Excelente! El modelo se entrenó bien y alcanzó una exactitud de más del 98 % en el conjunto de validación en 5 épocas.
Entrenamiento de un clasificador comprimible
La reparametrización con sanción por entropía (EPR) tiene dos ingredientes principales:
La aplicación de una sanción a los pesos del modelo durante el entrenamiento que corresponde a su entropía en un modelo probabilístico, que coincide con el esquema de codificación de pesos. A continuación, definimos un
Regularizer
Keras que implementa esta sanción.La reparametrización de pesos; es decir, llevarlos a la representación latente que es más fácil de comprimir (produce una mejor compensación entre la capacidad de compresión y el desempeño del modelo). Para núcleos convolucionales, se ha demostrado que el dominio de Fourier los representa bien. Para otros parámetros, en el siguiente ejemplo simplemente se usa la cuantificación escalar (redondeo) con un tamaño de paso de cuantificación variable.
Primero, defina la sanción.
En el ejemplo siguiente se usa un modelo de código/probabilístico implementado en la clase tfc.PowerLawEntropyModel
inspirado por la publicación Optimizing the Communication-Accuracy Trade-off in Federated Learning with Rate-Distortion Theory (Optimización de la compensación de exactitud-comunicación en aprendizaje federal con la teoría de tasa-distorsión). La sanción se define como: donde es un parámetro del modelo o es la representación latente y es una pequeña constante para la estabilidad numérica con valores cercanos a 0.
La sanción es, efectivamente, una pérdida de regularización (a veces, denominada "pérdida de peso"). El hecho de que sea cóncava con una cúspide en cero favorece la dispersión del peso. El esquema de código aplicado para comprimir los pesos, un código gamma de Elias, produce códigos de longitud de bits para la magnitud del elemento. Es decir, al coincidir con la sanción y al aplicar esta última se minimiza la longitud de código esperada.
En segundo lugar, defina las subclases de CustomDense
y CustomConv2D
que tienen la siguiente funcionalidad adicional:
Toman una instancia del regulador que figura arriba y la aplican a los núcleos y sesgos durante el entrenamiento.
Definen el núcleo y el sesgo como una
@property
que realiza la cuantificación con gradientes directos cuando se accede a las variables. Esta exactitud refleja el cálculo que se lleva a cabo más adelante en el modelo comprimido.Definen las variables
log_step
adicionales, que representan el logaritmo del tamaño del paso de cuantificación. Mientras más aproximada sea la cuantificación, menor será el tamaño del modelo, pero también será menor la exactitud. Los tamaños de los pasos de cuantificación se pueden entrenar para cada parámetro del modelo, de modo que al realizar la optimización de la función de pérdida con sanción se determinará cuál es el mejor tamaño para el paso de cuantificación.
El paso de cuantificación se define de la siguiente manera:
Con esto, podemos definir la capa densa:
La capa convolucional es análoga. Además, el núcleo de convolución se almacena como su transformada discreta de Fourier real (RDFT) siempre que el núcleo esté configurado y la transformada esté invertida cada vez que este se use. Debido a que los diferentes componentes de frecuencia del núcleo tienden a ser más o menos comprimibles, cada uno de ellos tiene su propio tamaño de paso de cuantificación asignado.
Defina la transformada de Fourier y su inversa de la siguiente manera:
Con esto, defina la capa convolucional como:
Defina un modelo clasificador con la misma arquitectura que ve arriba, pero use estas capas modificadas:
Y entrene el modelo:
El modelo comprimible ha alcanzado una exactitud similar a la del clasificador simple.
Sin embargo, el modelo todavía no está realmente comprimido. Para lograrlo, definimos otro conjunto de subclases que almacena los núcleos y los sesgos en forma comprimida, como una secuencia de bits.
Compresión del clasificador
Las subclases de CustomDense
y CustomConv2D
definidas a continuación convierten los pesos de una capa densa comprimible en cadenas binarias. Además, almacenan el logaritmo del tamaño del paso de la cuantificación a la mitad de la precisión, para ahorrar espacio. Siempre que se accede al núcleo o sesgo mediante @property
, se descomprimen a partir de su representación de cadena y se descuantifican.
Primero, defina las funciones para comprimir y descomprimir un parámetro del modelo:
Con esto podemos definir CompressedDense
:
La clase de capa convolucional es análoga a la anterior.
Para transformar el modelo comprimible en uno comprimido podemos aprovechar y usar la función clone_model
. compress_layer
convierte cualquier capa comprimible en comprimida y, simplemente, pasa a través de cualquier otro tipo de capa (como Flatten
, etc.).
Ahora, validemos que el modelo comprimido aún se comporta como se espera:
¡La exactitud de clasificación del modelo comprimido es idéntica a la lograda durante el entrenamiento!
Además, el tamaño del modelo comprimido pesa mucho menos que el del tamaño del modelo original:
Para almacenar los modelos en el disco se requiere de sobrecosto para almacenar la arquitectura del modelo, los gráficos de función del modelo, etc.
Los métodos de compresión sin pérdida como ZIP son buenos para comprimir este tipo de datos, pero no los pesos en sí mismos. Es el motivo por el que sigue siendo beneficioso usar EPR para contar el tamaño del modelo incluido en ese sobrecosto, después de aplicar también la compresión ZIP:
Efecto de la regularización y compensación de tamaño-exactitud
Arriba, el hiperparámetro se estableció en 2 (normalizado por la cantidad de parámetros del modelo). A medida que aumentamos , los pesos del modelo reciben cada vez más sanciones por la comprimibilidad.
Para valores bajos, la sanción puede funcionar como un regularizador de peso. De hecho, tiene un efecto favorable en el desempeño de la generalización del clasificador y puede contribuir a una exactitud levemente mayor en el conjunto de datos de validación:
Para valores más altos, vemos un tamaño de modelo cada vez más pequeño, pero también la exactitud disminuye gradualmente. Para verlo, entrene algunos modelos y grafique su tamaño con respecto a la exactitud:
Lo ideal sería que en el gráfico se mostrara una compensación entre tamaño y exactitud con forma de codo, pero lo normal es que las métricas de exactitud, en cierto modo, tengan ruido. Dependiendo de la inicialización, la curva puede exhibir algunos pliegues.
Debido al efecto de regularización, el modelo EPR comprimido es más exacto en el conjunto de prueba que en el modelo original para valores pequeños de . El modelo EPR comprimido también es mucho más chico en comparación con los tamaños posteriores a la compresión ZIP adicional.
Descompresión del clasificador
CompressedDense
y CompressedConv2D
descomprimen los pesos de cada pase hacia adelante. De este modo, se vuelven ideales para dispositivos de memoria limitada, pero la descompresión puede ser costosa desde el punto de vista del cálculo, en particular en tamaños de lotes pequeños.
Para descomprimir el modelo una vez y usarlo para más entrenamientos o inferencias, podemos volver a convertirlo en modelo con capas regulares o comprimibles. Puede resultar útil para la implementación de modelos o en escenarios de entrenamiento federado.
Primero, lo volvemos a convertir en modelo simple, podemos hacer inferencias o continuar el entrenamiento regular sin una sanción por compresión:
Tenga en cuenta que la exactitud en la validación cae después de entrenar durante una época adicional, ya que el entrenamiento se hace sin regularización.
Como alternativa, podemos volver a convertir el modelo en uno "comprimible", para inferencias o más entrenamiento con una sanción por compresión:
Aquí, la exactitud mejora después de entrenar durante una época adicional.