Cómo interpretar el resultado de MLMultiArray en segmentación semántica a través de CoreML?
Estoy tratando de implementar un modelo de segmentación semántica en mi aplicación. He logrado convertir el modelo u2net a un modelo CoreML. No puedo obtener un resultado funcional a partir de la salida MLMultiArray. La descripción de la especificación es la siguiente:
Entrada:
nombre: “input”
tipo:
tipo de imagen:
ancho: 512
alto: 512
espacio de color: RGB
Salida:
nombre: “x_1”
tipo:
tipo de matriz múltiple:
forma: 1
forma: 3
forma: 512
forma: 512
dataType: FLOAT32
El modelo funciona muy bien al abrirlo y utilizar la funcionalidad de vista previa del modelo en Xcode. Muestra las 2 etiquetas diferentes en 2 colores (solo hay 2 clases + 1 fondo). Quiero tener la misma salida en mi aplicación, sin embargo, cuando proceso manualmente la salida de MLMultiArray a una CGImage obtengo resultados diferentes. Estoy utilizando el código proporcionado en https://github.com/powermobileweb/CoreMLHelpers de la siguiente manera:
let image = output.cgImage(min: -1, max: 1, channel: 0, axes: (1,2,3))
Esto me da algo que se ve utilizable pero tiene mucho desvanecimiento dentro de cada canal. Lo que necesito es una imagen con solo un valor de color para cada etiqueta.
He intentado convertir la salida del modelo directamente a una imagen a través de este código de muestra (https://developer.apple.com/forums/thread/81571#241998). Esto simplemente muestra “Error en la inferencia” en la vista previa del modelo de Xcode. Cuando intento eliminar la dimensión adicional innecesaria en la salida de MultiArray, obtengo este error:
“Error leyendo la especificación protobuf. Error del validador: la capa ‘x_1’ de tipo ‘Convolution’ tiene un rango de salida 3 pero espera un rango de al menos 4.”
¿Qué hace la vista previa del modelo en Xcode que yo no estoy haciendo? ¿Hay un paso de posprocesamiento que debo seguir para obtener una salida utilizable?
davy.ai
Solución para implementar un modelo de segmentación semántica en una aplicación
Para implementar un modelo de segmentación semántica en una aplicación utilizando CoreML, se pueden seguir los siguientes pasos:
La especificación de la
output
proporcionada en la pregunta describe un modelo que recibe una imagen RGB con dimensiones de 512×512 píxeles y devuelve una salida MultiArray. La salida MultiArray tiene 3 dimensiones (con tipo de datos FLOAT32) que representan las 2 etiquetas diferentes y el fondo.Al procesar la salida MLMultiArray a una CGImage, es importante tener en cuenta que el código proporcionado escala los valores de salida al rango de -1 a 1. Esto puede causar gradiente dentro de cada canal, aunque la imagen se vea útil de alguna manera.
Para obtener una imagen con un color único para cada etiqueta, se requiere un paso de post-procesamiento. Una forma de lograr esto es aplicar un mapa de colores a los valores de salida. Se puede utilizar el siguiente código para esto:
Este código utiliza la función
colormap
para asignar a cada etiqueta un color específico. La líneacontext.draw(output)
se utiliza para dibujar la salida MLMultiArray en un contexto de gráficos principales. Luego, la variablelabel
se utiliza para obtener la etiqueta con la mayor probabilidad y asignarle un color utilizando la funcióncolormap
. Por último, se crea la imagen de salida utilizando los datos RGB modificados.