Puesta a punto de un Vision Transformer

Eduardo Simon
.
June 1, 2023
Puesta a punto de un Vision Transformer

Ajuste de un modelo de Vision Transformer para la clasificación de imágenes en categorías de taxonomía de la IAB

En la era digital actual, con restricciones técnicas y regulaciones legales en constante aumento, la necesidad de contextualizar el contenido para personalizar los anuncios y garantizar la privacidad del usuario nunca ha sido tan importante. Además, los anunciantes se esfuerzan por mantener una asociación positiva y confiable entre su marca y el contenido en el que se muestran sus anuncios. Por lo tanto, la categorización del contenido de texto, imágenes y vídeo puede proporcionar una mejor experiencia de usuario a través de anuncios mejor contextuales, al tiempo que proporciona un mejor rendimiento y garantías a los anunciantes. Destaca cómo el uso de la categorización de imágenes del contenido de un sitio web para colocar anuncios adyacentes significativos puede resultar beneficioso para todas las partes interesadas.

Por lo tanto, la capacidad de clasificar y comprender imágenes se ha vuelto cada vez más valiosa en varios sectores. Ya sea para la organización del contenido, la publicidad dirigida o el análisis de clientes, la clasificación de imágenes desempeña un papel crucial a la hora de extraer información significativa de los datos visuales.

En esta entrada del blog, analizaremos el proceso de ajustar un modelo Vision Transformer (ViT) de la biblioteca Hugging Face para la clasificación de imágenes en las categorías de la taxonomía de contenido del laboratorio tecnológico del Interactive Advertising Bureau (IAB), el estándar del sector de la publicidad. Los Vision Transformers han demostrado recientemente un éxito notable en la visión artificial, lo que los convierte en una opción interesante para la clasificación de imágenes. Al aprovechar la potencia de los modelos previamente entrenados y alinear las predicciones con la taxonomía de la IAB, podemos aprovechar la posibilidad de clasificar las imágenes con precisión.

A lo largo de este post, profundizaremos en los conceptos fundamentales de las VIT, explicando su arquitectura y sus ventajas frente a las técnicas tradicionales de visión por computador. A continuación, presentaremos las categorías taxonómicas de la IAB, destacando su importancia a la hora de organizar el contenido visual. Después, llegaremos al meollo de la entrada del blog: el proceso de ajuste. Empezando por seleccionar un modelo previamente entrenado del centro de modelos Hugging Face, implementaremos rápidamente el preprocesamiento de datos, el entrenamiento de modelos y la evaluación, aprovechando la potencia de Amazon SageMaker Studio.

Comprensión de los transformadores de visión

Los transformadores de visión, introducidos en 2021 por Dosovitskiy y otros, se han convertido en una poderosa alternativa a las arquitecturas tradicionales, como las redes neuronales convolucionales (CNN) en las tareas de visión artificial. Los transformadores, que se diseñaron inicialmente para tareas de procesamiento del lenguaje natural (PNL), han demostrado recientemente un éxito notable en las tareas de clasificación de imágenes.

Un transformador de visión puro divide una imagen en partes más pequeñas y las trata como fichas (de forma similar a las palabras en la PNL). Luego, cada parche se incrusta linealmente y se añaden incrustaciones de posición para realizar la clasificación, utilizando el método de añadir a la secuencia un «símbolo de clasificación» (CLS) que se pueda aprender más. La secuencia de vectores resultante se envía a un codificador transformador estándar y se procesa a través de múltiples capas de mecanismos de autoatención.

Figura 1: Descripción general del modelo (Dosovitskiy, et al. 2021)

Se ha realizado un extenso trabajo para comparar los VIT con las CNN más modernas en cuanto a su desempeño en las tareas de clasificación de imágenes (Maurício, et al. 2023). Vamos a tratar brevemente más información sobre el rendimiento de las dos arquitecturas y lo que las distingue.

En comparación con las CNN, las VIT ofrecen mejores capacidades de escalabilidad y generalización. Cuando se entrena previamente con grandes cantidades de datos y, a continuación, se transfiere a varios centros de reconocimiento de imágenes de tamaño mediano o pequeño (ImageNet, CIFAR-100, VTAB), el ViT obtiene excelentes resultados en comparación con las CNN más modernas, al tiempo que requiere muchos menos recursos computacionales para su entrenamiento.

Por lo tanto, al capacitar previamente a los VIT en conjuntos de datos a gran escala, como ImageNet-21k (14 millones de imágenes, 21 843 clases), podemos aprovechar las representaciones aprendidas para adaptarnos a tareas específicas de clasificación de imágenes mediante un ajuste fino, lo que reduce la necesidad de una formación exhaustiva desde cero y, por lo tanto, el tiempo de capacitación y los costos generales.

Sin embargo, las CNN obtienen excelentes resultados cuando se entrenan desde cero en volúmenes de datos más pequeños como los que requieren Vision Transformers. Este comportamiento diferente parece deberse a la presencia en las CNN de sesgos inductivos, que estas redes aprovechan para captar más rápidamente las particularidades de las imágenes analizadas, aunque, por otro lado, acaben dificultando la comprensión de las relaciones globales. Por otro lado, los VIT están libres de estos sesgos, lo que les permite captar también las dependencias de largo alcance en las imágenes, a costa de disponer de más datos de entrenamiento. El mecanismo de autoatención permite al modelo captar las dependencias globales y locales dentro de la imagen, lo que le permite comprender las relaciones contextuales entre las diferentes regiones.

Entre otras diferencias notables entre las dos arquitecturas, las VIT funcionan mejor y son más resistentes a las imágenes con perturbaciones naturales o adversas en comparación con las CNN, y las VIT son más resistentes a los ataques adversarios y las CNN son más sensibles a las funciones de alta frecuencia.

En general, la arquitectura basada en transformadores (o la combinación de VIT con CNN) permite una mayor precisión en comparación con las redes de CNN, y funciona mejor en comparación con las redes de CNN gracias al funcionamiento del mecanismo de autoatención. La arquitectura ViTS es más ligera que la de las CNN, ya que consume menos recursos computacionales y requiere menos tiempo de entrenamiento, y es más sólida que las redes CNN para imágenes que tienen ruido o están aumentadas.

Por otro lado, las CNN pueden generalizar mejor con conjuntos de datos más pequeños y obtener una mayor precisión que los VIT, pero por el contrario, los VIT tienen la ventaja de aprender mejor la información con menos imágenes cuando se ajustan con precisión. Sin embargo, se ha observado que el rendimiento de los ViT puede tener problemas con la generalización cuando se entrena con conjuntos de datos de imágenes más pequeños.

Comprensión de la taxonomía del contenido de la IAB

