Segmentacija instance z YOLOv7 v Python PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Segmentacija primerkov z YOLOv7 v Pythonu

Predstavitev

Zaznavanje predmetov je obsežno področje računalniškega vida in ena pomembnejših aplikacij računalniškega vida »v naravi«. Iz nje je bila izluščena segmentacija primerkov, katere naloga je, da modeli predvidijo ne samo oznako in omejevalni okvir predmeta, temveč tudi »območje«, ki ga pokriva – razvrsti vsako slikovno piko, ki pripada temu predmetu.

Semantična segmentacija razvrsti vse piksle na sliki po njihovih pomensko oznaka (avtomobil, pločnik, stavba). Primer Segmentacija razvršča vse slikovne pike vsakega zaznanega predmeta individualno, in Car1 se razlikuje od Car2.

Konceptualno – sta si podobna, vendar segmentacija primerkov združuje semantično segmentacijo in zaznavanje objektov. Na srečo je mogoče zaznavanje objektov, semantično segmentacijo in segmentacijo primerkov z razširitvijo izvesti s skupnim zaledjem, z različnimi glavami omrežja, saj so zadolženi za konceptualno podobno nalogo in si tako delijo računalniške predstavitve tega znanja.

Zaznavanje objektov, semantična segmentacija, segmentacija primerkov in zaznavanje ključnih točk niso tako standardizirani kot klasifikacija slik, predvsem zato, ker večino novega razvoja običajno izvajajo posamezni raziskovalci, vzdrževalci in razvijalci, ne pa velike knjižnice in ogrodja. Težko je zapakirati potrebne pomožne skripte v ogrodje, kot sta TensorFlow ali PyTorch, in vzdrževati smernice API-ja, ki so usmerjale dosedanji razvoj.

Na srečo za množice – Ultralytics je razvil preprost, zelo zmogljiv in lep API za zaznavanje predmetov okoli svojega YOLOv5, ki so ga druge raziskovalne in razvojne ekipe razširile v novejše različice, kot je YOLOv7.

V tem kratkem vodniku bomo izvedli segmentacijo primerkov v Pythonu z najsodobnejšim YOLOv7.

YOLO in segmentacija primerkov

YOLO (pogledaš samo enkrat) je metodologija, pa tudi družina modelov, zgrajenih za odkrivanje objektov. Od ustanovitve leta 2015 so YOLOv1, YOLOv2 (YOLO9000) in YOLOv3 predlagali isti avtorji – in skupnost za globoko učenje je v naslednjih letih nadaljevala z odprtokodnim napredkom.

Ultralytics' YOLOv5 je ogromen repozitorij in prva implementacija YOLO na produkcijski ravni v PyTorch, ki je doživela veliko uporabo v industriji. Implementacija PyTorch ga je naredila bolj dostopnega kot kadar koli prej, kar je bilo običajno narejeno v C++, vendar je glavni razlog, da je postal tako priljubljen, zaradi čudovito preprostega in zmogljivega API-ja, zgrajenega okoli njega, ki omogoča vsakomur, da lahko zažene nekaj vrstic Pythona kodo, ki lahko zgradi detektorje predmetov.

YOLOv5 je postal tako stalnica, da ga večina repozitorijev, ki želijo napredovati metodo YOLO, uporablja kot osnovo in ponuja podoben API, podedovan od Ultralytics. YOLOR (Naučiš se samo enega prikaza) naredil natanko to in isti avtorji so YOLOv7 zgradili na vrhu YOLOR-ja.

YOLOv7 je prvi model YOLO, ki je dobavljen z novimi glavami modelov, ki omogočajo ključne točke, segmentacijo primerkov in zaznavanje objektov, kar je bil zelo smiseln dodatek. Upajmo, da bomo v prihodnje videli vse večje število modelov, ki temeljijo na YOLO in ponujajo podobne zmogljivosti takoj po izdelavi.

Zaradi tega sta segmentacija primerkov in zaznavanje ključnih točk hitrejša kot kdaj koli prej, s preprostejšo arhitekturo kot dvostopenjski detektorji.

Sam model je bil ustvarjen z arhitekturnimi spremembami, pa tudi z optimiziranimi vidiki usposabljanja, imenovanimi »bag-of-freebies«, kar je povečalo natančnost brez povečanja stroškov sklepanja.

Segmentacija primerkov z YOLOv7

Standardna knjižnica, ki se uporablja za na primer segmentacijo, odkrivanje objektov in oceno ključnih točk v Pythonu, je Detectron2, ki jo je zgradil Meta AI.

