opt = optim.SGD(params=model.parameters(), lr=0.1)6 m) V) p h& n8 \: B
$ C w# O2 f; B
for iter in range(20): E. e* V! s; G" [, c) Q2 N" K
% V* {% K3 o/ J' N
# 1) 消除之前的梯度(如果存在) 6 j! _4 n/ d. g3 \
0 F: {' a, K9 l
opt.zero_grad() ! E- i! x! p0 ~: s# e) J
) F5 e; t) ]% e. B5 V, [
2 G6 T; W4 ^" m8 D4 k9 L
3 K- o+ F/ n' p$ Y+ Y* v
# 2) 预测8 _! T. |+ r2 {6 T
- }& H* |; x9 E) k% }
pred = model(data) {4 ^5 D6 c' k: V/ L) p4 {3 @
+ f1 F; P+ Y3 ^# ~7 n4 l; `
. M5 b+ M4 R, ?: C, t, u
/ R* D7 S4 [) e
# 3) 计算损失 . k- N- y6 O7 M# U( i* A
" W. S2 n$ h7 C2 Y" \; M
loss = ((pred - target)**2).sum() ' O( p* {' S- y
6 U1 ]3 e7 O7 ]7 `, B! b
# ]7 K7 z3 Y m0 h9 _9 e
6 d Y" y @( Z! ?
# 4) 指出那些导致损失的参数(损失回传)$ i* w: U6 i8 u& k: z5 F! u
( K# n9 f# x0 N# y R" \/ S
loss.backward() ) x$ }7 k+ L, f& ]) Y
- y) Z" ~& v6 {" F9 F0 S9 C1 G3 d3 I6 J
for name, param in model.named_parameters():3 `* y. O, i- ~# R) W
2 Y: J( H' e. Q7 C, M1 `
print(name, param.data, param.grad) 5 x6 e/ P: w. E1 x" C7 _6 E
( k( r9 K! [2 V$ J# j4 F- o
# 5) 更新参数 6 p$ Z$ T5 c4 i- t; ~, F% `. i1 Y) H
) a" k% v- k' B1 ]
opt.step()% W [! l0 k- l! A
J* b* H; K" c
: ^5 p1 d, X/ ]3 q. `
' [7 F' k; M# R' i9 |+ m
# 6) 打印进程 ( E* T" n9 k) x5 V5 T/ ]. t
& b3 B% `, T& z) y
print(loss.data) z4 q' x% }. G* L! M% E7 ~
& o, V2 r& e- K: \! E
, Z. [3 z: ^$ [6 z, L
7 c" V- [% H2 _! r- f+ t) k
if __name__ == "__main__":+ y; R& E7 N% p1 `8 ^
* e8 U; E( I' ^$ `$ t, B
train() 8 c; _+ i2 {; }4 ~8 b+ D7 L* W
% v% |' y2 k( A9 f4 p. N6 j
复制代码
param.data是参数的当前值,而param.grad是参数的梯度值。在进行反向传播计算时,每个参数都会被记录其梯度信息,以便在更新参数时使用。通过访问param.data和param.grad,可以查看参数当前的值和梯度信息。值得注意的是,param.grad在每次调用backward()后都会自动清空,因此如果需要保存梯度信息,应该在计算完梯度之后及时将其提取并保存到其他地方。1 e E" v1 d! P4 }4 N% o: y
& q& o+ V. v5 M- B% m
计算结果:
weight tensor([[0.4456, 0.3017]]) tensor([[-2.4574, -0.7452]]). j" D; Z: j- o+ A5 p0 q, T, A