YOLO ile Derin Öğrenme! | Veri İşaretleme | Veri Eğitme | Görüntü İşleme

Enistein

Kıdemli Üye
16 Eyl 2012
2,219
1,206
Amsterdam
8BfzfS111434df5fdd155e.md.png

İyi günler Türk Hack Team ailesi.


Bugün sizlere YOLO (You Only Look Once) ile derin öğrenmeyi anlatacağım.
Kısacası veri işaretlemeden, işaretlediğiniz veriyi işlemeye kadar uzun bir yazı olacak.
Sonuna kadar okumanızı tavsiye ediyorum.
Aynı zamanda çok uzun zamandır görüntü işleme üzerine çalışıyorum. Konuyla ilgili sorularınız olursa, seve seve cevaplarım.


YOLO Nedir?

6OfL8I.gif


cTJfVcC.png

YOLO (You Only Look Once) derin öğrenme tabanlı bir nesne tanıma algoritmasıdır. Bu algoritma, girdi olarak verilen görüntülerde nesneleri hızlı ve doğru bir şekilde tespit etmek için kullanılır. YOLO, aynı anda tüm görüntüyü bir kerede tarar ve nesneleri tespit etmek için bir çok farklı bölgeye böler. Bu sayede, diğer nesne tanıma algoritmalarına göre daha hızlı çalışır.

YOLO, daha önceki nesne tanıma algoritmalarından farklı olarak, nesneleri tespit etmek için klasik bir "sliding window" yöntemi kullanmaz. Bu yöntem, görüntüyü belirli bir bölgeye parçalara ayırarak her parça için ayrı ayrı nesne tanıma işlemi yapar. YOLO ise, görüntüyü tek bir çalışma alanına böler ve tüm nesneleri aynı anda tespit etmeye çalışır. Bu sayede, nesne tanıma işlemi çok daha hızlı gerçekleşir.

YOLO, ayrıca, nesnelerin tespit edilmesi sırasında konumlarını ve boyutlarını da hesaplar. Bu sayede, tespit edilen nesnelerin nerede ve ne boyutta olduğu belirlenir. Bu özellik, YOLO'yu diğer nesne tanıma algoritmalarından daha çok sınıflandırma ve pozisyon tahmini gibi uygulamalar için kullanılmasını sağlar.

Ön Hazırlık

6OfL8I.gif

Yolo'yu kullanabilmek için bazı gereksinimlere ihtiyacımız var. Bildiğiniz üzere "yapay zeka" kategorisine giren araçlar, genelde gpu'ya ihtiyaç duyuyor. Yolo için iyi bir performans almak istiyorsak GPU'nun hakkını vermemiz gerekiyor. GPU'nuz iyi değilse CPU üzerinden daha düşük FPS görüntü işleyebilirsiniz.

AoWbkNQ.png

GPU optimizasyonu başlı başına bir dert. Bazı projelerde haftalarca optimize etmeye uğraştığım oldu. Başlı başına bir konu olduğu için çok detaya girmeyeceğim. Fakat ilgi olursa onu farklı bir başlıkta tekrar anlatırım. Linux'da güzel performans almak için, Nvidia CUDA ve CuDNN kurmak gerekiyor. Bu linkten CUDA indirebilirsiniz. Ayrıca bu linkten CuDNN indirebilirsiniz. Fakat CuDNN indirebilmek için Nvidia'ya kayıt olmak gerekiyor.

