QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3056|回复: 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实现)- v0 ^+ O+ n' w. K
    ' J- h& `6 T/ ]$ `% b0 y3 M6 j9 R
    背景
    / ]: y; }- z4 v1 y# G& i! t' f初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
    9 T; u% p3 W0 r; k- N* C
    + _* e5 t+ Y4 J【神经网络分类算法原理详解】
    ' M" v" A' ]6 q- b# E% K8 h+ P! p3 ]1 E+ s. c  G
    注意
    % B; [7 w( _( j' }: w) h站长提供的图片有点小问题,我们更正如下9 @/ g& H8 l9 n# a/ r& C* f

    5 L% v( m' h  S6 j# H
    / M) Y  w; D' M- k$ h2 y; L, N+ b/ |1 K/ ]+ ~6 C
    问题3 g: p" L( p7 j! e7 @) u3 V
    根据上图所示,我们有已知
    5 O1 L4 M; S3 m$ G$ Q8 b
    % L4 C( l  e6 e' U# ^3 d, ~* |#输入层
      Y! S- o: _+ _* _- q: J1 \i1=0.05
    + g' Z. y, I+ D$ k" p: @i2=0.1
    * B& L! _# W# y; [& Z6 r4 ~2 f. b. b" \: Z) z/ R* s
    #输出层
    ! u2 ]5 ]& \: B: ]8 ?9 M/ ~o1=0.01
    ' g( s. g( ~! {5 X9 i* G: @/ Q& x8 F$ Z5 \o2=0.99" a/ v8 t  [+ _  a* o9 Y
    这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
    8 t7 i/ L7 x' e3 m' p" t/ j! a% s7 M
    神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1
    . {  f$ _$ m" l9 O4 J+ ]7 d2 a! I. G: Q$ W  w/ v# x2 d
    神经元h2的输入  (hi2)=w3*i1+w4*i2+b15 t1 _9 H3 H9 E1 D4 ?8 _

    , M9 [! t( c/ N. L& W# ~) [神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
    , x) {1 T0 D! X# M& {" {
    + K) o/ C$ A4 x3 h' O神经元h1的输出  (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))! P& V* \' z/ a+ w3 g0 B# j

    1 P" R; t" v" b/ H! @8 B9 N* S同理
    # R7 W* i1 p5 {
    # \; N; n1 `, n9 ^' e神经元h2的输出  (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
    & G1 d# t, b! _# D7 Y  K4 r0 k- g' x, N% {; q$ d" d
    接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式8 A# d; m5 @3 @3 F0 H( h4 @: A

    ! m3 b- J0 J3 l8 ?; p9 X# V神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
    : s' n8 [# q* }7 d
    7 `+ k! e' Z; ]. }$ T" _神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2+ Q  a# t# M2 P, g' ^0 C. u
    ( t0 ~9 K* |) [/ f7 n/ ]
    再经过非线性变换Sigmoid函数得到7 Q/ Q- A7 _( a) L

    ! ?3 D+ @2 s4 {: F神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))2 m8 i8 y! y: H* Q* H4 G! t( l; r
    6 z  j* ]' V7 u/ x2 U$ p) s
    神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))
    , {4 M1 D3 c; t; g- U6 b- j, e0 b1 k7 C: ]8 a" |8 u
    我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
    6 G2 C+ }1 z8 B) s# }+ m9 q7 f) f; K3 T9 E' V, v- C
    损失值  ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
    4 c8 }( |0 X9 @, h! X5 b* a" M' ]& g( a! e
    由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
    # V6 S* \' _9 _# }- g+ v, X3 }9 a  e
    ) y; l! Z% P! E, U0 F5 n学习次数 (learning_time 简写为 lt)我们限定最大为10000次
    9 f5 p6 ~5 f2 y2 g8 n$ x# ^/ w: G7 ^
    学习率 (learning_rate 简写为 lr)我们设定为0.5
    ' T9 G: |0 ~5 h* G( X% h+ k
    & G5 w/ w# R$ ?1 x依次求解代求参数! l. e; {1 V' `8 R% o$ P" P1 v

    5 K2 o% ]! e( s- t5 pw1~w8,以及b1,b20 @2 i( U: c1 w7 W) y% _2 U
    , ?' v1 e6 S: v
    / T7 A: ]7 {8 W# L! G( {( O  t1 u6 w
    8 W. R8 Z  X* [
    损失值 (eo) 的偏导数
    1 d1 y4 n8 T2 F1 X* W. Z0 A) F( [
    再更新该参数,更新公式为
    6 p7 @, B6 V5 E7 u1 h' F( t4 Q& ^& t5 ?
    参数_new=参数-学习率*偏导(eo,参数)
    ( e6 N6 e- J2 G9 [( z. i7 n! Q随后进入下一轮学习5 D0 |- m$ b. U7 y* Z1 g
    ; w! K+ f% l1 A9 m9 X; v+ X: c
    终止条件(满足其中一个即可停止训练)
    ) S3 P% L7 R- n7 q9 m# _0 X  D
    : M7 W. F0 }( N; X8 x1.学习次数达到上限
    4 C2 }" j  q, V) Y$ [( C- d- |  L0 u; ^3 m' e
    2.损失值达到可容忍的范围  I. K& d- g2 |; d0 |7 X% l! ?( Z
    ; u( @* z9 A2 t' R. O6 O3 Z& H
    导数, \- s% x  G! E/ J- R! W% x
    f(x)=1/(1+e^(-x))的导数是
    7 l& t- x! U* O/ ]( F6 Mf'(x)=f(x)*(1-f(x))
    ( Z* g) ^2 y4 b' P8 }: n! N4 e% w源码' @6 R+ H; e: C% D
    import math% D- z2 z4 I4 K) n) |4 D# F' c
    ( C2 X! T* E; _
    #参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】5 d2 l8 O- O) Z# ~6 R/ `, X
    #网址中图片有误,请看我博文上的图片
    & K+ O6 j8 v7 z' \
    + |  l; f' K7 G1 F8 N#输入层! m5 w8 Z4 z8 F1 ?" n
    i1=0.05. Z% u  Q0 O0 r) u) ?* p4 k! }% \
    i2=0.1+ _$ a  D! M& U  N: v
    #权值参数/ X& z- d- n, u, D' o3 V8 V" A
    w1=0.15' b1 _. q- }. [' A( c* }
    w2=0.29 j0 M* v1 F0 ~9 ^
    w3=0.25
    1 H# i9 Y0 F$ lw4=0.3
    ) n8 E: K2 s" I  Aw5=0.4
    2 y; y- M$ ^8 N+ c7 v" Q# l* a) ww6=0.45( L8 z7 r8 i5 I  Q. o# G
    w7=0.5
    + `8 V: E2 j. @2 q+ v9 m, Bw8=0.55
    8 D% S  V1 ?& a% s* M& Q#输出层标记(即期望值)5 }9 L9 h, A# c/ Z! j) ]( ~
    o1=0.01
    , t0 H) q0 O6 i! m" `o2=0.99
    ) i3 V7 n+ Q, @- @! b6 M#偏置项参数
    3 S: h2 v9 j4 _5 C% F5 [b1=0.351 E1 s; k' A- M8 \" {
    b2=0.6
    7 Y) W. Q6 X6 O5 y2 |9 p( \: s. L; M7 |$ ?, X) b5 v
    #学习率* Q; ?" E8 ^+ O+ l
    lr=0.5
    0 N3 V# ?7 Y% l#学习周期
    + u/ `0 I. t- ^lt=0, h( d) r& r$ s8 _' r) r' k3 m
    max_lt=10000
    + H3 O' |1 R, K( f+ q: r: C#允许误差
    . {% F; b: V8 P4 R" Z! r4 Veo_allow=1e-5
    1 y3 [* X0 D( f8 ?* B' Z' `. M% K  v" ?' b" ]/ f) D8 E
    #线性转换8 a: k; e/ r- E5 S5 H' D
    def linear(w_one,w_two,i_one,i_two,b):
    ; I) I8 t/ d% h; d+ O& h    return w_one*i_one+w_two*i_two+b. ]& p/ S( h9 v6 \% P, b
    #非线性转换
    : m" q6 ?( ~  {8 |0 Ldef none_linear(i):
    ! e' r1 s8 O4 o  }! ]    return 1.0/(1+math.exp(-i))
    : \2 z# g) `. {/ o# O) |2 N# `5 m8 `7 F
    print("训练开始")
    $ ~( Q3 b' ]% ~- X8 p, H#学习周期结束前一直学习
    ! u- q! d0 F; Bwhile lt<max_lt:
    : I0 K- B7 i; ?4 ^2 r7 D    lt+=14 x" M$ a) n9 |- ~! O* D, f0 A: y
        #求h1和h2输入值5 [' p6 C  r: v1 l) p
        hi1=linear(w1,w2,i1,i2,b1)$ H  Y. _  O% ]- V2 J
        hi2=linear(w3,w4,i1,i2,b1)
    & J7 F+ \. w2 W6 N    #求h1和h2输出值! ~) v* ?) N  q
        ho1=none_linear(hi1)
    2 S/ d  f" H- K+ M, Q9 R, Y    ho2=none_linear(hi2)
    9 e# ~  c( I8 e% t" x. r& s& h0 J/ B    #求o1和o2输入值' B) d1 F% ]. e5 s
        oi1=linear(w5,w6,ho1,ho2,b2)) W) r' u+ k# ^$ `
        oi2=linear(w7,w8,ho1,ho2,b2)& e  [5 i. [4 Y) c2 g
        #求o1和o2输出值
    . _4 N) v5 `4 z9 ?7 W    oo1=none_linear(oi1)7 {/ {& c/ K, O( y, u0 N
        oo2=none_linear(oi2)
    % B" y7 {2 n' i: y
    ; F3 P; A: v( p2 E& G' V/ q    #求当前计算总误差# `1 F/ b. B4 E8 r
        eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2* n" K1 W) Q) S7 G2 ?% H
        print(f"第{lt}次训练,当前计算总误差={eo}")
    4 w) R$ Q  ?& t( s# v8 Z5 Z; M    #误差已经在允许范围,退出训练
    1 q& v7 ], c6 ?! O7 o, t2 v) n% R& [    if eo<eo_allow:
    / A# w# J2 b5 s, ]7 E7 ~1 X        print("误差已经在允许范围,训练结束\n")# `( Z" [! u0 l
            break
    ) i* P; y; C; t& i$ Q6 j! i3 Q) H    #偏导4 G  n  S5 g' J
        d_eo_oo1=oo1-o1) c+ y" U3 o, ^1 u8 Y' N) `/ J# E
        d_eo_oo2=oo2-o2
    % U  s& K) m, @8 [4 R    d_oo1_oi1=oo1*(1-oo1)6 B" Q) u5 r. R* T, C$ e; P' w8 p
        d_oo2_oi2=oo2*(1-oo2)
    ' T" F9 p0 A" U3 i" @6 S7 M8 h5 b    d_eo_oi1=d_eo_oo1*d_oo1_oi1
    # d" i: w5 e& x8 k    d_eo_oi2=d_eo_oo2*d_oo2_oi2
    * \9 C. M2 v6 l3 b( l1 ?    #求w5_new7 G- w5 I( d8 m% N
        d_oi1_w5=ho1" V5 w9 [$ r- ~5 ]6 X( x
        d_eo_w5=d_eo_oi1*d_oi1_w5. R0 t. b0 A3 ^" d1 Z% b- {
        w5_new=w5-lr*d_eo_w5
    % e' U6 P) z! y$ P# J) i. z    #求w6_new
    # I1 n/ {: ~& L5 Q! K6 R9 P    d_oi1_w6=ho2
    8 Q& e* h, a* l# C/ P* |. ?    d_eo_w6=d_eo_oi1*d_oi1_w64 b* A& A6 m/ f7 n  M8 ^
        w6_new=w6-lr*d_eo_w6  r, n8 U, @. @1 ]
        #求w7_new
    ! n: l" ]0 l' p6 B    d_oi2_w7=ho1
    5 S* f/ Y! k( D6 i$ ?    d_eo_w7=d_eo_oi2*d_oi2_w71 Z0 M! e4 M6 ]7 }. p
        w7_new=w7-lr*d_eo_w71 U( P9 W( y7 M6 G+ r# y8 s
        #求w8_new
    " j2 ]1 D. V% r0 H0 S    d_oi2_w8=ho2
    3 f3 J3 u9 V+ k1 M# w    d_eo_w8=d_eo_oi2*d_oi2_w8
    5 S5 [- Q1 }: D6 F, _- Q    w8_new=w8-lr*d_eo_w8
    9 [5 B6 N5 Q" J! |/ T$ L    #求b2_new
    9 P6 J- x) A5 D+ z6 p1 Q    d_oi1_b2=1) f! h4 N5 N( X  v+ \
        d_oi2_b2=1
    3 H) c: ]; l6 f7 u    d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2. `3 G4 V  ?4 Z, b! t7 [
        b2_new=b2-lr*d_eo_b2
    + K5 y2 {+ \) v    d_oi1_ho1=w5( r9 h3 |1 }; S
        d_oi1_ho2=w6
    ) ~# g  i, R2 i! c: I) ^( J    d_oi2_ho1=w7' ~$ C9 c8 }; {+ E/ N% R% ]/ G; t
        d_oi2_ho2=w8/ F3 U& A  A% U0 N& \, Y
        d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1
    , e; @) [) @" W* y1 R8 C    d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
    ( v* Q% q1 X- |4 p! O! y' x    d_ho1_hi1=ho1*(1-ho1)
    / M0 L  s& y) |% U    d_ho2_hi2=ho2*(1-ho2)
    ' s% M+ `# {. N    d_eo_hi1=d_eo_ho1*d_ho1_hi19 G3 B5 B2 J3 j" |8 c
        d_eo_hi2=d_eo_ho2*d_ho2_hi2
    . Q7 l% S& G0 ^0 R6 O4 o    #求w1_new1 Z( R2 ^$ \0 u
        d_hi1_w1=i1
    4 u- `5 m8 [3 r( e6 f/ K    d_eo_w1=d_eo_hi1*d_hi1_w1- Y. I' A9 F# R* u( c# w" A+ G2 l
        w1_new=w1-lr*d_eo_w13 Y( }. z+ f+ Q: |/ u' i" J5 }/ Y
        #求w2_new
    / @, i7 b  ~/ \1 I& {( Y3 T    d_hi1_w2=i2
    , J: Z0 [- D# S+ u, Q& n    d_eo_w2=d_eo_hi1*d_hi1_w2
    ! v& I9 p6 D3 ^1 R& P    w2_new=w2-lr*d_eo_w28 ^$ X. S  @' z: J8 B. `3 K2 C
        #求w3_new6 z- y4 |0 X9 D/ l7 E
        d_hi2_w3=i17 ]9 V& f1 u* G8 T) ?, o; v$ x
        d_eo_w3=d_eo_hi2*d_hi2_w3# N/ Z! g; w; C6 P; [# _
        w3_new=w3-lr*d_eo_w30 a# a  `" _. B: a: N
        #求w4_new9 h7 T3 v: c- f0 m# F! q7 D
        d_hi2_w4=i2
    4 f" W+ F3 G6 r# T" w    d_eo_w4=d_eo_hi2*d_hi2_w44 [$ z# I+ O, h
        w4_new=w4-lr*d_eo_w4& p( s& o; g3 c) o
        #求b1_new
    7 z9 n7 q8 x/ K9 B) W3 W. j    d_hi1_b1=1
    9 j! k& l; B% J; Q2 t3 u. a: \7 g    d_hi2_b1=1
      c1 O; q# q0 B    d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1
    , }! V: ~/ `! K! k' h7 x    b1_new=b1-lr*d_eo_b16 t0 C' S7 y6 v8 J
        #更新反向传播
    % Z' v: o9 s& N: l5 T/ h    w1=w1_new
    ! X3 n6 V* A. ?0 O9 ~    w2=w2_new0 U, ^  V# D! d2 G! P& ]
        w3=w3_new
    . i- x) X# K0 B* {0 |& k  P    w4=w4_new& g/ B6 P+ A" ~0 M1 m
        b1=b1_new$ z9 _1 Q& R/ T, [" q$ t" |8 c2 |
        w5=w5_new
    + g$ G: {9 l* V. O4 s3 @7 u8 `    w6=w6_new
    % M7 d. ~) m" e$ V& f; ~( P    w7=w7_new
    7 P6 @- P* h" {' l    w8=w8_new
    % C& ~1 r5 U' s    b2=b2_new
    * F; t% k8 l( Oprint(f"当前计算总误差={eo}")% K# A! {, z  [) `( L
    print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
    2 d, }) n9 K1 [7 d4 S' iprint(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")3 D( l  \9 R/ p% R# E
    print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
    ; }2 W8 J& J) |* F& W/ R4 E  x0 g% m3 O; i7 g
    结果
    ! \. m7 D4 D2 L2 G7 E# j8 m( ]( s

    * V4 T2 G- |9 e0 U结语
    3 D; H) Y0 a2 o* \- v1 X可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。) z1 I9 E, z& X+ B% R

    $ S1 o6 b# H6 C- Q2 n, ?; Z补充: {" @: f* v+ i4 g
    程序中d_{a}_{b}格式的变量表示a对b偏导6 E7 l  b# I1 B! A7 I) F+ P$ j7 |9 i
    ————————————————
    + H4 N1 ~! ~* B1 W7 L* B! ?版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ @" g" Z0 _% A, t
    原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954- n2 Z8 F+ d0 A5 E

    - f7 D8 K9 s, ]% |& Y4 f2 E) ]/ r7 ]2 a) @7 t0 f: O
    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-7-31 23:20 , Processed in 2.120886 second(s), 51 queries .

    回顶部