.. _sec_geometry-linear-algebraic-ops: Geometri ve Doğrusal Cebirsel İşlemler ====================================== :numref:`sec_linear-algebra` içinde, doğrusal cebirin temelleriyle karşılaştık ve verilerimizi dönüştürürken genel işlemleri ifade etmek için nasıl kullanılabileceğini gördük. Doğrusal cebir, derin öğrenmede ve daha geniş anlamda makine öğrenmesinde yaptığımız işlerin çoğunun altında yatan temel matematiksel sütunlardan biridir. :numref:`sec_linear-algebra`, modern derin öğrenme modellerinin mekaniğini iletmek için yeterli mekanizmayı içerirken, konuyla ilgili daha çok şey var. Bu bölümde daha derine ineceğiz, doğrusal cebir işlemlerinin bazı geometrik yorumlarını vurgulayacağız ve özdeğerler (eigenvalues) ve özvektörler (eigenvectors) dahil birkaç temel kavramı tanıtacağız. Vektörlerin Geometrisi ---------------------- İlk olarak, uzaydaki noktalar veya yönler olarak vektörlerin iki ortak geometrik yorumunu tartışmamız gerekiyor. Temel olarak bir vektör, aşağıdaki Python listesi gibi bir sayı listesidir. .. raw:: latex \diilbookstyleinputcell .. code:: python v = [1, 7, 0, 1] Matematikçiler bunu genellikle bir *sütun* veya *satır* vektörü olarak yazarlar; .. math:: \mathbf{x} = \begin{bmatrix}1\\7\\0\\1\end{bmatrix}, veya .. math:: \mathbf{x}^\top = \begin{bmatrix}1 & 7 & 0 & 1\end{bmatrix}. Bunlar genellikle veri örneklerinin sütun vektörleri ve ağırlıklı toplamları oluşturmada kullanılan ağırlıkların satır vektörleri olduğu farklı yorumlara sahiptir. Ancak esnek olmak faydalı olabilir. :numref:`sec_linear-algebra` bölümünde açıkladığımız gibi, tek bir vektörün varsayılan yönelimi bir sütun vektörü olsa da, tablo halindeki bir veri kümesini temsil eden herhangi bir matris için, her bir veri örneğini matriste bir satır vektörü olarak ele almak daha gelenekseldir. Bir vektör verildiğinde, ona vermemiz gereken ilk yorum uzayda bir nokta olduğudur. İki veya üç boyutta, bu noktaları, *köken (orijin)* adı verilen sabit bir referansa kıyasla uzaydaki konumlarını belirtmek için vektör bileşenlerini kullanarak görselleştirebiliriz. Bu, şurada görülebilir :numref:`fig_grid`. .. _fig_grid: .. figure:: ../img/grid-points.svg Vektörleri düzlemdeki noktalar olarak görselleştirmenin bir örneği. Vektörün ilk bileşeni :math:`x` koordinatını verir, ikinci bileşen :math:`y` koordinatını verir. Görselleştirilmesi çok daha zor olsa da, daha yüksek boyutlar da benzerdir. Bu geometrik bakış açısı, sorunu daha soyut bir düzeyde ele almamızı sağlar. Artık resimleri kedi veya köpek olarak sınıflandırmak gibi başa çıkılmaz görünen bir problemle karşılaşmadığımızdan, görevleri soyut olarak uzaydaki nokta toplulukları olarak değerlendirmeye ve görevi iki farklı nokta kümesini nasıl ayıracağımızı keşfetmek olarak resmetmeye başlayabiliriz. Buna paralel olarak, insanların genellikle vektörleri aldıkları ikinci bir bakış açısı vardır: Uzayda yönler olarak. :math:`\mathbf{v} = [3,2]^\top` vektörünü başlangıç noktasından :math:`3` birim sağda ve :math:`2` birim yukarıda bir konum olarak düşünmekle kalmayabiliriz, aynı zamanda onu sağa doğru :math:`3` adım ve yukarı doğru :math:`2` adım şekilde yönün kendisi olarak da düşünebiliriz. Bu şekilde, şekildeki tüm vektörleri aynı kabul ederiz :numref:`fig_arrow`. .. _fig_arrow: .. figure:: ../img/par-vec.svg Herhangi bir vektör, düzlemde bir ok olarak görselleştirilebilir. Bu durumda, çizilen her vektör :math:`(3,2)` vektörünün bir temsilidir. Bu değişik gösterimin faydalarından biri, vektör toplama işlemini görsel olarak anlamlandırabilmemizdir. Özellikle, bir vektör tarafından verilen yönleri izliyoruz ve şekil :numref:`fig_add-vec` içinde görüldüğü gibi, sonra diğerinin verdiği yönleri takip ediyoruz. .. _fig_add-vec: .. figure:: ../img/vec-add.svg Önce bir vektörü, sonra diğerini takip ederek vektör toplamayı görselleştirebiliriz. Vektör çıkarma işleminin benzer bir yorumu vardır. :math:`\mathbf{u} = \mathbf{v} + (\mathbf{u}-\mathbf{v})` özdeşliğini göz önünde bulundurursak, :math:`\mathbf{u}-\mathbf{v}` vektörü, bizi :math:`\mathbf{v}` noktasından :math:`\mathbf{u}` noktasına götüren yöndür. Nokta (İç) Çarpımları ve Açılar ------------------------------- :numref:`sec_linear-algebra` içinde gördüğümüz gibi, :math:`\mathbf{u}` ve :math:`\mathbf{v}` gibi iki sütun vektörü alırsak, bunların nokta çarpımını aşağıdaki işlemi hesaplayarak oluşturabiliriz: .. math:: \mathbf{u}^\top\mathbf{v} = \sum_i u_i\cdot v_i. :label: eq_dot_def :eq:`eq_dot_def` simetrik olduğundan, klasik çarpmanın gösterimini kopyalayacağız ve şöyle yazacağız: .. math:: \mathbf{u}\cdot\mathbf{v} = \mathbf{u}^\top\mathbf{v} = \mathbf{v}^\top\mathbf{u}, Böylece vektörlerin sırasını değiştirmenin aynı cevabı vereceği gerçeğini vurgulamış olacağız. İç çarpım :eq:`eq_dot_def` ayrıca geometrik bir yorumu da kabul eder: O da iki vektör arasındaki açı ile yakından ilgilidir. :numref:`fig_angle` içinde gösterilen açıyı düşünün. .. _fig_angle: .. figure:: ../img/vec-angle.svg Düzlemdeki herhangi iki vektör arasında iyi tanımlanmış bir :math:`\theta` açısı vardır. Bu açının iç çarpıma yakından bağlı olduğunu göreceğiz. Başlamak için iki belli vektörü ele alalım: .. math:: \mathbf{v} = (r,0) \; \text{ve} \; \mathbf{w} = (s\cos(\theta), s \sin(\theta)). :math:`\mathbf{v}` vektörü :math:`r` uzunluğundadır ve :math:`x` eksenine paralel uzanır, :math:`\mathbf{w}` vektörü :math:`s` uzunluğundadır ve :math:`x` ekseni ile arasında :math:`\theta` açısı vardır. Bu iki vektörün iç çarpımını hesaplarsak, şunu görürüz: .. math:: \mathbf{v}\cdot\mathbf{w} = rs\cos(\theta) = \|\mathbf{v}\|\|\mathbf{w}\|\cos(\theta). Bazı basit cebirsel işlemlerle, terimleri yeniden düzenleyebiliriz. .. math:: \theta = \arccos\left(\frac{\mathbf{v}\cdot\mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}\right). Kısacası, bu iki belli vektör için, normlarla birleştirilmiş iç çarpım bize iki vektör arasındaki açıyı söyler. Aynı gerçek genel olarak doğrudur. Burada ifadeyi türetmeyeceğiz, ancak :math:`\|\mathbf{v} - \mathbf{w}\|^2`'yi iki şekilde yazmayı düşünürsek, biri nokta çarpımı ile, diğeri geometrik olarak kosinüsler yasasının kullanımı ile, tam ilişkiyi elde edebiliriz. Gerçekten de, herhangi iki vektör, :math:`\mathbf{v}` ve :math:`\mathbf{w}` için, aralarındaki açı: .. math:: \theta = \arccos\left(\frac{\mathbf{v}\cdot\mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}\right). :label: eq_angle_forumla Hesaplamadaki hiçbir şey iki boyutluluğu referans almadığı için bu güzel bir sonuçtur. Aslında bunu üç veya üç milyon boyutta da sorunsuz olarak kullanabiliriz. Basit bir örnek olarak, bir çift vektör arasındaki açıyı nasıl hesaplayacağımızı görelim: .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from IPython import display from d2l import mxnet as d2l from mxnet import gluon, np, npx npx.set_np() def angle(v, w): return np.arccos(v.dot(w) / (np.linalg.norm(v) * np.linalg.norm(w))) angle(np.array([0, 1, 2]), np.array([2, 3, 4])) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array(0.41899002) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import torch import torchvision from IPython import display from torchvision import transforms from d2l import torch as d2l def angle(v, w): return torch.acos(v.dot(w) / (torch.norm(v) * torch.norm(w))) angle(torch.tensor([0, 1, 2], dtype=torch.float32), torch.tensor([2.0, 3, 4])) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor(0.4190) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from IPython import display import tensorflow as tf from d2l import tensorflow as d2l def angle(v, w): return tf.acos(tf.tensordot(v, w, axes=1) / (tf.norm(v) * tf.norm(w))) angle(tf.constant([0, 1, 2], dtype=tf.float32), tf.constant([2.0, 3, 4])) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Şu anda kullanmayacağız, ancak açılarının :math:`\pi/2` (veya eşdeğer olarak :math:`90^{\circ}`) olduğu vektörleri *dik* olarak isimlendireceğimizi bilmekte fayda var. Yukarıdaki denklemi inceleyerek, bunun :math:`\theta = \pi/2` olduğunda gerçekleştiğini görürüz, bu :math:`\cos(\theta) = 0` ile aynı şeydir. Bunun gerçekleşmesinin tek yolu, nokta çarpımın kendisinin sıfır olmasıdır ve ancak ve ancak :math:`\mathbf{v}\cdot\mathbf{w} = 0` ise iki vektör dik olur. Bu, nesneleri geometrik olarak anlarken faydalı bir formül olacaktır. Şu soruyu sormak mantıklıdır: Açıyı hesaplamak neden yararlıdır? Cevap, verinin sahip olmasını beklediğimiz türden değişmezlikten gelir. Bir imge ve her piksel değerinin aynı, ancak parlaklığın :math:`\% 10` olduğu kopya bir imge düşünün. Tek tek piksellerin değerleri genel olarak asıl değerlerden uzaktır. Bu nedenle, hakiki imge ile daha karanlık olan arasındaki mesafe hesaplanırsa, mesafe büyük olabilir. Gene de, çoğu makine öğrenmesi uygulaması için *içerik* aynıdır---kedi/köpek sınıflandırıcısı söz konusu olduğunda yine de bir kedinin imgesidir. Ancak, açıyı düşünürsek, herhangi bir :math:`\mathbf{v}` vektörü için :math:`\mathbf{v}` ve :math:`0.1\cdot\mathbf{v}` arasındaki açının sıfır olduğunu görmek zor değildir. Bu, ölçeklemenin vektörlerin yönlerini koruduğu ve sadece uzunluğu değiştirdiği gerçeğine karşılık gelir. Açı, koyu imgeyi aynı kabul edecektir. Buna benzer örnekler her yerdedir. Metinde, aynı şeyleri söyleyen iki kat daha uzun bir belge yazarsak tartışılan konunun değişmemesini isteyebiliriz. Bazı kodlamalar için (herhangi sözcük dağarcığındaki kelimelerin kaç kere geçtiğinin sayılması gibi), bu, belgeyi kodlayan vektörün ikiye çarpılmasına karşılık gelir ki, böylece yine açıyı kullanabiliriz. Kosinüs Benzerliği ~~~~~~~~~~~~~~~~~~ Açının iki vektörün yakınlığını ölçmek için kullanıldığı makine öğrenmesi bağlamlarında, uygulayıcılar benzerlik miktarını ifade etmek için *kosinüs benzerliği* terimini kullanırlar. .. math:: \cos(\theta) = \frac{\mathbf{v}\cdot\mathbf{w}}{\|\mathbf{v}\|\|\mathbf{w}\|}. İki vektör aynı yönü gösterdiğinde kosinüs maksimum :math:`1`, zıt yönleri gösterdiklerinde minimum :math:`-1` ve birbirlerine dik iseler :math:`0` değerini alır. Yüksek boyutlu vektörlerin bileşenleri ortalama :math:`0` ile rastgele örneklenirse, kosinüslerinin neredeyse her zaman :math:`0`'a yakın olacağını unutmayın. Hiperdüzlemler -------------- Vektörlerle çalışmaya ek olarak, doğrusal cebirde ileri gitmek için anlamanız gereken bir diğer önemli nesne olan *hiperdüzlem*, bir doğrunun (iki boyut) veya bir düzlemin (üç boyut) daha yüksek boyutlarına genellenmesidir. :math:`d` boyutlu bir vektör uzayında, bir hiperdüzlemin :math:`d-1` boyutu vardır ve uzayı iki yarı-uzaya böler. Bir örnekle başlayalım. Sütun vektörümüzün :math:`\mathbf{w}=[2,1]^\top` olduğunu varsayalım. ":math:`\mathbf{w}\cdot\mathbf{v} = 1` olan :math:`\mathbf{v}` noktaları nedir?", bilmek istiyoruz. Yukarıda :eq:`eq_angle_forumla` içindeki nokta çarpımları ile açılar arasındaki bağlantıyı hatırlayarak, bunun aşağıdaki denkleme eşdeğer olduğunu görebiliriz: .. math:: \|\mathbf{v}\|\|\mathbf{w}\|\cos(\theta) = 1 \; \iff \; \|\mathbf{v}\|\cos(\theta) = \frac{1}{\|\mathbf{w}\|} = \frac{1}{\sqrt{5}}. .. _fig_vector-project: .. figure:: ../img/proj-vec.svg Trigonometriyi anımsarsak, :math:`\|\mathbf{v}\|\cos(\theta)` formülünün :math:`\mathbf{v}` vektörünün :math:`\mathbf{w}` yönüne izdüşümünün uzunluğu olduğunu görürüz. Bu ifadenin geometrik anlamını düşünürsek, :numref:`fig_vector-project` içinde gösterildiği gibi, bunun :math:`\mathbf{v}`'nin :math:`\mathbf{w}` yönündeki izdüşümünün uzunluğunun tam olarak :math:`1/\|\mathbf{w}\|` olduğunu söylemeye eşdeğer olduğunu görürüz. Bunun doğru olduğu tüm noktalar kümesi, :math:`\mathbf{w}` vektörüne dik açıda olan bir doğrudur. İstersek, bu doğrunun denklemini bulabilir ve bunun :math:`2x + y = 1` veya eşdeğer olarak :math:`y = 1 - 2x` olduğunu görebiliriz. Şimdi :math:`\mathbf{w}\cdot\mathbf{v} > 1` veya :math:`\mathbf{w}\cdot\mathbf{v} < 1` ile nokta kümesini sorduğumuzda ne olduğuna bakarsak, bunların sırasıyla :math:`1/\|\mathbf{w}\|`'den daha uzun veya daha kısa izdüşümlerin (projeksiyon) olduğu durumlar olduğunu görebiliriz. Dolayısıyla, bu iki eşitsizlik çizginin her iki tarafını da tanımlar. Bu şekilde, :numref:`fig_space-division` içinde gördüğümüz gibi, uzayımızı iki yarıya bölmenin bir yolunu bulduk, öyleki bir taraftaki tüm noktaların nokta çarpımı bir eşiğin altında ve diğer tarafında ise yukarıdadır. .. _fig_space-division: .. figure:: ../img/space-division.svg Şimdi ifadenin eşitsizlik versiyonunu ele alırsak, hiperdüzlemimizin (bu durumda: sadece bir çizgi) uzayı iki yarıma ayırdığını görürüz. Daha yüksek boyuttaki hikaye hemen hemen aynıdır. Şimdi :math:`\mathbf{w} = [1,2,3]^\top` alırsak ve :math:`\mathbf{w}\cdot\mathbf{v} = 1` ile üç boyuttaki noktaları sorarsak, verilen :math:`\mathbf{w}` vektörüne dik açıda bir düzlem elde ederiz. İki eşitsizlik yine düzlemin iki tarafını şu şekilde, :numref:`fig_higher-division`, gösterildiği gibi tanımlar . .. _fig_higher-division: .. figure:: ../img/space-division-3d.svg Herhangi bir boyuttaki hiperdüzlemler, uzayı ikiye böler. Bu noktada görselleştirme yeteneğimiz tükenirken, bizi bunu onlarca, yüzlerce veya milyarlarca boyutta yapmaktan hiçbir şey alıkoyamaz. Bu genellikle makinenin öğrendiği modeller hakkında düşünürken ortaya çıkar. Örneğin :numref:`sec_softmax` içindeki gibi doğrusal sınıflandırma modellerini farklı hedef sınıfları ayıran hiperdüzlemleri bulma yöntemleri olarak anlayabiliriz. Bu bağlamda, bu tür hiperdüzlemlere genellikle *karar düzlemleri* adı verilir. Derin eğitilmiş sınıflandırma modellerinin çoğu, bir eşiksiz en büyük işleve (softmak) beslenen doğrusal bir katmanla sona erer, bu nedenle derin sinir ağının rolü, hedef sınıfların hiperdüzlemler tarafından temiz bir şekilde ayrılabileceği şekilde doğrusal olmayan bir gömme bulmak olarak yorumlanabilir. El yapımı bir örnek vermek gerekirse, Fashion MNIST veri kümesinden (:numref:`sec_fashion_mnist`) küçük tişört ve pantolon resimlerini sınıflandırmak için sadece ortalamalarını birleştiren bir vektör alıp karar düzlemini ve göz kararı kaba bir eşiği tanımlayarak makul bir model oluşturabileceğimize dikkat edin. İlk önce verileri yükleyeceğiz ve ortalamaları hesaplayacağız. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Veri kümesine yükle train = gluon.data.vision.FashionMNIST(train=True) test = gluon.data.vision.FashionMNIST(train=False) X_train_0 = np.stack([x[0] for x in train if x[1] == 0]).astype(float) X_train_1 = np.stack([x[0] for x in train if x[1] == 1]).astype(float) X_test = np.stack( [x[0] for x in test if x[1] == 0 or x[1] == 1]).astype(float) y_test = np.stack( [x[1] for x in test if x[1] == 0 or x[1] == 1]).astype(float) # Ortalamaları hesapla ave_0 = np.mean(X_train_0, axis=0) ave_1 = np.mean(X_train_1, axis=0) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Veri kümesine yükle trans = [] trans.append(transforms.ToTensor()) trans = transforms.Compose(trans) train = torchvision.datasets.FashionMNIST(root="../data", transform=trans, train=True, download=True) test = torchvision.datasets.FashionMNIST(root="../data", transform=trans, train=False, download=True) X_train_0 = torch.stack( [x[0] * 256 for x in train if x[1] == 0]).type(torch.float32) X_train_1 = torch.stack( [x[0] * 256 for x in train if x[1] == 1]).type(torch.float32) X_test = torch.stack( [x[0] * 256 for x in test if x[1] == 0 or x[1] == 1]).type(torch.float32) y_test = torch.stack([torch.tensor(x[1]) for x in test if x[1] == 0 or x[1] == 1]).type(torch.float32) # Ortalamaları hesapla ave_0 = torch.mean(X_train_0, axis=0) ave_1 = torch.mean(X_train_1, axis=0) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Veri kümesine yükle ((train_images, train_labels), ( test_images, test_labels)) = tf.keras.datasets.fashion_mnist.load_data() X_train_0 = tf.cast(tf.stack(train_images[[i for i, label in enumerate( train_labels) if label == 0]] * 256), dtype=tf.float32) X_train_1 = tf.cast(tf.stack(train_images[[i for i, label in enumerate( train_labels) if label == 1]] * 256), dtype=tf.float32) X_test = tf.cast(tf.stack(test_images[[i for i, label in enumerate( test_labels) if label == 0]] * 256), dtype=tf.float32) y_test = tf.cast(tf.stack(test_images[[i for i, label in enumerate( test_labels) if label == 1]] * 256), dtype=tf.float32) # Ortalamaları hesapla ave_0 = tf.reduce_mean(X_train_0, axis=0) ave_1 = tf.reduce_mean(X_train_1, axis=0) .. raw:: html
.. raw:: html
Bu ortalamaları ayrıntılı olarak incelemek bilgilendirici olabilir, bu yüzden neye benzediklerini çizelim. Bu durumda, ortalamanın gerçekten de bir tişörtün bulanık görüntüsüne benzediğini görüyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama tişörtü çizdir d2l.set_figsize() d2l.plt.imshow(ave_0.reshape(28, 28).tolist(), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_29_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama tişörtü çizdir d2l.set_figsize() d2l.plt.imshow(ave_0.reshape(28, 28).tolist(), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_32_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama tişörtü çizdir d2l.set_figsize() d2l.plt.imshow(tf.reshape(ave_0, (28, 28)), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_35_0.svg .. raw:: html
.. raw:: html
İkinci durumda, yine ortalamanın bulanık bir pantolon görüntüsüne benzediğini görüyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama pantolonu çizdir d2l.plt.imshow(ave_1.reshape(28, 28).tolist(), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_41_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama pantolonu çizdir d2l.plt.imshow(ave_1.reshape(28, 28).tolist(), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_44_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Ortalama pantolonu çizdir d2l.plt.imshow(tf.reshape(ave_1, (28, 28)), cmap='Greys') d2l.plt.show() .. figure:: output_geometry-linear-algebraic-ops_80b1c3_47_0.svg .. raw:: html
.. raw:: html
Tamamen makine öğrenmeli bir çözümde, eşiği veri kümesinden öğrenecektik. Bu durumda, el ile eğitim verilerinde iyi görünen bir eşiği göz kararı aldık. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Göz elde edilen eşiği ile test kümesi doğruluğunu yazdırın w = (ave_1 - ave_0).T predictions = X_test.reshape(2000, -1).dot(w.flatten()) > -1500000 # Doğruluk np.mean(predictions.astype(y_test.dtype) == y_test, dtype=np.float64) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array(0.801, dtype=float64) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Göz elde edilen eşiği ile test kümesi doğruluğunu yazdırın w = (ave_1 - ave_0).T # '@' is Matrix Multiplication operator in pytorch. predictions = X_test.reshape(2000, -1) @ (w.flatten()) > -1500000 # Doğruluk torch.mean((predictions.type(y_test.dtype) == y_test).float(), dtype=torch.float64) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output /tmp/ipykernel_5428/1764750836.py:2: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2985.) w = (ave_1 - ave_0).T .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor(0.7870, dtype=torch.float64) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Göz elde edilen eşiği ile test kümesi doğruluğunu yazdırın w = tf.transpose(ave_1 - ave_0) predictions = tf.reduce_sum(X_test * tf.nest.flatten(w), axis=0) > -1500000 # Doğruluk tf.reduce_mean( tf.cast(tf.cast(predictions, y_test.dtype) == y_test, tf.float32)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Doğrusal Dönüşümlerin Geometrisi -------------------------------- :numref:`sec_linear-algebra` ve yukarıdaki tartışmalar sayesinde, vektörlerin geometrisine, uzunluklara ve açılara dair sağlam bir anlayışa sahibiz. Bununla birlikte, tartışmayı atladığımız önemli bir nesne var ve bu, matrislerle temsil edilen doğrusal dönüşümlerin geometrik bir şekilde anlaşılmasıdır. Potansiyel olarak farklı yüksek boyutlu iki uzay arasında verileri dönüştürken matrislerin neler yapabileceğini tam olarak içselleştirmek, önemli bir uygulama gerektirir ve bu ek bölümün kapsamı dışındadır. Bununla birlikte, sezgimizi iki boyutta oluşturmaya başlayabiliriz. Bir matrisimiz olduğunu varsayalım: .. math:: \mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}. Bunu rastgele bir :math:`\mathbf{v} = [x, y]^\top` vektörüne uygulamak istersek, çarpar ve görürüz ki .. math:: \begin{aligned} \mathbf{A}\mathbf{v} & = \begin{bmatrix}a & b \\ c & d\end{bmatrix}\begin{bmatrix}x \\ y\end{bmatrix} \\ & = \begin{bmatrix}ax+by\\ cx+dy\end{bmatrix} \\ & = x\begin{bmatrix}a \\ c\end{bmatrix} + y\begin{bmatrix}b \\d\end{bmatrix} \\ & = x\left\{\mathbf{A}\begin{bmatrix}1\\0\end{bmatrix}\right\} + y\left\{\mathbf{A}\begin{bmatrix}0\\1\end{bmatrix}\right\}. \end{aligned} Bu, net bir şeyin bir şekilde anlaşılmaz hale geldiği garip bir hesaplama gibi görünebilir. Bununla birlikte, bize bir matrisin *herhangi* bir vektörü *iki belirli vektöre* göre nasıl dönüştürdüğünü yazabileceğimizi söyler: :math:`[1,0]^\top` and :math:`[0,1]^\top`. Bu bir an için düşünmeye değer. Esasen sonsuz bir problemi (herhangi bir gerçel sayı çiftine olanı) sonlu bir probleme (bu belirli vektörlere ne olduğuna) indirgedik. Bu vektörler, uzayımızdaki herhangi bir vektörü bu *taban vektörlerin* ağırlıklı toplamı olarak yazabileceğimiz örnek bir *taban*\ dır. Belli bir matrisi kullandığımızda ne olacağını çizelim .. math:: \mathbf{A} = \begin{bmatrix} 1 & 2 \\ -1 & 3 \end{bmatrix}. Belirli :math:`\mathbf{v} = [2, -1]^\top` vektörüne bakarsak, bunun :math:`2\cdot[1,0]^\top + -1\cdot[0,1]^\top` olduğunu görürüz, dolayısıyla :math:`A` matrisinin bunu :math:`2(\mathbf{A}[1,0]^\top) + -1(\mathbf{A}[0,1])^\top = 2[1, -1]^\top - [2,3]^\top = [0, -5]^\top`'e göndereceğini biliyoruz. Bu mantığı dikkatlice takip edersek, diyelim ki tüm tamsayı nokta çiftlerinin ızgarasını (grid) göz önünde bulundurarak, matris çarpımının ızgarayı eğriltebileceğini, döndürebileceğini ve ölçekleyebileceğini görürüz, ancak ızgara yapısı numref:\ ``fig_grid-transform`` içinde gördüğünüz gibi kalmalıdır. .. _fig_grid-transform: .. figure:: ../img/grid-transform.svg Verilen temel vektörlere göre hareket eden :math:`\mathbf {A}` matrisi. Tüm ızgaranın onunla birlikte nasıl taşındığına dikkat edin. Bu, matrisler tarafından temsil edilen doğrusal dönüşümler hakkında içselleştirilmesi gereken en önemli sezgisel noktadır. Matrisler, uzayın bazı bölümlerini diğerlerinden farklı şekilde bozma yeteneğine sahip değildir. Tüm yapabilecekleri, uzayımızdaki hakiki koordinatları almak ve onları eğriltmek, döndürmek ve ölçeklendirmektir. Bazı çarpıklıklar şiddetli olabilir. Örneğin matris .. math:: \mathbf{B} = \begin{bmatrix} 2 & -1 \\ 4 & -2 \end{bmatrix}, iki boyutlu düzlemin tamamını tek bir çizgiye sıkıştırır. Bu tür dönüşümleri tanımlamak ve bunlarla çalışmak daha sonraki bir bölümün konusudur, ancak geometrik olarak bunun yukarıda gördüğümüz dönüşüm türlerinden temelde farklı olduğunu görebiliriz. Örneğin, :math:`\mathbf{A}` matrisinden gelen sonuç, orijinal ızgaraya "geri eğilebilir". :math:`\mathbf{B}` matrisinden gelen sonuçlar olamaz çünkü :math:`[1,2]^\top` vektörünün nereden geldiğini asla bilemeyiz --- bu :math:`[1,1]^\top` veya :math:`[0,-1]^\top` mıydı? Bu resim :math:`2\times 2` matrisi için olsa da, hiçbir şey öğrenilen dersleri daha yüksek boyutlara taşımamızı engellemiyor. :math:`[1,0, \ldots,0]` gibi benzer taban vektörleri alırsak ve matrisimizin onları nereye gönderdiğini görürsek, matris çarpımının, uğraştığımız boyut uzayında tüm uzayı nasıl bozduğu hakkında bir fikir edinmeye başlayabiliriz. Doğrusal Bağımlılık ------------------- Matrisi tekrar düşünün .. math:: \mathbf{B} = \begin{bmatrix} 2 & -1 \\ 4 & -2 \end{bmatrix}. Bu, tüm düzlemi :math:`y = 2x` tek doğruda yaşaması için sıkıştırır. Şimdi şu soru ortaya çıkıyor: Bunu sadece matrise bakarak tespit etmemizin bir yolu var mı? Cevap, gerçekten edebiliriz. :math:`\mathbf{b}_1 = [2,4]^\top` ve :math:`\mathbf{b}_2 = [-1,-2]^\top`, :math:`\mathbf {B}`'nin iki sütunu olsun. :math:`\mathbf{B}` matrisi tarafından dönüştürülen her şeyi, matrisin sütunlarının ağırlıklı toplamı olarak yazabileceğimizi unutmayın: :math:`a_1\mathbf{b}_1 + a_2\mathbf{b}_2` gibi. Buna *doğrusal birleşim (kombinasyon)* diyoruz. :math:`\mathbf{b}_1 = -2\cdot\mathbf{b}_2` olması, bu iki sütunun herhangi bir doğrusal kombinasyonunu tamamen, mesela, :math:`\mathbf{b}_2` cinsinden yazabileceğimiz anlamına gelir, çünkü .. math:: a_1\mathbf{b}_1 + a_2\mathbf{b}_2 = -2a_1\mathbf{b}_2 + a_2\mathbf{b}_2 = (a_2-2a_1)\mathbf{b}_2. Bu, sütunlardan birinin uzayda tek bir yön tanımlamadığından bir bakıma gereksiz olduğu anlamına gelir. Bu matrisin tüm düzlemi tek bir çizgiye indirdiğini gördüğümüz için bu bizi çok şaşırtmamalı. Dahası, :math:`\mathbf{b}_1 = -2\cdot\mathbf{b}_2` doğrusal bağımlılığının bunu yakaladığını görüyoruz. Bunu iki vektör arasında daha simetrik hale getirmek için şöyle yazacağız: .. math:: \mathbf{b}_1 + 2\cdot\mathbf{b}_2 = 0. Genel olarak, eğer aşağıdaki denklem için *hepsi sıfıra eşit olmayan* :math:`a_1, \ldots, a_k` katsayıları varsa, bir :math:`\mathbf{v}_1, \ldots, \mathbf{v}_k` vektörler topluluğunun *doğrusal olarak bağımlı* olduğunu söyleyeceğiz: .. math:: \sum_{i=1}^k a_i\mathbf{v_i} = 0. Bu durumda, vektörlerden birini diğerlerinin birtakım birleşimi olarak çözebilir ve onu etkili bir şekilde gereksiz hale getirebiliriz. Bu nedenle, bir matrisin sütunlarındaki doğrusal bir bağımlılık, matrisimizin uzayı daha düşük bir boyuta sıkıştırdığına bir kanıttır. Doğrusal bağımlılık yoksa, vektörlerin *doğrusal olarak bağımsız* olduğunu söyleriz. Bir matrisin sütunları doğrusal olarak bağımsızsa, sıkıştırma gerçekleşmez ve işlem geri alınabilir. Kerte (Rank) ------------ Genel bir :math:`n\times m` matrisimiz varsa, matrisin hangi boyut uzayına eşlendiğini sormak mantıklıdır. Cevabımız *kerte* olarak bilinen bir kavram olacaktır. Önceki bölümde, doğrusal bir bağımlılığın uzayın daha düşük bir boyuta sıkıştırılmasına tanıklık ettiğini ve bu nedenle bunu kerte kavramını tanımlamak için kullanabileceğimizi ifade ettik. Özellikle, bir :math:`\mathbf{A}` matrisinin kertesi, sütunların tüm alt kümeleri arasındaki doğrusal bağımsız en büyük sütun sayısıdır. Örneğin, matris .. math:: \mathbf{B} = \begin{bmatrix} 2 & 4 \\ -1 & -2 \end{bmatrix}, :math:`\mathrm{kerte}(B) = 1`'e sahiptir, çünkü iki sütunu doğrusal olarak bağımlıdır, ancak iki sütun da kendi başına doğrusal olarak bağımlı değildir. Daha zorlu bir örnek için, .. math:: \mathbf{C} = \begin{bmatrix} 1& 3 & 0 & -1 & 0 \\ -1 & 0 & 1 & 1 & -1 \\ 0 & 3 & 1 & 0 & -1 \\ 2 & 3 & -1 & -2 & 1 \end{bmatrix}, ve :math:`\mathbf{C}`'nin kertesinin iki olduğunu gösterebiliriz, çünkü örneğin ilk iki sütun doğrusal olarak bağımsızdır, ancak herhangi bir dört sütunlu toplulukta üç sütun bağımlıdır. Bu prosedür, açıklandığı gibi, çok verimsizdir. Verdiğimiz matrisin sütunlarının her alt kümesine bakmayı gerektirir ve bu nedenle sütun sayısına bağlı, potansiyel olarak üsteldir. Daha sonra bir matrisin kertesini hesaplamanın hesaplama açısından daha verimli bir yolunu göreceğiz, ancak şimdilik, kavramın iyi tanımlandığını görmek ve anlamı anlamak yeterlidir. Tersinirlik (Invertibility) --------------------------- Yukarıda doğrusal olarak bağımlı sütunları olan bir matris ile çarpmanın geri alınamayacağını gördük, yani girdiyi her zaman kurtarabilecek ters işlem yoktur. Bununla birlikte, tam kerteli bir matrisle çarpma durumunda (yani, :math:`\mathbf{A}`, :math:`n\times n`'lik :math:`n` kerteli matristir), bunu her zaman geri alabilmeliyiz. Şu matrisi düşünün: .. math:: \mathbf{I} = \begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 \end{bmatrix}. Bu, köşegen boyunca birlerin ve başka yerlerde sıfırların bulunduğu matristir. Buna *birim* matris diyoruz. Uygulandığında verilerimizi değiştirmeden bırakan matristir. :math:`\mathbf{A}` matrisimizin yaptıklarını geri alan bir matris bulmak için, şu şekilde bir :math:`\mathbf{A}^{-1}` matrisi bulmak istiyoruz: .. math:: \mathbf{A}^{-1}\mathbf{A} = \mathbf{A}\mathbf{A}^{-1} = \mathbf{I}. Buna bir sistem olarak bakarsak, :math:`n\times n` bilinmeyenli (:math:`\mathbf{A}^{-1}`'nin girdileri) ve :math:`n\times n` denklemimiz var (:math:`\mathbf{A}^{-1}\mathbf{A}` çarpımının her girdisi ve :math:`\mathbf{I}`'nin her girdisi arasında uyulması gereken eşitlik), bu nedenle genel olarak bir çözümün var olmasını beklemeliyiz. Nitekim bir sonraki bölümde sıfır olmadığı sürece çözüm bulabileceğimizi gösterme özelliğine sahip olan *determinant* adlı bir miktar göreceğiz. Böyle bir :math:`\mathbf{A}^{-1}` matrise, *ters* matris diyoruz. Örnek olarak, eğer :math:`\mathbf{A}` genel bir :math:`2\times 2` matris ise .. math:: \mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, o zaman tersinin şöyle olduğunu görebiliriz: .. math:: \frac{1}{ad-bc} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}. Yukarıdaki formülün verdiği ters ile çarpmanın pratikte işe yaradığını görmek için test edebiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python M = np.array([[1, 2], [1, 4]]) M_inv = np.array([[2, -1], [-0.5, 0.5]]) M_inv.dot(M) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[1., 0.], [0., 1.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python M = torch.tensor([[1, 2], [1, 4]], dtype=torch.float32) M_inv = torch.tensor([[2, -1], [-0.5, 0.5]]) M_inv @ M .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[1., 0.], [0., 1.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python M = tf.constant([[1, 2], [1, 4]], dtype=tf.float32) M_inv = tf.constant([[2, -1], [-0.5, 0.5]]) tf.matmul(M_inv, M) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Sayısal (Numerik) Sorunlar ~~~~~~~~~~~~~~~~~~~~~~~~~~ Bir matrisin tersi teoride yararlı olsa da, pratikte bir problemi çözmek için çoğu zaman matris tersini *kullanmak* istemediğimizi söylemeliyiz. Genel olarak, .. math:: \mathbf{A}\mathbf{x} = \mathbf{b}, gibi doğrusal denklemleri çözmek için sayısal olarak çok daha kararlı algoritmalar vardır, aşağıdaki gibi tersini hesaplamaktan ve çarpmaktan daha çok tercih edebileceğimiz yöntemlerdir. .. math:: \mathbf{x} = \mathbf{A}^{-1}\mathbf{b}. Küçük bir sayıya bölünmenin sayısal kararsızlığa yol açması gibi, düşük kerteye olmaya yakın bir matrisin ters çevrilmesi de kararsızlığa neden olabilir. Dahası, :math:`\mathbf{A}` matrisinin *seyrek* olması yaygındır, yani sadece az sayıda sıfır olmayan değer içerir. Örnekleri araştıracak olsaydık, bunun tersin de seyrek olduğu anlamına gelmediğini görürdük. :math:`\mathbf{A}`, yalnızca :math:`5` milyon tanesi sıfır olmayan girdileri olan :math:`1` milyona :math:`1` milyonluk bir matris olsa bile (ve bu nedenle yalnızca bu :math:`5` milyon girdiyi saklamamız gerekir), tersi genellikle hemen hemen hepsi eksi değer olmayan tüm girdilere sahip olacaktır ki tüm :math:`1\text{M}^2` girdiyi saklamamızı gerektirir --- bu da :math:`1` trilyon girdidir! Doğrusal cebir ile çalışırken sıkça karşılaşılan çetrefilli sayısal sorunlara tam olarak dalacak vaktimiz olmasa da, ne zaman dikkatli bir şekilde ilerlemeniz gerektiği konusunda size biraz önsezi sağlamak istiyoruz ve pratikte genellikle ters çevirmekten kaçınmak yararlı bir kuraldır. Determinant ----------- Doğrusal cebirin geometrik görünümü, *determinant* olarak bilinen temel bir miktarı yorumlamanın sezgisel bir yolunu sunar. Önceki ızgara görüntüsünü, ama şimdi vurgulanmış bölgeyle (:numref:`fig_grid-filled`) düşünün. .. _fig_grid-filled: .. figure:: ../img/grid-transform-filled.svg :math:`\mathbf{A}` matrisi yine ızgarayı bozuyor. Bu sefer, vurgulanan kareye ne olduğuna özellikle dikkat çekmek istiyoruz. Vurgulanan kareye bakın. Bu, kenarları :math:`(0,1)` ve :math:`(1,0)` ile verilen bir karedir ve dolayısıyla bir birim alana sahiptir. :math:`\mathbf{A}` bu kareyi dönüştürdükten sonra, bunun bir paralelkenar olduğunu görürüz. Bu paralelkenarın başladığımızdaki aynı alana sahip olması için hiçbir neden yok ve aslında burada gösterilen özel durumda aşağıdaki matristir. .. math:: \mathbf{A} = \begin{bmatrix} 1 & 2 \\ -1 & 3 \end{bmatrix}, Bu paralelkenarın alanını hesaplamak ve alanın :math:`5` olduğunu elde etmek koordinat geometrisinde bir alıştırmadır. Genel olarak, bir matrisimiz varsa, .. math:: \mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, biraz hesaplamayla elde edilen paralelkenarın alanının :math:`ad-bc` olduğunu görebiliriz. Bu alan, *determinant* olarak adlandırılır. Bunu bazı örnek kodlarla hızlıca kontrol edelim. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import numpy as np np.linalg.det(np.array([[1, -1], [2, 3]])) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 5.000000000000001 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python torch.det(torch.tensor([[1, -1], [2, 3]], dtype=torch.float32)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor(5.) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.linalg.det(tf.constant([[1, -1], [2, 3]], dtype=tf.float32)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Aramızdaki kartal gözlüler, bu ifadenin sıfır, hatta negatif olabileceğini fark edecek. Negatif terim için, bu genel olarak matematikte ele alınan bir ifade meselesidir: Eğer matris şekli ters çevirirse, alanın aksine çevrildiğini söyleriz. Şimdi determinant sıfır olduğunda daha fazlasını öğreneceğimizi görelim. Bir düşünelim. .. math:: \mathbf{B} = \begin{bmatrix} 2 & 4 \\ -1 & -2 \end{bmatrix}. Bu matrisin determinantını hesaplarsak, :math:`2\cdot(-2) - 4\cdot(-1) = 0` elde ederiz. Yukarıdaki anlayışımıza göre, bu mantıklı. :math:`\mathbf{B}`, orijinal görüntüdeki kareyi sıfır alana sahip bir çizgi parçasına sıkıştırır. Ve aslında, dönüşümden sonra sıfır alana sahip olmanın tek yolu, daha düşük boyutlu bir alana sıkıştırılmaktır. Böylece, aşağıdaki sonucun doğru olduğunu görüyoruz: Bir :math:`A` matrisinin, ancak ve ancak determinantı sıfıra eşit değilse tersi hesaplanabilir. Son bir yorum olarak, düzlemde herhangi bir figürün çizildiğini hayal edin. Bilgisayar bilimcileri gibi düşünürsek, bu şekli küçük kareler toplamına ayırabiliriz, böylece şeklin alanı özünde sadece ayrıştırmadaki karelerin sayısı olur. Şimdi bu rakamı bir matrisle dönüştürürsek, bu karelerin her birini, determinant tarafından verilen alana sahip olan paralelkenarlara göndeririz. Herhangi bir şekil için determinantın, bir matrisin herhangi bir şeklin alanını ölçeklendirdiği (işaretli) sayıyı verdiğini görüyoruz. Daha büyük matrisler için belirleyicilerin hesaplanması zahmetli olabilir, ancak sezgi aynıdır. Determinant, :math:`n\times n` matrislerin :math:`n`-boyutlu hacimlerini ölçeklendiren faktör olarak kalır. Tensörler ve Genel Doğrusal Cebir İşlemleri ------------------------------------------- :numref:`sec_linear-algebra`'de tensör kavramı tanıtıldı. Bu bölümde, tensör daralmalarına (büzülmesine) (matris çarpımının tensör eşdeğeri) daha derinlemesine dalacağız ve bir dizi matris ve vektör işlemi üzerinde nasıl birleşik bir görünüm sağlayabileceğini göreceğiz. Matrisler ve vektörlerle, verileri dönüştürmek için onları nasıl çarpacağımızı biliyorduk. Bize yararlı olacaksa, tensörler için de benzer bir tanıma ihtiyacımız var. Matris çarpımını düşünün: .. math:: \mathbf{C} = \mathbf{A}\mathbf{B}, Veya eşdeğer olarak .. math:: c_{i, j} = \sum_{k} a_{i, k}b_{k, j}. Bu model tensörler için tekrar edebileceğimiz bir modeldir. Tensörler için, neyin toplanacağına dair evrensel olarak seçilebilecek tek bir durum yoktur, bu yüzden tam olarak hangi indeksleri toplamak istediğimizi belirlememiz gerekir. Örneğin düşünün, .. math:: y_{il} = \sum_{jk} x_{ijkl}a_{jk}. Böyle bir dönüşüme *tensör daralması* denir. Tek başına matris çarpımının olduğundan çok daha esnek bir dönüşüm ailesini temsil edebilir. Sık kullanılan bir gösterimsel sadeleştirme olarak, toplamın ifadede birden fazla kez yer alan indislerin üzerinde olduğunu fark edebiliriz, bu nedenle insanlar genellikle, toplamın örtülü olarak tüm tekrarlanan indisler üzerinden alındığı *Einstein gösterimi* ile çalışır. Bu aşağıdaki kompakt ifadeyi verir: .. math:: y_{il} = x_{ijkl}a_{jk}. Doğrusal Cebirden Yaygın Örnekler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Daha önce gördüğümüz doğrusal cebirsel tanımların kaçının bu sıkıştırılmış tensör gösteriminde ifade edilebileceğini görelim: - :math:`\mathbf{v} \cdot \mathbf{w} = \sum_i v_iw_i` - :math:`\|\mathbf{v}\|_2^{2} = \sum_i v_iv_i` - :math:`(\mathbf{A}\mathbf{v})_i = \sum_j a_{ij}v_j` - :math:`(\mathbf{A}\mathbf{B})_{ik} = \sum_j a_{ij}b_{jk}` - :math:`\mathrm{tr}(\mathbf{A}) = \sum_i a_{ii}` Bu şekilde, çok sayıda özel gösterimi kısa tensör ifadeleriyle değiştirebiliriz. Kodla İfade Etme ~~~~~~~~~~~~~~~~ Tensörler de kod içinde esnek bir şekilde çalıştırılabilir. :numref:`sec_linear-algebra` içinde görüldüğü gibi, aşağıda gösterildiği gibi tensörler oluşturabiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Tensörleri tanımla B = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) A = np.array([[1, 2], [3, 4]]) v = np.array([1, 2]) # Şekilleri yazdır A.shape, B.shape, v.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output ((2, 2), (2, 2, 3), (2,)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Tensörleri tanımla B = torch.tensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) A = torch.tensor([[1, 2], [3, 4]]) v = torch.tensor([1, 2]) # Şekilleri yazdır A.shape, B.shape, v.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (torch.Size([2, 2]), torch.Size([2, 2, 3]), torch.Size([2])) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Tensörleri tanımla B = tf.constant([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) A = tf.constant([[1, 2], [3, 4]]) v = tf.constant([1, 2]) # Şekilleri yazdır A.shape, B.shape, v.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (TensorShape([2, 2]), TensorShape([2, 2, 3]), TensorShape([2])) .. raw:: html
.. raw:: html
Einstein toplamı doğrudan uygulanır. Einstein toplamında ortaya çıkan indisler bir dizi olarak aktarılabilir ve ardından işlem yapılan tensörler eklenebilir. Örneğin, matris çarpımını uygulamak için, yukarıda görülen Einstein toplamını (:math:`\mathbf{A}\mathbf{v} = a_{ij}v_j`) düşünebilir ve uygulamayı (gerçeklemeyi) elde etmek için indisleri söküp atabiliriz: .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Matris çarpımını yeniden uygula np.einsum("ij, j -> i", A, v), A.dot(v) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (array([ 5, 11]), array([ 5, 11])) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Matris çarpımını yeniden uygula torch.einsum("ij, j -> i", A, v), A@v .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (tensor([ 5, 11]), tensor([ 5, 11])) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Matris çarpımını yeniden uygula tf.einsum("ij, j -> i", A, v), tf.matmul(A, tf.reshape(v, (2, 1))) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (, ) .. raw:: html
.. raw:: html
Bu oldukça esnek bir gösterimdir. Örneğin, geleneksel olarak şu şekilde yazılanı hesaplamak istiyorsak, .. math:: c_{kl} = \sum_{ij} \mathbf{b}_{ijk}\mathbf{a}_{il}v_j. Einstein toplamı aracılığıyla şu şekilde uygulanabilir: .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.einsum("ijk, il, j -> kl", B, A, v) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 90, 126], [102, 144], [114, 162]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python torch.einsum("ijk, il, j -> kl", B, A, v) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 90, 126], [102, 144], [114, 162]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.einsum("ijk, il, j -> kl", B, A, v) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Bu gösterim insanlar için okunabilir ve etkilidir, ancak herhangi bir nedenle programlı olarak bir tensör daralması üretmeniz gerekirse hantaldır. Bu nedenle ``einsum``, her tensör için tamsayı indisleri sağlayarak alternatif bir gösterim sağlar. Örneğin, aynı tensör daralması şu şekilde de yazılabilir: .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.einsum(B, [0, 1, 2], A, [0, 3], v, [1], [2, 3]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 90, 126], [102, 144], [114, 162]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # PyTorch bu tür gösterimi desteklemez. .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # TensorFlow bu tür gösterimi desteklemez. .. raw:: html
.. raw:: html
Her iki gösterim, tensör daralmalarının kodda kısa ve verimli bir şekilde temsiline izin verir. Özet ---- - Vektörler, uzayda geometrik olarak noktalar veya yönler olarak yorumlanabilir. - Nokta çarpımları, keyfi olarak yüksek boyutlu uzaylar için açı kavramını tanımlar. - Hiperdüzlemler, doğruların ve düzlemlerin yüksek boyutlu genellemeleridir. Genellikle bir sınıflandırma görevinde son adım olarak kullanılan karar düzlemlerini tanımlamak için kullanılabilirler. - Matris çarpımı, geometrik olarak, temel koordinatların tekdüze bozulmaları olarak yorumlanabilir. Vektörleri dönüştürmenin çok kısıtlı, ancak matematiksel olarak temiz bir yolunu temsil ederler. - Doğrusal bağımlılık, bir vektör topluluğunun beklediğimizden daha düşük boyutlu bir uzayda olduğunu anlamanın bir yoludur (diyelim ki :math:`2` boyutunda bir uzayda yaşayan :math:`3` vektörünüz var). Bir matrisin kertesi, doğrusal olarak bağımsız olan sütunlarının en büyük alt kümesinin ebadıdır. - Bir matrisin tersi tanımlandığında, matris tersi bulma, ilkinin eylemini geri alan başka bir matris bulmamızı sağlar. Matris tersi bulma teoride faydalıdır, ancak sayısal kararsızlık nedeniyle pratikte dikkat gerektirir. - Determinantlar, bir matrisin bir alanı ne kadar genişlettiğini veya daralttığını ölçmemizi sağlar. Sıfır olmayan bir determinant, tersinir (tekil olmayan) bir matris anlamına gelir ve sıfır değerli bir determinant, matrisin tersinemez (tekil) olduğu anlamına gelir. - Tensör daralmaları ve Einstein toplamı, makine öğrenmesinde görülen hesaplamaların çoğunu ifade etmek için düzgün ve temiz bir gösterim sağlar. Alıştırmalar ------------ 1. Aralarındaki açı nedir? .. math:: \vec v_1 = \begin{bmatrix} 1 \\ 0 \\ -1 \\ 2 \end{bmatrix}, \qquad \vec v_2 = \begin{bmatrix} 3 \\ 1 \\ 0 \\ 1 \end{bmatrix} 2. Doğru veya yanlış: :math:`\begin{bmatrix}1 & 2\\0&1\end{bmatrix}` ve :math:`\begin{bmatrix}1 & -2\\0&1\end{bmatrix}` birbirinin tersi mi? 3. Düzlemde :math:`100\mathrm{m}^2` alanına sahip bir şekil çizdiğimizi varsayalım. Şeklin aşağıdaki matrise göre dönüştürüldükten sonraki alanı nedir? .. math:: \begin{bmatrix} 2 & 3\\ 1 & 2 \end{bmatrix}. 4. Aşağıdaki vektör kümelerinden hangisi doğrusal olarak bağımsızdır? - :math:`\left\{\begin{pmatrix}1\\0\\-1\end{pmatrix}, \begin{pmatrix}2\\1\\-1\end{pmatrix}, \begin{pmatrix}3\\1\\1\end{pmatrix}\right\}` - :math:`\left\{\begin{pmatrix}3\\1\\1\end{pmatrix}, \begin{pmatrix}1\\1\\1\end{pmatrix}, \begin{pmatrix}0\\0\\0\end{pmatrix}\right\}` - :math:`\left\{\begin{pmatrix}1\\1\\0\end{pmatrix}, \begin{pmatrix}0\\1\\-1\end{pmatrix}, \begin{pmatrix}1\\0\\1\end{pmatrix}\right\}` 5. Bazı :math:`a , b, c` ve :math:`d` değerleri için :math:`A = \begin{bmatrix}c\\d\end{bmatrix}\cdot\begin{bmatrix}a & b\end{bmatrix}` olarak yazılmış bir matrisiniz olduğunu varsayalım . Doğru mu yanlış mı: Böyle bir matrisin determinantı her zaman :math:`0`'dır? 6. :math:`e_1 = \begin{bmatrix}1\\0\end{bmatrix}` ve :math:`e_2 = \begin{bmatrix}0\\1\end{bmatrix}` vektörleri diktir. :math:`Ae_1` ve :math:`Ae_2`'nin dik olması için :math:`A` matrisindeki koşul nedir? 7. Rasgele bir :math:`A` matrisi için Einstein gösterimi ile :math:`\mathrm{tr}(\mathbf{A}^4)`'u nasıl yazabilirsiniz? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html