IlmHamroh
Data Science va sun'iy intellekt/Neyron tarmoqlar11/12-dars23 daqiqa
Mundarija (21)

20.11-dars: Birinchi to'liq tarmoq

20-QISM — NEYRON TARMOQLAR · 11-dars


1. Kirish va motivatsiya

Bo'laklar tayyor: neyron, aktivatsiya, arxitektura, oldinga o'tish, loss, backprop, optimizator, boshlanish, tensorlar, regularizatsiya. Endi ularni bitta o'rgatish sikliga yig'amiz.

O'rgatish sikli — chuqur o'rganishdagi eng ko'p yoziladigan kod. Uning tuzilishi hamma joyda bir xil: batchlar bo'ylab yurish, loss ni hisoblash, orqaga qaytish, qadam tashlash, davr oxirida validatsiya qilish. Shu besh qadam MNIST dan GPT gacha o'zgarmaydi.

Lekin sikl atrofida juda ko'p detal bor: train() va eval() rejimlari, zero_grad ning o'rni, metrikalarni to'g'ri yig'ish, jadvalni qachon qadamlash, erta to'xtash va eng yaxshi holatni saqlash. Bu detallar o'tkazib yuborilganda kod "ishlayotgandek" ko'rinadi, lekin natija noto'g'ri bo'ladi.

Bu darsda siklni qadamma-qadam quramiz va har detalning nima uchun kerakligini ko'rsatamiz. Oxirida sklearn bilan solishtirib, tarmoq haqiqatan ishlayotganini tekshiramiz.

Real vaziyat. Muhandis o'rgatish siklini yozdi, model 0.94 aniqlik berdi. Ishlab chiqarishda 0.71 chiqdi. Sabab: model.eval() chaqirilmagan va BatchNorm test batchining statistikasidan foydalangan. Bir qator kod — 0.23 aniqlik.

Bu darsda to'liq o'rgatish siklini quramiz.

Bu darsda:

  • O'rgatish siklining tuzilishi
  • train va eval rejimlari
  • Batch va davr
  • Metrikalarni to'g'ri yig'ish
  • Loglash va kuzatish
  • Tuzoqlar
  • Amaliy: to'liq sikl

ℹ Misollar real torch/sklearn bilan (Python 3.14, torch 2.14 CPU).


2. Nazariya — chuqur tushuntirish

2.1. Siklning tuzilishi

text
for davr in range(davrlar):
    # --- O'RGATISH ---
    model.train()                       # dropout/BN yoqiladi
    for Xb, yb in oquv_batchlari:
        opt.zero_grad()                 # oldingi gradientni tozalash
        chiqish = model(Xb)             # oldinga
        loss = kriteriy(chiqish, yb)    # loss
        loss.backward()                 # orqaga
        opt.step()                      # qadam

    # --- VALIDATSIYA ---
    model.eval()                        # dropout/BN o'chiriladi
    with torch.no_grad():               # graf qurilmaydi
        for Xb, yb in val_batchlari:
            ...                          # metrikalarni yig'ish

    jadval.step()                       # lr ni yangilash
    # erta to'xtash tekshiruvi

Besh qadam: zero_grad → forward → loss → backward → step. Tartib qat'iy.

2.2. train va eval

