Segmentación eficiente de imágenes con PyTorch: Parte 3

1. Descripción

        En esta serie de 4 partes, analizaremos la segmentación de imágenes desde cero utilizando técnicas de aprendizaje profundo en PyTorch. Esta sección se centrará en cómo optimizar nuestro modelo de línea de base CNN utilizando circunvoluciones separables en profundidad para reducir la cantidad de parámetros entrenables y hacer que el modelo se pueda implementar en dispositivos móviles y otros dispositivos de borde.

Figura 1: Resultados de ejecutar la segmentación de imágenes utilizando una CNN con circunvoluciones separables en profundidad en lugar de circunvoluciones regulares. De arriba a abajo, la imagen de entrada, la máscara de segmentación real y la máscara de segmentación prevista. 

2. Esquema del artículo

        En este artículo, mejoraremos la red neuronal convolucional (CNN) que construimos anteriormente para reducir la cantidad de parámetros que se pueden aprender en la red. La tarea de identificar píxeles de mascotas (píxeles pertenecientes a gatos, perros, hámsteres, etc.) en la imagen de entrada sigue siendo la misma. Nuestra red preferida seguirá siendo SegNet , y el único cambio que haremos será reemplazar nuestras capas convolucionales con convoluciones separables en profundidad (DSC). Antes de hacerlo, profundizaremos en la teoría y la práctica de las circunvoluciones separables en profundidad y apreciaremos las ideas detrás de la técnica.

        En este artículo, nos referiremos al código y los resultados de este cuaderno para el entrenamiento de modelos y al código y los resultados de este cuaderno para comenzar con DSC. Si desea reproducir los resultados, necesitará una GPU para asegurarse de que el primer portátil se ejecute en un tiempo razonable. El segundo portátil puede ejecutarse en una CPU normal.

3. Esta serie de artículos

        Esta serie está dirigida a lectores de todos los niveles de experiencia en aprendizaje profundo. Si desea aprender sobre el aprendizaje profundo y la IA visual en la práctica con una sólida experiencia teórica y práctica, ¡está en el lugar correcto! Esta será una serie de 4 partes con los siguientes artículos:

  1. conceptos e ideas
  2. modelos basados ​​​​en CNN
  3. Convolución separable en profundidad (este documento)
  4. Modelos basados ​​en transformadores visuales

4. Introducción

        Comencemos la discusión observando más de cerca las circunvoluciones desde la perspectiva del tamaño del modelo y el costo computacional. La cantidad de parámetros entrenables es un buen indicador del tamaño del modelo, y la cantidad de operaciones de tensor refleja la complejidad del modelo o el costo computacional. Considere que tenemos una capa convolucional con n filtros de tamaño dk x dk. Supongamos además que la capa procesa una entrada de forma mxhxw, donde  m  es el número de canales de entrada y h w  son las dimensiones de alto y ancho, respectivamente. En este caso, la capa convolucional producirá una salida de forma  nxhxw  , como se muestra en la Figura 2. Suponemos que la convolución usa  stride=1 . Avancemos y evalúemos esta configuración en términos de parámetros entrenables y costo computacional.

Figura 2: Un filtro de convolución convencional aplicado a una entrada para producir una salida. Asuma stride=1 y padding=dk-2. Fuente: Libro de aprendizaje profundo eficiente

        Evaluación de parámetros entrenables: Tenemos  n filtros y cada filtro tiene m x dk  x dk  parámetros aprendibles. Esto da como resultado un total de  parámetros de aprendizaje nxmx dk x dk . Ignore la terminología de sesgo para simplificar esta discusión. Veamos el siguiente código de PyTorch para verificar nuestra comprensión.

import torch
from torch import nn
def num_parameters(m):
return sum([p.numel() for p in m.parameters()])
dk, m, n = 3, 16, 32
print(f"Expected number of parameters: {m * dk * dk * n}")
conv1 = nn.Conv2d(in_channels=m, out_channels=n, kernel_size=dk, bias=False)
print(f"Actual number of parameters: {num_parameters(conv1)}")

        imprime lo siguiente.

Expected number of parameters: 4608
Actual number of parameters: 4608

        Ahora, vamos a evaluar el costo computacional de la convolución.

        Evaluación de costos computacionales: cuando se ejecuta con stride=1  y padding=dk-2 en una entrada de tamaño hxw  , un solo filtro de convolución de forma mx dk x dk aplicará el filtro de convolución  hxw  veces, para La parte hxw  se aplica una vez en total para cada imagen parte de  dk  x dk  . Resulta en un costo de  mx dk x dk xhxw por filtro o canal de salida . Como deseamos calcular n canales de salida, el costo total será mx  dk x dk xhxn . Avancemos y verifiquemos esto usando el paquete torchinfo PyTorch.

