Meydan okuma 4
- Makine Öğrenmesi kursu
- İleri seviye
- Ders 78/78
- 8 dk
Eğitim döngüsü yazarsın.
Meydan okuma 4: dondur, ince ayarla
Son meydan okumada transfer öğrenmenin iki aşamasını uygulayacaksın. "Önceden eğitilmiş" gövdeyi bir yan görevde eğiterek kendin hazırlayacak, sonra yeni bir görev için önce yalnızca başı, ardından tüm ağı küçük oranla eğiteceksin:
# 1. hazırlık: gövde + baş_A, görev A üzerinde
# 2. aşama 1: gövde donuk, baş_B eğitilir
# 3. aşama 2: gövde açık (lr küçük), gövde + baş_B birlikteHer aşamada eğitilebilir parametre sayısını kontrol etmek, dondurmanın gerçekten uygulandığını doğrular.
Uygulama Hazırlık ve aşama 1
Gövde (Linear(2, 32) → ReLU → Linear(32, 32) → ReLU) ve baş_A = Linear(32, 2) ile görev A'yı (ay verisi) 300 adım eğit. Sonra gövdeyi dondur; görev B (etiketleri ters çevrilmiş ay: 1 - y) için yeni baş_B = Linear(32, 2)'yi 100 adım eğit. Aşama 1'deki eğitilebilir parametre sayısını ve görev B doğruluğunun 0.95'ten büyük olduğunu aynı satırda yazdır.
Başlangıç kodu
import math
import torch
from torch import nn
torch.manual_seed(0)
def ay(n):
t = torch.rand(n) * math.pi
ust = torch.stack([torch.cos(t), torch.sin(t)], 1)
alt = torch.stack([1 - torch.cos(t), 0.5 - torch.sin(t)], 1)
X = torch.cat([ust, alt]) + 0.1 * torch.randn(2 * n, 2)
y = torch.cat([torch.zeros(n), torch.ones(n)]).long()
return X, y
X, y = ay(200)
# buraya yazÖrnek çözüm
import math
import torch
from torch import nn
torch.manual_seed(0)
def ay(n):
t = torch.rand(n) * math.pi
ust = torch.stack([torch.cos(t), torch.sin(t)], 1)
alt = torch.stack([1 - torch.cos(t), 0.5 - torch.sin(t)], 1)
X = torch.cat([ust, alt]) + 0.1 * torch.randn(2 * n, 2)
y = torch.cat([torch.zeros(n), torch.ones(n)]).long()
return X, y
X, y = ay(200)
govde = nn.Sequential(nn.Linear(2, 32), nn.ReLU(), nn.Linear(32, 32), nn.ReLU())
bas_A = nn.Linear(32, 2)
kayip_fn = nn.CrossEntropyLoss()
opt = torch.optim.Adam(list(govde.parameters()) + list(bas_A.parameters()), lr=0.01)
for _ in range(300):
opt.zero_grad()
kayip_fn(bas_A(govde(X)), y).backward()
opt.step()
for p in govde.parameters():
p.requires_grad = False
bas_B = nn.Linear(32, 2)
model = nn.Sequential(govde, bas_B)
opt = torch.optim.Adam(bas_B.parameters(), lr=0.01)
for _ in range(100):
opt.zero_grad()
kayip_fn(model(X), 1 - y).backward()
opt.step()
egitilebilir = sum(p.numel() for p in model.parameters() if p.requires_grad)
with torch.no_grad():
print(egitilebilir, (model(X).argmax(1) == 1 - y).float().mean().item() > 0.95)Beklenen çıktı
66 True
Uygulama Aşama 2: ince ayar
Aşama 1 sonrası (kod hazır) gövdeyi aç ve gövde için lr=1e-4, baş için lr=1e-3 olan parametre gruplarıyla Adam kur. 100 adım ince ayar yap. Eğitilebilir parametre sayısını ve görev B doğruluğunun hâlâ 0.95'ten büyük olduğunu aynı satırda yazdır.
Başlangıç kodu
import math
import torch
from torch import nn
torch.manual_seed(0)
def ay(n):
t = torch.rand(n) * math.pi
ust = torch.stack([torch.cos(t), torch.sin(t)], 1)
alt = torch.stack([1 - torch.cos(t), 0.5 - torch.sin(t)], 1)
X = torch.cat([ust, alt]) + 0.1 * torch.randn(2 * n, 2)
y = torch.cat([torch.zeros(n), torch.ones(n)]).long()
return X, y
X, y = ay(200)
govde = nn.Sequential(nn.Linear(2, 32), nn.ReLU(), nn.Linear(32, 32), nn.ReLU())
bas_B = nn.Linear(32, 2)
model = nn.Sequential(govde, bas_B)
kayip_fn = nn.CrossEntropyLoss()
opt = torch.optim.Adam(model.parameters(), lr=0.01)
for _ in range(400):
opt.zero_grad()
kayip_fn(model(X), 1 - y).backward()
opt.step()
for p in govde.parameters():
p.requires_grad = False
# buraya yazÖrnek çözüm
import math
import torch
from torch import nn
torch.manual_seed(0)
def ay(n):
t = torch.rand(n) * math.pi
ust = torch.stack([torch.cos(t), torch.sin(t)], 1)
alt = torch.stack([1 - torch.cos(t), 0.5 - torch.sin(t)], 1)
X = torch.cat([ust, alt]) + 0.1 * torch.randn(2 * n, 2)
y = torch.cat([torch.zeros(n), torch.ones(n)]).long()
return X, y
X, y = ay(200)
govde = nn.Sequential(nn.Linear(2, 32), nn.ReLU(), nn.Linear(32, 32), nn.ReLU())
bas_B = nn.Linear(32, 2)
model = nn.Sequential(govde, bas_B)
kayip_fn = nn.CrossEntropyLoss()
opt = torch.optim.Adam(model.parameters(), lr=0.01)
for _ in range(400):
opt.zero_grad()
kayip_fn(model(X), 1 - y).backward()
opt.step()
for p in govde.parameters():
p.requires_grad = False
for p in govde.parameters():
p.requires_grad = True
opt = torch.optim.Adam([{"params": govde.parameters(), "lr": 1e-4}, {"params": bas_B.parameters(), "lr": 1e-3}])
for _ in range(100):
opt.zero_grad()
kayip_fn(model(X), 1 - y).backward()
opt.step()
egitilebilir = sum(p.numel() for p in model.parameters() if p.requires_grad)
with torch.no_grad():
print(egitilebilir, (model(X).argmax(1) == 1 - y).float().mean().item() > 0.95)Beklenen çıktı
1218 True
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Aşama 1'de optimize ediciye hangi parametreler verilmelidir?
- Yalnızca yeni başın parametreleri Doğru cevap
- Tüm parametreler
- Yalnızca gövde
- Hiçbiri
Açıklama: Gövde donuk olduğu için güncellenmeyecektir; optimize ediciye yalnızca baş verilir.
2 Gövdeyi tekrar eğitilebilir yap.
for p in govde.parameters():
p.requires_grad = ____
for p in govde.parameters():
p.requires_grad = True
Açıklama: Aşama 2'de gövde açılır.
3 Aşamaları eşleştir.
| Kavram | Anlamı |
|---|---|
hazırlık |
Gövde yan görevde öğrenir |
aşama 1 |
Gövde donuk, baş eğitilir |
aşama 2 |
Hepsi, küçük lr |
parametre sayımı |
Dondurma kontrolü |