QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3069|回复: 0
打印 上一主题 下一主题

[其他资源] 人工神经网络——反向传播算法初体验(python实现)

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-12 18:40 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    人工神经网络——反向传播算法初体验(python实现)) N# s, T' H3 m% C# }* S

    % ]) J6 B' v+ I$ i# n0 k4 B# n背景9 u' L+ A' I! @
    初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
    0 C. r  |0 w2 C% e* G$ R( _5 [) {& ~) T1 t$ d" j% k
    【神经网络分类算法原理详解】
    : |2 d( W6 I0 e- C- t. w8 B( j( @" e  P2 l9 d! H# F
    注意4 v7 n7 ~* A$ a) s% E9 D  S7 o- }7 K
    站长提供的图片有点小问题,我们更正如下
    ( Y; i' d) P, F, v2 o  P$ M: d0 U$ y" e4 q) I
    + S9 L. D: }9 f1 y' F  {: N
      y1 E/ \( Q3 g7 S8 Y
    问题
    . {$ H' v# {# h+ q1 I- k根据上图所示,我们有已知) l5 S- S, F" A" X. c

    ; f) P0 g4 G& V) q$ D% q#输入层
    6 x# a5 ~3 e8 e1 m' \$ ?i1=0.054 x& r! X# _3 j. V" c/ q/ Z
    i2=0.1
    ; T, f9 E7 m% n8 P& `& j* Q5 w  _' p- C: T" p% q- K/ e. d) j5 V
    #输出层
    5 G+ c1 N5 u& V) [o1=0.01' B* |+ z; [  E8 e
    o2=0.99
    ) X1 y; @7 I  j1 E  {, O* a1 U6 j这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
    1 M& X# J( K' ^& w2 z7 E0 i: c) s4 Q& p7 R- S  `8 y! |2 y7 y2 S8 j* p
    神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1
    4 |# g) I! O; b* r1 f1 c" K; \% }# V8 t( ~
    神经元h2的输入  (hi2)=w3*i1+w4*i2+b1: e8 y% ~+ m" B+ T! i. N
    ( G! h4 H! u8 T6 n9 ?8 Z
    神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
    9 P9 Q- ~1 z. l3 n5 j1 d* I  y+ a9 k- x% w. ^  i
    神经元h1的输出  (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
    ( e' z+ Z7 I- |5 F6 {5 l9 y& p$ @) o+ D: t/ e1 t2 P% D1 S
    同理5 X- `+ e! u) h; b, N9 o. F
    6 M$ f, y: i6 o8 Y! q( j
    神经元h2的输出  (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
    & M" @& z' n% o+ ]8 D9 a8 v
    3 [  }7 Z  q  H* P5 p接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式' e& ?& m8 A3 `) B$ o0 ^
    ) F8 q: s5 E/ e
    神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b26 e* I, m" s" o" v0 d  X1 E

    6 M) [# X0 {$ U! u; y神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2$ J6 w$ X8 U, ~4 S1 T! a
    $ u4 {# y0 `# Y' N- l
    再经过非线性变换Sigmoid函数得到8 E" q& w4 \. f( G7 [

    7 g* x+ p- L" h6 G* e神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))
    ) |, G. c! p- w, u3 H$ V3 @0 j& f; p) P; f& h- T
    神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))
    ; f* o# B9 p8 p5 o! ^( T, Y5 V
    我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为4 h" v- e5 r( b! j$ ^% x

    ) I6 x. m& ^1 y) _, q/ C  ?4 B损失值  ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
    . W: s, i5 v* V' o8 h8 U& C* s
    3 F  o" X& Z& G# ]" K  O0 @- M由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
    " i# q, v0 w0 @1 J* q
    1 W) ^+ `! W9 I4 H学习次数 (learning_time 简写为 lt)我们限定最大为10000次; Q/ n, o0 t1 P
    1 g) U: O, J$ X" L" T" \# _4 u
    学习率 (learning_rate 简写为 lr)我们设定为0.5% l- W) W% B7 L" k4 @) \9 ?% l
    ( K$ Z3 \- V1 Y  ^
    依次求解代求参数: t/ H6 ~; k6 }

    - t. V1 t/ y& ew1~w8,以及b1,b2* L0 m" w3 ?1 Z5 V& p) {" o

    , `7 i" e' s0 H0 f! A1 s/ ~! I
    / X, h- V. d( b$ S7 u' [) m: H* B
    : _, X- p  [* M8 s# L6 L' k损失值 (eo) 的偏导数
    5 i% n8 e& @5 D8 T2 y2 S' a2 L7 i4 Q" ?, w+ L" a
    再更新该参数,更新公式为. b2 Q( V9 k/ l
    0 a7 O, A2 @8 ^
    参数_new=参数-学习率*偏导(eo,参数)
      }* ^+ @, S7 e: V# g随后进入下一轮学习
    , t1 H  ^. |5 }4 y) k! B. g3 r! [  Z; O- }8 w+ N* r' @+ x
    终止条件(满足其中一个即可停止训练)- p' V4 W9 y) ~- A6 Y
    2 l* r' k- X' B! [2 ^; P
    1.学习次数达到上限
    # Z3 S. Q- R* c+ H* O1 v' E2 J) x( e0 Z) t* F' u6 S% V3 P
    2.损失值达到可容忍的范围, z! D. p) |! {* G4 p% L
    $ r7 D; `0 o) z9 Z  u
    导数
    8 d0 t) [$ r" Q& R& zf(x)=1/(1+e^(-x))的导数是
    ) j: T& m! A7 g. B. K4 E7 H4 Vf'(x)=f(x)*(1-f(x))4 p  G) I5 y% ^" F9 n# Q
    源码
    7 l. _' ~6 e- \" s$ O2 R2 Eimport math# Y& f" S5 G- {8 B$ R: X  g
    7 n8 z# W, H. `6 Y& V
    #参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】/ }! g5 n8 Y+ e( ^4 y0 k1 l  o2 O
    #网址中图片有误,请看我博文上的图片1 q/ _, u! u1 D% t3 ^
    ' R% W0 j& s6 H/ G; P& w
    #输入层
    ; O# C' y; q. c8 `; C5 |* A" l' `i1=0.057 K5 Y3 a8 {* g# {
    i2=0.1
    9 Q5 t1 U% O/ p& K7 {#权值参数
    4 h0 c+ B6 A5 z$ [w1=0.15" Q2 f3 |9 B2 K' u0 X: }& |' \
    w2=0.2+ u+ ^2 D  ?% g, K
    w3=0.25
    ; V: I7 [# w) Y/ p0 Lw4=0.3+ s2 v$ r3 z8 w3 O
    w5=0.4
    9 ]$ _7 d7 {% m( C* N5 Xw6=0.45
    % w) T: n' t( l, w. iw7=0.5% G( V) E( ]! u+ c
    w8=0.55
    ! g1 c/ r) V: l3 `; @#输出层标记(即期望值)! l) s2 p7 z, `; K4 t
    o1=0.01
    ; ]8 r  E  m. M( {! fo2=0.99- K3 C: m" N  e5 W5 }* }; x
    #偏置项参数
    " V0 A! m& b$ ]* e8 `' v# O5 C8 }b1=0.35
    ! b* B  |& c6 V7 ob2=0.65 S( k( |& L0 e: [

    4 \& W6 B& D% p#学习率
    6 l. y' P: q: c( zlr=0.5
    0 {4 `9 ?3 E2 {3 D2 X#学习周期% [. j' K4 I2 v( ]1 D
    lt=0: ?6 U3 `( h7 K8 T7 I
    max_lt=100009 z  a! m9 J8 h1 k6 [0 V& R1 P
    #允许误差, ?$ t! Z; V6 i
    eo_allow=1e-5
    $ w3 m$ `- m% C
    ' X/ ^/ Z4 Y% U" i$ @#线性转换
    8 ]! ^: n; ]* A: o5 X6 udef linear(w_one,w_two,i_one,i_two,b):: }2 M* z4 }0 @9 h- f0 J
        return w_one*i_one+w_two*i_two+b
    3 J. t0 w- L# q! Q8 A) i. P% W#非线性转换
    6 n5 _- k/ S, z) ~9 udef none_linear(i):
    ' z6 \' C6 O+ ^# o/ I  x" v! I    return 1.0/(1+math.exp(-i))
    ; D# a$ [, N9 g
    ) X! B0 ]8 B0 c9 W, x* e0 g  u/ Qprint("训练开始")
    + p; s2 D, v9 u/ d2 T" U#学习周期结束前一直学习3 u3 [8 d( z" n' L0 c, H8 d7 ~
    while lt<max_lt:
    + ]8 ]0 T/ K6 {& a( E2 o    lt+=1
    0 S# T, Z# ~* [4 \+ B0 f* r! m2 j5 L    #求h1和h2输入值
    2 {. z5 U+ d. o% j8 H3 m7 @' z+ n    hi1=linear(w1,w2,i1,i2,b1)
    - l$ Q/ ~2 D  N+ N    hi2=linear(w3,w4,i1,i2,b1)
      G7 w5 C! Z! Z/ a! L    #求h1和h2输出值8 i6 a$ ~4 g8 J; {: I
        ho1=none_linear(hi1)
    ) ]; ?: V1 T& M: u4 S    ho2=none_linear(hi2)
    8 f: n. p/ Z1 r% X4 W    #求o1和o2输入值
    2 @% T2 I) s: l& b" C' u3 n- \    oi1=linear(w5,w6,ho1,ho2,b2)
    ' L0 b6 p5 J- m; a$ t  [    oi2=linear(w7,w8,ho1,ho2,b2)) j$ {; m& P2 S7 A# D
        #求o1和o2输出值
    # M6 V7 X8 z2 T2 @' O4 I% K$ ^9 Y/ W    oo1=none_linear(oi1)* W8 J2 V2 D3 x; Z2 z
        oo2=none_linear(oi2)6 ]0 @8 _' b4 u& h8 `/ T' f

    ( O* [. b& F7 c    #求当前计算总误差0 J! h3 @& \, i1 j) z4 C+ h
        eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2) i- |0 O" [( r; G* x8 D% P- `
        print(f"第{lt}次训练,当前计算总误差={eo}")+ f! B9 d2 Z  C0 g3 ~" ~' W$ L/ ]; R
        #误差已经在允许范围,退出训练
    3 U: `+ Y9 u* H9 e, i  |    if eo<eo_allow:
    * |4 K( V# a. K% R/ y$ o6 D$ c& ]        print("误差已经在允许范围,训练结束\n")3 p/ r! _0 ?% S# r
            break: l; X7 U+ p% K! {  w
        #偏导6 L) L% A/ V  J; v& \
        d_eo_oo1=oo1-o1
    ; x. Y* A4 o) y9 d    d_eo_oo2=oo2-o2& M) M- e; e$ W4 t  ^7 E
        d_oo1_oi1=oo1*(1-oo1)8 y, g3 O/ k4 D: h$ T+ L; i  X
        d_oo2_oi2=oo2*(1-oo2)  d" e# h! |2 U& \" R9 A! `" F
        d_eo_oi1=d_eo_oo1*d_oo1_oi1( C( c, S+ w6 _" j1 O& x
        d_eo_oi2=d_eo_oo2*d_oo2_oi2
    4 k' f: F' Z7 J- b. ^) W- O    #求w5_new
    : Z9 e! B# a/ w  V    d_oi1_w5=ho1+ R! O$ q- r* D/ i. m' `
        d_eo_w5=d_eo_oi1*d_oi1_w5
    * j, D. u% I  \    w5_new=w5-lr*d_eo_w5+ F/ z6 g  o7 k6 X# _" B
        #求w6_new6 k2 N- F+ _6 V, Q+ m$ X( i: P
        d_oi1_w6=ho2
    4 P% k1 k  m) l' Y7 Q    d_eo_w6=d_eo_oi1*d_oi1_w6
    " e, W5 j9 z  m; i- @$ T7 z& J) [    w6_new=w6-lr*d_eo_w66 u7 s# J( _( d, L1 o% ~  t
        #求w7_new
    2 u/ J, l% u+ v- d# j1 J    d_oi2_w7=ho1" q5 ]* y) z- g  ^$ I+ I! T
        d_eo_w7=d_eo_oi2*d_oi2_w7
    # K! G3 b0 P7 g5 h' `( j5 Z/ J  h6 n    w7_new=w7-lr*d_eo_w7
    3 y, a$ W# l& m    #求w8_new. G$ ~% p* y& ~
        d_oi2_w8=ho2  J4 H7 ?7 ], R1 a" D
        d_eo_w8=d_eo_oi2*d_oi2_w81 V- p4 J9 D0 G( |9 `9 c5 o
        w8_new=w8-lr*d_eo_w82 z* H/ O! ]- m
        #求b2_new, y/ ?- h- U9 V/ H! H
        d_oi1_b2=1
    4 ^. i" Z/ x  F  ]3 W1 J    d_oi2_b2=1
    - ]6 s* Y4 T  R$ Y1 d0 U    d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
    5 F9 @. ~0 o/ r0 u    b2_new=b2-lr*d_eo_b2; I3 }2 l6 O+ [1 X; F7 {' S6 |
        d_oi1_ho1=w5' Q6 _+ H) ]) X+ y6 w+ `
        d_oi1_ho2=w66 \- {; M! V# Q5 S
        d_oi2_ho1=w7" S) \4 A4 x" T0 c/ P  h
        d_oi2_ho2=w8
    & l9 `# S# B% p/ E+ C    d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
    3 Y/ h% }8 B7 p, \6 s7 v6 r; x    d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
    7 S  R" x, A% h5 a5 z    d_ho1_hi1=ho1*(1-ho1)- R# T) |" r3 @" r5 K
        d_ho2_hi2=ho2*(1-ho2); ^, e( R! u: \- a4 L* K- j0 l- l
        d_eo_hi1=d_eo_ho1*d_ho1_hi1
    ' M/ @# y& s6 m6 x' o    d_eo_hi2=d_eo_ho2*d_ho2_hi29 q1 y  A3 ]! ~: _1 F1 u
        #求w1_new
    8 M. _+ H9 y( @. k' x. p7 F9 W  e    d_hi1_w1=i1" t# ]( T) B6 F, S" _- w% k/ T3 J
        d_eo_w1=d_eo_hi1*d_hi1_w1
    ; \6 U; [; q% s    w1_new=w1-lr*d_eo_w1
    6 T' c9 R4 O, P1 i    #求w2_new3 X0 ]6 }. N; f9 I1 g* ~
        d_hi1_w2=i2" m! ^+ Y6 S" F4 j+ a
        d_eo_w2=d_eo_hi1*d_hi1_w2* E4 [3 w5 _) G- S
        w2_new=w2-lr*d_eo_w2- U- B! M; `, E$ S- [" {# s* p( J
        #求w3_new
    & h( d8 K3 q6 d2 {( q; }- D9 U* l    d_hi2_w3=i17 Z$ q* ~$ M, Y; b( u- R
        d_eo_w3=d_eo_hi2*d_hi2_w3- |; x3 a9 B! h
        w3_new=w3-lr*d_eo_w36 R4 P3 M( Z  C# z* U2 B2 Q
        #求w4_new
    6 f  h$ Q2 O( C4 C) `# q    d_hi2_w4=i2
    / G& }0 l/ J$ B9 W    d_eo_w4=d_eo_hi2*d_hi2_w4
    ( E- d  q) M) p7 U" i$ K/ E7 u4 {/ F    w4_new=w4-lr*d_eo_w4; m! ]. l9 k" r( _  ]
        #求b1_new
    - Z. a! \  q3 ^    d_hi1_b1=11 W+ `: o% P+ d; }
        d_hi2_b1=1
    7 u0 C- E7 ]* G    d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
    5 M  D# Y0 @: t& g" N; u    b1_new=b1-lr*d_eo_b1. j5 {7 w7 e3 a& Y' ^9 c4 c
        #更新反向传播! l2 g) g) F. B) |7 U$ }" D
        w1=w1_new
    2 t  L' H4 y8 w' m8 T0 g8 ]    w2=w2_new
    6 q! c& e1 T; P% M2 ?, i    w3=w3_new
    * g' H6 B) E/ X9 I  u3 M( [/ _    w4=w4_new
    # ]! V# u7 ^' t. q# z/ U    b1=b1_new" f, t  J2 ?/ b' I+ C$ U; G
        w5=w5_new
    9 j# E% [! x* c2 V' ]) s    w6=w6_new. {+ e- n# {8 z/ N  n2 w. O5 ], v
        w7=w7_new9 H7 ^0 I5 E5 l+ w* l0 {
        w8=w8_new, [6 n* r7 ^( V5 Y
        b2=b2_new
    1 K. Y# u- P6 U) o, Sprint(f"当前计算总误差={eo}")* g% a& T! }) `8 t% z' u
    print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
    " \5 P& q' W; Xprint(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")
    , M% e" K8 r$ O( z0 `print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
    , l# G7 ?1 q& ?" Z8 M+ @4 B8 p9 `" P* J) \
    结果
    : D; w+ b1 w. x" `% D1 U8 O
    - g  ^( d) r# Q- N" V0 A8 f( D* A2 o- {- X" c9 S
    结语
    - N; q$ G& @/ ]' J. ~8 d可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。# V' O4 R/ O6 H# ^' z

    2 F, |* R  q7 ~, g; z: G# J5 W补充9 ?0 g( m" R3 Y; C1 m
    程序中d_{a}_{b}格式的变量表示a对b偏导6 T8 L2 m) f0 k% A6 ]4 J9 ?" A" z( a
    ————————————————
    + {; h; b2 J! @% C$ K% T版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 q  h, T8 a( u3 H* R/ c9 E原文链接:https://blog.csdn.net/qq_36694133/article/details/1266679549 `9 u& Q# W& k( ]/ D$ t
    0 @" J4 q0 h- j8 R! r, l/ P6 R

    4 p7 D7 f& p! ~- f0 x  i+ [; w
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-8-24 04:59 , Processed in 0.520659 second(s), 51 queries .

    回顶部