Knjižnica ponuja različne priročne metode in razrede za pomoč pri lepi vizualizaciji rezultatov, vendar je osnovna izvedba za odkrivanje maska ​​R-CNN. Izkazalo se je, da YOLO na vseh področjih prekaša modele, ki temeljijo na R-CNN. Repozitorij YOLOv7 je združljiv z Detectron2 in je združljiv s svojim API-jem in orodji za vizualizacijo, kar olajša izvajanje hitre in natančne segmentacije primerkov, ne da bi se morali naučiti novega API-ja. Pravzaprav lahko zamenjate hrbtenico Mask R-CNN in jo nadomestite z YOLOv7.

Namestitev odvisnosti – YOLOv7 in Detectron2

Najprej pojdimo naprej in namestimo odvisnosti. Klonirali bomo repo GitHub za projekt YOLOv7 in namestili najnovejšo različico Detectron2 prek pip:

! git clone -b mask https://github.com/WongKinYiu/yolov7.git
! pip install pyyaml==5.1
! pip install 'git+https://github.com/facebookresearch/detectron2.git'

Detectron2 zahteva pyyaml prav tako. Če želite zagotoviti združljivost, boste želeli določiti tudi izvajanje torch različica:

! pip install torch==1.10.1+cu111 torchvision==0.11.2+cu111 torchaudio==0.10.1 -f https://download.pytorch.org/whl/torch_stable.html

Glavna veja YOLOv7 ne podpira segmentacije primerkov, saj je odvisna od projekta tretje osebe. Vendar pa je mask podružnica je bila narejena točno za to podporo, zato nameščamo mask vejo projekta. Nazadnje boste želeli ročno ali z:

%cd yolov7
! curl -L https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-mask.pt -o yolov7-mask.pt

Najprej smo se preselili v yolov7 (preneseni imenik, ki vsebuje projekt) in nato tja prenesel datoteko z utežmi. S tem – naše odvisnosti so postavljene! Uvozimo pakete in razrede, ki jih bomo uporabljali:

import matplotlib.pyplot as plt
import torch
import cv2
import yaml
from torchvision import transforms
import numpy as np

from utils.datasets import letterbox
from utils.general import non_max_suppression_mask_conf

from detectron2.modeling.poolers import ROIPooler
from detectron2.structures import Boxes
from detectron2.utils.memory import retry_if_cuda_oom
from detectron2.layers import paste_masks_in_image

Inferenca segmentacije primerka z YOLOv7

Najprej si oglejmo sliko, ki jo bomo segmentirali:

street_img = cv2.imread('../street.png')
street_img = cv2.cvtColor(street_img, cv2.COLOR_BGR2RGB)

fig = plt.figure(figsize=(12, 6))
plt.imshow(street_img)

To je posnetek zaslona iz pogleda Google Zemljevidov v živo! Ker model ni vnaprej usposobljen za veliko razredov, bomo verjetno videli samo semantično segmentacijo za razrede, kot je 'oseba', 'avto', itd. brez "drobnozrnatih" razredov, kot je 'prometna luč'.

Zdaj se lahko lotimo nalaganja modela in njegove priprave za sklepanje. The hyp.scratch.mask.yaml datoteka vsebuje konfiguracije za hiperparametre, zato jo bomo najprej naložili, preverili aktivno napravo (GPE ali CPE) in naložili model iz datoteke uteži, ki smo jo pravkar prenesli:

Oglejte si naš praktični, praktični vodnik za učenje Gita z najboljšimi praksami, standardi, sprejetimi v panogi, in priloženo goljufijo. Nehajte Googlati ukaze Git in pravzaprav naučiti it!

with open('data/hyp.scratch.mask.yaml') as f:
    hyp = yaml.load(f, Loader=yaml.FullLoader)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def load_model():
    model = torch.load('yolov7-mask.pt', map_location=device)['model']
    
    model.eval()

    if torch.cuda.is_available():
        
        
        model.half().to(device)
    return model

model = load_model()

Nato ustvarimo pomožno metodo za izvajanje sklepanja! Želeli bomo, da prebere sliko, jo preoblikuje in podloži na pričakovano velikost vnosa, uporabi transformacije, jo serira in posreduje v model:

def run_inference(url):
    image = cv2.imread(url) 
    
    image = letterbox(image, 640, stride=64, auto=True)[0] 
    
    image = transforms.ToTensor()(image) 
    
    image = image.half().to(device)
    
    image = image.unsqueeze(0) 
    output = model(image) 
    return output, image

output, image = run_inference('../street.png')

