# Legendação de imagens

A legendação de imagens é a tarefa de prever uma legenda para uma imagem dada. Aplicações comuns no mundo real incluem auxiliar pessoas com deficiência visual, o que pode ajudá-las a navegar por diferentes situações. Portanto, a legendação de imagens ajuda a melhorar a acessibilidade do conteúdo para as pessoas, descrevendo-lhes as imagens.

Este guia mostrará como:

* Ajuste fino de um modelo de legendagem de imagens.
* Use o modelo ajustado para inferência.

Antes de começar, verifique se você tem todas as bibliotecas necessárias instaladas:

```bash
pip install transformers datasets evaluate -q
pip install jiwer -q
```

Recomendamos que você faça login na sua conta do Hugging Face para que possa enviar e compartilhar seu modelo com a comunidade. Quando solicitado, insira seu token para fazer login:

```python
from huggingface_hub import notebook_login

notebook_login()
```

## Carregue o conjunto de dados de legendas BLIP de Pokémon

Use a biblioteca 🤗 Dataset para carregar um dataset que consiste em pares {image-caption}. Para criar seu próprio dataset de legendagem de imagens em PyTorch, você pode seguir [este notebook](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/GIT/Fine_tune_GIT_on_an_image_captioning_dataset.ipynb).

```python
from datasets import load_dataset

ds = load_dataset("lambdalabs/pokemon-blip-captions")
ds
```

```bash
DatasetDict({
    train: Dataset({
        features: ['image', 'text'],
        num_rows: 833
    })
})
```

O conjunto de dados possui duas características, `image` e `text`.

Muitos conjuntos de dados de legendagem de imagens contêm várias legendas por imagem. Nesses casos, uma estratégia comum é amostrar aleatoriamente uma legenda entre as disponíveis durante o treinamento.

Divida o split de treino do conjunto de dados em um conjunto de treino e um conjunto de teste com o método [train_test_split](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.train_test_split):

```python
ds = ds["train"].train_test_split(test_size=0.1)
train_ds = ds["train"]
test_ds = ds["test"]
```

Vamos visualizar alguns exemplos do conjunto de treinamento.

```python
from textwrap import wrap
import matplotlib.pyplot as plt
import numpy as np

def plot_images(images, captions):
    plt.figure(figsize=(20, 20))
    for i in range(len(images)):
        ax = plt.subplot(1, len(images), i + 1)
        caption = captions[i]
        caption = "\n".join(wrap(caption, 12))
        plt.title(caption)
        plt.imshow(images[i])
        plt.axis("off")

sample_images_to_visualize = [np.array(train_ds[i]["image"]) for i in range(5)]
sample_captions = [train_ds[i]["text"] for i in range(5)]
plot_images(sample_images_to_visualize, sample_captions)
```

    

## Pré-processar o conjunto de dados

Como o conjunto de dados possui duas modalidades (imagem e texto), o pipeline de pré-processamento irá pré-processar as imagens e as legendas.

Para isso, carregue a classe de processador associada ao modelo que você está prestes a ajustar finamente.

```python
from transformers import AutoProcessor

checkpoint = "microsoft/git-base"
processor = AutoProcessor.from_pretrained(checkpoint)
```

O processador pré-processará a imagem internamente (o que inclui redimensionamento e escalonamento de pixels) e tokenizará a legenda.

```python
def transforms(example_batch):
    images = [x for x in example_batch["image"]]
    captions = [x for x in example_batch["text"]]
    inputs = processor(images=images, text=captions, padding="max_length")
    inputs.update({"labels": inputs["input_ids"]})
    return inputs

train_ds.set_transform(transforms)
test_ds.set_transform(transforms)
```

Com o conjunto de dados pronto, você agora pode configurar o modelo para o ajuste fino.

## Carregar um modelo base

Carregue o ["microsoft/git-base"](https://huggingface.co/microsoft/git-base) em um objeto [AutoModelForCausalLM](/docs/transformers/main/pt/model_doc/auto#transformers.AutoModelForCausalLM).

```python
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(checkpoint)
```

## Avaliar

Os modelos de legendagem de imagens são tipicamente avaliados com o [Rouge Score](https://huggingface.co/spaces/evaluate-metric/rouge) ou o [Word Error Rate](https://huggingface.co/spaces/evaluate-metric/wer). Neste guia, você usará o Word Error Rate (WER).

Usamos a biblioteca 🤗 Evaluate para isso. Para possíveis limitações e outras armadilhas do WER, consulte [este guia](https://huggingface.co/spaces/evaluate-metric/wer).

```python
from evaluate import load
import torch

wer = load("wer")

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predicted = logits.argmax(-1)
    decoded_labels = processor.batch_decode(labels, skip_special_tokens=True)
    decoded_predictions = processor.batch_decode(predicted, skip_special_tokens=True)
    wer_score = wer.compute(predictions=decoded_predictions, references=decoded_labels)
    return {"wer_score": wer_score}
```

## Treinar

Agora, você está pronto para começar o ajuste fino do modelo. Você usará o 🤗 [Trainer](/docs/transformers/main/pt/main_classes/trainer#transformers.Trainer) para isso.

Primeiro, defina os argumentos de treinamento usando [TrainingArguments](/docs/transformers/main/pt/main_classes/trainer#transformers.TrainingArguments).

```python
from transformers import TrainingArguments, Trainer

model_name = checkpoint.split("/")[1]

training_args = TrainingArguments(
    output_dir=f"{model_name}-pokemon",
    learning_rate=5e-5,
    num_train_epochs=50,
    fp16=True,
    per_device_train_batch_size=32,
    per_device_eval_batch_size=32,
    gradient_accumulation_steps=2,
    save_total_limit=3,
    eval_strategy="steps",
    eval_steps=50,
    save_strategy="steps",
    save_steps=50,
    logging_steps=50,
    remove_unused_columns=False,
    push_to_hub=True,
    label_names=["labels"],
    load_best_model_at_end=True,
)
```

Em seguida, passe-os, junto com os conjuntos de dados e o modelo, para o 🤗 Trainer.

```python
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_ds,
    eval_dataset=test_ds,
    compute_metrics=compute_metrics,
)
```

Para iniciar o treinamento, basta chamar [train()](/docs/transformers/main/pt/main_classes/trainer#transformers.Trainer.train) no objeto [Trainer](/docs/transformers/main/pt/main_classes/trainer#transformers.Trainer).

```python
trainer.train()
```

Você deve observar que a perda de treinamento diminui de forma suave à medida que o treinamento avança.

Quando o treinamento for concluído, compartilhe seu modelo no Hub com o método [push_to_hub()](/docs/transformers/main/pt/main_classes/trainer#transformers.Trainer.push_to_hub) para que todos possam usá-lo:

```python
trainer.push_to_hub()
```

## Inferência

Pegue uma imagem de exemplo de `test_ds` para testar o modelo.

```python
from PIL import Image
import requests

url = "https://huggingface.co/datasets/sayakpaul/sample-datasets/resolve/main/pokemon.png"
image = Image.open(requests.get(url, stream=True).raw)
image
```

    

Prepare a imagem para o modelo.

```python
from accelerate import Accelerator

device = Accelerator().device
inputs = processor(images=image, return_tensors="pt").to(device)
pixel_values = inputs.pixel_values
```

Chame `generate` e decodifique as previsões.

```python
generated_ids = model.generate(pixel_values=pixel_values, max_length=50)
generated_caption = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(generated_caption)
```

```bash
a drawing of a pink and blue pokemon
```

Parece que o modelo ajustado gerou uma legenda bastante boa!

