QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3031|回复: 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) c" W3 s( R, V3 J
    , J- W& _$ g- F5 o7 v9 P
    背景( L# {! I! a0 G" t
    初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下) G. ^3 c; o( a% g* D

    ' v) s$ X9 ]9 k【神经网络分类算法原理详解】. D, d3 M3 L" [* \
    . M/ Q4 [. p7 t0 A. t  ?' ~
    注意& E3 w- W, g( j- V, L2 Z7 q0 h8 t
    站长提供的图片有点小问题,我们更正如下% J$ @' N) j; U" ?# \
    1 D5 D% }2 ^3 U4 R8 d$ _" O
    ; b, Q6 F! r6 _! |1 V& [% j( r4 q4 X
    - Z1 M' x( P: k, H) s8 p
    问题
    0 U& J) m! i2 s( P根据上图所示,我们有已知9 h. s, ]2 x* }2 h
    ! i  C* }6 Y/ r; Z2 H* [' _
    #输入层
    $ G+ G: {5 ?. O4 D- [i1=0.05, W6 Q. E: {# M+ W1 Z. z
    i2=0.1) H6 s# `" `% E# r7 {; o, u

    . [9 t: Z6 |3 c#输出层
    - _4 \- W) D+ jo1=0.010 Y" D, K- N" I4 O5 h
    o2=0.99' J, f8 b& H# |  L5 v( ]
    这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的
    4 H; c8 T: `  A. [6 g6 b2 ~$ `/ F# b9 t; }. x( C( ?
    神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b15 \0 j; d; t9 {2 Y  I
    2 I+ h0 J- Y& w" h# M2 ~  W
    神经元h2的输入  (hi2)=w3*i1+w4*i2+b19 Z1 t6 G: ~; A

      ^# `1 P' j% g* d. P7 n9 A神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出7 U3 ]( B  L+ X/ g) x+ j/ R# U
    8 W  t# R3 r5 ~: G) |
    神经元h1的输出  (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
    . _8 H$ T+ G/ S; D+ K: G' ?& ]* I
    * }: w% V; x) ]1 i# |9 K同理+ Q! u$ N/ L! f" e# P

    0 a3 _8 c2 W2 p) o" Q+ I& L神经元h2的输出  (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))# Q# h) d, j- t9 t2 L2 b* W3 g5 e8 S
    ; V# s/ n! f# l! Z
    接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
    1 y0 u$ q  w+ [
    + {- w( q7 o2 \' x0 Q) _  W+ J神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2  z- D# q2 g0 Z" N  v3 Q

    . B1 ?. i0 c/ T: t- X5 }2 V* m神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b2
    # M/ [) b( w$ R# G
    8 c* s- F5 Z, ~9 `+ o/ N. Y再经过非线性变换Sigmoid函数得到
    / @7 b) a$ H& E) O1 Q2 E! u6 t1 c8 q/ ]: Q
    神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))- h( U2 P: |( D/ ?: T$ F
    ; _" ~  K; w; Y' u8 P; c! i
    神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))( v9 p( a# w# j: ^
      {5 Q% z; n' y, O% n- A
    我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
    - e, V: U' E- T% Z- Y
    6 n$ Z( a3 j* P% C8 [% ?/ |损失值  ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2
    ) F* n8 g: K4 R- W- g2 B7 C
    1 ]; @1 Y0 L0 N0 z) I2 r由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
    0 h3 q6 Q/ }/ F1 N( M6 S+ }2 W2 n) U3 a* m" W7 |3 e2 Q% t9 Q7 ]
    学习次数 (learning_time 简写为 lt)我们限定最大为10000次  B  x- b3 f8 z- D; i
    $ b1 G$ V1 u8 M0 u5 Y+ n
    学习率 (learning_rate 简写为 lr)我们设定为0.5- |7 q: @; m$ h$ E
    + C' _# B( D% m4 T: x- Y
    依次求解代求参数
    / W5 X4 X, {$ S$ l; W0 D. s0 \- w) n; \0 X* q0 C+ p
    w1~w8,以及b1,b2* R2 ~- n9 [6 i" R

    $ b! x6 T/ N5 k' P; K  J  B* [
    + n8 ~/ Y% O+ v% A, T  P: B
    % c! i% f6 k. E& {损失值 (eo) 的偏导数2 L  ~7 D0 y* ^* H$ H* g0 K

    8 T* K. m+ j  x8 k再更新该参数,更新公式为, I2 s, I7 B  S& w8 v* a6 G/ @. Z! V$ L) Z
    " }: Y7 \( ?, \
    参数_new=参数-学习率*偏导(eo,参数)
    5 G. f, {' s6 f( b7 |4 O9 m! n随后进入下一轮学习
    " m5 [0 W7 x3 ?5 C2 G
    " J  E5 `7 o; i+ }+ j终止条件(满足其中一个即可停止训练)
    5 R5 X, [5 [) ?/ \' W! C
    ' m! I% x& ?; {) R6 V1.学习次数达到上限
    2 D' X$ O- c3 w7 D  Z7 y
    8 l* R, r: n4 A3 h1 w% V2.损失值达到可容忍的范围/ R$ Y+ a! D" _8 `0 Z! h
    + C9 X* R8 G8 R8 I2 r& z* `* Z
    导数
    ' f8 M0 s9 J* [$ O5 Yf(x)=1/(1+e^(-x))的导数是
    % f/ |9 ?! l  A; g. Xf'(x)=f(x)*(1-f(x))
    1 h0 }) V, {+ s* c+ u9 k源码/ }# ?( l5 x8 \! Q* J7 p5 p
    import math- q- O0 p5 {- N
    8 x6 }; s4 J* o: o
    #参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】. ]% e3 _/ W! n2 v- h) @5 u8 a( ?
    #网址中图片有误,请看我博文上的图片0 R4 m/ s! d3 F! w

    9 x" w9 N; u+ N1 R# l: |#输入层, ?  j- l) B. M: Z5 d7 I5 _
    i1=0.05
    " J  f3 F1 S( c/ D: b$ u0 m/ Wi2=0.1
    ) o3 C6 J* ^9 d#权值参数
    0 A5 U4 n  z/ m- Y4 t% U8 z/ N% ?/ I5 Tw1=0.158 v8 `* X% S2 _- l2 P
    w2=0.2
    4 Q3 N3 {: Y% j' `1 b& `: {) tw3=0.25, Y2 A" S3 t! @, \, T
    w4=0.3
    2 @% ~6 t7 O2 `" V! Sw5=0.4! j0 `% d# l7 d$ ]" _$ H- }' [
    w6=0.45. z5 M5 P7 b% D" U% F' K) F
    w7=0.5! F: s/ c; W' m) X& Z- E; q# @
    w8=0.55% N, c. \3 U8 c# Y
    #输出层标记(即期望值)
    , v1 H3 F7 i* l( L8 u/ S( bo1=0.01+ L0 Y' o0 g, Y3 G' k0 }$ a6 d
    o2=0.990 r* H( \* T# O! F0 d% F
    #偏置项参数7 E; x% F4 K3 j! N9 D0 ~, g) k
    b1=0.35
    - S, p, j3 j7 Sb2=0.6
    + F% Q& v: ~. U( R- h- H4 ]6 x, Q, T% _" S
    #学习率; \+ S7 Y) ~6 _+ ]
    lr=0.5% Y4 `5 c+ J. Z
    #学习周期$ J" l5 S% }* h  n- H/ V4 B; b
    lt=0
    / r1 Y- Z6 t  T: _max_lt=10000
    4 H; \9 x  e) }4 N+ a; o" H, ^#允许误差3 W/ `; a  }$ _+ @2 o9 v' D
    eo_allow=1e-5. o4 I9 h2 Y* i8 l& L8 a  P
    4 X# ?' W& p: _% m+ }
    #线性转换
    9 J) Z  ]. Q$ M: Adef linear(w_one,w_two,i_one,i_two,b):# r& @8 r3 `! }$ x- e* c" a  J
        return w_one*i_one+w_two*i_two+b# V- D7 r' i9 W6 {3 [) q/ K6 g8 r
    #非线性转换
    ( M8 y- u, L# a! Qdef none_linear(i):
    # @; Z7 l+ F+ O% o    return 1.0/(1+math.exp(-i))
    $ Z0 _. }& N9 ~, S4 Q2 @, C! @) Z3 x0 M1 c/ A7 ^
    print("训练开始")8 ~8 Q+ t3 u7 i. d
    #学习周期结束前一直学习
    8 k$ q7 e* j8 Twhile lt<max_lt:3 a. b, V1 g+ N  Z7 o# A1 o
        lt+=11 s' u6 D3 U0 `* D6 e( V4 i
        #求h1和h2输入值
    , }5 m+ M1 S8 f% \) F4 q    hi1=linear(w1,w2,i1,i2,b1)
    ! G, V4 ^% `" r: {9 u" H  a4 m    hi2=linear(w3,w4,i1,i2,b1)
    ' N9 j9 V4 B) i8 `3 I5 T1 e- N- I) j* _    #求h1和h2输出值3 H, X- r* j$ k! y7 }) L
        ho1=none_linear(hi1)2 y6 C5 V* D& i. f2 f& ]) c
        ho2=none_linear(hi2)! n6 Y  ^* r) w8 w
        #求o1和o2输入值: T! p- l& ^6 [( B. M& E6 _7 f
        oi1=linear(w5,w6,ho1,ho2,b2)1 P. A  W  f1 S" r0 K, S: o  H
        oi2=linear(w7,w8,ho1,ho2,b2)
    1 l8 a: y2 U* p6 A0 Q    #求o1和o2输出值3 D$ }6 u' I, P
        oo1=none_linear(oi1)' L1 I5 H  ^0 V
        oo2=none_linear(oi2)3 x6 H1 q1 r6 Q, n# _, ^
    9 \0 d- G, S& w  d6 n2 J, D( ]
        #求当前计算总误差
    ! p, W  Z3 K. F. B2 V    eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/27 ]1 n0 Z; P; Y2 ~
        print(f"第{lt}次训练,当前计算总误差={eo}")# Z5 |: c3 e! I3 m0 _  J" V
        #误差已经在允许范围,退出训练! W. l& U$ k# ~- L' Y$ u( i! H
        if eo<eo_allow:
    " l# p0 C9 e3 r5 F        print("误差已经在允许范围,训练结束\n")" T2 B- P8 i2 k6 e% d4 e
            break
    - b3 ~2 n. M' I" }8 r    #偏导1 i! f3 m" h7 ~3 E: J' S/ e6 c& K
        d_eo_oo1=oo1-o1* w  V9 j9 n* B9 e7 m
        d_eo_oo2=oo2-o2  D" o4 a- t8 {; W/ g8 t. J
        d_oo1_oi1=oo1*(1-oo1)
    5 {$ Y9 k4 P0 Y    d_oo2_oi2=oo2*(1-oo2)
    4 T6 [2 w$ W  p$ n0 V* P    d_eo_oi1=d_eo_oo1*d_oo1_oi1
    . h" D9 q+ ^/ H! A    d_eo_oi2=d_eo_oo2*d_oo2_oi2
    : ]3 ~3 h* k  Z) R/ }# O/ W; W& F    #求w5_new
    9 L( H3 A( _$ [6 F. l. Y' r    d_oi1_w5=ho1# ]- G% [2 K1 M$ S7 m
        d_eo_w5=d_eo_oi1*d_oi1_w5
    , s5 z1 e; J: D. e* m7 P    w5_new=w5-lr*d_eo_w5) o3 b2 Z$ W7 l# L6 Q  t8 \3 F0 z
        #求w6_new6 E3 g, n3 L, s
        d_oi1_w6=ho2# G/ _6 m% d" f8 h8 F2 a
        d_eo_w6=d_eo_oi1*d_oi1_w6* d; M$ P. o! v3 l& W' j3 R
        w6_new=w6-lr*d_eo_w6
    + a+ T# R5 f) |" B    #求w7_new9 k6 Z6 n; h' a" u! T
        d_oi2_w7=ho1
    ' l/ D; u# W& B' o- X: ]    d_eo_w7=d_eo_oi2*d_oi2_w7
    7 t$ w' x- c* j- d9 l8 O  _$ w    w7_new=w7-lr*d_eo_w7
    + V/ k2 p& t7 m/ k: R; e    #求w8_new  a6 [1 f  _: f% {' j) C5 g" O
        d_oi2_w8=ho2
    6 J9 [8 L/ C% `+ p2 e2 v    d_eo_w8=d_eo_oi2*d_oi2_w81 k8 }7 \# v2 C4 e! F* I) t
        w8_new=w8-lr*d_eo_w8
    6 z3 j3 h0 _  h1 H0 g' H    #求b2_new
    + K8 k) j2 p9 R' t. x! l) H    d_oi1_b2=1
    6 b" w8 q' {5 E" P$ \    d_oi2_b2=1
    8 Z$ C! u$ G1 f    d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2
    # f+ R0 P; s  K1 _    b2_new=b2-lr*d_eo_b24 N+ {" M' Z8 a+ f% {
        d_oi1_ho1=w5
    $ }9 k8 ?9 q( m6 {    d_oi1_ho2=w6
    $ P* h% [* _2 F9 t1 d$ f    d_oi2_ho1=w7
    6 a% [; A7 E' N- ^    d_oi2_ho2=w87 T: B) N) N9 a
        d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho1; ~6 [% p! b) ^' I( i9 R
        d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho2
    ; `2 G3 f* I& B! _; {: i    d_ho1_hi1=ho1*(1-ho1)
    # C8 E6 H* \' j% }7 ~, s' S8 V- z    d_ho2_hi2=ho2*(1-ho2)
    6 P  j3 T+ e7 m: V/ W' j9 X    d_eo_hi1=d_eo_ho1*d_ho1_hi1
    0 b4 t$ f3 t9 M9 {* \    d_eo_hi2=d_eo_ho2*d_ho2_hi2
    ( j2 x7 C/ i; e3 H. ]    #求w1_new' Q) O! E+ [6 C1 E' b
        d_hi1_w1=i16 I! S" b" E$ A4 h' e! d) B
        d_eo_w1=d_eo_hi1*d_hi1_w1: A6 a3 W& L: x" S: I
        w1_new=w1-lr*d_eo_w1" {/ r' W- [* d% F# g, [
        #求w2_new1 o9 r2 y" W. h
        d_hi1_w2=i2
    ! @# ?7 l. x$ _3 |  f    d_eo_w2=d_eo_hi1*d_hi1_w2! `+ P2 ^8 v$ F+ s+ Z% B4 d
        w2_new=w2-lr*d_eo_w26 f% ]. p5 {( x3 ]/ N$ p
        #求w3_new! h* I+ F5 r9 @* B: k5 i
        d_hi2_w3=i10 A3 l* v- R, z- t6 O+ a
        d_eo_w3=d_eo_hi2*d_hi2_w36 ~) _: {9 h. k- S- A" q. O: G- M( L
        w3_new=w3-lr*d_eo_w3. p. H- Y- u9 }0 N, S# K
        #求w4_new8 g( z% ?& I+ c7 U7 N0 t: c# ^
        d_hi2_w4=i2. L0 h0 S4 Q  l# e( M( ]$ E
        d_eo_w4=d_eo_hi2*d_hi2_w45 [( G" l- I% N* x- |
        w4_new=w4-lr*d_eo_w4
      O/ D: Y0 ~1 K8 r9 s    #求b1_new
    # X7 N5 q* v, \8 B    d_hi1_b1=1& Y  E/ @( L! B
        d_hi2_b1=1
    ! n0 y1 Z  h; O+ p    d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1' ?6 v$ w0 {7 \4 b
        b1_new=b1-lr*d_eo_b1
    % e' @' H, [! N+ c    #更新反向传播
    $ c: j' a% v% N: Z: t) x& s9 M    w1=w1_new
    , k3 z7 }; e6 E$ Q, }    w2=w2_new8 E& C- g, J$ r5 D& [& p$ x
        w3=w3_new
    4 U1 e% A  U8 {9 u4 E$ ^    w4=w4_new
    ( L) W% L1 L7 e8 h# u- r, X/ A    b1=b1_new
    ( f: L* \8 B8 p    w5=w5_new; r/ w9 u) l5 U* r  F  V2 v/ s
        w6=w6_new
    3 R0 u- Y+ J& c    w7=w7_new
    1 Z9 [& t7 T5 p3 C2 t    w8=w8_new6 h0 ]: I; ]7 ]
        b2=b2_new
    6 E: S# d9 T' |5 }! o" Pprint(f"当前计算总误差={eo}")
    8 p% a' p3 c$ M' V9 ]print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
    0 y1 T+ r$ f: o# cprint(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")9 Z0 l$ Q) ]- R# B1 d
    print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")5 \% u- ^7 H" y7 z+ G

    & x+ S, H6 a7 X5 Y% t6 s, [/ c结果
    8 r6 D# g# G' j0 ~9 D7 J( z$ S# u
    ! v5 I* n+ \" @' j- Q
    ! M- o% |! @# r( t, I$ w结语
    ; R5 y, l2 O. |5 I9 l; Z可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。
    0 I8 b) ?: C, z- q# L* N" V! @( s! F% m: m
    补充
    9 ?; L' _. v! K$ @2 B) L$ _程序中d_{a}_{b}格式的变量表示a对b偏导0 D, W2 v- T2 B
    ————————————————% O$ e, G" A, K
    版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ; L4 [; l  T: ^  D原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
    8 s+ D4 ~' a1 ^. }/ c- |0 j0 r7 T
    ; f9 ]; Y- C; F- I& {1 S$ r
    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-6-12 09:31 , Processed in 0.425754 second(s), 51 queries .

    回顶部