text
model.train():
  Dropout    -> FAOL (neyronlar o'chiriladi)
  BatchNorm  -> batch statistikasini ishlatadi VA harakatlanuvchini yangilaydi

model.eval():
  Dropout    -> o'chiriladi (hech narsa tushmaydi)
  BatchNorm  -> HARAKATLANUVCHI statistikani ishlatadi

UNUTILSA NIMA BO'LADI:
  eval() siz bashorat -> dropout faol -> TASODIFIY natija
  train() siz o'rgatish -> BN statistikasi yangilanmaydi

no_grad() BOSHQA NARSA:
  u graf qurilishini to'xtatadi (xotira/tezlik)
  rejimni O'ZGARTIRMAYDI

DEMAK BAHOLASHDA IKKALASI HAM KERAK:
  model.eval()
  with torch.no_grad():

eval() va no_grad() — ikki boshqa narsa; baholashda ikkalasi ham kerak.

2.3. Batch va davr

text
DAVR (epoch): butun o'quv to'plamidan bir marta o'tish
BATCH: bir qadamda ishlatiladigan namunalar

qadamlar_soni = ceil(N / batch)

HAR DAVRDA ARALASHTIRISH SHART:
  aralashtirilmasa batchlar har davrda bir xil bo'ladi
  -> gradient shovqini tuzilmali bo'lib qoladi
  -> yaqinlashish yomonlashadi

OXIRGI BATCH:
  N batch ga bo'linmasa oxirgisi kichik bo'ladi
  drop_last=True - uni tashlab yuborish (BatchNorm uchun foydali)

VALIDATSIYADA ARALASHTIRISH KERAK EMAS

Har davrda aralashtiring — bu bir qator, lekin sezilarli farq beradi.

2.4. Metrikalarni to'g'ri yig'ish

text
XATO:
  loss_jami += loss.item()
  o'rtacha = loss_jami / batchlar_soni       <- oxirgi batch kichik bo'lsa NOTO'G'RI

TO'G'RI (namunalar bo'yicha vaznlangan):
  loss_jami += loss.item() * len(Xb)
  o'rtacha = loss_jami / N

ANIQLIK:
  togri += (chiqish.argmax(1) == yb).sum().item()
  aniqlik = togri / N

DIQQAT: .item() SHART -
  tensorni yig'sangiz butun graf xotirada qoladi (20.9-dars)

Metrikani namunalar soni bo'yicha vaznlang, batchlar soni bo'yicha emas.

2.5. Loglash va kuzatish

text
HAR DAVRDA YOZILADI:
  davr raqami
  o'quv loss, validatsiya loss
  o'quv metrika, validatsiya metrika
  joriy lr
  davr vaqti (ixtiyoriy)

NIMA IZLAYMIZ:
  val_loss o'smoqdami       -> yodlash
  train_loss tushmayaptimi  -> lr yoki arxitektura muammosi
  ikkalasi ham yuqorimi     -> yetarsiz o'rganish
  keskin sakrashlar         -> lr juda katta

EGRI CHIZIQLARNI CHIZING: jadval raqamlaridan ko'ra tezroq o'qiladi

EPS: bir necha davrda hech narsa o'zgarmasa - to'xtating va tekshiring

Har davrda ikkala loss ni ham yozing — bittasi hech narsa aytmaydi.

2.6. Takrorlanuvchanlik

text
torch.manual_seed(0)
np.random.seed(0)
random.seed(0)

DataLoader uchun:
  generator = torch.Generator().manual_seed(0)
  DataLoader(..., generator=generator, worker_init_fn=...)

TO'LIQ DETERMINIZM (sekinroq):
  torch.use_deterministic_algorithms(True)
  torch.backends.cudnn.deterministic = True

AMALDA: bitta seed yetarli emas -
  bir necha seed bilan ishga tushirib, O'RTACHA va STD ni bering
  (18.3-dars: bitta natija - bu bitta namuna)

Bitta seed natijasi — bitta namuna; muhim qarorlarni bir necha yurish asosida qabul qiling.

2.7. Tuzoqlar

Asosiy tuzoqlar: eval() ni unutish; zero_grad ni noto'g'ri joyga qo'yish; loss ni batchlar soni bo'yicha o'rtachalash; validatsiyani no_grad siz qilish; har davrda aralashtirmaslik; jadvalni har batchda qadamlash (agar u davr uchun mo'ljallangan bo'lsa); erta to'xtashni test to'plamida qilish; metrikalarni tensor holida yig'ish.


3. Tez ma'lumotnoma

python
import torch

def davr_orgat(model, yuklovchi, opt, kriteriy):
    model.train()
    jami, n = 0.0, 0
    for Xb, yb in yuklovchi:
        opt.zero_grad()
        loss = kriteriy(model(Xb), yb)
        loss.backward()
        opt.step()
        jami += loss.item() * len(Xb)
        n += len(Xb)
    return jami / n

@torch.no_grad()
def bahola(model, yuklovchi, kriteriy):
    model.eval()
    jami, togri, n = 0.0, 0, 0
    for Xb, yb in yuklovchi:
        chiqish = model(Xb)
        jami += kriteriy(chiqish, yb).item() * len(Xb)
        togri += (chiqish.argmax(1) == yb).sum().item()
        n += len(Xb)
    return jami / n, togri / n

Sikl xulosasi

train() -> batchlar -> zero_grad/forward/loss/backward/step
eval() + no_grad() -> validatsiya
metrikani NAMUNA soni bo'yicha vaznlang
har davrda aralashtiring
eng yaxshi holatni saqlang

4. Batafsil misollar

Misollar real torch/sklearn bilan (Python 3.14, torch 2.14 CPU).

Misol 1 — Siklni qadamma-qadam qurish

python
"""Besh qadam va ularning tartibi (real torch)."""

import torch
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


def main() -> None:
    torch.manual_seed(0)
    X, y = make_classification(n_samples=2000, n_features=16,
                               n_informative=8, n_redundant=3,
                               n_classes=3, flip_y=0.1, class_sep=1.0,
                               random_state=0)
    Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3,
                                          random_state=0, stratify=y)
    sc = StandardScaler().fit(Xtr)
    Xtr_t = torch.tensor(sc.transform(Xtr), dtype=torch.float32)
    Xte_t = torch.tensor(sc.transform(Xte), dtype=torch.float32)
    ytr_t = torch.tensor(ytr, dtype=torch.int64)
    yte_t = torch.tensor(yte, dtype=torch.int64)

    model = torch.nn.Sequential(
        torch.nn.Linear(16, 64), torch.nn.ReLU(),
        torch.nn.Linear(64, 32), torch.nn.ReLU(),
        torch.nn.Linear(32, 3))
    opt = torch.optim.AdamW(model.parameters(), lr=0.01,
                            weight_decay=1e-4)
    kriteriy = torch.nn.CrossEntropyLoss()

    print("=== 1. Bitta qadam, ochiq ===")
    Xb, yb = Xtr_t[:64], ytr_t[:64]
    print(f"  {'bosqich':<22} {'holat'}")
    print(f"  {'0. boshlang_ich grad':<22} "
          f"{model[0].weight.grad}")
    opt.zero_grad()
    chiqish = model(Xb)
    print(f"  {'1. zero_grad()':<22} tozalandi")
    print(f"  {'2. forward':<22} chiqish shakli "
          f"{tuple(chiqish.shape)}")
    loss = kriteriy(chiqish, yb)
    print(f"  {'3. loss':<22} {loss.item():.6f}")
    loss.backward()
    print(f"  {'4. backward()':<22} grad normasi "
          f"{model[0].weight.grad.norm().item():.6f}")
    eski = model[0].weight.detach().clone()
    opt.step()
    ozgarish = (model[0].weight.detach() - eski).norm().item()
    print(f"  {'5. step()':<22} og'irlik {ozgarish:.6f} ga o'zgardi")

    print("\n=== 2. zero_grad ni unutsak ===")
    m2 = torch.nn.Linear(4, 2)
    Xk = torch.randn(8, 4)
    yk = torch.randint(0, 2, (8,))
    print(f"  {'qadam':>6} {'zero_grad BOR':>16} {'zero_grad YO_Q':>17}")
    m3 = torch.nn.Linear(4, 2)
    m3.load_state_dict(m2.state_dict())
    for i in range(1, 5):
        m2.zero_grad()
        kriteriy(m2(Xk), yk).backward()
        n1 = m2.weight.grad.norm().item()
        kriteriy(m3(Xk), yk).backward()
        n2 = m3.weight.grad.norm().item()
        print(f"  {i:>6} {n1:>16.6f} {n2:>17.6f}")
    print("  tozalamasak gradient har qadamda YIG'ILADI")

    print("\n=== 3. Batch bo'ylab bitta davr ===")
    g = torch.Generator().manual_seed(0)
    tartib = torch.randperm(len(ytr_t), generator=g)
    batch = 128
    jami, n = 0.0, 0
    print(f"  {'batch':>6} {'hajm':>6} {'loss':>10} "
          f"{'yig_ilgan o_rtacha':>20}")
    for k, boshi in enumerate(range(0, len(ytr_t), batch)):
        idx = tartib[boshi:boshi + batch]
        opt.zero_grad()
        loss = kriteriy(model(Xtr_t[idx]), ytr_t[idx])
        loss.backward()
        opt.step()
        jami += loss.item() * len(idx)
        n += len(idx)
        if k < 3 or boshi + batch >= len(ytr_t):
            print(f"  {k:>6} {len(idx):>6} {loss.item():>10.4f} "
                  f"{jami / n:>20.4f}")
    print(f"  davr loss: {jami / n:.4f} ({n} namuna)")

    print("\n=== 4. Noto'g'ri o'rtachalash ===")
    kichik = torch.tensor([0.5, 0.5, 0.5, 5.0])       # oxirgi batch
    hajmlar = torch.tensor([128, 128, 128, 4])
    print(f"  batch loss lari: {kichik.tolist()}")
    print(f"  batch hajmlari:  {hajmlar.tolist()}")
    print(f"  batchlar bo'yicha (NOTO'G'RI): "
          f"{kichik.mean().item():.4f}")
    print(f"  namunalar bo'yicha (TO'G'RI):  "
          f"{(kichik * hajmlar).sum().item() / hajmlar.sum().item():.4f}")
    print("  kichik oxirgi batch natijani BUZADI")

    print("\n=== 5. To'liq sikl ===")
    torch.manual_seed(0)
    model = torch.nn.Sequential(
        torch.nn.Linear(16, 64), torch.nn.ReLU(),
        torch.nn.Linear(64, 32), torch.nn.ReLU(),
        torch.nn.Linear(32, 3))
    opt = torch.optim.AdamW(model.parameters(), lr=0.01,
                            weight_decay=1e-4)
    print(f"  {'davr':>6} {'o_quv loss':>12} {'test loss':>11} "
          f"{'test aniqlik':>13}")
    for davr in range(1, 41):
        model.train()
        tartib = torch.randperm(len(ytr_t), generator=g)
        jami, n = 0.0, 0
        for boshi in range(0, len(ytr_t), batch):
            idx = tartib[boshi:boshi + batch]
            opt.zero_grad()
            loss = kriteriy(model(Xtr_t[idx]), ytr_t[idx])
            loss.backward()
            opt.step()
            jami += loss.item() * len(idx)
            n += len(idx)
        if davr in (1, 5, 10, 20, 40):
            model.eval()
            with torch.no_grad():
                chiqish = model(Xte_t)
                te_loss = kriteriy(chiqish, yte_t).item()
                aniq = (chiqish.argmax(1)
                        == yte_t).float().mean().item()
            print(f"  {davr:>6} {jami / n:>12.4f} {te_loss:>11.4f} "
                  f"{aniq:>13.4f}")
    print("  ⭐ Besh qadam + aralashtirish + baholash")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bitta qadam, ochiq ===
  bosqich                holat
  0. boshlang_ich grad   None
  1. zero_grad()         tozalandi
  2. forward             chiqish shakli (64, 3)
  3. loss                1.100298
  4. backward()          grad normasi 0.072048
  5. step()              og'irlik 0.319961 ga o'zgardi

=== 2. zero_grad ni unutsak ===
   qadam    zero_grad BOR    zero_grad YO_Q
       1         0.461770          0.461770
       2         0.461770          0.923539
       3         0.461770          1.385309
       4         0.461770          1.847079
  tozalamasak gradient har qadamda YIG'ILADI

=== 3. Batch bo'ylab bitta davr ===
   batch   hajm       loss   yig_ilgan o_rtacha
       0    128     1.0775               1.0775
       1    128     1.0250               1.0513
       2    128     0.9808               1.0278
      10    120     0.7638               0.8924
  davr loss: 0.8924 (1400 namuna)

=== 4. Noto'g'ri o'rtachalash ===
  batch loss lari: [0.5, 0.5, 0.5, 5.0]
  batch hajmlari:  [128, 128, 128, 4]
  batchlar bo'yicha (NOTO'G'RI): 1.6250
  namunalar bo'yicha (TO'G'RI):  0.5464
  kichik oxirgi batch natijani BUZADI

=== 5. To'liq sikl ===
    davr   o_quv loss   test loss  test aniqlik
       1       0.9112      0.8467        0.6383
       5       0.5621      0.6838        0.7533
      10       0.4611      0.7205        0.7483
      20       0.2956      0.8465        0.7133
      40       0.0962      1.2832        0.6917
  ⭐ Besh qadam + aralashtirish + baholash

Nima ko'rsatdi: 2.1, 2.3, 2.4-bo'limlar.

Misol 2 — train va eval rejimlari

python
"""Rejimlarni unutishning narxi (real torch)."""

import torch
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


def yasa(seed=0):
    torch.manual_seed(seed)
    return torch.nn.Sequential(
        torch.nn.Linear(16, 64),
        torch.nn.BatchNorm1d(64),
        torch.nn.ReLU(),
        torch.nn.Dropout(0.4),
        torch.nn.Linear(64, 3))


def main() -> None:
    X, y = make_classification(n_samples=2000, n_features=16,
                               n_informative=8, n_redundant=3,
                               n_classes=3, flip_y=0.1, class_sep=1.0,
                               random_state=0)
    Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3,
                                          random_state=0, stratify=y)
    sc = StandardScaler().fit(Xtr)
    Xtr_t = torch.tensor(sc.transform(Xtr), dtype=torch.float32)
    Xte_t = torch.tensor(sc.transform(Xte), dtype=torch.float32)
    ytr_t = torch.tensor(ytr, dtype=torch.int64)
    yte_t = torch.tensor(yte, dtype=torch.int64)

    model = yasa()
    opt = torch.optim.AdamW(model.parameters(), lr=0.01)
    kriteriy = torch.nn.CrossEntropyLoss()
    g = torch.Generator().manual_seed(0)
    for _ in range(60):
        model.train()
        tartib = torch.randperm(len(ytr_t), generator=g)
        for boshi in range(0, len(ytr_t), 128):
            idx = tartib[boshi:boshi + 128]
            opt.zero_grad()
            kriteriy(model(Xtr_t[idx]), ytr_t[idx]).backward()
            opt.step()

    print("=== 1. Bir xil kirish, ikki rejim ===")
    model.train()
    with torch.no_grad():
        t1 = model(Xte_t[:4])
        t2 = model(Xte_t[:4])
    model.eval()
    with torch.no_grad():
        e1 = model(Xte_t[:4])
        e2 = model(Xte_t[:4])
    print(f"  train() da ikki yurish bir xilmi: "
          f"{torch.allclose(t1, t2)}")
    print(f"  eval()  da ikki yurish bir xilmi: "
          f"{torch.allclose(e1, e2)}")
    print(f"  train() va eval() farqi (o'rtacha): "
          f"{(t1 - e1).abs().mean().item():.4f}")

    print("\n=== 2. Aniqlikdagi farq ===")
    def aniqlik(rejim):
        if rejim == "train":
            model.train()
        else:
            model.eval()
        with torch.no_grad():
            return (model(Xte_t).argmax(1)
                    == yte_t).float().mean().item()

    print(f"  {'rejim':<10} {'test aniqlik':>13}")
    for rejim in ["train", "eval"]:
        print(f"  {rejim:<10} {aniqlik(rejim):>13.4f}")
    print(f"  farq: {aniqlik('eval') - aniqlik('train'):+.4f}")

    print("\n=== 3. train() da natija barqaror emas ===")
    model.train()
    ballar = []
    for _ in range(10):
        with torch.no_grad():
            ballar.append((model(Xte_t).argmax(1)
                           == yte_t).float().mean().item())
    print(f"  10 yurish: min {min(ballar):.4f}, max {max(ballar):.4f}")
    print(f"  o'rtacha {sum(ballar) / 10:.4f}, "
          f"tarqoqlik {max(ballar) - min(ballar):.4f}")

    print("\n=== 4. BatchNorm statistikasi ===")
    bn = model[1]
    print(f"  harakatlanuvchi o'rtacha (birinchi 4): "
          f"{bn.running_mean[:4].tolist()}")
    print(f"  harakatlanuvchi dispersiya (birinchi 4): "
          f"{[round(v, 4) for v in bn.running_var[:4].tolist()]}")
    print(f"  kuzatilgan batchlar: {int(bn.num_batches_tracked)}")

    print("\n=== 5. Kichik batchda BatchNorm ===")
    model.eval()
    with torch.no_grad():
        togri_bashorat = model(Xte_t[:3])
    model.train()
    with torch.no_grad():
        xato_bashorat = model(Xte_t[:3])
    print(f"  3 namunali kirish:")
    print(f"  {'namuna':>7} {'eval() (to_g_ri)':<28} "
          f"{'train() (xato)':<28}")
    for i in range(3):
        print(f"  {i:>7} {str([round(v, 3) for v in togri_bashorat[i].tolist()]):<28} "
              f"{str([round(v, 3) for v in xato_bashorat[i].tolist()]):<28}")

    print("\n=== 6. no_grad va eval boshqa narsa ===")
    model.train()
    with torch.no_grad():
        a = model(Xte_t[:8])
    print(f"  train() + no_grad():")
    print(f"    grad_fn: "
          f"{type(a.grad_fn).__name__ if a.grad_fn else 'None'}")
    print(f"    dropout faolmi: HA (rejim train)")
    model.eval()
    b = model(Xte_t[:8])
    print(f"  eval() + no_grad SIZ:")
    print(f"    grad_fn: "
          f"{type(b.grad_fn).__name__ if b.grad_fn else 'None'}")
    print(f"    dropout faolmi: YO'Q (rejim eval)")
    print("  ⭐ Baholashda IKKALASI ham kerak")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bir xil kirish, ikki rejim ===
  train() da ikki yurish bir xilmi: False
  eval()  da ikki yurish bir xilmi: True
  train() va eval() farqi (o'rtacha): 0.9344

=== 2. Aniqlikdagi farq ===
  rejim       test aniqlik
  train             0.7050
  eval              0.7483
  farq: +0.0450

=== 3. train() da natija barqaror emas ===
  10 yurish: min 0.6900, max 0.7283
  o'rtacha 0.7115, tarqoqlik 0.0383

=== 4. BatchNorm statistikasi ===
  harakatlanuvchi o'rtacha (birinchi 4): [-0.04862187057733536, -0.17329974472522736, -0.12270306795835495, 0.17733359336853027]
  harakatlanuvchi dispersiya (birinchi 4): [1.0472, 1.4632, 1.1927, 0.812]
  kuzatilgan batchlar: 674

=== 5. Kichik batchda BatchNorm ===
  3 namunali kirish:
   namuna eval() (to_g_ri)             train() (xato)
        0 [-0.254, -0.298, 0.157]      [1.461, -2.733, 0.166]
        1 [0.519, 0.523, -1.983]       [-0.579, 0.75, -1.421]
        2 [-0.932, 2.773, -3.562]      [-0.745, 2.413, -3.694]

=== 6. no_grad va eval boshqa narsa ===
  train() + no_grad():
    grad_fn: None
    dropout faolmi: HA (rejim train)
  eval() + no_grad SIZ:
    grad_fn: AddmmBackward0
    dropout faolmi: YO'Q (rejim eval)
  ⭐ Baholashda IKKALASI ham kerak

Nima ko'rsatdi: 2.2-bo'lim.

Misol 3 — Loglash va o'rgatish egri chizig'i

python
"""Nima yoziladi va u nima haqida gapiradi (real torch)."""

import numpy as np
import torch
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


def tayyorla(n=1600, seed=0):
    X, y = make_classification(n_samples=n, n_features=20,
                               n_informative=8, n_redundant=4,
                               n_classes=3, flip_y=0.15, class_sep=0.8,
                               random_state=seed)
    Xtr, Xva, ytr, yva = train_test_split(X, y, test_size=0.35,
                                          random_state=0, stratify=y)
    sc = StandardScaler().fit(Xtr)
    T = lambda M: torch.tensor(sc.transform(M), dtype=torch.float32)
    return (T(Xtr), torch.tensor(ytr, dtype=torch.int64),
            T(Xva), torch.tensor(yva, dtype=torch.int64))


def orgat(Xtr, ytr, Xva, yva, lr=0.01, kenglik=256, davrlar=80):
    torch.manual_seed(0)
    model = torch.nn.Sequential(
        torch.nn.Linear(20, kenglik), torch.nn.ReLU(),
        torch.nn.Linear(kenglik, kenglik), torch.nn.ReLU(),
        torch.nn.Linear(kenglik, 3))
    opt = torch.optim.AdamW(model.parameters(), lr=lr,
                            weight_decay=1e-6)
    kriteriy = torch.nn.CrossEntropyLoss()
    g = torch.Generator().manual_seed(0)
    tarix = []
    for davr in range(1, davrlar + 1):
        model.train()
        tartib = torch.randperm(len(ytr), generator=g)
        jami, n = 0.0, 0
        for boshi in range(0, len(ytr), 128):
            idx = tartib[boshi:boshi + 128]
            opt.zero_grad()
            loss = kriteriy(model(Xtr[idx]), ytr[idx])
            loss.backward()
            opt.step()
            jami += loss.item() * len(idx)
            n += len(idx)
        model.eval()
        with torch.no_grad():
            chiqish = model(Xva)
            va_loss = kriteriy(chiqish, yva).item()
            va_aniq = (chiqish.argmax(1) == yva).float().mean().item()
            tr_aniq = (model(Xtr).argmax(1) == ytr).float().mean().item()
        tarix.append((davr, jami / n, va_loss, tr_aniq, va_aniq))
    return tarix


def main() -> None:
    Xtr, ytr, Xva, yva = tayyorla()
    print(f"  o'quv {len(ytr)}, validatsiya {len(yva)}")

    print("\n=== 1. Normal o'rgatish jurnali ===")
    tarix = orgat(Xtr, ytr, Xva, yva)
    print(f"  {'davr':>6} {'o_quv loss':>12} {'val loss':>10} "
          f"{'o_quv aniq':>12} {'val aniq':>10}")
    for satr in tarix:
        if satr[0] in (1, 5, 10, 20, 40, 80):
            print(f"  {satr[0]:>6} {satr[1]:>12.4f} {satr[2]:>10.4f} "
                  f"{satr[3]:>12.4f} {satr[4]:>10.4f}")

    print("\n=== 2. Nimani ko'ryapmiz ===")
    val_loss = [t[2] for t in tarix]
    eng_davr = int(np.argmin(val_loss)) + 1
    print(f"  eng past val loss: {min(val_loss):.4f} "
          f"({eng_davr}-davr)")
    print(f"  oxirgi val loss:   {val_loss[-1]:.4f}")
    print(f"  o'sish: {val_loss[-1] - min(val_loss):+.4f}")
    print(f"  oxirgi o'quv/val aniqlik farqi: "
          f"{tarix[-1][3] - tarix[-1][4]:+.4f}")
    print("  val loss eng past nuqtadan keyin O'SDI -> yodlash")

    print("\n=== 3. lr juda katta ===")
    tarix2 = orgat(Xtr, ytr, Xva, yva, lr=0.5, davrlar=20)
    print(f"  {'davr':>6} {'o_quv loss':>12} {'val loss':>10} "
          f"{'val aniq':>10}")
    for satr in tarix2:
        if satr[0] in (1, 2, 5, 10, 20):
            print(f"  {satr[0]:>6} {satr[1]:>12.4f} {satr[2]:>10.4f} "
                  f"{satr[4]:>10.4f}")
    print("  loss sakraydi va tushmaydi - lr ni kamaytiring")

    print("\n=== 4. lr juda kichik ===")
    tarix3 = orgat(Xtr, ytr, Xva, yva, lr=1e-5, davrlar=20)
    print(f"  {'davr':>6} {'o_quv loss':>12} {'val loss':>10} "
          f"{'val aniq':>10}")
    for satr in tarix3:
        if satr[0] in (1, 5, 10, 20):
            print(f"  {satr[0]:>6} {satr[1]:>12.4f} {satr[2]:>10.4f} "
                  f"{satr[4]:>10.4f}")
    print(f"  20 davrda loss atigi "
          f"{tarix3[0][1] - tarix3[-1][1]:.4f} ga tushdi")

    print("\n=== 5. Model juda kichik ===")
    tarix4 = orgat(Xtr, ytr, Xva, yva, kenglik=2, davrlar=40)
    print(f"  {'davr':>6} {'o_quv aniq':>12} {'val aniq':>10} "
          f"{'farq':>8}")
    for satr in tarix4:
        if satr[0] in (1, 10, 20, 40):
            print(f"  {satr[0]:>6} {satr[3]:>12.4f} {satr[4]:>10.4f} "
                  f"{satr[3] - satr[4]:>8.4f}")
    print("  ikkalasi ham past, farq kichik -> YETARSIZ o'rganish")

    print("\n=== 6. To'rt holatni ajratish ===")
    holatlar = [
        ("normal", tarix[19][3], tarix[19][4]),
        ("yodlash", tarix[-1][3], tarix[-1][4]),
        ("lr katta", tarix2[-1][3], tarix2[-1][4]),
        ("yetarsiz", tarix4[-1][3], tarix4[-1][4]),
    ]
    print(f"  {'holat':<12} {'o_quv':>8} {'val':>8} {'farq':>8} "
          f"{'tashxis'}")
    for nom, tr, va in holatlar:
        tashxis = ("yodlash" if tr - va > 0.08
                   else "yetarsiz" if tr < 0.6 else "yaxshi")
        print(f"  {nom:<12} {tr:>8.4f} {va:>8.4f} {tr - va:>8.4f} "
              f"{tashxis}")
    print("  ⭐ Ikkala ballni birga ko'rish tashxis beradi")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
  o'quv 1040, validatsiya 560

=== 1. Normal o'rgatish jurnali ===
    davr   o_quv loss   val loss   o_quv aniq   val aniq
       1       0.9748     0.8056       0.6913     0.6214
       5       0.5268     0.7393       0.8317     0.7089
      10       0.3135     0.8488       0.9221     0.7000
      20       0.0542     1.4307       0.9923     0.7143
      40       0.0014     1.9917       1.0000     0.7000
      80       0.0003     2.2928       1.0000     0.7018

=== 2. Nimani ko'ryapmiz ===
  eng past val loss: 0.7149 (4-davr)
  oxirgi val loss:   2.2928
  o'sish: +1.5779
  oxirgi o'quv/val aniqlik farqi: +0.2982
  val loss eng past nuqtadan keyin O'SDI -> yodlash

=== 3. lr juda katta ===
    davr   o_quv loss   val loss   val aniq
       1    1601.2189   407.7646     0.2482
       2     188.6824    22.1733     0.4536
       5       1.1238     1.1354     0.3429
      10       1.0614     1.1001     0.3589
      20       1.0423     1.1051     0.3696
  loss sakraydi va tushmaydi - lr ni kamaytiring

=== 4. lr juda kichik ===
    davr   o_quv loss   val loss   val aniq
       1       1.1114     1.1133     0.3054
       5       1.1028     1.1056     0.2929
      10       1.0933     1.0969     0.3196
      20       1.0755     1.0808     0.4357
  20 davrda loss atigi 0.0360 ga tushdi

=== 5. Model juda kichik ===
    davr   o_quv aniq   val aniq     farq
       1       0.4173     0.4018   0.0155
      10       0.5827     0.5607   0.0220
      20       0.6096     0.5732   0.0364
      40       0.6644     0.6107   0.0537
  ikkalasi ham past, farq kichik -> YETARSIZ o'rganish

=== 6. To'rt holatni ajratish ===
  holat           o_quv      val     farq tashxis
  normal         0.9923   0.7143   0.2780 yodlash
  yodlash        1.0000   0.7018   0.2982 yodlash
  lr katta       0.3779   0.3696   0.0082 yetarsiz
  yetarsiz       0.6644   0.6107   0.0537 yaxshi
  ⭐ Ikkala ballni birga ko'rish tashxis beradi

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — To'liq o'rgatuvchi va sklearn bilan tekshiruv

python
"""Erta to'xtash, jadval va sklearn bilan solishtirish."""

import warnings

import numpy as np
import torch
from sklearn.datasets import make_classification
from sklearn.exceptions import ConvergenceWarning
from sklearn.metrics import accuracy_score, log_loss
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler


class Orgatuvchi:
    def __init__(self, kirish, sinflar, kenglik=64, lr=0.01,
                 wd=1e-4, dropout=0.2, seed=0):
        torch.manual_seed(seed)
        self.model = torch.nn.Sequential(
            torch.nn.Linear(kirish, kenglik), torch.nn.ReLU(),
            torch.nn.Dropout(dropout),
            torch.nn.Linear(kenglik, kenglik // 2), torch.nn.ReLU(),
            torch.nn.Linear(kenglik // 2, sinflar))
        self.opt = torch.optim.AdamW(self.model.parameters(), lr=lr,
                                     weight_decay=wd)
        self.kriteriy = torch.nn.CrossEntropyLoss()
        self.g = torch.Generator().manual_seed(seed)
        self.tarix = []

    def davr(self, X, y, batch=128):
        self.model.train()
        tartib = torch.randperm(len(y), generator=self.g)
        jami, n = 0.0, 0
        for boshi in range(0, len(y), batch):
            idx = tartib[boshi:boshi + batch]
            self.opt.zero_grad()
            loss = self.kriteriy(self.model(X[idx]), y[idx])
            loss.backward()
            self.opt.step()
            jami += loss.item() * len(idx)
            n += len(idx)
        return jami / n

    @torch.no_grad()
    def bahola(self, X, y):
        self.model.eval()
        chiqish = self.model(X)
        return (self.kriteriy(chiqish, y).item(),
                (chiqish.argmax(1) == y).float().mean().item())

    def orgat(self, Xtr, ytr, Xva, yva, davrlar=200, sabr=20):
        jadval = torch.optim.lr_scheduler.CosineAnnealingLR(
            self.opt, T_max=davrlar)
        eng, eng_holat, eng_davr, hisob = float("inf"), None, 0, 0
        for davr in range(1, davrlar + 1):
            tr_loss = self.davr(Xtr, ytr)
            va_loss, va_aniq = self.bahola(Xva, yva)
            self.tarix.append((davr, tr_loss, va_loss, va_aniq,
                               jadval.get_last_lr()[0]))
            jadval.step()
            if va_loss < eng - 1e-4:
                eng, eng_davr, hisob = va_loss, davr, 0
                eng_holat = {k: v.clone() for k, v
                             in self.model.state_dict().items()}
            else:
                hisob += 1
                if hisob >= sabr:
                    break
        if eng_holat is not None:
            self.model.load_state_dict(eng_holat)
        return davr, eng_davr

    @torch.no_grad()
    def ehtimollik(self, X):
        self.model.eval()
        return torch.softmax(self.model(X), dim=1).numpy()


def main() -> None:
    X, y = make_classification(n_samples=5000, n_features=24,
                               n_informative=12, n_redundant=5,
                               n_classes=4, flip_y=0.1, class_sep=1.0,
                               random_state=0)
    Xtr, Xrest, ytr, yrest = train_test_split(X, y, test_size=0.4,
                                              random_state=0, stratify=y)
    Xva, Xte, yva, yte = train_test_split(Xrest, yrest, test_size=0.5,
                                          random_state=0, stratify=yrest)
    sc = StandardScaler().fit(Xtr)
    T = lambda M: torch.tensor(sc.transform(M), dtype=torch.float32)
    Xtr_t, Xva_t, Xte_t = T(Xtr), T(Xva), T(Xte)
    ytr_t = torch.tensor(ytr, dtype=torch.int64)
    yva_t = torch.tensor(yva, dtype=torch.int64)
    yte_t = torch.tensor(yte, dtype=torch.int64)
    print(f"  o'quv {len(ytr)}, validatsiya {len(yva)}, test {len(yte)}")

    print("\n=== 1. O'rgatish ===")
    o = Orgatuvchi(24, 4)
    param = sum(p.numel() for p in o.model.parameters())
    print(f"  parametrlar: {param}")
    tugagan, eng_davr = o.orgat(Xtr_t, ytr_t, Xva_t, yva_t)
    print(f"  {tugagan}-davrda to'xtadi, eng yaxshisi {eng_davr}-davr")

    print("\n=== 2. Jurnal ===")
    print(f"  {'davr':>6} {'o_quv loss':>12} {'val loss':>10} "
          f"{'val aniq':>10} {'lr':>10}")
    for satr in o.tarix:
        if satr[0] in (1, 5, 20, 50, eng_davr, tugagan):
            print(f"  {satr[0]:>6} {satr[1]:>12.4f} {satr[2]:>10.4f} "
                  f"{satr[3]:>10.4f} {satr[4]:>10.6f}")

    print("\n=== 3. Yakuniy natijalar ===")
    print(f"  {'to_plam':<14} {'loss':>9} {'aniqlik':>9}")
    for nom, Xq, yq in [("o'quv", Xtr_t, ytr_t),
                        ("validatsiya", Xva_t, yva_t),
                        ("test", Xte_t, yte_t)]:
        l, a = o.bahola(Xq, yq)
        print(f"  {nom:<14} {l:>9.4f} {a:>9.4f}")

    print("\n=== 4. sklearn bilan solishtirish ===")
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", ConvergenceWarning)
        m = MLPClassifier(hidden_layer_sizes=(64, 32), max_iter=400,
                          learning_rate_init=0.01, alpha=1e-4,
                          random_state=0, early_stopping=True,
                          n_iter_no_change=20,
                          validation_fraction=0.2).fit(
                              sc.transform(Xtr), ytr)
    p_torch = o.ehtimollik(Xte_t)
    p_sk = m.predict_proba(sc.transform(Xte))
    print(f"  {'model':<14} {'test aniqlik':>13} {'test log_loss':>15}")
    print(f"  {'torch':<14} "
          f"{accuracy_score(yte, p_torch.argmax(1)):>13.4f} "
          f"{log_loss(yte, p_torch):>15.4f}")
    print(f"  {'sklearn':<14} "
          f"{accuracy_score(yte, p_sk.argmax(1)):>13.4f} "
          f"{log_loss(yte, p_sk):>15.4f}")
    print(f"  bashoratlar mos kelishi: "
          f"{(p_torch.argmax(1) == p_sk.argmax(1)).mean():.4f}")

    print("\n=== 5. Bir necha seed ===")
    ballar = []
    for seed in range(5):
        oo = Orgatuvchi(24, 4, seed=seed)
        oo.orgat(Xtr_t, ytr_t, Xva_t, yva_t, davrlar=120, sabr=15)
        ballar.append(oo.bahola(Xte_t, yte_t)[1])
    ballar = np.array(ballar)
    print(f"  5 ta seed: {ballar.round(4).tolist()}")
    print(f"  o'rtacha {ballar.mean():.4f}, std {ballar.std(ddof=1):.4f}")
    print(f"  SE: {ballar.std(ddof=1) / np.sqrt(5):.4f}")
    print("  ⭐ Bitta yurish natijasi - bu bitta namuna")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
  o'quv 3000, validatsiya 1000, test 1000

=== 1. O'rgatish ===
  parametrlar: 3812
  33-davrda to'xtadi, eng yaxshisi 13-davr

=== 2. Jurnal ===
    davr   o_quv loss   val loss   val aniq         lr
       1       1.1413     0.9618     0.6290   0.010000
       5       0.7127     0.7448     0.7530   0.009990
      13       0.5909     0.6973     0.7840   0.009911
      20       0.5319     0.7147     0.7950   0.009779
      33       0.4414     0.7595     0.8080   0.009382

=== 3. Yakuniy natijalar ===
  to_plam             loss   aniqlik
  o'quv             0.4909    0.8527
  validatsiya       0.6973    0.7840
  test              0.6821    0.7960

=== 4. sklearn bilan solishtirish ===
  model           test aniqlik   test log_loss
  torch                 0.7960          0.6821
  sklearn               0.7480          0.8097
  bashoratlar mos kelishi: 0.8360

=== 5. Bir necha seed ===
  5 ta seed: [0.796, 0.811, 0.8, 0.799, 0.792]
  o'rtacha 0.7996, std 0.0071
  SE: 0.0032
  ⭐ Bitta yurish natijasi - bu bitta namuna

Nima ko'rsatdi: 2.1, 2.6-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"no_grad() eval() o'rnini bosadi" Ikki boshqa narsa
"zero_grad ixtiyoriy" Gradient yig'iladi
"Batchlar bo'yicha o'rtachalash to'g'ri" Namunalar bo'yicha vaznlang
"Aralashtirish kichik detal" Yaqinlashishga ta'sir qiladi
"Bitta seed yetarli" Bu bitta namuna
"O'quv loss yetarli" Ikkala loss ham kerak
"Jadval har batchda" Ta'rifiga qarab
"Test to'plamida erta to'xtash" Bu leakage

6. Keng tarqalgan xatolar va yechimlari

1. eval() ni unutish

python
with torch.no_grad(): bashorat = model(X)      # ⚠️ dropout faol
model.eval()                                   # ✅
with torch.no_grad(): bashorat = model(X)

2. zero_grad noto'g'ri joyda

python
for Xb, yb in yuklovchi:
    loss.backward(); opt.step()                # ⚠️
for Xb, yb in yuklovchi:
    opt.zero_grad(); ...                       # ✅

3. Noto'g'ri o'rtachalash

python
jami += loss.item(); o_rt = jami / batchlar    # ⚠️
jami += loss.item() * len(Xb); o_rt = jami / n # ✅

4. Aralashtirmaslik

python
for boshi in range(0, N, batch): idx = ...     # ⚠️ har davr bir xil
tartib = torch.randperm(N, generator=g)        # ✅

5. Tensorni yig'ish

python
tarix.append(loss)                             # ⚠️ graf saqlanadi
tarix.append(loss.item())                      # ✅

6. train() ni qaytarmaslik

python
# baholashdan keyin to'g'ridan-to'g'ri o'rgatish  # ⚠️
model.train()   # har davr boshida                # ✅

7. Validatsiyada no_grad yo'q

python
for Xb, yb in val: chiqish = model(Xb)         # ⚠️ xotira
with torch.no_grad(): ...                      # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 20.7, 20.9, 20.10-darslar (o'tilgan): Optimizator, tensorlar, regularizatsiya
  • 20.12-dars: To'liq amaliyot
  • 21-qism: nn.Module, DataLoader, GPU
  • 23-qism va keyingilari: Barcha o'rgatish sikllari

8. Eng yaxshi amaliyotlar

  1. Har davr boshida train().

  2. Baholashda eval() + no_grad().

  3. zero_grad ni sikl boshida.

  4. Metrikani namunalar bo'yicha vaznlang.

  5. Har davrda aralashtiring.

  6. Ikkala loss ni ham yozing.

  7. Eng yaxshi holatni saqlang.

  8. Bir necha seed bilan tekshiring.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # siklning besh qadami?
2.  # train() nima qiladi?
3.  # eval() nima qiladi?
4.  # no_grad() nima qiladi?
5.  # baholashda nechtasi kerak?
6.  # loss ni qanday o'rtachalash?
7.  # aralashtirish qachon?
8.  # qadamlar soni formulasi?
9.  # drop_last nima uchun?
10. # jurnalda nima bo'ladi?
11. # val_loss o'ssa nima?
12. # bitta seed yetarlimi?
Javoblar
  1. zero_grad, forward, loss, backward, step
  2. Dropout/BN ni o'rgatish rejimiga
  3. Ularni inference rejimiga
  4. Grafni qurmaydi
  5. Ikkalasi
  6. Namunalar bo'yicha vaznlab
  7. Har davrda
  8. ceil(N / batch)
  9. Kichik oxirgi batchni tashlash
  10. Davr, ikkala loss, metrika, lr
  11. Yodlash
  12. Yo'q

Vazifa 2: Xatolarni tuzating

python
1.  with torch.no_grad(): bashorat = model(X)

2.  jami += loss.item(); o_rt = jami / batchlar

3.  for boshi in range(0, N, batch): idx = ...

4.  tarix.append(loss)

5.  for Xb, yb in val: chiqish = model(Xb)
Javoblar
python
1.  model.eval(); with torch.no_grad(): bashorat = model(X)

2.  jami += loss.item() * len(Xb); o_rt = jami / n

3.  tartib = torch.randperm(N, generator=g)

4.  tarix.append(loss.item())

5.  with torch.no_grad():
        for Xb, yb in val: chiqish = model(Xb)

Vazifa 3: Sikl

Modellang:

  1. Bitta qadam
  2. zero_grad
  3. Batch
  4. To'liq sikl

Vazifa 4: Rejimlar

Modellang:

  1. Ikki rejim
  2. Aniqlik
  3. Barqarorlik
  4. BatchNorm

Vazifa 5: Jurnal

Modellang:

  1. Normal
  2. lr katta
  3. lr kichik
  4. Model kichik

Vazifa 6: To'liq

Modellang:

  1. O'rgatish
  2. Jurnal
  3. Natijalar
  4. Seedlar

Vazifa 7: O'ylash

Siklingiz ishlayapti, lekin validatsiya balli o'quv ballidan yuqori chiqyapti. Bu mumkinmi va sabablari nima?

Javob

Ha, mumkin — va bu ko'pincha xato emas. Uch sabab bor, ikkitasi normal, bittasi muammo.

Sabab 1 (normal): dropout o'rgatishda faol

O'quv loss train() rejimida, dropout yoqilgan holda hisoblanadi — ya'ni zaiflashtirilgan model o'lchanadi. Validatsiya esa eval() rejimida, to'liq model bilan.

python
# to'g'ri taqqoslash uchun
model.eval()
with torch.no_grad():
    tr_loss_halol = kriteriy(model(Xtr), ytr).item()
print(tr_loss_halol, va_loss)     # endi taqqoslash mumkin

dropout=0.5 bo'lsa bu farq sezilarli bo'ladi.

Sabab 2 (normal): o'quv loss davr davomida o'rtachalanadi

Sikl ichida tr_loss butun davr bo'ylab yig'iladi — birinchi batchlar yomonroq modeldan olingan. Validatsiya esa davr oxirida, eng yaxshi holatda o'lchanadi.

Ya'ni siz "davr o'rtasidagi model" va "davr oxiridagi model" ni solishtiryapsiz.

Sabab 3 (muammo): validatsiya to'plami osonroq

python
print(np.bincount(ytr) / len(ytr))
print(np.bincount(yva) / len(yva))     # taqsimot mos kelyaptimi
print(len(ytr), len(yva))              # val juda kichikmi

Validatsiya kichik bo'lsa (masalan 100 namuna), uning balli juda shovqinli bo'ladi va tasodifan yuqori chiqishi mumkin. stratify ishlatilmagan bo'lsa taqsimot ham farq qilishi mumkin.

Qaysi biri ekanini aniqlash:

Tekshiruv Natija Xulosa
dropout=0 bilan qayta Farq yo'qoldi Sabab 1
Davr oxirida eval bilan o'quv loss Farq yo'qoldi Sabab 2
Val hajmi < 200 Shovqin katta Sabab 3
Sinf taqsimoti farqli stratify yo'q Sabab 3

Qachon xavotir olish kerak:

  • Farq katta (> 0.05 aniqlikda) va dropout yo'q
  • Validatsiya doimiy yuqori, davrdan davrga
  • Validatsiya to'plami o'quvdan kichikroq va osonroq (masalan, chetdagi qiymatlar faqat o'quvda)

Eng jiddiy holat: validatsiya to'plami tasodifan tozaroq bo'lsa — masalan siz chetdagi qiymatlarni faqat validatsiyadan olib tashlagan bo'lsangiz. Bunda validatsiya balli haqiqiy natijadan yuqori bo'ladi va siz noto'g'ri model tanlaysiz.

Amaliy qadam: o'quv ballini ham eval() rejimida, davr oxirida o'lchang. Shunda ikkala son bir xil sharoitda olinadi va taqqoslash ma'noga ega bo'ladi.

Nimani mustahkamlaydi: 2.2, 2.5-bo'limlar.


Xulosa

Bu darsda to'liq o'rgatish siklini qurdik.

Eng muhim uch fikr:

  1. Besh qadam va ularning tartibi. zero_grad → forward → loss → backward → step. 1-misolda zero_grad ni tashlab yuborganda gradient normasi har qadamda yig'ilib bordi — model esa "ishlayotgandek" ko'rinadi. Bu sikl MNIST dan tortib eng katta modellargacha o'zgarmaydi.

  2. train(), eval() va no_grad() — uch boshqa narsa. train()/eval() rejimni almashtiradi (dropout, BatchNorm), no_grad() esa grafni o'chiradi. 2-misolda train() rejimida qilingan 10 ta bashorat 10 xil aniqlik berdi. Baholashda ikkalasi ham kerak.

  3. Jurnal tashxis quroli. Faqat o'quv loss ni yozish hech narsa bermaydi. Ikkala loss va ikkala metrika birga yozilganda to'rt holat aniq ajraladi: normal, yodlash (o'quv >> val), yetarsiz o'rganish (ikkalasi past, farq kichik) va noto'g'ri lr (loss sakraydi yoki qimirlamaydi). Va oxirida — bitta seed natijasi bitta namuna, shuning uchun muhim qarorlarni bir necha yurish o'rtachasi bilan qabul qiling.

Keyingi darsda 20-qism amaliyoti: hamma narsani bitta loyihaga yig'amiz — xom ma'lumotdan boshlab, arxitektura tanlash, o'rgatish, regularizatsiya, baholash va saqlashgacha.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
20.11-dars: Birinchi to'liq tarmoq — IlmHamroh