数学建模社区-数学中国
标题:
人工神经网络——反向传播算法初体验(python实现)
[打印本页]
作者:
杨利霞
时间:
2022-9-12 18:40
标题:
人工神经网络——反向传播算法初体验(python实现)
人工神经网络——反向传播算法初体验(python实现)
7 H3 R+ j& ?0 l# K$ o+ \
q8 u/ W2 K2 @
背景
6 M# U: U) ^' j$ i3 _) x1 p
初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
! f S4 |+ o0 I% h7 M$ ~* f
. E' q: e7 d( @0 q
【神经网络分类算法原理详解】
1 Q/ D6 |7 C) J) n0 n
4 y; ^* U1 B$ r% g+ ]
注意
( E Q8 E+ c0 a" @, u# i" ~
站长提供的图片有点小问题,我们更正如下
+ r, m& X& f2 P) t
& q; J; S# I0 k8 O! y$ X, P% [% P
$ A' n- S5 z( g) u) J* y
+ Q4 [# F* F2 X7 j+ _* m& n, A/ N
问题
) l. R, v+ G* F5 l' P& n
根据上图所示,我们有已知
. Q; P) e" W# A) p5 L* W% V
# A* a7 D* V' p4 N
#输入层
4 y' q& h, D) e! r; ^; |( M
i1=0.05
. p6 G f d' k! t. j# Z7 v
i2=0.1
7 B7 M6 ]1 D' }" @' @
% e# g$ S, B9 C7 [) b: n4 n
#输出层
' [) R1 \5 q' o S1 ]% A
o1=0.01
) [. U3 j1 N. `! l9 F; n
o2=0.99
& ?; \( G2 l6 I. w( g/ B/ t
这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
% v/ j+ g2 |* @: n! g' w- ~, c/ x3 a
# K5 f6 m5 h! c: g0 A: {
神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1
1 d0 R# q& {* W% M4 v
C% b5 N& F) H/ z3 _, v6 `
神经元h2的输入 (hi2)=w3*i1+w4*i2+b1
5 U/ N& V: G. U2 q- [; d" Q* j1 {0 x
5 l( _% q! P# t7 _. w( ^
神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
0 i7 \8 X- z0 F1 T) [% B
, g) b0 X3 Z- p3 c
神经元h1的输出 (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
0 h0 Z, l( R3 W7 m0 M W& e+ } l! o/ m
* L- a* f, w6 b# y D6 N
同理
! `/ D6 R9 O& }# L/ I, P; n4 Z" j- H7 w
- f5 ]0 a) M) @- ~' r/ {
神经元h2的输出 (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
9 g. \" t9 U& r+ P% p+ o4 A: ]7 y, k* a
4 d Y: x. ~$ U2 }' W
接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
1 @& q0 Q' W0 V% O* L' H ~
% n2 h( Q9 i" a2 ~% [* B% L j
神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
; L3 c2 _5 U! Y- Q- A
5 e9 J0 z+ Z% S4 _5 F$ ^, @. |
神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2
& h( j2 Y) b4 A7 L- v8 ]7 {9 {
: V; [% ^& B5 ~, Z
再经过非线性变换Sigmoid函数得到
. p1 W! C. h$ V) Y
1 j$ q% H9 h+ F/ |& f
神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))
) h4 K3 R" T" A/ S, W! b
7 r# I' ~. p$ r) x
神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))
8 J9 m+ V7 r1 K0 S* n
% m+ O6 P8 S& u0 y% `3 u. k5 a/ Q
我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
7 q& \& O( e% b! K6 }5 K( H- b
e0 T1 l, [! E8 X! z9 V$ W; B
损失值 ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
$ S; M# ~/ x Z8 ^
/ ^7 r' U- b2 o# E5 V
由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
I6 t' ~8 g/ Y9 U% M
- } V' `1 x% n. [! L7 Z
学习次数 (learning_time 简写为 lt)我们限定最大为10000次
( b( |/ ?+ n" N; @0 F1 `
1 w0 {, G( P. m \/ j. q& ]9 p
学习率 (learning_rate 简写为 lr)我们设定为0.5
& u' _2 F) D/ P' I% L# D# D9 Q
! o8 `2 q( ?1 W3 Q% i6 z
依次求解代求参数
3 ~9 {( t) D6 c* c) ^
% M' ^% |/ U) N7 m7 P* a; L
w1~w8,以及b1,b2
F6 K7 A% s" L3 l( s
! ?5 A8 S6 g/ F& m) n
跟
/ s8 [: T+ H: ?% [, Y
! p; A) G1 V# X5 R- N
损失值 (eo) 的偏导数
# G/ q+ g9 }- G& ?4 o& E7 T
+ V: ~4 S! S1 E/ |4 g. N3 q
再更新该参数,更新公式为
( I9 R5 d, F2 X: M: g6 l q; J' t
9 a9 u1 @/ _; X; ?1 I" J; W. l5 B
参数_new=参数-学习率*偏导(eo,参数)
& W& I2 _; ]; A$ O/ _- X
随后进入下一轮学习
2 q7 v% J; Q2 i. S, T, B$ ]9 N
3 O# W! g: D3 M f! v% C
终止条件(满足其中一个即可停止训练)
" N5 D# g9 ?7 Y8 C# r
4 o% e i% I9 x8 w4 @( f
1.学习次数达到上限
0 q2 E4 U9 n0 g. y" v E- Q
. l \' H: Z- B6 }
2.损失值达到可容忍的范围
) V4 w H) k( p" p0 \9 X+ x
" p3 y9 s* v* N9 ]; \8 o$ J. T4 s
导数
$ y. Y. [0 w( R
f(x)=1/(1+e^(-x))的导数是
; l; V; r& k( ~5 { k% M2 L
f'(x)=f(x)*(1-f(x))
4 H: Y. E, b+ t) a- \" X
源码
. h4 e9 C1 N9 M7 b
import math
/ @' H0 P! q$ j& E. z: v# k: }
8 A3 M' {9 b( e0 @5 }. h. o+ m* G
#参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】
4 A! `- c- ^. R- N9 F
#网址中图片有误,请看我博文上的图片
9 v2 O) T9 r+ f' J* c& r
% Q6 a0 s0 N$ f* ]
#输入层
" _. Q& I' a( g& p, u* ~
i1=0.05
, |+ I2 `5 r# F! T- d
i2=0.1
7 ^; l( U1 Z: Y9 Y6 U9 T! e9 \
#权值参数
s# D/ H M0 P0 Y
w1=0.15
3 V0 l$ }+ o7 k; W
w2=0.2
% ]; ^- V# t" n1 W* q1 F0 G
w3=0.25
! {; {1 p; C1 ]( k5 q# T/ z
w4=0.3
4 k4 e, n1 e' O5 v6 X4 Z8 P
w5=0.4
# ]' P) G3 i* V& a. s3 M
w6=0.45
+ x- x4 G: p0 p
w7=0.5
& ?0 E) l- P0 |
w8=0.55
3 D, n/ r+ {! g7 w
#输出层标记(即期望值)
& J2 l3 k7 y( Y- S/ S, t% ~
o1=0.01
. f4 l; o: i) w0 g
o2=0.99
$ b( b+ E: e" E
#偏置项参数
7 S0 [5 u2 }) e% F9 [
b1=0.35
+ k! v M! s7 `$ q2 ^) R
b2=0.6
M, r" T1 ~+ ^# E
4 ~# V$ \/ ^- q* w% }
#学习率
! }( Z: @" T+ `# b! m/ D
lr=0.5
! N/ Q6 r2 r5 e. \2 K0 x- L+ B* j
#学习周期
7 ]" w2 F& U5 ~, Y- ~" H2 I
lt=0
2 w2 s' B3 f$ c- d [9 U
max_lt=10000
$ o. X8 f2 X/ }
#允许误差
- c5 x! T- G( ]
eo_allow=1e-5
6 S. s' v9 C& I- H8 x9 T3 l I; G
& i4 o2 t7 K6 A# B
#线性转换
- p5 C/ a7 k1 B# g" Q- b+ G
def linear(w_one,w_two,i_one,i_two,b):
8 F6 ~ N D; H
return w_one*i_one+w_two*i_two+b
7 a0 c# r1 x6 L$ P
#非线性转换
- K; G! L- x$ e- |
def none_linear(i):
3 Q' j& I# P! ?
return 1.0/(1+math.exp(-i))
1 n# h3 u; p5 z! m$ k3 ~/ W
" c+ h1 o2 f5 a/ ?9 U& w
print("训练开始")
3 h z; R3 p8 }* v9 @
#学习周期结束前一直学习
: C2 [7 D) f m2 x T0 C
while lt<max_lt:
8 @& ^) c% ?: \( B
lt+=1
( @$ c# q# Y* x5 i. t
#求h1和h2输入值
& D! L: @" e7 @& J. z! q# _
hi1=linear(w1,w2,i1,i2,b1)
' c. ^: z) E6 T
hi2=linear(w3,w4,i1,i2,b1)
" {1 q+ S! `9 x, x6 J
#求h1和h2输出值
! V& W8 N1 s. o5 i
ho1=none_linear(hi1)
4 f0 D: k, Y# G' s6 ~; N
ho2=none_linear(hi2)
0 @1 V( z% u, H5 @+ E3 Q
#求o1和o2输入值
& Q1 d0 }1 ~- \8 F; a* u Y
oi1=linear(w5,w6,ho1,ho2,b2)
1 }' I4 R. [ f. e- z( G
oi2=linear(w7,w8,ho1,ho2,b2)
7 S3 [" X/ ^* C0 n
#求o1和o2输出值
2 }. d @" r9 c5 @8 A! Q! Q
oo1=none_linear(oi1)
+ R7 r7 }+ |! S( \7 `* i! L
oo2=none_linear(oi2)
" P7 L# w9 a" Z
2 v2 h8 W+ e" l# Z: P; G" z) s
#求当前计算总误差
7 O, O$ M- P! ^* w. V# J; S# ?% x! K* U+ u
eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2
& D! G/ u9 J3 g1 J/ H
print(f"第{lt}次训练,当前计算总误差={eo}")
0 }- F; |4 y4 ^5 s; E. C; G
#误差已经在允许范围,退出训练
& j7 Y- C7 u' Y0 U: r! j/ m6 j' m
if eo<eo_allow:
! ^3 m, }6 Y6 e3 |* P) R
print("误差已经在允许范围,训练结束\n")
. @8 O( I" L ^6 g
break
1 r3 D; ?6 {5 u7 e8 M
#偏导
' a& Y+ d, _. V# Y* n
d_eo_oo1=oo1-o1
3 A# S0 c! M ]+ x' L3 ~+ B
d_eo_oo2=oo2-o2
9 n! V! h6 @" a, h% ^3 |
d_oo1_oi1=oo1*(1-oo1)
6 ]3 S: u2 M6 P' ^7 U0 I, p; L
d_oo2_oi2=oo2*(1-oo2)
; P3 |3 o2 P7 I4 E% j& D* I
d_eo_oi1=d_eo_oo1*d_oo1_oi1
, h7 J3 n/ a z1 h
d_eo_oi2=d_eo_oo2*d_oo2_oi2
" _8 F% D( M/ {- W1 g; P+ ~
#求w5_new
% F0 e' _ {" V* v: r4 A a1 K
d_oi1_w5=ho1
& @8 X- C3 L5 y) {" l
d_eo_w5=d_eo_oi1*d_oi1_w5
1 {1 s' K6 b2 N& n0 G' L
w5_new=w5-lr*d_eo_w5
; \( j" b1 T" V% r a! F- _, Y3 w& _
#求w6_new
+ c& o' D {2 o
d_oi1_w6=ho2
+ Q- H. X2 j3 U; e! M2 N. y9 p V
d_eo_w6=d_eo_oi1*d_oi1_w6
" o- E* J+ h2 ~' M0 ]- l _$ S s
w6_new=w6-lr*d_eo_w6
* Z+ K/ i& `$ f x: b* E8 g
#求w7_new
1 Z9 {3 M9 r5 t4 d
d_oi2_w7=ho1
, S |& L% R i: u b8 S4 _
d_eo_w7=d_eo_oi2*d_oi2_w7
6 M: ^+ j8 ^' u' x; t$ q+ J2 o1 j
w7_new=w7-lr*d_eo_w7
# R( E. W7 n) y1 z" e }
#求w8_new
4 d" ^% U4 V0 X' X
d_oi2_w8=ho2
2 m& v4 M5 q1 E
d_eo_w8=d_eo_oi2*d_oi2_w8
/ s o9 j5 b) u& r
w8_new=w8-lr*d_eo_w8
6 e2 n' i) D! F5 c3 L: Y/ I: Q
#求b2_new
- v1 F! ?3 R( d6 _% l) j& B$ b3 d
d_oi1_b2=1
* P. N- }, E. D' M$ T* p
d_oi2_b2=1
" H8 L' h( z0 K- m# u; c
d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
9 \) ~$ |0 z& M/ r
b2_new=b2-lr*d_eo_b2
$ ^/ h1 W9 w' U# L1 x- O
d_oi1_ho1=w5
" S$ J" C) K* |0 C
d_oi1_ho2=w6
5 }6 V4 u- T! K0 T0 Q$ a! b
d_oi2_ho1=w7
- Z% d2 e8 G8 h4 a S, `
d_oi2_ho2=w8
2 A0 e) R1 h# N: I, D G3 w
d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
' S6 X3 J. Q7 s. g! }& f7 r7 ~
d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
/ I0 _7 B) c' i q
d_ho1_hi1=ho1*(1-ho1)
8 a, N8 M) i7 I5 V5 `% c
d_ho2_hi2=ho2*(1-ho2)
3 \( P! g, D% t" j3 i/ t
d_eo_hi1=d_eo_ho1*d_ho1_hi1
: S5 M! H$ C' {$ a8 a
d_eo_hi2=d_eo_ho2*d_ho2_hi2
) v1 h/ f# W3 z1 u4 C. N% ?
#求w1_new
) A1 k$ {0 c# X( q/ J# p% r& C
d_hi1_w1=i1
, d) |6 X$ j: S) p' e$ _) v
d_eo_w1=d_eo_hi1*d_hi1_w1
& h% `7 I$ P% [$ Z& q! ~% C# X
w1_new=w1-lr*d_eo_w1
7 N3 _5 E! f2 B! X7 v
#求w2_new
: e/ F w. W ^0 _. g
d_hi1_w2=i2
. O0 n8 y! T: F- n
d_eo_w2=d_eo_hi1*d_hi1_w2
! n, m% K+ [0 L$ Q
w2_new=w2-lr*d_eo_w2
, O) b8 p J' D1 D& t( J8 o
#求w3_new
4 k/ V+ W4 b& H
d_hi2_w3=i1
' @, T, ~: o9 D" J% g! t1 }. G
d_eo_w3=d_eo_hi2*d_hi2_w3
, E5 Q" T5 p! Q+ J% }
w3_new=w3-lr*d_eo_w3
2 ~( I. N" E, @0 I
#求w4_new
3 d/ t+ @4 u4 Q0 O
d_hi2_w4=i2
1 t3 e' L/ O) ]' d( R/ p* u: _
d_eo_w4=d_eo_hi2*d_hi2_w4
; d) A7 B A% r* L# m# T) u u
w4_new=w4-lr*d_eo_w4
+ `/ ?% a3 ?3 }3 ~" ^# c
#求b1_new
" @% r8 L# w0 J. L0 u/ }' o
d_hi1_b1=1
( F* p+ J: e' E
d_hi2_b1=1
+ I. R2 H6 P3 C w0 ~8 B' w
d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
0 M, r: M: e2 u( x( E
b1_new=b1-lr*d_eo_b1
) A! d( O( s' K+ x1 B
#更新反向传播
# }( z5 f) u, y A" H' H
w1=w1_new
; e! R; W1 p' P- }
w2=w2_new
" n" `# _3 M7 X9 I% n- Z
w3=w3_new
& Y- t+ e" W# ?+ h: A. k
w4=w4_new
W: c2 `. f# H
b1=b1_new
: q; {' u: }% C& s* |. w
w5=w5_new
) q0 _7 O. G2 z8 D6 E# I$ v1 L1 U
w6=w6_new
# ]& i/ B0 M- \
w7=w7_new
8 @# Y' D X# y) {3 d- s `9 \0 ^
w8=w8_new
9 l: W: L5 C3 j) D3 S! i- J6 b
b2=b2_new
- h0 X7 q& Q9 K2 ]! x2 u
print(f"当前计算总误差={eo}")
! t4 Q" D0 H' x9 j
print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
% J* Q [2 Y3 e- G9 n+ ~ s
print(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")
9 r) ~5 B0 T0 _5 ~$ q
print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
: W% `9 y7 E ~5 j" s- L, k
) L1 n3 Y& j7 ] R% R# z8 Q
结果
8 {( O6 ^2 Q8 u2 L) G
; r. d4 J! m! r/ t. i
$ ?2 e# X o. M
结语
3 e6 G# \0 e* v
可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。
2 x8 R# e5 A5 P5 ?9 N
8 F% D- b7 u2 S8 j( P" N( {. a
补充
$ u% M; p6 c! e/ I; |
程序中d_{a}_{b}格式的变量表示a对b偏导
6 J! E, F+ l. U
————————————————
% |" Z$ ?0 _( j* \) c
版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
+ Z+ N, W A* \ e
原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
8 }) y1 j# h7 f/ V8 J
' y; t: A# e8 a
$ `& G' a0 W/ s$ W3 u# Y
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5