Diğer gereklilikler:
Python3
OpenCV
Darknet( Yolo, Darknet framework'ünden türemiştir. )

Yolo | Veri İşaretleme

6OfL8I.gif

Derin öğrenme algoritmamızın, görüntüleri tanıyabilmesi için görüntüleri işaretlememiz gerekiyor. İşaretleme için
LabelImg yazılımını tavsiye ederim. Bütün platformlarda çalışmaktadır.
Kod:
pip3 install labelimg
komutu ile bilgisayarınıza kurabilirsiniz.
Ardından terminalinize
labelImg yazarak çalıştırabilirsiniz.
KO4b7sQ.png


Sol tarafta yer alan menüden işaretleyeceğimiz
veri tipini YOLO yapmamız gerekiyor. Bunu yaptıktan sonra Open Dir butonuna basarak, görüntülerimizin olduğu klasörü açabiliriz.
KOz23o0.png


Görselde gördüğünüz gibi, veri tipimi YOLO olarak ayarladım. Ardından Open Dir butonundan görsellerimin bulunduğu klasörü seçtim. Sağ tarafta
File List yazan yerde, klasördeki görüntüler görünüyor.
Burada sağ tarafta
use default label seçeneğini seçip, işaretleyeceğim veriye isim veriyorum. Ardından sol tarafta yer alan Create RectBox butonu aracılığıyla, algılamak istediğim objeleri işaretlemeye başlıyorum. Ayrıca Create RectBox butonuna basmak yerine w tuşuna basarak kısayolu kullanabilirsiniz.
YGwWnDW.png


Ardından
ctrl-s veya sol taraftaki menüde Save butonuna basarak, işaretlenmiş verileri kaydediyoruz. Verileri kaydettikten sonra sol yukarıdan Next Image butonuna basarak, diğer görsellere geçiş yapabilirsiniz. Bütün görselleri tamamladıktan sonra eğitim kısmına geçebiliriz.

Yolo | Veri Eğitme

6OfL8I.gif

Bu bölümü yazarken çok düşündüm. Veriyi bilgisayar tarafında eğiterek mi anlatsam? Yoksa Google Colab üzerinden mi anlatsam? diye. Fakat Google Colab üzerinden anlatmak daha mantıklı geldi.
Herkesin bilgisayarı çok iyi GPU'ya sahip olamıyor. Görüntü işlerken sıkıntı değil ama eğitirken sıkıntı yaratabilir. Ayrıca Windows için veri eğitme baya meşakatli bir iş.
Bundan dolayı Google Colab üzerinden anlatacağım.
Eğer bilgisayardan eğitmek isterseniz, aynı adımlar bilgisayar üzerinden yapılacak. Tıkanırsanız, sorduğunuz takdirde yanıtlarım. Sizin için hazır scriptlerin olduğu şöyle bir colab dosyası oluşturdum. Tıklayarak erişebilirsiniz.

Colab dosyasını kendi drivenize kopyalayın. Ardından işaretlediğiniz görüntüleri zipleyerek, Colab dosyasıyla aynı klasöre atın.
7DXnEtM.png

Yukarıdaki görselde gösterdiğim gibi, Colab üzerinde çalışmadan önce Runtime > Change Runtime seçeneğine girip, Hardware accelerator olarak GPU'yu seçiyoruz. Verimizi daha hızlı eğitmek için bunu yapmak şart.
Ardından

Kod:
!nvidia-smi
komutu ile driverlarımızı kontrol edebiliriz.
Al02RoQ.png


Colab dosyamız, Drive üzerinde yer alan dosyalara erişebilmesi için aşağıdaki komutları yazıyoruz.
Python:
from google.colab import drive
drive.mount('/content/gdrive')
!ln -s /content/gdrive/My\ Drive/ /mydrive
!ls /mydrive

p08OCUx.png

Erişime izin verdikten sonra aşağıdaki komutlar ile Darknet framework'unu indirip, OpenCV'yi GPU'ya göre yapılandırıyoruz. Bu işlem 2-3 dakika sürebilir.
28sOukX.png


Ardından
Kod:
!cp cfg/yolov4-tiny.cfg cfg/yolov4-tiny-training.cfg
komutu ile yolov4-tiny configuration dosyamızı eğitim için kopyalıyoruz.
Burada önemli bir detay vermek istiyorum. Yolov4-tiny, tiny bir modeldir. Yani daha düşük doğrulukta yüksek performansla çalışır. Raspberry Pi, Jetson Nano, Xavier, vb. gibi donanımlarda çalıştırmak için makul bir modeldir. İsterseniz yolov4,yolov5,yolov7 versiyonlarını kullanabilirsiniz.
Ardından configuration dosyamızı modelimize göre yapılandırıyoruz. Burada standart olarak batch değerlerimizi, classes değerlerimizi ayarlıyoruz. Eğer bu konular hakkında detaylı bir bilginiz yoksa şimdilik dokunmayın. Tecrübe edindikçe performansını kendinize göre ayarlarsınız.

Kod:
!sed -i 's/batch=1/batch=64/' cfg/yolov4-tiny-training.cfg[/COLOR][/CENTER][/COLOR][/CENTER]
[COLOR=rgb(239, 239, 239)][CENTER][COLOR=rgb(239, 239, 239)][CENTER]!sed -i 's/subdivisions=1/subdivisions=16/' cfg/yolov4-tiny-training.cfg
!sed -i 's/max_batches = 500200/max_batches = 4000/' cfg/yolov4-tiny-training.cfg
!sed -i '610 s@classes=80@classes=1@' cfg/yolov4-tiny-training.cfg
!sed -i '696 s@classes=80@classes=1@' cfg/yolov4-tiny-training.cfg
!sed -i '783 s@classes=80@classes=1@' cfg/yolov4-tiny-training.cfg
!sed -i '603 s@filters=255@filters=18@' cfg/yolov4-tiny-training.cfg
!sed -i '689 s@filters=255@filters=18@' cfg/yolov4-tiny-training.cfg
!sed -i '776 s@filters=255@filters=18@' cfg/yolov4-tiny-training.cfg



Ardından model adımıza ait drivede bir names dosyası oluşturuyoruz, darknet'in eğitim için ihtiyaç duyduğu diğer objeleri oluşturuyoruz.
Kod:
!echo "postit <-- buraya model adı yazılacak!!!!!!" > data/obj.names[/COLOR][/CENTER][/COLOR][/CENTER]
[COLOR=rgb(239, 239, 239)][CENTER][COLOR=rgb(239, 239, 239)][CENTER]!echo -e 'classes= 1\ntrain  = data/train.txt\nvalid  = data/test.txt\nnames = data/obj.names\nbackup = /mydrive' > data/obj.data
!mkdir data/obj



Ardından darknet yapay sinir ağımızı indiriyoruz.
Kod:
!wget https://pjreddie.com/media/files/darknet53.conv.74
4koxOCr.png

Ardından Yoloya postitimizin yolunu girerek içerisindeki dosyaları klasöre çıkartıyoruz.
Kod:
!unzip /mydrive/postit.zip -d data/obj
fpr7RA7.png

Ardından txt dosyalarımızı, darknetin algılayabileceği şekilde modifiye ediyoruz ve listeye dönüştürüyoruz. Bunun için aşağıdaki scripti kullanabilirsiniz.

Python:
import glob
import os
import re
txt_file_paths = glob.glob(r"data/obj/*.txt")
for i, file_path in enumerate(txt_file_paths):
    # get image size
    with open(file_path, "r") as f_o:
        lines = f_o.readlines()
        text_converted = []
        for line in lines:
            print(line)
            numbers = re.findall("[0-9.]+", line)
            print(numbers)
            if numbers:
              try:
                  # Define coordinates
                  text = "{} {} {} {} {}".format(0, numbers[1], numbers[2], numbers[3], numbers[4])
                  text_converted.append(text)
                  print(i, file_path)
                  print(text)
              except:
                pass
        # Write file
        with open(file_path, 'w') as fp:
            for item in text_converted:
                fp.writelines("%s\n" % item)
jUkJQ5v.png

Ardından görüntülerimizin yolunu images_list değişkenine atayıp train.txt dosyasına kaydediyoruz.
Python:
import glob
images_list = glob.glob("data/obj/*.png")
print(images_list)

#train.txt dosyasını oluştur
file = open("data/train.txt", "w")
file.write("\n".join(images_list))
file.close()
8lbi5oN.png

Son olarak
Kod:
!./darknet detector train data/obj.data cfg/yolov4-tiny-training.cfg darknet53.conv.74 -dont_show
komutu ile eğitimi başlatıyoruz.

kqHuOEy.png

Colab verimizi eğitmeye başladı, gördüğünüz gibi. Artık veri eğitildikçe drive üzerinde yolov4-tiny-training_last.weights adında dosyalarımızın oluştuğunu gözlemleyebilirsiniz.
4e4Aiv6.png

Ortalama 1-2 saat eğitildikten sonra eğitilmiş veriyi indirip, görüntü işlemeye başlayabilirsiniz. Google Colab ortalama 4 saat sonra eğitimi kendiliğinden durdurur. Fakat Colab Pro kullanırsanız bu süreler daha da uzayabilir.

Yolo | Görüntü İşleme

6OfL8I.gif

Aslında Yolo ile birçok farklı kütüphane ile görüntü işlenebiliyor. Örneğin Pytorch, Tensorflow, vb. Fakat ben bu içeriği doğrudan, Yoloyu ortaya yolo yapan Darknet frameworkü üzerinden anlattığım için weights uzantılı dosyalar üzerinden anlatacağım. Yani bu durumda OpenCV kullanacağız. Kodların anlamlarını kod içerisinde yorum satırı olarak yazacağım.

Kodumuzu yazmadan önce, eğitmiş olduğumuz weights dosyasını, eğitim için oluşturduğumuz cfg dosyasını indirip aynı klasöre atıyoruz.
Ayrıca coco.names adında bir dosya oluşturup içerisine işaretlediğimiz objenin adını giriyoruz. Eğer birden fazla obje mevcutsa alt alta yazabilirsiniz.

Eğitim uzun sürdüğü için ben içeriği daha önceden eğitmiş olduğum çatlak modeliyle yapacağım. Bilginiz olsun. Yukarıda postit eğitiyordun, çatlak ne alaka diye sormayın :D

OpenCV + Yolo ile fotoğraf işleme örnek kod (Kodu anlamanız için açıklamaları okuyun!! boşuna yazmadım :) )



