Logo
tensor X @ W X.T reshape ‖x‖₂ broadcast A·B A.sum()
Yapay Sinir Ağları · Hafta 01

Yapay Sinir Ağlarının
Dili

Tensör · Lineer Cebir · Hız — Sıfırdan Kur, Anla, Hızlandır

▌Y = X @ W  # her ağ, özünde bu
Dönemin Haritası

YSA'nın Tarihi = Bu Dönemin Planı

Biyolojik nörondan esinlenen 80 yıllık bir hikâye — her dönüm noktası bir hafta. Hepsi aynı dili konuşuyor: bu haftanın araçları.

01 · Temeller H1–H4

1943 McCulloch–Pitts: nöronun matematiksel modeli → H2
1949 Hebb kuralı → H3
1958 Rosenblatt perceptronu → H4
1960 Widrow–Hoff, Delta kuralı → H3

araç: nokta çarpım · türev

02 · Çok Katmanlı H5–H8

1969 Minsky–Papert: tek katman XOR'u çözemez → H4–H5
1986 Rumelhart–Hinton–Williams: geri yayılım → H6–H7

araç: matris çarpımı · zincir kuralı

03 · İleri Mimariler H10–H13

1982 Hopfield ağı → H13
1982 Kohonen SOM → H11
1987 ART (Carpenter–Grossberg) → H13
1988 RBF ağları → H10 · LVQ → H12

araç: norm · uzaklık ‖x−c‖

04 · Derin Öğrenme H14–H15

1989 LeCun: evrişimli ağ (CNN) → H14
2012 AlexNet: GPU + derin CNN → H15

araç: 4B tensör · broadcasting · GPU

Bu hafta: tensör (veri) ve lineer cebir (hesap) — NumPy/PyTorch ile uygulamalı. Türev (değişim) Hafta 3'te, öğrenme kurallarıyla birlikte; otomatik türev (autograd) 7. haftada.

Neden Bunlar?

Her Ağ, Aynı Üç Şey

Veri → Tensör

Görüntü, ses, metin — hepsi sayı dizisi olur.

Hesap → Matris

Katman = matris çarpımı; hızlı, paralel.

Değişim → Türev

"Hangi yöne?" sorusunun cevabı. Hafta 3'te, öğrenmeyle birlikte.

Bu hafta ilk ikisini elle anlayıp koda dökeceğiz; türev Hafta 3'te. Dersin geri kalanı hep bu üç dilin cümleleri.

Veri İşleme

Tensör: Yapıtaşı & Oluşturma

30B skaler
314
1B vektör
012345
2B matris (2×3)
····
····
3B+ tensör
import torch
x = torch.arange(6)          # [0, 1, 2, 3, 4, 5]

X = x.reshape(2, 3)          # [[0, 1, 2],
                             #  [3, 4, 5]]
X.shape                      # (2, 3)  ·  X.numel() → 6
torch.zeros(2, 3)            # sıfır matrisi (torch.ones / torch.randn)

shape = boyutlar, numel = eleman sayısı. NumPy'da birebir: np.arange, reshape.

İndeksleme

Eriş, Dilimle, Ata

X = torch.arange(12).reshape(3, 4)
#  [[ 0,  1,  2,  3],
#   [ 4,  5,  6,  7],
#   [ 8,  9, 10, 11]]
X[-1]      # [8, 9, 10, 11]   son satır
X[:, 1]    # [1, 5, 9]        2. sütun
X[1, 2]    # 6                tek eleman

Python gibi 0-tabanlı; a:b aralığı b hariç. : "tüm o eksen" demek.

Dilime atama yapabilirsin — tek seferde bir bloğu güncelle.

Negatif indeks sondan sayar: X[-1] son satır, X[:, -1] son sütun.

İşlemler

Eleman-Eleman & Birleştirme

