paint-brush
MinIO ve YOLO ile Özel Bir Veri Kümesi Kullanılarak Nesne Algılama Modeli Nasıl Eğitilirile@minio
8,522 okumalar
8,522 okumalar

MinIO ve YOLO ile Özel Bir Veri Kümesi Kullanılarak Nesne Algılama Modeli Nasıl Eğitilir

ile MinIO13m2023/11/22
Read on Terminal Reader

Çok uzun; Okumak

Bu yazıda, özel bir görüntü veri kümesi oluşturacağız ve ardından her yerde bulunan nesne algılama görevi için Yalnızca Bir Kez Bakarsınız (YOLO) modelini eğiteceğiz. Daha sonra MinIO Bucket Notifications'ı kullanarak yeni bir görüntü üzerinde otomatik olarak çıkarım yapabilen bir sistem uygulayacağız.
featured image - MinIO ve YOLO ile Özel Bir Veri Kümesi Kullanılarak Nesne Algılama Modeli Nasıl Eğitilir
MinIO HackerNoon profile picture
0-item
1-item

Bilgisayarla görme, yapay zekanın son derece ilgi çekici bir uygulaması olmaya devam ediyor. İster bir savaş alanındaki unsurları tanımak ister mahsul verimini tahmin etmek olsun, bilgisayarlı görme, muhtemelen yapay zekanın ticari açıdan en değerli (ve toplumsal açıdan önemli) alanlarından biridir.


Bununla birlikte, en iyi bilgisayarlı görme yeteneklerinin benimsenmesindeki hız sınırlayıcı, çoğu zaman bir veri kümesi oluşturma ve bilgisayarlı görme görevinizi yeni bir görüntü üzerinde gerçekleştirecek basit bir uçtan uca sistem tasarlamayla ilişkili karmaşıklıklardır.


Bu blog yazısında, CVAT ve MinIO Bucket Notifications gibi sınıfının en iyisi araçlarla bu sorunların nasıl çözüleceğine adım adım bakacağız. Bu yazının sonunda, özel bir veri kümesi üzerinde bir nesne algılama modelini eğitebilecek ve bunu, yeni bir görüntü göründüğünde tahminlerde bulunmak için kullanabileceksiniz.

Öncül

Diyelim ki uydu görüntülerinde bulunan uçak türlerini tanıyabilmek istiyoruz. Ayrıca sıfırdan başladığımızı varsayalım: önceden oluşturulmuş veri kümeleri yok, önceden eğitilmiş modeller yok. Uydu görüntülerimizde tespit edip tanımak istediğimiz iki örnek uçak:


Soldan sağa: (1) Su-30, (2) Tu-95


Bu yazıda özetlenen adımlar hemen hemen her alana genelleştirilebilir. Uçak türlerini tespit etmek yerine arazi kullanımını sınıflandırıyor veya mahsul verimini tahmin etmek için regresyon yapıyor olabiliriz. Geleneksel görüntülerin ötesinde, LiDAR nokta bulutları veya 3D Sismik Görüntüler gibi diğer çok boyutlu veri türlerini de eğitiyor ve bunlar üzerinde çıkarımlar yapıyor olabiliriz; mesele sadece eğitim verilerinin nasıl göründüğü (ve potansiyel olarak YOLO yerine farklı bir derin öğrenme modeli) meselesi haline geliyor. Belirli bir kullanım durumu için bunun nasıl görüneceğine ilişkin daha fazla sorunuz varsa GitHub deposunda sorun oluşturmaktan çekinmeyin!


1. Adım: Eğitim Örneklerinin Alınması ve Yönetilmesi

Bu proje için, büyük ölçüde isteğe bağlı bir görüntüleme uydusuna sahip olmadığım için, Google Earth'teki hava alanlarını ziyaret ettim ve bu uçaklardan bazılarının görülebildiği alanların birden fazla ekran görüntüsünü aldım. Bu görüntü setinin birleştirilmesi oldukça zaman aldı, bu yüzden hepsini MinIO sunucumdaki "nesne algılama" başlıklı bir klasörde sakladım. Üretim ortamında, toplanan numunelerinizi MinIO'da saklamanın faydaları daha da ileri görüşlü hale gelir. Aktif-aktif çoğaltma, en yüksek düzeyde şifreleme ve süper hızlı GET/PUT'lar (birkaç örnek vermek gerekirse), özenle topladığınız örneklerin yüksek oranda kullanılabilir, güvenli ve emniyetli olacağı anlamına gelir.

