.. _sec_nin: Ağ İçinde Ağ (Network in Network - NiN) ======================================= LeNet, AlexNet ve VGG ortak bir tasarım deseni paylaşır: Öznitelikleri bir dizi evrişim ve ortaklama katmanları aracılığıyla *mekansal* yapıdan faydalanarak çıkar ve daha sonra tam bağlı katmanlar aracılığıyla temsilleri sonradan işle. AlexNet ve VGG tarafından LeNet üzerindeki iyileştirmeler, esas olarak bu sonraki ağların bu iki modülü nasıl genişlettiği ve derinleştirdiği konusunda yatmaktadır. Alternatif olarak, tam bağlı katmanları süreç içinde daha önce kullanmayı hayal edebiliriz. Bununla birlikte, yoğun katmanların dikkatsiz kullanımı, temsilin mekansal yapısını tamamen görmezden gelebilir; *ağ içindeki ağ* (*NiN*) blokları burada bir alternatif sunuyor. Çok basit bir anlayışa dayalı olarak önerildiler: Her piksel için kanallarda ayrı ayrı bir MLP kullanmak :cite:`Lin.Chen.Yan.2013`. NiN Blokları ------------ Evrişimli katmanların girdi ve çıktılarının, örneğe, kanala, yüksekliğe ve genişliğe karşılık gelen eksenlere sahip dört boyutlu tensörlerden oluştuğunu hatırlayın. Ayrıca, tam bağlı katmanların girdi ve çıktılarının tipik olarak örneğe ve özniteliğe karşılık gelen iki boyutlu tensörler olduğunu hatırlayın. NiN'in arkasındaki fikir, her piksel konumuna (her yükseklik ve genişlik için) tam bağlı bir katman uygulamaktır. Ağırlıkları her mekansal konum boyunca bağlarsak, bunu bir :math:`1\times 1` evrişimli katman (:numref:`sec_channels` içinde açıklandığı gibi) veya her piksel konumunda bağımsız olarak hareket eden tam bağlı bir katman olarak düşünebiliriz. Bunu görmenin bir başka yolu da mekansal boyuttaki her elemanın (yükseklik ve genişlik) bir örneğe eşdeğer ve bir kanalın bir özniteliğe eşdeğer olduğunu düşünmektir. :numref:`fig_nin`, VGG ve NiN arasındaki ana yapısal farklılıkları ve bloklarını göstermektedir. NiN bloğu, bir evrişimli katmandan ve ardından ReLU etkinleştirmeleri ile piksel başına tam bağlı katmanlar olarak hareket eden iki :math:`1\times 1` evrişimli katmandan oluşur. İlk katmanın evrişim penceresi şekli genellikle kullanıcı tarafından ayarlanır. Sonraki pencere şekilleri :math:`1 \times 1`'e sabitlenir. .. _fig_nin: .. figure:: ../img/nin.svg :width: 600px VGG and NiN mimarilerinin ve bloklarının karşılaştırılması .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python from d2l import mxnet as d2l from mxnet import np, npx from mxnet.gluon import nn npx.set_np() def nin_block(num_channels, kernel_size, strides, padding): blk = nn.Sequential() blk.add(nn.Conv2D(num_channels, kernel_size, strides, padding, activation='relu'), nn.Conv2D(num_channels, kernel_size=1, activation='relu'), nn.Conv2D(num_channels, kernel_size=1, activation='relu')) return blk .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn from d2l import torch as d2l def nin_block(in_channels, out_channels, kernel_size, strides, padding): return nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding), nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU()) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import tensorflow as tf from d2l import tensorflow as d2l def nin_block(num_channels, kernel_size, strides, padding): return tf.keras.models.Sequential([ tf.keras.layers.Conv2D(num_channels, kernel_size, strides=strides, padding=padding, activation='relu'), tf.keras.layers.Conv2D(num_channels, kernel_size=1, activation='relu'), tf.keras.layers.Conv2D(num_channels, kernel_size=1, activation='relu')]) .. raw:: html
.. raw:: html
NiN Modeli ---------- Orijinal NiN ağı, AlexNet'ten kısa bir süre sonra önerildi ve açıkçası ondan biraz ilham almıştır. NiN, :math:`11\times 11`, :math:`5\times 5` ve :math:`3\times 3` pencere şekilleri ile evrişimli katmanlar kullanır ve karşılık gelen çıktı kanalı sayıları AlexNet'teki ile aynıdır. Her NiN bloğunu, 2'lik bir adım ve :math:`3\times 3`'lük bir pencere şekli ile bir maksimum ortaklama katmanı izler. NiN ve AlexNet arasındaki önemli bir fark, NiN'in tam bağlı katmanlardan kaçınmasıdır. Bunun yerine NiN, etiket sınıflarının sayısına eşit sayıda çıktı kanalı içeren bir NiN bloğu kullanır ve onun ardından gelen *global* ortalama ortaklama katmanı ile bir logit vektörü oluşturur. NiN'in tasarımının bir avantajı, gerekli model parametrelerinin sayısını önemli ölçüde azaltmasıdır. Bununla birlikte, pratikte, bu tasarım bazen artan model eğitim süresi gerektirir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = nn.Sequential() net.add(nin_block(96, kernel_size=11, strides=4, padding=0), nn.MaxPool2D(pool_size=3, strides=2), nin_block(256, kernel_size=5, strides=1, padding=2), nn.MaxPool2D(pool_size=3, strides=2), nin_block(384, kernel_size=3, strides=1, padding=1), nn.MaxPool2D(pool_size=3, strides=2), nn.Dropout(0.5), # 10 etiket sınıfı var nin_block(10, kernel_size=3, strides=1, padding=1), # Global ortalama ortaklama katmanı, pencere şeklini girdinin # yüksekliğine ve genişliğine otomatik olarak ayarlar nn.GlobalAvgPool2D(), # Dört boyutlu çıktıyı (toplu iş boyutu, 10) # şeklinde iki boyutlu çıktıya dönüştür nn.Flatten()) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = nn.Sequential( nin_block(1, 96, kernel_size=11, strides=4, padding=0), nn.MaxPool2d(3, stride=2), nin_block(96, 256, kernel_size=5, strides=1, padding=2), nn.MaxPool2d(3, stride=2), nin_block(256, 384, kernel_size=3, strides=1, padding=1), nn.MaxPool2d(3, stride=2), nn.Dropout(0.5), # 10 etiket sınıfı var nin_block(384, 10, kernel_size=3, strides=1, padding=1), nn.AdaptiveAvgPool2d((1, 1)), # Dört boyutlu çıktıyı (toplu iş boyutu, 10) # şeklinde iki boyutlu çıktıya dönüştür nn.Flatten()) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def net(): return tf.keras.models.Sequential([ nin_block(96, kernel_size=11, strides=4, padding='valid'), tf.keras.layers.MaxPool2D(pool_size=3, strides=2), nin_block(256, kernel_size=5, strides=1, padding='same'), tf.keras.layers.MaxPool2D(pool_size=3, strides=2), nin_block(384, kernel_size=3, strides=1, padding='same'), tf.keras.layers.MaxPool2D(pool_size=3, strides=2), tf.keras.layers.Dropout(0.5), # 10 etiket sınıfı var nin_block(10, kernel_size=3, strides=1, padding='same'), tf.keras.layers.GlobalAveragePooling2D(), tf.keras.layers.Reshape((1, 1, 10)), # Dört boyutlu çıktıyı (toplu iş boyutu, 10) # şeklinde iki boyutlu çıktıya dönüştür tf.keras.layers.Flatten(), ]) .. raw:: html
.. raw:: html
Her bloğun çıktı şeklini görmek için bir veri örneği oluşturuyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = np.random.uniform(size=(1, 1, 224, 224)) net.initialize() for layer in net: X = layer(X) print(layer.name, 'cikti sekli:\t', X.shape) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output sequential1 cikti sekli: (1, 96, 54, 54) pool0 cikti sekli: (1, 96, 26, 26) sequential2 cikti sekli: (1, 256, 26, 26) pool1 cikti sekli: (1, 256, 12, 12) sequential3 cikti sekli: (1, 384, 12, 12) pool2 cikti sekli: (1, 384, 5, 5) dropout0 cikti sekli: (1, 384, 5, 5) sequential4 cikti sekli: (1, 10, 5, 5) pool3 cikti sekli: (1, 10, 1, 1) flatten0 cikti sekli: (1, 10) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = torch.rand(size=(1, 1, 224, 224)) for layer in net: X = layer(X) print(layer.__class__.__name__,'cikti sekli:\t', X.shape) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Sequential cikti sekli: torch.Size([1, 96, 54, 54]) MaxPool2d cikti sekli: torch.Size([1, 96, 26, 26]) Sequential cikti sekli: torch.Size([1, 256, 26, 26]) MaxPool2d cikti sekli: torch.Size([1, 256, 12, 12]) Sequential cikti sekli: torch.Size([1, 384, 12, 12]) MaxPool2d cikti sekli: torch.Size([1, 384, 5, 5]) Dropout cikti sekli: torch.Size([1, 384, 5, 5]) Sequential cikti sekli: torch.Size([1, 10, 5, 5]) AdaptiveAvgPool2d cikti sekli: torch.Size([1, 10, 1, 1]) Flatten cikti sekli: torch.Size([1, 10]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = tf.random.uniform((1, 224, 224, 1)) for layer in net().layers: X = layer(X) print(layer.__class__.__name__,'cikti sekli:\t', X.shape) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Sequential cikti sekli: (1, 54, 54, 96) MaxPooling2D cikti sekli: (1, 26, 26, 96) Sequential cikti sekli: (1, 26, 26, 256) MaxPooling2D cikti sekli: (1, 12, 12, 256) Sequential cikti sekli: (1, 12, 12, 384) MaxPooling2D cikti sekli: (1, 5, 5, 384) Dropout cikti sekli: (1, 5, 5, 384) Sequential cikti sekli: (1, 5, 5, 10) GlobalAveragePooling2D cikti sekli: (1, 10) Reshape cikti sekli: (1, 1, 1, 10) Flatten cikti sekli: (1, 10) .. raw:: html
.. raw:: html
Eğitim ------ Daha önce olduğu gibi modeli eğitmek için Fashion-MNIST'i kullanıyoruz. NiN'in eğitimi AlexNet ve VGG'ninkine benzerdir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr, num_epochs, batch_size = 0.1, 10, 128 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss 0.998, train acc 0.650, test acc 0.653 2930.3 examples/sec on gpu(0) .. figure:: output_nin_8ad4f3_39_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr, num_epochs, batch_size = 0.1, 10, 128 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss 0.364, train acc 0.864, test acc 0.845 3180.3 examples/sec on cuda:0 .. figure:: output_nin_8ad4f3_42_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr, num_epochs, batch_size = 0.1, 10, 128 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss 0.349, train acc 0.872, test acc 0.880 3663.5 examples/sec on /GPU:0 .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. figure:: output_nin_8ad4f3_45_2.svg .. raw:: html
.. raw:: html
Özet ---- - NiN, evrişimli bir tabaka ve birden fazla :math:`1\times 1` evrişimli katmanlardan oluşan bloklar kullanır. Bu, piksel başına daha fazla doğrusal olmayan işleve izin vermek için evrişimli yığın içinde kullanılabilir. - NiN, tam bağlı katmanları kaldırır ve onları kanal sayısını istenen çıktı sayısına indirdikten sonra (örneğin, Fashion-MNIST için 10) küresel ortalama ortaklama ile yer değiştirir (yani, tüm konumlar üzerinden toplar). - Tam bağlı katmanların çıkarılması aşırı öğrenmeyi azaltır. NiN önemli ölçüde daha az parametreye sahiptir. - NiN tasarımı, müteakip birçok CNN tasarımını etkiledi. Alıştırmalar ------------ 1. Sınıflandırma doğruluğunu artırmak için hiper parametreleri ayarlayın. 2. NiN bloğunda neden iki :math:`1\times 1` evrişimli katman var? Bunlardan birini çıkarın, deneysel olguları gözlemleyin ve çözümleyin. 3. NiN için kaynak kullanımını hesaplayın. 1. Parametrelerin sayısı nedir? 2. Hesaplama miktarı nedir? 3. Eğitim sırasında ihtiyaç duyulan bellek miktarı nedir? 4. Tahmin sırasında gereken bellek miktarı nedir? 4. :math:`384 \times 5 \times 5` gösterimini bir adımda :math:`10 \times 5 \times 5` gösterimine indirgeme ile ilgili olası sorunlar nelerdir? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html