x = torch.tensor([1., 2, 4, 8])
y = torch.tensor([2., 2, 2, 2])
x + y     # [ 3.,  4.,  6., 10.]
x * y     # [ 2.,  4.,  8., 16.]
x ** y    # [ 1.,  4., 16., 64.]
torch.exp(x)         # [2.7, 7.4, 54.6, 2981.]
torch.cat((x, y))    # [1,2,4,8, 2,2,2,2]

Standart işlemler (+ - * / **) aynı şekilli tensörlerde eleman-eleman çalışır.

cat ile eksende birleştir; == ile maske üret; X.sum() ile topla.

Kural: döngü değil, tüm tensör üstünde tek işlem düşün — birazdan bunun hız demek olduğunu ölçeceğiz.

Broadcasting

Farklı Şekiller Nasıl Toplanır?

123
+
1020
=
1121 1222 1323
3×1 + 1×2 → 3×2
a = torch.tensor([[1], [2], [3]])   # 3×1
b = torch.tensor([[10, 20]])        # 1×2
a + b        # → [[11, 21], [12, 22], [13, 23]]  (3×2, döngüsüz!)

Boyut 1 olan eksen otomatik tekrarlanır. Bias eklerken (X @ W + b) tam bunu kullanacağız.

Bellek & Dönüşüm

Yerinde İşlem & NumPy ↔ Torch

X, Y = torch.ones(3, 4), torch.ones(3, 4)
before = id(Y)
Y = Y + X;   id(Y) == before   # False → yeni bellek!

Z = torch.zeros_like(Y);  Z[:] = X + Y   # yerinde yaz
X += Y                                    # yerinde (bellek dostu)
A = X.numpy()            # Torch → NumPy
B = torch.from_numpy(A)  # NumPy → Torch

a = torch.tensor([3.5])
a.item()                 # → 3.5  (1-elemanlı → sayı)

Büyük tensörlerde yerinde işlem (+=, [:]) gereksiz kopya üretmez. .numpy() / from_numpy kopyalamaz — bellek paylaşılır: birini değiştirirsen öteki de değişir!

Ön İşleme · pandas

Ham Veri → Temiz Tablo

OdaAlan_m2IsitmaFiyat
3120Kombi4200
NaN95Soba2900
2NaNKombi3100
4150NaN5600
3115Soba3800
girdiler (özellikler) · hedef: fiyat, bin ₺ ev.csv indir
import pandas as pd
data = pd.read_csv('ev.csv')   # 5 ev × 4 sütun (soldaki tablo)
data.isna().sum()   # sütun başına eksik: Oda 1, Alan_m2 1, Isitma 1

X = data.iloc[:, :3]   # girdiler: ilk 3 sütun (Oda, Alan_m2, Isitma)
y = data.iloc[:, 3]    # hedef: 4. sütun (Fiyat)

Üç sorun var: ① sayısal eksik (Oda, Alan_m2) · ② kategorik eksik (Isitma) · ③ metin değerler (Kombi, Soba). Model yalnız sayı anlar → önce temizlemeliyiz.

Hazırla & Çevir

Eksiği Doldur, Tensöre Çevir

X = X.fillna({'Isitma': 'Bilinmiyor'})  # ② kategorik eksik → yeni kategori
X = pd.get_dummies(X, dtype=float)       # ③ metin → 0/1 sütunlar (one-hot)
X = X.fillna(X.mean())                   # ① sayısal eksik → sütun ortalaması
X = torch.tensor(X.values, dtype=torch.float32)  # X.shape → (5, 5)
OdaAlan_m2Isitma_BilinmiyorIsitma_KombiIsitma_Soba
3120010
395001
2120010
4150100
3115001

yeşil = eksikti, dolduruldu · 4 sütun → 5 sütun, hepsi sayı

② "Bilgi yok" da bir bilgidir: eksik ısıtma Bilinmiyor adlı kendi kategorisi olur.

③ get_dummies her kategoriye bir 0/1 sütun açar; her evde tam biri 1. dtype=float şart: pandas 2 varsayılanı True/False, torch.tensor hata verir.