Adım 2: Veri Kümesini Oluşturma

Veri Kümesini Oluşturma


Kullanım durumunuza yönelik bir nesne algılama modeli eğitmek amacıyla etiketlenmiş (veya 'açıklamalı') bir veri kümesine ihtiyaç vardır. Bunun için harika bir araç OpenCV'nin CVAT'ıdır. Harika bir özellik, CVAT'ın, klasörünüzün görüntülerini doğrudan veri kümesi açıklama aracına beslemek için MinIO klasörünüzü bir "bulut depolama" olarak bağlamaya yönelik bir yardımcı program sağlamasıdır. Bunu yapmak için, özellikle MinIO Sunucusunu şirket içinde veya yerel olarak dizüstü bilgisayarınızda çalıştırıyorsanız, MinIO Sunucunuzun ana bilgisayarının CVAT sunucusu tarafından erişilebilir olduğundan emin olun. Ayrıca, bir not olarak CVAT'ı kullanmanın iki yolu vardır: (1) app.cvat.ai adresinde sağlanan web uygulamasını kullanarak veya (2) yerel olarak çalıştırarak. Her iki durumda da CVAT'ı açtıktan sonra menü çubuğundaki "Bulut Depolamalar"a tıklayın. Buradan (S3 Uyumlu) MinIO kovanızı eklemek için bir form doldurabilirsiniz:


Bulut depolama alanı oluşturun


Şimdi “Görevler” altında yeni etiketleme görevimizi oluşturalım:


Etiketleme Görevi


Doldurmanız gereken bir form istenecektir:


Yeni bir görev oluştur


Görevi oluştururken sınıf etiketlerini doğru tanımlamak önemlidir (Algılamak istediğim iki düzleme karşılık gelen “SU30” ve “TU95” başlıklı iki Dikdörtgen etiketi tanımladım):


Sınıf etiketlerini tanımlama


Artık geri kalan adım, önceden eklediğimiz MinIO paketimizi veri kaynağı olarak eklemektir. "Dosya Seç"in altında "Bulut Depolama"yı tıklayın ve bu kaynak için daha önce sağladığınız adı girin. Yukarıda “minio-cv-bucket” ismini kullandım.


MinIO Kovasını veri kaynağı olarak ekleme


Yükleme işlemi birkaç dakika sürecektir. Tamamlandığında, ek açıklama işinizi "İşler" altında görebilmeniz gerekir.


Yükleme tamamlandı


Artık işin üzerine tıklayarak görsellerinizin her birine açıklama eklemeye başlayabilirsiniz. Uyarı: Bu orantısız bir şekilde zaman alıcı bir süreç olabilir. Genel olarak, büyük açıklama gereksinimleri olan bir üretim ortamında, bu görevi özel bir dahili ekibe veya üçüncü taraf bir veri etiketleme şirketine devretmek en iyisi olabilir.


Ek açıklama eklemeye başlanıyor


Açıklama eklemeyi tamamladığınızda veri kümesini YOLO formatında dışa aktarın.


Verileri dışa aktarma

3. Adım: Eğitim Verilerini Düzenleme

Dışa aktarılan veri kümeniz zip dosyası biçiminde olacaktır. Sıkıştırılmış dosyayı açtığınızda, YOLO biçimli ek açıklama metin dosyaları kapalı bir klasörde olacaktır. Onlara göz atmaktan çekinmeyin. YOLO formatında, her görüntünün ek açıklamaları, her satırın sınırlayıcı kutunun ve sınıfın iki köşesini içerdiği bir metin dosyasındadır. Sınıf numarası, görevi oluştururken etiketleri tanımladığınız sıraya karşılık gelir. Yani bu örnekte 0, Su-30'a, 1 ise Tu-95'e karşılık gelecektir.