El Interactive Advertising Bureau (IAB) ha desarrollado una taxonomía integral que desempeña un papel fundamental en la organización y la categorización del contenido digital. Su taxonomía proporciona un marco estandarizado para la clasificación del contenido, lo que permite una segmentación eficiente del contenido, la publicidad contextual y la segmentación de la audiencia.

La taxonomía de la IAB está estructurada jerárquicamente, con varios niveles de categorías y subcategorías. En el nivel superior, cubre amplias categorías de contenido, como arte y entretenimiento, deportes y más.

Luego, cada categoría se divide en subcategorías más específicas, lo que crea un sistema de clasificación más preciso y granular que puede capturar una amplia gama de tipos de contenido. Por ejemplo, dentro de la categoría Deportes, hay subcategorías como baloncesto, fútbol y tenis.

En la industria de la publicidad digital, la taxonomía de la IAB cumple varios propósitos. Ayuda a los anunciantes a alinear sus campañas con categorías de contenido específicas, garantizando que sus anuncios se muestren en contextos relevantes. Los editores de contenido pueden usar la taxonomía para categorizar su contenido de manera eficaz, lo que facilita a los usuarios el descubrimiento de información relevante. Además, la taxonomía de la IAB facilita la segmentación de la audiencia al permitir a los anunciantes segmentar categorías específicas que se ajusten a los intereses de su público objetivo.

En la siguiente sección, exploraremos cómo ajustar un modelo ViT para clasificar con precisión las imágenes en las categorías taxonómicas específicas de la IAB.

Bien: ajuste de un modelo de Vision Transformer

El ajuste fino de un modelo de transformador de visión implica adaptar un modelo previamente entrenado a un conjunto de datos a gran escala y ajustarlo a tareas posteriores más pequeñas, como la clasificación de imágenes en las categorías de taxonomía de la IAB. Este proceso nos permite aprovechar los conocimientos y las representaciones aprendidos con el modelo previamente entrenado, lo que nos permite ahorrar tiempo y recursos computacionales. Para ello, eliminamos el cabezal de predicción previamente entrenado y colocamos una nueva capa de retroalimentación, en la que K salidas representan el número de clases posteriores.

Para afinar el modelo ViT utilizaremos la biblioteca Hugging Face. Esta biblioteca ofrece una amplia gama de modelos de transformadores de visión previamente entrenados y proporciona una interfaz fácil de usar para ajustar e implementar estos modelos. Al utilizar la biblioteca Hugging Face, podemos aprovechar la disponibilidad de sus modelos, su fácil integración, el sólido apoyo de la comunidad y los beneficios de la transferencia del aprendizaje.

Como queríamos abordar este problema con un modelo de entrenamiento supervisado que utilizara las categorías de la IAB como etiquetas, necesitábamos un conjunto de datos debidamente etiquetado. Para ello, recopilamos y etiquetamos un conjunto de datos interno de imágenes permitidas para uso comercial. Como punto de referencia, las imágenes se etiquetan individualmente con una única categoría IAB de nivel 1. El conjunto de datos se compone de archivos de imágenes, organizados en carpetas por categoría, de modo que podemos cargarlos fácilmente en el formato adecuado mediante la biblioteca de conjuntos de datos de Hugging Face.

Con las funciones de Studio de SageMaker, podemos lanzar fácilmente una libreta respaldada por una instancia de GPU, como una ml.g4dn.xlarge, para llevar a cabo nuestro experimento de entrenamiento de un modelo de clasificación de referencia.

Para empezar, instalemos primero las bibliotecas necesarias de Hugging Face y PyTorch en el entorno virtual de nuestro portátil:

no-line-numbers!pip install transformers==4.26.1 datasets==2.10.1 evaluate==0.4.0 -q
no-line-numbers!pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 -q

Tenga en cuenta que el signo de exclamación (!) nos permite ejecutar comandos de shell desde una celda de código de Jupyter Notebook.

Ahora, hagamos las importaciones necesarias para que el portátil funcione correctamente:

no-line-numbersimport evaluateimport jsonimport numpy as npimport osimport pandas as pdimport pyarrow as paimport requestsimport torchfrom datasets import load_dataset, load_from_disk, Dataset, Features, Array3Dfrom io import BytesIOfrom transformers import AutoProcessor, ViTFeatureExtractor, ViTForImageClassification, Trainer, TrainingArguments, default_data_collatorfrom typing import Tuplefrom PIL import Image

Vamos a definir algunas variables:

no-line-numbers# The directory where our images are saved in folders by categoryimages_dir = "./dataset"# The output directory of the processed datasetstrain_save_path = "./processed-datasets/train"val_save_path = "./processed-datasets/val"test_save_path = "./processed-datasets/test"# Sizes of dataset splitsval_size = 0.2test_size = 0.1# Name of model as named in the HuggingFace Hubmodel_name = "google/vit-base-patch16-224-in21k"

Aprovechamos el crear un conjunto de datos de imágenes función para cargar fácilmente nuestro conjunto de datos personalizado especificando nuestra carpeta local donde se almacenan las imágenes en carpetas por categoría.

no-line-numbersdataset = load_dataset("imagefolder", data_dir=images_dir, split='train')

Realicemos un poco de limpieza de datos y eliminemos del conjunto de datos las imágenes que no sean RGB (canal único, escala de grises).

no-line-numbers# Remove from dataset images which are non-RGB (single-channel, grayscale)condition = lambda data: data['image'].mode == 'RGB'dataset = dataset.filter(condition)

Ahora dividimos nuestro conjunto de datos en conjuntos de entrenamiento, validación y prueba.

no-line-numbersdef split_dataset( dataset: Dataset, val_size: float=0.2, test_size: float=0.1) -> Tuple[Dataset, Dataset, Dataset]: """ Returns a tuple with three random train, validation and test subsets by splitting the passed dataset. Size of the validation and test sets defined as a fraction of 1 with the `val_size` and `test_size` arguments. """ print("Splitting dataset into train, validation and test sets...") # Split dataset into train and (val + test) sets split_size = round(val_size + test_size, 3) dataset = dataset.train_test_split(shuffle=True, test_size=split_size) # Split (val + test) into val and test sets split_ratio = round(test_size / (test_size + val_size), 3) val_test_sets = dataset['test'].train_test_split(shuffle=True, test_size=split_ratio) train_dataset = dataset["train"] val_dataset = val_test_sets["train"] test_dataset = val_test_sets["test"] return train_dataset, val_dataset, test_dataset# Split dataset into train and test setstrain_dataset, val_dataset, test_dataset = split_dataset(dataset, val_size, test_size)

Por último, podemos preparar estas imágenes para nuestro modelo.

Cuando se entrenan los modelos de ViT, se aplican transformaciones específicas a las imágenes que se introducen en ellos para que se ajusten al formato de entrada esperado.