① Oda: (3+2+4+3)/4 = 3 · Alan: (120+95+150+115)/4 = 120.

Ön işleme = veriyi eksiksiz sayısal tensöre çevirmek. (Not: ortalamayı tüm veriden aldık; 8. haftada neden yalnız eğitim verisinden alınması gerektiğini göreceğiz.)

Lineer Cebir

Skaler → Vektör → Matris

\[ x\in\mathbb{R}, \quad \mathbf{x}\in\mathbb{R}^{n}, \quad \mathbf{A}\in\mathbb{R}^{m\times n} \]

🔈 okunuş: ∈ “elemanıdır”: x ∈ ℝ → x bir reel sayıdır·ℝ “reel sayılar”: ℝⁿ: n elemanlı reel vektör

x = torch.tensor(3.0)               # skaler
v = torch.arange(4)                 # [0, 1, 2, 3]
A = torch.arange(6).reshape(3, 2)   # [[0,1],[2,3],[4,5]]

A.T                                 # [[0,2,4],[1,3,5]]  (2×3)

Vektör = bir eksen, matris = iki eksen, tensör = n eksen. Devrik satır↔sütun takas eder.

Bir örnek genelde bir vektör; bir veri kümesi (batch) bir matris; bir grup görüntü bir 4B tensör.

Aritmetik

Hadamard Çarpımı (eleman-eleman)

\[ (\mathbf{A}\odot\mathbf{B})_{ij} = A_{ij}\,B_{ij} \] \[ \begin{bmatrix}1&2\\3&4\end{bmatrix}\odot\begin{bmatrix}2&0\\1&3\end{bmatrix} = \begin{bmatrix}2&0\\3&12\end{bmatrix} \]

🔈 okunuş: ⊙ “hadamard”: eleman-eleman çarpım·Aij “A i j”: i. satır, j. sütun

A = torch.tensor([[1., 2], [3, 4]])
B = torch.tensor([[2., 0], [1, 3]])
A * B        # [[2, 0], [3, 12]]  Hadamard
A + 2        # her elemana skaler ekle
A * 2        # her elemanı ölçekle

Dikkat: A * B (Hadamard) ≠ A @ B (matris çarpımı). İlki eleman-eleman, ikincisi satır×sütun.

İndirgeme

Topla, Ortala, Eksen Seç

\[ \sum_{i} x_i, \qquad \bar{x} = \frac{1}{n}\sum_{i} x_i \]

🔈 okunuş: Σ “sigma (büyük)”: hepsini topla·x̄ “x bar”: ortalama

A = torch.arange(1., 7).reshape(2, 3)  # [[1,2,3],[4,5,6]]  (float!)
A.sum(), A.mean()              # 21., 3.5  (mean int'te hata verir)
A.sum(axis=0)                  # [5, 7, 9]   (sütunlar)
A.sum(axis=1)                  # [6, 15]     (satırlar)
A.sum(axis=1, keepdims=True)   # [[6],[15]]  boyut korunur

axis=0 satırlar boyunca toplar → sütun sonucu. keepdims ekseni 1 olarak tutar.

Normalizasyonda sık kalıp: A / A.sum(axis=1, keepdims=True) — keepdims sayesinde broadcast çalışır.

Sayısal Örnek

İndirgeme — Somut Sayılar

\[ A=\begin{bmatrix}1&2&3\\4&5&6\end{bmatrix} \]
\[ \text{sum(axis=0)}=\begin{bmatrix}5&7&9\end{bmatrix} \] sütunları topla ↓   (1+4, 2+5, 3+6)
\[ \text{sum(axis=1)}=\begin{bmatrix}6\\15\end{bmatrix} \] satırları topla →   (1+2+3, 4+5+6)

axis=0 → sütun toplamı, axis=1 → satır toplamı · ayrıca sum()=21, mean()=3.5.

Nokta Çarpım

Nokta Çarpım: Bir Nöronun Çekirdeği