Bu noktada yeni bir çalışma dizini oluşturun (veya önceden oluşturduğunuz bir dizini girin). Bu dizin içinde 'dataset' adında bir alt dizin oluşturun. 'Veri kümesi' içinde, çalışma dizininiz şöyle görünecek şekilde dizinler oluşturun:


 my_cv_project (WORKING DIRECTORY) |---- dataset |----images |----train |----val |----test |----annotations |----train |----val |----test



Artık hem görüntüler hem de bunlara karşılık gelen açıklamalar (metin dosyaları) için train, val ve test alt dizinlerini doldurmanız gerekecek. Numunelerinizi nasıl almak ve bölmek istediğiniz size kalmış. Toplam eğitim örneği miktarınızı %80 eğitim, %10 doğrulama ve %10 teste bölmek iyi bir uygulamadır. Resimlerinizi bölümlendirmeden önce rastgele karıştırdığınızdan emin olun.


Kişisel olarak, 'nesne algılama' grubumdaki tüm görüntüleri hızlı bir şekilde almak için MinIO Client'ın mc cp'sini komut satırında kullandım. Alternatif olarak, tüm örnek görsellerinizi yerel bilgisayarınızda zaten tek bir yerde bulunduruyorsanız, doğrudan bununla çalışabilirsiniz. Tüm örneklerimi tek bir yerde topladıktan sonra, resimlerimi ve açıklamalarımı karıştırmak, bölmek ve train, val ve test dizinlerine taşımak için bir Python betiği kullandım. İşte kolaylık sağlamak için sağlanan komut dosyası . Nasıl kullanılacağına dair herhangi bir sorunuz varsa, depoda sorun yapmaktan çekinmeyin!


Son olarak, resimler/tren, resimler/val veya resimler/test'e yerleştirdiğiniz her resim için eşleşen ek açıklama .txt dosyasının aynı zamanda annotations/ dizini içindeki karşılık gelen alt dizinde olduğundan emin olun. Örneğin:


 my_cv_project (WORKING DIRECTORY) |---- dataset |----images |----train - 5.png - 3.png - 2.png |----val - 4.png |----test - 1.png |----annotations |----train - 5.txt - 3.txt - 2.txt |----val - 4.txt |----test - 1.txt


Artık verilerimiz hazır. Nesne algılama modelimize bir göz atıp eğitime başlamanın zamanı geldi.

Adım 4: Nesne Algılama Modeli

Nesne tanımada mevcut altın standart (performans ve kullanım kolaylığı açısından), YOLO (Yalnızca Bir Kez Bakarsınız) sınıfı modellerdir. Bu yazının yazıldığı sırada YOLOv8 en son sürümdür ve Ultralytics tarafından açık kaynak olarak korunmaktadır. YOLOv8, modeli yeni oluşturulan ek açıklamalarımız üzerinde eğitmek (ve sonunda çıkarımı da yürütmek) için kullanabileceğimiz basit bir API sağlar.


YOLOv8'i indirelim:


 $ pip install ultralytics


Artık eğitmek, doğrulamak ve tahmin etmek için YOLOv8 CLI aracını veya Python SDK'yı kullanabiliriz. Daha fazla bilgi için YOLOv8 belgelerine bakın.

Adım 5: Eğitim

Çalışma dizininizde veri kümesinin konumlarını ve sınıflarla ilgili ayrıntıları belirten bir YAML dosyası tanımlayın. Yolların daha önce çalışma dizininde oluşturduğum yollarla aynı olduğuna dikkat edin. Dosyamı ' objdetect.yaml ' olarak adlandırdım. Ayrıca, iki uçak sınıfı etiketinin CVAT'ta olduğu gibi aynı sırada tanımlanması gerektiğine dikkat edin.


 train: ./dataset/images/train/ val: ./dataset/images/val/ test: ./dataset/images/test/ # number of classes nc: 2 # class names names: ["SU-30","TU-95"]


Aşağıdaki komutla (YOLO CLI aracını kullanarak) YOLOv8 modelini veri kümemiz üzerinde eğitmeye başlayın. Eğitim için yapılandırabileceğiniz tüm farklı seçenekler hakkında daha fazla bilgi edinmek için YOLO belgelerine bakın. Burada 100 dönemlik eğitime başlıyorum ve görüntü boyutunu 640 piksel olarak ayarlıyorum (eğitim sırasında tüm eğitim görsellerimiz buna göre ölçeklendirilecektir):


 $ yolo task=detect \ mode=train \ model=yolov8s.pt \ data=objdetect.yaml \ epochs=100 \ imgsz=640