from torchinfo import summary
h, w = 128, 128
print(f"Expected total multiplies: {m * dk * dk * h * w * n}")
summary(conv1, input_size=(1, m, h, w))

imprimirá lo siguiente.

Expected total multiplies: 75497472


==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
Conv2d                                   [1, 32, 128, 128]         4,608
==========================================================================================
Total params: 4,608
Trainable params: 4,608
Non-trainable params: 0
Total mult-adds (M): 75.50
==========================================================================================
Input size (MB): 1.05
Forward/backward pass size (MB): 4.19
Params size (MB): 0.02
Estimated Total Size (MB): 5.26
==========================================================================================

        Si ignoramos los detalles de implementación de las capas convolucionales por un momento, nos damos cuenta de que, en un nivel alto, las capas convolucionales simplemente convierten las entradas mxhxw en   salidas nxhxw . La transformación se logra a través de filtros entrenables que aprenden gradualmente las funciones a medida que ven la entrada. La siguiente pregunta es: ¿es posible lograr esta transformación utilizando menos parámetros de aprendizaje y al mismo tiempo garantizar un compromiso mínimo en la capacidad de aprendizaje de las capas? Se proponen circunvoluciones separables en profundidad para responder a esta pregunta exacta. Echémosle un vistazo más de cerca y veamos cómo se comparan con nuestras métricas de evaluación.

5. Convolución separable en profundidad

El concepto de convolución separable en profundidad (DSC) fue propuesto originalmente         por Laurent Sifre en su tesis doctoral " Dispersión de movimiento rígido para la clasificación de imágenes ". Desde entonces, se han utilizado con éxito en varias redes convolucionales profundas populares, como XceptionNet y MobileNet .

        La principal diferencia entre la convolución regular y DSC es que DSC consta de 2 convoluciones de la siguiente manera:

  1. Convolución agrupada en profundidad , donde el número m de canales de entrada es igual al número de canales de salida, de modo que cada canal de salida se ve afectado por un solo canal de entrada. En PyTorch, esto se denomina convolución "agrupada". Puede leer más sobre circunvoluciones agrupadas en PyTorch aquí .
  2. Convolución puntual (tamaño de filtro = 1), que funciona como una convolución normal, por lo que cada uno de los n filtros funciona en todos los m canales de entrada para producir un único valor de salida.

Figura 3: Un filtro convolucional separable en profundidad aplicado a una entrada para producir una salida. Asuma stride=1 y padding=dk-2 . Fuente: Libro de aprendizaje profundo eficiente

        Realicemos el mismo ejercicio que la convolución regular DSC y calculemos la cantidad de parámetros y cálculos entrenables.

        Evaluación de parámetros entrenables: una convolución "agrupada" tiene m filtros, cada uno con dk  x dk  parámetros aprendibles, lo que da como resultado m canales de salida. Esto da como resultado un total de parámetros aprendibles de mx dk  x dk  . Una convolución puntual tiene n filtros de tamaño mx 1 x 1 que suman como máximo nxmx 1  x 1 parámetros aprendibles. Veamos el siguiente código de PyTorch para verificar nuestra comprensión.

class DepthwiseSeparableConv(nn.Sequential):
    def __init__(self, chin, chout, dk):
        super().__init__(
            # Depthwise convolution
            nn.Conv2d(chin, chin, kernel_size=dk, stride=1, padding=dk-2, bias=False, groups=chin),
            # Pointwise convolution
            nn.Conv2d(chin, chout, kernel_size=1, bias=False),
        )

conv2 = DepthwiseSeparableConv(chin=m, chout=n, dk=dk)
print(f"Expected number of parameters: {m * dk * dk + m * 1 * 1 * n}")
print(f"Actual number of parameters: {num_parameters(conv2)}")

        Esto se imprimirá.

Expected number of parameters: 656
Actual number of parameters: 656

        Podemos ver que la versión DSC tiene unas  7 veces menos parámetros . A continuación, centrémonos en el costo computacional de la capa DSC.

        Evaluación de costos computacionales: supongamos que nuestra entrada tiene dimensiones espaciales  mxhxw . En la sección de convolución agrupada de DSC, tenemos m filtros, cada uno de tamaño dk x dk . Los filtros se aplican a sus canales de entrada correspondientes, lo que da como resultado un costo de segmento de  mx dk x dk xhxw . Para la convolución puntual, aplicamos n filtros de tamaño mx 1  x 1 para producir  canales de salida. Esto da como resultado un costo de segmento de nx  mx 1 x 1 xhxw . Necesitamos sumar el costo de las operaciones de grupo y punto a punto para calcular el costo total. Avancemos  y verifiquemos esto usando el paquete torchinfo PyTorch.

print(f"Expected total multiplies: {m * dk * dk * h * w + m * 1 * 1 * h * w * n}")
s2 = summary(conv2, input_size=(1, m, h, w))
print(f"Actual multiplies: {s2.total_mult_adds}")
print(s2)

