Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Sirpanuvchi oyna
- 2.2. Klassik yadrolar
- 2.3. Padding
- 2.4. Stride va chiqish o'lchami formulasi
- 2.5. Cross-correlation va konvolyutsiya
- 2.6. Chiziqlilik va im2col
- 2.7. Tuzoqlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Konvolyutsiya qo'lda va torch bilan
- Misol 2 — Klassik yadrolar
- Misol 3 — Padding, stride va o'lcham formulasi
- Misol 4 — Cross-correlation, chiziqlilik va im2col
- 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.2-dars: Konvolyutsiya
22-QISM — KOMPYUTER KO'RISH · 2-dars
1. Kirish va motivatsiya
22.1-darsda ko'rdik: rasmni flatten qilib piksellarni belgi sifatida ishlatsak, shakl joyi o'zgarishi bilan model adashadi. Sintetik shakllarda logistik regressiya shakl markazda bo'lganda xatosiz ishladi, tasodifiy joyda esa 0.7 atrofida qoldi. Bizga joyga bog'liq bo'lmagan belgi kerak: "bu yerda vertikal chegara bor", "bu yerda burchak bor" — rasmning qayerida bo'lishidan qat'i nazar.
Konvolyutsiya aynan shuni qiladi. Kichik sonlar matritsasi — yadro (kernel, filtr) — rasm ustida sirpanadi va har joyda bitta skalyar ko'paytma hisoblaydi. Natija — yangi "rasm", u har joyda yadroga o'xshash naqsh qanchalik kuchli ekanini ko'rsatadi. Yadro bitta, joylar ko'p — shu sabab "chegara detektori" rasmning hamma joyida bir xil ishlaydi.
Konvolyutsiya kompyuter ko'rishga neyron tarmoqlardan ancha oldin kirgan: xiralashtirish, keskinlashtirish, Sobel chegara detektori — hammasi qo'lda tanlangan yadrolar. CNN ning g'oyasi oddiy: yadrolarni qo'lda tanlash o'rniga ularni o'rgatamiz. Lekin buning uchun avval amalning o'zini ichidan tushunish kerak — padding, stride, chiqish o'lchami va torch aslida nimani hisoblashini.
Real vaziyat. Bir muhandis tibbiy rasmlar uchun CNN yozdi va har qatlamdan keyin o'lchamni qo'lda hisobladi. Uchinchi qatlamda stride=2 va toq o'lcham tufayli bir piksel yo'qoldi, Linear qatlamiga kiruvchi o'lcham mos kelmay, RuntimeError: mat1 and mat2 shapes cannot be multiplied chiqdi. Formulani bilganida bu xatoni kod yozishdan oldin ko'rgan bo'lardi.
Bu darsda konvolyutsiyani qo'lda yozamiz va torch bilan aynan solishtiramiz.
Bu darsda:
- Sirpanuvchi oyna: konvolyutsiya qadam-baqadam
- Klassik yadrolar: xiralashtirish, chegara, Sobel
- Padding va stride
- Chiqish o'lchami formulasi
- Cross-correlation va konvolyutsiya
- Chiziqlilik va im2col
- Tuzoqlar
ℹ Misollar real torch/numpy bilan (Python 3.14, torch 2.14 CPU).
2. Nazariya — chuqur tushuntirish
2.1. Sirpanuvchi oyna
KIRISH x: (H, W), YADRO k: (kh, kw)
chiqish[i, j] = SUM_{a, b} x[i + a, j + b] * k[a, b]
a = 0..kh-1, b = 0..kw-1
QADAMLAR:
1. yadroni chap-yuqori burchakka qo'yish
2. ostidagi oyna bilan elementma-element ko'paytirish
3. yig'indini chiqishga yozish
4. bir qadam o'ngga siljish; qator tugasa - pastga
MISOL (3x3 yadro, 5x5 kirish, padding yo'q):
chiqish 3x3 - yadro faqat 3 x 3 = 9 joyga to'liq sig'adi
BITTA CHIQISH = oyna va yadroning SKALYAR KO'PAYTMASI
-> oyna yadroga "o'xshasa", javob katta
-> yadro - naqsh shabloniKonvolyutsiya — har joyda bir xil yadro bilan skalyar ko'paytma; natija — naqsh qayerda kuchli ekanining xaritasi.
2.2. Klassik yadrolar
XIRALASHTIRISH (yig'indi = 1, yorqinlik saqlanadi):
o'rtacha 3x3: 1/9 * [[1,1,1],[1,1,1],[1,1,1]]
Gauss 3x3: 1/16 * [[1,2,1],[2,4,2],[1,2,1]]
-> shovqin kamayadi, chegaralar yumshaydi
KESKINLASHTIRISH (yig'indi = 1):
[[0,-1,0],[-1,5,-1],[0,-1,0]] = aynan + (aynan - xira)
CHEGARA (yig'indi = 0, tekis joyda javob 0):
Laplas: [[0,1,0],[1,-4,1],[0,1,0]] - hamma yo'nalish
Sobel x: [[-1,0,1],[-2,0,2],[-1,0,1]] - vertikal chegara
Sobel y: [[-1,-2,-1],[0,0,0],[1,2,1]] - gorizontal chegara
kattalik: sqrt(gx^2 + gy^2)
YIG'INDI QOIDASI:
yig'indi 1 -> tekis joy o'zgarmaydi
yig'indi 0 -> tekis joy 0 ga aylanadi, faqat O'ZGARISH qoladi
SHOVQIN: chegara yadrolari shovqinni kuchaytiradi
-> avval xiralashtirish, keyin chegara (Canny g'oyasi)Yadro yig'indisi uning vazifasini aytadi: 1 — silliqlash, 0 — o'zgarishni topish.
2.3. Padding
MUAMMO: padding siz har qatlamda rasm kichrayadi
28 -> 26 -> 24 -> ... (3x3 yadro)
va chekka piksellar kamroq "ko'riladi"
PADDING p: chetga p qator/ustun qo'shish
p = (k - 1) / 2 (toq k) -> o'lcham saqlanadi ("same")
k=3 -> p=1, k=5 -> p=2, k=7 -> p=3
TURLARI (F.pad mode=...):
constant (0) - eng keng tarqalgan, chegara qorayadi
reflect - ko'zgu: [3 2 | 1 2 3 | 2 1]
replicate - chetini takrorlash: [1 1 | 1 2 3 | 3 3]
circular - aylanma: [2 3 | 1 2 3 | 1 2]
nn.Conv2d(..., padding=1, padding_mode="zeros"/"reflect"/...)
padding="same" - faqat stride=1 da p = (k - 1) / 2 o'lchamni saqlaydi; nol padding chegara piksellarini qoraytiradi.
2.4. Stride va chiqish o'lchami formulasi
STRIDE s: oyna har safar s piksel siljiydi
s = 2 -> chiqish taxminan 2 barobar kichik (har o'qda)
FORMULA (har o'q uchun alohida):
H_chiq = floor((H + 2p - k) / s) + 1
MISOLLAR:
H=28, k=3, p=1, s=1 -> 28 (same)
H=28, k=3, p=1, s=2 -> 14
H=27, k=3, p=1, s=2 -> 14
H=8, k=3, p=0, s=2 -> 3 (floor(2.5) + 1)
FLOOR NIMANI ANGLATADI:
kasr chiqsa, oxirgi to'liq sig'maydigan oyna TASHLANADI
-> oxirgi qator/ustun hech qachon ko'rilmasligi mumkin
DILATION d: yadro elementlari orasida d-1 bo'shliq
samarali yadro: k_eff = d * (k - 1) + 1
formulada k o'rniga k_eff floor((H + 2p - k) / s) + 1 — CNN yozishda eng ko'p ishlatiladigan formula.
2.5. Cross-correlation va konvolyutsiya
MATEMATIK KONVOLYUTSIYA:
(x * k)[i, j] = SUM x[i - a, j - b] * k[a, b]
-> yadro 180 gradusga BURILADI
CROSS-CORRELATION:
(x . k)[i, j] = SUM x[i + a, j + b] * k[a, b]
-> yadro burilmaydi
torch.nn.functional.conv2d, nn.Conv2d -> CROSS-CORRELATION
scipy.signal.correlate2d -> cross-correlation
scipy.signal.convolve2d -> haqiqiy konvolyutsiya
conv(x, k) = corr(x, flip(k))
NEGA FARQ MUHIM EMAS (tarmoqda):
yadro o'rgatiladi -> tarmoq kerak bo'lsa burilgan yadroni o'rganadi
simmetrik yadroda (Gauss) ikkalasi bir xil
QACHON MUHIM:
qo'lda yozilgan yadroni kutubxonalar orasida ko'chirganda
signal ishlashda (scipy) va tarmoqda (torch) natija taqqoslangandaChuqur o'rganishdagi "konvolyutsiya" — aslida cross-correlation; o'rgatiladigan yadroda bu farq yo'qoladi.
2.6. Chiziqlilik va im2col
CHIZIQLILIK:
conv(a*x + b*y, k) = a*conv(x, k) + b*conv(y, k)
conv(x, k1) + conv(x, k2) = conv(x, k1 + k2)
KETMA-KET:
conv(conv(x, k1), k2) = conv(x, conv(k1, k2)) (katta yadro)
-> nochiziqliksiz ikki qatlam = bitta qatlam
-> shuning uchun qatlamlar orasida ReLU (20-qism)
im2col (unfold):
har oynani ustun qilib yoyish: (N, C*k*k, L) L - joylar soni
og'irlik: (out, C*k*k)
chiqish = W @ ustunlar -> (N, out, L) -> (N, out, H_chiq, W_chiq)
-> konvolyutsiya = MATRITSA KO'PAYTMASI
-> GPU/BLAS da tez, lekin xotira k*k marta ko'pKonvolyutsiya — chiziqli amal; ichida u oynalar ustida matritsa ko'paytmasi.
2.7. Tuzoqlar
Asosiy tuzoqlar: chiqish o'lchamini formulasiz "taxmin qilish"; floor tufayli oxirgi qator/ustun tashlanishini sezmaslik; padding="same" ni stride=2 bilan ishlatish; nol padding chegara piksellarini qoraytirishini unutish; torch va scipy.signal.convolve2d natijasini to'g'ridan-to'g'ri taqqoslash (biri yadroni buradi); chegara yadrosini shovqinli rasmga xiralashtirmasdan qo'llash; F.conv2d ga (H, W) yoki (C, H, W) ni (N, C, H, W) o'rniga berish; qatlamlar orasida nochiziqlik qo'ymaslik.
3. Tez ma'lumotnoma
import numpy as np
import torch
import torch.nn.functional as F
def chiqish_olchami(h, k, p=0, s=1, d=1):
return (h + 2 * p - d * (k - 1) - 1) // s + 1
def conv2d_qolda(x, k, padding=0, stride=1):
"""(H, W) x (kh, kw) - cross-correlation, torch kabi."""
x = np.pad(x, padding)
kh, kw = k.shape
h = (x.shape[0] - kh) // stride + 1
w = (x.shape[1] - kw) // stride + 1
return np.array([[np.sum(x[i * stride:i * stride + kh,
j * stride:j * stride + kw] * k)
for j in range(w)] for i in range(h)])
SOBEL_X = torch.tensor([[-1., 0, 1], [-2, 0, 2], [-1, 0, 1]])
GAUSS = torch.tensor([[1., 2, 1], [2, 4, 2], [1, 2, 1]]) / 16
x = torch.rand(1, 1, 28, 28) # (N, C, H, W)
gx = F.conv2d(x, SOBEL_X.view(1, 1, 3, 3), padding=1) # (1, 1, 28, 28)Konvolyutsiya xulosasi
chiqish[i, j] = sum(oyna * yadro) - cross-correlation (torch)
H_chiq = floor((H + 2p - k) / s) + 1
same: p = (k - 1) / 2, faqat stride=1
yig'indi 1 -> silliqlash, yig'indi 0 -> chegara
conv = corr(flip(k)); o'rgatishda farq yo'q
conv - chiziqli: qatlamlar orasida ReLU shart4. Batafsil misollar
Misollar real torch/numpy bilan (Python 3.14, torch 2.14 CPU).
Misol 1 — Konvolyutsiya qo'lda va torch bilan
"""Konvolyutsiya qo'lda (sirpanuvchi oyna) va torch bilan aynan solishtirish."""
import numpy as np
import torch
import torch.nn.functional as F
def conv2d_qolda(x, k, padding=0, stride=1):
"""x: (H, W), k: (kh, kw). Aslida cross-correlation - torch kabi."""
if padding:
x = np.pad(x, padding)
kh, kw = k.shape
h_ch = (x.shape[0] - kh) // stride + 1
w_ch = (x.shape[1] - kw) // stride + 1
chiqish = np.zeros((h_ch, w_ch), dtype=np.float64)
for i in range(h_ch):
for j in range(w_ch):
oyna = x[i * stride:i * stride + kh, j * stride:j * stride + kw]
chiqish[i, j] = np.sum(oyna * k)
return chiqish
def jadval(m, fmt="{:>5.0f}"):
for qator in m:
print(" " + " ".join(fmt.format(v + 0.0) for v in qator))
def main() -> None:
x = np.array([[1, 2, 0, 3, 1],
[0, 1, 3, 1, 2],
[2, 1, 0, 2, 0],
[1, 3, 2, 1, 1],
[0, 2, 1, 0, 3]], dtype=np.float64)
k = np.array([[1, 0, -1],
[2, 0, -2],
[1, 0, -1]], dtype=np.float64)
print("=== 1. Kirish (5x5) va yadro (3x3) ===")
jadval(x)
print(" yadro:")
jadval(k)
print("\n=== 2. Bitta oyna qadam-baqadam (chiqish[0, 0]) ===")
oyna = x[0:3, 0:3]
kopaytma = oyna * k
print(" oyna * yadro (elementma-element):")
jadval(kopaytma)
print(f" yig'indi: {kopaytma.sum():.0f}")
print("\n=== 3. To'liq chiqish (padding=0, stride=1) ===")
y = conv2d_qolda(x, k)
print(f" shakl: {y.shape} (5 - 3 + 1 = 3)")
jadval(y)
print("\n=== 4. torch.nn.functional.conv2d bilan solishtirish ===")
xt = torch.tensor(x).view(1, 1, 5, 5)
kt = torch.tensor(k).view(1, 1, 3, 3)
print(f" F.conv2d kirish (N,C,H,W): {tuple(xt.shape)}, "
f"og'irlik (out,in,kh,kw): {tuple(kt.shape)}")
for p, s in [(0, 1), (1, 1), (1, 2), (2, 3)]:
qolda = conv2d_qolda(x, k, padding=p, stride=s)
tt = F.conv2d(xt, kt, padding=p, stride=s)[0, 0].numpy()
print(f" padding={p}, stride={s}: shakl {qolda.shape}, "
f"aynan teng: {np.array_equal(qolda, tt)}, "
f"maks farq {np.abs(qolda - tt).max():.1e}")
print("\n=== 5. float32 da ===")
rng = np.random.default_rng(0)
katta = rng.normal(0, 1, (32, 32))
yadro = rng.normal(0, 1, (5, 5))
q = conv2d_qolda(katta, yadro, padding=2)
t32 = F.conv2d(torch.tensor(katta, dtype=torch.float32).view(1, 1, 32, 32),
torch.tensor(yadro, dtype=torch.float32).view(1, 1, 5, 5),
padding=2)[0, 0].numpy()
farq = np.abs(q - t32).max()
print(f" 32x32, yadro 5x5: maks farq {farq:.1e}")
print(f" np.allclose(atol=1e-5): {np.allclose(q, t32, atol=1e-5)}")
print(" float32 yaxlitlash - farq faqat oxirgi raqamlarda")
print("\n=== 6. Hisob hajmi ===")
h, w, kk = 224, 224, 3
amallar = h * w * kk * kk
print(f" 224x224 rasm, 3x3 yadro, padding=1: {amallar:,} ko'paytirish")
print(f" 64 kirish va 64 chiqish kanal bilan: "
f"{amallar * 64 * 64:,}")
print(" ⭐ Konvolyutsiya = har joyda bir xil yadro bilan skalyar ko'paytma")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Kirish (5x5) va yadro (3x3) ===
1 2 0 3 1
0 1 3 1 2
2 1 0 2 0
1 3 2 1 1
0 2 1 0 3
yadro:
1 0 -1
2 0 -2
1 0 -1
=== 2. Bitta oyna qadam-baqadam (chiqish[0, 0]) ===
oyna * yadro (elementma-element):
1 0 0
0 0 -6
2 0 0
yig'indi: -3
=== 3. To'liq chiqish (padding=0, stride=1) ===
shakl: (3, 3) (5 - 3 + 1 = 3)
-3 -2 1
0 0 2
-1 5 0
=== 4. torch.nn.functional.conv2d bilan solishtirish ===
F.conv2d kirish (N,C,H,W): (1, 1, 5, 5), og'irlik (out,in,kh,kw): (1, 1, 3, 3)
padding=0, stride=1: shakl (3, 3), aynan teng: True, maks farq 0.0e+00
padding=1, stride=1: shakl (5, 5), aynan teng: True, maks farq 0.0e+00
padding=1, stride=2: shakl (3, 3), aynan teng: True, maks farq 0.0e+00
padding=2, stride=3: shakl (3, 3), aynan teng: True, maks farq 0.0e+00
=== 5. float32 da ===
32x32, yadro 5x5: maks farq 1.8e-06
np.allclose(atol=1e-5): True
float32 yaxlitlash - farq faqat oxirgi raqamlarda
=== 6. Hisob hajmi ===
224x224 rasm, 3x3 yadro, padding=1: 451,584 ko'paytirish
64 kirish va 64 chiqish kanal bilan: 1,849,688,064
⭐ Konvolyutsiya = har joyda bir xil yadro bilan skalyar ko'paytmaNima ko'rsatdi: 2.1, 2.4-bo'limlar.
Misol 2 — Klassik yadrolar
"""Klassik yadrolar: xiralashtirish, chegara, Sobel (real torch)."""
import numpy as np
import torch
import torch.nn.functional as F
from sklearn.datasets import load_digits
YADROLAR = {
"aynan": [[0, 0, 0], [0, 1, 0], [0, 0, 0]],
"o'rtacha 3x3": [[1 / 9] * 3] * 3,
"Gauss 3x3": [[1 / 16, 2 / 16, 1 / 16], [2 / 16, 4 / 16, 2 / 16],
[1 / 16, 2 / 16, 1 / 16]],
"keskinlash": [[0, -1, 0], [-1, 5, -1], [0, -1, 0]],
"Laplas": [[0, 1, 0], [1, -4, 1], [0, 1, 0]],
"Sobel x": [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]],
"Sobel y": [[-1, -2, -1], [0, 0, 0], [1, 2, 1]],
}
def qolla(rasm, yadro):
x = rasm.view(1, 1, *rasm.shape)
k = torch.tensor(yadro, dtype=torch.float32).view(1, 1, 3, 3)
return F.conv2d(x, k, padding=1)[0, 0]
def ascii_chiz(m):
for qator in m:
s = ""
for v in qator:
s += " +" if v > 0.5 else (" -" if v < -0.5 else " .")
print(" " + s)
def main() -> None:
rng = np.random.default_rng(0)
toza = torch.zeros(14, 14)
toza[5:10, 4:11] = 1.0
shovqin = torch.tensor(rng.normal(0, 0.2, (14, 14)), dtype=torch.float32)
rasm = toza + shovqin
tekis = (slice(1, 4), slice(1, 13)) # kvadratdan uzoq fon
print("=== 1. Yadro yig'indisi nimani anglatadi ===")
print(f" {'yadro':<14} {'yig_indi':>9} {'tekis fonda':>12} "
f"{'kvadrat ichida':>15}")
for nom, k in YADROLAR.items():
y = qolla(toza, k)
print(f" {nom:<14} {np.sum(k):>9.2f} {y[tekis].abs().mean():>12.3f} "
f"{y[6:9, 6:9].mean():>15.3f}")
print(" yig'indi 1 - yorqinlik saqlanadi; yig'indi 0 - tekis joyda 0")
print("\n=== 2. Xiralashtirish shovqinni kamaytiradi ===")
print(f" shovqinli rasmda fon std: {rasm[tekis].std():.3f}")
for nom in ["o'rtacha 3x3", "Gauss 3x3"]:
y = qolla(rasm, YADROLAR[nom])
print(f" {nom:<13} dan keyin fon std: {y[tekis].std():.3f}")
print(f" nazariy (o'rtacha 3x3, mustaqil shovqin): 0.2 / 3 = "
f"{0.2 / 3:.3f}")
print("\n=== 3. Sobel x - vertikal chegaralar (toza kvadrat) ===")
gx = qolla(toza, YADROLAR["Sobel x"])
ascii_chiz(gx.numpy())
print(" + : chapdan o'ngga yorqinlashadi, - : qorayadi")
print("\n=== 4. Sobel y - gorizontal chegaralar ===")
gy = qolla(toza, YADROLAR["Sobel y"])
ascii_chiz(gy.numpy())
print(" + : yuqoridan pastga yorqinlashadi, - : qorayadi")
print("\n=== 5. Gradient kattaligi va shovqin ===")
mag = torch.sqrt(gx ** 2 + gy ** 2)
chegara = mag > 1.0
print(f" toza rasm: chegara piksellari {int(chegara.sum())}, "
f"maks kattalik {mag.max():.2f}")
for nom, kirish in [("shovqinli", rasm),
("avval Gauss", qolla(rasm, YADROLAR["Gauss 3x3"]))]:
m = torch.sqrt(qolla(kirish, YADROLAR["Sobel x"]) ** 2
+ qolla(kirish, YADROLAR["Sobel y"]) ** 2)
topildi = m > 1.0
togri = int((topildi & chegara).sum())
yolgon = int((topildi & ~chegara).sum())
print(f" {nom:<12} to'g'ri topilgan {togri:>3}, "
f"yolg'on chegara {yolgon:>3}")
print("\n=== 6. Raqam rasmida (load_digits) ===")
raqam = torch.tensor(load_digits().images[0], dtype=torch.float32) / 16
for nom in ["Sobel x", "Laplas"]:
y = qolla(raqam, YADROLAR[nom])
print(f" {nom:<8}: min {y.min():.2f}, max {y.max():.2f}, "
f"|y| > 0.5 bo'lgan piksellar {int((y.abs() > 0.5).sum())}/64")
print(" ⭐ Yadro - naqsh detektori: yadroga o'xshash joyda javob katta")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Yadro yig'indisi nimani anglatadi ===
yadro yig_indi tekis fonda kvadrat ichida
aynan 1.00 0.000 1.000
o'rtacha 3x3 1.00 0.000 1.000
Gauss 3x3 1.00 0.000 1.000
keskinlash 1.00 0.000 1.000
Laplas 0.00 0.000 0.000
Sobel x 0.00 0.000 0.000
Sobel y 0.00 0.000 0.000
yig'indi 1 - yorqinlik saqlanadi; yig'indi 0 - tekis joyda 0
=== 2. Xiralashtirish shovqinni kamaytiradi ===
shovqinli rasmda fon std: 0.174
o'rtacha 3x3 dan keyin fon std: 0.068
Gauss 3x3 dan keyin fon std: 0.080
nazariy (o'rtacha 3x3, mustaqil shovqin): 0.2 / 3 = 0.067
=== 3. Sobel x - vertikal chegaralar (toza kvadrat) ===
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . + + . . . . . - - . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
+ : chapdan o'ngga yorqinlashadi, - : qorayadi
=== 4. Sobel y - gorizontal chegaralar ===
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . + + + + + + + + + . .
. . . + + + + + + + + + . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . - - - - - - - - - . .
. . . - - - - - - - - - . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
+ : yuqoridan pastga yorqinlashadi, - : qorayadi
=== 5. Gradient kattaligi va shovqin ===
toza rasm: chegara piksellari 48, maks kattalik 4.24
shovqinli to'g'ri topilgan 47, yolg'on chegara 45
avval Gauss to'g'ri topilgan 48, yolg'on chegara 21
=== 6. Raqam rasmida (load_digits) ===
Sobel x : min -2.94, max 3.44, |y| > 0.5 bo'lgan piksellar 54/64
Laplas : min -2.06, max 1.44, |y| > 0.5 bo'lgan piksellar 27/64
⭐ Yadro - naqsh detektori: yadroga o'xshash joyda javob kattaNima ko'rsatdi: 2.2-bo'lim.
Misol 3 — Padding, stride va o'lcham formulasi
"""Padding, stride va chiqish o'lchami formulasi (real torch)."""
import torch
import torch.nn.functional as F
def formula(h, k, p, s, d=1):
k_eff = d * (k - 1) + 1
return (h + 2 * p - k_eff) // s + 1
def main() -> None:
torch.manual_seed(0)
print("=== 1. Formula va haqiqiy shakl ===")
print(f" {'H':>4} {'k':>3} {'p':>3} {'s':>3} {'(H+2p-k)/s+1':>14} "
f"{'formula':>8} {'torch':>6}")
holatlar = [(28, 3, 0, 1), (28, 3, 1, 1), (28, 5, 2, 1), (28, 3, 1, 2),
(27, 3, 1, 2), (32, 7, 3, 2), (8, 3, 0, 2), (224, 11, 2, 4)]
hammasi = True
for h, k, p, s in holatlar:
x = torch.zeros(1, 1, h, h)
w = torch.zeros(1, 1, k, k)
haqiqiy = F.conv2d(x, w, padding=p, stride=s).shape[-1]
kasr = (h + 2 * p - k) / s + 1
f = formula(h, k, p, s)
hammasi &= f == haqiqiy
print(f" {h:>4} {k:>3} {p:>3} {s:>3} {kasr:>14.2f} {f:>8} "
f"{haqiqiy:>6}")
print(f" formula (pastga yaxlitlab) hamma holatda to'g'ri: {hammasi}")
print("\n=== 2. 'same' padding ===")
for k in [3, 5, 7]:
p = (k - 1) // 2
print(f" k={k}: p=(k-1)/2={p} -> 32 dan {formula(32, k, p, 1)}")
y = F.conv2d(torch.zeros(1, 1, 32, 32), torch.zeros(1, 1, 5, 5),
padding="same")
print(f" padding='same', k=5: {tuple(y.shape)}")
try:
F.conv2d(torch.zeros(1, 1, 32, 32), torch.zeros(1, 1, 3, 3),
padding="same", stride=2)
print(" 'same' + stride=2 ishladi (kutilmagan)")
except (RuntimeError, ValueError) as xato:
print(f" 'same' + stride=2: {type(xato).__name__} - "
f"{str(xato)[:43]}")
print("\n=== 3. Yaxlitlash: qaysi piksellar e'tiborsiz qoladi ===")
for h, k, p, s in [(8, 3, 0, 2), (9, 3, 0, 2), (8, 3, 1, 2)]:
x = torch.ones(1, 1, h, h, requires_grad=True)
w = torch.ones(1, 1, k, k)
F.conv2d(x, w, padding=p, stride=s).sum().backward()
g = x.grad[0, 0]
korilmagan = int((g == 0).sum())
qatorlar = (g == 0).all(dim=1).nonzero().flatten().tolist()
ustunlar = (g == 0).all(dim=0).nonzero().flatten().tolist()
print(f" H={h}, k={k}, p={p}, s={s}: chiqish {formula(h, k, p, s)}, "
f"ko'rilmagan piksellar {korilmagan}, qatorlar {qatorlar}, "
f"ustunlar {ustunlar}")
print("\n=== 4. Padding turi: chegaradagi qiymat ===")
x = torch.ones(1, 1, 6, 6)
k = torch.full((1, 1, 3, 3), 1 / 9)
print(" kirish hammasi 1, yadro - o'rtacha 3x3")
print(f" {'rejim':<10} {'burchak':>8} {'chekka':>7} {'markaz':>7}")
for rejim in ["constant", "reflect", "replicate", "circular"]:
xp = F.pad(x, (1, 1, 1, 1), mode=rejim)
y = F.conv2d(xp, k)[0, 0]
print(f" {rejim:<10} {y[0, 0]:>8.3f} {y[0, 3]:>7.3f} "
f"{y[3, 3]:>7.3f}")
print(" nol padding chegarani qoraytiradi (burchak 4/9, chekka 6/9)")
print("\n=== 5. Dilation - kengaytirilgan yadro ===")
for d in [1, 2, 3]:
y = F.conv2d(torch.zeros(1, 1, 32, 32), torch.zeros(1, 1, 3, 3),
dilation=d)
print(f" k=3, dilation={d}: samarali yadro {d * 2 + 1}x{d * 2 + 1}, "
f"chiqish {y.shape[-1]} (formula {formula(32, 3, 0, 1, d)})")
print("\n=== 6. O'lchamlar zanjiri ===")
x = torch.zeros(1, 3, 64, 64)
print(f" kirish: {tuple(x.shape)}")
for i, (k, p, s) in enumerate([(3, 1, 1), (3, 1, 2), (3, 1, 2),
(3, 0, 1), (3, 1, 2)], 1):
x = F.conv2d(x, torch.zeros(3, 3, k, k), padding=p, stride=s)
print(f" {i}-qadam k={k}, p={p}, s={s}: {tuple(x.shape)}")
print(" ⭐ Chiqish = floor((H + 2p - k) / s) + 1")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Formula va haqiqiy shakl ===
H k p s (H+2p-k)/s+1 formula torch
28 3 0 1 26.00 26 26
28 3 1 1 28.00 28 28
28 5 2 1 28.00 28 28
28 3 1 2 14.50 14 14
27 3 1 2 14.00 14 14
32 7 3 2 16.50 16 16
8 3 0 2 3.50 3 3
224 11 2 4 55.25 55 55
formula (pastga yaxlitlab) hamma holatda to'g'ri: True
=== 2. 'same' padding ===
k=3: p=(k-1)/2=1 -> 32 dan 32
k=5: p=(k-1)/2=2 -> 32 dan 32
k=7: p=(k-1)/2=3 -> 32 dan 32
padding='same', k=5: (1, 1, 32, 32)
'same' + stride=2: RuntimeError - padding='same' is not supported for strided
=== 3. Yaxlitlash: qaysi piksellar e'tiborsiz qoladi ===
H=8, k=3, p=0, s=2: chiqish 3, ko'rilmagan piksellar 15, qatorlar [7], ustunlar [7]
H=9, k=3, p=0, s=2: chiqish 4, ko'rilmagan piksellar 0, qatorlar [], ustunlar []
H=8, k=3, p=1, s=2: chiqish 4, ko'rilmagan piksellar 0, qatorlar [], ustunlar []
=== 4. Padding turi: chegaradagi qiymat ===
kirish hammasi 1, yadro - o'rtacha 3x3
rejim burchak chekka markaz
constant 0.444 0.667 1.000
reflect 1.000 1.000 1.000
replicate 1.000 1.000 1.000
circular 1.000 1.000 1.000
nol padding chegarani qoraytiradi (burchak 4/9, chekka 6/9)
=== 5. Dilation - kengaytirilgan yadro ===
k=3, dilation=1: samarali yadro 3x3, chiqish 30 (formula 30)
k=3, dilation=2: samarali yadro 5x5, chiqish 28 (formula 28)
k=3, dilation=3: samarali yadro 7x7, chiqish 26 (formula 26)
=== 6. O'lchamlar zanjiri ===
kirish: (1, 3, 64, 64)
1-qadam k=3, p=1, s=1: (1, 3, 64, 64)
2-qadam k=3, p=1, s=2: (1, 3, 32, 32)
3-qadam k=3, p=1, s=2: (1, 3, 16, 16)
4-qadam k=3, p=0, s=1: (1, 3, 14, 14)
5-qadam k=3, p=1, s=2: (1, 3, 7, 7)
⭐ Chiqish = floor((H + 2p - k) / s) + 1Nima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 4 — Cross-correlation, chiziqlilik va im2col
"""Cross-correlation va konvolyutsiya, chiziqlilik, im2col (real torch/scipy)."""
import numpy as np
import torch
import torch.nn.functional as F
from scipy import signal
def main() -> None:
rng = np.random.default_rng(0)
x = rng.integers(0, 5, (6, 6)).astype(np.float64)
k = np.array([[1, 2, 0],
[0, 1, 0],
[0, 0, -1]], dtype=np.float64) # nosimmetrik
xt = torch.tensor(x).view(1, 1, 6, 6)
def torch_conv(yadro):
return F.conv2d(xt, torch.tensor(yadro).view(1, 1, 3, 3))[0, 0].numpy()
print("=== 1. torch nimani hisoblaydi ===")
tt = torch_conv(k)
korr = signal.correlate2d(x, k, mode="valid")
konv = signal.convolve2d(x, k, mode="valid")
print(f" F.conv2d == scipy correlate2d: {np.array_equal(tt, korr)}")
print(f" F.conv2d == scipy convolve2d: {np.array_equal(tt, konv)}")
print(" torch 'conv2d' aslida CROSS-CORRELATION hisoblaydi")
print("\n=== 2. Farq - yadroni 180 gradusga burish ===")
burilgan = np.flip(k)
print(" burilgan yadro:")
for qator in burilgan:
print(" " + " ".join(f"{v:>4.0f}" for v in qator))
print(f" convolve2d(x, k) == correlate2d(x, flip(k)): "
f"{np.array_equal(konv, signal.correlate2d(x, burilgan, 'valid'))}")
print(f" F.conv2d(x, flip(k)) == convolve2d(x, k): "
f"{np.array_equal(torch_conv(burilgan.copy()), konv)}")
print("\n=== 3. Simmetrik yadroda farq yo'q ===")
gauss = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 16
print(f" Gauss: correlate == convolve: "
f"{np.allclose(signal.correlate2d(x, gauss, 'valid'), signal.convolve2d(x, gauss, 'valid'))}")
sobel = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=float)
a = signal.correlate2d(x, sobel, "valid")
b = signal.convolve2d(x, sobel, "valid")
print(f" Sobel x: convolve == -correlate: {np.array_equal(b, -a)}")
print(" o'rgatiladigan yadroda farq muhim emas - tarmoq burilgan")
print(" versiyani o'rganadi")
print("\n=== 4. Chiziqlilik ===")
x2 = rng.normal(0, 1, (6, 6))
chap = signal.correlate2d(2 * x + 3 * x2, k, "valid")
ong = (2 * signal.correlate2d(x, k, "valid")
+ 3 * signal.correlate2d(x2, k, "valid"))
print(f" conv(2a + 3b) == 2 conv(a) + 3 conv(b): {np.allclose(chap, ong)}")
ikki = (signal.correlate2d(x, k, "valid")
+ signal.correlate2d(x, sobel, "valid"))
birga = signal.correlate2d(x, k + sobel, "valid")
print(f" conv(x, k1) + conv(x, k2) == conv(x, k1 + k2): "
f"{np.allclose(ikki, birga)}")
print("\n=== 5. Ketma-ket ikki yadro = bitta katta yadro ===")
katta = rng.normal(0, 1, (12, 12))
ketma = signal.convolve2d(signal.convolve2d(katta, gauss, "valid"),
sobel, "valid")
birlashgan = signal.convolve2d(gauss, sobel) # 5x5
bir_marta = signal.convolve2d(katta, birlashgan, "valid")
print(f" birlashgan yadro shakli: {birlashgan.shape}")
print(f" Gauss keyin Sobel == bitta 5x5 yadro: "
f"{np.allclose(ketma, bir_marta)}")
print(" nochiziqlik (ReLU) bo'lmasa, qatlamlar bitta qatlamga qisqaradi")
print("\n=== 6. im2col: konvolyutsiya = matritsa ko'paytmasi ===")
torch.manual_seed(0)
xb = torch.randn(2, 3, 8, 8)
w = torch.randn(4, 3, 3, 3)
ustunlar = F.unfold(xb, kernel_size=3, padding=1) # (N, C*k*k, L)
print(f" unfold shakli: {tuple(ustunlar.shape)} "
f"(N, C*k*k = {3 * 9}, joylar L = {8 * 8})")
y_mat = (w.view(4, -1) @ ustunlar).view(2, 4, 8, 8)
y_conv = F.conv2d(xb, w, padding=1)
print(f" matmul natijasi shakli: {tuple(y_mat.shape)}")
print(f" F.conv2d bilan maks farq: {(y_mat - y_conv).abs().max():.1e}")
print(f" allclose: {torch.allclose(y_mat, y_conv, atol=1e-5)}")
print(" ⭐ Konvolyutsiya - og'irligi baham ko'rilgan chiziqli amal")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. torch nimani hisoblaydi ===
F.conv2d == scipy correlate2d: True
F.conv2d == scipy convolve2d: False
torch 'conv2d' aslida CROSS-CORRELATION hisoblaydi
=== 2. Farq - yadroni 180 gradusga burish ===
burilgan yadro:
-1 0 0
0 1 0
0 2 1
convolve2d(x, k) == correlate2d(x, flip(k)): True
F.conv2d(x, flip(k)) == convolve2d(x, k): True
=== 3. Simmetrik yadroda farq yo'q ===
Gauss: correlate == convolve: True
Sobel x: convolve == -correlate: True
o'rgatiladigan yadroda farq muhim emas - tarmoq burilgan
versiyani o'rganadi
=== 4. Chiziqlilik ===
conv(2a + 3b) == 2 conv(a) + 3 conv(b): True
conv(x, k1) + conv(x, k2) == conv(x, k1 + k2): True
=== 5. Ketma-ket ikki yadro = bitta katta yadro ===
birlashgan yadro shakli: (5, 5)
Gauss keyin Sobel == bitta 5x5 yadro: True
nochiziqlik (ReLU) bo'lmasa, qatlamlar bitta qatlamga qisqaradi
=== 6. im2col: konvolyutsiya = matritsa ko'paytmasi ===
unfold shakli: (2, 27, 64) (N, C*k*k = 27, joylar L = 64)
matmul natijasi shakli: (2, 4, 8, 8)
F.conv2d bilan maks farq: 3.8e-06
allclose: True
⭐ Konvolyutsiya - og'irligi baham ko'rilgan chiziqli amalNima ko'rsatdi: 2.5, 2.6-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"nn.Conv2d matematik konvolyutsiya hisoblaydi" |
Cross-correlation — yadro burilmaydi |
| "Chiqish o'lchami = kirish o'lchami" | Faqat p = (k - 1) / 2 va s = 1 da |
"stride=2 o'lchamni aniq ikkiga bo'ladi" |
floor — toq o'lchamda yaxlitlanadi |
| "Padding faqat o'lcham uchun" | Chegara piksellari qiymatiga ham ta'sir qiladi |
| "Chegara yadrosi shovqinga chidamli" | Shovqinni kuchaytiradi — avval xiralashtiring |
| "Ko'p konvolyutsiya qatlami — murakkab funksiya" | Nochiziqliksiz bitta konvolyutsiyaga teng |
| "Yadro o'lchami — faqat tezlik masalasi" | Qancha qo'shnini ko'rishni belgilaydi |
| "Konvolyutsiya — maxsus sehrli amal" | Oynalar ustida matritsa ko'paytmasi |
6. Keng tarqalgan xatolar va yechimlari
1. Kirish shaklida N va C yo'q
F.conv2d(torch.rand(28, 28), w) # ⚠️
F.conv2d(torch.rand(28, 28).view(1, 1, 28, 28), w) # ✅ (N, C, H, W)2. O'lchamni taxmin qilish
nn.Linear(32 * 13 * 13, 10) # "27 // 2 = 13" deb taxmin # ⚠️
chiqish_olchami(27, 3, 1, 2) # -> 14, keyin Linear(32*14*14) # ✅3. same + stride
F.conv2d(x, w, padding="same", stride=2) # ⚠️ RuntimeError
F.conv2d(x, w, padding=1, stride=2) # ✅4. Juft yadro va same
nn.Conv2d(1, 8, kernel_size=4, padding=2) # 28 -> 29 # ⚠️
nn.Conv2d(1, 8, kernel_size=3, padding=1) # 28 -> 28 # ✅5. scipy va torch natijasini to'g'ridan-to'g'ri taqqoslash
signal.convolve2d(x, k, "valid") == F.conv2d(...) # ⚠️ yadro burilgan
signal.correlate2d(x, k, "valid") == F.conv2d(...) # ✅6. Shovqinli rasmga to'g'ridan-to'g'ri Sobel
g = F.conv2d(x, SOBEL_X, padding=1) # ⚠️
g = F.conv2d(F.conv2d(x, GAUSS, padding=1), SOBEL_X, padding=1) # ✅7. Qatlamlar orasida nochiziqlik yo'q
nn.Sequential(nn.Conv2d(1, 8, 3), nn.Conv2d(8, 8, 3)) # ⚠️
nn.Sequential(nn.Conv2d(1, 8, 3), nn.ReLU(), nn.Conv2d(8, 8, 3)) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 10-qism (o'tilgan): Skalyar ko'paytma va matritsa ko'paytmasi
- 20-qism (o'tilgan): Nochiziqlik nima uchun kerak
- 22.1-dars (o'tilgan):
(N, C, H, W)shakli - Keyingi dars:
nn.Conv2d— ko'p kanalli va o'rgatiladigan yadrolar - CNN arxitekturalari mavzusida: Stride va padding bilan o'lcham boshqaruvi
- Vaqt qatorlari va NLP qismlarida: Bir o'lchamli konvolyutsiya (
Conv1d) — xuddi shu g'oya
8. Eng yaxshi amaliyotlar
Har qatlamdan keyin o'lchamni formula bilan hisoblang.
O'lchamni saqlash uchun toq yadro va
p = (k - 1) / 2.O'lchamni kamaytirish uchun
stride=2— toq o'lchamlarga e'tibor bering.Yangi yadroni avval kichik qo'lda misolda tekshiring.
scipybilan solishtirishdacorrelate2ddan foydalaning.Chegara topishdan oldin xiralashtiring.
Chegara piksellari muhim bo'lsa,
reflectpadding ni sinab ko'ring.Konvolyutsiyalar orasida doim nochiziqlik.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # 5x5 kirish, 3x3 yadro, p=0, s=1 - chiqish?
2. # 28x28, k=5, p=2, s=1 - chiqish?
3. # 32x32, k=3, p=1, s=2 - chiqish?
4. # 27x27, k=3, p=0, s=2 - chiqish?
5. # o'rtacha 3x3 yadroning yig'indisi?
6. # Sobel x qanday chegarani topadi?
7. # yig'indisi 0 yadro tekis joyda nima beradi?
8. # nn.Conv2d konvolyutsiyami yoki cross-correlation?
9. # k=7 uchun "same" padding?
10. # k=3, dilation=2 samarali yadro o'lchami?
11. # nol padding bilan hammasi 1 rasmni o'rtacha 3x3 bilan - burchak qiymati?
12. # unfold (N, C, 8, 8), k=3, p=1 shakli (C=3)?Javoblar
- 3×3
- 28×28
- 16×16
- 13×13 (
floor(24 / 2) + 1) - 1
- Vertikal (chapdan o'ngga o'zgarish)
- 0
- Cross-correlation
- 3
- 5×5
- 4/9 ≈ 0.444
(N, 27, 64)
Vazifa 2: Xatolarni tuzating
1. F.conv2d(torch.rand(28, 28), w)
2. F.conv2d(x, w, padding="same", stride=2)
3. nn.Conv2d(1, 8, kernel_size=4, padding=2) # o'lcham saqlansin
4. assert np.allclose(signal.convolve2d(x, k, "valid"), F.conv2d(xt, kt)[0, 0])
5. nn.Sequential(nn.Conv2d(1, 8, 3), nn.Conv2d(8, 8, 3))Javoblar
1. F.conv2d(torch.rand(28, 28).view(1, 1, 28, 28), w)
2. F.conv2d(x, w, padding=1, stride=2)
3. nn.Conv2d(1, 8, kernel_size=3, padding=1)
4. assert np.allclose(signal.correlate2d(x, k, "valid"), F.conv2d(xt, kt)[0, 0])
5. nn.Sequential(nn.Conv2d(1, 8, 3), nn.ReLU(), nn.Conv2d(8, 8, 3))Vazifa 3: Qo'lda
Modellang:
- Bitta oyna
- To'liq chiqish
F.conv2dbilan tenglikfloat32farqi
Vazifa 4: Yadrolar
Modellang:
- Yig'indi qoidasi
- Xiralashtirish va shovqin
- Sobel x va y
- Gauss + Sobel
Vazifa 5: O'lchamlar
Modellang:
- Formula jadvali
- Same padding
- Ko'rilmagan piksellar
- Padding turlari
Vazifa 6: Nazariya tekshiruvi
Modellang:
- Correlate va convolve
- Yadroni burish
- Chiziqlilik
- im2col
Vazifa 7: O'ylash
Hamkasbingiz so'radi: "Sobel, Gauss kabi yadrolar o'nlab yillar ishlatilgan va yaxshi ishlaydi. Nega CNN da yadrolarni tasodifiy boshlab o'rgatamiz? Yaxshi yadrolarni qo'lda qo'ysak, tezroq o'rganmaydimi?" Nima deysiz?
Javob
Qisqa javob: qo'lda qo'yilgan yadrolar faqat birinchi qatlamdagi oddiy naqshlarni qamraydi. Vazifaga kerak bo'lgan murakkab naqshlarni (ko'z, g'ildirak, o'sma chegarasi) hech kim qo'lda yoza olmaydi — ularni ma'lumotdan o'rganish kerak.
Qo'lda yadrolar nimaga yaxshi:
- Chegara, silliqlash, gradient — umumiy, ko'p vazifada foydali
- 2-misolda Gauss + Sobel shovqinli rasmda yolg'on chegaralarni 45 tadan 21 taga kamaytirdi — qo'lda ham ancha narsa qilish mumkin
Nega baribir o'rgatiladi:
Ko'p qatlamlilik. Ikkinchi, uchinchi qatlam yadrolari birinchi qatlam chiqishlari ustida ishlaydi. "Sobel javoblarining qanday birikmasi mushuk qulog'ini bildiradi?" — bunga qo'lda javob yo'q.
Vazifaga moslik. Rentgen rasmida muhim chegaralar va avtomobil suratidagi muhim chegaralar boshqa-boshqa. O'rgatish yadrolarni aynan shu vazifaga moslaydi.
O'rgatilgan birinchi qatlam baribir shunga o'xshaydi. Katta to'plamlarda o'rgatilgan CNN larning birinchi qatlam yadrolari chizib ko'rilsa, ular ko'pincha chegara detektorlari va rang dog'lariga o'xshaydi — ya'ni tarmoq Sobel ga o'xshash narsani o'zi topadi.
Qo'lda boshlash — kichik yutuq. Tasodifiy boshlangan birinchi qatlam bir necha davrda chegara detektorlariga aylanadi. Asosiy o'rgatish vaqti chuqur qatlamlarga ketadi.
Qachon qo'lda yadro foydali:
| Holat | Nima qilish |
|---|---|
| Ma'lumot juda kam | Qo'lda belgilar (Sobel, histogram) + klassik model |
| Oldindan ishlov berish | Shovqinni Gauss bilan kamaytirish |
| Tushuntirish kerak | "Chegara zichligi" kabi tushunarli belgilar |
| Ko'p ma'lumot | O'rgatiladigan yadrolar, yaxshisi oldindan o'rgatilgan model |
Hamkasbga javob:
"Qo'lda yadrolar birinchi qatlam uchun yaxshi, lekin CNN ning kuchi chuqur qatlamlarda — u yerdagi naqshlarni qo'lda yozib bo'lmaydi. O'rgatilgan birinchi qatlam baribir chegara detektorlariga o'xshab qoladi. Ma'lumot kam bo'lsa, qo'lda yadrolardan emas, oldindan o'rgatilgan tarmoqdan boshlagan ma'qul — bu transfer learning mavzusida keladi."
Nimani mustahkamlaydi: 2.2, 2.6-bo'limlar.
Xulosa
Bu darsda konvolyutsiyani ichidan ko'rdik.
Eng muhim uch fikr:
Konvolyutsiya — sirpanuvchi skalyar ko'paytma. 1-misolda qo'lda yozilgan sirpanuvchi oyna
F.conv2dbilan to'rtta padding/stride kombinatsiyasida aynan teng chiqdi (float64da farq 0),float32da esa farq faqat 1.8e-06. 2-misolda yig'indisi 1 bo'lgan yadrolar tekis joyni o'zgartirmadi, yig'indisi 0 bo'lganlar esa tekis joyda 0 berdi. O'rtacha 3×3 yadro fon shovqinining std sini 0.174 dan 0.068 ga tushirdi, Gauss dan keyin Sobel yolg'on chegaralarni 45 tadan 21 taga kamaytirdi.Chiqish o'lchami =
floor((H + 2p - k) / s) + 1. 3-misolda formula sakkizta holatning hammasidatorchbilan mos keldi.floorning narxi ham ko'rindi:H=8, k=3, p=0, s=2da oxirgi qator va ustun (15 piksel) hech qachon ko'rilmadi,p=1qo'yilganda esa hammasi qamrab olindi. Nol padding hammasi 1 bo'lgan rasmda burchakni 0.444 ga, chekkani 0.667 ga tushirdi;reflect,replicatevacircular1.000 ni saqladi.Torch "konvolyutsiyasi" — cross-correlation va chiziqli amal. 4-misolda
F.conv2dscipy.signal.correlate2dbilan teng,convolve2dbilan esa faqat yadro 180 gradusga burilganda teng chiqdi. Gauss dan keyin Sobel bitta 5×5 yadroga teng — nochiziqliksiz qatlamlar bittaga qisqaradi.unfold+ matritsa ko'paytmasiF.conv2dnatijasini 3.8e-06 aniqlikda takrorladi.
Keyingi darsda nn.Conv2d qatlami: ko'p kanalli konvolyutsiya, parametrlar soni formulasi, retseptiv maydon va og'irlik baham ko'rish siljishga qanday ekvivariantlik berishi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!