\[ \mathbf{x}^\top \mathbf{y} = \sum_{i} x_i y_i \]

🔈 okunuş: xᵀ “x transpoz”: sütun vektörü satıra çevir

x = torch.tensor([1., 2., 3.])
w = torch.tensor([0.5, -1., 2.])

torch.dot(w, x)          # 0.5 - 2 + 6 = 4.5
torch.sum(w * x)         # aynı sonuç

Ağırlıklı toplam = nokta çarpım. Nöronun w·x + b ifadesinin ilk yarısı.

Tek nöron bir nokta çarpım; bir katman bunun yüzlercesi → matris çarpımı.

Çarpımlar

Katman = Matris Çarpımı

\[ (\mathbf{A}\mathbf{B})_{ij} = \sum_k A_{ik}B_{kj} \]
A = torch.tensor([[1., 2], [3, 4]])
x = torch.tensor([1., 1])
torch.mv(A, x)   # matris×vektör → [3., 7.]
torch.mm(A, A)   # matris×matris → [[7,10],[15,22]]
A @ A            # aynısı (NumPy'da: A @ B)

İç boyutlar uyuşmalı: (m×k)·(k×n) → m×n. Bir ağın tüm işi bu çarpımlara iner.

İyi haber: matris çarpımı utanç verecek kadar paralel — önce elle hesaplayalım, sonra hızını ölçelim.

Sayısal Örnek

Matris Çarpımı — Adım Adım

