# Phân loại hình ảnh

Phân loại hình ảnh gán một nhãn hoặc lớp cho một hình ảnh. Khác với phân loại văn bản hoặc âm thanh, đầu vào là các giá trị pixel cấu thành nên hình ảnh. Phân loại hình ảnh có nhiều ứng dụng, chẳng hạn như phát hiện thiệt hại sau thảm họa thiên nhiên, theo dõi sức khỏe cây trồng, hoặc hỗ trợ sàng lọc hình ảnh y tế để tìm dấu hiệu bệnh tật.

Hướng dẫn này minh họa cách:

1. Tinh chỉnh [ViT](../model_doc/vit) trên bộ dữ liệu [Food-101](https://huggingface.co/datasets/ethz/food101) để phân loại món ăn trong hình ảnh.
2. Sử dụng mô hình đã tinh chỉnh của bạn để suy luận.

Để xem tất cả các kiến trúc và checkpoint tương thích với tác vụ này, chúng tôi khuyến nghị bạn kiểm tra [trang tác vụ](https://huggingface.co/tasks/image-classification)

Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt tất cả các thư viện cần thiết:

```bash
pip install transformers datasets evaluate accelerate pillow torchvision scikit-learn trackio
```

Chúng tôi khuyến khích bạn đăng nhập vào tài khoản Hugging Face của mình để tải lên và chia sẻ mô hình của bạn với cộng đồng. Khi được yêu cầu, hãy nhập token của bạn để đăng nhập:

```py
>>> from huggingface_hub import notebook_login

>>> notebook_login()
```

## Tải bộ dữ liệu Food-101

Bắt đầu bằng cách tải một tập con nhỏ hơn của bộ dữ liệu Food-101 từ thư viện 🤗 Datasets. Điều này sẽ cho bạn cơ hội thử nghiệm và đảm bảo mọi thứ hoạt động trước khi dành thêm thời gian huấn luyện trên toàn bộ bộ dữ liệu.

```py
>>> from datasets import load_dataset

>>> food = load_dataset("ethz/food101", split="train[:5000]")
```

Chia split `train` của bộ dữ liệu thành tập train và tập test bằng phương thức [train_test_split](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.train_test_split):

```py
>>> food = food.train_test_split(test_size=0.2)
```

Sau đó, hãy xem một ví dụ:

```py
>>> food["train"][0]
{'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=512x512 at 0x7F52AFC8AC50>,
 'label': 79}
```

Mỗi ví dụ trong bộ dữ liệu có hai trường:

- `image`: một hình ảnh PIL của món ăn
- `label`: lớp nhãn của món ăn

Để giúp mô hình dễ dàng lấy tên nhãn từ id nhãn, hãy tạo một từ điển ánh xạ tên nhãn sang số nguyên và ngược lại:

```py
>>> labels = food["train"].features["label"].names
>>> label2id, id2label = dict(), dict()
>>> for i, label in enumerate(labels):
...     label2id[label] = str(i)
...     id2label[str(i)] = label
```

Bây giờ bạn có thể chuyển đổi id nhãn thành tên nhãn:

```py
>>> id2label[str(79)]
'prime_rib'
```

## Tiền xử lý

Bước tiếp theo là nạp một bộ xử lý ảnh ViT để xử lý ảnh thành một tensor:

```py
>>> from transformers import AutoImageProcessor

>>> checkpoint = "google/vit-base-patch16-224-in21k"
>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint)
```

Áp dụng một số phép biến đổi hình ảnh lên các hình ảnh để giúp mô hình chống lại hiện tượng overfitting tốt hơn. Ở đây bạn sẽ sử dụng module [`transforms`](https://pytorch.org/vision/stable/transforms.html) của torchvision, nhưng bạn cũng có thể sử dụng bất kỳ thư viện hình ảnh nào bạn thích.

Cắt một phần ngẫu nhiên của ảnh, thay đổi kích thước và chuẩn hóa bằng giá trị trung bình và độ lệch chuẩn của ảnh:

```py
>>> from torchvision.transforms import RandomResizedCrop, Compose, Normalize, ToTensor

>>> normalize = Normalize(mean=image_processor.image_mean, std=image_processor.image_std)
>>> size = (
...     image_processor.size["shortest_edge"]
...     if "shortest_edge" in image_processor.size
...     else (image_processor.size["height"], image_processor.size["width"])
... )
>>> _transforms = Compose([RandomResizedCrop(size), ToTensor(), normalize])
```

Sau đó, tạo một hàm tiền xử lý để áp dụng các phép biến đổi và trả về `pixel_values` - đầu vào cho mô hình - của hình ảnh:

```py
>>> def transforms(examples):
...     examples["pixel_values"] = [_transforms(img.convert("RGB")) for img in examples["image"]]
...     del examples["image"]
...     return examples
```

Để áp dụng hàm tiền xử lý trên toàn bộ bộ dữ liệu, hãy sử dụng phương thức [with_transform](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.with_transform) của 🤗 Datasets. Các phép biến đổi sẽ được áp dụng theo thời gian thực khi bạn tải một phần tử của bộ dữ liệu:

```py
>>> food = food.with_transform(transforms)
```

Bây giờ hãy tạo một lô ví dụ sử dụng [DefaultDataCollator](/docs/transformers/main/vi/main_classes/data_collator#transformers.DefaultDataCollator). Khác với các data collator khác trong 🤗 Transformers, `DefaultDataCollator` không áp dụng các bước tiền xử lý bổ sung như padding.

```py
>>> from transformers import DefaultDataCollator

>>> data_collator = DefaultDataCollator()
```

## Đánh giá

Việc đưa một chỉ số vào trong quá trình huấn luyện thường hữu ích để đánh giá hiệu suất của mô hình. Bạn có thể nhanh chóng tải một phương pháp đánh giá bằng thư viện 🤗 [Evaluate](https://huggingface.co/docs/evaluate/index). Đối với tác vụ này, hãy tải chỉ số [accuracy](https://huggingface.co/spaces/evaluate-metric/accuracy) (xem [quick tour](https://huggingface.co/docs/evaluate/a_quick_tour) của 🤗 Evaluate để tìm hiểu thêm về cách tải và tính toán một chỉ số):

```py
>>> import evaluate

>>> accuracy = evaluate.load("accuracy")
```

Sau đó, tạo một hàm truyền các dự đoán và nhãn của bạn vào [compute](https://huggingface.co/docs/evaluate/main/en/package_reference/main_classes#evaluate.EvaluationModule.compute) để tính độ chính xác:

```py
>>> import numpy as np

>>> def compute_metrics(eval_pred):
...     predictions, labels = eval_pred
...     predictions = np.argmax(predictions, axis=1)
...     return accuracy.compute(predictions=predictions, references=labels)
```

Hàm `compute_metrics` của bạn đã sẵn sàng, và bạn sẽ quay lại với nó khi thiết lập quá trình huấn luyện.

## Huấn luyện

Nếu bạn chưa quen với việc tinh chỉnh mô hình bằng [Trainer](/docs/transformers/main/vi/main_classes/trainer#transformers.Trainer), hãy xem hướng dẫn cơ bản [tại đây](../training)!

Bạn đã sẵn sàng để bắt đầu huấn luyện mô hình của mình! Nạp ViT bằng [AutoModelForImageClassification](/docs/transformers/main/vi/model_doc/auto#transformers.AutoModelForImageClassification). Chỉ định số lượng nhãn cùng với số nhãn dự kiến, và các ánh xạ nhãn:

```py
>>> from transformers import AutoModelForImageClassification, TrainingArguments, Trainer

>>> model = AutoModelForImageClassification.from_pretrained(
...     checkpoint,
...     num_labels=len(labels),
...     id2label=id2label,
...     label2id=label2id,
... )
```

Tới bước này, chỉ còn ba bước nữa:

1. Định nghĩa các siêu tham số huấn luyện của bạn trong [TrainingArguments](/docs/transformers/main/vi/main_classes/trainer#transformers.TrainingArguments). Điều quan trọng là bạn không được xóa các cột không sử dụng vì điều đó sẽ làm mất cột `image`. Nếu không có cột `image`, bạn sẽ không thể tạo `pixel_values`. Hãy đặt `remove_unused_columns=False` để ngăn chặn hành vi này! Tham số bắt buộc duy nhất khác là `output_dir`, chỉ định nơi lưu trữ mô hình của bạn. Bạn sẽ đẩy mô hình này lên Hub bằng cách đặt `push_to_hub=True` (bạn cần đăng nhập vào Hugging Face để tải lên mô hình). Vào cuối mỗi epoch, [Trainer](/docs/transformers/main/vi/main_classes/trainer#transformers.Trainer) sẽ đánh giá độ chính xác và lưu checkpoint huấn luyện.
2. Truyền các đối số huấn luyện vào [Trainer](/docs/transformers/main/vi/main_classes/trainer#transformers.Trainer) cùng với mô hình, tập dữ liệu, tokenizer, data collator và hàm `compute_metrics`.
3. Gọi [train()](/docs/transformers/main/vi/main_classes/trainer#transformers.Trainer.train) để tinh chỉnh mô hình của bạn.

```py
>>> training_args = TrainingArguments(
...     output_dir="my_awesome_food_model",
...     remove_unused_columns=False,
...     eval_strategy="epoch",
...     save_strategy="epoch",
...     learning_rate=5e-5,
...     per_device_train_batch_size=16,
...     gradient_accumulation_steps=4,
...     per_device_eval_batch_size=16,
...     num_train_epochs=3,
...     warmup_steps=0.1,
...     logging_steps=10,
...     report_to="trackio",
...     run_name="food101",
...     load_best_model_at_end=True,
...     metric_for_best_model="accuracy",
...     push_to_hub=True,
... )

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     data_collator=data_collator,
...     train_dataset=food["train"],
...     eval_dataset=food["test"],
...     processing_class=image_processor,
...     compute_metrics=compute_metrics,
... )

>>> trainer.train()
```

Khi quá trình huấn luyện hoàn tất, hãy chia sẻ mô hình của bạn lên Hub bằng phương thức [push_to_hub()](/docs/transformers/main/vi/main_classes/trainer#transformers.Trainer.push_to_hub) để mọi người có thể sử dụng mô hình của bạn:

```py
>>> trainer.push_to_hub()
```

Để xem một ví dụ chi tiết hơn về cách tinh chỉnh mô hình cho phân loại hình ảnh, hãy xem [notebook PyTorch](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification.ipynb) tương ứng.

## Suy luận

Tuyệt, giờ đây bạn đã tinh chỉnh một mô hình, bạn có thể sử dụng nó để suy luận!

Tải một hình ảnh mà bạn muốn chạy suy luận:

```py
>>> ds = load_dataset("ethz/food101", split="validation[:10]")
>>> image = ds["image"][0]
```

    

Cách đơn giản nhất để thử nghiệm mô hình đã tinh chỉnh của bạn cho suy luận là sử dụng nó trong một [pipeline()](/docs/transformers/main/vi/main_classes/pipelines#transformers.pipeline). Khởi tạo một `pipeline` cho phân loại hình ảnh với mô hình của bạn, và truyền hình ảnh của bạn vào đó:

```py
>>> from transformers import pipeline

>>> classifier = pipeline("image-classification", model="my_awesome_food_model")
>>> classifier(image)
[{'score': 0.31856709718704224, 'label': 'beignets'},
 {'score': 0.015232225880026817, 'label': 'bruschetta'},
 {'score': 0.01519392803311348, 'label': 'chicken_wings'},
 {'score': 0.013022331520915031, 'label': 'pork_chop'},
 {'score': 0.012728818692266941, 'label': 'prime_rib'}]
```

Bạn cũng có thể tự động tái tạo kết quả của `pipeline` nếu muốn:

Tải bộ xử lý ảnh để tiền xử lý ảnh và trả về `input` dưới dạng tensor PyTorch:

```py
>>> from transformers import AutoImageProcessor
>>> import torch

>>> image_processor = AutoImageProcessor.from_pretrained("my_awesome_food_model")
>>> inputs = image_processor(image, return_tensors="pt")
```

Truyền các đầu vào của bạn vào mô hình và trả về logits:

```py
>>> from transformers import AutoModelForImageClassification

>>> model = AutoModelForImageClassification.from_pretrained("my_awesome_food_model")
>>> with torch.no_grad():
...     logits = model(**inputs).logits
```

Lấy nhãn dự đoán có xác suất cao nhất và sử dụng ánh xạ `id2label` của mô hình để chuyển đổi nó thành nhãn:

```py
>>> predicted_label = logits.argmax(-1).item()
>>> model.config.id2label[predicted_label]
'beignets'
```