Esto se imprimirá.

Expected total multiplies: 10747904
Actual multiplies: 10747904
==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
DepthwiseSeparableConv                   [1, 32, 128, 128]         --
├─Conv2d: 1-1                            [1, 16, 128, 128]         144
├─Conv2d: 1-2                            [1, 32, 128, 128]         512
==========================================================================================
Total params: 656
Trainable params: 656
Non-trainable params: 0
Total mult-adds (M): 10.75
==========================================================================================
Input size (MB): 1.05
Forward/backward pass size (MB): 6.29
Params size (MB): 0.00
Estimated Total Size (MB): 7.34
========================================================================================== 

Comparemos el tamaño y el costo de las dos circunvoluciones, con algunos ejemplos para ganar algo de intuición.

6. Comparación de tamaño y costo de circunvoluciones convencionales y separables en profundidad

        Para comparar el tamaño y el costo de las convoluciones regulares y las convoluciones separables en profundidad, supondremos una red con un tamaño de entrada de 128 x  128 , un tamaño de kernel de 3  x 3 y una red que gradualmente reduce a la mitad la dimensión espacial y duplica el número de red de dimensiones del canal. Suponemos que hay una capa de conversión 2D en cada paso, pero en realidad, puede haber más.

Figura 4: Comparación del número de parámetros entrenables (tamaño) y extras (costo) para circunvoluciones regulares y separables en profundidad. También mostramos la relación entre el tamaño y el costo de las 2 circunvoluciones. Fuente: Autor.

Puede ver que, en promedio, el tamaño y el costo computacional de DSC es aproximadamente del 11 % al 12 % del costo de la convolución regular en la configuración anterior.

Figura 5: Tamaño relativo y costo de un DSC VS/s convencional. Fuente: Autor.

        Ahora que tenemos una buena comprensión de los tipos de convoluciones y sus costos relativos, debe preguntarse si hay alguna desventaja en el uso de DSC. ¡Todo lo que hemos visto hasta ahora parece indicar que son mejores en todos los sentidos! Bueno, no hemos considerado un aspecto importante, su impacto en la precisión de nuestro modelo. Profundicemos en ello con el siguiente experimento.

7. SegNet usando convolución separable en profundidad

        Este cuaderno contiene todo el código de esta sección.

        Adaptaremos el modelo SegNet de la publicación anterior y reemplazaremos todas las capas convolucionales regulares con capas DSC. Después de hacer esto, notamos que la cantidad de parámetros en el portátil se redujo de 15,27 millones a 1,75 millones, ¡una reducción del 88,5 %! Esto es coherente con nuestra estimación anterior de una reducción del 11 % al 12 % en la cantidad de parámetros entrenables de la red.

Se utilizó una configuración similar a la anterior durante el entrenamiento y la validación del modelo. La configuración se especifica de la siguiente manera.

  1. Se aplica un aumento de datos de fluctuación de color y volteo horizontal aleatorio al conjunto de entrenamiento para evitar el sobreajuste
  2. Cambiar el tamaño de la imagen a 128x128 píxeles sin relación de aspecto conservando la operación de cambio de tamaño
  3. No aplica ninguna normalización de entrada a las imágenes, sino que utiliza una capa de normalización por lotes como primera capa del modelo.
  4. El modelo fue entrenado para 001 épocas usando el optimizador Adam con LR de 20.0 y sin planificador de LR
  5. La función de pérdida de entropía cruzada se utiliza para clasificar los píxeles como pertenecientes a mascota, fondo o borde de mascota

El modelo logró una precisión de validación del 96,20 % después de 86 épocas de entrenamiento. Esto es inferior a la precisión del 88,28 % lograda por el modelo que usa convoluciones regulares en el mismo número de épocas de entrenamiento. Hemos determinado experimentalmente que el entrenamiento para más épocas mejora la precisión de ambos modelos, por lo que 20 épocas definitivamente no es el final del ciclo de entrenamiento. A los efectos de este artículo, nos detenemos en 20 épocas con fines de demostración.

Dibujamos un gif que muestra cómo el modelo aprende a predecir máscaras de segmentación para las 21 imágenes del conjunto de validación.

Figura 6: Un gif que muestra cómo el modelo SegNet con DSC aprende a predecir máscaras de segmentación para 21 imágenes en el conjunto de validación. Fuente: Autor

Ahora que entendemos cómo progresa el modelo a través del ciclo de entrenamiento, comparemos el ciclo de entrenamiento del modelo con convolución regular y DSC.