Python:
import cv2 as cv #Opencv import ediyoruz.
import numpy as np
img = cv.imread('catlak.jpg') # işlemek istediğimiz görüntünün yolu
# Burada coco.names dosyamızı oluşturuyoruz. Ayrıca algılanan objelere rastgele renk atmak için colors değişkenimizi oluşturuyoruz.
classes = open('coco.names').read().strip().split('\n')
np.random.seed(42)
colors = np.random.randint(0, 255, size=(len(classes), 3), dtype='uint8')
net = cv.dnn.readNetFromDarknet('yolov4-tiny.cfg', 'catlak.weights')  #OpenCV'nin dnn.readNetFromDarknet fonksiyonundan faydalanıyoruz. ve eğittiğimiz weights dosyası ile cfg dosyasını tanımlıyoruz.
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

# output katmanımızı tanımlıyoruz.
ln = net.getLayerNames()
#ln = [ln[i[0] -1] for i in net.getUnconnectedOutLayers()] # Windows bilgisayarlarda bu komut geçerli.
ln = [ln[i -1] for i in net.getUnconnectedOutLayers()]
# görüntünün blob değerlerini ayarlıyoruz. Daha hızlı görüntü işlemek için (416,416) boyutunu küçültebilirsiniz. Fakat kaliteden feragat edersiniz.
blob = cv.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
r = blob[0, 0, :, :]
#ağımızın girdilerini tanımlıyoruz.
net.setInput(blob)
outputs = net.forward(ln)
boxes = []
confidences = []
classIDs = []
h, w = img.shape[:2]
for output in outputs: # ağımızın verdiği çıktıları alıyoruz
    for detection in output: # tespit edilenleri for döngüsüne alıyoruz.
        scores = detection[5:]
        classID = np.argmax(scores)
        confidence = scores[classID]
        if confidence > 0.5: # tespit edilen görüntüler %50 doğruluk ve üzerindeyse doğru kabul ediyoruz.
            box = detection[:4] * np.array([w, h, w, h]) # tespit edilen görüntünün dikdörtgen şeklinde kenarlarını alıyoruz
            (centerX, centerY, width, height) = box.astype("int") # görüntünün
            x = int(centerX - (width / 2)) # x merkezi
            y = int(centerY - (height / 2)) # y merkezi
            box = [x, y, int(width), int(height)]
            boxes.append(box) #liste olarak hepsini kaydediyoruz
            confidences.append(float(confidence))
            classIDs.append(classID)
