.. _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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. 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
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html