Гузариш ба мундариҷа
Мавзӯи 3 аз 6

Ҳосилаҳои худкор

Ҳосилаҳо ба шабака барои чӣ лозиманд

Омӯзиш параметрҳоро тавре интихоб мекунад, ки функсияи хато (loss) кам шавад. Ҳамаи қиматҳои имконпазири ҳатто чанд ҳазор параметрро санҷидан ғайриимкон аст. Роҳнамо лозим аст: агар параметри муайян каме зиёд шавад, хато чӣ гуна тағйир меёбад? Ҳосила ба ин савол ҷавоб медиҳад.

Барои як адад ҳосила нишебии график дар нуқтаи интихобшуда аст. Барои чанд параметр маҷмӯи ҳосилаҳо градиент (gradient) ном дорад. PyTorch онро бо autograd худкор ҳисоб мекунад: мо хатогиро бо амалҳои одии тензорӣ тавсиф мекунем ва китобхона вобастагиҳоро пайгирӣ мекунад.

1. Фаъол кардани пайгирӣ

requires_grad=True нишон медиҳад, ки ҳосилаҳо нисбат ба ин тензор лозиманд. Чунин тензор бояд навъи касрӣ ё комплексӣ дошта бошад; дар курс ададҳои касриро истифода мебарем. Пеш аз гузариши баръакс .grad ба None баробар аст. backward() ҳосилаҳои натиҷаро нисбат ба тензорҳои ибтидоӣ ҳисоб мекунад.

import torch
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 1
print(x.grad)
y.backward()
print(y.item(), x.grad.item())

Натиҷа:

None
5.0 4.0

Ҳангоми x = 2 қимати x² + 1 ба 5 ва нишебӣ 2x = 4 мешавад. Инҳо бузургиҳои гуногунанд: y.item() қимати функсия ва x.grad.item() ҳассосияти натиҷа ба тағйири вуруд аст. Ҳосилаи мусбат маънои онро дорад, ки каме афзудани x натиҷаро зиёд мекунад.

2. Граф ва қоидаи занҷирӣ

Графи ҳисоб амалҳо ва робитаҳои байни онҳоро сабт мекунад. Ҳар гиреҳ медонад, ки натиҷа аз кадом вурудҳо ҳосил шуд. Агар аввал x-ро ба 3 зарб занем ва баъд натиҷаро квадрат кунем, ҳассосиятҳо зарб мешаванд: 2u · 3.

import torch
x = torch.tensor(2.0, requires_grad=True)
u = 3 * x
y = u ** 2
y.backward()
print(u.item(), y.item(), x.grad.item())
print(u.is_leaf, x.is_leaf)

Натиҷа:

6.0 36.0 36.0
False True

Ҳангоми u = 6 ҳосилаи квадрат нисбат ба u ба 12 ва ҳосилаи u нисбат ба x ба 3 баробар аст: натиҷа 36 мешавад. backward() графро ба ақиб гузашта, агар чанд роҳ ба як параметр расанд, саҳмҳоро ҷамъ мекунад. Мисли смета: тағйири як нарх ба ҷамъ тавассути ҳамаи мавқеъҳои истифодабарандаи он нарх таъсир мекунад.

Тензори ибтидоии x барги граф (leaf) аст (is_leaf=True), вале u-и мобайнӣ нест. Бо танзимоти пешфарз .grad дар баргҳое нигоҳ дошта мешавад, ки ҳосила талаб мекунанд.

3. Чаро пеш аз backward коҳишдиҳӣ лозим аст

Барои даъвати backward() бе аргумент натиҷаи ҳисоб бояд як адад дошта бошад. Агар якчанд хато бошад, аввал интихоб кунед, ки чиро беҳтар мекунед: ҷамъ ё миёнаро. Онҳо градиентҳои гуногун медиҳанд.

import torch
x = torch.tensor([1.0, 3.0], requires_grad=True)
(x ** 2).sum().backward()
print(x.grad.tolist())
x.grad.zero_()
(x ** 2).mean().backward()
print(x.grad.tolist())

Натиҷа:

[2.0, 6.0]
[1.0, 3.0]

Барои ҷамъи квадратҳо ҳосилаҳо 2x мебошанд. Дар миёна ҳар саҳм боз ба шумораи унсурҳо, дар ин ҷо ба ду, тақсим мешавад. Барои вурудҳои мустақил ҷамъ ҳосилаҳоро дар як гузариш мегирад. Хатои миёна барои омӯзиш қулай аст: такрори намунаҳои якхела градиентро дучанд намекунад.

4. Градиентҳо ҷамъ мешаванд

