Cuantificación del modelo de red (cuantificación de bits bajos)-----notas de estudio

cuantización de bits bajos

1. ¿Qué es la cuantificación?

La llamada cuantificación de modelos es una tecnología de compresión de modelos que convierte el almacenamiento de punto flotante (operación) en almacenamiento de enteros (operación).
En pocas palabras, significa que un peso debe ser representado por float 32, y después de la cuantificación, solo necesita ser representado por int 8. No es un conocimiento nuevo que podemos obtener casi 4 veces la cuantificación de la aceleración de la red con solo esta operación Usamos cuantización cuando preprocesamos imágenes. Recuerde que normalmente normalizamos una imagen de tipo uint8 con un valor que va de 0 a 255 en un tensor de tipo float32 con un valor que va de 0,0 a 1,0 Este proceso es la descuantificación. De manera similar, a menudo ajustamos la salida del tensor por la red en el rango de 0,0 a 1,0 a datos de imagen de tipo uint8 con un valor de 0 a 255. Este proceso es cuantificación

2. Por qué cuantificar

Con la rápida aplicación de la tecnología de aprendizaje profundo en muchos campos, incluida la visión por computadora-CV, el procesamiento del lenguaje natural-PNL, el habla, etc., ha surgido una gran cantidad de modelos de red basados ​​en el aprendizaje profundo. Estos modelos tienen la característica de que son grandes y complejos, aptos para razonar en tarjetas N, pero no aptos para dispositivos integrados como teléfonos móviles, y los clientes suelen necesitar implementar estos modelos complejos en algunos dispositivos integrados de bajo coste, por lo que creando una contradicción. Para resolver bien esta contradicción, surgió la cuantificación del modelo, que puede comprimir el modelo sin perder una pequeña cantidad de precisión, lo que hace posible aplicar estos modelos complejos a terminales integrados como teléfonos móviles y robots.
A medida que las predicciones del modelo se vuelven más precisas y las redes más profundas, la cantidad de memoria consumida por las redes neuronales se convierte en una preocupación central , especialmente en los dispositivos móviles. Normalmente, el teléfono móvil actual suele estar equipado con 4 GB de memoria para admitir el funcionamiento simultáneo de múltiples aplicaciones, y los tres modelos suelen ocupar 1 GB de memoria para ejecutarse una vez.
El tamaño del modelo no es solo una cuestión de capacidad de memoria, sino también del ancho de banda de la memoria . El modelo usa los pesos del modelo para cada predicción, y las aplicaciones relacionadas con imágenes generalmente requieren procesamiento de datos en tiempo real, lo que significa al menos 30 FPS. Por lo tanto, si se implementa una red ResNet-50 relativamente pequeña para la clasificación, se requieren 3 GB/s de ancho de banda de memoria para ejecutar el modelo de red. Cuando la red está funcionando, la memoria, la CPU y la batería se consumirán rápidamente, y no podemos permitirnos un precio tan alto para hacer que el dispositivo sea un poco más inteligente.
Por supuesto, la cuantización también tiene efectos secundarios, es decir, reducirá la precisión de la inferencia . Como puede verse en la siguiente figura, float32 es mucho más alto que int8 en términos de rango y precisión. Si la cuantificación no es buena, se producirá un desbordamiento de datos y una pérdida de precisión, por lo que el algoritmo de cuantificación determina directamente la calidad del efecto de cuantificación.
inserte la descripción de la imagen aquí

3. El propósito de la cuantificación

Acelere la velocidad de inferencia, reduzca la memoria de inferencia y reduzca el espacio de almacenamiento de archivos modelo

4. Clasificación de los métodos cuantitativos

(1) Cuantificación posterior al entrenamiento y entrenamiento consciente de la cuantificación Cuantificación
posterior al entrenamiento (PTQ = Cuantización posterior al entrenamiento):
se refiere a entrenar primero el modelo con datos float32 de precisión completa y luego cuantificar el modelo entrenado a int8
; El entrenamiento (QAT = Quantization Aware Training)
se refiere a insertar un módulo de cuantificación durante el entrenamiento de la red y completar la cuantificación durante el entrenamiento, para que los parámetros de la red puedan adaptarse mejor a la pérdida de información causada por la cuantificación.
• En comparación, el entrenamiento consciente de la cuantificación es teóricamente más preciso, pero es más difícil de implementar y más complicado de usar.

(2) Cuantificación simétrica y cuantificación asimétrica
inserte la descripción de la imagen aquí

La cuantización simétrica es mapear simétricamente inserte la descripción de la imagen aquí
los números de coma flotante cuyo rango de entrada es el rango a lo largo del punto cero parainserte la descripción de la imagen aquí

La cuantificación asimétrica mapea un número de coma flotante cuyo rango de entrada es un rango, que es [0,255] en tflite, que está a solo un desplazamiento de distancia.
En comparación, la cuantificación asimétrica tiene mayor precisión en teoría, pero es más difícil de implementar.

(3) Cuantificación lineal y cuantificación no lineal
El uso de una función lineal realizará el mapeo de conversión de cuantificación y descuantificación, es decir, cuantificación lineal; por supuesto,
también se pueden usar otras conversiones de funciones no lineales (como ), es decir, cuantificación no lineal.
inserte la descripción de la imagen aquí

