QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3005|回复: 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实现)+ ?- V/ k( I( O
    " l! t1 w. s5 B9 D
    背景, P* x$ b& ?; p0 Z! w  ^: w
    初次接触反向传播算法,根据C语言中文网的站长提供的思路,照着做一遍找一下感觉,其中链接如下
    . l7 V) \# }* v: [0 x/ F6 R; _& r- F& n0 ^
    【神经网络分类算法原理详解】! D) R0 u  ^* F% C2 a
    9 g- h5 x. _1 k
    注意
    1 g7 ~; @! a: E) L& [; u4 d- p站长提供的图片有点小问题,我们更正如下
    & m5 Y% I. i* `7 U, C! N5 T1 K/ n, U+ F. T4 T

    " d4 \" K# C; z% A( Z, m4 K; x7 c+ I
    问题
    , v+ {2 x2 w  N& w: e根据上图所示,我们有已知
    : z3 i, K* @0 h# R
    $ l, e: @2 u, _' F- [% a+ h. e! D#输入层+ ^! s2 r' l+ \  i" q" \* n5 o6 P
    i1=0.05
    * O! c# v2 q) ]) R! D3 U% A; Gi2=0.1
    # D0 x) Q7 h) [" k9 E% f( Z' A! _. s; Y
    #输出层" N# T" H  z9 S' ~
    o1=0.01
    . L  j9 |1 h; D( L4 Y, uo2=0.99
    & J, P5 c' Z5 P# U( |: G8 i这个神经网络是我们假想的,我们假想从输入层[i1,i2]==>>[o1,o2]的过程是这样的3 o+ K: Q# J7 V/ s' G0 ]) U5 p
    5 c: z- D) V) P( H* T8 j
    神经元h1的输入(h1 input 简写为 hi1)=w1*i1+w2*i2+b1$ O. y- X: L5 }' W; F7 r$ b

    9 j6 T0 Y* _1 t; V8 ]神经元h2的输入  (hi2)=w3*i1+w4*i2+b1
    2 \& K% C/ |  ~  r8 g2 M4 H7 k& e+ i, {# J" p' W9 O
    神经元h1接收到输入后,通过非线性转换函数【这里选择Sigmoid函数】变换得到神经元h1的输出
    & D/ U5 C4 |4 R: ^- m
    6 w/ o5 `) y/ X神经元h1的输出  (ho1)=1.0/(1+math.exp((-1)*神经元h1的输入))
    + f. ^! {! g1 D5 C5 a) u
    1 G" a3 ^, A  h2 P/ [同理
    2 M9 z" b" A7 m2 R1 f1 u' E) ~  C; I1 y9 l  |
    神经元h2的输出  (ho2)=1.0/(1+math.exp((-1)*神经元h2的输入))
    3 L% S3 w+ z, p& A' O( f, J: s2 T7 P+ b- R
    接下来我们再把隐藏层当作输入层,输出层当作隐藏层,类比推出有关神经元o1,神经元o2的一些表达式
    6 Y% d" E; j# r0 `. N, f$ K; M, F
    神经元o1的输入 (oi1)=w5*ho1+w6*ho2+b2
    4 y8 b. X6 |/ y
    ; |+ k" X, w/ L6 e8 k. I神经元o2的输入 (oi2)=w7*ho1+w8*ho2+b24 U5 n# T0 K0 @7 F# ]/ D
    3 L+ Z  x4 ]$ I% V; ^5 G$ s* J
    再经过非线性变换Sigmoid函数得到
    5 x  D% s; ?2 Y% w4 |- Z7 ~9 I
    4 l6 ^, A8 r5 @6 b" L4 o- U神经元o1的输出 (oo1)=1.0/(1+math.exp((-1)*oi1))0 C* B1 g' M6 `/ l- J+ A

    # z$ r( ?3 w( V7 F  i) Q; `神经元o2的输出 (oo2)=1.0/(1+math.exp((-1)*oi2))- e9 _: |0 F* b- w3 X3 I

    $ _/ R. |& P+ N6 V我们将得到的神经元o1输出,神经元o2输出跟我们知道的期望值o1,o2进行比对,定义其损失函数为
    3 H3 I6 W& ~" d' \+ A! M
    8 s' v) u# S3 R1 v. |/ t5 G% J5 V损失值  ( error 简写为 eo)=((oo1-o1)^2+(oo2-o2)^2)/2' y, p: |. o9 v4 m; `

    9 Z4 m& }% j8 @6 P  f由于我们的期望值精确到小数点后两位,损失函数为平方,所以我们仅需让损失容忍度(eo_allow)调整到1e-5即可满足
    6 @( A, c: j7 ^4 |: D* v
    ( W- g6 q. r! K5 z" S) m6 T学习次数 (learning_time 简写为 lt)我们限定最大为10000次
    ' w8 E# m, F' }" f6 ]% P# v9 L9 v/ Z$ O7 M* o) q! V
    学习率 (learning_rate 简写为 lr)我们设定为0.5, W$ E7 O% C" U/ d7 t& L$ U

    + v9 ?% p' I7 @! S, s% c. c& C依次求解代求参数
    / m- b/ T  f% j1 Y  g* i1 X, K# G
    ) ~  U, [- q9 W. i6 b  ^! aw1~w8,以及b1,b2
    ; X  y# l: F2 c7 ^* d% B. R0 Y& Q; N; ^: x: B, J% \# b% K
    8 B, E4 l3 ?3 m% C% P4 I1 o! l

    ! \% R+ D- D- B; _6 P" A6 E2 ^损失值 (eo) 的偏导数/ H% j4 G4 I4 t8 j- z  l- `$ P1 U; G
    % G/ p1 g2 D" Q/ u& Z0 h
    再更新该参数,更新公式为* s) e2 t7 n2 L& d

    7 N2 [1 e: V# G, i7 Y, n- j5 v参数_new=参数-学习率*偏导(eo,参数)6 r; I2 _4 f3 n) B: ~- [
    随后进入下一轮学习
    5 J5 S3 N, L- w' f! l/ c4 v
    " h7 U8 q$ h. L) y7 c: d+ \0 b终止条件(满足其中一个即可停止训练)# t: a: D  t6 @8 E
    3 [0 n5 N9 G) E. [9 K* }  d
    1.学习次数达到上限
    . J4 Y: f% Q5 W/ i& i
    5 D2 i' w( w# N0 x; p$ b# J2.损失值达到可容忍的范围% {: G4 R' U9 I9 L. N7 b0 |! |1 F
    3 d, A$ G4 v) p# r% e
    导数, w+ |/ B$ D8 g/ p4 l6 S. X
    f(x)=1/(1+e^(-x))的导数是" i" l0 e6 \. q6 {2 h
    f'(x)=f(x)*(1-f(x))
    / Q: Z7 f& o2 {6 l源码
    7 ~9 m( U( r& N3 qimport math
    & H9 y" X: Z7 o+ I& n9 O. z8 ]6 J7 S! D) e/ e" {$ I9 g4 v# p
    #参考自网址【http://c.biancheng.net/ml_alg/ann-principle.html】
    ( C4 r7 Z7 ~) ^. j* O#网址中图片有误,请看我博文上的图片" k. I0 O" p# A/ s' Z

    9 O, S1 h0 z6 [7 P8 n0 B( W" ^#输入层
    8 ]& t% E  a7 o0 C5 C3 Y. wi1=0.05
    # J1 a* K/ f$ {& v. bi2=0.1
    + V3 O, Q: w5 u5 h, d. L#权值参数  E* }3 Q0 R/ t
    w1=0.15
    ; F2 a: X- F1 F# J! w" |9 qw2=0.2
    4 b6 Q* g  v. E6 r+ j3 Iw3=0.25
    4 @; Z& g) y. D2 W5 Tw4=0.3/ H/ @/ @. `: V" {% X5 p
    w5=0.4
    5 v7 n. z. D8 m; s7 M  `& Lw6=0.456 ^) p! c2 J* q. Y8 C6 p7 \& u3 E
    w7=0.5
    3 g& E1 I! B  kw8=0.55- y- F& w3 K; b, U# I: a
    #输出层标记(即期望值)
    ; P9 T" G7 k1 {/ y5 go1=0.01) f4 d5 j' o* M" E" m
    o2=0.99# B' V6 F1 Y0 o8 y. V1 o
    #偏置项参数
    . P5 s, T9 W  w9 g( a% E" a# c* E3 Gb1=0.35: m) T, R" h: K- b3 Z5 q+ M
    b2=0.67 a8 e- a6 i/ `( F* ]! e2 y/ m

    $ P5 v7 c; {" Y7 X8 u' {+ z#学习率
    - n) o, j9 y. w8 w: }+ X$ Llr=0.5$ a. N. Z3 I3 S8 K0 d/ h$ W
    #学习周期
    9 Y7 w/ D7 Z' g0 H' G3 L" G: rlt=0
    ( I' d4 N3 b% r9 J% J- J) pmax_lt=100000 g: c; ?7 q1 c9 P- l
    #允许误差5 G/ v! s' ~4 q
    eo_allow=1e-5
      l) i5 f; f, F% e. K" g* P
    1 A! }; _* K2 `) S; z! R#线性转换
    . E8 u) `0 w; C. ?- `def linear(w_one,w_two,i_one,i_two,b):
    + K4 f# S. Z1 h, R8 @; y    return w_one*i_one+w_two*i_two+b# |  J1 |6 G7 T1 M* h/ W7 f
    #非线性转换
      c3 v+ q! E# T2 |8 Sdef none_linear(i):( ^, [- B) `2 n! c# [) m+ I
        return 1.0/(1+math.exp(-i))  O. c4 `7 s. q! _: ]8 `" x' [/ J
    " H  c4 R  N$ e) R+ m; r* W
    print("训练开始")
    % W2 ~8 Y/ R& w, E7 b, n#学习周期结束前一直学习
    + Z. Y' v- w: D' i  xwhile lt<max_lt:
    # _1 B) j) a# F& ]    lt+=1
    % z* `' a" A7 F    #求h1和h2输入值
    9 \, ?* o' q& u. p! Q; V: W6 T% Y    hi1=linear(w1,w2,i1,i2,b1)9 B: F0 W; P$ U, _, d
        hi2=linear(w3,w4,i1,i2,b1)* I9 x$ P; K( M5 S* l* e6 I
        #求h1和h2输出值
    * G3 |2 H& b* X4 V* J    ho1=none_linear(hi1)
    2 J3 r  k0 M. }3 Z. x- }  |, |5 `    ho2=none_linear(hi2)$ S  \) @+ F0 c: y
        #求o1和o2输入值* `  G7 g& {4 z
        oi1=linear(w5,w6,ho1,ho2,b2)6 {3 r3 h; H' w6 J& |3 L: J
        oi2=linear(w7,w8,ho1,ho2,b2)1 M  p3 C8 B% }8 x% z7 s5 R
        #求o1和o2输出值1 V- q/ B- r# {& r3 B2 a
        oo1=none_linear(oi1)
    0 Z7 E9 h' v3 l, |0 a+ x; D    oo2=none_linear(oi2)
    + i0 C4 U8 O9 X3 ^; ~' {
    ( k2 D# \# w: M" ?    #求当前计算总误差
    # E  p* W) ~0 E' s* U- m    eo=(math.pow(oo1-o1,2)+math.pow(oo2-o2,2))/2
    6 M  B+ u& Y. j  p    print(f"第{lt}次训练,当前计算总误差={eo}")7 \/ i# h5 M( H8 s( r
        #误差已经在允许范围,退出训练
    - }" Y9 R6 {, W9 O9 V: @7 s2 q    if eo<eo_allow:4 j( U5 ^. {# k* {! l9 N- R
            print("误差已经在允许范围,训练结束\n")
    $ h$ d% t3 I8 R" ]+ z        break- [) R, k+ R# \* T. q) Y
        #偏导) e) C) Z$ U  R6 j2 K; h
        d_eo_oo1=oo1-o1
    1 W# D0 q0 T  S# O* B    d_eo_oo2=oo2-o2
    3 q$ U/ X2 |4 g    d_oo1_oi1=oo1*(1-oo1)
    ' u2 L6 u2 w- a0 P6 W    d_oo2_oi2=oo2*(1-oo2), W2 q- d6 _: h2 n
        d_eo_oi1=d_eo_oo1*d_oo1_oi15 L) o3 W  q/ [8 K; X, k7 }$ n
        d_eo_oi2=d_eo_oo2*d_oo2_oi2$ I% u. C- y2 Y+ _/ I+ N. R
        #求w5_new
    3 Y! s9 H0 B( k0 i: ~    d_oi1_w5=ho1# H. x9 D" b! i% S
        d_eo_w5=d_eo_oi1*d_oi1_w58 `* ^7 K! |4 d
        w5_new=w5-lr*d_eo_w5
    ( V; T/ O0 Z2 Z6 W, }    #求w6_new
    0 i5 R4 R1 A" }' O8 T$ j    d_oi1_w6=ho2' `4 y. y+ {1 T1 D/ E2 ^$ K% u( O
        d_eo_w6=d_eo_oi1*d_oi1_w6
    % Z- J  ^+ `% ]4 K2 ]2 B' w; f' h    w6_new=w6-lr*d_eo_w6
    % j9 m0 K$ d; a% M    #求w7_new
    : `5 ?# l- [& I7 o7 }    d_oi2_w7=ho1
    9 Z4 R2 P9 _$ O, ^/ |    d_eo_w7=d_eo_oi2*d_oi2_w7
    : |4 ^' U3 D5 b7 ?    w7_new=w7-lr*d_eo_w7
    5 X% Y2 P- h- h4 D5 e* h    #求w8_new
    . [3 W% U" y5 }/ \6 X    d_oi2_w8=ho2* V5 t& k, r. T# Q
        d_eo_w8=d_eo_oi2*d_oi2_w8
    3 r: B2 L4 z& C: e. Z/ B, U+ H    w8_new=w8-lr*d_eo_w8
    ' Z$ n! g0 N9 k0 f# M    #求b2_new* `1 r* [1 g4 S: T  C/ D$ E) }( {
        d_oi1_b2=1
    ' ^) ~/ ~% I/ H    d_oi2_b2=1
    5 u! v8 M& M; W+ h. P# b    d_eo_b2=d_eo_oi1*d_oi1_b2+d_eo_oi2*d_oi2_b2& ], v1 x4 b! ]7 _
        b2_new=b2-lr*d_eo_b2$ ]& `1 m1 c! g; d
        d_oi1_ho1=w5
    + ^/ v/ y, v, V6 }  A    d_oi1_ho2=w6! Q+ i4 \* e6 O
        d_oi2_ho1=w7
    - a: s4 j& \1 m0 R9 _    d_oi2_ho2=w8
    ' S, [. f0 @$ F' Y% }    d_eo_ho1=d_eo_oi1*d_oi1_ho1+d_eo_oi2*d_oi2_ho15 L9 p& p! V; v% T3 X2 ?( c
        d_eo_ho2=d_eo_oi1*d_oi1_ho2+d_eo_oi2*d_oi2_ho29 v( g0 n: J6 M7 c0 ?- f$ t. r
        d_ho1_hi1=ho1*(1-ho1)# ^5 W# L& P, |' t. }% s
        d_ho2_hi2=ho2*(1-ho2)
    9 X4 z; U8 I3 A    d_eo_hi1=d_eo_ho1*d_ho1_hi1" g' e" Q# v  \0 g, }% q3 B
        d_eo_hi2=d_eo_ho2*d_ho2_hi2
    + {7 d" e  r+ A# k0 `7 [% b    #求w1_new
    9 f. ]5 c" {/ I    d_hi1_w1=i1
    & E: n. O  s6 _. o. ?    d_eo_w1=d_eo_hi1*d_hi1_w1& M& c3 I" O9 o' o/ C4 }, D
        w1_new=w1-lr*d_eo_w1
    7 |, P$ |' q! D    #求w2_new
    ; j8 P+ X! H. ^2 D3 D    d_hi1_w2=i2
    , R2 W/ A* r' j3 ]    d_eo_w2=d_eo_hi1*d_hi1_w2
    3 _# @2 D- Y! {5 q) U' G# t; W2 F    w2_new=w2-lr*d_eo_w28 }6 \" ]4 I  |& l
        #求w3_new, [# A; x9 Z3 `" l7 L2 Q" D
        d_hi2_w3=i14 M, [) O! m- Y5 L7 L
        d_eo_w3=d_eo_hi2*d_hi2_w3, l5 M( C2 O# _0 x
        w3_new=w3-lr*d_eo_w3
    1 _. r: ~: k9 u5 I; W6 d    #求w4_new
    4 w8 V( J( H  n% d; Q: u    d_hi2_w4=i2/ D" {4 F$ B" ]# R4 d8 N7 e5 f5 Q
        d_eo_w4=d_eo_hi2*d_hi2_w4
    * F/ p$ q" \8 p, x- A9 H2 x2 t% R    w4_new=w4-lr*d_eo_w4; x3 t  m$ p2 z# W$ E2 M
        #求b1_new, C% j7 y( `& p# H4 ], m3 Q
        d_hi1_b1=1
    4 n, ~7 o2 s( U# D    d_hi2_b1=1
    $ z+ y  s% J8 b0 V' J0 G: m# q# A    d_eo_b1=d_eo_hi1*d_hi1_b1+d_eo_hi2*d_hi2_b1' S8 ]- Y, f+ S+ v
        b1_new=b1-lr*d_eo_b1
    * \* N$ @+ ]. ~) U    #更新反向传播
    1 t! ~% t! O2 h8 r  I* `    w1=w1_new
    ; J: I4 Y3 y1 ?8 E* ~+ Q1 k    w2=w2_new7 V1 P* O9 G; H# K% Q
        w3=w3_new8 C% W, t3 h- P( n2 s
        w4=w4_new
    3 k6 Y: f; o  z3 F, s; M1 Q: k    b1=b1_new
    5 N& H3 R8 y  T$ K    w5=w5_new
    2 i4 F1 {; q& e# W: E$ Y' y5 H    w6=w6_new. X2 {' t2 i: L. {, k
        w7=w7_new+ g7 x) q9 P  G% |1 Y; Z
        w8=w8_new8 \% P5 q4 W  d, {
        b2=b2_new9 g* o. |& k$ U; V$ w6 F) X
    print(f"当前计算总误差={eo}")
    * m% b5 l* U/ }- l1 {print(f"w1={w1}\nw2={w2}\nw3={w3}\nw4={w4}\nb1={b1}\n")
    , I1 f( q( S  O% h4 ?, R0 Gprint(f"w5={w5}\nw6={w6}\nw7={w7}\nw8={w8}\nb2={b2}\n")
    8 B# R, d* z1 K0 `print(f"期望值:[{o1},{o2}],预测值:[{oo1},{oo2}]")
    ) v: j0 c' N) ]8 W$ ^& }0 x
    0 y, i; K& b7 z; ?. d5 |结果
    ; m' h& G( M" X; ?) L
    % m( {) j) A/ _+ t% B$ C1 S; M$ M. b1 C
    结语" r# v9 H8 p- v1 {
    可以看到,在经过七千多次训练之后,我们找到了一组参数满足我们假想的关系,本次人工神经网络训练完成,反向传播算法体验结果良好。
    ! t6 n7 V4 }3 m1 j/ B. Q0 h5 h6 v: n: }2 {. ~& \* z5 m. D- T
    补充
    1 ^& j  A9 J; U2 l- Y程序中d_{a}_{b}格式的变量表示a对b偏导1 G  ^6 r6 ^& j8 Z
    ————————————————+ q9 y# B# ~$ k
    版权声明:本文为CSDN博主「冰凌呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) T. b% L2 V% s% t" U) u# u
    原文链接:https://blog.csdn.net/qq_36694133/article/details/126667954
    & h( A) c- y+ i: r; M% E( N5 I) w, |) \. E) ]9 a/ M
    - Y# X# j5 W7 @
    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-4-17 11:43 , Processed in 0.393541 second(s), 51 queries .

    回顶部