- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565164 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174772
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
人工神经网络——反向传播算法初体验(python实现)
6 l6 O' r l( t' I' F/ ?) `5 k: r5 [( t
背景
/ _4 T; D# p6 p# K初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
: u' u# _9 P/ u( i6 {+ {; O; c$ x
* c! }/ R: O' T【神经网络分类算法原理详解】
. T: v! f3 X2 m! E
) }9 f6 O' a. z+ ? u( l* j1 P9 S注意
- ^3 ^. G) l9 Z4 }站长提供的图片有点小问题,我们更正如下3 @6 W" m& B7 L* Z% r) V8 s
7 Y4 I+ Y" _2 V1 Q% A# C; s
9 M2 `5 ]: R- k: Z+ _/ r/ t3 I2 b/ `5 M" ^$ a
问题
3 ]( y1 Y. O$ Q根据上图所示,我们有已知
9 x# K. i$ u6 ?; D. P. \1 Z! E
; k p* w; D! \#输入层
" _3 v! i6 C' c" v% {5 a5 ai1=0.05# o) R3 q/ v- ?% h
i2=0.12 z: H. O9 I( @$ {
$ |' }$ G% w6 [/ }% ]
#输出层
% A: J' M7 ]' R: F/ ]o1=0.01
; Q! d: P8 ?6 S s; {: [o2=0.99
/ v( h7 c2 k/ H/ ^ W) ~这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
' n% j/ U/ P. y- Y$ H1 w; X0 d2 X6 E2 ]' W6 P4 n$ E& e1 C q
神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b10 R! r; R4 [5 g" K$ o
4 x8 }4 g& Z6 W
神经元h2的输入 (hi2)=w3*i1+w4*i2+b12 e% l$ x Z3 {7 k2 \
5 g" v) s. J. p' H- H$ B" O9 {
神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出6 D: t8 w% f* T0 ~
6 O( X7 A, U, ^5 [; f* T神经元h1的输出 (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
2 ]7 |, X7 y% g& ?9 @4 U5 q7 b! `
同理) b! w* Y6 ?$ u+ \9 X" A
# I) h1 u" ^! l* h
神经元h2的输出 (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))" r6 E/ C% o" W8 V; X0 t% L0 K
: F0 h, P1 A8 ?4 l) E# [
接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
, ?7 M1 X3 p1 }, r/ W, M7 @; i7 H% w, i a% E, N/ e T
神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
" b' u3 o2 y5 g3 S; R V2 \' Z4 n! n" }7 j
神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2
2 ]9 j3 f5 l, @& s1 t$ w
# @% @9 W- b+ _5 o% B再经过非线性变换Sigmoid函数得到
; Q( \( q+ M" w/ r
% F0 ]2 g1 u) m( ^5 a) K1 a E神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))
i* b& A: e$ e# l- v9 p9 w- }3 N! j9 y; p, z& Z9 t
神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))% Z) j, W7 M& X& A2 I6 @4 a
& }" s+ E2 H" I: M. O我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
2 b! k, ~# e" q ]0 N
; I& C0 \- T$ J1 o: z) |, }损失值 ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
$ V6 q8 b; T; i# O' }8 Q' E& a9 l
6 _# e3 ], [# _$ X( D, O由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足1 K3 {( k6 A$ m G4 T. e
- g0 |. D7 b6 w# R- L% c& `8 V8 a
学习次数 (learning_time 简写为 lt)我们限定最大为10000次
$ J1 a' b0 ]) ~7 {$ n8 e" L; \: Q
学习率 (learning_rate 简写为 lr)我们设定为0.5
" y ], C4 q( j7 `0 e* ~+ m
7 S [" j# V# @2 z7 ]依次求解代求参数
2 ~: d1 ]" f9 R3 R: Q2 F0 ^2 {0 v. ^$ l N1 H. ]" x* g+ \
w1~w8,以及b1,b21 c7 s, ^, [3 z' B
" S0 Y7 n- [9 H: Z) G9 g
跟
) |* M# M! Y, b7 h0 Z5 @& o5 t% F' r8 e. j. a9 m
损失值 (eo) 的偏导数$ a1 D/ s: e) w# G2 W
* G4 _' P0 O0 Z1 B8 ?再更新该参数,更新公式为4 ^2 m& D$ t/ \$ j" @
) K4 [% B# S! R2 L
参数_new=参数-学习率*偏导(eo,参数)
5 X1 N1 u1 [2 z& C2 L4 m7 w随后进入下一轮学习
2 ^1 s* m4 D4 z4 l) n, a/ R6 s* g7 o. B* \2 ?& I
终止条件(满足其中一个即可停止训练)
% B' O) Y: R: V6 n) @
; F6 M& Z b; F' v1 P; ^: P' ?6 r1.学习次数达到上限0 U/ J% O& w# z& S+ M$ e- y5 x
: s* f( u2 D4 f4 p. }% M
2.损失值达到可容忍的范围+ w/ ^. J8 W7 L7 O0 _8 X K* T
& U/ Y- n" B/ }5 S4 T- y
导数( d" I3 W, j' p Z2 L1 y# o; G8 O
f(x)=1/(1+e^(-x))的导数是. M; b1 `9 H+ Q: `. A$ V# A
f'(x)=f(x)*(1-f(x))( D* B9 l% k9 ~
源码
; N4 I7 x' i; ^! |2 n& _import math8 p6 y- Y5 {" L# ?
( e' \5 U1 C; {1 H% e$ z( @#参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】
" {. W) M7 U$ G& o* f( B4 R#网址中图片有误,请看我博文上的图片
/ l! H& W( s) q6 F p& r# j
. ?! N- t2 C0 m' m: `- g0 U#输入层/ P" v' j q `) q/ i7 {
i1=0.05 ]* z( c t4 r4 g% W. `" ~, `
i2=0.1
3 p$ f1 c4 X& n$ o#权值参数& m- O; q) n- U* T. x
w1=0.155 `4 P# E/ v8 W
w2=0.2
' N( e* o: q- V" `$ Pw3=0.25
- b6 H" ~% @, K% w8 l2 E6 vw4=0.3
# G% W D' o. n' k2 l' a' Sw5=0.4; v! O! L6 v( @8 i/ K
w6=0.45: H( z# a2 o' y( I
w7=0.5
; B( I( H, G7 n% K. Q2 Kw8=0.55. Z4 t5 T3 g E, h! }9 _. [2 P
#输出层标记(即期望值)
! L# a1 C- i. s8 h$ W! P3 io1=0.01# O B. S5 J& r) z# |
o2=0.99
) B' B# @6 E( l2 n0 A0 e; b: f4 m#偏置项参数
3 u8 n* z5 z0 pb1=0.35
- s, E0 v+ ~- V. m4 [2 Lb2=0.6% \" n- s8 P$ t
) n( p6 E- s' f1 ?0 t" _' R4 j#学习率
@# J3 W. ^9 w% W4 |! {lr=0.5
7 Y: l5 c1 W; u, L#学习周期
; x) H8 @) S" Q# e K4 x8 rlt=01 |8 ^ b" X* G+ N7 m( u; t! W
max_lt=10000
3 C+ ]) Y. ^( g0 \+ z2 b#允许误差4 w: q/ h; |5 b$ M* j
eo_allow=1e-5
K3 _+ P3 t. I6 e$ Z) m4 q/ _5 Q6 x- s% Q% N* N
#线性转换9 b7 m$ C( _0 P, D
def linear(w_one,w_two,i_one,i_two,b):
5 c! l# D, i- Y- ?8 o+ r7 S return w_one*i_one+w_two*i_two+b
; c5 n- ]9 N7 x' L3 F5 L: x#非线性转换& R' g* b3 `/ X1 B% ], L9 {
def none_linear(i):- _* ^6 r( e' s5 k( m, C! W' d: b
return 1.0/(1+math.exp(-i))
7 w1 C1 B7 a2 y- g- w/ B/ [( @- A) y0 n& B% l1 a- f! m
print("训练开始")
$ {; ], w# d2 |7 @) Y, f#学习周期结束前一直学习+ R4 {: |. X. V5 ]' h2 @2 x7 y' @. C/ |
while lt<max_lt:% {3 v) {( u5 J# |% ^- i: s* ^, m
lt+=11 I( }9 p( J9 }$ q6 C
#求h1和h2输入值( k2 V% Y1 a" F, S0 x/ M& `$ ]
hi1=linear(w1,w2,i1,i2,b1), {! \3 s! h7 b9 u/ s
hi2=linear(w3,w4,i1,i2,b1)
/ }. q" D6 p# ^, s% \# ^ #求h1和h2输出值( _: i$ D4 b% V- o
ho1=none_linear(hi1)
( t; x9 _# K, j, B ho2=none_linear(hi2)
4 [- c4 Y0 \( j, Y #求o1和o2输入值
4 c: R/ i* _2 y0 W) `4 z oi1=linear(w5,w6,ho1,ho2,b2)
g! z2 C1 j. G! u8 Q oi2=linear(w7,w8,ho1,ho2,b2)) d, Z4 I6 }" G
#求o1和o2输出值, H/ \2 p$ F/ m: X4 ?8 `
oo1=none_linear(oi1)) @! r1 L5 `* T6 K
oo2=none_linear(oi2)6 P# W1 [% ?! Z
' [" k. J( ?3 q% v( }3 h #求当前计算总误差
, U7 B" \% A$ a: a) g/ ~1 |; L eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2
( l# \2 b" L1 M. X/ @& |7 G print(f"第{lt}次训练,当前计算总误差={eo}")5 @+ U8 V0 w6 e/ }$ W
#误差已经在允许范围,退出训练
- O0 ^# \! N$ D1 c5 f: k/ \ if eo<eo_allow:! u$ Q _: d- f, d' F# b Y. y
print("误差已经在允许范围,训练结束\n")9 i$ Z! g5 _' i: {1 O6 {* ~
break; m) }- f1 I3 p
#偏导; _; J6 E! v4 X4 M- C7 \+ \
d_eo_oo1=oo1-o1. v* V- M9 h, b2 X5 [2 A
d_eo_oo2=oo2-o20 B* k" a0 v/ w" U0 B
d_oo1_oi1=oo1*(1-oo1)% q) _0 @; ]3 [
d_oo2_oi2=oo2*(1-oo2)1 n; o9 q. M4 H9 n& H
d_eo_oi1=d_eo_oo1*d_oo1_oi1
/ N% ~( l$ D9 t2 ^/ i d_eo_oi2=d_eo_oo2*d_oo2_oi2
; g8 O. y+ w2 [0 A$ b x #求w5_new
% K2 Y j3 |7 W8 v, j8 d d_oi1_w5=ho1
. A, i/ b3 G$ ]0 I2 \ d_eo_w5=d_eo_oi1*d_oi1_w5
7 o! A8 T5 Z( r' q% C; w w5_new=w5-lr*d_eo_w5* ^5 J1 d4 |- C L6 P, J
#求w6_new; s6 g( B7 }+ s- r4 Y
d_oi1_w6=ho2* x4 f/ F/ J' Q5 `4 E' N
d_eo_w6=d_eo_oi1*d_oi1_w6
9 H; p; s, L; h! u- N/ t w6_new=w6-lr*d_eo_w65 @4 x0 t; i: y+ ^1 ?4 q- X
#求w7_new
3 F' E1 e1 x" X% J, i( K" u- L5 H d_oi2_w7=ho1
3 q4 N" a5 Q9 W# b K- {% f% j d_eo_w7=d_eo_oi2*d_oi2_w70 J+ O' @) E* P( l6 n+ ?
w7_new=w7-lr*d_eo_w7* t' f1 p7 D4 p4 v
#求w8_new) l( ^0 H5 ?) m8 S# C8 g
d_oi2_w8=ho2' b" u: }! J% g5 S% a5 `- p2 H
d_eo_w8=d_eo_oi2*d_oi2_w8) @8 V) V6 T3 v) f9 L
w8_new=w8-lr*d_eo_w8
6 D; ]1 R! B9 A+ S1 \8 Q5 H: k #求b2_new
+ Q: x: V) j4 R# G d_oi1_b2=1
& i. `- l2 a1 d& l" b2 ], G x d_oi2_b2=1) m$ }4 p+ }; X+ P* x& A" k3 C! f
d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
) H+ u# Y( P% ^# Y$ A6 ^& h/ k b2_new=b2-lr*d_eo_b2( E/ |( L9 }( [7 F3 D _
d_oi1_ho1=w57 J9 |' _5 \1 L
d_oi1_ho2=w65 F5 d/ Z0 ^7 H$ T
d_oi2_ho1=w72 H, U% l- _: q& }' n8 a- k' \
d_oi2_ho2=w8
4 M [2 q/ W" {- h. H1 h, W2 i2 g d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
+ k+ C0 S) F' r; S7 W0 S" [ d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
; a0 U6 F; G2 _& E' w l' | d_ho1_hi1=ho1*(1-ho1)0 n% x2 y! Q, B( r# F
d_ho2_hi2=ho2*(1-ho2); p: l x0 R$ j) w
d_eo_hi1=d_eo_ho1*d_ho1_hi1
- t7 r% n" W0 |2 k" I d_eo_hi2=d_eo_ho2*d_ho2_hi2$ _0 Z8 L$ o) b2 Z
#求w1_new
2 N% h( {4 n9 k% d8 O d_hi1_w1=i1" `2 m# ]5 v7 o$ ?' E/ ^" U
d_eo_w1=d_eo_hi1*d_hi1_w1
' K9 i4 p' \- A4 L/ e# M4 j. o w1_new=w1-lr*d_eo_w1& E" K& K, P5 J! l% m
#求w2_new
/ I3 n4 [0 {9 t. l, A d_hi1_w2=i21 M- }: S, x3 o/ _
d_eo_w2=d_eo_hi1*d_hi1_w23 U, h: F f- a5 l7 _5 T, _# T9 R
w2_new=w2-lr*d_eo_w2
; N$ {" D4 h' F% r! a1 U: a #求w3_new& O3 X; P! u! I- u& s; u0 i/ d
d_hi2_w3=i1
% T$ E1 d6 C8 \( E2 ?" y1 N; d d_eo_w3=d_eo_hi2*d_hi2_w3
! u* p, ?" W4 g. Q w3_new=w3-lr*d_eo_w3' R" _0 `) |( V1 S% ^3 f
#求w4_new
x: A2 t6 r8 _ d_hi2_w4=i24 a0 ?( T) y! T4 o8 G7 M+ [
d_eo_w4=d_eo_hi2*d_hi2_w45 i9 d: [# K$ l V& `3 g4 ?6 _
w4_new=w4-lr*d_eo_w4
- j$ W/ k t& P! g& Q9 O d #求b1_new: W( I6 f8 A* \+ f5 D7 k& k" u
d_hi1_b1=1
1 v, U; Q5 I$ B% J. }9 { d_hi2_b1=1
- w; ^- R- X6 v6 [" r d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
7 D; E3 M8 x% v1 Z" a9 `5 V% R b1_new=b1-lr*d_eo_b15 `$ Z) \2 k6 Z9 g- f* O9 {2 z
#更新反向传播& d1 H5 e% A/ p; n0 N% {* m! e5 r; j
w1=w1_new
3 n8 i6 g) O W- `" g E0 M8 Z w2=w2_new
' x) k6 Q5 _; y0 u" p w3=w3_new
6 X i% R' Y" j* h" I w4=w4_new4 f5 n4 J+ b5 l2 `1 E! x B" x2 X
b1=b1_new) D/ v$ x, {$ z- Z7 i8 F% W( w1 y a
w5=w5_new
5 ~6 o/ d1 }2 m+ s+ z w6=w6_new
0 u+ `% c2 \' X6 b( N& M w7=w7_new
$ D6 A2 O8 E% c5 W w8=w8_new
3 X, c" A% B- D9 }* I! N. N b2=b2_new
) ?* g7 [ N, ?1 Y0 q) rprint(f"当前计算总误差={eo}")
# A+ l1 `9 z {/ l+ pprint(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
; ]9 B8 |* _* [print(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")1 n9 h3 A) U& [9 O! y& \
print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")" P- Z7 P9 v# L* x9 N% l6 P* p
8 N0 F" a, I1 J! t4 `( D" U
结果
1 h2 q/ j! ?: e# {, k; T) w
4 `& X- D. N, Z8 P* G. {% a* D$ Z' E
结语- l Z1 N2 o9 g3 e
可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。! v+ Q% C3 ~: N$ x) U5 u
' y# r# h) k }. g补充# I8 T6 x( W5 e
程序中d_{a}_{b}格式的变量表示a对b偏导' \1 m4 j& O# m/ R: x
————————————————
7 {' o% L' u) K+ H版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
4 y. w g5 o) ?) X0 [& j原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
! ^* E+ U9 i1 F# Z4 |& p
9 X& r \8 N2 Q" R! M t) V/ a- E7 O- z
3 z5 d/ d. R( [) Q+ K# @ |
zan
|