Eğitim biraz zaman alacaktır, özellikle de bir dizüstü bilgisayar üzerinde çalışıyorsanız (benim gibi), o yüzden şimdi ara vermek (veya önceden okumak 😀) için iyi bir zaman!


Eğitim döngüsünün sonunda, eğitilen modeliniz diğer ilginç grafikler ve çizelgelerle birlikte 'çalışmalar' adı verilen otomatik olarak oluşturulan bir dizinde saklanacaktır. Terminal çıkışı (aşağıdaki gibi) en son çalıştırmanın sonuçlarının spesifik konumunu gösterecektir. Bir modeli her eğittiğinizde, 'runs/detect/' içinde benzer bir dizin oluşturulacaktır.


 Results saved to runs/detect/train


Not: run/detect/train/weights/, tam olarak eğitilmiş ağırlıklara sahip PT dosyalarını içerecektir. Bu konumu daha sonra hatırlayın.

Adım 5B: Model Doğrulaması ve Testi

Doğrulamayı aşağıdaki komutla çalıştırabilirsiniz:


 $ yolo task=detect \ mode=val \ model=path/to/best.pt \ data=objdetect.yaml


Sonuçlar otomatik olarak çalışma dizininizdeki 'çalıştır/algıla/val' biçiminde bir yola sahip bir klasörde saklanacaktır.


Test kümesinde çıkarım yapmak için aşağıdaki komutu kullanabilirsiniz:


 $ yolo task=detect \ mode=predict \ model=path/to/best.pt \ conf=0.5 \ source=dataset/images/test


Sonuçlar 'çalıştır/algıla/tahmin et' dosyasında saklanacaktır. İşte test setindeki bazı tahmin sonuçları:


Tahmin sonuçları


Adım 6: MinIO Paket Bildirimlerini Kullanarak Yeni Görüntü Çıkarımı

Artık uydu görüntüsünde bulunan bazı uçak türlerini tanıyabilen eğitilmiş bir modelimiz olduğuna göre, bunu yeni görüntüler için basit bir şekilde nasıl kullanabiliriz ?


MinIO Paket Bildirimlerini Kullanma


MinIO Bucket Notifications bunun için mükemmel bir araçtır. Bir webhook yardımıyla kovamıza düşen yeni bir görüntü üzerinden otomatik olarak nesne algılama çıkarımı yapabilecek bir sistem kurabiliriz.


Yüksek düzeyde 3 adımımız var. Öncelikle eğitilen modelimizle yeni bir görüntü üzerinde nesne tespiti gerçekleştirmek için webhook görevi görebilecek bir uç nokta tanımlamamız gerekiyor. İkinci olarak, MinIO Sunucu dağıtımımız için, bazı olaylar meydana geldiğinde webhook uç noktamıza ulaşması talimatını veren bazı ortam değişkenlerini yapılandırmamız gerekiyor. Üçüncü olarak, ne tür paket olayları (yani PUT) üzerinde işlem yapmak istediğimizi yapılandırmamız gerekiyor. Adım adım üzerinden geçelim.


