.. _sec_nadaraya-watson: Dikkat Ortaklama: Nadaraya-Watson Çekirdek Bağlanımı ==================================================== Artık :numref:`fig_qkv` çerçevesinde dikkat mekanizmalarının ana bileşenlerini biliyorsunuz. Yeniden özetlemek için sorgular (istemli işaretler) ve anahtarlar (istemsiz işaretler) arasındaki etkileşimler *dikkat ortaklama* ile sonuçlanır. Dikkat ortaklama, çıktıyı üretmek için seçici olarak değerleri (duyusal girdiler) bir araya getirir. Bu bölümde, dikkat mekanizmalarının pratikte nasıl çalıştığına dair üst düzey bir görünüm vermek için dikkat ortaklamasını daha ayrıntılı olarak anlatacağız. Özellikle, 1964 yılında önerilen Nadaraya-Watson çekirdek bağlanım modeli, makine öğrenmesini dikkat mekanizmaları ile göstermek için basit ama eksiksiz bir örnektir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python from d2l import mxnet as d2l from mxnet import autograd, gluon, np, npx from mxnet.gluon import nn npx.set_np() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn from d2l import torch as d2l .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import tensorflow as tf from d2l import tensorflow as d2l tf.random.set_seed(seed=1322) .. raw:: html
.. raw:: html
Veri Kümesi Oluşturma --------------------- İşleri basit tutmak için, aşağıdaki regresyon problemini ele alalım: :math:`\{(x_1, y_1), \ldots, (x_n, y_n)\}` girdi-çıktı çiftlerinin bir veri kümesi verildiğinde :math:`\{(x_1, y_1), \ldots, (x_n, y_n)\}`, :math:`\hat{y} = f(x)` yeni bir :math:`x` girdisinin çıktısını tahmin etmek için :math:`\hat{y} = f(x)` nasıl öğrenilir? Burada :math:`\epsilon` gürültü terimi ile aşağıdaki doğrusal olmayan fonksiyona göre yapay bir veri kümesi oluşturuyoruz: .. math:: y_i = 2\sin(x_i) + x_i^{0.8} + \epsilon, burada :math:`\epsilon` sıfır ortalama ve 0.5 standart sapma ile normal bir dağılıma uyar. Hem 50 eğitim örneği hem de 50 test örneği üretilir. Dikkat modelini daha sonra daha iyi görselleştirmek için, eğitim girdileri sıralanır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n_train = 50 # Eğitim örneklerinin adedi x_train = np.sort(np.random.rand(n_train) * 5) # Eğitim girdileri def f(x): return 2 * np.sin(x) + x**0.8 y_train = f(x_train) + np.random.normal(0.0, 0.5, (n_train,)) # Eğitim çıktıları x_test = np.arange(0, 5, 0.1) # Test örnekleri y_truth = f(x_test) # Test örneklerinin adedi gerçek referans değeri n_test = len(x_test) # Test örneklerinin adedi n_test .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 50 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n_train = 50 # Eğitim örneklerinin adedi x_train, _ = torch.sort(torch.rand(n_train) * 5) # Eğitim girdileri def f(x): return 2 * torch.sin(x) + x**0.8 y_train = f(x_train) + torch.normal(0.0, 0.5, (n_train,)) # Eğitim çıktıları x_test = torch.arange(0, 5, 0.1) # Test örnekleri y_truth = f(x_test) # Test örneklerinin adedi gerçek referans değeri n_test = len(x_test) # Test örneklerinin adedi n_test .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 50 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n_train = 50 x_train = tf.sort(tf.random.uniform(shape=(n_train,), maxval=5)) def f(x): return 2 * tf.sin(x) + x**0.8 y_train = f(x_train) + tf.random.normal((n_train,), 0.0, 0.5) # Eğitim çıktıları x_test = tf.range(0, 5, 0.1) # Test örnekleri y_truth = f(x_test) # Test örneklerinin adedi gerçek referans değeri n_test = len(x_test) # Test örneklerinin adedi n_test .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 50 .. raw:: html
.. raw:: html
Aşağıdaki işlev, tüm eğitim örneklerini (dairelerle temsil edilmiş), gürültü terimi olmadan gerçek referans değer veri üretme işlevi 'f'yi ("Truth" ile etiketlenmiş) ve öğrenilen tahmin işlevini ("Pred" ile etiketlenmiş) çizer. .. raw:: latex \diilbookstyleinputcell .. code:: python def plot_kernel_reg(y_hat): d2l.plot(x_test, [y_truth, y_hat], 'x', 'y', legend=['Truth', 'Pred'], xlim=[0, 5], ylim=[-1, 5]) d2l.plt.plot(x_train, y_train, 'o', alpha=0.5); Ortalama Ortaklama ------------------ Bu regresyon problemi için belki de dünyanın “en aptalca” tahmin edicisiyle başlıyoruz: Ortalama ortaklama kullanarak tüm eğitim çıktıları üzerinde ortalama, .. math:: f(x) = \frac{1}{n}\sum_{i=1}^n y_i, :label: eq_avg-pooling aşağıda çizilmiştir. Gördüğümüz gibi, bu tahminci gerçekten o kadar akıllı değil. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python y_hat = y_train.mean().repeat(n_test) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_29_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python y_hat = torch.repeat_interleave(y_train.mean(), n_test) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_32_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python y_hat = tf.repeat(tf.reduce_mean(y_train), repeats=n_test) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_35_0.svg .. raw:: html
.. raw:: html
Parametrik Olmayan Dikkat Ortaklama ----------------------------------- Açıkçası, ortalama ortaklama girdileri, :math:`x_i`, atlar. Girdi yerlerine göre :math:`y_i` çıktılarını ağırlıklandırmak için Nadaraya :cite:`Nadaraya.1964` ve Watson :cite:`Watson.1964` tarafından daha iyi bir fikir önerildi: .. math:: f(x) = \sum_{i=1}^n \frac{K(x - x_i)}{\sum_{j=1}^n K(x - x_j)} y_i, :label: eq_nadaraya-watson burada :math:`K` bir *çekirdek*\ tir. :eq:`eq_nadaraya-watson` içindeki tahmin ediciye *Nadaraya-Watson çekirdek regresyonu* denir. Burada çekirdeklerin ayrıntılarına dalmayacağız. :numref:`fig_qkv` içindeki dikkat mekanizmalarının çerçevesini hatırlayın. Dikkat açısından bakıldığında, :eq:`eq_nadaraya-watson` denklemini *dikkat ortaklama*\ nın daha genelleştirilmiş bir formunda yeniden yazabiliriz: .. math:: f(x) = \sum_{i=1}^n \alpha(x, x_i) y_i, :label: eq_attn-pooling burada :math:`x` sorgu ve :math:`(x_i, y_i)` anahtar-değer çiftidir. :eq:`eq_attn-pooling` ve :eq:`eq_avg-pooling` karşılaştırılırsa, buradaki dikkat havuzlama :math:`y_i` değerlerinin ağırlıklı bir ortalamasıdır. :eq:`eq_attn-pooling` içindeki *dikkat ağırlığı* :math:`\alpha(x, x_i)`, :math:`x` sorgu ve :math:`\alpha` ile modellenen anahtar :math:`x_i` arasındaki etkileşime dayalı olarak karşılık gelen :math:`y_i` değerine atanır. Herhangi bir sorgu için, tüm anahtar-değer çiftleri üzerindeki dikkat ağırlıkları geçerli bir olasılık dağılımıdır: Negatif değillerdir ve bire toplanırlar. Dikkat ortaklama sezgileri kazanmak için, sadece aşağıda tanımlanan bir *Gauss çekirdeği*\ ni düşünün .. math:: K(u) = \frac{1}{\sqrt{2\pi}} \exp(-\frac{u^2}{2}). Gauss çekirdeğini :eq:`eq_attn-pooling` ve :eq:`eq_nadaraya-watson` denklemlerine koyarsak .. math:: \begin{aligned} f(x) &=\sum_{i=1}^n \alpha(x, x_i) y_i\\ &= \sum_{i=1}^n \frac{\exp\left(-\frac{1}{2}(x - x_i)^2\right)}{\sum_{j=1}^n \exp\left(-\frac{1}{2}(x - x_j)^2\right)} y_i \\&= \sum_{i=1}^n \mathrm{softmax}\left(-\frac{1}{2}(x - x_i)^2\right) y_i. \end{aligned} :label: eq_nadaraya-watson-gaussian :eq:`eq_nadaraya-watson-gaussian` içinde, verilen :math:`x` sorgusuna daha yakın olan bir :math:`x_i` anahtarı, anahtarın karşılık gelen :math:`y_i` değerine atanan *daha büyük bir dikkat ağırlığı* aracılığıyla *daha fazla dikkat* alacaktır. Nadaraya-Watson çekirdek regresyonu parametrik olmayan bir modeldir; bu nedenle :eq:`eq_nadaraya-watson-gaussian`, *parametrik olmayan dikkat ortaklama* örneğidir. Aşağıda, bu parametrik olmayan dikkat modeline dayanarak tahmini çiziyoruz. Tahmin edilen çizgi düzgün ve ortalama ortaklama tarafından üretilen gerçek referans değere daha yakındır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_repeat` şekli: (`n_test`, `n_train`), burada her satır aynı test # girdilerini içerir (yani aynı sorgular) X_repeat = x_test.repeat(n_train).reshape((-1, n_train)) # `x_train`'in anahtarları içerdiğine dikkat edin. `attention_weights` şekli: # (`n_test`, `n_train`)'dir, burada her satır, her sorguya verilen değerler # (`y_train`) arasında atanacak dikkat ağırlıklarını içerir attention_weights = npx.softmax(-(X_repeat - x_train)**2 / 2) # Each element of `y_hat` is weighted average of values, where weights are # attention weights # `y_hat`'nin her bir öğesi, ağırlıkların dikkat ağırlıkları olduğu # değerlerin ağırlıklı ortalamasıdır. y_hat = np.dot(attention_weights, y_train) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_41_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_repeat` şekli: (`n_test`, `n_train`), burada her satır aynı test # girdilerini içerir (yani aynı sorgular) X_repeat = x_test.repeat_interleave(n_train).reshape((-1, n_train)) # `x_train`'in anahtarları içerdiğine dikkat edin. `attention_weights` şekli: # (`n_test`, `n_train`)'dir, burada her satır, her sorguya verilen değerler # (`y_train`) arasında atanacak dikkat ağırlıklarını içerir attention_weights = nn.functional.softmax(-(X_repeat - x_train)**2 / 2, dim=1) # `y_hat`'nin her bir öğesi, ağırlıkların dikkat ağırlıkları olduğu # değerlerin ağırlıklı ortalamasıdır. y_hat = torch.matmul(attention_weights, y_train) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_44_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_repeat` şekli: (`n_test`, `n_train`), burada her satır aynı test # girdilerini içerir (yani aynı sorgular) X_repeat = tf.repeat(tf.expand_dims(x_train, axis=0), repeats=n_train, axis=0) # `x_train`'in anahtarları içerdiğine dikkat edin. `attention_weights` şekli: # (`n_test`, `n_train`)'dir, burada her satır, her sorguya verilen değerler # (`y_train`) arasında atanacak dikkat ağırlıklarını içerir attention_weights = tf.nn.softmax(-(X_repeat - tf.expand_dims(x_train, axis=1))**2/2, axis=1) # `y_hat`'nin her bir öğesi, ağırlıkların dikkat ağırlıkları olduğu # değerlerin ağırlıklı ortalamasıdır. y_hat = tf.matmul(attention_weights, tf.expand_dims(y_train, axis=1)) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_47_0.svg .. raw:: html
.. raw:: html
Şimdi dikkat ağırlıklarına bir göz atalım. Burada test girdileri sorgulardır, eğitim girdileri ise anahtarlardır. Her iki girdi sıralandığından, sorgu-anahtar çifti ne kadar yakın olursa, dikkat ortaklamasında dikkat ağırlığı o kadar yüksek olur. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(np.expand_dims(np.expand_dims(attention_weights, 0), 0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_53_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(attention_weights.unsqueeze(0).unsqueeze(0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_56_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(tf.expand_dims(tf.expand_dims(attention_weights, axis=0), axis=0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_59_0.svg .. raw:: html
.. raw:: html
**Parametrik Dikkat Ortaklama** ------------------------------- Parametrik olmayan Nadaraya-Watson çekirdek regresyonu *tutarlılık* avantajından yararlanır: Yeterli veri verildiğinde bu model en uygun çözüme yakınlaşır. Bununla birlikte, öğrenilebilir parametreleri dikkat ortaklamasına kolayca tümleştirebiliriz. Örnek olarak, :eq:`eq_nadaraya-watson-gaussian` denkleminden biraz farklı olarak, aşağıdaki gibi :math:`x` sorgu ve :math:`x_i` anahtarı arasındaki uzaklık, öğrenilebilir bir parametre :math:`w` ile çarpılır: .. math:: \begin{aligned}f(x) &= \sum_{i=1}^n \alpha(x, x_i) y_i \\&= \sum_{i=1}^n \frac{\exp\left(-\frac{1}{2}((x - x_i)w)^2\right)}{\sum_{j=1}^n \exp\left(-\frac{1}{2}((x - x_j)w)^2\right)} y_i \\&= \sum_{i=1}^n \mathrm{softmax}\left(-\frac{1}{2}((x - x_i)w)^2\right) y_i.\end{aligned} :label: eq_nadaraya-watson-gaussian-para Bölümün geri kalanında, :eq:`eq_nadaraya-watson-gaussian-para` denklemindeki dikkat ortaklama parametresini öğrenerek bu modeli eğiteceğiz. .. _subsec_batch_dot: Toplu Matris Çarpması ~~~~~~~~~~~~~~~~~~~~~ Minigruplar için dikkati daha verimli bir şekilde hesaplamak için, derin öğrenme çerçeveleri tarafından sağlanan toplu matris çarpma yardımcı programlarından yararlanabiliriz. İlk minigrup :math:`n` matrisleri :math:`\mathbf{X}_1, \ldots, \mathbf{X}_n` şekil :math:`a\times b` içerdiğini ve ikinci minibatch :math:`n` matrisleri :math:`b\times c` şekilli :math:`\mathbf{Y}_1, \ldots, \mathbf{Y}_n` matrisleri içerdiğini varsayalım. Onların toplu matris çarpımı :math:`n` şekil :math:`a\times c` matrisleri :math:`\mathbf{X}_1\mathbf{Y}_1, \ldots, \mathbf{X}_n\mathbf{Y}_n` ile sonuçlanır. Bu nedenle, iki şekil tensör verilen (:math:`n`, :math:`a`, :math:`b`) ve (:math:`n`, :math:`b`, :math:`c`), toplu matris çarpma çıktılarının şekli (:math:`n`, :math:`a`, :math:`c`)'dir. İlk minigrubun :math:`a\times b` şeklinde :math:`\mathbf{X}_1, \ldots, \mathbf{X}_n` :math:`n` matrisi içerdiğini ve ikinci minigrubun :math:`b\times c` şeklinde :math:`\mathbf{Y}_1, \ldots, \mathbf{Y}_n` :math:`n` matrisi içerdiğini varsayalım. Onların toplu matris çarpımı, :math:`\mathbf{X}_1\mathbf{Y}_1, \ldots, \mathbf{X}_n\mathbf{Y}_n` :math:`a\times c` şeklinde :math:`n` matris ile sonuçlanır. Bu nedenle, (:math:`n`, :math:`a`, :math:`b`) ve (:math:`n`, :math:`b`, :math:`c`) şeklinde iki tensör verildiğinde, toplu matris çarpım çıktılarının şekli (:math:`n`, :math:`a`, :math:`c`)'dir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = np.ones((2, 1, 4)) Y = np.ones((2, 4, 6)) npx.batch_dot(X, Y).shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (2, 1, 6) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = torch.ones((2, 1, 4)) Y = torch.ones((2, 4, 6)) torch.bmm(X, Y).shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output torch.Size([2, 1, 6]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = tf.ones((2, 1, 4)) Y = tf.ones((2, 4, 6)) tf.matmul(X, Y).shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output TensorShape([2, 1, 6]) .. raw:: html
.. raw:: html
Dikkat mekanizmaları bağlamında, bir minigruptaki değerlerin ağırlıklı ortalamalarını hesaplamak için minigrup matris çarpımını kullanabiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python weights = np.ones((2, 10)) * 0.1 values = np.arange(20).reshape((2, 10)) npx.batch_dot(np.expand_dims(weights, 1), np.expand_dims(values, -1)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[[ 4.5]], [[14.5]]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python weights = torch.ones((2, 10)) * 0.1 values = torch.arange(20.0).reshape((2, 10)) torch.bmm(weights.unsqueeze(1), values.unsqueeze(-1)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[[ 4.5000]], [[14.5000]]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python weights = tf.ones((2, 10)) * 0.1 values = tf.reshape(tf.range(20.0), shape = (2, 10)) tf.matmul(tf.expand_dims(weights, axis=1), tf.expand_dims(values, axis=-1)).numpy() .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[[ 4.5]], [[14.5]]], dtype=float32) .. raw:: html
.. raw:: html
Modeli Tanımlama ~~~~~~~~~~~~~~~~ Minigrup matris çarpımını kullanarak, aşağıda :eq:`eq_nadaraya-watson-gaussian-para` denklemindeki parametrik dikkat ortaklamayı temel alan Nadaraya-Watson çekirdek regresyonunun parametrik versiyonunu tanımlıyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class NWKernelRegression(nn.Block): def __init__(self, **kwargs): super().__init__(**kwargs) self.w = self.params.get('w', shape=(1,)) def forward(self, queries, keys, values): # `queries` ve `attention_weights` çıktısının şekli: # (sorgu sayısı, anahtar/değer çifti sayısı) queries = queries.repeat(keys.shape[1]).reshape((-1, keys.shape[1])) self.attention_weights = npx.softmax( -((queries - keys) * self.w.data())**2 / 2) # `values` (değerler) şekli: (sorgu sayısı, anahtar/değer çifti sayısı) return npx.batch_dot(np.expand_dims(self.attention_weights, 1), np.expand_dims(values, -1)).reshape(-1) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class NWKernelRegression(nn.Module): def __init__(self, **kwargs): super().__init__(**kwargs) self.w = nn.Parameter(torch.rand((1,), requires_grad=True)) def forward(self, queries, keys, values): # `queries` ve `attention_weights` çıktısının şekli: # (sorgu sayısı, anahtar/değer çifti sayısı) queries = queries.repeat_interleave(keys.shape[1]).reshape((-1, keys.shape[1])) self.attention_weights = nn.functional.softmax( -((queries - keys) * self.w)**2 / 2, dim=1) # `values` (değerler) şekli: (sorgu sayısı, anahtar/değer çifti sayısı) return torch.bmm(self.attention_weights.unsqueeze(1), values.unsqueeze(-1)).reshape(-1) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python class NWKernelRegression(tf.keras.layers.Layer): def __init__(self, **kwargs): super().__init__(**kwargs) self.w = tf.Variable(initial_value=tf.random.uniform(shape=(1,))) def call(self, queries, keys, values, **kwargs): # For training queries are `x_train`. Keys are distance of taining data for each point. Values are `y_train`. # Shape of the output `queries` and `attention_weights`: (no. of queries, no. of key-value pairs) queries = tf.repeat(tf.expand_dims(queries, axis=1), repeats=keys.shape[1], axis=1) self.attention_weights = tf.nn.softmax(-((queries - keys) * self.w)**2 /2, axis =1) # Shape of `values`: (no. of queries, no. of key-value pairs) return tf.squeeze(tf.matmul(tf.expand_dims(self.attention_weights, axis=1), tf.expand_dims(values, axis=-1))) .. raw:: html
.. raw:: html
Eğitim ~~~~~~ Aşağıda, dikkat modelini eğitmek için eğitim veri kümesini anahtar ve değerlere dönüştürürüz. Parametrik dikkat ortaklamada, herhangi bir eğitim girdisi çıktısını tahmin etmek için kendisi dışındaki tüm eğitim örneklerinden anahtar-değer çiftlerini alır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim girdilerini içerir X_tile = np.tile(x_train, (n_train, 1)) # `Y_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim çıktılarını içerir Y_tile = np.tile(y_train, (n_train, 1)) # `keys`'in şekli: (`n_train`, `n_train` - 1) keys = X_tile[(1 - np.eye(n_train)).astype('bool')].reshape((n_train, -1)) # `values`'in şekli: (`n_train`, `n_train` - 1) values = Y_tile[(1 - np.eye(n_train)).astype('bool')].reshape((n_train, -1)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim girdilerini içerir X_tile = x_train.repeat((n_train, 1)) # `Y_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim çıktılarını içerir Y_tile = y_train.repeat((n_train, 1)) # `keys`'in şekli: (`n_train`, `n_train` - 1) keys = X_tile[(1 - torch.eye(n_train)).type(torch.bool)].reshape((n_train, -1)) # `values`'in şekli: (`n_train`, `n_train` - 1) values = Y_tile[(1 - torch.eye(n_train)).type(torch.bool)].reshape((n_train, -1)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `X_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim girdilerini içerir X_tile = tf.repeat(tf.expand_dims(x_train, axis=0), repeats=n_train, axis=0) # `Y_tile`'in şekli: (`n_train`, `n_train`), burada her sütun aynı # eğitim çıktılarını içerir Y_tile = tf.repeat(tf.expand_dims(y_train, axis=0), repeats=n_train, axis=0) # `keys`'in şekli: (`n_train`, `n_train` - 1) keys = tf.reshape(X_tile[tf.cast(1 - tf.eye(n_train), dtype=tf.bool)], shape=(n_train, -1)) # `values`'in şekli: (`n_train`, `n_train` - 1) values = tf.reshape(Y_tile[tf.cast(1 - tf.eye(n_train), dtype=tf.bool)], shape=(n_train, -1)) .. raw:: html
.. raw:: html
Kare kayıp ve rasgele gradyan inişi kullanarak, parametrik dikkat modelini eğitiriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = NWKernelRegression() net.initialize() loss = gluon.loss.L2Loss() trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.5}) animator = d2l.Animator(xlabel='epoch', ylabel='loss', xlim=[1, 5]) for epoch in range(5): with autograd.record(): l = loss(net(x_train, keys, values), y_train) l.backward() trainer.step(1) print(f'epoch {epoch + 1}, loss {float(l.sum()):.6f}') animator.add(epoch + 1, float(l.sum())) .. figure:: output_nadaraya-watson_61a333_113_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = NWKernelRegression() loss = nn.MSELoss(reduction='none') trainer = torch.optim.SGD(net.parameters(), lr=0.5) animator = d2l.Animator(xlabel='epoch', ylabel='loss', xlim=[1, 5]) for epoch in range(5): trainer.zero_grad() l = loss(net(x_train, keys, values), y_train) l.sum().backward() trainer.step() print(f'epoch {epoch + 1}, loss {float(l.sum()):.6f}') animator.add(epoch + 1, float(l.sum())) .. figure:: output_nadaraya-watson_61a333_116_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = NWKernelRegression() loss_object = tf.keras.losses.MeanSquaredError() optimizer = tf.keras.optimizers.SGD(learning_rate=0.5) animator = d2l.Animator(xlabel='epoch', ylabel='loss', xlim=[1, 5]) for epoch in range(5): with tf.GradientTape() as t: loss = loss_object(y_train, net(x_train, keys, values)) * len(y_train) grads = t.gradient(loss, net.trainable_variables) optimizer.apply_gradients(zip(grads, net.trainable_variables)) print(f'epoch {epoch + 1}, loss {float(loss):.6f}') animator.add(epoch + 1, float(loss)) .. figure:: output_nadaraya-watson_61a333_119_0.svg .. raw:: html
.. raw:: html
Parametrik dikkat modelini eğittikten sonra, tahminini çizebiliriz. Eğitim veri kümesini gürültüye oturtmaya çalışırken, tahmin edilen çizgi, daha önce çizilen parametrik olmayan karşılığından daha az pürüzsüzdür. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `keys`'in şekli: (`n_test`, `n_train`), burada her sütun aynı eğitim # girdilerini (yani aynı anahtarları) içerir keys = np.tile(x_train, (n_test, 1)) # `value`'in şekli: (`n_test`, `n_train`) values = np.tile(y_train, (n_test, 1)) y_hat = net(x_test, keys, values) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_125_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `keys`'in şekli: (`n_test`, `n_train`), burada her sütun aynı eğitim # girdilerini (yani aynı anahtarları) içerir keys = x_train.repeat((n_test, 1)) # `value`'in şekli: (`n_test`, `n_train`) values = y_train.repeat((n_test, 1)) y_hat = net(x_test, keys, values).unsqueeze(1).detach() plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_128_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # `keys`'in şekli: (`n_test`, `n_train`), burada her sütun aynı eğitim # girdilerini (yani aynı anahtarları) içerir keys = tf.repeat(tf.expand_dims(x_train, axis=0), repeats=n_test, axis=0) # `value`'in şekli: (`n_test`, `n_train`) values = tf.repeat(tf.expand_dims(y_train, axis=0), repeats=n_test, axis=0) y_hat = net(x_test, keys, values) plot_kernel_reg(y_hat) .. figure:: output_nadaraya-watson_61a333_131_0.svg .. raw:: html
.. raw:: html
Parametrik olmayan dikkat ortaklama ile karşılaştırıldığında, öğrenilebilir ve parametrik ayarda büyük dikkat ağırlıkları olan bölge daha keskinleşir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(np.expand_dims(np.expand_dims(net.attention_weights, 0), 0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_137_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(net.attention_weights.unsqueeze(0).unsqueeze(0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_140_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.show_heatmaps(tf.expand_dims(tf.expand_dims(net.attention_weights, axis=0), axis=0), xlabel='Sorted training inputs', ylabel='Sorted testing inputs') .. figure:: output_nadaraya-watson_61a333_143_0.svg .. raw:: html
.. raw:: html
Özet ---- - Nadaraya-Watson çekirdek regresyonu, makine öğrenmesinin dikkat mekanizmaları ile bir örneğidir. - Nadaraya-Watson çekirdek regresyonunun dikkat ortaklaması, eğitim çıktılarının ağırlıklı bir ortalamasıdır. Dikkat açısından bakıldığında, dikkat ağırlığı, bir sorgunun işlevine ve değerle eşleştirilmiş anahtara dayanan bir değere atanır. - Dikkat ortaklama parametrik olabilir de olmayabilir de. Alıştırmalar ------------ 1. Eğitim örneklerinin sayısını artırın. Parametrik olmayan Nadaraya-Watson çekirdek regresyonunu daha iyi öğrenebilir misin? 2. Parametrik dikkat ortaklama deneyinde öğrendiğimiz :math:`w`'nin değeri nedir? Dikkat ağırlıklarını görselleştirirken ağırlıklı bölgeyi neden daha keskin hale getiriyor? 3. Daha iyi tahmin etmek için parametrik olmayan Nadaraya-Watson çekirdek regresyonuna nasıl hiper parametre ekleyebiliriz? 4. Bu bölümün çekirdek regresyonu için başka bir parametrik dikkat ortaklama tasarlayın. Bu yeni modeli eğitin ve dikkat ağırlıklarını görselleştirin. .. raw:: html
mxnetpytorch
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html