Para asegurarnos de aplicar las transformaciones correctas, utilizaremos un «autoprocesador» inicializado con una configuración que se guardó en el Hub de Hugging Face junto con la preentrenada «google/vit-base-patch16-224 en 21k» modelo que planeamos usar.

Por lo tanto, preprocesamos nuestros conjuntos de datos con el autoprocesador de imágenes del modelo:

no-line-numbersdef process_examples(examples, image_processor): """Processor helper function. Used to process batches of images using the passed image_processor. Parameters ---------- examples A batch of image examples. image_processor A HuggingFace image processor for the selected model. Returns ------- examples A batch of processed image examples. """ # Get batch of images images = examples['image'] # Preprocess inputs = image_processor(images=images) # Add pixel_values examples['pixel_values'] = inputs['pixel_values'] return examplesdef apply_processing( model_name: str, train_dataset: Dataset, val_dataset: Dataset, test_dataset: Dataset) -> Tuple[Dataset, Dataset, Dataset]: """ Apply model's image AutoProcessor to transform train, validation and test subsets. Returns train, validation and test datasets with `pixel_values` in torch tensor type. """ # Extend the features features = Features({ **train_dataset.features, 'pixel_values': Array3D(dtype="float32", shape=(3, 224, 224)), }) # Instantiate image_processor image_processor = AutoProcessor.from_pretrained(model_name) # Preprocess images train_dataset = train_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) val_dataset = val_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) test_dataset = test_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) # Set to torch format for training train_dataset.set_format('torch', columns=['pixel_values', 'label']) val_dataset.set_format('torch', columns=['pixel_values', 'label']) test_dataset.set_format('torch', columns=['pixel_values', 'label']) # Remove unused column train_dataset = train_dataset.remove_columns("image") val_dataset = val_dataset.remove_columns("image") test_dataset = test_dataset.remove_columns("image") return train_dataset, val_dataset, test_dataset# Apply AutoProcessortrain_dataset, val_dataset, test_dataset = apply_processing(model_name, train_dataset, val_dataset, test_dataset)


Ahora guardamos nuestros conjuntos de datos procesados:

no-line-numbers# Save train, validation and test preprocessed datasetstrain_dataset.save_to_disk(train_save_path, num_shards=1)val_dataset.save_to_disk(val_save_path, num_shards=1)test_dataset.save_to_disk(test_save_path, num_shards=1)


Pasemos a la etapa de entrenamiento. Empezamos cargando los conjuntos de datos del tren y la validación.

no-line-numberstrain_dataset = load_from_disk(train_save_path)val_dataset = load_from_disk(val_save_path)


Nuestro nuevo modelo perfeccionado tendrá la siguiente cantidad de clases de salida:

no-line-numbersnum_classes = train_dataset.features["label"].num_classes

Ahora, definamos una 'vitForImageClassification', que coloca una capa lineal (nn.Linear) sobre un modelo de ViT previamente entrenado. La capa lineal se coloca encima del último estado oculto del token [CLS], lo que sirve como una buena representación de una imagen completa.

También especificamos el número de neuronas de salida configurando el parámetro `num_labels`.

no-line-numbers# Download model from model hubmodel = ViTForImageClassification.from_pretrained(model_name, num_labels=num_classes)# Download feature extractor from hubfeature_extractor = ViTFeatureExtractor.from_pretrained(model_name)

Vamos a continuar definiendo una función `compute_metrics`. Esta función se usa para calcular cualquier métrica objetivo definida en cada paso de la evaluación.

Aquí, utilizamos la métrica de «precisión» de los «conjuntos de datos», que se puede usar fácilmente para comparar las predicciones con las etiquetas esperadas en el conjunto de validación.

También definimos una métrica personalizada para calcular la precisión en «k» de nuestras predicciones. La precisión en «k» es el número de casos en los que la etiqueta real se encuentra en el conjunto de las «k» clases más probables.

no-line-numbers# K for top accuracy metrick_for_top_acc = 3# Compute metrics function for binary classificationacc_metric = evaluate.load("accuracy", module_type="metric")def compute_metrics(eval_pred): predicted_probs, labels = eval_pred # Accuracy predicted_labels = np.argmax(predicted_probs, axis=1) acc = acc_metric.compute(predictions=predicted_labels, references=labels) # Top-K Accuracy top_k_indexes = [np.argpartition(row, -k_for_top_acc)[-k_for_top_acc:] for row in predicted_probs] top_k_classes = [top_k_indexes[i][np.argsort(row[top_k_indexes[i]])] for i, row in enumerate(predicted_probs)] top_k_classes = np.flip(np.array(top_k_classes), 1) acc_k = { f"accuracy_k" : sum([label in predictions for predictions, label in zip(top_k_classes, labels)]) / len(labels) } # Merge metrics acc.update(acc_k) return acc

Como nos gustaría conocer los nombres de las clases reales como salidas, en lugar de solo índices enteros, configuramos el mapeo 'id2label' y 'label2id' como atributos para la configuración del modelo (al que se puede acceder como model.config):

no-line-numbers# Change labelsid2label = {key:train_dataset.features["label"].names[index] for index,key in enumerate(model.config.id2label.keys())}label2id = {train_dataset.features["label"].names[index]:value for index,value in enumerate(model.config.label2id.values())}model.config.id2label = id2labelmodel.config.label2id = label2id

A continuación, especificamos los directorios de salida del modelo y otros artefactos, y el conjunto de hiperparámetros que utilizaremos para el entrenamiento.

no-line-numbersmodel_dir = "./model"output_data_dir = "./outputs"# Total number of training epochs to performnum_train_epochs = 15# The batch size per GPU/TPU core/CPU for trainingper_device_train_batch_size = 32# The batch size per GPU/TPU core/CPU for evaluationper_device_eval_batch_size = 64# The initial learning rate for AdamW optimizerlearning_rate = 2e-5# Number of steps used for a linear warmup from 0 to learning_ratewarmup_steps = 500# The weight decay to apply to all layers except all bias and LayerNorm weights in AdamW optimizerweight_decay = 0.01main_metric_for_evaluation = "accuracy"

Solo necesitamos definir dos cosas más antes de que podamos empezar a entrenar.

Primero, los 'TrainingArguments', que es una clase que contiene todos los atributos para personalizar el entrenamiento. Allí establecemos la evaluación y los puntos de control que deben realizarse al final de cada época, los directorios de salida y establecemos los hiperparámetros (como la tasa de aprendizaje y los batch_sizes).

Luego, creamos un 'Trainer', donde pasamos el nombre del modelo, el 'TrainingArguments', la función 'compute_metrics', los conjuntos de datos y el extractor de características.