8. Comparación de precisión

        Encontramos útil mirar el ciclo de entrenamiento del modelo usando convoluciones regulares y DSC. La principal diferencia que notamos es durante las primeras etapas (épocas) de entrenamiento, después de lo cual ambos modelos entran aproximadamente en el mismo flujo de predicciones. De hecho, después de entrenar ambos modelos durante 100 épocas, notamos que la precisión del modelo que usaba DSC era solo un 1 % más baja que la del modelo con convoluciones regulares. Esto es consistente con nuestras observaciones para 20 épocas de entrenamiento.

Figura 7: Un gif que muestra el progreso de la máscara de segmentación predicha por el modelo SegNet usando convoluciones regulares con DSC. Fuente: Autor.

        Notará que ambos modelos obtienen predicciones aproximadamente correctas después de solo 6 épocas de entrenamiento; es decir, uno puede ver intuitivamente que los modelos predicen algo útil. Luego, la mayor parte del arduo trabajo de entrenar al modelo es asegurarse de que la máscara predicha tenga los límites más estrechos posibles y esté lo más cerca posible de la mascota real en la imagen. Esto significa que, si bien se puede esperar un aumento absoluto menor en la precisión en épocas de entrenamiento posteriores, esto tiene un impacto mucho mayor en la calidad de la predicción. Observamos que a valores de precisión absoluta más altos (del 89% al 90%), un aumento de precisión de un solo dígito conduce a una mejora cualitativa significativa en la predicción.

9. Comparación con el modelo de red de las Naciones Unidas

        Realizamos un experimento cambiando una cantidad de hiperparámetros con un enfoque en mejorar la precisión general para ver qué tan cerca está esta configuración de la óptima. A continuación se muestra la configuración para este experimento.

  1. Tamaño de imagen: 128 x 128 — igual que los experimentos hasta ahora
  2. Épocas de entrenamiento: 100: el experimento actual entrenó durante 20 épocas
  3. Mejoras: más mejoras, como rotación de imágenes, abandono de canales, eliminación de bloques aleatorios. Usamos albumentaciones en lugar de conversión de Torchvision. Protein convierte automáticamente la máscara de segmentación para nosotros
  4. Programador LR: usando el programador StepLR, decae por un factor de 8.25 cada 0 ciclos de tren
  5. Función de pérdida: probamos 4 funciones de pérdida diferentes: entropía cruzada, focal, dados, entropía cruzada ponderada. Dice tuvo el peor desempeño, mientras que el resto fue casi comparable entre sí. De hecho, la mejor diferencia de precisión entre el resto después de 100 épocas está en el cuarto decimal (suponiendo que la precisión sea un número entre 0,0 y 1,0)
  6. Tipo de convolución: Regular
  7. Tipo de modelo: UNet: el experimento actual utiliza el modelo SegNet

        Para la configuración anterior, logramos la mejor precisión de validación del 91,3 %. Notamos que el tamaño de la imagen afecta significativamente la mejor precisión de validación. Por ejemplo, cuando cambiamos el tamaño de la imagen a 256 x 256, la mejor precisión de validación es del 93,0 %. Sin embargo, el entrenamiento lleva mucho más tiempo y usa más memoria, lo que significa que tenemos que reducir el tamaño del lote.

Figura 8: Resultados de entrenar un modelo UNet para 100 épocas de entrenamiento con los hiperparámetros anteriores. Fuente: Autor.

Puede ver que el pronóstico es mucho más suave y claro que lo que hemos visto hasta ahora.

10. Conclusión

        En la Parte 3 de esta serie, aprendimos sobre la convolución separable en profundidad (DSC) como una técnica para reducir el tamaño del modelo y el costo de entrenamiento/inferencia sin reducir significativamente la precisión de la validación. Analizamos las ventajas y desventajas de tamaño/costo entre convencional y DSC para ciertas configuraciones.

        Mostramos cómo ajustar un modelo SegNet para usar DSC en PyTorch. Esta técnica se puede aplicar a cualquier CNN profunda. De hecho, podemos reemplazar selectivamente algunas capas convolucionales con DSC; es decir, no necesariamente necesitamos reemplazar todas las capas convolucionales. Elegir qué capas reemplazar dependerá del equilibrio que desee lograr entre el tamaño del modelo/costo del tiempo de ejecución y la precisión de la predicción. Esta decisión dependerá de su caso de uso específico y configuración de implementación.

        Aunque este documento entrena el modelo para 20 épocas, explicamos que esto es insuficiente para las cargas de trabajo de producción y proporcionamos una idea de lo que se puede esperar si el modelo se entrena para más épocas. Además, presentamos algunos hiperparámetros que se pueden ajustar durante el entrenamiento del modelo. Si bien esta lista no es exhaustiva, debería darle una idea de las complejidades y decisiones necesarias para entrenar un modelo de segmentación de imágenes para cargas de trabajo de producción.

Supongo que te gusta

Origin blog.csdn.net/gongdiwudu/article/details/132346499
Recomendado
Clasificación