Por el contrario, la cuantificación no lineal es teóricamente más precisa (todavía no necesariamente práctica), pero es más difícil de implementar, y la mayoría del hardware no admite el razonamiento de la cuantificación no lineal, y los registros son limitados (coeficientes de cuantificación segmentados).
Tanto TensorRT como ncnn han elegido el método más simple y rudo de "cuantificación posterior al entrenamiento + cuantización simétrica + cuantización lineal",

5. Esquema de cuantificación en Ncnn y tensorrt

(1) Usando cuantificación simétrica *

inserte la descripción de la imagen aquí

Ahora que se selecciona el modo de cuantización simétrica + cuantización lineal, mientras disfruta de las ventajas de la simplicidad y la aspereza, también se sacrificará la precisión. En el proceso de cuantificación
de datos float32 de inserte la descripción de la imagen aquí
función lineal inserte la descripción de la imagen aquí
a , si los datos de entrada no se distribuyen simétricamente a lo largo del punto cero, inevitablemente se desperdiciará una parte de int8. inserte la descripción de la imagen aquí
Dado que el rango de los datos de int8 en sí es pequeño, demasiado desperdicio conducirá inevitablemente a una fuerte caída en la precisión de la cuantificación. ¿Se
puede saturar la cuantificación de int8 tanto como sea posible truncando parte de los datos de float32? Es decir, dado que los valores propios de la red neuronal convolucional generalmente se distribuyen cerca del punto cero, algunos valores grandes con baja frecuencia de ocurrencia pueden considerarse truncados. Así que puedes considerar usar la siguiente cuantificación:
inserte la descripción de la imagen aquí

Es decir, los números de coma flotante mayores que T se cuantifican en 127 y los números de coma flotante menores que -T se cuantifican en -127. Entonces, ¿cuánto truncamiento es apropiado (es decir, cómo elegir T)?
A continuación, analice cómo ncnn construye un modelo matemático para resolver este problema
de divergencia de Kullback-Leibler:
inserte la descripción de la imagen aquí

Por lo tanto, esperamos que la divergencia KL antes de la cuantificación y después de la cuantificación sea cercana y no esté demasiado separada, para garantizar que la precisión después de la cuantificación no disminuya demasiado.

1. Establecimiento del modelo matemático de cuantificación int8
Se mencionó anteriormente que NCNN usa cuantificación simétrica + cuantificación lineal, y se truncará. Luego observe cómo construir un modelo matemático a partir de estas tres palabras clave.

2. Cuantificación simétrica
inserte la descripción de la imagen aquí

3. Truncar
inserte la descripción de la imagen aquí

(2) Cuantificación lineal

inserte la descripción de la imagen aquí

Dado que representa la distribución truncada de los datos originales de float32 y la distribución de los datos originales de float32 cuantificados a int8, esperamos que las dos distribuciones sean lo más similares posible, es decir, cuanto menor sea la divergencia KL, mejor. De esta forma se establece un modelo matemático, y el problema de cómo cuantificar se transforma en el valor de divergencia KL que minimiza la suma por selección.

inserte la descripción de la imagen aquí

(3) Cálculo de escala inferior

inserte la descripción de la imagen aquí

Se mencionó anteriormente que los valores de divergencia KL de las dos distribuciones se pueden minimizar y resolver. Sin embargo, cabe señalar que la divergencia KL requiere que las dos distribuciones tengan la misma longitud, pero es una distribución discreta con una longitud de , pero una distribución discreta con una longitud de 128. Por lo tanto, debe muestrear el muestreo superior para que sea tan largo y luego calcular la divergencia KL
inserte la descripción de la imagen aquí

Por lo tanto, el proceso completo de cálculo cuantitativo de cada parte inferior se puede expresar como: valor estadístico, luego dividido en partes, histograma estadístico, normalización de histograma

Cabe señalar que el índice que representa el contenedor truncado (es decir, el umbral en el código c++) no es un umbral real, por lo que después de obtenerlo, conviértalo al umbral truncado en la fórmula (6) de acuerdo con la siguiente fórmula, es decir, se calcula bottom_scale

inserte la descripción de la imagen aquí

(4) Cálculo de Weight_scale
El umbral de truncamiento de bottom_blob se calculó antes, y el umbral de truncamiento de todos los pesos de peso de convolución debe calcularse a continuación. Cabe señalar que el umbral de truncamiento de peso es una matriz.
El peso del peso de la convolución se distribuye uniformemente en comparación con bottom_blob y está cerca de 0 (si no me cree, puede encontrar una red para ver el peso de una determinada capa), y el efecto no se trunca, por lo que el la cuantificación del peso es relativamente simple: razonar y calcular el peso
volumen Salida del producto
Salida estadística de cada canalinserte la descripción de la imagen aquí

El peso de cuantificación de cada canal de salida correspondiente al kernel de convolución es weight_scales[n]=127/absmax
para que se obtengan todos los parámetros de cuantificación de bottom_blob y peso

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_43391596/article/details/128985461
Recomendado
Clasificación