no-line-numbers# Define training argstraining_args = TrainingArguments( output_dir = model_dir, num_train_epochs = num_train_epochs, per_device_train_batch_size = per_device_train_batch_size, per_device_eval_batch_size = per_device_eval_batch_size, warmup_steps = warmup_steps, weight_decay = weight_decay, evaluation_strategy = "epoch", save_strategy = "epoch", logging_strategy = "epoch", logging_dir = f"{output_data_dir}/logs", learning_rate = float(learning_rate), load_best_model_at_end = True, metric_for_best_model = main_metric_for_evaluation,)# Create Trainer instancetrainer = Trainer( model = model, args = training_args, compute_metrics = compute_metrics, train_dataset = train_dataset, eval_dataset = val_dataset, data_collator = default_data_collator, tokenizer = feature_extractor)

Empieza a entrenar llamando a 'trainer.train () ':

no-line-numberstrainer.train()

Al inspeccionar las métricas del entrenamiento, podemos ver cómo la pérdida y la precisión se estabilizan al final del entrenamiento.

no-line-numberslog_history = pd.DataFrame(trainer.state.log_history)log_history = log_history.fillna(0)log_history = log_history.groupby(['epoch']).sum()log_history

no-line-numberslog_history[["loss", "eval_loss", "eval_accuracy", "eval_accuracy_k"]].plot(subplots=True)I I

Figura 3: Pérdida y precisión después del ajuste

Ahora que estamos satisfechos con nuestros resultados, solo tenemos que guardar el modelo entrenado.

no-line-numberstrainer.save_model(model_dir)

Por fin tenemos nuestro modelo ViT perfeccionado. Ahora, necesitamos verificar su rendimiento en el set de prueba. Primero recarguemos nuestro modelo, creemos una nueva instancia de Trainer y, a continuación, llamemos al método `evaluate` para validar el rendimiento del modelo en el conjunto de prueba.

no-line-numbers# Load datasettest_dataset = load_from_disk(test_save_path)# Load trained modelmodel = ViTForImageClassification.from_pretrained('./model')# Load feature extractorfeature_extractor = ViTFeatureExtractor.from_pretrained('./model') # Create Trainer instancetrainer = Trainer( model=model, compute_metrics=compute_metrics, data_collator=default_data_collator, tokenizer=feature_extractor)# Evaluate modeleval_results = trainer.evaluate(eval_dataset=test_dataset)# Writes eval_result to file which can be accessed laterwith open(os.path.join(output_data_dir, "eval_results.json"), "w") as writer: print(f"Logging evaluation results at {output_data_dir}/eval_results.json") writer.write(json.dumps(eval_results))print(json.dumps(eval_results, indent=4))

no-line-numbers{ "eval_loss": 2.441051483154297, "eval_accuracy": 0.48269581056466304, "eval_accuracy_k": 0.7103825136612022, "eval_runtime": 1.9207, "eval_samples_per_second": 285.83, "eval_steps_per_second": 35.924}

Veamos el rendimiento de nuestro modelo en la naturaleza. Obtendremos una imagen aleatoria de la web y veremos cómo el modelo predice las etiquetas más probables para ella:

no-line-numbers# Get test image from the webtest_image_url = 'https://media.cnn.com/api/v1/images/stellar/prod/111024080409-steve-jobs-book.jpg'response = requests.get(test_image_url)test_image = Image.open(BytesIO(response.content))# Resize and display the imageaspect_ratio = test_image.size[0] / test_image.size[1]max_height = 250resized_width = int(max_height * aspect_ratio)resized_img = test_image.resize((resized_width, max_height))display(resized_img)

no-line-numbers# Predict the top k classes for the test imageinputs = feature_extractor(images=test_image, return_tensors="pt").to("cuda")outputs = model(**inputs)logits = outputs.logitstop_classes = torch.topk(outputs.logits, k_for_top_acc).indices.flatten().tolist()for i, class_idx in enumerate(top_classes): print(str(i + 1), "- Predicted class:", model.config.id2label[class_idx])

Resultados

no-line-numbers1 - Predicted class: Education2 - Predicted class: Books and Literature3 - Predicted class: Productivity

Conclusión y trabajo futuro

Al seguir estos pasos y aprovechar las capacidades de ajustar y transferir el aprendizaje con los VIT, demostramos que podemos lograr una buena clasificación de imágenes de referencia en las categorías de taxonomía de la IAB. Esto abre oportunidades para diversas aplicaciones, como la segmentación del contenido, la publicidad contextual, la personalización del contenido y la segmentación de la audiencia.

Con la disponibilidad de modelos previamente entrenados y bibliotecas fáciles de usar, como Hugging Face, el ajuste preciso de los transformadores de visión se ha vuelto más accesible y eficiente.
Al concluir, si bien estamos satisfechos con el rendimiento de referencia que logramos, es esencial considerar posibles trabajos futuros y mejoras del modelo para mejorar el rendimiento del modelo. Estas son algunas áreas en las que centrarse:

Ajuste de hiperparámetros: realice una búsqueda sistemática de hiperparámetros para identificar los valores óptimos, incluida la tasa de aprendizaje, el tamaño del lote y la disminución del peso.

Arquitectura de modelos: explore diferentes arquitecturas de transformadores, como los modelos híbridos que combinan transformadores con CNN, para mejorar aún más el rendimiento.

Aumento de datos: aplique técnicas como el recorte aleatorio, la rotación, el volteo y la fluctuación de color para expandir artificialmente el conjunto de datos de entrenamiento y mejorar la generalización del modelo.

Mejora del conjunto de datos: entrene el modelo en conjuntos de datos más grandes y específicos para tareas. Los conjuntos de entrenamiento pueden variar según la tarea. Por ejemplo, puede depender de si estamos categorizando el contenido web o de vídeo. Además, en cualquier caso, recopilar imágenes adicionales con anotaciones, especialmente para las categorías desafiantes o subrepresentadas, puede mejorar el rendimiento del modelo.

Por último, recuerde estar atento a los últimos avances en este campo, ya que las nuevas técnicas y avances siguen dando forma al mundo de la visión artificial y la inteligencia artificial.

Gracias por leer y, si tiene alguna pregunta o comentario, no dude en ponerse en contacto con nosotros. ¡Feliz ajuste y clasificación de imágenes con ViTS y Hugging Face!

Fuentes

[2010.11929] Una imagen vale 16×16 palabras: transformadores para el reconocimiento de imágenes a escala

Una imagen vale 16 × 16 palabras: transformadores para el reconocimiento de imágenes a escala | Papers With Code

[2108.08810] ¿Los transformadores de visión se parecen a las redes neuronales convolucionales?

Comparación de transformadores de visión y redes neuronales convolucionales para la clasificación de imágenes: una revisión de la literatura

Manténgase a la vanguardia de las últimas tendencias y conocimientos sobre big data, aprendizaje automático e inteligencia artificial. ¡No se lo pierda y suscríbase a nuestro boletín de noticias!

