# Phân đoạn hình ảnh

Mô hình phân đoạn hình ảnh tách các vùng tương ứng với các khu vực quan tâm khác nhau trong một hình ảnh. Các mô hình này hoạt động bằng cách gán một nhãn cho từng pixel. Có một số loại phân đoạn: phân đoạn ngữ nghĩa, phân đoạn thực thể và phân đoạn toàn cảnh.

Trong hướng dẫn này, chúng ta sẽ:

1. [Khám phá các loại phân đoạn khác nhau](#types-of-segmentation).
2. [Có một ví dụ fine-tuning end-to-end cho phân đoạn ngữ nghĩa](#fine-tuning-a-model-for-segmentation).

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:

```py
# uncomment to install the necessary libraries
!pip install -q datasets transformers evaluate accelerate 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 để có thể 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()
```

## Các loại phân đoạn

Semantic segmentation gán một nhãn hoặc lớp cho từng pixel trong một hình ảnh. Hãy xem xét đầu ra của một mô hình phân đoạn ngữ nghĩa. Mô hình sẽ gán cùng một lớp cho mọi thể hiện của một đối tượng mà nó gặp trong hình ảnh, ví dụ, tất cả các con mèo sẽ được dán nhãn là "cat" thay vì "cat-1", "cat-2". Chúng ta có thể sử dụng pipeline phân đoạn hình ảnh của transformers để suy luận nhanh một mô hình phân đoạn ngữ nghĩa. Hãy xem xét hình ảnh ví dụ.

```python
from transformers import pipeline
from PIL import Image
import requests

url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/segmentation_input.jpg"
image = Image.open(requests.get(url, stream=True).raw)
image
```

     

Chúng ta sẽ sử dụng [nvidia/segformer-b1-finetuned-cityscapes-1024-1024](https://huggingface.co/nvidia/segformer-b1-finetuned-cityscapes-1024-1024).

```python
semantic_segmentation = pipeline("image-segmentation", "nvidia/segformer-b1-finetuned-cityscapes-1024-1024")
results = semantic_segmentation(image)
results
```

Đầu ra của pipeline phân đoạn bao gồm một mask cho mỗi lớp được dự đoán.

```bash
[{'score': None,
  'label': 'road',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'sidewalk',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'building',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'wall',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'pole',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'traffic sign',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'vegetation',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'terrain',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'sky',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': None,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>}]
```

Khi xem xét mặt nạ cho lớp ô tô, chúng ta có thể thấy mọi chiếc ô tô đều được phân loại với cùng một mặt nạ.

```python
results[-1]["mask"]
```

     

Trong phân đoạn thực thể, mục tiêu không phải là phân loại từng pixel, mà là dự đoán một mặt nạ cho **mọi thực thể của một đối tượng** trong một hình ảnh cho trước. Cách hoạt động của nó rất giống với phát hiện đối tượng, trong đó có một hộp bao quanh cho mỗi thực thể, nhưng thay vào đó là một mặt nạ phân đoạn. Chúng ta sẽ sử dụng [facebook/mask2former-swin-large-cityscapes-instance](https://huggingface.co/facebook/mask2former-swin-large-cityscapes-instance) cho mục đích này.

```python
instance_segmentation = pipeline("image-segmentation", "facebook/mask2former-swin-large-cityscapes-instance")
results = instance_segmentation(image)
results
```

Như bạn có thể thấy bên dưới, có nhiều chiếc xe được phân loại, và không có phân loại nào cho các pixel khác ngoài những pixel thuộc về các instance của xe và người.

```bash
[{'score': 0.999944,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999945,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999652,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.903529,
  'label': 'person',
  'mask': <PIL.Image.Image image mode=L size=612x415>}]
```

Xem xét một trong các mặt nạ xe hơi bên dưới.

```python
results[2]["mask"]
```

     

Phân đoạn toàn cảnh (Panoptic segmentation) kết hợp phân đoạn ngữ nghĩa và phân đoạn thực thể, trong đó mỗi pixel được phân loại vào một lớp và một thực thể của lớp đó, và có nhiều mặt nạ (mask) cho mỗi thực thể của một lớp. Chúng ta có thể sử dụng [facebook/mask2former-swin-large-cityscapes-panoptic](https://huggingface.co/facebook/mask2former-swin-large-cityscapes-panoptic) cho mục đích này.

```python
panoptic_segmentation = pipeline("image-segmentation", "facebook/mask2former-swin-large-cityscapes-panoptic")
results = panoptic_segmentation(image)
results
```

Như bạn có thể thấy bên dưới, chúng ta có nhiều lớp hơn. Chúng ta sẽ minh họa sau đó để thấy rằng mỗi pixel được phân loại vào một trong các lớp.

```bash
[{'score': 0.999981,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999958,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.99997,
  'label': 'vegetation',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999575,
  'label': 'pole',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999958,
  'label': 'building',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999634,
  'label': 'road',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.996092,
  'label': 'sidewalk',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.999221,
  'label': 'car',
  'mask': <PIL.Image.Image image mode=L size=612x415>},
 {'score': 0.99987,
  'label': 'sky',
  'mask': <PIL.Image.Image image mode=L size=612x415>}]
```

Hãy cùng so sánh song song tất cả các loại phân đoạn.

     

Sau khi đã xem qua các loại phân đoạn khác nhau, chúng ta sẽ đi sâu vào việc tinh chỉnh một mô hình cho phân đoạn ngữ nghĩa.

Các ứng dụng thực tế phổ biến của phân đoạn ngữ nghĩa bao gồm huấn luyện xe tự lái để nhận diện người đi bộ và các thông tin giao thông quan trọng, nhận diện tế bào và các bất thường trong hình ảnh y tế, và giám sát các thay đổi môi trường từ hình ảnh vệ tinh.

## Chỉnh huấn luyện Mô hình cho Phân đoạn

Chúng ta sẽ:

1. Huấn luyện lại [SegFormer](../model_doc/segformer#segformer) trên bộ dữ liệu [SceneParse150](https://huggingface.co/datasets/merve/scene_parse_150).
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-segmentation)

### Tải bộ dữ liệu SceneParse150

Bắt đầu bằng cách tải một tập con nhỏ hơn của bộ dữ liệu SceneParse150 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

>>> ds = load_dataset("merve/scene_parse_150", split="train[:50]")
```

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
>>> ds = ds.train_test_split(test_size=0.2)
>>> train_ds = ds["train"]
>>> test_ds = ds["test"]
```

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

```py
>>> train_ds[0]
{'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=512x683 at 0x7F9B0C201F90>,
 'annotation': <PIL.PngImagePlugin.PngImageFile image mode=L size=512x683 at 0x7F9B0C201DD0>,
 'scene_category': 368}

# view the image
>>> train_ds[0]["image"]
```

- `image`: một hình ảnh PIL của cảnh.
- `annotation`: một ảnh PIL của bản đồ phân đoạn, đây cũng là mục tiêu của mô hình.
- `scene_category`: một id danh mục mô tả cảnh trong ảnh, ví dụ "kitchen" hoặc "office". Trong hướng dẫn này, bạn chỉ cần `image` và `annotation`, cả hai đều là ảnh PIL.

Bạn cũng sẽ cần tạo một từ điển ánh xạ từ id nhãn sang lớp nhãn, điều này sẽ hữu ích khi bạn thiết lập mô hình sau này. Tải các ánh xạ từ Hub và tạo các từ điển `id2label` và `label2id`:

```py
>>> import json
>>> from pathlib import Path
>>> from huggingface_hub import hf_hub_download

>>> repo_id = "huggingface/label-files"
>>> filename = "ade20k-id2label.json"
>>> id2label = json.loads(Path(hf_hub_download(repo_id, filename, repo_type="dataset")).read_text())
>>> id2label = {int(k): v for k, v in id2label.items()}
>>> label2id = {v: k for k, v in id2label.items()}
>>> num_labels = len(id2label)
```

### Tiền xử lý

Bước tiếp theo là nạp một bộ xử lý ảnh SegFormer để chuẩn bị ảnh và chú thích cho mô hình. Một số bộ dữ liệu, như bộ này, sử dụng chỉ số không làm lớp nền. Tuy nhiên, lớp nền thực tế không được bao gồm trong 150 lớp, vì vậy bạn cần đặt `do_reduce_labels=True` để trừ một khỏi tất cả các nhãn. Chỉ số không được thay thế bằng `255` để hàm mất mát của SegFormer bỏ qua nó:

```py
>>> from transformers import AutoImageProcessor

>>> checkpoint = "nvidia/mit-b0"
>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint, do_reduce_labels=True)
```

Việc áp dụng một số kỹ thuật tăng cường dữ liệu cho bộ dữ liệu ảnh là phổ biến nhằm giúp mô hình chống lại hiện tượng quá khớp tốt hơn. Trong hướng dẫn này, bạn sẽ sử dụng hàm [`ColorJitter`](https://pytorch.org/vision/stable/generated/torchvision.transforms.ColorJitter.html) từ [torchvision](https://pytorch.org/vision/stable/index.html) để thay đổi ngẫu nhiên các thuộc tính màu của một ảnh, nhưng bạn cũng có thể sử dụng bất kỳ thư viện ảnh nào bạn thích.

```py
>>> from torchvision.transforms import ColorJitter

>>> jitter = ColorJitter(brightness=0.25, contrast=0.25, saturation=0.25, hue=0.1)
```

Bây giờ hãy tạo hai hàm tiền xử lý để chuẩn bị ảnh và chú thích cho mô hình. Các hàm này chuyển đổi ảnh thành `pixel_values` và chú thích thành `labels`. Đối với tập huấn luyện, `jitter` được áp dụng trước khi cung cấp ảnh cho bộ xử lý ảnh. Đối với tập kiểm tra, bộ xử lý ảnh cắt và chuẩn hóa `images`, và chỉ cắt `labels` vì không áp dụng tăng cường dữ liệu trong quá trình kiểm tra.

```py
>>> def train_transforms(example_batch):
...     images = [jitter(x) for x in example_batch["image"]]
...     labels = [x for x in example_batch["annotation"]]
...     inputs = image_processor(images, labels)
...     return inputs

>>> def val_transforms(example_batch):
...     images = [x for x in example_batch["image"]]
...     labels = [x for x in example_batch["annotation"]]
...     inputs = image_processor(images, labels)
...     return inputs
```

Để áp dụng `jitter` cho toàn bộ bộ dữ liệu, hãy sử dụng hàm [set_transform](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.set_transform) của 🤗 Datasets. Biến đổi được áp dụng trực tiếp, giúp nhanh hơn và tiết kiệm dung lượng ổ đĩa hơn:

```py
>>> train_ds.set_transform(train_transforms)
>>> test_ds.set_transform(val_transforms)
```

### Đá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 nạp 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 nạp chỉ số [mean Intersection over Union](https://huggingface.co/spaces/evaluate-metric/accuracy) (IoU) (xem [quick tour](https://huggingface.co/docs/evaluate/a_quick_tour) của 🤗 Evaluate để tìm hiểu thêm về cách nạp và tính toán một chỉ số):

```py
>>> import evaluate

>>> metric = evaluate.load("mean_iou")
```

Sau đó, tạo một hàm để [tính toán](https://huggingface.co/docs/evaluate/main/en/package_reference/main_classes#evaluate.EvaluationModule.compute) các chỉ số. Dự đoán của bạn cần được chuyển đổi thành logits trước, sau đó được định dạng lại để khớp với kích thước của nhãn trước khi bạn có thể gọi [compute](https://huggingface.co/docs/evaluate/main/en/package_reference/main_classes#evaluate.EvaluationModule.compute):

```py
>>> import numpy as np
>>> import torch
>>> from torch import nn

>>> def compute_metrics(eval_pred):
...     with torch.no_grad():
...         logits, labels = eval_pred
...         logits_tensor = torch.from_numpy(logits)
...         logits_tensor = nn.functional.interpolate(
...             logits_tensor,
...             size=labels.shape[-2:],
...             mode="bilinear",
...             align_corners=False,
...         ).argmax(dim=1)

...         pred_labels = logits_tensor.detach().cpu().numpy()
...         metrics = metric.compute(
...             predictions=pred_labels,
...             references=labels,
...             num_labels=num_labels,
...             ignore_index=255,
...             reduce_labels=False,
...         )
...         for key, value in metrics.items():
...             if isinstance(value, np.ndarray):
...                 metrics[key] = value.tolist()
...         return metrics
```

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! Hãy nạp SegFormer bằng [AutoModelForSemanticSegmentation](/docs/transformers/main/vi/model_doc/auto#transformers.AutoModelForSemanticSegmentation), và truyền cho mô hình ánh xạ giữa các id nhãn và các lớp nhãn:

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

>>> model = AutoModelForSemanticSegmentation.from_pretrained(checkpoint, 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 này 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ỉ số IoU 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="segformer-b0-scene-parse-150",
...     learning_rate=6e-5,
...     num_train_epochs=50,
...     per_device_train_batch_size=2,
...     per_device_eval_batch_size=2,
...     save_total_limit=3,
...     eval_strategy="steps",
...     save_strategy="steps",
...     save_steps=20,
...     eval_steps=20,
...     logging_steps=1,
...     report_to="trackio",
...     run_name="scene-parse-150",
...     eval_accumulation_steps=5,
...     remove_unused_columns=False,
...     push_to_hub=True,
... )

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=train_ds,
...     eval_dataset=test_ds,
...     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()
```

### 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 lại bộ dữ liệu và nạp một hình ảnh để suy luận.

```py
>>> from datasets import load_dataset

>>> ds = load_dataset("merve/scene_parse_150", split="train[:50]")
>>> ds = ds.train_test_split(test_size=0.2)
>>> test_ds = ds["test"]
>>> image = ds["test"][0]["image"]
>>> image
```

    

Chúng ta sẽ xem cách suy luận mà không dùng pipeline. Xử lý ảnh bằng image processor và đặt `pixel_values` lên GPU:

```py
>>> from accelerate import Accelerator
>>> device = Accelerator().device
>>> encoding = image_processor(image, return_tensors="pt")
>>> pixel_values = encoding.pixel_values.to(device)
```

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

```py
>>> outputs = model(pixel_values=pixel_values)
>>> logits = outputs.logits.cpu()
```

Tiếp theo, điều chỉnh lại kích thước của logits về kích thước ảnh gốc:

```py
>>> upsampled_logits = nn.functional.interpolate(
...     logits,
...     size=image.size[::-1],
...     mode="bilinear",
...     align_corners=False,
... )

>>> pred_seg = upsampled_logits.argmax(dim=1)[0]
```

Để trực quan hóa kết quả, hãy nạp [bảng màu tập dữ liệu](https://github.com/tensorflow/models/blob/3f1ca33afe3c1631b733ea7e40c294273b9e406d/research/deeplab/utils/get_dataset_colormap.py#L51) dưới dạng `ade_palette()`, ánh xạ mỗi lớp sang giá trị RGB tương ứng.

```py
def ade_palette():
  return np.asarray([
      [0, 0, 0],
      [120, 120, 120],
      [180, 120, 120],
      [6, 230, 230],
      [80, 50, 50],
      [4, 200, 3],
      [120, 120, 80],
      [140, 140, 140],
      [204, 5, 255],
      [230, 230, 230],
      [4, 250, 7],
      [224, 5, 255],
      [235, 255, 7],
      [150, 5, 61],
      [120, 120, 70],
      [8, 255, 51],
      [255, 6, 82],
      [143, 255, 140],
      [204, 255, 4],
      [255, 51, 7],
      [204, 70, 3],
      [0, 102, 200],
      [61, 230, 250],
      [255, 6, 51],
      [11, 102, 255],
      [255, 7, 71],
      [255, 9, 224],
      [9, 7, 230],
      [220, 220, 220],
      [255, 9, 92],
      [112, 9, 255],
      [8, 255, 214],
      [7, 255, 224],
      [255, 184, 6],
      [10, 255, 71],
      [255, 41, 10],
      [7, 255, 255],
      [224, 255, 8],
      [102, 8, 255],
      [255, 61, 6],
      [255, 194, 7],
      [255, 122, 8],
      [0, 255, 20],
      [255, 8, 41],
      [255, 5, 153],
      [6, 51, 255],
      [235, 12, 255],
      [160, 150, 20],
      [0, 163, 255],
      [140, 140, 140],
      [250, 10, 15],
      [20, 255, 0],
      [31, 255, 0],
      [255, 31, 0],
      [255, 224, 0],
      [153, 255, 0],
      [0, 0, 255],
      [255, 71, 0],
      [0, 235, 255],
      [0, 173, 255],
      [31, 0, 255],
      [11, 200, 200],
      [255, 82, 0],
      [0, 255, 245],
      [0, 61, 255],
      [0, 255, 112],
      [0, 255, 133],
      [255, 0, 0],
      [255, 163, 0],
      [255, 102, 0],
      [194, 255, 0],
      [0, 143, 255],
      [51, 255, 0],
      [0, 82, 255],
      [0, 255, 41],
      [0, 255, 173],
      [10, 0, 255],
      [173, 255, 0],
      [0, 255, 153],
      [255, 92, 0],
      [255, 0, 255],
      [255, 0, 245],
      [255, 0, 102],
      [255, 173, 0],
      [255, 0, 20],
      [255, 184, 184],
      [0, 31, 255],
      [0, 255, 61],
      [0, 71, 255],
      [255, 0, 204],
      [0, 255, 194],
      [0, 255, 82],
      [0, 10, 255],
      [0, 112, 255],
      [51, 0, 255],
      [0, 194, 255],
      [0, 122, 255],
      [0, 255, 163],
      [255, 153, 0],
      [0, 255, 10],
      [255, 112, 0],
      [143, 255, 0],
      [82, 0, 255],
      [163, 255, 0],
      [255, 235, 0],
      [8, 184, 170],
      [133, 0, 255],
      [0, 255, 92],
      [184, 0, 255],
      [255, 0, 31],
      [0, 184, 255],
      [0, 214, 255],
      [255, 0, 112],
      [92, 255, 0],
      [0, 224, 255],
      [112, 224, 255],
      [70, 184, 160],
      [163, 0, 255],
      [153, 0, 255],
      [71, 255, 0],
      [255, 0, 163],
      [255, 204, 0],
      [255, 0, 143],
      [0, 255, 235],
      [133, 255, 0],
      [255, 0, 235],
      [245, 0, 255],
      [255, 0, 122],
      [255, 245, 0],
      [10, 190, 212],
      [214, 255, 0],
      [0, 204, 255],
      [20, 0, 255],
      [255, 255, 0],
      [0, 153, 255],
      [0, 41, 255],
      [0, 255, 204],
      [41, 0, 255],
      [41, 255, 0],
      [173, 0, 255],
      [0, 245, 255],
      [71, 0, 255],
      [122, 0, 255],
      [0, 255, 184],
      [0, 92, 255],
      [184, 255, 0],
      [0, 133, 255],
      [255, 214, 0],
      [25, 194, 194],
      [102, 255, 0],
      [92, 0, 255],
  ])
```

Sau đó, bạn có thể kết hợp và vẽ ảnh của bạn cùng với bản đồ phân đoạn dự đoán:

```py
>>> import matplotlib.pyplot as plt
>>> import numpy as np

>>> color_seg = np.zeros((pred_seg.shape[0], pred_seg.shape[1], 3), dtype=np.uint8)
>>> palette = np.array(ade_palette())
>>> for label, color in enumerate(palette):
...     color_seg[pred_seg == label, :] = color
>>> color_seg = color_seg[..., ::-1]  # convert to BGR

>>> img = np.array(image) * 0.5 + color_seg * 0.5  # plot the image with the segmentation map
>>> img = img.astype(np.uint8)

>>> plt.figure(figsize=(15, 10))
>>> plt.imshow(img)
>>> plt.show()
```

    

