1. Başlamadan önce
Bu codelab'de, evrişimler ve bunların bilgisayarla görme senaryolarında neden bu kadar etkili olduğu hakkında bilgi edineceksiniz.
Önceki kod laboratuvarında, moda ürünlerinin bilgisayarla görme uygulaması için basit bir derin sinir ağı (DNN) oluşturmuştunuz. Bu kısıtlama, resimde yalnızca giyim eşyasının bulunması ve ortalanması gerektiğinden uygulandı.
Elbette bu gerçekçi bir senaryo değildir. DNN'nizin, diğer nesnelerle birlikte olan veya ön planda ve merkezde olmayan resimlerdeki giyim eşyasını tanımlayabilmesini istersiniz. Bunu yapmak için evrişimleri kullanmanız gerekir.
Ön koşullar
Bu codelab, önceki iki bölümde tamamlanan çalışmalara (Makine öğreniminin "Merhaba Dünya"sına merhaba deyin ve Bilgisayarla görme modeli oluşturma) dayanmaktadır. Devam etmeden önce lütfen bu codelab'leri tamamlayın.
Neler öğreneceksiniz?
- Evrişimler nedir?
- Özellik haritası oluşturma
- Gruplandırma nedir?
Ne oluşturacaksınız?
- Bir resmin özellik haritası
Gerekenler
Codelab'in geri kalanının kodunu Colab'de çalıştırabilirsiniz.
Ayrıca TensorFlow'un ve önceki codelab'de yüklediğiniz kitaplıkların da yüklü olması gerekir.
2. Evrişim nedir?
Evrişim, bir görüntünün üzerinden geçen, onu işleyen ve önemli özellikleri çıkaran bir filtredir.
Sneaker giyen bir kişinin fotoğrafı olduğunu varsayalım. Resimde bir spor ayakkabının olduğunu nasıl tespit edersiniz? Programınızın resmi spor ayakkabı olarak "görmesi" için önemli özellikleri ayıklamanız ve gereksiz özellikleri bulanıklaştırmanız gerekir. Buna özellik eşleme denir.
Özellik eşleme süreci teorik olarak basittir. Resimdeki her pikseli tarar ve ardından komşu piksellere bakarsınız. Bu piksellerin değerlerini bir filtrenin eşdeğer ağırlıklarıyla çarpın.
Örneğin:

Bu durumda, 3x3 konvolüsyon matrisi veya görüntü çekirdeği belirtilir.
Mevcut piksel değeri 192'dir. Yeni pikselin değerini, komşu değerlere bakarak, bunları filtrede belirtilen değerlerle çarparak ve yeni piksel değerini nihai tutar yaparak hesaplayabilirsiniz.
Şimdi de 2 boyutlu bir gri tonlamalı görüntüde temel bir evrişim oluşturarak evrişimlerin nasıl çalıştığını keşfetme zamanı.
Bunu SciPy'den alınan çıkış resmiyle göstereceksiniz. Çok sayıda açı ve çizgi içeren güzel bir yerleşik resim.
3. Kodlamaya başlama
Öncelikle bazı Python kitaplıklarını ve tırmanış resmini içe aktararak başlayın:
import cv2
import numpy as np
from scipy import misc
i = misc.ascent()
Ardından, görüntünün nasıl göründüğünü anlamak için Pyplot kitaplığını matplotlib kullanarak görüntüyü çizin:
import matplotlib.pyplot as plt
plt.grid(False)
plt.gray()
plt.axis('off')
plt.imshow(i)
plt.show()