Ajuste de un modelo de Vision Transformer para la clasificación de imágenes en categorías de taxonomía de la IAB

En la era digital actual, con restricciones técnicas y regulaciones legales en constante aumento, la necesidad de contextualizar el contenido para personalizar los anuncios y garantizar la privacidad del usuario nunca ha sido tan importante. Además, los anunciantes se esfuerzan por mantener una asociación positiva y confiable entre su marca y el contenido en el que se muestran sus anuncios. Por lo tanto, la categorización del contenido de texto, imágenes y vídeo puede proporcionar una mejor experiencia de usuario a través de anuncios mejor contextuales, al tiempo que proporciona un mejor rendimiento y garantías a los anunciantes. Destaca cómo el uso de la categorización de imágenes del contenido de un sitio web para colocar anuncios adyacentes significativos puede resultar beneficioso para todas las partes interesadas.

Por lo tanto, la capacidad de clasificar y comprender imágenes se ha vuelto cada vez más valiosa en varios sectores. Ya sea para la organización del contenido, la publicidad dirigida o el análisis de clientes, la clasificación de imágenes desempeña un papel crucial a la hora de extraer información significativa de los datos visuales.

En esta entrada del blog, analizaremos el proceso de ajustar un modelo Vision Transformer (ViT) de la biblioteca Hugging Face para la clasificación de imágenes en las categorías de la taxonomía de contenido del laboratorio tecnológico del Interactive Advertising Bureau (IAB), el estándar del sector de la publicidad. Los Vision Transformers han demostrado recientemente un éxito notable en la visión artificial, lo que los convierte en una opción interesante para la clasificación de imágenes. Al aprovechar la potencia de los modelos previamente entrenados y alinear las predicciones con la taxonomía de la IAB, podemos aprovechar la posibilidad de clasificar las imágenes con precisión.

A lo largo de este post, profundizaremos en los conceptos fundamentales de las VIT, explicando su arquitectura y sus ventajas frente a las técnicas tradicionales de visión por computador. A continuación, presentaremos las categorías taxonómicas de la IAB, destacando su importancia a la hora de organizar el contenido visual. Después, llegaremos al meollo de la entrada del blog: el proceso de ajuste. Empezando por seleccionar un modelo previamente entrenado del centro de modelos Hugging Face, implementaremos rápidamente el preprocesamiento de datos, el entrenamiento de modelos y la evaluación, aprovechando la potencia de Amazon SageMaker Studio.

Comprensión de los transformadores de visión

Los transformadores de visión, introducidos en 2021 por Dosovitskiy y otros, se han convertido en una poderosa alternativa a las arquitecturas tradicionales, como las redes neuronales convolucionales (CNN) en las tareas de visión artificial. Los transformadores, que se diseñaron inicialmente para tareas de procesamiento del lenguaje natural (PNL), han demostrado recientemente un éxito notable en las tareas de clasificación de imágenes.

Un transformador de visión puro divide una imagen en partes más pequeñas y las trata como fichas (de forma similar a las palabras en la PNL). Luego, cada parche se incrusta linealmente y se añaden incrustaciones de posición para realizar la clasificación, utilizando el método de añadir a la secuencia un «símbolo de clasificación» (CLS) que se pueda aprender más. La secuencia de vectores resultante se envía a un codificador transformador estándar y se procesa a través de múltiples capas de mecanismos de autoatención.

Figura 1: Descripción general del modelo (Dosovitskiy, et al. 2021)

Se ha realizado un extenso trabajo para comparar los VIT con las CNN más modernas en cuanto a su desempeño en las tareas de clasificación de imágenes (Maurício, et al. 2023). Vamos a tratar brevemente más información sobre el rendimiento de las dos arquitecturas y lo que las distingue.

En comparación con las CNN, las VIT ofrecen mejores capacidades de escalabilidad y generalización. Cuando se entrena previamente con grandes cantidades de datos y, a continuación, se transfiere a varios centros de reconocimiento de imágenes de tamaño mediano o pequeño (ImageNet, CIFAR-100, VTAB), el ViT obtiene excelentes resultados en comparación con las CNN más modernas, al tiempo que requiere muchos menos recursos computacionales para su entrenamiento.

Por lo tanto, al capacitar previamente a los VIT en conjuntos de datos a gran escala, como ImageNet-21k (14 millones de imágenes, 21 843 clases), podemos aprovechar las representaciones aprendidas para adaptarnos a tareas específicas de clasificación de imágenes mediante un ajuste fino, lo que reduce la necesidad de una formación exhaustiva desde cero y, por lo tanto, el tiempo de capacitación y los costos generales.

Sin embargo, las CNN obtienen excelentes resultados cuando se entrenan desde cero en volúmenes de datos más pequeños como los que requieren Vision Transformers. Este comportamiento diferente parece deberse a la presencia en las CNN de sesgos inductivos, que estas redes aprovechan para captar más rápidamente las particularidades de las imágenes analizadas, aunque, por otro lado, acaben dificultando la comprensión de las relaciones globales. Por otro lado, los VIT están libres de estos sesgos, lo que les permite captar también las dependencias de largo alcance en las imágenes, a costa de disponer de más datos de entrenamiento. El mecanismo de autoatención permite al modelo captar las dependencias globales y locales dentro de la imagen, lo que le permite comprender las relaciones contextuales entre las diferentes regiones.

Entre otras diferencias notables entre las dos arquitecturas, las VIT funcionan mejor y son más resistentes a las imágenes con perturbaciones naturales o adversas en comparación con las CNN, y las VIT son más resistentes a los ataques adversarios y las CNN son más sensibles a las funciones de alta frecuencia.

En general, la arquitectura basada en transformadores (o la combinación de VIT con CNN) permite una mayor precisión en comparación con las redes de CNN, y funciona mejor en comparación con las redes de CNN gracias al funcionamiento del mecanismo de autoatención. La arquitectura ViTS es más ligera que la de las CNN, ya que consume menos recursos computacionales y requiere menos tiempo de entrenamiento, y es más sólida que las redes CNN para imágenes que tienen ruido o están aumentadas.

Por otro lado, las CNN pueden generalizar mejor con conjuntos de datos más pequeños y obtener una mayor precisión que los VIT, pero por el contrario, los VIT tienen la ventaja de aprender mejor la información con menos imágenes cuando se ajustan con precisión. Sin embargo, se ha observado que el rendimiento de los ViT puede tener problemas con la generalización cuando se entrena con conjuntos de datos de imágenes más pequeños.

Comprensión de la taxonomía del contenido de la IAB

El Interactive Advertising Bureau (IAB) ha desarrollado una taxonomía integral que desempeña un papel fundamental en la organización y la categorización del contenido digital. Su taxonomía proporciona un marco estandarizado para la clasificación del contenido, lo que permite una segmentación eficiente del contenido, la publicidad contextual y la segmentación de la audiencia.

