数学建模社区-数学中国
标题:
随机梯度下降算法SGD(Stochastic gradient descent)
[打印本页]
作者:
2744557306
时间:
2023-11-28 14:57
标题:
随机梯度下降算法SGD(Stochastic gradient descent)
SGD是什么
% t+ J" s* l& E/ k, z5 B5 v+ W0 M
SGD是Stochastic Gradient Descent(随机梯度下降)的缩写,是深度学习中常用的优化算法之一。SGD是一种基于梯度的优化算法,用于更新深度神经网络的参数。它的基本思想是,在每一次迭代中,随机选择一个小批量的样本来计算损失函数的梯度,并用梯度来更新参数。这种随机性使得算法更具鲁棒性,能够避免陷入局部极小值,并且训练速度也会更快。
+ z3 x- _! D% I8 d1 p" k' i7 g1 c
怎么理解梯度?
% a: F# ?. y& p% w) n7 H# y( ]
假设你在爬一座山,山顶是你的目标。你知道自己的位置和海拔高度,但是不知道山顶的具体位置和高度。你可以通过观察周围的地形来判断自己应该往哪个方向前进,并且你可以根据海拔高度的变化来判断自己是否接近山顶。
+ n1 q" j( }8 T5 a2 {$ j7 }% z
+ ^+ S Q* x8 O( G9 T9 t1 K/ x
在这个例子中,你就可以把自己看作是一个模型,而目标就是最小化海拔高度(损失函数)。你可以根据周围的地形(梯度)来判断自己应该往哪个方向前进,这就相当于使用梯度下降法来更新模型的参数(你的位置和海拔高度)。
1 B" Q+ O( _, K& o1 B7 w3 {
- y2 t. N# N& m) G- H: l. Y
每次你前进一步,就相当于模型更新一次参数,然后重新计算海拔高度。如果你发现海拔高度变小了,就说明你走对了方向,可以继续往这个方向前进;如果海拔高度变大了,就说明你走错了方向,需要回到上一个位置重新计算梯度并选择一个新的方向前进。通过不断重复这个过程,最终你会到达山顶,也就是找到了最小化损失函数的参数。
: p/ i6 B/ T2 _' c2 \$ T6 x
R" X8 h/ s: F( {
为什么引入SGD
3 G9 n3 t. F; w1 ^( i0 W2 z
深度神经网络通常有大量的参数需要学习,因此优化算法的效率和精度非常重要。传统的梯度下降算法需要计算全部样本的梯度,非常耗时,并且容易受到噪声的影响。随机梯度下降算法则可以使用一小部分样本来计算梯度,从而大大提高了训练速度和鲁棒性。此外,SGD还可以避免陷入局部极小值,使得训练结果更加准确。
0 Y# w z8 T3 h$ y$ A: U* d
# ?. ^; }7 p/ {1 }! K$ \. W8 K
怎么用SGD
import torch
- D5 b" W3 \3 W
0 B% l: @. C! E( S
from torch import nn
4 X- ?2 l7 o6 i- z7 m7 X& \
6 i3 ^4 a! R$ L9 {) ^+ [
from torch import optim
1 X, }- `: w/ N/ ]" y/ f
8 c. a( `8 m* K( C% h
. _1 G; F4 R: z" Q' D `# D3 p
e( N1 A+ e* Q' m8 \
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
4 Q* |/ a# b9 ?; V( k! R; K
- T/ Y* J+ n0 w% n: l1 t$ j
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)
: g) g$ `+ b/ {6 a; e
* R. Y! a: H y" @
* D$ d9 Y- B- U6 J+ `* V+ }
z# m' x+ v# }4 m" _5 U
model = nn.Linear(2, 1)
8 ^/ T8 t$ D% }5 t% f
0 p6 f3 V$ i! y/ U7 x7 r0 s
$ S( P/ M! D! I
" Q2 C6 u+ W. p8 L% t; M H
def train():
5 ]# o5 K7 R) n# w1 Y! z
# A& \# M( g% ] p
opt = optim.SGD(params=model.parameters(), lr=0.1)
. Z# r# b6 H" o
( J3 k! ]" M* \- @& q4 F' T
for iter in range(20):
; r# h/ ~7 U7 M& x% n% [
3 G) `' H) h3 C; I
# 1) 消除之前的梯度(如果存在)
9 t" ^# ]: D0 ]. j
$ V# Q' M6 `, k1 z1 _
opt.zero_grad()
1 k0 t& i' m% r1 z, q
- J* h" f# N! m! K' I3 T
" d, S& A% ?4 g% b( i# [. R7 y
, M: s+ u/ O. m/ B. z5 F! a% J9 g
# 2) 预测
9 w q( v, o) J6 b( ]
1 C1 Y2 Y# j! q# N, G" H
pred = model(data)
; r' }) `" W' @# i5 L
6 O5 C8 J3 s* {. [+ C% K. Z. P
& O8 T" F7 Q8 F1 n/ G9 O/ g
/ X. q b+ x% p9 `
# 3) 计算损失
8 q2 j8 ~6 d: R# C
) _5 ?3 ]3 q4 f3 z3 D
loss = ((pred - target)**2).sum()
# c: _' q: i& [3 T' D
3 @, g4 W6 a0 z1 j+ W6 L
5 [3 E! \- C# @. k2 Z v
) [8 |5 v- T5 [8 F' _
# 4) 指出那些导致损失的参数(损失回传)
1 e+ I3 I6 ?1 n2 L" C! ]
& K: T" P7 e3 f. q" h6 ]
loss.backward()
" o' g; ], ]1 d J/ e0 U9 X: e
: Z Z& l* @2 r# K* \# {# b" d( }1 u
for name, param in model.named_parameters():
- B5 g; G$ v* L7 T9 t
5 `8 T- L) { m- U p$ k
print(name, param.data, param.grad)
6 \4 G5 c( o, l1 m+ g: C2 c% A
- z8 y5 K" D) }/ c6 T1 l {
# 5) 更新参数
) P/ }) Z6 |5 L$ m- d
, V4 T; M' t- u* N2 H1 `. l: X
opt.step()
( T' t) K0 C3 n+ J- s; ~$ y) J i, S; @
" ?! I/ ]9 y _! f; M/ w9 X
+ X! c6 U- [. V6 m9 _# Y
! V" m( T1 Y# ~% U" X: i$ U
# 6) 打印进程
: S- ~7 n2 E% H/ M' o. m {) p
% Q9 |; t* G! a& _' m6 k1 c
print(loss.data)
3 p+ r# {7 n. }6 Y, E& V- C
1 c7 s- q8 g u& w# ~
: ^+ i/ f6 y2 |8 i0 O. o
+ {1 V h8 \6 c/ a E0 z) X
if __name__ == "__main__":
5 i0 C" M1 k+ U+ M4 Z4 [
" `% v+ r: u. [7 ]+ u4 f& y
train()
3 M! n/ j, W8 J' F+ x) D
+ q" B( ~; r5 q# D+ [
复制代码
param.data是参数的当前值,而param.grad是参数的梯度值。在进行反向传播计算时,每个参数都会被记录其梯度信息,以便在更新参数时使用。通过访问param.data和param.grad,可以查看参数当前的值和梯度信息。值得注意的是,param.grad在每次调用backward()后都会自动清空,因此如果需要保存梯度信息,应该在计算完梯度之后及时将其提取并保存到其他地方。
( H" n) w& E9 Z% \- s. Y
& c2 b; {* b$ G1 n/ x
计算结果:
weight tensor([[0.4456, 0.3017]]) tensor([[-2.4574, -0.7452]])
5 \1 @# P$ ]# Z* }8 Z& V
# ~; @' \ N$ c$ p! |5 p0 Q% C
bias tensor([-0.2108]) tensor([-2.6971])
" l) c' w9 M5 m4 R7 @$ k
$ ~$ L. S% V# v; q
tensor(0.8531)
8 ^' \0 C3 t3 z$ `. h6 Q
4 E# R9 V! s& D! w
weight tensor([[0.6913, 0.3762]]) tensor([[-0.2466, 1.1232]])
& l3 T+ Z; N' j2 E o% j
8 x; [6 d! O5 ~/ l' s$ P6 m
bias tensor([0.0589]) tensor([0.7416])
3 N! e3 z2 J" Z% u. T
* k# q0 i9 s# O: l3 g5 N
tensor(0.2712)
9 ]% `+ u# |1 Q/ K3 {4 ^/ q. B
! H- j! Q) r* l/ C, B# j) x
weight tensor([[0.7160, 0.2639]]) tensor([[-0.6692, 0.4266]])
0 N: _/ O) e( X7 h
% p$ b/ R1 ~7 n9 L! b
bias tensor([-0.0152]) tensor([-0.2023])
D c; O& \2 _ x1 F" |
) K, f8 ]* N( _; a, `
tensor(0.1529)
6 b# s! Y+ H8 S9 J% G1 ? @1 z2 e
+ h5 A( o! f5 L- E. D+ C
weight tensor([[0.7829, 0.2212]]) tensor([[-0.4059, 0.4707]])
% }& n* s- m" d' y
* V# }4 q n& C# _2 ?
bias tensor([0.0050]) tensor([0.0566])
) q; I2 H" S6 o
* W8 J$ |7 W* d" v2 L: \& p
tensor(0.0963)
1 x+ D0 ]5 `! @
- y" N$ y; `$ L
weight tensor([[0.8235, 0.1741]]) tensor([[-0.3603, 0.3410]])
" w0 `( i& k$ c1 v8 M
2 ], ?( {4 u9 s0 H
bias tensor([-0.0006]) tensor([-0.0146])
- p& x. \) D5 b' A/ I
: B& V7 h" c, g% H! c& q6 Y' }$ t3 ^
tensor(0.0615)
4 J) {# z8 C6 f* [% ?* q6 p
4 h+ I) O. o n1 h$ j4 ?* g3 V
weight tensor([[0.8595, 0.1400]]) tensor([[-0.2786, 0.2825]])
5 G! X, q1 S ]! l
% Q2 Z- E# S/ T5 N& O
bias tensor([0.0008]) tensor([0.0048])
/ P4 y) d- x$ m* A6 q* P: f$ c
: u! I9 b( W5 w& G: w+ E& i8 r/ S- `
tensor(0.0394)
/ M/ ~2 n6 j- }
+ I" H: N& `' Z, q& d5 l2 V
weight tensor([[0.8874, 0.1118]]) tensor([[-0.2256, 0.2233]])
+ t) d+ C( p) \2 W3 g" k! }0 A* W
o9 K7 Q) R* m8 m* \
bias tensor([0.0003]) tensor([-0.0006])
/ N( g7 C# ~) `& P
& A2 X. H5 Z3 \) E" E/ t6 ~+ u6 Q
tensor(0.0252)
* D; V, n+ K0 d6 s
2 H# H0 P! W! k! v) `( h
weight tensor([[0.9099, 0.0895]]) tensor([[-0.1797, 0.1793]])
; t( D8 s% J- P/ O
6 a& Q! A$ V( C3 q! L7 X5 u
bias tensor([0.0004]) tensor([0.0008])
0 ?( \! }# b, i) q) e1 t4 y
% D) s! E* _* x- n7 i" ^% S- X6 l
tensor(0.0161)
" A ]9 A! E5 g3 f5 E& R$ q/ P* f( C
: i' ]; N$ a3 {- B2 v
weight tensor([[0.9279, 0.0715]]) tensor([[-0.1440, 0.1432]])
. m1 `8 s: \$ @) `2 s
8 v2 H0 b ]) A2 ^
bias tensor([0.0003]) tensor([0.0003])
" t% z4 j. p3 \7 U$ z; _! J. g8 h0 e
- j/ z- w( N$ J. x% j. U2 T
tensor(0.0103)
. V6 s# B! l( I" @- H
( H1 P4 f; v F) p' q+ r- D1 R
weight tensor([[0.9423, 0.0572]]) tensor([[-0.1152, 0.1146]])
+ z ] ?) ~9 B5 k' Z6 ^! x7 F
! ]- l& Y1 @! r$ ]3 R% N0 t2 x; Q
bias tensor([0.0003]) tensor([0.0004])
, ` Q4 f- k+ v% a# @+ s* S
8 i% s+ w' R, J% B, M0 d- I
tensor(0.0066)
4 W9 v: C4 |" a5 U8 `; |. X/ U) w
& j8 L+ f5 a$ K. I
weight tensor([[0.9538, 0.0458]]) tensor([[-0.0922, 0.0917]])
- `! l( h- R: l# ]# q2 J: c# y
) a! E' B) ~6 i2 v8 F% u i
bias tensor([0.0003]) tensor([0.0003])
- z- R; V7 V5 `3 Y7 X1 o
% \; i4 i* c9 `) W h
tensor(0.0042)
5 D$ `* v9 h8 d' r
0 h! O n% h! [( Q2 L, a. C. b
weight tensor([[0.9630, 0.0366]]) tensor([[-0.0738, 0.0733]])
% f- G4 t2 G1 J1 m6 H
' q; K: }4 B2 K( t! ~ D# F
bias tensor([0.0002]) tensor([0.0003])
E. _3 [( y) ^9 A, [$ Q
& A2 J0 c, W( V& O" c; \% x
tensor(0.0027)
1 H) L& A7 K0 _. o5 j) V
) s6 j8 y7 x* E1 _/ _! I
weight tensor([[0.9704, 0.0293]]) tensor([[-0.0590, 0.0586]])
' W D: i) y: I7 ?8 {9 \: A
3 m' B" z9 ~9 r- j8 T
bias tensor([0.0002]) tensor([0.0002])
7 a" [# k; _- ?3 K# w6 F, n
( Z% e6 G% |" n3 j
tensor(0.0017)
K9 U- ^$ `3 U- A& w& ~1 c* S
3 y5 H* B3 N9 t" I, R
weight tensor([[0.9763, 0.0234]]) tensor([[-0.0472, 0.0469]])
! Y [9 j5 b# a0 e3 s3 I
" X3 b5 d* R$ J
bias tensor([0.0002]) tensor([0.0002])
F, H3 g. }4 ?
; c0 `, B0 z y
tensor(0.0011)
: j t* W0 {' F4 t. p5 R/ @# m
8 [* q! L. a, F) ~% P/ F% g
weight tensor([[0.9811, 0.0187]]) tensor([[-0.0378, 0.0375]])
9 T; h- J# L( Z6 |
, f. q5 G, G8 q+ S
bias tensor([0.0001]) tensor([0.0002])
* j; s8 G. h2 i* j" [4 e% x2 u
" m( K: o: a$ x1 s: T
tensor(0.0007)
# d( P5 E* A5 F. d1 C, x0 z
8 E: `# a: H. i% ^ K Z! ~
weight tensor([[0.9848, 0.0150]]) tensor([[-0.0303, 0.0300]])
& M9 S% N/ x8 z* S3 g5 j' @5 q; P# j' b
8 ~' K" U" Z$ L- T$ {- [* U' N
bias tensor([0.0001]) tensor([0.0002])
- {% T" h9 z" X8 G9 ~ \
0 @! h9 E Z& K% }% l' ?
tensor(0.0005)
: M% P- ?% X) e# j" x1 q3 Z
, \$ | D$ Y5 T% @
weight tensor([[0.9879, 0.0120]]) tensor([[-0.0242, 0.0240]])
" t w$ L8 L! b s; k8 x
$ N9 ^, _9 S- X# `3 P { D
bias tensor([0.0001]) tensor([0.0001])
- V8 [- N8 g( e* b. d \
q/ M& }8 ~: G* H
tensor(0.0003)
) d0 J$ Q. O3 R5 e9 S
# E9 [/ w. q+ G, N$ [
weight tensor([[0.9903, 0.0096]]) tensor([[-0.0194, 0.0192]])
9 M: n( A9 a" o* {" h( h
4 F# v$ _' d: o8 B+ _: [1 ~/ F
bias tensor([9.7973e-05]) tensor([0.0001])
- X2 W5 t+ Y$ {9 {" K2 k, Y6 @
6 U0 `) I: M4 }7 i, k6 J1 C
tensor(0.0002)
1 v8 V' `, S9 ^2 g6 t( Z. R d( R
+ I% u4 L5 R: R: P) s; Y) M0 v2 ]1 ^
weight tensor([[0.9922, 0.0076]]) tensor([[-0.0155, 0.0153]])
0 I7 k) |8 v+ b
7 s. d; ]: O: L1 n+ Z# p( D1 M
bias tensor([8.5674e-05]) tensor([0.0001])
* U1 Y3 S5 e; p; D# ^7 a
/ C/ v" m0 d& O4 j% Y
tensor(0.0001)
* E7 p$ I, e: A( v: l
+ N$ V- W! w# M) T6 n- ?9 v
weight tensor([[0.9938, 0.0061]]) tensor([[-0.0124, 0.0123]])
" B. B. O& }6 c& h! J/ U( o3 |, C
& r9 t7 R9 Y6 Q, ?4 L7 {+ Q" \6 N
bias tensor([7.4933e-05]) tensor([9.4233e-05])
) Y3 m; {5 h+ v" t
9 l- _5 u. n. b5 o. Y! k0 i4 `
tensor(7.6120e-05)
复制代码
9 X2 q) A5 N/ S' ~
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5