Ö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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html