18.2. Özayrışmalar
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in SageMaker Studio Lab

Özdeğerler genellikle doğrusal cebiri incelerken karşılaşacağımız en yararlı kavramlardan biridir, ancak yeni başlayanlar olarak önemlerini gözden kaçırmak kolaydır. Aşağıda, özayrışmayı tanıtıyoruz ve neden bu kadar önemli olduğuna dair bir fikir aktarmaya çalışıyoruz.

Aşağıdaki girdileri içeren bir \(A\) matrisimiz olduğunu varsayalım:

(18.2.1)\[\begin{split}\mathbf{A} = \begin{bmatrix} 2 & 0 \\ 0 & -1 \end{bmatrix}.\end{split}\]

Herhangi bir \(\mathbf{v} = [x, y]^\top\) vektörüne \(A\) uygularsak, bir \(\mathbf{A}\mathbf{v} = [2x, -y]^\top\) vektörü elde ederiz. Bunun sezgisel bir yorumu var: Vektörü \(x\) yönünde iki kat geniş olacak şekilde uzatın ve ardından \(y\) yönünde ters çevirin.

Ancak, bir şeyin değişmeden kaldığı bazı vektörler vardır. Yani \([1, 0]^\top\), \([2, 0]^\top\)’e ve \([0, 1]^\top\), \([0, -1]^\top\)’e gönderilir. Bu vektörler hala aynı doğrudadır ve tek değişiklik, matrisin onları sırasıyla \(2\) ve \(-1\) çarpanı ile genişletmesidir. Bu tür vektörlere özvektörler diyoruz ve bunların uzatıldıkları çarpan da özdeğerlerdir.

Genel olarak, bir \(\lambda\) sayısı ve şöyle bir \(\mathbf{v}\) vektörü bulabilirsek

(18.2.2)\[\mathbf{A}\mathbf{v} = \lambda \mathbf{v}\]

\(\mathbf{v}\) \(A\) için bir özvektör ve \(\lambda\) bir özdeğerdir deriz.

18.2.1. Özdeğerleri Bulma

Onları nasıl bulacağımızı anlayalım. Her iki taraftan \(\lambda \mathbf{v}\) çıkararak ve ardından vektörü dışarıda bırakarak, yukarıdakinin şuna eşdeğer olduğunu görürüz:

(18.2.3)\[(\mathbf{A} - \lambda \mathbf{I})\mathbf{v} = 0.\]

(18.2.3) denkleminin gerçekleşmesi için, \((\mathbf{A} - \lambda \mathbf{I})\)’nın bir yönü sıfıra kadar sıkıştırması gerektiğini görüyoruz, bu nedenle tersinir değildir ve bu nedenle determinant sıfırdır. Böylece, özdeğerleri, \(\lambda\) değerinin ne zaman \(\det(\mathbf{A}-\lambda \mathbf{I}) = 0\) olduğunu bularak bulabiliriz. Özdeğerleri bulduktan sonra, ilişkili özvektör(leri) bulmak için \(\mathbf{A}\mathbf{v} = \lambda \mathbf{v}\)’yı çözebiliriz.

18.2.1.1. Bir örnek

Bunu daha zorlu bir matrisle görelim

(18.2.4)\[\begin{split}\mathbf{A} = \begin{bmatrix} 2 & 1\\ 2 & 3 \end{bmatrix}.\end{split}\]

\(\det(\mathbf{A}-\lambda \mathbf{I}) = 0\) olarak düşünürsek, bunun \(0 = (2-\lambda)(3-\lambda)-2 = (4-\lambda)(1-\lambda)\) polinom denklemine eşdeğer olduğunu görürüz. Böylece, iki özdeğer \(4\) ve \(1\)’dir. İlişkili vektörleri bulmak için bunu çözmemiz gerekir:

(18.2.5)\[\begin{split}\begin{bmatrix} 2 & 1\\ 2 & 3 \end{bmatrix}\begin{bmatrix}x \\ y\end{bmatrix} = \begin{bmatrix}x \\ y\end{bmatrix} \; \text{ve} \; \begin{bmatrix} 2 & 1\\ 2 & 3 \end{bmatrix}\begin{bmatrix}x \\ y\end{bmatrix} = \begin{bmatrix}4x \\ 4y\end{bmatrix} .\end{split}\]

