数学建模社区-数学中国
标题:
人工神经网络——反向传播算法初体验(python实现)
[打印本页]
作者:
杨利霞
时间:
2022-9-12 18:40
标题:
人工神经网络——反向传播算法初体验(python实现)
人工神经网络——反向传播算法初体验(python实现)
( p# l6 q6 d/ B0 s
6 M% b# T. |) I# u. ?4 ]
背景
/ d6 ~/ J& a# H# O& b! s
初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
+ q" Y! d* q5 k+ l
" _3 V' L3 W4 h) H
【神经网络分类算法原理详解】
8 M* M8 n: c8 W9 |! E W1 u
9 j q/ s$ C8 }5 a
注意
3 Q1 I, {4 f7 G
站长提供的图片有点小问题,我们更正如下
3 M+ m* y. m& G* s4 g& s9 h
' Q6 q8 k( G3 D: K l
1 i+ M" i: ^5 ]
5 M9 m! n. v0 h3 M- s) N) h
问题
1 ~, u! H+ t) W$ M: q& o; y
根据上图所示,我们有已知
$ c. a1 b1 I9 j0 h4 O' x- O5 U
4 q% w3 i. S5 ]$ g# N' o
#输入层
. S% a8 b) p4 Q. V, D
i1=0.05
0 h7 q% V3 y0 n1 B/ a7 j
i2=0.1
0 w& a( T, l' N: e
6 r9 @2 |0 q: p! f. O! q
#输出层
4 D5 @ `3 U5 e( \ @
o1=0.01
# K- X) J8 i8 i, }" j: G
o2=0.99
1 i5 z& T6 s$ t: s1 @/ }. F8 ^4 I
这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
3 } [! l6 o- O1 o' a w
6 E. m( W3 F$ p' @7 J
神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1
3 A( a7 P) S5 K9 \$ A% P
, Q. ^+ A. T; a, h7 t
神经元h2的输入 (hi2)=w3*i1+w4*i2+b1
6 @) v% q& @" p; i2 \
n: G- t0 q9 P& u) t$ w! K( z
神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
: w$ a# m8 B$ p$ ]/ c. Y3 V+ ~
$ T1 d: X$ a& }! a: `: X! q5 z
神经元h1的输出 (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
+ d6 `2 }) J8 l
' O `# ^ x% V) I z0 c
同理
, c; c3 Q! v" C1 }( O- e" M$ G) e2 q: k
0 a" u; }8 r7 W, }! d$ w- Y/ C
神经元h2的输出 (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
# S% L; N2 P4 F/ Y; \$ ~1 r( p7 w f
% H/ u1 x; A! ]( M$ P4 x
接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
" Q) U, ~8 ^1 z
- G1 H* H! B& j% R
神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
6 G. f, U: P% D3 k9 X, v# |
! d) x: u5 Q3 j, L
神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2
! D; d- s( m' R; G! p
* M7 E( k4 S. Y- G
再经过非线性变换Sigmoid函数得到
3 ^7 d) v. I4 S- o
$ J- s) Q W/ H E
神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))
* X) o; M$ n0 a& a1 _
+ _+ o6 T/ T. Y% ?- k0 O
神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))
( k. C- a3 u. |
) Q1 w! C' t6 h0 H
我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
' U* I3 H N$ m8 t/ {" U
- r) g7 A; c, m/ k
损失值 ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
2 f' R f& o" D, K# b
7 Q) Q* F5 \6 V* I9 A: e* e
由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
X" ?0 H4 r) j( O8 e
! n7 B* {# b/ } r( E. {3 A( W
学习次数 (learning_time 简写为 lt)我们限定最大为10000次
& J1 C h1 x0 U0 |
, A) A" K9 u; j1 O
学习率 (learning_rate 简写为 lr)我们设定为0.5
, g f8 @. Y A9 ?! K
8 Z. R, p- s9 Y
依次求解代求参数
, x& e# d4 M1 n8 Z7 k' N
& P6 z! Q. p6 W. p+ O- D$ s P1 q
w1~w8,以及b1,b2
C+ ]; J$ y7 P+ p% G" N* H5 b
* b0 m( R/ i& }2 L! \( |: F
跟
! u: ~/ w8 f& h& q0 D) P/ ]; I9 t* x
7 V$ Z/ s. l) B0 Q
损失值 (eo) 的偏导数
4 M! ~0 }6 V( @, \
( C: ~3 v ]" A0 {7 F; x9 |) h) |
再更新该参数,更新公式为
7 o* v* K2 S4 C) f0 N. g2 e
# R1 d8 ]! I- g% f* U7 ]( b
参数_new=参数-学习率*偏导(eo,参数)
, d4 a+ Z% l2 d. g
随后进入下一轮学习
- {! r t- f7 @3 C, p. ^
( K( I! F7 z& Z& w5 Z: i4 e o
终止条件(满足其中一个即可停止训练)
* ~; k4 o7 B F
e4 i3 o- X4 h( y- b
1.学习次数达到上限
3 b; t- e6 w1 y$ `7 @5 R
+ R: ]. `+ j! ^
2.损失值达到可容忍的范围
% ^- Q8 w$ ~5 c$ w) i w/ A/ O
2 F- D0 c/ i& H, {
导数
: S$ V! h$ L3 Z
f(x)=1/(1+e^(-x))的导数是
9 z6 L& I8 N8 q' w+ g% H
f'(x)=f(x)*(1-f(x))
5 X1 x: v) v6 o& H% |
源码
; Q2 c3 d( E3 y/ j( p4 c' v5 u6 N
import math
5 d \3 f- B# f
7 U, a! B% x+ `: Y! ~7 G
#参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】
& W' M1 a/ b4 `1 p
#网址中图片有误,请看我博文上的图片
3 `! ]; M' ?! O0 @! d0 t: z
. U/ e, R: u; j$ S2 j
#输入层
- ^& I! h% R, |3 M% {
i1=0.05
: H! R( [- Q* _ F0 j
i2=0.1
3 t$ |8 S. J3 x1 n$ i0 E1 D
#权值参数
5 F4 ]- S6 Z0 ^+ T
w1=0.15
3 E, Z5 _# d' \4 R
w2=0.2
+ ]& j L- V( H$ Y( Y, }
w3=0.25
; y! d! E) _' I7 @- X
w4=0.3
* f0 O3 Y8 M0 V; @2 _" }0 S
w5=0.4
1 _0 j) l& o8 x5 ^; B- \* T; C
w6=0.45
3 [* Y2 g" E; T& Z: y7 x8 w
w7=0.5
4 T* b( J- D4 N S2 t/ x' w) Q
w8=0.55
J+ O% G& Q2 }: p% u; @
#输出层标记(即期望值)
6 C& i! G5 e& _! `$ i- O
o1=0.01
% t" v$ c0 g+ Q# J
o2=0.99
+ M4 b9 r" g4 f, m; h4 b
#偏置项参数
! L( `6 x. v; ^
b1=0.35
5 D+ P5 F: ^& p* i3 [# T; I- q
b2=0.6
1 Z1 d. s1 q8 u. [5 ]
3 } D8 }5 R5 ~4 P) M3 C% p! v
#学习率
+ Q5 k, p2 L% @; V
lr=0.5
! p4 o1 L. d* D
#学习周期
# Z6 ~; s' h! P$ U0 {
lt=0
/ [; z$ K( M! w
max_lt=10000
& h) r* n9 a r4 U! B- c( i: R
#允许误差
0 v. z5 \3 k# p
eo_allow=1e-5
6 n0 l+ h) ~* i& Z. a* `
) @8 h* _0 q! ^3 t
#线性转换
$ Z* c1 k/ o! \/ X2 M+ B
def linear(w_one,w_two,i_one,i_two,b):
; c1 q; G' S9 t6 ~; o
return w_one*i_one+w_two*i_two+b
9 q# u9 J2 }' t" g
#非线性转换
% ^. Y% f, f! I% }8 h
def none_linear(i):
, N. x. z/ Y( ]* t, N" [5 t$ c, e8 g
return 1.0/(1+math.exp(-i))
8 @6 [& \# D" I0 I- _5 T8 N
: g1 _ k: \. q' x, M! C
print("训练开始")
7 s/ `: q3 J* B1 i; a2 ]0 L
#学习周期结束前一直学习
W# Q* p/ d) o/ Q+ r
while lt<max_lt:
- h; g9 u9 ]# y9 c7 |6 q( X
lt+=1
" S" ?" H' i& d: k* v( O
#求h1和h2输入值
+ r E x$ c" q$ r; h1 q$ y
hi1=linear(w1,w2,i1,i2,b1)
* ~% u! p) }/ [% r& o- d
hi2=linear(w3,w4,i1,i2,b1)
& ?$ V/ q/ ^) |) e8 W! L
#求h1和h2输出值
8 |1 Q7 W) i4 F; C
ho1=none_linear(hi1)
r$ \ P8 x) r0 S9 u
ho2=none_linear(hi2)
* b: k- a3 x2 C$ \& T
#求o1和o2输入值
1 M- [/ E' {$ l, X1 E$ x0 U
oi1=linear(w5,w6,ho1,ho2,b2)
- k" V- h w" B' X* F; ?% T
oi2=linear(w7,w8,ho1,ho2,b2)
8 S# \; O# D) X8 A# H, y
#求o1和o2输出值
2 [ p% ?# A5 @
oo1=none_linear(oi1)
+ l9 K7 a" r9 i) U4 V( g7 h/ M: P/ G
oo2=none_linear(oi2)
* {$ D# M8 k0 k! r N
7 T! w6 O- ]- n, K' t
#求当前计算总误差
& D" t, [: R& C( r
eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2
. \% q5 h$ F$ n" b& w6 K) Q7 r
print(f"第{lt}次训练,当前计算总误差={eo}")
' i2 M1 {1 F( a& a+ Y7 l) P2 z) X0 I
#误差已经在允许范围,退出训练
7 ]1 k2 x3 S! P* `' I% o! l
if eo<eo_allow:
1 O8 ? J! D3 w f; G
print("误差已经在允许范围,训练结束\n")
, v& V1 g8 {* j* Q: {% @) i
break
% [. \8 l, a3 Y
#偏导
]7 ^+ [# C' [8 G* O1 ]
d_eo_oo1=oo1-o1
3 q+ L& G, Z3 @( _9 W9 b" i
d_eo_oo2=oo2-o2
9 \9 S8 |/ s+ L- v$ |9 F* D8 q. |
d_oo1_oi1=oo1*(1-oo1)
( P s1 T& A5 r3 Q% \$ S
d_oo2_oi2=oo2*(1-oo2)
' l) D" t: q; N1 z, ~. d* S, a
d_eo_oi1=d_eo_oo1*d_oo1_oi1
7 s; J; E! c5 q7 v4 d
d_eo_oi2=d_eo_oo2*d_oo2_oi2
8 ]9 Q3 x9 _% Q
#求w5_new
3 ^. H. R( y1 l5 q+ p6 h% H
d_oi1_w5=ho1
- a3 m; Q% U! k" e; f/ H
d_eo_w5=d_eo_oi1*d_oi1_w5
- `& {$ _- E9 V: w! u! w8 q
w5_new=w5-lr*d_eo_w5
2 S% j0 X w: }# ?8 A$ U/ @
#求w6_new
, P5 ^, Z$ G; w) k% V
d_oi1_w6=ho2
k2 a) q4 V' p/ o- ^. |
d_eo_w6=d_eo_oi1*d_oi1_w6
: p$ W y# ~8 H G/ [
w6_new=w6-lr*d_eo_w6
( x1 z+ e/ N: E. n" i
#求w7_new
: z$ ~) W0 U1 C. o9 Z2 s3 C
d_oi2_w7=ho1
; L4 F1 o9 ?1 L4 ^/ f* \
d_eo_w7=d_eo_oi2*d_oi2_w7
8 }/ X/ m7 f8 G0 n9 F6 ?/ l+ ]
w7_new=w7-lr*d_eo_w7
$ z, m. L; k' T3 J, E
#求w8_new
, T' v7 K" @( L& |0 l$ }( L
d_oi2_w8=ho2
) p# U+ I1 }& Z u" Q9 {! v
d_eo_w8=d_eo_oi2*d_oi2_w8
+ B0 { c3 ~! G' \8 M
w8_new=w8-lr*d_eo_w8
/ A0 [" H1 N( P4 p; k+ {+ p: u: E
#求b2_new
/ J) F! h3 m( m) R
d_oi1_b2=1
! y( j }& E/ U7 {! K
d_oi2_b2=1
8 U7 `+ n- h) f
d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
9 t% [; l" O; I: U* h
b2_new=b2-lr*d_eo_b2
; h3 A) j1 F4 x
d_oi1_ho1=w5
. V" @3 }9 o6 T2 i% z" F/ z- t9 Y
d_oi1_ho2=w6
1 }# C: [$ w4 \, g! r3 v- q0 J
d_oi2_ho1=w7
! y$ s/ X0 d1 m2 s5 C7 t$ W0 \" Y, F1 p
d_oi2_ho2=w8
8 Z% C2 h% g/ [" L, g
d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
' P( C, R. k* [. q8 p3 \. _2 n* r
d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
* \2 R7 D- k( f! M9 L7 g" W9 r v
d_ho1_hi1=ho1*(1-ho1)
: `8 N$ q' E8 ?4 r8 w, [3 R( E9 C
d_ho2_hi2=ho2*(1-ho2)
$ m& v! u7 V) n$ O
d_eo_hi1=d_eo_ho1*d_ho1_hi1
' W" w! G, {- L1 D' `! ^/ d" j
d_eo_hi2=d_eo_ho2*d_ho2_hi2
- Q6 I. Y# k6 A
#求w1_new
5 q% Q2 M9 P' {7 C6 c
d_hi1_w1=i1
4 ? T/ e& i6 G5 `
d_eo_w1=d_eo_hi1*d_hi1_w1
& e [& J+ \# E: g- ^. c
w1_new=w1-lr*d_eo_w1
2 m+ ~$ E" s& r$ e
#求w2_new
4 K4 `; X B6 e0 Y+ a
d_hi1_w2=i2
4 K# O, D$ \! v, l8 X& y7 [3 t7 S
d_eo_w2=d_eo_hi1*d_hi1_w2
) B# E/ F. w7 q' i
w2_new=w2-lr*d_eo_w2
3 j' e3 {7 s/ C, _/ H: m
#求w3_new
9 ~& X5 r% X0 J8 F$ w- `# \; J, ]
d_hi2_w3=i1
9 t9 l: V; M$ L- B$ m8 C& p+ `& v4 s
d_eo_w3=d_eo_hi2*d_hi2_w3
% o5 c& o5 W5 |6 J: s3 B
w3_new=w3-lr*d_eo_w3
+ ~# _1 p$ ^3 y4 b4 ?1 T. w) @
#求w4_new
8 D3 K3 s, p: o A) r' V4 \
d_hi2_w4=i2
+ x( ]% ] l9 K `" s
d_eo_w4=d_eo_hi2*d_hi2_w4
4 |9 x( @0 `+ R* ]" S
w4_new=w4-lr*d_eo_w4
5 E0 c3 C1 D1 T; L* @# G
#求b1_new
1 i" P4 p) F! O! x8 {2 J; o; I+ k
d_hi1_b1=1
# f7 V$ F+ ?$ W
d_hi2_b1=1
, ~7 I" ^, {4 n' {8 q3 y/ `
d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
7 ^* y) n8 |8 m& k, b8 ]
b1_new=b1-lr*d_eo_b1
/ g+ w. @& p) p7 z) q2 T- Q! b6 p; q" h
#更新反向传播
- L7 R* {0 N; H# _8 d' Z" F
w1=w1_new
1 w3 S q# F% t: u r' L
w2=w2_new
) x$ c; {* R; S+ B/ @
w3=w3_new
' M8 h; F( X* }$ S7 S0 |2 E0 D
w4=w4_new
, P+ Z N% [2 j& m" h: k& m, m& u
b1=b1_new
& H, A2 T: l" G/ ?
w5=w5_new
8 W0 h: s+ U! l# @
w6=w6_new
4 L0 k# ^9 y- k1 c: U! B
w7=w7_new
- w. I4 W7 k* Q# C
w8=w8_new
# l+ k8 J# c( p% N& S
b2=b2_new
% T) \% O& O- x" Q! r5 q3 K
print(f"当前计算总误差={eo}")
2 C1 y: U# M4 ^* {- ~9 ]6 a$ p
print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
% `% M {5 T- g4 g3 m" g
print(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")
% R' {2 x. m- @; l. K
print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
5 F0 Y6 m- F" D6 q' E
7 E( P' r- O# v3 p. ]2 P* X" [- i$ i
结果
% A$ |! O' k- D' ?" M8 m# R E
8 p0 c* Z! j9 _( N
6 ~& ^) i: W) n( H* \6 J7 j
结语
0 M$ I- g) i6 C
可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。
2 h: z; l9 Q! I0 x
. {$ }3 w1 c6 ~8 }! a6 m r8 |
补充
+ g; A* G, F [4 V4 x
程序中d_{a}_{b}格式的变量表示a对b偏导
4 r3 R: X/ Y$ @& c- m3 }+ T% z
————————————————
" T' ~' j0 Z# [/ T& V
版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# j' z* Z; z! N& i# i; ]
原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
4 W. G- y X! h, w9 k& n
. [9 R; `- O* b( ~/ k/ l( f& \4 M0 F
& U: Z2 Q8 L4 s# e2 H
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5