Ana içeriğe geç

Makine Öğrenmesine Giriş - Normlar

Kodu ve görselleştirmeyi kullanarak lineer cebiri öğrenin.
· 15 dk. oku

Yapay Zeka ile Keşfedin

Giriş

Lineer cebir, veri biliminde ihtiyaç duyduğumuz temel matematiksel araçlardan biridir. Bu kavramları bir miktar anlamak, çeşitli algoritmaları daha iyi kavramanıza yardımcı olabilir. Veri bilimi/makine öğrenmesi yolculuğu için gerçekten mükemmel bir temel sunar.

Bu eğitimin amacı, Python/Numpy ile kod yazarak veri bilimi için matematiğe giriş yapmaktır. Lineer cebir gibi teorik konularda pratik dersler yapmanın faydalı olabileceğini düşünüyorum; çünkü kod yazmak ve okumak matematiksel kavramları gerçekten anlamanın iyi bir yoludur. Ve hepsinden önemlisi, bunun çok eğlenceli olabileceğine inanıyorum!

Özel bir ön koşul yoktur; ancak matrisin ne olduğunu veya skaler çarpımı nasıl yapacağınızı bilmiyorsanız, Ian Goodfellow’un derin öğrenme kitabına dair serimin ilk yazıları (1’den 4’e) iyi bir başlangıçtır.

Bu derste, makine öğrenmesi ve derin öğrenme için önemli bir kavrama yaklaşacağız: norm. Norm, örneğin bir modelin başarımını değerlendirmek için yaygın olarak kullanılır. Bu dersin sonunda, umarım bu kavrama ve makine öğrenmesinde neden bu kadar değerli olduğuna dair daha iyi bir sezgi kazanmış olacaksınız. Ayrıca, normun türevinin bir makine öğrenmesi algoritmasını eğitmek için nasıl kullanıldığını da göreceğiz.

Temel Kurulum

Her şeyden önce, kullanacağımız kütüphaneleri kuracağız:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

Ve bs komutu için kalın semboller, norm komutu için norm sembolü olacak şekilde bazı LaTeX kısayolları ekleyelim:

$$
\newcommand\bs[1]{\boldsymbol{#1}}
\newcommand\norm[1]{\left\lVert#1\right\rVert}
$$

$$ \newcommand\bs[1]{\boldsymbol{#1}} \newcommand\norm[1]{\left\lVert#1\right\rVert} $$

Ayarlamamız gereken son şey, oluşturacağımız grafiklerin görünümü:

# Plot parameters
sns.set()
%pylab inline
pylab.rcParams['figure.figsize'] = (4, 4)
plt.rcParams['xtick.major.size'] = 0
plt.rcParams['ytick.major.size'] = 0
Populating the interactive namespace from numpy and matplotlib

Pratik Bir Örnek

Basit bir örnekle başlayalım. Farklı özellikler içeren şarkılardan oluşan bir veri kümeniz olduğunu hayal edin. Şimdi, müzik türü, enstrümantasyon vb. gibi diğer özelliklere göre bir şarkının süresini tahmin eden bir model kurmak istediğinizi varsayalım. Bir model eğittiniz ve artık onu yeni bir şarkının süresini tahmin etmede değerlendirmek istiyorsunuz. Bunu yapmanın bir yolu, bazı yeni verileri alıp modelinizle şarkı sürelerini tahmin etmektir. Bu gözlemler için her şarkının gerçek süresini bildiğinizden, her gözlem için gerçek ve tahmin edilen süreleri karşılaştırabilirsiniz. 7 gözlem için saniye cinsinden aşağıdaki sonuçlara sahipsiniz:

errorModel1 = [22, -4, 2, 7, 6, -3, 12]

Bu farklar, modelin hatası olarak düşünülebilir. Mükemmel bir model yalnızca 0’lardan oluşurken, çok kötü bir modelde devasa pozitif veya negatif değerler olurdu.

Şimdi başka bir modeli denediğinizi ve tahmin edilen ve gerçek şarkı süreleri arasındaki farkların aşağıdaki gibi olduğunu hayal edin:

errorModel2 = [14, 9, -13, 19, 8, -21, 4]

En iyi modeli bulmak istiyorsanız ne yapabilirsiniz? Doğal bir yol, bu hataların mutlak değerlerinin toplamını almak olurdu. Mutlak değer kullanılır çünkü negatif bir hata (gerçek sürenin tahmin edilenden küçük olması) da hatadır. Toplam hata ne kadar küçükse model o kadar iyidir:

totalErrorModel1 = np.sum(np.abs(errorModel1))
totalErrorModel1
56
totalErrorModel2 = np.sum(np.abs(errorModel2))
totalErrorModel2
88

Görünüşe göre model 1, model 2’ye kıyasla epey daha iyi.

Tebrikler! Her model için hata vektörünün normunu az önce hesapladınız!

Sezgi

Normu, vektörün uzunluğu olarak düşünebilirsiniz. Bunun grafiksel temsilini kafanızda canlandırmak için, önceki örneğimize geri dönelim. Hata vektörleri çok boyutludur: her gözlem için bir boyut vardır. Son örnekte, 7 gözlem 7 boyuta karşılık geliyordu. 7 boyutu temsil etmek hâlâ zor olduğu için örneği tekrar basitleştirip yalnızca 2 gözlemi tutalım:

errorModel1 = [22, -4]
errorModel2 = [14, 9]

Artık bu vektörleri, dizinin ilk elemanının x-koordinatı, ikinci elemanının y-koordinatı olduğunu kabul ederek temsil edebiliriz. Vektörleri kolayca çizmek ve görünümleri hakkında fikir sahibi olmak için bir fonksiyon yazarak başlayacağız.

Python ve Matplotlib ile Vektörler Nasıl Çizilir

Vektörleri çizmemize yardımcı olacak bir fonksiyona ihtiyacımız var. Önce onu nasıl kullanacağımızla başlayalım. Vektörlerin koordinatlarına karşılık gelen dizi listesini vermek ve bu vektörlerin çizimini almak istiyoruz. Ayrıca grafikte vektörleri ayırt edebilmek için bir renk dizisi de verebileceğimizi varsayalım. Özetle, fonksiyonu şu şekilde çağırmak isteriz:

plotVectors([vector1, vector2], ['red', 'blue'])

Bu fonksiyonu yazalım:

def plotVectors(vecs, cols, alpha=1):
    """
    Plot set of vectors.

    Parameters
    ----------
    vecs : array-like
        Coordinates of the vectors to plot. Each vector is in an array. For
        instance: [[1, 3], [2, 2]] can be used to plot 2 vectors.
    cols : array-like
        Colors of the vectors. For instance: ['red', 'blue'] will display the
        first vector in red and the second in blue.
    alpha : float
        Opacity of vectors

    Returns:

    fig : instance of matplotlib.figure.Figure
        The figure of the vectors
    """
    plt.axvline(x=0, color='#A9A9A9', zorder=0)
    plt.axhline(y=0, color='#A9A9A9', zorder=0)

    for i in range(len(vecs)):
        if (isinstance(alpha, list)):
            alpha_i = alpha[i]
        else:
            alpha_i = alpha
        if (len(vecs[i])==2):
            x = np.concatenate([[0,0],vecs[i]])
        elif (len(vecs[i])==4):
            x = vecs[i]
        plt.quiver([x[0]],
                   [x[1]],
                   [x[2]],
                   [x[3]],
                   angles='xy', scale_units='xy', scale=1, color=cols[i],
                  alpha=alpha_i)

Girdi olarak çizilecek vektörlerin dizisini (vecs) ve renklerini (cols) alır. Vektörde yalnızca 2 boyut belirtilmişse, (0, 0)’dan başlatır. Arka planda, bu vektör dizisi üzerinde yineleme yapar ve çizim için plt.quiver() kullanırız.

Şimdi yeni fonksiyonumuzu kullanarak 1 ve 2 numaralı modelin hatalarını çizelim:

plotVectors([errorModel1, errorModel2], [sns.color_palette()[0], sns.color_palette()[1]])

plt.xlim(-1, 25)
plt.ylim(-5, 10)
plt.show()
graph

Not: Limitler gibi çizim yapılandırmaları ekleyebilmek için plt.show()’u fonksiyonun içine koymadık.

Not 2: sns.color_palette() ile seaborn’un renklerini elle kullandık

Bu şekilde her model için birer hata vektörümüz var. Daha iyi model, sadece daha kısa vektöre karşılık gelen modeldir. Vektörlerin uzunluğunu hesaplamanın bir yolu Pisagor teoremidir: $\sqrt{x^2+y^2}$. İki vektörün uzunluğunu hesaplayabiliriz:

# Lenght of the vector errorModel1
np.sqrt(errorModel1[0]**2+errorModel1[1]**2)
22.360679774997898
# Lenght of the vector errorModel2
np.sqrt(errorModel2[0]**2+errorModel2[1]**2)
16.643316977093239

Tebrikler! Hata vektörlerinin başka bir normunu daha hesapladınız. Birinci modelin hata vektörünün uzunluğu $22.36$, ikinci modelin hata vektörünün uzunluğu ise yaklaşık $16.64$. Bu durumda ikinci model daha iyi, ancak yalnızca ilk iki değeri kullandığımızı unutmayın.

Önce hataların toplamını hesapladık, ancak bir vektörün normunu hesaplamak için Pisagor teoremini de kullanabiliriz. Bunlar iki farklı normdur ve normların birden fazla şekilde hesaplanabileceğini gösterir.

Norm Fonksiyonları: Tanımlar

Bir vektörün normu, bir vektörü pozitif bir değere eşleyen herhangi bir fonksiyon olabilir. Farklı fonksiyonlar kullanılabilir; birkaç örnek göreceğiz. Bu fonksiyonlar, aşağıdaki özelliklerle karakterize ediliyorsa norm olarak adlandırılabilir:

  • Normlar negatif olmayan değerlerdir. Normları uzunluk olarak düşünürseniz, neden negatif olamayacağını kolayca görebilirsiniz.

  • Vektör sıfır vektörü olduğunda ve ancak o zaman normlar $0$’dır.

  • Normlar üçgen eşitsizliğine uyar. Aşağıya bakın.

  • $\norm{k\cdot \bs{u}}=\norm{k}\cdot\norm{\bs{u}}$. Burada $k$ bir skaler, $\bs{u}$ bir vektördür. Bir vektörün bir skalerle çarpımının normu, bu skalerin mutlak değeri ile vektörün normunun çarpımına eşittir.

Genellikle iki dikey çizgiyle yazılır: $\norm{\bs{x}}$

Üçgen Eşitsizliği

Yukarıda bir fonksiyonun norm olarak adlandırılabilmesi için üçgen eşitsizliğine uyması gerektiğini gördük. Bu, bazı vektörlerin toplamının normunun, bu vektörlerin normlarının toplamından küçük veya ona eşit olduğu anlamına gelir:

$$ \norm{\bs{u}+\bs{v}} \leq \norm{\bs{u}}+\norm{\bs{v}} $$

Örnek 1.

Bunun ne anlama geldiğini göstermek için, her biri iki eleman içeren iki vektör alacağız (yine x ve y koordinatları olarak temsil etmek için kullanışlı). Vektörlerimiz şunlardır:

$$ \bs{u}= \begin{bmatrix} 1 & 6 \end{bmatrix} $$
u = np.array([1, 6])
u
array([1, 6])

ve

$$ \bs{v}= \begin{bmatrix} 4 & 2 \end{bmatrix} $$
v = np.array([4, 2])
v
array([4, 2])

Kıyaslayalım:

$$ \norm{\bs{u}+\bs{v}} $$

ve:

$$ \norm{\bs{u}}+\norm{\bs{v}} $$

Normların farklı türlerini daha sonra göreceğiz, ancak şimdilik klasik olanı, Öklid Normu’nu ($L^2$) kullanacağız. $L^2$ normu Numpy’daki np.linalg.norm() fonksiyonuyla hesaplanabilir (bkz. dokümanda daha fazla detay).

$$ \norm{\bs{u}+\bs{v}} = \sqrt{(1+4)^2+(6+2)^2} = \sqrt{89} \approx 9.43 $$

$L^1$ veya $L^2$ normlarının ne olduğunu ayrıntılı olarak birazdan göreceğiz.

np.linalg.norm(u+v)
9.4339811320566032

ve

$$ \norm{\bs{u}}+\norm{\bs{v}} = \sqrt{1^2+6^2}+\sqrt{4^2+2^2} = \sqrt{37}+\sqrt{20} \approx 10.55 $$
np.linalg.norm(u)+np.linalg.norm(v)
10.554898485297798

Üçgen eşitsizliğinin sağlandığını görebiliriz; çünkü:

$$ \norm{\bs{u}+\bs{v}} \leq \norm{\bs{u}}+\norm{\bs{v}} $$

Grafiksel açıklama

Bu teoremin grafiksel temsili onu oldukça bariz kılar. plotVectors fonksiyonumuzu kullanarak $\bs{u}$, $\bs{v}$ ve $\bs{u}+\bs{v}$ vektörlerini çizecek ve vektörleri belirtmek için biraz metin ekleyeceğiz:

u = np.array([0,0,1,6])
v = np.array([0,0,4,2])
w = u+v

u_bis = [u[2], u[3], v[2], v[3]]

plotVectors([u, u_bis, w],
            [sns.color_palette()[0],
            sns.color_palette()[1],
            sns.color_palette()[2]])

plt.xlim(-2, 6)
plt.ylim(-2, 9)

plt.text(-1, 3.5, r'$||\vec{u}||$', color=sns.color_palette()[0], size=20)
plt.text(2.5, 7.5, r'$||\vec{v}||$', color=sns.color_palette()[1], size=20)
plt.text(2, 2, r'$||\vec{u}+\vec{v}||$', color=sns.color_palette()[2], size=20)

plt.show()
plt.close()
graph

$\bs{u}$’nun uzunluğu ile $\bs{v}$’nin uzunluğunun toplamı, $\bs{u}+\bs{b}$ vektörünün uzunluğundan daha büyüktür. Geometrik olarak bu, iki nokta arasındaki en kısa yolun bir doğru olduğunu söyler!

p-normlar: Genel Kurallar

Bir fonksiyonun norm olarak adlandırılması için gereken koşulları gördük. Bu, norm olarak kullanılabilecek birden fazla fonksiyon olduğu anlamına gelir. Bu farklı normların artılarını ve eksilerini daha sonra göreceğiz. $p$’ye bağlı olan şu fonksiyon kategorisine $p$-norm deriz:

$$ \norm{\bs{x}}_p=(\sum_i|\bs{x}_i|^p)^{1/p} $$

Bu denklemi adım adım inceleyelim. Elemanların toplamı olduğunu görebiliriz; dolayısıyla $i$ elemanları üzerinde bir yineleme gibi düşünebiliriz:

  1. $\vert\bs{x}_i\vert$ $i$. elemanın mutlak değerini hesaplayın
  2. $\vert\bs{x}_i\vert^p$ $p$ kuvvetini alın
  3. $\sum_i\vert\bs{x}_i\vert^p$ Bu kuvvetlendirilmiş mutlak değerlerin hepsini toplayın
  4. $(\sum_i\vert\bs{x}_i\vert^p)^{1/p}$ Sonucun $\frac{1}{p}$ kuvvetini alın

Bu, yaygın olarak kullanılan şu $p$-norm örnekleriyle netleşecektir.

$L^0$ normu

$p=0$ ise formül şu olur:

$$ \norm{\bs{x}}_0=(\sum_i|\bs{x}_i|^0)^{1/0} $$

Bakarsak ne anlama geldiğini görebiliriz. Mutlak değerlere 0 kuvvetini uygulamak, sıfır olmayan her değer için $1$, $0$ için ise $0$ verir.

Dolayısıyla bu norm, vektördeki sıfır olmayan elemanların sayısına karşılık gelir. Aslında tam anlamıyla bir norm değildir; çünkü vektörü $\alpha$ ile çarparsanız bu sayı değişmez (yukarıdaki kural 4).

$L^1$ normu

$p=1$ ise, basitçe mutlak değerlerin toplamına sahip oluruz. Bu, dersin başında sezgisel olarak kullandığımız şeydir:

function

$L^2$ normu (Öklid normu)

Öklid normu, $p=2$ olan $p$-normdur. Aşağıda göreceğimiz karesel $L^2$ normuyla birlikte en sık kullanılan norm olabilir.

$$ \norm{\bs{x}}_2=(\sum_i \bs{x}_i^2)^{1/2}=\sqrt{\sum_i \bs{x}_i^2} $$

$x$ kare alındığı için mutlak değere artık ihtiyaç olmadığını not edebiliriz. Yukarıda vektörlerimizin uzunluğunu Pisagor teoremiyle hesaplarken de bunu kullanmıştık.

Bu norma başka bir örnek görelim:

Örnek 2.

Grafiksel olarak, Öklid normu, orijinden doğrusal birleşimle elde edilen noktaya kadar olan vektörün uzunluğuna karşılık gelir (Pisagor teoremi). 2 boyutta bir örnek göreceğiz: $\bs{u}$ vektörünün x-koordinatı ve y-koordinatına karşılık gelen iki değeri vardır. Bu koordinatlarla noktayı çizip orijinden bu noktaya bir vektör çizerseniz, $L^2$ normu bu vektörün uzunluğu olacaktır.

Örneğin:

$$ \bs{u}= \begin{bmatrix} 3 \\ 4 \end{bmatrix} $$

Önce formülle normu hesaplayalım:

formula

Yani $L^2$ normu $5$’tir.

Bu arada, $L^2$ normunun Numpy’daki linalg.norm() fonksiyonuyla hesaplanabildiğini hatırlayın:

np.linalg.norm([3, 4])
5.0

Vektörün grafiksel temsili şöyle:

u = np.array([3, 4])

plt.ylim(-1, 5)
plt.xlim(-1, 5)
plotVectors([u], [sns.color_palette()[0]])
graph

Vektörün orijinden (0, 0) noktasından (3, 4) noktasına gittiğini ve uzunluğunun 5 olduğunu görebiliriz.

Bu durumda vektör 2 boyutlu bir uzayda, ancak bu daha fazla boyut için de geçerlidir.

$$ \bs{u}= \begin{bmatrix} u_1\\ u_2\\ \cdots \\ u_n \end{bmatrix} $$
$$ \norm{\bs{u}}_2 = \sqrt{u_1^2+u_2^2+\cdots+u_n^2} $$

Karesel Öklid normu (karesel $L^2$ normu)

$$ \norm{\bs{u}}_2^2 = (\sqrt{\sum_i \bs{x}_i^2})^2 = \sum_i\bs{x}_i^2 $$

Karesel $L^2$ normu kullanışlıdır; çünkü karekökü ortadan kaldırır ve vektördeki her bir değerin karesinin basit toplamına ulaşırız.

Karesel Öklid normu, kısmen $\bs{x}^\text{T}\bs{x}$ vektör işlemiyle hesaplanabildiği için makine öğrenmesinde yaygın olarak kullanılır. Optimizasyon sayesinde performans kazanımları olabilir. Daha fazla detay için buraya ve buraya bakın.

Örnek 3.

Bu örnekte, karesel Öklid normunun vektörleştirilmiş işlemlerle hesaplanabildiğini göreceğiz. $\bs{x}$ adlı bir vektörle başlayalım:

$$ \bs{x}= \begin{bmatrix} 2 \\ 5 \\ 3 \\ 3 \end{bmatrix} $$

Her zamanki gibi süreci doğrulamak için kod kullanacağız. Önce Numpy vektörümüz $\bs{x}$’i oluşturalım:

x = np.array([[2], [5], [3], [3]])
x
array([[2],
       [5],
       [3],
       [3]])

Şimdi bu vektörün transpozunu alalım. Bu, başlangıçtaki sütun vektörünü satır vektörüne dönüştürür:

$$ \bs{x}^\text{T}= \begin{bmatrix} 2 & 5 & 3 & 3 \end{bmatrix} $$

$\bs{x}$’in transpozunu Numpy nesnelerinin T yöntemiyle hesaplayabiliriz:

x.T
array([[2, 5, 3, 3]])

$\bs{x}$ ile $\bs{x}^\text{T}$’nin skaler çarpımı (skaler çarpım hakkında hatırlatmaya ihtiyacınız varsa bakın) aslında her elemanın kendisiyle çarpımına karşılık gelir:

formula

Bu tam olarak karesel Öklid normunun tanımıdır!

Numpy ile kontrol edelim. Unutmayın (ve kendinizi ikna etmek için deneyin) ki skaler çarpımda vektörlerin sırası önemlidir:

euclideanNorm = x.T.dot(x)
euclideanNorm
array([[47]])

Bu bizim karesel Öklid normumuz olmalı! $L^2$ normundan hesaplayıp karesini alarak doğrulayalım:

np.linalg.norm(x)**2
47.0

Çalışıyor! Vektörleştirilmiş bir işlem kullanabilme imkânı, diğer normlara göre büyük bir avantajdır.

Karesel $L^2$ normunun türevi

Normların, hata vektörlerini özetleyerek bir modelin başarımını değerlendirmekte kullanılabildiğini gördük.

Şimdi bir adım ileri gidip modelimizin parametrelerini toplam hatayı azaltacak şekilde nasıl değiştirebileceğimizi bilmek istiyoruz. Bunu yapmak için, parametre değerlerinin bir fonksiyonu olarak modelin hatasını ilişkilendiren bir maliyet fonksiyonu kullanabiliriz. Bu fonksiyonun minimumunu bulmak için gradyan inişi algoritması kullanılabilir. Gradyan inişi, her parametreye göre türevleri (kısmi türevler = gradyanlar) hesaplayarak yapılır. Bu nedenle, türevi verimli bir şekilde hesaplayabilmek kritik önemdedir.

Nitekim karesel $L^2$ normunun büyük bir avantajı, kısmi türevlerinin kolayca hesaplanabilmesidir. Şu vektörü ele alalım:

$$ \bs{u}= \begin{bmatrix} u_1\\ u_2\\ \cdots \\ u_n \end{bmatrix} $$

Karesel $L^2$ normunun şu şekilde hesaplandığını görmüştük:

$$ \norm{\bs{u}}_2^2 = u_1^2+u_2^2+\cdots+u_n^2 $$

Ardından kısmi türevleri hesaplamak için, diğer tüm değişkenleri sabit kabul ederiz. Örneğin, $u_1$’e göre kısmi türev, $u_1^2+a$’nın türevidir (burada $a$ diğer tüm değişkenlere karşılık gelen sabittir). Bu nedenle aşağıdaki kısmi türevleri elde ederiz:

$$ \begin{cases} \dfrac{d\norm{\bs{u}}_2^2}{du_1} = 2u_1\\ \dfrac{d\norm{\bs{u}}_2^2}{du_2} = 2u_2\\ \cdots\\ \dfrac{d\norm{\bs{u}}_2^2}{du_n} = 2u_n \end{cases} $$

Karesel $L^2$ normunun gradyanlarıyla ilgili güzel olan, türevlerin diğer değişkenlere bağlı olmamasıdır. $L^2$ normunda bunun böyle olmadığını göreceğiz.

$L^2$ normunun türevi

$L^2$ normu durumunda türev daha karmaşıktır ve vektörün her elemanını dikkate alır. Örnek olarak son vektör $\bs{u}$’yu ele alalım. $L^2$ normu şöyledir:

$$ \norm{\bs{u}}_2 = \sqrt{(u_1^2+u_2^2+\cdots+u_n^2)} = (u_1^2+u_2^2+\cdots+u_n^2)^{\frac{1}{2}} $$

Bunun $u_1$’e göre türevini hesaplayalım:

formula

$u_1$’in kısmi türevinin hâlâ $u_2...u_n$’yi içerdiğini görebiliriz. Diğer gradyanlar da aynı yapıyı izler:

$$ \begin{cases} \dfrac{d\norm{\bs{u}}_2}{du_1} = \dfrac{u_1}{\sqrt{(u_1^2+u_2^2+\cdots+u_n^2)}}\\ \dfrac{d\norm{\bs{u}}_2}{du_2} = \dfrac{u_2}{\sqrt{(u_1^2+u_2^2+\cdots+u_n^2)}}\\ \cdots\\ \dfrac{d\norm{\bs{u}}_2}{du_n} = \dfrac{u_n}{\sqrt{(u_1^2+u_2^2+\cdots+u_n^2)}}\\ \end{cases} $$

Diğer hususlar

Karesel $L^2$ normu harikadır, ancak bir sorunu, fonksiyonun yavaş artması nedeniyle 0 ile küçük değerleri ayırt etmesinin zor olmasıdır.

Bunu, karesel $L^2$ normunu $L^2$ normuyla grafiksel olarak karşılaştırarak görebiliriz. $z$ ekseni norma karşılık gelir, $x$ ve $y$ eksenleri iki parametreye karşılık gelir. Aynı şey 2’den fazla boyut için de geçerlidir, ancak görselleştirmesi zor olurdu.

$L^2$ normu:

formula

Karesel $L^2$ normu:

formula

Karşılaştırma için $L^1$ normu:

formula

Bu grafikler şu web sitesi yardımıyla yapılmıştır. Şekillerini daha iyi kavramak için bu normları gidip hareket ettirerek çizin.

Maksimum norm

$L^\infty$ normudur ve vektörün en büyük elemanının mutlak değerine karşılık gelir.

$$ \norm{\bs{x}}_\infty = \max\limits_i|x_i| $$

Matris normları: Frobenius normu

formula

Bu, düzleştirdikten sonra matrisin $L^2$ normunu almaya eşdeğerdir.

Aynı Numpy fonksiyonu kullanılabilir:

A = np.array([[1, 2], [6, 4], [3, 2]])
A
array([[1, 2],
       [6, 4],
       [3, 2]])
np.linalg.norm(A)
8.3666002653407556

Skaler çarpımın normlarla ifadesi

$$ \bs{x}^\text{T}\bs{y} = \norm{\bs{x}}_2\cdot\norm{\bs{y}}_2\cos\theta $$

$\bs{x}$ ve $\bs{y}$ vektörleri arasındaki skaler çarpım, bu vektörlerin $L^2$ normlarıyla elde edilebilir. $\theta$ iki vektör arasındaki açıdır.

Örnek 4.

İki boyutta iki vektör alalım:

$$ \bs{x}= \begin{bmatrix} 0 \\ 2 \end{bmatrix} $$

ve

$$ \bs{y}= \begin{bmatrix} 2 \\ 2 \end{bmatrix} $$

Aşağıdaki grafik, bunların görsel temsilini gösterir:

x = [0,0,0,2]
y = [0,0,2,2]

plotVectors([x, y], [sns.color_palette()[0], sns.color_palette()[1]])

plt.xlim(-1, 3)
plt.ylim(-1, 3)

plt.text(-0.5, 1, r'$\vec{x}$', size=18, color=sns.color_palette()[0])
plt.text(1.5, 0.5, r'$\vec{y}$', size=18, color=sns.color_palette()[1])
<matplotlib.text.Text at 0x10a33b950>
graph

Bu örneği basitliği için seçtik. Gördüğümüz gibi $\theta$ açısı 45°’dir.

Önce, vektörlerin skaler çarpımını hesaplayalım:

$$ \bs{x^\text{T}y}= \begin{bmatrix} 0 & 2 \end{bmatrix} \cdot \begin{bmatrix} 2 \\ 2 \end{bmatrix} = 0\times2+2\times2 = 4 $$
x = np.array([0, 2])
y = np.array([2, 2])

x.dot(y)
4

Şimdi de normlarını hesaplayalım:

$$ \norm{\bs{x}}_2=\sqrt{0^2+2^2}=\sqrt{4}=2 $$

ve

$$ \norm{\bs{y}}_2=\sqrt{2^2+2^2}=\sqrt{8} $$

Dolayısıyla yukarıdaki formülle:

$$ 2\times\sqrt{8}\times cos(45)=4 $$

Bu, skaler çarpımla elde ettiğimiz sonuçla aynıdır. Numpy kullanarak yapılan işlemler aşağıdadır. Sadece, np.cos radyan cinsinden açı aldığı için Numpy’daki deg2rad fonksiyonunu kullandığımıza dikkat edin; bu yüzden dönüşüm yapmamız gerekir.

# Note: np.cos take the angle in radian
np.cos(np.deg2rad(45))*2*np.sqrt(8)
4.0000000000000009

Sonuç

$L^2$ normu (matris durumunda Frobenius normu) ve karesel $L^2$ normu, makine öğrenmesi, derin öğrenme ve genel olarak veri biliminde yaygın olarak kullanılır. Örneğin, normlar birer maliyet fonksiyonu olarak kullanılabilir. Diyelim ki bir veri noktası kümesine bir doğru uydurmak istiyorsunuz. Daha iyi doğruyu bulmanın bir yolu, rastgele parametrelerle başlayıp maliyet fonksiyonunu minimize ederek yinelemektir. Maliyet fonksiyonu, modelinizin hatasını temsil eden bir fonksiyondur; dolayısıyla bu hatayı olabildiğince küçük tutmak istersiniz. Normlar burada faydalıdır; çünkü bu hatayı ölçmenin bir yolunu sunar. Norm, tüm hatalarınızı içeren vektörü basit bir skalara dönüştürür ve maliyet fonksiyonu, parametrelerinizin bir kümesi için bu skaler değerdir.

Normların, bir diziyi bir skalara indirgemekten ibaret olduğunu gördük. Ayrıca bunu hesaplamak için kullanabileceğimiz fonksiyona bağlı olarak bazı varyasyonlar olduğunu fark ettik. Hangi normun seçileceği, büyük ölçüde çözülecek probleme bağlıdır; çünkü birini ya da diğerini uygulamanın artıları ve eksileri vardır. Örneğin, $L^1$ normu, $L^2$ normuna göre daha dayanıklıdır. Bu, $L^2$ normunun aykırı değerlere daha duyarlı olduğu anlamına gelir; zira büyük hata değerleri, çok büyük karesel hata değerleri üretir.

Bu eğitim, Goodfellow ve diğerlerinin Derin Öğrenme Kitabı’ndaki lineer cebir bölümüne dair serimden bu makaleye dayanmaktadır.

Kaynaklar

https://www.quora.com/Why-is-L1-regularization-better-than-L2-regularization-provided-that-all-Norms-are-equivalent

http://www.deeplearningbook.org/contents/linear_algebra.html

https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.linalg.norm.html

https://hadrienj.github.io/deep-learning-book-series-home/

http://christopher5106.github.io/deep/learning/2016/09/16/about-loss-functions-multinomial-logistic-logarithm-cross-entropy-square-errors-euclidian-absolute-frobenius-hinge.html

https://datascience.stackexchange.com/questions/10188/why-do-cost-functions-use-the-square-error

Konular

İlgili