Veri Artırma

Bu yazının amacı iyi bir CNN modeli geliştirmek için sınırlı veya az miktardaki verimizi nasıl artırabileceğimiz olacaktır. Veri artırma işlemine ilk başta sadece NumPy kütüphanesi kullanarak nasıl yapılır onu göstermek istiyorum. Bir veriyi nasıl tüm kombinasyonlarıyla artırırız ki modelimiz daha iyi performansa sahip olsun bunu kovalıyacağız. Görüntü verisini artırmak en basitinden gürültü ekleme, döndürme, kaydırma, ölçekleme ve çevirme gibi şeyler akla gelir. Bunun en güzel örneklerini de GAN modelinde görebiliriz. Şimdi verimizi nasıl artıracağız görelim.

Veri artırma işlemine henüz girmeden, orijinal görüntümüz bu olsun:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

img = Image.open('funny_hats.jpg')
HEIGHT, WIDTH, DEPTH = np.size(img)

img = np.array(img)
plt.imshow(img)
plt.show()

Yukardaki kod parçacığı resmimizi görebiliriz.

Ters Çevirme:

# Flipping images with Numpy
flipped_img = np.fliplr(img)
plt.imshow(flipped_img)
plt.show()

En popüler metodlardan biridir. Ters çevrilmiş verinin modelinizin performansını artıracağı aşikardır. Mesela orijinal görüntümüz bir ayakkabı olsun. Sadece sağ ayakkabıyı kullanarak sol ayakkabıyı da bu şekilde edebildiğimizi düşünün.

Öteleme:

Amacı detect etmek olan modeller için öteleme ile elde edilmiş verinin de değeri yadsınamaz. Mesela bir araba düşünün, arabanın öteleme yüzünden görüntüden kaybolsun. Öteleme ile elde edilen veriler sayesinde yine o görüntünün araba olduğu anlaşılacaktır.

# Sola Kaydırma
for i in range(HEIGHT, 1, -1):
  for j in range(WIDTH):
     if (i < HEIGHT-20):
       img[j][i] = img[j][i-20]
     elif (i < HEIGHT-1):
       img[j][i] = 0
plt.imshow(img)
plt.show()

# Sağa Kaydırma
for j in range(WIDTH):
  for i in range(HEIGHT):
    if (i < HEIGHT-20):
      img[j][i] = img[j][i+20]
plt.imshow(img)
plt.show()

# Yukarı Kaydırma
for j in range(WIDTH):
  for i in range(HEIGHT):
    if (j < WIDTH - 20 and j > 20):
      img[j][i] = img[j+20][i]
    else:
      img[j][i] = 0
plt.imshow(img)
plt.show()


#Aşağı Kaydırma
for j in range(WIDTH, 1, -1):
  for i in range(278):
    if (j < 144 and j > 20):
      img[j][i] = img[j-20][i]
plt.imshow(img)
plt.show()

Gürültü ekleme:

Gürültü eklemek aydınlatma bozulmalarında sınıflandırmaya yardımcı olabilir ve genel olarak modeli daha performanslı hale getirebilir. Bazı kötü eğitilmiş modellerde verinin gürültü eklenerek çoğaltılmasıyla artık görüntünün sınıflandırılamaz hale gelmiştir.

# ADDING NOISE
noise = np.random.randint(5, size = (HEIGHT, WIDTH, DEPTH), dtype = 'uint8')

for i in range(WIDTH):
    for j in range(HEIGHT):
        for k in range(DEPTH):
            if (img[i][j][k] != 255):
                img[i][j][k] += noise[i][j][k]
plt.imshow(img)
plt.show()

GANs:

GAN’lar ile oluşturulmuş verilerin enteresan olduğu söylenebilir öyleki gerçeğe çok yakındır. GAN ile oluşturulan rakamlar:

Bu sefer veri artırma işlemini Keras kütüphanesi kullanarak gerçekleştireceğim.

İlk olarak kütüphanemizi import edelim.

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img

Daha sonrasında veri üretirken kullanacağımız fonksiyon olan ImageDataGenerator’ün hiperparametrelerini ayarlayarak değişkene atayalım. Bu fonksiyon ile ilgili ayrıntılı bilgiye https://keras.io/preprocessing/image/ adresinden ulaşabilirsiniz.

datagen = ImageDataGenerator(rotation_range=40,
                             width_shift_range=0.2,
                             height_shift_range=0.1,
                             shear_range=0.2,
                             zoom_range=0.2,
                             horizontal_flip=True,
                             vertical_flip=True,
                             fill_mode='nearest')

Daha sonrasında çoğaltmak istediğimiz veriyi yükleyip dizi  şekline çeviriyoruz ki işlem yapabilelim.

img=load_img('funny_hats.jpg')
x=img_to_array(img)
x=x.reshape( (1,) + x.shape)

Sonrasında belirlediğim parametrelere göre 50 tane yeni veri istediğim klasöre kaydedilmiş oluyor.

# tek resimden 50 tane farklı resim üret ve Artirilmis_Veri klasörüne .jpeg formatında kaydet.
i = 0

for batch in datagen.flow(x, batch_size=1,
                          save_to_dir='Artirilmis_Veri', 
                          save_format='jpeg'):
    i += 1
    if i > 50:
        break   

Yani  burada yapılan şey, bir önceki konuda anlattığım popüler veri artırma yöntemlerini ve daha nicesinin kullanarak istediğimiz sayıda her türlü kombinasyonu düşünerek veri oluşturmaya olanak sağlamasıdır. Örnek olarak 50 taneden 24 tanesinin ekran görüntüsü aşağıdaki gibidir. (resmi yeni sekmede açıp bakınız)