MinIO paketine eklenen yeni bir görüntü üzerinde çıkarım yapan basit bir Flask tabanlı sunucunun ( detection_server.py ) kodu:


 """ This is a simple Flask inference server implementation that serves as a webhook for the event of a new image being added to a MinIO bucket. Object detection using YOLO will be performed on that image and the resulting predictions will be returned. """ from flask import Flask, request, abort, make_response from ultralytics import YOLO import tempfile from minio import Minio # Make sure the following are populated with your MinIO details # (Best practice is to use environment variables!) MINIO_ENDPOINT = '' MINIO_ACCESS_KEY = '' MINIO_SECRET_KEY = '' model = YOLO('/PATH/TO/best.pt') # load a custom model (path to trained weights) client = Minio( MINIO_ENDPOINT, access_key=MINIO_ACCESS_KEY, secret_key=MINIO_SECRET_KEY, ) app = Flask(__name__) @app.route('/', methods=['POST']) async def inference_bucket_webhook(): """ This endpoint will be called when a new object is placed in your inference bucket """ if request.method == 'POST': # Get the request event from the 'POST' call event = request.json bucket = event['Records'][0]['s3']['bucket']['name'] obj_name = event['Records'][0]['s3']['object']['key'] with tempfile.TemporaryDirectory() as temp_dir: temp_file_name = temp_dir+'/'+obj_name client.fget_object(bucket, obj_name, temp_file_name) # See https://docs.ultralytics.com/modes/predict/ for more information about YOLO inference options results = model.predict(source=temp_file_name, conf=0.5, stream=False) # A list of bounding boxes (if any) is returned. # Each bounding box is in the format [x1, y1, x2, y2, probability, class]. result = {"results": results[0].boxes.data.tolist()} print(result) resp = make_response(result, 200) return resp else: abort(400) if __name__ == '__main__': app.run()


Çıkarım sunucusunu başlatalım:


 $ python detection_server.py * Serving Flask app 'detection_server' * Debug mode: off * Running on http://127.0.0.1:5000 Press CTRL+C to quit


Flask uygulamasının çalıştığı ana bilgisayar adını ve bağlantı noktasını not edin.


Daha sonra MinIO tarafındaki web kancalarını yapılandırmaya başlayalım. Öncelikle aşağıdaki ortam değişkenlerini ayarlayın. <FONKSİYON ADI> kısmını seçtiğiniz bir fonksiyon adıyla değiştirin. Basit olması açısından 'çıkarımı' tercih ettim. Ayrıca uç nokta ortam değişkeninin çıkarım sunucunuz için doğru ana makineye ve bağlantı noktasına ayarlandığından emin olun. Bu durumda http://localhost:5000 Flask uygulamamızın çalıştığı yerdir.


 $ export MINIO_NOTIFY_WEBHOOK_ENABLE_<YOURFUNCTIONNAME>=on $ export MINIO_NOTIFY_WEBHOOK_ENDPOINT_<YOURFUNCTIONNAME>=http://localhost:5000


Şimdi, mc admin service restart ALIAS komutunu kullanarak MinIO Sunucusunu yeniden başlatın veya sunucuyu ilk kez başlatıyorsanız minio sunucu komutunu da kullanabilirsiniz. MinIO Sunucusunu yeniden başlatma/yeniden başlatma hakkında daha fazla bilgi için MinIO belgelerine bakın. Not: ALIAS, MinIO sunucu dağıtımınızın takma adı ile değiştirilmelidir. Bir takma adın nasıl ayarlanacağı veya mevcut takma adların nasıl görüntüleneceği hakkında daha fazla bilgi için dokümanlara göz atın.