\[ \begin{bmatrix}{\color{#f87171}1}&{\color{#f87171}2}&{\color{#f87171}3}\\4&5&6\end{bmatrix} \begin{bmatrix}{\color{#34d399}1}&0\\{\color{#34d399}0}&1\\{\color{#34d399}1}&1\end{bmatrix} = \begin{bmatrix}{\color{#fbbf24}4}&5\\10&11\end{bmatrix} \]
\[ {\color{#fbbf24}C_{11}} = {\color{#f87171}1}\!\cdot\!{\color{#34d399}1} + {\color{#f87171}2}\!\cdot\!{\color{#34d399}0} + {\color{#f87171}3}\!\cdot\!{\color{#34d399}1} = {\color{#fbbf24}4} \]

Her hücre = soldaki satır · sağdaki sütun (nokta çarpım). Aynı mantık matris-vektörde de geçerli.

Etkileşimli · Tahmin Et → Ölç

Aynı Hesap, Farklı Hız

256×256 matris çarpımı = 2·256³ ≈ 33,6 milyon işlem · sonuçlar birebir aynı

① Tahmin: saf Python döngüsü, NumPy A @ B'den kaç kat yavaş?

③ Canlı ölç — şimdi, bu tarayıcıda. Önce tahmin: n iki katına çıkınca süre kaç kat artar?

[canlı] JavaScript · tek iş parçacığı · BLAS yok · 5 turun en iyisi

② Önceden ölçüldü (log ölçek, 256×256, laptop)

[ölçüldü] Surface Laptop 7 · Snapdragon X, 12 çekirdek · Python 3.12.4 · NumPy 1.26.3 · PyTorch 2.3.1 CPU · medyan · 29.09.2026

Fark döngü → vektörleştirme'den ve float64 → float32'den geliyor. Sürpriz: CPU'da NumPy = PyTorch (ikisi de BLAS çağırır). O zaman PyTorch neden var? → sonraki slayt

Etkileşimli · Neden PyTorch?

Gerçek Veri: MNIST'i Bir Katmandan Geçir

MNIST test kümesinden 0-9 el yazısı rakam örnekleri

Her rakam 28×28 = 784 piksel → reshape(-1) ile bir satır. 60.000 görüntü: X: (60000, 784) · W: (784, 512) → Y = X @ W ≈ 48 milyar işlem

① Tahmin: saf Python bunu ~7 dakikada yapıyor. PyTorch GPU'da kaç saniye sürer?
Y = X @ W                  # CPU
Xg = X.to('cuda')          # tek satır fark
Wg = W.to('cuda')
Yg = Xg @ Wg               # aynı kod, GPU'da

Veri GPU'ya bir kez taşınır (11 ms). Küçük işte (256²) taşıma, GPU'yu CPU'dan yavaş yapar.

② Önceden ölçüldü (log ölçek, sunucu)

[ölçüldü] i9-14900KF (24 çekirdek) + RTX 6000 Ada · NumPy 2.3.3 · PyTorch 2.9 · CUDA 13 · medyan · 29.09.2026 · Python: 100 görüntüde ölçüldü, ×600

PyTorch'un gücü: aynı kod GPU'da → NumPy'dan ~25×, float16 ile ~140×. NumPy GPU'ya çıkamaz.

Normlar

Bir Vektörün Büyüklüğü

\[ \|\mathbf{x}\|_2 = \sqrt{\sum_i x_i^2}, \qquad \|\mathbf{x}\|_1 = \sum_i |x_i| \]
u = torch.tensor([3., -4.])
torch.linalg.norm(u)        # 5.  L2 (Öklid uzunluğu)
u.abs().sum()               # 7.  L1 (mutlak değer toplamı)
torch.linalg.norm(torch.ones(4, 9))   # 6.  Frobenius

Örn: \( \|[3,-4]\|_2=\sqrt{9+16}=5 \) (3-4-5 üçgeni), \( \|[3,-4]\|_1=3+4=7 \). Frobenius \( \|\mathbf{A}\|_F \) = matrisi düzleştirip alınan L2.

İki nokta arası uzaklık = farkın normu: \( \|\mathbf{x}-\mathbf{c}\|_2 \) — RBF, SOM, LVQ haftalarının temeli.

Toparlayalım

YSA'nın Dilini Öğrendik

🧊 Tensör

Oluştur, dilimle, işle, broadcast, ön-işle → sayısal tensör.

➗ Lineer cebir

Nokta/matris çarpımı, indirgeme, normlar. Katman = \( \mathbf{XW}+\mathbf{b} \).

📏 Norm & uzaklık

‖x‖₂, ‖x‖₁, Frobenius; iki nokta arası uzaklık ‖x − c‖.

⚡ Hız

Döngü yerine vektörleştir, float32 kullan; PyTorch ile aynı kod GPU'da ~25×.

Sonraki hafta: bu araçlarla ilk yapay nöronu kuracak ve aktivasyon fonksiyonlarını öğreneceğiz; türev Hafta 3'te, autograd + geri yayılım 7. haftada.

Mini Quiz · Haftayı Yokla

Kendini Test Et

1) Skaler, vektör, matris… ortak adı?
2) A.sum(axis=0) ne verir?
3) A * B hangi işlem?
4) u = [3, −4] için ‖u‖₂ kaçtır?
Uygulama · ~40 dk

Dili Kendin Konuş

1 · Tensör. arange(12).reshape(3,4); dilimle, sum(axis=0), mean, broadcasting dene.

2 · Ön işleme. ev.csv'yi indir, oku; ①②③'ü uygula, tensöre çevir. Kontrol: X.shape == (5, 5), 2. satır [3, 95, 0, 0, 1].

3 · Lineer cebir. A @ B, mv, dot; torch.norm ile L2/L1 hesapla.

4 · Uzaklık. \( \mathbf{x}=[1,2] \) ile \( \mathbf{c}=[4,6] \) arasındaki L2 uzaklığı önce elle, sonra torch.linalg.norm(x - c) ile bul; L1 uzaklıkla karşılaştır.

İpucu: her adımı önce elle hesapla, sonra kodda doğrula.

Sonraki Hafta

Hafta 2 — Yapay Nöron & Aktivasyon

Dili öğrendik. Şimdi ilk nöronu kuruyor, aktivasyon fonksiyonlarıyla XOR duvarını aşmanın yolunu görüyoruz.

← Ders Ana Sayfasına Dön