.. _sec_mlp_scratch:
Çok Katmanlı Algılayıcıların Sıfırdan Uygulanması
=================================================
Artık çok katmanlı algılayıcıları (MLP'ler) matematiksel olarak
nitelendirdiğimize göre, birini kendimiz uygulamaya çalışalım. Softmax
regresyonu (:numref:`sec_softmax_scratch`) ile elde ettiğimiz önceki
sonuçlarla karşılaştırmak için Fashion-MNIST imge sınıflandırma veri
kümesi (:numref:`sec_fashion_mnist`) ile çalışmaya devam edeceğiz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
from d2l import mxnet as d2l
from mxnet import gluon, np, npx
npx.set_np()
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import tensorflow as tf
from d2l import tensorflow as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
.. raw:: html
.. raw:: html
Model Parametrelerini İlkleme
-----------------------------
Fashion-MNIST'in 10 sınıf içerdiğini ve her imgenin
:math:`28 \times 28 = 784` gri tonlamalı piksel değerleri ızgarasından
oluştuğunu hatırlayın. Yine şimdilik pikseller arasındaki uzamsal yapıyı
göz ardı edeceğiz, bu nedenle bunu 784 girdi özniteliği ve 10 sınıf
içeren basit bir sınıflandırma veri kümesi olarak düşünebiliriz.
Başlarken, bir gizli katman ve 256 gizli birim içeren bir MLP
uygulayacağız. Bu miktarların ikisini de hiper parametreler olarak kabul
edebileceğimizi unutmayın. Tipik olarak, belleğin donanımda öyle tahsis
edildiğinden ve adreslendiğinden hesaplama açısından verimli olma
eğiliminde olan 2'nin katlarında katman genişliklerini seçiyoruz.
Yine, parametrelerimizi birkaç tensörle temsil edeceğiz. *Her katman*
için, bir ağırlık matrisini ve bir ek girdi vektörünü izlememiz
gerektiğini unutmayın. Her zaman olduğu gibi, bu parametrelere göre
kaybın gradyanları için bellek ayırıyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = np.random.normal(scale=0.01, size=(num_inputs, num_hiddens))
b1 = np.zeros(num_hiddens)
W2 = np.random.normal(scale=0.01, size=(num_hiddens, num_outputs))
b2 = np.zeros(num_outputs)
params = [W1, b1, W2, b2]
for param in params:
param.attach_grad()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(
num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(
num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = tf.Variable(tf.random.normal(
shape=(num_inputs, num_hiddens), mean=0, stddev=0.01))
b1 = tf.Variable(tf.zeros(num_hiddens))
W2 = tf.Variable(tf.random.normal(
shape=(num_hiddens, num_outputs), mean=0, stddev=0.01))
b2 = tf.Variable(tf.random.normal([num_outputs], stddev=.01))
params = [W1, b1, W2, b2]
.. raw:: html
.. raw:: html
Etkinleştirme Fonksiyonu
------------------------
Her şeyin nasıl çalıştığını bildiğimizden emin olmak için, ReLU
aktivasyonunu yerleşik ``relu`` işlevini doğrudan çağırmak yerine
maksimum işlevi kullanarak kendimiz uygulayacağız.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def relu(X):
return np.maximum(X, 0)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def relu(X):
return tf.math.maximum(X, 0)
.. raw:: html
.. raw:: html
Model
-----
Uzamsal yapıyı göz ardı ettiğimiz için, her iki boyutlu imgeyi
``num_inputs`` uzunluğuna sahip düz bir vektör halinde (``reshape``)
yeniden şekillendiriyoruz. Son olarak, modelimizi sadece birkaç satır
kodla uyguluyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(np.dot(X, W1) + b1)
return np.dot(H, W2) + b2
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1) # Burada '@' matris carpimini temsil eder
return (H@W2 + b2)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def net(X):
X = tf.reshape(X, (-1, num_inputs))
H = relu(tf.matmul(X, W1) + b1)
return tf.matmul(H, W2) + b2
.. raw:: html
.. raw:: html
Kayıp İşlevi
------------
Sayısal kararlılığı sağlamak için ve softmaks işlevini zaten sıfırdan
uygularken (:numref:`sec_softmax_scratch`), softmaks ve çapraz entropi
kaybını hesaplamak için yüksek seviyeli API'lerden birleşik işlevi
kullanıyoruz. Bu karmaşıklıkla ilgili önceki tartışmamızı
:numref:`subsec_softmax-implementation-revisited` içinden hatırlayın.
İlgili okuru, uygulama ayrıntıları hakkındaki bilgilerini derinleştirmek
için kayıp işlevi kaynak kodunu incelemeye teşvik ediyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
loss = gluon.loss.SoftmaxCrossEntropyLoss()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
loss = nn.CrossEntropyLoss(reduction='none')
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def loss(y_hat, y):
return tf.losses.sparse_categorical_crossentropy(
y, y_hat, from_logits=True)
.. raw:: html
.. raw:: html
Eğitim
------
Neyse ki, MLP'ler için eğitim döngüsü softmax bağlanımıyla tamamen
aynıdır. Tekrar ``d2l`` paketini kullanarak, ``train_ch3`` fonksiyonunu
çağırıyoruz (bkz. :numref:`sec_softmax_scratch`), dönem sayısını 10 ve
öğrenme oranını 0.1 olarak ayarlıyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_epochs, lr = 10, 0.1
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,
lambda batch_size: d2l.sgd(params, lr, batch_size))
.. figure:: output_mlp-scratch_106d07_63_0.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
.. figure:: output_mlp-scratch_106d07_66_0.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
num_epochs, lr = 10, 0.1
updater = d2l.Updater([W1, W2, b1, b2], lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
.. figure:: output_mlp-scratch_106d07_69_0.svg
.. raw:: html
.. raw:: html
Öğrenilen modeli değerlendirmek için onu bazı test verisine uyguluyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
d2l.predict_ch3(net, test_iter)
.. figure:: output_mlp-scratch_106d07_75_0.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
d2l.predict_ch3(net, test_iter)
.. figure:: output_mlp-scratch_106d07_78_0.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
d2l.predict_ch3(net, test_iter)
.. figure:: output_mlp-scratch_106d07_81_0.svg
.. raw:: html
.. raw:: html
Özet
----
- Manuel olarak yapıldığında bile basit bir MLP uygulamanın kolay
olduğunu gördük.
- Bununla birlikte, çok sayıda katmanla, MLP'leri sıfırdan uygulamak
yine de karmaşık olabilir (örneğin, modelimizin parametrelerini
adlandırmak ve takip etmek).
Alıştırmalar
------------
1. Hiper parametre ``num_hiddens`` değerini değiştirin ve bu hiper
parametrenin sonuçlarınızı nasıl etkilediğini görün. Diğerlerini
sabit tutarak bu hiper parametrenin en iyi değerini belirleyiniz.
2. Sonuçları nasıl etkilediğini görmek için ek bir gizli katman eklemeyi
deneyiniz.
3. Öğrenme oranını değiştirmek sonuçlarınızı nasıl değiştirir? Model
mimarisini ve diğer hiper parametreleri (dönem sayısı dahil)
sabitlersek, hangi öğrenme oranı size en iyi sonuçları verir?
4. Tüm hiper parametreleri (öğrenme oranı, dönem sayısı, gizli katman
sayısı, katman başına gizli birim sayısı) birlikte optimize ederek
elde edebileceğiniz en iyi sonuç nedir?
5. Birden fazla hiper parametre ile uğraşmanın neden çok daha zor
olduğunu açıklayınız.
6. Birden fazla hiper parametre üzerinde bir arama yapılandırmak için
düşünebileceğiniz en akıllı strateji nedir?
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html