4-bo‘lim
Autograd - avtomatik hosila
requires_grad, backward(), gradientlarning to'planishi, zero_grad() nima uchun kerakligi va no_grad rejimi.
Ushbu bo‘lim mundarijasi
Oldingi darslikda siz har bir qatlam uchun hosilani qo'lda chiqardingiz. Bu bo'limda o'sha ishni PyTorch bajaradi - va bu uning asosiy qobiliyati.
Birinchi hosila #
import torch
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2
y.backward()
print("y =", y.item(), "| dy/dx =", x.grad.item())
y = 9.0 | dy/dx = 6.0
Matematika bilan solishtiramiz: y = x² ning hosilasi 2x, x = 3 da
esa 2 · 3 = 6. PyTorch aynan shu javobni berdi - lekin siz hech qanday
formula yozmadingiz.
| Qism | Ma'nosi |
|---|---|
requires_grad=True | «Bu tenzor bo'yicha hosila kerak bo'ladi» |
y.backward() | Hosilalarni hisoblab, .grad ga yozadi |
x.grad | Natija - dy/dx |
Bir nechta o'zgaruvchi #
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(5.0, requires_grad=True)
z = x * y + y ** 2
z.backward()
print("z =", z.item(), "| dz/dx =", x.grad.item(), "| dz/dy =", y.grad.item())
z = 35.0 | dz/dx = 5.0 | dz/dy = 12.0
Tekshiramiz: ∂z/∂x = y = 5, ∂z/∂y = x + 2y = 2 + 10 = 12. Ikkalasi ham
to'g'ri.
Modelda minglab parametr bo'ladi va backward() ularning hammasi uchun
hosilani bitta chaqiruvda hisoblaydi.
Hisoblash grafi #
Graf oldindan emas, hisoblash paytida quriladi - 1-bo'limda aytilgan define-by-run mana shu. Har bir natija tenzori o'zini kim yaratganini eslab qoladi:
a = torch.tensor(2.0, requires_grad=True)
b = a * 3
print("grad_fn bor:", b.grad_fn is not None)
grad_fn bor: True
Gradientlar to'planadi #
Bu PyTorch ning eng ko'p adashtiradigan xatti-harakati:
w = torch.tensor(1.0, requires_grad=True)
for i in range(3):
out = w * 2
out.backward()
print(f" {i+1}-chaqiruvdan keyin w.grad =", w.grad.item())
1-chaqiruvdan keyin w.grad = 2.0
2-chaqiruvdan keyin w.grad = 4.0
3-chaqiruvdan keyin w.grad = 6.0
Hosila har safar 2 bo'lishi kerak edi, lekin u qo'shilib bordi:
2, 4, 6.
Yechim - har qadamdan oldin tozalash:
w = torch.tensor(1.0, requires_grad=True)
for i in range(3):
if w.grad is not None:
w.grad.zero_()
out = w * 2
out.backward()
print(f" {i+1}-chaqiruvdan keyin w.grad =", w.grad.item())
1-chaqiruvdan keyin w.grad = 2.0
2-chaqiruvdan keyin w.grad = 2.0
3-chaqiruvdan keyin w.grad = 2.0
zero_grad() ni unutish - eng ko'p uchraydigan xatoHaqiqiy o'qitish siklida siz w.grad.zero_() emas,
optimizer.zero_grad() yozasiz (6-bo'limda). Lekin mohiyat bir xil.
Uni unutsangiz, quvur yiqilmaydi va xato ham chiqmaydi. Model shunchaki
yomon o'qiydi: gradientlar to'planib, qadamlar tobora kattalashadi,
yo'qotish sakraydi yoki nan ga aylanadi.
Belgisi: birinchi bir-ikki qadamda yo'qotish tushadi, keyin keskin
o'sib ketadi. Shunday bo'lsa - birinchi bo'lib zero_grad() ni
qidiring.
Bu ataylab qilingan. Katta modelni o'qitishda paketni bo'lib-bo'lib hisoblash kerak bo'ladi (gradient accumulation): xotira yetmasa, 64 o'rniga 4 tadan to'rt marta hisoblab, gradientlarni to'plab, keyin bitta qadam qo'yiladi.
To'planish o'chirilgan bo'lsa, bu imkoniyat yo'qolardi.
no_grad - hosila kerak bo'lmaganda #
Modelni sinayotganda hosila kerak emas. Uni hisoblash esa vaqt va xotira oladi:
a = torch.tensor(2.0, requires_grad=True)
b = a * 3
print("grad_fn bor:", b.grad_fn is not None)
with torch.no_grad():
c = a * 3
print("no_grad ichida grad_fn:", c.grad_fn is not None)
grad_fn bor: True
no_grad ichida grad_fn: False
| Qachon ishlatiladi | Nima uchun |
|---|---|
| Validatsiya va test | Hosila kerak emas - tezroq va kam xotira |
| Bashorat (inference) | Xuddi shu sabab |
| Parametrni qo'lda o'zgartirish | Graf buzilmasligi uchun |
Ishlab chiqarishda torch.inference_mode() ham bor - u no_grad dan
biroz tezroq va aynan bashorat uchun mo'ljallangan.
detach() #
Ba'zan tenzorni grafdan uzib olish kerak bo'ladi - masalan, uni jurnalga yozish yoki NumPy ga o'tkazish uchun:
qiymat = tenzor.detach().cpu().numpy()
requires_grad=True bo'lgan tenzorni to'g'ridan-to'g'ri .numpy() qilsangiz,
xato chiqadi:
RuntimeError: Can't call numpy() on Tensor that requires grad.
Use tensor.detach().numpy() instead.
Xato xabarining o'zi yechimni aytib turibdi - PyTorch ning yaxshi tomoni shunda.
y = x ** 3uchunx = 2da hosilani PyTorch bilan toping va qo'lda tekshiring.z = 3*x + 4*yuchun ikkala hosilani hisoblang.backward()ni ikki marta chaqirib,gradqanday o'zganini kuzating.zero_()qo'shib, natijani barqarorlashtiring.requires_grad=Falsebo'lgan tenzorgabackward()qo'llab, xatoni o'qing.grad_fnni oddiy vano_gradichida yaratilgan tenzorlarda solishtiring.torch.no_grad()ichida bajarilgan amal tezligini oddiysi bilan taqqoslang.requires_grad=Truetenzorni.numpy()qilishga urinib, xato xabarini yozib oling.detach()bilan uni tuzating.- Gradient to'planishi nima uchun foydali bo'lishi mumkinligini bitta misol bilan yozing.
Xulosa #
requires_grad=Truetenzor bo'yicha hosila kerakligini bildiradi.backward()grafdagi barcha parametrlar uchun hosilani bitta chaqiruvda hisoblaydi.- Natija
.gradmaydonida saqlanadi. - Graf hisoblash paytida quriladi - har natija tenzorida
grad_fnbo'ladi. - Gradientlar to'planadi:
backward()ni ikki marta chaqirsangiz, qiymat qo'shiladi. - Shuning uchun har qadamdan oldin
zero_grad()chaqiriladi. - Uni unutish quvurni yiqitmaydi - model shunchaki yomon o'qiydi, yo'qotish sakraydi.
- To'planish ataylab qilingan: katta paketni bo'lib hisoblash uchun kerak.
torch.no_grad()validatsiya va bashoratda tezlik hamda xotira tejaydi..detach()tenzorni grafdan uzadi - NumPy ga o'tkazishdan oldin kerak.
Keyingi bo'limda nn.Module yordamida birinchi haqiqiy modelni quramiz.
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.