Transformers documentation
Görüntü Segmentasyonu
Görüntü Segmentasyonu
Görüntü segmentasyon modelleri, bir görüntüdeki farklı ilgi alanlarına karşılık gelen bölgeleri ayırır. Bu modeller, her piksele bir etiket atayarak çalışır. Segmentasyonun çeşitli türleri vardır: anlamsal segmentasyon, örnek segmentasyonu ve panoptik segmentasyon.
Bu kılavuzda şunları yapacağız:
Başlamadan önce, gerekli tüm kütüphanelerin yüklendiğinden emin olun:
# uncomment to install the necessary libraries
!pip install -q datasets transformers evaluate accelerate trackioModelinizi yükleyip toplulukla paylaşabilmeniz için Hugging Face hesabınıza giriş yapmanızı öneririz. İstendiğinde giriş yapmak için token'ınızı girin:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Segmentasyon Türleri
Anlamsal segmentasyon, bir görüntüdeki her bir piksele bir etiket veya sınıf atar. Anlamsal segmentasyon modeli çıktısına bir bakalım. Model, bir görüntüde karşılaştığı bir nesnenin tüm örneklerine aynı sınıfı atar; örneğin, tüm kediler “cat-1”, “cat-2” yerine “cat” olarak etiketlenir. Transformers kütüphanesinin görüntü segmentasyon hattını (pipeline) kullanarak bir anlamsal segmentasyon modelini hızlıca çalıştırabiliriz. Örnek görüntüye bir bakalım.
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
nvidia/segformer-b1-finetuned-cityscapes-1024-1024 kullanacağız.
semantic_segmentation = pipeline("image-segmentation", "nvidia/segformer-b1-finetuned-cityscapes-1024-1024")
results = semantic_segmentation(image)
resultsSegmentasyon hattı çıktısı, tahmin edilen her sınıf için bir maske içerir.
[{'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>}]Araba sınıfının maskesine baktığımızda, her arabanın aynı maske ile sınıflandırıldığını görebiliriz.
results[-1]["mask"]
Örnek segmentasyonunda amaç her pikseli sınıflandırmak değil, verilen bir görüntüdeki nesnenin her örneği için bir maske tahmin etmektir. Nesne algılama ile çok benzer şekilde çalışır; her örnek için bir sınırlayıcı kutu yerine bir segmentasyon maskesi bulunur. Bunun için facebook/mask2former-swin-large-cityscapes-instance kullanılacaktır.
instance_segmentation = pipeline("image-segmentation", "facebook/mask2former-swin-large-cityscapes-instance")
results = instance_segmentation(image)
resultsAşağıda görebileceğiniz gibi, birden fazla araç sınıflandırılmış olup, araç ve kişi örneklerine ait olmayan pikseller için herhangi bir sınıflandırma yapılmamıştır.
[{'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>}]Aşağıdaki araç maskelerinden birini inceliyoruz.
results[2]["mask"]
Panoptik segmentasyon, her pikselin bir sınıfa ve o sınıfın bir örneğine (instance) sınıflandırıldığı, her sınıf örneği için birden fazla maske bulunan semantik segmentasyon ve örnek segmentasyonunu birleştirir. Bunu facebook/mask2former-swin-large-cityscapes-panoptic ile yapabiliriz.
panoptic_segmentation = pipeline("image-segmentation", "facebook/mask2former-swin-large-cityscapes-panoptic")
results = panoptic_segmentation(image)
resultsAşağıda görebileceğiniz gibi daha fazla sınıfımız var. Daha sonra, her pikselin sınıflardan birine sınıflandırıldığını göstermek için bir örnek sunacağız.
[{'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>}]Tüm segmentasyon türleri için yan yana bir karşılaştırma yapalım.

Tüm segmentasyon türlerini gördükten sonra, semantik segmentasyon için bir modelin ince ayarına derinlemesine bakalım.
Anlamsal segmentasyonun yaygın gerçek dünya uygulamaları arasında, otonom araçların yaya ve önemli trafik bilgilerini tanımlaması için eğitim verilmesi, tıbbi görüntülerde hücreleri ve anormallikleri belirleme ve uydu görüntülerinden çevresel değişiklikleri izleme yer alır.
Segmentasyon için Bir Modelin İnce Ayarı
Şimdi şunları yapacağız:
- SegFormer modelini SceneParse150 veri setinde ince ayarlayın.
- İnce ayarladığınız modeli çıkarım için kullanın.
Bu görevle uyumlu tüm mimarileri ve denetim noktalarını görmek için görev sayfasını kontrol etmenizi öneririz.
SceneParse150 veri setini yükle
Önce 🤗 Datasets kütüphanesinden SceneParse150 veri setinin daha küçük bir alt kümesini yükleyerek başlayın. Bu, tam veri setinde eğitim için daha fazla zaman harcamadan önce deneyler yapmanıza ve her şeyin çalıştığını doğrulamanıza olanak tanır.
>>> from datasets import load_dataset
>>> ds = load_dataset("merve/scene_parse_150", split="train[:50]")Veri setinin train bölümünü train_test_split yöntemiyle eğitim ve test kümesine ayırın:
>>> ds = ds.train_test_split(test_size=0.2)
>>> train_ds = ds["train"]
>>> test_ds = ds["test"]Sonra bir örneğe göz atın:
>>> 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: Sahnenin bir PIL görüntüsü.annotation: segmentasyon haritasının bir PIL görüntüsü, aynı zamanda modelin hedefi.scene_category: “mutfak” veya “ofis” gibi bir görüntü sahnesini tanımlayan bir kategori kimliği. Bu kılavuzda yalnızcaimageveannotationalanlarına ihtiyacınız olacak; her ikisi de PIL görüntüleridir.
Daha sonra modeli yapılandırırken işinize yarayacak, bir etiket kimliğini bir etiket sınıfına eşleyen bir sözlük de oluşturmak isteyeceksiniz. Eşlemeleri Hub'dan indirin ve id2label ile label2id sözlüklerini oluşturun:
>>> 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)Ön işleme
Bir sonraki adım, görüntüleri ve etiketleri model için hazırlamak üzere bir SegFormer görüntü işleyicisi yüklemektir. Bu gibi bazı veri kümeleri, arka plan sınıfı olarak sıfır indeksini kullanır. Ancak arka plan sınıfı aslında 150 sınıfın içinde yer almadığından, tüm etiketlerden bir çıkarmak için do_reduce_labels=True değerini ayarlamanız gerekir. Sıfır indeksi, SegFormer'ın kayıp fonksiyonu tarafından yok sayılması için 255 ile değiştirilir:
>>> from transformers import AutoImageProcessor
>>> checkpoint = "nvidia/mit-b0"
>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint, do_reduce_labels=True)Bir görüntü veri setine, modelin aşırı öğrenmeye karşı daha dayanıklı hale gelmesi için bazı veri artırma işlemleri uygulamak yaygın bir uygulamadır. Bu kılavuzda, torchvision kütüphanesinden ColorJitter fonksiyonunu kullanarak bir görüntünün renk özelliklerini rastgele değiştireceksiniz; ancak istediğiniz herhangi bir görüntü kütüphanesini de kullanabilirsiniz.
>>> from torchvision.transforms import ColorJitter
>>> jitter = ColorJitter(brightness=0.25, contrast=0.25, saturation=0.25, hue=0.1)Şimdi, görüntüleri ve etiketleri modele hazırlamak için iki ön işleme fonksiyonu oluşturun. Bu fonksiyonlar görüntüleri pixel_values ve etiketleri labels biçimine dönüştürür. Eğitim seti için, görüntüler görüntü işleyiciye verilmeden önce jitter uygulanır. Test seti için ise görüntü işleyici images öğelerini kırpıp normalize eder ve test sırasında veri artırımı uygulanmadığından yalnızca labels öğelerini kırpma işlemini gerçekleştirir.
>>> 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 inputsVeri setinin tamamına jitter uygulamak için 🤗 Datasets'in set_transform işlevini kullanın. Dönüşüm anlık olarak uygulandığından daha hızlıdır ve daha az disk alanı tüketir:
>>> train_ds.set_transform(train_transforms)
>>> test_ds.set_transform(val_transforms)Değerlendir
Eğitim sırasında bir metrik kullanmak, model performansınızı değerlendirmek için genellikle faydalıdır. 🤗 Evaluate kütüphanesiyle bir değerlendirme yöntemini hızla yükleyebilirsiniz. Bu görev için mean Intersection over Union (IoU) metrik yükleyin (metrik yüklemenin ve hesaplanmasının nasıl yapıldığı hakkında daha fazla bilgi için 🤗 Evaluate quick tour sayfasına bakın):
>>> import evaluate
>>> metric = evaluate.load("mean_iou")Ardından metrikleri hesaplamak için bir işlev oluşturun. Tahminleriniz, compute çağrısından önce önce logitlere dönüştürülmeli ve ardından etiketlerin boyutuyla eşleşecek şekilde yeniden şekillendirilmelidir:
>>> 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 metricscompute_metrics fonksiyonunuz artık hazır ve eğitiminizi kurarken ona geri döneceksiniz.
Eğit
Trainer ile bir modeli ince ayar yapma konusunda deneyiminiz yoksa, temel öğreticiyi burada inceleyebilirsiniz!
Artık modelinizi eğitmeye hazırsınız! AutoModelForSemanticSegmentation ile SegFormer’ı yükleyin ve modele etiket kimlikleri ile etiket sınıfları arasındaki eşlemeyi iletin:
>>> from transformers import AutoModelForSemanticSegmentation, TrainingArguments, Trainer
>>> model = AutoModelForSemanticSegmentation.from_pretrained(checkpoint, id2label=id2label, label2id=label2id)Bu noktada yalnızca üç adım kaldı:
- Eğitim hiperparametrelerinizi TrainingArguments içinde tanımlayın. Kullanılmayan sütunları kaldırmamanız önemlidir, çünkü bu işlem
imagesütununu düşürür.imagesütunu olmadanpixel_valuesoluşturamazsınız. Bu davranışı önlemek içinremove_unused_columns=Falseayarlayın! Tek diğer zorunlu parametre, modelinizi nereye kaydedeceğinizi belirtenoutput_dir'dir. Modelinizi Hub'apush_to_hub=Trueayarlayarak yükleyeceksiniz (modelinizi yüklemek için Hugging Face'e giriş yapmış olmanız gerekir). Her epoch sonunda Trainer, IoU metrikini değerlendirir ve eğitim checkpoint'ini kaydeder. - Eğitim argümanlarını, model, veri seti, tokenizer, veri toplayıcı ve
compute_metricsfonksiyonuyla birlikte Trainer'a iletin. - Modelinizi ince ayar yapmak için train() çağrın.
>>> 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()Eğitim tamamlandıktan sonra, modelinizi herkesin kullanabilmesi için push_to_hub() yöntemiyle Hub'a paylaşın:
>>> trainer.push_to_hub()Çıkarım
Harika, bir model ayarladıktan sonra artık çıkarım için kullanabilirsiniz!
Veri setini yeniden yükleyin ve çıkarım için bir görüntü yükleyin.
>>> 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
Şimdi bir pipeline olmadan çıkarım yapmayı göreceğiz. Görüntüyü bir görüntü işleyiciyle işleyin ve pixel_values değerlerini bir GPU'ya yerleştirin:
>>> from accelerate import Accelerator
>>> device = Accelerator().device
>>> encoding = image_processor(image, return_tensors="pt")
>>> pixel_values = encoding.pixel_values.to(device)Girdinizi modele iletin ve logits değerlerini döndürün:
>>> outputs = model(pixel_values=pixel_values)
>>> logits = outputs.logits.cpu()Ardından, logitleri orijinal görüntü boyutuna yeniden ölçekleyin:
>>> upsampled_logits = nn.functional.interpolate(
... logits,
... size=image.size[::-1],
... mode="bilinear",
... align_corners=False,
... )
>>> pred_seg = upsampled_logits.argmax(dim=1)[0]Sonuçları görselleştirmek için, her sınıfı RGB değerlerine eşleyen veri seti renk paletini ade_palette() olarak yükleyin.
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],
])Ardından görüntünüzü ve tahmin edilen segmentasyon haritasını birleştirip çizebilirsiniz:
>>> 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()