14-bo‘lim

Rasmlarni tasniflash

Fashion-MNIST to'plami, torchvision datasets, zich tarmoq va CNN ni haqiqiy ma'lumotda solishtirish, sinflar bo'yicha tahlil.

🕑 8 daqiqa o‘qish 📄 629 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Ma'lumotni yuklash
  2. Ikki modelni o'qitamiz
  3. Natijani o'qiymiz
  4. Qaysi sinf qiyin
  5. Nima bilan chalkashtiryapti
  6. Xulosa

Nazariya yetarli - endi haqiqiy to'plamda ishlaymiz. Fashion-MNIST kiyim rasmlaridan iborat: 70 000 ta kulrang 28x28 rasm, 10 ta sinf.

Ma'lumotni yuklash #

torchvision mashhur to'plamlarni o'zi yuklab beradi:

Python
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

torch.manual_seed(42)

o_ds = datasets.FashionMNIST("./data", train=True,  download=True, transform=transforms.ToTensor())
t_ds = datasets.FashionMNIST("./data", train=False, download=True, transform=transforms.ToTensor())

sinflar = ['Futbolka', 'Shim', 'Sviter', 'Libos', 'Palto',
           'Sandal', "Ko'ylak", 'Krossovka', 'Sumka', 'Botinka']

print("o'quv:", len(o_ds), "| test:", len(t_ds), "| sinflar:", len(sinflar))
x, y = o_ds[0]
print("rasm:", tuple(x.shape), "min/max:", round(x.min().item(), 2), round(x.max().item(), 2))
print("sinf taqsimoti:", torch.bincount(o_ds.targets).tolist())
Natija
o'quv: 60000 | test: 10000 | sinflar: 10
rasm: (1, 28, 28) min/max: 0.0 1.0
sinf taqsimoti: [6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000]

Har sinfdan aynan 6000 tadan - to'plam mukammal muvozanatli. Bu qulay: aniqlikni baholashda hech qanday tuzatish kerak emas.

transforms.ToTensor() ikkita ishni bajaradi: rasmni tenzorga aylantiradi va qiymatlarni 0-255 dan 0.0-1.0 ga keltiradi.

train=True va train=False

Fashion-MNIST allaqachon ikkiga bo'lingan: 60 000 o'quv va 10 000 test. Bu standart bo'linish - shuning uchun turli maqolalardagi natijalarni bir-biri bilan solishtirish mumkin.

O'z loyihangizda bunday tayyor bo'linish bo'lmasa, uni random_split bilan o'zingiz qilasiz (7-bo'lim).

Ikki modelni o'qitamiz #

Python
o_dl = DataLoader(o_ds, batch_size=64, shuffle=True)
t_dl = DataLoader(t_ds, batch_size=256)

class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.xususiyat = 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))
        self.tasnif = nn.Sequential(nn.Flatten(), nn.Linear(32 * 7 * 7, 10))

    def forward(self, x):
        return self.tasnif(self.xususiyat(x))

O'quv sikli 8-bo'limdagi bilan bir xil - faqat ma'lumot boshqacha.

Natija
--- Zich tarmoq (101,770 parametr) ---
Davr | O'quv yo'q. | Test yo'q. | Test aniqlik | Vaqt
   1 |     0.5459 |     0.4845 |      83.33% |   6.1s
   2 |     0.3987 |     0.4080 |      85.69% |   5.8s
   3 |     0.3611 |     0.3952 |      85.87% |   5.8s
   4 |     0.3318 |     0.3918 |      86.02% |   5.7s
   5 |     0.3132 |     0.3538 |      87.33% |   5.7s

--- CNN (20,490 parametr) ---
Davr | O'quv yo'q. | Test yo'q. | Test aniqlik | Vaqt
   1 |     0.5235 |     0.3838 |      86.64% |  12.2s
   2 |     0.3447 |     0.3407 |      87.63% |  12.4s
   3 |     0.3060 |     0.3133 |      88.73% |  12.5s
   4 |     0.2825 |     0.3311 |      88.35% |  12.6s
   5 |     0.2656 |     0.2976 |      89.34% |  12.4s

Natijani o'qiymiz #

ModelParametrlarTest aniqligiBir davr vaqti
Zich tarmoq101 77087.33%~5.8 s
CNN20 49089.34%~12.4 s

CNN 5 barobar kam parametr bilan 2 foiz ko'proq aniqlik berdi. Buning sababi 13-bo'limda aytilgan edi: konvolyutsiya piksellarning qo'shnichiligini saqlaydi.

CNN sekinroq ishladi - bu normal

Parametrlar kam bo'lsa ham, CNN ikki barobar ko'p vaqt oldi. Chunki konvolyutsiya har piksel uchun qayta-qayta hisoblanadi, zich qatlam esa bitta katta matritsa ko'paytmasi.

CPU da bu farq sezilarli. GPU da esa konvolyutsiya juda yaxshi parallellashadi va farq deyarli yo'qoladi - aynan shuning uchun rasm modellari GPU da o'qitiladi.

Diqqat qiling: 4-davrda CNN ning test yo'qotishi 0.3133 dan 0.3311 ga o'sdi, keyin yana tushdi. Bunday kichik tebranish normal - 11-bo'limdagi barqaror o'sish esa muammo belgisi edi.

Qaysi sinf qiyin #

Umumiy aniqlik 89.34% - lekin u har sinfda bir xil emas:

Python
cnn.eval()
togri = torch.zeros(10); jami = torch.zeros(10)
chalkashlik = torch.zeros(10, 10, dtype=torch.long)

