.. _sec_linear-algebra:
Doğrusal Cebir
==============
Şimdi verileri saklayabileceğinize ve oynama yapabileceğinize göre, bu
kitapta yer alan modellerin çoğunu anlamanız ve uygulamanızda gereken
temel doğrusal cebir bilgilerini kısaca gözden geçirelim. Aşağıda,
doğrusal cebirdeki temel matematiksel nesneleri, aritmetiği ve işlemleri
tanıtarak, bunların her birini matematiksel gösterim ve koddaki ilgili
uygulama ile ifade ediyoruz.
Sayıllar
--------
Doğrusal cebir veya makine öğrenmesi üzerine hiç çalışmadıysanız,
matematikle ilgili geçmiş deneyiminiz muhtemelen bir seferde bir sayı
düşünmekten ibaretti. Ayrıca, bir çek defterini dengelediyseniz veya
hatta bir restoranda akşam yemeği için ödeme yaptıysanız, bir çift
sayıyı toplama ve çarpma gibi temel şeyleri nasıl yapacağınızı zaten
biliyorsunuzdur. Örneğin, Palo Alto'daki sıcaklık :math:`52` Fahrenheit
derecedir. Usul olarak, sadece bir sayısal miktar içeren değerlere
*sayıl (skaler)* diyoruz. Bu değeri Celsius'a (metrik sistemin daha
anlamlı sıcaklık ölçeği) dönüştürmek istiyorsanız, :math:`f`'i
:math:`52` olarak kurup :math:`c = \frac{5}{9}(f - 32)` ifadesini
hesaplarsınız. Bu denklemde ---:math:`5`, :math:`9` ve :math:`32`---
terimlerinin her biri skaler değerlerdir. :math:`c` ve :math:`f`
göstermelik ifadelerine (placeholders) *değişkenler* denir ve bilinmeyen
skaler değerleri temsil ederler.
Bu kitapta, skaler değişkenlerin normal küçük harflerle (ör. :math:`x`,
:math:`y` ve :math:`z`) gösterildiği matematiksel gösterimi kabul
ediyoruz. Tüm (sürekli) *gerçel değerli* skalerlerin alanını
:math:`\mathbb{R}` ile belirtiyoruz. Amaca uygun olarak, tam olarak
*uzayın* ne olduğunu titizlikle tanımlayacağız, ancak şimdilik sadece
:math:`x \in \mathbb{R}` ifadesinin :math:`x` değerinin gerçel değerli
olduğunu söylemenin usula uygun bir yolu olduğunu unutmayın. :math:`\in`
sembolü "içinde" olarak telaffuz edilebilir ve sadece bir kümeye üyeliği
belirtir. Benzer şekilde, :math:`x` ve :math:`y`'nin değerlerinin
yalnızca :math:`0` veya :math:`1` olabilen rakamlar olduğunu belirtmek
için :math:`x, y \in \{0, 1 \}` yazabiliriz.
Skaler, sadece bir elemente sahip bir tensör ile temsil edilir. Sıradaki
kod parçasında, iki skalere değer atıyoruz ve onlarla toplama, çarpma,
bölme ve üs alma gibi bazı tanıdık aritmetik işlemleri
gerçekleştiriyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
from mxnet import np, npx
npx.set_np()
x = np.array(3.0)
y = np.array(2.0)
x + y, x * y, x / y, x ** y
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array(5.), array(6.), array(1.5), array(9.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import torch
x = torch.tensor(3.0)
y = torch.tensor(2.0)
x + y, x * y, x / y, x**y
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor(5.), tensor(6.), tensor(1.5000), tensor(9.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
import tensorflow as tf
x = tf.constant(3.0)
y = tf.constant(2.0)
x + y, x * y, x / y, x**y
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
,
,
)
.. raw:: html
.. raw:: html
Vektörler (Yöneyler)
--------------------
Bir vektörü basitçe skaler değerlerin bir listesi olarak
düşünebilirsiniz. Bu değerlere vektörün *elemanları* (*giriş değerleri*
veya *bileşenleri*) diyoruz. Vektörlerimiz veri kümemizdeki örnekleri
temsil ettiğinde, değerleri gerçek dünyadaki önemini korur. Örneğin, bir
kredinin temerrüde düşme (ödenmeme) riskini tahmin etmek için bir model
geliştiriyorsak, her başvuru sahibini, gelirine, istihdam süresine,
önceki temerrüt sayısına ve diğer faktörlere karşılık gelen bileşenleri
olan bir vektörle ilişkilendirebiliriz. Hastanedeki hastaların
potansiyel olarak yaşayabilecekleri kalp krizi riskini araştırıyor
olsaydık, her hastayı bileşenleri en güncel hayati belirtilerini,
kolesterol seviyelerini, günlük egzersiz dakikalarını vb. içeren bir
vektörle temsil edebilirdik. Matematiksel gösterimlerde, genellikle
vektörleri kalın, küçük harfler (örneğin, :math:`\mathbf{x}`,
:math:`\mathbf{y}` ve :math:`\mathbf{z})` olarak göstereceğiz.
Vektörlerle tek boyutlu tensörler aracılığıyla çalışırız. Genelde
tensörler, makinenizin bellek sınırlarına tabi olarak keyfi uzunluklara
sahip olabilir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = np.arange(4)
x
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([0., 1., 2., 3.])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = torch.arange(4)
x
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([0, 1, 2, 3])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = tf.range(4)
x
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Bir vektörün herhangi bir öğesini bir altindis kullanarak
tanımlayabiliriz. Örneğin, :math:`\mathbf{x}`'in :math:`i.` elemanını
:math:`x_i` ile ifade edebiliriz. :math:`x_i` öğesinin bir skaler
olduğuna dikkat edin, bu nedenle ondan bahsederken fontta kalın yazı
tipi kullanmıyoruz. Genel literatür sütun vektörlerini vektörlerin
varsayılan yönü olarak kabul eder, bu kitap da öyle kabullenir.
Matematikte, :math:`\mathbf{x}` vektörü şu şekilde yazılabilir:
.. math:: \mathbf{x} =\begin{bmatrix}x_{1} \\x_{2} \\ \vdots \\x_{n}\end{bmatrix},
:label: eq_vec_def
burada :math:`x_1, \ldots, x_n` vektörün elemanlarıdır. Kod olarak,
herhangi bir öğeye onu tensöre indeksleyerek erişiriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x[3]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(3.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x[3]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(3)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x[3]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Uzunluk, Boyutluluk ve Şekil
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bazı kavramları tekrar gözden geçirelim :numref:`sec_ndarray`. Bir
vektör sadece bir sayı dizisidir. Ayrıca her dizinin bir uzunluğu olduğu
gibi, her vektör de bir uzunluğa sahiptir. Matematiksel gösterimde,
:math:`\mathbf{x}` vektörünün :math:`n` gerçel değerli skalerlerden
oluştuğunu söylemek istiyorsak, bunu :math:`\mathbf{x} \in \mathbb{R}^n`
olarak ifade edebiliriz. Bir vektörün uzunluğuna genel olarak vektörün
*boyutu* denir.
Sıradan bir Python dizisinde olduğu gibi, Python'un yerleşik (built-in)
``len()`` işlevini çağırarak bir tensörün uzunluğuna erişebiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
len(x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
4
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
len(x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
4
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
len(x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
4
.. raw:: html
.. raw:: html
Bir tensör bir vektörü (tam olarak bir ekseni ile) temsil ettiğinde,
uzunluğuna ``.shape`` özelliği ile de erişebiliriz. Şekil, tensörün her
ekseni boyunca uzunluğu (boyutsallığı) listeleyen bir gruptur. Sadece
bir ekseni olan tensörler için, şeklin sadece bir elemanı vardır.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(4,)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
torch.Size([4])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
TensorShape([4])
.. raw:: html
.. raw:: html
"Boyut" kelimesinin bu bağlamlarda aşırı yüklenme eğiliminde olduğunu ve
bunun da insanları şaşırtma yöneliminde olduğunu unutmayın. Açıklığa
kavuşturmak için, bir *vektörün* veya *ekseninin* boyutluluğunu onun
uzunluğuna atıfta bulunmak için kullanırız; yani bir vektörün veya
eksenin eleman sayısı. Halbuki, bir tensörün boyutluluğunu, bir tensörün
sahip olduğu eksen sayısını ifade etmek için kullanırız. Bu anlamda, bir
tensörün bazı eksenlerinin boyutluluğu, bu eksenin uzunluğu olacaktır.
Matrisler
---------
Vektörler, skalerleri sıfırdan birinci dereceye kadar genelleştirirken,
matrisler de vektörleri birinci dereceden ikinci dereceye genelleştirir.
Genellikle kalın, büyük harflerle (örn., :math:`\mathbf{X}`,
:math:`\mathbf{Y}`, and :math:`\mathbf{Z}`) göstereceğimiz matrisler,
kodda iki eksenli tensörler olarak temsil edilir.
Matematiksel gösterimde, :math:`\mathbf{A}` matrisinin gerçel değerli
skaler :math:`m` satır ve :math:`n` sütundan oluştuğunu ifade etmek için
:math:`\mathbf{A} \in \mathbb{R}^{m \times n}`'i kullanırız. Görsel
olarak, herhangi bir :math:`\mathbf{A} \in \mathbb{R}^{m \times n}`
matrisini :math:`a_{ij}` öğesinin :math:`i.` satıra ve :math:`j.` sütuna
ait olduğu bir tablo olarak gösterebiliriz:
.. math:: \mathbf{A}=\begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \\ \end{bmatrix}.
:label: eq_matrix_def
Herhangi bir :math:`\mathbf{A}\in \mathbb{R}^{m\times n}` için,
:math:`\mathbf{A}` (:math:`m`, :math:`n`) veya :math:`m\times n`
şeklindedir. Özellikle, bir matris aynı sayıda satır ve sütuna sahip
olduğunda, şekli bir kareye dönüşür; dolayısıyla buna *kare matris*
denir.
Bir tensörü örneği yaratırken, en sevdiğimiz işlevlerden herhangi birini
çağırıp :math:`m` ve :math:`n` iki bileşeninden oluşan bir şekil
belirterek :math:`m \times n` matrisi oluşturabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = np.arange(20).reshape(5, 4)
A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = torch.arange(20).reshape(5, 4)
A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = tf.reshape(tf.range(20), (5, 4))
A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Satır (:math:`i`) ve sütun (:math:`j`) indekslerini belirterek
:math:`\mathbf{A}` matrisinin :math:`a_{ij}` skaler öğesine
erişebiliriz, :math:`[\mathbf{A}]_{ij}` gibi. Bir :math:`\mathbf{A}`
matrisinin skaler elemanları verilmediğinde, örneğin
:eq:`eq_matrix_def` gibi, basitçe :math:`\mathbf{A}` matrisinin
küçük harfli altindislisi :math:`a_{ij}`'yi kullanarak
:math:`[\mathbf{A}]_{ij}`'ye atıfta bulunuruz. Gösterimi basit tutarken
indeksleri ayırmak için virgüller yalnızca gerekli olduğunda eklenir,
örneğin :math:`a_{2, 3j}` ve :math:`[\mathbf{A}]_{2i-1, 3}` gibi.
Bazen eksenleri ters çevirmek isteriz. Bir matrisin satırlarını ve
sütunlarını değiştirdiğimizde çıkan sonuç matrisine *devrik (transpose)*
adı verilir. Usul olarak, bir :math:`\mathbf{A}`'nin devriğini
:math:`\mathbf{A}^\top` ile gösteririz ve eğer
:math:`\mathbf{B} = \mathbf{A}^\top` ise herhangi bir :math:`i` and
:math:`j` için :math:`b_{ij} = a_{ji}`'dir. Bu nedenle,
:eq:`eq_matrix_def`'deki :math:`\mathbf{A}`'nin devriği bir
:math:`n\times m` matristir:
.. math::
\mathbf{A}^\top =
\begin{bmatrix}
a_{11} & a_{21} & \dots & a_{m1} \\
a_{12} & a_{22} & \dots & a_{m2} \\
\vdots & \vdots & \ddots & \vdots \\
a_{1n} & a_{2n} & \dots & a_{mn}
\end{bmatrix}.
Şimdi kodda bir matrisin devriğine erişiyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.T
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 0., 4., 8., 12., 16.],
[ 1., 5., 9., 13., 17.],
[ 2., 6., 10., 14., 18.],
[ 3., 7., 11., 15., 19.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.T
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 0, 4, 8, 12, 16],
[ 1, 5, 9, 13, 17],
[ 2, 6, 10, 14, 18],
[ 3, 7, 11, 15, 19]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.transpose(A)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Kare matrisin özel bir türü olarak, bir *simetrik matris*
:math:`\mathbf{A}`, devriğine eşittir:
:math:`\mathbf{A} = \mathbf{A}^\top`. Burada simetrik bir matrisi ``B``
diye tanımlıyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = np.array([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[1., 2., 3.],
[2., 0., 4.],
[3., 4., 5.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[1, 2, 3],
[2, 0, 4],
[3, 4, 5]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = tf.constant([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Şimdi ``B``\ yi kendi devriğiyle karşılaştıralım.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B == B.T
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ True, True, True],
[ True, True, True],
[ True, True, True]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B == B.T
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[True, True, True],
[True, True, True],
[True, True, True]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B == tf.transpose(B)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Matrisler yararlı veri yapılarıdır: Farklı değişim (varyasyon) kiplerine
(modalite) sahip verileri düzenlememize izin verirler. Örneğin,
matrisimizdeki satırlar farklı evlere (veri örneklerine) karşılık
gelirken, sütunlar farklı özelliklere karşılık gelebilir. Daha önce
elektronik tablo yazılımı kullandıysanız veya şurayı okuduysanız
:numref:`sec_pandas`, bu size tanıdık gelecektir. Bu nedenle, tek bir
vektörün varsayılan yönü bir sütun vektörü olmasına rağmen, bir tablo
veri kümesini temsil eden bir matriste, her veri örneğini matristeki bir
satır vektörü olarak ele almak daha gelenekseldir. Ve sonraki bölümlerde
göreceğimiz gibi, bu düzen ortak derin öğrenme tatbikatlarını mümkün
kılacaktır. Örneğin, bir tensörün en dış ekseni boyunca, veri
örneklerinin minigruplarına veya minigrup yoksa yalnızca veri
örneklerine erişebilir veya bir bir sayabiliriz.
Tensörler
---------
Vektörlerin skalerleri genellemesi ve matrislerin vektörleri genellemesi
gibi, daha fazla eksenli veri yapıları oluşturabiliriz. Tensörler (bu
alt bölümdeki "tensörler" cebirsel nesnelere atıfta bulunur) bize
rastgele sayıda ekseni olan :math:`n`-boyutlu dizileri tanımlamanın
genel bir yolunu verir. Vektörler, örneğin, birinci dereceden
tensörlerdir ve matrisler ikinci dereceden tensörlerdir. Tensörler, özel
bir yazı tipinin büyük harfleriyle (ör. :math:`\mathsf{X}`,
:math:`\mathsf{Y}` ve :math:`\mathsf{Z}`) ve indeksleme mekanizmalarıyla
(ör. :math:`X_{ijk}` ve :math:`[\mathsf{X}]_{1, 2i-1, 3}`),
matrislerinkine benzer gösterilir.
Renk kanallarını (kırmızı, yeşil ve mavi) istiflemek için yükseklik,
genişlik ve bir *kanal* eksenine karşılık gelen 3 eksene sahip
:math:`n`-boyutlu dizi olarak gelen imgelerle çalışmaya başladığımızda
tensörler daha önemli hale gelecektir. Şimdilik, daha yüksek dereceli
tensörleri atlayacağız ve temellere odaklanacağız.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
X = np.arange(24).reshape(2, 3, 4)
X
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]],
[[12., 13., 14., 15.],
[16., 17., 18., 19.],
[20., 21., 22., 23.]]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
X = torch.arange(24).reshape(2, 3, 4)
X
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
X = tf.reshape(tf.range(24), (2, 3, 4))
X
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Tensör Aritmetiğinin Temel Özellikleri
--------------------------------------
Skalerler, vektörler, matrisler ve rasgele sayıda eksenli tensörler (bu
alt bölümdeki "tensörler" cebirsel nesnelere atıfta bulunur), çoğu zaman
kullanışlı olan bazı güzel özelliklere sahiptir. Örneğin, bir eleman
yönlü işlemin tanımından, herhangi bir eleman yönlü tekli işlemin
işlenen nesnenin şeklini değiştirmediğini fark etmiş olabilirsiniz.
Benzer şekilde, aynı şekle sahip herhangi bir iki tensör göz önüne
alındığında, herhangi bir ikili elemanlı işlemin sonucu, gene aynı şekle
sahip bir tensör olacaktır. Örneğin, aynı şekle sahip iki matris
toplama, bu iki matrisin üzerinde eleman yönlü toplama gerçekleştirir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = np.arange(20).reshape(5, 4)
B = A.copy() # `A`nın kopyasını yeni bellek tahsis ederek `B`ye atayın
A, A + B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
array([[ 0., 2., 4., 6.],
[ 8., 10., 12., 14.],
[16., 18., 20., 22.],
[24., 26., 28., 30.],
[32., 34., 36., 38.]]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone() # `A`nın kopyasını yeni bellek tahsis ederek `B`ye atayın
A, A + B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
tensor([[ 0., 2., 4., 6.],
[ 8., 10., 12., 14.],
[16., 18., 20., 22.],
[24., 26., 28., 30.],
[32., 34., 36., 38.]]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A = tf.reshape(tf.range(20, dtype=tf.float32), (5, 4))
B = A # Yeni bellek tahsis ederek `A`yı `B`ye klonlamak yok
A, A + B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
)
.. raw:: html
.. raw:: html
Özellikle, iki matrisin eleman yönlü çarpımına *Hadamard çarpımı*
(matematik gösterimi :math:`\odot`) denir. :math:`i.` satır ve
:math:`j.` sütununun öğesi :math:`b_{ij}` olan
:math:`\mathbf{B}\in\mathbb{R}^{m\times n}` matrisini düşünün.
:math:`\mathbf{A}` (:eq:`eq_matrix_def`'da tanımlanmıştır) ve
:math:`\mathbf{B}` matrislerinin Hadamard çarpımı:
.. math::
\mathbf{A} \odot \mathbf{B} =
\begin{bmatrix}
a_{11} b_{11} & a_{12} b_{12} & \dots & a_{1n} b_{1n} \\
a_{21} b_{21} & a_{22} b_{22} & \dots & a_{2n} b_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m1} b_{m1} & a_{m2} b_{m2} & \dots & a_{mn} b_{mn}
\end{bmatrix}.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A * B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A * B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A * B
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Bir tensörün skaler ile çarpılması veya toplanması, işlenen tensörün her
elemanını skaler ile toplayacağından veya çarpacağından tensörün şeklini
de değiştirmez.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
a = 2
X = np.arange(24).reshape(2, 3, 4)
a + X, (a * X).shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([[[ 2., 3., 4., 5.],
[ 6., 7., 8., 9.],
[10., 11., 12., 13.]],
[[14., 15., 16., 17.],
[18., 19., 20., 21.],
[22., 23., 24., 25.]]]),
(2, 3, 4))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
a = 2
X = torch.arange(24).reshape(2, 3, 4)
a + X, (a * X).shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([[[ 2, 3, 4, 5],
[ 6, 7, 8, 9],
[10, 11, 12, 13]],
[[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]]]),
torch.Size([2, 3, 4]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
a = 2
X = tf.reshape(tf.range(24), (2, 3, 4))
a + X, (a * X).shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
TensorShape([2, 3, 4]))
.. raw:: html
.. raw:: html
.. _subseq_lin-alg-reduction:
İndirgeme
---------
Keyfi tensörlerle gerçekleştirebileceğimiz faydalı işlemlerden biri
elemanlarının toplamını hesaplamaktır. Matematiksel gösterimde,
:math:`\sum` sembolünü kullanarak toplamları ifade ederiz. :math:`d`
uzunluğa sahip :math:`\mathbf{x}` vektöründeki öğelerin toplamını ifade
etmek için :math:`\sum_{i=1}^d x_i` yazarız. Kodda, toplamı hesaplamak
için sadece ilgili işlevi çağırabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = np.arange(4)
x, x.sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([0., 1., 2., 3.]), array(6.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = torch.arange(4, dtype=torch.float32)
x, x.sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([0., 1., 2., 3.]), tensor(6.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
x = tf.range(4, dtype=tf.float32)
x, tf.reduce_sum(x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
)
.. raw:: html
.. raw:: html
Rasgele şekilli tensörlerin elamanları üzerindeki toplamları ifade
edebiliriz. Örneğin, :math:`m\times n` matris :math:`\mathbf{A}`
öğelerinin toplamı :math:`\sum_{i=1}^{m} \sum_{j=1}^{n} a_{ij}` diye
yazılabilir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, A.sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
((5, 4), array(190.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, A.sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(torch.Size([5, 4]), tensor(190.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, tf.reduce_sum(A)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(TensorShape([5, 4]), )
.. raw:: html
.. raw:: html
Varsayılan olarak, toplamı hesaplama işlevini çağırmak, tüm eksenleri
boyunca bir tensörü skalere *indirger*. Toplama yoluyla tensörün
indirgendiği eksenleri de belirtebiliriz. Örnek olarak matrisleri alın.
Tüm satırların öğelerini toplayarak satır boyutunu (eksen 0) indirgemek
için, işlevi çağırırken ``axis=0`` değerini belirtiriz. Girdi matrisi,
çıktı vektörü oluşturmak için eksen 0 boyunca indirgendiğinden, girdinin
eksen 0 boyutu, çıktının şeklinde kaybolur.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis0 = A.sum(axis=0)
A_sum_axis0, A_sum_axis0.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([40., 45., 50., 55.]), (4,))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis0 = A.sum(axis=0)
A_sum_axis0, A_sum_axis0.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([40., 45., 50., 55.]), torch.Size([4]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis0 = tf.reduce_sum(A, axis=0)
A_sum_axis0, A_sum_axis0.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
TensorShape([4]))
.. raw:: html
.. raw:: html
``axis=1`` olarak belirtmek, tüm sütunların öğelerini toplayarak sütun
boyutunu (eksen 1) azaltacaktır. Böylece, girdinin eksen 1 boyutu,
çıktının şeklinde kaybolur.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis1 = A.sum(axis=1)
A_sum_axis1, A_sum_axis1.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([ 6., 22., 38., 54., 70.]), (5,))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis1 = A.sum(axis=1)
A_sum_axis1, A_sum_axis1.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A_sum_axis1 = tf.reduce_sum(A, axis=1)
A_sum_axis1, A_sum_axis1.shape
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
TensorShape([5]))
.. raw:: html
.. raw:: html
Bir matrisin toplama yoluyla hem satırlar hem de sütunlar boyunca
indirgenmesi, matrisin tüm öğelerinin toplanmasıyla eşdeğerdir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.sum(axis=[0, 1]) # `A.sum()` ile aynı
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(190.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.sum(axis=[0, 1]) # `A.sum()` ile aynı
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(190.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.reduce_sum(A, axis=[0, 1]) # `tf.reduce_sum(A)` ile aynı
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
İlgili bir miktar da *ortalama*\ dır. Ortalamayı, toplamı toplam eleman
sayısına bölerek hesaplıyoruz. Kod olarak, keyfi şekildeki tensörlerdeki
ortalamanın hesaplanmasında ilgili işlevi çağırabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.mean(), A.sum() / A.size
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array(9.5), array(9.5))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.mean(), A.sum() / A.numel()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor(9.5000), tensor(9.5000))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.reduce_mean(A), tf.reduce_sum(A) / tf.size(A).numpy()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
)
.. raw:: html
.. raw:: html
Benzer şekilde, ortalama hesaplama fonksiyonu, belirtilen eksenler
boyunca bir tensörü de indirgeyebilir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([ 8., 9., 10., 11.]), array([ 8., 9., 10., 11.]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([ 8., 9., 10., 11.]), tensor([ 8., 9., 10., 11.]))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.reduce_mean(A, axis=0), tf.reduce_sum(A, axis=0) / A.shape[0]
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
)
.. raw:: html
.. raw:: html
.. _subseq_lin-alg-non-reduction:
İndirgemesiz Toplama
~~~~~~~~~~~~~~~~~~~~
Gene de, bazen toplamı veya ortalamayı hesaplamak için işlevi çağırırken
eksen sayısını değiştirmeden tutmak yararlı olabilir.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
sum_A = A.sum(axis=1, keepdims=True)
sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 6.],
[22.],
[38.],
[54.],
[70.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
sum_A = A.sum(axis=1, keepdims=True)
sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 6.],
[22.],
[38.],
[54.],
[70.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
sum_A = tf.reduce_sum(A, axis=1, keepdims=True)
sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Örneğin, ``sum_A`` her satırı topladıktan sonra hala iki eksenini
koruduğundan,\ ``A``'yı yayınlayarak ``sum_A`` ile bölebiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A / sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[0. , 0.16666667, 0.33333334, 0.5 ],
[0.18181819, 0.22727273, 0.27272728, 0.3181818 ],
[0.21052632, 0.23684211, 0.2631579 , 0.28947368],
[0.22222222, 0.24074075, 0.25925925, 0.2777778 ],
[0.22857143, 0.24285714, 0.25714287, 0.27142859]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A / sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[0.0000, 0.1667, 0.3333, 0.5000],
[0.1818, 0.2273, 0.2727, 0.3182],
[0.2105, 0.2368, 0.2632, 0.2895],
[0.2222, 0.2407, 0.2593, 0.2778],
[0.2286, 0.2429, 0.2571, 0.2714]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A / sum_A
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Bir eksen boyunca ``A``'nın öğelerinin biriktirilmiş (kümülatif)
toplamını hesaplamak istiyorsak, ``axis=0`` diyelim (satır satır),
``cumsum`` işlevini çağırabiliriz. Bu işlev girdi tensörünü herhangi bir
eksen boyunca indirgemez.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.cumsum(axis=0)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.cumsum(axis=0)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.cumsum(A, axis=0)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Nokta Çarpımları
----------------
Şimdiye kadar sadece eleman yönlü işlemler, toplamalar ve ortalamalar
gerçekleştirdik. Ayrıca tüm yapabileceğimiz bu olsaydı, doğrusal cebir
muhtemelen kendi bölümünü hak etmeyecekti. Bununla birlikte, en temel
işlemlerden biri iç çarpımdır. İki vektör
:math:`\mathbf{x}, \mathbf{y} \in \mathbb{R}^d` verildiğinde, *iç
çarpımları* :math:`\mathbf{x}^\top \mathbf{y}` (veya
:math:`\langle \mathbf{x}, \mathbf{y} \rangle`), aynı konumdaki öğelerin
çarpımlarının toplamıdır:
:math:`\mathbf{x}^\top \mathbf{y} = \sum_{i=1}^{d} x_i y_i`.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
y = np.ones(4)
x, y, np.dot(x, y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(array([0., 1., 2., 3.]), array([1., 1., 1., 1.]), array(6.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
y = torch.ones(4, dtype = torch.float32)
x, y, torch.dot(x, y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
y = tf.ones(4, dtype=tf.float32)
x, y, tf.tensordot(x, y, axes=1)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(,
,
)
.. raw:: html
.. raw:: html
İki vektörün nokta çarpımlarını, eleman yönlü bir çarpma ve ardından bir
toplam gerçekleştirerek eşit şekilde ifade edebileceğimizi unutmayın:
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
np.sum(x * y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(6.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
torch.sum(x * y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(6.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.reduce_sum(x * y)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Nokta çarpımları çok çeşitli bağlamlarda kullanışlıdır. Örneğin,
:math:`\mathbf{x} \in \mathbb{R}^d` vektörü ve
:math:`\mathbf{w} \in \mathbb{R}^d` ile belirtilen bir ağırlık kümesi
verildiğinde, :math:`\mathbf{x}` içindeki değerlerin :math:`\mathbf{w}`
ağırlıklarına göre ağırlıklı toplamı :math:`\mathbf{x}^\top \mathbf{w}`
nokta çarpımı olarak ifade edilebilir. Ağırlıklar negatif olmadığında ve
bire (örn., :math:`\left(\sum_{i=1}^{d} {w_i} = 1\right)`)
toplandığında, nokta çarpımı *ağırlıklı ortalama*\ yı ifade eder. İki
vektörü birim uzunluğa sahip olacak şekilde normalleştirdikten sonra,
nokta çarpımlar arasındaki açının kosinüsünü ifade eder. *Uzunluk*
kavramını bu bölümün ilerleyen kısımlarında usüle uygun tanıtacağız.
Matris-Vektör Çarpımları
------------------------
Artık nokta çarpımlarını nasıl hesaplayacağımızı bildiğimize göre,
*matris-vektör çarpımları*\ nı anlamaya başlayabiliriz.
:math:`\mathbf{A} \in \mathbb{R}^{m \times n}` matrisini ve
:math:`\mathbf{x} \in \mathbb{R}^n` vektörünü sırasıyla tanımladık ve
:eq:`eq_matrix_def` ve :eq:`eq_vec_def`'de görselleştirdik.
:math:`\mathbf{A}` matrisini satır vektörleriyle görselleştirerek
başlayalım.
.. math::
\mathbf{A}=
\begin{bmatrix}
\mathbf{a}^\top_{1} \\
\mathbf{a}^\top_{2} \\
\vdots \\
\mathbf{a}^\top_m \\
\end{bmatrix},
burada her :math:`\mathbf{a}^\top_{i} \in \mathbb{R}^n`,
:math:`\mathbf{A}` matrisinin :math:`i .` satırını temsil eden bir satır
vektörüdür. Matris-vektör çarpımı :math:`\mathbf{A}\mathbf{x}`, basitçe
:math:`i.` elemanı :math:`\mathbf{a}^\top_i \mathbf{x}` iç çarpımı olan
:math:`m` uzunluğunda bir sütun vektörüdür.
.. math::
\mathbf{A}\mathbf{x}
= \begin{bmatrix}
\mathbf{a}^\top_{1} \\
\mathbf{a}^\top_{2} \\
\vdots \\
\mathbf{a}^\top_m \\
\end{bmatrix}\mathbf{x}
= \begin{bmatrix}
\mathbf{a}^\top_{1} \mathbf{x} \\
\mathbf{a}^\top_{2} \mathbf{x} \\
\vdots\\
\mathbf{a}^\top_{m} \mathbf{x}\\
\end{bmatrix}.
:math:`\mathbf{A}\in \mathbb{R}^{m \times n}` matrisi ile çarpmayı
vektörleri :math:`\mathbb{R}^{n}`'den :math:`\mathbb{R}^{m}`'e yansıtan
bir dönüşüm olarak düşünebiliriz. Bu dönüşümler oldukça faydalı oldu.
Örneğin, döndürmeleri bir kare matrisle çarpma olarak gösterebiliriz.
Sonraki bölümlerde göreceğimiz gibi, bir önceki katmanın değerleri göz
önüne alındığında, bir sinir ağındaki her bir katman hesaplanırken
gereken en yoğun hesaplamaları tanımlamak için matris-vektör
çarpımlarını da kullanabiliriz.
.. raw:: html
.. raw:: html
Matris-vektör çarpımlarını tensörlerle kodda ifade ederken, nokta
çarpımlarındaki aynı ``dot`` işlevini kullanırız. ``A`` matrisi ve ``x``
vektörü ile ``np.dot(A, x)`` dediğimizde matris-vektör çarpımı
gerçekleştirilir. ``A`` sütun boyutunun (eksen 1 boyunca uzunluğu) ``x``
boyutuyla (uzunluğu) aynı olması gerektiğini unutmayın.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, x.shape, np.dot(A, x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
((5, 4), (4,), array([ 14., 38., 62., 86., 110.]))
.. raw:: html
.. raw:: html
Matris-vektör çarpımlarını tensörlerle kodda ifade ederken, ``mv``
işlevini kullanırız. ``A`` matrisi ve ``x`` vektörü ile
``torch.mv(A, x)`` dediğimizde matris-vektör çarpımı gerçekleştirilir.
``A`` sütun boyutunun (eksen 1 boyunca uzunluğu) ``x`` boyutuyla
(uzunluğu) aynı olması gerektiğini unutmayın.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, x.shape, torch.mv(A, x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))
.. raw:: html
.. raw:: html
Matris-vektör çarpımlarını tensörlerle kodda ifade ederken, ``matvec``
işlevini kullanırız. ``A`` matrisi ve ``x`` vektörü ile
``tf.linalg.matvec(A, x)`` dediğimizde matris-vektör çarpımı
gerçekleştirilir. ``A`` sütun boyutunun (eksen 1 boyunca uzunluğu) ``x``
boyutuyla (uzunluğu) aynı olması gerektiğini unutmayın.
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
A.shape, x.shape, tf.linalg.matvec(A, x)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
(TensorShape([5, 4]),
TensorShape([4]),
)
.. raw:: html
.. raw:: html
Matris-Matris Çarpımı
---------------------
Eğer nokta ve matris-vektör çarpımlarını anladıysanız, *matris-matris
çarpımı* açık olmalıdır.
:math:`\mathbf{A} \in \mathbb{R}^{n \times k}` ve
:math:`\mathbf{B} \in \mathbb{R}^{k \times m}` diye iki matrisimizin
olduğunu diyelim:
.. math::
\mathbf{A}=\begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1k} \\
a_{21} & a_{22} & \cdots & a_{2k} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n1} & a_{n2} & \cdots & a_{nk} \\
\end{bmatrix},\quad
\mathbf{B}=\begin{bmatrix}
b_{11} & b_{12} & \cdots & b_{1m} \\
b_{21} & b_{22} & \cdots & b_{2m} \\
\vdots & \vdots & \ddots & \vdots \\
b_{k1} & b_{k2} & \cdots & b_{km} \\
\end{bmatrix}.
:math:`\mathbf{A}` matrisinin :math:`i.` satırını temsil eden satır
vektörünü :math:`\mathbf{a}^\top_{i}` ile belirtelim ve
:math:`\mathbf{B}` matrisinin :math:`j.` sütunu da
:math:`\mathbf{b}_{j}` olsun. :math:`\mathbf{C} = \mathbf{A}\mathbf{B}`
matris çarpımını üretmek için :math:`\mathbf{A}`'yı satır vektörleri ve
:math:`\mathbf{B}`'yi sütun vektörleri ile düşünmek en kolay yoldur:
.. math::
\mathbf{A}=
\begin{bmatrix}
\mathbf{a}^\top_{1} \\
\mathbf{a}^\top_{2} \\
\vdots \\
\mathbf{a}^\top_n \\
\end{bmatrix},
\quad \mathbf{B}=\begin{bmatrix}
\mathbf{b}_{1} & \mathbf{b}_{2} & \cdots & \mathbf{b}_{m} \\
\end{bmatrix}.
Daha sonra, :math:`\mathbf{C} \in \mathbb{R}^{n \times m}` matris
çarpımı her bir :math:`c_{ij}` öğesi
:math:`\mathbf{a}^\top_i \mathbf{b}_j` nokta çarpımı hesaplanarak
üretilir:
.. math::
\mathbf{C} = \mathbf{AB} = \begin{bmatrix}
\mathbf{a}^\top_{1} \\
\mathbf{a}^\top_{2} \\
\vdots \\
\mathbf{a}^\top_n \\
\end{bmatrix}
\begin{bmatrix}
\mathbf{b}_{1} & \mathbf{b}_{2} & \cdots & \mathbf{b}_{m} \\
\end{bmatrix}
= \begin{bmatrix}
\mathbf{a}^\top_{1} \mathbf{b}_1 & \mathbf{a}^\top_{1}\mathbf{b}_2& \cdots & \mathbf{a}^\top_{1} \mathbf{b}_m \\
\mathbf{a}^\top_{2}\mathbf{b}_1 & \mathbf{a}^\top_{2} \mathbf{b}_2 & \cdots & \mathbf{a}^\top_{2} \mathbf{b}_m \\
\vdots & \vdots & \ddots &\vdots\\
\mathbf{a}^\top_{n} \mathbf{b}_1 & \mathbf{a}^\top_{n}\mathbf{b}_2& \cdots& \mathbf{a}^\top_{n} \mathbf{b}_m
\end{bmatrix}.
Matris-matris çarpımı :math:`\mathbf{AB}`'yi sadece :math:`m` tane
matris-vektör çarpımı gerçekleştirmek ve sonuçları :math:`n\times m`
matrisi oluşturmak için birleştirmek olarak düşünebiliriz. Aşağıdaki kod
parçasında, ``A`` ve ``B`` üzerinde matris çarpımı yapıyoruz. Burada
``A``, 5 satır ve 4 sütunlu bir matristir ve ``B`` 4 satır ve 3 sütunlu
bir matristir. Çarpma işleminden sonra 5 satır ve 3 sütun içeren bir
matris elde ederiz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = np.ones(shape=(4, 3))
np.dot(A, B)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = torch.ones(4, 3)
torch.mm(A, B)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]])
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
B = tf.ones((4, 3), tf.float32)
tf.matmul(A, B)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Matris-matris çarpımı basitçe *matris çarpımı* olarak adlandırılabilir
ve Hadamard çarpımı ile karıştırılmamalıdır.
.. _subsec_lin-algebra-norms:
Normlar (Büyüklükler)
---------------------
Doğrusal cebirde en kullanışlı operatörlerden bazıları *normlardır*.
Gayri resmi olarak, bir vektörün normu bize bir vektörün ne kadar
*büyük* olduğunu söyler. Burada ele alınan *ebat* kavramı boyutsallık
değil, bileşenlerin büyüklüğü ile ilgilidir.
Doğrusal cebirde, bir vektör normu, bir vektörü bir skalere eşleştiren
ve bir avuç dolusu özelliği karşılayan bir :math:`f` fonksiyonudur.
Herhangi bir :math:`\mathbf{x}` vektörü verildiğinde, ilk özellik, bir
vektörün tüm elemanlarını sabit bir :math:`\alpha` çarpanına göre
ölçeklendirirsek, normunun da aynı sabit çarpanın *mutlak değerine* göre
ölçeklendiğini söyler:
.. math:: f(\alpha \mathbf{x}) = |\alpha| f(\mathbf{x}).
İkinci özellik, tanıdık üçgen eşitsizliğidir:
.. math:: f(\mathbf{x} + \mathbf{y}) \leq f(\mathbf{x}) + f(\mathbf{y}).
Üçüncü özellik, normun negatif olmaması gerektiğini söyler:
.. math:: f(\mathbf{x}) \geq 0.
Çoğu bağlamda herhangi bir şey için en küçük *ebat* 0 olduğu için bu
mantıklıdır. Nihai özellik, en küçük normun sadece ve sadece tüm
sıfırlardan oluşan bir vektör tarafından elde edilmesini gerektirir.
.. math:: \forall i, [\mathbf{x}]_i = 0 \Leftrightarrow f(\mathbf{x})=0.
Normların mesafe ölçülerine çok benzediğini fark edebilirsiniz. Ayrıca
eğer ilkokuldan Öklid mesafesini hatırlarsanız (Pisagor teoremini
düşünün), o zaman negatif olmama ve üçgen eşitsizlik kavramları
zihininizde bir zil çalabilir. Aslında Öklid mesafesi bir normdur:
Özellikle :math:`L_2` normudur. :math:`n` boyutlu vektör,
:math:`\mathbf{x}`, içindeki öğelerin :math:`x_1,\ldots,x_n` olduğunu
varsayalım. :math:`\mathbf{x}`'in :math:`L_2` *normu*, vektör öğelerinin
karelerinin toplamının kareköküdür:
.. math:: \|\mathbf{x}\|_2 = \sqrt{\sum_{i=1}^n x_i^2},
burada :math:`2` altindisi genellikle :math:`L_2` normlarında atlanır,
yani, :math:`\|\mathbf{x}\|`, :math:`\|\mathbf{x}\|_2` ile eşdeğerdir.
Kodda, bir vektörün :math:`L_2` normunu aşağıdaki gibi hesaplayabiliriz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
u = np.array([3, -4])
np.linalg.norm(u)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(5.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
u = torch.tensor([3.0, -4.0])
torch.norm(u)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(5.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
u = tf.constant([3.0, -4.0])
tf.norm(u)
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Derin öğrenmede, kare :math:`L_2` normuyla daha sık çalışırız. Ayrıca,
vektör öğelerinin mutlak değerlerinin toplamı olarak ifade edilen
:math:`L_1` *normu* ile de sık karşılaşacaksınız:
.. math:: \|\mathbf{x}\|_1 = \sum_{i=1}^n \left|x_i \right|.
:math:`L_2` normuna kıyasla, sıradışı (aykırı) değerlerden daha az
etkilenir. :math:`L_1` normunu hesaplamak için, elemanların toplamı
üzerinde mutlak değer fonksiyonunu oluştururuz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
np.abs(u).sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(7.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
torch.abs(u).sum()
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(7.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.reduce_sum(tf.abs(u))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Hem :math:`L_2` normu hem de :math:`L_1` normu, daha genel :math:`L_p`
*normu*\ nun özel durumlarıdır:
.. math:: \|\mathbf{x}\|_p = \left(\sum_{i=1}^n \left|x_i \right|^p \right)^{1/p}.
:math:`L_2` vektör normlarına benzer bir şekilde,
:math:`\mathbf{X} \in \mathbb{R}^{m \times n}` matrisinin *Frobenius
normu*, matris elemanlarının karelerin toplamının kare köküdür:
.. math:: \|\mathbf{X}\|_F = \sqrt{\sum_{i=1}^m \sum_{j=1}^n x_{ij}^2}.
Frobenius normu, vektör normlarının tüm özelliklerini karşılar. Matris
şeklindeki bir vektörün bir :math:`L_2` normu gibi davranır. Aşağıdaki
işlevi çağırmak, bir matrisin Frobenius normunu hesaplar.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
np.linalg.norm(np.ones((4, 9)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
array(6.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
torch.norm(torch.ones((4, 9)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
tensor(6.)
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
tf.norm(tf.ones((4, 9)))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
.. _subsec_norms_and_objectives:
Normlar ve Amaç Fonksiyonları
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kendimizi aşmak istemesek de, şimdiden bu kavramların neden faydalı
olduğuna dair bazı sezgiler ekleyebiliriz. Derin öğrenmede, genellikle
optimizasyon (eniyileme) sorunlarını çözmeye çalışıyoruz: Gözlenen
verilere atanan olasılığı *en üst düzeye çıkar*; tahminler ve
gerçek-doğru gözlemler arasındaki mesafeyi *en aza indir*. Benzer öğeler
arasındaki mesafe en aza indirilecek ve benzer olmayan öğeler arasındaki
mesafe en üst düzeye çıkarılacak şekilde öğelere (kelimeler, ürünler
veya haber makaleleri gibi) vektör ifadeleri ata. Çoğu zaman, amaç
fonksiyonları, ki belki de derin öğrenme algoritmalarının (verilerin
yanı sıra) en önemli bileşenleridir, normlar cinsinden ifade edilir.
Doğrusal Cebir Hakkında Daha Fazlası
------------------------------------
Sadece bu bölümde, modern derin öğrenmenin dikkate değer bir bölümünü
anlamak için ihtiyaç duyacağınız tüm doğrusal cebiri öğrettik. Doğrusal
cebirde çok daha fazlası vardır ve daha fazla matematik makine öğrenmesi
için yararlıdır. Örneğin, matrisler faktörlere ayrıştırılabilir ve bu
ayrışmalar gerçek dünya veri kümelerinde düşük boyutlu yapıları ortaya
çıkarabilir. Veri kümelerindeki yapıyı keşfetmek ve tahmin problemlerini
çözmek için matris ayrıştırmalarına ve onların yüksek dereceli
tensörlere genellemelerini kullanmaya odaklanan koca makine öğrenmesi
alt alanları vardır. Ancak bu kitap derin öğrenmeye odaklanmaktadır.
Gerçek veri kümelerinde faydalı makine öğrenmesi modelleri uygulayarak
ellerinizi kirlettikten sonra daha fazla matematik öğrenmeye çok daha
meyilli olacağınıza inanıyoruz. Bu nedenle, daha sonra daha fazla
matematiği öne sürme hakkımızı saklı tutarken, bu bölümü burada
toparlayacağız.
Doğrusal cebir hakkında daha fazla bilgi edinmek istiyorsanız, şunlardan
birine başvurabilirsiniz: `Doğrusal cebir işlemleri üzerine çevrimiçi
ek `__
veya diğer mükemmel kaynaklar
:cite:`Strang.1993,Kolter.2008,Petersen.Pedersen.ea.2008`.
Özet
----
- Skalerler, vektörler, matrisler ve tensörler doğrusal cebirdeki temel
matematiksel nesnelerdir.
- Vektörler skaleri genelleştirir ve matrisler vektörleri
genelleştirir.
- Skalerler, vektörler, matrisler ve tensörler sırasıyla sıfır, bir,
iki ve rastgele sayıda eksene sahiptir.
- Bir tensör, belirtilen eksenler boyunca ``toplam`` ve ``ortalama``
ile indirgenebilir.
- İki matrisin eleman yönlü olarak çarpılmasına Hadamard çarpımı denir.
Matris çarpımından farklıdır.
- Derin öğrenmede, genellikle :math:`L_1` normu, :math:`L_2` normu ve
Frobenius normu gibi normlarla çalışırız.
- Skalerler, vektörler, matrisler ve tensörler üzerinde çeşitli
işlemler gerçekleştirebiliriz.
Alıştırmalar
------------
1. :math:`\mathbf{A}`'nın devrik bir matrisinin devrik işleminin
:math:`\mathbf{A}`, yani :math:`(\mathbf{A}^\top)^\top = \mathbf{A}`
olduğunu kanıtlayın.
2. :math:`\mathbf{A}` ve :math:`\mathbf{B}` matrisleri verildiğinde,
devriklerin toplamının bir toplamın devriğine eşit olduğunu gösterin:
:math:`\mathbf{A}^\top + \mathbf{B}^\top = (\mathbf{A} + \mathbf{B})^\top`.
3. Herhangi bir kare matris :math:`\mathbf{A}` verildiğinde,
:math:`\mathbf{A} + \mathbf{A}^\top` her zaman simetrik midir? Neden?
4. Bu bölümde (2, 3, 4) şeklinde ``X`` tensörünü tanımladık. ``len(X)``
çıktısı nedir?
5. Rasgele şekilli bir tensör ``X`` için, ``len(X)`` her zaman belirli
bir ``X`` ekseninin uzunluğuna karşılık gelir mi? Bu eksen nedir?
6. ``A / A.sum(axis=1)`` komutunu çalıştırın ve ne olduğuna bakın.
Sebebini analiz edebilir misiniz?
7. Manhattan'da iki nokta arasında seyahat ederken, koordinatlar
açısından, yani cadde ve sokak cinsinden, kat etmeniz gereken mesafe
nedir? Çaprazlama seyahat edebilir misiniz?
8. (2, 3, 4) şekilli bir tensörü düşünün. 0, 1 ve 2 ekseni boyunca
toplam çıktılarının şekilleri nelerdir?
9. 3 veya daha fazla eksenli bir tensörü ``linalg.norm`` fonksiyonuna
besleyin ve çıktısını gözlemleyin. Bu işlev keyfi şekilli tansörler
için ne hesaplar?
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html