3 minute read

Tras ver los resultados de la semana anterior, se propuso reentrenar un modelo neuronal para obtener una mejor segmentación semántica del entorno. Para ello se creo un mapa similar al del Pinar y se ha estudiado el uso de los scripts de entrenamiento proporcionados por David Pascual.

Mapa de entrenamiento

Fue necesario crear un mapa nuevo que tuviese una estructura similar al del Pinar, a este mapa se le llamó PinarTrain, que se trata de un mapa simple que contiene los mismos elementos pero en un entorno más reducido.

Mapa de entrenamiento

Entrenamiento del modelo

Creación del dataset de entreanamiento

Se contacto con David Pascual para informarse sobre como usar los scripts de entrenamiento proporcionados, se comentó que antes de usarlos, primero hay que crear el dataset con una estructura concreta para realizar el entrenamiento:

dataset_dir
|--train
|--val
|--test
|--dataset.parquet
|--ontology.json

Donde, dentro del train, val y test se guardan, para cada muestra, las imagenes RGB (image.png) y su correspondiente imágen de etiqueta (label.png). La imágen de etiqueta, se trata de una imagen de un canal con valores del 0 al número de clases en total. Para conseguir la imágen de etiqueta, se modificó el script o3d-semantiLidarViz-1.5.py:

    ########### Obtener etiquetas crudas ###########
    raw_array = np.frombuffer(image.raw_data, dtype=np.uint8)
    raw_array = np.reshape(raw_array, (image.height, image.width, 4))
    seg_raw_array = np.copy(raw_array[:, :, :3])

    raw_labels = seg_raw_array[:, :, 2]
    ########### Obtener etiquetas crudas ###########

Donde primero se extrae los valores BGRA de cada pixel del buffer y se convierte a un array numpy de 8 bits para poder manejarlo, después se reorganiza el vector a una matriz tridimensional y se crea una copia editable con los canales BGR ya que el buffer original esta protegido y finalemente se extrae el canar R que es el que contiene la etiqueta de clase. Después simplemente se guardan las imágenes cada 20 frames al igual que se hacía con las RGB.

Mapa de entrenamiento
Mapa de entrenamiento

Se decidió dividir las imágenes de manera aleatoria entre train, val y test con una proporción del 60-20-20 respectivamente. Dejandose una estructura:

dataset_dir
|--train
|----rgb
|----segmentation_idx
|--val
|----rgb
|----segmentation_idx
|--test
|----rgb
|----segmentation_idx
|--dataset.parquet
|--ontology.json

El dataset.parquet es el fichero que contiene la dirección a cada muestra, creado mediante la montura de un dataframe de pandas en el que se encuentra toda la información y despues exportado a dicho formato. Ejemplo:

import pandas as pd

samples = {
    "0040": {"image": "train/rgb/rgb_0040.png", "label": "train/segmentation_idx/segmentation_idx_0040.png", "split": "train"},
    "0060": {"image": "train/rgb/rgb_0060.png", "label": "train/segmentation_idx/segmentation_idx_0060.png", "split": "train"},
    "0080": {"image": "train/rgb/rgb_0080.png", "label": "train/segmentation_idx/segmentation_idx_0080.png", "split": "train"},
    "0120": {"image": "val/rgb/rgb_0120.png", "label": "val/segmentation_idx/segmentation_idx_0120.png", "split": "val"},
    "0020": {"image": "test/rgb/rgb_0020.png", "label": "test/segmentation_idx/segmentation_idx_0020.png", "split": "test"},
    ...
}

df = pd.DataFrame.from_dict(samples, orient="index")
df.to_parquet("dataset.parquet")

Finalmente, el ontology.json contiene el diccionario de las clases que se usan, en este caso de CARLA, con el nombre, el índice y su valor RGB.

Entreanamiento del modelo

Después de la explicación del script train.py y de su archivo de configuración cfg.yaml se decidió usar los valores por defecto para esta primera prueba, es decir:

  • Se utilizó el modelo segformer_mit-b2_8xb1-160k_cityscapes-1024x1024 de mmsegmentation, ya que por pruebas realizadas por David Pascual es un modelo que ha demostrado dar buenos resultados sin realizar un consumo elevado.
  • Se mantuvo una tasa de aprendizaje variable desde 0.0001 hasta un mínimo de 0.00000001 para que sea lo más preciso posible al final.
  • Con un número máximo de 100 épocas (ciclos completos del conjunto de datos de entrenamiento) con un batch size de 8 imágenes (número de muestras utilizadas en una iteración), aunque este número se podía aumentar dependiendo de la memoria del ordenador.
  • Se dejo por defecto las transformaciones de color, de giro horizontal y de añadido de ruido, es decir una probabilidad del 50% por cada transformación en imágen.
  • Una paciencia de 15 épocas, es decir, que si el módelo no encuentra ninguna mejora en 15 épocas entonces detendrá el entrenamiento.

Finalmente se obtuvo el módelo prueba-epoch=epoch=98-step=step=1089-val_miou=val_miou=0.14.pt, siendo epoch el número de epocas, step el número de pasos de entrenamiento (número de batches realizados) y mIoU (mean Intersection over Union) mide la superposición entre las predicciones y las etiquetas reales.

Resultado puesto a prueba