Bunu sırasıyla \([1, -1]^\top\) ve \([1, 2]^\top\) vektörleriyle çözebiliriz.

Bunu yerleşik numpy.linalg.eig rutinini kullanarak kodda kontrol edebiliriz.

%matplotlib inline
import numpy as np
from IPython import display
from d2l import mxnet as d2l

np.linalg.eig(np.array([[2, 1], [2, 3]]))
(array([1., 4.]),
 array([[-0.70710678, -0.4472136 ],
        [ 0.70710678, -0.89442719]]))
%matplotlib inline
import torch
from IPython import display
from d2l import torch as d2l

torch.eig(torch.tensor([[2, 1], [2, 3]], dtype=torch.float64),
          eigenvectors=True)
/tmp/ipykernel_4566/1653148152.py:6: UserWarning: torch.eig is deprecated in favor of torch.linalg.eig and will be removed in a future PyTorch release.
torch.linalg.eig returns complex tensors of dtype cfloat or cdouble rather than real tensors mimicking complex tensors.
L, _ = torch.eig(A)
should be replaced with
L_complex = torch.linalg.eigvals(A)
and
L, V = torch.eig(A, eigenvectors=True)
should be replaced with
L_complex, V_complex = torch.linalg.eig(A) (Triggered internally at  ../aten/src/ATen/native/BatchLinearAlgebra.cpp:3427.)
  torch.eig(torch.tensor([[2, 1], [2, 3]], dtype=torch.float64),
torch.return_types.eig(
eigenvalues=tensor([[1., 0.],
        [4., 0.]], dtype=torch.float64),
eigenvectors=tensor([[-0.7071, -0.4472],
        [ 0.7071, -0.8944]], dtype=torch.float64))
%matplotlib inline
from IPython import display
import tensorflow as tf
from d2l import tensorflow as d2l

tf.linalg.eig(tf.constant([[2, 1], [2, 3]], dtype=tf.float64))
(<tf.Tensor: shape=(2,), dtype=complex128, numpy=array([1.+0.j, 4.+0.j])>,
 <tf.Tensor: shape=(2, 2), dtype=complex128, numpy=
 array([[-0.70710678+0.j, -0.4472136 +0.j],
        [ 0.70710678+0.j, -0.89442719+0.j]])>)

numpy kütüphanesinin özvektörleri bir uzunluğunda normalleştirdiğini, oysa bizimkileri keyfi uzunlukta kabul ettiğimizi unutmayın. Ek olarak, işaret seçimi keyfidir. Bununla birlikte, hesaplanan vektörler, aynı özdeğerlerle elle bulduklarımıza paraleldir.

18.2.2. Matris Ayrıştırma

Önceki örnek ile bir adım daha devam edelim.

(18.2.6)\[\begin{split}\mathbf{W} = \begin{bmatrix} 1 & 1 \\ -1 & 2 \end{bmatrix},\end{split}\]

Sütunları \(\mathbf{A}\) matrisinin özvektörleri olduğu matris olsun.

(18.2.7)\[\begin{split}\boldsymbol{\Sigma} = \begin{bmatrix} 1 & 0 \\ 0 & 4 \end{bmatrix},\end{split}\]

Köşegen üzerinde ilişkili özdeğerleri olan matris olsun. Özdeğerlerin ve özvektörlerin tanımı bize şunu söyler:

(18.2.8)\[\mathbf{A}\mathbf{W} =\mathbf{W} \boldsymbol{\Sigma} .\]

\(W\) matrisi ters çevrilebilir, bu yüzden her iki tarafı da sağdan \(W^{-1}\) ile çarpabiliriz ve görürüz ki:

(18.2.9)\[\mathbf{A} = \mathbf{W} \boldsymbol{\Sigma} \mathbf{W}^{-1}.\]

Bir sonraki bölümde bunun bazı güzel sonuçlarını göreceğiz, ancak şimdilik sadece, doğrusal olarak bağımsız özvektörlerin tam bir topluluğunu bulabildiğimiz sürece böyle bir ayrışmanın var olacağını bilmemiz gerekiyor (böylece \(W\) tersinirdir).

18.2.3. Özayrışmalar Üzerinde İşlemler

Özayrışmalar, (18.2.9), ilgili güzel bir şey, genellikle karşılaştığımız birçok işlemi özayrışmalar açısından temiz bir şekilde yazabilmemizdir. İlk örnek olarak şunları düşünün:

(18.2.10)\[\mathbf{A}^n = \overbrace{\mathbf{A}\cdots \mathbf{A}}^{\text{$n$ kere}} = \overbrace{(\mathbf{W}\boldsymbol{\Sigma} \mathbf{W}^{-1})\cdots(\mathbf{W}\boldsymbol{\Sigma} \mathbf{W}^{-1})}^{\text{$n$ kere}} = \mathbf{W}\overbrace{\boldsymbol{\Sigma}\cdots\boldsymbol{\Sigma}}^{\text{$n$ kere}}\mathbf{W}^{-1} = \mathbf{W}\boldsymbol{\Sigma}^n \mathbf{W}^{-1}.\]

Bu bize, bir matrisin herhangi bir pozitif kuvveti için, özayrışmasının özdeğerlerin sadece aynı kuvvete yükseltilmesiyle elde edildiğini söyler. Aynısı negatif kuvvetler için de gösterilebilir, bu nedenle bir matrisi tersine çevirmek istiyorsak, yapmamız gereken yalnızca

(18.2.11)\[\mathbf{A}^{-1} = \mathbf{W}\boldsymbol{\Sigma}^{-1} \mathbf{W}^{-1},\]

veya başka bir deyişle, her bir özdeğeri ters çevirin. Bu, her özdeğer sıfır olmadığı sürece işe yarayacaktır, bu nedenle tersinebilirin sıfır özdeğer olmamasıyla aynı olduğunu görürüz.

Aslında, ek çalışma şunu gösterebilir: Eğer \(\lambda_1, \ldots, \lambda_n\) bir matrisin özdeğerleriyse, o zaman o matrisin determinantı

(18.2.12)\[\det(\mathbf{A}) = \lambda_1 \cdots \lambda_n,\]

veya tüm özdeğerlerin çarpımıdır. Bu sezgisel olarak mantıklıdır, çünkü \(\mathbf{W}\) ne kadar esnetme yaparsa, \(W^{-1}\) bunu geri alır, dolayısıyla sonunda gerçekleşen tek uzatma köşegen matris \(\boldsymbol{\Sigma}\) ile çarpma yoluyla olur, ki o da köşegen elemanların çarpımına göre hacimleri uzatır.

Son olarak, kertenin matrisinizin en büyük doğrusal olarak bağımsız sütunlarının sayısı olduğunu hatırlayın. Özayrışmayı yakından inceleyerek, kertenin \(\mathbf{A}\)’nın sıfır olmayan özdeğerlerinin sayısıyla aynı olduğunu görebiliriz.

Örnekler devam edebilirdi, ancak umarız ki mesele açıktır: Özayrışmalar, birçok doğrusal-cebirsel hesaplamayı basitleştirebilir ve birçok sayısal (numerik) algoritmanın ve doğrusal cebirde yaptığımız analizlerin çoğunun altında yatan temel bir işlemdir.

18.2.4. Simetrik Matrislerin Özayrışmaları

Yukarıdaki işlemin çalışması için yeterli doğrusal olarak bağımsız özvektör bulmak her zaman mümkün değildir. Örneğin matris

(18.2.13)\[\begin{split}\mathbf{A} = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix},\end{split}\]

