.. _sec_linear_scratch: Sıfırdan Doğrusal Regresyon Uygulaması Yaratma ============================================== Artık doğrusal regresyonun arkasındaki temel fikirleri anladığınıza göre, işe ellerimizi daldırarak kodda uygulamaya başlayabiliriz. Bu bölümde, veri komut işleme hattı (pipeline), model, kayıp fonksiyonu ve minigrup rasgele gradyan iniş eniyileyici dahil olmak üzere tüm yöntemi sıfırdan uygulayacağız. Modern derin öğrenme çerçeveleri neredeyse tüm bu çalışmayı otomatikleştirebilirken, bir şeyleri sıfırdan uygulamak, ne yaptığınızı gerçekten bildiğinizden emin olmanın tek yoludur. Dahası, modelleri ihtiyacımıza göre özelleştirken, kendi katmanlarımızı veya kayıp işlevlerimizi tanımlama zamanı geldiğinde, kaputun altında işlerin nasıl ilerlediğini anlamak kullanışlı olacaktır. Bu bölümde, sadece tensörlere ve otomatik türev almaya güveneceğiz. Daha sonra, derin öğrenme çerçevelerinin çekici ek özelliklerden yararlanarak daha kısa bir uygulama sunacağız. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import random from d2l import mxnet as d2l from mxnet import autograd, np, npx npx.set_np() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import random import torch from d2l import torch as d2l .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import random import tensorflow as tf from d2l import tensorflow as d2l .. raw:: html
.. raw:: html
Veri Kümesini Oluşturma ----------------------- İşleri basitleştirmek için, gürültülü doğrusal bir model için yapay bir veri kümesi oluşturacağız. Görevimiz, veri kümemizde bulunan sonlu örnek kümesini kullanarak bu modelin parametrelerini elde etmek olacaktır. Verileri düşük boyutlu tutacağız, böylece kolayca görselleştirebiliriz. Aşağıdaki kod parçacığında, her biri standart bir normal dağılımdan örneklenmiş 2 öznitelikten oluşan 1000 örnekli bir veri kümesi oluşturuyoruz. Böylece, sentetik veri kümemiz matris :math:`\mathbf{X}\in \mathbb{R}^{1000 \times 2}` olacaktır. Veri kümemizi oluşturan gerçek parametreler :math:`\mathbf{w} = [2, -3.4]^\top` ve :math:`b = 4.2` olacaktır ve sentetik etiketlerimiz aşağıdaki :math:`\epsilon` gürültü terimli doğrusal modele göre atanacaktır: .. math:: \mathbf{y}= \mathbf{X} \mathbf{w} + b + \mathbf\epsilon. :math:`\epsilon`'u öznitelikler ve etiketlerdeki olası ölçüm hatalarını yakalıyor diye düşünebilirsiniz. Standart varsayımların geçerli olduğunu ve böylece :math:`\epsilon` değerinin ortalaması 0 olan normal bir dağılıma uyduğunu varsayacağız. Problemimizi kolaylaştırmak için, standart sapmasını 0.01 olarak ayarlayacağız. Aşağıdaki kod, sentetik veri kümemizi üretir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def synthetic_data(w, b, num_examples): #@save """Veri yaratma, y = Xw + b + gürültü.""" X = np.random.normal(0, 1, (num_examples, len(w))) y = np.dot(X, w) + b y += np.random.normal(0, 0.01, y.shape) return X, y.reshape((-1, 1)) true_w = np.array([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def synthetic_data(w, b, num_examples): #@save """Veri yaratma, y = Xw + b + gürültü.""" X = torch.normal(0, 1, (num_examples, len(w))) y = torch.matmul(X, w) + b y += torch.normal(0, 0.01, y.shape) return X, y.reshape((-1, 1)) true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def synthetic_data(w, b, num_examples): #@save """Veri yaratma, y = Xw + b + gürültü.""" X = tf.zeros((num_examples, w.shape[0])) X += tf.random.normal(shape=X.shape) y = tf.matmul(X, tf.reshape(w, (-1, 1))) + b y += tf.random.normal(shape=y.shape, stddev=0.01) y = tf.reshape(y, (-1, 1)) return X, y true_w = tf.constant([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000) .. raw:: html
.. raw:: html
``features``'deki (öznitelikleri tutan değişken) her satırın 2 boyutlu bir veri örneğinden oluştuğuna ve ``labels``'deki (etiketleri tutan değişken) her satırın 1 boyutlu bir etiket değerinden (bir skaler) oluştuğuna dikkat edin. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print('oznitelikler:', features[0],'\netiket:', labels[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output oznitelikler: [2.2122064 1.1630787] etiket: [4.662078] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print('oznitelikler:', features[0],'\netiket:', labels[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output oznitelikler: tensor([0.1546, 2.3925]) etiket: tensor([-3.6205]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print('oznitelikler:', features[0],'\netiket:', labels[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output oznitelikler: tf.Tensor([ 1.0085982 -0.9955097], shape=(2,), dtype=float32) etiket: tf.Tensor([9.597065], shape=(1,), dtype=float32) .. raw:: html
.. raw:: html
İkinci öznitelik ``features[:, 1]`` ve ``labels`` kullanılarak bir dağılım grafiği oluşturup ikisi arasındaki doğrusal korelasyonu net bir şekilde gözlemleyebiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.set_figsize() # İki nokta üstüste sadece gösterim amaçlıdır d2l.plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(), 1); .. figure:: output_linear-regression-scratch_58de05_39_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.set_figsize() # İki nokta üstüste sadece gösterim amaçlıdır d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1); .. figure:: output_linear-regression-scratch_58de05_42_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.set_figsize() # İki nokta üstüste sadece gösterim amaçlıdır d2l.plt.scatter(features[:, 1].numpy(), labels.numpy(), 1); .. figure:: output_linear-regression-scratch_58de05_45_0.svg .. raw:: html
.. raw:: html
Veri Kümesini Okuma ------------------- Model eğitimlerinin, veri kümesi üzerinde birden çok geçiş yapmaktan, her seferde bir minigrup örnek almaktan ve bunları modelimizi güncellemek için kullanmaktan oluştuğunu hatırlayın. Bu süreç, makine öğrenmesi algoritmalarını eğitmek için çok temel olduğundan, veri kümesini karıştırmak ve ona minigruplar halinde erişmek için bir yardımcı işlev tanımlamaya değer. Aşağıdaki kodda, bu işlevselliğin olası bir uygulamasını göstermek için ``data_iter`` işlevini tanımlıyoruz. Fonksiyon, bir grup boyutunu, bir öznitelik matrisini ve bir etiket vektörünü alarak ``batch_size`` boyutundaki minigrupları verir. Her bir minigrup, bir dizi öznitelik ve etiketten oluşur. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples)) # Örnekler belirli bir sıra gözetmeksizin rastgele okunur random.shuffle(indices) for i in range(0, num_examples, batch_size): batch_indices = np.array( indices[i: min(i + batch_size, num_examples)]) yield features[batch_indices], labels[batch_indices] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples)) # Örnekler belirli bir sıra gözetmeksizin rastgele okunur random.shuffle(indices) for i in range(0, num_examples, batch_size): batch_indices = torch.tensor( indices[i: min(i + batch_size, num_examples)]) yield features[batch_indices], labels[batch_indices] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples)) # Örnekler belirli bir sıra gözetmeksizin rastgele okunur random.shuffle(indices) for i in range(0, num_examples, batch_size): j = tf.constant(indices[i: min(i + batch_size, num_examples)]) yield tf.gather(features, j), tf.gather(labels, j) .. raw:: html
.. raw:: html
Genel olarak, paralelleştirme işlemlerinde mükemmel olan GPU donanımından yararlanmak için makul boyutta minigruplar kullanmak istediğimizi unutmayın. Her örnek, modellerimiz üzerinden paralel olarak beslenebildiği ve her örnek için kayıp fonksiyonunun gradyanı da paralel olarak alınabildiğinden, GPU'lar, yüzlerce örneği yalnızca tek bir örneği işlemek için gerekebileceğinden çok daha az kısa sürede işlememize izin verir. Biraz sezgi oluşturmak için, ilk olarak küçük bir grup veri örneği okuyup yazdıralım. Her minigruptaki özniteliklerin şekli bize hem minigrup boyutunu hem de girdi özniteliklerinin sayısını söyler. Aynı şekilde, minigrubumuzun etiketleri de ``batch_size`` ile verilen şekle sahip olacaktır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python batch_size = 10 for X, y in data_iter(batch_size, features, labels): print(X, '\n', y) break .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [[-1.6242899 -3.2149546 ] [ 1.5702168 1.11278 ] [-0.36137256 0.98650014] [ 1.317333 0.63940585] [-2.1471155 -0.6573725 ] [-1.4225755 -1.1081946 ] [-1.5367762 1.0635569 ] [-1.48432 1.0816108 ] [-0.1742568 1.9691626 ] [-0.38354877 1.6984322 ]] [[11.875465 ] [ 3.5531938 ] [ 0.11717813] [ 4.6646976 ] [ 2.157684 ] [ 5.1158175 ] [-2.4930956 ] [-2.441576 ] [-2.8460252 ] [-2.335064 ]] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python batch_size = 10 for X, y in data_iter(batch_size, features, labels): print(X, '\n', y) break .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 1.4869, 1.5494], [-0.8690, -0.0986], [ 1.5624, 0.0090], [-0.4172, 0.9719], [ 0.3500, -0.1156], [-0.3433, 2.4511], [-1.1783, -1.2873], [-1.1068, -0.5236], [ 0.8041, 0.2262], [-2.2314, 0.0541]]) tensor([[ 1.9146], [ 2.7896], [ 7.2889], [ 0.0441], [ 5.3029], [-4.8102], [ 6.2084], [ 3.7547], [ 5.0364], [-0.4410]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python batch_size = 10 for X, y in data_iter(batch_size, features, labels): print(X, '\n', y) break .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tf.Tensor( [[ 1.8249083 0.43419597] [ 0.7772833 0.6235751 ] [-0.7631955 0.08624952] [ 0.5574609 1.3876617 ] [ 0.17594892 1.5851324 ] [ 0.21412234 -1.7341554 ] [ 0.06975526 0.54019475] [-2.0243845 0.78842735] [-1.2418027 0.4114364 ] [ 0.39266726 -1.0444765 ]], shape=(10, 2), dtype=float32) tf.Tensor( [[ 6.3809032 ] [ 3.630106 ] [ 2.377214 ] [ 0.59058595] [-0.8450924 ] [10.518543 ] [ 2.5056705 ] [-2.541665 ] [ 0.30798355] [ 8.541502 ]], shape=(10, 1), dtype=float32) .. raw:: html
.. raw:: html
Yinelemeyi çalıştırırken, tüm veri kümesi tükenene kadar art arda farklı minigruplar elde ederiz (bunu deneyin). Yukarıda uygulanan yineleme, eğitici amaçlar için iyi olsa da, gerçek problemlerde bizim başımızı belaya sokacak şekilde verimsizdir. Örneğin, tüm verileri belleğe yüklememizi ve çok sayıda rastgele bellek erişimi gerçekleştirmemizi gerektirir. Derin öğrenme çerçevesinde uygulanan yerleşik yineleyiciler önemli ölçüde daha verimlidir ve hem dosyalarda depolanan verilerle hem de veri akışları aracılığıyla beslenen verilerle ilgilenebilirler. Model Parametrelerini İlkleme ----------------------------- Modelimizin parametrelerini minigrup rasgele gradyan inişiyle optimize etmeye başlamadan önce, ilk olarak bazı parametrelere ihtiyacımız var. Aşağıdaki kodda, ağırlıkları, ortalaması 0 ve standart sapması 0.01 olan normal bir dağılımdan rasgele sayılar örnekleyerek ve ek girdiyi 0 olarak ayarlayarak ilkliyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python w = np.random.normal(0, 0.01, (2, 1)) b = np.zeros(1) w.attach_grad() b.attach_grad() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python w = torch.normal(0, 0.01, size=(2,1), requires_grad=True) b = torch.zeros(1, requires_grad=True) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python w = tf.Variable(tf.random.normal(shape=(2, 1), mean=0, stddev=0.01), trainable=True) b = tf.Variable(tf.zeros(1), trainable=True) .. raw:: html
.. raw:: html
Parametrelerimizi ilkledikten sonra, bir sonraki görevimiz, verilerimize yeterince iyi uyum sağlayana kadar onları güncellemektir. Her güncelleme, parametrelere göre kayıp fonksiyonumuzun gradyanını almayı gerektirir. Gradyan verildiğinde, her parametreyi kaybı azaltabilecek yönde güncelleyebiliriz. Hiç kimse gradyanları açıkça hesaplamak istemediğinden (bu sıkıcı ve hataya açıktır), gradyanı hesaplamak için :numref:`sec_autograd` içinde tanıtıldığı gibi otomatik türev almayı kullanırız. Modeli Tanımlama ---------------- Daha sonra, modelimizi, onun girdileri ve parametreleri çıktıları ile ilişkilendirerek tanımlamalıyız. Doğrusal modelin çıktısını hesaplamak için, :math:`\mathbf{X}` girdi özniteliklerinin ve :math:`\mathbf{w}` model ağırlıklarının matris vektör nokta çarpımını alıp her bir örneğe :math:`b` ek girdisini eklediğimizi hatırlayın. Aşağıda :math:`\mathbf{Xw}` bir vektör ve :math:`b` bir skalerdir. Yayma mekanizmasının şurada açıklandığı anımsayalım :numref:`subsec_broadcasting`. Bir vektör ve bir skaleri topladığımızda, skaler vektörün her bileşenine eklenir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def linreg(X, w, b): #@save """Doğrusal regresyon modeli.""" return np.dot(X, w) + b .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def linreg(X, w, b): #@save """Doğrusal regresyon modeli.""" return torch.matmul(X, w) + b .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def linreg(X, w, b): #@save """Doğrusal regresyon modeli.""" return tf.matmul(X, w) + b .. raw:: html
.. raw:: html
Kayıp Fonksiyonunu Tanımlama ---------------------------- Modelimizi güncellemek, kayıp fonksiyonumuzun gradyanını almayı gerektirdiğinden, önce kayıp fonksiyonunu tanımlamalıyız. Burada kare kayıp fonksiyonunu şurada açıklandığı, :numref:`sec_linear_regression`, gibi kullanacağız . Uygulamada, ``y`` gerçek değerini tahmin edilen değer ``y_hat`` şekline dönüştürmemiz gerekir. Aşağıdaki işlev tarafından döndürülen sonuç da ``y_hat`` ile aynı şekle sahip olacaktır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def squared_loss(y_hat, y): #@save """Kare kayıp.""" return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def squared_loss(y_hat, y): #@save """Kare kayıp.""" return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def squared_loss(y_hat, y): #@save """Kare kayıp.""" return (y_hat - tf.reshape(y, y_hat.shape)) ** 2 / 2 .. raw:: html
.. raw:: html
Optimizasyon Algoritmasını Tanımlama ------------------------------------ :numref:`sec_linear_regression` içinde tartıştığımız gibi, doğrusal regresyon kapalı biçim bir çözüme sahiptir. Ancak, bu doğrusal regresyon hakkında bir kitap değil: Derin öğrenme hakkında bir kitap. Bu kitabın tanıttığı diğer modellerin hiçbiri analitik olarak çözülemediğinden, bu fırsatı minigrup rasgele gradyan inişinin ilk çalışan örneğini tanıtmak için kullanacağız. Her adımda, veri kümemizden rastgele alınan bir minigrup kullanarak, parametrelerimize göre kaybın gradyanını tahmin edeceğiz. Daha sonra kayıpları azaltabilecek yönde parametrelerimizi güncelleyeceğiz. Aşağıdaki kod, bir küme parametre, bir öğrenme oranı ve bir grup boyutu verildiğinde minigrup rasgele gradyan iniş güncellemesini uygular. Güncelleme adımının boyutu, öğrenme oranı ``lr`` tarafından belirlenir. Kaybımız, örneklerin minigrubu üzerinden bir toplam olarak hesaplandığından, adım boyutumuzu grup boyutuna (``batch_size``) göre normalleştiririz, böylece tipik bir adım boyutunun büyüklüğü, grup boyutu seçimimize büyük ölçüde bağlı olmaz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def sgd(params, lr, batch_size): #@save """Minigrup rasgele gradyan inişi.""" for param in params: param[:] = param - lr * param.grad / batch_size .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def sgd(params, lr, batch_size): #@save """Minigrup rasgele gradyan inişi.""" with torch.no_grad(): for param in params: param -= lr * param.grad / batch_size param.grad.zero_() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def sgd(params, grads, lr, batch_size): #@save """Minigrup rasgele gradyan inişi.""" for param, grad in zip(params, grads): param.assign_sub(lr*grad/batch_size) .. raw:: html
.. raw:: html
Eğitim ------ Artık tüm parçaları yerine koyduğumuza göre, ana eğitim döngüsünü uygulamaya hazırız. Bu kodu anlamanız çok önemlidir çünkü derin öğrenmede kariyeriniz boyunca neredeyse aynı eğitim döngülerini tekrar tekrar göreceksiniz. Her yinelemede, bir minigrup eğitim örneği alacağız ve bir dizi tahmin elde etmek için bunları modelimizden geçireceğiz. Kaybı hesapladıktan sonra, her parametreye göre gradyanları depolayarak ağ üzerinden geriye doğru geçişi başlatırız. Son olarak, model parametrelerini güncellemek için optimizasyon algoritması ``sgd``'yi çağıracağız. Özetle, aşağıdaki döngüyü uygulayacağız: - :math:`(\mathbf {w}, b)` parametrelerini ilkletin. - Tamamlanana kadar tekrarlayın - Gradyanı hesaplayın: :math:`\mathbf{g} \leftarrow \partial_{(\mathbf{w},b)} \frac{1}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} l(\mathbf{x}^{(i)}, y^{(i)}, \mathbf{w}, b)` - Parametreleri güncelleyin: :math:`(\mathbf{w}, b) \leftarrow (\mathbf{w}, b) - \eta \mathbf{g}` Her bir *dönemde (epoch)*, eğitim veri kümesindeki her örnekten geçtikten sonra (örneklerin sayısının grup boyutuna bölünebildiği varsayılarak) tüm veri kümesini (``data_iter`` işlevini kullanarak) yineleyeceğiz. Dönemlerin sayısı, ``num_epochs``, ve öğrenme hızı, ``lr``, burada sırasıyla 3 ve 0.03 olarak belirlediğimiz hiper parametrelerdir. Ne yazık ki, hiper parametrelerin belirlenmesi zordur ve deneme yanılma yoluyla bazı ayarlamalar gerektirir. Bu ayrıntıları şimdilik atlıyoruz, ancak daha sonra :numref:`chap_optimization` içinde tekrarlayacağız. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr = 0.03 num_epochs = 3 net = linreg loss = squared_loss for epoch in range(num_epochs): for X, y in data_iter(batch_size, features, labels): with autograd.record(): l = loss(net(X, w, b), y) # `X` ve `y`'deki minigrup kaybı # `l`'nin şekli (`batch_size`, 1) olduğu ve skaler bir değişken olmadığı için, # `l`'deki öğeler,[`w`, `b`]'ye göre gradyanların olduğu yeni bir değişken # elde etmek için birbirine eklenir. l.backward() sgd([w, b], lr, batch_size) # Parametreleri gradyanlarına göre güncelle train_l = loss(net(features, w, b), labels) print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [21:55:08] src/base.cc:49: GPU context requested, but no GPUs found. epoch 1, loss 0.025044 epoch 2, loss 0.000090 epoch 3, loss 0.000051 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr = 0.03 num_epochs = 3 net = linreg loss = squared_loss for epoch in range(num_epochs): for X, y in data_iter(batch_size, features, labels): l = loss(net(X, w, b), y) # `X` ve `y`'deki minigrup kaybı # [`w`, `b`]'e göre `l` üzerindeki gradyanı hesaplayın l.sum().backward() sgd([w, b], lr, batch_size) # Parametreleri gradyanlarına göre güncelle with torch.no_grad(): train_l = loss(net(features, w, b), labels) print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output epoch 1, loss 0.035539 epoch 2, loss 0.000133 epoch 3, loss 0.000050 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lr = 0.03 num_epochs = 3 net = linreg loss = squared_loss for epoch in range(num_epochs): for X, y in data_iter(batch_size, features, labels): with tf.GradientTape() as g: l = loss(net(X, w, b), y) # `X` ve `y`'deki minigrup kaybı # [`w`, `b`]'e göre `l` üzerindeki gradyanı hesaplayın dw, db = g.gradient(l, [w, b]) # Parametreleri gradyanlarına göre güncelle sgd([w, b], [dw, db], lr, batch_size) train_l = loss(net(features, w, b), labels) print(f'donem {epoch + 1}, kayip {float(tf.reduce_mean(train_l)):f}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output donem 1, kayip 0.051920 donem 2, kayip 0.000222 donem 3, kayip 0.000052 .. raw:: html
.. raw:: html
Bu durumda, veri kümemizi kendimiz sentezlediğimiz için, gerçek parametrelerin ne olduğunu tam olarak biliyoruz. Böylece eğitimdeki başarımızı, gerçek parametreleri eğitim döngümüz aracılığıyla öğrendiklerimizle karşılaştırarak değerlendirebiliriz. Gerçekten de birbirlerine çok yakın oldukları ortaya çıkıyor. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(f'w tahminindeki hata: {true_w - w.reshape(true_w.shape)}') print(f'b tahminindeki hata: {true_b - b}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output w tahminindeki hata: [0.00038254 0.00028729] b tahminindeki hata: [-4.6253204e-05] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(f'w tahminindeki hata: {true_w - w.reshape(true_w.shape)}') print(f'b tahminindeki hata: {true_b - b}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output w tahminindeki hata: tensor([0.0002, 0.0002], grad_fn=) b tahminindeki hata: tensor([-4.7684e-07], grad_fn=) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(f'w tahminindeki hata: {true_w - tf.reshape(w, true_w.shape)}') print(f'b tahminindeki hata: {true_b - b}') .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output w tahminindeki hata: [-0.0001471 -0.00130081] b tahminindeki hata: [0.00119877] .. raw:: html
.. raw:: html
Parametreleri mükemmel bir şekilde elde ettiğimizi kabullenmememiz gerektiğini unutmayın. Bununla birlikte, makine öğrenmesinde, genellikle temeldeki gerçek parametreleri elde etmek ile daha az ilgileniriz ve yüksek derecede doğru tahminlere yol açan parametrelerle daha çok ilgileniriz. Neyse ki, zorlu optimizasyon problemlerinde bile, rasgele gradyan inişi, kısmen derin ağlar için, oldukça doğru tahmine götüren parametrelerin birçok konfigürasyonunun mevcut olmasından dolayı, genellikle dikkate değer ölçüde iyi çözümler bulabilir. Özet ---- - Derin bir ağın, katmanları veya süslü optimize edicileri tanımlamaya gerek kalmadan sadece tensörler ve otomatik türev alma kullanarak nasıl sıfırdan uygulanabileceğini ve optimize edilebileceğini gördük. - Bu bölüm sadece mümkün olanın yüzeyine ışık tutar. İlerideki bölümlerde, yeni tanıttığımız kavramlara dayalı yeni modelleri açıklayacak ve bunları daha kısaca nasıl uygulayacağımızı öğreneceğiz. Alıştırmalar ------------ 1. Ağırlıkları sıfıra ilkleseydik ne olurdu? Algoritma yine de çalışır mıydı? 2. Voltaj ve akım arasında bir model bulmaya çalışan `Georg Simon Ohm `__ olduğunuzu varsayın. Modelinizin parametrelerini öğrenmek için otomatik türev almayı kullanabilir misiniz? 3. Spektral enerji yoğunluğunu kullanarak bir nesnenin sıcaklığını belirlemek için `Planck Yasası `__'nı kullanabilir misiniz? 4. İkinci türevleri hesaplamak isterseniz karşılaşabileceğiniz sorunlar nelerdir? Onları nasıl düzeltirsiniz? 5. ``squared_loss`` işlevinde ``reshape`` işlevi neden gereklidir? 6. Kayıp işlevi değerinin ne kadar hızlı düştüğünü bulmak için farklı öğrenme oranları kullanarak deney yapın. 7. Örneklerin sayısı parti boyutuna bölünemezse, ``data_iter`` işlevinin davranışına ne olur? .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html