Bunun bir merdiven boşluğu resmi olduğunu görebilirsiniz. Deneyebileceğiniz ve izole edebileceğiniz birçok özellik vardır. Örneğin, güçlü dikey çizgiler var.
Resim, NumPy dizisi olarak depolandığından dönüştürülmüş resmi yalnızca bu diziyi kopyalayarak oluşturabiliriz. size_x ve size_y değişkenleri, resmin boyutlarını tutar. Böylece daha sonra bu boyutlar üzerinde döngü oluşturabilirsiniz.
i_transformed = np.copy(i)
size_x = i_transformed.shape[0]
size_y = i_transformed.shape[1]
4. Evrişim matrisini oluşturma
Öncelikle, 3x3 dizisi olarak bir konvolüsyon matrisi (veya çekirdek) oluşturun:
# This filter detects edges nicely
# It creates a filter that only passes through sharp edges and straight lines.
# Experiment with different values for fun effects.
#filter = [ [0, 1, 0], [1, -4, 1], [0, 1, 0]]
# A couple more filters to try for fun!
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
#filter = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
# If all the digits in the filter don't add up to 0 or 1, you
# should probably do a weight to get it to do so
# so, for example, if your weights are 1,1,1 1,2,1 1,1,1
# They add up to 10, so you would set a weight of .1 if you want to normalize them
weight = 1
Şimdi çıkış piksellerini hesaplayın. Resmi 1 piksellik bir kenar boşluğu bırakarak yineleyin ve mevcut pikselin her bir komşusunu filtrede tanımlanan değerle çarpın.
Bu, geçerli pikselin üstündeki ve solundaki komşusunun filtrenin sol üstteki öğesiyle çarpılacağı anlamına gelir. Ardından, sonucu ağırlıkla çarpın ve sonucun 0 ile 255 arasında olduğundan emin olun.
Son olarak, yeni değeri dönüştürülmüş resme yükleyin:
for x in range(1,size_x-1):
for y in range(1,size_y-1):
output_pixel = 0.0
output_pixel = output_pixel + (i[x - 1, y-1] * filter[0][0])
output_pixel = output_pixel + (i[x, y-1] * filter[0][1])
output_pixel = output_pixel + (i[x + 1, y-1] * filter[0][2])
output_pixel = output_pixel + (i[x-1, y] * filter[1][0])
output_pixel = output_pixel + (i[x, y] * filter[1][1])
output_pixel = output_pixel + (i[x+1, y] * filter[1][2])
output_pixel = output_pixel + (i[x-1, y+1] * filter[2][0])
output_pixel = output_pixel + (i[x, y+1] * filter[2][1])
output_pixel = output_pixel + (i[x+1, y+1] * filter[2][2])
output_pixel = output_pixel * weight
if(output_pixel<0):
output_pixel=0
if(output_pixel>255):
output_pixel=255
i_transformed[x, y] = output_pixel
5. Sonuçları inceleme
Şimdi, filtreyi uygulamanın etkisini görmek için resmi çizin:
# Plot the image. Note the size of the axes -- they are 512 by 512
plt.gray()
plt.grid(False)
plt.imshow(i_transformed)
#plt.axis('off')
plt.show()

Aşağıdaki filtre değerlerini ve bunların görüntü üzerindeki etkisini göz önünde bulundurun.
[-1,0,1,-2,0,2,-1,0,1] değerini kullanmak çok güçlü bir dikey çizgi grubu oluşturur:

[-1,-2,-1,0,0,0,1,2,1] değerini kullandığınızda yatay çizgiler elde edersiniz:

Farklı değerleri keşfedin. Ayrıca 5x5 veya 7x7 gibi farklı boyutlardaki filtreleri de deneyin.
6. Gruplandırmayı anlama
Resmin temel özelliklerini belirlediğinize göre ne yapmanız gerekir? Resimleri sınıflandırmak için ortaya çıkan özellik haritasını nasıl kullanıyorsunuz?
Havuzlama, evrişimlere benzer şekilde özellikleri tespit etmede büyük ölçüde yardımcı olur. Birleştirme katmanları, mevcut olarak algılanan özellikleri korurken bir görüntüdeki toplam bilgi miktarını azaltır.
Birkaç farklı havuz oluşturma türü vardır ancak Maksimum (Max) Havuz Oluşturma adlı bir türü kullanacaksınız.
Resmi yineleyin ve her noktada pikseli ve hemen sağındaki, altındaki ve sağ-altındaki komşularını göz önünde bulundurun. Bunların en büyüğünü (bu nedenle maksimum havuzlama) alıp yeni resme yükleyin. Bu nedenle, yeni resim eski resmin dörtte biri boyutunda olacaktır. 
7. Havuz oluşturma için kod yazma
Aşağıdaki kodda (2, 2) havuz oluşturma işlemi gösterilmektedir. Çıktıyı görmek için çalıştırın.
Resmin orijinal boyutunun dörtte biri olmasına rağmen tüm özelliklerini koruduğunu görürsünüz.
new_x = int(size_x/2)
new_y = int(size_y/2)
newImage = np.zeros((new_x, new_y))
for x in range(0, size_x, 2):
for y in range(0, size_y, 2):
pixels = []
pixels.append(i_transformed[x, y])
pixels.append(i_transformed[x+1, y])
pixels.append(i_transformed[x, y+1])
pixels.append(i_transformed[x+1, y+1])
pixels.sort(reverse=True)
newImage[int(x/2),int(y/2)] = pixels[0]
# Plot the image. Note the size of the axes -- now 256 pixels instead of 512
plt.gray()
plt.grid(False)
plt.imshow(newImage)
#plt.axis('off')
plt.show()

Bu grafiğin eksenlerine dikkat edin. Resim artık orijinal boyutunun dörtte biri olan 256x256 boyutunda ve resimde daha az veri olmasına rağmen algılanan özellikler geliştirildi.
8. Tebrikler
İlk bilgisayar görme modelinizi oluşturdunuz. Bilgisayar görüşü modellerinizi daha da geliştirmeyi öğrenmek için Bilgisayar görüşünü geliştirmek için evrişimli nöral ağlar (CNN'ler) oluşturma başlıklı makaleye gidin.