tek bir özvektöre, \((1, 0)^\top\), sahiptir. Bu tür matrisleri işlemek için, ele alabileceğimizden daha gelişmiş tekniklere ihtiyacımız var (Jordan Normal Formu veya Tekil Değer Ayrıştırması gibi). Dikkatimizi sık sık tam bir özvektörler kümesinin varlığını garanti edebileceğimiz matrislere sınırlamamız gerekecek.

En sık karşılaşılan aile, \(\mathbf{A} = \mathbf{A}^\top\) olan simetrik matrislerdir. Bu durumda, \(W\)’i bir dikgen (ortogonal) matris olarak alabiliriz — sütunlarının tümü birbirine dik açıda birim uzunluklu vektörler olan bir matris, burada \(\mathbf{W}^\top = \mathbf{W}^{-1}\)’dir - ve tüm özdeğerler gerçel olacaktır. Böylece, bu özel durumda (18.2.9) denklemini şöyle yazabiliriz

(18.2.14)\[\mathbf{A} = \mathbf{W}\boldsymbol{\Sigma}\mathbf{W}^\top .\]

18.2.5. Gershgorin Çember Teoremi

Özdeğerlerle sezgisel olarak akıl yürütmek genellikle zordur. Rasgele bir matris sunulursa, özdeğerleri hesaplamadan ne oldukları hakkında söylenebilecek çok az şey vardır. Bununla birlikte, en büyük değerler köşegen üzerindeyse, iyi bir tahmin yapmayı kolaylaştıran bir teorem vardır.