La taxonomía de la IAB está estructurada jerárquicamente, con varios niveles de categorías y subcategorías. En el nivel superior, cubre amplias categorías de contenido, como arte y entretenimiento, deportes y más.

Luego, cada categoría se divide en subcategorías más específicas, lo que crea un sistema de clasificación más preciso y granular que puede capturar una amplia gama de tipos de contenido. Por ejemplo, dentro de la categoría Deportes, hay subcategorías como baloncesto, fútbol y tenis.

En la industria de la publicidad digital, la taxonomía de la IAB cumple varios propósitos. Ayuda a los anunciantes a alinear sus campañas con categorías de contenido específicas, garantizando que sus anuncios se muestren en contextos relevantes. Los editores de contenido pueden usar la taxonomía para categorizar su contenido de manera eficaz, lo que facilita a los usuarios el descubrimiento de información relevante. Además, la taxonomía de la IAB facilita la segmentación de la audiencia al permitir a los anunciantes segmentar categorías específicas que se ajusten a los intereses de su público objetivo.

En la siguiente sección, exploraremos cómo ajustar un modelo ViT para clasificar con precisión las imágenes en las categorías taxonómicas específicas de la IAB.

Bien: ajuste de un modelo de Vision Transformer

El ajuste fino de un modelo de transformador de visión implica adaptar un modelo previamente entrenado a un conjunto de datos a gran escala y ajustarlo a tareas posteriores más pequeñas, como la clasificación de imágenes en las categorías de taxonomía de la IAB. Este proceso nos permite aprovechar los conocimientos y las representaciones aprendidos con el modelo previamente entrenado, lo que nos permite ahorrar tiempo y recursos computacionales. Para ello, eliminamos el cabezal de predicción previamente entrenado y colocamos una nueva capa de retroalimentación, en la que K salidas representan el número de clases posteriores.

Para afinar el modelo ViT utilizaremos la biblioteca Hugging Face. Esta biblioteca ofrece una amplia gama de modelos de transformadores de visión previamente entrenados y proporciona una interfaz fácil de usar para ajustar e implementar estos modelos. Al utilizar la biblioteca Hugging Face, podemos aprovechar la disponibilidad de sus modelos, su fácil integración, el sólido apoyo de la comunidad y los beneficios de la transferencia del aprendizaje.

Como queríamos abordar este problema con un modelo de entrenamiento supervisado que utilizara las categorías de la IAB como etiquetas, necesitábamos un conjunto de datos debidamente etiquetado. Para ello, recopilamos y etiquetamos un conjunto de datos interno de imágenes permitidas para uso comercial. Como punto de referencia, las imágenes se etiquetan individualmente con una única categoría IAB de nivel 1. El conjunto de datos se compone de archivos de imágenes, organizados en carpetas por categoría, de modo que podemos cargarlos fácilmente en el formato adecuado mediante la biblioteca de conjuntos de datos de Hugging Face.

Con las funciones de Studio de SageMaker, podemos lanzar fácilmente una libreta respaldada por una instancia de GPU, como una ml.g4dn.xlarge, para llevar a cabo nuestro experimento de entrenamiento de un modelo de clasificación de referencia.

Para empezar, instalemos primero las bibliotecas necesarias de Hugging Face y PyTorch en el entorno virtual de nuestro portátil:

no-line-numbers!pip install transformers==4.26.1 datasets==2.10.1 evaluate==0.4.0 -q
no-line-numbers!pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 -q

Tenga en cuenta que el signo de exclamación (!) nos permite ejecutar comandos de shell desde una celda de código de Jupyter Notebook.

Ahora, hagamos las importaciones necesarias para que el portátil funcione correctamente:

no-line-numbersimport evaluateimport jsonimport numpy as npimport osimport pandas as pdimport pyarrow as paimport requestsimport torchfrom datasets import load_dataset, load_from_disk, Dataset, Features, Array3Dfrom io import BytesIOfrom transformers import AutoProcessor, ViTFeatureExtractor, ViTForImageClassification, Trainer, TrainingArguments, default_data_collatorfrom typing import Tuplefrom PIL import Image

Vamos a definir algunas variables:

no-line-numbers# The directory where our images are saved in folders by categoryimages_dir = "./dataset"# The output directory of the processed datasetstrain_save_path = "./processed-datasets/train"val_save_path = "./processed-datasets/val"test_save_path = "./processed-datasets/test"# Sizes of dataset splitsval_size = 0.2test_size = 0.1# Name of model as named in the HuggingFace Hubmodel_name = "google/vit-base-patch16-224-in21k"

Aprovechamos el crear un conjunto de datos de imágenes función para cargar fácilmente nuestro conjunto de datos personalizado especificando nuestra carpeta local donde se almacenan las imágenes en carpetas por categoría.

no-line-numbersdataset = load_dataset("imagefolder", data_dir=images_dir, split='train')

Realicemos un poco de limpieza de datos y eliminemos del conjunto de datos las imágenes que no sean RGB (canal único, escala de grises).

no-line-numbers# Remove from dataset images which are non-RGB (single-channel, grayscale)condition = lambda data: data['image'].mode == 'RGB'dataset = dataset.filter(condition)

Ahora dividimos nuestro conjunto de datos en conjuntos de entrenamiento, validación y prueba.

no-line-numbersdef split_dataset( dataset: Dataset, val_size: float=0.2, test_size: float=0.1) -> Tuple[Dataset, Dataset, Dataset]: """ Returns a tuple with three random train, validation and test subsets by splitting the passed dataset. Size of the validation and test sets defined as a fraction of 1 with the `val_size` and `test_size` arguments. """ print("Splitting dataset into train, validation and test sets...") # Split dataset into train and (val + test) sets split_size = round(val_size + test_size, 3) dataset = dataset.train_test_split(shuffle=True, test_size=split_size) # Split (val + test) into val and test sets split_ratio = round(test_size / (test_size + val_size), 3) val_test_sets = dataset['test'].train_test_split(shuffle=True, test_size=split_ratio) train_dataset = dataset["train"] val_dataset = val_test_sets["train"] test_dataset = val_test_sets["test"] return train_dataset, val_dataset, test_dataset# Split dataset into train and test setstrain_dataset, val_dataset, test_dataset = split_dataset(dataset, val_size, test_size)

Por último, podemos preparar estas imágenes para nuestro modelo.

Cuando se entrenan los modelos de ViT, se aplican transformaciones específicas a las imágenes que se introducen en ellos para que se ajusten al formato de entrada esperado.

Para asegurarnos de aplicar las transformaciones correctas, utilizaremos un «autoprocesador» inicializado con una configuración que se guardó en el Hub de Hugging Face junto con la preentrenada «google/vit-base-patch16-224 en 21k» modelo que planeamos usar.

