flowchart LR
A["while"] --> B["for + range"]
B --> C["break / continue"]
C --> D["enumerate / zip"]
D --> E["Nested loops"]
E --> F["List comprehension"]
F --> G["💎 for epoch in range(EPOCHS):"]
G --> H["💎 for batch in dataloader:"]
H --> I["⚡ MODERN AI'NIN ANA MOTORU"]
style G fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style H fill:#fce4ec,stroke:#c2185b,stroke-width:3px
style I fill:#ffcdd2,stroke:#b71c1c,stroke-width:3px
9 Döngüler
for batch in dataloader — modern AI’nın ana motoru
- Mosh’un videosu: Chapters 20-22 + 24 (While → Guessing → For → 2D) (≈38 dk)
- Bölüm aralığı: 2:14:16 — 2:52:44
- Kaynaklar: Python docs — control flow · Python docs — range · Python docs — itertools
- Okuma süresi: ≈60 dk
9.1 Bu Derste Ne Var?
Bu kursun en kritik dersi. Mosh dört chapter’da Python’un tekrar etme yetisini öğretiyor; biz bunu modern ML kodunun ana motoruna bağlıyoruz. for batch in dataloader: satırı olmasaydı, sinir ağları eğitilmez, LLM’ler üretilmez, modern AI olmazdı.
Dersin yedi parçası:
whiledöngüsü. — Koşul True iken tekrar.- Guessing Game (proje). —
while+if. fordöngüsü. — Koleksiyon gezme.range(). — Sayı dizisi.breakvecontinue. — Akış kontrol.- Nested loops + 2D listeler. — Matris işleme.
- ML eğitim döngüsü. — Mosh’un öğrettiklerinin AI’da uygulanması.
for batch in dataloader= ML eğitim döngüsünün ANA MOTORU. Her sinir ağı eğitimi, her LLM fine-tune, her görüntü sınıflandırma — hepsi bu satırla çalışır. Mosh’un “döngüde her öğeye bir şey yap” sezgisi, milyarlarca parametre üstünde milyonlarca veri örneğini işleyen ML pipeline’ının çekirdek pattern’ı.for epoch in range(EPOCHS)= dış eğitim döngüsü. Bir epoch = veri setinin tamamen bir kez işlenmesi.while= early stopping kontrolü.while patience_counter < max_patience: train_one_epoch().break= early termination.if val_loss > best_loss: break.continue= bad batch skip.if torch.isnan(loss): continue.enumerate= batch index + batch.for i, batch in enumerate(loader):logging için.zip= paralel iteration.for img, label in zip(images, labels):.- Nested for = batch × feature processing. Python loop’ta yavaş, vektörlü yap’la tek hamlede.
- List comprehension = vectorized construction.
losses = [train(b) for b in batches].
9.2 Neden Döngü?
Şimdiye kadar yazdığımız kodun büyük eksiği: tekrar yok. Öğrenci sicil dict’imiz üç öğrenci tutarsa her birine elle erişmek zorunda kalıyoruz. 100 öğrencide kopya-yapıştır cehennem.
“süre döngü temelde python içinde bir döngüdür. ve yürüt Birden çok kez bir kod bloğu.” — Mosh (Türkçe dublaj), 2:14:16
Döngü üç güç sağlar:
- Tekrar — aynı kodu N kez çalıştır.
- Gezme — bir koleksiyondaki tüm öğelere ulaş.
- Birikim — sonuçları toplama, sayma, filtreleme.
9.2.1 İki Tür
| Tür | Ne zaman? |
|---|---|
while |
Koşula bağlı — bilinmeyen iterasyon sayısı |
for |
Bilinen koleksiyon — her elemanı sırayla |
ML’de:
for batch in dataloader:(her batch) →forfor epoch in range(100):(100 epoch) →forwhile not converged:→whilewhile patience > 0:→while
9.3 while Döngüsü
“buna döngü olarak bakın bekçi. ve temelde kod boyunca döngü devam edeceğiz while döngüsü içinde. bu durum doğru olduğu sürece.” — Mosh (Türkçe dublaj), 2:15:36
9.3.1 Sentaks
while kosul:
# girintili kod (kosul True ise, sonra TEKRAR kontrol)Kritik fark if’ten: while kodu çalıştırıp koşulu tekrar kontrol eder. if bir kere.
9.3.2 İlk Örnek
i = 1
while i <= 10:
print(i)
i += 1 # "i = i + 1" kisayolu
print("Dongu bitti")Çıktı: 1, 2, 3, ..., 10, Dongu bitti.
9.3.3 += Kısayollar
i = 5
i += 1 # i = i + 1 -> 6
i -= 2 # i = i - 2
i *= 3 # i = i * 3
i //= 2 # i = i // 2
i %= 2 # i = i % 29.3.4 Sonsuz Döngü Tuzağı
i = 1
while i <= 10:
print(i)
# i += 1 unutuldu! i hep 1, sonsuz dongu!PyCharm’da Ctrl+C ile dur. Bilinçli sonsuz döngü (while True: + break) ML’de yaygın.
9.3.5 while = Early Stopping
import torch
model = ...
optimizer = ...
best_val_loss = float('inf')
patience = 5
patience_counter = 0
epoch = 0
max_epochs = 1000
while patience_counter < patience and epoch < max_epochs:
train_one_epoch(model, optimizer)
val_loss = validate(model)
if val_loss < best_val_loss:
best_val_loss = val_loss
patience_counter = 0 # iyilesti, sabir resetle
else:
patience_counter += 1 # iyilesmedi, sabir azalt
epoch += 1
print(f"Egitim {epoch} epoch sonra bitti")Mosh’un i <= 10 sayı mantığı, ML’de “sabır kalması” koşuluna dönüşür.
9.4 Proje — Guessing Game
“bir süre döngü denilen bir şey […] sürekli olarak kişiye sormak için sözcüğü tahmin etmek doğru tahmin edene kadar.” — Mosh (Türkçe dublaj), 2:21:47
9.4.1 Basit Sürüm
secret_word = "draft"
guess = ""
while guess != secret_word:
guess = input("Tahmin et: ")
print("Kazandiniz!")Problem: sonsuz tahmin yapabilir.
9.4.2 Üç Hak Sınırlı
secret_word = "draft"
guess_count = 0
guess_limit = 3
for attempt in range(guess_limit):
guess = input(f"Tahmin et ({guess_limit - attempt} hak): ")
if guess == secret_word:
print("Kazandiniz!")
break
else:
# for-else: for normal bittiyse (break olmadan) calisir
print("Kaybettiniz!")for-else — Python’a özgü tuhaf ama güzel: for döngüsü break ile bitmediyse else çalışır.
9.4.3 Guessing Game = ML Hyperparameter Search
Mosh’un üç-hak oyunu, ML hyperparameter search’ün mikro modeli:
import random
best_loss = float('inf')
attempts = 0
max_attempts = 50
while attempts < max_attempts and best_loss > target_loss:
config = {
"lr": 10 ** random.uniform(-5, -1),
"batch_size": random.choice([16, 32, 64, 128]),
"hidden_dim": random.choice([64, 128, 256, 512]),
}
val_loss = train_and_evaluate(config)
if val_loss < best_loss:
best_loss = val_loss
best_config = config
attempts += 1Mosh’un guessing game’i = AutoML/Optuna’nın felsefi temeli.
9.5 for Döngüsü
“bir for döngüsü python’da bize izin veren özel bir döngü türüdür farklı koleksiyonlar üzerinde dolaşmak” — Mosh (Türkçe dublaj), 2:32:50
9.5.1 Sentaks
for degisken in koleksiyon:
# her oge icin tekrarlanir
print(degisken)9.5.2 String, List, Tuple, Set, Dict
# String:
for letter in "Draft Academy":
print(letter)
# List:
friends = ["Kevin", "Karen", "Jim"]
for friend in friends:
print(f"Merhaba {friend}!")
# Tuple:
for c in (3, 5, 7):
print(c)
# Dict:
kullanici = {"ad": "Deniz", "yas": 35, "sehir": "Istanbul"}
for key, value in kullanici.items():
print(f"{key}: {value}")while ile aynı işi yapmak için index yönetmek gerekir; for çok daha Pythonic.
9.5.3 Yararlı Helpers — enumerate, zip
# enumerate - index + eleman:
friends = ["Kevin", "Karen", "Jim"]
for i, friend in enumerate(friends):
print(f"{i}: {friend}")
# 0: Kevin
# 1: Karen
# 2: Jim
# zip - paralel iteration:
isimler = ["Deniz", "Aylin", "Mosh"]
yaslar = [35, 28, 40]
for ad, yas in zip(isimler, yaslar):
print(f"{ad} ({yas})")
# reversed / sorted:
for friend in reversed(friends):
print(friend)
for friend in sorted(friends):
print(friend)9.6 range()
list(range(5)) # [0, 1, 2, 3, 4]
list(range(2, 8)) # [2, 3, 4, 5, 6, 7]
list(range(0, 20, 3)) # [0, 3, 6, 9, 12, 15, 18]
list(range(10, 0, -1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]range(stop) — stop dahil değil (yarı açık aralık).
9.6.1 for ile Kullanım
for i in range(5):
print(i)
# 100 kez tekrar (sadece tekrar):
for _ in range(100):
print("merhaba") # 100 kez basilir_ — “değişkene ihtiyacım yok, sadece tekrar etmeliyim”.
9.6.2 range vs enumerate
friends = ["Kevin", "Karen", "Jim"]
# C/Java tarzi (Python'da KOTU):
for i in range(len(friends)):
print(f"{i}: {friends[i]}")
# Pythonic:
for i, friend in enumerate(friends):
print(f"{i}: {friend}")PEP 8 + linter’lar enumerate öneriri.
9.6.3 range ML’in Epoch Döngüsü
import torch
import torch.nn as nn
EPOCHS = 100
BATCH_SIZE = 64
model = ...
optimizer = ...
for epoch in range(EPOCHS): # outer for - epoch sayisi
epoch_losses = []
for batch_idx, batch in enumerate(train_loader): # inner for + enumerate
loss = compute_loss(batch)
loss.backward()
optimizer.step()
optimizer.zero_grad()
epoch_losses.append(loss.item())
if batch_idx % 100 == 0: # mod ile periyodik log
print(f"Epoch {epoch}, Batch {batch_idx}: loss={loss.item():.4f}")
avg_loss = sum(epoch_losses) / len(epoch_losses)
print(f"Epoch {epoch} avg loss: {avg_loss:.4f}")Mosh’un for i in range(10): mikro örneği ↔︎ ML’in for epoch in range(EPOCHS): makro hali. Aynı yapı, daha büyük ölçek.
Her ML eğitim sistemi bu iki nested for döngüsünden oluşur:
- Outer: epochs üzerinde (
range) - Inner: batch’ler üzerinde (
dataloader)
9.7 break ve continue
# break - donguden tamamen cik:
for i in range(10):
if i == 5:
break
print(i)
# 0, 1, 2, 3, 4
# continue - bu iterasyonu atla:
for i in range(10):
if i % 2 == 0:
continue
print(i)
# 1, 3, 5, 7, 99.7.1 ML Eşdeğerleri
# break = early stopping:
for epoch in range(MAX_EPOCHS):
if val_loss > best_loss * 1.1:
print("Early stopping!")
break
# continue = bad batch skip:
for batch in train_loader:
loss = compute_loss(batch)
if torch.isnan(loss):
print("Bad batch, atlandi")
continue
loss.backward()
optimizer.step()9.8 Nested Loops + 2D Listeler
matris = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(matris[0]) # [1, 2, 3]
print(matris[0][2]) # 3
print(matris[2][0]) # 7
# Nested for - her elemani yazdir:
for satir in matris:
for eleman in satir:
print(eleman, end=" ")
print()
# 1 2 3
# 4 5 6
# 7 8 99.8.1 Çarpım Tablosu
for i in range(1, 6):
for j in range(1, 6):
print(f"{i*j:3d}", end=" ")
print()9.8.2 Nested = Çarpımsal Maliyet
# 100 x 100 = 10K iterasyon
# 1000 x 1000 = 1M iterasyon
# 1000 x 1000 x 1000 = 1B (tehlikeli!)9.8.3 Vectorization Kararı
Python nested loops kavramsal olarak doğru ama performans için yetersiz:
import time
import numpy as np
import torch
A = [[i*j for j in range(1000)] for i in range(1000)] # 1000x1000
# Python loops:
start = time.time()
result = [[x ** 2 for x in row] for row in A]
print(f"Python: {time.time() - start:.3f}s")
# ~0.5 sn
# NumPy:
A_np = np.array(A)
start = time.time()
result_np = A_np ** 2
print(f"NumPy: {time.time() - start:.6f}s")
# ~0.003 sn - 100+ kat
# PyTorch GPU:
A_t = torch.tensor(A).cuda()
start = time.time()
result_t = A_t ** 2
torch.cuda.synchronize()
print(f"PyTorch GPU: {time.time() - start:.6f}s")
# 1000+ katML perspektifi:
for batch in dataloader:OK çünkü batch sayısı az (~1000).for pixel in image:YASAK çünkü pixel sayısı çok (224×224×3 ≈ 150K). Tensor op ile yap.
9.9 List Comprehension
Mosh göstermez ama modern Python’un en sevdiği deyim.
# Klasik for:
kareler = []
for i in range(10):
kareler.append(i * i)
# List comprehension:
kareler = [i * i for i in range(10)]
# Filtreli:
cift_kareler = [i * i for i in range(10) if i % 2 == 0]
# Dict comprehension:
kareler_dict = {i: i*i for i in range(5)}
# Set comprehension:
benzersiz_kareler = {x*x for x in [-2, -1, 0, 1, 2]}9.9.1 Comprehension ML’de
# Bir liste tensoru cevirme:
tensors = [torch.tensor(data) for data in batches]
# Filtering:
valid_losses = [loss for loss in all_losses if not torch.isnan(loss)]
# Dict olusturma:
param_count = {name: p.numel() for name, p in model.named_parameters()}3 satırı tek satıra indirir. Okunabilir ve hızlı.
9.10 ML Eğitim Döngüsü — KURSUN ZIRVESI
Bu bölüm Ders 8’in ve tüm kursun zirvesi. Mosh’un öğrettikleri tek bir kod parçasında bir araya geliyor. Bu kod, modern AI’nın kalbi.
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
# Ders 7 (dict + config):
config = {
"lr": 1e-3,
"batch_size": 64,
"epochs": 100,
"patience": 5,
"device": "cuda" if torch.cuda.is_available() else "cpu",
}
model = MyModel().to(config["device"])
optimizer = torch.optim.AdamW(model.parameters(), lr=config["lr"])
criterion = nn.CrossEntropyLoss()
train_loader = DataLoader(train_dataset, batch_size=config["batch_size"], shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=config["batch_size"], shuffle=False)
# Ders 4 (list):
train_losses = []
val_losses = []
best_val_loss = float('inf')
patience_counter = 0
# DIS DONGU - epochs:
for epoch in range(config["epochs"]):
# === EGITIM FAZI ===
model.train()
epoch_train_losses = []
# IC DONGU - batch:
for batch_idx, batch in enumerate(train_loader):
# Ders 4 (tuple unpacking):
images = batch["image"].to(config["device"])
labels = batch["label"].to(config["device"])
# Ders 5 (fonksiyon):
logits = model(images)
loss = criterion(logits, labels)
# Ders 6 (if) + Ders 8 (continue):
if torch.isnan(loss):
print(f"NaN at epoch {epoch}, batch {batch_idx} - skip")
continue
optimizer.zero_grad()
loss.backward()
optimizer.step()
epoch_train_losses.append(loss.item())
# Ders 6 (if) + Ders 2 (modulus):
if batch_idx % 100 == 0:
print(f"E{epoch} B{batch_idx}: loss={loss.item():.4f}")
# === DOGRULAMA ===
model.eval()
epoch_val_losses = []
with torch.no_grad():
for batch in val_loader:
images = batch["image"].to(config["device"])
labels = batch["label"].to(config["device"])
logits = model(images)
loss = criterion(logits, labels)
epoch_val_losses.append(loss.item())
# Ders 4 (sum + len):
avg_train_loss = sum(epoch_train_losses) / len(epoch_train_losses)
avg_val_loss = sum(epoch_val_losses) / len(epoch_val_losses)
train_losses.append(avg_train_loss)
val_losses.append(avg_val_loss)
print(f"Epoch {epoch}: train={avg_train_loss:.4f}, val={avg_val_loss:.4f}")
# Ders 8 (break) + Ders 7 (dict):
if avg_val_loss < best_val_loss:
best_val_loss = avg_val_loss
patience_counter = 0
torch.save({
"epoch": epoch,
"model_state_dict": model.state_dict(),
"val_loss": avg_val_loss,
}, "best_model.pt")
else:
patience_counter += 1
if patience_counter >= config["patience"]:
print(f"Early stopping at epoch {epoch}")
break
print("Egitim bitti!")9.10.1 Mosh’un 8 Dersinin Tek Class’ta Sentezi
Bu tek kod parçasında:
| Ders | Konsept | Yerleşim |
|---|---|---|
| 1 | print, sıralı yürütme | her print(...) ve kodun akışı |
| 2 | değişken, tip, math | lr = 1e-3, modulus (batch_idx % 100) |
| 3 | input → config dict | JSON config yükleme aynı pattern |
| 4 | list, append, tuple unpacking | train_losses = [], images, labels = batch |
| 5 | def, return | model(images), criterion(...) |
| 6 | if, comparison | if torch.isnan(...), if avg_val_loss < best |
| 7 | dict, .get | config["lr"], batch["image"], model.state_dict() |
| 8 | for, range, break, continue | tüm döngü iskeleti |
Mosh’un 8 dersi, modern AI’nın tek bir eğitim sistemine dökülüyor.
9.10.2 for batch in dataloader — Modern AI’nın Tek Cümlesi
for batch in dataloader:
...Bu dokuz karakter modern AI’nın çekirdek mantığını taşır. GPT-4 eğitilirken bu satır milyonlarca kez çağrıldı. Stable Diffusion’da gigabayt veri akıttı.
9.11 Bu Dersin Özeti
while kosul:— koşul True iken tekrar.for x in koleksiyon:— her öğeye uygula.range(start, stop, step)— sayı dizisi.enumerate(...)— (index, eleman) tuple.zip(a, b)— paralel iteration.break— döngüden çık.continue— bu iterasyonu atla.- Nested loops — çarpımsal.
- List comprehension —
[ifade for x in iter if kosul]. - ML training loop — Mosh’un sentezi.
while koşullu tekrar, for koleksiyon gezme — Mosh’un sekiz dakikalık i <= 10 mikro örneği ve “for letter in ‘Draft Academy’” pattern’ı, modern AI’nın çekirdek kodu olan for epoch in range(EPOCHS): for batch in dataloader: train(batch) döngüsünün birebir atasıdır; her sinir ağı eğitimi, her LLM fine-tune, her görüntü sınıflandırması bu döngü üzerinde inşa edilir; break early stopping’tir, continue bad batch skip’tir, enumerate logging’in temelidir; ve Mosh’un üç-hak Guessing Game’i, modern hyperparameter search’ün ilkel formudur.
9.12 Egzersizler
Egzersiz 1. En büyük sayıyı bul (max() kullanma):
nums = [3, 7, 1, 9, 4, 6, 8, 2]
en_buyuk = ??? # baslangic
for n in nums:
if ???:
en_buyuk = n
print(en_buyuk) # 9Egzersiz 2. Guessing Game (5 hak + ipucu):
secret = "python"
attempts = 5
for i in range(attempts):
guess = input(f"Tahmin ({attempts - i} hak): ")
if guess == secret:
print("Kazandiniz!")
break
else:
ipucu = ??? # eslesen harfler
print(f"Ipucu: {ipucu}")
else:
print(f"Kaybettiniz! Kelime: {secret}")Egzersiz 3. 5×5 çarpım tablosu:
for i in range(1, 6):
for j in range(1, 6):
print(???, end=" ")
print()Egzersiz 4. (enumerate + zip + list comp)
isimler = ["Deniz", "Aylin", "Mosh"]
yaslar = [35, 28, 40]
# Klasik:
yas_dict = {}
for ad, yas in zip(isimler, yaslar):
yas_dict[ad] = yas
# Comprehension (tek satir):
yas_dict_compact = {???}
# Enumerate ile numaralandirilmis:
sirali_dict = {???}
# {1: "Deniz", 2: "Aylin", 3: "Mosh"}Egzersiz 5. (Builder eksen — fake training loop)
import random
dataset = [random.uniform(0, 1) for _ in range(1000)]
EPOCHS = 10
BATCH_SIZE = 50
train_losses = []
best_loss = float('inf')
patience_counter = 0
PATIENCE = 3
for epoch in range(EPOCHS):
epoch_losses = []
n_batches = ??? # dataset // BATCH_SIZE
for batch_idx in range(n_batches):
start = batch_idx * BATCH_SIZE
end = start + BATCH_SIZE
batch = ??? # dataset slicing
loss = sum(batch) / len(batch) + random.uniform(-0.1, 0.1)
if batch_idx % 5 == 0:
print(f"E{epoch} B{batch_idx}: {loss:.4f}")
epoch_losses.append(loss)
avg_loss = ???
train_losses.append(avg_loss)
print(f"Epoch {epoch} avg: {avg_loss:.4f}")
if avg_loss < best_loss:
best_loss = avg_loss
patience_counter = 0
else:
patience_counter += 1
if patience_counter >= PATIENCE:
print("Early stopping!")
break
print(f"\nBitti! Best loss: {best_loss:.4f}")PyTorch eğitim kodunun iskeletini birebir anlamış olacaksın.
9.13 Sonraki Ders İçin Hazırlık
Ders 9: Uygulama — Çevirmen ve İyi Yorum Alışkanlığı
Kısa bir pratik ders. Mosh’un Ch 25 + Ch 26 (Translator + Comments).
- Mosh’un Ch 25-26’sını izle (2:52:44-3:04:23, ~12 dk).
- Şu cümleyi içselleştir: “Yorum kodu çalışmaz ama okuyucuya rehberlik eder.”
for batch in dataloader: — bu dokuz karakter modern AI’nın çekirdek mantığını taşır; Mosh’un Ch 22’de öğrettiği for letter in "Draft Academy": ve Ch 20’de öğrettiği while i <= 10: mikro örnekleri, GPT-4 eğitilirken, Stable Diffusion’da, BERT fine-tune’larında birebir aynı yapıyla milyonlarca kez çağrıldı; break early stopping’dir, continue bad batch skip’tir, enumerate logging’dir, nested loops vectorization kararının kapısıdır — Mosh’un sekiz dersinde öğrettiği her şey bu derste tek bir ML eğitim sisteminde birleşiyor.