数学建模社区-数学中国

标题: 人工神经网络——反向传播算法初体验(python实现) [打印本页]

作者: 杨利霞    时间: 2022-9-12 18:40
标题: 人工神经网络——反向传播算法初体验(python实现)
人工神经网络——反向传播算法初体验(python实现): ]/ w3 p+ f3 r1 {# t4 m
% c% t! B7 N% M5 G
背景6 Z) q4 P; B3 L/ y
初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下$ \8 K" `* T+ G* |4 P
& E, w! j* O; B+ H# N. [
【神经网络分类算法原理详解】; ^  [- u2 {; M* _

( I/ F0 @$ R$ J7 q5 q注意4 v# ]' W3 c% a; _9 P+ y
站长提供的图片有点小问题,我们更正如下( i( x3 g+ G; U/ W- ]
1 u  r  Z# V" }, K9 F

) u0 A# e( T) e/ W; C8 f; i2 g, ?- b; a/ h4 Z# _1 a
问题
; G. a/ X! `/ z/ V根据上图所示,我们有已知
7 M+ S' u) S" J9 c% d$ [( S$ z
#输入层
6 Y6 G6 f" [3 }i1=0.05
7 c( ]' b# U% {9 x4 P+ k# xi2=0.15 V- O  X: F$ b3 R1 w0 M

1 k7 y% _5 t' I& E9 G+ e$ a9 |& |#输出层, a' p3 W$ _4 W* D! X6 k6 Z
o1=0.010 ~. v0 R- j2 N' p6 ~  P
o2=0.99( q7 D* _4 G/ }- m' M
这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
! ~* d, Z2 E" Y, W' r$ A
* a3 y4 `8 x$ E神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1
% K+ J$ \; ^! h
9 E7 z+ m, U  \0 B- |: p  x. c神经元h2的输入  (hi2)=w3*i1+w4*i2+b12 G$ K* U& v9 M! p; D! s" N2 l3 s
$ t3 @/ W9 o2 w2 S4 P7 t
神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
- J7 s( y6 ?4 T! _2 B2 a0 ]. S; O# N7 i
神经元h1的输出  (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入)); b; W5 B% f. a/ W" k6 L0 ~& h* U

+ Y6 H! G4 i+ R9 {同理
: I1 b2 M* g7 P3 q, y9 d6 r
; q% `* w% @* B6 G神经元h2的输出  (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
, V4 a, P! }/ z" {" x6 e( m% D9 j
接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
: E& |  J3 c2 g" F% x8 n5 ]' }" R2 P- t6 W' `( s, m
神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
' s! h" s! Y4 q
( D3 v: M( {; s- @, Z神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b28 I- z% }3 |% f1 c; g
7 C1 K. i' k! n
再经过非线性变换Sigmoid函数得到1 H& V- U% J1 {6 S5 b2 Z" M

2 b8 H. v1 m& a" e神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))9 r3 s$ G2 x$ Q# U
9 P2 u( }' m0 f+ J2 S# ]- h6 e. g
神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2)): }6 K" ^' J7 E! c3 j5 N9 X! }

+ P- p$ Q% V2 J* g: s' T我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为9 U( D1 M, Y- h$ y, X3 k

3 P( W" c# o$ @2 A4 d9 x9 Y) U/ U损失值  ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/29 V( v" r3 l# T% d6 c& B

7 p1 f* S* d7 ?) L/ s& L3 ?& G由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足' b+ F/ K$ z5 |$ z- S1 D  w4 t
' c8 R  Z) E0 i; A5 Z4 a
学习次数 (learning_time 简写为 lt)我们限定最大为10000次
/ f, j% o# r" C' [
' r) A3 ?% t2 t学习率 (learning_rate 简写为 lr)我们设定为0.5+ F% _& o7 {/ U4 y% h" Q3 t# H. W

0 R( S7 x  b7 M- s3 }依次求解代求参数! \- C! i  x2 K! ]) ^; ~! N
7 N9 y6 Q) \$ W1 T( w
w1~w8,以及b1,b2
0 x; t8 R) r( x) _  s3 p; r" }
. l7 y- u; n% b* f1 W  u; y; y  S: y# L
$ a7 _( C$ B2 `3 J& Y
损失值 (eo) 的偏导数. c7 n5 `9 m. _/ o

3 R( T" R- g  ?% D* y+ N1 \再更新该参数,更新公式为! Z1 r9 t+ O0 O: G* z; w
1 P1 D6 g, a- b  G& {  {' S# n
参数_new=参数-学习率*偏导(eo,参数)
* w. c3 X; H- b& V4 G随后进入下一轮学习/ G# t( f. T2 M. A# p$ `
" J& k( N# X+ `$ y
终止条件(满足其中一个即可停止训练)
: W1 y2 }4 h) V
1 S1 _  B+ o( Z; w& B! Y, n1.学习次数达到上限: Q5 G! W1 A$ P% q& A, s* C
  b4 O; a6 P; F' U5 Y7 W6 p
2.损失值达到可容忍的范围* }8 {6 q* p, h! r  P% z/ |5 N
0 g. Z$ ?3 z/ _- X9 v& v1 v: q9 z
导数* r" S8 w" w3 U6 t! K8 i; M
f(x)=1/(1+e^(-x))的导数是+ f+ ~/ ]# j3 K, u/ K, v
f'(x)=f(x)*(1-f(x))
3 r' Q6 {$ \% p5 a2 F3 k3 u源码
9 C6 q" ~7 n8 a/ Simport math$ O1 |9 o/ w" R( p/ l+ `/ G8 Z
6 y$ ?; \7 e$ a& \: Y) D
#参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】
1 c; y& S0 _. o7 O- t, ?#网址中图片有误,请看我博文上的图片
1 X) }) e3 W2 [, m
& J( S' k9 q- q4 E: p#输入层
& R2 o- A' b6 O' ]1 |+ Z& li1=0.05
+ I1 q* H2 f8 [6 Ii2=0.10 E$ S" R! e0 [% \& e* @. m+ ?
#权值参数
" d% b2 y4 W2 E* a# M. i. ]: aw1=0.15# W" U9 `7 C* ~- P
w2=0.2+ C* Y. ~# [: ~( y
w3=0.25( [& K; t" T" X, i
w4=0.3% t7 P9 n7 X2 h+ P
w5=0.46 \4 n2 u# ^$ |$ p( E, a/ r2 V
w6=0.45
" ^: j7 D/ C- D, c) J4 J' {& l% B7 kw7=0.50 Q3 E. ^! z: G( b. L7 x$ S
w8=0.557 d% p' E$ \6 j9 J5 q5 a' T  O/ }
#输出层标记(即期望值)6 @  e& P. J4 }# N: X3 a
o1=0.01/ Z' D7 E1 }9 }5 N: N* v, o
o2=0.99  b1 e5 t" ^% g6 v; l
#偏置项参数6 w" X4 Y1 |3 T7 c7 h
b1=0.35
' Y5 a3 b9 }. i4 |8 M9 `b2=0.62 H9 P. |3 L1 ]; h% Z& _
$ u  d3 h' D" r
#学习率
/ X  `  L6 Z6 {/ W& t, [3 Glr=0.5
# @6 d9 ?4 [9 {3 s# [; H#学习周期
7 D  P; T# |+ C7 E1 }, q1 P6 d5 e# qlt=0: d& x, t9 P  h  b  a
max_lt=10000
" u3 M5 U# k  R. W/ b* X#允许误差2 `8 c0 \' j! p: f7 a' ^( Q
eo_allow=1e-5
; V! G; S) O8 {0 A# L2 W- N
- u+ l2 U$ ^$ c. |7 `# y#线性转换
; J9 d3 L! t7 }9 W+ idef linear(w_one,w_two,i_one,i_two,b):
+ w9 Q& {6 z9 P- C2 B# x% j    return w_one*i_one+w_two*i_two+b* j# ~4 C% e1 m. k2 O
#非线性转换; s# P9 d0 m. P& T6 ~$ [' u
def none_linear(i):! i5 B, z8 c6 u9 _  B$ [
    return 1.0/(1+math.exp(-i))6 m, c* j) ?+ y7 m
% h2 V1 ^/ _* c- Z
print("训练开始")# D; Q9 F& Z4 k. S- H
#学习周期结束前一直学习9 k, o; b1 i. Q. e
while lt<max_lt:+ M4 R; Z% t  V: W$ `  h$ N  @0 o5 j9 F
    lt+=1) h5 Z2 t5 T$ }9 p
    #求h1和h2输入值
, Q  l  v5 }  j% m    hi1=linear(w1,w2,i1,i2,b1)
7 C! F+ \+ a  d  |) B    hi2=linear(w3,w4,i1,i2,b1)5 H& U" P; ?: f  h4 |
    #求h1和h2输出值- B1 ], D/ X. m3 v  C
    ho1=none_linear(hi1)
' S- x( c- c8 d$ c1 p8 f# O    ho2=none_linear(hi2)
% u2 o: V$ z5 m4 q9 F    #求o1和o2输入值
9 x2 j, y; D5 y9 B    oi1=linear(w5,w6,ho1,ho2,b2)
* w: T& b0 {( ]9 u8 X' B: R. r    oi2=linear(w7,w8,ho1,ho2,b2)
( Y6 {4 K9 t5 v  T  w5 A    #求o1和o2输出值% m7 ^; y0 ^; f9 q" V- O
    oo1=none_linear(oi1)# r: @3 A0 T0 B4 y' L
    oo2=none_linear(oi2), u! a3 D/ S; z  k. J  h1 o2 d
8 b- C& J6 \+ S* s) l; T
    #求当前计算总误差
4 N+ K5 {( e. T! b; y2 N5 u1 e    eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2
" x$ m9 S3 r" |6 v9 `  V    print(f"第{lt}次训练,当前计算总误差={eo}")+ n$ I: W( _+ A  n* E0 z% g! q
    #误差已经在允许范围,退出训练* {5 y& |1 @7 y. p; i3 G
    if eo<eo_allow:
* f: k% b) C, s/ ?. f        print("误差已经在允许范围,训练结束\n")# c% Z! T3 C. m! X/ H% W+ Q+ A
        break: t" w8 f- h8 g
    #偏导
7 Z- q0 ]. c6 X* W! r    d_eo_oo1=oo1-o1* A8 W9 |, u( p" x* |4 M
    d_eo_oo2=oo2-o2% ~3 V) Y# W: U3 Q5 v( }3 I' g
    d_oo1_oi1=oo1*(1-oo1)6 S# g! Y& z: X/ B( V" E% U
    d_oo2_oi2=oo2*(1-oo2)- u- E& n# R4 I' a0 r- {6 F
    d_eo_oi1=d_eo_oo1*d_oo1_oi1
1 B. p5 Y- v' X9 F9 [' T    d_eo_oi2=d_eo_oo2*d_oo2_oi2% j4 E, ^* L3 Z
    #求w5_new
/ |: m5 _5 w5 k9 j& I+ N  Q/ g    d_oi1_w5=ho1% A' R" C+ @2 d1 r2 U! {0 b
    d_eo_w5=d_eo_oi1*d_oi1_w5, K* K! m* t( E
    w5_new=w5-lr*d_eo_w5& z* x/ g) V0 Z. d5 A: W4 T
    #求w6_new
* Y* Z4 N. Q- ?$ G2 r; e4 c    d_oi1_w6=ho2
" [! T3 H7 A1 `+ q4 b+ f+ o' k. Y    d_eo_w6=d_eo_oi1*d_oi1_w6! x* o& H' x+ N! a! F6 b: B
    w6_new=w6-lr*d_eo_w6# v. S# ?8 l& h2 U* [' a7 L, g! R' G
    #求w7_new# o1 v; {! z  U7 Y" ]& ~
    d_oi2_w7=ho1" b& W/ n: j3 T" a, p
    d_eo_w7=d_eo_oi2*d_oi2_w7
) |. Z" w6 N* u: Z8 w    w7_new=w7-lr*d_eo_w7
" y# H* v: ~, {. j( O( [    #求w8_new
5 m% L7 Y$ x7 X4 K, C; V9 l/ {    d_oi2_w8=ho2
$ D) o9 d: ]; S" n/ P% s    d_eo_w8=d_eo_oi2*d_oi2_w8$ A$ W$ |; ?& T
    w8_new=w8-lr*d_eo_w8
$ t! y( ]& F+ U/ ~& ^2 f    #求b2_new" x; B  s  X" p8 G; k
    d_oi1_b2=1
& x2 D- i3 r, @7 E5 R    d_oi2_b2=1
5 W5 A' q/ b2 |: R8 B    d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
; o  c/ x* ?' O6 I4 P4 Y5 Y" B  [    b2_new=b2-lr*d_eo_b29 l+ h& g, i4 n. L' u
    d_oi1_ho1=w5
( q+ N8 x; f  d7 V; H' e    d_oi1_ho2=w6$ {) f: Z  a9 b5 M! N/ F! q
    d_oi2_ho1=w7
7 X: t: I# ]" K: h3 y  m( h    d_oi2_ho2=w80 M' ?$ C) h; Z, p; c% A
    d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
7 ~2 D2 F0 D1 B2 S    d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
% F9 `9 q5 J& l  Z% R0 C% D    d_ho1_hi1=ho1*(1-ho1)8 _: b$ g( m3 K5 S/ k
    d_ho2_hi2=ho2*(1-ho2): d& R! \6 s  i7 F* H% `
    d_eo_hi1=d_eo_ho1*d_ho1_hi17 m1 \/ R( M0 ~4 W) A4 m/ Y/ p, b
    d_eo_hi2=d_eo_ho2*d_ho2_hi28 z3 b) s- q+ T7 v+ Z
    #求w1_new
, |4 v3 J' f4 G3 X; {0 g    d_hi1_w1=i1) T6 R  R+ {1 S' l! ?
    d_eo_w1=d_eo_hi1*d_hi1_w12 H' [. ~% r9 x9 F* |: ]. a
    w1_new=w1-lr*d_eo_w1
6 @2 U; \% ^$ ]- t4 E8 J    #求w2_new
( i$ X: n: |0 ]" K    d_hi1_w2=i2) l/ Z" r. [6 U4 o  H( V
    d_eo_w2=d_eo_hi1*d_hi1_w2! q9 D7 p/ K1 [
    w2_new=w2-lr*d_eo_w2
% b8 T. T( v8 J. j5 W    #求w3_new( p+ Q! x% H$ c- U) u1 O: x/ w
    d_hi2_w3=i1
0 ?7 o, [0 I$ e5 w  P2 o$ u    d_eo_w3=d_eo_hi2*d_hi2_w3
) z2 E9 x$ }8 Q. ]! b) z2 J    w3_new=w3-lr*d_eo_w3% P* S0 R& |# L" w9 g4 x8 V3 i4 j
    #求w4_new
7 w. a5 E8 L2 U# e    d_hi2_w4=i28 d# D  m' j3 y6 d- m
    d_eo_w4=d_eo_hi2*d_hi2_w45 _: E/ Q! ]9 R) o% Z, F% D
    w4_new=w4-lr*d_eo_w4, L7 \6 B3 {4 l- C( ~! L" d
    #求b1_new  Z; A2 G, |& Q' [2 m- d
    d_hi1_b1=1' r! Y8 ?5 j4 t; v& m2 U
    d_hi2_b1=1
# v% u& N5 ~. U3 @" P2 o1 D2 }    d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
& T5 U0 a) D6 ~5 H: P6 c    b1_new=b1-lr*d_eo_b14 K1 c3 n+ j$ @* V
    #更新反向传播- Z0 H% W6 e' K. o# ^8 P# p
    w1=w1_new2 t# c8 n/ K9 X2 D" ?7 B
    w2=w2_new. d4 e  L8 Z7 n) n
    w3=w3_new; i  f2 K$ F6 {& I+ D2 t1 z
    w4=w4_new
' @, {7 y6 g$ E! A    b1=b1_new
, P' z- o. U+ ~    w5=w5_new
, n% G) Q4 K. H    w6=w6_new
" e, e! T$ t: l5 R1 e' b    w7=w7_new
- D$ ?* {5 J  i7 K3 C* C, @    w8=w8_new! h& T8 h. h+ M% ^! K
    b2=b2_new
, M0 @3 r4 M2 d4 j1 Hprint(f"当前计算总误差={eo}")4 c* W% E" i/ w
print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
9 q9 k9 r- {& r7 Bprint(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")( u# r+ ^2 q) f5 }
print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
7 U+ n- h5 [3 ^1 l  ~% n
, v* K# c. c  I结果6 f; q; i1 p. j) Z& w! [* Y

5 N- r  |# N5 V" V9 o6 [# i9 u3 v
结语
! E9 S, v: V: ]' ]% F可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。
) x; i8 u# A( A2 x0 Q5 M- z8 ~) g: p3 }; k8 g& g, ?- u3 A& l% V
补充: y/ o$ u1 Q; }" _
程序中d_{a}_{b}格式的变量表示a对b偏导; i3 I7 _) Q# z" N
————————————————/ E' |( T2 x; b3 x' p+ R
版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
) r& o( v# D; Q% Z  m, L$ N7 ~' h原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
: j1 d) `1 ?7 y4 n6 h+ Q
' f6 X: V1 B* @- c' f
9 q& J/ {2 D& ~% V' b% k




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5