Funkcija vrne izhod modela in samo sliko (naloženo, podloženo in drugače obdelano). Rezultat je slovar:

output.keys()

Napovedi, ki jih je naredil model, so neobdelane – morali jih bomo posredovati non_max_supression()in uporabite ROIPooler podjetja Detectron2.

Opomba: »Združevanje ROI« je okrajšava za "Združevanje interesnih regij" in se uporablja za pridobivanje zemljevidov majhnih funkcij za naloge zaznavanja in segmentacije objektov v regijah, ki lahko vsebujejo predmete.

inf_out = output['test']
attn = output['attn']
bases = output['bases']
sem_output = output['sem']

bases = torch.cat([bases, sem_output], dim=1)
nb, _, height, width = image.shape
names = model.names
pooler_scale = model.pooler_scale

pooler = ROIPooler(output_size=hyp['mask_resolution'], 
                   scales=(pooler_scale,), 
                   sampling_ratio=1, 
                   pooler_type='ROIAlignV2', 
                   canonical_level=2)
                   

output, output_mask, _, _, _ = non_max_suppression_mask_conf(inf_out, 
                                                             attn, 
                                                             bases, 
                                                             pooler, 
                                                             hyp, 
                                                             conf_thres=0.25, 
                                                             iou_thres=0.65, 
                                                             merge=False, 
                                                             mask_iou=None)                 

Tukaj – pridobili smo napovedi za predmete in njihove oznake v output in maske, ki bi morale pokrivati ​​te predmete output_mask:

output[0].shape 
output_mask[0].shape 

Model je na sliki našel 30 primerkov, z vsakim je povezana oznaka. Ustvarimo škatle za naše primerke s pomočjo Detectron2 Boxes razreda in strnite pred_masks (ki vsebujejo logično masko) v niz slikovnih pik, ki jih lahko uporabimo nad izvirno sliko:

pred, pred_masks = output[0], output_mask[0]
base = bases[0]
bboxes = Boxes(pred[:, :4])

original_pred_masks = pred_masks.view(-1, 
                                      hyp['mask_resolution'], 
                                      hyp['mask_resolution'])

pred_masks = retry_if_cuda_oom(paste_masks_in_image)(original_pred_masks, 
                                                     bboxes, 
                                                     (height, width), 
                                                     threshold=0.5)
                                                     

pred_masks_np = pred_masks.detach().cpu().numpy()
pred_cls = pred[:, 5].detach().cpu().numpy()
pred_conf = pred[:, 4].detach().cpu().numpy()
nimg = image[0].permute(1, 2, 0) * 255
nimg = nimg.cpu().numpy().astype(np.uint8)
nimg = cv2.cvtColor(nimg, cv2.COLOR_RGB2BGR)
nbboxes = bboxes.tensor.detach().cpu().numpy().astype(np.int)

O original_pred_masks označuje predvidene maske za izvirno sliko:

original_pred_masks.shape 

In končno lahko narišemo rezultate z:

def plot_results(original_image, pred_img, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=True):
  for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
    if conf < 0.25:
        continue
    color = [np.random.randint(255), np.random.randint(255), np.random.randint(255)]

    pred_img = pred_img.copy()
                             
    
    pred_img[one_mask] = pred_img[one_mask] * 0.5 + np.array(color, dtype=np.uint8) * 0.5
    
    pred_img = cv2.rectangle(pred_img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), color, 2)

    if plot_labels:
      label = '%s %.3f' % (names[int(cls)], conf)
      t_size = cv2.getTextSize(label, 0, fontScale=0.1, thickness=1)[0]
      c2 = bbox[0] + t_size[0], bbox[1] - t_size[1] - 3
      pred_img = cv2.rectangle(pred_img, (bbox[0], bbox[1]), c2, color, -1, cv2.LINE_AA)
      pred_img = cv2.putText(pred_img, label, (bbox[0], bbox[1] - 2), 0, 0.5, [255, 255, 255], thickness=1, lineType=cv2.LINE_AA)  

  fig, ax = plt.subplots(1, 2, figsize=(pred_img.shape[0]/10, pred_img.shape[1]/10), dpi=150)

  original_image = np.moveaxis(image.cpu().numpy().squeeze(), 0, 2).astype('float32')
  original_image = cv2.cvtColor(original_image, cv2.COLOR_RGB2BGR)
  
  ax[0].imshow(original_image)
  ax[0].axis("off")
  ax[1].imshow(pred_img)
  ax[1].axis("off")