\(\mathbf{A} = (a_{ij})\) herhangi bir (\(n\times n\)) kare matris olsun. Şöyle tanımlayalım: \(r_i = \sum_{j \neq i} |a_{ij}|\). \(\mathcal{D}_i\) karmaşık düzlemde \(a_{ii}\) merkezli \(r_i\) yarıçaplı diski temsil etsin. Daha sonra, \(\mathbf{A}\)’nın her özdeğeri \(\mathcal{D}_i\)’den birinin içinde bulunur.

Bunu açmak biraz zaman alabilir, o yüzden bir örneğe bakalım. Şu matrisi düşünün:

(18.2.15)\[\begin{split}\mathbf{A} = \begin{bmatrix} 1.0 & 0.1 & 0.1 & 0.1 \\ 0.1 & 3.0 & 0.2 & 0.3 \\ 0.1 & 0.2 & 5.0 & 0.5 \\ 0.1 & 0.3 & 0.5 & 9.0 \end{bmatrix}.\end{split}\]

Elimizde \(r_1 = 0.3\), \(r_2 = 0.6\), \(r_3 = 0.8\) ve \(r_4 = 0.9\) var. Matris simetriktir, bu nedenle tüm özdeğerler gerçeldir. Bu, tüm özdeğerlerimizin aşağıdaki aralıklardan birinde olacağı anlamına gelir.

(18.2.16)\[[a_{11}-r_1, a_{11}+r_1] = [0.7, 1.3],\]
(18.2.17)\[[a_{22}-r_2, a_{22}+r_2] = [2.4, 3.6],\]
(18.2.18)\[[a_{33}-r_3, a_{33}+r_3] = [4.2, 5.8],\]
(18.2.19)\[[a_{44}-r_4, a_{44}+r_4] = [8.1, 9.9].\]

Sayısal hesaplamanın gerçekleştirilmesi, özdeğerlerin yaklaşık \(0.99\), \(2.97\), \(4.95\), \(9.08\) olduğunu ve rahatlıkla sağlanan aralıklar içinde olduğunu gösterir.

A = np.array([[1.0, 0.1, 0.1, 0.1],
              [0.1, 3.0, 0.2, 0.3],
              [0.1, 0.2, 5.0, 0.5],
              [0.1, 0.3, 0.5, 9.0]])

v, _ = np.linalg.eig(A)
v
array([9.08033648, 0.99228545, 4.95394089, 2.97343718])
A = torch.tensor([[1.0, 0.1, 0.1, 0.1],
              [0.1, 3.0, 0.2, 0.3],
              [0.1, 0.2, 5.0, 0.5],
              [0.1, 0.3, 0.5, 9.0]])

v, _ = torch.eig(A)
v
tensor([[0.9923, 0.0000],
        [9.0803, 0.0000],
        [4.9539, 0.0000],
        [2.9734, 0.0000]])
A = tf.constant([[1.0, 0.1, 0.1, 0.1],
                [0.1, 3.0, 0.2, 0.3],
                [0.1, 0.2, 5.0, 0.5],
                [0.1, 0.3, 0.5, 9.0]])

v, _ = tf.linalg.eigh(A)
v
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0.99228525, 2.9734395 , 4.953943  , 9.080336  ], dtype=float32)>

Bu şekilde, özdeğerler yaklaşık olarak tahmin edilebilir ve köşegenin diğer tüm öğelerden önemli ölçüde daha büyük olması durumunda yaklaşımlar oldukça doğru olacaktır.

Bu küçük bir şey, ancak özayrışma gibi karmaşık ve incelikli bir konuda, yapabileceğimiz herhangi bir sezgisel kavrayışa sahip olmak iyidir.

