Evrişimli Ağlar ile U-Net Görüntü Segmentasyonu
Günümüzde, bilgisayarlı görü alanında görüntü verileri üzerinde semantik segmentasyon sıkça kullanılmaktadır. U-Net, nesnelerin maskelenmesi için içerisinde evrişimli sinir ağlarını barındıran bir omurga ağıdır.
🧶U-Net, adını şekilde görüldüğü gibi U harfine benzer mimarisinden almaktadır. Giriş görüntüleri, çıkışta bölümlere ayrılmış bir çıkış haritası olarak elde edilir.
U-Net ağının temel seviye bilgileri ve çalışma mimarisine U-Net ile Görüntü Segmentasyonu yazısından ulaşabilirsiniz. Bu yazıda, Python programlama dilinde U-Net ağının adım adım kodlaması anlatılmaktadır.
🚀 U-Net ile görüntü segmentasyonu videosu için lütfen tıklayınız.
Adım 1: Veri setinin elde edilmesi
Bu adımda, eğer veri setiniz var olan bir kod içerisinden çekilecek ise aşağıdaki gibi dosya içerisinden yükleme yapabilirsiniz. Eğer veri setiniz çalıştığınız aktif klasörde ise dosya içerisinden veriyi yükleyerek çalışabilirsiniz. Aşağıdaki kod satırındaki gibi çalışacaksanız, verinin yüklenirken bir hazırlık aşamasından geçirilmesi gerekmektedir.
Modülü içeri aktardığımız Python dosyasının kodlarına aşağıda yer verilmektedir. Buradaki r değişkeni veri setinin indirileceği adrese istek yapmaktadır. Download_dataset dosyasından verilerin indirilmesi için istek yapılan varsayılan olarak gelen alan adı yerine indirmek istediğiniz bağlantıyı yazmalısınız.
Çalışma boyunca kullanılan kütüphanelere aşağıda yer verilmiştir.
* pip install -r requirements.txt * komutu ile bu ortama kütüphaneler yüklenmelidir.
📣 DİKKAT !
Download_dataset dosyasına ait Python kodları, aktif çalışılacak olan Python klasöründe yer almalıdır. Böylelikle, daha sonra bu dosya içerisinden veri setinin indirilmesi sağlanabilir. Bir sonraki adım ise verilerin hazırlanması aşamasıdır.
Adım 2: Verilerin hazırlanması
Bu adımda, veri kümesine alınan görüntüler 512 x 512 boyutuna indirgenir. Böylelikle, çalışmada kullanılan tüm veriler tek tip veri boyutuna getirilmiştir.
🪐Bilindiği gibi, evrişimli sinir ağı modeli boyunca uygulanılan yükseklik ve genişlikte boyut küçültme işlemi yani havuzlama katmanı — maksimum, ortalama veya medyan gibi farklı yaklaşımlarla birleştirmek mümkündür ve kodun ikinci yarısında uygulanmaktadır. Bu katmanlar sayesinde, çıktının çözünürlüğünün arttırılması hedeflenmiştir. Yüksek çözünürlüklü özellikler ve örneklenmiş çıktı, yerelleştirme için model boyunca birleştirilir. Sıralı bir evrişim katmanı daha sonra bu bilgilere dayanarak daha kesin bir çıktı oluşturmayı amaçlar.
Bu kod satırında içeriye aktarılan images_prepare modülünün tamamına aşağıdan ulaşabilirsiniz.
Adım 3: Maskelerin elde edilmesi
Yukarıda bahsi geçen masks_prepare dosyası aşağıdaki kod parçacığı alınarak kaydedilmiştir. Bu adımda ilk olarak pre_masks fonksiyonu kullanılarak yeniden boyutlandırılmış veriler fonksiyona argüman olarak gönderilmiştir.
🧮 Görüntüler, 1 boyuta dönüştürülerek NumPy dizisine atanmıştır. Görüntü değerlerinin diziye dönüştürülme aşaması, piksel değerleri ile işlem yapılması için şarttır. Görüntülerden çıkarım yapılan maskeler bir klasöre kaydedilmektedir. Kısacası, U-Net diğer algoritmalara göre bir etiket referansı ile değil matematiksel çıkarım yapılan maskeler ile çalışmaktadır.
Adım 4: Verinin ölçeklendirilmesi ve dönüşümü
Bu adımda veriler images ve masks olarak adlandırılan X ve Y değerleri Float32 olarak ölçeklendirilir. Bu adımda, eğitim ve test kümesinde 105 adeti ile işlem yapacağım için NumPy dizisi için dizi üzerinde değişiklik yapılmıştır. Bunu kendi verinize göre değiştirebilirsiniz. plt.imshow ile rastgele çektiğiniz bir görüntü verisinin kontrolünü yapabilirsiniz.
Adım 5: U-Net modelinin oluşturulması
Bu adımda, klasörde oluşturulan UNET fonksiyonu kullanılmıştır. Model için gerekli katmanlar olan CONV2D, MaxPooling2D, BatchNormalization, Conv2DTranspose, Dropout katmanları içeriye aktarılmıştır.
Çalışma klasöründe yer alan model.py dosyasından çekilen U-Net modeli için bir fonksiyon oluşturulması çalışma açısından işi hızlandıracaktır. Bir sonraki model için yine yukarıdaki gibi U-Net modeli çekilmelidir.
Kod içerisinde bulunan katmanların görselleştirilmesi için ise model.summary() kullanılmıştır. Katmanlar özetlendiğinde aşağıdaki gibi çıktı alınmaktadır. Görselde görüldüğü kadar az katman bulunmuyor, yalnızca ilk katmanları yer kaplamaması adına ekledim.
Adım 6: U-Net modelinin compile ve fit edilmesi
Bu aşamada iki ayrı fonksiyon kullanılmaktadır.
- model.compile: Kayıp fonksiyonu, optimize ediciyi ve metrikleri tanımlar. Eğitmek için derlenmiş bir modele ihtiyacınız vardır (çünkü eğitim, kayıp fonksiyonu ve optimize ediciyi kullanır). Ancak tahmin için bir model derlemek gerekli değildir.
- model.fit: Modeli belirli sayıda dönem için eğitir. Burada epochs parametresi 100 verildiği için 100 adımda eğitim tamamlanacaktır. Burada seçilen metrik [“accuracy”] olarak verildiği için eğitim sırasında adım adım doğruluk değerleri izlenecektir.
Kodda da belirtildiği gibi derleme sırasında seçilen metrikler, kayıp fonksiyonu ve optimize edici tamamen kişiye bağlı olarak seçilebilir. Bunu değiştirip doğruluk değişimini gözle görebilirsiniz. Sonuç olarak model eğitime başlandığında aşağıdaki gibi dönem değişimleri gözlemlenmektedir. Bu aşamaya kadar geldiyseniz, TEBRİKLER!
Adım 7: Modelin tahmin aşaması
Eğitim bittiğinde ise bir sonraki adım tahmin adımıdır. Burada görüldüğü gibi öncelikle x_test olarak ayırdığımız veriler predict fonksiyonu ile bir değişkene atanır ve kullanılır. Tahmin sonucunu predict değerini ekrana yazdırarak görebilirsiniz.
📑 Çalışmada kullanılan akademik makale;
U-Net: Convolutional Networks for Biomedical Image Segmentation
👁🗨 Çalışmada kullanılan kodların ana kaynağı;
REFERANSLAR
- “Semantic Segmentation”, Tingwu Wang, Machine Learning Group, University of Toronto.