4-bo‘lim

Autograd - avtomatik hosila

requires_grad, backward(), gradientlarning to'planishi, zero_grad() nima uchun kerakligi va no_grad rejimi.

🕑 10 daqiqa o‘qish 📄 608 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Birinchi hosila
  2. Bir nechta o'zgaruvchi
  3. Hisoblash grafi
  4. Gradientlar to'planadi
  5. no_grad - hosila kerak bo'lmaganda
  6. detach()
  7. Xulosa

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 #

Python
import torch

x = torch.tensor(3.0, requires_grad=True)
y = x ** 2
y.backward()

print("y =", y.item(), "| dy/dx =", x.grad.item())
Natija
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.

QismMa'nosi
requires_grad=True«Bu tenzor bo'yicha hosila kerak bo'ladi»
y.backward()Hosilalarni hisoblab, .grad ga yozadi
x.gradNatija - dy/dx

Bir nechta o'zgaruvchi #

Python
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())
Natija
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 #

z = x * y + y² uchun graf oldinga orqaga x y x * y y ** 2 + z z.backward() - zanjir qoidasi bo'yicha orqaga qaytadi
Har amal grafga yoziladi; backward() shu graf bo'ylab teskari yuradi

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:

Python
a = torch.tensor(2.0, requires_grad=True)
b = a * 3
print("grad_fn bor:", b.grad_fn is not None)
Natija
grad_fn bor: True

Gradientlar to'planadi #

Bu PyTorch ning eng ko'p adashtiradigan xatti-harakati:

Python
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())
Natija
  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:

Python
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())
Natija
  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 xato

Haqiqiy 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.

Nega umuman to'planadi?

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:

Python
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)
Natija
grad_fn bor: True
no_grad ichida grad_fn: False
Qachon ishlatiladiNima uchun
Validatsiya va testHosila kerak emas - tezroq va kam xotira
Bashorat (inference)Xuddi shu sabab
Parametrni qo'lda o'zgartirishGraf 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:

Python
qiymat = tenzor.detach().cpu().numpy()

requires_grad=True bo'lgan tenzorni to'g'ridan-to'g'ri .numpy() qilsangiz, xato chiqadi:

Natija
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.

Amaliy topshiriq
  1. y = x ** 3 uchun x = 2 da hosilani PyTorch bilan toping va qo'lda tekshiring.
  2. z = 3*x + 4*y uchun ikkala hosilani hisoblang.
  3. backward() ni ikki marta chaqirib, grad qanday o'zganini kuzating.
  4. zero_() qo'shib, natijani barqarorlashtiring.
  5. requires_grad=False bo'lgan tenzorga backward() qo'llab, xatoni o'qing.
  6. grad_fn ni oddiy va no_grad ichida yaratilgan tenzorlarda solishtiring.
  7. torch.no_grad() ichida bajarilgan amal tezligini oddiysi bilan taqqoslang.
  8. requires_grad=True tenzorni .numpy() qilishga urinib, xato xabarini yozib oling.
  9. detach() bilan uni tuzating.
  10. Gradient to'planishi nima uchun foydali bo'lishi mumkinligini bitta misol bilan yozing.

Xulosa #

  • requires_grad=True tenzor bo'yicha hosila kerakligini bildiradi.
  • backward() grafdagi barcha parametrlar uchun hosilani bitta chaqiruvda hisoblaydi.
  • Natija .grad maydonida saqlanadi.
  • Graf hisoblash paytida quriladi - har natija tenzorida grad_fn bo'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.

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.