IlmHamroh
Data Science va sun'iy intellekt/Kompyuter korish1/14-dars27 daqiqa
Mundarija (21)

22.1-dars: Rasm ma'lumoti

22-QISM — KOMPYUTER KO'RISH · 1-dars


1. Kirish va motivatsiya

21-qismda PyTorch bilan to'liq ishlashni o'rgandik: nn.Module, Dataset va DataLoader, optimizatorlar, Trainer, checkpoint, regularizatsiya va diagnostika. Hozirgacha ma'lumotimiz asosan jadval edi — har qator bir obyekt, har ustun bir belgi. Endi yangi turdagi ma'lumotga o'tamiz: rasmlar.

Kompyuter uchun rasm — sehrli narsa emas. Bu sonlar massivi: har piksel uchun bir (kulrang) yoki uchta (qizil, yashil, ko'k) son. 1920×1080 o'lchamli rangli surat — bu 1080 × 1920 × 3 = 6 220 800 ta son. Qiyinchilik aynan shu yerda: sonlar juda ko'p, ular orasidagi fazoviy bog'lanish esa (qo'shni piksellar o'xshash) jadvalda yo'q edi.

Bu qismda kompyuter ko'rishning asosiy vositalarini o'rganamiz: konvolyutsiya, pooling, CNN arxitekturalari, transfer learning. Lekin ularning hammasi bitta poydevorga tayanadi — rasmni tensor sifatida to'g'ri tushunish. Shakl (H, W, C) mi yoki (C, H, W) mi, uint8 mi yoki float32 mi, qiymatlar 0..255 mi yoki 0..1 mi — bu savollardagi xato model "o'rganmayapti" degan eng ko'p uchraydigan shikoyatlarning sababi.

Real vaziyat. Bir jamoa mahsulot suratlarini tasniflash modelini o'rgatdi: o'quvda aniqlik 94%, ishlab chiqarishda esa 61%. Bir hafta arxitekturani o'zgartirishdi. Oxirida sabab topildi: o'quvda rasmlar PIL orqali RGB tartibida o'qilgan, ishlab chiqarish servisi esa boshqa kutubxona bilan BGR tartibida o'qigan. Qizil va ko'k kanallar almashgan edi. Bitta qator tuzatish aniqlikni qaytardi.

Bu darsda rasmni sonlar massivi sifatida ko'ramiz va uni modelga to'g'ri tayyorlashni o'rganamiz.

Bu darsda:

  • Piksel, kanal va shakl: (H, W, C) va (C, H, W)
  • uint8 va float: tur va oraliq
  • Normalizatsiya: 0..1 va kanal bo'yicha mean/std
  • PIL bilan o'qish, yozish, o'lcham o'zgartirish
  • Batch: (N, C, H, W)
  • load_digits va sintetik shakllar
  • Tuzoqlar

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


2. Nazariya — chuqur tushuntirish

2.1. Rasm — sonlar massivi

text
KULRANG RASM:  (H, W)        har piksel - bitta son (yorqinlik)
RANGLI RASM:   (H, W, 3)     har piksel - uchta son (R, G, B)
SHAFFOF:       (H, W, 4)     R, G, B + alfa (shaffoflik)

H - balandlik (qatorlar soni), W - kenglik (ustunlar soni)
C - kanallar soni

rasm[y, x]      -> bitta piksel: [R, G, B]
rasm[y, x, 0]   -> shu pikselning qizil qiymati
rasm[:, :, 0]   -> butun qizil kanal, shakl (H, W)

KOORDINATALAR:
  (0, 0) - chap-YUQORI burchak
  y pastga o'sadi, x o'ngga o'sadi
  (matematikadagi grafikdan farqli - y teskari)

SONLAR SONI: H * W * C
  28x28 kulrang       ->       784
  224x224 rangli      ->   150 528
  1080x1920 rangli    -> 6 220 800

Rasm — (H, W, C) shaklli sonlar massivi; birinchi indeks qator (y), ikkinchisi ustun (x).

2.2. uint8 va float

text
SAQLASH:  uint8 - 0..255 butun sonlar, 1 bayt
          fayllar (PNG, JPEG), PIL, kamera - hammasi uint8

HISOB:    float32 - 0.0..1.0 (yoki normallashgan), 4 bayt
          tarmoq og'irliklari float, gradient float

uint8 TUZOG'I - arifmetika 256 bo'yicha aylanadi:
  200 + 100 = 44      (300 - 256)
  100 - 200 = 156     (-100 + 256)
  xato chiqmaydi, jim buziladi

TO'G'RI YO'L:
  x = rasm.astype(np.float32) / 255.0       # numpy
  x = torch.from_numpy(rasm).float() / 255  # torch
  yoki: int16 ga o'tkazib, hisoblab, clip(0, 255), uint8 ga qaytarish

XOTIRA:  float32 uint8 dan 4 barobar ko'p joy oladi
  -> diskda va xotirada uint8 saqlang, batch ga olganda float qiling

Saqlash — uint8, hisob — float32; uint8 ustida arifmetika jim buziladi.

2.3. numpy (H, W, C) va torch (C, H, W)

text
numpy / PIL / matplotlib:   (H, W, C)     "kanal oxirida"
torch (nn.Conv2d):          (C, H, W)     "kanal oldinda"
batch:                      (N, C, H, W)

O'TKAZISH:
  t = torch.from_numpy(rasm).permute(2, 0, 1)      # (H,W,C) -> (C,H,W)
  rasm = t.permute(1, 2, 0).numpy()                # orqaga

permute - o'qlarni ALMASHTIRADI (piksellar joyida qoladi)
reshape - sonlarni YANGI shaklga QUYADI (tartib o'zgarmaydi)

  reshape(3, H, W) xato: (H, W, 3) xotirada R,G,B,R,G,B,... ketma-ket
  reshape uni "birinchi H*W son - 0-kanal" deb o'qiydi -> aralash

permute dan keyin tensor contiguous EMAS (faqat ko'rinish)
  .contiguous() - kerak bo'lsa nusxa oladi (view() uchun)

KULRANG: (H, W) -> unsqueeze(0) -> (1, H, W)
         batch: (N, H, W) -> unsqueeze(1) -> (N, 1, H, W)

O'qlarni almashtirish — permute, hech qachon reshape emas; kulrang rasmga ham kanal o'qi kerak.

2.4. Normalizatsiya

text
1) 0..1 GA MASSHTAB:
   x = rasm / 255.0
   eng oddiy, ko'p hollarda yetarli

2) KANAL BO'YICHA mean/std (standartlash):
   mean_c = x[:, c, :, :].mean()    - butun o'quv to'plami bo'yicha
   std_c  = x[:, c, :, :].std()
   x_norm[:, c] = (x[:, c] - mean_c) / std_c

   torch da: dim=(0, 2, 3) bo'yicha - N, H, W ustidan, C qoladi
   shakl: mean.view(1, C, 1, 1) - broadcasting uchun

NEGA KANAL BO'YICHA:
   R, G, B kanallar yorqinligi va tarqoqligi har xil
   bitta umumiy mean/std - kanallar orasidagi siljishni qoldiradi

ImageNet STATISTIKASI (torchvision namunalaridan mashhur):
   mean = [0.485, 0.456, 0.406]
   std  = [0.229, 0.224, 0.225]
   oldindan o'rgatilgan modelga - AYNAN o'sha statistika bilan

QOIDA: mean/std FAQAT o'quv to'plamida hisoblanadi (17-qism, leakage)

Statistika kanal bo'yicha, dim=(0, 2, 3) ustidan, faqat o'quv to'plamida.

2.5. PIL bilan fayllar

text
from PIL import Image

img = Image.open(yol)           # dangasa: piksellar kerak bo'lganda o'qiladi
img = img.convert("RGB")        # RGBA, P (palitra), L -> RGB
arr = np.asarray(img)           # (H, W, 3) uint8

img.size       -> (W, H)        !!! kenglik birinchi
arr.shape      -> (H, W, 3)

Image.fromarray(arr).save("x.png")
img.resize((W, H), Image.Resampling.BILINEAR)   # (kenglik, balandlik)
img.crop((chap, yuqori, o'ng, past))
img.convert("L")                # kulrang: 0.299R + 0.587G + 0.114B

FORMATLAR:
  PNG  - yo'qotishsiz, niqoblar/yorliqlar uchun
  JPEG - yo'qotishli, suratlar uchun kichik fayl
         qayta saqlash har safar sifatni yana pasaytiradi

RESIZE USULLARI:
  NEAREST  - eng yaqin piksel, yangi qiymat yaratmaydi (niqob, yorliq)
  BILINEAR - 4 qo'shni o'rtachasi, silliq
  BICUBIC  - 16 qo'shni, silliqroq

torchvision - rasm uchun standart kutubxona (transforms, datasets),
  lekin bu kursda u yo'q: hammasini PIL + numpy + torch bilan qilamiz

PIL — fayl va o'lcham uchun, hisob — numpy/torch da; img.size ning tartibi (W, H).

2.6. Batch va ma'lumot to'plamlari

text
BATCH: (N, C, H, W)
  N - rasmlar soni, C - kanal, H x W - o'lcham
  bitta batchdagi hamma rasm BIR XIL o'lchamda bo'lishi shart
  -> resize/crop Dataset ichida qilinadi

MLP uchun: x.flatten(1) -> (N, C*H*W)   (20-qism)
CNN uchun: (N, C, H, W) o'zicha qoladi  (keyingi darslar)

KICHIK TO'PLAMLAR (internetsiz):
  sklearn.datasets.load_digits  - 1797 ta 8x8 raqam, 0..16 qiymatlar
    .images (1797, 8, 8), .data (1797, 64), .target (1797,)
  sintetik shakllar - numpy bilan: doira, kvadrat, chiziq
    afzalligi: haqiqiy javobni biz bilamiz, murakkablikni boshqaramiz

KATTA TO'PLAMLAR (nazariy):
  MNIST, CIFAR-10, ImageNet - odatda torchvision.datasets orqali

Batch — (N, C, H, W); sintetik to'plam g'oyani tekshirishning eng arzon yo'li.

2.7. Tuzoqlar

Asosiy tuzoqlar: uint8 ustida arifmetika (200 + 100 = 44); (H, W, C) dan (C, H, W) ga reshape bilan o'tish; img.size ni (H, W) deb o'qish; RGB va BGR tartibini aralashtirish; kulrang rasmga kanal o'qini qo'shmaslik; normalizatsiya statistikasini test to'plamida hisoblash; oldindan o'rgatilgan modelga boshqa mean/std berish; niqob (yorliq) rasmini BILINEAR bilan kichraytirish; nisbatni saqlamasdan resize qilish; JPEG ni yo'qotishsiz deb o'ylash.


3. Tez ma'lumotnoma

python
import numpy as np
import torch
from PIL import Image


def rasm_oqi(yol):
    """Fayl -> (C, H, W) float32, 0..1."""
    with Image.open(yol) as img:
        arr = np.asarray(img.convert("RGB"))          # (H, W, 3) uint8
    return torch.from_numpy(arr).permute(2, 0, 1).float() / 255.0


def kanal_statistikasi(x):
    """x: (N, C, H, W) - faqat o'quv to'plami."""
    return x.mean(dim=(0, 2, 3)), x.std(dim=(0, 2, 3))


def normallashtir(x, orta, std):
    return (x - orta.view(1, -1, 1, 1)) / std.view(1, -1, 1, 1)


def tensor_rasmga(t):
    """(C, H, W) 0..1 -> PIL."""
    arr = (t.clamp(0, 1) * 255).round().byte().permute(1, 2, 0).numpy()
    return Image.fromarray(arr)

Rasm ma'lumoti xulosasi

rasm: (H, W, C) uint8 0..255  ->  torch: (C, H, W) float32 0..1
o'tkazish: permute(2, 0, 1), reshape EMAS
batch: (N, C, H, W); kulrang: unsqueeze(1)
normalizatsiya: kanal bo'yicha, dim=(0, 2, 3), faqat o'quvda
PIL: size = (W, H); resize((W, H)); niqob uchun NEAREST

4. Batafsil misollar

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

Misol 1 — Rasm sonlar massivi sifatida

python
"""Rasm = sonlar massivi: (H, W, C), uint8, kanallar (real numpy/torch)."""

import numpy as np
import torch


def rasm_yarat(h=6, w=8):
    """Chap yarmi qizil, o'ng yarmi ko'k, o'rtada oq kvadrat."""
    rasm = np.zeros((h, w, 3), dtype=np.uint8)
    rasm[:, : w // 2] = [220, 30, 30]
    rasm[:, w // 2:] = [30, 60, 200]
    rasm[2:4, 3:5] = [255, 255, 255]
    return rasm


def main() -> None:
    rasm = rasm_yarat()

    print("=== 1. Shakl va tur ===")
    h, w, c = rasm.shape
    print(f"  shakl (H, W, C): {rasm.shape}")
    print(f"  dtype: {rasm.dtype}, min {rasm.min()}, max {rasm.max()}")
    print(f"  piksellar soni: {h * w}, sonlar soni: {rasm.size}")
    print(f"  xotira: {rasm.nbytes} bayt (har son 1 bayt)")

    print("\n=== 2. Bitta piksel va bitta kanal ===")
    print(f"  rasm[0, 0]  (chap-yuqori): {rasm[0, 0].tolist()}  -> qizil")
    print(f"  rasm[0, 7]  (o'ng-yuqori): {rasm[0, 7].tolist()}  -> ko'k")
    print(f"  rasm[2, 3]  (markaz):      {rasm[2, 3].tolist()} -> oq")
    print("  R kanali (rasm[:, :, 0]):")
    for qator in rasm[:, :, 0]:
        print("   ", " ".join(f"{v:>3}" for v in qator))

    print("\n=== 3. uint8 tuzog'i ===")
    a = np.array([200], dtype=np.uint8)
    b = np.array([100], dtype=np.uint8)
    with np.errstate(over="ignore"):
        yigindi = a + b
        ayirma = b - a
    print(f"  uint8: 200 + 100 = {int(yigindi[0])}  (256 ga bo'lgandagi qoldiq)")
    print(f"  uint8: 100 - 200 = {int(ayirma[0])}")
    yorqin = np.clip(rasm.astype(np.int16) + 100, 0, 255).astype(np.uint8)
    print(f"  to'g'ri yorqinlashtirish (int16 + clip): "
          f"{rasm[0, 0].tolist()} -> {yorqin[0, 0].tolist()}")

    print("\n=== 4. float ga o'tkazish ===")
    f = rasm.astype(np.float32) / 255.0
    print(f"  float32 oralig'i: [{f.min():.4f}, {f.max():.4f}]")
    print(f"  xotira: {f.nbytes} bayt ({f.nbytes // rasm.nbytes} barobar)")

    print("\n=== 5. numpy (H,W,C) -> torch (C,H,W) ===")
    t = torch.from_numpy(rasm).permute(2, 0, 1)
    print(f"  permute(2, 0, 1) shakli: {tuple(t.shape)}")
    print(f"  contiguous: {t.is_contiguous()}  (faqat ko'rinish o'zgardi)")
    print(f"  t[0] == rasm[:, :, 0]: "
          f"{torch.equal(t[0], torch.from_numpy(rasm[:, :, 0]))}")
    xato = torch.from_numpy(rasm).reshape(3, h, w)
    print(f"  reshape(3, H, W) bilan 0-kanal == R kanali: "
          f"{torch.equal(xato[0], torch.from_numpy(rasm[:, :, 0]))}")
    print(f"  reshape 0-kanalining 1-qatori: {xato[0, 0, :6].tolist()}")
    print("  reshape piksellarni aralashtirib yubordi - permute kerak")
    orqaga = t.permute(1, 2, 0).numpy()
    print(f"  orqaga (H,W,C): {orqaga.shape}, "
          f"aslidek: {np.array_equal(orqaga, rasm)}")

    print("\n=== 6. Kulrang (grayscale) ===")
    vazn = np.array([0.299, 0.587, 0.114])
    kul = rasm.astype(np.float64) @ vazn
    print(f"  kul shakli: {kul.shape}")
    print(f"  qizil piksel -> {kul[0, 0]:.1f}, ko'k -> {kul[0, 7]:.1f}, "
          f"oq -> {kul[2, 3]:.1f}")
    oddiy = rasm.astype(np.float64).mean(axis=2)
    print(f"  oddiy o'rtacha: qizil {oddiy[0, 0]:.1f}, ko'k {oddiy[0, 7]:.1f}")
    print("  ko'z yashilga eng sezgir - vaznlar teng emas")
    print("  ⭐ Rasm - (H, W, C) sonlar massivi; torch uchun (C, H, W)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Shakl va tur ===
  shakl (H, W, C): (6, 8, 3)
  dtype: uint8, min 30, max 255
  piksellar soni: 48, sonlar soni: 144
  xotira: 144 bayt (har son 1 bayt)

=== 2. Bitta piksel va bitta kanal ===
  rasm[0, 0]  (chap-yuqori): [220, 30, 30]  -> qizil
  rasm[0, 7]  (o'ng-yuqori): [30, 60, 200]  -> ko'k
  rasm[2, 3]  (markaz):      [255, 255, 255] -> oq
  R kanali (rasm[:, :, 0]):
    220 220 220 220  30  30  30  30
    220 220 220 220  30  30  30  30
    220 220 220 255 255  30  30  30
    220 220 220 255 255  30  30  30
    220 220 220 220  30  30  30  30
    220 220 220 220  30  30  30  30

=== 3. uint8 tuzog'i ===
  uint8: 200 + 100 = 44  (256 ga bo'lgandagi qoldiq)
  uint8: 100 - 200 = 156
  to'g'ri yorqinlashtirish (int16 + clip): [220, 30, 30] -> [255, 130, 130]

=== 4. float ga o'tkazish ===
  float32 oralig'i: [0.1176, 1.0000]
  xotira: 576 bayt (4 barobar)

=== 5. numpy (H,W,C) -> torch (C,H,W) ===
  permute(2, 0, 1) shakli: (3, 6, 8)
  contiguous: False  (faqat ko'rinish o'zgardi)
  t[0] == rasm[:, :, 0]: True
  reshape(3, H, W) bilan 0-kanal == R kanali: False
  reshape 0-kanalining 1-qatori: [220, 30, 30, 220, 30, 30]
  reshape piksellarni aralashtirib yubordi - permute kerak
  orqaga (H,W,C): (6, 8, 3), aslidek: True

=== 6. Kulrang (grayscale) ===
  kul shakli: (6, 8)
  qizil piksel -> 86.8, ko'k -> 67.0, oq -> 255.0
  oddiy o'rtacha: qizil 93.3, ko'k 96.7
  ko'z yashilga eng sezgir - vaznlar teng emas
  ⭐ Rasm - (H, W, C) sonlar massivi; torch uchun (C, H, W)

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

Misol 2 — PIL: fayl, format va o'lcham

python
"""PIL bilan o'qish, yozish, o'lcham o'zgartirish (vaqtincha papkada)."""

import os
import shutil
import tempfile

import numpy as np
from PIL import Image


def rasm_yarat(h=48, w=64, seed=0):
    """Gradient fon + doira + shovqin: haqiqiy suratga o'xshash."""
    rng = np.random.default_rng(seed)
    y, x = np.mgrid[0:h, 0:w]
    r = (x / (w - 1) * 255)
    g = (y / (h - 1) * 255)
    b = np.full((h, w), 120.0)
    doira = (x - 40) ** 2 + (y - 20) ** 2 < 12 ** 2
    r[doira], g[doira], b[doira] = 250, 230, 40
    rasm = np.stack([r, g, b], axis=2) + rng.normal(0, 6, (h, w, 3))
    return np.clip(rasm, 0, 255).astype(np.uint8)


def main() -> None:
    papka = tempfile.mkdtemp()
    try:
        arr = rasm_yarat()
        img = Image.fromarray(arr)

        print("=== 1. numpy -> PIL ===")
        print(f"  numpy shakli (H, W, C): {arr.shape}")
        print(f"  PIL size (W, H): {img.size}, mode: {img.mode}")
        print("  DIQQAT: PIL (kenglik, balandlik), numpy (balandlik, kenglik)")

        print("\n=== 2. PNG va JPEG ga yozib, qayta o'qish ===")
        print(f"  {'format':<12} {'hajm, bayt':>11} {'aynan tengmi':>13} "
              f"{'maks farq':>10} {'o_rtacha farq':>14}")
        xom = arr.nbytes
        for nom, kw in [("png", {}), ("jpg", {"quality": 95}),
                        ("jpg", {"quality": 50})]:
            yol = os.path.join(papka, f"rasm_{kw.get('quality', 0)}.{nom}")
            img.save(yol, **kw)
            with Image.open(yol) as o:
                qayta = np.asarray(o.convert("RGB"))
            farq = np.abs(qayta.astype(int) - arr.astype(int))
            belgi = nom + (f" q={kw['quality']}" if kw else "")
            print(f"  {belgi:<12} {os.path.getsize(yol):>11} "
                  f"{str(np.array_equal(qayta, arr)):>13} "
                  f"{farq.max():>10} {farq.mean():>14.2f}")
        print(f"  siqilmagan hajm: {xom} bayt")
        print("  PNG - yo'qotishsiz, JPEG - piksellarni o'zgartiradi")

        print("\n=== 3. O'lchamni o'zgartirish ===")
        kichik = img.resize((16, 12), Image.Resampling.BILINEAR)
        print(f"  resize((16, 12)) -> size {kichik.size}, "
              f"numpy {np.asarray(kichik).shape}")
        for usul in ["NEAREST", "BILINEAR", "BICUBIC"]:
            katta = img.resize((128, 96), getattr(Image.Resampling, usul))
            k = np.asarray(katta)
            noyob = len(np.unique(k.reshape(-1, 3), axis=0))
            print(f"  {usul:<9} 2x kattalashtirish: noyob ranglar {noyob:>5}")
        print(f"  asl rasmdagi noyob ranglar: "
              f"{len(np.unique(arr.reshape(-1, 3), axis=0))}")
        print("  NEAREST yangi rang yaratmaydi (niqob/yorliq uchun shu kerak)")

        print("\n=== 4. Nisbatni saqlash ===")
        w, h = img.size
        yangi_w = 32
        yangi_h = round(h * yangi_w / w)
        print(f"  {w}x{h} -> {yangi_w}x{yangi_h}  (nisbat {w / h:.3f} -> "
              f"{yangi_w / yangi_h:.3f})")
        chozilgan = img.resize((32, 32))
        print(f"  majburan 32x32: nisbat {w / h:.3f} -> 1.000 "
              f"(doira ellipsga aylanadi), size {chozilgan.size}")

        print("\n=== 5. Kulrang va kesish ===")
        kul = img.convert("L")
        k = np.asarray(kul)
        print(f"  convert('L'): mode {kul.mode}, numpy {k.shape}, {k.dtype}")
        qolda = np.round(arr.astype(float) @ [0.299, 0.587, 0.114])
        print(f"  qo'lda formula bilan maks farq: "
              f"{np.abs(qolda - k).max():.0f}")
        kesik = img.crop((28, 8, 52, 32))
        print(f"  crop((chap, yuqori, o'ng, past)=(28, 8, 52, 32)) -> "
              f"size {kesik.size}")
        print(f"  numpy ekvivalenti arr[8:32, 28:52]: "
              f"{np.array_equal(np.asarray(kesik), arr[8:32, 28:52])}")
        print(f"  papkadagi fayllar: {len(os.listdir(papka))}")
    finally:
        shutil.rmtree(papka)
    print(f"  papka o'chirildi: {not os.path.exists(papka)}")
    print("  ⭐ PIL - fayl va o'lcham, numpy/torch - hisob")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. numpy -> PIL ===
  numpy shakli (H, W, C): (48, 64, 3)
  PIL size (W, H): (64, 48), mode: RGB
  DIQQAT: PIL (kenglik, balandlik), numpy (balandlik, kenglik)

=== 2. PNG va JPEG ga yozib, qayta o'qish ===
  format        hajm, bayt  aynan tengmi  maks farq  o_rtacha farq
  png                 6257          True          0           0.00
  jpg q=95            2291         False        102           5.34
  jpg q=50             974         False        114           7.75
  siqilmagan hajm: 9216 bayt
  PNG - yo'qotishsiz, JPEG - piksellarni o'zgartiradi

=== 3. O'lchamni o'zgartirish ===
  resize((16, 12)) -> size (16, 12), numpy (12, 16, 3)
  NEAREST   2x kattalashtirish: noyob ranglar  3051
  BILINEAR  2x kattalashtirish: noyob ranglar 11648
  BICUBIC   2x kattalashtirish: noyob ranglar 11908
  asl rasmdagi noyob ranglar: 3051
  NEAREST yangi rang yaratmaydi (niqob/yorliq uchun shu kerak)

=== 4. Nisbatni saqlash ===
  64x48 -> 32x24  (nisbat 1.333 -> 1.333)
  majburan 32x32: nisbat 1.333 -> 1.000 (doira ellipsga aylanadi), size (32, 32)

=== 5. Kulrang va kesish ===
  convert('L'): mode L, numpy (48, 64), uint8
  qo'lda formula bilan maks farq: 1
  crop((chap, yuqori, o'ng, past)=(28, 8, 52, 32)) -> size (24, 24)
  numpy ekvivalenti arr[8:32, 28:52]: True
  papkadagi fayllar: 3
  papka o'chirildi: True
  ⭐ PIL - fayl va o'lcham, numpy/torch - hisob

Nima ko'rsatdi: 2.5-bo'lim.

Misol 3 — load_digits, histogram va normalizatsiya

python
"""load_digits, histogram, batch (N, C, H, W) va normalizatsiya."""

import numpy as np
import torch
from sklearn.datasets import load_digits


def yaxlit(t, n=4):
    return [round(float(v), n) + 0.0 for v in t]


def rangli_toplam(n=200, h=16, w=16, seed=0):
    """Kanallari har xil yorqinlikdagi sintetik RGB to'plam (uint8)."""
    rng = np.random.default_rng(seed)
    orta = np.array([150.0, 100.0, 60.0])
    tarqoq = np.array([40.0, 25.0, 15.0])
    x = rng.normal(orta, tarqoq, (n, h, w, 3))
    return np.clip(x, 0, 255).astype(np.uint8)


def main() -> None:
    d = load_digits()
    print("=== 1. load_digits ===")
    print(f"  images: {d.images.shape}, data: {d.data.shape}, "
          f"dtype {d.images.dtype}")
    print(f"  qiymatlar oralig'i: {d.images.min():.0f}..{d.images.max():.0f} "
          f"(16 darajali kulrang)")
    print(f"  sinflar: {np.unique(d.target).tolist()}")
    print(f"  data[0] == images[0].ravel(): "
          f"{np.array_equal(d.data[0], d.images[0].ravel())}")
    print(f"  0-rasm, yorliq {d.target[0]}:")
    belgi = " .:-=+*#%@"
    for qator in d.images[0]:
        print("    " + "".join(belgi[int(v * 9 / 16)] * 2 for v in qator))

    print("\n=== 2. Piksel histogrammasi ===")
    soni, chegara = np.histogram(d.images, bins=[0, 1, 4, 8, 12, 16.5])
    jami = soni.sum()
    for i in range(len(soni)):
        ulush = soni[i] / jami
        print(f"  [{chegara[i]:>4.0f}, {chegara[i + 1]:>4.1f}) "
              f"{ulush:>6.1%} {'#' * int(ulush * 50)}")
    print(f"  nol piksellar: {(d.images == 0).mean():.1%} - fon ustun")
    chekka = d.images[:, :, 0].mean()
    markaz = d.images[:, 3:5, 3:5].mean()
    print(f"  chap ustun o'rtachasi {chekka:.2f}, markaz o'rtachasi "
          f"{markaz:.2f}")

    print("\n=== 3. Batch: (N, C, H, W) ===")
    x = torch.tensor(d.images, dtype=torch.float32).unsqueeze(1)
    print(f"  unsqueeze(1): {tuple(x.shape)}  (N, C=1, H, W)")
    batch = x[:32]
    print(f"  bitta batch: {tuple(batch.shape)}")
    print(f"  bitta rasm (C, H, W): {tuple(batch[0].shape)}")
    tekis = batch.flatten(1)
    print(f"  flatten(1) - MLP uchun: {tuple(tekis.shape)}")

    print("\n=== 4. Oddiy masshtab: 0..1 ===")
    x01 = x / 16.0
    print(f"  /16 dan keyin: [{x01.min():.1f}, {x01.max():.1f}], "
          f"o'rtacha {x01.mean():.3f}")

    print("\n=== 5. Kanal bo'yicha mean/std ===")
    rgb = rangli_toplam()
    t = torch.from_numpy(rgb).permute(0, 3, 1, 2).float() / 255.0
    print(f"  RGB to'plam: {tuple(t.shape)}")
    orta = t.mean(dim=(0, 2, 3))
    std = t.std(dim=(0, 2, 3))
    print(f"  kanal o'rtachalari: {yaxlit(orta)}")
    print(f"  kanal std lari:     {yaxlit(std)}")
    norm = (t - orta.view(1, 3, 1, 1)) / std.view(1, 3, 1, 1)
    print(f"  normallashgandan keyin o'rtacha: "
          f"{yaxlit(norm.mean(dim=(0, 2, 3)))}")
    print(f"  normallashgandan keyin std:      "
          f"{yaxlit(norm.std(dim=(0, 2, 3)))}")
    umumiy = (t - t.mean()) / t.std()
    print(f"  bitta umumiy mean/std bilan kanal o'rtachalari: "
          f"{yaxlit(umumiy.mean(dim=(0, 2, 3)), 3)}")
    print("  umumiy normalizatsiya kanallar orasidagi farqni qoldiradi")

    print("\n=== 6. Broadcasting tuzog'i ===")
    try:
        _ = t - orta.view(3)
        print("  view(3) bilan ayirish ishladi (kutilmagan)")
    except RuntimeError as xato:
        print(f"  (N,3,H,W) - (3,): RuntimeError - {str(xato)[:45]}")
    print("  ⭐ Statistikani (0, 2, 3) o'qlar bo'yicha, shaklni (1,3,1,1) qiling")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. load_digits ===
  images: (1797, 8, 8), data: (1797, 64), dtype float64
  qiymatlar oralig'i: 0..16 (16 darajali kulrang)
  sinflar: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  data[0] == images[0].ravel(): True
  0-rasm, yorliq 0:
        ::##++
        ##%%++%%::
      ..%%..  **==
      ::**    ====
      ::==    ++==
      ::**    **--
      ..##::++**
        --##++

=== 2. Piksel histogrammasi ===
  [   0,  1.0)  48.9% ########################
  [   1,  4.0)   9.0% ####
  [   4,  8.0)   9.8% ####
  [   8, 12.0)  10.1% #####
  [  12, 16.5)  22.2% ###########
  nol piksellar: 48.9% - fon ustun
  chap ustun o'rtachasi 0.00, markaz o'rtachasi 9.53

=== 3. Batch: (N, C, H, W) ===
  unsqueeze(1): (1797, 1, 8, 8)  (N, C=1, H, W)
  bitta batch: (32, 1, 8, 8)
  bitta rasm (C, H, W): (1, 8, 8)
  flatten(1) - MLP uchun: (32, 64)

=== 4. Oddiy masshtab: 0..1 ===
  /16 dan keyin: [0.0, 1.0], o'rtacha 0.305

=== 5. Kanal bo'yicha mean/std ===
  RGB to'plam: (200, 3, 16, 16)
  kanal o'rtachalari: [0.5866, 0.3901, 0.2332]
  kanal std lari:     [0.1565, 0.098, 0.059]
  normallashgandan keyin o'rtacha: [0.0, 0.0, 0.0]
  normallashgandan keyin std:      [1.0, 1.0, 1.0]
  bitta umumiy mean/std bilan kanal o'rtachalari: [1.002, -0.072, -0.93]
  umumiy normalizatsiya kanallar orasidagi farqni qoldiradi

=== 6. Broadcasting tuzog'i ===
  (N,3,H,W) - (3,): RuntimeError - The size of tensor a (16) must match the size
  ⭐ Statistikani (0, 2, 3) o'qlar bo'yicha, shaklni (1,3,1,1) qiling

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

Misol 4 — Sintetik shakllar va piksel bazaviysi

python
"""Sintetik shakllar to'plami: doira va kvadrat, piksellarda bazaviy model."""

import warnings

import numpy as np
import torch
from sklearn.linear_model import LogisticRegression


def shakl_chiz(turi, h, markaz_y, markaz_x, radius):
    y, x = np.mgrid[0:h, 0:h]
    if turi == 0:      # doira
        return ((y - markaz_y) ** 2 + (x - markaz_x) ** 2
                <= radius ** 2).astype(np.float32)
    return ((np.abs(y - markaz_y) <= radius)
            & (np.abs(x - markaz_x) <= radius)).astype(np.float32)


def toplam(n, h=16, siljish=True, shovqin=0.15, seed=0):
    """siljish=False - hamma shakl markazda; True - tasodifiy joyda."""
    rng = np.random.default_rng(seed)
    x = np.zeros((n, 1, h, h), dtype=np.float32)
    y = rng.integers(0, 2, n)
    for i in range(n):
        r = int(rng.integers(2, 5))
        if siljish:
            my, mx = rng.integers(r, h - r, 2)
        else:
            my = mx = h // 2
        x[i, 0] = shakl_chiz(y[i], h, my, mx, r)
    x += rng.normal(0, shovqin, x.shape).astype(np.float32)
    return torch.from_numpy(np.clip(x, 0, 1)), torch.from_numpy(y)


def pikselda_bahola(x_tr, y_tr, x_te, y_te):
    with warnings.catch_warnings(record=True) as ogoh:
        warnings.simplefilter("always")
        m = LogisticRegression(C=0.1, max_iter=3000)
        m.fit(x_tr.flatten(1).numpy(), y_tr.numpy())
    return m.score(x_te.flatten(1).numpy(), y_te.numpy()), len(ogoh)


def main() -> None:
    print("=== 1. Bitta doira va bitta kvadrat (shovqinsiz) ===")
    for turi, nom in [(0, "doira"), (1, "kvadrat")]:
        s = shakl_chiz(turi, 9, 4, 4, 3)
        print(f"  {nom} (radius 3), yuzasi {int(s.sum())} piksel:")
        for qator in s:
            print("    " + "".join("##" if v else ". " for v in qator))

    print("\n=== 2. To'plam ===")
    x, y = toplam(1000)
    print(f"  x: {tuple(x.shape)} {x.dtype}, y: {tuple(y.shape)}")
    print(f"  sinflar balansi: doira {int((y == 0).sum())}, "
          f"kvadrat {int((y == 1).sum())}")
    print(f"  qiymatlar oralig'i: [{x.min():.2f}, {x.max():.2f}]")
    yuza = (x > 0.5).float().sum(dim=(1, 2, 3))
    for k, nom in [(0, "doira"), (1, "kvadrat")]:
        print(f"  {nom:<8} o'rtacha yuza: {yuza[y == k].mean():.1f} piksel")

    print("\n=== 3. Piksel = belgi: logistik regressiya ===")
    print(f"  {'holat':<28} {'o_quv':>6} {'test aniqlik':>13}")
    natija = {}
    for siljish in [False, True]:
        for n_tr in [200, 1000]:
            x_tr, y_tr = toplam(n_tr, siljish=siljish, seed=1)
            x_te, y_te = toplam(1000, siljish=siljish, seed=2)
            aniq, n_ogoh = pikselda_bahola(x_tr, y_tr, x_te, y_te)
            natija[(siljish, n_tr)] = aniq
            holat = "tasodifiy joyda" if siljish else "hammasi markazda"
            print(f"  {holat:<28} {n_tr:>6} {aniq:>13.3f}")
            if n_ogoh:
                print(f"    ogohlantirishlar: {n_ogoh}")
    farq = natija[(False, 1000)] - natija[(True, 1000)]
    print(f"  markazdan tasodifiy joyga o'tganda aniqlik "
          f"{farq:.3f} ga kamaydi" if farq > 0 else
          f"  markazdan tasodifiy joyga o'tganda aniqlik kamaymadi "
          f"({farq:+.3f})")

    print("\n=== 4. Nega qiyin: bir xil shakl, boshqa piksellar ===")
    a = torch.from_numpy(shakl_chiz(1, 16, 5, 5, 3))
    b = torch.from_numpy(shakl_chiz(1, 16, 10, 10, 3))
    kesishma = int((a * b).sum())
    print(f"  ikki kvadrat (har biri {int(a.sum())} piksel), faqat joyi "
          f"boshqa: umumiy piksellar {kesishma}")
    print(f"  piksel vektorlari orasidagi kosinus: "
          f"{torch.nn.functional.cosine_similarity(a.flatten(), b.flatten(), dim=0):.3f}")
    print("  piksel modeli uchun bular deyarli 'boshqa' rasmlar")
    print("  ⭐ Joyga bog'liq bo'lmagan belgi kerak - bu konvolyutsiya ishi")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bitta doira va bitta kvadrat (shovqinsiz) ===
  doira (radius 3), yuzasi 29 piksel:
    . . . . . . . . .
    . . . . ##. . . .
    . . ##########. .
    . . ##########. .
    . ##############.
    . . ##########. .
    . . ##########. .
    . . . . ##. . . .
    . . . . . . . . .
  kvadrat (radius 3), yuzasi 49 piksel:
    . . . . . . . . .
    . ##############.
    . ##############.
    . ##############.
    . ##############.
    . ##############.
    . ##############.
    . ##############.
    . . . . . . . . .

=== 2. To'plam ===
  x: (1000, 1, 16, 16) torch.float32, y: (1000,)
  sinflar balansi: doira 463, kvadrat 537
  qiymatlar oralig'i: [0.00, 1.00]
  doira    o'rtacha yuza: 30.6 piksel
  kvadrat  o'rtacha yuza: 51.5 piksel

=== 3. Piksel = belgi: logistik regressiya ===
  holat                         o_quv  test aniqlik
  hammasi markazda                200         1.000
  hammasi markazda               1000         1.000
  tasodifiy joyda                 200         0.682
  tasodifiy joyda                1000         0.709
  markazdan tasodifiy joyga o'tganda aniqlik 0.291 ga kamaydi

=== 4. Nega qiyin: bir xil shakl, boshqa piksellar ===
  ikki kvadrat (har biri 49 piksel), faqat joyi boshqa: umumiy piksellar 4
  piksel vektorlari orasidagi kosinus: 0.082
  piksel modeli uchun bular deyarli 'boshqa' rasmlar
  ⭐ Joyga bog'liq bo'lmagan belgi kerak - bu konvolyutsiya ishi

Nima ko'rsatdi: 2.6-bo'lim va keyingi darslar motivatsiyasi.


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

Noto'g'ri fikr To'g'risi
"Rasm — maxsus obyekt" (H, W, C) sonlar massivi
"reshape va permute bir xil" reshape piksellarni aralashtiradi
"uint8 da hisoblash xavfsiz" 256 bo'yicha jim aylanadi
"img.size — (H, W)" PIL da (W, H)
"Kulrang rasmga kanal kerak emas" nn.Conv2d uchun (N, 1, H, W)
"Bitta umumiy mean/std yetarli" Kanallar har xil — kanal bo'yicha
"JPEG ga saqlash — nusxa olish" Piksellar o'zgaradi
"Piksellar — yaxshi belgilar" Joy o'zgarsa, belgi butunlay o'zgaradi

6. Keng tarqalgan xatolar va yechimlari

1. uint8 ustida arifmetika

python
yorqin = rasm + 100                                    # ⚠️ 200 + 100 = 44
yorqin = np.clip(rasm.astype(np.int16) + 100, 0, 255)  # ✅

2. reshape bilan o'q almashtirish

python
t = torch.from_numpy(rasm).reshape(3, h, w)            # ⚠️ aralash
t = torch.from_numpy(rasm).permute(2, 0, 1)            # ✅

3. PIL size tartibi

python
h, w = img.size                                        # ⚠️ teskari
w, h = img.size                                        # ✅

4. Kanal o'qisiz kulrang batch

python
x = torch.tensor(d.images)                  # (N, 8, 8)  # ⚠️
x = torch.tensor(d.images).unsqueeze(1)     # (N, 1, 8, 8)  # ✅

5. Noto'g'ri broadcasting

python
x - orta                           # orta (3,)          # ⚠️
x - orta.view(1, 3, 1, 1)                               # ✅

6. Statistika test to'plamida

python
orta = hamma_x.mean(dim=(0, 2, 3))                      # ⚠️ leakage
orta = oquv_x.mean(dim=(0, 2, 3))                       # ✅

7. Niqobni BILINEAR bilan kichraytirish

python
niqob.resize((64, 64), Image.Resampling.BILINEAR)       # ⚠️ 0.5 sinf
niqob.resize((64, 64), Image.Resampling.NEAREST)        # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 20-qism (o'tilgan): MLP — flatten(1) bilan rasmni vektor qilish
  • 21-qism (o'tilgan): Dataset, DataLoader, augmentatsiya
  • 17-qism (o'tilgan): Masshtablash va leakage
  • Keyingi darslar: Konvolyutsiya (N, C, H, W) tensor ustida ishlaydi
  • Transfer learning mavzusida: ImageNet mean/std va oldindan o'rgatilgan modellar
  • Segmentatsiya mavzusida: Niqoblar va NEAREST resize

8. Eng yaxshi amaliyotlar

  1. Diskda uint8, hisobda float32.

  2. O'qlarni faqat permute bilan almashtiring.

  3. Har doim shaklni chop eting (x.shape) — birinchi batchda.

  4. Rasmni convert("RGB") bilan o'qing — RGBA, palitra, kulrangni bir xillashtiring.

  5. Normalizatsiya statistikasini faqat o'quvda hisoblang.

  6. Oldindan o'rgatilgan model — o'sha mean/std.

  7. Niqob va yorliqlar uchun NEAREST.

  8. Yangi g'oyani avval sintetik to'plamda tekshiring.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # 224x224 rangli rasmda nechta son bor?
2.  # np.uint8(250) + np.uint8(10) ning natijasi?
3.  # (H, W, C) -> (C, H, W) qaysi funksiya bilan?
4.  # PIL img.size nimani qaytaradi?
5.  # load_digits images shakli?
6.  # load_digits qiymatlar oralig'i?
7.  # kulrang batch (N, H, W) ni Conv2d uchun qanday tayyorlaysiz?
8.  # kanal bo'yicha mean uchun qaysi dim?
9.  # mean (3,) ni (N, 3, H, W) dan ayirish uchun shakl?
10. # niqobni kichraytirishda qaysi usul?
11. # PNG va JPEG ning asosiy farqi?
12. # uint8 va float32 xotira nisbati?
Javoblar
  1. 224 × 224 × 3 = 150 528
  2. 4 (260 - 256)
  3. permute(2, 0, 1)
  4. (W, H)
  5. (1797, 8, 8)
  6. 0..16
  7. x.unsqueeze(1) → (N, 1, H, W)
  8. dim=(0, 2, 3)
  9. view(1, 3, 1, 1)
  10. NEAREST
  11. PNG yo'qotishsiz, JPEG yo'qotishli
  12. 1 : 4

Vazifa 2: Xatolarni tuzating

python
1.  t = torch.from_numpy(rasm).reshape(3, h, w)

2.  h, w = img.size

3.  yorqin = rasm + 80        # rasm uint8

4.  x_norm = (x - x.mean()) / x.std()     # x: (N, 3, H, W), kanallar har xil

5.  niqob = niqob.resize((32, 32))        # niqob - sinf raqamlari
Javoblar
python
1.  t = torch.from_numpy(rasm).permute(2, 0, 1)

2.  w, h = img.size

3.  yorqin = np.clip(rasm.astype(np.int16) + 80, 0, 255).astype(np.uint8)

4.  orta, std = x.mean(dim=(0, 2, 3)), x.std(dim=(0, 2, 3))
    x_norm = (x - orta.view(1, 3, 1, 1)) / std.view(1, 3, 1, 1)

5.  niqob = niqob.resize((32, 32), Image.Resampling.NEAREST)

Vazifa 3: Massiv

Modellang:

  1. Shakl va tur
  2. Piksel va kanal
  3. uint8 tuzog'i
  4. permute va reshape

Vazifa 4: PIL

Modellang:

  1. (W, H) va (H, W)
  2. PNG va JPEG
  3. Resize usullari
  4. Kulrang va kesish

Vazifa 5: Normalizatsiya

Modellang:

  1. load_digits
  2. Histogram
  3. Batch shakli
  4. Kanal bo'yicha mean/std

Vazifa 6: Sintetik to'plam

Modellang:

  1. Doira va kvadrat
  2. Tasodifiy joy
  3. Piksel bazaviysi
  4. Kosinus o'xshashlik

Vazifa 7: O'ylash

Hamkasbingiz aytdi: "Rasmni flatten qilib, 20-qismdagi MLP ga beramiz — u universal approksimator, hammasini o'zi o'rganadi. Konvolyutsiyaga nima hojat?" 4-misol natijalariga tayanib nima deysiz?

Javob

Qisqa javob: nazariy jihatdan MLP istalgan funksiyani ifodalay oladi, lekin ma'lumot yetarli bo'lsa. Rasmlarda muammo — ifodalash emas, o'rganish uchun kerak bo'ladigan misollar soni.

4-misol nimani ko'rsatdi:

Shakl doim markazda bo'lganda, piksellardagi logistik regressiya 200 ta misolda ham xatosiz ishladi. Shakl tasodifiy joyda bo'lganda esa 1000 ta misolda ham aniqlik 0.7 atrofida qoldi. Sabab: joyi boshqa ikki kvadrat umumiy piksellarga deyarli ega emas (kosinus 0.08). Piksel modeli uchun "chap-yuqoridagi kvadrat" va "o'ng-pastdagi kvadrat" — butunlay boshqa naqshlar. U har bir joy uchun kvadratni alohida o'rganishi kerak.

Hisob:

text
16x16 rasmda shakl ~ 100 xil joyda turishi mumkin
MLP har joy uchun alohida misollar ko'rishi kerak
224x224 rasmda joylar soni - o'n minglab
+ o'lcham, burilish, yorug'lik o'zgarishlari
-> kerakli ma'lumot hajmi portlaydi

Konvolyutsiya nima beradi:

  1. Og'irlik baham ko'rish — bitta kichik filtr (masalan, 3×3) rasmning hamma joyida qo'llanadi. "Burchak" ni bir joyda o'rgangan filtr uni hamma joyda taniydi.
  2. Lokal bog'lanish — har chiqish faqat kichik qo'shnichilikka qaraydi; qo'shni piksellar orasidagi bog'lanish tabiiy ravishda hisobga olinadi.
  3. Parametrlar keskin kam — 224×224×3 kirishdan 1000 neyronli Linear 150 million parametr, 3×3 filtrli 64 kanalli Conv2d esa 1 792 parametr.

Amaliy tavsiya:

python
# 1. Avval piksel bazaviysi (logistik regressiya yoki MLP) - taqqoslash uchun
# 2. Keyin kichik CNN - bir xil bo'linish, bir xil metrika
# 3. Farqni o'lchang: CNN ning ustunligi aynan siljish ko'p bo'lganda katta

Hamkasbga javob:

"MLP buni ifodalay oladi, lekin o'rganish uchun har joydagi har shakl misolini ko'rishi kerak. Sintetik to'plamda shakl joyi o'zgarganda piksel modeli 0.7 da qoldi. Konvolyutsiya bitta filtrni hamma joyda ishlatadi — shu sabab u kam ma'lumotda ham siljishga chidamli. Keling, ikkalasini bir xil bo'linishda solishtiramiz."

Nimani mustahkamlaydi: 2.1, 2.3, 2.6-bo'limlar.


Xulosa

Bu darsda rasmni sonlar massivi sifatida ko'rdik.

Eng muhim uch fikr:

  1. Rasm — (H, W, C) massiv, torch uchun (C, H, W). 1-misolda 6×8 rangli rasm 144 ta sondan iborat bo'ldi va permute(2, 0, 1) uni to'g'ri (3, 6, 8) ga o'tkazdi, reshape(3, H, W) esa kanallarni aralashtirib yubordi. uint8 ustida arifmetika jim buziladi: 200 + 100 = 44, 100 - 200 = 156. Shuning uchun hisobdan oldin float32 ga o'tiladi — bu 4 barobar ko'p xotira.

  2. Fayl bilan PIL, normalizatsiya kanal bo'yicha. 2-misolda PNG rasmni aynan qaytardi, JPEG esa quality=95 da ham piksellarni o'rtacha 5.34 ga (keskin chegaralarda 102 gacha) o'zgartirdi. NEAREST yangi rang yaratmadi (3051 ta noyob rang saqlandi), BILINEAR esa 11 648 taga oshirdi — niqoblar uchun bu halokatli. 3-misolda kanal bo'yicha mean/std har kanalni aniq 0 va 1 ga keltirdi, bitta umumiy mean/std esa kanallar o'rtachasini 1.00, -0.07, -0.93 da qoldirdi.

  3. Piksellar joyga bog'liq belgi. 4-misolda shakl doim markazda bo'lganda piksellardagi logistik regressiya 1.000 aniqlik berdi, shakl tasodifiy joyda bo'lganda esa 1000 ta misolda ham 0.709 da qoldi. Joyi boshqa ikki bir xil kvadratning kosinus o'xshashligi atigi 0.082 — piksel modeli uchun ular boshqa rasmlar. Bu muammoni hal qiladigan vosita — konvolyutsiya.

Keyingi darsda konvolyutsiya: sirpanuvchi oynani numpy da qo'lda yozamiz, chegara va xiralashtirish yadrolarini qo'llaymiz, padding va stride bilan chiqish o'lchamini hisoblaymiz va natijani torch bilan aynan solishtiramiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
22.1-dars: Rasm ma'lumoti — IlmHamroh