Son olarak haber almak istediğimiz paketi ve etkinliği ekleyelim. Bizim durumumuzda, kovamıza ` put' olayları (yeni nesnelerin oluşturulması) hakkında bilgi almak istiyoruz. Bu amaç için “tespit-çıkarım” başlıklı yepyeni, boş bir kova hazırladım ve bunu 'KOVA'nın yerine koyacağım.


 $ mc event add ALIAS/BUCKET arn:minio:sqs::<YOURFUNCTIONNAME>:webhook --event put


Bu komutu çalıştırdığınızda " s3:ObjectCreated:* " çıktısının alınıp alınmadığını doğrulayarak paket bildirimleri için doğru olay türünü yapılandırıp yapılandırmadığınızı kontrol edebilirsiniz:


 $ mc event ls local/detect-inference arn:minio:sqs::<YOURFUNCTIONNAME>:webhook


Paket olaylarını bir webhook'ta yayınlamaya ilişkin daha ayrıntılı bir açıklama için dokümanlara göz atın. Artık yepyeni bir görüntü üzerinde nesne algılamayı denemeye hazırız!

Çıkarım Sistemimizi denemek

Çıkarım yapmak istediğim yeni görsel ('1.png' başlıklı):


Çıkarım sistemini denemek


Yeni görüntüyü 'çıkarımı tespit etme' grubuma bırakıyorum:


Resim yeni bir pakete bırakılıyor


Neredeyse anında Flask sunucumda aşağıdaki sonuçları görebiliyorum:


 $ python detection_server.py * Serving Flask app 'detection_server' * Debug mode: off * Running on http://127.0.0.1:5000 Press CTRL+C to quit image 1/1 /var/folders/xf/q7x0z8sn5nvckccp1g0m1vpm0000gn/T/tmpo6jx3w8u/1.png: 448x736 2 SU-30s, 101.0ms Speed: 4.1ms preprocess, 101.0ms inference, 5.8ms postprocess per image at shape (1, 3, 448, 736) {'results': [[1927.78369140625, 627.7123413085938, 1995.090576171875, 715.3443603515625, 0.8142037987709045, 0.0], [1735.740234375, 477.2108154296875, 1809.181640625, 555.767578125, 0.7766116261482239, 0.0]]} 127.0.0.1 - - [14/Sep/2023 15:39:21] "POST / HTTP/1.1" 200 -


Sonuçlar listesinde tespit edilen her sınırlayıcı kutunun YOLO formatında [x1, y1, x2, y2, olasılık, sınıf] olduğunu unutmayın. Orijinal görüntünün üzerine eklenen sınırlayıcı kutular ve tahmin edilen sınıflar şunlardır:


Diğer iki jet Su-30 değil. İlk veri kümem yaklaşık 100 görüntü içeriyordu, bu yüzden modelin benzer görünümlü uçaklar arasındaki nüansları zaten yakalayabildiğine şaşırdım. Sanırım buradaki ders şu: Gradyan inişini asla hafife almayın!


Not: Üretim ortamları ve/veya büyük makine öğrenimi modelleri için, çıkarımı daha sağlam ve güvenilir hale getirmek amacıyla PyTorch Serve veya Triton Server gibi yerleşik bir model hizmet çerçevesinin kullanılması iyi bir fikirdir. Bununla ilgileniyorsanız, MinIO ve PyTorch Serve ile Yapay Zeka Modeli Hizmetini Optimize Etme hakkındaki önceki yazıya göz atın.

Son Düşünceler

Yaptık! Toplanan görüntü örneklerimizi güvenli ve kullanılabilir tutmak için MinIO ve CVAT'ın nasıl bir araya geldiğinin yanı sıra özel nesne algılama veri kümemizi nasıl oluşturacağımızı da inceledik. Daha sonra özel görevimiz için kendi özel YOLO modelimizi eğittik. Son olarak, 50 satırın biraz üzerinde kodla, MinIO Bucket Notifications'ı kullanarak, özel eğitilmiş nesne algılama modelimizi geçerek yeni bir görüntü çalıştırabilecek bir çıkarım sunucusu oluşturduk.


MinIO ve YOLO uçta konuşlandırıldı.


Ayrıca, bilgisayarla görmenin görev açısından kritik uygulamalarının çoğu için, çıkarımı uçta gerçekleştirmek en iyisidir. Aksi takdirde, söz konusu uygulamalar, yeni verilerin genel buluta yüklenmesi ve buluttaki bir çıkarım sunucusunun yanıtla geri dönmesinin beklenmesiyle ilişkili gecikmelere karşı savunmasızdır; hatalı ağ bağlantısı risklerinden bahsetmeye bile gerek yok. Bu nedenle, veri katmanı olarak MinIO'yu merkeze alan bir bilgisayarlı görüntü hattı çok daha anlamlıdır. Tamamen yerleşik donanım ve yazılımla, eğitimli modelimizi yakalayabilen, depolayabilen ve yeni görüntüler üzerinde kullanabilen bir hava alanı üzerinde uçan bir drone hayal edin. MinIO sunucusunun yerel dağıtımıyla, gönderinin sonunda oluşturduğumuz Kova Bildirimi tabanlı çıkarım sistemi, bu senaryo ve bunun gibi sayısız senaryo için mükemmel şekilde çalışıyor.


Sorularınız varsa Slack Kanalımıza katılın veya [email protected] adresinden bize bir not bırakın. Sana yardım etmek için burdayız.


Burada da yayınlandı.