.. _sec_conv_layer: İmgeler için Evrişimler ======================= Artık evrişimli katmanların teoride nasıl çalıştığını anladığımıza göre, uygulamada nasıl çalıştıklarını görmeye hazırız. İmge verilerindeki yapıyı keşfetmek için etkili mimariler olarak evrişimli sinir ağlarının motivasyonunu temel alarak imgeler üzerinde çalışan örneğimize bağlı kalıyoruz. Çapraz Korelasyon İşlemi ------------------------ Kesin olarak konuşursak, evrişimli katmanların yanlış adlandırıldığını hatırlayın, çünkü ifade ettikleri işlemler daha doğru bir şekilde çapraz korelasyon olarak tanımlanabilir. :numref:`sec_why-conv` içindeki evrişimli tabaka açıklamalarına göre, böyle bir katmanda, bir girdi tensör ve bir çekirdek tensör çapraz korelasyon işlemi yoluyla bir çıktı tensörü üretmek için birleştirilir. Şimdilik kanalları yok sayalım ve bunun iki boyutlu veri ve gizli temsillerle nasıl çalıştığını görelim. :numref:`fig_correlation` içinde, girdi, yüksekliği 3 ve genişliği 3 olan iki boyutlu bir tensördür. Tensörün şeklini :math:`3 \times 3` veya (:math:`3`, :math:`3`) diye belirtiyoruz. Çekirdeğin yüksekliğinin ve genişliğinin her ikisi de 2'dir. *Çekirdek penceresinin* (veya *evrişim penceresi*) şekli çekirdeğin yüksekliği ve genişliği ile verilir (burada :math:`2 \times 2`'dir). .. _fig_correlation: .. figure:: ../img/correlation.svg İki boyutlu çapraz korelasyon işlemi. Gölgeli kısımlar, çıktı hesaplaması için kullanılan girdi ve çekirdek tensör elemanlarının yanı sıra ilk çıktı elemanıdır: :math:`0\times0+1\times1+3\times2+4\times3=19`. İki boyutlu çapraz korelasyon işleminde, girdi tensörünün sol üst köşesinde konumlandırılmış evrişim penceresi ile başlar ve hem soldan sağa hem de yukarıdan aşağıya doğru, girdi tensörü boyunca kaydırırız. Evrişim penceresi belirli bir konuma kaydırıldığında, bu pencerede bulunan girdi alt-tensör ve çekirdek tensör eleman yönlü olarak çarpılır ve elde edilen tensör tek bir sayıl (skaler) değer oluşturacak şekilde toplanır. Bu sonuç, çıktı tensörünün ilgili konumdaki değerini verir. Burada, çıktı tensörünün yüksekliği ve genişliği 2'dir ve dört eleman iki boyutlu çapraz korelasyon işleminden türetilmiştir: .. math:: 0\times0+1\times1+3\times2+4\times3=19,\\ 1\times0+2\times1+4\times2+5\times3=25,\\ 3\times0+4\times1+6\times2+7\times3=37,\\ 4\times0+5\times1+7\times2+8\times3=43. Her eksen boyunca, çıktı boyutunun girdi boyutundan biraz daha küçük olduğunu unutmayın. Çekirdeğin genişliği ve yüksekliği birden büyük olduğundan, çekirdeğin tamamen imge içine sığdığı konumlar için çapraz korelasyonu düzgün bir şekilde hesaplayabiliriz, çıktı boyutu :math:`n_h \times n_w` eksi evrişim çekirdeğinin boyutu :math:`k_h \times k_w` ile verilir. .. math:: (n_h-k_h+1) \times (n_w-k_w+1). Evrişim çekirdeğini imge boyunca “kaydırmak” için yeterli alana ihtiyacımız olduğu durum budur. Daha sonra, imgeyi sınırının etrafında sıfırlarla doldurarak boyutun değişmeden nasıl tutulacağını göreceğiz, böylece çekirdeği kaydırmak için yeterli alanımız olacak. Daha sonra, bir girdi tensör ``X`` ve bir çekirdek tensör ``K`` kabul eden ve bir çıktı tensör ``Y`` döndüren ``corr2d`` işlevinde bu işlemi uyguluyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python from d2l import mxnet as d2l from mxnet import autograd, np, npx from mxnet.gluon import nn npx.set_np() def corr2d(X, K): #@save """2 boyutlu çapraz korelasyonu hesapla.""" h, w = K.shape Y = np.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1)) for i in range(Y.shape[0]): for j in range(Y.shape[1]): Y[i, j] = (X[i:i + h, j:j + w] * K).sum() return Y .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn from d2l import torch as d2l def corr2d(X, K): #@save """2 boyutlu çapraz korelasyonu hesapla.""" h, w = K.shape Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1)) for i in range(Y.shape[0]): for j in range(Y.shape[1]): Y[i, j] = (X[i:i + h, j:j + w] * K).sum() return Y .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import tensorflow as tf from d2l import tensorflow as d2l def corr2d(X, K): #@save """2 boyutlu çapraz korelasyonu hesapla.""" h, w = K.shape Y = tf.Variable(tf.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))) for i in range(Y.shape[0]): for j in range(Y.shape[1]): Y[i, j].assign(tf.reduce_sum( X[i: i + h, j: j + w] * K)) return Y .. raw:: html
.. raw:: html
İki boyutlu çapraz korelasyon işleminin yukarıdaki uygulamasının çıktısını doğrulamak için :numref:`fig_correlation` içinden girdi tensörünü ``X``'i ve çekirdek tensörünü ``K``'yı inşa edebiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = np.array([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]) K = np.array([[0.0, 1.0], [2.0, 3.0]]) corr2d(X, K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[19., 25.], [37., 43.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]) K = torch.tensor([[0.0, 1.0], [2.0, 3.0]]) corr2d(X, K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[19., 25.], [37., 43.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = tf.constant([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]) K = tf.constant([[0.0, 1.0], [2.0, 3.0]]) corr2d(X, K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Evrişimli Katmanlar ------------------- Bir evrişimli katman, girdi ve çekirdeği çapraz-ilişkilendirir (cross-correlate) ve çıktı üretmek için bir skaler ek girdi ekler. Bir evrişimli tabakanın iki parametresi çekirdek ve skaler ek girdidir. Modelleri evrişimli katmanlara göre eğitirken, tam bağlı bir katmanda olduğu gibi, çekirdekleri genelde rastgele olarak ilkleriz. Yukarıda tanımlanan ``corr2d`` işlevine dayanan iki boyutlu bir evrişimli katmanı uygulamaya hazırız. ``__init__`` kurucu işlevinde, iki model parametresi olarak ``weight`` ve ``bias``'i beyan ederiz. İleri yayma işlevi ``corr2d`` işlevini çağırır ve ek girdiyi ekler. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class Conv2D(nn.Block): def __init__(self, kernel_size, **kwargs): super().__init__(**kwargs) self.weight = self.params.get('weight', shape=kernel_size) self.bias = self.params.get('bias', shape=(1,)) def forward(self, x): return corr2d(x, self.weight.data()) + self.bias.data() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class Conv2D(nn.Module): def __init__(self, kernel_size): super().__init__() self.weight = nn.Parameter(torch.rand(kernel_size)) self.bias = nn.Parameter(torch.zeros(1)) def forward(self, x): return corr2d(x, self.weight) + self.bias .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class Conv2D(tf.keras.layers.Layer): def __init__(self): super().__init__() def build(self, kernel_size): initializer = tf.random_normal_initializer() self.weight = self.add_weight(name='w', shape=kernel_size, initializer=initializer) self.bias = self.add_weight(name='b', shape=(1, ), initializer=initializer) def call(self, inputs): return corr2d(inputs, self.weight) + self.bias .. raw:: html
.. raw:: html
:math:`h \times w` evrişiminde veya :math:`h \times w` evrişim çekirdeğinde, evrişim çekirdeğinin yüksekliği ve genişliği sırasıyla :math:`h` ve :math:`w`'dir. Ayrıca :math:`h \times w` evrişim çekirdeğine sahip bir evrişimli tabakaya kısaca :math:`h \times w` evrişim tabaka diye atıfta bulunuyoruz. İmgelerde Nesne Kenarını Algılama --------------------------------- Evrişimli bir katmanın basit bir uygulamasını ayrıştırmak için biraz zaman ayıralım: Piksel değişiminin yerini bularak bir imgedeki nesnenin kenarını tespit etme. İlk olarak, :math:`6\times 8` piksellik bir “imge” oluşturuyoruz. Orta dört sütun siyah (0) ve geri kalanı beyaz (1) olsun. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = np.ones((6, 8)) X[:, 2:6] = 0 X .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = torch.ones((6, 8)) X[:, 2:6] = 0 X .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = tf.Variable(tf.ones((6, 8))) X[:, 2:6].assign(tf.zeros(X[:, 2:6].shape)) X .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Daha sonra, 1 yüksekliğinde ve 2 genişliğinde bir çekirdek ``K`` inşa ediyoruz. Girdi ile çapraz korelasyon işlemini gerçekleştirdiğimizde, yatay olarak bitişik elemanlar aynıysa, çıktı 0'dır. Aksi takdirde, çıktı sıfır değildir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python K = np.array([[1.0, -1.0]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python K = torch.tensor([[1.0, -1.0]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python K = tf.constant([[1.0, -1.0]]) .. raw:: html
.. raw:: html
``X`` (girdimiz) ve ``K`` (çekirdeğimiz) argümanlarıyla çapraz korelasyon işlemini gerçekleştirmeye hazırız. Gördüğünüz gibi, beyazdan siyaha kenar için 1 ve siyahtan beyaza kenar için -1 tespit ediyoruz. Diğer tüm çıktılar 0 değerini alır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python Y = corr2d(X, K) Y .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python Y = corr2d(X, K) Y .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python Y = corr2d(X, K) Y .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Artık çekirdeği devrik imgeye uygulayabiliriz. Beklendiği gibi, yok oluyor. Çekirdek ``K`` yalnızca dikey kenarları algılar. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python corr2d(d2l.transpose(X), K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python corr2d(X.t(), K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python corr2d(tf.transpose(X), K) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Bir Çekirdeği Öğrenme --------------------- Sonlu farklar ``[1, -1]`` ile bir kenar dedektörü tasarlamak, aradığımız şeyin tam olarak ne olduğunu biliyorsak temiz olur. Ancak, daha büyük çekirdeklere baktığımızda ve ardışık evrişim katmanlarını göz önünde bulundurduğumuzda, her filtrenin manuel olarak ne yapması gerektiğini tam olarak belirtmek imkansız olabilir. Şimdi ``X``'ten ``Y``'yi oluşturan çekirdeği yalnızca girdi-çıktı çiftlerine bakarak öğrenip öğrenemeyeceğimizi görelim. Önce bir evrişimli tabaka oluşturup çekirdeğini rastgele bir tensör olarak ilkletiriz. Daha sonra, her yinelemede, ``Y``'yi evrişimli tabakanın çıktısıyla karşılaştırmak için kare hatayı kullanacağız. Daha sonra çekirdeği güncellemek için gradyanı hesaplayabiliriz. Basitlik uğruna, aşağıda iki boyutlu evrişimli katmanlar için yerleşik sınıfı kullanıyoruz ve ek girdiyi görmezden geliyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # 1 çıktı kanallı ve (1, 2) şekilli çekirdekli iki boyutlu bir evrişim katmanı # oluşturun. Basitlik adına, burada ek girdiyi görmezden geliyoruz. conv2d = nn.Conv2D(1, kernel_size=(1, 2), use_bias=False) conv2d.initialize() # İki boyutlu evrişimli katman, (örnek, kanal, yükseklik, genişlik) biçiminde # dört boyutlu girdi ve çıktı kullanır; burada toplu iş boyutunun (gruptaki örnek sayısı) # ve kanal sayısının her ikisi de 1'dir. X = X.reshape(1, 1, 6, 8) Y = Y.reshape(1, 1, 6, 7) lr = 3e-2 # Öğrenme oranı for i in range(10): with autograd.record(): Y_hat = conv2d(X) l = (Y_hat - Y) ** 2 l.backward() # Çekirdeği güncelle conv2d.weight.data()[:] -= lr * conv2d.weight.grad() if (i + 1) % 2 == 0: print(f'donem {i + 1}, loss {float(l.sum()):.3f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output donem 2, loss 4.949 donem 4, loss 0.831 donem 6, loss 0.140 donem 8, loss 0.024 donem 10, loss 0.004 [21:49:27] src/base.cc:49: GPU context requested, but no GPUs found. .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # 1 çıktı kanallı ve (1, 2) şekilli çekirdekli iki boyutlu bir evrişim katmanı # oluşturun. Basitlik adına, burada ek girdiyi görmezden geliyoruz. conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False) # İki boyutlu evrişimli katman, (örnek, kanal, yükseklik, genişlik) biçiminde # dört boyutlu girdi ve çıktı kullanır; burada toplu iş boyutunun (gruptaki örnek sayısı) # ve kanal sayısının her ikisi de 1'dir. X = X.reshape((1, 1, 6, 8)) Y = Y.reshape((1, 1, 6, 7)) lr = 3e-2 # Öğrenme oranı for i in range(10): Y_hat = conv2d(X) l = (Y_hat - Y) ** 2 conv2d.zero_grad() l.sum().backward() # Çekirdeği güncelle conv2d.weight.data[:] -= lr * conv2d.weight.grad if (i + 1) % 2 == 0: print(f'donem {i + 1}, loss {l.sum():.3f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output donem 2, loss 10.132 donem 4, loss 1.769 donem 6, loss 0.325 donem 8, loss 0.066 donem 10, loss 0.016 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # 1 çıktı kanallı ve (1, 2) şekilli çekirdekli iki boyutlu bir evrişim katmanı # oluşturun. Basitlik adına, burada ek girdiyi görmezden geliyoruz. conv2d = tf.keras.layers.Conv2D(1, (1, 2), use_bias=False) # İki boyutlu evrişimli katman, (örnek, yükseklik, genişlik, kanal) biçiminde # dört boyutlu girdi ve çıktı kullanır; burada toplu iş boyutunun (gruptaki örnek sayısı) # ve kanal sayısının her ikisi de 1'dir. X = tf.reshape(X, (1, 6, 8, 1)) Y = tf.reshape(Y, (1, 6, 7, 1)) lr = 3e-2 # Learning rate Y_hat = conv2d(X) for i in range(10): with tf.GradientTape(watch_accessed_variables=False) as g: g.watch(conv2d.weights[0]) Y_hat = conv2d(X) l = (abs(Y_hat - Y)) ** 2 # Çekirdeği güncelle update = tf.multiply(lr, g.gradient(l, conv2d.weights[0])) weights = conv2d.get_weights() weights[0] = conv2d.weights[0] - update conv2d.set_weights(weights) if (i + 1) % 2 == 0: print(f'donem {i + 1}, loss {tf.reduce_sum(l):.3f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output donem 2, loss 16.067 donem 4, loss 5.488 donem 6, loss 2.065 donem 8, loss 0.815 donem 10, loss 0.329 .. raw:: html
.. raw:: html
Hatanın 10 yinelemeden sonra küçük bir değere düştüğünü fark ediniz. Şimdi öğrendiğimiz çekirdek tensörüne bir göz atacağız. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python conv2d.weight.data().reshape((1, 2)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 0.9895 , -0.9873705]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python conv2d.weight.data.reshape((1, 2)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 0.9744, -0.9929]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.reshape(conv2d.get_weights()[0], (1, 2)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Gerçekten de, öğrenilen çekirdek tensör, daha önce tanımladığımız çekirdek tensörüne ``K``'e oldukça yakındır. Çapraz Korelasyon ve Evrişim ---------------------------- Çapraz korelasyon ve evrişim işlemleri arasındaki ilişkilendirmeler için :numref:`sec_why-conv` içindeki gözlemlerimizi hatırlayın. Burada iki boyutlu evrişimli katmanları düşünmeye devam edelim. Bu tür katmanlar çapraz korelasyon yerine :eq:`eq_2d-conv-discrete` içinde tanımlandığı gibi tam evrişim işlemlerini gerçekleştirirse ne olur? Tam *evrişim* işleminin çıktısını elde etmek için, iki boyutlu çekirdek tensörünü hem yatay hem de dikey olarak çevirmemiz ve daha sonra girdi tensörüyle *çapraz korelasyon* işlemini gerçekleştirmemiz gerekir. Çekirdekler derin öğrenmede verilerden öğrenildiğinden, bu tür katmanlar tam evrişim işlemlerini veya çapraz korelasyon işlemlerini gerçekleştirse de, evrişimli katmanların çıktılarının etkilenmeden kalması dikkat çekicidir. Bunu göstermek için, bir evrişimli katmanın *çapraz korelasyon* gerçekleştirdiğini ve çekirdeği :numref:`fig_correlation` içinde öğrendiğini varsayalım, burada :math:`\mathbf{K}` matris olarak ifade ediliyor. Bu katman yerine tam *evrişim* gerçekleştirdiğinde, diğer koşulların değişmeden kaldığını varsayarsak, :math:`\mathbf{K}'` hem yatay hem de dikey olarak çevrildikten sonra :math:`\mathbf{K}` ile aynı olacaktır. Yani, evrişimli tabaka :numref:`fig_correlation` ve :math:`\mathbf{K}'`'deki girdi için tam *evrişim* gerçekleştirdiğinde, :numref:`fig_correlation` içinde gösterilen aynı çıktı (girdi ve :math:`\mathbf{K}`'nin çapraz korelasyon) elde edilecektir. Derin öğrenme yazınındaki standart terminolojiye uygun olarak, çapraz korelasyon işlemine bir evrişim olarak atıfta bulunmaya devam edeceğiz, katı bir şekilde konuşursak da, biraz farklı olsa da. Ayrıca, bir katman temsilini veya bir evrişim çekirdeğini temsil eden herhangi bir tensörün girdisini (veya bileşenini) ifade etmek için *eleman (öğe)* terimini kullanıyoruz. Öznitelik Eşleme ve Alım Alanı (Receptive Field) ------------------------------------------------ :numref:`subsec_why-conv-channels` içinde açıklandığı gibi, :numref:`fig_correlation` içindeki evrişimli katman çıktısı bazen *öznitelik eşleme (feature mapping)* olarak adlandırılır, çünkü uzamsal boyutlarda (örn. genişlik ve yükseklik) sonraki katmana öğrenilmiş temsiller (öznitelikler) olarak kabul edilebilir. CNN'lerde, herhangi tabakanın herhangi bir elemanı :math:`x` için, *alım alanı*, ileri yayma sırasında :math:`x`'nin hesaplanmasını etkileyebilecek tüm elemanları (önceki katmanlardan) ifade eder. Alım alanın girdinin gerçek boyutundan daha büyük olabileceğini unutmayın. Alım alanını açıklamak için :numref:`fig_correlation` içeriğini kullanmaya devam edelim. :math:`2 \times 2` evrişim çekirdeği göz önüne alındığında, gölgeli çıktı elemanının alım alanı (:math:`19` değeri) girdinin gölgeli kısmındaki dört öğedir. Şimdi :math:`2 \times 2` çıktısını :math:`\mathbf{Y}` olarak ifade edelim ve :math:`\mathbf{Y}`'yi girdi alıp tek :math:`z` eleman çıktısı veren :math:`2 \times 2` evrişimli tabakalı daha derin bir CNN düşünelim. Bu durumda, :math:`\mathbf{Y}`'deki :math:`z`'nin alım alanı :math:`\mathbf{Y}`'nin dört öğesini içerirken, girdideki alım alanı dokuz girdi elemanını içerir. Böylece, bir öznitelik eşlemedeki herhangi bir elemanın daha geniş bir alan üzerindeki girdi özelliklerini algılamak için daha büyük bir alım alanına ihtiyacı olduğunda, daha derin bir ağ kurabiliriz. Özet ---- - İki boyutlu bir evrişimli tabakanın çekirdek hesaplaması, iki boyutlu bir çapraz korelasyon işlemidir. En basit haliyle, bu iki boyutlu girdi verisi ve çekirdek üzerinde çapraz korelasyon işlemi gerçekleştirir ve sonra bir ek girdi ekler. - İmgelerdeki kenarları tespit etmek için bir çekirdek tasarlayabiliriz. - Çekirdeğin parametrelerini verilerden öğrenebiliriz. - Verilerden öğrenilen çekirdekler ile, evrişimli katmanların çıktıları, bu tür katmanlarda gerçekleştirilen işlemlerden bağımsız kalarak (tam evrişim veya çapraz korelasyon) etkilenmez. - Bir öznitelik eşlemedeki herhangi bir öğe, girdideki daha geniş öznitelikleri algılamak için daha büyük bir alım alanına ihtiyaç duyduğunda, daha derin bir ağ düşünülebilir. Alıştırmalar ------------ 1. Çapraz kenarlı bir ``X`` imgesi oluşturun. 1. Çekirdek ``K``'yi bu bölümde uygularsanız ne olur? 2. ``X`` devrik olursa ne olur? 3. ``K`` devrik olursa ne olur? 2. Oluşturduğumuz ``Conv2D`` sınıfının gradyanını otomatik olarak bulmaya çalıştığınızda ne tür bir hata mesajı görürsunuz? 3. Girdi ve çekirdek tensörlerini değiştirerek çapraz korelasyon işlemini nasıl bir matris çarpımı olarak temsil edebilirsiniz? 4. Bazı çekirdekleri manuel olarak tasarlayın. 1. İkinci türev için bir çekirdeğin biçimi nedir? 2. İntegral için bir çekirdek nedir? 3. :math:`d` derece türevi elde etmek için bir çekirdeğin minimum boyutu nedir? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html