12-bo‘lim
Regularizatsiya usullari
Dropout, weight decay, erta to'xtatish, modelni kichraytirish va ko'proq ma'lumot - beshta usul o'lchab solishtiriladi.
Ushbu bo‘lim mundarijasi
Oldingi bo'limda muammoni ko'rdik: eng yaxshi model 3-davrda edi, 200-davrda esa yo'qotish 5 barobar yomonlashdi. Endi buni tuzatamiz.
Kod oldingi bo'limdagi malumot(), tarmoq(), baholash() va oqit()
funksiyalaridan foydalanadi.
1. Dropout #
nn.Dropout(p) o'qitish paytida neyronlarning p ulushini tasodifiy
o'chiradi. Model hech bir neyronga ortiqcha tayanmaydigan bo'ladi:
import torch
import torch.nn as nn
torch.manual_seed(1)
d = nn.Dropout(0.5)
x = torch.ones(1, 10)
d.train()
print("train:", d(x).tolist()[0])
d.eval()
print("eval: ", d(x).tolist()[0])
train: [2.0, 2.0, 2.0, 2.0, 0.0, 2.0, 2.0, 0.0, 0.0, 2.0]
eval: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
Ikki narsaga e'tibor bering:
trainrejimida 3 ta qiymat 0 bo'ldi, qolganlari esa 2.0 ga ko'tarildi. PyTorch tirik qolganlarni1/(1-p)ga ko'paytiradi, shunda umumiy yig'indi o'rtacha o'zgarmaydi.evalrejimida Dropout umuman ishlamaydi - barcha qiymatlar o'zgarishsiz o'tdi.
eval() ni unutishning aynan sababiYuqoridagi natija shuni ko'rsatadi: model.eval() chaqirilmasa,
bashoratlar har safar boshqacha chiqadi - chunki har chaqiruvda
boshqa neyronlar o'chiriladi.
Model buzilgandek tuyuladi, aslida esa faqat bitta qator yetishmaydi.
2. Weight decay #
Weight decay og'irliklarni nolga tortadi - katta og'irliklar uchun jarima qo'yadi. PyTorch da bu optimizatorning bitta parametri:
opt = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=0.01)
3. Erta to'xtatish #
Eng oddiy va eng samarali usul: validatsiya yaxshilanmay qolganda to'xtash va eng yaxshi modelni tiklash.
eng_yaxshi, eng_davr, sabr, kutildi = float('inf'), 0, 10, 0
for davr in range(1, 201):
model.train()
for xb, yb in oquv_dl:
opt.zero_grad()
kriteriya(model(xb), yb).backward()
opt.step()
vy, va = baholash(model, valid_dl)
if vy < eng_yaxshi:
eng_yaxshi, eng_davr, kutildi = vy, davr, 0
torch.save(model.state_dict(), "eng_yaxshi.pt")
else:
kutildi += 1
if kutildi >= sabr:
print(f"{davr}-davrda to'xtatildi ({sabr} davr yaxshilanish bo'lmadi)")
break
print(f"eng yaxshi davr: {eng_davr}, yo'qotish: {eng_yaxshi:.4f}")
model.load_state_dict(torch.load("eng_yaxshi.pt"))
vy, va = baholash(model, valid_dl)
print(f"tiklangan model: yo'qotish={vy:.4f} aniqlik={va:.2%}")
13-davrda to'xtatildi (10 davr yaxshilanish bo'lmadi)
eng yaxshi davr: 3, yo'qotish: 0.1604
tiklangan model: yo'qotish=0.1604 aniqlik=92.50%
200 davr o'rniga 13 davr ishladi - 15 barobar tez. Aniqlik esa 88.25% dan 92.50% ga ko'tarildi.
Erta to'xtatishning butun mag'zi - eng yaxshi holatni diskka saqlash.
Faqat to'xtab qo'ysangiz, qo'lingizda oxirgi (yomonlashgan) model qoladi.
sabr (patience) odatda 5-20 oralig'ida tanlanadi.
4 va 5. Modelni kichraytirish, ma'lumotni ko'paytirish #
Bularga alohida kod kerak emas: birinchisida yashirin=16, ikkinchisida
n_oquv=600 beriladi.
Hammasini o'lchaymiz #
Beshta usulni bir xil sharoitda 200 davr o'qitib solishtiramiz:
for nom, yasa, wd in [
("Hech nima", lambda: tarmoq(), 0.0),
("Dropout 0.5", lambda: tarmoq(dropout=0.5), 0.0),
("weight_decay 0.01", lambda: tarmoq(), 0.01),
("Dropout + wd", lambda: tarmoq(dropout=0.5), 0.01),
("Kichik model (16)", lambda: tarmoq(yashirin=16), 0.0),
]:
o_dl, v_dl = yuklagich()
t = oqit(yasa(), o_dl, v_dl, 200, wd=wd)
eng = min(t, key=lambda r: r[2])
print(f"{nom:21s} | {eng[2]:23.4f} | {t[-1][2]:6.4f} | {t[-1][3]:6.2%}")
Usul | Eng yaxshi valid. yo'q. | Oxirgi | Aniqlik
----------------------|-------------------------|--------|--------
Hech nima | 0.1604 | 0.7954 | 88.25%
Dropout 0.5 | 0.1990 | 3.0249 | 88.50%
weight_decay 0.01 | 0.1584 | 0.2410 | 89.00%
Dropout + wd | 0.1755 | 0.2442 | 90.75%
Kichik model (16) | 0.2195 | 0.6971 | 88.50%
600 namuna (10x) | 0.1497 | 0.7385 | 94.75%
Bu jadval bir nechta muhim haqiqatni ko'rsatadi.
Ma'lumot g'olib chiqdi. 600 namuna aniqlikni 88.25% dan 94.75% ga ko'tardi - boshqa hech bir usul bunga yaqinlasha olmadi.
Weight decay oxirgi qiymatni tuzatdi. «Hech nima» da yo'qotish 0.7954 gacha o'sdi, weight decay bilan esa 0.2410 da qoldi - deyarli o'smadi.
Dropout yolg'iz o'zi yordam bermadi. Eng yaxshi natijasi (0.1990) hech narsa qilmaslikdan (0.1604) yomonroq, oxirgi qiymati esa 3.0249 gacha ko'tarildi.
Dropout katta, chuqur tarmoqlar uchun mo'ljallangan. Bizdagi masalada atigi 60 ta namuna bor - Dropout ularni yanada shovqinli qiladi.
Bu muhim saboq: regularizatsiya usullari universal emas. Har birini o'z masalangizda o'lchab ko'ring, kitobdagi tavsiyaga ko'r-ko'rona ishonmang. Aynan shuning uchun bu jadval haqiqiy o'lchov natijalaridan tuzilgan.
Tanlash tartibi #
Usullar jadvali #
| Usul | Qanday yoziladi | Qachon |
|---|---|---|
| Ko'proq ma'lumot | To'plamni kengaytirish, augmentatsiya (15-bo'lim) | Imkon bo'lsa - har doim birinchi |
| Erta to'xtatish | Validatsiyani kuzatib, eng yaxshisini saqlash | Deyarli har doim |
| Weight decay | Adam(..., weight_decay=0.01) | Model katta bo'lsa |
| Dropout | nn.Dropout(0.2-0.5) qatlamlar orasiga | Chuqur tarmoqlarda |
| Kichikroq model | Yashirin o'lchamni kamaytirish | Ma'lumot juda kam bo'lsa |
| Batch normalization | nn.BatchNorm1d/2d | Chuqur tarmoqlarda barqarorlik uchun |
Uchta usulni birdan qo'shsangiz, qaysi biri yordam berganini bilmay qolasiz. Har safar bitta narsani o'zgartiring va natijani yozib boring - yuqoridagi jadval aynan shunday tuzilgan.
nn.Dropout(0.5)nitrain()vaeval()rejimlarida sinab, farqni ko'ring.- Tirik qolgan qiymatlar nega 2.0 ga ko'tarilganini tushuntiring.
- Modelga Dropout qo'shib, 200 davr o'qiting va natijani yozing.
weight_decay=0.01qo'shib, oxirgi validatsiya yo'qotishini solishtiring.weight_decayni 0.1 ga oshirib, model kuchsizlanganini kuzating.- Erta to'xtatishni
sabr=10bilan yozing. sabrni 3 va 30 qilib, qaysi davrda to'xtaganini solishtiring.- Eng yaxshi modelni fayldan tiklab, aniqligini o'lchang.
- O'quv namunalarini 600 ga oshirib, barcha usullarni qayta o'lchang.
- Beshta usul natijasini bitta jadvalga yig'ib, o'z xulosangizni yozing.
Xulosa #
- Dropout o'qitishda neyronlarni tasodifiy o'chiradi,
eval()da esa umuman ishlamaydi. - Tirik qolgan qiymatlar
1/(1-p)ga ko'paytiriladi - shuning uchun o'rtacha o'zgarmaydi. - Weight decay katta og'irliklarga jarima qo'yadi:
Adam(..., weight_decay=0.01). - Bizning o'lchovda u yo'qotishning o'sishini to'xtatdi: 0.7954 o'rniga 0.2410.
- Erta to'xtatish eng arzon usul: 15 barobar tez ishladi va aniqlikni 92.5% ga ko'tardi.
- Uning sharti - eng yaxshi holatni diskka saqlash, faqat to'xtash yetarli emas.
- Ko'proq ma'lumot eng kuchli usul bo'lib chiqdi: aniqlik 88.25% dan 94.75% ga.
- Dropout yolg'iz o'zi bu masalada yordam bermadi - kichik to'plamda zarar qildi.
- Regularizatsiya usullari universal emas: har birini o'z masalangizda o'lchang.
- Bir vaqtda bitta o'zgarish kiriting, aks holda nima yordam berganini bilmaysiz.
Keyingi bo'limda rasmlar bilan ishlashga o'tamiz va konvolyutsion tarmoqlar bilan tanishamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.