18.2.6. Yararlı Bir Uygulama: Yinelenen Eşlemelerin Gelişimi

Artık özvektörlerin prensipte ne olduğunu anladığımıza göre, bunların sinir ağı davranışının merkezinde olan bir problemin derinlemesine anlaşılmasını sağlamak için nasıl kullanılabileceklerini görelim: Uygun ağırlık ilklenmesi.

18.2.6.1. Uzun Vadeli Davranış Olarak Özvektörler

Derin sinir ağlarının ilklenmesinin tam matematiksel araştırması, metnin kapsamı dışındadır, ancak özdeğerlerin bu modellerin nasıl çalıştığını görmemize nasıl yardımcı olabileceğini anlamak için burada bir basit örnek sürümünü görebiliriz. Bildiğimiz gibi, sinir ağları, doğrusal olmayan işlemlerle doğrusal dönüşüm katmanlarını serpiştirerek çalışır. Burada basitleştirmek için, doğrusal olmayanlığın olmadığını ve dönüşümün tek bir tekrarlanan matris işlemi \(A\) olduğunu varsayacağız, böylece modelimizin çıktısı şu şekildedir:

(18.2.20)\[\mathbf{v}_{out} = \mathbf{A}\cdot \mathbf{A}\cdots \mathbf{A} \mathbf{v}_{in} = \mathbf{A}^N \mathbf{v}_{in}.\]

Bu modeller ilklendirildiğinde, \(A\) Gauss girdileri olan rastgele bir matris olarak alınır, bu yüzden onlardan birini yapalım. Somut olmak gerekirse, ortalama sıfır, değişinti (varyans) bir olan Gauss dağılımından gelen bir \(5\times 5\) matrisi ile başlıyoruz.

np.random.seed(8675309)

k = 5
A = np.random.randn(k, k)
A
array([[ 0.58902366,  0.73311856, -1.1621888 , -0.55681601, -0.77248843],
       [-0.16822143, -0.41650391, -1.37843129,  0.74925588,  0.17888446],
       [ 0.69401121, -1.9780535 , -0.83381434,  0.56437344,  0.31201299],
       [-0.87334496,  0.15601291, -0.38710108, -0.23920821,  0.88850104],
       [ 1.29385371, -0.76774106,  0.20131613,  0.91800842,  0.38974115]])
torch.manual_seed(42)

k = 5
A = torch.randn(k, k, dtype=torch.float64)
A
tensor([[ 0.2996,  0.2424,  0.2832, -0.2329,  0.6712],
        [ 0.7818, -1.7903, -1.7484,  0.1735, -0.1182],
        [-1.7446, -0.4695,  0.4573,  0.5177, -0.2771],
        [-0.6641,  0.6551,  0.2616, -1.5265, -0.3311],
        [-0.6378,  0.1072,  0.7096,  0.3009, -0.2869]], dtype=torch.float64)
k = 5
A = tf.random.normal((k, k), dtype=tf.float64)
A
<tf.Tensor: shape=(5, 5), dtype=float64, numpy=
array([[-0.64241693,  0.46744037, -1.04704188,  0.87126171,  0.75035732],
       [-0.78274106, -0.50938515,  0.82650349,  0.428774  , -2.01193394],
       [-0.5753367 ,  0.52193376,  1.88873707,  0.07065693, -1.17942956],
       [ 0.88036076, -0.12285584,  1.43576121,  0.63153031, -0.29144734],
       [ 0.07963274, -0.2155769 , -1.02987077, -0.05746226,  1.45934347]])>

18.2.6.2. Rastgele Verilerde Davranış

Oyuncak modelimizde basitlik sağlamak için, \(\mathbf{v}_{in}\) ile beslediğimiz veri vektörünün rastgele beş boyutlu bir Gauss vektörü olduğunu varsayacağız. Ne olmasını istediğimizi düşünelim. Bağlam için, bir imge gibi girdi verilerini, imgenin bir kedi resmi olma olasılığı gibi bir tahmine dönüştürmeye çalıştığımız genel bir makine öğrenmesi problemini düşünelim. Tekrarlanan \(\mathbf{A}\) uygulaması rastgele bir vektörü çok uzun olacak şekilde esnetirse, o zaman girdideki küçük değişiklikler çıktıdaki büyük değişikliklere yükseltilir — girdi imgesindeki küçük değişiklikler çok farklı tahminlere yol açar. Bu doğru görünmüyor!