Ҳар гузариши баръакс натиҷаро ба .grad илова мекунад. Ин ҷамъкунии қасдонаи градиентҳои чанд бастаро имкон медиҳад, вале дар омӯзиши одӣ қиматҳои пешинаро тоза кардан лозим аст. Дар мисол ҳар дафъа ифодаи нав сохта мешавад, пас истифодаи дубораи графи кӯҳна мушкил нест.

import torch
x = torch.tensor(2.0, requires_grad=True)
(x ** 2).backward()
print(x.grad.item())
(x ** 2).backward()
print(x.grad.item())
x.grad.zero_()
print(x.grad.item())

Натиҷа:

4.0
8.0
0.0

.zero_() тензорро дар ҷояш тағйир медиҳад. Пеш аз backward()-и аввал градиент метавонад None бошад, бинобар ин ҳанӯз чизе барои тоза кардан нест.

5. Қадам ба муқобили градиент

Градиент самти афзоиши хатогиро нишон медиҳад. Барои камкунӣ параметрро ба самти муқобил мекӯчонанд. Суръати омӯзиш (learning rate, lr) андозаи қадамро муайян мекунад. Як қадам барои квадрати ададро мебинем: параметри мусбат бояд ба сифр наздик шавад.

import torch
w = torch.tensor(4.0, requires_grad=True)
loss = w ** 2
loss.backward()
print(loss.item(), w.grad.item())
with torch.no_grad():
    w -= 0.1 * w.grad
print(round(w.item(), 2), round((w ** 2).item(), 2))
with torch.no_grad():
    result = w * 3
print(w.requires_grad, result.requires_grad)

Натиҷа:

16.0 8.0
3.2 10.24
True False

Хато аз 16 то 10.24 кам шуд. torch.no_grad() сабти амалҳои навро хомӯш карда, requires_grad-и параметрро нигоҳ медорад. Пеш аз қадами нав градиентро тоза ва графи нави хатогиро созед.

lr-и калон метавонад хатогиро зиёд кунад, хурд бошад қадамҳои зиёд талаб мекунад. Барои регрессия аксар вақт MSE, миёнаи квадратҳои фарқи пешгӯиҳо аз ҳадафҳо, истифода мешавад.

Хатоҳои маъмул ва ислоҳи онҳо

  1. Адади бутун бо requires_grad. torch.tensor(2, requires_grad=True) хато медиҳад: ададҳои бутун барои чунин ҳосилагирӣ мувофиқ нестанд. 2.0 нависед ё dtype=torch.float32-ро муайян кунед.

  2. Гузариши баръакс аз вектор бе аргумент. Якчанд натиҷа як хатои умумии ягонаро муайян намекунанд. Коҳишдиҳии мувофиқро интихоб кунед; дар ин намоиш ҷамъ гирифта мешавад:

import torch
x = torch.tensor([1.0, 2.0], requires_grad=True)
try:
    (x ** 2).backward()
except RuntimeError as e:
    print(type(e).__name__)
(x ** 2).sum().backward()
print(x.grad.tolist())

Натиҷа:

RuntimeError
[2.0, 4.0]
  1. Сабти навсозӣ дар граф. Тағйири барг бо w -= ... ҳангоми фаъол будани autograd хатои RuntimeError медиҳад. Параметрро дар дохили torch.no_grad() нав кунед, чунон ки дар мисоли як қадам нишон дода шуд.

  2. Фаромӯш кардани тозакунӣ. Ду ифодаи нав ба ҷойи 4 градиенти 8 доданд. Байни қадамҳо градиенти пешинаро тоза кунед. Тозакунӣ пас аз ҳисоби градиенти нав, вале пеш аз истифодаи он, роҳнамои заруриро нест мекунад.

  3. Backward-и такрорӣ дар графи кӯҳна. Пас аз y.backward() даъвати дубораи y.backward() одатан RuntimeError медиҳад: маълумоти мобайнии захирашуда озод шудааст. Дар омӯзиши одӣ y-ро дар ҳар қадам аз нав ҳисоб кунед. retain_graph=True барои ҳолатҳои махсус аст, на барои ислоҳи давраи одии омӯзиш.

Ёддошт

Зарурати шумо Тарзи иҷро
Сабти вобастагиҳо Тензори касрӣ бо requires_grad=True
Гирифтани ҳосилаҳо Хатои скалярӣ, баъд .backward()
Хондани натиҷа .grad-и параметри ибтидоӣ
Тоза кардани саҳми пешина .grad.zero_() баъди пайдоиши градиент
Навсозии параметр Ба муқобили градиент, дар torch.no_grad()
Оғози қадами нав Гузариши мустақими нав ва графи нав
Муқоисаи sum ва mean Миёна градиентро ба шумораи унсурҳо тақсим мекунад