Özelleştirilmiş Katmanlar
=========================
Derin öğrenmenin başarısının ardındaki faktörlerden biri, çok çeşitli
görevlere uygun mimariler tasarlamak için yaratıcı yollarla
oluşturulabilen çok çeşitli katmanların mevcut olmasıdır. Örneğin,
araştırmacılar özellikle imgelerle baş etmek, metin, dizili veriler
üzerinde döngü yapmak ve dinamik programlama yapmak için katmanlar icat
ettiler. Er ya da geç, derin öğrenme çerçevesinde henüz var olmayan bir
katmanla karşılaşacaksınız (veya onu icat edeceksiniz). Özel bir katman
oluşturmanız gerekebilir. Bu bölümde size bunu nasıl yapacağınızı
gösteriyoruz.
Paramatresiz Katmanlar
----------------------
Başlangıç olarak, kendi parametresi olmayan özelleştirilmiş bir katman
oluşturalım. Bloğu tanıttığımızı bölümü hatırlarsanız,
:numref:`sec_model_construction` içindeki, burası size tanıdık
gelecektir. Aşağıdaki ``CenteredLayer`` sınıfı, girdiden ortalamayı
çıkarır. Bunu inşa etmek için, temel katman sınıfından kalıtımla
üretmemiz ve ileri yayma işlevini uygulamamız gerekir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
from mxnet import np, npx
from mxnet.gluon import nn
npx.set_np()
class CenteredLayer(nn.Block):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def forward(self, X):
return X - X.mean()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import torch
from torch import nn
from torch.nn import functional as F
class CenteredLayer(nn.Module):
def __init__(self):
super().__init__()
def forward(self, X):
return X - X.mean()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import tensorflow as tf
class CenteredLayer(tf.keras.Model):
def __init__(self):
super().__init__()
def call(self, inputs):
return inputs - tf.reduce_mean(inputs)
.. raw:: html
.. raw:: html
Katmanımızın amaçlandığı gibi çalıştığını, ona biraz veri besleyerek
doğrulayalım.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
layer = CenteredLayer()
layer(np.array([1, 2, 3, 4, 5]))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([-2., -1., 0., 1., 2.])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
layer = CenteredLayer()
layer(torch.FloatTensor([1, 2, 3, 4, 5]))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([-2., -1., 0., 1., 2.])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
layer = CenteredLayer()
layer(tf.constant([1, 2, 3, 4, 5]))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Artık katmanımızı daha karmaşık modeller oluşturmada bir bileşen olarak
kullanabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = nn.Sequential()
net.add(nn.Dense(128), CenteredLayer())
net.initialize()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = tf.keras.Sequential([tf.keras.layers.Dense(128), CenteredLayer()])
.. raw:: html
.. raw:: html
Ekstra bir makulluk kontrolü olarak, ağa rastgele veri gönderebilir ve
ortalamanın gerçekte 0 olup olmadığına bakabiliriz. Kayan virgüllü
sayılarla uğraştığımız için, nicemlemeden dolayı çok küçük sıfır olmayan
bir sayı görebiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
Y = net(np.random.uniform(size=(4, 8)))
Y.mean()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(3.783498e-10)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
Y = net(torch.rand(4, 8))
Y.mean()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(-7.4506e-09, grad_fn=)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
Y = net(tf.random.uniform((4, 8)))
tf.reduce_mean(Y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Parametreli Katmanlar
---------------------
Artık basit katmanları nasıl tanımlayacağımızı bildiğimize göre, eğitim
yoluyla ayarlanabilen parametrelerle katmanları tanımlamaya geçelim.
Bazı temel idari işlevleri sağlayan parametreler oluşturmak için
yerleşik işlevleri kullanabiliriz. Özellikle erişim, ilkleme, paylaşma,
modeli kaydetme ve yükleme parametrelerini yönetirler. Bu şekilde, diğer
faydaların yanı sıra, her özel katman için özel serileştirme
(serialization) rutinleri yazmamız gerekmeyecek.
Şimdi tam bağlı katman sürümümüzü uygulayalım. Bu katmanın iki
parametreye ihtiyaç duyduğunu hatırlayınız, biri ağırlığı ve diğeri ek
girdiyi temsil etmek için. Bu uygulamada, varsayılan olarak ReLU
etkinleştirmesini kullanıyoruz. Bu katman, sırasıyla girdilerin ve
çıktıların sayısını gösteren ``in_units`` ve ``units`` girdi
argümanlarının girilmesini gerektirir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
class MyDense(nn.Block):
def __init__(self, units, in_units, **kwargs):
super().__init__(**kwargs)
self.weight = self.params.get('weight', shape=(in_units, units))
self.bias = self.params.get('bias', shape=(units,))
def forward(self, x):
linear = np.dot(x, self.weight.data(ctx=x.ctx)) + self.bias.data(
ctx=x.ctx)
return npx.relu(linear)
Daha sonra, ``MyDense`` sınıfını ilkliyoruz ve model parametrelerine
erişiyoruz.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
dense = MyDense(units=3, in_units=5)
dense.params
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
mydense0_ (
Parameter mydense0_weight (shape=(5, 3), dtype=)
Parameter mydense0_bias (shape=(3,), dtype=)
)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
class MyLinear(nn.Module):
def __init__(self, in_units, units):
super().__init__()
self.weight = nn.Parameter(torch.randn(in_units, units))
self.bias = nn.Parameter(torch.randn(units,))
def forward(self, X):
linear = torch.matmul(X, self.weight.data) + self.bias.data
return F.relu(linear)
Daha sonra, ``MyLinear`` sınıfını ilkliyoruz ve model parametrelerine
erişiyoruz.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
linear = MyLinear(5, 3)
linear.weight
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
Parameter containing:
tensor([[-0.4603, 0.5533, 0.0135],
[-1.0431, -1.7814, 0.5278],
[-0.9134, 0.1051, -0.5784],
[ 1.8552, 0.6963, 0.8525],
[-0.5034, 1.6521, -1.1436]], requires_grad=True)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
class MyDense(tf.keras.Model):
def __init__(self, units):
super().__init__()
self.units = units
def build(self, X_shape):
self.weight = self.add_weight(name='weight',
shape=[X_shape[-1], self.units],
initializer=tf.random_normal_initializer())
self.bias = self.add_weight(
name='bias', shape=[self.units],
initializer=tf.zeros_initializer())
def call(self, X):
linear = tf.matmul(X, self.weight) + self.bias
return tf.nn.relu(linear)
Daha sonra, ``MyDense`` sınıfını ilkliyoruz ve model parametrelerine
erişiyoruz.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
dense = MyDense(3)
dense(tf.random.uniform((2, 5)))
dense.get_weights()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
[array([[ 0.03330242, 0.0457952 , -0.01465737],
[ 0.05158572, -0.02191112, 0.03810618],
[-0.0173367 , -0.06167042, -0.02427012],
[ 0.04562289, 0.01620819, 0.04083775],
[ 0.10629302, 0.045753 , -0.07166722]], dtype=float32),
array([0., 0., 0.], dtype=float32)]
.. raw:: html
.. raw:: html
Özel kesim katmanları kullanarak doğrudan ileri yayma hesaplamaları
yapabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
dense.initialize()
dense(np.random.uniform(size=(2, 5)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[0. , 0.01633355, 0. ],
[0. , 0.01581812, 0. ]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
linear(torch.rand(2, 5))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[0.6806, 1.0990, 1.5497],
[0.0000, 0.0619, 0.8226]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
dense(tf.random.uniform((2, 5)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Özelleştirilmiş kesim katmanlar kullanarak da modeller oluşturabiliriz.
Bir kere ona sahip olduğumuzda, onu tıpkı yerleşik tam bağlı katman gibi
kullanabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = nn.Sequential()
net.add(MyDense(8, in_units=64),
MyDense(1, in_units=8))
net.initialize()
net(np.random.uniform(size=(2, 64)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[0.06508517],
[0.0615553 ]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))
net(torch.rand(2, 64))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[9.2351],
[7.0112]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
net = tf.keras.models.Sequential([MyDense(8), MyDense(1)])
net(tf.random.uniform((2, 64)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Özet
----
- Temel katman sınıfı üzerinden özel kesim katmanlar tasarlayabiliriz.
Bu, kütüphanedeki mevcut katmanlardan farklı davranan yeni esnek
katmanlar tanımlamamıza olanak tanır.
- Tanımlandıktan sonra, özel kesim katmanlar keyfi bağlamlarda ve
mimarilerde çağrılabilir.
- Katmanlar, yerleşik işlevler aracılığıyla yaratılabilen yerel
parametrelere sahip olabilirler.
Alıştırmalar
------------
1. Bir girdi alan ve bir tensör indirgemesi hesaplayan bir katman
tasarlayınız, yani :math:`y_k = \sum_{i, j} W_{ijk} x_i x_j`
döndürsün.
2. Verilerin Fourier katsayılarının ilk baştaki yarısını döndüren bir
katman tasarlayınız.
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html