Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Nima uchun rasm uchun konvolyutsiya
- 2.2. Birinchi CNN va shakllar zanjiri
- 2.3. Parametrlar hisobi
- 2.4. Halol taqqoslash
- 2.5. Siljishga barqarorlik: ekvivariantlik va invariantlik
- 2.6. Chalkashlik matritsasi va xatolar tahlili
- 2.7. Tuzoqlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Birinchi CNN: shakllar zanjiri va o'rgatish
- Misol 2 — CNN va MLP: halol taqqoslash
- Misol 3 — Siljishga barqarorlik
- Misol 4 — Chalkashlik matritsasi va xato qilingan misollar
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
22.5-dars: Birinchi CNN
22-QISM — KOMPYUTER KO'RISH · 5-dars
1. Kirish va motivatsiya
Oldingi to'rt darsda qurilish bloklarini alohida-alohida ko'rdik: 22.1-darsda rasm — bu (C, H, W) shakldagi sonlar massivi ekanini, 22.2-darsda konvolyutsiyani qo'lda hisoblashni, 22.3-darsda nn.Conv2d va retseptiv maydonni, 22.4-darsda pooling ni. Endi ularni bitta tarmoqqa yig'amiz va birinchi marta haqiqiy rasm ma'lumotida o'rgatamiz.
Ma'lumot sifatida sklearn.datasets.load_digits ni olamiz: 1797 ta qo'lda yozilgan raqam, har biri 8×8 piksel, 17 xil yorqinlik darajasi (0–16). Bu juda kichik rasmlar — lekin CNN ning asosiy g'oyalarini ko'rsatish uchun yetarli, va har bir tajriba bir necha soniyada tugaydi.
Bu darsning markaziy savoli: CNN oddiy MLP dan nimasi bilan yaxshi? 20-qismda ko'rgan to'liq bog'langan tarmoq ham rasmni 64 ta sonli vektor sifatida qabul qilib, raqamlarni yaxshi taniydi. Shuning uchun "CNN yaxshiroq" degan da'voni halol tekshiramiz: parametrlar sonini tenglashtiramiz, bir necha seed bilan o'rgatamiz, juftlashgan farq va uning standart xatosini hisoblaymiz (18-qism). Keyin CNN ning haqiqiy ustunligi qayerda ekanini ko'ramiz — siljishga barqarorlikda.
Real vaziyat. Bank chek skanerlaridagi raqamlarni tanish uchun jamoa MLP o'rgatdi: test to'plamida 98% aniqlik. Ishlab chiqarishda esa aniqlik keskin tushib ketdi. Sabab: yangi skanerlar raqamni kadrda bir-ikki piksel boshqa joyga qo'yardi. Test to'plami o'quv to'plami bilan bir xil kesilgan edi, shuning uchun bu zaiflik baholashda ko'rinmadi. Bu darsning 3-misoli aynan shu holatni o'lchaydi.
Bu darsda birinchi CNN ni quramiz va uni MLP bilan halol taqqoslaymiz.
Bu darsda:
- Nima uchun rasm uchun konvolyutsiya
- Birinchi CNN va shakllar zanjiri
- Parametrlar hisobi
- Halol taqqoslash: parametr, seed, juftlashgan farq
- Siljishga barqarorlik: ekvivariantlik va invariantlik
- Chalkashlik matritsasi va xatolar tahlili
- Tuzoqlar
ℹ Misollar real torch/numpy bilan (Python 3.14, torch 2.14 CPU).
2. Nazariya — chuqur tushuntirish
2.1. Nima uchun rasm uchun konvolyutsiya
MLP RASMNI QANDAY KO'RADI:
8x8 rasm -> 64 ta son (flatten)
har yashirin neyron 64 pikselning HAMMASIGA o'z og'irligi bilan bog'langan
piksel (2, 3) va (2, 4) qo'shni ekanini MLP BILMAYDI
piksellarni istalgan qat'iy tartibda aralashtirsak - MLP uchun farqi yo'q
RASMNING TUZILISHI:
1. lokallik - ma'no qo'shni piksellardan chiqadi (chiziq, burchak)
2. takrorlanish - bir xil naqsh (vertikal chiziq) rasmning istalgan joyida
3. ierarxiya - chiziqlar -> shakllar -> raqam
CNN BU TUZILISHNI ARXITEKTURAGA QO'YADI:
lokal bog'lanish - har chiqish faqat k x k qo'shnilikni ko'radi
og'irlik ulashish - bitta filtr butun rasm bo'ylab yuradi
qatlamlar ketma-ketligi - retseptiv maydon kengayadi 22.3-bob
NATIJA:
kamroq parametr, kuchliroq "oldindan taxmin" (inductive bias)
siljishga ekvivariant konvolyutsiya (2.5)CNN rasm haqidagi bilimni arxitekturaga joylaydi — MLP esa uni ma'lumotdan noldan o'rganishi kerak.
2.2. Birinchi CNN va shakllar zanjiri
KIRISH: (B, 1, 8, 8) B - batch, 1 - kanal (kulrang), 8x8
nn.Conv2d(1, 16, 3, padding=1) -> (B, 16, 8, 8) padding=1: o'lcham saqlanadi
nn.ReLU() -> (B, 16, 8, 8)
nn.MaxPool2d(2) -> (B, 16, 4, 4) har o'q 2 barobar kichik
nn.Conv2d(16, 32, 3, padding=1) -> (B, 32, 4, 4)
nn.ReLU() -> (B, 32, 4, 4)
nn.MaxPool2d(2) -> (B, 32, 2, 2)
nn.Flatten() -> (B, 128) 32 * 2 * 2
nn.Linear(128, 10) -> (B, 10) logitlar
ODATIY NAQSH:
[Conv -> ReLU -> Pool] x N -> Flatten -> Linear
fazoviy o'lcham kichrayadi, kanallar soni o'sadi
"qayerda" ma'lumoti -> "nima" ma'lumotiga almashadi
SHAKLNI TEKSHIRISH:
for qatlam in model: x = qatlam(x); print(qatlam, x.shape)
Linear ning kirish o'lchami (128) aynan shunday topiladi Shakllar zanjirini har doim chop eting — Linear ning kirish o'lchamidagi xato CNN dagi eng ko'p uchraydigan xato.
2.3. Parametrlar hisobi
Conv2d(C_kir, C_chiq, k):
og'irlik: C_chiq * C_kir * k * k
bias: C_chiq
RASM O'LCHAMIGA BOG'LIQ EMAS (og'irlik ulashish)
Linear(n_kir, n_chiq):
n_kir * n_chiq + n_chiq
BIZNING CNN:
Conv2d(1, 16, 3): 16*1*9 + 16 = 160
Conv2d(16, 32, 3): 32*16*9 + 32 = 4640
Linear(128, 10): 128*10 + 10 = 1290
JAMI: 6090
MLP 64 -> h -> 10:
64*h + h + h*10 + 10 = 75h + 10
h = 80 -> 6010 (CNN ga deyarli teng)
DIQQAT:
8x8 rasmda farq kichik
224x224x3 rasmda MLP ning birinchi qatlami: 150528 * h
h = 1000 bo'lsa 150 million parametr - bitta qatlamda
shu rasmda Conv2d(3, 64, 3) - atigi 1792 parametrKonvolyutsiya parametrlari rasm o'lchamiga bog'liq emas — katta rasmda aynan shu hal qiluvchi.
2.4. Halol taqqoslash
NOHALOL TAQQOSLASH (ko'p uchraydi):
CNN 100k parametr, MLP 5k parametr -> "CNN yaxshi"
CNN 3 seed ichidan eng yaxshisi, MLP bitta seed
CNN uchun lr sozlangan, MLP uchun standart
HALOL TAQQOSLASH:
1. parametr soni taxminan TENG (yoki ikkala tomonga ham katta variant)
2. bir xil bo'linish, bir xil davrlar, bir xil optimizator
3. bir necha seed (3-5)
4. juftlashgan farq: har seed da d_s = aniq_CNN_s - aniq_MLP_s
o'rtacha d, SE = std(d) / sqrt(n)
|o'rtacha d| > 2 * SE -> farq sezilarli (taxminiy qoida)
NIMA UCHUN JUFTLASHGAN:
bir seed da ikkala model bir xil tartibda ma'lumot ko'radi
seed ta'siri qisman kamayadi -> farq aniqroq baholanadi
XULOSANI KOD YOZSIN:
if abs(d) <= 2*se: "farq sezilarli emas"
"CNN ustun" deb qattiq yozilgan matn - xato manbaiTaqqoslash natijasi bitta raqam emas, farq va uning SE si — 18-qismdagi qoida bu yerda ham amal qiladi.
2.5. Siljishga barqarorlik: ekvivariantlik va invariantlik
EKVIVARIANTLIK (konvolyutsiya):
kirishni siljitsak -> chiqish ham XUDDI SHUNCHA siljiydi
conv(siljit(x)) = siljit(conv(x)) (chegaradan tashqari)
sabab: bitta filtr hamma joyda bir xil
INVARIANTLIK (pooling va oxirgi qatlamlar):
kirishni siljitsak -> chiqish O'ZGARMAYDI
MaxPool2d(2) kichik siljishlarga QISMAN invariant
(siljish oyna ichida qolsa - maksimum o'zgarmaydi)
TO'LIQ INVARIANTLIK YO'Q:
Flatten + Linear har joyga o'z og'irligini beradi
-> katta siljish CNN ni ham adashtiradi
global average pooling 22.6-bob invariantlikni kuchaytiradi
MLP:
na ekvivariant, na invariant
1 piksel siljish -> 64 ta kirishning deyarli hammasi o'zgaradi
MLP uchun bu butunlay yangi vektor
8x8 RASMDA:
1 piksel = rasm kengligining 12.5%
2 piksel = 25% - bu KATTA siljish, ikkala model ham yomonlashadiKonvolyutsiya siljishga ekvivariant, pooling qisman invariant — MLP da bu xossalar umuman yo'q.
2.6. Chalkashlik matritsasi va xatolar tahlili
UMUMIY ANIQLIK YASHIRADI:
98% aniqlik - lekin qaysi 2% xato?
bitta sinf 90%, qolganlari 99% bo'lishi mumkin
CHALKASHLIK MATRITSASI (14-qism):
M[i, j] = haqiqiy i, bashorat j bo'lgan namunalar soni
diagonal - to'g'ri, diagonaldan tashqari - xato
sinf bo'yicha recall = M[i, i] / M[i, :].sum()
XATOLARNI KO'ZDAN KECHIRISH:
xato qilingan rasmlarni CHIZIB ko'ring
ko'pincha: yorliq xatosi, noaniq yozuv, haqiqatan o'xshash sinflar
modelning ishonchi (softmax) ham ko'rsating:
yuqori ishonch bilan xato -> tekshirish kerak (yorliq xatosi?)
past ishonch bilan xato -> noaniq namuna
KEYINGI QADAM:
eng ko'p chalkashgan juftlik (masalan 8 va 1) -> ma'lumot yoki
augmentatsiya 22.8-bob shu juftlikka qaratiladiXatolarni raqam bilan emas, rasm bilan tahlil qiling — ko'pincha sabab bir qarashda ko'rinadi.
2.7. Tuzoqlar
Asosiy tuzoqlar: kanal o'qini unutish ((B, 8, 8) o'rniga (B, 1, 8, 8) kerak); Linear kirish o'lchamini qo'lda noto'g'ri hisoblash; piksellarni masshtablamaslik (0–16 o'rniga 0–1); CNN va MLP ni turli parametr soni bilan taqqoslash; bitta seed bilan "CNN yaxshi" deyish; test to'plamida siljish yo'q deb barqarorlikni tekshirmaslik; faqat umumiy aniqlikka qarab, sinflar bo'yicha xatoni ko'rmaslik; model.eval() va torch.no_grad() siz baholash.
3. Tez ma'lumotnoma
import numpy as np
import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
d = load_digits()
X = (d.images / 16.0).astype(np.float32) # (1797, 8, 8), 0..1
Xtr, Xte, ytr, yte = train_test_split(X, d.target, test_size=0.3,
random_state=0, stratify=d.target)
Xtr = torch.tensor(Xtr).unsqueeze(1) # (N, 1, 8, 8)
model = nn.Sequential(
nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32 * 2 * 2, 10))
x = torch.zeros(1, 1, 8, 8)
for qatlam in model:
x = qatlam(x)
print(type(qatlam).__name__, tuple(x.shape))
param_soni = sum(p.numel() for p in model.parameters())Birinchi CNN xulosasi
kirish (B, 1, H, W), piksellar 0..1
[Conv -> ReLU -> Pool] x N -> Flatten -> Linear
shakllar zanjirini chop eting
MLP bilan: teng parametr, bir necha seed, juftlashgan farq + SE
siljish va sinflar bo'yicha xatoni alohida tekshiring4. Batafsil misollar
Misollar real torch/numpy bilan (Python 3.14, torch 2.14 CPU).
Misol 1 — Birinchi CNN: shakllar zanjiri va o'rgatish
"""load_digits da birinchi CNN: shakllar, parametrlar, o'rgatish."""
import numpy as np
import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
def cnn_yarat():
return nn.Sequential(
nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32 * 2 * 2, 10))
def aniqlik(model, X, y):
model.eval()
with torch.no_grad():
return (model(X).argmax(1) == y).float().mean().item()
def main() -> None:
d = load_digits()
X = (d.images / 16.0).astype(np.float32)
Xtr, Xte, ytr, yte = train_test_split(X, d.target, test_size=0.3,
random_state=0, stratify=d.target)
Xtr = torch.tensor(Xtr).unsqueeze(1)
Xte = torch.tensor(Xte).unsqueeze(1)
ytr, yte = torch.tensor(ytr), torch.tensor(yte)
print("=== 1. Ma'lumot ===")
print(f" xom rasmlar: {d.images.shape}, qiymatlar "
f"{d.images.min():.0f}..{d.images.max():.0f}")
print(f" o'quv tensori: {tuple(Xtr.shape)} (N, kanal, H, W)")
print(f" test tensori: {tuple(Xte.shape)}")
print(f" masshtab: {Xtr.min().item():.1f}..{Xtr.max().item():.1f}")
print("\n=== 2. Shakllar zanjiri ===")
torch.manual_seed(0)
model = cnn_yarat()
x = Xtr[:4]
print(f" {'kirish':<41} {str(tuple(x.shape)):>16}")
for qatlam in model:
x = qatlam(x)
n = sum(p.numel() for p in qatlam.parameters())
nom = repr(qatlam).split("(")[0]
print(f" {nom:<12} {n:>6} parametr {'':>12} "
f"{str(tuple(x.shape)):>16}")
jami = sum(p.numel() for p in model.parameters())
print(f" jami parametr: {jami}")
print("\n=== 3. O'rgatish (Adam, lr=0.003, batch 64) ===")
opt = torch.optim.Adam(model.parameters(), lr=0.003)
g = torch.Generator().manual_seed(0)
print(f" {'davr':>5} {'o_quv loss':>11} {'o_quv aniq':>11} "
f"{'test aniq':>10}")
for davr in range(1, 31):
model.train()
tartib = torch.randperm(len(ytr), generator=g)
jami_loss = 0.0
for i in range(0, len(ytr), 64):
idx = tartib[i:i + 64]
opt.zero_grad()
loss = nn.functional.cross_entropy(model(Xtr[idx]), ytr[idx])
loss.backward()
opt.step()
jami_loss += loss.item() * len(idx)
if davr in (1, 2, 5, 10, 20, 30):
print(f" {davr:>5} {jami_loss / len(ytr):>11.4f} "
f"{aniqlik(model, Xtr, ytr):>11.4f} "
f"{aniqlik(model, Xte, yte):>10.4f}")
print("\n=== 4. Bitta bashorat ===")
model.eval()
with torch.no_grad():
p = torch.softmax(model(Xte[:1]), 1)[0]
top = p.topk(3)
print(f" haqiqiy: {int(yte[0])}")
for ehtimol, sinf in zip(top.values, top.indices):
print(f" sinf {int(sinf)}: {ehtimol.item():.4f}")
oquv = aniqlik(model, Xtr, ytr)
test = aniqlik(model, Xte, yte)
print(f"\n yakuniy: o'quv {oquv:.4f}, test {test:.4f}, "
f"farq {oquv - test:.4f}")
if oquv - test > 0.05:
print(" o'quv va test orasida katta farq - yodlash belgisi")
else:
print(" o'quv va test yaqin - kuchli yodlash yo'q")
print(" ⭐ 6090 parametrli CNN 8x8 raqamlarni ishonchli taniydi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ma'lumot ===
xom rasmlar: (1797, 8, 8), qiymatlar 0..16
o'quv tensori: (1257, 1, 8, 8) (N, kanal, H, W)
test tensori: (540, 1, 8, 8)
masshtab: 0.0..1.0
=== 2. Shakllar zanjiri ===
kirish (4, 1, 8, 8)
Conv2d 160 parametr (4, 16, 8, 8)
ReLU 0 parametr (4, 16, 8, 8)
MaxPool2d 0 parametr (4, 16, 4, 4)
Conv2d 4640 parametr (4, 32, 4, 4)
ReLU 0 parametr (4, 32, 4, 4)
MaxPool2d 0 parametr (4, 32, 2, 2)
Flatten 0 parametr (4, 128)
Linear 1290 parametr (4, 10)
jami parametr: 6090
=== 3. O'rgatish (Adam, lr=0.003, batch 64) ===
davr o_quv loss o_quv aniq test aniq
1 2.1906 0.7629 0.7519
2 1.5956 0.8250 0.8222
5 0.2158 0.9507 0.9444
10 0.0760 0.9833 0.9741
20 0.0195 0.9968 0.9778
30 0.0087 0.9992 0.9796
=== 4. Bitta bashorat ===
haqiqiy: 1
sinf 1: 0.9561
sinf 8: 0.0418
sinf 4: 0.0020
yakuniy: o'quv 0.9992, test 0.9796, farq 0.0196
o'quv va test yaqin - kuchli yodlash yo'q
⭐ 6090 parametrli CNN 8x8 raqamlarni ishonchli taniydiNima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 2 — CNN va MLP: halol taqqoslash
"""Teng parametrli CNN va MLP: bir necha seed, juftlashgan farq."""
import numpy as np
import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
def cnn_yarat():
return nn.Sequential(
nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32 * 2 * 2, 10))
def mlp_yarat(h):
return nn.Sequential(nn.Flatten(), nn.Linear(64, h), nn.ReLU(),
nn.Linear(h, 10))
def orgat(model, X, y, seed, davrlar=30):
opt = torch.optim.Adam(model.parameters(), lr=0.003)
g = torch.Generator().manual_seed(seed)
for _ in range(davrlar):
model.train()
tartib = torch.randperm(len(y), generator=g)
for i in range(0, len(y), 64):
idx = tartib[i:i + 64]
opt.zero_grad()
nn.functional.cross_entropy(model(X[idx]), y[idx]).backward()
opt.step()
model.eval()
return model
def aniqlik(model, X, y):
with torch.no_grad():
return (model(X).argmax(1) == y).float().mean().item()
def main() -> None:
d = load_digits()
X = (d.images / 16.0).astype(np.float32)
Xtr, Xte, ytr, yte = train_test_split(X, d.target, test_size=0.3,
random_state=0, stratify=d.target)
Xtr = torch.tensor(Xtr).unsqueeze(1)
Xte = torch.tensor(Xte).unsqueeze(1)
ytr, yte = torch.tensor(ytr), torch.tensor(yte)
modellar = {"CNN": cnn_yarat,
"MLP h=80": lambda: mlp_yarat(80),
"MLP h=256": lambda: mlp_yarat(256)}
seedlar = [0, 1, 2, 3]
print("=== 1. Parametrlar soni ===")
for nom, yasa in modellar.items():
n = sum(p.numel() for p in yasa().parameters())
print(f" {nom:<10} {n:>7}")
print("\n=== 2. Test aniqligi (har seed) ===")
natija = {nom: [] for nom in modellar}
for s in seedlar:
for nom, yasa in modellar.items():
torch.manual_seed(s)
m = orgat(yasa(), Xtr, ytr, s)
natija[nom].append(aniqlik(m, Xte, yte))
print(f" {'seed':>5} " + " ".join(f"{n:>10}" for n in modellar))
for k, s in enumerate(seedlar):
print(f" {s:>5} " + " ".join(f"{natija[n][k]:>10.4f}"
for n in modellar))
print(f" {'o_rt':>5} " + " ".join(f"{np.mean(natija[n]):>10.4f}"
for n in modellar))
print("\n=== 3. Juftlashgan farq (CNN - MLP) ===")
cnn = np.array(natija["CNN"])
print(f" {'raqib':<10} {'o_rt farq':>10} {'SE':>8} {'xulosa':>28}")
for nom in ["MLP h=80", "MLP h=256"]:
farq = cnn - np.array(natija[nom])
se = farq.std(ddof=1) / np.sqrt(len(farq))
if abs(farq.mean()) <= 2 * se:
xulosa = "sezilarli farq yo'q"
elif farq.mean() > 0:
xulosa = "CNN sezilarli yaxshi"
else:
xulosa = "MLP sezilarli yaxshi"
print(f" {nom:<10} {farq.mean():>+10.4f} {se:>8.4f} {xulosa:>28}")
xato_cnn = 1 - cnn.mean()
xato_mlp = 1 - np.mean(natija["MLP h=80"])
print(f"\n xato ulushi: CNN {xato_cnn:.4f}, MLP h=80 {xato_mlp:.4f}")
if xato_cnn < xato_mlp:
print(f" CNN xatolari soni MLP xatolarining {xato_cnn / xato_mlp:.0%} "
f"qismini tashkil etadi")
else:
print(" CNN xatolari MLP xatolaridan kam emas")
print(" 8x8 markazlangan raqamlarda ikkala model ham 97% dan yuqori")
print(" ⭐ Farq kichik bo'lsa ham SE bilan tekshirilgan farq - fakt")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Parametrlar soni ===
CNN 6090
MLP h=80 6010
MLP h=256 19210
=== 2. Test aniqligi (har seed) ===
seed CNN MLP h=80 MLP h=256
0 0.9796 0.9778 0.9778
1 0.9833 0.9778 0.9796
2 0.9870 0.9759 0.9815
3 0.9852 0.9759 0.9796
o_rt 0.9838 0.9769 0.9796
=== 3. Juftlashgan farq (CNN - MLP) ===
raqib o_rt farq SE xulosa
MLP h=80 +0.0069 0.0021 CNN sezilarli yaxshi
MLP h=256 +0.0042 0.0009 CNN sezilarli yaxshi
xato ulushi: CNN 0.0162, MLP h=80 0.0231
CNN xatolari soni MLP xatolarining 70% qismini tashkil etadi
8x8 markazlangan raqamlarda ikkala model ham 97% dan yuqori
⭐ Farq kichik bo'lsa ham SE bilan tekshirilgan farq - faktNima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 3 — Siljishga barqarorlik
"""Test rasmlarini 1-2 piksel siljitsak CNN va MLP qanday o'zgaradi."""
import numpy as np
import torch
import torch.nn as nn
from scipy import ndimage
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
def cnn_yarat():
return nn.Sequential(
nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32 * 2 * 2, 10))
def mlp_yarat():
return nn.Sequential(nn.Flatten(), nn.Linear(64, 80), nn.ReLU(),
nn.Linear(80, 10))
def orgat(model, X, y, seed, davrlar=30):
opt = torch.optim.Adam(model.parameters(), lr=0.003)
g = torch.Generator().manual_seed(seed)
for _ in range(davrlar):
model.train()
tartib = torch.randperm(len(y), generator=g)
for i in range(0, len(y), 64):
idx = tartib[i:i + 64]
opt.zero_grad()
nn.functional.cross_entropy(model(X[idx]), y[idx]).backward()
opt.step()
model.eval()
return model
def aniqlik(model, X, y):
with torch.no_grad():
return (model(X).argmax(1) == y).float().mean().item()
def siljit(X, dy, dx):
"""Butun piksel siljish, bo'shagan joy 0 bilan to'ldiriladi."""
return np.stack([ndimage.shift(x, (dy, dx), order=0, mode="constant")
for x in X])
def main() -> None:
d = load_digits()
X = (d.images / 16.0).astype(np.float32)
Xtr, Xte, ytr, yte = train_test_split(X, d.target, test_size=0.3,
random_state=0, stratify=d.target)
T = lambda a: torch.tensor(a).unsqueeze(1)
Xtr_t, Xte_t = T(Xtr), T(Xte)
ytr_t, yte_t = torch.tensor(ytr), torch.tensor(yte)
print("=== 1. Konvolyutsiya ekvivariantligi ===")
torch.manual_seed(0)
conv = nn.Conv2d(1, 4, 3, padding=1)
x = Xte_t[:1]
xs = T(siljit(Xte[:1], 0, 1))
with torch.no_grad():
a = conv(xs)
b = torch.roll(conv(x), 1, dims=3)
ichki = (a - b)[..., 2:-2].abs().max().item()
print(f" conv(siljit(x)) va siljit(conv(x)) ichki farqi: {ichki:.2e}")
print(" (chegara ustunlari hisobga olinmadi)")
with torch.no_grad():
p1 = nn.MaxPool2d(2)(torch.relu(conv(x)))
p2 = nn.MaxPool2d(2)(torch.relu(conv(xs)))
ozgardi = (p1 - p2).abs().gt(1e-6).float().mean().item()
print(f" pooling dan keyin 1 piksel siljishda o'zgargan qiymatlar: "
f"{ozgardi:.1%}")
print(" pooling faqat QISMAN invariant")
print("\n=== 2. Siljitilgan test to'plamlari ===")
yonalishlar = {1: [(0, 1), (0, -1), (1, 0), (-1, 0)],
2: [(0, 2), (0, -2), (2, 0), (-2, 0)]}
toplamlar = {0: [Xte_t]}
for k, yon in yonalishlar.items():
toplamlar[k] = [T(siljit(Xte, dy, dx)) for dy, dx in yon]
for k in (1, 2):
chiqqan = np.mean([(np.abs(siljit(Xte, dy, dx)).sum((1, 2))
< np.abs(Xte).sum((1, 2)) - 1e-6).mean()
for dy, dx in yonalishlar[k]])
print(f" {k} piksel: siyohning bir qismi kadrdan chiqqan rasmlar "
f"{chiqqan:.1%}")
print("\n=== 3. Aniqlik (3 seed, 4 yo'nalish o'rtachasi) ===")
natija = {"CNN": {k: [] for k in toplamlar},
"MLP": {k: [] for k in toplamlar}}
for s in range(3):
for nom, yasa in [("CNN", cnn_yarat), ("MLP", mlp_yarat)]:
torch.manual_seed(s)
m = orgat(yasa(), Xtr_t, ytr_t, s)
for k, lst in toplamlar.items():
natija[nom][k].append(np.mean([aniqlik(m, Z, yte_t)
for Z in lst]))
print(f" {'siljish':>8} {'CNN':>8} {'MLP':>8} {'farq':>8} {'SE':>7} "
f"{'sezilarli':>10}")
for k in toplamlar:
c = np.array(natija["CNN"][k])
m = np.array(natija["MLP"][k])
farq = c - m
se = farq.std(ddof=1) / np.sqrt(len(farq))
print(f" {k:>6}px {c.mean():>8.4f} {m.mean():>8.4f} "
f"{farq.mean():>+8.4f} {se:>7.4f} "
f"{str(abs(farq.mean()) > 2 * se):>10}")
print("\n=== 4. Nisbiy yo'qotish ===")
for nom in ["CNN", "MLP"]:
t0 = np.mean(natija[nom][0])
t1 = np.mean(natija[nom][1])
t2 = np.mean(natija[nom][2])
print(f" {nom}: 1px da aniqlikning {1 - t1 / t0:.0%} qismi, "
f"2px da {1 - t2 / t0:.0%} qismi yo'qoldi")
c1 = np.mean(natija["CNN"][1])
m1 = np.mean(natija["MLP"][1])
if c1 > m1:
print(f" 1px siljishda CNN MLP dan {c1 - m1:.2f} ga yuqori")
else:
print(" 1px siljishda CNN ustunlik ko'rsatmadi")
if c1 < 0.9:
print(" lekin CNN ham kuchli yomonlashdi: to'liq invariantlik YO'Q")
print(" ⭐ Barqarorlikni alohida o'lchang - toza test uni ko'rsatmaydi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Konvolyutsiya ekvivariantligi ===
conv(siljit(x)) va siljit(conv(x)) ichki farqi: 0.00e+00
(chegara ustunlari hisobga olinmadi)
pooling dan keyin 1 piksel siljishda o'zgargan qiymatlar: 46.9%
pooling faqat QISMAN invariant
=== 2. Siljitilgan test to'plamlari ===
1 piksel: siyohning bir qismi kadrdan chiqqan rasmlar 53.8%
2 piksel: siyohning bir qismi kadrdan chiqqan rasmlar 94.2%
=== 3. Aniqlik (3 seed, 4 yo'nalish o'rtachasi) ===
siljish CNN MLP farq SE sezilarli
0px 0.9833 0.9772 +0.0062 0.0027 True
1px 0.6446 0.4606 +0.1840 0.0161 True
2px 0.2282 0.1136 +0.1147 0.0129 True
=== 4. Nisbiy yo'qotish ===
CNN: 1px da aniqlikning 34% qismi, 2px da 77% qismi yo'qoldi
MLP: 1px da aniqlikning 53% qismi, 2px da 88% qismi yo'qoldi
1px siljishda CNN MLP dan 0.18 ga yuqori
lekin CNN ham kuchli yomonlashdi: to'liq invariantlik YO'Q
⭐ Barqarorlikni alohida o'lchang - toza test uni ko'rsatmaydiNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Chalkashlik matritsasi va xato qilingan misollar
"""CNN qaysi raqamlarni adashtiradi - matritsa va rasmlar."""
import numpy as np
import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
def cnn_yarat():
return nn.Sequential(
nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32 * 2 * 2, 10))
def orgat(model, X, y, seed, davrlar=30):
opt = torch.optim.Adam(model.parameters(), lr=0.003)
g = torch.Generator().manual_seed(seed)
for _ in range(davrlar):
model.train()
tartib = torch.randperm(len(y), generator=g)
for i in range(0, len(y), 64):
idx = tartib[i:i + 64]
opt.zero_grad()
nn.functional.cross_entropy(model(X[idx]), y[idx]).backward()
opt.step()
model.eval()
return model
def chiz(rasm):
belgilar = " .:+#"
qatorlar = []
for satr in rasm:
qatorlar.append("".join(belgilar[min(4, int(v * 5))] * 2
for v in satr))
return qatorlar
def main() -> None:
d = load_digits()
X = (d.images / 16.0).astype(np.float32)
Xtr, Xte, ytr, yte = train_test_split(X, d.target, test_size=0.3,
random_state=0, stratify=d.target)
Xtr_t = torch.tensor(Xtr).unsqueeze(1)
Xte_t = torch.tensor(Xte).unsqueeze(1)
torch.manual_seed(0)
model = orgat(cnn_yarat(), Xtr_t, torch.tensor(ytr), seed=0)
with torch.no_grad():
p = torch.softmax(model(Xte_t), 1).numpy()
bashorat = p.argmax(1)
print("=== 1. Chalkashlik matritsasi (qator - haqiqiy) ===")
M = confusion_matrix(yte, bashorat)
print(" " + "".join(f"{j:>4}" for j in range(10)))
for i in range(10):
print(f" {i:>3}: " + "".join(f"{M[i, j]:>4}" for j in range(10)))
print(f" jami aniqlik: {np.trace(M) / M.sum():.4f}, "
f"xatolar: {M.sum() - np.trace(M)} / {M.sum()}")
print("\n=== 2. Sinflar bo'yicha recall ===")
recall = M.diagonal() / M.sum(1)
tartib = np.argsort(recall)
for i in tartib[:4]:
print(f" raqam {i}: {recall[i]:.4f}")
print(f" eng yaxshi: raqam {tartib[-1]} ({recall[tartib[-1]]:.4f})")
print(f" sinflar orasidagi oraliq: {recall.max() - recall.min():.4f}")
print("\n=== 3. Eng ko'p chalkashgan juftliklar ===")
Mx = M.copy()
np.fill_diagonal(Mx, 0)
juftlar = sorted(((Mx[i, j], i, j) for i in range(10)
for j in range(10) if Mx[i, j] > 0), reverse=True)
for soni, i, j in juftlar[:4]:
print(f" haqiqiy {i} -> bashorat {j}: {soni} marta")
print("\n=== 4. Xato qilingan rasmlar ===")
xato = np.where(bashorat != yte)[0]
ishonch = p[xato, bashorat[xato]]
tanlov = xato[np.argsort(-ishonch)[:3]]
rasmlar = [chiz(Xte[i]) for i in tanlov]
sarlavha = [f"h={yte[i]} b={bashorat[i]} p={p[i, bashorat[i]]:.2f}"
for i in tanlov]
print(" " + " ".join(f"{s:<16}" for s in sarlavha))
for q in range(8):
print(" " + " ".join(f"{r[q]:<16}" for r in rasmlar))
yuqori = int((ishonch > 0.9).sum())
print(f"\n xatolardan {yuqori} tasi 0.9 dan yuqori ishonch bilan")
print(f" xatolardagi o'rtacha ishonch: {ishonch.mean():.3f}")
togri = np.where(bashorat == yte)[0]
print(f" to'g'ri javoblardagi o'rtacha ishonch: "
f"{p[togri, bashorat[togri]].mean():.3f}")
print(" ⭐ Xatolarni ko'zdan kechiring - sabab ko'pincha rasmning o'zida")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Chalkashlik matritsasi (qator - haqiqiy) ===
0 1 2 3 4 5 6 7 8 9
0: 54 0 0 0 0 0 0 0 0 0
1: 0 53 0 0 0 0 0 0 2 0
2: 0 1 52 0 0 0 0 0 0 0
3: 0 0 0 52 0 0 0 0 1 2
4: 0 0 0 0 54 0 0 0 0 0
5: 0 0 0 1 0 54 0 0 0 0
6: 0 1 0 0 0 0 53 0 0 0
7: 0 0 0 0 0 0 0 54 0 0
8: 0 1 0 0 0 0 0 1 50 0
9: 0 0 0 0 0 0 0 0 1 53
jami aniqlik: 0.9796, xatolar: 11 / 540
=== 2. Sinflar bo'yicha recall ===
raqam 3: 0.9455
raqam 8: 0.9615
raqam 1: 0.9636
raqam 2: 0.9811
eng yaxshi: raqam 4 1.0000-bob
sinflar orasidagi oraliq: 0.0545
=== 3. Eng ko'p chalkashgan juftliklar ===
haqiqiy 3 -> bashorat 9: 2 marta
haqiqiy 1 -> bashorat 8: 2 marta
haqiqiy 9 -> bashorat 8: 1 marta
haqiqiy 8 -> bashorat 7: 1 marta
=== 4. Xato qilingan rasmlar ===
h=8 b=1 p=0.79 h=3 b=9 p=0.72 h=9 b=8 p=0.64
:::: ..##:: ++##++
..#### ###### ##::::##
..##++##.. ##++## :::: ::++
..##++## ..####:: :::: ####
###### ....##.. ####::##
##++:: ##:: ::..
..## ++## ++::::##.. ..##..::::
++++:: ::####++ ++####..
xatolardan 0 tasi 0.9 dan yuqori ishonch bilan
xatolardagi o'rtacha ishonch: 0.603
to'g'ri javoblardagi o'rtacha ishonch: 0.990
⭐ Xatolarni ko'zdan kechiring - sabab ko'pincha rasmning o'zidaNima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "CNN har doim MLP dan ancha yaxshi" | Kichik markazlangan rasmda farq kichik — o'lchash kerak |
| "Ko'proq parametr — shuning uchun CNN yutdi" | Halol taqqoslashda parametr teng qilinadi |
| "CNN siljishga to'liq invariant" | Konvolyutsiya ekvivariant, pooling qisman invariant |
| "Bitta seed yetarli" | Seed farqi model farqidan katta bo'lishi mumkin |
| "Test aniqligi 98% — ishlab chiqarishga tayyor" | Siljish kabi o'zgarishlarni alohida tekshiring |
"Conv2d parametrlari rasm o'lchami bilan o'sadi" |
Faqat kanal va yadro o'lchamiga bog'liq |
| "Kanal o'qi ixtiyoriy" | Conv2d (B, C, H, W) kutadi |
| "Umumiy aniqlik hammasini aytadi" | Sinflar bo'yicha recall va xato rasmlari kerak |
6. Keng tarqalgan xatolar va yechimlari
1. Kanal o'qi yo'q
model(torch.tensor(Xtr)) # (N, 8, 8) # ⚠️
model(torch.tensor(Xtr).unsqueeze(1)) # (N, 1, 8, 8) # ✅2. Linear kirishi qo'lda noto'g'ri
nn.Linear(32 * 8 * 8, 10) # ikki pooling unutilgan # ⚠️
nn.Linear(32 * 2 * 2, 10) # shakllar zanjiridan olingan # ✅3. Masshtablanmagan piksellar
X = d.images.astype(np.float32) # 0..16 # ⚠️
X = (d.images / 16.0).astype(np.float32) # 0..1 # ✅4. Teng bo'lmagan taqqoslash
# CNN 100k parametr va MLP 5k parametr # ⚠️
# parametr soni taxminan teng + katta variant ham # ✅5. Bitta seed
aniq_cnn > aniq_mlp # bitta ishga tushirish # ⚠️
farq = cnn_s - mlp_s; abs(farq.mean()) > 2 * se # ✅6. np.roll bilan siljitish
np.roll(x, 1, axis=1) # o'ng chet chapga o'tadi # ⚠️
ndimage.shift(x, (0, 1), order=0, mode="constant") # ✅7. eval siz baholash
aniq = (model(Xte).argmax(1) == yte).float().mean() # ⚠️
model.eval()
with torch.no_grad(): aniq = ... # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 20-qism (o'tilgan): MLP, orqaga tarqalish, yo'qotish funksiyalari
- 21.5-dars (o'tilgan): Trainer — bu darsdagi o'rgatish sikli uning soddalashgan shakli
- 18-qism (o'tilgan): Juftlashgan taqqoslash va standart xato
- 22.3, 22.4-darslar (o'tilgan):
nn.Conv2d, retseptiv maydon, pooling - Keyingi darslar: CNN arxitekturalari, chuqur CNN ni o'rgatish, rasm augmentatsiyasi, transfer learning
8. Eng yaxshi amaliyotlar
Kirishni
(B, C, H, W)shaklga keltiring va 0–1 ga masshtablang.Shakllar zanjirini chop eting.
Parametrlar sonini hisoblang va hisobotda ko'rsating.
Bazaviy model (MLP yoki logistik regressiya) bilan taqqoslang.
Teng parametr, bir necha seed, juftlashgan farq + SE.
Siljish kabi real o'zgarishlarga barqarorlikni alohida o'lchang.
Sinflar bo'yicha recall va chalkashlik matritsasini ko'ring.
Xato qilingan rasmlarni ko'zdan kechiring.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # load_digits rasmlari o'lchami va qiymatlar oralig'i?
2. # Conv2d kutadigan kirish shakli?
3. # Conv2d(16, 32, 3) parametrlari soni?
4. # 8x8 kirish ikki MaxPool2d(2) dan keyin?
5. # Flatten dan keyingi o'lcham (32 kanal)?
6. # MLP 64 -> 80 -> 10 parametrlari?
7. # halol taqqoslashning 3 sharti?
8. # juftlashgan farqda SE formulasi?
9. # ekvivariantlik nima?
10. # nima uchun MLP siljishga zaif?
11. # np.roll bilan siljitishning muammosi?
12. # chalkashlik matritsasida M[i, j]?Javoblar
(8, 8), 0–16(B, C, H, W)32 * 16 * 9 + 32 = 46402 × 232 * 2 * 2 = 12864 * 80 + 80 + 80 * 10 + 10 = 6010- Teng parametr, bir xil bo'linish/davrlar, bir necha seed
std(d, ddof=1) / sqrt(n)- Kirish siljisa, chiqish ham shuncha siljiydi
- Har piksel o'z og'irligiga ega — siljish butunlay yangi vektor beradi
- Chetdan chiqqan piksellar qarama-qarshi chetga o'tadi
- Haqiqiy
i, bashoratjbo'lgan namunalar soni
Vazifa 2: Xatolarni tuzating
1. model(torch.tensor(d.images, dtype=torch.float32))
2. nn.Linear(32 * 8 * 8, 10) # ikki MaxPool2d(2) dan keyin
3. print("CNN yaxshiroq" if aniq_cnn > aniq_mlp else "MLP yaxshiroq")
4. x_sil = np.roll(x, 2, axis=1)
5. aniq = (model(Xte).argmax(1) == yte).float().mean() # train rejimidaJavoblar
1. model(torch.tensor(d.images / 16.0, dtype=torch.float32).unsqueeze(1))
2. nn.Linear(32 * 2 * 2, 10)
3. farq = cnn_s - mlp_s
se = farq.std(ddof=1) / np.sqrt(len(farq))
print("sezilarli" if abs(farq.mean()) > 2 * se else "sezilarli emas")
4. x_sil = ndimage.shift(x, (0, 2), order=0, mode="constant")
5. model.eval()
with torch.no_grad():
aniq = (model(Xte).argmax(1) == yte).float().mean()Vazifa 3: Birinchi CNN
Modellang:
- Shakllar zanjiri
- Parametrlar
- O'rgatish egri chizig'i
- Bitta bashorat
Vazifa 4: Halol taqqoslash
Modellang:
- Teng parametr
- Seedlar
- Juftlashgan farq
- Katta MLP
Vazifa 5: Siljish
Modellang:
- Ekvivariantlik
- 1 va 2 piksel
- Juftlashgan farq
- Nisbiy yo'qotish
Vazifa 6: Xatolar
Modellang:
- Matritsa
- Recall
- Juftliklar
- Rasmlar
Vazifa 7: O'ylash
Hamkasbingiz aytdi: "Bizda CNN va MLP deyarli bir xil test aniqligi berdi (98.3% va 97.7%). Demak CNN ga vaqt sarflashning keragi yo'q, oddiy MLP ni ishlatamiz." Siz nima deysiz?
Javob
Qisqa javob: toza test to'plamidagi aniqlik — savolning faqat bir qismi. Qaror ma'lumot va ishlab chiqarish sharoitiga bog'liq.
1. Avval farqning o'zini tekshiring. 0.6 foiz punkt farq bitta seed da tasodif bo'lishi mumkin. Bir necha seed bilan juftlashgan farq va SE hisoblang. 2-misolda bu farq kichik bo'lsa ham SE bilan solishtirildi — shundan keyingina "sezilarli" yoki "sezilarli emas" deyish mumkin.
2. Aniqlikni xato ulushi sifatida ham ko'ring. 98.3% va 97.7% — bu 1.7% va 2.3% xato. Ya'ni bir model ikkinchisidan taxminan 30% kam xato qiladi. Chek skanerida kuniga 100 000 raqam bo'lsa, bu yuzlab xato demakdir.
3. Toza test sharoitni aks ettiradimi? load_digits raqamlari markazlangan va bir xil masshtabda. Ishlab chiqarishda esa:
- raqam kadrda boshqa joyda bo'lishi mumkin (siljish)
- rasm kattaroq bo'lishi mumkin (28×28, 64×64)
- yorug'lik va qalinlik boshqacha
3-misolda 1 piksel siljishda MLP ning aniqligi CNN aniqligidan ancha ko'proq tushdi. Toza testda bu umuman ko'rinmaydi.
4. Masshtab haqida. 8×8 da MLP ning birinchi qatlami 64 × h. Real skanerda 64×64 rasm bo'lsa — 4096 × h, va har piksel o'z og'irligini alohida o'rganishi kerak. CNN parametrlari esa rasm o'lchamiga bog'liq emas.
Tavsiya:
# 1. Ikkala model uchun 3-5 seed, juftlashgan farq + SE
# 2. Ishlab chiqarishga o'xshash test: siljitilgan, shovqinli rasmlar
# 3. Agar MLP hamma sharoitda teng bo'lsa - soddasini tanlang
# 4. Aks holda - CNN (yoki siljish augmentatsiyasi bilan MLP ni sinang)Hamkasbga javob: "Soddaroq modelni tanlash to'g'ri tamoyil — lekin bir xil sharoitda teng bo'lsa. Keling, ikkalasini ishlab chiqarishga o'xshash test to'plamida (siljish, shovqin bilan) bir necha seed bilan solishtiraylik. Agar MLP u yerda ham teng bo'lsa — MLP ni olamiz."
Nimani mustahkamlaydi: 2.4, 2.5-bo'limlar.
Xulosa
Bu darsda birinchi CNN ni qurdik va uni MLP bilan halol taqqosladik.
Eng muhim uch fikr:
CNN —
[Conv → ReLU → Pool] × N → Flatten → Linear. 1-misolda shakllar zanjiri(B, 1, 8, 8)dan(B, 32, 2, 2)gacha kichrayib,Flattendan keyin 128 o'lchamli vektorga aylandi —Linear(128, 10)ning kirishi aynan shu zanjirdan olinadi. 6090 parametrli tarmoq 30 davrda test to'plamida0.9796aniqlikka yetdi, o'quv va test orasidagi farq atigi0.02. Konvolyutsiya parametrlari faqat kanal va yadro o'lchamiga bog'liq — rasm kattalashsa ham ular o'zgarmaydi.Halol taqqoslash — teng parametr, bir necha seed, juftlashgan farq. 2-misolda 6090 parametrli CNN va 6010 parametrli MLP to'rt seed da bir xil sharoitda o'rgatildi: o'rtacha
0.9838va0.9769. Farq kichik (+0.0069), lekin uningSEsi0.0021— ya'ni farq2 × SEdan katta va sezilarli. Uch barobar katta MLP (19 210 parametr) ham farqni yopmadi (+0.0042,SE 0.0009). Xato ulushi bo'yicha CNN MLP xatolarining taxminan 70% ini qildi. Bu xulosani kod natijadan hisobladi — oldindan yozilgan "CNN ustun" matni emas.CNN ning haqiqiy ustunligi — siljishga barqarorlik, lekin u to'liq emas. 3-misolda konvolyutsiya ekvivariantligi aniq tasdiqlandi (ichki farq
0), pooling esa faqat qisman invariant chiqdi. Test rasmlarini 1 piksel siljitganda CNN aniqligi0.64ga, MLP niki0.46ga tushdi — farq+0.18, toza testdagi+0.006dan o'ttiz barobar katta. Lekin CNN ham aniqligining uchdan bir qismini yo'qotdi: 8×8 rasmda 1 piksel — kenglikning 12.5% i, vaFlatten + Linearhar joyga o'z og'irligini beradi. 4-misoldagi chalkashlik matritsasi esa 540 ta testdan 11 ta xatoni ko'rsatdi: eng qiyin sinf3(recall0.9455), xatolardagi o'rtacha ishonch0.60— to'g'ri javoblardagi0.99dan ancha past.
Keyingi darsda CNN arxitekturalari: LeNet, VGG va ResNet uslubidagi bloklar, 3×3 yadrolar to'plami, residual ulanish va global average pooling.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!