Slika je kopirana, tako da transformacij ne uporabimo na sliki na mestu, ampak na kopiji. Za vsako slikovno piko, ki se ujema med vhodno sliko in predvidenimi maskami, uporabimo barvo z motnostjo 0.5 in za vsak predmet narišemo a cv2.Rectangle() ki ga zajema iz omejevalnih polj (bbox). Če želite izrisati oznake, pri katerih bi lahko prišlo do precejšnjega prekrivanja, obstaja plot_labels zastava v plot_results() podpis metode. Poskusimo narisati sliko, s katero smo začeli delati prej, z oznakami in brez:

%matplotlib inline
plot_results(image, nimg, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=False)

Segmentacija instance z YOLOv7 v Python PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

%matplotlib inline
plot_results(image, nimg, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=True)

Segmentacija instance z YOLOv7 v Python PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Narisali smo obe sliki – izvirno in segmentirano sliko v enem izrisu. Za večjo ločljivost prilagodite dpi (pik na palec) argument v subplots() pokličite in narišite samo sliko s predvidenim segmentacijskim zemljevidom/oznakami, da bo slika v celoti zasedla.

Naprej – Praktično poglobljeno učenje za računalniški vid

Ali zaradi vaše radovedne narave želite iti dlje? Priporočamo, da si ogledate naše Tečaj: »Praktično poglobljeno učenje za računalniški vid s Pythonom«.

Segmentacija instance z YOLOv7 v Python PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Še en tečaj računalniškega vida?

Ne bomo izvajali klasifikacije števk MNIST ali načina MNIST. Svojo so že zdavnaj odslužili. Preveč učnih virov se osredotoča na osnovne nabore podatkov in osnovne arhitekture, preden prepusti naprednim arhitekturam črnih skrinjic breme zmogljivosti.

Želimo se osredotočiti na demistifikacija, praktičnosti, razumevanje, intuicija in pravi projekti. Želim se naučiti kako lahko kaj spremeniš? Popeljali vas bomo od načina, na katerega naši možgani obdelujejo slike, do pisanja raziskovalnega klasifikatorja globokega učenja za raka dojke do omrežij globokega učenja, ki »halucinirajo«, vas naučijo načel in teorije s praktičnim delom ter vas opremijo z znanje in izkušnje ter orodja, da postanete strokovnjak za uporabo globokega učenja za reševanje računalniškega vida.

Kaj je notri?

  • Prva načela vida in kako lahko računalnike naučimo "videti"
  • Različne naloge in aplikacije računalniškega vida
  • Strokovna orodja, ki vam bodo olajšala delo
  • Iskanje, ustvarjanje in uporaba naborov podatkov za računalniški vid
  • Teorija in uporaba konvolucijskih nevronskih mrež
  • Obravnava premikov domene, sopojavljanja in drugih pristranskosti v nizih podatkov
  • Prenos učenja in uporaba časa za usposabljanje in računalniških virov drugih v vašo korist
  • Izdelava in usposabljanje najsodobnejšega klasifikatorja raka dojke
  • Kako uporabiti zdrav odmerek skepticizma za glavne ideje in razumeti posledice splošno sprejetih tehnik
  • Vizualizacija »konceptnega prostora« ConvNet z uporabo t-SNE in PCA
  • Študije primerov o tem, kako podjetja uporabljajo tehnike računalniškega vida za doseganje boljših rezultatov
  • Pravilno vrednotenje modela, vizualizacija latentnega prostora in prepoznavanje pozornosti modela
  • Izvajanje domenskih raziskav, obdelava lastnih naborov podatkov in vzpostavljanje testov modelov
  • Vrhunske arhitekture, razvoj idej, kaj jih dela edinstvene in kako jih uresničiti
  • KerasCV – knjižnica WIP za ustvarjanje najsodobnejših cevovodov in modelov
  • Kako razčleniti in brati prispevke ter jih implementirati sami
  • Izbira modelov glede na vašo aplikacijo
  • Ustvarjanje cevovoda strojnega učenja od konca do konca
  • Pokrajina in intuicija pri zaznavanju predmetov s hitrejšimi R-CNN, RetinaNets, SSD in YOLO
  • Instančna in pomenska segmentacija
  • Prepoznavanje predmetov v realnem času z YOLOv5
  • Usposabljanje detektorjev predmetov YOLOv5
  • Delo s transformatorji z uporabo KerasNLP (industrijska knjižnica WIP)
  • Integracija Transformers s ConvNets za ustvarjanje napisov slik
  • Deepdream
  • Optimizacija modela globokega učenja za računalniški vid

Časovni žig:

Več od Stackabuse