Diğer taraftan, \(\mathbf{A}\) rasgele vektörleri daha kısa olacak şekilde küçültürse, o zaman birçok katmandan geçtikten sonra, vektör esasen hiçbir şeye (sıfıra yakın) küçülür ve çıktı girdiye bağlı olmaz. Bu da açıkça doğru değil!

Çıktımızın girdimize bağlı olarak değiştiğinden emin olmak için büyüme ve bozulma arasındaki dar çizgide yürümemiz gerekir, ancak çok fazla değil!

\(\mathbf{A}\) matrisimizi rastgele bir girdi vektörüyle tekrar tekrar çarptığımızda ne olacağını görelim ve normunu takip edelim.

# `A`'yı tekrar tekrar uyguladıktan sonra normların dizisini hesapla
v_in = np.random.randn(k, 1)

norm_list = [np.linalg.norm(v_in)]
for i in range(1, 100):
    v_in = A.dot(v_in)
    norm_list.append(np.linalg.norm(v_in))

d2l.plot(np.arange(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_39_0.svg
# `A`'yı tekrar tekrar uyguladıktan sonra normların dizisini hesapla
v_in = torch.randn(k, 1, dtype=torch.float64)

norm_list = [torch.norm(v_in).item()]
for i in range(1, 100):
    v_in = A @ v_in
    norm_list.append(torch.norm(v_in).item())

d2l.plot(torch.arange(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_42_0.svg
# `A`'yı tekrar tekrar uyguladıktan sonra normların dizisini hesapla
v_in = tf.random.normal((k, 1), dtype=tf.float64)

norm_list = [tf.norm(v_in).numpy()]
for i in range(1, 100):
    v_in = tf.matmul(A, v_in)
    norm_list.append(tf.norm(v_in).numpy())

d2l.plot(tf.range(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_45_0.svg

Norm kontrolsüz bir şekilde büyüyor! Nitekim bölüm listesini alırsak, bir desen göreceğiz.

# Normların ölçeklendirme çarpanını hesapla
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i - 1])

d2l.plot(np.arange(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_51_0.svg
# Normların ölçeklendirme çarpanını hesapla
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i - 1])

d2l.plot(torch.arange(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_54_0.svg
# Normların ölçeklendirme çarpanını hesapla
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i - 1])

d2l.plot(tf.range(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_57_0.svg

Yukarıdaki hesaplamanın son kısmına bakarsak, rastgele vektörün 1.974459321485[...] çarpanı ile esnediğini görürüz, burada son kısım biraz kayar, ancak esneme çarpanı sabittir.

18.2.6.3. Özvektörlerle İlişkilendirme

Özvektörlerin ve özdeğerlerin, bir şeyin gerildiği (esnetildiği) miktara karşılık geldiğini gördük, ancak bu, belirli vektörler ve belirli gerilmeler içindi. \(\mathbf{A}\) için ne olduklarına bir göz atalım. Burada bir uyarı: Hepsini görmek için karmaşık sayılara gitmemiz gerekeceği ortaya çıkıyor. Bunları esnemeler ve dönüşler olarak düşünebilirsiniz. Karmaşık sayının normunu (gerçek ve sanal kısımların karelerinin toplamının karekökü) alarak, bu esneme çarpanını ölçebiliriz. Bunları da sıralayabiliriz.

# Özdeğerleri hesapla
eigs = np.linalg.eigvals(A).tolist()
norm_eigs = [np.absolute(x) for x in eigs]
norm_eigs.sort()
print(f'norms of eigenvalues: {norm_eigs}')
norms of eigenvalues: [0.8786205280381857, 1.2757952665062624, 1.4983381517710659, 1.4983381517710659, 1.974459321485074]
# Özdeğerleri hesapla
eigs = torch.eig(A)[0][:,0].tolist()
norm_eigs = [torch.abs(torch.tensor(x)) for x in eigs]
norm_eigs.sort()
print(f'norms of eigenvalues: {norm_eigs}')
norms of eigenvalues: [tensor(0.3490), tensor(0.5691), tensor(0.5691), tensor(1.1828), tensor(2.4532)]
# Özdeğerleri hesapla
eigs = tf.linalg.eigh(A)[0].numpy().tolist()
norm_eigs = [tf.abs(tf.constant(x, dtype=tf.float64)) for x in eigs]
norm_eigs.sort()
print(f'norms of eigenvalues: {norm_eigs}')
norms of eigenvalues: [<tf.Tensor: shape=(), dtype=float64, numpy=0.6707651114229611>, <tf.Tensor: shape=(), dtype=float64, numpy=0.8539886978255797>, <tf.Tensor: shape=(), dtype=float64, numpy=1.3604962353327834>, <tf.Tensor: shape=(), dtype=float64, numpy=1.6990642471568578>, <tf.Tensor: shape=(), dtype=float64, numpy=3.349600378501881>]

18.2.6.4. Bir Gözlem

Burada biraz beklenmedik bir şey görüyoruz: Daha önce rasgele bir vektöre uzun vadeli gerilmesi için \(\mathbf{A}\) matrisimizi uygularken tanımladığımız sayı tam olarak (on üç ondalık basamağa kadar doğru!) \(\mathbf{A}\)’nın en büyük özdeğeridir. Bu açıkça bir tesadüf değil!

Ama şimdi geometrik olarak ne olduğunu düşünürsek, bu mantıklı gelmeye başlar. Rastgele bir vektör düşünün. Bu rasgele vektör her yönü biraz işaret ediyor, bu nedenle özellikle en büyük özdeğerle ilişkili \(\mathbf{A}\) özvektörüyle çok az olsa bile bir miktar aynı yönü gösteriyor. Bu o kadar önemlidir ki ana (esas) özdeğer ve ana (esas) özvektör olarak adlandırılır. \(\mathbf{A}\)’yı uyguladıktan sonra, rastgele vektörümüz her olası özvektörle ilişkili olduğu gibi mümkün olan her yönde gerilir, ancak en çok bu özvektörle ilişkili yönde esnetilir. Bunun anlamı, \(A\)’da uygulandıktan sonra, rasgele vektörümüzün daha uzun olması ve ana özvektör ile hizalanmaya daha yakın bir yönü göstermesidir. Matrisi birçok kez uyguladıktan sonra, ana özvektörle hizalama gittikçe daha yakın hale gelir, ta ki tüm pratik amaçlar için rastgele vektörümüz temel özvektöre dönüştürülene kadar! Aslında bu algoritma, bir matrisin en büyük özdeğerini ve özvektörünü bulmak için kuvvet yinelemesi olarak bilinen şeyin temelidir. Ayrıntılar için, örneğin, bkz. (Van Loan and Golub, 1983).

18.2.6.5. Normalleştirmeyi (Düzgelemeyi) Düzeltme

Şimdi, yukarıdaki tartışmalardan, rastgele bir vektörün esnetilmesini veya ezilmesini istemediğimiz sonucuna vardık, rastgele vektörlerin tüm süreç boyunca yaklaşık aynı boyutta kalmasını istiyoruz. Bunu yapmak için, şimdi matrisimizi bu ana özdeğere göre yeniden ölçeklendiriyoruz, böylece en büyük özdeğer şimdi eskinin yerine sadece bir olur. Bakalım bu durumda ne olacak.

# `A` matrisini yeniden ölçeklendir
A /= norm_eigs[-1]

# Aynı deneyi tekrar yapın
v_in = np.random.randn(k, 1)

norm_list = [np.linalg.norm(v_in)]
for i in range(1, 100):
    v_in = A.dot(v_in)
    norm_list.append(np.linalg.norm(v_in))

d2l.plot(np.arange(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_75_0.svg
# `A` matrisini yeniden ölçeklendir
A /= norm_eigs[-1]

# Aynı deneyi tekrar yapın
v_in = torch.randn(k, 1, dtype=torch.float64)

norm_list = [torch.norm(v_in).item()]
for i in range(1, 100):
    v_in = A @ v_in
    norm_list.append(torch.norm(v_in).item())

d2l.plot(torch.arange(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_78_0.svg
# `A` matrisini yeniden ölçeklendir
A /= norm_eigs[-1]

# Aynı deneyi tekrar yapın
v_in = tf.random.normal((k, 1), dtype=tf.float64)

norm_list = [tf.norm(v_in).numpy()]
for i in range(1, 100):
    v_in = tf.matmul(A, v_in)
    norm_list.append(tf.norm(v_in).numpy())

d2l.plot(tf.range(0, 100), norm_list, 'Iteration', 'Value')
../_images/output_eigendecomposition_ee2e00_81_0.svg

Aynı zamanda ardışık normlar arasındaki oranı daha önce olduğu gibi çizebiliriz ve gerçekten dengelendiğini görebiliriz.

# Oranı da çiz
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i-1])

d2l.plot(np.arange(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_87_0.svg
# Oranı da çiz
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i-1])

d2l.plot(torch.arange(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_90_0.svg
# Oranı da çiz
norm_ratio_list = []
for i in range(1, 100):
    norm_ratio_list.append(norm_list[i]/norm_list[i-1])

d2l.plot(tf.range(1, 100), norm_ratio_list, 'Iteration', 'Ratio')
../_images/output_eigendecomposition_ee2e00_93_0.svg

18.2.7. Sonuçlar

Şimdi tam olarak ne umduysak görüyoruz! Matrisleri ana özdeğere göre normalleştirdikten sonra, rastgele verilerin eskisi gibi patlamadığını görüyoruz, bunun yerine nihai belirli bir değerde dengelenirler. Bunları ilk ana özdeğerlerden yapabilmek güzel olurdu ve matematiğine derinlemesine bakarsak, bağımsız, ortalaması sıfır varyansı bir olan Gauss dağılımlı girdileri olan büyük bir rastgele matrisin en büyük özdeğerinin, ortalamada yaklaşık \(\sqrt{n}\) veya bizim durumumuzda \(\sqrt{5}\approx 2.2\) civarında olduğunu görebiliriz; bu dairesel yasa olarak bilinen büyüleyici bir gerçekten kaynaklanır (Ginibre, 1965). Rastgele matrislerin özdeğerlerinin (ve tekil değerler olarak adlandırılan ilgili bir konunun) arasındaki ilişkinin, şu adreste (Pennington et al., 2017) ve sonraki çalışmalarda tartışıldığı gibi sinir ağlarının uygun şekilde ilklendirilmesiyle derin bağlantıları olduğu gösterilmiştir.

18.2.8. Özet

  • Özvektörler, yön değiştirmeden bir matris tarafından esnetilen vektörlerdir.

  • Özdeğerler, özvektörlerin matris uygulamasıyla gerildikleri miktardır.

  • Bir matrisin özayrışımı, birçok işlemin özdeğerler üzerindeki işlemlere indirgenmesine izin verebilir.

  • Gershgorin Çember Teoremi, bir matrisin özdeğerleri için yaklaşık değerler sağlayabilir.

  • Yinelenen matris kuvvetlerinin davranışı, öncelikle en büyük özdeğerin boyutuna bağlıdır. Bu anlayış, sinir ağı ilkleme teorisinde birçok uygulamaya sahiptir.

18.2.9. Alıştırmalar

  1. Aşağıdaki matrisin özdeğerleri ve özvektörleri nedir?

    (18.2.21)\[\begin{split}\mathbf{A} = \begin{bmatrix} 2 & 1 \\ 1 & 2 \end{bmatrix}\end{split}\]
  2. Aşağıdaki matrisin özdeğerleri ve özvektörleri nelerdir ve bu örnekte bir öncekine kıyasla garip olan nedir?

    (18.2.22)\[\begin{split}\mathbf{A} = \begin{bmatrix} 2 & 1 \\ 0 & 2 \end{bmatrix}\end{split}\]
  3. Özdeğerleri hesaplamadan, aşağıdaki matrisin en küçük özdeğerinin \(0.5\)’den az olması mümkün müdür? Not: Bu problemi kafanızda yapılabilirsiniz.

    (18.2.23)\[\begin{split}\mathbf{A} = \begin{bmatrix} 3.0 & 0.1 & 0.3 & 1.0 \\ 0.1 & 1.0 & 0.1 & 0.2 \\ 0.3 & 0.1 & 5.0 & 0.0 \\ 1.0 & 0.2 & 0.0 & 1.8 \end{bmatrix}.\end{split}\]