Por lo tanto, preprocesamos nuestros conjuntos de datos con el autoprocesador de imágenes del modelo:

no-line-numbersdef process_examples(examples, image_processor): """Processor helper function. Used to process batches of images using the passed image_processor. Parameters ---------- examples A batch of image examples. image_processor A HuggingFace image processor for the selected model. Returns ------- examples A batch of processed image examples. """ # Get batch of images images = examples['image'] # Preprocess inputs = image_processor(images=images) # Add pixel_values examples['pixel_values'] = inputs['pixel_values'] return examplesdef apply_processing( model_name: str, train_dataset: Dataset, val_dataset: Dataset, test_dataset: Dataset) -> Tuple[Dataset, Dataset, Dataset]: """ Apply model's image AutoProcessor to transform train, validation and test subsets. Returns train, validation and test datasets with `pixel_values` in torch tensor type. """ # Extend the features features = Features({ **train_dataset.features, 'pixel_values': Array3D(dtype="float32", shape=(3, 224, 224)), }) # Instantiate image_processor image_processor = AutoProcessor.from_pretrained(model_name) # Preprocess images train_dataset = train_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) val_dataset = val_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) test_dataset = test_dataset.map(process_examples, batched=True, features=features, fn_kwargs={"image_processor": image_processor}) # Set to torch format for training train_dataset.set_format('torch', columns=['pixel_values', 'label']) val_dataset.set_format('torch', columns=['pixel_values', 'label']) test_dataset.set_format('torch', columns=['pixel_values', 'label']) # Remove unused column train_dataset = train_dataset.remove_columns("image") val_dataset = val_dataset.remove_columns("image") test_dataset = test_dataset.remove_columns("image") return train_dataset, val_dataset, test_dataset# Apply AutoProcessortrain_dataset, val_dataset, test_dataset = apply_processing(model_name, train_dataset, val_dataset, test_dataset)


Ahora guardamos nuestros conjuntos de datos procesados:

no-line-numbers# Save train, validation and test preprocessed datasetstrain_dataset.save_to_disk(train_save_path, num_shards=1)val_dataset.save_to_disk(val_save_path, num_shards=1)test_dataset.save_to_disk(test_save_path, num_shards=1)


Pasemos a la etapa de entrenamiento. Empezamos cargando los conjuntos de datos del tren y la validación.

no-line-numberstrain_dataset = load_from_disk(train_save_path)val_dataset = load_from_disk(val_save_path)


Nuestro nuevo modelo perfeccionado tendrá la siguiente cantidad de clases de salida:

no-line-numbersnum_classes = train_dataset.features["label"].num_classes

Ahora, definamos una 'vitForImageClassification', que coloca una capa lineal (nn.Linear) sobre un modelo de ViT previamente entrenado. La capa lineal se coloca encima del último estado oculto del token [CLS], lo que sirve como una buena representación de una imagen completa.

También especificamos el número de neuronas de salida configurando el parámetro `num_labels`.

no-line-numbers# Download model from model hubmodel = ViTForImageClassification.from_pretrained(model_name, num_labels=num_classes)# Download feature extractor from hubfeature_extractor = ViTFeatureExtractor.from_pretrained(model_name)

Vamos a continuar definiendo una función `compute_metrics`. Esta función se usa para calcular cualquier métrica objetivo definida en cada paso de la evaluación.

Aquí, utilizamos la métrica de «precisión» de los «conjuntos de datos», que se puede usar fácilmente para comparar las predicciones con las etiquetas esperadas en el conjunto de validación.

También definimos una métrica personalizada para calcular la precisión en «k» de nuestras predicciones. La precisión en «k» es el número de casos en los que la etiqueta real se encuentra en el conjunto de las «k» clases más probables.

no-line-numbers# K for top accuracy metrick_for_top_acc = 3# Compute metrics function for binary classificationacc_metric = evaluate.load("accuracy", module_type="metric")def compute_metrics(eval_pred): predicted_probs, labels = eval_pred # Accuracy predicted_labels = np.argmax(predicted_probs, axis=1) acc = acc_metric.compute(predictions=predicted_labels, references=labels) # Top-K Accuracy top_k_indexes = [np.argpartition(row, -k_for_top_acc)[-k_for_top_acc:] for row in predicted_probs] top_k_classes = [top_k_indexes[i][np.argsort(row[top_k_indexes[i]])] for i, row in enumerate(predicted_probs)] top_k_classes = np.flip(np.array(top_k_classes), 1) acc_k = { f"accuracy_k" : sum([label in predictions for predictions, label in zip(top_k_classes, labels)]) / len(labels) } # Merge metrics acc.update(acc_k) return acc

Como nos gustaría conocer los nombres de las clases reales como salidas, en lugar de solo índices enteros, configuramos el mapeo 'id2label' y 'label2id' como atributos para la configuración del modelo (al que se puede acceder como model.config):

no-line-numbers# Change labelsid2label = {key:train_dataset.features["label"].names[index] for index,key in enumerate(model.config.id2label.keys())}label2id = {train_dataset.features["label"].names[index]:value for index,value in enumerate(model.config.label2id.values())}model.config.id2label = id2labelmodel.config.label2id = label2id

A continuación, especificamos los directorios de salida del modelo y otros artefactos, y el conjunto de hiperparámetros que utilizaremos para el entrenamiento.

no-line-numbersmodel_dir = "./model"output_data_dir = "./outputs"# Total number of training epochs to performnum_train_epochs = 15# The batch size per GPU/TPU core/CPU for trainingper_device_train_batch_size = 32# The batch size per GPU/TPU core/CPU for evaluationper_device_eval_batch_size = 64# The initial learning rate for AdamW optimizerlearning_rate = 2e-5# Number of steps used for a linear warmup from 0 to learning_ratewarmup_steps = 500# The weight decay to apply to all layers except all bias and LayerNorm weights in AdamW optimizerweight_decay = 0.01main_metric_for_evaluation = "accuracy"

Solo necesitamos definir dos cosas más antes de que podamos empezar a entrenar.

Primero, los 'TrainingArguments', que es una clase que contiene todos los atributos para personalizar el entrenamiento. Allí establecemos la evaluación y los puntos de control que deben realizarse al final de cada época, los directorios de salida y establecemos los hiperparámetros (como la tasa de aprendizaje y los batch_sizes).

Luego, creamos un 'Trainer', donde pasamos el nombre del modelo, el 'TrainingArguments', la función 'compute_metrics', los conjuntos de datos y el extractor de características.