with torch.no_grad():
    for xb, yb in t_dl:
        p = cnn(xb).argmax(1)
        for haq, bash in zip(yb, p):
            jami[haq] += 1
            chalkashlik[haq, bash] += 1
            if haq == bash:
                togri[haq] += 1

for i in range(10):
    print(f"{sinflar[i]:10s} | {togri[i]/jami[i]:6.1%}")
Natija
Sinf       | Aniqlik
-----------|--------
Futbolka   |  80.9%
Shim       |  97.7%
Sviter     |  83.1%
Libos      |  95.6%
Palto      |  83.7%
Sandal     |  97.0%
Ko'ylak    |  65.7%
Krossovka  |  94.8%
Sumka      |  97.8%
Botinka    |  97.1%

umumiy: 89.34%

Farq juda katta: Sumka 97.8%, Ko'ylak esa atigi 65.7%. Umumiy son buni butunlay yashirgan edi.

Nima bilan chalkashtiryapti #

Python
juft = [(chalkashlik[i,j].item(), i, j) for i in range(10) for j in range(10) if i != j]
for n, i, j in sorted(juft, reverse=True)[:5]:
    print(f"  {sinflar[i]:10s} -> {sinflar[j]:10s} : {n} marta")
Natija
  Ko'ylak    -> Futbolka   : 114 marta
  Ko'ylak    -> Palto      : 92 marta
  Futbolka   -> Ko'ylak    : 88 marta
  Sviter     -> Palto      : 84 marta
  Futbolka   -> Libos      : 65 marta

Xatolar tasodifiy emas. Hammasi ustki kiyimlar orasida: ko'ylak, futbolka, sviter, palto. 28x28 kulrang rasmda ularning shakli deyarli bir xil - mato va tugmalar ko'rinmaydi.

Poyabzal va sumka esa hech qachon ular bilan chalkashmadi.

CNN ning sinflar bo'yicha aniqligi Futbolka 80.9% Shim 97.7% Sviter 83.1% Libos 95.6% Palto 83.7% Sandal 97.0% Ko'ylak 65.7% Krossovka 94.8% Sumka 97.8% Botinka 97.1% 0% 25% 50% 75% 100% Umumiy 89.34% - lekin sinflar orasidagi farq 32 foizga yetadi
Poyabzal va sumka oson; ustki kiyimlar bir-biri bilan chalkashadi
Umumiy aniqlikka ishonmang

89% degan son modelni yaxshi ko'rsatadi. Aslida esa u ko'ylaklarning uchdan birini noto'g'ri tasniflaydi.

Agar bu do'kon uchun yozilgan tizim bo'lsa, ko'ylak buyurtmalari muntazam noto'g'ri turkumga tushardi - va bu umumiy hisobotda ko'rinmasdi.

Har doim sinflar bo'yicha taqsimotni chiqaring. 18-bo'limda buni chuqurroq ko'ramiz.

Natijani yaxshilash yo'llari

Ushbu 89.34% - boshlang'ich natija. Uni oshirish uchun: ko'proq davr, uchinchi konvolyutsion blok, BatchNorm2d, ma'lumotni normallash va kengaytirish (15-bo'lim), yoki tayyor modeldan foydalanish (16-bo'lim). Har birini alohida sinab, ta'sirini o'lchang.

Amaliy topshiriq
  1. Fashion-MNIST ni yuklab, o'quv va test hajmini chop eting.
  2. Bitta rasmning shakli va qiymatlar oralig'ini tekshiring.
  3. Sinf taqsimotini bincount bilan chiqaring.
  4. Zich tarmoqni 5 davr o'qitib, test aniqligini yozing.
  5. CNN ni xuddi shu sharoitda o'qitib, natijalarni solishtiring.
  6. Ikkala modelning parametrlari sonini va davr vaqtini jadvalga yozing.
  7. Sinflar bo'yicha aniqlikni hisoblang va eng yomonini toping.
  8. Eng ko'p chalkashgan 5 ta juftlikni chiqaring.
  9. Xatolar nega aynan ustki kiyimlar orasida ko'pligini tushuntiring.
  10. CNN ga uchinchi konvolyutsion blok qo'shib, aniqlik o'zgarishini o'lchang.

Xulosa #

  • torchvision.datasets mashhur to'plamlarni bitta qator bilan yuklaydi.
  • transforms.ToTensor() rasmni tenzorga aylantiradi va 0-1 oralig'iga keltiradi.
  • Fashion-MNIST muvozanatli: har sinfdan 6000 tadan.
  • CNN 20 490 parametr bilan 89.34%, zich tarmoq 101 770 parametr bilan 87.33% berdi.
  • Ya'ni CNN 5 barobar kam parametrda aniqroq ishladi.
  • CNN CPU da sekinroq, chunki konvolyutsiya ko'p hisob talab qiladi - GPU da bu farq yo'qoladi.
  • Test yo'qotishining kichik tebranishi normal; barqaror o'sish esa ortiqcha moslashish belgisi.
  • Umumiy aniqlik sinflar orasidagi katta farqni yashiradi.
  • Bizning modelda Sumka 97.8%, Ko'ylak esa atigi 65.7% aniqlik berdi.
  • Xatolar tasodifiy emas - ular o'zaro o'xshash sinflar orasida to'planadi.

Keyingi bo'limda ma'lumotni normallash va sun'iy kengaytirish bilan natijani yaxshilaymiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.