indices = cv.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4) # iç içe geçen aynı dikdörtgenleri ayıklıyoruz.
if len(indices) > 0:
    for i in indices.flatten(): #iç içe olmayan objelerin etrafına dikdörtgen çiziyoruz.
        (x, y) = (boxes[i][0], boxes[i][1])
        (w, h) = (boxes[i][2], boxes[i][3])
        color = [int(c) for c in colors[classIDs[i]]]
        cv.rectangle(img, (x, y), (x + w, y + h), color, 2)
        text = "{}: {:.4f}".format(classes[classIDs[i]], confidences[i])
        cv.putText(img, text, (x, y - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
cv.imshow('window', img) # görüntüyü göster
cv.waitKey(0)

Ve sonuç TADAAAA!
hjQyjQU.png


OpenCV + Yolo ile video veya gerçek zamanlı görüntü işleme örnek kod:

Python:
import cv2 as cv #Opencv import ediyoruz.
import numpy as np
frame = cv.VideoCapture("video.mp4") # işlemek istediğimiz görüntünün yolu eğer kameranızı kullanmak isterseniz cv.VideoCapture(0) olarak değiştirebilirsiniz.
# Burada coco.names dosyamızı oluşturuyoruz. Ayrıca algılanan objelere rastgele renk atmak için colors değişkenimizi oluşturuyoruz.
classes = open('coco.names').read().strip().split('\n')
np.random.seed(42)
colors = np.random.randint(0, 255, size=(len(classes), 3), dtype='uint8')
net = cv.dnn.readNetFromDarknet('yolov4-tiny.cfg', 'catlak.weights')  #OpenCV'nin dnn.readNetFromDarknet fonksiyonundan faydalanıyoruz.
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

# output katmanımızı tanımlıyoruz.
ln = net.getLayerNames()
#ln = [ln[i[0] -1] for i in net.getUnconnectedOutLayers()] # Windows bilgisayarlarda bu komut geçerli.
ln = [ln[i -1] for i in net.getUnconnectedOutLayers()]
while(True):
    _,img = frame.read()
    # görüntünün blob değerlerini ayarlıyoruz. Daha hızlı görüntü işlemek için (416,416) boyutunu küçültebilirsiniz. Fakat kaliteden feragat edersiniz.
    blob = cv.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
    r = blob[0, 0, :, :]
    #ağımızın girdilerini tanımlıyoruz.
    net.setInput(blob)
    outputs = net.forward(ln)
    boxes = []
    confidences = []
    classIDs = []
    h, w = img.shape[:2]
    for output in outputs: # ağımızın verdiği çıktıları alıyoruz
        for detection in output: # tespit edilenleri for döngüsüne alıyoruz.
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]
            if confidence > 0.5: # tespit edilen görüntüler %50 doğruluk ve üzerindeyse doğru kabul ediyoruz.
                box = detection[:4] * np.array([w, h, w, h]) # tespit edilen görüntünün dikdörtgen şeklinde kenarlarını alıyoruz
                (centerX, centerY, width, height) = box.astype("int") # görüntünün
                x = int(centerX - (width / 2)) # x merkezi
                y = int(centerY - (height / 2)) # y merkezi
                box = [x, y, int(width), int(height)]
                boxes.append(box) #liste olarak hepsini kaydediyoruz
                confidences.append(float(confidence))
                classIDs.append(classID)
    indices = cv.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4) # iç içe geçen aynı dikdörtgenleri ayıklıyoruz.
    if len(indices) > 0:
        for i in indices.flatten(): #iç içe olmayan objelerin etrafına dikdörtgen çiziyoruz.
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])
            color = [int(c) for c in colors[classIDs[i]]]
            cv.rectangle(img, (x, y), (x + w, y + h), color, 2)
            text = "{}: {:.4f}".format(classes[classIDs[i]], confidences[i])
            cv.putText(img, text, (x, y - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
    cv.imshow('window', img) # görüntüyü göster
    cv.waitKey(1)
EhrPBUw.png



6OfL8I.gif

Konunun sonuna gelmiş bulunmaktayız. Umarım faydalı bir konu olmuştur.
İyi Forumlar!
 
Son düzenleme:

'GÖKKURT

Katılımcı Üye
10 Şub 2019
343
221
Şimdi diyorsunuz ki doğal sinyal ve görüntü işleme, video işleme, bilgisayar oyunları, robotlar ve otonom arabalar, ses, konuşma, yüz, metin tanıma, nesne algılama alanlarında kullanılan YOLO ile Zeki MÜREN'de bizi tanıyabilirdi :ROFLMAO: Sayın Hocam online oyun karakter taraması yaparak daha sonra tarafınızdan hazırlanan bir proğram ile mouse imlecimiz ilgili karakterlere yönelse (kutucuk bazlı) biz sadece tıklama yaparak (autoclick yaparsanız parmağımız yorulmaz:D) " HEADSHOT" piri olabilirmiyiz :D Elinize Emeğinize Sağlık güzel konu ...(y)
 

Enistein

Kıdemli Üye
16 Eyl 2012
2,219
1,206
Amsterdam
Şimdi diyorsunuz ki doğal sinyal ve görüntü işleme, video işleme, bilgisayar oyunları, robotlar ve otonom arabalar, ses, konuşma, yüz, metin tanıma, nesne algılama alanlarında kullanılan YOLO ile Zeki MÜREN'de bizi tanıyabilirdi :ROFLMAO: Sayın Hocam online oyun karakter taraması yaparak daha sonra tarafınızdan hazırlanan bir proğram ile mouse imlecimiz ilgili karakterlere yönelse (kutucuk bazlı) biz sadece tıklama yaparak (autoclick yaparsanız parmağımız yorulmaz:D) " HEADSHOT" piri olabilirmiyiz :D Elinize Emeğinize Sağlık güzel konu ...(y)
Görüntü işleme ile yapılacakların sınırı yok :D kafamızı sadece oyun hilelerine odaklamayalım :D
 

acadbond

Yeni üye
26 Tem 2019
14
4
40
Elazığ
Çok güzel bir konu dediklerinizi tek tek uyguladım. fakat eksik kaldım bazı yerlerde. bununda nedeni olayı tam kavrayamam oldu. yada tam anlayılamadım. her ne kadar anlamaya çalışsam da. Tavsiyeniz nedir ?
 

Enistein

Kıdemli Üye
16 Eyl 2012
2,219
1,206
Amsterdam
Çok güzel bir konu dediklerinizi tek tek uyguladım. fakat eksik kaldım bazı yerlerde. bununda nedeni olayı tam kavrayamam oldu. yada tam anlayılamadım. her ne kadar anlamaya çalışsam da. Tavsiyeniz nedir ?
Deep Learning zor bir alandır. Bundan dolayı her adımı hassas bir şekilde uygulamanız gerekiyor. Tam olarak nerede eksik kaldınız?
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.