no-line-numbers# Define training argstraining_args = TrainingArguments( output_dir = model_dir, num_train_epochs = num_train_epochs, per_device_train_batch_size = per_device_train_batch_size, per_device_eval_batch_size = per_device_eval_batch_size, warmup_steps = warmup_steps, weight_decay = weight_decay, evaluation_strategy = "epoch", save_strategy = "epoch", logging_strategy = "epoch", logging_dir = f"{output_data_dir}/logs", learning_rate = float(learning_rate), load_best_model_at_end = True, metric_for_best_model = main_metric_for_evaluation,)# Create Trainer instancetrainer = Trainer( model = model, args = training_args, compute_metrics = compute_metrics, train_dataset = train_dataset, eval_dataset = val_dataset, data_collator = default_data_collator, tokenizer = feature_extractor)

Empieza a entrenar llamando a 'trainer.train () ':

no-line-numberstrainer.train()

Al inspeccionar las métricas del entrenamiento, podemos ver cómo la pérdida y la precisión se estabilizan al final del entrenamiento.

no-line-numberslog_history = pd.DataFrame(trainer.state.log_history)log_history = log_history.fillna(0)log_history = log_history.groupby(['epoch']).sum()log_history

no-line-numberslog_history[["loss", "eval_loss", "eval_accuracy", "eval_accuracy_k"]].plot(subplots=True)I I

Figura 3: Pérdida y precisión después del ajuste

Ahora que estamos satisfechos con nuestros resultados, solo tenemos que guardar el modelo entrenado.

no-line-numberstrainer.save_model(model_dir)

Por fin tenemos nuestro modelo ViT perfeccionado. Ahora, necesitamos verificar su rendimiento en el set de prueba. Primero recarguemos nuestro modelo, creemos una nueva instancia de Trainer y, a continuación, llamemos al método `evaluate` para validar el rendimiento del modelo en el conjunto de prueba.

no-line-numbers# Load datasettest_dataset = load_from_disk(test_save_path)# Load trained modelmodel = ViTForImageClassification.from_pretrained('./model')# Load feature extractorfeature_extractor = ViTFeatureExtractor.from_pretrained('./model') # Create Trainer instancetrainer = Trainer( model=model, compute_metrics=compute_metrics, data_collator=default_data_collator, tokenizer=feature_extractor)# Evaluate modeleval_results = trainer.evaluate(eval_dataset=test_dataset)# Writes eval_result to file which can be accessed laterwith open(os.path.join(output_data_dir, "eval_results.json"), "w") as writer: print(f"Logging evaluation results at {output_data_dir}/eval_results.json") writer.write(json.dumps(eval_results))print(json.dumps(eval_results, indent=4))

no-line-numbers{ "eval_loss": 2.441051483154297, "eval_accuracy": 0.48269581056466304, "eval_accuracy_k": 0.7103825136612022, "eval_runtime": 1.9207, "eval_samples_per_second": 285.83, "eval_steps_per_second": 35.924}

Veamos el rendimiento de nuestro modelo en la naturaleza. Obtendremos una imagen aleatoria de la web y veremos cómo el modelo predice las etiquetas más probables para ella:

no-line-numbers# Get test image from the webtest_image_url = 'https://media.cnn.com/api/v1/images/stellar/prod/111024080409-steve-jobs-book.jpg'response = requests.get(test_image_url)test_image = Image.open(BytesIO(response.content))# Resize and display the imageaspect_ratio = test_image.size[0] / test_image.size[1]max_height = 250resized_width = int(max_height * aspect_ratio)resized_img = test_image.resize((resized_width, max_height))display(resized_img)

no-line-numbers# Predict the top k classes for the test imageinputs = feature_extractor(images=test_image, return_tensors="pt").to("cuda")outputs = model(**inputs)logits = outputs.logitstop_classes = torch.topk(outputs.logits, k_for_top_acc).indices.flatten().tolist()for i, class_idx in enumerate(top_classes): print(str(i + 1), "- Predicted class:", model.config.id2label[class_idx])

Resultados

no-line-numbers1 - Predicted class: Education2 - Predicted class: Books and Literature3 - Predicted class: Productivity

Conclusión y trabajo futuro

Al seguir estos pasos y aprovechar las capacidades de ajustar y transferir el aprendizaje con los VIT, demostramos que podemos lograr una buena clasificación de imágenes de referencia en las categorías de taxonomía de la IAB. Esto abre oportunidades para diversas aplicaciones, como la segmentación del contenido, la publicidad contextual, la personalización del contenido y la segmentación de la audiencia.

Con la disponibilidad de modelos previamente entrenados y bibliotecas fáciles de usar, como Hugging Face, el ajuste preciso de los transformadores de visión se ha vuelto más accesible y eficiente.
Al concluir, si bien estamos satisfechos con el rendimiento de referencia que logramos, es esencial considerar posibles trabajos futuros y mejoras del modelo para mejorar el rendimiento del modelo. Estas son algunas áreas en las que centrarse:

Ajuste de hiperparámetros: realice una búsqueda sistemática de hiperparámetros para identificar los valores óptimos, incluida la tasa de aprendizaje, el tamaño del lote y la disminución del peso.

Arquitectura de modelos: explore diferentes arquitecturas de transformadores, como los modelos híbridos que combinan transformadores con CNN, para mejorar aún más el rendimiento.

Aumento de datos: aplique técnicas como el recorte aleatorio, la rotación, el volteo y la fluctuación de color para expandir artificialmente el conjunto de datos de entrenamiento y mejorar la generalización del modelo.

Mejora del conjunto de datos: entrene el modelo en conjuntos de datos más grandes y específicos para tareas. Los conjuntos de entrenamiento pueden variar según la tarea. Por ejemplo, puede depender de si estamos categorizando el contenido web o de vídeo. Además, en cualquier caso, recopilar imágenes adicionales con anotaciones, especialmente para las categorías desafiantes o subrepresentadas, puede mejorar el rendimiento del modelo.

Por último, recuerde estar atento a los últimos avances en este campo, ya que las nuevas técnicas y avances siguen dando forma al mundo de la visión artificial y la inteligencia artificial.

Gracias por leer y, si tiene alguna pregunta o comentario, no dude en ponerse en contacto con nosotros. ¡Feliz ajuste y clasificación de imágenes con ViTS y Hugging Face!

Fuentes

[2010.11929] Una imagen vale 16×16 palabras: transformadores para el reconocimiento de imágenes a escala

Una imagen vale 16 × 16 palabras: transformadores para el reconocimiento de imágenes a escala | Papers With Code

[2108.08810] ¿Los transformadores de visión se parecen a las redes neuronales convolucionales?

Comparación de transformadores de visión y redes neuronales convolucionales para la clasificación de imágenes: una revisión de la literatura

Manténgase a la vanguardia de las últimas tendencias y conocimientos sobre big data, aprendizaje automático e inteligencia artificial. ¡No se lo pierda y suscríbase a nuestro boletín de noticias!