From 33477fd296af62130163017d23ed0826df10a533 Mon Sep 17 00:00:00 2001 From: Morten Hjorth-Jensen Date: Sun, 13 Oct 2024 17:18:30 +0200 Subject: [PATCH] update --- .../_build/.doctrees/environment.pickle | Bin 484338 -> 538155 bytes .../_build/.doctrees/exercisesweek41.doctree | Bin 251793 -> 253032 bytes .../_build/.doctrees/exercisesweek42.doctree | Bin 0 -> 88770 bytes .../_build/.doctrees/intro.doctree | Bin 53133 -> 53176 bytes .../_build/.doctrees/week42.doctree | Bin 0 -> 605741 bytes .../html/_images/exercisesweek41_16_2.png | Bin 21978 -> 22302 bytes .../html/_images/exercisesweek41_22_1.png | Bin 20216 -> 22492 bytes .../html/_images/exercisesweek41_5_1.png | Bin 22046 -> 22024 bytes .../html/_images/exercisesweek42_34_0.png | Bin 0 -> 40673 bytes .../_build/html/_images/week42_173_0.png | Bin 0 -> 18573 bytes .../_build/html/_images/week42_173_1.png | Bin 0 -> 14628 bytes .../_build/html/_images/week42_173_2.png | Bin 0 -> 31496 bytes .../_build/html/_images/week42_173_3.png | Bin 0 -> 17868 bytes .../_build/html/_images/week42_242_1.png | Bin 0 -> 4442 bytes .../html/_sources/exercisesweek41.ipynb | 2 +- .../html/_sources/exercisesweek42.ipynb | 467 ++ .../_build/html/_sources/week42.ipynb | 6209 ++++++++++++++++ .../_build/html/exercisesweek41.html | 242 +- .../_build/html/exercisesweek42.html | 825 +++ doc/LectureNotes/_build/html/genindex.html | 10 + doc/LectureNotes/_build/html/intro.html | 10 + doc/LectureNotes/_build/html/objects.inv | Bin 1162 -> 1197 bytes doc/LectureNotes/_build/html/search.html | 10 + doc/LectureNotes/_build/html/searchindex.js | 2 +- doc/LectureNotes/_build/html/week42.html | 5223 ++++++++++++++ .../jupyter_execute/exercisesweek41.ipynb | 240 +- .../_build/jupyter_execute/exercisesweek41.py | 2 +- .../jupyter_execute/exercisesweek41_16_2.png | Bin 21978 -> 22302 bytes .../jupyter_execute/exercisesweek41_22_1.png | Bin 20216 -> 22492 bytes .../jupyter_execute/exercisesweek41_5_1.png | Bin 22046 -> 22024 bytes .../jupyter_execute/exercisesweek42.ipynb | 498 ++ .../_build/jupyter_execute/exercisesweek42.py | 268 + .../jupyter_execute/exercisesweek42_34_0.png | Bin 0 -> 40673 bytes .../_build/jupyter_execute/week42.ipynb | 6414 +++++++++++++++++ .../_build/jupyter_execute/week42.py | 3636 ++++++++++ .../_build/jupyter_execute/week42_173_0.png | Bin 0 -> 18573 bytes .../_build/jupyter_execute/week42_173_1.png | Bin 0 -> 14628 bytes .../_build/jupyter_execute/week42_173_2.png | Bin 0 -> 31496 bytes .../_build/jupyter_execute/week42_173_3.png | Bin 0 -> 17868 bytes .../_build/jupyter_execute/week42_242_1.png | Bin 0 -> 4442 bytes doc/LectureNotes/week42.ipynb | 6209 ++++++++++++++++ 41 files changed, 30024 insertions(+), 243 deletions(-) create mode 100644 doc/LectureNotes/_build/.doctrees/exercisesweek42.doctree create mode 100644 doc/LectureNotes/_build/.doctrees/week42.doctree create mode 100644 doc/LectureNotes/_build/html/_images/exercisesweek42_34_0.png create mode 100644 doc/LectureNotes/_build/html/_images/week42_173_0.png create mode 100644 doc/LectureNotes/_build/html/_images/week42_173_1.png create mode 100644 doc/LectureNotes/_build/html/_images/week42_173_2.png create mode 100644 doc/LectureNotes/_build/html/_images/week42_173_3.png create mode 100644 doc/LectureNotes/_build/html/_images/week42_242_1.png create mode 100644 doc/LectureNotes/_build/html/_sources/exercisesweek42.ipynb create mode 100644 doc/LectureNotes/_build/html/_sources/week42.ipynb create mode 100644 doc/LectureNotes/_build/html/exercisesweek42.html create mode 100644 doc/LectureNotes/_build/html/week42.html create mode 100644 doc/LectureNotes/_build/jupyter_execute/exercisesweek42.ipynb create mode 100644 doc/LectureNotes/_build/jupyter_execute/exercisesweek42.py create mode 100644 doc/LectureNotes/_build/jupyter_execute/exercisesweek42_34_0.png create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42.ipynb create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42.py create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42_173_0.png create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42_173_1.png create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42_173_2.png create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42_173_3.png create mode 100644 doc/LectureNotes/_build/jupyter_execute/week42_242_1.png create mode 100644 doc/LectureNotes/week42.ipynb diff --git a/doc/LectureNotes/_build/.doctrees/environment.pickle b/doc/LectureNotes/_build/.doctrees/environment.pickle index bbc5888a1c39fb98ae16e5e18b6eb1d4492039bd..0bb60bbf7546cae2aa4899aa34ed12a5ac209eef 100644 GIT binary patch literal 538155 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 CS>6`_ literal 484338 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 diff --git a/doc/LectureNotes/_build/.doctrees/exercisesweek41.doctree b/doc/LectureNotes/_build/.doctrees/exercisesweek41.doctree index 171c9d575be0dd557a4039ea0a1a11134f5e2d5d..cd456f04b3fb9fbfcba9dc491cc91878ea4ef8d9 100644 GIT binary patch delta 94570 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 z.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 delta 93224 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 AeE3Db`r6%}`?;U~lPsqZz6!iY6HF_NQU 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 hs-S`MsRu8$j@} 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 z z;PXD3yY(9u*VR!;TbfQ=bfYjl#cd?b#}o^p%4YzW7c@s59MF2%-Tn#?<8cQc%Z9?P zY7rmdvS*-aH%wnKhk)|~THI+SuOq+}J1Q*;{er(*RIHb;V9v|!u#&ZLfB`+8d|G=p z@JkO-7}UP7i=YTq{DPim8PMSwD2bzawP+%^N4@QW_bkZ#Qax0NgVcy~@RKyT55$34 z!$86nG9vzAj5*Hnh4@1H`|PnM=rJjzBAbs4uW}5BS1AjhOWb-Dy@T!Mywe-yhQX=& z1P5>ruHlM12on^_!A`wLHR{9eS_su~Y$DB=l@Z1cTpNJz7rkyMxZg?e)F*Tw0|r9` z$=s52m=Cz+RRWfBrruAH zG4YKg5-PI|yMzV}eh@hV{_OP(gBLR}eTX8aY)YDI246rlpcsR` z`4rs4@DWU>T#IP4`)tLJ$bUK_1TMV1ZA@Hi@|=qUN!Cq*Cf`W*RA zf6B(YESc@6P2B)lZEIq%g@WJ)*Wtx)jeJ7G#hPmnxeNXvNK&K0{N`kDmzNC@u?Hr^ zy-^M{tZ!sEYxguS!fm2DVi7bS9ySr!R7VP(DOa3#4Zxbk!(6VHi8&PQ^JR+x8On70 zGr(B_Iu#P-_5vOYL&KGcn;FigO#(JK%Rzf?S%8b|poQdjrIKSBu-*qy7W)pit=NT$ z6SKu!K!}kt26*xqNs_S45uSX$A6KsfK6fQiG6a1!&TZ47+Y_XdpCM#&?$Cy=-KyUb z^OJ-nrlSUqKf$1msW-ld2T-)%tXZ=+oZ>UgJ99hsLS<79$j>f zFe30&myj#cOR_Lic@0mIJ-oP~T;UtdNw0;1V|bORd9iJJO@?c$aD9Ce@E+F2S;mW~ zVbB=Gv^EYgaokdgS*46^s9a!*`*pw;uU8~!GtSWb!0swVQ^C^O`8?2%y6)kKY~*|K zW)w>FmCxA9w3CIZZq@8`Ad0ZQ9cA3adk~tW4H3PcP!9-OX?t<5Fo@b1Sf4fmnB+@7 z#nS=Tr+b6j6UmSHU%xozxv5{(MRaR-3lXC5hzLYhaO;2cFc^)bm_`v|SrbgEY_@9c z&w6>E@$gbILx~|7Gz5rA3|y2R%ljf)=3dRx{oQxv~{I_zIyUdbFVuoI6+4@MuY+^V<)FkH@ZM#gu*Jnkwn0?C&>m(MVQ z^>yb$tx0Xl?dPleCNtJ3%dk-v5 zrbw+QXDAeK4Z2Jc#c>nvKJ^b=2(k?x=ABJ(t8eBn37Ps_+{&9!Zvg;Ck71DM$5!kg z?D31UZDO~8VZ?U9idcps{YqiKSmaUE-P+UPjU2+~o&+&ZMLcyikH=+ykI$pJVGZ!C zeY+?(jcXzi=}Y#NqMkj}F<>R`R2gnDBaQ__69e;vRsBG!&j+6uOV0JrF~*~VdE*HN z=aL?>Q#GjCxqc;EZL_Uu|Dmzm)!j&dPOtmMk7|c1f$p54g&d7h>BidC4aS}`m748r=dNB3}zvtxs} zk7WiY7rHZ_DpGN{6iJMi^Hhjqw>72Ct`>d@fio)nELER=+sdofHJ10Kn&|4W6|?O= z$+P8*ve34tU3Sz%dYydSLk(XVO997RW@5zqP4|gwrL=8?4b09Jt_B+qBW34dUh4=H z$wc2?a}dO}HZ8~vRNr~Z$gN<);@WkR;eM~7dpU=g3i2^XvcqYBB%h1JH{4nupp#qV zg1u?j+MUnKjP9Z4m4es~Rc);)=YB&seDrMVGe4PbyONjE7c=Txa58-=$%fM>yHbbG z!{*^z%b!rM`geOf?&=;A52+PCb&x;}I(fMN>gbwk+v^5zb2uTu;i!G@+*0=*qnssQ zj?EC}_ITHEBRyU)g*_f?pO-iNs$Y+heB+9QN;wTK&~;SzH<2l`hXMf7?~F5L9#GUc z#1A5jMl=J9&jrKsxqbo#-W4*-2 zha&EFP{Rwzn~hnHp?$}PosP=~hqzJMHyO$`XE?|FKfm&w4%#+Jupq4fu1uPaj3kl_~ zE3%!x2Ya9~?nfHO`C=4wny)|t&-3XUJ>~bUwfGL!nIIqO${=eS`gHm15U$E3iG`rt ze*Na31)sj|v|$#g@9hG0b(F|Eo41d4ezw70?lTP$PL{xLRBN{CPb5+~5(dC7;lzw6hk&259cXxP`ULw=ubfOfv{ zwBS0N>`=mag@NFNy(U2BCbm!r@77x$`T$=(1yMw;VTwz^-^vi=!j|RO@hKAtGxM@y zSAXhPVgxw`=fh^41?N47G^}qC$rFLGnHJaPRN(>WH7aU`*=A`~9!h%FVL)n)06Y(3 zXxV4Iej(y4V&$#2moxgb-)@~n05L_}V-R)~WIBGhtL<&J4)6U6v#hCKr!8cB_e0Wa zyeshILCh``>wLB}m!G_x6VaT==DS;sI(;1ZWcOvP``pVf6d>nVGpif({TA3UQIH`- zu6wN;FAscH?hl&O#=9 zyu}#LP=(B&_jfkCAxK!hvt6bjXzuJbXKYjbG`e- zN%VRI{5gB!{al#c#%;AQEBV>g4}-1Im*ol7%~R7{M1C|Hu3^mR-*gjGun%2CFG;x! ziR9xeR$_)G;`a1_5mE>IXLC?R7oCc4>j3{8E!8kG;Ff#4pa~pN8#8t@#n0N@SSUmnv?@OI?lK~DA za0ohrmq+}a%usJn`-*hZg3J*%sG?)8Di(%+VU!`-c^rjlv%izXi+Eg~!ndf7FnSb? zX81#!iw6E?Hj1H<6R^>qRg#e&8Ck5~`=SxAf&j;p$$}U)E55E=etRfaFS|LyePuQ!1~CVk3)>^vy2W9*ugE8zQ4NHD7l(T9^gEmhq>|TG{;zOFKG`rFn-7q1Q}NU zY@f&1;QW>_UF!8$uDsF9U6a={%$7p$(!N}So}NeZGm~UAUBuweq>QZKLIs@woR9Y~3N12m}_p=L{)6iX{XFgL5`ojWhIu z+}6j%%lIT!7}DSu&A-HsQqxTkahx-YlqG;~;g_;m5w3 zG`)GN!Xul|6 zV%qN${l$L|NBfyC3X{5aNZoLCuS*=1-wsQcCzB9%pE0QE&gO9#kX8F&RD<8<>Nre4 z_q;XK3audi4ysO%Le6!KdkXb!Z^87uKTm^&Y|2D7!UV@!J?qY+bq~fSr7``yT)Glz zryo&|tIOa2%O-(aAUAI81^KWMh3Tkqb2LvQG)lX{3o@ZphR7{c4l&slUa6PrfVCDs z4st_G^D%z9@9I}K?(aSvz1fE-rPAWAT^#a(XEK1Q@sWbuy4yt+w=45r_}PhfD^L52 zhDhw^QdEhhpIAAbVNTR1K~xS9lzi*5iwtOrlY21kTW_a!xiLk4PP}7?ypOYSOr?%E zx}N``3Y`do{rR&AgIX~0q_p?lY#R#r23JW-v$JvHkMq$0Z2&^$vBc6M!tUt*R0X#Vj3% zcV(vjI$nF+OV{Zjj;H z$YG8Gc77e>-MIk8CKZGB)cYm&4rly-;=+>B9MS8UIC1ZL!Bw@SlF&){64SNZ_E69F zeSViSyW_O`-3e5$U@*M|sQ3HK5FQu@`+Y0cpF%2_miRDCA2J&+UGKT(h-icNUc7gM zVQk?qWfZ&2X#U7-po~?apXh@d6&6Zbszc4A}kXQN5I5q)4jk=k4`;H8$ZsMa72LHe7Kw#}4E?kB?=?TI8h_abH6^x>@UC4$+{$Eez_XSv}f$E}a(m}38x zz8dvLJ#UkEe|GGw@`My0&ic z(8^cX3)Xm8m;#&5?)8cH#u7ft{f!N{OUo@cyjl=VWicuY-Lz%;{f%`R%(27tUhvK3 zMITo4e+TIQ`{;h|FySO2lybY00IBqD%+OP<>79u6;MoI;+h2Tz5K6{^OGux0Ff`zn znf4uj7t;DHrZj`KIyKqJ%{vs;BRM_HZr;s9LAEosZ|yUT?gmX3JLNSB`w#WCeRsc) z@8(@qxCy!x61*qu;S31CJ1il0XV4?6^J;ocU5JL4UcA3u&rmy_9$v#LDt;f{@9`~R z5A~%f5sZT}0^AFw&74+c__*MAx1a7K5b!d7>$$B}mei@P`90k7`}$r63`ns5c|UTx z<<5=h_?#w)I-=a~KI(F`_H2ql^81b0X4tEcuL(gn)-5cc@@|}9oIE3)>e1RPai=67 zE4t3|9>;TVykWzXe+NS$f1lVE9@h1-{sXlWnKKZ(T2!hE6k=P*BU|3+`~LfB<6R|0 zeChxWeou+t;mu}LP7DNf(4rCGGnp)zhbY&fQNl7I7U!O9V=n)`SVVufZ+B>uN_gPi zl2`7q)Vd{@16zFj*@*S#+tXOcA>Yq-P-jOX@IEN0`_OUGzGLd^s(;k-vM3`^HCfLGHtew8*O{4<4d+B?{gw zPE4agw`u0F)v@2;5P7_ct-s7Y=@V=yW}F?Jb~s(Z0X(RxpZ$`iziSEf{+Ru(?<}y~ zCHeN&iBHHOb#Ak?Rdh&({%rckBqk4AP}Q>Ea86zwFT2~V^wZ9Sn?@qB1wxJ%1tS3b z9K)p@RdyS?rO``WME*L?8^y45(zI6Ib!zVJ)1Rk3s$`j*P5fh&-S5}aM2UT) zP`o0=LjNVNC#6J&4!!35Jw$1k*!w#ia{GKtzwC9F+_BEQJ36z}4E1stP4kLq-9xO2 zq`7t|9yU;oRCuG_+?^xeiUA+nyT+sceJdY?Iu(*@a`(e=zr@Z89}!$tIK2GBp}q_9 zJYUbv&BfwTNLvbI_5g$dDM3#ZAC-^OaY#HlJY}r+DjE@1a+%h+WjS|un5fMLM{fIm9=g{` zXs`bgZw1Ww&K-=b!4dmr_@7oC?G^+SL+1KDl$*Tpkr+6{F)QWP9T{TXwxuVu1A^WN zU0nzb{hQ&{nfesumzR6G@)o`{k-{&;_VT>pVt^g^nf^ee@H~st&JY;*?1ic)~Oq@PkG?yyFrf9Wvg9PEL|zc&NuA zxfGiEbQ_7fsm6PIORL|;TgQ^D@SLCU95nW(+Whi7wJY|`XGd^n&c$qsa!-U#{iJT|H~Y=&C`Wd7nY)iOGY*2?$r;zU9?|{t$CrN8`!q)a$^4 zt|d~S1I>22J;N8NR_FMV@j#ItEuuUTdz~ihvcW|bDXJ-Xe2~@PJ2(j@Iif!y&mvRMRQKH`03?QN@lX%iLwGv zp~gOtVV99Prpn3X@?C)U4c1t&XC}M6JeD3Qx?@)gkOisN?WOW%C|2UhaQma|Wr% zz&z#i?m~qj44t{wv8$c>IPMVG7#-Xrmwn<0#e`wxjV&uy1%g1 zgk)^UTgaC7VdPnVH+pM3PaEj}82Cv^e%XVGU|P}Sy^Ef5+*9GbU*oL5 ze<^(n!siQ)?9bX8U;rWc_U}6aWlOD^MT$S--d3NtjeH%cMiQ>ZJKUDy6R`^Mk=O}x z)JQW<^9{^sP@Cf#U$%7@b;PeV5>;ET52@UF;ly5R!;;N>hR+0LdfT#hC2oIktVQI_ zo7s6-zRz8|L`@=A#(HT!mj(K;%b9*5(cVz5o~g6cyZ>Re#7)V)<3rP8G}2QM1-Jo# zOE$*!xvYFWP3|u?5icTxk5fjkhAR_Ts-Zw-TgyBob9#6u1q>Ogfl&b}@4$&)N#k5L zQdOuG7Aw-vR9svCK5xWyy;a^3aH4Or-D*&*m)i!|Pu&6BK&ZM?VFu<@^H{p>+Ua<3 zMP_Rppq?GwTO_>eV+Xa(T_dAs^Td3Cee|clnYzf|Y%)*Omu^og@nDHw$6BSzP;RrG zJZ=ywivelp?X+D6XLk!)+?CXT!&=FO^bWt9(E#WjTzFW98Wnh-Ngw$vX2r+A{QLY+<0l(Pz9a^ z04Bq2-_(Av&#DI1Q1M;wL1qX10vYA~4XL>@S{uXKusxs!InF8Tv_nj9dYRNK9|p>6 ziNBLSib=i)>+0`UQ7g&Ti`*%~1s;o}zQFB3X&rYcUWj>n=uGX@(R`$$;f!)qR00QE{|cb9#9Myx9V-W= z_cHO^Mo*PWdXe)n@gmROXr~_DWqQygU)zB+Lx5k}RqJlvn0`_Z^mzickzp8LKy z)jVoWR>bBLDxMs&a4bnil1+|!EHArBwlGT=u?{r4ix$^cymD=4uY`9o(e%wualld6I4o1#sSuQBUmQWkYU|l`EU~w~co1&-QQ+8< zA{tT=-cRwwI?k!WI&C<(xS}!yx{HRQ_TpE^ye#C1!wkDdF+EdjJ^Bk>6h?c=E@4T9 z!wsgYP0S(K<%Bv#9iD_aq?P!qskXBJ{+874j z^&FR$k2U_8#7ciP^IYBpY(4%5^GDG0A@-c4AqG_=Nxx%c=i_^KdaGM_KGD;Cn2ek^ z#hE86Mq5haRc9JhQ!zeXe7Vw#-r=l>$+Wd03Nuyi5(~8`o2`&QlWLij5^|eO(<1-v zTC9OJjf#B771{Lph&@!h^6Q^Dit4c^C(_ z+VG-m0cU)(h-Y(x?DP7t!-#`QPayi;`ive_X^L1Mn|>tWd~Ts3}g z0wlB;LQRob&y4zmgLjQ1m+W1#X%q=rf*chs5Y(vHicl7VnpAL?->4g#dE{Md) zZSu&+mh+N-p84^Bd%WV?Q9uACr-V(?f-QhP*;%05LdQl@aID$ro9BMWLJ%*S8R?b` zau3lEQp*}n#3aI{dQ6Z!O=DV-O-1j;FxniMTl_Hte*cz1{B_ghqCA$Nlx7#R+ifA~ z3}ocP7Bea^av+xd>D>mNIS}`5jqbvIrm^m7Ms`=o7`cB_e;$B;Klcjc{R`;DE*M`> zyV1M7zWW{iQCUqz4~esVp17azFCo7CwEyzG@aXBAoV29mDi%Voe|)}@3(wl)x&5JY z(e%E7maPB0iF`JfEJ9np9F{~Hu6E!29C~U^{Y7Wxz$1`NB&IFWnPohtnI$F)85*%z zQ0L$)F!%qM;du9`srxgm5;txENb#KG{@dX`2c^_LweZ_5`LQ zL`b#|?0iUUCN_Y_!DAtxe5JYxK#k!!LC=5LCM%f2_yI|Ib0w$j_`b@R`>LG}(YD?` zQV-nP4pu^C)#4+G1k`+H!QY1G_DLH621zH%`+BB<(<^imiA~4zkEXlf%f4>_X9|CjTv<01%A%xU* z19l2hu2Q`LC>Ha=KRx*RA@r6IV<=}MFp_yk9$eC^YFkAFPhS=bh%=zcCd~>vAE}y(4$I_ z7?x92F?LR8seoN*nB+zL4gYHvGfJLyrTHCzIX4sy^HG73&>a~7UOE_>72|tD|D6jp z&BaK~AqK#7M{WFYD(sukbmn5Fz9^?yt{m`3t!J*>GA1b354 zrH3p>rmuGJOg1X^F%C<}N=OJ0sjl;IAd8lb`xgwk%_q5l0#)0d{lbttj7487fm?ke zy$iWyrxQeQz&ZS;4gBaEoSe4OzDP4x$6|BF3vs0tiRs-8S8R%rP;>3Mo2`9fM zEebKm`~N;4!7W7)2#eVq+>DsYACZbIG+psAhNdeo2UQ3I3P@bMzoqiHuIZpH#XQMd z_2X|ni1cLPj?cLBl23LJzNCMoROfZ{^>uG|P`O1F>RC{zHmA)V@*#mFdUJ!!pCRYZ z%fwk(@D`tv$1Dvu!!E#Pt8RzeAp?6$XS(wG9k*O_djDW+FQ*IMGo2NU>Wy)$l`^-Gx6a`|-}JK6`)q6b2j$3!(4jQk5ro_7PCPbonWp z{rxc_evi*o>tD9#${0Y-9^VFiDea9Jkon&C`e7YdQ<+9mn+)*`C)_v7NvNX*qL^6O z|L)z!fXMA`_*cw!Z~L9#^^BJJngU6~*API^;%(fC;!b-mc(v&<553!W8YW8n?2^!S z)ygfVziTiw{-{X6^#aQ0vcyw7kxM=z?ngt#@jbF`fOBOkOKUjZlW_U_Iu+M$Xp#L~ zZeDvAA4nv zs=|yKGZ=^FtOaM{q?j$Okj@1MyM7LhPkb3~AgZdBa|r}h<{vkyE)!Ykh~nndCfDkG zmW*z}O`2w$Z+iUZ2JWhsX)HR-TIfEpuiW#Bm%bZbInA7M+bbr8?&_CMy;6lv@}XbK z<3=vE+=V0>MfCe;NBeCA`siAhO2%#})l?!WgWN7Yo55#=MXbBN zwZCUnnYzXlKj2oUv$0@@%^ETs*{N?l`|HmynC-WXCm*{hu9VPJrc`rsXTgTx=$s-P1} z8z|x~m0961*0ww*K>0(M~t!O9{ zQ~7bx?#=GA#45DnEEc#g#~9}bcdpgg3(Sw)m>#!x?p<_A+_9 zW;5(!%J+K2+_my`Xr3O)G-m_LRsFH)t5ywCAeoWx*jBWF7M$nZ@m5$f&y(`>uTpCC@Kk1si?xBueM+L7ot3EjXDD8StqQ)lt_0f&+tX^eRg=V&>ppQSE*XxG4 z{k((z>zIaO{=nQ$a}77Rm2ehZUq-YqjvCln4&4Om^11+^hz!q5g?lJC)id2-z^9+p zH>A3U6EiV^+gM`0)0pSDtP60_!nkB^BnFfAkN( zO{<{gAy<3Wqu#FmU!=Q?$KUmB!{CHe=?zL|`!f)L35hc%@Gi3Xpw80~h6MP1v4tfR zpC7r#_YWH$%?6xWq2Xv~S)OC^HS=`UTGj&Yp%k;_G*adG{C7|51@6T^ZGE_c-c$yjOxGnYS=x;CyM>5&E zi$szJ{CY^=a_)zE-TzI*xQ5yWB0&2o-QQ72g{ap6x|+QE0^~sU=L4+F2lDKx*nAxe zr~Ev+NQ1+JNHI2qrUKmWlSCje_a5bW0{{-->F=-}mS)>-`U!%XCuTocs-8ebO)g!s z!pMr_;w=AL(-4o1KX-5br`~pDbVBC>Gr0$5hqeX|E-=6SDAFw#+GrB!X{C zIB#8S2*3L*Obosc1ix{%H_T6L_W}2}{Z@U1Jgd-dz-iUJRaged>#mE=B!&KIZ~-d= z0QzxM#56+zHm;nK^XJMV+R4;P|N4ub5@5Fz1&-{pT|H$m=Z~x&F>BAh{-fT2ZHq{H z>q`JBOUx>WGee=@J;}iisi4%swH|yWeIqiaZfwaem%yi;>W_d7J^-(GoToS<)AumIfHj;!K3yt}kPH73E1GY?C~@0 ziRXFdHVMx1g&b?SU|!NXfYe~ey=pl(Yu|_+{w0e^@Sqgq@VCS-wtn@#V!L0ks7j4&xJi9zu7sB$*_z)%@$l#QlqT*z25wjD?dl zU?@m-EQlWf0T<*ICRv#qc-eg%dHDE}#9x^2NfN|x#yiD&4^+{}`jhT?V$_}rvCpqh z)=endJKa87!C0!h>7?}>ho}}32+Su59gVhBE|8Ye7Cf{##%TjyEIi;R4JTCimEu49 zGa0BdfC32fei~pvXYgWMy8f{f|4L=$Paq`g3g{!Z51XJ`VOW2Bh`ox}kIg(GvMriz zFZa;_tpxN6)tUYl{5WS5{YaLvBtFU^bdI}OO0mwic1*?&$;vSS=dB-Zp9EQD0$34W z8)FNqDa4$o-Xp_)i=DU>+5VLpy>P;QQ)f5dEl3Z?i~ei6^DWc99_E3=QHzuGRzFMB z#f0o1iOD*24k8L*AVJ@6iTN%y)&8^(4tQa~Qx&VooQi&~Klsj#FxaF2+}%dZwLd_G zoMNfX;D}l42BiILZ@ZWB)EJBQD}JO8>bl?R1QV$v<^j_gw*ucZ9o@5r+6l4fl$k#_ zO4-0~;z^h(JPaBBe>?xmA`l;XoECm(%|h#uUK5&R22d)TNv(xahLfR z+KI={wzUS*#W_otHb0dqSAEt6p7G+X0Q{^d4N#Fhrpw zlf&2ZI+oXQM?o9F4RV2XO#y=qTqs}B=! z@khHY%(M6%q3@jBia8|uR@uqeMbg{GmUQ$k{t31Hr@;)D&X`})Lnm-my@Pz%z8qvu zryT1^l=T&{iVroiERCd(LuOfQv%hi1^B@hb`$m^IRFRm*VR$ zAtv>2`*_~=o_ZkOxAp%$J*6Ha;w{cl-af8UA6Ar-5v z5{n6UyNxnKy!S^6rszK{OfNV$by3$o1$Fyu<)Tj^c04!Y(Pe}69qbhMLS?M-MRuof zuaRQ?s`l_QK3I{2ty^Im5C6Og3E9Vm@AB)E-r7d-{ot%xZ}q9r0+W zQ+%!tv^acaZq+BW@m}-wRjg}C>t_}~j|u zTUXIEtl8bYiyCNi#1s+&|K0h6I5fMGE=6UWoSPHAN`q@Lj5=W6XFkWO!q? zb0#eXBEa9(O=EB2lG4fM=u9tMcb~>Dh=dmKm-J$pb#pe(vcl$%RA2iTE1LQ7P-9AM zLvL_I2JKWUj5@21(MsivCH?!?Jfr5v$7g~O=YdCzbIs(s_3D^sT4zE|oN`-ScU6Mc z#(-0uHXi&$%KEq3nGpTCgd6%nE;=ID^X!jA=XMh!R&Y~}hg=`p9@pGf=u0$=HP`EA zn%m)UN0y&6VL=mEo}w-d2<{a2=i_N;va7{z`+|c$G4xtpb$PK_`w^MN%rHdm0O|)B zp58|N=WE#00CCNHLAiG%Cu!B8VK$_(qipFNgRkGb(R0V_HK6#mRKMf>Irnb*Ch^>Z zoU;Dxk~;a$xOMi3NOgAuoTwWl)e_w_Ead&~a}oY-DM|}|0?f*S_DQ%^kV^CC%f&3- z8LpSD-$zA2c$DiE`Sk`N-`{tTW9#2jszU%0u9}eheRs$+7o0H>10~SMAn96nc(lby zu)l(3i872V+zXpLKJf!MX?I-8Vfa~4G=hA%SFtz3K6n@W@uLuUkTHicnpicOF9+v$ z;A{5#c`~a<(LtZZummThaHTt;BKL1&9Q*ip8}0xmoy|MA7mw6i_cd>X@&yAJSm*qG z=szPqKElN;Fq4{KNDFvouqXc87w6!KZ50A$;sLvG08wpz!T$IE+7G+I z>*rbX9>1K>Z+Fvp!Or&BgEwO9(tj@pWU*JBMci98*jv_ zeV9RNJfK}9xP^Yaqz*^G==o-M5YDhFLX(>>nutCX$%0XSZPji*TWI3qE@k5DmG{z1 zF{j4#!@KjxI1IB?@m@8m;{-{~yq7>3{oTozLu277IG>ArIEzCe?V$bfe45(u??c|z z=+~1WU)H^`e&q(tHcvo`IuOSO&?&qGlLei6kww(a^g{QCr3YB)+tb4YO1rZ}zC(7rQQPNYw*4dA?sRkb=(~08_b=p<+&&wuQK{X^quc$koyy+3 z;(m&T|E6WXT^i7TZ}4F%P@gc0^Ag7e>awyl**-U~bR{H|dwFSCUlakT1k?g-7lzX6 z6H-3QA%qk`(3_riqds`2KNCyY<_J7@fc_YqK_&Nv``-fi0Dy!1JRm0v9uVf6>D!fs z1yT|zRnqm`T~{m)cG)P^PSU2j`iIwDoKkZ4PQJe(A|O17#_9Sob{Fn6+fXidksqZ= zU%vPsI4Ig%hSol}Rz65|fjD~~!x)wjJ*7YT>GfFu))4WZ&)>(tdt2#8IrOy+VL0WE z71sary7PS8Bk4uXA!yBBaHoovVm$gnn0-DQs+KCB6W(V})2@?M_cvnFS|pB&SYb6l zjC&&!(9ltfv;VwJ?6iXpXG9Kn)#En;qC62u;b1oMst*|#!D0POBeB)er3`5lG;kfY(9%H|rj|NOu z_SoZ55fHUl6P0 zIXhG@rR`0aR>spGFA$AdEF$nESO37%3!@k_0T~r3F+}q=Yna2Z{g}6^-pAK8j4pUJ zyW*>Uh{SVzi#Z3tHpp?C&uKIr-3={vqNy&~Dt@-lmIG=o9vL^=Z~pOQG_@YuNI2zG z)C6PLr)LbJy|veSh?m_1yIdpUE;sncmHjZnx3!3v>kIfMn|fsy7!N9MjrLF%F$@zV z$$}sVNwuXrRCU)%yf*{EG>?G73@suH1MKYY+B3-YrB1AUo`rXE_d*)+USqARTjd9K zY~dg)@lM%oP+yd0V#IEaw6b|SQbYj?j?pMzgl4A4MAqZ>w9sSj7N`VHCJ1B-8 zm-olp9KPW`&P1v9AQ`=N(dCi<-gS$W?!0~;?V-+q7IetZmi13Rxk1NT=C0Xzp38J- z(4(3M;_Hjr`}5Lw>d_D@aAgdUUkr!YKfjpKSv;$dt}BLEo!#H}T8*{`x>7N~1|J`z z+}>m5&u*YACV6IUpEl1xy3|rH+wxpW=54)(Z$L&A*#}E#%48am)BWwjFLiL2?d@N` z0KV!QLwMahoHlYxXs#Ot(@X+r+!RAq4o1c;r-MFdpHC$M)#zB}$g%lHEYE1}IGf^z zcz-&{Eo6_5YO)2VwmNZvBfkN&6_YXsugAHS#_~y!U=Y|Repp(MR$bDJq>wdLDB?o` zE-p$*4{?APYEkMh&=lv)>F~6P)|NYfOzPy38p6$FbD*`Gn}db2jGfkkWeE*<-?sQ$ zQ6I|<1;w{38xOHWTJYGtM@K?91$|&ZfSQTD_xR-3_iLT;$2mN>SRjW~W!F;|sjy2d zgcBhOk89&1$5;+A7=<#AlN49P^Tl|*sKrn0H(GxG+k8bp443nMPjKL#u;Z&^NBlw< zSN-!nUKdSFlk)dCQG4C01BI1$>gRS1f9>!b+TQ>+h|dvAGx`qFI;K$oqM*SoQ^s0M zX8O5*=SMC-@o!1<%fi(T@$GZ}jacgR{1ua$@ZYa}+`QQ9I^459b*nx9>)`I7Jorj& zqB+g&bL&`OuN^-`(q3}Wjye}}YTWDd8A~+Gb{>~vsU3mi;E{mb_e5)VgU>#rsdi{9 zgzuP&n_uwvx2il%5(Arf=Wvind-0sR@spq(14u+%x6j3MY(0$Dqhz-WNbG<1qU=q4 zjz(9vL7_p-jL+-Go7%j-oZUw{sSyJOwnk!(p;lE)tyV44E* zqIvXMc!H|K!(EZ4_5R;=4|6{7`l?fq zIWIo>*W}^X0}nn#V1L8KFe$)RHUrXZbNoFow@Kknmoi~=I_UP4iqMMe;01JXtgwfv zasN9LKd=I-T?}NT>egzC?oDg4s;w#lqilWiU3DAX z?lM}z$eTPrI*h}~$<1C+s~PU2DcR1=eK8ZcVNm}WB zgSV`MJ_NZTP->?iD*cEl7@xdZooyY7cHjge)GI<`HNZ9nUzYt#(C|Q({6h9aw88uJ z0|)PB=kCVG+7hGz%mDUgZb#4@4tYD(pO(FP)_#Plu~0B9#)2BQ?0YJ_NZG>f1Z>7T z2T39%y~Y#4U_hJv%PDLzbfxX5K_HKU$R`UfN+ zcmXom@jLZSrnD8C80U=~b^MpR+Yc}uazuM{Q2~g+s#WjJBh6P`cPX#b_2oT&V*SJL zYyjHO@AXST3oD25HydjR`~}Vj`2<2Uu0$Xms`D9X(;9N4z|m~c8`#IvL1PPr#}A^o z7G)QBTWcMMBva~}!5B+=Iyfh9S2bt0K-G7ve=CorQ1ZAg-o8Toe#A8Gi~l&YpBenA z$IGfsS)cpLZGYg^U1w|=G22z}7-#Cx6Ya`hWT|~HQ@y-bpOXP1lzKsdX}86Abv%T4 zKAy^D_T-g%)?my;z>9#un`wL9o&4~-Ny{5{Szfq3dDOu3%k}Zr@sG+V>G7y}G+Osh zCuQg@CS~}h@HwyGK`&}vr1JGT+Oi>xbf|Qz;KNk7VJ_HoS^C#HKwI0vG}+VR{fCR2 zBGjSCx|g<1pHl}fYd;RqBUW;{qqC87;oEOXXP^!TbQ;UEWJ{msqWGupqI~VSuwlay z#*}LTet_@#msaT#Gj{5{Unq^yYsR@_J+T-5tU(sLmEpDqWyRQ51m`LG24o)KWSJra`Qc7Yjp`XOTV`rZ5l|S?*E(gRAk^B&1Pue~qKYrj0#Gi8c zX~SwFvsO!jdNOeS=kQE*wZ=c9i4-p+6T{O4V^RM~&jzJI8F!Go*$<)c@;V<~p6 zxTo-|U%RjHfjye%w16f*=~YK+Oga6c%}3$9(Rlfz2CNGo zlu~xpUXQ1n&Ev*<8Jp?{?1z0)7bx`a2X!%t=;8>xb?^Yl04OslvYWh|E&}Q~weA|E z>_yL&BMx?G4xZBhzPu=xNWF@&$Q%BZVIe}`5fX)f?uxxB{ zviqFL-O5-+DYa->(k`5|2c!^_r!_d!f;C5pZ0I5oG@G8YGx;;dFz$R1L}C#+3?S<5 zr&oW+xW0|+!@X*`)&8r_a+{~&#M-PLoIcGBL|-C^j&!ks|8Ubo!3D;>sT#}i zZ{Jq~1sxR?35oCBwoksc#SM6D2a779k)ey+_HB+n6=51C`eOVf%An zM@fw?BEXa;rrtY26{pBwYlLOyA-qMe*g}irGHXEllEld>Iv$U>X7qgD7|%Y`S=Bw_ zl)ExmNBzg1?0#0VM3m>KuS|$x$BAlhslrzBaJ@u@|6;GP*(g@cgD3%rKZ%(UZEO4ED^16_mB+e1I*%S!3n&j~475KpVN?veVDIpF2P9W`;vZE=x8aQLE70*EPei}UcheNV?=iJ~ihl&|grq@`%wDNXiP=!!JR-;~ z#RqHj;qd-BnQWUg7iWVW>kV!wC@6NE^VL@CQ(iSI^f_`{1 zj;7d@xy!t~JwN(d`8AY+&o6vxZ8PI`)vD~-X5o~V8s~36@cp(262;9r%kWHk#;gbM zKBaxr?U@x%wK$pSt}H9XTvu^4AC~07`uSUE1^;?cC@LYTUOkVEZFWs5o;j|58}rKc zBm&ddszhxo=rY}d^@eK%%7E*={#Og@+G=R2k02(nhe$h(U9)b%QmXbPq;q8r$@hGL zaQ4i+1dA-T69&XVp4aH~OOOu!w24yv*=Io(O7)elcLBTIQl}?>zg>u0IHSoHg5`#g zP6uD9V;oyk$c`gI2>+;y5bed5j>wSRso3}c{*b2Z)aT!o3;9mJUqyaU$m!S!H(i8J z&uji4YyZ~kD%);rVqc<2QA%}?pD^pJN=U)%L8?TujWM<{V9eH1G-Wn6V8HCbNOe$W zIhcnt|F;_bo2%BUQfVDT8PfZXK8E_}-5ta8JokOKb~SNxdP;$&Zlk|G$|>VN`mxz< zqFW;GUssH?8wY2J@B7`~r2F@K`N-c$EKNtYkB35p4;O5)&H`g-ccNd1ugUN1b~CJ* zGpd`$@O!S>>fdS^y>J}>Zc!`9;kEePKGy9rJSH_fYnX(ytI($KG6wjGBUyPz69bdA zhhQm^g>G7SECcaOU-da@5YYzg4epQx$a8R-;U(Z-PoB3qeH}Pm&O;w9G7EMWX5_e| z=&f=ZD;i2Tpf(666JL*;)~$uQePGh=ZgiM=94%=dD*z)?OF?4q0#&J_}fdgnA%s49j!(hOB2uoK48RUBX=)upX(p z<;;K9?e=TGr5q@6B}Cj4fFefS(u(P0>P+`|c#Be3SD>x$N@VTPH#$WZS4 z3%yYf?lY6I$yn?_wuKRYQ0s!UETrW7ZHgx!sjFJLU*P8>49n~IihZHbb>plwD+hI< zwR+i6Z>yiuRgp+T#-76_8NKZwAxh}8iaZ=>R#W-)p z6E1a>0WvF=NM~O?!hwA|uLJFa^~%nS!*ck-rmzT0ek288q5tXg-G76fpWQgxXQ2Ja zjxdX)#&xywV}5*8_d{LS-zbL`dVSAk<($7$`Hj*(?vN#3`|EYlt+?L6Ta+LN0DcLC zpxw@qBG*SjN||=% z+S>K(vzQq1HXs9@pWM{7&wbWzyTbsvNO#4voAj_Li{GZ%K2iZ3i1Yfq$!iU%cFbf-P3(- z0W|t9#eW4nUe9c32jTYsw~XClxU8LMoXLzz&r3)#y=)UD$?djABAoVsc-rPIw% z+~IA|PFHRNp<-n=-_{rT{KCN`LtQAw+|{g)-_|7>~#Oge2T6hS#Cl-MB^9k#fkI z`q6!<445!}2ETHy66a}5ZNXd0ZUS`XKlKLWMPRop4?aRq0G_zDKfp@p0c>34)Es>i z=HUh;KGkC+Wd=;WSYm zo-qPWz)%5Gm;uRxjjP|Q*~2eRAIKIyK6-b&uEu{S_w`@YAO}f?g87Z;of$gRuXX&2 z$fB|bBwTBEK9VqU{;q+m)_(grPoY&Ka)TL3!2a-e+Y`jubJ z%XZN0Gr{W7OqijT+~ym*P3r=TRyW|Eqk#l%E>Uu?jLCE@jscH``dK)fk8ioG-tg}Z z$qf&J8HQcUS+4)3lnQw>5XY71e1QK}O0}_x-}I!`S;%Oi@Q4$pP!JS!k2w;GfKsU1 z`#6CDvFXqEC#Bv!L=Bw}_`#M@8e-IkglQNA`pCuUzSPLapdo9#g}$#|q1R@@9p_%s zSi3u8&J&37?hT4YZ{2dxzKU0!wwnJ)X-Y`Vjcr?~yn z`}c{bMtWeJB{n;PdT<^b)tA?>mrvV$=5z2mFD%5~qmU>)x5?K`fnFqsJdVYj9s}|K z$NfOiL$8;2W-1z*)WV{DwBZq|*cX_b21W$PCs3_GYoU$krf6$4v$%8AZSGJ{pqM_+y{S6fE7F$sWDkV*JCOr zA`SA#XL)QcHMg(Se$+nk*uy?2bVkuBqi8`(avhjKU?k#BKfwbW$pARty?&ss^MktF z*S?j13BA>fJjJnLr5l{)XA(A8BQ*iCic?Q54 zeq;z?-&J!>w&0d2O8QEgxu zN262MHr&IrJ_r^SBG#r5tb^HcfjJ@Wfkz+_2atkI1lI>`uOHEv1&N>qZTEXDO8YZ2 zw0RZ~%W{!7frYNi7gnn45iUsyY?L3pl+Rvx#q;T4{bVXkLrT%Zl>B|S3Hd~l2FE~e zWu+C|Ri#+UL|-}Q_PGHo=-HzQX=A>yTO$EmgaY(fKj7wXA{BRNH>1tTZsEc}Z}aA0 z#{LAk>Jv0;Sm~Nevf766ZC@9QMBB)zy@BH%= z1YA9_S2EPSz_hGDUp+95{dyk!82NkkLW=nX5q0rBxhIXcLwd1heF_L~rVSYF-CKW# z!UxlfNPjmC`WLP;ljI9}Z*`mEja)vDAHF8V9`ZA<(t^N&8m5~7|NlRPqTm4nT)`Z}YqFfsvS2F&MK4xB+%e6ls(fGzaU+)?$E8)lX1B&2JO z(_C-U8zbX-V8(vlLMvCDZ`cBUzeJ=c4yWl?6un0*PJ@bk!gA8dmntFmXxcdYFP80z zw+bY8Z5uPYp}#u-wfv>x=UVP@ht>hd9)64fjQK-1-Vw><8ol97Xy5J+Y2c^_Q(3 zK38aP!)L^l4X{P~2;*&xHixdcBkUepyM8^N#YI;h4}@iC|2*5hZBYNo_Kq7F;&BFvscl71W@8~u*ZYma&HWA@9kG@b}DblLQF^a!w;{=?XCp& znxnJfA!Y8Fng0en+z;m%)2SG;ejH>R;2@!(Z#QQ`gp6pWjXOCOh5Q!LgZi8GHz(-> zbWbTKH+H;J>!QeRzNC4O3S@Wb4|mi5s)F%XZ)Gxy;bE@h3O5fC=j=Qx7ajcwU_S9$FF1>r4qo<1;xnT<{ zwRON1VQP7XvHn3VeuMi~(ZPl>;dS4m!oINO3fbGQ0*Ih`;A3xCmg-wk@! z7b7G{RPmaAS@r(v;??^SyX{uM5PH)G2vF&-$N5x8cMDrGC=iWa15PcwTQK(yH{`>7 zcybd&GX!mxbnS_db_tJhTipBzwc&QLyMY+*@1Be^o7lz@Hvspp7de^)$$5uI{tz6A z;|_fa)R^CbwMkYU;eas4hsw#1%=GEXE9b4-UQw9sq5G#xdCk~U1Hh~ATXEXG!1FX| zg>pe_=@471(WH{9hpbht%dm9X~p)B7*crZx)Ss=*{hgI^75Nc+C)| z&*zsGX%1_v-kyoy+s^RV#9tCBY{ty5FPnQq_REFbhV~T@kc2JTC7iZ@{}w)PR*Nu8 zg^Aj;na_2Qn+f;R&t&w@oKkL?qOX?y4!~jRn{8SM)rTy=Y(M2)XteOcrk_ba-o4s( zlQ9Oy{b;Vi0L~hKgmVSfe#V^;Fv5MVhVr;)n?9*}GJEz%aK6nlo~dJeZu*tQ>jc^x00Zr! zKN9mWdJ2S?tU?g#cQFDWzkXzJZPDx5totsjE^Q^ zt5&nvil5pV7Z74W$9Ekpf%{Nl;G#)McczI6x*{k>&{?>7V62gT-hDdTLJDO!Rxej5 z2Q=iH#n+H6$R_ox3TMKOV7Q+$1SN19jD;VSaR}5;$hZSTOn;aah~?k}n_$ek5-<81 zvOQCEMWsfsv4bxVT+{rNpRLnnxJ{LY!F8w2JHFaS_iC{hf_CdOOCC}KCmvnE+hsnk*`l)d>WBUsm_+I6 z3if@S83p>sxqlvvvXDj&tljKx)v8} zgwk5x-Sitze zM|>=WVT#k(JC%(!kSF9BnT2@xY%iaAf-FbmB3u&KH}=Z!Yo<4>IodvWoW--?x9 z4x$w8(Z#%K)&3c8{FZPpK?n?xfQ&e3Jvrge-^aqnO>6o5MJl8ysfdpBibb-WLc4Q4 z(YVj<{Sk|aAZVlp7V9ut37;G^H57893y>L6f2n)A5`JL$Qx;pkqo*_i`jxNi-J0E% zcF0>8ex+pwA3F?_*X5glrx?@KzG1*)XoWQtrf2Jy}BFS!7_Kwf#g`|3LIYJ99qLb~Ct3tkW_{F7PDFy_c?9BdEPQD#MOAlUDx zLTaS{5MDu+%;$4$P~L|r;6yk}4g|c#fGF&g&)S~?-hsT90!wpfD3Zt-3SKj@XNUf`NEbGuCe=0*F!Vc8vN)B<&spPf%*R&Ea$~|ZVKtoOF z-|(N;f`$IX9=y)v69@q41>gw!#}x&Pkl4ilSWLJS-X!>KRo1uDOOtc$#5uoS4%(C3wm+s(U;5>0Q+x7^f?^(MySCn<1ttTwR6?1Q% zAx%#^?6*^5?%wEp!P>z9$@XPqnn0Ku_3U_fhizCf6G_sgekC<8>dl?i2w zbpu%{6vA|85Ia&tCp81y6`z}NJN;Z_M~n0;lPF}pxpA}hK7a|t0Z3AgZze;NgXqcI zw?1NE^BJffVl!c!0_7Q+b@~N*WkOXlh~aT9;V1$RCxN<-;ON=aNOGiR(b(G`j|Zu%>vnF-+4%_leJpZnl^Z^@yciynOLEE`GC|qIs&Y?9KOgs6`<5IP^4$ zFZf9~m#ysXEp@)tD2jdO6c#!yd~oh$kkR-}a^L07FG!tsGwHt4Ez@nLUWQZ#fg2n@ zgls~zlkC-3WCE!V6K(qSp0=4yd9-r{;qDB&1aX|NYwPa{RlJ9AzjVd8V_iYInCBcQ zz!YvRa{b1RF%dig`T>HQZ$K@W@(z2A^umw-$9zwgc$gC<4Pa|J9%P|KJ7CSe^wdkS zFaP?@FZ)qATN^Xo+1fm1S>v9$ECWE=nPuW54-p{<+)cwk=D64v8^}4KyblBA4N&o~ zXL)TzfX+_Y8bP*n2wz7y-xmf29Kq^(hR!Iv{on(#;Qcu}PyNUOnPnn4%yyLB)`L#1 z|6;7>`2Om%M3k;1VQU$xmS;P7@FxqDHvI-p{XT`dQBgjy5M`?_2*dcOCe$XR^Gk^w?%qfmOmywVNfG%(W$h`s^FG@Poh7hgw;u#jqwJ( z?F%E0^RCO$$-nC3=JMhq*tPuzmg@1ow=a8_H>$OOGXE)3L{wrA9W7 z&8+;ro(~ZPh3u=){#?ub@UZeH;OO}I+#^p2n0t>8ac6JQ6FBi6|5LCzvJ&15uwr z8{8h>`nkLd#I4HNQFb((Ce+sHiY8;6#*nY_`*)BV`4={z*3;+F-7>kaq7jJx5@CI= zby3NR4jyOLiEKIm@seKd+7`WN#yi2o?3Y2)AP?dP00byrvjUnl(t43=xd-}MQ}1B@ z#3h*b*^?Qo!P$OR=@?|lNc3BQ;?@4-pB}-%z(yP>S|0%^EL{Z?v0Z7zeW!Z=y={Mb z3~%-7cQ~JptN(Mpeh~4yskTrGnD?17T5|T`!^nh*vW`;$;8%J=ukhU;e|L@+4kTJ%h<5Hh7{UcGPm>gh4~di=B>^y!LnSjBV8Q%nnmDa%)jSmM<^nZp=wdp4tVq zGiu&ULiv9mF1Ec@m}`&Sz5CgSzyZO0GdBq2ekB3&!bZ!u!^%;HtIp+6eTDIe=v;Y} zIiy~Cc5XY-@O{okwq|;GPm|RP8#)s%<}cjM%**NEI=WD+uM!i4Q`1;E1@Uovy(3=| zeb-gbaegY6xIcgj>FAZNRr&*&ZJY(35(=vdMY$^Q3iK0YcsyaU?Hq1&H?c1gk@qq2 z;_6nYY3WH#*$Y(W=P76hA0pr#w-v7LoQmM3{R9`PA{4s$=h{!p$yL`(x2XI~<;08K zXlE}WYxcjyeiE2mJ1Ipg9CFO5>A*(Z-)j_%V2pFI z`DPRY&n;Hzrkba|opvKPLDSTrSqI`B;@l&Gx!sZJz^Ejg?tkx(g3o=P({V&F4HP&i z`G*c6<+ROUTRvg!-(5hELZF#Qp_7)Qt9>Xcm}(8hSo6d{?S$rqh4Kj*gU*^~?SQ9P zpjVSOj5)AdWJ^L#Ho5Ojw?id*O;M0!U{gub4jlg)IJ@SNGxJZ(w7T5R+MbkmlykDN zw!M|LmQ|MR&;ObhI2$mQP(hy<9S&KW)0FLF|J^+43qY`3cZdG*1YN`tOXse>ZeJQN zAhB(tvFZSuI%-?%O|~-VWpNv$H;Z*f^W<4NZDH6xzn zV4vSv&gs8`~(MT zF--fOAO&d1LximwdNkbo_P~)}q%xqM+~~?%kbGKIT?U8JeoTd8}>NVO{6BxcErSsu%0t(hJwm zTNatwv|v%v)j7er8=0UJ>D@SFXg^*9kw&Y}Xt(FS=I0UJ^3B2BMO0wB*co~9^-*q- zdBkLW|)Z*(QXlk-H}jbvSR^&6+0* z|IbYcbe&n;4^PeS_5ODBe4=SY4WWT88aLwgMr#m$N93y`yVG-1a-cV#ZQ&4dwINQW zNb9-kl)XfH6{tLxVaOakf*A7KzyC7sf7=WV4##-e^cRb23YUU*RSvfUF<>fvdv-+U z&O1hJ^d~v3#G3)%TUmNmWciv22FcwPWXp|3eb^Um^M zqXr@7r6YS@G|+@&_97*#P+O=5xY(l4UZE=_k}*@=Q$(gutd<9@1VS=AvI+W<@xDXT zIUUJoHe!Q zoD|le9vxeu2VjN36I8rS@OKSYu11$+P%CYpf_!~(l=U#-`=OztyhqzUptboT4v|We zf9F@*Ltom@$q`}UjZaTCvYHoiVIW%F@%mMQUg`OH`Dus;ieI)6RA=L2i8`cQlstYu zV)n2m58txfMyqG^Cl~hn{(?k${}P4acSF8a3;5Rn=H#Z<_hLveIeBURxef_caebFCSdF{D;{6yn7!W+ z@vHS?vUU@EDrWEsXeDQ%PXTPjt^u$5+|Pa6E8kwNs?WhePYYJL({{@+J}hXpNDA!E zzZn)^BbSv0^=3ib1xdE?)m}h*J0vmv@^zz{X@&$c0y6^mB8lM)8ALVeiTSgjOQq`_ z;i+nP-^yE$g3gnG?{1MdqWt4mo)jwnG#sY7McN?!M(;2sRPnHPPvV(+-q=1;QJ*Hz zo^2o~84}QL6sF%KKjq{3XSZVzZ^v@;GMEPFQ;TxXCC-ipGUd$41;D z&8bz{%lmDyVcVtilifo)lK!A$U|H+SM$g!!-q{X?cjE#k0FRW4o?nc{=NoWBun47f z%9O*44|T1w!vPC}baJ|3+xqPrUJ&x;Q$PQyFEAkHILMEY85Z=HP1Jv&cfI&q8C*;? z&C~;!KXT2F(~TO#D_q)a$0MMwY&E1KEeMO-xUEza*kPy-*fQ4)qZq^gX7K0b6aqsL zu^glbw3bO|wio0*CF{8k0WWN)X~m6U9h}r?)ha9c`;5=It4+v{-|*CZqz9tB-f7BC zz-I9tcktDq-H_maMcnn&V(>2P77p*bP$lHF=2Y;q&m-^j0C!_HA94tr-~&M&>S zW!zxE7SJP{e~Y&tkATD@tMymjX6BJu?_aY$k)}$@rG|a=B$5P1wg!1*=XY{sv5MR= zHQbe_(;PRQsc&{c4HhF5!~J(l9+h%m0gj>$z~XeSvHEXNmLQ$vtA8aGeE}f$iiIkB z@#SxF;kw(xRsk7}&SNxkF$aQ$$eO6xkxhqR#{W@>-`|ghnqu`P9 zKjagEfbTXQRQ8O1H>wl&8(=Qm%mRJOrJ5FLLwK^b0?*L%_;s?g{5i`Zq|55=P8Mbg zY+>IG61Sk}uD2JYir;0T+Ym~O97xOc^={w8VLgqJV} z&}n@g^=}Be4)_J=#GsCq=AWk_B9F6OK>{KRbnK%|OMMK#v%Ydr3g$`m4)vdUxg6T` zeixs(6Mxxyv*--pZ+3lK`?u1e2YWj6W!td&aYOoGfQwpn0xu^`v5vt$fYid(vr`L^ z@~1PKt`js;hgq{a9kUTsf;|+p*AL+;P;U4aR<9V@*ihmOTev$Jx946zS0r*{wzY@_P!yG=D5RFv3v9JKK-*~ zdNhoi_T?cT22Z;lvEK5hDY&WuDZeK_pJ(fp3It&$1kdeQnM>~!cqBWLK&M^d%yu4B*ew)bAG-Vd^?T4A(GW@YlAc=!`9W3B;ixs5PA;t*SgTE4|7RZU^Axp1 z$T2^VgTUINSH(Nn5>sFWErLJ zj%NdeI`5D|e-XS_NSB#&*r4CjNr42qK*v(2UdM**neqRS5A7$-4e-+oVxXth!o7of z@noNVhj!JrbL8vjlQ9{>coDN5FUn@H?s$ zs2r#oR=yTc4hiNthc%@R_mLFnzr%+nmpO;6_4(-gYu*zOmtN1Q2?KN-Lm2tnT_Al- z;U7+-m^1+8#$utL*XB9()RgkKJK*`TZ3GVi?3>iia%QC?c*hoWaa?~!BfdZgh<&?> zxxP3!K;!}PK(6R}1B-0H(Ig!B8M@?zl-IdiN?lS5x$Kz^#cGp-*qGkFg@Z#Aa+wXa z-CPvh84ow9Z2NW!ln&{VZ3?BOVI0w#Uxk}@ruS5NSE}F5MMXG^t^#Tk4o;3391Wrs(upBe)>>NT>_ z`&Zn4NH8=36?#5wJuF56=UDL!$=_jHRmj%?VS*s2lf5BT3uBetxwxWW6FG#DjZ!WWU@pFzwzq2VUa;8BL;$Z^g{IWZIfWa#r%*aaYLpXR? zHO8O@e95?1ZvH|LNsRYT`(@t&*;Z+u)2d#=bJakK2R{vM?*n_CwPrK!&z%C4TE#L6 zPF$;on9!hKC+Hu!iIeo{4h)vpAfE9e;KM3(h#n+RNqkU91H_31l79py%-L4Z+{@C__cMGAh@cns%{_zy--6fVbi^#!8!6BS{q}eAKZx(*fiQh;i#% zKwcH@VtD2ea=r2E0uJA!RsU-FQ;wIs4*A2JqKW~*MECz=DD zoeO)K16SelTi2G{KO>5y%ZfRLO|f)V2=unWDgo^LmV;;nm*;S1W1WkoXYFoz~g1zE(0 zQH4Nd_4v07^5%LPUEA^<>*#@iNJ6N%c~{QLw9#!B>)j3EJ!MtR+vhQ>VZFVlddWOf zWwq$2PUD(=_EC0+{r&QTp{IiF2`?IF0)gW|nRmV?>jWsn#0I+GkMc9?=cO|@JZv=( z>sl59P~qZFB9&WnYmPY@B9P$w!ODX05l@~Z7NYmAD=(7mp@|TDjf9<<0p2kKU}Ivo z?~27qL7t4YjfxD>-+z37o|G|7`@`RPVuBz0zjmHDt>=#KpT`y-yhVAP{oo&n`T9YQ z+UDjdpHuk}e9ZBE?*0M7$j^gws&MJ)e%PJYjKz%9AOxI&-1dV6%x&&DHE4J3zhZbc zPUeAIqQ!u}gD`-J;laBe$L~2>I<7gDq>SBV{eF<#Kyc)4;+4JVAwMR$BirL(f1H=V zuN6Nl;+(Bfg3hkT4s5CH`!i*S<}{v=&jvmpG))Z4jJP+G^=#LoF%DPLVeMaIO@Qj` zja-W#8ci-Z=@%%Ac;GVx%&mv1lecFa{;~@)EKc`}*{Ln{9GCU`4iZev&)C2@qW8Ed zK3Heu4?FsLc1u#R)7IY+_pZJ)m_6d}|7i(k48jccDHCIBM#UW)}^D znCpIm${USS^~!5MssArOS3`94<0rzR=e6tC-ut_g=U?%Wl;VG8a67{99oO6KPBEO~ zaC4zCMf5}BW-e+wthI5v+qj5zb@Yu2ZeOfK=hSJUd%0+bq_}!?a|Ar@B*y1*KDV1n zyDa*>`#o*F%Qfwsqu&x*XeUsUBDgnvYej*4TCQ+}9Oae>{5RN!Y=m?qR%lo_O9e2s zg;AHpn78E38-VcP4rnB3Tc#z-f%wfoj7!Pnp3sR4icl!w#jr zbaDR}iFaQeQoahO>%N?YH9fc2kT^;72r3kjgkXK1^`qm1&oeonzTK%83j`sY&9!5G-hZ0Qr(So`=e0z` zer%h|!tngXK+gBLQb67AsLF>Cha~--hBR6e)(7et8-`1)XxW0S5>&!`yjH?c%>UY7 z2fN`)<>4L4r;257zn22en9Fd!^Q+@l$$WwhgaKmqI6Mx z5&~^i!j~YO1~Vz3e%Ysr?=d1oDoQphWtGFOa&-! z1>vWfkgs7()DiE!_Rqry`e>~~hjH@(AxHR$FFe`wQ`c2gs06YLwd}~(!rEEp`(vI? zC+N$(+g&;GBEBQur)GE>K3r&>DZ4l=+PKr`!of$=7i8HYnm?Y>U|)ioadnpUZ6ylfX9wff zMJ{kuN5}F0xIA^QFKGeqq1XQXtgAbi8W(gy{EEYI#3U&PR4UU2Ivb33ptp*jg=1ih zJ08JLNR2VwzNA9*&I*2Yt@dWU0j}xmfR4C66DOP^n;aE&Lh|U22oOqMNFIkOd_U5M zt6OTM1c2HRhnOE?KcLjqd>t+uK3O}#NDxqEX+V{YY7r`DoP4O)tEb5Xgl zdH}((X0~=E`Yv6&as0h$y$`%h1KAF!L%*ue2^n^qwaMbXvcX12V7xp#HhI@Wq_&ymc34Of5t~lydUf0uY@1hH^`K;-r=wUH7 zhjl6`9)a!bTyO@y%BlCY{PsCQJf|TaTY(|4jdX)2ah=ek{aER`HS^IIXW)paaMK|BV4~;nPMhlV*GS*qiA)#KSK^uFR%LeIS zMc#t0*AG{wr64FDhaZ54idA@xDFFU4P_+SC*Lm;NclU z?CUnyW!vd1x|Wd6OQ-8I<tHEF%P54`qo(XVS4?g+rYFRvZ5J!;Bk2jN0-N3saU zpBkn{P(`*I=Yi+owN}+6BIJ=-5{Kw5$L+#lKN_K2#r?dtK>7xM4PxHur^^jcVxQ)Q zDB$30 z__U%*P3Pl>0!PQb({COI_??^G9-YoUmtExm!FvMqeV% zAV;6jkXbLk_i&7hpbTi4;8!x%@OHf&yb2|CyROC0o)?E0WQ&Pj*F?C4d+oUP_6+Q+ zn;~+zbL>wFod7mpG+QwK)h)TfEW-LhrZJ#vFx6xTXD3>7M4iE!r6L`mTC0g9a z1^JfCbyd{<__j@k7TEa#8Po#0K@7Tq(M7(|l<5i{0bI#tbP^qLa~y(&*5E3*wa4@h zQw>YJ0g?LaaBR+NTAsb8EVb-)zx%rm9xq8?^kV;THy~#ZnCPIrL{kB#9!>6`Rt^cR zj7H1=ND1q&w06YI54!K8Xv))t<+c1Pc=_(LNG3Xh=tE=pPLs%O)}HMxX#`)29}>nl zq69s~glX;CmErkEyAshh1h!fp(^wTO(a=Df1#!FK_wsrY*^ienH|If~(w&3vH`I#K zdtAXDIUh8)+1yoeH;A_{vWmnA;Ah-W^2lof7UkB zyBnX^HI1)b2c)PR`EISg`77GqRD-jgpJ5Mnkdme89`kf{AwdHhWH{1Ax|v2j=Z8c3 zEk(W7M8mNe1XKudyOP!a_G=C>k_?+#+2-q z$M}GJz{D7?_B4e-AZWwbH-FO!9VK`P1hj|}ag@eT)SIm4T$;x~& zHYQ~+#Kw=e@9D78Q@;rS748p-6q?3M2GrP|sb2C<@EBaf+WCMnkGlwqO`&^ky|%|R zti#u8e1YPz#Bsy|5&yEW$4TFHYMl&895XfyAFr<@VC(k4N^bzYx5g*an#vrx*w_Nt zs4&UqC#1rMfnPSr-l%@a|JxxTh*|g5I~Q~t^wjIcMcmn5$MyGMAz=R8BQ(LMKq?AV z%&%Se-Zuf0-UL@zFNteJ>PKw+vi9-_gx2Fc$4M!4=~`KsT-k{{OdkTxfNR-hT) z-roVvE9?0=UX#!Hblnf3piUm;vjnbpdneZJPGJS!CBxfBcm&7?2o0^C>zU7g)<;}M zY*UzgaxQ;@3!MTU3c(3E66t6@M5kRMsd*NNhZo#=^u}E}#Y2TCLk*eqOSm>ppFP}@ zuW(@e(Y0ql?Og?#1f{3Jw-$hKTOxeUxC|t9iG|CNjX35X)y> z=7kNOGo+y3F{ItgMut2~>TJal9rUs9TjlXKMGkgyh3#A(XKyC+Bp=E?>SuE+T(}enfq`a>3DGJy6QC%>nan=Ve^l)Q6nvXSe z+>G;HG(eVW&#a^3F^$)?8R$D$^EISP-gfw0ZC5pT52n-KfHi^YxPN#tdd*)%oWdOu zK1Un~eOg=-IBs9lX5v2GAeINGWrV+7?#21<8D??*ZgN~xfZcD=t3M{_f5_X^nE6~3 zsPW*Mt6`(@H@N>oXT8pXvPExZH=U~mXb?P{of;+q9-tCj`xea%jE=UArD(9;x)_jp z)slMOx=F(NO?9lahX+6bid5d(;mK2yfpYzhdWoCy(^#J5^|f72Dtx6*r0$B{4xg%S z?Hq#RmN~x8#)v_FRNQfnkYgXbMFv$D8ZOuG@E@-~6l*D-u@7<7;J#wE@qZ$-03_PJ z8hRgA^!wqRkU4{AtSP?QF1S+Run9-<4$D~Yjo%s|uNa5$*DR_o6+CY@sF#%=bK_r- zd_L{R5!mFz6ZH>76Up!xkwL*CPKptZ$G@+85wu^rc@P8ML(USuF0gt7Dn)lINa45t z=}O^S?haF(t*^L5@Hm#Qunz@ZBrk{Z@&rOFoOs>2UU}CeY6PnvRJ>Qw!BK6zRpo)8 zAuP4jLv^p1j@|_KfWz6febk!!i1M|c^p-U#k$Qx+>p(ULrNRRbEnxL(dFfl=ZFq0C zKg8RB#)nMK6f>KXh7(I+*#uNzCq9jROSnMbHmXZp?F!Dp*$}TmZ;8mbj26^`R@Kds zcVF%}DwjCB4R|El^QU)}`XRZV*2fhTyUylEj=o0<*Tx?`o$|Fw;gyhrthq&)wQI6T$Cu^}|?A0vb#bCr6KG zc3Fbw-6uOJpTu{w!^yzyY+Nc+pUHa!>E#CS0rX#yaM|cn!nndC*jgN@Y`6D%$=K32 zxzuk5er7Pj>8!h}G2V3DAQioLBhuf9N7uD~dl_HXhMD*A;>uh34viXcif3$K9Jjy3!i-yf{~*4KA%&6>~OHG|yH*gc2D3(xuw zt;>6@4Pjb--6^3Qdh?Pe)RE(VeC{>(ZgjNa>TAEQ@S{G*+N%z$8P={7H{t#;I@h9% z;IuBOWw6VRxM1u}*L~sqq+p$rjh=rVq<$w@qZ?On4t#KExb5F%j+g^}4?&`$XW?Mn z9~$3pTkkRv6evQ>z+T%30>1VApyJGv^y_o@r4LKQ0>LJ2#_>|kI|*;KO^@93f8Ljv zF+w_a#Af~yq-O4FN3nu%4}94sUIMvnS>YtN;5I7D>O4RvW>HL)P9+RY1{@3?|in4OcM;oCAV9v8%pHmWMe7G4m^xQ9T*(4Zr%6K%C8^Q#=BLnIL zv}dJItdNI8xrMFsEIj3~>0dwT2<{4E74gh9ZDv16lcJ21Lx%EL@9p{>ypKfpl3Lf7 z5$gaP-8oyhfA+~xB`_|DKB?!;o@u)-it*T=?@oPM`@QvQgSGX>iC$EIb7z&uGw*@>U3)Fy|Cc9+ z`CCh0w&E5AYTM}f4Jw2VtYs2&+UzD^<++3L^HB2F2{$?xUndFBmsjU9$CR|GR;GRb`JzX>@mv|}hYx1o zro&16^A&^okY<~+D9g+f8N)l~i@pVv$z0;pdj9a%v)S3>UV~e>mmza%AD02FR847c zPA(rg7gH9*h#-hxFs!?cs4bR<6}4`L@N00Bn;NG$?uVR=L}!0lNY?ajw0g2-mk5^@ zG3PyvDxu$_#ZK?xd}6(`yN(jDCR8PA+mmxh&v({A@sM#b={|w6V>atOuD7!l_v&`z1h=-}kzZ*X+`Lc@J z(0`%Z^?AXN#NPB5Ohzu*+H-H##P1rlBao~>Rc0#z^L9R=FbKM}U)8usOU}R`)_1DP z(4R9XoEQ?^&#$06;61xn{%29a4F5rWKNI4h+^F_2e5;nO>TrpG7Lq36kkc|U+;sG6 zqFY<9=j+Tm|FeH`-oMwJgZiFSB`1tH(*Ke2;O;n$tJO7x!NJ?=>XGgBDaxE1LGYo>@$~5sGItRlm4~GI;v% z0YUE3`6TkEU!x5hOg-=v>s}h=u#z=%Nun{s+@iaH6Q<#p^FS+*&KAl~cWh8%2P zP)~W!vHF>ZK8QbiOVKZUk4T4Ob3DXF^KA~B1JF&|3jkAXb;YEr59yOsqHZOr=jB35 zB|F4a|k66z|(t0ie3Tyh?w};6r_a}6^XueX)NjiVp z@1}WnO!|SP{~W@&duC%t{@X7rGlH@m($_&H1y-l!+DDa3q*z^IG9 zF!@Sc7zr(*1^Se3pdQEjt)_j5y-(-+{wQ#R=$|-9_J{eEHza|a1@PkjunRL-F)|q@ zTA|t*X;qX=^9Fi(8OuUdGDJBa3Hxh$rzn7srwsM(XKPogM1mXGMFXq_Klq_`c)Riv z(Q7?9=dW9({t{<{Dl=PMDh#H%EMjk)ER3S;FaThATF|dKKR5=WopqDOFrvvR? zEu>eP^H9Aq;G`nxWw0kwQoFO&xN;uViY=gV{Hs#B-;NmGd9_`Ru27R$^9#Ks3Ngu0 zmdYh%wCO~=>#FXRqTsQUnze2q9j}!V6@>o#EBMB2+%#lJnrg$v|vp4&GC02o(nO4bmVsp^J6M&($QCji~ zR1-zvj|R$BJ zoSyPdxLT<`?PUB3(2XV6T^V|x-hm!2co)qUpA`$G5z1!*MF5HdZFzaE#nEFW7)8hi zG)QAYU5T;I%uhLjUa!)RgE^V20pdKxbT1XevzN%)#u5 z_#&WD5sgrV%|U_Fmpg^>jFEV!*Nb-%mkrCxj+k-rl7^6=-Cc!5J=89g+KP;G5y0DG zrRkf>WwjpaH1Gx*U8K6!UDPozR4o!mqZkBrx~Y^JfVqvFV!l)FCsw&#z7_Vt7Yd?o zcpijx5e7_gDy#L;;=*Wj$cXHIu7F(&!qR7|sViO>;se;a# zV6W<-kD+(i(xif4fV5v7 z->(jvD7MaTBjZ^rvPUGV+`|2-dfc?{VmnzARe0&eVqn?e*EjW`&UNS4YJ&%Fd~&ec z#IAL9ScHwS_jPov9Whw#dONAPn%s=?h_`JtP4FQk5BBd+wY83-Xm`Yym-7ZXb!4}? z5gbX$4V(&?NPNE00hj;02pfNk=FkW%BR(&64fMw*n^uc9h zmjiy(qK0?Nni{HvfG3x7UG#+&I%2omiy=S=UnRf=cqBpnAr#J`+!tgD5E5Kn9)%b z;D$J0yoMo!BXx>^$EZLIm{B+jZOj^8`1KA}YFnwb!n{A$Rm(TmNGDG<-&5j_OL$bt zsEBwEdN0IRhQDtFi)q2vP6pDE;5!${uO^?EF)$`xMqPPLG_1%NBx(2W2x(0jy< zc%sEb#j#R0D<;UF1kAY6bmn8;T{ zs+g*BzG?@3R8HAXi;dh=0!Tz6wXm;dw+$sShwUOPmvz`Kdm|eFq!h`1^dV_2ugl7$ zLovQ~N($yHdReIUkYBDJ^yQ~sJ-X{-+x2Pic zY9k}tsCSF8R;?L~A$goeZ@g8tG%;ZLRJN zw18cQz#lGm6M+?6r0VddKFjI+md}ZaVjU-EIT_fYB`;?bK})0<;XPuF+E%ZRRjH1t zK#xX*l~xIq3sQ`_S7=Fbo%t19qfAuwOSKWsU+WbP5Cg=NFx!Zkp(=5IQwBo8yC@EN z9U~0WF*n^xop>cR3f7nYVL%%AL4pxr>nF?my(qvbpch1E?Bhp)U6apvhnWm&%5U)8 z!)zM|K$2p~#Y)YNDdk5&FKX9A**!wd!B7O%`@mgvr`=f|PFS*7OkD>nd7oYik^hSr zUqdUVBeQ9Bm}zigZ@h;+oe(-Xwk~r`e%~371_9vij98(`7ZU&w1pJeV-lNZu^w!`N~KAG5I1`g~LA`1}XSSp{$Y(HS__hG>(kd zO*yC(hXM31H8$H&`$nCiBdC@hP7zw$U}9?dQ3`bjqrT!r=P0q+Q2TN}E95IluF}C8 zTS%M52K_@2;qW!b0ns0C@wI}67Y%SpZ|37d0mLrTjqoVjNiiSndI|FPdJu3=P>7&E z=s2CJtg?t|kAmfB1dZ%^WXFp2Yg*^kLUvwlnDIK_pn)jZjbF)@=V%2nZt4gi!X8PN z5;b=1%>r%O(Lzhg6*cV|ovOI}D$=hEi)F+u0cV@-6Ds*Nx#Vuz?q!8pV5`Q%Mem~9 z45W(-(Ez*MYFbziWY}f9P3;=-&;ll_MW#@MatdA{yK2T!5wMk1Bc!hv;ZeAm9c-ssI9`cO;B3K}=2^6=f$$n0PzV2>s1 zt!8K}t#ZEcFk3OkOL~GJ{PuLvkc{B<&8XKH)Rhh}+=W=ekAoL)t2<4J}<8(S5 z7>$;|MHX(>**1kifk6_%1`b;qG50M}Q4uwdhM}0U|b8K|7pF@ z?eXj4s3CdrHQH{3c+U-TI03%A-3u*aC*FX^hKu@ue?(vQ)*PMgm&vftm(K-;6|qS; zIfnThx4PY6oR1IZ36NA~lbi8yEus~D7wy@r;~-4yatIa@GEc=_HqYm#;i6D#wg4y{ zP82A%8yM?*syMP2qZj1dm@Q=i(4poerPkDi-lMLS9l}XPIxCix6dwi4T0fG)&7t-djH=0; zzz=1^TO7=R%Z{c?%VwLe^^|rR(NTX%f!W=Jtv80b$OC4NLl}59bQzh1O2{7v7Frhh zRDHE?_kH;-D9$2$ccm~)(4bgLdt=iCdVd6^c}mvclpy1xwcCME9W8kyoqnmSqUlRq zLvaaJShjOp6v_hAltImBXtqOLaRw#QvpPsURf_ijd;?5aw-XKmO?r z1`A=sYDEvC^07+zLj|?jTuq7s(b&J{yY)a<>GYSy8Qip0p$E$pI#zhOO+j*YxNLYGsh0M~n_g75;XkXXx84Ndt-+^Y z3~l1#%FHRQjfxcR78_{y+bjEmC_9^ZyHP0>$Oq8m3;YIT7q4L#1IWJZN?>@*Gpsh2 zwZ4*&XK#=3RSV#Lf!qcpbO1@u~8uiR`Z0^~P@QeyEr50xs*`EOhjH?s#g-qBc z)W~!a$vyfEZLy~T7n<#dtNOZ&lOsZTL$a-cdTSgJqMbwv%@NRD&-zzqR-bz(bXq@gPqkOMk4mCRwEh%Qa;yBUDfEjTPX1De#eS`L+ z)0<)`6DJH=Yp}W28pRb7!uenbJiNhjcgW|~R$NR8RynQfq`4(^{$M<7BNetzSoF?{Zom%ENvIjIfxultS@2`KHJN*jS%}|0^>0M(2K` z3D^w`XsxD;Z5>Rbt4Udb4VFu!)~)@fbI4gn%j;daR%wh7;s~$3{?cOG40IEdEhYkS z=xlN{1SSm7|6VN`D4?8nBiD*3O+?&bmF>jM_}nBwwo0hjfQK%(iis z$Nmi$gbJ$pU43OvH-<#8IUNr+ccR93)%nv=c1eG)e09 zUTzD5tAcmm-j7znLK-gIdTR8&p-e`fEVZyPuP4@iOhP}ot17vn8l5Ah)&=e=o5qj^P)B6JnF?)x*Vbag)10V9x5Wi+7P zAZfwDUaIbWQN5-`VU3oHjb$ALITgy8P5|RYtTs`Mq{vaa{IXb2A@+fO!jbHaSIUaF53u*WkLwN{<40#_kW z5C~13qiCW&>T+^wHANS#NjkPQEZ_DwS=ia{8-JO8cB^o0*08Jr~#m~+hms#7t=$Lel3t}A_TKl zdw~IPLlthWN0E*I1`*T*LIS}*zE(tIizv_<@yrN*&REzF8`HvkIg*e>Uif&_Y6 z=?HxmByYIa9q&_tZfGj=P-y-ryoVaXALxTF7ii34CrIDF0t>8vHyZexdPO598CLu{oIT?_c_Oh~uw29nB5DMYbMU;Pac&<+ezTXT)BbM9CTg+L+V{M^b{18$;;a!E3dMB=8G}wR zp(8Jr82E?vL?^9BTS4TwGvi@A=e-V&#lDjFj>OTPsOGciA=OR7HJ+gTA^f*hsSm1` zBhmBP;dFf6Xo1g0_SuLOR*}z-DJ>0k zdWixLN=T}F4xk_KwXcV|r`U?@2_P^-ow(OK9&`l>-nbVLsY(s|!S93Zjozim1`{(j zc-7|HrBqk|d|8@y5|v>ldJ`C2KW~VRrXcNCe zl`a|#=Rw3sO6kSAf?$jsGn7iLg$@!SUnyRlq1^^;io-Lt9o~T5z8K5KwqY(!=mQ%EVFjURBTu~i`jBxbG#b{ceAEQ+mWIFtv=*v+iV+E3hDJ(P1t)9_|q;Cx-6%xHaDK!gS z%fTi#Zu!L`FGU(!oeW?Jy?DdPQiPvH{n5@|2AleIH|`5Y^e!9$6-_M2xNa;~BYh39 zcp;+0U=2%ofau|6w!rVNcUQoe&llH$Ys7S~tHS{@BO=AYg*E&&UyoQ<6v95kZdH^p za0IIe1;&ep3Mz#11gvQD94Owx?a2sH<;JL2*aiXU*5jywXl+p2P)TJ{jhcp5-w1^z z21eXFFNfwE^d^SWz62vcxK4I$mrDHvz&v&uGLKE5Q*({Ba1-Z855F$BflEU7Rgvv1R{!BuxWve2ol3Jc6GxI?y+iyx+)H0T`(z2aG{`8%=_rJ63gXKODBS*qA8)a5qOk-#lJ@lP`=i=_JN6lt5W?gr_cSdT6H@pASGK) zEu+X$kq%Z-T+#`us3F~>spV{2Aa)|(s*5g<8i>$49m=b%y~QmRE2SpaRbAv2T3}6n zf-*#~Zy>IPFhFpTsuX%d#lHY2(U3V44fBl^RdcW}zu{ZE419|C-@RKORd!e8^-kt0L;2;vOWb>6S)k73(=&O0HQJq3jszalSsKrxIeJQk2Y9;qjH3YhE zY&KLm0o4`pD(#5S4XSb3-$Z<)Hf^`kggs6fF;t}>DllAm(SD-RMW>l{YA>#h;$G>c zrX12~VBZ41dfUBG;)Cflm+PSkaBBm9Gw1^n5B0SX-q^|hO0tgNgsy{TW|T`QG2~lY zVBNuf)~h>MPE=dcDfszP3yIF)I@pg7y2U`Z(CjZ)A{`d4ocRV&BfFSd^c%#?(uC5u5m-$}vbtYJ*K)iHX81L$*=04$X}n5UhPnMv zrVgEcR*$nro6R~HjT8iMisE9`1S4jAwUH62Q<1-|BYsd!Er7XXx$ZaXSfC$q3xGQW1i|aP*=!5*wpfAn5(GuK2tTFQq5Ap?2mxUZ zsey%=QzQF9&m&E>MiLi+r4G~__+*0PQ7u83G(fm(HC0^!RpyP9*Fa0Gu_*Hq| zvI?IwLbWIg!_R*6r#%nL9!S({&F0RlQ1KI`sN2LG#KCMTmyuMDja90(j?tWgoUnuX zo?ca|jkFA2!4kchK}ia1AxhzsfEyITh=eUGz$VO47gLeYKW9|sSHKEZq0Y!=7y%eO zTn5!_6Yph$hC7uiN<9&zMD0{iq&mD_g}>hH6AVvSL;Ep}_HGg7im(6(JKCeN21Gl! zLMGnaw4tJh3$!mtjb~KX1ZuDW0(yP$AdG8%&(c$WsatJl>u+VJgJ3;| z`qd3zGNh?kAna&q=%emB3K!k=s;Dz+is+_;P-Prr4?<{pjZh_Q-*`1Jid2knHH&5_ z#wvighjf!dn?>k^_-dNH7V=X%&)CBe0mQ7qkE^{d*ud0y8C}rhDELMGdXkq0alir* z5>=WA(6oVvHK^cNX*R()(H4PH_$)dFd~K^8M$u8%KP-px z$U^uL(~h9%Ez~3%B7kJ=AOZ+Nd*xlL(O@ZwHHg$2<>%|j{X^9@)j77$&88Vdp1cA4 zG60>R2jRzk7-*Z6wCQ$Wmy}a}hOheOPkSDsXqVZORHe|v3SRg@Xc1ZUhU*~T@bCLt z{ifU8bu%JL!KLPQ5Jt^aIkljB5H~L3ZP#zosEsbv#Of*xoEu{D<=JN31Yk_xRj$xa}mpI z3x6tuvt)HM)PzM(LaCP?3UpNB?FJuj90c;UlO{|``YA#BII1#2TJo879L^U zhk)7cMoaJ)qS{AX>Vd^d4aPG^SbJ6@*k1*_rG8_Y6Y3ypy9RASTSO0pL1h_lZu|Z* zS`+{et#P${B!=@j(l%m%pCk|plaYT!g-&3EjfmDf(t_3K5e8|52AI&B%9waE`pXLN z_aJs8(6k7St&tvYbjRf-`m4fPy6KDrbeQh(TskNcD;EmS{hb=Pb5NunqZ-s1svk9^ zb6`^f6<*2BkZciE)E!=TIt#utK>eeLvffn|h0K~nTB#B4)HyG3TyPr4@v6T}HSf_p zXq_ek(4{yTK(-bHS6z8Y{*+V)9|)z}6lD0Je_}f^+5+)JkdI8pi_BUHmhcXGRpd-s z(_zSm1Os;+x*;X9(@Z5IKzrCq1S$O*SfY8Ok31E}RbjghiVNUzYMfRCU-$}jHGW{* zXA|O1paRw2CX-C`kj1W#fhA`?-+evO274E3|2xD;!p-C&avR)owIar`LVF26I10RW zFv|E4!v65c-zUx;Dyr_nXaGBNSRq@oCH%I;_$Nt;heu|*En`fH-s1qcs(=mxIUeyCP;W={`9aM9C9-J4h{th z>B&kP5mx9L1br|zqP>eqJQBJ=z4^Ye4=?s0)v4s6IP^Avcf|MxO$Ma%Hj0jOgwrkVJJ(Vam0@%8 z8@sjPP%kcKps)eA0P@#9C4kscX+_B`sug zETRVdo%{{5bigX@QA$KuLuKq8q5&6p!lhDgT%Yy5;1mFFLnH?JYOwkVYG30jx|cYw zyehM{(v8)E_^x~fwbmcPUtey9Q!%>=?HGIWS__9U?Ft_Y;e3EEyimHBRS^DfWPtVC z@*q@?2;<^{1`~L2QFgOa@;4V!eH$kFO#tk}F_55SX7w3>hn*N0g2$a6wB4v{@w_2m3C!xk0Vkba$CZ{*$Mg5wuuF!I# z3(hNLTdc>)Cfg(59O3J5>GY|L^ynUTq!*DR)Oq!W!btQrQuPUnhd^$c?;@mITFekM zl(%ia2OuE`Ocaz30P-^^-_yhUx?f$tb@MbX?Fxcu0)0KgKNVZ>B?!}z0M*bBu>d0yTR zfx+%oinB&t(-D(s`?a>X^5L8euF<&J{F<_mb0)3|}(cV)X+jey-MoWH^SiHUus*;F0op9mIQPt{W^1 zG(D;Vjy2zx!Bq;IkW=7~;RJ<Xl6FZ&Fc8@+43g$Jql#u&C+co}Liv>dH zyyI2&>nZ|nZ{zl;&WTs1H_r7_ioV`lH{gR$r-=F>FAnBpuyJotGQoBGT(8?~CMBt=Ey!#d?2!Q*k z?CJv!H5G<{bcUj?IVql1c6(T}KxIb9z}!OP`SlhNfFM;c8`d<`<$;?p$k$Y0xzu@~ z$QNgbVc~2;Z7tO}2u86`2(`fXmCcL6MsJ|ZQTVckL+=Bw9DwvFQb=(;GwritbWjg< z2T|~fB-SCo#bRO@aY_0vRiDqjDEe()hd>K#geps)P%5s0%;LFXyjY3n!NY;NT*7(r z6=1r862%RIr4l+Fmn$)34EOsnm?{0u>!9vi%@k$r-=ORY1YeCVl5N}oq;1ITrFmHw?$<@FACG;VO^JK8T}3Ln)L+Jx2hj z)nEjr5!)~ibU$p6{a_su_p@cOlAlKu_;jd6$<69{2|RsW%{xVHO>vmja~UYpK~IN1 zH0CkHqP)cU7j6)9Z(s;aS_B;;+6Ba|QSkxg)4k5}V!<2t0(0Vn;m{F`fUuga@O**r zASh`X*VBhy7=per#pDCq3KC}-a5SxCl4m(bw*do;gxd)Clvb+P$*t<>e+}BL^bk4^ z?Wg-g#DQA_ltX9>oIgXTxwWoE!bU)u0O$Y$(n3m|PZp(Av<7{Ma-D6P&vQZK0@f?! zLIG(}wy5n$E@qMCc95!PDr+y{D@FgRCUU{pnD=VLWjgJ1ISv-mxX}sjr}}gc>{_|v z10PSQMO;hGc_4VLH4CG4r`{2`XemLyOd-HG1A(kiS;e;XQ9iq03TZSb^AR@A&;zpK zzX=6__yfNns59m3*a}2wt1U9BJ;)jf?P{p)=rW!qC;`r|$FFN+u?U`}Rd8Q_*j^bI zLD>U$5d5XFa))^6wq@`Qf^)E0T3xqP*l&$hJf_JiSm>hr=Cl^twx{SG0%pN$zBoml zLpdjm2l{la;*{i6bS~NIq0+QL@7CD0kkgBM+hhQ%ux~>{ejngFVI0dilVRWQ${i40 z%TsW`CGta`hWK0p+)l-Gxeu2cMJCMl-Il`S5i6kSssaxY(t}1k3ye4n31BV?J8=N! zlw~vL<*wxbT9%|owR*6Wo$D||+cPwxM;E(VZO3f`t^T-x)=@@#6)DdeH?cmL?YFZK zDAlFW5F(-b^J zhKklQNL@vwzUO8*Tk<-$=KS58XTJ6Wo?bLJ@lVHI;Z^ph^r4$Thzfc z8YO;L4^_6P2=J~8xf<2U<>;(tT?s~IP|&Rpwn;4>M%RfP(t$Vzi4?Z5j#sEIFIXOP zTr?<;`6N1R=YSbp*Hj&6O==5n>6{;# zh(P<5VwvKulMPt=V)IgJUlyu{uA`{%T2>m88YX~fM+Sj`B6Fy%;z34w&4cs~9l)p| z#bB5WG~y$W@(s}-UG*ZZv^8>l9t6jz7o;> zOA~3K#5jO5y9@k8ACoy+#@r-K-i`>xTTs8SN)@5SsCW3Lgcc0Q?Sa7so+J@cp=b@! zGT0TM)Gf-1PJ)lEQbGb2AM73jJ+G7|c0eFr1JitLot@U#Enw!##l4&W^+P@{>16{3 zCUIgFs`Z4C;t;+~uCBM}wtfQ)xVTf`;DmNMsL$eg6xB>}-IAPYr~Ig$EMzEM2HMU} zF$A{V-Y9HLHwjQP0%n)O`>vt7p=X4$A}G%?T&=hA4~Jf;tMLlQqq-^MdGjb(ttUG@ ziuVz3F#rYL5aMvfCBWdVB8t)zdYkH{5C_sar7ZlGNe*OznEK2Al;SmSycpa2wsYA} zWaIF)#cXTQH0sM#>QfgZyz8IBTn8!q+@Swi)Bo6H@mu`%^Yb14_m8`-pMJ~qTc_Xl zjZde4=x08CG5reu@m2iy2k_q?#D9P28=u~Omu%>Yq5srKHYEMi;unnRkIsh}W%{!4 zo44Qpndyt^htv1wzw?9m%V(#bH-_Auq2~V%F6G<<(*56{``?@Y{liUcjF-jF7(?Oi z&41$f=G*TW38MH@I*?1B-hN>OjNGR*-bdzmqX)*j{SH+?x|x$k!l#@icTU{%%}>da!Wx6 z+yAHR-G1>|xBRhB58wQ(yYMQ0pZ{fhV*f36%d}?6*8BYDKJ%Ft zCTlDT+u3j?&h(u}9v?}md1ji26E)c*O9Fk2>7A*bC7KId@hZ0&a-)Uz5&acC1~~k8 z$w|B8sqyHtN8bqC;*AGg4lt6q^Ncvjvy+W0L&JTzg?bRoByK1Q_5|y)B8&25=Xo)e zH|)94*3E}TTml|R6|QCy=6xhf5`z2!|KTgo(9k`?T97<5$-|-J!BW9!*=(gk-^9Lg zH07j;z}ARlEQf-61(DFv0q^gX>#x>4;QKsy$>tU21+*XNV{W9+5E7cn($(0I@QW;w zm?RFqo%%hv@7f5n$yCQDGkwO1vpu`f1L0;PHtdzA%Xl_TpN;Ir>yZ^5M6Uvm`QbfF z10ybFRe0k;*CY=wGnp0={=J!U`qfBY4l#f1Iq-N#i<90WZH%Fy>7KEy(#@&|cGcqR zY~8+?e)0Cl&shwgI!pPyaj>`*tW?^X(-)QL%L*vTzIglDE9VQKMNeLnzQlTTzUKBa zHB8%T{=+ab zEQ{k{{{HgO@3uv9Tk9W=Y0`TWb;f%%G)ls`$NCkGK%t|(UgP*AThKgi$1@y_bg-%H zd_6k#-dHx-|KB>?{Fs6G7w_KoH=lOf{A+ln zckd+A@?c9lFZ0)7rob3eUuiQq0`!s|vk(nQc*SfTcE^;X=r!GhwP!TQxp*nLQ!%Z~r0e^7rQ7 zNpPKEbjw@9f08{@ zK~$LE#m*hhGm&LFqnPrzt2i{z$^hl2xN~&Jm+n8GYYUzF6tn#UN3%Vze%3iqZ@-1f zXPt6~-|RPLfBfG3gQH>I{?g{5&!dCkSKc~fEC^J=L*NMb7U#uU&&j;C;qSq$I#T{# zeA|gP@%S!wP0#lq=Km?{-gTR^?jQU%>qvI(7)Nb5ciz6lvbCaFugz!{ez0iP>!aoC z3az>CIzEZ--*psja{^FL3Ag=${EX)jzcC{+*1A6WtNrHZ1De(M<~{s)Y+@-G_PPJr z)6Yo-{ zml_d^YfNj*b=;i_MxD4Ob%9mj66hksJzE;Ld3BK$>5>Ta<`-DvpPnOA>H_=2CDBEO zJ4c?x*?ZL`%>@QKN0#q~v&GD4~O+5T`p!5dkErUeQcC=TVZKM`yid z*G9U;XjspG?g{76iE9#PFE^Jc7Z~i>lDN*GA3I~=yQDa4m~);#dzsDW66I1Oo+DM} zBD%mO)P)8-N2UbRB>OFLm(h_ffi5-TIZ}O#sj?ko;P8hNV?KWJf9I)_ z-?{Df512~y^}#K5FfE41rIX(QupCe&CqJ{LpZ_kM z4)4wXAN+WVC;X+)ebq)2v0Gf8aPPAwEF=kJ2M$$P;U=aLVTZyz8^qnwc56*G0COS9 z)zv&hc&{=&J)PlKmQ z7QqS0!H&?FA!Y#n!NzuOWIz>ssOb(ogZb~OFac(rMe~?fYy)`6ccte$*b4AvbqXgk z+ypEQYiM>SgChwh%EK9ejn8><2Y8YvEodV|6g@9;=?`I(2#RB3q+0l z*3Wl*?Qv)K#5LK=yla<0mm2ZeGP%r+1W9$)(sK!Pfx*s^C1dCM&)Ebnc`h{ISu$N_ zOWI2GHglN)Psrq)C2w;+zxS?2zUO?_p_SVb{1#vl;oQK9!oQ)POi-Hh;PO~U{FH)- z+7g}}uxsSA+5gsh6n z4eu7Np5PG$cyvrtA_2Rx0CP~k44X%}dJ_PrdDf^TV&3r;KywU?$D27{+s~EAXQW&4 zV?u+<_*yg3B8vt&u5Uao3S-W+D}ui!b*0E{SA2azRQQqA-7CH)N`)Z-JC&K!#F zzI^GZGaeSwk3T^npSXsp&-351OQK7S_-vVu74lh&&Lt32$mb1qjx4DQ zEPt0Y7a8sxdA|CH=g|4F9~aAxfM zGvU;TC9-rO;f?70VK8z!dyzCFY?666vhXB*ZXJR2Z$~%taHHs)vkx^I>+0o822r{@ zr_RY`=hq3Xpy`lAkXX?OFjhPq84B|ns!Gns-J%724G5|rupr^AMCA7sJUKx*z6y~K z)WfM)EEsD@h^G>8%AO_MG^5XH{Dag>Zbw#t3S<_gKY7gVm2(jVpLw%Ff>2bMi@Yai zH(hE#ti(S<3-Xb4--&AyXRjHTG#41`*^;=9*^kd%y)IGCAL|TBrr&BS8dfuK@4Y#P z%U2)RZq~u_;5GI)-9C63r1`IpR@mbQ%KMJivqWGAisvyk;Cc~{Uwg(x-%=d<0{X`F zyq6mB9I1ZdEcNFS=FEZ4k>PvpDPd=&-v8{xH#w%o+gw-I@}xugzC~j1thzkQdxPdx483i$f2*0>it{1tdc2^2X{C96KuMQqnU(!R67 z$R$a`q@Rrt++$V1Evxt<4fo(G3-cY?V}s0zr(#w?S4`X}%lh=7eK2+oH5Dkopnzjv z)}{vMNea?rCfoRHZ1oXF!j{(FEJgJVARC&7M%=y$yEEYD-c0qS_#reE=?kVR=+O=l zy8|kP{Y6#`n5nFSmJ~c`6w>9cvRp^e(*w~>r;BiPz+$A?$`BCKB;N(L@}V47E`Rsp&M@JJph8ObUYu)Z-1`WNCw!!Y?!v{z-^;ho%x3cTUO($wT>?JyMu`8D zN8+CXYo55~C(m2ou17w1q!Ti{egB(KeQX(4-0;NB<;L&F9mQcS9OhVjr)vYcguCTX?|n0$tN?pI`{F&re3P0&&K+VO>6TfWfi!{UDp zN9eWb2)PPC;&3-;&srm#JY-)ShWPM~Gj%Vr?07g&@#8+U9XRVrDYZw>0v0z`d0?3a zR*>cyci3}3|Fd*#yf^<%u|)h= zFX(Por!CqW(VfgPV;(i0RTHVM9I@=7px>F%`wxKGJA~5N^l2YD zMqIQ7%=9~~2$y~c5pC+0=`sVJBh&Re>2}+CxP7<# zPdxGCwqE+K<#Er}`_MX;9LtU~tv|Ats3OL;mmCnYeUoz}zRk$GXU;jM&{NF04{#3R zkOXoVp$?P)9gG>bkw?K2%a(iU<@T$XfBt=D$bA++o?^%~e#tiE{>8B&_g4`#E6MVL znL0;C#|d>ssW?VF2XHgR;8ChVhyY~vuU<%i9Gmj0h$;b#0ND{BXI716gxoQY{2s*e z0~nI*M()ZrW5QNfVH6_aKN4jaM*zq9$$T;>V2|%7IzGH&8?(It2LV}auc#`S3>_PP z2kXerx6m-wT`;%^_^nS_9WQ%G>!i7&KpK(F5!4Q0MCX1G2x<`9v=IS-VAX5<3~)V| zz?^n<{8;$1yRbvow}JKVU>BmajX}nNSAb;;yOS!_VAL^$yeN!KCOeu&7wAxP%&yEu z-k)1pU1mUR{qLrQ`iMz(;+l`oT}v)u&L8X9a=47K^d%OxOPb4!caB68j5@3U8lr(}`z$+!SfuJv&WP#1#nn zDFi|Q^MZB;T`bEzy>cgr%*+rwb?6*JLK*-v97BjAS(#yY-GpGLya*0D%6T7*mp7g+ zmFckP3J5812eK`=cZ_3zjVOS<8i$@|h_eDHG=NjctN=}|8R4KrI7?;OADM^el4GYm zvQqrayu*a115ZbXj7q?CJnPY2cNQDsA~s5nJtnf_zxlI&n$k*=&PH(_7aYbE$Dufd zN_?)Us-mkXaSmZjR0L)QXRc)&ydesaqfzb%Z5kDv0ib}2aELlFXy$NWV{B`}uAUZ4 z!Xtn%4Q1ix+|mTNZiG2uMUl)o!WS@>VC!3)X&_-(!M8bI&-+0xuOs;fK2uY9&C<2#A7aH(vna);A$1Kr-Jmb$cj<$5G*l6OnmJJn7YqggrimDZ-Gt zwC7Ef6LLl_Fp_C&T2ZCv-DJO>`Cm6DjeiWban)|800ZYB z#lbvfILWsQ!XQdy)iF!ZF8A@Bz|mS3GonMpzKijR48p^cSx9A-iVS?>X7wd~gh4gjfo~x$XNwaKa=s0vMdswy za7GOu2)D{AQed+)i*^SFARw}cz!%WgE%ha#44(PmZ#+rx36Rljs6{GXsc{v;SUFI9{b9}s83()>EwP4BYM+{_S5_?!qJJEb6XBV78A(LS zLs}+0`5tx<5Eiv);DQ%q2UGiLLz-LS3vKOxdh<=M+T zxqByFXhf{;YkEVEB>GNVlRSSKUGiLFv}eoWvVuN%;v2OW_U%*eIPp}E>ks|zHn^9% z_ywf?ZzOZY9*6{pqnk?H5B+9vu1+~|Og~fcE3*R%OC^viXZpNE@?%mAAVWYLuD@otvo`-F(tYpE|12{sA11Y+W*mR?%m1cD zLHeiJEq82D00CrieK+k-iSiA{b2|b8P+X5f$jHdE2qSmMPP3vA%m=eW?fGy>(rK!| zQ?uBarw?j0M+WHca2hirQv~Pe3Qc~E7$gd1uMkwlmmma+kfew<9*6;=88A3KF*T@D zJ;3*DTQu1^`^jCq=@O&imHg*VIF(LZlf833zw;Ejx=lI=L65)^Wz@>t4}`h;9vCHCm^WuzxhOv z_`^8nrEjjReg1p>wf2NFuAX0iM2*~jE0lrCDWCp4{>3^ue_EOT$n*nL#m#>avj+|H z3m@IlF!#a)-{sb-t}p=o-PzgqRH&o4o}xlubXj|`6KM#l2QoweYC#mHIlLoJzrmic z`9G!&{@(nz9+@+$7$nvE=Qw*}{x^1uOZEO1jOznA7$qSzf!ZM1js=|ur$mA6?gG)X zyp&7HT3XV~b5Q=*%xdeJ(|+yl0Hk@|m>Syd*5LXA&-oN&f0XJH(d$_QA_eeE;L8o@-i21Ko?js1$)2dsKo6 zAZ&Qh0jvNPss_7yhRm~B8Y{8xG8CJU6<0w3nRs_?Ko51+Vb&dKF?(m=Ybdzm#%WR< zL*HNo&kkIU9910P&bzJd%zi)gwX7{0CAn$u@xqt`g$fiDJCNT;^yTV({~LeceU|vW zyFE?heaA)MlIAkwJzE~v zt_{D_igbzajsu){=DSMtTg^ppX;JG}Tahp|S~_}-Pg0|Q!BL~uD`sl+^VnZ5!Pu`S z9`oU)VomK`VZK1S))K}1<*p#3OA7Lpx2gx1cn@53Lg>5VeAbo)|GF#4`jUc}dhQWj z<~+dd)2=@u-qYSGuF9IYnR6AV>zOY#;yF@%^&vfOzu(&jFFW!5k00Hxt>_%x&TY3p z%53t}BqPk>dA$){aa7YD14>kAkL2xw7O=#C@i9RBG`e4T5zTxLAX<*y#;sZ$!@#5ITa z>3O^4_FKDs{Mr-G;Vk~Q1$q9;-M4#e?%w{~4Qq4Afpi=uEZ}}*sM>%(yhXh3x9|5u z{|v-Dtppp)P_y$8OyU{3zMCtZVG*$?Ecc#ZiL6nGZj4;r53`qf7}pB8)QFh--+00r zIC0I7pEWbi`Z#Z#6VLzn+WBjbtevmCe2Jnkw$t7E>!X)1nFa$u;+O{ee?Oi>hX(r( zo*c?jg>U)PnVz>?0J;CKqwjps>SJ9Le$|oNdSEj7-Y$$~#yvizuAxcUn%i;y!vJMl z%_d-}e%m)beKGyzyMJ&g<^OZr>qXR-Hj+jrQvJ@8s{^jgs(j)+N#w)4@a%hD-hQ3Dm74!HaMo{L_(3pUKD>Az>h-7^>+L+dF9#tRL^j(|%RRiE7;(dvYP zCqY%W49=26^AK|c#{|t>L|~T%a-jinko6Bc$HixQuX6OnHQCEdzDuM_jreSttaBDe zO_II8v(|!3qDzc+jx>MhZOhW$)VFWFaB5eyBSitbAo z8#oR)I%bjo3vx=y3ObBsG8vdo5Bu|B*bfmSmkvQ}@T>9AW{eubnFCQkf|0)5oCUKf z5&h1bA;3838yN4vmBq&G2*e)2Vbpx%!MA~o38jprYhCj~I@F#NGxqPA5?6mGB1B+{ zS^)X#(xkGmrVl%ZA)gts(tRp$hlLu4Csl6U38E;6MBMe3oS?VW zq-64wp*KT5ru-C9YNZjE(A&=Tak{C)Gvt#vQ3HGvZlNndb4^BE%ElPv2#JrFcJ zoF30TcU*E^YQ%G-O4@=PY99{9$}^5ZmqeEs?Hp;o^7a$iu}dGg=)`wFZkhhwQ?-~&I>*XAm_bIOUx1~XAiI{-pe%rs>voQZZ>F|GV{?C~I z{BU4{T<+iaA8eQVpR!vVm%H}?0Z`7t*mJ~3t+!%7e*vO3eJ%a175LzG~sd$F43 zAabvu-iQ6stQNR>f$|s8V5YilX4*AEXbwYs2CmN!FW$T8QQ8_qzxx%0fQ z5UK=tJ9fgO(U+`(93BtIV}cYQnK6V@P=|y9tLqsGSA=2)N*qN<6TCQFXgTaet#%{= zJs55!d<(HIuv)z<`+6$=*#aC0X&t*TbCLOS?Ys*Oh!yewKEWzHaZUOX@6ILAWyX89 zJg%ecyC@7{EhN{I-TnKCZ#V)IDAq3gtm2Hq;2nSHg>`~frY|dxM7}JP+~0F{qV*aW zyd(Th3*C95+jkt`!~~p5Hd@bm2UGX)x!cV3_~(yxjwFBZ^nSPX?d@AGIPsm%(ebue zh-(RuGCq!l-2QqC9@oP!8%x2n$L_l9276hvQUE5QmUvyridv81oSJ6h=ym>-UFr2hip12_d9*VkVPQM z7%Tf~d(19^;xC^N%JuqBevH{o9__I^n{)mZ`V`qKTCvBwvv_ppgNLNGJO3wVcUs@f zcBh|a_BoU967Bi-o{;<0p0u9O6`xIC;+?ym{W9Y{TOOAh|N6NL(AmRh4|PJ0$9KDH zNjbaSx$XAb4jb8JQ@Z|i#2Mz;aZj-$znD`wP!51TDkaVo1xA#0mYw*-o~QXArJeKM z{AcmwkwcA@Sp4Si+P3A-uv;A4^7ikcrQe~qpsf^0Cy7Yo9CE!6PF3t$WWB@wS-1WOWU79fJ2Xi|HI;sXgl+ zTbB8+no8%dAFbU7Pwgq8CH~1HGK7)UuwY=+rwrQQm4_u=uPW|bHwlNV*jP~EFFLN? zSKfNNYjr$u5#Gyxb0pKL{dnSe|%N^(^E6*+;;m#O98(omCTM6 zr$F2O5Fj4=!=qEoIWeAcihY>CiJ`paXDmkEk)pDjv_!{u`$f1v!Wqos~)w%?O>8AWO%>B zR+g{~K1A80{)#2#I3!>39Qd8Otl-NIztQ*GUyM;q1T#G-F}UM7z$Gsb&cR}mH*cqJ zB5M?PqxY|Y#_U$Ty7P!k7PBZ61A(1WKsy#}QcQy=(p(S#jAxDe;OY<=tH$AsLN%00 zqi)Me&u8X9Ws|_({)E1QiPUAar%V#plwh}GR^Zw&qNgobZ}2NdyJFItpCZ$2r$tFt zvtSC7g6Rh#4*OmfM~0{))gbyC3<3LNBV6J2k!wXLD!5fvkd_V3gs0a?FN{5x9dC1W z3A`GiW%7(z|3NN8IOlSS&9C$kTkS*&m87?I-Xe18vP+DH4e~orPNnKzyyM(#O zaL<;;ZG=$T;jEqIk|uHfVCTq^y1*WHNpq3m&XEW7qLlYsAJZ<4)6_49{GvK`x}TH_?B3cOj8~Vs0Ymw%ZT6*Ov438VE+q`647cr4Kj}Kg=G`uK4AL zFnHeLv6(j^C}-bv=wt}yZx0LlM2%1eULq8xmjkl3$Jo;bL|!naCfK)7pM(pNK;c|uUGK*5IH@R z)VSFqXcyz?cMVT2*P*Hu&`^98^&A85E{7cd6)VX(aliFEP6#A>nFn_rSC<+QZ|1KZ zZLm|pl@r%wFEfj7nJzTqvt@F58$a~;OLdm~6D~gSERJq?+qwLOyL;d`sMu?L{xhG+ zTY)$V$P?{{M$7u>6tZ^*^OX4+h?H4}Gz1f zr~8zmt&bQ3zCaYw2GA64gc7Qf8&73|lXo(~Qy~LmHYB8&mP><~5i1&n zUJzjOR285j#zL>u){^!dvV}qdp1RarVKfES43lcLX6nvF-BF9C*0y6ahiSoNA3ZBQ zqz63&0X-VeF!T0;e$8gkdi&<9MOX)UDnSMBBL$yea}e(i5-_p~x-UH9j018B_UXvv z2{xB+x>5lzITosB;1Sm|B6DP*f4mPzUw`TT?sDm=Q=ej=|Bp}5qbIIO+EUVzu;-si z%zk@(+q$0Z5~Dp^7MK3~_*@O*lI8rd&XFW_0afM_<|4zLBhSa@s#TXT=Z|%cBneCV zP_+1+^t(%x3k-ISELlf?o^#T;1iI9S=SY>hz`^Gd=_13OBTwcchpf zM>1Vtz;k3GpTu+rEfw)j28v6lOO1GrR2g$OooO$*gu2jx=g9OEXIXD9SMgOJd)x<3Am%Ayq;Lsg5uGK; zS>gVPsX=LhK7|V;C{FO|06l%jyX~o-&t9_V@dQ7f5@h<4W(S#gc8e2a>fNH4qeRdF z_<>X`t0Q*AdQ94G?kU+!@51yhZBP-b$8bCn(V3!ycM1c>-R{NqU5Lg7UJ|@fK>)1_ z+-FW9DiNqRXaV~{T=(J}3|JOQ=hYc#c#bpSy2d@|-``Ig@L|hO5?qi(uUwR3 zx?a;+j4s`Raw_}e9)JK>rw+Umhxt7d!Z~K2VnTfB$b>+o&dNZY`pBNp`G0F3{(t9* zhyT}p(LVhD_R-;g+t1^eBG{aWQ{Tk8Lw@oqP9Eb&lXDbY9wLNI)JdRMIh66>l=%Pg z8=M*W@68$c@92l?ka{@zOHknV@6L_6w4OYbzd+HD+e(~OXSPT2aC-z&s zJ@Fy*#Xmdxo`+v*4=?ot=cQT?$x5>R?!P|o#F?~zjfBF>w%(Ujp!WFT;Ck8r@UT)I z^N0xb;kxaAwQqYn9H#d-;3d6$*>tw^UEOD<;!*ak3QN|u^#HjRz(}(Va=FNp>qfCE%G z8-;CkP9%;bTbZ!$^}qvSCG$}DOcRlFW(&ZMR4B9A*c|4dWSDDqP%%&)*0-=k7CBlh zo9KA~@sO@FnVpzpge$>lM|n0Ajt#v++);N!^wvbMP8N77Gs9)c#qiPWnSn`qtBFKm zmO~W}yWt?5o$5N)Vqf&$Ju+NcEcUK%+fsJ#K7g~m-+c`1rtdov?s3)m!cm>p%#iBr z{VbOMH<$3g;w5aaif_ISKmq>MYn1oq)*gBKapl@z|Hff=KIOP_-R2xu4<3#d&8+L7 zBkTX3^Yo=7=Sh;>5mfi5Wc-_-9s%$i2jeMj&-dizrA*~@L~%+-l%+23e_${8d6DMo zz4;A(JT_efstf)t+vUl!TTYnt4;=RY1v~7IpOa4UgveM7C|1JGOtdCO)e*&cr$7Avm_u$05vg>Ukb7!)XPwUFb{Sz zzSK1PUxC7b7i5zqLgb{00cU{1q_6|<|Df?kD04#%oKl+}>587*Ig<22E4%+{S z4%%<7vfrPp%w7h)Z@#AA&&uGvxwWUPjsM_L$%?{V8**^i&5xZlptx^>tJ@> zNoUl(gZX=0C(3JfPC6yi?$69K^j<8|IRc+_C^J;N%M`Gb;rHD8z}^J&KShuI-uzGE z$754PhjQ{C+lTTmuv?yYDE}pPD3_@w)}jlyi!acg8oWkMu^}DRa4#iFzEQew1WJ<; zi*u5bYMx#wh=!xgP8`(8T7hDAgyNVZv??3)|6}h>fFsS0^T0WK$l@^^9!>EY7H2Rs z017}|0ID!#lWYKuqj5IQ0;XqLb)xD=U8oC%YGTEpX^C_crLcCmT4}X9sDqX$du3T# zuVk(dSu0DjC5IGRQ=XDnV(i>!w@gaG830ua84N51E_Z*6&&CElwPXQTok=9i@$fsYf? z7EzrT2%UU}LBJZRNylsG_|1fSKb?U@rJgKEK;}9eK}w8KS~^JNVgVO4kmyAx?EEp0 z@>U0~xy}-GkDita`J+*BB6$bx@D?4NE4% z+wQu5!X$XHJT2(;(&l5U$lR{?SVv~8r_CHuT0a{(rk?36U|b)xKrD3u?J zWtw~)X+0qg#46}bEGy%o52{;xnvb%zF4m3tq*jIaeAW1+erVo!5Pg8Vw;}sxzLaRxVm8%je#HaZWwke4fHl$$FkTtMT zM@tB^Az4UCKxlgvWrtR1Pm5C%D2D3?m^~MsC2X}22s|2rJDw@Ut2xBS2ze-^8y6w)Bfh3#kfdt-3C+({q#|-r?HCf zg1S*0W!SMQ@-`z%4htR#MiXV+3a$+#dj67sNa~MGcQ+`M&d@_yAlhw1v?WVu^R4<& z>gR%p?XTtZvE;rZwkA8SX^}p3Pfec~67yBR(`gzsAf3NE0Ok~^Cwdax#|r%0bl_>O z1^BHWtO)q{AQAB43lNxwrwcXHH#)T_!K<_-Y9(@QXzfZk^x9#9XrVYx5c^=Apxc9- zpa&-uEXG50r(Nr+Qu3)?Y?ns=5169^{cnnt9L;~XorFa>kv(G^OnAzHTazPG;0@UF zDFR^J@Mp6WU?p}%5#gV+7JexkTTp^Kkv3!DH=y%uFFeiFhNtl@c~_o>J}_F>Q1)72 zEI4*MQNStHRgKTh4FFsJuoQ^+MbF#fZiG18q=BRk2`O07q>F(uvVWNHB-?MYM~A_8CvB~RcBK6= zMcP@A_U&>tcjwq`lKb&Xce5V<`RSdz$HqDTeH+0UxhP)%*%3w77j8$w%Siee;PZkc z{i#n&>?+_j4f^{QC>N}$Kv#?KB=XJqX_7oUlt~1dGjwH2>;}6XKg}kBGAK%gt~w<# z+JW5BM4Oh)R-^Ga65=vX5z^P9w^9`WD~#-Dk*p7Pj2cl5x@FMklx+$|@sr(X<=Ev^|hvG+79l0=&qXv6_g-50V3jG|?$jQX$(%QS;!n!TM(rYccnV?K3b zMT@uN?%PSEyOx418@-dkk{K2lR`s802f#t%1y5 zjB{AKif2~%{F+{eX=v1_LdzxhVny81#S!;2f8l^Q#rYy{gU1!pS6!)$Ek9^uh&<%P zgQU+NiVeSW8PR6tcoi3oAPz1My)~bwBveR8z(V|}P77lc{tp*BNyXjos0ddEyG8{L zc=CdjD+OHR&XO~=v@ncA&ulzqDj~{?k}aH$@J`ib#9+>B7_dIWu7Tq|*+PNL?}$O5 zyXFX{QlWa3cIOZ+m%-5ice03H+3|Fd?@C!z-)hB-#xm_+u#!)0oXN`a9wDp>6@oul z=lYYj>OC>GUvz&^nCV6LjIr%r%JgaQUs4ASXmr|i3RuMk4rPA)H9}f)(qA(pc9@gy zLP{e{#jjPh=EIqUUrRzUV#e+W*GmUqSxXR?a#i)>mHUY1m5aL9hzpE!3mojG@no@r zSRXUIht#=vHi{@A1lKZ`omjsYYebR2#oEEd{Ov9R0=qhPnbdDBNuW73KG2t z($0tW+g1)}H)=(G2wZR(8D(Jy!1)sm4yD;5hbnsyZZb6N8*}?dhR6!WISgYZf+u;& zFjC0C>n6Av;#NsBChj6G&t*y}^24g&A{Hh6Wzn@uc3D9RcCuXHwq_Q7AoIGyP@Q#i+aI@VuH5VkQ{*QAWjuYds$7K z%g@vxVR4#;VFf_4Ywqxf>x-gUioL2N755$OeWtXf(N8VV*q_??s#TxA!YM##1maQB zG~4+8Kei@%(&>LsQK}dM)9K%8B{mH(`xl47I|&8Rx~4_X3o^P01#2T4OnZI9qlt(& z>&rV;hu3#N^Oz)F-Q9DG7}LcM!7>Wdt=JV@pZCLghv= zogLT!Quh7?H3J0#9&p;BA)gOFX^XSBI~b8Tw(B0M4`HKcw#|2QS{MgX+gC{|Yd}rH zi0D`>W7p(1d5Z-{8tK?RV2-jjPH7bZmcYiSbG##7OA27jw`yy$C*kmQr2&W`F%2Me zk29*q)V${=`a@5z;h>)xBzhinDL@(W1@bfn=V@IXXhY1Zm1a-HyQ1a_UmZe&5RX<$ z`N2V=;^5L2qK2GH?4%n?jROi*FcqG<8WWrLpBW@3I}nwoe0-=YZ&G7y_E5MR{LKd& zf|~HlN=UylNbujN7^>{0sl9X>#<1n^D)aa zUtH%S6tTdZeE##hezylM&U*3gFkGEl#C-kyeB|7%ym^=1jl>xv%&%c)E*Qx0^}NN9 zYgY=I4sAR{I3_E%!mG02gEANd^66|lntG^Z^I&V`!3m>ZbPqQW*LjNXRZNF|Kj$hR>jMO zBPpb5nK_4*P2~#jOfi$Dcmtw&+{+bEAxUkTk#&HA{@!YPZN=ZW*qZD~GkW_UNQ{Xg zG0o@-$B908^G(;mzeDE_CLRR@j^C_ccm@f^Q%Y>Nn?DW2UP?QF@3f;9$Q1L7GLPE{ zMZ(?s$)T6-Qb3zaB?VNq=0{AQ;CQt-9vx@?dhV&C8xu`W-8eglKMs@RxYcB<`4&Yx z9@xAlpe-fwvEeR-5SBVAM)2IaeR=fe)`o^%K(4B0%yk}NuZ-YV2Iode}5PV#Q%n*aQz zyzA^vh8lPQat*(rz>K^IU1XR<9bSyE#$PZ6pDbX;TAFR3J9Ct)=XWyB<5a(yAhT!5M--mQ}F!4D` zOL^4d-=U-=IQfeFWz5wxnuS|im2iPa@!-&60ZpMfR*G`g(2>)j?sHBqAQu@$@<}>C z3||S$jb@r+DA}n#TuRS!Y^G-+c`wi6(h{e5DO_93P8(1jlniT*yM)G&ehkK(5)PmO z>Rhz0O3IFTNu@gknQN*)3~GYxo~nZxe%i()tf?Fxp(zq%)!qB?wR?=Y%Rz3Bp?u$%dwU?q2=ZshV!@khH%a2;LBP9LQQWFmjprzj=&woDl zkyy#?{iqDxmCx1@{$|f3Y+k{nKnT5@9x~5{q+OOFXr>S2{;?#D7Vc-S7RcArqw8#~ zw-|;LZEM(hss}DAXQ|msX@}7$rMX@7gGOhh4%($)GYyCOC{vA@8a-+cfDj?Oxg14* zLDC?G0MarF2R_NgBMP*oEc)D?4^adii_-j$BD?2!x&TR8gW^~yJHnA``_A{}T$+S-_L%7474zLf)oDQ;G>zuCM z%bc#LIbD)-+L2Q->#$bMah^WO@-at6WL*rR1XqpI)&mA6T-|VlywF2)Lr7gg!DaY~ zHRwm!8}>EWhL|B~R93{^nL8&He@y$QVG+;9eBKl`2Pri)Gc+=xb}3KyFcOV+dnyjn z{#F~ZtrYa&oS1X`vd&V*R|yrf(>;;jqyQpn3%3cd+gVD4H6@d5Y1|U@#k*iYd$z5W(~ir6ZXS{9NxpU zmSp=)_UJIU?wnmCVMmVfC(9{o-kCbgV3HvWWroJVGI*@YFw4X~GUgsSg9R=Q-w5JU zDK8)CsNfz$aaNd;D?sg`JX-wXF5ZZXr@k?j5^JAl)Tgkx=+QE0!Qy)1gNr4Jqk%P< zal3JZ22-XT#JF(7Dgs<+KxJgOg-u27rgeolrBD9DKmu+1e!(_{R_)gXuY4hOnX{WTpwcOCo{ zPIv+m0pi;?4(b7im{AK4 zU>~d#JUU49I9RM&!0y{(b*<+Swy{{LA!s(4caX)(#?rM3aQxigEcC;PZ}ki#rD*9w zq;G@3u?Qj!uGVkefHMAzwz%xP`GLig{sL z2klr|eS|~=T_Tluh?2#_7e%d??(%@$^O2W!Ea6M1=Xc^G=jX1w+~pX5?wSv&Smuzo z!Hjn5tEs#3=MW90heLfcfg~w~={uhQwRZBG_uxs~`lMTTskhir&v>?Gq=K%-5sYkV zpyEJ{)cAzwPn7eZo3Riax88!_2H&v6jq#U6FISDf=$mZ5FxMFyKTIOW zk{OZUl!u&nDhv|kg*>h+MgUQcQvV_eQl2gn%p>0tUX$6#iX|M>#@(J)Jkhx)O5ssS zBQrm|vk6q>IX0+1E)+(lBXPKjytFZPj{8GmulO1mshqFoYhbV-r^f=Is=h)Pf7FSb zloV~gmy<#M2&RbSIL-gKIP|K;yUJ3Gax7HRdZmSm6YV9M_1POd6U_6%n_~^S70FWs zQT19}&1|nVfZh)Qy`40A5efS9yY+@PKH2HlASFL^K~|GbvV&`6L$y z6X7$q2HJ0pw7ta7swE%>!1fYta?6S`VlSXLP`mIVtpi$Pd~0k~pMI#l`b6Z*j&E5* zsd*wt3ZuS_WplU40;+E#ytd-5!?I!t-{wu6dxrhv6lKjS_{V#x!XrXP)S;qR|3Ix2 zvBj8LdphXBvhj<5)50QKEE|*DHIKbR8Zk72MUh@1`Ps0U@n%HYIRqKsTV)BOksyM) zYQ*{>e5TX?*8k!Fm6a$B7blTx{*H8Y&CKo14ivIAddKJCfBi&@FrwY{d$=*r`LiOg z``M*LB4ZuJixbM%zv_TeO`di*efTLpji2m$8ozPnDY4^d$6GeVH2OMEqu>Z#rdwG9 z2H&uCO1|^rQ}WP+1A4S6`EPbwv;}pO6(d$S%}*)vMyzX|+!`mP_#pw7kHO6|xbo}C zTavTlWW##$v{J~AZ$*pgav}d5ju<2>=|VyU-#l&`hbG-yK4H24fQ?S9g7WRH%wMn@ zr%zU-f6>--d)BFm(6{eOG>f4z5&Gi5argC4ey_rw9C`DFfp?@&QY*r{3w;eGYGG=W z_v`D}*g|IDXnZz`)L%p3loS;KM=*&FEq%vO13r%|@|93F6Ej|d=j0s1TakO6drYCQ zL*<2#zeYK$v)59%egS_+D1eNb7H!e4n)|}Y&|v12G!=YtDt1WZ!{(isnMsCXY%~*Y z7q--tN`!`+XY@sZ%a7Z@(h1rA355KQZPaEZdc$Ce60K3J~Nhp9sNpxe>eW9CZKV3M!8g3$vly>pO* zeTI3`x-kk3lpZT|1@sMq_lQ|iFRXL(+#tbyGvlTvqtl?WzVABtM;VJ0BR8L{!+w5{ z!`6dK#5HeFeeZyQ?gCL;5K16gHyqP0Cbi&y!g9sG`o@CG zF>Na$UZ~B(y;hfCGIsU?rlynStcM-rQ=gFPkOEbc{g03=7WBa%nQTEy@i@Jp>#io+9pR3NJ(O5~l5}5JN+GgCQ3jrcQG7r;lE2_WSR=Fo# zXzM>o%OQKjOZRz4PMYcAbyZz`>rrc#nItIQaRH{2Ks z!zg<@a^7O_ydPaj%rUO{yO^B|3ZU4xJl$#)(zxb-rh}OEI z=TSC~0zu}J6-AFu-orMj9g3dqkz(W!n!VO=0JS?$(uUcNCq-ShJ1%8hmMxnOSd@0{ zCFe#`*=3L8puh9G?5E;P%I;*Z}r&4k$Cd5uS1DT z!$&LRsxi^eLSd@?cYn?Sdx~nC&zN`6jPtNrTeh!pissKIb6OO{vu1^Ep$aYey;QtF zFA)*%B=NCrJJcm+!1<%X)-uP|Vi)2Qkqlq>S&5^0Rz;((FKg75%oVc*9ygSuyBdy? z`D6)dJ)=I$X*4l#5gFu6Vnm3Fz(kmq6WuZktW8X614zr1LQ%u6o*#(+#CTP+N<^$sx7il79xQEho6*P+429!f~QMn^AanhD-h#>m=JQxCSNpZV7ow%8KA;9h`RiFlacc2dlO{m4}D;6B|8 z%CQ@tC6c;od`Caaf(g1`d}v5)T-uT4HJ2a*sWkD}0$~s|kN@N-vx^h!H%{e@C{$_0I?E4Q;Xnmbs!YE! zyR+&{gn_cuwD5k*<6y*W=y2vx=9)3Y)pSyNK5~(^6!~4S9Z=L)Y_w}7{)aJYLHg{s z73u%hR=Fp_f9MA#nnmY~@SQA_qJXeacBgl(bv22qTJxO{3gc!%2B$!3`reYTp*4hB zspY+F7_QGJ*}a-X2o&U-NHTAB0!cxSpbS?@Q8#mQn^zgz&ku-67(h#M3XMmnm^^zJ ze>&}h#a86)zbq&20ais@8_A8lnK2c2&QvlfcCY~{day{2lV|2N%rJlDu?={l%JLx6edV5IQ6!24cSMB4 zaQdgLFSNOP|6Boi`(Wdwpc~w_LmO)xW`$rzo?1b8oeL>UbuI@0pY0pKs|vuU&C1=# z^-Jl|n_4xutkwYyADCyi#+vs46E32qcsf%7W~wEAwGbG0mr@cD#>c78tHwwB2KQSO zxF43|?#Nlw1g=)CCvcyd!cxm@#z zz@yxqNo2X!7jw_$6$<`3N5Nm~8wF1)6nwG|6lm3YLcxcxvs=a7=`#SY9h4c)q##;} zo#BdC9IwMIr-c%7WNS-%L{Pwm+EA$aevYc|>l;;Wg{trA165izg({`;IN3^m+{zyx zkiDsD&FcxNwBRZRQd-!R3ruMl=SmCyFm#s3Y2!9-zrbCy%xaC@s|M6!v{m{@FFIHk z!Nj8gI~S5u-0WNqZ2untquqqm$1n*`{RgR2eVJ8JaygQD=z#~8C`cP73z1ihYfr?x zEU6G-!%b%>FE2j^O0LLgEt)}k-YiA3mI~D)9)LSKT8?LqGnH|sT#b&piqZIS^awY( z9~7!c{Em8bfiFTr5^f}Iq~Kg}5&R33s`16)bfr>!-s?S!=JONK8mjpTWO(u>>xq~* zm&fJoUfklxGh2+ZA&$C-*9wVDDg%vfow+=q>@Mfal}x2du8fp>y8@{bEhYH9#5>7& zI$wYfDX#w8g*!+%CA1 znXEy?_DT1o`vnU)#K+Re(eXv%4)mdXhHD9PWifsWhWU}dGI~J2A)njl^YI4Qi!#Ke zdngdT4atePoIrTUUCh*z+430Am(21c(>O|n9Im&5wmTzw(dUB!N0}|fjFZoZoi#K& z#%W<3P=xb{pPcrGW?(K018HZvIcSp8cB_ML z8%ymsOy(u_i0K2N={Dc2BUf;F>r1t!t?$wBS8NS;*1;lJ%|mK6i&4?mHho3*!fX}d zn;h{I&6dRC4rNArU#l9<`>ExCO=AOhWk`fRLOehql0Qh$n&!u=#y5IKoDqEZfd`r& z>dI4ICd1h}M$#V1lrdk81rH9u^q-aHvFTp7V{Nk1sCm?~(mb*Q2Cj{kKRXQAnhE_; z#*qa2%_jx3_?tVjg^SXJ>ymL9<`&LvA%RZIgn<5^&G%g8%L-8=7v>n(^kjsvWcmyTnL^n%ZBg8#tj6dV%g;gi`j|T? z+PWJVBemPbE=++YUd`n#4Y^0n-dbB?dj|{vYr_>UluFzgD`N{#j&M4PZtGBlc;I5^jwcjK!dL5Dh?p`jNtdQWjfkOIuvr~+lubTOx`6BE}s?3 z_@xG4=W-4p_Ke;Sc45leAi5TH7>5v$hCrH~k~d{!ftuh7^VLcQ*=wY_S)_4o)$KFg5l*YpTob0bW0|k3`d;}{wF8eTp5s^5> zT7Al0OcsjFc28m0PWo%SPz4~kYDBZqtEAACR{{&#DtKl3$D+D!qgbbf?oj3f_8G8D zpaxi%f=(mo+vKusgQ2|+*Jh`!0MwMOqx(gJl7%$yTbB-K@6JhrO6yge#Cjt0j+=CJ zWK25B|u%?CIjsEbP&I%rd_v_ z`Gjo9JtkQ5rS~J}gt7G;2&|Kls)qpVkQ4Hh^RoFKqBh!FiIbP7CclzFTpdct(ROU+ zs&U@)LV@nUBC$W_G;Hgf54o944Fo4bW9~p;B7lEG6W9y;Llf8+2mBNM5!}+m9mc&C zmhdp_H!qI;>rP-O>_@%?TgrBZ!avOGT4CZa{hiE}8kjfDAeO^Fsce+FQrVU`2d}Ve znBAWDR5f2hN~G*lY(iySVW1Iqg%Ng0wpvn`oSP+FjuMPci()YR(sc+zTw#p^a!7?- zF2YR=CvheZ(S|ig&Q2b%<6rAL31WovVVd<|wAvw?LUmbq?5IKapQxG0NyG(ibs2|KW(u#sp3 zWhNg|LJ?bppd0Chjuz25G)NW#8N~q4=puFwPgz-4<_0inny?y3bKtGtZ(Cv|K#_Z1oZV!{*U)aLK;vDgCR=V6*!E!#W$qNXtH!^P!z4fHMlk}0@=b~mY4?D zpjx~TRD)UZI#dH{@gh)Nzc2&R02)AJ7lGw5Mt5L^QdTzQD~EQwYj<-_BGUMaU!34&Cd%-a4Esi?6{I3Z8pbmbA_O6d^XJJ}p>XVaMvV=^HJiyN zT^QIzDZUvkMRVmBo=atpFoFsEq2Q+HUL?1GKQQJGpk->haGK8+kQvzG#C4fbSl5IX zuRKA8?(o;cd{8{hn!88rwAASitf$VT%mNiinvd>GW?XR1z!&T zJ;wc~cTO{jN?JVd{Tw+ro^pHWGGc7a$?r2!PDhK$krC0H>`gYO*Wq7f9YRE_()2W& zHj2niy2t&df|I}`A!j_PGKf6OxE{uUrzc$kG(6$< zWOL{v3S%ZLIE78n$f1v+e+ilCZ4fxh-x1C(9Y7mW2*5ax6E7EVn}kV*d}c`9Gbs!s zfrSK-Z`VNm6QCg6Wg$l~;^NgXJz61?TG2Wx0wVSasvU^!+7t+d%o?~#jdexpUlO#B z6YZ7cu!THcu(ti;$n!2Y{v%p0S7Ws1hM~GcZ_jvu3h^mg&y1ajY=-6@gPxq{f@0@pFGJ(tH4L}azr1Y#Pq$>FC~qp@W6dG|Ak zr`*q2sn#~y7cwuti20$hQr997`E`!-I>!-Q>UEC81mEi%r;xuCjw97AW}5iJE~bg} zGwElI9Vkb}F8(2h%sl==Kl=l@LlnCttI^UpK)Go8124Xu{viJUp%+<1=f|k>=*_@8 zpApC7zh<^mjTtZDqX<0Zs+tj(uZ$FalJaKoSHngYKblt{*pt!R%SPUON+4m^%SMr& zKFwttM3j_FLOE!oDGXD5HN`-M)>L^^zcBUssTrXG8UpC4Z&S%Oo z+t}Z1%F;XRq>k}`8(21>GakYNDn5cg&8T;`j6e`?E^R=gNanpeWaEJ~!Mn!(CRZVs zDA3)TD8#+1{P@~B^uDt94)cC^jcV}>lI%{hj`;mb(tDar9#01D1n__VL@|H#a=EOH z@-b~7!%bHuS+97ZRc7)pH=q8<0@D(i)OPy=K3|>w;hEE>+}G>L@<(58zL70nFEtz) zdiMhlWcFq^woZL3i${g)_-}oCH+^IG2){xH_-B53?mGJ$-^d4iRA3{rwXnamwG#^* z`VxVKv%_1n>j#mo)7avSFSeM?EH52qEG-Y^I`@ zUCqs$9iD~#<=B3S+MbKdF7HRy@M|WGe>M+pEfzMX6Gi;KRrh6Y+}hik%x?q}vHi2e z;nwj|c%!;z9A^)rH03vubH^*k z=^KluON;Y!(f#H6#{9vQ-?zP6y_wri9F`_=XlXZB-<;jQk&dn#+1VS7?SqYttYom1lPoJ#M988B7L#0GKRLgpA%^x;`-uRSfXSxyE4A0CoHdZQodwaVJ81MC)^LwRY zI!-^YdrxZ%3&82o`mNplQ@mKXxf8p7GkrhT>yUFU*7_rm*;mE7Ro3vyS*DY zoyFhfo!AX(@2GNcP^{E~Gv2+$l0UhcPS?X#Y+2~{PTo7^JB~K$xmaMP7WGbh^R-~8 z5ZFw48%BBG*eV!CrLw+}sl|LVv67Ka8|l-@8*@`zhc~xt@fj~w^DmzG=OP}D*Bh)Y z_h|`TXFVPc&#e0B6&z2Ud!PQDASgR#xLYoJrQt0$7pKqLaxig*wgZ*)R3i{JmbW(=hvl<)wdQS{MHjQh++l9vbZ5Ih8%Q6Y zO&wG+)BaecPGxr^k$N5Y+DILEYWt9*j&r)tmT8X?cDlQ z@O0823e8jlt0&WdDO-%~dp37>eV+B3yVd>rT6BGJvf|lXoDYQ7kGF0lmg2#s##(6G zlW43qa_iA>aVBf*7Q>B3>TER_Tw34UTiD&3o{3g+GpkF52pB|T`z%?kc{9sKq?VlW zuk8b#c_W)$*vNTTmzEo;Mr78XDAya=uxIHymPox3PUJUJ#=-t-_Vi$Dax$Jt)oQgy z*yG)}u~`S6_C3p>XXD0N%;SxFQX7l2r*UJUQmgIkZESjjK1^?MH`pj2)IF=klW4BG zafbg^Gr`l1nS=8FN)GF8FW*Sd`8~@swOAmzIX^q=*$f0Qx5tNzpoyE=v*|5ts}XoO znf7|a!O$TvRLv3H?AH(C8;h)uvwE^Nf0Rt6cDAaUpfAtH{F1kRlwU#!B-U6WdZT`L zGvuB01{-;=XU$s+dG=R}zG$=_ucnswf`_Ta!&}~4XB)+|_oRA~NheaN`6bUxDe0}p zXYhBk5b}67=eNp%t%Z#ppWl}|^oB}X>$^vlT;p)}c<;tcVs?IhD(FicOeQz?PG-Vu z%d7rq+%pr+o_JEL*}AuWxV5mI&qofUm3?ojmRt9vW^!kTiO6(cQvw^ z-#ZRt&EBeGwXE!grna|sxBZ7FDSP zW1lrb`?2-hP9#!*q}WNtOS>n#(F3n{0rR$&+N&>Y1tVC?QSW4}aw|{k(w{LJsc<}z zm^@2(XSPlt;&Qn_*fX7~Y}dkd;B9tmYGX4zc|GpUEG5H}bzeQ<3B{v}#ghynAe_QK zHNzkBdS>Dk&&>47>T01l74}5ey{UMyICZ+cY9* zsfD9~SfZ9$!1QkIH=>oftj80tr0NCWer0jd<3I34ih*)C=m}%h2eH! z^UIm#^($x2x8fM6rnDEdN^r)w$C+Vz|M)1#g8 ztwiB)bNAFsgQ(BMPJ^|SXJ&FT96oJKh7V$~$@*rhwz5+@p4-_z#40(NKQL+=Gohfb zmd(@;Z&a$m*yK#Kv~w8nc$UEKyptYpEf6}aox=BpHL|;PBeE0-?5CD;Gv4r2&A^<@ zOr91_7v}1*a4B5f0PjgpCKnE>sJ_3FojKdX7%I`_%#xAGY$sPXuZR3A-p#P#O(jCX z$sk1E)Z|g6kz9+EuWuC(Yw?CRIak>)0S}pV&{`?J9uKT;o&+{M)069&4c~NSuTa_9 zX$1Yb<)vgL;7z61!CT7L=jX#a9;~{hO~gY_7Rt4H4I*TEW2P1fmh=9=&fYg7)ZSn=MPaeQ2^W+LFVJIQLTRytvP)3b7TI5mAU5SR|F#wVwyrW%vMBzRM3 zHI!cp1_F_#bb2ebxEf2v*J{!A=&En)J-nQcIOYBH<5& z!w3GFabsg?z8qOTyJ3_ArQK4kwqJ?){LzhUI9jiH1B!HR}Ik0+m2DM~vE47@Y`3iZrgCYNk-@A|pcbGhh#$vgX zLMfEWPpu!%udm*m&Zj)kDMAONF4Z4&$CgBcMSKSiE=Y zX6<-&cg?$*y1p2j4nP{5`D&@md~B=XU*Ft>R=2ko!GcXD_Vy~V{RSjVv2jv^TsZMe zdpw@$lj3wTzfqgcW(vkhE?2Fd>|hOLxBZn+B2o^dHcLgwHb35lVwJ-KFHnqTInMlt zYq{-cEmjUB_Anp*y?n&$@gySa>oYTPZwia55zd9Z>DtypHJn^p^d~o$GRMJ_4Wkj7 zjxI%t#lysYDH^Ew4^OA!)5S)k5eV*=64gj55(;{~o`sly-+yyvF}LY~JU|G0=$_lc6oeTyZ5vdyF|MIETNt_ABdatJ8D4BvT9d9K^VPA?zs`W9!8qAOD; z{!}eARS0Hp;f_(LzLk@eDPyrtx&iviHck^OOQ-8AHUG@g*8HvDdOfwiSf5O;7K`~! zpTC+|+V(})A(ZNq1#jfkXl$I_tS&CE0_N+{LZJdcuAdO7_>Tbw*pF`(GjqVjt;Lg- z)m!**4>-x?`tHNuNZgta%}hfDG?EK@iTLi$R&6F(+S^L4NB6UU8#+c}Y0tk9_r#1Nz7eR;;_vc&Go( z-`T96u0xj#2DfTA7q^b1H>Wm&vGU5zQY4Vb9K1WJ1+CpV{VY~3jBO;46{r9^1P zGo4AM=C*y+MEJ(m()?+7eE~AoyBjz@NgmG^C;dCcNl$t$zBV{m+wDW|9iN#>G3suqwG=v;P97I?>G+l} zvAVs>-mO)=TcM??)ss+_Xmw|Dac4QQU7w0B4wX#aa}VpRZ~oSQA9>Kk$;n~9uyr#6G|cWm zQa0*!z+T!5gep1E)r~EP3U7U9CAM_BHhbL{JFAvXfZKyWfn-y3VG6q;?^bQ8(Ab=> z$JbXpjdEzc5G*gw&!U~31CGD7ncBWTd*GW7ACxxtJXvFUeI^wFPn}A~m+MnIY;S@& z0BZpkimX9WuHeXfz&A#SK`?=hLe|BZtS6Rhc-Ds3S zPh>0t&t5JUyi+qbORK8^PcnORx^{#;>cWw)6e0~io!s*$BEHz^a(HSlF})KwP1Sw6?OGZ#Xl8Q< zG}t(-23a4VKJ>A*nK#a`!-B90=XTPY@$jpj|3!A!phwg;4uOkA1Z+saw0d?kW0B3q z!b~1pCJ*Gx>?yDV`4UX{6YJMKxd3wWg+aQ>Xe3n%EQU*@4}*Ww-ZoP`@UJ)Gk;Vb? zD*Eg7{LNx=#h~8OD=>rNY zbnx|=InpoZkNlC z%||HZ6mt_j&)XA0+D`2?-*4u+8AqTD5*W%PhU3he64l|BWm)ivR+a^=AZZo%PNkm* z4pe?7o@2`R$tNFpVC6xaj{LCIH#MC8xOmZgH_tG~f>K55HHz#JLBnmoOJ|%B4l@)^ z<4>nRZ3=6qG*Yu4mL9YqtD<6oo4HM%4URG#vB=XhB2Z#U#8)H{!&E}d0-{prBgLVZ zK}bB|QZ8yB2m_HS1q45^#7Yzdi=ZV0+ZGTFAx^;|Ls2}76Euaq8OnCM%BGYuDlK9VJ*Djf>@+_#?@qT|$sYDuDw0#{_NDWZX)058Wr zfF6Kr74iEvd#hRiTS)TsS5N|up`Z2}%= zbnOq|2amtUS2OD+a@e62;%Z2wz_Q$ms5@4i>IEiIPc6thmyB?2JzRQMAj&;kPg2)NkLX;J(*3^7eeH%_%qqme4-{{O!vmY7IG;+m9219r9W^VxVNM zJlr{dzt*0Hm*V|i_jJxf;bA>Jiqu7&7lB4CPj+D%N*r`6=`f1!@?l9yT_qpxDTe(` zh+)@*&L>!+;5#atq#4A{c<>!c7<>nzY0D?R4M50n~nABY$DL89!MSy~OljCdYH4p4;F zA_uRh9e&%em}ZKV?1 z7_H6OKiZpPZI+Tq36&>8q~x$|DH7z+t%w8B_C*%*Ji~f57sFD+rh<)$R3;w$`n){3 zKt}+~@r0pUy-W2(50-(d&g+-t(dfB{cmPFJw}5oYiQSC@DFR;Qse~} z9MeA;47s%LIyVhY`z$fs(aSc-KByUFHOzcfV#bEqP6k-F>>KRTFr@D3l-e?bR0y!F!dlC&QBsK~q5YjDVUa~LcxVSm z5;U65ByjE0DF49lNu{}E-+W8i7LdC@-8(#V#w?dCKLp+8z)vPd%`8RGJImD^&lE{& z8BR(d?-AaL%LLGY)|j|m5lM|4ZbyTiIa!J)ixujG-%w&EK4N+ZrImdC-m#)>E-%sw zHfZmoiPmh!);w$?g&3e#xcj;20E>-rU5_-d|R4Wn_Go9@;b4ZXzZx%J+f zOXz*>1~kCiV5P`2OgFdY-KTdl?kN5*b3b(~BhkdDppI@jiJ%_xHl-AwX*cLMxz8|Y z+~+x>25EU`9n@zoKB%^8!I5`0yOO&T7z?C#e7BHfm5LY-XMW`vNQQ;P<1QW z4J_k#d}^XHs$n)!zdT5o-ra`cRiDkaMI4}TGM)><5NSM7<`HszYhCbXhxRPw+k6-+ zP);`ewodlf28oz&5fp4+>8jIa`!d}?={UiEK1ew9#Hw@+j>E|MzwY76^IW8fDQ(Xy z+PL2oO$Z|ZsN#joTex@=swF@cWRccD&aEMtgg9TW?E6YJ)(@HqGN8P2!+1* zQMV5%LlMb<$J=z;{%!$NT{^{`$mcwNs98hcZh$RHR4^$t2aI1(-7G5nD}*Srj~u`t za=nWkq(WC0LW$BA1)k&$7*Y4AGB1phhPHqRtf;t=J)VW(g03GdA@lMCvO(g;N;i9% zgjK^wInIIlMB#{jAwAYOevVLLW{P!VcWuxmd~5(v94R=3?=8hnkQ74e;HV<VPSu(ZTOK}BAu9~f6SlgPRr97(C$?F$JvBnez&=}U%wrw?A8H7vCsGxHFl_b-q z{uZs?wzb+5k2qB{Dn`Xa1hiyyB44>EAf#gda<$O&5ZlOAH3UtrX74A>Ys7GW`*on3 z{wLtCUCIPJ+Zz|qP}ge>2cRt~vr&4l+DII$4j2pno}Pi#f<4Pq$Wb7^UbV~;X_u175lMsS;3O*ZOiR%`@{TIcj@Sq&`Tydj zLaCAHC3gfW`>Kt~`se?DWNV?lj?hK`t04$F#A5%%D>~6?fxfciaG0R(YxEOJ|8iWT ze|P7sh{WyihO%6tWxf+`rFSyE;v7oCOq-iI$`vw5v0BZu`?AN}X&fsm#R^CQk7#xz zD9t1Ekc?DYbfGr8pL`Wjj!3J!n+G!(-b$|Svb)U12@UA<>iTtD$zo~VJ#?F1MThGn zLuv>9iC1#y+PZvY#{sH%=)+cPQvb{LO|};LUbboo+OmDNx5?E|*=r34pe<@!^No^V zg!t9o$OX-`xDWOWyQal`n_5-^biS>5UW4XA&}!@KbYHVt<7&-X4IQvZVKFfGm$@+L zcd8VP-}Rs0^&<;&@};}u_49M(W$LGj6+>ZQ=z^w-PbqvUkd&#S`FBp!8C*Moy*{?- z#SEoyj-BDaOCc7GW!Nng*qj%Tk9!yyxN$Yb5dt^BYD&o?92ld+aa<)h#aSEc-4M_+ z5^kKn%w*ls7>o<&rb>Ub7@78Ln1)67{#MkmN@nFwE0wB!$y%+@TQ%b;fNQNu zc(9+UYrfd#l9e=8rpUN%UcpWJxp3LCt8&t~2M0=n=@I67Jv_kElfnVam2N16m)wh- zn9J@6EAYGep7WZTb2SD1k>i_}SWp|^O$n;BzLYpHew;>l)%elA2U=GH{b5NfooSkg zQ>*p^y;T#$snt}N(WJ~*ghE1l&ncfEE8)V`_lXcK@nojPP6*J_RVO3c2P3d!o$6vJ z5%|ZiY_c>CIfv*&Tz667_G=PFAafSjfPE*nth5xSC+isGHFuDu{biRPB0!_S1ee~N z+Kb+~WB@hg=F+?zESF^S6&irUlqktB z1iO}loQbH0;sR<>_Q$TSY*Z_n_!N&4AI2ZkG+#CTu;@*7o&2|2jjm|0ES{D+9*R4NnCVB>AttwaE`l|Xg> z+L()L-Tbyw^9y&{LG48X3Kqa+G92kumYaSG)C41wBY@;i*6DeE_Ttf93G4ylI2<_PR^~N^7CJAVNW%38q?~5pzRV*X z_!&PV&&`a5R0Sv0WAG3XLSWi3jg1%)a_Cg7BjOm)2cvH~Fr-+L%K#3C>C;pkH*?=6 zOXI!wu~V$72S38~Jn5EmI1KGj=EX}TE)5%(+>rwYtakrLh|Yx)#UCVRYMLLf8t<@S zvArY$ZxRs}-=^4;z%Vm2G+#}tN}GyT*SNaR9PtA=bL>HzIsWmg@!TM1Zr(C;_sV_L zCU`2YElMktv{`QcTo|PMd$mwR!Bim~K%Zd9S&0*>pjF ziL={pLA0cF__P2fvADWkLh_;aO)ix_f(nEf zU15z^iQzQMG5qpYdN8G<R(`#QQQK>`p--;tQ&3cliqVhLti1;XK05T33ry7z!RgVg`akG#pGNXj>j1B6?<0!qW#8XfX9v z?LyH0;vk`Ywl^x)0PVF#HyE35wXO^yOzf|%+~Kze3H)Q`V$`6MueuKZZTj$O1q%RL zKUhKd!$E@Z?lx>g1F3D1ZXkACbN}xkp?F;QY)lrXjlSiR!>Idrdc66X)nM12W3+L4 z2$rF8kHF`8n>Hes#g{dlTy8%DL9qK$5d1tL_#P#bT!hVwwBmrA?#iVmYLq@=RW66z zjXShGvYpj;-_023bY9;RyJHB0NVB)X5@4oQJ&y^wpj!1gB{3BkO08=CjkZ2NeOFHk zMT=(_PF%k9l@nQa-%5Y)6mEDWfA5sf=MuV-sU7Kka7|D;F|L*JJyPOD0Rcl^hW}vbb5vAVPLZ4LdQ7@rSZ{IgV z1;~O*>8F!249e+~M1oNu9A7nZT^1AhPAM<`r@kUXq6}6=TP?q9#^y33YUU_ifesJH zT?WCw@W`=ad(4hjhEkv985+tIjE74+W4JY$V!?1{Lc-lhmI^pP$TDuTEl3o>d>JHr z&$*!g^G$)Ohd4kA?W<50cpNXxn)#Mk&;+%_{Erw3z6f(0ZF88Gf!y5iTQa94{FFQ) zH@C~-Ok?Sojw@slYN!@p^wL380nnMF1=JKM-}p5S>qQ+Jz7)C6ST^7n|h21!7y$p*qOxsujFlUpGgA(&n+=5f2}1jCdsvcJ*b+JcW8|vAD+0hnThn zKL$*=y3Pebz%?o;S>$k6+Lt?kgtH|#|7kpa9fl`hXt9IvdiTe)5-1$4= zKn2VQW)^#-7mpT`D8y|Jcf`(z>#Oj#-{k#8*G}*kEP|UIUc5?}_ zbAYrOV2V;F0L53f)01Cqwl8I6>c#f;#DbpnoA#hW;5mGeGtzYU2(Ev<%Nz+q*cYC8 z_5lX|RpX+kt!b5ZRLW-A&yj;xV z&o}KX-#&42ob8WSv(U<*@A28NdAQ|3+{498Jt?elEKi0#guvA6%;E79dP7-l5B``5 zuBOn)SHS3|Bwn7R#j3wOxF9AAzvSew<#J%FXr+03+HZ3^^rLECM8`}^dk-`CIn9LX z6{&W}WZ_t-J0MFEkR{b510*|0K%TOV(SdAK_sw2PcLU8h))K4Esm2*>-!@3t-fM$R zqjuFTBE77$q?dAlrGH=Q-|QKtHojCrd5S;6brGew=u2I#8jkKmXAY>gEbWfY_8;pR z#hR(3-P(Salb)$tKiU-N3c;iAfZR1h9J30$jPU>dAR%zFhA1N9d{c?ob|z*GKO~c! ztRW#-L+%;~!ONaoeY1BL&XGx-oU`m(9SPORFk+UKxz+EvzLmBA28L%>LUe}SLrB~g z6{A#ev2V1psuqDO8@D0l(!+DwHW2@(KiCnN12|Zgx9{|2D$j$yIg?$CM zwuoL_KwxavJf0-Ad(wlG1+o~o zk!SCOJ#DMm6Jh^dg<8=wBWw!LVVY#mSdz2e?7yx9+})RhHgrW5*5$Ay`94m52n()JT&c`>~433P2zk69wZnY zr~zRGH6ziu9Cq=&KXVG%8g{#e_V3)~#fU9aAF^H6i}`J22nh&yD)3~qoB>0lIpZ5T zGjM?-b!ZIIg~Xu2T1E7}`=~%U!fp5KdT5u44HAfCp*uthLCP09gyJ^oF{r0 z4qcRaPg^3=y6;fPspmHdUrO__kHkuD??+t%+49+n)$i{at8F&;3NT@iwbH_KJ+1~Z z&YsI#;rLR|aA>>ecGU6Um^K4=aKf}h0A?#HFv~Ao<{FncxZG|W;8(Jy-4ZF8S4k*8UX#(a~faY zy!uaV5Vn_qZFsc;U+`)mX>Fhsq+w{l4LhLFDrp{N#4F^8`DEn>4}aXMwzS8fCMEuX z;s64HOowo?REh#Z%y(y#TI-6xST{E7mSe;XX|mJ~pGL5c(H{53c3*!P<1Zyc9dxr+ zRKE|Xz98%UM+)%@H5%*vd@dQy3++P>F{ti=DC{9NnkkX-n?Db&193 zv8|>4olBFp7TT}IHvCKtLE~p0mX@u@xso*7?5mms_}y3fKXD>w>q_@nR&i9U^pqvB z02n}4GjaD-N5abu5f@*hzvKjzwnll9Jj_OlFD_avx|NA97l@(m1?AX#D2oYtsb}gU zs{&;c{$(dvtP`|lnIK}t+}Nb?UYa$$)HyG)W4yA?6tQExly=z5Xj-C-O?U3%)BP(> zDAK0;M6;Um6tXnk@?JB3(t=&Gz`1NLdIaVv)LYYiea4cX)75JEBg!o#?u94XF|(7{ z47Q-3SDQ22S@6#i>Y(`TjdMX@}uNnG2x56G4hpV+NuD)<1OC0P%wJ&A2b z%gu|^^1pCI#)q}&Q}hIv_i)!B)&Gjy)t`2klNHLd0V36nugtzWhNK#?a=er&Vp|B* zS+;yGq>P7_!tVUQtp?A#XkUkAQ{cQY~;hF*!LC z@=b-O>CuJ!cYa?m6b=UHdD1;K;R^@-;lNB7k27e?7Ys~IPY0>3Nfe$5O!-27zgc+( zZBI_3#3VlZ-N6aJAD?GtSm_rvfNXk;e*%Zftb$&mi0z^nQV1hL4qJt7*wsN2PrF{O zp1*9AF&UpJ$D&3BKa48p`P`t2wh)q`27{)<%qsv)RS1%_KKX#F0< z5f);n_L^6@Uv8Y`HP+%&R7{Lnq9uYQDsVwYqUQm(3O(s1Fy^T_Xp+e89WOw&6zPX~ z>_M@T$-y*T5)O-Aib~F6{9lCgtHvMTPbVuojhd3x{MPqLcJMV;McHg3--T7Y!;-_4 zaRLn+qf_i7&Bzn$SxZvy6D&bAoZ5L7tx~`iu)-ov=!A_0OtPE9x5UzAhzsTw4%oJV z($6rXx;t4a!Se~ryv&0RgFd@UgXhGcZS`ojP%f)1&OAj1+i#nBon5v@D}@TI{<3K@ zM2Var(KwDu@+027BR-5#fBXZKPjM)Me4QU@T-ZdRE!oUOzmj~OXkNeY^47*UfW{mkvCR;16FEcd zL7O4|@v1R4$Qe?}vL`fP^|ubA?u>tJ?M&YrJJd#UuPr!?+KTJ9SXiz=y6vsPzU>2= zUmoN%`1@!1YHasV*#SLPbxP-!q!f_9OIzin6z~Wwr5H5R%X#;xl6C6lDA@N9L~CCA zpsuv1jY37Z&v82ha%^$y5oNc6H-XN+WMP~hMfmD?x&S#_gN3P3QZDm{(W6Ez>=B^F zZBt{Nd6ycZn0Eb@!mIukt!8blwihp?wwj#rcNJ$8qhg$KNnUJoLF8!Q53bFwIDE{U z5`jSZtgt6vp|MX65_NBoWS}}z?;M8SowBuAQj~4=b8WiMV27D<-$rBzviz6Gae}B3 zD8J?#&82(B0u+5?uxG3P!D6o-M^tM5!8a_?!aQH!2i$j3`Fl7p_^%ZacSet2Afq?* zSWwatJ%eo6ik_dmIC}n#6M8hhm}L3y<&}gnxTq;}C!E#Tzhsm7BSak`UjY)3QOumM8oC~afb)|a<;*og(W64f5y=^nb%xJFOKv8sN-wuUXi zbR7@6|5IDd&WzK{M(|aIRM9hIoNo|l(m+t}x{b4Wg(Fw+E%9ijiT{0&1NQbik8&){ zzNBi~dEd1iE=W1jw1a&#?EV zh%mXexx44rowH)3&&vG)?#6)4B@KyxcaHM0F%6)aa~EpR3aC+wy2i96wzXys*&=KV z7@{6RQ$N3xk%#%{7>s3!JVGF81jL_#z5i&Nc?*#@uW%$t;xQlPgfV{mpKVR_MD1Tw z)Gmg=sQt}4zO?~c-*+3h@n3vU*UZ!San%ePuWPoS4WGF>+l}{Kjs&54Y_=)T6@uT< zAjqip7zFPhBn0mu2yCRQ`fECVb{KvC){BXrp=e{h5QL*Fn%JkkA4Z0@Yfgi!b2$e9 ztt;bA+Uga{!}89$MrM14l~n02G&glm+(Lu>9vkS26wBow#E=ALT0dCPvpY!iyiKSJ zk_*btnyud)fa)$mG;ZJ|K_b8YAZ}?kPYm;|oJz3Fw}yp0&NE`wkw!$^p2B3LoDw; z=*>~VtgZ)4@C47gmkS_h!)D4LzhjCHaRNgkR!KMscnf@kY!!vKQM`iN#}v-FURjKm zfIVQET`{E@yKzC|L~?@VeW#vy^c4g$0-h*XDye04|JKW%R&AMHeqSK|ylv?@nYtXx z4B4iR(T6#~avC*QdMocR9xK~@DE^$_DfCk=Y$g^z2~a-&zynx&_)kB4+mlA}2TCIm z@IoW$`wY@|+VI)F?>16RbZ(Jq?{HYb3i_tw=Zhip3q8Z3Ni1g^KGA%W#%Z)+TV8h^ z?wgqQ$yt;j0?RuqHT>Kl0azXwOVq$0V51Jm>%5RPn|0_OnY0GUJvZSnZp(u2sL223 zAZK`jcCEb&91Zw>Yj%UV`3`+wX9_bx@Q&ZCg#UjI5-lr(6rysR&4D)SfY9zLoW`n@ z3a6?ypNg}#z1lNiM6T=?UgeK zvw#X(zyV0xU7%87Ph=<*m|Q;GqDj!owxn*ZTYu1S7QxT_Y>$X?paJ0nzq7OqJ=C4T zl`ZI+PBFNn6yE`R(WsjtjBG_h>(^Q)v(pVapeeOoD90F2CCXIl4Afs1Q2~%RJV0d2 zjo_tfHpxheLM)nurB}=BYJB(AH7=~CchREKbG}&ajeeUX2$L?wnr;0c*J-o$8~SRWM@{UA+%db2LSuuyKVFgTbsR`qESu1e%!{6HKEx zIv>Ry^&|k{(D5Lj9nM+t$BcU%cgrLF+3kEZmc<|CkilK|tVTxjTVJ#pi5NCVpTJ-{ zsa`#JssBjLm;zmCX3c+Tx>pHCCj2d-m802Yw8XMQKp{wul9w?9wE?%2!oHU+voP0K z2KOYwcbhDdGJ;fU_=hPY+@NOaA*6CJ#id$=$(3hp!<|34QjYGCOE8llT^FaaOPJ(@ zJaagwSi+T!l?+|R$Zp3eLp>>{GN>nyp5fYuYF2ajUg3ag3rV~I2{moRZ(To+5HiH- z;Sbh%`Mj-qXW?pE>i@l(3DG?hu1}CcYQefTW`~bX!?!3AZ?R08fW!7y0@Sp9K=XgA zFYwHmo_64UJ+5!0o~R3R(CLx$7L1O^i(5je&^tB1Tci@ldwUGq+x% z4Hwz~qr@3@_}R^G)RGt?_HM*1V>HlFHZHbxL+}e-dpop_Fas*h{QBJSfbLoLOr%T` z6?vu}v_7qQL_PhsqW*I| zL)F8Ae9Y97R3A>Dns9Qf+LHMCTg7ALs?hqO)>5rO5Cp&I-F6RJjcimrO zb4vHOo;LVmdm{`T0>8~JEAXG+T}R?LWCwyN=bHcgC1mKdnQm4Qb!HlGM%u;ZyJTx? zvNiW@#F&GK@S;kYpt~1M~ix)>=90fvayB{9!4{m;W9Y|am|D0CdRpVFtS%AzO`JcOBhkN+a zbiDZ#N5c_FUaHVmHU`&Z3O-6(y2nlh@tI2hu;%l?NS13b}tCLT<0xzp&K?0KR(_9yjIPdU*$#M(Q2tdfQDz zBWOoD{+IN=%P8&h4qH#dr1i?^wFw>*zt zmecz%KRkWxK!!(7@4s=&b3|7jWqG`6Zg~b@i$5E#Y9c26?U5gzb0<&I+of4LXqUI!*zZcaGp-n;V0Z+}N(;j$Nz^$K%?X=3vkY*aRc=)jaa5kjiz%q7c z4{7RX<;mDU`fvHlsfQ7~=;rKK`98_%>zF@w`2Xw9lL1kW#H;eIcgblr1&n@w@cE(Y z&uiVCA6M=0l^=@HO=~*RB`w3Mjoqxn*e;R^Fe1CjC>vOHesYCUI#?z zfKF(-mO-$^25A%A5cz6K7m-NuTDq-`o08OCopI!PGBd(Ij?3Fe$o4Ocl&dS0$bYrj|^H(sBaRuUDOG&%=7Q9hgSPtBY z$^Z*v1>q$iu;ZmLUIp*~+U(FK>u&xag#c9DZJ^F2lBTHB!Nyv0IPKCbKJ9DvBTZ}#^=4PHBtZ4T^i=# z_q~@*fzj_}uXSEY$|T2KONV7h1|<#@@U=u#BMwhEoIx5=qe)%5wzgbvv}!O|G3i4{ z*9O+mhHG?+%Fj&GrMITjwS(pQx!7`r``|r#a%KzD@{wEn(pr>S?=Ro<`?7LPuO}r7t=M$NYeqsjhmc;2 z1PIwpEHcr5gi|z#(jLJQ@87yJAAf4~xEPXhVjT3M3$SPekcdqSM;KV1TEK|yX-du1`omyS zpazU|b7?ETy+>v@&q$+OXdJN#hCcX;ZP-Z$TgObMU5O+}Do1aK;f zQ4}UeU&eYEm3_!z|2adcFmyz5&|91$Dmqm`eMDjwhV z>$ed0zX1akN2qCv+^2?dYe7}c47wyBK^>w3oyNsu0jk%o$fG z)VJP#pcC-tMEv^BnI{IA7Y=uZ>%v3GPs@Q9bsOtY3A1gC2!0YKqB{=sn9 zm}3=xY>$&rk-t4M#3*FeT=^sJU>Sf375S}68`buAnD{zjS`Ih$6C-*9;K@#M4ZRk< z4z3!mq1R|+=n3jN_vjqzJy0Qz>o7d5H@ltoJ!bEDQ%AZ&MjJn)=WH9bkdc-6UonwE zSZxGh)qC8!IIws~?=&~EWl@nsQ+QU5m<*F1qNcn}voKj@JIBiZ&4oHz`Ll60oS5#s zFKJeR%=i%NqHH_Am}6q$aKVw4_?FuY5#AyT(VL1HNmy(nW}R`P77()7kG?SVV!uBL zEZ$=O1LGs?ZS}lF^NwwG4T(kgl!?M$-$tIw9pX*id=PQMJ7w3HnwgD+fQHyf;({h8 zh_~M>#`28yb|r5PNn1uck?1GJ5)DGIdb`OqLAYxD?5gTcb+QxV25iB2Xr5qCeH762 z&A~#vxac4Dfe1|%VRI-N0LSxF6bN4 z>z9NsWBzTsPI7Pan%*wAwxgXBNGJVfNm8x%DT0t6C9Ja)N1pIyq}|pPxZpk|XRbGw zrsC}!f(5c{kh{}wkfTW;cN=8m5vZLsB>=E0D2d{cNFmTH#jjw^xBB}@sWCOb3)Kp& z<`8_1lmZk&(2OJ#3bvr76PQ~MX37bivFf3HP{VPDqLk}v0`<2=>9q8@d?8gq}AQ*Cv5@H z`1&~OCiLOQ9X@o>2+4_O4Sfg-0tCT&wBeY2QW&HLb`Y$Jo-vBq@1+N(YQus?F7*Ek zbDWam`{eLRpEr}<(v$WaXOrk)0|+~HbsOTy&!D9c01tg`Y5+uu0C*O;la1dEKu!O| z%JV(XDwn-S8{hZ7BS#i!5n~tt$lN1r1xWHKOGl<1$<(Ja4d5pt!7_CN67;#?$Rher z?X()TsJ$may0VB#+k(@ScJgG9)ov@leUNJ-OG7c0TCho1a2655r+JV<-V%%>=ZzyL zFVcDpIW>mGbEyb_^_(JLv47!o5ig^Qn6_Y`vmVu(*;;--UXr#rQd-SPccO|j=|nq? z!zE~^)xl5tEv<%14TBBS5 z^Hfp`s2fnN_Zz0Kn9{>+1j9t*2<9irsQrQJC*D9!A`kV(jD8=)>k5JnRw4RxQbOg` z$akv(EKu`X`K@xb++h}Zz*36pO@1J475AIiEv=dw9DZS<4K>lQ_Bx!PbkUOpH&!QY zp1`;aovtGy)?TsLER<{Q^;@lOF@P8Ol$a)7<@|>IrdZ-p7l@_M3(RaHJ`mNq=>s6Z z3x=1HeHCk;d*L;`uX?Ls#)dJ=@qsA=QxDAM%b6PSU7Ed>Q94&WQH{ma z&gDLh)s%hV0Y>kQm0&a2&dlg~z@i=u9^Hl;n<}pQ&{YSHO_gzD6Nnh}8k|ZyJ-Y@$ z!*Oim6;B#R3VDct;?u`ou1X+rx#Q?v95~aRi;e+l!67gmUW4f-%%02Jo%Dvnnn2+O z?Jh2+QVhByahXR;T{f#LD=QY+T7|hIb_EoLFE%n!;R65pA`n&K z0+DRb@lvC(gU~llu+pI&gmR%YtFO*9x{98{rOXj8#ZaOiOUWysp{kL)6p()wphAHo zqH}L_`H19wxZR^=;4^@03G-|C@42|%%M0pd*s1saizTV-Ew%UZLdh=o_2OMi(#&SL zHLEwL$L91{NX9vWi^lLhRGxc1r^h_9aZZon5)xO5IXwoVP9gMw7Mjyz#rm8c3&aw0 zdThzC)^mC+l-YgT5Sd-+iPDpmTM(>OUd2DOT)Bi#NOV7fipuWB=m$bISLHR7%a=X@ zqhV(_TzQU_mp=dDPh0EU$8|g1t;(11G8FSww(X7Um{#}n zVN>EsT?97scYvQs#D>R|8mr&nr~GtFmCtu~)2boTaE4$fBYf~Q&8t)IMgvfMn_ zE4J#zY7XU2KYj9&bhdeL?)16nCbK8hieFU89L`DHJV_f>tZz5)t_Ti` zyb?qkpzJkAxOx&y_EV%5C?Hwh2eUO`LXXN#asTkqBGb>_KYaYf;=xt}qOPlKzSV7Z z?jOFph}bV(WQ}_F;rqb)Z5PQ~-N!N)4=vX2+lG5a!`GCMCjQ+r zgNxFVQ4E>87_tU@V-;rCkQUzGs3RiL#Ug&o$k%FD>zkjxorxIPDmrtPt*1V=x%%v> zHPy?RQ_`XEdmr08_4Ko6o?Sb=T3g5WXKHA}J|QD355wxGrMfBi^s_6gHE_5r`0NTM zQZ`MjuHnHdjO*+xTc;+RFrU}b<{^ea&R8CTJq|{EM!FD+X(dg%Vx& zd{MrJlYP41WCybH-n6}?e#W*%F5jEyQ!J0!*u~ZpkMD{lDHoRt+~4?T1NPi0nE^%V z=n-phwil9kdb*~>gB)Q1fK#$%1DTgUay`&c*yl}TS&jI$u+2{kAapUadjwB#m~p{2 zo9Nj?YFc_+nm+aV^>mrAD|Ot?c1rkm8#rpY+K(_9aX8m86Pi-0-{S#Woy4-J*6;S%jP9l!XSALJVPw z7d2{h5evX3Oj0iS*@&T0@tSV=d@m_Ice};5IB5}YRr6cLs%NcU%kRSVpQ&VAScb+{ zhsG6on-^2;k);1NQlubc94+A6#htDS*&yMLj5#~v+#%yAV$O+c+1*BK&)J=I-{1Chtz~0vw3ndtMs6mk zAnZY8x;fG7#>g*QiFS;o?k@BEmg_rUD!|~tB!gNXo=*?|utz?!;TdinG!gN*%H+08 z1Y9mGw-KQhIhWX`u2?LAWhqO$Ra1b^SD_?qZ`7CUWQ4oVskp=lxxv8v~usb!z&*Qm&rTu@i*8gKM^}ep^e^$Vjwb?K+kix zwR>KnlfND7r2k>%Rjm#5PPh$e1}V0$Z@him%md}yIf|jn_I~d;m?aCIx#bETqv2nj z6NJLM>P3-`_$Q_?a9DTo$EKp7yfI8_Z@1q2c$mw*aJO zqQK@8Bi(vXWI@RW3(F4i-vC`5=5L@a0I1seaWkfxy zhc$;%ZWL0=qqI|MsWGB=QW9`AWq4;MYD^!mBS|89L{`RPdr{ghHj$>ni|YK}g>d`& z_x#v5G32~c_FLh+zM1y}6DIz7>`;az%lqt(F(=-8Vo&#>_Yh4!bXA=sa|}l!P!=75 zVumCH%Et%oRBu@ZmrIyvl1GN=*^C@zjtxHy-Y7;XoiLWrndM;|E(31)ZUHSf%_qkK zufA#ef%mcC5PLI;y+|5#kYM>yIsazZ`j;IzG$2F|+;FR74PTS5{f3`(3&a<3_$}bI zo_Gu78C#MJ6A-r*l>l2axvpWM43k9ZP9{2Nbfa4S0MYMVQ2#O`Q|7Bs{1DZ8+!wt6 zkrSk&5{zKG7YZyOG7ja*2ga#otYIa{v(G0p}*O*t~;>4VS9~E}^Q)&`dFJY3HhK-ypuA|OESCigI^h}! zZcZ_e(nhpNj?lHVSG-fMzmebD%X>*r)>c-}o?Ln633w&eLVtYSCrp4Ff+zj?%ryJcgZXsrBmgMPG4rVG zVvD!bFAs0&*GDV6BST4Li21n55R-Ja{9G>?ck>xQ%FXxWXy?xZ)u=Uw0_72&X#*4W z!+}JqpTgELClNQq}o`bP3$xs--xG9h1#vqw~U$DVKMFtPV$a;{d!{9dV4oWuadZ0k}(b zXk*-!u$F<_J{%&2!=e*c3xUZ&6OiHJtuHKBxM&=`3XCU^Ff+$s>4nN{qX>!YWRkfD z3_TB}Jn*itr+zVpN0KP>gfhST7jli=k^GA}zl8O6h&8T!HtLkqAvRHBno6(F>QI-} zfAiRpBXV-1>xhw&uU;=An`moK`GwMpGzW*xawnHdi!+Cq>ENGsvAUB9o^0eK)m8B9 zwS;GNZ9kmTl>GXcm9U|@^;#{$Z7%jwn5N#xB6rC#@e69it90_~u(}I7p)C!b(%Hw3 zm~+aiY2*YY!MR%|5SCDrG9}cnSR=;C6*khUg>1W&Zx%OKZih|PbH-IXUUIdkq;{h* z{13e0Vt|Y{9s28fK#dJnffNH!U&3Y_U{S#R2n$(}2t9)ZiWUGTPpSv~sw%fE{2R6? zrcTQ5DK=W>dhHa&TeaBE;RZ2g*J(I;ad&dh_AkWIX$LPBmceSsYI!2209!^F!4(=c z`KYJ$l+0Qo*Bp0B9RA9+E8eR3Oi7c<0Xn%V3@F7lErdd7QPY25;nuLja~mKwG~I5W zp?TGUVG*#tQ>cK&gXKafeia?77NdsKihCssNHqFLS`j)aOBp>+jyr6TW>MIA+8bHQ zic4}>3eLLM~QY@;B&VYY*u)Scm4%jR=1K_e5 z{%K?8phbsIV%Dbdo$nh3avu^q1T7(4m^{>%h3Ya2%@zB*H%rxUcPbxedBN4tj?U({ z#)Rx9p{}#c^Sd;4o!hYLu|MjFwbS3X*)FH_5n|g|BmT+MH>WlKQx#+5@%Cq|DK{Qf z2J8m?@ZoE1$5Y->@R8f*v&6uP>@n*z5O{FQmG@E^wkcfnaFJ|3b|L!BJ*lm*tQ&Mf zM|7)|$I5Frp@fBv9g|UxSp!?n4&mAMC!`@S)=*bQPI`ro)s~Sjd8?dLa0`dE+u8 z4_NFgs zL0t`|1&_x_Y9VHw|H;lX$l|AK1f>hNyhb2Quj3=p5;s4^;B_IUne8$hVzP z$lxlWZzkgdt(sL#Dt~*3RYTtp9skIxu8rkWXgoDAM8}0+ur?CEsoRO0R*dTbOIwRD zWQbF)9xhPLw;VGcSq?1`JR24%KFr!A?}Z+boQ2NtV-$;)6PFqMf_`n1rQ0`_5yN+J zF@qe!Shb8?-mY)u&j^yEl|RKt9J+DOJ$lgI{HJzNz9CgS!<9Sq+CyT)V!loL4jOZK z=0DDeLv+e?X_L?%oL#AL7r$Y=1Lsw-Amu0K#or|uxYQ*nHr#7z>j422%ta&@J-bkT zb|_3=T3G)N=-xLfRml_iWXXh%gxr=PluiCb^O*h!7z1rq?}`r|6cNmIE*`$pWVg0O zPXt8ZrB5%CD>hn){(LCH|r=kZm~9q+r}PWXFvF>miUu%93PygBL0Cv|+Y&kw{}2r-v`Hu{)-x*-_k z2g{w)lk89ru#?qK07&S_@Lsd83?^|8EUGwk&(K~pGI%^U%Uce680d&C=X>65LNM-*?oOA@_r&(M)fB5G{UUqI$ z?F-UxlP1~Dnq54)?X1^2FHmi(^*0`IfyWM?k6!PZ;8WB}%M(2U@3{ZXFTO8}$tDya@W*<2?X4E@q_1SB^&w+_NpFVsdt&CTF9al%K`1 z5!))kCOdrSszHqSX6p-3_G1BVaJi=x2#;tx28{gsMJqv5VpYSGJj-Q<6@E?`!)4)tHl^MUbq944o6_eHfXrGI!X7i_RIxx>e2^;C z>-ZX&oSMMx@sQ~Vu@4JQ{Ex7CwA$o9cqWSKb@h?)OcU2#XQ9cb;gREZd+YHBVQLb* z_AKH!@T^k5FQz1uh&BPhZ1~C;BOvyi3L(vG8Y)|hB6uQ|*k!xC2S%q_-fF>p%*4Gn z*k6~VpEKD#_!lGSJ**GH_^OCohqp*nf`4IvAi?h$>3)IvH2nOxvf;3tF$8wi43 z6X;-@@E7fxRBt)Mr}h$ z*|N?UOLKNoGlQ!y*3n}T-s*0ni?4i!AK+MI&q;2I3Rq7%Xo*4_BxJdG0rO+|m z+AthMnad*v1^lLtKlAkKPaH?wi8X$xXqgNy<+%-i*UTs9$eP0k&^Xrg;TIKuWN6s& z+5Qj2S_seRC^8(|fH~%1GmCG@ntI@Ui#kjIdB8RtKEiEgj;8uy52B#c$bw5r-TK4Z z+Jgaq4ISXa*#BmH@;w~hsaX#1vGAPPo(^L#5(Yh-`u1Q#G&Q+L z*Z)cC8>XP30JR-xwXxf7!u&D4dr5(^B|qhK+Hjfmp*t^MK?*?l;c zo~AWzf6b3R7@;ya5-hZ{Gd1P%SZ?Op!h5bqPl2(R1kHQ&a5-j_s#9ylI^X+M-*|hz z_dRE#zp#7X-a~RB-^7g?NIYaw46pLl zh6UptsWOT9?SFolS%~k*IO+L-Ow8QOCU&}Z3BAqcD-LdvkwO`acDIx2R#_RXAh5l0jpuaxYFg6(5F^ z%mnqLS=QX`U>UnaLz+5T`IRBdXNbUG{%7^UjZmNMbS~@oK@P_2>m)h5ETx2*hF{fOT5Yb{&$uuvtJZ+1OFDC)I7IJlf zkH)JE52~V=Srd}dyX^wY8T<{qb+wh@Yj!Jrz+V=_8H5jQTZiFuun4~uYdAciJ_pBr zvH``$ueg0;MkP|z$AS&v2~=Y*(5b0s#B&NwRX^Y(1ADN7hu*;oo?`_6cASG{vV-(HTPI2T z7e>Ho8Wnjk9lPp`p!e8IJ~A}mi#>Jli@m@gK6=gE)}yF+bbRW506aYrGIqn8tbPJ0 z9mUbl9?F{n?_s5pad+|I|Il+0Th9>&zuZA6YCK>_Y(~6*`lQuhmb{iIecctANtv4% z5_Twxp>}CDaV=t};W}(FG_d^Hey6zPuoUVJBGyP!0yi|=f#;o%qGf9)xN=sz}+z-=0rPJ-J&s7vG1bU-NXnPd84^D*}OeL-T zi6!{I#1m<+r{jj4P&Xr&3``-(3$34k8oUf+n(Y(GcA-YvnXfiWd2MBCxTYNOt^`6= zhNy@Qm16`XZGY-?oK({8lsi4PtgeKWs#2V+;B7@Ui8@=OSAC20ubhE+nrXvBF~@~a z1d=ubp_tNjz7-1vgsz%z#n=Wpc5O;ifHAhBMb^Tyeiw(v!~mM4`N&$sJSDY;Lcq!p}eWT*YZH=RgW#F6FxlvZRn2^EJrJUeaP|{ zLD=uSf6-WO{-{)$07#Ts{mJ5 zvsw+PbumI&66!IT+X*x&oImM*)I$83d=&;=Ib_s z?=9~dd++z{Y169Q1m!2o{OI3%4m%8g>S)@+mA7sac#wK4dmRHvA=-k5HBaa~*nMlU z$y?D`0xTSI?x#Zfmm%6Bkf5o!VNC}9xd$NUWmbPqIuAj zyi<7(^7<|C=qs~alrAHXme?@dZDgY>)HBH|U?-U9c7X}uI4F1l79NlziVXza2{o2v zXT<-s_-$>K!L%W#sf$(R_YFf3RaSy^+0<^zEQCR`bT+suM6Iv~X{9s*ZME_TZHH=_ zZ}r5z6ZF>ijlJ{GOFj6b$I>F9O!KW?FCR{CdEaBh$w=vdZypObn!^pT7YTg~KgWNb zbdFuM!xeKWFRSYxAEJh7FPG_TZAhqPoZIC+A))dHWw^RA(xELU+}4#dZ|cGn&L{gE zbu^05F6FSYq2&BW7IKx7+_Oh3%lH_DMtj%yS{iLhs(6U*@4G%pssPb6nh5RJ2J!Ko62E0?Gp} zO~Gv%CTMi#J`Zn5e5_?xV#C-5xP_>?POUvd^*xh`kgNHO!(8iA&BQxiQ#OQ!d3FSx zl2GQ-ETHL4WH#-MJsFD9(Ox^b&^x0;QNz=9@UnV!26{2(ffv!y4^Wi~HrRs?IG- z%1T8HR*^bESkV$kc)OG)j9?j4rA-WnNwGePz|)Cg7RW=1@eO)uH>!8Muws|O@lUoM z{t22%d)R%ikAM*p$~-^q*6`*seOqJC!@~rZX0b=T+03TBX=ZeB1_#EQ&`g?}YCbbK zy#9P<(cCoiIW-9)aW~FH)f2`${GNI5kbCAy+%uaVA_5K7zMVE1>hIpYo9)y4b zpNJvw(EPxcj8;xPeB{XCi4oU_PBNA27%&Kq54nx-*L8PdK8aMlW38cg3dgRBshYkA znM)>=*?tRljyJQnq`L%Ygck6R%EmK$O8;^@$-F*V`L&Vv4>yFi)$X?;dIS`1IlL?P z>}2Q5gYl#-3?1VxJF^7dhZFFI>o)0a!gPjXb#Lv+boX!%KY}w4 zS(}Ih1!0r86?tJEjPe1zw~5!U0quNE8ga zd9*;EcTuXawU@46edU%kw*|&q(cX-bPt*UD^u1e#`U64$Fzl^Hp({)V;ly%_?K#0v)Grv>G@JwdiUc_Ln<|YSfO>WIkx@NiB``@KOR)HV9d$m2_f03WcX` z5$_vNsLLZ=ggS)wqQ&aLq63RmAT&hL0)-0L0d&F`b}7%7j4Xo4P-PAPmxH6lw z<4tE)ElxA5%QHF3-lS&K;52hOGZ|uW_sfJ0B#e3Z74)r+o=m!e4nKXX0rc5M{*x+1 zwMG_B<@~Gl^8U$daQ)qn+6Qnvu8DRDf|zm>sw8u3Ph8)Eqq1~eB-v?xh`q-Mo@^xw z=l;EWk%akm&5TdM^~om{-}DuUud(W-d3E1*DBM7cCBy$|<}#lsaz zZ*hn=EVQ+?fOD36ubGEgdH29BHS(_L$uaaBKW0?EE(HqY4gENBFs{1CQQ{3QDusxLbE0lOzBKqqVe%5Kl^)9u6uF;jH1;$J}E zFcMI}3pZZ%PQQWf_!TX9D?i7X9j*MV1=Ofl&V^4b8Lx-w_SCbzdun;N+4c4nfA;Pz zJ~a@SstpSa*=xTBNW_Uax`*L1{#r$>BwbHjgbW$=zvCOG<_v zQfY);F9IWlYrp`oo}FxEJ+M#OLc+3)A6NeImq%qC`lOR{ATd}B zKzV-ZUF-JB^lc>o%3-#C<_q4QAl6U<$Vo_`Z&lZoq2>2{OY_8ccItAytYU%Un0=({ zC2LpKEKGQ$269HNuUee>lx`}vajLUx`bbjC-swwzk1g|(g`c8uLX`J-&)5vs zOL${f^f2Kiy81$_t8k(G)mFIgafACT6nt#}VfIxzY72kpPY12gnsmJiElNkB zA6$f^SFkgw{35r}(aPT)Yd2A-cRw8Y#8=kFUqTMg1v(8e0Cv5|HKFA^tV{Q(?=p_y zu%vIohX_fno92=87SA>h7)_b45vSO^cU%NtbaqlA+G?vIpYyoVqIfs3fp*Yx_nX`ndMy34~Tg5^#h+k*Lron1mv|x|Ug8L(6O$ z27%Q^9>LSBdJuz870SD1Q2Iz%p=Xn2p`3cmh|Q>3L>eYuTd;Yg?QlUQ*#>;o6V#PP zvTD>R6?=_Ms>dDT%udRr*|W6}Fh+gPK;pb#tmf{P3mwF^R6j~Zm?3r+(af>vDFn`G zrB&f>!5<)>n>$j2O>&G$i(Aw7klE=5-uyEK*$p zaKhvhS2l7y`AXJSv4&$s2F4adu+69UpT>aCo=%ym;TOZ2tD!GCi0Qc?@+W6whn_+I zc4ix>?7gYyb`T#POAKqDzChswVRPBQ&D3r{sjRo5-cPu~^bW&FknR-9TZuJ<9aP_S zqgYI-YFHkxklwAzq7yTcSBPVZ5ajD;OdM!LCgs-Uz2Nf41lwaXZ2Pv31@A>RPa{VT zGUb$?0w@^shOhGb<#zf+V`t}td!_>5r=>$3%A7^FYgx#j4{|LuLB_V(z=DI;T0c?8 z5riMC*Mtsqel5RMte%UWC>)EP2zPC4vz16GfF1wo_dI1}=l_jvCr-+a%Z`(_RXSrco(Y5- z8~+%_no2uq#lu;}luFnzT=0sByh@5j5qpjV)FpM)K3(z^WcdXT2oo$7mTln{bF^sR z4^n%$A3+@G=5g`DGXl}?@JO}Or;~6vmoVC*3Hyf6pc5g>*dU3Q?GocI=HlR95&oP51Q8MRJFr);j_bF&nyId3s;jvw2;Sti?sm$+&w2qn4Vze+ zis~3})kIzr%D{Y}}| znSSXrCpm?4p!Lh3ix=o&yj%hkVhy&1V4-eY-5QRh4o96_K<*cP+e(xPc$NVzF4yTIE#&(H(#_GySYAfH_E(uQ559)|PEJ>|Z zMAX&f$7^_eW(8sjbH#}$V09&BlE>mbBvccnt_5MDEoo#Z`KpPEoD-4@+)+5fOcZ;v z#wTuIlIT=tGgV39TU}RfbCyB>s_aKbg>zgM`%BvF)jSxEWPpb$~6~c1T z$Jt0p=DXMJp84)|k-^*V?A;sQNbkNeSU=O3vwj#ALr!*#8|iDW+8gPJZs(oBS?}RS zVkmV%?dsB)C>1#o2mc;O5^@X>LsM?1GrE)HBF`4{+BMXhH#ZV7C!&?Kv2V2SbS zaplP+uLIm8#Dcx%*WK4l1Ri_~vi@~wkIX0}cs!{Cwq2xB159i@n7l1*zt}aj(eUxa zzO`Qxqv21UjQke)Q*(bn0G~azLlL~1!{(~KP&l<%(EIteGwa>&bH43lTk_Dk!=bnD z_}ebL1JaY;0Z&YG2mH==+dJUcJL(SjUPxCV#G1!=pJ_5&;9rHs)!nM_vdapsq-q9t z`dB-_`bv=Znv&=(0;O71E@HKz^?{&`*iUNP>Jz7O7QvwDmtMp3tke+QAGjRaljYVn zOxFA`K8O(P^TRk#5#Py=oao*eb&59j^OMpGFHA!(eEnxEy>RJ)(F>j_CL*Mta!xml zvsYPtIu;?_SuKtcA^pi)&~RQrkRUJ%7xM_=-HI;3S`AV{h8-_=N-8#lF~uCUxTWbT zErRE0r8#7ojOpb!e#-*3CRHX;N&on_LzHWDf>tZ-n;Z6MphM;GTvr{_87Hc6=elay zQZx|=bk%z2O<)__F6Ory5beS+wq0*er1O@#RDQ!?A#A`{p&H$#7^7~<(T7HWN8g;8 zW_cUtxaL=*9l^@=*s){RXyU3W&{2c9Lbr*Rsa~sF!#*$QAY@{^ON(6bLQuAfCKk76 zy_-^PulJ5Gy{MX8xMU1&6GxNMwxH{(p)3b!#u9ukTv1k^aG!&~eV;}FXU;wowHRYG zjnN{iCJaKU>_4@FHLiARFkVf=^aC-40N(auN~L;lo1T<8ZqSGPShz;jJtA+ycrxr| zMPRX2te1DO?C5D#xoG68cmSi1MQxv8deC;NxjKf>-ds6%YUQ@E{yjld4o@TCwhlX? z5k(?=;OltqgaPG^7VH{mglqg}B5Xkf9c68^W3)Z6v4~Kd{)y#&e=q{o!T@E83s!50 zp|J*|Ur;}?=Eb^2H3liDESJ>-TP(G|t~*tLzloa-x+rCmY?hmFRx2V4Pg`A>b~G^M z7V{F9^N5w&P93c4F~E%Ei6?Ld7NRed+lbg#Zd)4?4WTH_(C)-S&yh4p#iG7<8|n*lJV@gg#70HK(J>GD(PR*}laQ>hUg3(pk0d zV9%(*p7jPBjW}AW!k|^F!;hfv7=j^VBX8&LlsgA~i<==29~whn8zNUE5V2#2p>$EJ|yLW$e&1-WCx|*gmMqo<+p6)B<~i?wKvg`PL{q1zW3H zb9J2_AKKnugD_3s0QG$_vkK)c3$Dcr0_3*f+HF;EgM~^6>a)F<#xT)*M(QqVlqoI6 z8^Y1B4V_79XhRw?ZA6KUJnc2|^eBy3b24pBcA%}x@Co74y4bA|(`;l8(7iVBT3^Yo zaw-e2kW8>h-m`DxvU*FLO6hjjV(|X({L@DE27;Zbzv8ovkLX>slcX5U;F;ttS04J(Uh{3ha1cIik3c^|ho* z;WN{Oa)#nygOny%RJqB;Rsanv>yQ8xE16T7)0sjCW5Cr3uORi;+pxAQVXh@@^QskT zu$2i1mH2Dny7+5xh^-VYcpoG@I^r= zgUyzaZJ_;cq{g~$P@@1O@?Oa*&Se5UEPg_2?HA8!ATHcQSO>U7!yg(>vcQ1h`r;vB zr`FfN9l@p2<#lK-O(W(7J{PV?P+{o>^G50%AWj2&)-f_D#wWttK)HyYx{W|a5Zr5RHF?^+vjxA!o6Hm$xwmK`j>!eeJ&4nw zIUdYJrIVeIK3)q9yuuTzahX1#rX4P2>;l1|g%KFN2S8L=EKqS+z(Pu&fdw;L0}#87 zXY2347t+b z_Sh_ED!13|xO+8fhN|!tYQd5ZY5`j#qo{~LA*VJR){{t_PRTjmGwFTMMf{QxXT|mF za25d07HBL;F<{7cw+cUGHb72GY~@$aLLeef%DZ4i1EQXf^ZR%TE{Zra*Y0ky!}RK^ z2FbR(&hKZj?}f^i5n%CgC-yp2!Vm?4gw|L1ncrX6ZAkCiTlv;HyMbt;(ZY{3npT*B zui)4T|L0E5kp6ZLrJqZ_h2jTxQHHFtJ~+dbOmr};)0F6(lSupGaP8KdU;rYf*vWh zVDDLSKP&{m@Cx}%cU+Y2Dxm~W1^lx~kSnlCXZ!1$;!WVMCcN zdYVuu6AfsjIiL;DHgZ@QunXGlh-cO-dcBjj#(hg!2iJ?wHLJ^? zkR=%0Kq}6l`b>zzGSLY^u~-(7wj@{aZzeCk$#X5m+@tPo^r)L_DO79_9((@H zwG?wL#o%x#hE4O-8Tye`Kg_iho$Opo;p<_n96jI?gzV^515F_MpKB>d%0c`)*HX;2 z6hf6Js1GO)Q9`G=mI4ta=2{9x@+JK1X%psJ3W1NX$#X4*vMQNtDcXo3IEyY|* zL4D3#OQCL(xt3zCrI>3epu3-IDZcr&6xM}9+-$yYi2p|4&}{we@VA9ZDcm7a#eyJ=0!yY9cW$KCv77NjPcGHR?IGGpfgoKxs#19 z6v3s)Fc1=(>U3oqRe&Oou?b=Q!NsD6(Sa|6QLDVYD%ZLhzXW)OhD52LjiuU-Scf+d z{k@GKjfHL%J^)be!uca*tjSamZ)X@~tyW-SUP7RF>?$P6<(O&9ih*E zgT?7d0PGy)4kxRR4f3n@wCHSq3Hj_2%3LD9IPKbc~ zO*J1${5##I_vbT<=BAm?<(V8nZ$>j}aGE)ND2@&+{yyw^mC%p7*ZL(m`bdb@c`XL{ zS#I0{!X&;{sds=YfnN)7)v7j-{w&%$h%O^eS#-0AJPcw?_W~lj;pD%VuM~i76|NVg ze}m;Kz1ZTHZ^D&^dnbbFKKvc(olNQ_WHzXGy0uJnzL2L4wf*AWAo?&adRQb={)1wO z%WJR0Y;?X_P3gN>Dc$b4Rc*Rs!J|YZTQAkN4xv-V}b`DXP zX&1upT<-9~FK8@(!)=WgVZh_{4xVY1}h6A;fA z?HP0RRQmXD|H_xDxk~;^Z&ttlgI`^}m)kqOC@|4h>Les^Dg_*oxZuh-WrW==0co+I zqt>FJat%Ws!CUxY;AW6z)XDE*ed-N291t{IRw>y|u`3*Z*oYULXIwVAfH1Wt-5d6l4NWtLhtl3S@FStE$`_FQ%ThUy_uNND+>r3bQa2(rdOe0z2hw1bSJ5lT zu;Y%-F$h-@;;oH;3wkr1q;>*m244#v61}3*Busk&do!3-i_^^N@@(hhvk3+UUHYgH(4l77it=RZUYkw0 zgu`}AP2A9vX*+vea`>#fa7j%sW-VwicWvH3&IDCdZ41IBN0W0BW6Z>ma3jv-9Au@9 zJVF81H1DM!cz{CI@Prw1Sp1VAo61;v^Hqjy3uumEJz7yKHU?;<16x1rZb@~o-y$Z5 z*@7|naU9xp&}+^OW%vfs1ontf9S?dh#r8A^zmO#MS5CE`C_^^cjD=c8&N}2%eNoh``_Uc1a3%fn-Be`CEdB%k3I`^+x8FC2^y8FjI@Dk&50kW1dKN6er$A z1RVclVCFzRh_gB0e$#9}S)LHH>0cVJ*`-UwY_UD6mV5#{*Khkm(w3v7ZA6@xiCU$` zcv}_~uq*MeJ@PV^b`kD~%yEH07VhZH79$#Hg&oQ-j!G|p9?4TkxC_fO^L8;r6b3um zNenvnh-n=*VM*YC|RwwnJgFJ#jG>@upp4hsqM>k44=CR zgwN|amjUNNt$Wy`9idrTv+(-GfQ1hmvQsh*t(lgRx6oR@J!G3zBgjcuFXaE@aqxkP zjpT31r6qZ3An2|*)qQU>dRVb$)_U5plXEFKGs6L@YUHjQZX}0p~ntjG(ggSPerB*hl74w*>i|F`6?*bH03& zQiMKyx!m+~#%RtMMPreTmIxQVan2Yi9(P~dEAOG5H!%*s+N~B598Ok0 zVZ;uD8boPuF_8!jmM?`!WMTt`!-_fdIcr)5S*MlOKrgor?dB<`7DIgNXBJa=nEnPe zz*N>4;Z>Ig&BB68&dqPnJhN!f>|5ETT^zY|zcB1wKmKwB}{7V!0?>LEZs!E%|7B`u;t{aA5|m z;fQ_krh!<0w4G4q)Fgngo9=L;>ItJAju5u~ncZY&b9A>Rv1s}fNDyr}4nzQT84M%Z z>GUZ?%s07Rc8+O(JG&3gy)|E2h2yMUEf z3A>|}SB9*i;dQ>UWTAdTs(9Db9~#G21iRnvf_VutsU`T#N*WQ#C&s%7V2%6CMwem9 z1pdgMlXi0D(URgvto+ZBuU;-xuWaL8dPkavr`f)h<{V@!)|M@A3WPij@+d zUT{0L{6Pwtrpn;VU}jk;??}RdP8keu!SOQZr=G2MC(fWTEMi`tgF&23LK$!}z8iIR z0;qdanMG@3&&A*ma5Af7Zvb!b6I4zZYhZI%C{KPU^&`=(aKV^re&YHKHG&EwHd&*#_rAHt{X%D{;geyZfJSvNNf!Xw#~3) zoYlr|dIQRW)s^D%>IzbPz;H+GV>B$(Y*>m$Gk!_i=D=B9Y&F{L%k>Vd;SSu~IE?=D z>oY9|adW`cuuYtVGJ*2IY-qmuZs5MOEBEi}Zm@VuF!Rp{b<-ao_a$n7%A$00DTR#; z6z6~SyDWM2lNQ6p>W?W|FqqOq-#4s3*e_fV|8hio*)2n!4mm=pfvj&vz5rIiYOJFNC5ja3DjF(8p26?o| zDN^U*Y4ZX+ZBBqrGwGh%0p*1#F^=@QG>cJtcjIi@!>gxlG^I z*z+*^9ArV-tmN0f=f?)Gr9EwjPntTzR=*d%!%2pp-nR$J9E8cFD90d05jQ|?P>Lo@ z=4F0I=1O&`i+n{g1E)7PS2NKXWFEI~FTz8EZd{-M%)8T>=u9R$tKLC4ha_0M`B8{u zhkrl1mpP;pE8jur;y0&4RRuLrOu%>6140gkSph3OnT+~bBlJ&QH)&~gM`_? z{I~20`TYlW<+y`-_(5)}WwXb8QHi{_nlPM~PAuHhvmGQ!Y z9Grh1DrEyH6W>hBOH4QxQVR8yNvPT~8NN1@yhRTrl$u0$$_)7?*b8A_+)aLAdZ>7J z-z-|g?e{S*{E+Y=31tAg-p!_ix{SU&-gIWv;Mg-VNCfx!<(X`jU{15xeGGJvumU|n zUR)V(PV3WcU5g+Nr)(%;4h~KB6M_7L5X($10{OcS4;FzW(mFbeAISP*PSHJ-QP zhMf3D1JNMGS-qzb&{q&Cw~CNme3rzPa<|=3QW&_h;*sdSf+t}i&`%og{r#**_Ixv#rnKew73l1 zA%9t-GFnG|Mh@Ya&eus1M52(5FOueqjG9=96)kk~O0gd$_$gKsyOpVr)Ne0X*bo2u zk4Wka9u;yUThWVdD1OY+0y{%n&rfbqo#o`cJU_W`@&n$PpImh~@$cJyaxKjueBO&g zIEuca#m`y7)Q~e{@Oi)Uzgzy~vTi5N){Lt!C!f>LXldh<;CYmsZl_U25KFOM66s=6 z>}N^|8T*;$rvtfPI)_`S5 z&4f7J%5U${O+UXYd}Eeja*BwZ2tLi;WsAZZ<*RLpLn*;0$sLiiwF7CZ_?581Z530y z#d;Bus-dg^@6|-};IkYT^xTwi^62ZSn*vq3YnQdZ6f>cW4YE7cYI$>+QG;X8$Q&;4 zKNn}Pcf1+Rq`7J4^V#Y4u{V`zTbgDTA5A_^7Rw&?DUi_TaE|NiAITa!BZKcIlOX4S z5Z?eB0V+IE3Tz~@SL;n$Wi~uSXpssfu5XAv9#Ef=7;FAYM9k)K`VA-IeZBs2x5GAt zr+d>BvE=u?em&)bo;(3EW?^xmX>QRIJad}nxmV4XJHKAP6iA*&9F`}3ej^k=6D)>A zo`d?qgW8@pp=o{!cSf9?@TH`EX_}w3myJQYW6(6;c-EfHAJ^@~2QfWO<50xm!{x$h zXWK{dbmiwhN#`m!RT&|*CkHk{>dN0ip%)*5k@&;KXLJUf_J8;--9kyVNLe(`QYTcovJRk+L6wgg`lu z*m8(7$>93{sw5~xC~t)8&S>#HVwWEP^3V!&;Pr*l`C6l^EdI58Ul$jVZSY=;`Q?48 zR?OE)1jEpg%YayfAYE%wty}Gs6&TEnkkXjRSpcBBa2Mp~7IYY`1LX;fDVqWi>1vR$ zJg8fwim4$=`S~h>=y!Kv0zj#pc$Z7)R7z)3+TXvuIaH3?p>bPN%U%MKhzP>9@p zpJx^t2mmqa{I*IvV+}}agbJM+B|l84P{AUr5b!iwa102H7q(~t;b`&8Gui(hp){ig zal(IBqqsrloe5caH5nm40av^Ldj z;y3X47py;<8MHRdY_81auJ>j%s}`r3)ddmwwTifdKuk?UdU!LMMQhW{=G~eKvRuWX zd6LkoV~F}`sUHb>jLEgs|I71MOI^!%N@NLWpK5IIg2?RpUHhPIiXjalN!_+epkpfe zhI@#)t{4}m(iS0!@>?_|)h~o=Kp1q@);0{+&D#R>zx>VQfz1P*tmmL9G`1Sh=H=v1o6ynHNZc4>S6u4K-o$Ev=?MPkynoll+i#L6+24O97$)IUy;mdFrmbVGr zu#)0crEQh|O2>`T;|B~?6RLX9ItFM*%%)TdLx06(!J%dW_`&R!t1=L9+#Nk>&8P>h z27pQe4!iO3SQJdE3_|5DY@tZ)3jSD&hzfy4%e8 zDvcy(t+4Ggs#V7Ra+~~I*?2NDziyb}Oc6^{Yz6)DH5rLIh4I!Oh064e$8|SEgfsC%z${)DL zo#e+Ba5yn0uc527l}8W_V0^uqR^1yF5W&7!S#hthb#)|MK+k)=k%N`3KMK5d+mm4F z3@qVoV3Ui6m3oK)KJ@5;WeX?1klT~CMk4pql0k+0Z9+w2x|q-csY7*HUX(0AAuR4% zAuf2o#&qgIr}-+fj6$Ya6M>&(SyZ=;l7UnBSl%sl+F7;09OsRE3zAyUL;AYqv%Zt! zwF}cdTG{D!UyOj45UonYpiBuKjE7f1)afa&{5uj#qqyBCkrxaZotTTL;FoaoB{k9j zp;jxuVI^6#s$_0$+?wree7d8|XQ32DQJ zu}?c(2ho>>UIhI%7HBydtgRdab+upwj!H0ZxFZNSoLbU_Bm=9E_yPwvNMY^dA$pFA zUncnot)~l6&ep%c)zGm=jbu4FDTtLCL`2sI`ImPj;aXuYZ2?( z$~Psy(Wu+Mji~oP*XcreyTi$y$CV~$oB`z!Se~wX=IH8^oUcP~fing~Z?mlnUF~Qk zLXLm8h!L#jf{ShHDSZf2q{@O=__Zar9qux&7tux8IfQt}+!7t^Wr4u!HkE@gADGlT zaw&r9M{qj9n9iD#rEuyMos(rbmCJ_TJey3c4=)rT+$*r?QS^@PK&_|OxZ-4piK)#< z?$WhKgJ8F23o6bZ0WH^$G7yrrF%YxsE4w%+%pR{<%%WIp!opgI+DR;z1&>%2G?%YC zw87B~Z^xAiTZwg)-^OkjIvkb?n;|&)$8LtTVakLp*ntSWV=-8JLW;&VCpaqCW@JVf zcw2w{=;TR**xUlbf||PoM@e{e8i4~p+ol$>>FgHK)$cC+J2|l8U zoWfx`L4|#l_AUc#e!>acHr(#Eu(X3B7_UIgzDNtY35G2SG+WI#~LqUi63&u6pv4Wnl*gZ7EzB5d*;Xt!@5Ujeqf~q)Yo&wBs|D zG;i8wVe2CFVlL;bUd~0A5#7!!gJ5^}GSM}`?dxv>$BX%k8VJy|@3p{(gaWzWq$pUX zk}2mwOW%qy7?}!4Ii`#y*?J9VS&G|KUxqBOQ#JMYiA_$TM_iks1=Jq+5KlZXe^*u7~+D_Bis-t9$^3066Y%$JLl2KX+2bjxqX`SEROktE$ba@Q-6UN3-_Bn4Bq*c`vfW8kjuk=??TT4p)rPL@2CPolBXbk zR24EvUK%?TCZA*ScZWsIsE4*sR4{StxQk(t0?{ij;{=MQXUSlxPzcd7pMZ#h7fw%M z@A3xvwV2nT_Oxp*Vdh@-_Ga-mn(&_Vbk^@CFmUXtz!%cLcRSe0kh1BW5UcRI5jvu0 zN_e9tG`y~!k8P`W*)bj2NFjHhyv_#d`nm= zs2Cb8u(Egk#o^{~Q-hW)+wK$~jm$EKa4~)C_0}<5hsW^WlG<5%Dg}UO2IP(%bR^Y+28!FbE)fN<8hwTbLZvYS|1+~!i+0T^G_DFc5hk zSdi*K@v5N*W&)}NB0HsF0}UD8`e;H~l6v#$5qu4r1Dbs!5Uf%3<*lj? z1ds+87Zp24ttozyo@Iop0P4LX7J0dD1cb7M7v_vJ;dIRFB3OcwO`G0|6HaWd>MC%0 zLk$$1E}CAOkOe!@Dg+9UsISnFx>SZStm{UyMbLqc$_;Ld0)l~Xos@LWJGFsiO#{SU z`2kbn;VMjNDCW@T81gFRC~n&RtOJhm)HW0BW#9~sRmaa^1AxfW32`iaj{JC9kDF|^ zeex!5WmVGL9hK8WigK(DLqUV4+YF`?VuO$UzdOTa}OU0|N%ZSN?JzF4e>ZeWxcx%^n)n+3wYhzAsA z2rfVnf;#!?cE)*8!;1hwh)(UV*v2q84I%tYc`4znF1!-9$bx9;c(Zf7N-uBp?zT|B zt3%&4aj`!3O*#6E>>U|_DV8jE7MIZI`2auT+OVAunGD=nO$qZ!FiFRrR6BA4$EVQnF8i>_}a2$ zFNMUXJ^BbfWk>I1c(wgtsT9Li~$sVTxJroWVxYI4<$l?{T~aOAVPwEI=#p*w6=Y{{<)XG7~Og~ zx^(%%t1m>CZ{B?QCQQy?(up`&RHfX7Uo&__32|!@L_kN>!7b_8UKrz$?WBxuCWTW* z91Kgv?LDG)X;I-I;k;xdUSX!aY6xB6aA!#kAY2MYiNo)?`Um^a9kLSqR3N$ zB(bY9G=7)~Wn}qmo|{%_oEoC6||zZvnq*rT%f;djXPXVWfx9UB;pNfz+er!-G$$zCGKpOVyYT6%ijI# z1DCYcwdtUXdT6+0wK=n~dlHKol^Lg?SiYWyokw@ds{@+#P_esf^zEois@TC{HShlP(8VxnfY*E`VgS75I5)X~ zaaD1rLR?-`%0@M^U7|rF@G{sW%0Ui2ogueLyt`c7_bVZ{H(2J#5`?~;*2z zq3WQ+WH`kpm^>w!j^2rSE}N@jwgB4IZvi2_IV%4TVZJfLp7W-r=Lj0zY|r%U{bj8^ zf*#D}VvM4bHrwq@40ZL~Z44wFZE{PFyk!Cie|9<&<;tSv`hpfXYaD#PhNg^rggrq$ za=(FHB{4)$qGy&*X(HdQ$!)V9OT^#~*K$k?5<|>d7X&Tqv?+{X>=OqJUj$dj9#tn z)>gsvCW4Gz*($JaXisU|uG4wLI9cVAwl_MMnsOay6E?^m-R5r`gj^}Y57ey^+$3qj z30oNfhWxb4peZYyc*L`5pcG&-MUqKNEa9lJON0sFG1g34v`8_OBKkNv!KSu$t}Jwg3#CrO)6@GfOsbV&10CLz zs*-WF3Q4Dnc&zeOh13(-Ug`zx-QQcyPk7-fd(gHBI5y4o$QfD7!UZ-6?3QTCTEJwG zaf@8hZrf|y2g-OD=~5Z44EY19inRp}#pv2V!)`yneUUvlBb(FC5dnuKCr%Kwu!f`- zHdS`mAS?We4h66ht_M2EMNwM-?v>uJnS$dqVtM_o6plllPv8jyWt(mSwL9$LxBf7CDsvaMFMk&_KCe&)3tc z%qD8U1J{CyJB@!zxg8s_SH&CbX*XC^7v3ZsG-#KdW8WRUi5~8qi&UzVdl;}O)XxZq zm0gowskqsVMr>rER2^wr>9!P%)d`Tf1Os;S^>^oZyZ?%Gfjmv2npqe%vv~uPG`}k> zhJr9QpBsz-9*ZrnESw~Cw<`Uaq|(SyhwT@y6SoV#gLa*B5sl#(Z5|u3l*PT(Xr<*V zlG?4Vr0;l461PqCS@POyZ}!T!^)j?OEtnD@Kw4Uc;x(ZQ>>N{j;9T}i)7Wx-dG+4T zy<_)(wD>oV$e+qivN4Z*fIFOF<>rwORNOa;A~l&QvO-V>MpQVDeBi|q@U_|V$OkH% zV4%hHH<6Qyl9BKPfk9vaidmfnfOBW!eM@@Y7sNQ;avu3Whxc$?y9eMPO2Itxfr({o zc?5g;3+o_8Q>4WZfX7l##Dn8ga@bUuWetneDy{U@_)!}@k9?qmW$WOY z3Ro(xgSP3NM?Rp>yA0RdY z6D>H$nI2DUs3zu-50v@0fGYIEn@2uql^MbT0P=$q1UP5FZ9R{C&~x7Akq_*CnMXbl zP$)T|O*ErpSD{HHm20<-9O-W5OW(#v-*NkX z>0|i+6Zro-@&Bjr{}ZJrE4NZdj#OU7Ki$%a$|ZcF;#E{EJyd$QlrAlnmR{^>r1Bcd z<^85u`8ifz`uvA~D0@UI9<5x_?ZgLB`Qdo|!}o0$tJPcwxnb`gKC+E?nfKY`IW?Z& zcqKlb(v3wu)5AL#icnV<5tvIduQMn&s>4DO4v+AibiKQU(LR)NJ;^3XD6=v)EZpG7ubVK=V&5%`O;LIoo9x&x*-d6PM|Z38 zEVhf;7nmFtsPcU8qs!i-jVB&Has;t48i;_!Ag+v=mqqZMCR}S^UC~TQz}NPk1Ru`I z#zLmhYEh;2))ke78`2VVa*~cYm7-z5D|@iP*ehPqIl$BVndm@cOlRQILKLlPdW9|o zOZ)hDZRr62o?6;pT3W-G)A+&%XO<4|09FTVSmhYaZAgomsID7@CXLFreHA@$5s`?z z(DM|=h*b!?+jnw3o1ucw542gsbrhDSR5>O-We}xw9U~D>2l=+Pi2P^x2a3+?Hf1qD zqtav}ZqOEzfQrONM~PPv<*y^^F~YgXiWG| z%58>BPoH)-S2x?YbKb0bsV_U;3fZ`j<_W-e{bKI*mA(x#iU+@6+<2zaM@=6rA zMZtHa$L9yeJ4o{b6XBwiP|NcJBdFg$F!oZEd-nS$CC2_kdx=j#jII5T_MZHnw}2Si z*m>y4k?RPJCuzArU6pXZ30Z|8s7P+p!FI_P4kWA@b&ih85^{~Sm_lJGl43SqV;0%y zLAR+!nXZj>C60*=EpF@Am|nS!{B7(u1^kJukRaSTNX8_!@<`9iuxBM>^IsSKKYOoC#eW_CxZp(uUS$+tHLN3IFajud4l*u;{`y4(+l;kc5Q{m_`^wQj6blb+MujZYBW&bbMwiQM&R>%Zvl;Q`0^J? z3KS)m5HEQp?@@VN`BRt}rkNql0oe|}%GGalrHpjWg4?A=dAq1?QlRLWw`&)t@~&4! zu6BeUB3Dy4VhH4zJWb>rTQ6DIPIu0Jv**|_9f2Pm4Sc*j0ZGKnJfNAnNQEdg7qH5m za-)kpJ6#57CuJtz3XS>+$W3;3AP*4`>#AU$Ev(lipA!O*chZmttgjZAPc7m#Bz8RS zy`y4+D9fo@4%N12Pvu{n3E6ETXZR!7BXN1Dzccy@Z6CLrYl1V}>ezkuLETP#5VI88 zZtQ|jxP(~xI&GXE;@Ajffrw>Kz4XfED6Iq&;)c42rw9$aTLMZ?@mv%6pFm1b9V^^t z7Wi6a93$dqSR6?(-EM&LZ#4NkUrkvaqOEWUWNb(ikA2SdvR(WJo5L~j79`8BJC|sNY zz&%1|Ce4BPSh4%IKbw$H=CXm>*T3h-CSQDiKBmDb_R{^a=VQ()?w<>G15LaUz3I%N zwP|K^Wj1HRo6)RVoMu*+XL3ZnNzJIiY3B5yIKr?O(qYf5gnouI3t#yg_Hvnyi23`y z>W}#(BgFs4Wi3Ds<=9^LZDUq2*S^5n$~6db!42TTtViv;KgDE`P6+zh>4xMX2{C^OCR~{l@Hh{V)v%tDh@CAZvP}~c_*H)-y zoSo^}>0uu0bdS4`vhva>NmqI2>B?|sh5f;ECwB-d zo8`qZ9(#aEUJl&(2aqfHe^6h2z9ld^$A2hoW+!*GpyaHDu}8)m!84D3sC$1f2QGMo z*m?AwaEq!^2uWZb@yNduUtfjWe~;d*(ibo+hr}~}H|TWJSIT6f`(A!FF zJ7S*hbK}vB@8w?7luzamK(` zy;!ZI?cuhEFQmd~Ga;dsWHKy9YxG5X6pZ%9wZ4?syX90?V(g3-=xsVNvChxYmI9%5 zXbrlI@<Wy^prk1$d{@tf8cuf9^k*O)TwN#S*hiI!w+{1yZ1rAwa3(_IQtL6 z_wGtvnV?<{g8+V>+TgiXoI7Oa=_Vmyleqv{1; zqF1@)R90f_{l_R+*V$JthyN3{g`f4nY+F&sLrb)u>n14Ijh@l!Mtm%~(fEn48_~n2 z8zmQ&(+JmRSc?>X%Q zx!OD7%;~_Cuqi&m3J?B1gXA4u`Ui@J%p!)@tfd7hHTv$xGaqG~sWC zcg?1+-OS({^oU7G)W*#o6HzNzb<$_RFU{FpS+T)qFQWr_WyxK9{-LRPz}b4JN~CMl zmEdIa&=cZ=7J^Sd=BhH}JsYy9;JIj-c&uw8F#=%f0|5JKN7W(52<(tgyKo=PYrJ+2mQ8 z!VhF{FS-PaV!hz;&JCNIdSvqeEY8ZoxXjC;<=NiD%j^qK>I1gAhDrzkxiR7>jIZ|HK70{CLF3)~XEKQ&)S0Cq8^D z0Dmbs?|~LSuqS4)db$<{U&2A{i=%Jf9ysm$*?;?f2PE7(1HI3I`pqG^x54kWM!~(C zZu5KLkXue=B}VFkWp7^2y@8&+3(KCHx}yl}?=I+W9Pxy*o;hyx8XzLLT5{PQECRr+ zF?)I0ri7G*;3eC@VgW?s#Z9cw$z#P^;3_Vb=5Y@5Q~Vc~YGs=t;NO1*!=23Oe#&om zue}Q00h3`717~P4pbf(PxqO&R9mX>1urRe8S^;y#%P(z){DU+50L!IB!k+mMsKW|) zowkPCT4AKn16IIllc7wQFg;vhcYTIiuVyD?8~v@RXn#bn7%4iTOw>*WP8c){9C=Pt zTPr=Hav53fgCghZGv01C5xy|}?PpXOPjqkK z*YD)SG(-eq3!z9FI}4#LmFBvuf4ht*Dl(Ql%y?5JI^N@uI%Mt7kH<%Rm9`7GKB zIiR?iqDrk^H*VbZPDr~$j4aGKTrN5_1v?R55r$Dvbmo;`)E_U5U?or-0eom+)-h%m zoqBibu~bU6lu~r&S6rzmB9(`tIw4tf6&ZN*@TUmT!}-A$_Yfx7Dwk4PESsFL4T8f<3(xNky zcd$g>fzUxLPJ_l2ohdjUK4DoKnkAG^FzPJ$7@jFT=0xu?3^_vE#I_pw7Spg3`eC`) z(xjb9<6$*+v>RFwx0A*7Q=It_txUvMFaHVH{)#Vphcip+Wo9iSFW;g!vTUt*@p@-! zKH3Li(udH!>DD$l^7|u6tT|0{-6^(zOM}yj&NM3%g-TsnfCgK*^B6hShmmxS5vS6Y z^RfC3HOHIQnuT}AE+~S#w-$O)nGm`kEcZr3X^r0jammHZYyvOc>jE0tDOiQ>@_f^b zOgBE+tmha|(sX@n+1v2!q+!@NH#3GI#nysSr9d8#kc_SnVoaBl%kms11b3M#qUVup-dn&VEikW4&VBR3yw4 z#-BCL?8>aNM?)@K>RhXxi7QTD+2##a^?^^!Vo^N|Wv?`5gm4BtG02Ol2TA7GCJ=wA zp;R?|+p)m6mU;-6{TZyPHopc;mOuZgp`JfTu|w3L;53%CL>7C!4AE+-op{`!HQvQ~ z@bx6T+nq@`FwxXk7oEvGsngA=4rEQOBZT19PfaC!i|}>AJA^%iYbF4`NqCO%2f`^6 z0nLO})qt}IuMz%1xN#ET`-Cee1G0pMDS!~+JA`i&J|=ufc&rBSE5d!)-Y#`F;fbk$ z-x0n#4RAT(*gC*WLLb2<{E6^KLOcYB68=VbfpB3x;LC(vgeM41(*g4duMl1$>}&ws zPq?xXkR|Ln2C$oO=M2CdgeztOx(NFS9}#Yt1#k#evjP8M>Pe;^CtQ6jU^`*<9Ka01 z9>Q)y^f3Fo!}&LQk4>?1t>CBSb1&b(MI&2126vm(%Q*j*7J^R#He$t#g_B4P8H zfKEcs*?>6V%yR%M2(eXwD+sTy2E0rdzZUT68bEtHU=86X=L3F3FxCOO33pro_#xqa z!h4dskST(-9?%PL>cHGs(d{nQM&)k02$yakoYVnWM0i;NUL@SU0dOnf-i?5}2=8H- zmU@@)@K*pk2_2gN7ZN68f6~-M!u8B@EnyE~H(@P%h}D3CQ^W3qz9{LIqytgXc_`^P zlyn+OIt(S9g_4d!NhhJCgHX~rDCroKbP7s31SOq;l8!)0C!nMQP@?=w6kmzbD^YkQ z%C1Dwl_oUR`Y2HyC2E6OK}VFRixO4Ae}P^oQ4uBTfjU4dl&FOgmB3YKf)Z6wsTZZr z6n6Xz$hZD60Ri(OZ|%} zVX5mTASEpIXQqUuT1Z;LQfsP_5|(;{DPgJNB&39;?8!(8OU;;ql(5teri7(FVMfRymkKBk11ZX-DfFMZ0C@Y1hIQ^HFNp;Vfe zZf8n(=}o4DmmYwEXS+k}yzm9a6$TcM2Cl zlT&+{A_JxN@^B|pR}qAI9%bq|lF%&#A))7)5)wMO11TY)SIJ39lF*Mg0ECV*JQO6yXH=Z@bJvuWSmQlaZfYzmA3l`4O{dMw%Cg)m ziI7*t~*U@=gPgYQP)2~c)=s()GrW!P#NehGI7Pyd)RJ&}n7#}{mm ILU+r50icoXH~;_u literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/html/_images/exercisesweek41_16_2.png b/doc/LectureNotes/_build/html/_images/exercisesweek41_16_2.png index e9439ac0aa6c8808be6433aa47866b2d0bb71f53..0d1102c6be52b2eabab4bbf97bae20965c52662e 100644 GIT binary patch literal 22302 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 al)p(3Ya8}Z*$Y;!n5CHwEz8vT%s&C`p}gP# literal 21978 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%0AP!~Y&f;rQm+KKjtORDsLi#AD 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 diff --git a/doc/LectureNotes/_build/html/_images/exercisesweek41_22_1.png b/doc/LectureNotes/_build/html/_images/exercisesweek41_22_1.png index 63a694a365d630555eeb7df1a452ffa33b2bc604..7f7f05923cdf78570b1fa43d3d456c4bfe491532 100644 GIT binary patch literal 22492 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 literal 20216 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 diff --git a/doc/LectureNotes/_build/html/_images/exercisesweek41_5_1.png b/doc/LectureNotes/_build/html/_images/exercisesweek41_5_1.png index 088571c87a8b367d701bb9c9ae7767823a7f75b5..bc123afa507d9de44aee00c4744f4dca68004e42 100644 GIT binary patch literal 22024 zcmdSBWmsKJur9c9clRKH;1Jvi9z29VaJK-#-2=g$5Q1BR1$TE1!9s9%clYW2ednAx zGjs2AXYRk@d3Lhdd#zsG)zwvRRlP-+sOAKC#42~z)C_OFg?hK;FA;n zhc57+fV1>_=eKs|&TdAIW)LMKXL}nvXB#WyXRc7t39_@> z{?`R;c8(V8JQX!R!5}F1a#~Ih2$m7_1ydlFZv}z8b9pWGO5Hu}V8O#1&+HNDSjAKF z$7e!$70XxAUma;fbW7&xkachp3C1q88>Dm*CKnK#;}YM&_n4d*Pf#s?Kx>S8hRmAf zkM_xN2|+&lOVy9hUwJ)z{kntllxE2jOyh5w4a%CIaU~3JB`9vCZe5EqQ3pYAaB$)z zZaf+xQs5_}+b|UT;74^}gU=aB1F30fXwO>h4MXLEzp@)(Cd!+6!o$Nqqo+s261{#FO(C>d;W(5oM8uT%%jD~K|@2(%TDn-S`+!Lg@aZb~UGV9Wj0b`%h zh!h8Z4Gx~%pN-@yB(Wi5VaZBK!QYV%{>?R# zWi_4`8W|}iBZD}cE~L3Py)~S!V@(wn7Uq6FCTo4*G@hsAemcN_LqZZ(Ud|zW+E4p} znOV}vh`Kk5ECjr0fsp-f$1_#6w6v_-JXg|3^sW*R~D;Sx1nC@9w2*h@-mWTCcK|y;Wv*vNW*aM1#gG0T` z9%1X#qnD|v>2iXKXa{YKuyHL`iAF@aklX4;l0h$p+k61nlvTI3JBny>flnGG+At8_ zkMp5pxw5$`nWFD&J`gwyQV_D~S`r4q_+!JG^hS1owQ_o0+MFLPQF&b*_M{0omHXVe z+AOtFfH~(K_&r=`{>~5~V{bXf?dpP8pB>$|0=XsB)#7o*=@9rbMtCQ*pG()8d+(FtXG zpN2u6x$aL>GchywTMm6?$doOGO=+sr7Jy-5^^@k-}s z^P{sKA_HWI@l2&zo*Ao7Ej|V*H#V3z59=M+UU&!&9v`A)$7yH@$gh z+*W_+sy5Jw*zh6UH)mTz(LTdz0yURom1YW@4y)bTcWHtyMKi8ot8pORInoiozq;-G zk#^pj96A?fXIFugdp;s!QQBzp+DvocP*JgmM??%=3Yh)E$HB#=Db;PD3BsmfV337i z!y%#|Uam|O$A`Z!s(eVS^^5qpVA{dn#f*-QY7a^1H9Ei2)lJ*+aCCeLk@PDF#vq&2 z{>bvy=dk5UziKO8(4}(k;;SV$Y1LNm%fg9W?LpR-n3}UXvq8dbXTdK?NhaU`UoRZ_ zhJZVBii&=n6AL)f0b^ES(uY~)vk26uW-%Yg{(X}xtNBpM=lOZv`DTyt6%%?jCSbE) zUhd>)8Uv#;U2TPz;d^UEF6fMmC2}4+!wU=sG2ch>)z#JGo2^WfyUT;=1}BEc;}Ef| z=H})}QCeDBYgRN&Ox^{lGW{0R7X6s*?QQM330>ElQ!^l_EUhYY^Fd%cb8>U7c_x4d z_$Gpdidy8<@Z(fR?d)5mlG89e;^mhKHGz`!Hl4bU+11tfN$dtP@7@tC`rg^XBO<1V z$V8K)KPoz+uHU@VOx9jix|@Tmusp_vK3vd+T*43zDj|^k>PV8L-XZ+~X4xPHJm9 zX_=bR6%`fPpR7t(`O6^(baqP2yG-d}CUy{f3Jhe;z|*`asc?P#^y!m*AB7uK5gs2O zzi}AB(yL_HI8eQQ{n~tlb;BJM1EZ(eU$t`g<$o?QcFS|gk=8s z3e?m^B}Wf4)6c zMs<626l0O$fe74Tz3+oyG?iHN)8kbeZ&WZaQbgRO7=kXlLG(%~%cI$nP%k!`uR>Mj z`(DbF0^kI8E|*<(7QIG%_O|<%P;m%fPMf@7V(Pp*YKw^xdn7K=uIVh+ss5um4G&pUoLS5SZ&DmJB)mz1H957|A zw?#AMo+@4|pNUk})II^Lymm2VAPZc^N#@f%Qm$-_>%g5-@=Jt`jg4=-wxr?V;b6K* zmNnW?fmJKX%cHs;Ek;3Q?RPV1psKDO1bkhtQYvqrujEC;R)*K{5Z}@=cy&jS@nI7Y zg~(ERzym)QuMi#4PgEF$-8ugG8F103_?IOAH$3(~2Xf*4T;Hem91iCNfcEwq3wnV& zEav-!zmy%HVX2f)&Tc#xCy|12h;12h;=D-lNI~W*XuTe+zIRT?6Q7 zXlM3T;6eR_&!0b+lau3E=+l$N>4>ec0@@x4MUiny4lYDQu37Zp8UGC|{?8}(zd)J) zA8$N!=coquG?J7DwW6W|0G{_%=1~*2nZOzX+rXmVJZ-xH3=PfF=7}M2mFNJb^a6Lh zH~(=ch36XBPi!)>y}WoR;>CprP?c6DvK{#K-TAz%EXdnD#SUPEk!rLL{^Jt&X7d73 zaOm;q72DC+oBe?!ac|@Y=5gIbSf5Khb4uR}0|o{Ls6xt6Sz$qeIIvVZ9>5JVhs%Jg zM8zk0B*mWYxxTV!L6u4JhuX}2BLW)XGhyNRb0A-PBgQZw?bHE5;@L(QW~e#=JOTAw z&z?c@RWf_eM#N&eyQO}XrHXj*0yn7?bARuBMUVo-)*N1(IzX@Z&A%fMDV3EBoL%TI zP~^P32TULiIr;wXDs-V($L<{J+S=i3eKDySTN@iINd~^J0BF{(whZX+m#aE}gM-7N zponrkm~Ch(fG#djm=gV9wgwG&%)Biw^WPANVj4frU=sV4Y9V;C93%K17_nE#MrW7# z%IS`JM$k_kOcw&66YHP&pM@0Q%m2Mt|ZRBHvw@7yv*?@JR)TTeSC}Kz^agZ4GLLp;o52 zn1x)#6aQ+_s|-nA9_(AI-18vp47Q*+`5&FT6F&iFBK|qIKi_}{JWKb^cs>-Xre5j* z!v>5tJ`oWu3yWgTA6%d!%nf^w6w8$&O>zznoa#&jqr(=xu5Q<4WN*&_w0A*W z5S-#u^GdAX$beA*kYW=O0)eus5CPGIdWZG}X8-x4MlR+%4@Hz%ZTF{W;Cdk52ym_O z)!{<_@NlqlJ~X(30DB4x0=x_+UT_+2kYlh)Muvu@Jv}{3Ht-mfyXPC60Msx&aS;#@ zkW)~o+7aQe&H(bidtq+rqpeN48{TL71@WK9#!f}jL#>M=!vDJv`hQPt372JCXwlNxP;2jDy4G;My9-V9T=+>;yKTcOGy87Vg9S5Sf^- zb~n2n&}4<&VKa4CRhwAs*UcR@{-7bK+Bt5*kz{N{|KomiZ{&h48ve;r&}oXsuV@|q zV{8TzV@%z@3jMP!jvKW9tIHe0m66srVVN~aA6-oUCSgJErPrf_?kpqTb59TOh_@(4 zj2;1YjEs!0+}-(s>BS)=+}v5k#)&KAqL(lBh~VM1t&r)XKWy}?N{$2*mv8;{;!XIb zD9OK*dv2icR+Wnj!=5f4CVBq&(9;2_M=QJy6&CoEgn>2KO6R->Ija?O~OK21Nk?LmFlJQJf~d z5RSj7J-xlgAeZt@z=g?Dvf$tmd1%3-NwJ6_Jf((xgT~Kb^O#%kg=lK8ch~qGEIdt-G{) zh6Uy2*pSg?52vaPFfYE6D$|Zn2p|E(CxVNMtE;UH?1jUnGtKZX*bJ}XQ{UCKfCi_% zQUX}?y{!?q%F(upd;>L~^fuOHQN7B%*7&OD*Sj|d?!`kI-SB$7Spx%@2YvdLn8A_i zJTz9+QYB^+Lm&sy)6+9S4GeQm+*k98&rV0$k)^nsSCy1kYQMN~SlRCpwmD57F zzbA*6CiEIjALoaMCuG|OyHZUYIbRs_rO*d0KT7+Q-@E(ahnd&I9a_!Axp3f9P+&l6 zJ_G=d|6zjg9T7QsBuEKWA%SDRus=YeZh)5{k0AUcj7?xR=Vj2kKY#4y^@*QWN62sL zN5=3(oxGjVnwZ;K!^hMy-WOO0!3;*dQ&!W?HDpXULA3!M-^N6U$PAVOn?GT14Vu7d zsq{gksqJk`o9S{Gy(U)#$b6#Em;87XLLE?T&qQPC6u8kIMf7fx@0* zK`|9^l@L*8KhRU0@o$25&QL5J<>9%6 zcbJg07^OY^ppPIyKDQHC%}aNlE_7cg5VpK7V}nQ&_UJQy8RW z*RgdR5rIYb@Ce?j{kR7X#x>3Hh@ZBvLE^850bM62jPxISZ#AQzr4Oq*IX^a2`|mA1 zxhBloZAquG`lHswyu%_u#g5p@X=@KP@{CMdB;?d9zPhOC)w{C$$2huhx=JDb4kTCL z8l7vj^$Ei;aEEzcKYH?V4zK&&5tn+*FS5jIhZz`CKVOVGUy;zBcW)sO-w9ZnwWlIc zozLwdRQC78?cXDSX*xBu0g#l-fRf6f>9Y5$t?g@@`VWatUAs{}e*Uvzlu;u@?6r*8 zjqcmHqCUGw!lTAyDW4a`Z=Ljxdq=F?n?B%DwlnFf@o>%QC&ohFndglM#0piI1D)t6 zbm1YJsVc!&dSCnNS5ebZ41xsv@m`W__QSDorJK}h{vS;2iCyKCA~qw_KSq`^cP88C z_(6ROMt2?+2~CGflt zSVTUXYpa@Nhm@6W<&%UMlD(ske9@g(zZYkEjda1~M@2NGw8{357n?6Ey%&zQ(WGJy zm?@+hmbjZlG2P;p8vYSoAg(gr82qAZdHX>XtEj!-V(!^v=_O=V;VmVJG03O44rZ8R z(70Jm7C+kV&tR7CH0i(7|9n72DSm08nf<_niNrJu3FRwMLGKR{yrJV>lZfMePCy;y zHS<8Z7!KUt4ZVWT^VKzsba@JjQboGYDd|7c7fPd#Za1Q>-d}A}TecxgroZlZH#Sop zCRSwcHVtEWtN;0S$NhWc2aLqb#IPZsdrxDe4>YGDlfkSyq^L^kAA60CT+Bk1<;rcR zn-Y&2SCUb$*2Ma|-;bXnPY^^}dLXB~VM6y}Lr{t*oifnJ(pUM-MMn)(2vuzSUt&TUbp-Fv2VPlj zP#ZD;{)n^V93J3yEndN@`7vC`J3Jt@{$XS4SH(^GL;qtA`mE&Z{-2F_?df?Jj2(U1 zJKlu5A*suU3_{PIt-IO>!G?uw>*U1lh2;)}_VWpFFyO@rrOoLfAFSq%enjpK?o^)_ zFR;?%_!YP4O!e1_FDqjf^)+1a`UA{&iW~zf#xe$>cs@tVmLM<_#xGbFzn>pvm;Eu> zYQvJaJ5uOhoFMo5NS|5~b0LJ~GG{Vs3U4x6RfrsgT2sk@R=fd$Md#sD+l0igdRB6I z&<0YY{8I^XV-kHEc@Y7Ih{9aTunCD+b#0>{INv7m#7b7bNpgv9ojSzyVawtToQ@eXI+{0WF>fq%w2*e z$r;>3735iuNt;(EsgA@T$fLvDlqSZ7l<=P;QBhxsUAMOPZDmz5F{8QfG6Jk|whXNhf_?k~lNIF~5-!{fK`_TYe;%WUF?260c% zhq;aQZ$C)wryf$FVitOFL4Tk;nZk*RiazM$qFh(ZvfO&dQr6@>Q_jYP*WWL`vPk27 zw~1ppg=GBDfcZk2Z#*xc{&RJxk17_+XHQ3(L-N0<;>=g%f%5~x9<(4MC)XOu^UA=_ zcKb;ck3l~%T5ZdDe8>MQ>)!7_ERZkod|j$-QP)dD(dK(O4{U~}d%2_cY}kRB2mUe@ zQM$T@>^&(!c1Z7wP>Nn7cPV+^I(JngwmK)c@_B7$RmOA9FxxI@A2|~+K~@Ne#vsA; z)sz@m6600KyL~yMw%%UX2;6RxuUgW6L&Zl!b5m$tZ?Dwq3GPqkGpUcH=;Lw|$DD0T z|Fo^l2vO73q^C95rDZr%L2H z?htctDursLJg)T4lLU&vih zshZo}=j3DwDVa&p#s2=;z7Kl>rA0+gy7Y9!wOo}KcVc!KgTvWr^?Q#)VDEvfQmiA_ z`8WI-UQaYT?tRU^Tv?SK+%wZ4OR9TLHCv}5kvfMhkR+G`OP%L}@g|sh>@J&9Eg)`u z_F1Vcg-?dffVl05fU7Bgg9uM9kM&P)?9>4|U>N%c-&>b*MoVyF{|$(gt0OqSp__$Varh^HVkTDCHeN8K0Y4^ii$(|$j)h>2)M<6@uOA>;Gr7uLeS zgv93qO*)7vTi0?RSYto>tvFX(_uN0OgTpJEXgbLSeHLq&+RF>xRrd%Ya+@+KTTp6f zy85bs$Cvn07d3^>#X(C;aUTPh;x)JB?>-Y-Pi)!2^^f|zHE7VW+5P-(9(NPrbSj;v zOcfw&*)|<~W%J#6b(gevgQ=sGR#D!1IuKi>J)zI!0gZbemh>_?QzneZSi1~6cT*FLLQG-@sb#g@JWxISbL zOoZrzI9_dnH0OdXCL7KS3QG(Y!xg%V3QV=WVor{`3j}BAuS17SQEBr@A$BW+TZ+nW z$>b)^jrL*>7~i5(I4s~P4 z+0x8w@D9|UrJU66jgM_gp?$NElRyu~?~Vv|{1wce$<=Vt6kEjp8T|~BXuvFc_~&8t zF&}*3M8AC|g#;f|o`eWFLUXox{w9-4xsRHfH-Rw-e+Wx{ zZEs7lbJz2A@p~g34~^miFR@-LN){j2$vhAHfGVMpFuw=is(L=p5X(@tDjN8;JmST3 zKjWQ;1{yo-R)xWpn)Scld#JeFCm@l=dS_TrS*g~1{zrj^lk-hbP*CXi?{v^AcJ}zr zuHT6rF*>6^trLVX9d|gnq@(W(Bj!~|MZ}kmWX{+U66^+!*pi|G+&QsnhQ~kbvd&ia z1sWA555r;kvv!0APaYvJT2z^C?(Xmno~Vu2O*6R=CEIR5Ihl=ymR8!;wYGn75YNE( z=12Wnv{3hIPlW9vQXn-#tPX}hpK7N-Rb6hyPrpP3z1+3n;hHIB1H31XkE!n8Cp5+s z-AvE=CWfH)F?q}G7|7rx|Wux1k*7A z@1jq#m&BK~;J>Bxg~H`C*0Xounp4z?mJdx&=(z zx5CMfEmX516A%+uP^DC>6)-U5T!@swRJ-cTcxT}HhPsm_@pis8-1wD9BPyy7WT>{k z(4^^oyOR&{ArdSGt@FFqATdk}`RiFe5*u?S9->y3|J})azhA&CoSU{WviUo0aj6=^ zW8J;~H!cp@b4&Lu4TszZ)Sflly3k^xx`_BsxGF?bbpxi{S$u{_yGz}DeG!1pkizP< zk*FyJcC5HHuen(lq<~W?Z*FeTgTHi=Rn>T={25OELeXcoh*SGLOUkshTu*q?Ji_wO zEnDN{5OsllGjAhQFOvelQGQN#J0AYaxnwuWzW75b8Q;hDk&zLbWKab>_iUM%f)Z2s z`KKqqUd6vU3!FNcblSA66l6?AGMmP^yzU+E*Y`x7Wpy(=ON=g%vKwy{vZs(V!4l^x z#)X1G=X}hMjCfkhISotwoFD@%6Gi$N&_BoMq^!ScHf%#V<9eEup# zt>>iHX;X31hEdjeAd7att_33#&u*OB8X1@mnD{l~)O#q`OFDM(y9# z;TOi{Zio9@nlC~^vEm<`$)WXIgQr`~V*M6UX=!PYjq8!b5(#R1IIu%TMXj`=N{bHc z50T@U`u4-0iMpfJV1qJ+Fn7CMx>(N}e#ZKtqV*ZVb7Z~}H1X$%+%rf+{Vf}l?BbzQQwvz2%#1i{pL|rY$)ARI8?U{YkojBKobb$_4 z@a-Z5-Gdilg|%~Unk?=LKv$hhXg-u)?P|=S) z9<`#)`?aMbDX)|5?{eXjl7@q_u^}kQB4c2|;fj=dgf8o$Uqkh#aF;!#B>h*3t;KmKT6^c` zi#Dpb)cS)*TNSk&D!=d=a_RD#13eYjcl& zA=q+#F-U9t7)$QpmTT~ts_3^qZeb%Gef2DphSJ>|T>+1YN5|=u>x!J5!-L2e_O>sZ z_t>x7L3$-bCcy`sVfURMNu!{i+k!h|BxSl=oni+}A0KM-mef))QxT7|A$>^X@Mev~9THrTfkC&Un=@H;8zSfeVS)%URA#46h+qL=wIcxU@{Q*L^%+h;n zmTe`E|JQ_!#^(bQsnmJ(k≶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 literal 22046 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

0!=p8gEG%&L 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 diff --git a/doc/LectureNotes/_build/html/_images/exercisesweek42_34_0.png b/doc/LectureNotes/_build/html/_images/exercisesweek42_34_0.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d5908e0bbfa047af6c8e9602a7623d7c755e7f GIT binary patch literal 40673 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/html/_images/week42_173_0.png b/doc/LectureNotes/_build/html/_images/week42_173_0.png new file mode 100644 index 0000000000000000000000000000000000000000..492df86d67b1355f45ccca075bb5bd1b4dbe45c1 GIT binary patch literal 18573 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∓1w4JB3+UANTj2!EmqO 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

h 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/html/_images/week42_173_1.png b/doc/LectureNotes/_build/html/_images/week42_173_1.png new file mode 100644 index 0000000000000000000000000000000000000000..90948aee69ae83d1e057e5881a2fcc25bb6cab2e GIT binary patch literal 14628 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/html/_images/week42_173_2.png b/doc/LectureNotes/_build/html/_images/week42_173_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a76574b3ebd5077d9730bd5957b9bf7f4b1b518b GIT binary patch literal 31496 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 V2_H_Fz*K6KhKiPQfuhBe{{=V`u<8H+ literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/html/_images/week42_173_3.png b/doc/LectureNotes/_build/html/_images/week42_173_3.png new file mode 100644 index 0000000000000000000000000000000000000000..fc2c8902f26b17d512d53a6c2e8b355b39c41bdb GIT binary patch literal 17868 zcmdtKXINBOw>4U{t#qr%YXAfUT0teFL;*`g1Oy~glw<+PIZF{u(1M5-Nis+-lH?>o z5s(}Ukf>w|C?sdNbJK4+=f3xQ&Ub&Fer#0Owf9T0=*L>YlB?$8LKYG zrk0+p#^ly~{^lz}k#dD{ii-AhMJl>AM`={fow7gJ|2eny;`>v_8}{+j_$0^3gvNe2EKM*`oH-a#(nXkByC{b`sCD9>YF!z zqoU`(yR*JfFu1~u#%U}qEy>HtajZS?^!&(8tMJn6=+UDLqK?UT?%bImkqGMxg9`Z1 zpFay4efjfvcB@ey`>k911mjZ|Zu}8g_x}0wUk9rcMw^dNp3*Q!6ScIQMD0dCo*5OX zi7XW@N7ZQY=$5MRXcu<8I6=2M9xOphiO}yN5i^U-+L?(N>S>?j7iT(?qQqPX@CfU~ zNqhr~kFMADDo5U8cF9QBpj~yg$f&3K+qZ8CS_P?W7PDO`1Wcypi#|72a@jO(2JGu z84+IZ>XOw`z>12BMqM*}`nk4t67Fz}iotw$b4kpNtefGWd~@mf?%p1zz*KQGmuOku4ry(kX4Kl>}=+%&KesVVc($p-IlHc05_?Wd=+!@7kHNEm(j?Zt~1--`Ko z1}nEonNgxnsW2|&`7R3s7)D`hc8B>%Cwf}i)L3yh%ho8N;wlnk6z|xTtq`Yh`kJI!#$(PvaRSwWhv)9FP44QOCQnVlH^1C2^uLgjj5& zV`5@5Td`QxJ=>i|Oq8NTwo~w}?ezWqjq15L5Axe&uKoA}SlzX;Kt9Vg5^;NfXYsO} zVze-ilQrBDw?3ay>rXux=P}(Di`(CtF7n!O-J6y;cw1-m*6@7!!TwH>?XVd7V0VSo zlM&**yCl1|Fj(@w>Vzz*YAVO`mU zg?nlLEVdmcMCjw>Jl5wsJr*mmV`T#T{Hy*FyOL+GD)kgvbWe<_IUGoc!pkc%@4QoB z+KOjGZwxt+`f}sDy1FK&r?FGl6(V?vQq*WR2?>eTXc1-n#O$n=p%4Wojv_$~=H2n; zk#+xvPam|iWo&J8@*F4SS#R9vhtuP4Sfp)ZtW#)ic=ztz(0;S?eh!P38w_wRWK>mQ zl734K68oL@Zf+v33j;27)5C=pAr~7Tl-e6+G^E~-G}7H~|Mc@mZ4iTyWhet91B2yB zmRm!`Xs>PO+Pb>B{z41&mktJ=OE2IvRi0&VzdWP5<5KvgdPcj@^BY|XeDwHN9O|jM zd9JnBUKJJ=s;wDp>!+rqd|O|e|JMEH(Jrju<=52<#e=U#Dm@}9$jvk~H1wL8#Le%| zs83?C*zukW^^~}s>Vv&SjK|i(W*pihd_cl;)1FmOu&3B7V*|GHdDwo%dyFEsf^78h zp35(7;4prJP{1EgX@87ckK$BUiUM6(MMZO89~R<=D(s@wwLXL9)`hVby?Z+wR_$?U zN5$|{wSk%3R9;nHLm6Vv9=Db8BGwZFIMlL>Lda&@!HA~6!8z?J*&RHj6g;%;)ti8+itueH66cAbB>zBtO~ z=C;AlQmtXEsTn>rG&HfeXfU?){rmUhxwFgDZ+Ln8Vj!dxdsVumrKM%Ud@M&kmW@0f zr-Ef@gop(z+5>w?Ax0gqXF%cVZV(Zkz?(}^b0CWZP?P5HV#YT~Nl6$Djbyh`FD$YT zm~k@~kN*1WJv?$8o*bbJcYi(A8m&;iNlJpFhE@6z@%wMTy(uYi%kaQ>@02<(1v?uW zCg$ho%kO?_YiY>}6>BEU;Yj*gd&81rXcH%_$bi7Z_?yl$HRzZG#q3v+_aj)F>&AFx&ZO@SbA#XHU zE=15_>@MKjJ)g~5meut^yG*;$D$;O8iOj3>NXVXntvyibQBrLE?R~q%fi8aa^9erl zx&Rs^3SUu<%Yv;v(-JA5UFMhq5xVES^a&xG0gaK7k?qa#U}C8n8Kd7qS2sZwT%ib{oyU8t-%Nz#uLp4@w`1i9CbI6@$=Xh7AZGnXu+G5NEKdL1*Ka~I_v3HrA-I;C zn+wqE0{0&rXyL*OQ$dxDwpDJ|ouPD?NlfDFi2!)U~Hm(1Q=0|Tv;Ur?yC={+JRKdx#{M~w6(anJST zV(;I-|I(|{W25)!(G!n~v=zK~6}`QymRDA624Q8zTu7lnKbqGx=TWE{hm*A`fJlI4 zd~^{3I`)LZ1mp95u$!G5nB3CgMPe^RL`G&LBqW^KdHVFJ#)AjxAy<{dw`)Ga8?XY{ zby>&EpnKmvL;MtyvU%D+`5TlMA0-@nhDXGbJp z5bCL}bOVJdb#SE;OOg%lm1XftmJXzC1dIZ9(bUq?v$Zm9V~oU6S!VYy#c0QgdrUVU zt2j6~AVCA-7nR4bN9<_y za4{1zbIxRQ1Q!Q~9I~YY`Kr>t6`0L^qGT!j`weixZEGK;m4V!6cp+OER%2e}Gzw*Z z#j}?Nh58WqeoWp&d5jB5Fno_=9%y7?s}+bWXN5ERKN+T}jnc!bdZ%N$el%!DP>Zo! zNey&lH=hd zq$!o+y5A`mn>W0@AlDV|A>8@=-ISwSc9a4pf)!a*{ymRDRdm6linb{_!t3A))BUQ- z_c}M$sZh;<$Pna9AM$jaI2cKhmPk>+i@hLr&L^HezO>?MZ!!s>j6w-l$K1&5WU=dv zYthx>?n+Nj#gWLSj+s~f{sfd<7q(GW(0$f*lIC1vwV%H}%aA@giswTF z99~-42+fPXLBf3_qg{lh%gJD|+IDO{ zEvL4jb3|}uV*%6N*ZnCBbMxsb6iVrlvgvCXpO4Zoo2ztz=lU`uWu%8M(S>kh^j;qh z;@U~6cv~@KpkW3NvJ$l8qR?!2Vxu?3%LOZt?eNgCj4mtcqqBe2H=G9k9PwkEK4Xv4 zzEEq4hKnfjh%3e8_loPe2i_mia(8seo5`(=o>Lxz2Hlf-(Pw{2NYdQRO;qhKB>Y}jtl8R?sPKRqn>G$E$f>!XlNOauWfV=^`EjFu4(T~!Ehk^k`SpreO&Oz zO7^yQyMtU;rHz!J*F(lF+&@N1{F-_sO^_V&$mEg18~^CQ)YWRmyb=-94AOCAo*GB$ z>ikBuR{~A1kTI%xiB~9u1g{o9v&}SUh9_7YKA|+kY-O!y?A+dm#bmbGCx0H>ZrIDl z)P_im_l+5~halM{0473YO!6MA60rt)E}m*?c+ea&av>D;7u<(oX025}${1yonDO_z z3P=AvJ#`VWWweBKLicKgcSKvPcp4-zvz@Xm#AnpE9uGI9q^1%yvk!bYa`Y>4>+IAh zU(U?*{*I3a^WBUG!<(EICPN9b+Tc3I|>1h`k^(Azd*cl*6-cZBQW5)<^I~oH} zSctcko~+L7NLcOVrm@LAyToWo^3_~k`p&83j%i$caQE(WUft4!LE8#NpM#xI8YU*M zy1cEet)}+&5}WCXiF^1g%}n?;Y?aN)yGFW?R#;UWZF^D`o4F{I(XiSijEyad!X$AG506$=vDNmBp72;R1%2m3b0nY7r9f#U0o(&9sk;t&iFSo+_9a%eO|RY(O%x%s>b%9;6BBFqpR<4SiRW6tDbEqqi3W?|7a>4`khw9C@9S zFd`w)zt^Bp}N@* zvNbPXxk3P*2x&~5$gB5u+pfn}ZT71KoOs#ED+>e8-wW9?tRCh~-J-p0z`_T|!5s+x zxie?fen_Ut^XlzsM)2yb!fVo7a!^)QcE{nu2Nua>+iina`5h%riFVU>MyEnUak>ui zHpC34ql6zn2y~P~SNdujm)Dl~T}C4cu(_C9Gi+C{a}=`=y1R1&kK>u@$i{Z@mO zK(^W9H`-A<_LM@aD;>+Vji++jZUQ*A#i27{j|~=gcXfs0@$W&FAvlcJ16jqtz99OZ z`qt)cyr5MtHzYq9AR}?Ivv(kvd|4sf99Z=__gR#$yvsz3d(aM>mITYkQVpRjg>>Y! z!P!>ys?B5V7n-q#)Z+_RD)10CIV9h?bLS~PKYwUkoUO;lgaibvJKnO&PAn{BYi4WD z0!_qJd+*I_T|uG3rX(s}TYRR|akwqtq7rU3pLKxj#Q%B>BrXR=y zhMwo*gUy$_7Mi%&@jg`4trq~%q7g*flt3nETeJ1_QXSu5MqM?T7~dfHc46zX3gA_eUUY#bB|=-RkWxmN?7x zH|r!<1>dCR&os!-OHWNNpI95}6JMPSXT>Lr+y34$_iQjTE;sENS1s}I3O{tDD8t?o z?VjUUj4pSVx|>LM`i#y40^t}k3Ed}#=e0l1zDeaC%-H>Gbd9K`NgHcVTz<+mfsJ~`y~boU+4)OC2L9==8<;XXIuM!llJR%akeOxL{^GzQuhNX^73Gz zr$;K=EIIti_O#T3Mw*{LOrjOp3^60cwPu2*s`*{YlZ~x)@6EQ0JB;0)Hyasd5Xun( z6B7>8*c_)&G|1EGy(C37_t*+(T#=o|U}s9=Q)HM*9OCT+z%xvyD^m#Dnk`K-MDdVA zJd=_}kUK`naoZwDD>RGMtgX40DBV8Ntp;?@B%|p$vQTNNy4L2O4!TyGn$Vow!skef zNupBX>55VkvJuC`5dl2r^Q_ZR-1a}v3~eK|x?Cf?yk?Zq)Pmfhd(iWHXuUT+>(%^; zWqYU2(ESpQ_4Rsgj3@0h+YgUIRDM(#L9&mql z;+rQzW34vg-moF@dVlFQBXM;?IbOi9m;#kr@S~3#i4qM?D+o-{k*%^NnHcjmCJ$%O z&CV$-IK8un8?W}jSl=u8wYLYsW9Ip}nXd1Dzh`mFt4`+Ty4Ih!YWYMx9s#FPB#1|B%rt{EE^zE88B^_r^`Q|4!Qn-o$N3 z4Us#ia+-1^r-#a%Ecz`sOlAK!lgUl0}!`c*vs}L~OGl@sq;?!exM( zItO$EVGQPJoD?Vw#xPINOPVmEFBH~Q+n>Sl;bwL9Tn?m$D?mn(lXwx#7h zluyF?>CT-?{`~n)>`iwy$kI|?H@3H9A%V6Lzj{>`4+*tNk@kX)J&j`q){LZupzEo& zez&olah&PwDLA3&NRakUD8dcXveVb)YX>sv#p#KTdn&BYmB=4ul1sT|-+Jv8|AqlS zsI-c)Vnsds#7r#6{b^$-vc}GwJS~|JhWk;1a*&S}FT})L z5VGvK*V);Ly;=VXs17^^9?F-dJ(h&fgSM`XPwMUr)sLfHAL)POKQQl;u~d&qy;a#d zyfGPLQpFb$7G@H$qM4DLHBoFe`$FWBqI9yYAcR`OgEOgp7McMPJ z*b`pjbOIZD3&kfPTZ(pEIe{5$&=c?(RT_@&B`!}|q>^_mW3uf$)-3xXBI3~=nj9P) zP|14hyfitE{83ps!gdQMv4DJW*vz_QIf++BsFKgRZ1=| zknSj=K9=)LFBgG*Etq@pf`Y>Rf5E^(b*SL+>)?=KsiC1>w`O@o1Y5B$aU6apw{3WZ$SbBm>+dBl+9W zs|a59E9y%o#_d?9g!*|pJ<5TDkr#fQ`y#}02Ye={mOFA%>r*XV?#aI^1B8NMZD=)ydXAoCCb z<;`nVy&O_FUYc{XTwmH1kc7P9L-}i7Dg@4Kbs>Yh;#HTzzjmYIhAdBY0=#!FPJM>b!ks1VA90^One=$pOjk66;H5e-bhbK ze?VpF0f6`X5<{PZv&C&BxvFt#ZY!`H!)I^XPG6T(Yq60;Ky_kzocz7XHy;^h-(}Ig zLWDuR6_}nRTXur3A@pA7JUpQbc|s;XJYoM$Dpr%MYM7T;@8TtRRrrn#V=ttLHA2V@ zu+H1MPp)`YVGf3!bn(v0(SK9)`4D93o~QAG^aQeH_U@^_(l@5osz0bj=+JJ9HrrCu zfOv`82%gEa^9l?4Ebt-xnTCcDN~DRRd8aKgqmUp{Ov)f{^igap0tQ8RN=dy7RJi)yHAIwXwbIHI+wFuq8DRig+UupxSQNEq-LzJN~4UC9Q_Kld{_ad|m=R|E|ANU|I+sU~}uS zHh$H9x*kU!8Jw7GQ=^GF0yDf%+Cev*+xVs#+gLyV@k`(PLlD_UXSCCVA}j#j(iLMK z&Rz-7)5NWO!q|#zRTN+be<9BiP8Q?_6F+BfBE%?E%8X5pwfu#JS~cymvvJ1pwwK7~ zmxkN!@2#z5Hwv}B7TvQ{n>Et47dKr2S_>Kqx;Hg#ps?AQf$~>U&z#} zaLs^R4SSPUNC;D8NzAwD%fz;ir2KL_EW&j;29b&?_#I(YJcNne*IOsZO=>hMv=s-Y zEit0%!RYmO%s#sgNEHpFbENFP+N)!yw^mwHa~pKt!75!ncMCSu^m=RY$zkyw%7vz{ zs>2M-@{bEc;${b*zB!`%LeEG1`0?YbEA0|oSFV5);N83P**Ya;LW9iRyXnG;Wn$=$3?p0el|;+rS8?Y(!D8 zI_j!kq(>q~;=)0EZe5HxI}N1n+ya_>DKPme$cz0mR~(&OuJ3JpqMz1zzZmd$Md30N zcsr;V1Un!H?g79Z+(!!3EZ&zc&n<>hmXjG0iLJF_t}!d;=?iB$VCGp!)!Y6xcGa|xTa zEO(xLk5uVf8W3r_wDiWHtCG@ds4pka%$RTO?2JD6K?KtQ1_~SCvA7J7FB_q5flQA* zH$g@Hpin?;*F4cfGJ+M1g3o81=}oNwN|d5)ewMZ&{7$Pcux$6SKZNy!6c6JtV z#v}(~AN^0{1YR1{g?hlJ;;qA+??kWB(QQyl0R#tnMrX-H6eoW8SsPT3!@|N+==2{; z($mu;?u~FhgPe{I6*)B-8NaUXZkzEF$Bzpde*TpS+!0V2v?LP3s`l1(fOsRv!&fS% zm9J+s!nO~~K^H+NA7x1Bqb$MRZtcQmQiLj}c>ek&T{TJ2vL~INMd98(_B=Gy{1jtu zf@&Ca5tKEiwdu_LE2B&^jWuAJ!9gjpgCj^ zJxF9W`!=1uJxDiL=r~;`q8wDlbML@2J$BbKW*V)Ak_CkGWlFgqmUKO^c;@HqilbYR zxnp%WLnqID1jcWh02A21` z$Mg0Ql0-$Y0)D&b_ugjeVhj&oIKj6GAkr6N!zcAa8Mc7$Yi+A^`>;p!en;7L1&r@A zF5%j2Du(-VlO?7)k~e_S}Y60A5WQR>}%%(0!~} zRZ)5W<K_BGuH3&MzS&^ zDNF5Kzo}b8k~~kXM9T$H)yNf&VsE2!OWV~}YpX)=$xoOVX6h)iG0##s6PkXMoIy1i z4)2F-H;7AnUV5T-8?#MAi$a`*h=M&q?)Q%NBq5s-PQ zmO(&3f*f&qhV=zqhnegfH>We8zReo(JA$X+V*O@=Qh@N0S)# z4;E^yqDMjyIoSOBOg>8YDy%_h;)nDHxd&#sQ**Tm|4k?Z+YS4P9ifi8 zS6FvG)_dWz6e*Py@XX|)2gpi)9MU5ELSTfS@79yh4K%QdO4C}H?rudsiGG=l;_O9u z!q6Y^^Lt30iMXh?wmx8RSuUHgrz<9r=^U*}?WZt`QhFGo(jo%0du&>bv;Pfd)5);g zVg?AYk%vW~zsgMi2D9l%@~)HtFw2+QpS0n9|F1HWXdV*+v#}3HLDp0P6`&n2acL21XShEnr2f7fdT@V|NX2Sny|Y}`g5h7;!`??A#lB6D`#%)h z363Ye1G(&~0Fph3k!XXecQniLG>+b2Lhi4%ykfYwm&qh%$D?*zk-G9$X=VASb~_Le z`@bPS|H{SQgGgy~5-j0tE;eJiB7TL~hdki~lo^~Pm4$`>R}2m+TcIs0e{eyM0YwRX zGQId@ZHHMjwMA2YZ23bTO|*e>EAyGe9K}5*JqBOS_iE%8@ZSA*F2Ym|6>n)78N`c+ z7~jBS#+7s*Mf?i78oKC)w2w}{9$i))$=k|Ta~EMGw|{q~77L`~>xGne4V-(NfE~jX zZdh>tgvG__Pi+emsyyw^_js2&?)7s9zmR2*|hU-~fReY$sV}aqj;lG&wECQ25V%_wL=99oz;v z`{)VUuTbY69#EoS;2(VnPRkQ=;PK*MPoKDYQIPn7&iJ^XEgMP5=CI3#?F$D)ddiuGpMYZ_T9c@{Y%dH+6-^#e#%Eu zlM%<(8Rgn*@(UHcoB8VsUEstyM@MHi*w)wxm5iX(@h{BF8*XvYXMjWfrBmdpVJll+ z{nHtcmBn2V)0ZQ8^^ZSpgIg;lXXJu}_s1Sgw8GP8&zdhRPEBc=+ApoHhNhX#GX8CN zcsQ0sIdKMNzq+6cG~$NN=sJm*lUoix8WpI%XEfUZ{~+~d>qIsig8Uy~#;XQE*^;S%b2^1(-K*q>MDE8stE+K)$?mb@eN2aDRR91yMChYGw^x z-5A%!k?f5T59JfI+#SzMDrVv9svHoy?HOKh`|n!li+20rxd zTh%eN%YRlRBIZ&i!J?vedHB^$%N};{&=6W0&YU?TzcBZ$APpQ!M$-hSPk+NS$=-(R zZu|lX3F;l~|BA2Sde7PrzmIkQHQ3{z#wmmQw>wh6EC<)}=V{hQc@N}0U1q!L;!MB} z6XIAf-DqrV?6UdOFk81w4ZoTuu_uRo0KCXf#Bs!?1b*g$V)V_MhlQPM92G}nAw*bB zHiZp*Fnk6kT@X$Bs`pcJ^eQ+ZodE^1dMqz4F7EiLQ^igb;8DL)wD)rVxvU0$(NkwT8c8YI>SWLSnQyHY9{qE?+wve$n(O z65akKA|f@%8vQ-(leO389mc?$#R1N5#Kf3a4Uq>21vw$a%M`2w4lZyXWdO@eNlBS4 zn~qZli=OxXmKjp1V_;!n$pv$E_&~LJ=Or*F^A%orMyH8}<(~mO`#5s=?kq)Inhb zsyRCsf{`fqTd>xDDLJ}1i-!6A*RxtOBx%<2?m7eiqpz5T=PzDZ3>MqK?H^<`D8<}J z1ar}xcNKWsU-xy1iFaWvv$kR&wtkjJsJG+31A~d1ak@s3f%W6l=B$m zKyy@78GZ-TJ7NT6zj8(9`t|FUgT>jmc7N8MF;-Jo4~vcEk#lr$A%YKI=wS^?$g1~H zegwQI^xng5ZEp`0XrNFJ@3?x^)mE$n6|(_MpRcur@+h6?R#8%4XGWY zcjgOVGbbQ%7mD=;AfIa&n!o+ad^a&Q^NTm)&;x%L*f8@JR#sOvKo>zw=6m3K9=y-|Q=w8!z5R?=cZpL1qNcBtK1O_{iXN-$W%(svM#vkIFyy! z)pq_fd=?EIqAwhW^>pbUKYl=L)C5J~(xppmdY+TL&@iyt#Fg7WDN2Fzb^o@8!9w~C z`o1a-R~`@$fRy(`L(j#cJ$i*x!BmI%^OFM=G!bbDOuvQBvuX?dc~Y!0uiijEgORcE zf);Y#E>?`Z+65Ew92hN1Yz)ff3lQU=w6q-luft};D1g{zC4BT@O}YRwh-FS@NSUIl zs%o7Z9CGj8fNl>pe*n%LvHEMT&J5B9N`r(F5FA`$0L?-*96zdhL z%%pb)g-Z9E$4O7itS$^VmOG`q2 zLBVA?V9^6rUKL0$L#(Ki43s?sz;8cR7dSaLXVtC-hxm7JLPM!bcLnY2?ZH=AQc_a2 zLl*Z42g`HJy)aJ}uqXHiAl0Y;H3(Ib;PkzQ0=?dEe4Ls(0wx?KY(s!vne>E&?}P>@ zkZo>0CV~qaR6Pi3U0`opz<^Qc+I8TQK>gB7OCKQexGQ-mqtC!c4@_Wv&=-}98-g|l zL8qzvt&sw<(ZV)r_Vyn@NKF|U()9>C4(^4fR{g8w?zCWFs>Xx1UCA#YxUGR6J_}`V zo)rMee+M$QS%`&L6_q!zBa$V+oxjdW2XRg%Wh5yCb~lg;{iP+ygH23LIj>x)FK+Md zR!4X#{D3p*E+FM4*NXQ}Wd`0`(sor_srnuZMO?2NTUtWd4ol%IPzr|zuW(Blc|>{ZtdDfvmj@4n`8iTrpE<_COR_ zn;o#VlVFC>W04H>X*a6f5IDRwe86(_GUSzf1#u8V^j6$asM|z*SlDF=iR$Cx@pbHG z&SLJ%$Ck!9ldj5& z^y?x00FZv$Z2Zvef)*1Vy>gANy33hJHwjQ51UjJyGVwI4%vZ3x=jG+Cb0SC=I&3SW zUt}2uT}HX!s>?L2^}EcxvtX$OM}Fa$kz5qm)Y{@Dav|fMU7hVF4V4vuZ*^Gm7qeT zKo5+j8j)rkT2IwVY=r5$t=@yZFF*B@Z<{8Y6tB^azHVT zpFG(Er!lvur^kvJdwNB0;Td=uJwOl0DjD_G5qBf^%;i?+K-+-T@1V+XnfqoIj{)tg+-)(Z%4>%cjjn82vaql~dKZ!JO-wvejJv5dULVvA4O*OK z%hBp1ReaFp%yYe@WCUk*8KZk00vqDnwE(K!Cp5ynq6b%Gw5?SBrzV#qIEQ*m?~X^? z)jkJ`Zus2a-(YEJY|IF0cYF-ZVm3SA#C^EAwM7r{F!$9NuAa{?PEf)5o?{S)ra|Kx zUkcakw0vE=QPX#eP*sHXL`cy3*P&T>5p%EerjZ*I`jDrSJ|APvz5d9Pjam^XlP<*G(fAN6X`? zT5pU(mN2u>woyAf_kCQ7uqx`I}{Mix!Y6taBI0U#s;TJt@$- zk)nLJbYPSe5M|eWH1;21Tjuoz_qyv5x9qss+0(!5Lqe?0H@evv;(aP+UTr)t^MVZn0=oVG~39k$HA zC(`A1@7|vy?$b;>TKRY3xhYX1b~zQ~as}v`$$o`rsz15n#o8h~>SxH#%d6xz@h8c%+nij-hHPua$=m?-8(mhHQK_|8kLDrqL+O)5A#I)=sc1w8WG%3&wkR8iG-^ye8DL4tSr z@@0;jH+Q2NH2OUw=6WYNXTH8=t>-BjG8%H9j;;Su>mLLpez4C@$Zlk4bGez%W)NvJ z{4qUk<_UqM9yFDpL@EEnR%s~`8( zTZQ7hw=ImJPhLh_J1P(2LK18d8OTcR50@CeGp^bJ&Q)kL*!uufpFEIgkholrC__f~ zUE&u(TGc7%z@gLhq&cE71At-#p^h%KxIuGxP@N z;NW5|n=ycc3|NrA_LX)`tci+QK7RZSXt1nJY&J-wn9z^5>k=_Ogl+Zw30u3BL zY6vI|O3(DGzLt}KTtNKQ0A5y+ZuPnsC%RENueiiegs=u?kNeON4()_&6R6TFPfz(; zjnMrQrg#OpHF{yznnkbgJ#ZKVFcLoSfXm_uK6v#N&rb qty7?dlKTGpH8P9^FjZkqs^<1YHqK*6+ot-@mufd zA-q3$Zb&n;|Ke}I{#5eGhY{L_d$WDgPpqTH@IEu&aW?N96L!I7N6Wm|M;kM!-#Bx2 zthW!ka{dEjC&O^tUi6lLO4Vf0oL4zx}I_=1n3UGF1o}QlXg1|nt!4w&QD@>!) zx)BEZuKQyo_~Gsm@eU03m1`B)vd!jg3pL5RYE>%L$+DiY(G+9zE8gJdd4U>#`MxBJ z!C+Lbs1p|FGBQa@VHKK3vzvYRoW@`{MAnZc+eN)N+<>^^&ft=;SZsHA&3h!KMkO`~ zFk9}|k{{k)wzy0ZWueBpTr4thTnF0|PAVBXGLrhL{RX>_rCzX$m!WwvS2CBeMy^&2 z*t0nK07`fsn}E!XZrc<+biS^YhM&*F! z%tgkG+^mwmFF*11(+%oP-5V0V`%(^q-QH;@Os{`+9U07{A);SCx!hla@%B%ct+70G z$Vjl<8G9~1b#G{ghGbeB6MXvgw)IAK9}d-FGb!ecrY0s{<$n4py2jL;$i`i8l2YQs zOkDn;@}r_JF&NCl+FCen=*g3>W(KNvnzNLz(P3d(S(hGLS81cqwqM^vDM!|U4Xp-2 zMkKYgAY{6?T#|uJ+%D?KvN}@sLrJJw)BG7ddi_@WkGJfPAXBMSC@0mO_GaewFD@Dy z8s40D6sYBO!gbiVBjA~xd|8og-n=kSA)lp`RWyF?heQgyJ=`)rbGhEqma&CGJak$< zGoYu(8y-&Vn6=33po?rOcgcOai#wzwlf_}2+bK_d5JgTG`!=y(%lbilj)qL`W6Z@^ zVtVh}z53asNLlrSqwLf6j$j{1T#7mbo{SrFbn~Vvx7{RS+H*GLpiK99}WVu`( zH~&~$C?CRRUcP*}|3PT`T}(IzLm`ti9L3qj#zu&#sx!^W&{4Ys>2~lW8LwX2c~JO+ zvGR0oET2%h5_8+~Y`#XQk``#v)oQg*BR=fDf5U72ksEEHy1zY{I-@QtO*05ev;_HM zwQ`B_>ItzpbKREx&K_5v2kbzpr=5GY)kX}sBb*n0JEEH>OQOOZ{224U>hu&lE|i2X zzkbD5`Z}K~&b#1OgB37Ch@^oBp*>xNF6_vrsnW922Hd!p8-Q!MsCnki1jp2%xcMRb z65`{j%M1Xql)+Hl?Nt;zsY)7OT+}Hg8!CLO&$-4-{C4|l(zEW8FK=ojM5WN!TkqsZ zG<$3160>_JsMuapDT%!`Ha$-RR5T^Z!8%SV+*utY;rz*$Lgfo>Cvq%ZxYaUtZWtXN zo;Fa8Vv9IALP$gH#6=p#JdGd~WvCW+73Y3rteQ9)BIYwBDNf2yOiYNfJI1Z0o@K$0 zFTNWso8VOyP%M~sCML4`kS@SNd3OwdaS%3|LEuh{1=u zh|BFkZ7Ghj+sO(q>%hGGQWBk$V|&!Y!vh~1%NkR3_0PPs*;l?So|~hlz~fDcE6)qs z#+@|FORsORjQRo-W{(L9+Rmw^m|K|Vni0k#e~a<*lcT|$Y#T`fH_2SYEiiU$7%LTVs!l(?Se3c*=;;F}FZ(pYb?euE z>D&S;zF1ZDv{l)cl5AEB*yOq`%?67}8inwRi+O5-m|fi*{A8w7E?q-=x4)H0*%L6ce}!V-Q79#Y;oQUUDT%1~KRyNiIlpT`Bc2MyM9gfO1xi9{l8P@TC`bZKYV z98)n@T3lRguP#g@Pi12&O7@>0JXKRy=Ut8BRsfUqIzLo98=9$_spfh?Fl){}y%G*g zy2lrl=b1-RFZXb41^z0PnB=rWx`cH`(&M6Q;v{2NfuO2XLjJ zbJqFQMFuP=1RAwI!>hXhm`G`9Dd>6+N_)b4uDUrAx)yI+t~z^xChuUZ7vP|&3|N9E z5LVA{1FlTp%oLp@F;KEG*N$X0PV(kV6iBw(}IpX&wH-XN}A>ZL{O?s{@n5&3BD>vQall1h! zY=)4=CnQiroWFbjF9Y3MC%r$s09A^W}ys8Pn{(fdOA@3lmylVIcrE z-XYuNpeaOQ(CB;UKzyDq!H$? zbd4wK=`}YuBcvTp9$}xyAD$GRniNhPk9yn8`iGJHPjhj3SP{G)$Pdj2uEeAB`FtAT z$dMyZA;S}9s>ZTjTHD+E0S1Xvlasr$4fJ?jUGCr~&Rhj&zie!30tMi>=J=&9_O&kV zfo9AT*#v-|KOhhUfnCuLWtM4AuQ?{iLS>Wleo|7B72`+E!HWN`x<6UJZ&h{=u#$7} zdY|F(_>VaWN(q}HDi3I?1q?cqNF>SeBKD(4hk5jhiV7Mb;~p?QbRZb^dGvUzLx=pW zE32!k(fr3hXj4S4t9Y%3dV9UBb=%Awf(kS50Bi{9P5=xfkj>vGYx+{c|ILz1jY%J81s=eAMsNuJ@|XPCw!2)N6dL zGOzN_v%LqWddeuM>-@!^j-gQF$1Tpd7Yc+^96t$;6RrGq-$%#ARhOZ6|uoL zU%R-t@aUbLoxfYP$up<%F3fHQGu}O(xoXOlEEWqL=v*mU>YGhm0N6Cb^G>h8o|NA0U_NVIqdU>UEpEDXQ03G z=vj7de\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "bcb25e64", + "metadata": {}, + "source": [ + "# Exercises week 42\n", + "\n", + "**October 14-18, 2024**\n", + "\n", + "Date: **Deadline is Friday October 18 at midnight**\n" + ] + }, + { + "cell_type": "markdown", + "id": "bb01f126", + "metadata": {}, + "source": [ + "# Overarching aims of the exercises this week\n", + "\n", + "The aim of the exercises this week is to get started with implementing a neural network. There are a lot of technical and finicky parts of implementing a neutal network, so take your time.\n", + "\n", + "This week, you will implement only the feed-forward pass. Next week, you will implement backpropagation. We recommend that you do the exercises this week by editing and running this notebook file, as it includes several checks along the way that you have implemented the pieces of the feed-forward pass correctly. If you have trouble running a notebook, or importing pytorch, you can run this notebook in google colab instead: (LINK TO COLAB), though we recommend that you set up VSCode and your python environment to run code like this locally.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6f61b09", + "metadata": {}, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from autograd import grad" + ] + }, + { + "cell_type": "markdown", + "id": "6248ec53", + "metadata": {}, + "source": [ + "# Exercise 1\n", + "\n", + "Complete the following parts to compute the activation of the first layer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37f30740", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(2024)\n", + "\n", + "\n", + "def ReLU(z):\n", + " return np.where(z > 0, z, 0)\n", + "\n", + "\n", + "x = np.random.randn(2) # network input\n", + "W1 = np.random.randn(4, 2) # first layer weights" + ] + }, + { + "cell_type": "markdown", + "id": "edf7217b", + "metadata": {}, + "source": [ + "**a)** Define the bias of the first layer, `b1`with the correct shape\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2129c19f", + "metadata": {}, + "outputs": [], + "source": [ + "b1 = np.random.randn(4)" + ] + }, + { + "cell_type": "markdown", + "id": "09e8d453", + "metadata": {}, + "source": [ + "**b)** Compute the intermediary `z1` for the first layer\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6837119b", + "metadata": {}, + "outputs": [], + "source": [ + "z1 = W1 @ x + b1" + ] + }, + { + "cell_type": "markdown", + "id": "6f71374e", + "metadata": {}, + "source": [ + "**c)** Compute the activation `a1` for the first layer using the ReLU activation function defined earlier.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d41ed19", + "metadata": {}, + "outputs": [], + "source": [ + "a1 = ReLU(z1)" + ] + }, + { + "cell_type": "markdown", + "id": "088710c0", + "metadata": {}, + "source": [ + "Confirm that you got the correct activation with the test below.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d2f54b4", + "metadata": {}, + "outputs": [], + "source": [ + "sol1 = np.array([0.60610368, 4.0076268, 0.0, 0.56469864])\n", + "\n", + "print(np.allclose(a1, sol1))" + ] + }, + { + "cell_type": "markdown", + "id": "7fb0cf46", + "metadata": {}, + "source": [ + "# Exercise 2\n", + "\n", + "Compute the activation of the second layer with an output of length 8 and ReLU activation.\n", + "\n", + "**a)** Define the weight and bias of the second layer with the right shapes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00063acf", + "metadata": {}, + "outputs": [], + "source": [ + "W2 = np.random.randn(8, 4)\n", + "b2 = np.random.randn(8)" + ] + }, + { + "cell_type": "markdown", + "id": "5bd7d84b", + "metadata": {}, + "source": [ + "**b)** Compute intermediary `z2` and activation `a2` for the second layer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fd0383d", + "metadata": {}, + "outputs": [], + "source": [ + "z2 = W2 @ a1\n", + "a2 = ReLU(z2)" + ] + }, + { + "cell_type": "markdown", + "id": "1b5daae5", + "metadata": {}, + "source": [ + "Confirm that you got the correct activation shape with the test below.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f7f2f8a1", + "metadata": {}, + "outputs": [], + "source": [ + "print(a2.shape == (8,))" + ] + }, + { + "cell_type": "markdown", + "id": "3759620d", + "metadata": {}, + "source": [ + "# Exercise 3\n", + "\n", + "We often want our neural networks to have many layers of varying sizes. To avoid writing very long and error-prone code where we explicitly define and evaluate each layer we should keep all our layers in a single variable which is easy to create and use.\n", + "\n", + "**a)** Complete the function below so that it returns a list `layers` of weight and bias tuples `(W, b)` for each layer, in order, with the correct shapes that we can use later as our network parameters.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c58f10f9", + "metadata": {}, + "outputs": [], + "source": [ + "def create_layers(network_input_size, output_sizes):\n", + " layers = []\n", + "\n", + " i_size = network_input_size\n", + " for output_size in output_sizes:\n", + " W = np.random.rand(output_size, i_size)\n", + " b = np.random.rand(output_size)\n", + " layers.append((W, b))\n", + "\n", + " i_size = output_size\n", + " return layers" + ] + }, + { + "cell_type": "markdown", + "id": "bdc0cda2", + "metadata": {}, + "source": [ + "**b)** Comple the function below so that it evaluates the intermediate `z` and activation `a` for each layer, and returns the final activation `a`. This is the complete feed-forward pass, a full neural network!\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5262df05", + "metadata": {}, + "outputs": [], + "source": [ + "def feed_forward(layers, input):\n", + " a = input\n", + " for W, b in layers:\n", + " z = W @ a + b\n", + " a = ReLU(z)\n", + " return a" + ] + }, + { + "cell_type": "markdown", + "id": "245adbcb", + "metadata": {}, + "source": [ + "**c)** Create a network with input size 8 and layers with output sizes 10, 16, 6, 2. Evaluate it and make sure that you get the correct size vectors along the way.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89a8f70d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "306d8b7c", + "metadata": {}, + "source": [ + "# Exercise 4\n" + ] + }, + { + "cell_type": "markdown", + "id": "221c7b6c", + "metadata": {}, + "source": [ + "So far, every layer has used the same activation, ReLU. We often want to use other types of activation however, so we need to update our code to support multiple types of activation. Make sure that you have completed every previous exercise before trying this one.\n", + "\n", + "**a)** Make the `create_layers` function also accept a list of activation functions, which is used to add activation functions to each of the tuples in `layers`. Make new functions to not mess with the old ones.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9df82312", + "metadata": {}, + "outputs": [], + "source": [ + "def create_layers_4(network_input_size, output_sizes, activation_funcs):\n", + " layers = []\n", + "\n", + " i_size = network_input_size\n", + " for output_size, activation in zip(output_sizes, activation_funcs):\n", + " W = np.random.rand(output_size, i_size)\n", + " b = np.random.rand(output_size)\n", + " layers.append((W, b, activation))\n", + "\n", + " i_size = output_size\n", + " return layers" + ] + }, + { + "cell_type": "markdown", + "id": "10896d06", + "metadata": {}, + "source": [ + "**b)** Update the `feed_forward` function to support this change.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de062369", + "metadata": {}, + "outputs": [], + "source": [ + "def feed_forward_4(layers, input):\n", + " a = input\n", + " for W, b, activation in layers:\n", + " z = W @ a + b\n", + " a = activation(z)\n", + " return a" + ] + }, + { + "cell_type": "markdown", + "id": "efd07b4e", + "metadata": {}, + "source": [ + "**c)** Create and evaluate a neural network with 4 inputs and layers with output sizes 12, 10, 3 and activations ReLU, ReLU, softmax.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce6fcc2f", + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.special import softmax\n", + "\n", + "network_input_size = 4\n", + "output_sizes = [12, 10, 3]\n", + "activation_funcs = [ReLU, ReLU, softmax]\n", + "layers = create_layers_4(network_input_size, output_sizes, activation_funcs)\n", + "\n", + "x = np.random.randn(network_input_size)\n", + "predict = feed_forward_4(layers, x)" + ] + }, + { + "cell_type": "markdown", + "id": "54d5fde7", + "metadata": {}, + "source": [ + "The final exercise will hopefully be very simple if everything has worked so far. You will evaluate your neural network on the iris data set (https://scikit-learn.org/1.5/auto_examples/datasets/plot_iris_dataset.html).\n", + "\n", + "This dataset contains data on 150 flowers of 3 different types which can be separated pretty well using the four features given for each flower, which includes the width and length of their leaves. You are not expected to do any training of the network or actual classification, unless you feel like it, in that case you can do exercise 5.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6bd4c148", + "metadata": {}, + "outputs": [], + "source": [ + "# Loading and plotting iris dataset\n", + "from sklearn import datasets\n", + "import matplotlib.pyplot as plt\n", + "\n", + "iris = datasets.load_iris()\n", + "\n", + "_, ax = plt.subplots()\n", + "scatter = ax.scatter(iris.data[:, 0], iris.data[:, 1], c=iris.target)\n", + "ax.set(xlabel=iris.feature_names[0], ylabel=iris.feature_names[1])\n", + "_ = ax.legend(\n", + " scatter.legend_elements()[0], iris.target_names, loc=\"lower right\", title=\"Classes\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c528846f", + "metadata": {}, + "source": [ + "**c)** Loop over the iris dataset(`iris.data`) and evaluate the network for each data point.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2efc507d", + "metadata": {}, + "outputs": [], + "source": [ + "# No need to change this cell! Just make sure it works!\n", + "for x in iris.data:\n", + " prediction = feed_forward_4(layers, x)" + ] + }, + { + "cell_type": "markdown", + "id": "334560b6", + "metadata": {}, + "source": [ + "# Exercise 5 (Very optional and very hard :)\n" + ] + }, + { + "cell_type": "markdown", + "id": "ea0a8fe0", + "metadata": {}, + "source": [ + "**a)** Make the iris target values into one-hot vectors.\n", + "\n", + "**b)** Define the cross-entropy loss function to evaluate the performance of your network on the data set.\n", + "\n", + "**c)** Use the autograd package to take the gradient of the cross entropy wrt. the weights and biases of the network.\n", + "\n", + "**d)** Use gradient descent of some sort to optimize the parameters.\n", + "\n", + "**e)** Evaluate the accuracy of the network.\n", + "\n", + "**e)** Show off how you did in a group session!\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/LectureNotes/_build/html/_sources/week42.ipynb b/doc/LectureNotes/_build/html/_sources/week42.ipynb new file mode 100644 index 000000000..8699e7c79 --- /dev/null +++ b/doc/LectureNotes/_build/html/_sources/week42.ipynb @@ -0,0 +1,6209 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "474b773e", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "a8ac8249", + "metadata": { + "editable": true + }, + "source": [ + "# Week 42 Constructing a Neural Network code with examples\n", + "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and Facility for Rare Isotope Beams, Michigan State University\n", + "\n", + "Date: **October 14-18, 2024**" + ] + }, + { + "cell_type": "markdown", + "id": "c8760378", + "metadata": { + "editable": true + }, + "source": [ + "## Lecture October 14, 2024\n", + "1. Building our own Feed-forward Neural Network and discussion of project 2\n", + "\n", + "**Readings and videos.**\n", + "\n", + "1. These lecture notes\n", + "\n", + "\n", + "\n", + "2. For a more in depth discussion on neural networks we recommend Goodfellow et al chapters 6 and 7. \n", + "\n", + "3. Neural Networks demystified at \n", + "\n", + "4. Building Neural Networks from scratch at \n", + "\n", + "5. Video on Neural Networks at \n", + "\n", + "6. Video on the back propagation algorithm at \n", + "\n", + "I also recommend Michael Nielsen's intuitive approach to the neural networks and the universal approximation theorem, see the slides at ." + ] + }, + { + "cell_type": "markdown", + "id": "76c6895d", + "metadata": { + "editable": true + }, + "source": [ + "## Material for the active learning sessions on Tuesday and Wednesday\n", + " * Exercise on starting to write a code for neural networks, feed forward part. We will also continue ur discussions of gradient descent methods from last week. If you have time, start considering the back-propagation part as well (exercises for next week)\n", + "\n", + " * Discussion of project 2\n", + "\n", + " \n", + "\n", + "**Note**: some of the codes will also be discussed next week in connection with the solution of differential equations." + ] + }, + { + "cell_type": "markdown", + "id": "ebb39354", + "metadata": { + "editable": true + }, + "source": [ + "## Writing a code which implements a feed-forward neural network\n", + "\n", + "Last week we discussed the basics of neural networks and deep learning\n", + "and the basics of automatic differentiation. We looked also at\n", + "examples on how compute the parameters of a simple network with scalar\n", + "inputs and ouputs and no or just one hidden layers.\n", + "\n", + "We ended our discussions with the derivation of the equations for a\n", + "neural network with one hidden layers and two input variables and two\n", + "hidden nodes but only one output node." + ] + }, + { + "cell_type": "markdown", + "id": "cfb26b1b", + "metadata": { + "editable": true + }, + "source": [ + "## Mathematics of deep learning\n", + "\n", + "**Two recent books online.**\n", + "\n", + "1. [The Modern Mathematics of Deep Learning, by Julius Berner, Philipp Grohs, Gitta Kutyniok, Philipp Petersen](https://arxiv.org/abs/2105.04026), published as [Mathematical Aspects of Deep Learning, pp. 1-111. Cambridge University Press, 2022](https://doi.org/10.1017/9781009025096.002)\n", + "\n", + "2. [Mathematical Introduction to Deep Learning: Methods, Implementations, and Theory, Arnulf Jentzen, Benno Kuckuck, Philippe von Wurstemberger](https://doi.org/10.48550/arXiv.2310.20360)" + ] + }, + { + "cell_type": "markdown", + "id": "28f60678", + "metadata": { + "editable": true + }, + "source": [ + "## Reminder on books with hands-on material and codes\n", + "* [Sebastian Rashcka et al, Machine learning with Sickit-Learn and PyTorch](https://sebastianraschka.com/blog/2022/ml-pytorch-book.html)" + ] + }, + { + "cell_type": "markdown", + "id": "3c7f8f61", + "metadata": { + "editable": true + }, + "source": [ + "## Reading recommendations\n", + "\n", + "1. Rashkca et al., chapter 11, jupyter-notebook sent separately, from [GitHub](https://github.com/rasbt/machine-learning-book)\n", + "\n", + "2. Goodfellow et al, chapter 6 and 7 contain most of the neural network background." + ] + }, + { + "cell_type": "markdown", + "id": "9ee5faa5", + "metadata": { + "editable": true + }, + "source": [ + "## First network example, simple percepetron with one input\n", + "\n", + "As yet another example we define now a simple perceptron model with\n", + "all quantities given by scalars. We consider only one input variable\n", + "$x$ and one target value $y$. We define an activation function\n", + "$\\sigma_1$ which takes as input" + ] + }, + { + "cell_type": "markdown", + "id": "e82fbb01", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1x+b_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1b4862d", + "metadata": { + "editable": true + }, + "source": [ + "where $w_1$ is the weight and $b_1$ is the bias. These are the\n", + "parameters we want to optimize. The output is $a_1=\\sigma(z_1)$ (see\n", + "graph from whiteboard notes). This output is then fed into the\n", + "**cost/loss** function, which we here for the sake of simplicity just\n", + "define as the squared error" + ] + }, + { + "cell_type": "markdown", + "id": "f7b41bcb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;w_1,b_1)=\\frac{1}{2}(a_1-y)^2.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2825a689", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with no hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "1853d23c", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the parameters\n", + "\n", + "In setting up the feed forward and back propagation parts of the\n", + "algorithm, we need now the derivative of the various variables we want\n", + "to train.\n", + "\n", + "We need" + ] + }, + { + "cell_type": "markdown", + "id": "1625a8c3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1} \\hspace{0.1cm}\\mathrm{and}\\hspace{0.1cm}\\frac{\\partial C}{\\partial b_1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7427a24a", + "metadata": { + "editable": true + }, + "source": [ + "Using the chain rule we find" + ] + }, + { + "cell_type": "markdown", + "id": "d4911a64", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_1-y)\\sigma_1'x,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0f290988", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "4cbbad95", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_1-y)\\sigma_1',\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cc8122a6", + "metadata": { + "editable": true + }, + "source": [ + "which we later will just define as" + ] + }, + { + "cell_type": "markdown", + "id": "39f03825", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3eeb7a29", + "metadata": { + "editable": true + }, + "source": [ + "## Adding a hidden layer\n", + "\n", + "We change our simple model to (see graph)\n", + "a network with just one hidden layer but with scalar variables only.\n", + "\n", + "Our output variable changes to $a_2$ and $a_1$ is now the output from the hidden node and $a_0=x$.\n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "33e1d35f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1a_0+b_1 \\hspace{0.1cm} \\wedge a_1 = \\sigma_1(z_1),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e846a441", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_2 = w_2a_1+b_2 \\hspace{0.1cm} \\wedge a_2 = \\sigma_2(z_2),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fbb3f1ff", + "metadata": { + "editable": true + }, + "source": [ + "and the cost function" + ] + }, + { + "cell_type": "markdown", + "id": "40200643", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;\\boldsymbol{\\Theta})=\\frac{1}{2}(a_2-y)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a2e96689", + "metadata": { + "editable": true + }, + "source": [ + "with $\\boldsymbol{\\Theta}=[w_1,w_2,b_1,b_2]$." + ] + }, + { + "cell_type": "markdown", + "id": "1a014316", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with one hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "06a0b720", + "metadata": { + "editable": true + }, + "source": [ + "## The derivatives\n", + "\n", + "The derivatives are now, using the chain rule again" + ] + }, + { + "cell_type": "markdown", + "id": "48581ce4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial w_2}=(a_2-y)\\sigma_2'a_1=\\delta_2a_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "58f46792", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial b_2}=(a_2-y)\\sigma_2'=\\delta_2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc5aa924", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_2-y)\\sigma_2'a_1\\sigma_1'a_0,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "407690af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_2-y)\\sigma_2'\\sigma_1'=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8f5cacad", + "metadata": { + "editable": true + }, + "source": [ + "Can you generalize this to more than one hidden layer?" + ] + }, + { + "cell_type": "markdown", + "id": "79f592c1", + "metadata": { + "editable": true + }, + "source": [ + "## Important observations\n", + "\n", + "From the above equations we see that the derivatives of the activation\n", + "functions play a central role. If they vanish, the training may\n", + "stop. This is called the vanishing gradient problem, see discussions below. If they become\n", + "large, the parameters $w_i$ and $b_i$ may simply go to infinity. This\n", + "is referenced as the exploding gradient problem." + ] + }, + { + "cell_type": "markdown", + "id": "412247f9", + "metadata": { + "editable": true + }, + "source": [ + "## The training\n", + "\n", + "The training of the parameters is done through various gradient descent approximations with" + ] + }, + { + "cell_type": "markdown", + "id": "83c09361", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}\\leftarrow w_{i}- \\eta \\delta_i a_{i-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d341a3c7", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2bb5b78f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_i \\leftarrow b_i-\\eta \\delta_i,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3d6558a8", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ is the learning rate.\n", + "\n", + "One iteration consists of one feed forward step and one back-propagation step. Each back-propagation step does one update of the parameters $\\boldsymbol{\\Theta}$.\n", + "\n", + "For the first hidden layer $a_{i-1}=a_0=x$ for this simple model." + ] + }, + { + "cell_type": "markdown", + "id": "f55c404e", + "metadata": { + "editable": true + }, + "source": [ + "## Code example\n", + "\n", + "The code here implements the above model with one hidden layer and\n", + "scalar variables for the same function we studied in the previous\n", + "example. The code is however set up so that we can add multiple\n", + "inputs $x$ and target values $y$. Note also that we have the\n", + "possibility of defining a feature matrix $\\boldsymbol{X}$ with more than just\n", + "one column for the input values. This will turn useful in our next example. We have also defined matrices and vectors for all of our operations although it is not necessary here." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "076950d8", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "# We use the Sigmoid function as activation function\n", + "def sigmoid(z):\n", + " return 1.0/(1.0+np.exp(-z))\n", + "\n", + "def forwardpropagation(x):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_1 = np.matmul(x, w_1) + b_1\n", + " # activation in the hidden layer\n", + " a_1 = sigmoid(z_1)\n", + " # weighted sum of inputs to the output layer\n", + " z_2 = np.matmul(a_1, w_2) + b_2\n", + " a_2 = z_2\n", + " return a_1, a_2\n", + "\n", + "def backpropagation(x, y):\n", + " a_1, a_2 = forwardpropagation(x)\n", + " # parameter delta for the output layer, note that a_2=z_2 and its derivative wrt z_2 is just 1\n", + " delta_2 = a_2 - y\n", + " print(0.5*((a_2-y)**2))\n", + " # delta for the hidden layer\n", + " delta_1 = np.matmul(delta_2, w_2.T) * a_1 * (1 - a_1)\n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_1.T, delta_2)\n", + " output_bias_gradient = np.sum(delta_2, axis=0)\n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(x.T, delta_1)\n", + " hidden_bias_gradient = np.sum(delta_1, axis=0)\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "# Input variable\n", + "x = np.array([4.0],dtype=np.float64)\n", + "# Target values\n", + "y = 2*x+1.0 \n", + "\n", + "# Defining the neural network, only scalars here\n", + "n_inputs = x.shape\n", + "n_features = 1\n", + "n_hidden_neurons = 1\n", + "n_outputs = 1\n", + "\n", + "# Initialize the network\n", + "# weights and bias in the hidden layer\n", + "w_1 = np.random.randn(n_features, n_hidden_neurons)\n", + "b_1 = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "w_2 = np.random.randn(n_hidden_neurons, n_outputs)\n", + "b_2 = np.zeros(n_outputs) + 0.01\n", + "\n", + "eta = 0.1\n", + "for i in range(50):\n", + " # calculate gradients\n", + " derivW2, derivB2, derivW1, derivB1 = backpropagation(x, y)\n", + " # update weights and biases\n", + " w_2 -= eta * derivW2\n", + " b_2 -= eta * derivB2\n", + " w_1 -= eta * derivW1\n", + " b_1 -= eta * derivB1" + ] + }, + { + "cell_type": "markdown", + "id": "b5a2150f", + "metadata": { + "editable": true + }, + "source": [ + "We see that after some few iterations (the results do depend on the learning rate however), we get an error which is rather small." + ] + }, + { + "cell_type": "markdown", + "id": "cb93f2d2", + "metadata": { + "editable": true + }, + "source": [ + "## Simple neural network and the back propagation equations\n", + "\n", + "Let us now try to increase our level of ambition and attempt at setting \n", + "up the equations for a neural network with two input nodes, one hidden\n", + "layer with two hidden nodes and one output layer with one output node/neuron only (see graph)..\n", + "\n", + "We need to define the following parameters and variables with the input layer (layer $(0)$) \n", + "where we label the nodes $x_0$ and $x_1$" + ] + }, + { + "cell_type": "markdown", + "id": "893b1b33", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "x_0 = a_0^{(0)} \\wedge x_1 = a_1^{(0)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1554902", + "metadata": { + "editable": true + }, + "source": [ + "The hidden layer (layer $(1)$) has nodes which yield the outputs $a_0^{(1)}$ and $a_1^{(1)}$) with weight $\\boldsymbol{w}$ and bias $\\boldsymbol{b}$ parameters" + ] + }, + { + "cell_type": "markdown", + "id": "e01cd011", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)}\\right\\} \\wedge b^{(1)}=\\left\\{b_0^{(1)},b_1^{(1)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "691e42c5", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with two input nodes, one hidden layer and one output node\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "57573a8a", + "metadata": { + "editable": true + }, + "source": [ + "## The ouput layer\n", + "\n", + "Finally, we have the ouput layer given by layer label $(2)$ with output $a^{(2)}$ and weights and biases to be determined given by the variables" + ] + }, + { + "cell_type": "markdown", + "id": "91ff8dfb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}=\\left\\{w_{0}^{(2)},w_{1}^{(2)}\\right\\} \\wedge b^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "315f787f", + "metadata": { + "editable": true + }, + "source": [ + "Our output is $\\tilde{y}=a^{(2)}$ and we define a generic cost function $C(a^{(2)},y;\\boldsymbol{\\Theta})$ where $y$ is the target value (a scalar here).\n", + "The parameters we need to optimize are given by" + ] + }, + { + "cell_type": "markdown", + "id": "612ebd67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\Theta}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)},w_{0}^{(2)},w_{1}^{(2)},b_0^{(1)},b_1^{(1)},b^{(2)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c28762dc", + "metadata": { + "editable": true + }, + "source": [ + "## Compact expressions\n", + "\n", + "We can define the inputs to the activation functions for the various layers in terms of various matrix-vector multiplications and vector additions.\n", + "The inputs to the first hidden layer are" + ] + }, + { + "cell_type": "markdown", + "id": "b4d0309d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}z_0^{(1)} \\\\ z_1^{(1)} \\end{bmatrix}=\\left(\\begin{bmatrix}w_{00}^{(1)} & w_{01}^{(1)}\\\\ w_{10}^{(1)} &w_{11}^{(1)} \\end{bmatrix}\\right)^{T}\\begin{bmatrix}a_0^{(0)} \\\\ a_1^{(0)} \\end{bmatrix}+\\begin{bmatrix}b_0^{(1)} \\\\ b_1^{(1)} \\end{bmatrix},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f3c715f1", + "metadata": { + "editable": true + }, + "source": [ + "with outputs" + ] + }, + { + "cell_type": "markdown", + "id": "5db82289", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}a_0^{(1)} \\\\ a_1^{(1)} \\end{bmatrix}=\\begin{bmatrix}\\sigma^{(1)}(z_0^{(1)}) \\\\ \\sigma^{(1)}(z_1^{(1)}) \\end{bmatrix}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6b2ad78", + "metadata": { + "editable": true + }, + "source": [ + "## Output layer\n", + "\n", + "For the final output layer we have the inputs to the final activation function" + ] + }, + { + "cell_type": "markdown", + "id": "dcefdba1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} = w_{0}^{(2)}a_0^{(1)} +w_{1}^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d554c6ce", + "metadata": { + "editable": true + }, + "source": [ + "resulting in the output" + ] + }, + { + "cell_type": "markdown", + "id": "651ff447", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a^{(2)}=\\sigma^{(2)}(z^{(2)}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f171ceaa", + "metadata": { + "editable": true + }, + "source": [ + "## Explicit derivatives\n", + "\n", + "In total we have nine parameters which we need to train. Using the\n", + "chain rule (or just the back-propagation algorithm) we can find all\n", + "derivatives. Since we will use automatic differentiation in reverse\n", + "mode, we start with the derivatives of the cost function with respect\n", + "to the parameters of the output layer, namely" + ] + }, + { + "cell_type": "markdown", + "id": "609bb2dd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{i}^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial w_{i}^{(2)}}=\\delta^{(2)}a_i^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "da1d696b", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "d21d62cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta^{(2)}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fb9dd90f", + "metadata": { + "editable": true + }, + "source": [ + "and finally" + ] + }, + { + "cell_type": "markdown", + "id": "9026fb2d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial b^{(2)}}=\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2d20d5d1", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives of the hidden layer\n", + "\n", + "Using the chain rule we have the following expressions for say one of the weight parameters (it is easy to generalize to the other weight parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "e6fbb9b5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}= \\delta^{(2)}\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "781a7ac8", + "metadata": { + "editable": true + }, + "source": [ + "which, noting that" + ] + }, + { + "cell_type": "markdown", + "id": "3ee09d8f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} =w_0^{(2)}a_0^{(1)}+w_1^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65f44692", + "metadata": { + "editable": true + }, + "source": [ + "allows us to rewrite" + ] + }, + { + "cell_type": "markdown", + "id": "0b84b7af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c138bd", + "metadata": { + "editable": true + }, + "source": [ + "## Final expression\n", + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "3f81bb3f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_0^{(1)}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}\\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eb6783b2", + "metadata": { + "editable": true + }, + "source": [ + "we have" + ] + }, + { + "cell_type": "markdown", + "id": "1c754dbb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\delta_0^{(1)}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e0b9760c", + "metadata": { + "editable": true + }, + "source": [ + "Similarly, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "b1efb446", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{01}^{(1)}}=\\delta_0^{(1)}a_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2cf7b43f", + "metadata": { + "editable": true + }, + "source": [ + "## Completing the list\n", + "\n", + "Similarly, we find" + ] + }, + { + "cell_type": "markdown", + "id": "262b517f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{10}^{(1)}}=\\delta_1^{(1)}a_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "59285e3f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2813790f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{11}^{(1)}}=\\delta_1^{(1)}a_1^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a56b94b4", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined" + ] + }, + { + "cell_type": "markdown", + "id": "a3ed9010", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_1^{(1)}=w_1^{(2)}\\frac{\\partial a_1^{(1)}}{\\partial z_1^{(1)}}\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "03a5562c", + "metadata": { + "editable": true + }, + "source": [ + "## Final expressions for the biases of the hidden layer\n", + "\n", + "For the sake of completeness, we list the derivatives of the biases, which are" + ] + }, + { + "cell_type": "markdown", + "id": "025bd04f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{0}^{(1)}}=\\delta_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1ef6c2f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "157d7580", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{1}^{(1)}}=\\delta_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "389a7e2d", + "metadata": { + "editable": true + }, + "source": [ + "As we will see below, these expressions can be generalized in a more compact form." + ] + }, + { + "cell_type": "markdown", + "id": "bccf9918", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient expressions\n", + "\n", + "For this specific model, with just one output node and two hidden\n", + "nodes, the gradient descent equations take the following form for output layer" + ] + }, + { + "cell_type": "markdown", + "id": "ab05945c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}\\leftarrow w_{i}^{(2)}- \\eta \\delta^{(2)} a_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cb2ef195", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "da672f61", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b^{(2)} \\leftarrow b^{(2)}-\\eta \\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "95dd3d2b", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "532b99a2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}\\leftarrow w_{ij}^{(1)}- \\eta \\delta_{i}^{(1)} a_{j}^{(0)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5d5f45cc", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2333cfb1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_{i}^{(1)} \\leftarrow b_{i}^{(1)}-\\eta \\delta_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4b555f81", + "metadata": { + "editable": true + }, + "source": [ + "where $\\eta$ is the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "20c0952f", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the equations for a neural network\n", + "\n", + "The questions we want to ask are how do changes in the biases and the\n", + "weights in our network change the cost function and how can we use the\n", + "final output to modify the weights and biases?\n", + "\n", + "To derive these equations let us start with a plain regression problem\n", + "and define our cost function as" + ] + }, + { + "cell_type": "markdown", + "id": "5a155f81", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ff1fc071", + "metadata": { + "editable": true + }, + "source": [ + "where the $y_i$s are our $n$ targets (the values we want to\n", + "reproduce), while the outputs of the network after having propagated\n", + "all inputs $\\boldsymbol{x}$ are given by $\\boldsymbol{\\tilde{y}}_i$." + ] + }, + { + "cell_type": "markdown", + "id": "63576478", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a neural network with three hidden layers (last later = $l=L=4$, first layer $l=0$)\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "3410ad89", + "metadata": { + "editable": true + }, + "source": [ + "## Definitions\n", + "\n", + "With our definition of the targets $\\boldsymbol{y}$, the outputs of the\n", + "network $\\boldsymbol{\\tilde{y}}$ and the inputs $\\boldsymbol{x}$ we\n", + "define now the activation $z_j^l$ of node/neuron/unit $j$ of the\n", + "$l$-th layer as a function of the bias, the weights which add up from\n", + "the previous layer $l-1$ and the forward passes/outputs\n", + "$\\boldsymbol{a}^{l-1}$ from the previous layer as" + ] + }, + { + "cell_type": "markdown", + "id": "c71d887c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^l = \\sum_{i=1}^{M_{l-1}}w_{ij}^la_i^{l-1}+b_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ffeae21c", + "metadata": { + "editable": true + }, + "source": [ + "where $b_k^l$ are the biases from layer $l$. Here $M_{l-1}$\n", + "represents the total number of nodes/neurons/units of layer $l-1$. The\n", + "figure in the whiteboard notes illustrates this equation. We can rewrite this in a more\n", + "compact form as the matrix-vector products we discussed earlier," + ] + }, + { + "cell_type": "markdown", + "id": "2fe917a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{z}^l = \\left(\\boldsymbol{W}^l\\right)^T\\boldsymbol{a}^{l-1}+\\boldsymbol{b}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65404bec", + "metadata": { + "editable": true + }, + "source": [ + "## Inputs to the activation function\n", + "\n", + "With the activation values $\\boldsymbol{z}^l$ we can in turn define the\n", + "output of layer $l$ as $\\boldsymbol{a}^l = \\sigma(\\boldsymbol{z}^l)$ where $\\sigma$ is our\n", + "activation function. In the examples here we will use the sigmoid\n", + "function discussed in our logistic regression lectures. We will also use the same activation function $\\sigma$ for all layers\n", + "and their nodes. It means we have" + ] + }, + { + "cell_type": "markdown", + "id": "a6c0c8b6", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_j^l = \\sigma(z_j^l) = \\frac{1}{1+\\exp{-(z_j^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2454faec", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of input to first hidden layer $l=1$ from input layer $l=0$\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "e5b67040", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives and the chain rule\n", + "\n", + "From the definition of the input variable to the activation function, that is $z_j^l$ we have" + ] + }, + { + "cell_type": "markdown", + "id": "aaec49a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial w_{ij}^l} = a_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e8ad40d3", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "e04a4d28", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial a_i^{l-1}} = w_{ji}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9b121a33", + "metadata": { + "editable": true + }, + "source": [ + "With our definition of the activation function we have that (note that this function depends only on $z_j^l$)" + ] + }, + { + "cell_type": "markdown", + "id": "3bf7d884", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^l}{\\partial z_j^{l}} = a_j^l(1-a_j^l)=\\sigma(z_j^l)(1-\\sigma(z_j^l)).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7d58918c", + "metadata": { + "editable": true + }, + "source": [ + "## Derivative of the cost function\n", + "\n", + "With these definitions we can now compute the derivative of the cost function in terms of the weights.\n", + "\n", + "Let us specialize to the output layer $l=L$. Our cost function is" + ] + }, + { + "cell_type": "markdown", + "id": "d21dce97", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}^L) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2=\\frac{1}{2}\\sum_{i=1}^n\\left(a_i^L - y_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc143bea", + "metadata": { + "editable": true + }, + "source": [ + "The derivative of this function with respect to the weights is" + ] + }, + { + "cell_type": "markdown", + "id": "49415a06", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4398e11e", + "metadata": { + "editable": true + }, + "source": [ + "The last partial derivative can easily be computed and reads (by applying the chain rule)" + ] + }, + { + "cell_type": "markdown", + "id": "da3fca7e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}} = \\frac{\\partial a_j^L}{\\partial z_{j}^{L}}\\frac{\\partial z_j^L}{\\partial w_{ij}^{L}}=a_j^L(1-a_j^L)a_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9055bc57", + "metadata": { + "editable": true + }, + "source": [ + "## The back propagation equations for a neural network\n", + "\n", + "We have thus" + ] + }, + { + "cell_type": "markdown", + "id": "c7995e73", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}((\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)a_j^L(1-a_j^L)a_i^{L-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d142f966", + "metadata": { + "editable": true + }, + "source": [ + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "d5dc5f9f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = a_j^L(1-a_j^L)\\left(a_j^L - y_j\\right) = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5f598e3e", + "metadata": { + "editable": true + }, + "source": [ + "and using the Hadamard product of two vectors we can write this as" + ] + }, + { + "cell_type": "markdown", + "id": "9769b50e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\delta}^L = \\sigma'(\\boldsymbol{z}^L)\\circ\\frac{\\partial {\\cal C}}{\\partial (\\boldsymbol{a}^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5a8851ae", + "metadata": { + "editable": true + }, + "source": [ + "## Analyzing the last results\n", + "\n", + "This is an important expression. The second term on the right handside\n", + "measures how fast the cost function is changing as a function of the $j$th\n", + "output activation. If, for example, the cost function doesn't depend\n", + "much on a particular output node $j$, then $\\delta_j^L$ will be small,\n", + "which is what we would expect. The first term on the right, measures\n", + "how fast the activation function $f$ is changing at a given activation\n", + "value $z_j^L$." + ] + }, + { + "cell_type": "markdown", + "id": "b455efff", + "metadata": { + "editable": true + }, + "source": [ + "## More considerations\n", + "\n", + "Notice that everything in the above equations is easily computed. In\n", + "particular, we compute $z_j^L$ while computing the behaviour of the\n", + "network, and it is only a small additional overhead to compute\n", + "$\\sigma'(z^L_j)$. The exact form of the derivative with respect to the\n", + "output depends on the form of the cost function.\n", + "However, provided the cost function is known there should be little\n", + "trouble in calculating" + ] + }, + { + "cell_type": "markdown", + "id": "8b430778", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7fb2cea5", + "metadata": { + "editable": true + }, + "source": [ + "With the definition of $\\delta_j^L$ we have a more compact definition of the derivative of the cost function in terms of the weights, namely" + ] + }, + { + "cell_type": "markdown", + "id": "6c77ac74", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "708f42bb", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives in terms of $z_j^L$\n", + "\n", + "It is also easy to see that our previous equation can be written as" + ] + }, + { + "cell_type": "markdown", + "id": "40f66bf5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L =\\frac{\\partial {\\cal C}}{\\partial z_j^L}= \\frac{\\partial {\\cal C}}{\\partial a_j^L}\\frac{\\partial a_j^L}{\\partial z_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21b9ebbe", + "metadata": { + "editable": true + }, + "source": [ + "which can also be interpreted as the partial derivative of the cost function with respect to the biases $b_j^L$, namely" + ] + }, + { + "cell_type": "markdown", + "id": "665ad548", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L}\\frac{\\partial b_j^L}{\\partial z_j^L}=\\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c182abd9", + "metadata": { + "editable": true + }, + "source": [ + "That is, the error $\\delta_j^L$ is exactly equal to the rate of change of the cost function as a function of the bias." + ] + }, + { + "cell_type": "markdown", + "id": "aa70c6cf", + "metadata": { + "editable": true + }, + "source": [ + "## Bringing it together\n", + "\n", + "We have now three equations that are essential for the computations of the derivatives of the cost function at the output layer. These equations are needed to start the algorithm and they are" + ] + }, + { + "cell_type": "markdown", + "id": "db460a07", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
\n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{W^L})}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1},\n", + "\\label{_auto1} \\tag{1}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3af036d6", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5662288a", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
\n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "\\label{_auto2} \\tag{2}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6a8a1ac", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "dda8fce0", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
\n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "\\label{_auto3} \\tag{3}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1957ab0", + "metadata": { + "editable": true + }, + "source": [ + "## Final back propagating equation\n", + "\n", + "We have that (replacing $L$ with a general layer $l$)" + ] + }, + { + "cell_type": "markdown", + "id": "31c8f2c9", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\frac{\\partial {\\cal C}}{\\partial z_j^l}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bba8d29e", + "metadata": { + "editable": true + }, + "source": [ + "We want to express this in terms of the equations for layer $l+1$." + ] + }, + { + "cell_type": "markdown", + "id": "af4922ec", + "metadata": { + "editable": true + }, + "source": [ + "## Using the chain rule and summing over all $k$ entries\n", + "\n", + "We obtain" + ] + }, + { + "cell_type": "markdown", + "id": "f43f0f87", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\frac{\\partial {\\cal C}}{\\partial z_k^{l+1}}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}}=\\sum_k \\delta_k^{l+1}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eba489e4", + "metadata": { + "editable": true + }, + "source": [ + "and recalling that" + ] + }, + { + "cell_type": "markdown", + "id": "82610f92", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^{l+1} = \\sum_{i=1}^{M_{l}}w_{ij}^{l+1}a_i^{l}+b_j^{l+1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "62513d62", + "metadata": { + "editable": true + }, + "source": [ + "with $M_l$ being the number of nodes in layer $l$, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "ca381ec8", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bdf32ad4", + "metadata": { + "editable": true + }, + "source": [ + "This is our final equation.\n", + "\n", + "We are now ready to set up the algorithm for back propagation and learning the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "764448ea", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm\n", + "\n", + "The four equations provide us with a way of computing the gradient of the cost function. Let us write this out in the form of an algorithm.\n", + "\n", + "**First**, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "**Secondly**, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=1,2,3,\\dots,L$.\n", + "\n", + "**Notation**: The first hidden layer has $l=1$ as label and the final output layer has $l=L$." + ] + }, + { + "cell_type": "markdown", + "id": "989c3082", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm, part 2\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "9d14949a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4ee118b1", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "ba89ad67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1f840c5", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the Back propagation algorithm, part 3\n", + "\n", + "Finally, we update the weights and the biases using gradient descent\n", + "for each $l=L-1,L-2,\\dots,1$ (the first hidden layer) and update the weights and biases\n", + "according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "9f06bcfc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7063f2be", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3e299445", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ being the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "28921878", + "metadata": { + "editable": true + }, + "source": [ + "## Updating the gradients\n", + "\n", + "With the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "90f5404c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c2dfbd", + "metadata": { + "editable": true + }, + "source": [ + "we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,1$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "03805799", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4f8f9c02", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9bf86f9c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "A property that characterizes a neural network, other than its\n", + "connectivity, is the choice of activation function(s). As described\n", + "in, the following restrictions are imposed on an activation function\n", + "for a FFNN to fulfill the universal approximation theorem\n", + "\n", + " * Non-constant\n", + "\n", + " * Bounded\n", + "\n", + " * Monotonically-increasing\n", + "\n", + " * Continuous" + ] + }, + { + "cell_type": "markdown", + "id": "eeaed73c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions, Logistic and Hyperbolic ones\n", + "\n", + "The second requirement excludes all linear functions. Furthermore, in\n", + "a MLP with only linear activation functions, each layer simply\n", + "performs a linear transformation of its inputs.\n", + "\n", + "Regardless of the number of layers, the output of the NN will be\n", + "nothing but a linear function of the inputs. Thus we need to introduce\n", + "some kind of non-linearity to the NN to be able to fit non-linear\n", + "functions Typical examples are the logistic *Sigmoid*" + ] + }, + { + "cell_type": "markdown", + "id": "0786aaf0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\frac{1}{1 + e^{-x}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "aa76601b", + "metadata": { + "editable": true + }, + "source": [ + "and the *hyperbolic tangent* function" + ] + }, + { + "cell_type": "markdown", + "id": "e1bca915", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\tanh(x)\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1832a8c4", + "metadata": { + "editable": true + }, + "source": [ + "### Relevance\n", + "\n", + "The *sigmoid* function are more biologically plausible because the\n", + "output of inactive neurons are zero. Such activation function are\n", + "called *one-sided*. However, it has been shown that the hyperbolic\n", + "tangent performs better than the sigmoid for training MLPs. has\n", + "become the most popular for *deep neural networks*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5c689736", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "\"\"\"The sigmoid function (or the logistic curve) is a \n", + "function that takes any real number, z, and outputs a number (0,1).\n", + "It is useful in neural networks for assigning weights on a relative scale.\n", + "The value z is the weighted sum of parameters involved in the learning algorithm.\"\"\"\n", + "\n", + "import numpy\n", + "import matplotlib.pyplot as plt\n", + "import math as mt\n", + "\n", + "z = numpy.arange(-5, 5, .1)\n", + "sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))\n", + "sigma = sigma_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, sigma)\n", + "ax.set_ylim([-0.1, 1.1])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sigmoid function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Step Function\"\"\"\n", + "z = numpy.arange(-5, 5, .02)\n", + "step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)\n", + "step = step_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, step)\n", + "ax.set_ylim([-0.5, 1.5])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('step function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Sine Function\"\"\"\n", + "z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)\n", + "t = numpy.sin(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, t)\n", + "ax.set_ylim([-1.0, 1.0])\n", + "ax.set_xlim([-2*mt.pi,2*mt.pi])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sine function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Plots a graph of the squashing function used by a rectified linear\n", + "unit\"\"\"\n", + "z = numpy.arange(-2, 2, .1)\n", + "zero = numpy.zeros(len(z))\n", + "y = numpy.max([zero, z], axis=0)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, y)\n", + "ax.set_ylim([-2.0, 2.0])\n", + "ax.set_xlim([-2.0, 2.0])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('Rectified linear unit')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "0b3a4c95", + "metadata": { + "editable": true + }, + "source": [ + "## Fine-tuning neural network hyperparameters\n", + "\n", + "The flexibility of neural networks is also one of their main\n", + "drawbacks: there are many hyperparameters to tweak. Not only can you\n", + "use any imaginable network topology (how neurons/nodes are\n", + "interconnected), but even in a simple FFNN you can change the number\n", + "of layers, the number of neurons per layer, the type of activation\n", + "function to use in each layer, the weight initialization logic, the\n", + "stochastic gradient optmized and much more. How do you know what\n", + "combination of hyperparameters is the best for your task?\n", + "\n", + "* You can use grid search with cross-validation to find the right hyperparameters.\n", + "\n", + "However,since there are many hyperparameters to tune, and since\n", + "training a neural network on a large dataset takes a lot of time, you\n", + "will only be able to explore a tiny part of the hyperparameter space.\n", + "\n", + "* You can use randomized search.\n", + "\n", + "* Or use tools like [Oscar](http://oscar.calldesk.ai/), which implements more complex algorithms to help you find a good set of hyperparameters quickly." + ] + }, + { + "cell_type": "markdown", + "id": "9955a636", + "metadata": { + "editable": true + }, + "source": [ + "## Hidden layers\n", + "\n", + "For many problems you can start with just one or two hidden layers and\n", + "it will work just fine. For the MNIST data set you ca easily get a\n", + "high accuracy using just one hidden layer with a few hundred neurons.\n", + "You can reach for this data set above 98% accuracy using two hidden\n", + "layers with the same total amount of neurons, in roughly the same\n", + "amount of training time.\n", + "\n", + "For more complex problems, you can gradually ramp up the number of\n", + "hidden layers, until you start overfitting the training set. Very\n", + "complex tasks, such as large image classification or speech\n", + "recognition, typically require networks with dozens of layers and they\n", + "need a huge amount of training data. However, you will rarely have to\n", + "train such networks from scratch: it is much more common to reuse\n", + "parts of a pretrained state-of-the-art network that performs a similar\n", + "task." + ] + }, + { + "cell_type": "markdown", + "id": "f1aa77e9", + "metadata": { + "editable": true + }, + "source": [ + "## Vanishing gradients\n", + "\n", + "The Back propagation algorithm we derived above works by going from\n", + "the output layer to the input layer, propagating the error gradient on\n", + "the way. Once the algorithm has computed the gradient of the cost\n", + "function with regards to each parameter in the network, it uses these\n", + "gradients to update each parameter with a Gradient Descent (GD) step.\n", + "\n", + "Unfortunately for us, the gradients often get smaller and smaller as\n", + "the algorithm progresses down to the first hidden layers. As a result,\n", + "the GD update leaves the lower layer connection weights virtually\n", + "unchanged, and training never converges to a good solution. This is\n", + "known in the literature as **the vanishing gradients problem**." + ] + }, + { + "cell_type": "markdown", + "id": "3703bb33", + "metadata": { + "editable": true + }, + "source": [ + "## Exploding gradients\n", + "\n", + "In other cases, the opposite can happen, namely the the gradients can\n", + "grow bigger and bigger. The result is that many of the layers get\n", + "large updates of the weights the algorithm diverges. This is the\n", + "**exploding gradients problem**, which is mostly encountered in\n", + "recurrent neural networks. More generally, deep neural networks suffer\n", + "from unstable gradients, different layers may learn at widely\n", + "different speeds" + ] + }, + { + "cell_type": "markdown", + "id": "43b1aa26", + "metadata": { + "editable": true + }, + "source": [ + "## Is the Logistic activation function (Sigmoid) our choice?\n", + "\n", + "Although this unfortunate behavior has been empirically observed for\n", + "quite a while (it was one of the reasons why deep neural networks were\n", + "mostly abandoned for a long time), it is only around 2010 that\n", + "significant progress was made in understanding it.\n", + "\n", + "A paper titled [Understanding the Difficulty of Training Deep\n", + "Feedforward Neural Networks by Xavier Glorot and Yoshua Bengio](http://proceedings.mlr.press/v9/glorot10a.html) found that\n", + "the problems with the popular logistic\n", + "sigmoid activation function and the weight initialization technique\n", + "that was most popular at the time, namely random initialization using\n", + "a normal distribution with a mean of 0 and a standard deviation of\n", + "1." + ] + }, + { + "cell_type": "markdown", + "id": "463f4f64", + "metadata": { + "editable": true + }, + "source": [ + "## Logistic function as the root of problems\n", + "\n", + "They showed that with this activation function and this\n", + "initialization scheme, the variance of the outputs of each layer is\n", + "much greater than the variance of its inputs. Going forward in the\n", + "network, the variance keeps increasing after each layer until the\n", + "activation function saturates at the top layers. This is actually made\n", + "worse by the fact that the logistic function has a mean of 0.5, not 0\n", + "(the hyperbolic tangent function has a mean of 0 and behaves slightly\n", + "better than the logistic function in deep networks)." + ] + }, + { + "cell_type": "markdown", + "id": "6c9ea582", + "metadata": { + "editable": true + }, + "source": [ + "## The derivative of the Logistic funtion\n", + "\n", + "Looking at the logistic activation function, when inputs become large\n", + "(negative or positive), the function saturates at 0 or 1, with a\n", + "derivative extremely close to 0. Thus when backpropagation kicks in,\n", + "it has virtually no gradient to propagate back through the network,\n", + "and what little gradient exists keeps getting diluted as\n", + "backpropagation progresses down through the top layers, so there is\n", + "really nothing left for the lower layers.\n", + "\n", + "In their paper, Glorot and Bengio propose a way to significantly\n", + "alleviate this problem. We need the signal to flow properly in both\n", + "directions: in the forward direction when making predictions, and in\n", + "the reverse direction when backpropagating gradients. We don’t want\n", + "the signal to die out, nor do we want it to explode and saturate. For\n", + "the signal to flow properly, the authors argue that we need the\n", + "variance of the outputs of each layer to be equal to the variance of\n", + "its inputs, and we also need the gradients to have equal variance\n", + "before and after flowing through a layer in the reverse direction." + ] + }, + { + "cell_type": "markdown", + "id": "80c83d2c", + "metadata": { + "editable": true + }, + "source": [ + "## Insights from the paper by Glorot and Bengio\n", + "\n", + "One of the insights in the 2010 paper by Glorot and Bengio was that\n", + "the vanishing/exploding gradients problems were in part due to a poor\n", + "choice of activation function. Until then most people had assumed that\n", + "if Nature had chosen to use roughly sigmoid activation functions in\n", + "biological neurons, they must be an excellent choice. But it turns out\n", + "that other activation functions behave much better in deep neural\n", + "networks, in particular the ReLU activation function, mostly because\n", + "it does not saturate for positive values (and also because it is quite\n", + "fast to compute)." + ] + }, + { + "cell_type": "markdown", + "id": "55a1ad5d", + "metadata": { + "editable": true + }, + "source": [ + "## The RELU function family\n", + "\n", + "The ReLU activation function suffers from a problem known as the dying\n", + "ReLUs: during training, some neurons effectively die, meaning they\n", + "stop outputting anything other than 0.\n", + "\n", + "In some cases, you may find that half of your network’s neurons are\n", + "dead, especially if you used a large learning rate. During training,\n", + "if a neuron’s weights get updated such that the weighted sum of the\n", + "neuron’s inputs is negative, it will start outputting 0. When this\n", + "happen, the neuron is unlikely to come back to life since the gradient\n", + "of the ReLU function is 0 when its input is negative." + ] + }, + { + "cell_type": "markdown", + "id": "b7fafe4a", + "metadata": { + "editable": true + }, + "source": [ + "## ELU function\n", + "\n", + "To solve this problem, nowadays practitioners use a variant of the\n", + "ReLU function, such as the leaky ReLU discussed above or the so-called\n", + "exponential linear unit (ELU) function" + ] + }, + { + "cell_type": "markdown", + "id": "46e10153", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "ELU(z) = \\left\\{\\begin{array}{cc} \\alpha\\left( \\exp{(z)}-1\\right) & z < 0,\\\\ z & z \\ge 0.\\end{array}\\right.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0930ba50", + "metadata": { + "editable": true + }, + "source": [ + "## Which activation function should we use?\n", + "\n", + "In general it seems that the ELU activation function is better than\n", + "the leaky ReLU function (and its variants), which is better than\n", + "ReLU. ReLU performs better than $\\tanh$ which in turn performs better\n", + "than the logistic function.\n", + "\n", + "If runtime performance is an issue, then you may opt for the leaky\n", + "ReLU function over the ELU function If you don’t want to tweak yet\n", + "another hyperparameter, you may just use the default $\\alpha$ of\n", + "$0.01$ for the leaky ReLU, and $1$ for ELU. If you have spare time and\n", + "computing power, you can use cross-validation or bootstrap to evaluate\n", + "other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "5c0c59af", + "metadata": { + "editable": true + }, + "source": [ + "## More on activation functions, output layers\n", + "\n", + "In most cases you can use the ReLU activation function in the hidden\n", + "layers (or one of its variants).\n", + "\n", + "It is a bit faster to compute than other activation functions, and the\n", + "gradient descent optimization does in general not get stuck.\n", + "\n", + "**For the output layer:**\n", + "\n", + "* For classification the softmax activation function is generally a good choice for classification tasks (when the classes are mutually exclusive).\n", + "\n", + "* For regression tasks, you can simply use no activation function at all." + ] + }, + { + "cell_type": "markdown", + "id": "582e4df4", + "metadata": { + "editable": true + }, + "source": [ + "## Batch Normalization\n", + "\n", + "Batch Normalization aims to address the vanishing/exploding gradients\n", + "problems, and more generally the problem that the distribution of each\n", + "layer’s inputs changes during training, as the parameters of the\n", + "previous layers change.\n", + "\n", + "The technique consists of adding an operation in the model just before\n", + "the activation function of each layer, simply zero-centering and\n", + "normalizing the inputs, then scaling and shifting the result using two\n", + "new parameters per layer (one for scaling, the other for shifting). In\n", + "other words, this operation lets the model learn the optimal scale and\n", + "mean of the inputs for each layer. In order to zero-center and\n", + "normalize the inputs, the algorithm needs to estimate the inputs’ mean\n", + "and standard deviation. It does so by evaluating the mean and standard\n", + "deviation of the inputs over the current mini-batch, from this the\n", + "name batch normalization." + ] + }, + { + "cell_type": "markdown", + "id": "ea360013", + "metadata": { + "editable": true + }, + "source": [ + "## Dropout\n", + "\n", + "It is a fairly simple algorithm: at every training step, every neuron\n", + "(including the input neurons but excluding the output neurons) has a\n", + "probability $p$ of being temporarily dropped out, meaning it will be\n", + "entirely ignored during this training step, but it may be active\n", + "during the next step.\n", + "\n", + "The hyperparameter $p$ is called the dropout rate, and it is typically\n", + "set to 50%. After training, the neurons are not dropped anymore. It\n", + "is viewed as one of the most popular regularization techniques." + ] + }, + { + "cell_type": "markdown", + "id": "fee98b12", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient Clipping\n", + "\n", + "A popular technique to lessen the exploding gradients problem is to\n", + "simply clip the gradients during backpropagation so that they never\n", + "exceed some threshold (this is mostly useful for recurrent neural\n", + "networks).\n", + "\n", + "This technique is called Gradient Clipping.\n", + "\n", + "In general however, Batch\n", + "Normalization is preferred." + ] + }, + { + "cell_type": "markdown", + "id": "c9f175b0", + "metadata": { + "editable": true + }, + "source": [ + "## A top-down perspective on Neural networks\n", + "\n", + "The first thing we would like to do is divide the data into two or\n", + "three parts. A training set, a validation or dev (development) set,\n", + "and a test set. The test set is the data on which we want to make\n", + "predictions. The dev set is a subset of the training data we use to\n", + "check how well we are doing out-of-sample, after training the model on\n", + "the training dataset. We use the validation error as a proxy for the\n", + "test error in order to make tweaks to our model. It is crucial that we\n", + "do not use any of the test data to train the algorithm. This is a\n", + "cardinal sin in ML. Then:\n", + "\n", + "1. Estimate optimal error rate\n", + "\n", + "2. Minimize underfitting (bias) on training data set.\n", + "\n", + "3. Make sure you are not overfitting." + ] + }, + { + "cell_type": "markdown", + "id": "f6f04fbb", + "metadata": { + "editable": true + }, + "source": [ + "## More top-down perspectives\n", + "\n", + "If the validation and test sets are drawn from the same distributions,\n", + "then a good performance on the validation set should lead to similarly\n", + "good performance on the test set. \n", + "\n", + "However, sometimes\n", + "the training data and test data differ in subtle ways because, for\n", + "example, they are collected using slightly different methods, or\n", + "because it is cheaper to collect data in one way versus another. In\n", + "this case, there can be a mismatch between the training and test\n", + "data. This can lead to the neural network overfitting these small\n", + "differences between the test and training sets, and a poor performance\n", + "on the test set despite having a good performance on the validation\n", + "set. To rectify this, Andrew Ng suggests making two validation or dev\n", + "sets, one constructed from the training data and one constructed from\n", + "the test data. The difference between the performance of the algorithm\n", + "on these two validation sets quantifies the train-test mismatch. This\n", + "can serve as another important diagnostic when using DNNs for\n", + "supervised learning." + ] + }, + { + "cell_type": "markdown", + "id": "d4184eee", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of supervised learning with deep networks\n", + "\n", + "Like all statistical methods, supervised learning using neural\n", + "networks has important limitations. This is especially important when\n", + "one seeks to apply these methods, especially to physics problems. Like\n", + "all tools, DNNs are not a universal solution. Often, the same or\n", + "better performance on a task can be achieved by using a few\n", + "hand-engineered features (or even a collection of random\n", + "features)." + ] + }, + { + "cell_type": "markdown", + "id": "82d314da", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of NNs\n", + "\n", + "Here we list some of the important limitations of supervised neural network based models. \n", + "\n", + "* **Need labeled data**. All supervised learning methods, DNNs for supervised learning require labeled data. Often, labeled data is harder to acquire than unlabeled data (e.g. one must pay for human experts to label images).\n", + "\n", + "* **Supervised neural networks are extremely data intensive.** DNNs are data hungry. They perform best when data is plentiful. This is doubly so for supervised methods where the data must also be labeled. The utility of DNNs is extremely limited if data is hard to acquire or the datasets are small (hundreds to a few thousand samples). In this case, the performance of other methods that utilize hand-engineered features can exceed that of DNNs." + ] + }, + { + "cell_type": "markdown", + "id": "abc6640b", + "metadata": { + "editable": true + }, + "source": [ + "## Homogeneous data\n", + "\n", + "* **Homogeneous data.** Almost all DNNs deal with homogeneous data of one type. It is very hard to design architectures that mix and match data types (i.e. some continuous variables, some discrete variables, some time series). In applications beyond images, video, and language, this is often what is required. In contrast, ensemble models like random forests or gradient-boosted trees have no difficulty handling mixed data types." + ] + }, + { + "cell_type": "markdown", + "id": "bb7d1f89", + "metadata": { + "editable": true + }, + "source": [ + "## More limitations\n", + "\n", + "* **Many problems are not about prediction.** In natural science we are often interested in learning something about the underlying distribution that generates the data. In this case, it is often difficult to cast these ideas in a supervised learning setting. While the problems are related, it is possible to make good predictions with a *wrong* model. The model might or might not be useful for understanding the underlying science.\n", + "\n", + "Some of these remarks are particular to DNNs, others are shared by all supervised learning methods. This motivates the use of unsupervised methods which in part circumvent these problems." + ] + }, + { + "cell_type": "markdown", + "id": "442b1b5e", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back-propagation algorithm\n", + "\n", + "Let us write this out in the form of an algorithm.\n", + "\n", + "First, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "Secondly, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=2,3,\\dots,L$.\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "0005e340", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = f'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2b27751b", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,2$ as" + ] + }, + { + "cell_type": "markdown", + "id": "dd544b4b", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "57a7d213", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,2$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "932510f4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bf80ed99", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f682bf76", + "metadata": { + "editable": true + }, + "source": [ + "The parameter $\\eta$ is the learning parameter discussed in connection with the gradient descent methods.\n", + "Here it is convenient to use stochastic gradient descent (see the examples below) with mini-batches with an outer loop that steps through multiple epochs of training." + ] + }, + { + "cell_type": "markdown", + "id": "ad2b26a4", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up a Multi-layer perceptron model for classification\n", + "\n", + "We are now gong to develop an example based on the MNIST data\n", + "base. This is a classification problem and we need to use our\n", + "cross-entropy function we discussed in connection with logistic\n", + "regression. The cross-entropy defines our cost function for the\n", + "classificaton problems with neural networks.\n", + "\n", + "In binary classification with two classes $(0, 1)$ we define the\n", + "logistic/sigmoid function as the probability that a particular input\n", + "is in class $0$ or $1$. This is possible because the logistic\n", + "function takes any input from the real numbers and inputs a number\n", + "between 0 and 1, and can therefore be interpreted as a probability. It\n", + "also has other nice properties, such as a derivative that is simple to\n", + "calculate.\n", + "\n", + "For an input $\\boldsymbol{a}$ from the hidden layer, the probability that the input $\\boldsymbol{x}$\n", + "is in class 0 or 1 is just. We let $\\theta$ represent the unknown weights and biases to be adjusted by our equations). The variable $x$\n", + "represents our activation values $z$. We have" + ] + }, + { + "cell_type": "markdown", + "id": "a08331b2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = \\frac{1}{1 + \\exp{(- \\boldsymbol{x}})} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9ebfde52", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "531dfa25", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 1 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = 1 - P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8941d38c", + "metadata": { + "editable": true + }, + "source": [ + "where $y \\in \\{0, 1\\}$ and $\\boldsymbol{\\theta}$ represents the weights and biases\n", + "of our network." + ] + }, + { + "cell_type": "markdown", + "id": "7ae7e222", + "metadata": { + "editable": true + }, + "source": [ + "## Defining the cost function\n", + "\n", + "Our cost function is given as (see the Logistic regression lectures)" + ] + }, + { + "cell_type": "markdown", + "id": "cbb157cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\ln P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = - \\sum_{i=1}^n\n", + "y_i \\ln[P(y_i = 0)] + (1 - y_i) \\ln [1 - P(y_i = 0)] = \\sum_{i=1}^n \\mathcal{L}_i(\\boldsymbol{\\theta}) .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0178770c", + "metadata": { + "editable": true + }, + "source": [ + "This last equality means that we can interpret our *cost* function as a sum over the *loss* function\n", + "for each point in the dataset $\\mathcal{L}_i(\\boldsymbol{\\theta})$. \n", + "The negative sign is just so that we can think about our algorithm as minimizing a positive number, rather\n", + "than maximizing a negative number. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$ and\n", + "\n", + "$y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset (numbers from $0$ to $9$).. \n", + "\n", + "If $\\boldsymbol{x}_i$ is the $i$-th input (image), $y_{ic}$ refers to the $c$-th component of the $i$-th\n", + "output vector $\\boldsymbol{y}_i$. \n", + "The probability of $\\boldsymbol{x}_i$ being in class $c$ will be given by the softmax function:" + ] + }, + { + "cell_type": "markdown", + "id": "cb69f3df", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y_{ic} = 1 \\mid \\boldsymbol{x}_i, \\boldsymbol{\\theta}) = \\frac{\\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_c)}}\n", + "{\\sum_{c'=0}^{C-1} \\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_{c'})}} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "11aa1335", + "metadata": { + "editable": true + }, + "source": [ + "which reduces to the logistic function in the binary case. \n", + "The likelihood of this $C$-class classifier\n", + "is now given as:" + ] + }, + { + "cell_type": "markdown", + "id": "a225e57a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = \\prod_{i=1}^n \\prod_{c=0}^{C-1} [P(y_{ic} = 1)]^{y_{ic}} .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "569dd3f2", + "metadata": { + "editable": true + }, + "source": [ + "Again we take the negative log-likelihood to define our cost function:" + ] + }, + { + "cell_type": "markdown", + "id": "f8e84cae", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\log{P(\\mathcal{D} \\mid \\boldsymbol{\\theta})}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1dd303e8", + "metadata": { + "editable": true + }, + "source": [ + "See the logistic regression lectures for a full definition of the cost function.\n", + "\n", + "The back propagation equations need now only a small change, namely the definition of a new cost function. We are thus ready to use the same equations as before!" + ] + }, + { + "cell_type": "markdown", + "id": "33494270", + "metadata": { + "editable": true + }, + "source": [ + "## Example: binary classification problem\n", + "\n", + "As an example of the above, relevant for project 2 as well, let us consider a binary class. As discussed in our logistic regression lectures, we defined a cost function in terms of the parameters $\\beta$ as" + ] + }, + { + "cell_type": "markdown", + "id": "01bd6a05", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\beta}) = - \\sum_{i=1}^n \\left(y_i\\log{p(y_i \\vert x_i,\\boldsymbol{\\beta})}+(1-y_i)\\log{1-p(y_i \\vert x_i,\\boldsymbol{\\beta})}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "60f16a47", + "metadata": { + "editable": true + }, + "source": [ + "where we had defined the logistic (sigmoid) function" + ] + }, + { + "cell_type": "markdown", + "id": "ab0c42b3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =1\\vert x_i,\\boldsymbol{\\beta})=\\frac{\\exp{(\\beta_0+\\beta_1 x_i)}}{1+\\exp{(\\beta_0+\\beta_1 x_i)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dcfb2e28", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5076b392", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =0\\vert x_i,\\boldsymbol{\\beta})=1-p(y_i =1\\vert x_i,\\boldsymbol{\\beta}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9d6001f4", + "metadata": { + "editable": true + }, + "source": [ + "The parameters $\\boldsymbol{\\beta}$ were defined using a minimization method like gradient descent or Newton-Raphson's method. \n", + "\n", + "Now we replace $x_i$ with the activation $z_i^l$ for a given layer $l$ and the outputs as $y_i=a_i^l=f(z_i^l)$, with $z_i^l$ now being a function of the weights $w_{ij}^l$ and biases $b_i^l$. \n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "d0245c18", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_i^l = y_i = \\frac{\\exp{(z_i^l)}}{1+\\exp{(z_i^l)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "030ac014", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "bdc01c83", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_i^l = \\sum_{j}w_{ij}^l a_j^{l-1}+b_i^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1a77b25c", + "metadata": { + "editable": true + }, + "source": [ + "where the superscript $l-1$ indicates that these are the outputs from layer $l-1$.\n", + "Our cost function at the final layer $l=L$ is now" + ] + }, + { + "cell_type": "markdown", + "id": "1f169ed1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{W}) = - \\sum_{i=1}^n \\left(t_i\\log{a_i^L}+(1-t_i)\\log{(1-a_i^L)}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "6bc460e2", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined the targets $t_i$. The derivatives of the cost function with respect to the output $a_i^L$ are then easily calculated and we get" + ] + }, + { + "cell_type": "markdown", + "id": "fe1f92c0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial \\mathcal{C}(\\boldsymbol{W})}{\\partial a_i^L} = \\frac{a_i^L-t_i}{a_i^L(1-a_i^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "78cf6843", + "metadata": { + "editable": true + }, + "source": [ + "In case we use another activation function than the logistic one, we need to evaluate other derivatives." + ] + }, + { + "cell_type": "markdown", + "id": "81ed1ccc", + "metadata": { + "editable": true + }, + "source": [ + "## The Softmax function\n", + "In case we employ the more general case given by the Softmax equation, we need to evaluate the derivative of the activation function with respect to the activation $z_i^l$, that is we need" + ] + }, + { + "cell_type": "markdown", + "id": "2a16cf53", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial w_{jk}^l} =\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l} \\frac{\\partial z_j^l}{\\partial w_{jk}^l}= \\frac{\\partial f(z_i^l)}{\\partial z_j^l}a_k^{l-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21988141", + "metadata": { + "editable": true + }, + "source": [ + "For the Softmax function we have" + ] + }, + { + "cell_type": "markdown", + "id": "b37cc0cd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "f(z_i^l) = \\frac{\\exp{(z_i^l)}}{\\sum_{m=1}^K\\exp{(z_m^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "259618c5", + "metadata": { + "editable": true + }, + "source": [ + "Its derivative with respect to $z_j^l$ gives" + ] + }, + { + "cell_type": "markdown", + "id": "af5a331e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l}= f(z_i^l)\\left(\\delta_{ij}-f(z_j^l)\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "208ab286", + "metadata": { + "editable": true + }, + "source": [ + "which in case of the simply binary model reduces to having $i=j$." + ] + }, + { + "cell_type": "markdown", + "id": "8f30fbc3", + "metadata": { + "editable": true + }, + "source": [ + "## Developing a code for doing neural networks with back propagation\n", + "\n", + "One can identify a set of key steps when using neural networks to solve supervised learning problems: \n", + "\n", + "1. Collect and pre-process data \n", + "\n", + "2. Define model and architecture \n", + "\n", + "3. Choose cost function and optimizer \n", + "\n", + "4. Train the model \n", + "\n", + "5. Evaluate model performance on test data \n", + "\n", + "6. Adjust hyperparameters (if necessary, network architecture)" + ] + }, + { + "cell_type": "markdown", + "id": "09538ef9", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Here we will be using the MNIST dataset, which is readily available through the **scikit-learn**\n", + "package. You may also find it for example [here](http://yann.lecun.com/exdb/mnist/). \n", + "The *MNIST* (Modified National Institute of Standards and Technology) database is a large database\n", + "of handwritten digits that is commonly used for training various image processing systems. \n", + "The MNIST dataset consists of 70 000 images of size $28\\times 28$ pixels, each labeled from 0 to 9. \n", + "The scikit-learn dataset we will use consists of a selection of 1797 images of size $8\\times 8$ collected and processed from this database. \n", + "\n", + "To feed data into a feed-forward neural network we need to represent\n", + "the inputs as a design/feature matrix $X = (n_{inputs}, n_{features})$. Each\n", + "row represents an *input*, in this case a handwritten digit, and\n", + "each column represents a *feature*, in this case a pixel. The\n", + "correct answers, also known as *labels* or *targets* are\n", + "represented as a 1D array of integers \n", + "$Y = (n_{inputs}) = (5, 3, 1, 8,...)$.\n", + "\n", + "As an example, say we want to build a neural network using supervised learning to predict Body-Mass Index (BMI) from\n", + "measurements of height (in m) \n", + "and weight (in kg). If we have measurements of 5 people the design/feature matrix could be for example: \n", + "\n", + "$$ X = \\begin{bmatrix}\n", + "1.85 & 81\\\\\n", + "1.71 & 65\\\\\n", + "1.95 & 103\\\\\n", + "1.55 & 42\\\\\n", + "1.63 & 56\n", + "\\end{bmatrix} ,$$ \n", + "\n", + "and the targets would be: \n", + "\n", + "$$ Y = (23.7, 22.2, 27.1, 17.5, 21.1) $$ \n", + "\n", + "Since each input image is a 2D matrix, we need to flatten the image\n", + "(i.e. \"unravel\" the 2D matrix into a 1D array) to turn the data into a\n", + "design/feature matrix. This means we lose all spatial information in the\n", + "image, such as locality and translational invariance. More complicated\n", + "architectures such as Convolutional Neural Networks can take advantage\n", + "of such information, and are most commonly applied when analyzing\n", + "images." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ced37e42", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "ebabb274", + "metadata": { + "editable": true + }, + "source": [ + "## Train and test datasets\n", + "\n", + "Performing analysis before partitioning the dataset is a major error, that can lead to incorrect conclusions. \n", + "\n", + "We will reserve $80 \\%$ of our dataset for training and $20 \\%$ for testing. \n", + "\n", + "It is important that the train and test datasets are drawn randomly from our dataset, to ensure\n", + "no bias in the sampling. \n", + "Say you are taking measurements of weather data to predict the weather in the coming 5 days.\n", + "You don't want to train your model on measurements taken from the hours 00.00 to 12.00, and then test it on data\n", + "collected from 12.00 to 24.00." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2c87b9f9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-liner from scikit-learn library\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)\n", + "\n", + "# equivalently in numpy\n", + "def train_test_split_numpy(inputs, labels, train_size, test_size):\n", + " n_inputs = len(inputs)\n", + " inputs_shuffled = inputs.copy()\n", + " labels_shuffled = labels.copy()\n", + " \n", + " np.random.shuffle(inputs_shuffled)\n", + " np.random.shuffle(labels_shuffled)\n", + " \n", + " train_end = int(n_inputs*train_size)\n", + " X_train, X_test = inputs_shuffled[:train_end], inputs_shuffled[train_end:]\n", + " Y_train, Y_test = labels_shuffled[:train_end], labels_shuffled[train_end:]\n", + " \n", + " return X_train, X_test, Y_train, Y_test\n", + "\n", + "#X_train, X_test, Y_train, Y_test = train_test_split_numpy(inputs, labels, train_size, test_size)\n", + "\n", + "print(\"Number of training images: \" + str(len(X_train)))\n", + "print(\"Number of test images: \" + str(len(X_test)))" + ] + }, + { + "cell_type": "markdown", + "id": "0c186fec", + "metadata": { + "editable": true + }, + "source": [ + "## Define model and architecture\n", + "\n", + "Our simple feed-forward neural network will consist of an *input* layer, a single *hidden* layer and an *output* layer. The activation $y$ of each neuron is a weighted sum of inputs, passed through an activation function. In case of the simple perceptron model we have \n", + "\n", + "$$ z = \\sum_{i=1}^n w_i a_i ,$$\n", + "\n", + "$$ y = f(z) ,$$\n", + "\n", + "where $f$ is the activation function, $a_i$ represents input from neuron $i$ in the preceding layer\n", + "and $w_i$ is the weight to input $i$. \n", + "The activation of the neurons in the input layer is just the features (e.g. a pixel value). \n", + "\n", + "The simplest activation function for a neuron is the *Heaviside* function:\n", + "\n", + "$$ f(z) = \n", + "\\begin{cases}\n", + "1, & z > 0\\\\\n", + "0, & \\text{otherwise}\n", + "\\end{cases}\n", + "$$\n", + "\n", + "A feed-forward neural network with this activation is known as a *perceptron*. \n", + "For a binary classifier (i.e. two classes, 0 or 1, dog or not-dog) we can also use this in our output layer. \n", + "This activation can be generalized to $k$ classes (using e.g. the *one-against-all* strategy), \n", + "and we call these architectures *multiclass perceptrons*. \n", + "\n", + "However, it is now common to use the terms Single Layer Perceptron (SLP) (1 hidden layer) and \n", + "Multilayer Perceptron (MLP) (2 or more hidden layers) to refer to feed-forward neural networks with any activation function. \n", + "\n", + "Typical choices for activation functions include the sigmoid function, hyperbolic tangent, and Rectified Linear Unit (ReLU). \n", + "We will be using the sigmoid function $\\sigma(x)$: \n", + "\n", + "$$ f(x) = \\sigma(x) = \\frac{1}{1 + e^{-x}} ,$$\n", + "\n", + "which is inspired by probability theory (see logistic regression) and was most commonly used until about 2011. See the discussion below concerning other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "2cbece98", + "metadata": { + "editable": true + }, + "source": [ + "## Layers\n", + "\n", + "* Input \n", + "\n", + "Since each input image has 8x8 = 64 pixels or features, we have an input layer of 64 neurons. \n", + "\n", + "* Hidden layer\n", + "\n", + "We will use 50 neurons in the hidden layer receiving input from the neurons in the input layer. \n", + "Since each neuron in the hidden layer is connected to the 64 inputs we have 64x50 = 3200 weights to the hidden layer. \n", + "\n", + "* Output\n", + "\n", + "If we were building a binary classifier, it would be sufficient with a single neuron in the output layer,\n", + "which could output 0 or 1 according to the Heaviside function. This would be an example of a *hard* classifier, meaning it outputs the class of the input directly. However, if we are dealing with noisy data it is often beneficial to use a *soft* classifier, which outputs the probability of being in class 0 or 1. \n", + "\n", + "For a soft binary classifier, we could use a single neuron and interpret the output as either being the probability of being in class 0 or the probability of being in class 1. Alternatively we could use 2 neurons, and interpret each neuron as the probability of being in each class. \n", + "\n", + "Since we are doing multiclass classification, with 10 categories, it is natural to use 10 neurons in the output layer. We number the neurons $j = 0,1,...,9$. The activation of each output neuron $j$ will be according to the *softmax* function: \n", + "\n", + "$$ P(\\text{class $j$} \\mid \\text{input $\\boldsymbol{a}$}) = \\frac{\\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_j)}}\n", + "{\\sum_{c=0}^{9} \\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_c)}} ,$$ \n", + "\n", + "i.e. each neuron $j$ outputs the probability of being in class $j$ given an input from the hidden layer $\\boldsymbol{a}$, with $\\boldsymbol{w}_j$ the weights of neuron $j$ to the inputs. \n", + "The denominator is a normalization factor to ensure the outputs (probabilities) sum up to 1. \n", + "The exponent is just the weighted sum of inputs as before: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i+b_j.$$ \n", + "\n", + "Since each neuron in the output layer is connected to the 50 inputs from the hidden layer we have 50x10 = 500\n", + "weights to the output layer." + ] + }, + { + "cell_type": "markdown", + "id": "442935af", + "metadata": { + "editable": true + }, + "source": [ + "## Weights and biases\n", + "\n", + "Typically weights are initialized with small values distributed around zero, drawn from a uniform\n", + "or normal distribution. Setting all weights to zero means all neurons give the same output, making the network useless. \n", + "\n", + "Adding a bias value to the weighted sum of inputs allows the neural network to represent a greater range\n", + "of values. Without it, any input with the value 0 will be mapped to zero (before being passed through the activation). The bias unit has an output of 1, and a weight to each neuron $j$, $b_j$: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i + b_j.$$ \n", + "\n", + "The bias weights $\\boldsymbol{b}$ are often initialized to zero, but a small value like $0.01$ ensures all neurons have some output which can be backpropagated in the first training cycle." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "07fbb18c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# building our neural network\n", + "\n", + "n_inputs, n_features = X_train.shape\n", + "n_hidden_neurons = 50\n", + "n_categories = 10\n", + "\n", + "# we make the weights normally distributed using numpy.random.randn\n", + "\n", + "# weights and bias in the hidden layer\n", + "hidden_weights = np.random.randn(n_features, n_hidden_neurons)\n", + "hidden_bias = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "output_weights = np.random.randn(n_hidden_neurons, n_categories)\n", + "output_bias = np.zeros(n_categories) + 0.01" + ] + }, + { + "cell_type": "markdown", + "id": "6a3ea326", + "metadata": { + "editable": true + }, + "source": [ + "## Feed-forward pass\n", + "\n", + "Denote $F$ the number of features, $H$ the number of hidden neurons and $C$ the number of categories. \n", + "For each input image we calculate a weighted sum of input features (pixel values) to each neuron $j$ in the hidden layer $l$: \n", + "\n", + "$$ z_{j}^{l} = \\sum_{i=1}^{F} w_{ij}^{l} x_i + b_{j}^{l},$$\n", + "\n", + "this is then passed through our activation function \n", + "\n", + "$$ a_{j}^{l} = f(z_{j}^{l}) .$$ \n", + "\n", + "We calculate a weighted sum of inputs (activations in the hidden layer) to each neuron $j$ in the output layer: \n", + "\n", + "$$ z_{j}^{L} = \\sum_{i=1}^{H} w_{ij}^{L} a_{i}^{l} + b_{j}^{L}.$$ \n", + "\n", + "Finally we calculate the output of neuron $j$ in the output layer using the softmax function: \n", + "\n", + "$$ a_{j}^{L} = \\frac{\\exp{(z_j^{L})}}\n", + "{\\sum_{c=0}^{C-1} \\exp{(z_c^{L})}} .$$" + ] + }, + { + "cell_type": "markdown", + "id": "525624c4", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplications\n", + "\n", + "Since our data has the dimensions $X = (n_{inputs}, n_{features})$ and our weights to the hidden\n", + "layer have the dimensions \n", + "$W_{hidden} = (n_{features}, n_{hidden})$,\n", + "we can easily feed the network all our training data in one go by taking the matrix product \n", + "\n", + "$$ X W^{h} = (n_{inputs}, n_{hidden}),$$ \n", + "\n", + "and obtain a matrix that holds the weighted sum of inputs to the hidden layer\n", + "for each input image and each hidden neuron. \n", + "We also add the bias to obtain a matrix of weighted sums to the hidden layer $Z^{h}$: \n", + "\n", + "$$ \\boldsymbol{z}^{l} = \\boldsymbol{X} \\boldsymbol{W}^{l} + \\boldsymbol{b}^{l} ,$$\n", + "\n", + "meaning the same bias (1D array with size equal number of hidden neurons) is added to each input image. \n", + "This is then passed through the activation: \n", + "\n", + "$$ \\boldsymbol{a}^{l} = f(\\boldsymbol{z}^l) .$$ \n", + "\n", + "This is fed to the output layer: \n", + "\n", + "$$ \\boldsymbol{z}^{L} = \\boldsymbol{a}^{L} \\boldsymbol{W}^{L} + \\boldsymbol{b}^{L} .$$\n", + "\n", + "Finally we receive our output values for each image and each category by passing it through the softmax function: \n", + "\n", + "$$ output = softmax (\\boldsymbol{z}^{L}) = (n_{inputs}, n_{categories}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "32d0a43f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# setup the feed-forward pass, subscript h = hidden layer\n", + "\n", + "def sigmoid(x):\n", + " return 1/(1 + np.exp(-x))\n", + "\n", + "def feed_forward(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " return probabilities\n", + "\n", + "probabilities = feed_forward(X_train)\n", + "print(\"probabilities = (n_inputs, n_categories) = \" + str(probabilities.shape))\n", + "print(\"probability that image 0 is in category 0,1,2,...,9 = \\n\" + str(probabilities[0]))\n", + "print(\"probabilities sum up to: \" + str(probabilities[0].sum()))\n", + "print()\n", + "\n", + "# we obtain a prediction by taking the class with the highest likelihood\n", + "def predict(X):\n", + " probabilities = feed_forward(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + "predictions = predict(X_train)\n", + "print(\"predictions = (n_inputs) = \" + str(predictions.shape))\n", + "print(\"prediction for image 0: \" + str(predictions[0]))\n", + "print(\"correct label for image 0: \" + str(Y_train[0]))" + ] + }, + { + "cell_type": "markdown", + "id": "da2ede88", + "metadata": { + "editable": true + }, + "source": [ + "## Choose cost function and optimizer\n", + "\n", + "To measure how well our neural network is doing we need to introduce a cost function. \n", + "We will call the function that gives the error of a single sample output the *loss* function, and the function\n", + "that gives the total error of our network across all samples the *cost* function.\n", + "A typical choice for multiclass classification is the *cross-entropy* loss, also known as the negative log likelihood. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$$ y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$$ \n", + "\n", + "$$ y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset. \n", + "\n", + "Let $y_{ic}$ denote the $c$-th component of the $i$-th one-hot vector. \n", + "We define the cost function $\\mathcal{C}$ as a sum over the cross-entropy loss for each point $\\boldsymbol{x}_i$ in the dataset.\n", + "\n", + "In the one-hot representation only one of the terms in the loss function is non-zero, namely the\n", + "probability of the correct category $c'$ \n", + "(i.e. the category $c'$ such that $y_{ic'} = 1$). This means that the cross entropy loss only punishes you for how wrong\n", + "you got the correct label. The probability of category $c$ is given by the softmax function. The vector $\\boldsymbol{\\theta}$ represents the parameters of our network, i.e. all the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "069a250d", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the cost function\n", + "\n", + "The network is trained by finding the weights and biases that minimize the cost function. One of the most widely used classes of methods is *gradient descent* and its generalizations. The idea behind gradient descent\n", + "is simply to adjust the weights in the direction where the gradient of the cost function is large and negative. This ensures we flow toward a *local* minimum of the cost function. \n", + "Each parameter $\\theta$ is iteratively adjusted according to the rule \n", + "\n", + "$$ \\theta_{i+1} = \\theta_i - \\eta \\nabla \\mathcal{C}(\\theta_i) ,$$\n", + "\n", + "where $\\eta$ is known as the *learning rate*, which controls how big a step we take towards the minimum. \n", + "This update can be repeated for any number of iterations, or until we are satisfied with the result. \n", + "\n", + "A simple and effective improvement is a variant called *Batch Gradient Descent*. \n", + "Instead of calculating the gradient on the whole dataset, we calculate an approximation of the gradient\n", + "on a subset of the data called a *minibatch*. \n", + "If there are $N$ data points and we have a minibatch size of $M$, the total number of batches\n", + "is $N/M$. \n", + "We denote each minibatch $B_k$, with $k = 1, 2,...,N/M$. The gradient then becomes: \n", + "\n", + "$$ \\nabla \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\nabla \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{M} \\sum_{i \\in B_k} \\nabla \\mathcal{L}_i(\\theta) ,$$\n", + "\n", + "i.e. instead of averaging the loss over the entire dataset, we average over a minibatch. \n", + "\n", + "This has two important benefits: \n", + "1. Introducing stochasticity decreases the chance that the algorithm becomes stuck in a local minima. \n", + "\n", + "2. It significantly speeds up the calculation, since we do not have to use the entire dataset to calculate the gradient. \n", + "\n", + "The various optmization methods, with codes and algorithms, are discussed in our lectures on [Gradient descent approaches](https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html)." + ] + }, + { + "cell_type": "markdown", + "id": "29ab6ee7", + "metadata": { + "editable": true + }, + "source": [ + "## Regularization\n", + "\n", + "It is common to add an extra term to the cost function, proportional\n", + "to the size of the weights. This is equivalent to constraining the\n", + "size of the weights, so that they do not grow out of control.\n", + "Constraining the size of the weights means that the weights cannot\n", + "grow arbitrarily large to fit the training data, and in this way\n", + "reduces *overfitting*.\n", + "\n", + "We will measure the size of the weights using the so called *L2-norm*, meaning our cost function becomes: \n", + "\n", + "$$ \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) + \\lambda \\lvert \\lvert \\boldsymbol{w} \\rvert \\rvert_2^2 \n", + "= \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\theta) + \\lambda \\sum_{ij} w_{ij}^2,$$ \n", + "\n", + "i.e. we sum up all the weights squared. The factor $\\lambda$ is known as a regularization parameter.\n", + "\n", + "In order to train the model, we need to calculate the derivative of\n", + "the cost function with respect to every bias and weight in the\n", + "network. In total our network has $(64 + 1)\\times 50=3250$ weights in\n", + "the hidden layer and $(50 + 1)\\times 10=510$ weights to the output\n", + "layer ($+1$ for the bias), and the gradient must be calculated for\n", + "every parameter. We use the *backpropagation* algorithm discussed\n", + "above. This is a clever use of the chain rule that allows us to\n", + "calculate the gradient efficently." + ] + }, + { + "cell_type": "markdown", + "id": "b7c4a178", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplication\n", + "\n", + "To more efficently train our network these equations are implemented using matrix operations. \n", + "The error in the output layer is calculated simply as, with $\\boldsymbol{t}$ being our targets, \n", + "\n", + "$$ \\delta_L = \\boldsymbol{t} - \\boldsymbol{y} = (n_{inputs}, n_{categories}) .$$ \n", + "\n", + "The gradient for the output weights is calculated as \n", + "\n", + "$$ \\nabla W_{L} = \\boldsymbol{a}^T \\delta_L = (n_{hidden}, n_{categories}) ,$$\n", + "\n", + "where $\\boldsymbol{a} = (n_{inputs}, n_{hidden})$. This simply means that we are summing up the gradients for each input. \n", + "Since we are going backwards we have to transpose the activation matrix. \n", + "\n", + "The gradient with respect to the output bias is then \n", + "\n", + "$$ \\nabla \\boldsymbol{b}_{L} = \\sum_{i=1}^{n_{inputs}} \\delta_L = (n_{categories}) .$$ \n", + "\n", + "The error in the hidden layer is \n", + "\n", + "$$ \\Delta_h = \\delta_L W_{L}^T \\circ f'(z_{h}) = \\delta_L W_{L}^T \\circ a_{h} \\circ (1 - a_{h}) = (n_{inputs}, n_{hidden}) ,$$ \n", + "\n", + "where $f'(a_{h})$ is the derivative of the activation in the hidden layer. The matrix products mean\n", + "that we are summing up the products for each neuron in the output layer. The symbol $\\circ$ denotes\n", + "the *Hadamard product*, meaning element-wise multiplication. \n", + "\n", + "This again gives us the gradients in the hidden layer: \n", + "\n", + "$$ \\nabla W_{h} = X^T \\delta_h = (n_{features}, n_{hidden}) ,$$ \n", + "\n", + "$$ \\nabla b_{h} = \\sum_{i=1}^{n_{inputs}} \\delta_h = (n_{hidden}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4142969e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# to categorical turns our integer vector into a onehot representation\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# one-hot in numpy\n", + "def to_categorical_numpy(integer_vector):\n", + " n_inputs = len(integer_vector)\n", + " n_categories = np.max(integer_vector) + 1\n", + " onehot_vector = np.zeros((n_inputs, n_categories))\n", + " onehot_vector[range(n_inputs), integer_vector] = 1\n", + " \n", + " return onehot_vector\n", + "\n", + "#Y_train_onehot, Y_test_onehot = to_categorical(Y_train), to_categorical(Y_test)\n", + "Y_train_onehot, Y_test_onehot = to_categorical_numpy(Y_train), to_categorical_numpy(Y_test)\n", + "\n", + "def feed_forward_train(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " # for backpropagation need activations in hidden and output layers\n", + " return a_h, probabilities\n", + "\n", + "def backpropagation(X, Y):\n", + " a_h, probabilities = feed_forward_train(X)\n", + " \n", + " # error in the output layer\n", + " error_output = probabilities - Y\n", + " # error in the hidden layer\n", + " error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h)\n", + " \n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_h.T, error_output)\n", + " output_bias_gradient = np.sum(error_output, axis=0)\n", + " \n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(X.T, error_hidden)\n", + " hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "print(\"Old accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))\n", + "\n", + "eta = 0.01\n", + "lmbd = 0.01\n", + "for i in range(1000):\n", + " # calculate gradients\n", + " dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot)\n", + " \n", + " # regularization term gradients\n", + " dWo += lmbd * output_weights\n", + " dWh += lmbd * hidden_weights\n", + " \n", + " # update weights and biases\n", + " output_weights -= eta * dWo\n", + " output_bias -= eta * dBo\n", + " hidden_weights -= eta * dWh\n", + " hidden_bias -= eta * dBh\n", + "\n", + "print(\"New accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))" + ] + }, + { + "cell_type": "markdown", + "id": "4d79c3b3", + "metadata": { + "editable": true + }, + "source": [ + "## Improving performance\n", + "\n", + "As we can see the network does not seem to be learning at all. It seems to be just guessing the label for each image. \n", + "In order to obtain a network that does something useful, we will have to do a bit more work. \n", + "\n", + "The choice of *hyperparameters* such as learning rate and regularization parameter is hugely influential for the performance of the network. Typically a *grid-search* is performed, wherein we test different hyperparameters separated by orders of magnitude. For example we could test the learning rates $\\eta = 10^{-6}, 10^{-5},...,10^{-1}$ with different regularization parameters $\\lambda = 10^{-6},...,10^{-0}$. \n", + "\n", + "Next, we haven't implemented minibatching yet, which introduces stochasticity and is though to act as an important regularizer on the weights. We call a feed-forward + backward pass with a minibatch an *iteration*, and a full training period\n", + "going through the entire dataset ($n/M$ batches) an *epoch*.\n", + "\n", + "If this does not improve network performance, you may want to consider altering the network architecture, adding more neurons or hidden layers. \n", + "Andrew Ng goes through some of these considerations in this [video](https://youtu.be/F1ka6a13S9I). You can find a summary of the video [here](https://kevinzakka.github.io/2016/09/26/applying-deep-learning/)." + ] + }, + { + "cell_type": "markdown", + "id": "58012d93", + "metadata": { + "editable": true + }, + "source": [ + "## Full object-oriented implementation\n", + "\n", + "It is very natural to think of the network as an object, with specific instances of the network\n", + "being realizations of this object with different hyperparameters. An implementation using Python classes provides a clean structure and interface, and the full implementation of our neural network is given below." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ea4b7741", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "class NeuralNetwork:\n", + " def __init__(\n", + " self,\n", + " X_data,\n", + " Y_data,\n", + " n_hidden_neurons=50,\n", + " n_categories=10,\n", + " epochs=10,\n", + " batch_size=100,\n", + " eta=0.1,\n", + " lmbd=0.0):\n", + "\n", + " self.X_data_full = X_data\n", + " self.Y_data_full = Y_data\n", + "\n", + " self.n_inputs = X_data.shape[0]\n", + " self.n_features = X_data.shape[1]\n", + " self.n_hidden_neurons = n_hidden_neurons\n", + " self.n_categories = n_categories\n", + "\n", + " self.epochs = epochs\n", + " self.batch_size = batch_size\n", + " self.iterations = self.n_inputs // self.batch_size\n", + " self.eta = eta\n", + " self.lmbd = lmbd\n", + "\n", + " self.create_biases_and_weights()\n", + "\n", + " def create_biases_and_weights(self):\n", + " self.hidden_weights = np.random.randn(self.n_features, self.n_hidden_neurons)\n", + " self.hidden_bias = np.zeros(self.n_hidden_neurons) + 0.01\n", + "\n", + " self.output_weights = np.random.randn(self.n_hidden_neurons, self.n_categories)\n", + " self.output_bias = np.zeros(self.n_categories) + 0.01\n", + "\n", + " def feed_forward(self):\n", + " # feed-forward for training\n", + " self.z_h = np.matmul(self.X_data, self.hidden_weights) + self.hidden_bias\n", + " self.a_h = sigmoid(self.z_h)\n", + "\n", + " self.z_o = np.matmul(self.a_h, self.output_weights) + self.output_bias\n", + "\n", + " exp_term = np.exp(self.z_o)\n", + " self.probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + "\n", + " def feed_forward_out(self, X):\n", + " # feed-forward for output\n", + " z_h = np.matmul(X, self.hidden_weights) + self.hidden_bias\n", + " a_h = sigmoid(z_h)\n", + "\n", + " z_o = np.matmul(a_h, self.output_weights) + self.output_bias\n", + " \n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " return probabilities\n", + "\n", + " def backpropagation(self):\n", + " error_output = self.probabilities - self.Y_data\n", + " error_hidden = np.matmul(error_output, self.output_weights.T) * self.a_h * (1 - self.a_h)\n", + "\n", + " self.output_weights_gradient = np.matmul(self.a_h.T, error_output)\n", + " self.output_bias_gradient = np.sum(error_output, axis=0)\n", + "\n", + " self.hidden_weights_gradient = np.matmul(self.X_data.T, error_hidden)\n", + " self.hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " if self.lmbd > 0.0:\n", + " self.output_weights_gradient += self.lmbd * self.output_weights\n", + " self.hidden_weights_gradient += self.lmbd * self.hidden_weights\n", + "\n", + " self.output_weights -= self.eta * self.output_weights_gradient\n", + " self.output_bias -= self.eta * self.output_bias_gradient\n", + " self.hidden_weights -= self.eta * self.hidden_weights_gradient\n", + " self.hidden_bias -= self.eta * self.hidden_bias_gradient\n", + "\n", + " def predict(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + " def predict_probabilities(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return probabilities\n", + "\n", + " def train(self):\n", + " data_indices = np.arange(self.n_inputs)\n", + "\n", + " for i in range(self.epochs):\n", + " for j in range(self.iterations):\n", + " # pick datapoints with replacement\n", + " chosen_datapoints = np.random.choice(\n", + " data_indices, size=self.batch_size, replace=False\n", + " )\n", + "\n", + " # minibatch training data\n", + " self.X_data = self.X_data_full[chosen_datapoints]\n", + " self.Y_data = self.Y_data_full[chosen_datapoints]\n", + "\n", + " self.feed_forward()\n", + " self.backpropagation()" + ] + }, + { + "cell_type": "markdown", + "id": "04860b2c", + "metadata": { + "editable": true + }, + "source": [ + "## Evaluate model performance on test data\n", + "\n", + "To measure the performance of our network we evaluate how well it does it data it has never seen before, i.e. the test data. \n", + "We measure the performance of the network using the *accuracy* score. \n", + "The accuracy is as you would expect just the number of images correctly labeled divided by the total number of images. A perfect classifier will have an accuracy score of $1$. \n", + "\n", + "$$ \\text{Accuracy} = \\frac{\\sum_{i=1}^n I(\\tilde{y}_i = y_i)}{n} ,$$ \n", + "\n", + "where $I$ is the indicator function, $1$ if $\\tilde{y}_i = y_i$ and $0$ otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b52d4df3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "epochs = 100\n", + "batch_size = 100\n", + "\n", + "dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + "dnn.train()\n", + "test_predict = dnn.predict(X_test)\n", + "\n", + "# accuracy score from scikit library\n", + "print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + "\n", + "# equivalent in numpy\n", + "def accuracy_score_numpy(Y_test, Y_pred):\n", + " return np.sum(Y_test == Y_pred) / len(Y_test)\n", + "\n", + "#print(\"Accuracy score on test set: \", accuracy_score_numpy(Y_test, test_predict))" + ] + }, + { + "cell_type": "markdown", + "id": "6dce68ff", + "metadata": { + "editable": true + }, + "source": [ + "## Adjust hyperparameters\n", + "\n", + "We now perform a grid search to find the optimal hyperparameters for the network. \n", + "Note that we are only using 1 layer with 50 neurons, and human performance is estimated to be around $98\\%$ ($2\\%$ error rate)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "65caeb78", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "# store the models for later use\n", + "DNN_numpy = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "# grid search\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + " dnn.train()\n", + " \n", + " DNN_numpy[i][j] = dnn\n", + " \n", + " test_predict = dnn.predict(X_test)\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "0c44c38e", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fbdc64f1", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# visual representation of grid search\n", + "# uses seaborn heatmap, you can also do this with matplotlib imshow\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_numpy[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e07e69e3", + "metadata": { + "editable": true + }, + "source": [ + "## scikit-learn implementation\n", + "\n", + "**scikit-learn** focuses more\n", + "on traditional machine learning methods, such as regression,\n", + "clustering, decision trees, etc. As such, it has only two types of\n", + "neural networks: Multi Layer Perceptron outputting continuous values,\n", + "*MPLRegressor*, and Multi Layer Perceptron outputting labels,\n", + "*MLPClassifier*. We will see how simple it is to use these classes.\n", + "\n", + "**scikit-learn** implements a few improvements from our neural network,\n", + "such as early stopping, a varying learning rate, different\n", + "optimization methods, etc. We would therefore expect a better\n", + "performance overall." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f48eaa77", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.neural_network import MLPClassifier\n", + "# store models for later use\n", + "DNN_scikit = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = MLPClassifier(hidden_layer_sizes=(n_hidden_neurons), activation='logistic',\n", + " alpha=lmbd, learning_rate_init=eta, max_iter=epochs)\n", + " dnn.fit(X_train, Y_train)\n", + " \n", + " DNN_scikit[i][j] = dnn\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", dnn.score(X_test, Y_test))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "ac3c7bcb", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2d81262e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_scikit[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8f5f8f4b", + "metadata": { + "editable": true + }, + "source": [ + "## Building neural networks in Tensorflow and Keras\n", + "\n", + "Now we want to build on the experience gained from our neural network implementation in NumPy and scikit-learn\n", + "and use it to construct a neural network in Tensorflow. Once we have constructed a neural network in NumPy\n", + "and Tensorflow, building one in Keras is really quite trivial, though the performance may suffer. \n", + "\n", + "In our previous example we used only one hidden layer, and in this we will use two. From this it should be quite\n", + "clear how to build one using an arbitrary number of hidden layers, using data structures such as Python lists or\n", + "NumPy arrays." + ] + }, + { + "cell_type": "markdown", + "id": "6ec638b9", + "metadata": { + "editable": true + }, + "source": [ + "## Tensorflow\n", + "\n", + "Tensorflow is an open source library machine learning library\n", + "developed by the Google Brain team for internal use. It was released\n", + "under the Apache 2.0 open source license in November 9, 2015.\n", + "\n", + "Tensorflow is a computational framework that allows you to construct\n", + "machine learning models at different levels of abstraction, from\n", + "high-level, object-oriented APIs like Keras, down to the C++ kernels\n", + "that Tensorflow is built upon. The higher levels of abstraction are\n", + "simpler to use, but less flexible, and our choice of implementation\n", + "should reflect the problems we are trying to solve.\n", + "\n", + "[Tensorflow uses](https://www.tensorflow.org/guide/graphs) so-called graphs to represent your computation\n", + "in terms of the dependencies between individual operations, such that you first build a Tensorflow *graph*\n", + "to represent your model, and then create a Tensorflow *session* to run the graph.\n", + "\n", + "In this guide we will analyze the same data as we did in our NumPy and\n", + "scikit-learn tutorial, gathered from the MNIST database of images. We\n", + "will give an introduction to the lower level Python Application\n", + "Program Interfaces (APIs), and see how we use them to build our graph.\n", + "Then we will build (effectively) the same graph in Keras, to see just\n", + "how simple solving a machine learning problem can be.\n", + "\n", + "To install tensorflow on Unix/Linux systems, use pip as" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6443ca72", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "pip3 install tensorflow" + ] + }, + { + "cell_type": "markdown", + "id": "a8918d58", + "metadata": { + "editable": true + }, + "source": [ + "and/or if you use **anaconda**, just write (or install from the graphical user interface)\n", + "(current release of CPU-only TensorFlow)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "20e9a0f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf tensorflow\n", + "conda activate tf" + ] + }, + { + "cell_type": "markdown", + "id": "1381a34b", + "metadata": { + "editable": true + }, + "source": [ + "To install the current release of GPU TensorFlow" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "80e92af9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf-gpu tensorflow-gpu\n", + "conda activate tf-gpu" + ] + }, + { + "cell_type": "markdown", + "id": "074ac69f", + "metadata": { + "editable": true + }, + "source": [ + "## Using Keras\n", + "\n", + "Keras is a high level [neural network](https://en.wikipedia.org/wiki/Application_programming_interface)\n", + "that supports Tensorflow, CTNK and Theano as backends. \n", + "If you have Anaconda installed you may run the following command" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0d710bd3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda install keras" + ] + }, + { + "cell_type": "markdown", + "id": "7adbcab8", + "metadata": { + "editable": true + }, + "source": [ + "You can look up the [instructions here](https://keras.io/) for more information.\n", + "\n", + "We will to a large extent use **keras** in this course." + ] + }, + { + "cell_type": "markdown", + "id": "e17c7253", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Let us look again at the MINST data set." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "5ae741f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorflow as tf\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "4f7ef6bb", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-hot representation of labels\n", + "labels = to_categorical(labels)\n", + "\n", + "# split into train and test data\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "7b74e049", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "epochs = 100\n", + "batch_size = 100\n", + "n_neurons_layer1 = 100\n", + "n_neurons_layer2 = 50\n", + "n_categories = 10\n", + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "def create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, eta, lmbd):\n", + " model = Sequential()\n", + " model.add(Dense(n_neurons_layer1, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_neurons_layer2, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_categories, activation='softmax'))\n", + " \n", + " sgd = optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])\n", + " \n", + " return model" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "eaa25983", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "DNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + " \n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " DNN = create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories,\n", + " eta=eta, lmbd=lmbd)\n", + " DNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0)\n", + " scores = DNN.evaluate(X_test, Y_test)\n", + " \n", + " DNN_keras[i][j] = DNN\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Test accuracy: %.3f\" % scores[1])\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "949eca1f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " DNN = DNN_keras[i][j]\n", + "\n", + " train_accuracy[i][j] = DNN.evaluate(X_train, Y_train)[1]\n", + " test_accuracy[i][j] = DNN.evaluate(X_test, Y_test)[1]\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "bb8b8ac1", + "metadata": { + "editable": true + }, + "source": [ + "## The Breast Cancer Data, now with Keras" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "9d5ebbb2", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "import tensorflow as tf\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.model_selection import train_test_split as splitter\n", + "from sklearn.datasets import load_breast_cancer\n", + "import pickle\n", + "import os \n", + "\n", + "\n", + "\"\"\"Load breast cancer dataset\"\"\"\n", + "\n", + "np.random.seed(0) #create same seed for random number every time\n", + "\n", + "cancer=load_breast_cancer() #Download breast cancer dataset\n", + "\n", + "inputs=cancer.data #Feature matrix of 569 rows (samples) and 30 columns (parameters)\n", + "outputs=cancer.target #Label array of 569 rows (0 for benign and 1 for malignant)\n", + "labels=cancer.feature_names[0:30]\n", + "\n", + "print('The content of the breast cancer dataset is:') #Print information about the datasets\n", + "print(labels)\n", + "print('-------------------------')\n", + "print(\"inputs = \" + str(inputs.shape))\n", + "print(\"outputs = \" + str(outputs.shape))\n", + "print(\"labels = \"+ str(labels.shape))\n", + "\n", + "x=inputs #Reassign the Feature and Label matrices to other variables\n", + "y=outputs\n", + "\n", + "#%% \n", + "\n", + "# Visualisation of dataset (for correlation analysis)\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,2],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean perimeter',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,5],x[:,6],s=40,c=y, cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean compactness',fontweight='bold')\n", + "plt.ylabel('Mean concavity',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean texture',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,2],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean perimeter',fontweight='bold')\n", + "plt.ylabel('Mean compactness',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "# Generate training and testing datasets\n", + "\n", + "#Select features relevant to classification (texture,perimeter,compactness and symmetery) \n", + "#and add to input matrix\n", + "\n", + "temp1=np.reshape(x[:,1],(len(x[:,1]),1))\n", + "temp2=np.reshape(x[:,2],(len(x[:,2]),1))\n", + "X=np.hstack((temp1,temp2)) \n", + "temp=np.reshape(x[:,5],(len(x[:,5]),1))\n", + "X=np.hstack((X,temp)) \n", + "temp=np.reshape(x[:,8],(len(x[:,8]),1))\n", + "X=np.hstack((X,temp)) \n", + "\n", + "X_train,X_test,y_train,y_test=splitter(X,y,test_size=0.1) #Split datasets into training and testing\n", + "\n", + "y_train=to_categorical(y_train) #Convert labels to categorical when using categorical cross entropy\n", + "y_test=to_categorical(y_test)\n", + "\n", + "del temp1,temp2,temp\n", + "\n", + "# %%\n", + "\n", + "# Define tunable parameters\"\n", + "\n", + "eta=np.logspace(-3,-1,3) #Define vector of learning rates (parameter to SGD optimiser)\n", + "lamda=0.01 #Define hyperparameter\n", + "n_layers=2 #Define number of hidden layers in the model\n", + "n_neuron=np.logspace(0,3,4,dtype=int) #Define number of neurons per layer\n", + "epochs=100 #Number of reiterations over the input data\n", + "batch_size=100 #Number of samples per gradient update\n", + "\n", + "# %%\n", + "\n", + "\"\"\"Define function to return Deep Neural Network model\"\"\"\n", + "\n", + "def NN_model(inputsize,n_layers,n_neuron,eta,lamda):\n", + " model=Sequential() \n", + " for i in range(n_layers): #Run loop to add hidden layers to the model\n", + " if (i==0): #First layer requires input dimensions\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda),input_dim=inputsize))\n", + " else: #Subsequent layers are capable of automatic shape inferencing\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda)))\n", + " model.add(Dense(2,activation='softmax')) #2 outputs - ordered and disordered (softmax for prob)\n", + " sgd=optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])\n", + " return model\n", + "\n", + " \n", + "Train_accuracy=np.zeros((len(n_neuron),len(eta))) #Define matrices to store accuracy scores as a function\n", + "Test_accuracy=np.zeros((len(n_neuron),len(eta))) #of learning rate and number of hidden neurons for \n", + "\n", + "for i in range(len(n_neuron)): #run loops over hidden neurons and learning rates to calculate \n", + " for j in range(len(eta)): #accuracy scores \n", + " DNN_model=NN_model(X_train.shape[1],n_layers,n_neuron[i],eta[j],lamda)\n", + " DNN_model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=1)\n", + " Train_accuracy[i,j]=DNN_model.evaluate(X_train,y_train)[1]\n", + " Test_accuracy[i,j]=DNN_model.evaluate(X_test,y_test)[1]\n", + " \n", + "\n", + "def plot_data(x,y,data,title=None):\n", + "\n", + " # plot results\n", + " fontsize=16\n", + "\n", + "\n", + " fig = plt.figure()\n", + " ax = fig.add_subplot(111)\n", + " cax = ax.matshow(data, interpolation='nearest', vmin=0, vmax=1)\n", + " \n", + " cbar=fig.colorbar(cax)\n", + " cbar.ax.set_ylabel('accuracy (%)',rotation=90,fontsize=fontsize)\n", + " cbar.set_ticks([0,.2,.4,0.6,0.8,1.0])\n", + " cbar.set_ticklabels(['0%','20%','40%','60%','80%','100%'])\n", + "\n", + " # put text on matrix elements\n", + " for i, x_val in enumerate(np.arange(len(x))):\n", + " for j, y_val in enumerate(np.arange(len(y))):\n", + " c = \"${0:.1f}\\\\%$\".format( 100*data[j,i]) \n", + " ax.text(x_val, y_val, c, va='center', ha='center')\n", + "\n", + " # convert axis vaues to to string labels\n", + " x=[str(i) for i in x]\n", + " y=[str(i) for i in y]\n", + "\n", + "\n", + " ax.set_xticklabels(['']+x)\n", + " ax.set_yticklabels(['']+y)\n", + "\n", + " ax.set_xlabel('$\\\\mathrm{learning\\\\ rate}$',fontsize=fontsize)\n", + " ax.set_ylabel('$\\\\mathrm{hidden\\\\ neurons}$',fontsize=fontsize)\n", + " if title is not None:\n", + " ax.set_title(title)\n", + "\n", + " plt.tight_layout()\n", + "\n", + " plt.show()\n", + " \n", + "plot_data(eta,n_neuron,Train_accuracy, 'training')\n", + "plot_data(eta,n_neuron,Test_accuracy, 'testing')" + ] + }, + { + "cell_type": "markdown", + "id": "f1baeb0b", + "metadata": { + "editable": true + }, + "source": [ + "## Building a neural network code\n", + "\n", + "Here we present a flexible object oriented codebase\n", + "for a feed forward neural network, along with a demonstration of how\n", + "to use it. Before we get into the details of the neural network, we\n", + "will first present some implementations of various schedulers, cost\n", + "functions and activation functions that can be used together with the\n", + "neural network.\n", + "\n", + "The codes here were developed by Eric Reber and Gregor Kajda during spring 2023." + ] + }, + { + "cell_type": "markdown", + "id": "6549fa13", + "metadata": { + "editable": true + }, + "source": [ + "### Learning rate methods\n", + "\n", + "The code below shows object oriented implementations of the Constant,\n", + "Momentum, Adagrad, AdagradMomentum, RMS prop and Adam schedulers. All\n", + "of the classes belong to the shared abstract Scheduler class, and\n", + "share the update_change() and reset() methods allowing for any of the\n", + "schedulers to be seamlessly used during the training stage, as will\n", + "later be shown in the fit() method of the neural\n", + "network. Update_change() only has one parameter, the gradient\n", + "($δ^l_ja^{l−1}_k$), and returns the change which will be subtracted\n", + "from the weights. The reset() function takes no parameters, and resets\n", + "the desired variables. For Constant and Momentum, reset does nothing." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "21062ebc", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "class Scheduler:\n", + " \"\"\"\n", + " Abstract class for Schedulers\n", + " \"\"\"\n", + "\n", + " def __init__(self, eta):\n", + " self.eta = eta\n", + "\n", + " # should be overwritten\n", + " def update_change(self, gradient):\n", + " raise NotImplementedError\n", + "\n", + " # overwritten if needed\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Constant(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + "\n", + " def update_change(self, gradient):\n", + " return self.eta * gradient\n", + " \n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Momentum(Scheduler):\n", + " def __init__(self, eta: float, momentum: float):\n", + " super().__init__(eta)\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " self.change = self.momentum * self.change + self.eta * gradient\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Adagrad(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " return self.eta * gradient * G_t_inverse\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class AdagradMomentum(Scheduler):\n", + " def __init__(self, eta, momentum):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " self.change = self.change * self.momentum + self.eta * gradient * G_t_inverse\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class RMS_prop(Scheduler):\n", + " def __init__(self, eta, rho):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.second = 0.0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + " self.second = self.rho * self.second + (1 - self.rho) * gradient * gradient\n", + " return self.eta * gradient / (np.sqrt(self.second + delta))\n", + "\n", + " def reset(self):\n", + " self.second = 0.0\n", + "\n", + "\n", + "class Adam(Scheduler):\n", + " def __init__(self, eta, rho, rho2):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.rho2 = rho2\n", + " self.moment = 0\n", + " self.second = 0\n", + " self.n_epochs = 1\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " self.moment = self.rho * self.moment + (1 - self.rho) * gradient\n", + " self.second = self.rho2 * self.second + (1 - self.rho2) * gradient * gradient\n", + "\n", + " moment_corrected = self.moment / (1 - self.rho**self.n_epochs)\n", + " second_corrected = self.second / (1 - self.rho2**self.n_epochs)\n", + "\n", + " return self.eta * moment_corrected / (np.sqrt(second_corrected + delta))\n", + "\n", + " def reset(self):\n", + " self.n_epochs += 1\n", + " self.moment = 0\n", + " self.second = 0" + ] + }, + { + "cell_type": "markdown", + "id": "f965b277", + "metadata": { + "editable": true + }, + "source": [ + "### Usage of the above learning rate schedulers\n", + "\n", + "To initalize a scheduler, simply create the object and pass in the\n", + "necessary parameters such as the learning rate and the momentum as\n", + "shown below. As the Scheduler class is an abstract class it should not\n", + "called directly, and will raise an error upon usage." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "35ab935b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "momentum_scheduler = Momentum(eta=1e-3, momentum=0.9)\n", + "adam_scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)" + ] + }, + { + "cell_type": "markdown", + "id": "b26972b4", + "metadata": { + "editable": true + }, + "source": [ + "Here is a small example for how a segment of code using schedulers\n", + "could look. Switching out the schedulers is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3df9caac", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "weights = np.ones((3,3))\n", + "print(f\"Before scheduler:\\n{weights=}\")\n", + "\n", + "epochs = 10\n", + "for e in range(epochs):\n", + " gradient = np.random.rand(3, 3)\n", + " change = adam_scheduler.update_change(gradient)\n", + " weights = weights - change\n", + " adam_scheduler.reset()\n", + "\n", + "print(f\"\\nAfter scheduler:\\n{weights=}\")" + ] + }, + { + "cell_type": "markdown", + "id": "1c07f6da", + "metadata": { + "editable": true + }, + "source": [ + "### Cost functions\n", + "\n", + "Here we discuss cost functions that can be used when creating the\n", + "neural network. Every cost function takes the target vector as its\n", + "parameter, and returns a function valued only at $x$ such that it may\n", + "easily be differentiated." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "743aa0bd", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "def CostOLS(target):\n", + " \n", + " def func(X):\n", + " return (1.0 / target.shape[0]) * np.sum((target - X) ** 2)\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostLogReg(target):\n", + "\n", + " def func(X):\n", + " \n", + " return -(1.0 / target.shape[0]) * np.sum(\n", + " (target * np.log(X + 10e-10)) + ((1 - target) * np.log(1 - X + 10e-10))\n", + " )\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostCrossEntropy(target):\n", + " \n", + " def func(X):\n", + " return -(1.0 / target.size) * np.sum(target * np.log(X + 10e-10))\n", + "\n", + " return func" + ] + }, + { + "cell_type": "markdown", + "id": "c78bdc16", + "metadata": { + "editable": true + }, + "source": [ + "Below we give a short example of how these cost function may be used\n", + "to obtain results if you wish to test them out on your own using\n", + "AutoGrad's automatics differentiation." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4ec3a28c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from autograd import grad\n", + "\n", + "target = np.array([[1, 2, 3]]).T\n", + "a = np.array([[4, 5, 6]]).T\n", + "\n", + "cost_func = CostCrossEntropy\n", + "cost_func_derivative = grad(cost_func(target))\n", + "\n", + "valued_at_a = cost_func_derivative(a)\n", + "print(f\"Derivative of cost function {cost_func.__name__} valued at a:\\n{valued_at_a}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5c924e11", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "Finally, before we look at the neural network, we will look at the\n", + "activation functions which can be specified between the hidden layers\n", + "and as the output function. Each function can be valued for any given\n", + "vector or matrix X, and can be differentiated via derivate()." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "87402ee9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from autograd import elementwise_grad\n", + "\n", + "def identity(X):\n", + " return X\n", + "\n", + "\n", + "def sigmoid(X):\n", + " try:\n", + " return 1.0 / (1 + np.exp(-X))\n", + " except FloatingPointError:\n", + " return np.where(X > np.zeros(X.shape), np.ones(X.shape), np.zeros(X.shape))\n", + "\n", + "\n", + "def softmax(X):\n", + " X = X - np.max(X, axis=-1, keepdims=True)\n", + " delta = 10e-10\n", + " return np.exp(X) / (np.sum(np.exp(X), axis=-1, keepdims=True) + delta)\n", + "\n", + "\n", + "def RELU(X):\n", + " return np.where(X > np.zeros(X.shape), X, np.zeros(X.shape))\n", + "\n", + "\n", + "def LRELU(X):\n", + " delta = 10e-4\n", + " return np.where(X > np.zeros(X.shape), X, delta * X)\n", + "\n", + "\n", + "def derivate(func):\n", + " if func.__name__ == \"RELU\":\n", + "\n", + " def func(X):\n", + " return np.where(X > 0, 1, 0)\n", + "\n", + " return func\n", + "\n", + " elif func.__name__ == \"LRELU\":\n", + "\n", + " def func(X):\n", + " delta = 10e-4\n", + " return np.where(X > 0, 1, delta)\n", + "\n", + " return func\n", + "\n", + " else:\n", + " return elementwise_grad(func)" + ] + }, + { + "cell_type": "markdown", + "id": "45ddd0bc", + "metadata": { + "editable": true + }, + "source": [ + "Below follows a short demonstration of how to use an activation\n", + "function. The derivative of the activation function will be important\n", + "when calculating the output delta term during backpropagation. Note\n", + "that derivate() can also be used for cost functions for a more\n", + "generalized approach." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "77034679", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "z = np.array([[4, 5, 6]]).T\n", + "print(f\"Input to activation function:\\n{z}\")\n", + "\n", + "act_func = sigmoid\n", + "a = act_func(z)\n", + "print(f\"\\nOutput from {act_func.__name__} activation function:\\n{a}\")\n", + "\n", + "act_func_derivative = derivate(act_func)\n", + "valued_at_z = act_func_derivative(a)\n", + "print(f\"\\nDerivative of {act_func.__name__} activation function valued at z:\\n{valued_at_z}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9fd8140f", + "metadata": { + "editable": true + }, + "source": [ + "### The Neural Network\n", + "\n", + "Now that we have gotten a good understanding of the implementation of\n", + "some important components, we can take a look at an object oriented\n", + "implementation of a feed forward neural network. The feed forward\n", + "neural network has been implemented as a class named FFNN, which can\n", + "be initiated as a regressor or classifier dependant on the choice of\n", + "cost function. The FFNN can have any number of input nodes, hidden\n", + "layers with any amount of hidden nodes, and any amount of output nodes\n", + "meaning it can perform multiclass classification as well as binary\n", + "classification and regression problems. Although there is a lot of\n", + "code present, it makes for an easy to use and generalizeable interface\n", + "for creating many types of neural networks as will be demonstrated\n", + "below." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7540d755", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import math\n", + "import autograd.numpy as np\n", + "import sys\n", + "import warnings\n", + "from autograd import grad, elementwise_grad\n", + "from random import random, seed\n", + "from copy import deepcopy, copy\n", + "from typing import Tuple, Callable\n", + "from sklearn.utils import resample\n", + "\n", + "warnings.simplefilter(\"error\")\n", + "\n", + "\n", + "class FFNN:\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Feed Forward Neural Network with interface enabling flexible design of a\n", + " nerual networks architecture and the specification of activation function\n", + " in the hidden layers and output layer respectively. This model can be used\n", + " for both regression and classification problems, depending on the output function.\n", + "\n", + " Attributes:\n", + " ------------\n", + " I dimensions (tuple[int]): A list of positive integers, which specifies the\n", + " number of nodes in each of the networks layers. The first integer in the array\n", + " defines the number of nodes in the input layer, the second integer defines number\n", + " of nodes in the first hidden layer and so on until the last number, which\n", + " specifies the number of nodes in the output layer.\n", + " II hidden_func (Callable): The activation function for the hidden layers\n", + " III output_func (Callable): The activation function for the output layer\n", + " IV cost_func (Callable): Our cost function\n", + " V seed (int): Sets random seed, makes results reproducible\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " dimensions: tuple[int],\n", + " hidden_func: Callable = sigmoid,\n", + " output_func: Callable = lambda x: x,\n", + " cost_func: Callable = CostOLS,\n", + " seed: int = None,\n", + " ):\n", + " self.dimensions = dimensions\n", + " self.hidden_func = hidden_func\n", + " self.output_func = output_func\n", + " self.cost_func = cost_func\n", + " self.seed = seed\n", + " self.weights = list()\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + " self.classification = None\n", + "\n", + " self.reset_weights()\n", + " self._set_classification()\n", + "\n", + " def fit(\n", + " self,\n", + " X: np.ndarray,\n", + " t: np.ndarray,\n", + " scheduler: Scheduler,\n", + " batches: int = 1,\n", + " epochs: int = 100,\n", + " lam: float = 0,\n", + " X_val: np.ndarray = None,\n", + " t_val: np.ndarray = None,\n", + " ):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " This function performs the training the neural network by performing the feedforward and backpropagation\n", + " algorithm to update the networks weights.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray) : training data\n", + " II t (np.ndarray) : target data\n", + " III scheduler (Scheduler) : specified scheduler (algorithm for optimization of gradient descent)\n", + " IV scheduler_args (list[int]) : list of all arguments necessary for scheduler\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " V batches (int) : number of batches the datasets are split into, default equal to 1\n", + " VI epochs (int) : number of iterations used to train the network, default equal to 100\n", + " VII lam (float) : regularization hyperparameter lambda\n", + " VIII X_val (np.ndarray) : validation set\n", + " IX t_val (np.ndarray) : validation target set\n", + "\n", + " Returns:\n", + " ------------\n", + " I scores (dict) : A dictionary containing the performance metrics of the model.\n", + " The number of the metrics depends on the parameters passed to the fit-function.\n", + "\n", + " \"\"\"\n", + "\n", + " # setup \n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " val_set = False\n", + " if X_val is not None and t_val is not None:\n", + " val_set = True\n", + "\n", + " # creating arrays for score metrics\n", + " train_errors = np.empty(epochs)\n", + " train_errors.fill(np.nan)\n", + " val_errors = np.empty(epochs)\n", + " val_errors.fill(np.nan)\n", + "\n", + " train_accs = np.empty(epochs)\n", + " train_accs.fill(np.nan)\n", + " val_accs = np.empty(epochs)\n", + " val_accs.fill(np.nan)\n", + "\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + "\n", + " batch_size = X.shape[0] // batches\n", + "\n", + " X, t = resample(X, t)\n", + "\n", + " # this function returns a function valued only at X\n", + " cost_function_train = self.cost_func(t)\n", + " if val_set:\n", + " cost_function_val = self.cost_func(t_val)\n", + "\n", + " # create schedulers for each weight matrix\n", + " for i in range(len(self.weights)):\n", + " self.schedulers_weight.append(copy(scheduler))\n", + " self.schedulers_bias.append(copy(scheduler))\n", + "\n", + " print(f\"{scheduler.__class__.__name__}: Eta={scheduler.eta}, Lambda={lam}\")\n", + "\n", + " try:\n", + " for e in range(epochs):\n", + " for i in range(batches):\n", + " # allows for minibatch gradient descent\n", + " if i == batches - 1:\n", + " # If the for loop has reached the last batch, take all thats left\n", + " X_batch = X[i * batch_size :, :]\n", + " t_batch = t[i * batch_size :, :]\n", + " else:\n", + " X_batch = X[i * batch_size : (i + 1) * batch_size, :]\n", + " t_batch = t[i * batch_size : (i + 1) * batch_size, :]\n", + "\n", + " self._feedforward(X_batch)\n", + " self._backpropagate(X_batch, t_batch, lam)\n", + "\n", + " # reset schedulers for each epoch (some schedulers pass in this call)\n", + " for scheduler in self.schedulers_weight:\n", + " scheduler.reset()\n", + "\n", + " for scheduler in self.schedulers_bias:\n", + " scheduler.reset()\n", + "\n", + " # computing performance metrics\n", + " pred_train = self.predict(X)\n", + " train_error = cost_function_train(pred_train)\n", + "\n", + " train_errors[e] = train_error\n", + " if val_set:\n", + " \n", + " pred_val = self.predict(X_val)\n", + " val_error = cost_function_val(pred_val)\n", + " val_errors[e] = val_error\n", + "\n", + " if self.classification:\n", + " train_acc = self._accuracy(self.predict(X), t)\n", + " train_accs[e] = train_acc\n", + " if val_set:\n", + " val_acc = self._accuracy(pred_val, t_val)\n", + " val_accs[e] = val_acc\n", + "\n", + " # printing progress bar\n", + " progression = e / epochs\n", + " print_length = self._progress_bar(\n", + " progression,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " except KeyboardInterrupt:\n", + " # allows for stopping training at any point and seeing the result\n", + " pass\n", + "\n", + " # visualization of training progression (similiar to tensorflow progression bar)\n", + " sys.stdout.write(\"\\r\" + \" \" * print_length)\n", + " sys.stdout.flush()\n", + " self._progress_bar(\n", + " 1,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " sys.stdout.write(\"\")\n", + "\n", + " # return performance metrics for the entire run\n", + " scores = dict()\n", + "\n", + " scores[\"train_errors\"] = train_errors\n", + "\n", + " if val_set:\n", + " scores[\"val_errors\"] = val_errors\n", + "\n", + " if self.classification:\n", + " scores[\"train_accs\"] = train_accs\n", + "\n", + " if val_set:\n", + " scores[\"val_accs\"] = val_accs\n", + "\n", + " return scores\n", + "\n", + " def predict(self, X: np.ndarray, *, threshold=0.5):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs prediction after training of the network has been finished.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " II threshold (float) : sets minimal value for a prediction to be predicted as the positive class\n", + " in classification problems\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " This vector is thresholded if regression=False, meaning that classification results\n", + " in a vector of 1s and 0s, while regressions in an array of decimal numbers\n", + "\n", + " \"\"\"\n", + "\n", + " predict = self._feedforward(X)\n", + "\n", + " if self.classification:\n", + " return np.where(predict > threshold, 1, 0)\n", + " else:\n", + " return predict\n", + "\n", + " def reset_weights(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Resets/Reinitializes the weights in order to train the network for a new problem.\n", + "\n", + " \"\"\"\n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " self.weights = list()\n", + " for i in range(len(self.dimensions) - 1):\n", + " weight_array = np.random.randn(\n", + " self.dimensions[i] + 1, self.dimensions[i + 1]\n", + " )\n", + " weight_array[0, :] = np.random.randn(self.dimensions[i + 1]) * 0.01\n", + "\n", + " self.weights.append(weight_array)\n", + "\n", + " def _feedforward(self, X: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates the activation of each layer starting at the input and ending at the output.\n", + " Each following activation is calculated from a weighted sum of each of the preceeding\n", + " activations (except in the case of the input layer).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " \"\"\"\n", + "\n", + " # reset matrices\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + "\n", + " # if X is just a vector, make it into a matrix\n", + " if len(X.shape) == 1:\n", + " X = X.reshape((1, X.shape[0]))\n", + "\n", + " # Add a coloumn of zeros as the first coloumn of the design matrix, in order\n", + " # to add bias to our data\n", + " bias = np.ones((X.shape[0], 1)) * 0.01\n", + " X = np.hstack([bias, X])\n", + "\n", + " # a^0, the nodes in the input layer (one a^0 for each row in X - where the\n", + " # exponent indicates layer number).\n", + " a = X\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(a)\n", + "\n", + " # The feed forward algorithm\n", + " for i in range(len(self.weights)):\n", + " if i < len(self.weights) - 1:\n", + " z = a @ self.weights[i]\n", + " self.z_matrices.append(z)\n", + " a = self.hidden_func(z)\n", + " # bias column again added to the data here\n", + " bias = np.ones((a.shape[0], 1)) * 0.01\n", + " a = np.hstack([bias, a])\n", + " self.a_matrices.append(a)\n", + " else:\n", + " try:\n", + " # a^L, the nodes in our output layers\n", + " z = a @ self.weights[i]\n", + " a = self.output_func(z)\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(z)\n", + " except Exception as OverflowError:\n", + " print(\n", + " \"OverflowError in fit() in FFNN\\nHOW TO DEBUG ERROR: Consider lowering your learning rate or scheduler specific parameters such as momentum, or check if your input values need scaling\"\n", + " )\n", + "\n", + " # this will be a^L\n", + " return a\n", + "\n", + " def _backpropagate(self, X, t, lam):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs the backpropagation algorithm. In other words, this method\n", + " calculates the gradient of all the layers starting at the\n", + " output layer, and moving from right to left accumulates the gradient until\n", + " the input layer is reached. Each layers respective weights are updated while\n", + " the algorithm propagates backwards from the output layer (auto-differentation in reverse mode).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each.\n", + " II t (np.ndarray): The target vector, with n rows of p targets.\n", + " III lam (float32): regularization parameter used to punish the weights in case of overfitting\n", + "\n", + " Returns:\n", + " ------------\n", + " No return value.\n", + "\n", + " \"\"\"\n", + " out_derivative = derivate(self.output_func)\n", + " hidden_derivative = derivate(self.hidden_func)\n", + "\n", + " for i in range(len(self.weights) - 1, -1, -1):\n", + " # delta terms for output\n", + " if i == len(self.weights) - 1:\n", + " # for multi-class classification\n", + " if (\n", + " self.output_func.__name__ == \"softmax\"\n", + " ):\n", + " delta_matrix = self.a_matrices[i + 1] - t\n", + " # for single class classification\n", + " else:\n", + " cost_func_derivative = grad(self.cost_func(t))\n", + " delta_matrix = out_derivative(\n", + " self.z_matrices[i + 1]\n", + " ) * cost_func_derivative(self.a_matrices[i + 1])\n", + "\n", + " # delta terms for hidden layer\n", + " else:\n", + " delta_matrix = (\n", + " self.weights[i + 1][1:, :] @ delta_matrix.T\n", + " ).T * hidden_derivative(self.z_matrices[i + 1])\n", + "\n", + " # calculate gradient\n", + " gradient_weights = self.a_matrices[i][:, 1:].T @ delta_matrix\n", + " gradient_bias = np.sum(delta_matrix, axis=0).reshape(\n", + " 1, delta_matrix.shape[1]\n", + " )\n", + "\n", + " # regularization term\n", + " gradient_weights += self.weights[i][1:, :] * lam\n", + "\n", + " # use scheduler\n", + " update_matrix = np.vstack(\n", + " [\n", + " self.schedulers_bias[i].update_change(gradient_bias),\n", + " self.schedulers_weight[i].update_change(gradient_weights),\n", + " ]\n", + " )\n", + "\n", + " # update weights and bias\n", + " self.weights[i] -= update_matrix\n", + "\n", + " def _accuracy(self, prediction: np.ndarray, target: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates accuracy of given prediction to target\n", + "\n", + " Parameters:\n", + " ------------\n", + " I prediction (np.ndarray): vector of predicitons output network\n", + " (1s and 0s in case of classification, and real numbers in case of regression)\n", + " II target (np.ndarray): vector of true values (What the network ideally should predict)\n", + "\n", + " Returns:\n", + " ------------\n", + " A floating point number representing the percentage of correctly classified instances.\n", + " \"\"\"\n", + " assert prediction.size == target.size\n", + " return np.average((target == prediction))\n", + " def _set_classification(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Decides if FFNN acts as classifier (True) og regressor (False),\n", + " sets self.classification during init()\n", + " \"\"\"\n", + " self.classification = False\n", + " if (\n", + " self.cost_func.__name__ == \"CostLogReg\"\n", + " or self.cost_func.__name__ == \"CostCrossEntropy\"\n", + " ):\n", + " self.classification = True\n", + "\n", + " def _progress_bar(self, progression, **kwargs):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Displays progress of training\n", + " \"\"\"\n", + " print_length = 40\n", + " num_equals = int(progression * print_length)\n", + " num_not = print_length - num_equals\n", + " arrow = \">\" if num_equals > 0 else \"\"\n", + " bar = \"[\" + \"=\" * (num_equals - 1) + arrow + \"-\" * num_not + \"]\"\n", + " perc_print = self._format(progression * 100, decimals=5)\n", + " line = f\" {bar} {perc_print}% \"\n", + "\n", + " for key in kwargs:\n", + " if not np.isnan(kwargs[key]):\n", + " value = self._format(kwargs[key], decimals=4)\n", + " line += f\"| {key}: {value} \"\n", + " sys.stdout.write(\"\\r\" + line)\n", + " sys.stdout.flush()\n", + " return len(line)\n", + "\n", + " def _format(self, value, decimals=4):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Formats decimal numbers for progress bar\n", + " \"\"\"\n", + " if value > 0:\n", + " v = value\n", + " elif value < 0:\n", + " v = -10 * value\n", + " else:\n", + " v = 1\n", + " n = 1 + math.floor(math.log10(v))\n", + " if n >= decimals - 1:\n", + " return str(round(value))\n", + " return f\"{value:.{decimals-n-1}f}\"" + ] + }, + { + "cell_type": "markdown", + "id": "5ee996ef", + "metadata": { + "editable": true + }, + "source": [ + "Before we make a model, we will quickly generate a dataset we can use\n", + "for our linear regression problem as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "183b180b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "def SkrankeFunction(x, y):\n", + " return np.ravel(0 + 1*x + 2*y + 3*x**2 + 4*x*y + 5*y**2)\n", + "\n", + "def create_X(x, y, n):\n", + " if len(x.shape) > 1:\n", + " x = np.ravel(x)\n", + " y = np.ravel(y)\n", + "\n", + " N = len(x)\n", + " l = int((n + 1) * (n + 2) / 2) # Number of elements in beta\n", + " X = np.ones((N, l))\n", + "\n", + " for i in range(1, n + 1):\n", + " q = int((i) * (i + 1) / 2)\n", + " for k in range(i + 1):\n", + " X[:, q + k] = (x ** (i - k)) * (y**k)\n", + "\n", + " return X\n", + "\n", + "step=0.5\n", + "x = np.arange(0, 1, step)\n", + "y = np.arange(0, 1, step)\n", + "x, y = np.meshgrid(x, y)\n", + "target = SkrankeFunction(x, y)\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "poly_degree=3\n", + "X = create_X(x, y, poly_degree)\n", + "\n", + "X_train, X_test, t_train, t_test = train_test_split(X, target)" + ] + }, + { + "cell_type": "markdown", + "id": "21a48508", + "metadata": { + "editable": true + }, + "source": [ + "Now that we have our dataset ready for the regression, we can create\n", + "our regressor. Note that with the seed parameter, we can make sure our\n", + "results stay the same every time we run the neural network. For\n", + "inititialization, we simply specify the dimensions (we wish the amount\n", + "of input nodes to be equal to the datapoints, and the output to\n", + "predict one value)." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "37eba90c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "linear_regression = FFNN((input_nodes, output_nodes), output_func=identity, cost_func=CostOLS, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "58a6b726", + "metadata": { + "editable": true + }, + "source": [ + "We then fit our model with our training data using the scheduler of our choice." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "046d7076", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Constant(eta=1e-3)\n", + "scores = linear_regression.fit(X_train, t_train, scheduler)" + ] + }, + { + "cell_type": "markdown", + "id": "981e95ce", + "metadata": { + "editable": true + }, + "source": [ + "Due to the progress bar we can see the MSE (train_error) throughout\n", + "the FFNN's training. Note that the fit() function has some optional\n", + "parameters with defualt arguments. For example, the regularization\n", + "hyperparameter can be left ignored if not needed, and equally the FFNN\n", + "will by default run for 100 epochs. These can easily be changed, such\n", + "as for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6da23296", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scores = linear_regression.fit(X_train, t_train, scheduler, lam=1e-4, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ba0fea41", + "metadata": { + "editable": true + }, + "source": [ + "We see that given more epochs to train on, the regressor reaches a lower MSE.\n", + "\n", + "Let us then switch to a binary classification. We use a binary\n", + "classification dataset, and follow a similar setup to the regression\n", + "case." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "1bd5c3e5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "wisconsin = load_breast_cancer()\n", + "X = wisconsin.data\n", + "target = wisconsin.target\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "X_train, X_val, t_train, t_val = train_test_split(X, target)\n", + "\n", + "scaler = MinMaxScaler()\n", + "scaler.fit(X_train)\n", + "X_train = scaler.transform(X_train)\n", + "X_val = scaler.transform(X_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "9923ffbf", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "95431510", + "metadata": { + "editable": true + }, + "source": [ + "We will now make use of our validation data by passing it into our fit function as a keyword argument" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "9d71cef9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "acfee190", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we will create a neural network with 2 hidden layers with activation functions." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "c834fb60", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 1\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "neural_network = FFNN(dims, hidden_func=RELU, output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0c557301", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "neural_network.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = neural_network.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "750490a3", + "metadata": { + "editable": true + }, + "source": [ + "### Multiclass classification\n", + "\n", + "Finally, we will demonstrate the use case of multiclass classification\n", + "using our FFNN with the famous MNIST dataset, which contain images of\n", + "digits between the range of 0 to 9." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "5318d06b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_digits\n", + "\n", + "def onehot(target: np.ndarray):\n", + " onehot = np.zeros((target.size, target.max() + 1))\n", + " onehot[np.arange(target.size), target] = 1\n", + " return onehot\n", + "\n", + "digits = load_digits()\n", + "\n", + "X = digits.data\n", + "target = digits.target\n", + "target = onehot(target)\n", + "\n", + "input_nodes = 64\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 10\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "multiclass = FFNN(dims, hidden_func=LRELU, output_func=softmax, cost_func=CostCrossEntropy)\n", + "\n", + "multiclass.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = multiclass.fit(X, target, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ff519831", + "metadata": { + "editable": true + }, + "source": [ + "## Testing the XOR gate and other gates\n", + "\n", + "Let us now use our code to test the XOR gate." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "57e3fb33", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "X = np.array([ [0, 0], [0, 1], [1, 0],[1, 1]],dtype=np.float64)\n", + "\n", + "# The XOR gate\n", + "yXOR = np.array( [[ 0], [1] ,[1], [0]])\n", + "\n", + "input_nodes = X.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)\n", + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "scheduler = Adam(eta=1e-1, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X, yXOR, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "e4c08bad", + "metadata": { + "editable": true + }, + "source": [ + "Not bad, but the results depend strongly on the learning reate. Try different learning rates." + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/LectureNotes/_build/html/exercisesweek41.html b/doc/LectureNotes/_build/html/exercisesweek41.html index 666c1b83d..6ae56b051 100644 --- a/doc/LectureNotes/_build/html/exercisesweek41.html +++ b/doc/LectureNotes/_build/html/exercisesweek41.html @@ -323,6 +323,16 @@ const thebe_selector_output = ".output, .cell_output" Week 41 Neural networks and constructing a neural network code
+
  • + + Exercises week 42 + +
  • +
  • + + Week 42 Constructing a Neural Network code with examples + +
  • @@ -747,7 +757,7 @@ regression.

    eta = 1.0/np.max(EigValues) Niterations = 1000 - +#while (iter <= Ni... or test) for iter in range(Niterations): gradients = 2.0/n*X.T @ ((X @ theta)-y) theta -= eta*gradients @@ -794,15 +804,15 @@ regression.

    Own inversion
    -[[3.96581896]
    - [3.03624103]]
    -Eigenvalues of Hessian Matrix:[0.26120167 4.71129677]
    +[[4.04881585]
    + [2.96745096]]
    +Eigenvalues of Hessian Matrix:[0.37175588 4.15690073]
     theta from own gd
    -[[3.96581896]
    - [3.03624103]]
    +[[4.04881585]
    + [2.96745096]]
     theta from own sdg
    -[[3.99729015]
    - [3.02646648]]
    +[[4.04015455]
    + [2.95745651]]
     
    _images/exercisesweek41_5_1.png @@ -924,14 +934,14 @@ first example shows results with ordinary leats squares.

    Own inversion
    -[[4.03656288]
    - [2.95497813]]
    -Eigenvalues of Hessian Matrix:[0.29560433 4.58257727]
    +[[3.37007195]
    + [3.48441798]]
    +Eigenvalues of Hessian Matrix:[0.32411274 4.30450049]
     
    theta from own gd
    -[[4.03656288]
    - [2.95497813]]
    +[[3.37007195]
    + [3.48441798]]
     
    _images/exercisesweek41_16_2.png @@ -1002,73 +1012,73 @@ Eigenvalues of Hessian Matrix:[0.29560433 4.58257727]
    Own inversion
     [[4.]
      [3.]]
    -Eigenvalues of Hessian Matrix:[0.27750534 4.13217667]
    -0 [-10.24816468] [-11.05638246]
    -1 [-0.1602625] [0.14404536]
    -2 [-0.14949972] [0.13437168]
    -3 [-0.13945974] [0.12534765]
    -4 [-0.13009402] [0.11692966]
    -5 [-0.12135727] [0.10907699]
    -6 [-0.11320726] [0.10175169]
    -7 [-0.10560458] [0.09491833]
    -8 [-0.09851247] [0.08854388]
    -9 [-0.09189665] [0.08259753]
    -10 [-0.08572513] [0.07705051]
    -11 [-0.07996807] [0.07187601]
    -12 [-0.07459764] [0.06704902]
    -13 [-0.06958788] [0.0625462]
    -14 [-0.06491455] [0.05834577]
    -15 [-0.06055507] [0.05442743]
    -16 [-0.05648836] [0.05077224]
    -17 [-0.05269476] [0.04736252]
    -18 [-0.04915593] [0.04418179]
    -19 [-0.04585476] [0.04121466]
    -20 [-0.04277528] [0.0384468]
    -21 [-0.03990261] [0.03586482]
    -22 [-0.03722287] [0.03345624]
    -23 [-0.03472308] [0.03120942]
    -24 [-0.03239118] [0.02911348]
    -25 [-0.03021588] [0.0271583]
    -26 [-0.02818667] [0.02533443]
    -27 [-0.02629373] [0.02363304]
    -28 [-0.02452792] [0.02204591]
    -29 [-0.02288069] [0.02056537]
    +Eigenvalues of Hessian Matrix:[0.27227895 4.125757  ]
    +0 [-11.75978215] [-12.89770892]
    +1 [-0.06807123] [0.06136823]
    +2 [-0.06357887] [0.05731824]
    +3 [-0.05938299] [0.05353553]
    +4 [-0.05546402] [0.05000245]
    +5 [-0.05180367] [0.04670255]
    +6 [-0.04838489] [0.04362042]
    +7 [-0.04519174] [0.04074169]
    +8 [-0.04220931] [0.03805295]
    +9 [-0.03942371] [0.03554165]
    +10 [-0.03682195] [0.03319608]
    +11 [-0.03439189] [0.03100531]
    +12 [-0.0321222] [0.02895911]
    +13 [-0.0300023] [0.02704796]
    +14 [-0.0280223] [0.02526293]
    +15 [-0.02617297] [0.02359571]
    +16 [-0.02444569] [0.02203851]
    +17 [-0.0228324] [0.02058408]
    +18 [-0.02132557] [0.01922564]
    +19 [-0.01991819] [0.01795684]
    +20 [-0.0186037] [0.01677178]
    +21 [-0.01737595] [0.01566493]
    +22 [-0.01622922] [0.01463112]
    +23 [-0.01515818] [0.01366555]
    +24 [-0.01415781] [0.01276369]
    +25 [-0.01322347] [0.01192135]
    +26 [-0.01235079] [0.0111346]
    +27 [-0.0115357] [0.01039977]
    +28 [-0.0107744] [0.00971344]
    +29 [-0.01006335] [0.0090724]
     theta from own gd
    -[[3.92308585]
    - [3.06913112]]
    -0 [-0.02134409] [0.01918426]
    -1 [-0.01991068] [0.01789589]
    -2 [-0.01814351] [0.01630755]
    -3 [-0.01639489] [0.01473588]
    -4 [-0.01476927] [0.01327475]
    -5 [-0.01328972] [0.01194492]
    -6 [-0.01195336] [0.01074379]
    -7 [-0.0107497] [0.00966192]
    -8 [-0.00966668] [0.0086885]
    -9 [-0.00869259] [0.00781297]
    -10 [-0.00781659] [0.00702562]
    -11 [-0.00702885] [0.00631759]
    -12 [-0.00632049] [0.00568091]
    -13 [-0.00568352] [0.00510839]
    -14 [-0.00511073] [0.00459357]
    -15 [-0.00459568] [0.00413064]
    -16 [-0.00413253] [0.00371435]
    -17 [-0.00371605] [0.00334002]
    -18 [-0.00334155] [0.00300342]
    -19 [-0.00300479] [0.00270073]
    -20 [-0.00270197] [0.00242856]
    -21 [-0.00242967] [0.00218381]
    -22 [-0.00218481] [0.00196372]
    -23 [-0.00196462] [0.00176582]
    -24 [-0.00176663] [0.00158786]
    -25 [-0.00158859] [0.00142784]
    -26 [-0.00142849] [0.00128394]
    -27 [-0.00128453] [0.00115455]
    -28 [-0.00115508] [0.00103819]
    -29 [-0.00103867] [0.00093356]
    +[[3.96547946]
    + [3.03112129]]
    +0 [-0.00939922] [0.00847367]
    +1 [-0.00877892] [0.00791445]
    +2 [-0.00801346] [0.00722437]
    +3 [-0.00725498] [0.00654058]
    +4 [-0.00654864] [0.00590379]
    +5 [-0.00590456] [0.00532314]
    +6 [-0.00532167] [0.00479764]
    +7 [-0.0047956] [0.00432337]
    +8 [-0.00432129] [0.00389577]
    +9 [-0.00389382] [0.00351039]
    +10 [-0.0035086] [0.00316311]
    +11 [-0.00316149] [0.00285017]
    +12 [-0.00284871] [0.0025682]
    +13 [-0.00256688] [0.00231412]
    +14 [-0.00231293] [0.00208517]
    +15 [-0.0020841] [0.00187888]
    +16 [-0.00187791] [0.00169299]
    +17 [-0.00169212] [0.0015255]
    +18 [-0.00152471] [0.00137458]
    +19 [-0.00137387] [0.00123858]
    +20 [-0.00123795] [0.00111605]
    +21 [-0.00111547] [0.00100563]
    +22 [-0.00100511] [0.00090614]
    +23 [-0.00090567] [0.00081649]
    +24 [-0.00081607] [0.00073571]
    +25 [-0.00073534] [0.00066293]
    +26 [-0.00066259] [0.00059734]
    +27 [-0.00059703] [0.00053824]
    +28 [-0.00053797] [0.00048499]
    +29 [-0.00048474] [0.00043701]
     theta from own gd wth momentum
    -[[3.99663433]
    - [3.00302509]]
    +[[3.99839581]
    + [3.00144622]]
     
    @@ -1121,17 +1131,17 @@ theta from own gd wth momentum
    Own inversion
    -[[3.81924504]
    - [3.09224244]]
    -Eigenvalues of Hessian Matrix:[0.31096156 4.57735536]
    -0 [-15.77829399] [-18.53684024]
    -1 [-3.15242624e-15] [-1.65243388e-16]
    -2 [3.85975973e-17] [5.35468713e-17]
    -3 [3.85975973e-17] [5.35468713e-17]
    -4 [3.85975973e-17] [5.35468713e-17]
    +[[3.81818338]
    + [3.12840176]]
    +Eigenvalues of Hessian Matrix:[0.26024513 4.64291046]
    +0 [-16.3824865] [-20.20867716]
    +1 [9.71640303e-15] [1.05750493e-14]
    +2 [-2.05998413e-17] [-2.11570114e-16]
    +3 [6.96057795e-17] [1.90885733e-16]
    +4 [6.96057795e-17] [1.90885733e-16]
     beta from own Newton code
    -[[3.81924504]
    - [3.09224244]]
    +[[3.81818338]
    + [3.12840176]]
     
    @@ -1220,20 +1230,18 @@ beta from own Newton code
    Own inversion
    -[[3.84019294]
    - [3.22756518]]
    -Eigenvalues of Hessian Matrix:[0.2729933  4.56108455]
    +[[3.6955259]
    + [3.2809076]]
    +Eigenvalues of Hessian Matrix:[0.31381731 4.50516278]
    +theta from own gd
    +[[3.6955259]
    + [3.2809076]]
     
    -
    theta from own gd
    -[[3.84019294]
    - [3.22756518]]
    -
    -
    -_images/exercisesweek41_22_2.png +_images/exercisesweek41_22_1.png
    theta from own sdg
    -[[3.85298956]
    - [3.28358004]]
    +[[3.6805151 ]
    + [3.33045013]]
     
    @@ -1315,15 +1323,15 @@ Eigenvalues of Hessian Matrix:[0.2729933 4.56108455]
    Own inversion
    -[[4.1356995 ]
    - [3.09209032]]
    -Eigenvalues of Hessian Matrix:[0.31362428 4.21949761]
    +[[3.98751068]
    + [2.92901115]]
    +Eigenvalues of Hessian Matrix:[0.28244905 4.61501312]
     theta from own gd
    -[[4.13531906]
    - [3.09242193]]
    +[[3.98556236]
    + [2.93059014]]
     theta from own sdg with momentum
    -[[4.25003261]
    - [3.05169046]]
    +[[4.01133846]
    + [2.92452609]]
     
    @@ -1398,9 +1406,9 @@ theta from own sdg with momentum
    theta from own AdaGrad
    -[[2.00006114]
    - [2.99959609]
    - [4.00040218]]
    +[[1.99974365]
    + [3.0013839 ]
    + [3.99861193]]
     
    @@ -1482,9 +1490,9 @@ theta from own sdg with momentum
    theta from own RMSprop
    -[[1.99952851]
    - [3.00380258]
    - [3.995522  ]]
    +[[1.99757634]
    + [2.9983289 ]
    + [3.99759503]]
     
    @@ -1570,9 +1578,9 @@ theta from own sdg with momentum
    theta from own ADAM
    -[[1.99984836]
    - [3.00097416]
    - [3.99895448]]
    +[[1.99993596]
    + [3.00035483]
    + [3.99963172]]
     
    @@ -1645,7 +1653,7 @@ It provides composable transformations of Python+NumPy programs: differentiate, return asarray(x, dtype=self.dtype) -
    [<matplotlib.lines.Line2D at 0x145270160>]
    +
    [<matplotlib.lines.Line2D at 0x1360ef5e0>]
     
    _images/exercisesweek41_39_2.png @@ -1680,7 +1688,7 @@ It provides composable transformations of Python+NumPy programs: differentiate,
    -
    <matplotlib.collections.PathCollection at 0x1452d6eb0>
    +
    <matplotlib.collections.PathCollection at 0x135f8b1f0>
     
    _images/exercisesweek41_41_1.png diff --git a/doc/LectureNotes/_build/html/exercisesweek42.html b/doc/LectureNotes/_build/html/exercisesweek42.html new file mode 100644 index 000000000..f044e2489 --- /dev/null +++ b/doc/LectureNotes/_build/html/exercisesweek42.html @@ -0,0 +1,825 @@ + + + + + + + + Exercises week 42 — Applied Data Analysis and Machine Learning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + +
    +
    + +
    + + + + + + + + + + + + + + +
    + + + +
    +
    +
    +
    + + + +
    + + + +
    +

    Exercises week 42

    +

    October 14-18, 2024

    +

    Date: Deadline is Friday October 18 at midnight

    +
    +
    +

    Overarching aims of the exercises this week

    +

    The aim of the exercises this week is to get started with implementing a neural network. There are a lot of technical and finicky parts of implementing a neutal network, so take your time.

    +

    This week, you will implement only the feed-forward pass. Next week, you will implement backpropagation. We recommend that you do the exercises this week by editing and running this notebook file, as it includes several checks along the way that you have implemented the pieces of the feed-forward pass correctly. If you have trouble running a notebook, or importing pytorch, you can run this notebook in google colab instead: (LINK TO COLAB), though we recommend that you set up VSCode and your python environment to run code like this locally.

    +
    +
    +
    import autograd.numpy as np
    +from autograd import grad
    +
    +
    +
    +
    +
    +
    +

    Exercise 1

    +

    Complete the following parts to compute the activation of the first layer.

    +
    +
    +
    np.random.seed(2024)
    +
    +
    +def ReLU(z):
    +    return np.where(z > 0, z, 0)
    +
    +
    +x = np.random.randn(2)  # network input
    +W1 = np.random.randn(4, 2)  # first layer weights
    +
    +
    +
    +
    +

    a) Define the bias of the first layer, b1with the correct shape

    +
    +
    +
    b1 = np.random.randn(4)
    +
    +
    +
    +
    +

    b) Compute the intermediary z1 for the first layer

    +
    +
    +
    z1 = W1 @ x + b1
    +
    +
    +
    +
    +

    c) Compute the activation a1 for the first layer using the ReLU activation function defined earlier.

    +
    +
    +
    a1 = ReLU(z1)
    +
    +
    +
    +
    +

    Confirm that you got the correct activation with the test below.

    +
    +
    +
    sol1 = np.array([0.60610368, 4.0076268, 0.0, 0.56469864])
    +
    +print(np.allclose(a1, sol1))
    +
    +
    +
    +
    +
    True
    +
    +
    +
    +
    +
    +
    +

    Exercise 2

    +

    Compute the activation of the second layer with an output of length 8 and ReLU activation.

    +

    a) Define the weight and bias of the second layer with the right shapes.

    +
    +
    +
    W2 = np.random.randn(8, 4)
    +b2 = np.random.randn(8)
    +
    +
    +
    +
    +

    b) Compute intermediary z2 and activation a2 for the second layer.

    +
    +
    +
    z2 = W2 @ a1
    +a2 = ReLU(z2)
    +
    +
    +
    +
    +

    Confirm that you got the correct activation shape with the test below.

    +
    +
    +
    print(a2.shape == (8,))
    +
    +
    +
    +
    +
    True
    +
    +
    +
    +
    +
    +
    +

    Exercise 3

    +

    We often want our neural networks to have many layers of varying sizes. To avoid writing very long and error-prone code where we explicitly define and evaluate each layer we should keep all our layers in a single variable which is easy to create and use.

    +

    a) Complete the function below so that it returns a list layers of weight and bias tuples (W, b) for each layer, in order, with the correct shapes that we can use later as our network parameters.

    +
    +
    +
    def create_layers(network_input_size, output_sizes):
    +    layers = []
    +
    +    i_size = network_input_size
    +    for output_size in output_sizes:
    +        W = np.random.rand(output_size, i_size)
    +        b = np.random.rand(output_size)
    +        layers.append((W, b))
    +
    +        i_size = output_size
    +    return layers
    +
    +
    +
    +
    +

    b) Comple the function below so that it evaluates the intermediate z and activation a for each layer, and returns the final activation a. This is the complete feed-forward pass, a full neural network!

    +
    +
    +
    def feed_forward(layers, input):
    +    a = input
    +    for W, b in layers:
    +        z = W @ a + b
    +        a = ReLU(z)
    +    return a
    +
    +
    +
    +
    +

    c) Create a network with input size 8 and layers with output sizes 10, 16, 6, 2. Evaluate it and make sure that you get the correct size vectors along the way.

    +
    +
    +

    Exercise 4

    +

    So far, every layer has used the same activation, ReLU. We often want to use other types of activation however, so we need to update our code to support multiple types of activation. Make sure that you have completed every previous exercise before trying this one.

    +

    a) Make the create_layers function also accept a list of activation functions, which is used to add activation functions to each of the tuples in layers. Make new functions to not mess with the old ones.

    +
    +
    +
    def create_layers_4(network_input_size, output_sizes, activation_funcs):
    +    layers = []
    +
    +    i_size = network_input_size
    +    for output_size, activation in zip(output_sizes, activation_funcs):
    +        W = np.random.rand(output_size, i_size)
    +        b = np.random.rand(output_size)
    +        layers.append((W, b, activation))
    +
    +        i_size = output_size
    +    return layers
    +
    +
    +
    +
    +

    b) Update the feed_forward function to support this change.

    +
    +
    +
    def feed_forward_4(layers, input):
    +    a = input
    +    for W, b, activation in layers:
    +        z = W @ a + b
    +        a = activation(z)
    +    return a
    +
    +
    +
    +
    +

    c) Create and evaluate a neural network with 4 inputs and layers with output sizes 12, 10, 3 and activations ReLU, ReLU, softmax.

    +
    +
    +
    from scipy.special import softmax
    +
    +network_input_size = 4
    +output_sizes = [12, 10, 3]
    +activation_funcs = [ReLU, ReLU, softmax]
    +layers = create_layers_4(network_input_size, output_sizes, activation_funcs)
    +
    +x = np.random.randn(network_input_size)
    +predict = feed_forward_4(layers, x)
    +
    +
    +
    +
    +

    The final exercise will hopefully be very simple if everything has worked so far. You will evaluate your neural network on the iris data set (https://scikit-learn.org/1.5/auto_examples/datasets/plot_iris_dataset.html).

    +

    This dataset contains data on 150 flowers of 3 different types which can be separated pretty well using the four features given for each flower, which includes the width and length of their leaves. You are not expected to do any training of the network or actual classification, unless you feel like it, in that case you can do exercise 5.

    +
    +
    +
    # Loading and plotting iris dataset
    +from sklearn import datasets
    +import matplotlib.pyplot as plt
    +
    +iris = datasets.load_iris()
    +
    +_, ax = plt.subplots()
    +scatter = ax.scatter(iris.data[:, 0], iris.data[:, 1], c=iris.target)
    +ax.set(xlabel=iris.feature_names[0], ylabel=iris.feature_names[1])
    +_ = ax.legend(
    +    scatter.legend_elements()[0], iris.target_names, loc="lower right", title="Classes"
    +)
    +
    +
    +
    +
    +_images/exercisesweek42_34_0.png +
    +
    +

    c) Loop over the iris dataset(iris.data) and evaluate the network for each data point.

    +
    +
    +
    # No need to change this cell! Just make sure it works!
    +for x in iris.data:
    +    prediction = feed_forward_4(layers, x)
    +
    +
    +
    +
    +
    +
    +

    Exercise 5 (Very optional and very hard :)

    +

    a) Make the iris target values into one-hot vectors.

    +

    b) Define the cross-entropy loss function to evaluate the performance of your network on the data set.

    +

    c) Use the autograd package to take the gradient of the cross entropy wrt. the weights and biases of the network.

    +

    d) Use gradient descent of some sort to optimize the parameters.

    +

    e) Evaluate the accuracy of the network.

    +

    e) Show off how you did in a group session!

    +
    + + + + +
    + + + + + +
    +
    +
    +

    + + By Morten Hjorth-Jensen
    + + © Copyright 2021.
    +

    +
    +
    + + +
    +
    + + + + + \ No newline at end of file diff --git a/doc/LectureNotes/_build/html/genindex.html b/doc/LectureNotes/_build/html/genindex.html index e156a36e7..6fbd90fe7 100644 --- a/doc/LectureNotes/_build/html/genindex.html +++ b/doc/LectureNotes/_build/html/genindex.html @@ -319,6 +319,16 @@ const thebe_selector_output = ".output, .cell_output" Week 41 Neural networks and constructing a neural network code +
  • + + Exercises week 42 + +
  • +
  • + + Week 42 Constructing a Neural Network code with examples + +
  • diff --git a/doc/LectureNotes/_build/html/intro.html b/doc/LectureNotes/_build/html/intro.html index 77b08985a..744fbc75f 100644 --- a/doc/LectureNotes/_build/html/intro.html +++ b/doc/LectureNotes/_build/html/intro.html @@ -320,6 +320,16 @@ const thebe_selector_output = ".output, .cell_output" Week 41 Neural networks and constructing a neural network code +

  • + + Exercises week 42 + +
  • +
  • + + Week 42 Constructing a Neural Network code with examples + +
  • diff --git a/doc/LectureNotes/_build/html/objects.inv b/doc/LectureNotes/_build/html/objects.inv index 1c0b4dc14c6e0538ff22156fc2c77d6224fc2ec0..29c3fa7cea4b3a73119e89c9bb1cd7abd6e2b184 100644 GIT binary patch delta 1065 zcmV+^1lIeC39Si`b$^#jbE7yA$M1ZKJ|J?maODV3nAXxH1f}yX8}Ai79#Arw?oHkYj&Ch5lu(n;6VG-Ctjyq! zDJ23M9?GRlMX{pFO}Km1dy#c3NCHktbFyN`mF8(6)HL8VZH}X^Dj_xegQ*r0?wMI7 zsu2ip&5Rda2D1Qbf96=%m~s;qw8YO4^8jM*5I3d5Vw+>T?iJihQBc`E6NJp)i40m$ zp5@U#D7(iu?-a5?_$mZ#LAe`|KWfl>guiO*C|-tJxd>#jXv&=_+DD!tQ^wI?Hj$qn{VsOmb(mamyY|;FRa!>RGJt3e?NNz0?z(x$9eQDBb#1I z`51J?=qxE^vpvmOcJ~NazN4e2`&C3~UMoTys~@nlHkaz-E3?agm#VH%9=IY2=x!&z zqoi|3^@jL*)hp1!tLBJXBN!`OB?H3rJYgCpOb3M7dBQAAm<q&l8qmf5Ng)NG4|q$s|ZfCIdozo)Cu#akN7!iwxhbYtFWq8|T*Qy#6%*Mx1I^ z_z|qZeX*`c|ESEanPwjs%~avAtRvD%s%)R*EWL)e&Ud(#Yy^K0!zwG?lC_lV=%|H| zbjgpT5GA!ZrfZVWs1R9TDb?{y`@)5|7g^ZJg=wT13e+x97=S7qeAU`BRW9w{^pq@RPcHSNp2->@A-bausJn~Qd?oCP1>?8&$*^%vPU70wicdS7ZTK7{YBd3jj|V@wRtNuUl`Eu zl9{QA+}`z8h}VH%V{9Fp$LLf?efj+1L~})ZO_wFBQ`w?Ty0qpPqNE1+2615u;qf>qM zW!Zt}tIrTNL}0`^)oov{9eJ?|%~_V{H|6M5!F}O&tmUfbV^D&! zL|z++O~}tnb%d)B;mQ%7FsY?U2ukN&Hr{J^JfLJU*_*r%9N$`AD4`~wC!S^qtW4pK zDJ23059QLOqF7PoCfq&hy-2$i!~v(c*;$csrFjwvH4Avnn(e5oN=Oa=V4{VDduCRN zY6QYtGvh^>JSCftMtE%7tNB7j&p#7(KN*yY%+dkwcz6x4Rl1R?WxB7+u` zXL+I&t7E0TcjbmBWo z+ILiMh_6?@1|1AFTihDKSm7!j5N78IvoK*cAk5Db=3&BoKvi`3&ADcR9c3nA%<9_f6SbU`s) zlK@7ANCQi$j$hgV7vf%|H3@`UR3*hvQo>&4TAQ1`e|29l0g5$T%?L;{Oo9lHq^CQS zuz-t#rzOw!`f>!*@icCOOanot{UFm{1bHBdEliXcF7DeXk+;NOti35&uLLUDqy6-< zYi-W!J2EHg-Bf#NQ%0}Kh;zY=Xs|p|Xym`2gR?c4j~m~z3?rpU&dmL#dVxD@)37MxTvMVQFoKOG`5l@b~RjcZ1}Si{>(gGOO<>b|8LVof@Ih9dgJzbFbI)EK+d;n$$hwq3}wf9BdMVSn}ERXO?OVft-ao>OW(rAj&|7A#85l+nm A&Hw-a diff --git a/doc/LectureNotes/_build/html/search.html b/doc/LectureNotes/_build/html/search.html index c3546544a..0a1e35e24 100644 --- a/doc/LectureNotes/_build/html/search.html +++ b/doc/LectureNotes/_build/html/search.html @@ -325,6 +325,16 @@ const thebe_selector_output = ".output, .cell_output" Week 41 Neural networks and constructing a neural network code +

  • + + Exercises week 42 + +
  • +
  • + + Week 42 Constructing a Neural Network code with examples + +
  • diff --git a/doc/LectureNotes/_build/html/searchindex.js b/doc/LectureNotes/_build/html/searchindex.js index 4d8095c28..944ed7da0 100644 --- a/doc/LectureNotes/_build/html/searchindex.js +++ b/doc/LectureNotes/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["chapter1","chapter10","chapter11","chapter12","chapter13","chapter2","chapter3","chapter4","chapter5","chapter6","chapter7","chapter8","chapter9","chapteroptimization","clustering","exercisesweek34","exercisesweek35","exercisesweek36","exercisesweek37","exercisesweek38","exercisesweek39","exercisesweek41","intro","linalg","project1","project2","schedule","statistics","teachers","textbooks","week34","week35","week36","week37","week38","week39","week40","week41"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["chapter1.ipynb","chapter10.ipynb","chapter11.ipynb","chapter12.ipynb","chapter13.ipynb","chapter2.ipynb","chapter3.ipynb","chapter4.ipynb","chapter5.ipynb","chapter6.ipynb","chapter7.ipynb","chapter8.ipynb","chapter9.ipynb","chapteroptimization.ipynb","clustering.ipynb","exercisesweek34.ipynb","exercisesweek35.ipynb","exercisesweek36.ipynb","exercisesweek37.ipynb","exercisesweek38.ipynb","exercisesweek39.ipynb","exercisesweek41.ipynb","intro.md","linalg.ipynb","project1.ipynb","project2.ipynb","schedule.md","statistics.ipynb","teachers.md","textbooks.md","week34.ipynb","week35.ipynb","week36.ipynb","week37.ipynb","week38.ipynb","week39.ipynb","week40.ipynb","week41.ipynb"],objects:{},objnames:{},objtypes:{},terms:{"0":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,27,28,30,31,32,33,34,35,36,37],"00":[0,1,5,6,9,11,30,31,32,36,37],"000":[1,3,9],"0000":9,"00000":[9,11,35],"000000":[5,11,31],"00000000e":[5,31,36,37],"00001":35,"00001572":[],"00001716":[],"00002":35,"00002276":36,"00002585e":[],"00002833":36,"00003":35,"00003645":[],"00003828":[],"00005":35,"00006114":21,"00007":35,"00007706":[],"00007738":[],"00008335":[],"00009":35,"00009004":36,"0001":[1,17],"00010067":35,"00010366":[],"0001079":36,"00011562":36,"00011577":[],"00012":35,"00012565":36,"00013464":36,"000137":[],"00013938":37,"00013955":[],"00014166":[],"00014631":36,"00015678":36,"00016062":[],"00016449":[],"00016535":[],"00016719":35,"00017038":36,"00017733":[],"00018":35,"00018053":[],"00018212":[],"00018256":36,"00018651":[],"00019258":[],"0001984":36,"00019998":5,"0002065":[],"00021147":[],"00021259":36,"00021270681344726395":[],"00021771":37,"00021916":[],"000225":35,"00022969":[],"00023":35,"00023102":36,"00023414":[],"00023813":[],"00023978":[],"00024087":5,"00024755":36,"00024929":35,"00025662":35,"00026549":[],"000269":36,"00027188":[],"0002762":35,"00027746":35,"00028":35,"00028167":35,"00028825":36,"00029012":5,"0002926":[],"00030102":[],"00030601":35,"00030827":[],"00031208":35,"00031321":36,"00031535148309577417":[6,32],"0003153514830958095":[6,32],"00033415":31,"00033562":36,"00033679":[],"00033904":35,"00034006":37,"00034132":[],"00034209":36,"00034576":35,"00034688149480437765":[],"00034944":5,"00034953":[],"00036464":36,"0003701342170783489":[],"00037564":35,"00037737":[],"00038309":35,"000387":[],"00039072":36,"00039632":[],"00040218":21,"00041619":35,"000417932":2,"00042089":5,"00042093":35,"00042436":36,"00042444":35,"00042721":[],"0004388":[],"00044":35,"00044937":[],"00045472":36,"00046006":35,"00046111":35,"000464088":2,"00046631":[],"00047025":35,"00048158":[],"00049344":36,"00049636":[],"00049754":[],"00050694":5,"00050952":[],"00051088":35,"00051916":[],"00052102":35,"00052874":36,"00053001":[],"00053118":37,"00053122":[],"00056414":[],"00056603":35,"00057256":36,"00057726":35,"00057772":[],"00058016":[6,32],"00060":35,"00060704":6,"00061058":5,"00061352":36,"00062592":6,"00062668":[],"000626681519836":[],"00062713":35,"00063362":33,"00063866":33,"00063957":35,"00063965":[],"00065505":[],"00066091":36,"00066668":[6,32],"00067008":35,"00068091":33,"00068734":[6,32],"00069":35,"00069123":6,"00069482":35,"00070819":36,"0007086":35,"00072527":[],"00073541":5,"00074274":[],"00075296":36,"00075590":33,"00076202":35,"00076495":[6,32],"00076521":31,"00076908":6,"00076983":35,"0007698473260556325":[6,32],"0007698473260556343":[6,32],"000783":[],"00078324":[],"00078509":35,"00079125":6,"00079904":33,"00079968":5,"00080497":[],"00080683":36,"00082235":[],"00082916":36,"0008297":37,"0008297120772365539":[],"00083355":33,"00084215":[],"00084707":6,"00085292":35,"00085892":6,"00086984":35,"00087697":[6,32],"00088573":5,"00088848":36,"00089193":33,"00091307":36,"00092678":6,"00092898":33,"00093243":[],"00093356":21,"00094499":35,"00095488":[],"00095624":[],"00096314":5,"00096373":35,"00097416":21,"00097839":36,"00099778":[],"001":[1,2,8,13,17,32,34,35],"00100081":[],"00100202":31,"00100519":[6,32],"00100546":36,"00100913":[],"00103819":21,"00103867":21,"001047":35,"0010479245693919886":[6,33],"00105081":[6,32],"00105724":[],"00106677":5,"00106776":35,"00107405":[6,32],"00107739":36,"00108":35,"0010827":[],"00108471":[],"00109354":[],"001106660107757":27,"00110721":36,"00111756":[6,32],"00114401":[],"00114451":[],"00114855":[],"0011526":[6,32],"00115455":21,"00115508":21,"00115631":35,"00115999":5,"00116001":35,"00116737":[],"00118302":35,"00118584":6,"00118642":36,"00119688":33,"00119876":[],"00121925":36,"00122762":[],"00125057":[],"00126053":35,"001268544905013411":9,"00128394":21,"00128453":21,"00128479":5,"00128523":35,"00129599":37,"0013052":[],"00130648":36,"00130885":[],"00131072":35,"001323":[6,32],"00133638":[],"00134264":36,"00134424":[],"00135237":[],"00135922":[],"00136125":[],"00137814":6,"00139195":[],"00139705":5,"0014028":31,"00140846":33,"00141727":35,"00142396":35,"00142784":21,"00142849":21,"00143013":[],"00143869":36,"00144539":35,"0014522":35,"0014593":[],"001468":[],"00146807":[],"0014785":36,"00149311":[6,32],"00149679":[],"00149956":[6,32],"00151204":[],"00151416":[],"00151426":[],"00152117":[6,32],"00154115":[],"00154733":5,"00154853":33,"00156374":6,"00157766":35,"00157826":[],"00158":35,"00158427":36,"00158786":21,"00158859":21,"00160895":35,"00161463":[],"00162812":36,"00162921":[],"00163159":[],"00163548":[],"00167329":35,"00168251":5,"00168745":[],"00169":35,"00169056":[],"00170579":[],"00170809":[],"00171171":[],"00172865":[],"00174276":[6,32],"00174459":36,"00174738":[],"00174743":[],"00174795":35,"00175331":[6,32],"00176582":21,"00176663":21,"00178263":35,"00178952":[],"00179288":36,"001795":[],"00180673":35,"00181885":[],"00182423":[],"0018310257999764163":[],"00186347":5,"00187032":[],"0018798":[],"001880":5,"00189016":[],"00191076":[],"00192114":36,"00192154":[],"00193661":35,"0019575":[],"00196372":21,"00196462":21,"00197431":36,"00197505":35,"00198129":[],"00200":8,"00202433":37,"00202624":5,"00202756":[6,32],"00202904":[],"00203961":[],"0020489":[],"00206234":[],"00208188":35,"00209403":[],"00211332":[],"00211418":[],"00211555":36,"00211924":[],"00212766":[],"00213888":[],"00214559":35,"00216458":[],"0021741":36,"00217499":[6,32],"00217968":[],"00218381":21,"00218481":21,"00218823":35,"00219195":33,"00220013":[],"00223857":[],"00224413":5,"00224638":[],"00225842":35,"0022626":[],"00228042":[],"00228740":6,"00229111":[],"00230059":[],"00230805":[],"00232963":36,"0023548":[6,32],"00236284":[],"00236918":[],"00237699":35,"002381316302584885":[6,32],"0023813163025848865":[6,32],"0023941":36,"00242441":35,"0024271":[],"00242856":21,"00242954":33,"00242967":21,"00242999":6,"00243186":[6,32],"00243835":[],"0024401":5,"002446":[],"00248232":[],"00248779":36,"00249435":[6,32],"00250787":[],"00251359":[],"00254671":[],"00254966":[],"00254973":[],"00256001":[],"00256537":36,"00256622":[],"00259997":[],"00260839":[],"00263296":35,"00263638":36,"00263755":[],"00263812":[],"00264":35,"00264181":[],"00266858":2,"00268602":35,"00270073":21,"00270197":21,"00270244":5,"00270262":[],"00272337":[],"00274212":31,"00274676":[],"00274989":[6,32],"00275768":[],"00279722":[],"00282226":[],"00282302":35,"00282498":36,"00285068":[],"00288656":[],"00289724":[6,32],"00290316":36,"00290613":[],"00291535":35,"0029276":[],"00292882":[],"00293758":[],"00293838":5,"00295372":[],"00295713":[],"00297571":35,"00298783":[],"00300342":21,"00300479":21,"0030094":[],"00302509":21,"00302547":[],"00309418":[],"00310113":2,"00311085":36,"00312361":[6,32],"00315593":6,"003162":37,"00318725":[],"00319695":36,"00319887":[],"0032153180657605116":[6,33],"00322456":35,"00323332":[6,32],"0032542":5,"00325450":33,"00326986":[],"00327104":[],"00327797":[],"00329616":35,"00329927":[],"00330046":[],"003301":[6,32],"00330245":[],"00331927":[],"00334002":21,"00334047":[],"00334155":21,"00334797":[],"00335101":[],"00335174":[],"0033955154592040936":[6,33],"00340452":31,"00342565":36,"0034318":35,"00347534":[],"00348246":[],"00348281":36,"00348553":[],"00352046":36,"00352878":35,"00353823":5,"00353938":[],"00355323":31,"00355614":35,"00356356":[],"00359628":[],"0036237":[6,32],"0036367":[6,32],"00363823":[],"00364159":[],"00364235":[],"00364967":35,"00365819":[],"00369201":31,"00369236":[],"00369758":[6,32],"00369852":[],"00371435":21,"00371605":21,"00371656":[],"0037314":[],"00377231":36,"00379682":[],"00380258":21,"0038287":[],"0038335":[6,32],"00387671":36,"00389038":35,"003909404072811226":[6,33],"00391839":5,"0039259":[],"00392639":[],"0039455":[],"00398429":[],"00399521":[],"0039987":[6,32],"00399972":[],"004":[5,32,33],"00403677":35,"00405581":[],"0040792":[],"00408":35,"004091940707753939":[6,33],"00410183":31,"00410387":[6,32],"00410478":6,"004113634617443131":[6,31,32],"00411363461744314":[6,31,32],"004113634617443147":[6,31,32],"0041148":[],"00412":35,"0041283":[],"00413064":21,"00413253":21,"00415405":36,"00415497":[],"00415598634586135":[6,33],"00416103":35,"00416704":[],"00418347":[],"00418664":[],"00420072":33,"00424909":2,"00424967":[6,32],"00426027":5,"00426902":36,"00429456":[],"0042992":35,"00432864":[],"00433417":11,"00434043":[],"0043587":[],"00437846":[],"00438318":[],"00440346":[6,32],"00441097":35,"004423":[],"00443743":[6,32],"0044505":35,"00445186":35,"0044547":[],"00445655":11,"0045162":[],"00455966":[],"00457441":36,"004579219539673834":[6,33],"00458631":[],"00458878":[6,32],"00459357":21,"00459568":21,"004610275230656212":[6,33],"00461571":[],"00462287":[6,32],"00462662":[],"00463124":31,"00464677":[],"00465099":33,"0046544":[],"00468914":[],"00470102":36,"00471617":[],"00471782":5,"00472199":6,"00472276":[],"00472512":[6,32],"00474898":[],"00476012":35,"00478417":[],"00480881":[],"00483858":[],"00487029":35,"00493903":37,"0049544":[6,32],"00497837":32,"00498065":[],"00498243":[],"004999999999999991":[],"004999999999999996":0,"005":[],"005000000000000001":[],"00500716":[],"00502886":[],"00503732":36,"00503932":[],"00507531":[],"00509128":35,"00510839":21,"00511073":21,"00512599":[],"00512927":5,"00513051":[],"00515181":[],"00515889":[],"00516067":[],"00517114":[6,32],"00517673":36,"00519717":[],"00520911":35,"00521014":[],"00522055":[],"00526348":[6,32],"00527578":[],"00528252":31,"0053018":[6,32],"00531268":[],"00537955":[],"00539563":[],"00544547":35,"00546503":[],"00547113":[],"00551372":35,"00552462":[],"00554202":[],"00554552":[6,32],"00554707":36,"00556826":[6,32],"0055687":[],"00556946":[],"0055715":35,"00557893":[],"0055997":[],"00560098":[],"00561212":31,"00561262":[],"005643":[],"00564344":[],"00564365":35,"00566707":[],"0056799":5,"00568091":21,"00568352":21,"00569512":[],"00570059":36,"00570321":[],"0057065":[],"00571608":[],"00571884":31,"00572613":[],"00573661":[],"00573727":[],"00574735":[],"00575681":31,"00576997":[],"00578809":[],"00579953":[6,32],"0058243":35,"00585143":[],"00586355":[],"00588657":[6,32],"00588836":31,"0059267":[],"00593362":[],"0059591":35,"00597698":[],"00598464":[],"00606382":[],"00607783":6,"0061084":36,"006162":[6,32],"00617221":[],"00617499":5,"0062202":[],"00622617":[],"00622949":35,"00623535":[],"00625051":[],"00625672":[],"00627115":[],"00627746":36,"00630331":[6,32],"00631759":21,"00632049":21,"00632251":[],"00633289":[],"00634299":[],"00634575":[],"00635016":[],"00637188":[],"00637367":35,"0063878":[],"00641423":[],"00642221":[6,32],"00642737":[],"00644":35,"0064472":32,"00645121":[],"00647029":[],"00654835":[],"00657601":31,"00659604":[],"00660427":[6,32],"00666287":35,"00667611":[],"00672505":31,"00672607":[6,32],"00672654":36,"00673407":[6,32],"00674158":[],"00676256":[],"00676387":[6,32],"00677215":31,"00679013":[],"0068011":[6,32],"00681708":35,"00683748":5,"00683875021199284":[],"00683964":[6,32],"00685287":[],"00687309":[],"00688012":[],"00688182":[],"00689214":35,"00691012":[],"00691271":36,"00694315":[],"00696127":[],"0069668":[],"00697033":[],"007024126888938232":[6,33],"00702562":21,"00702721":[],"00702885":21,"0071129":[],"00712219":[],"0071264":35,"00715512":[],"00719176":[6,32],"00721287":[],"00727646693":[0,30],"00729134":35,"00731392e":[],"007315":31,"00732665":[],"0073544":31,"00736737":31,"007370297974992432":31,"00737863":31,"00740723":36,"0074331":5,"00746317":[],"00747773":[],"00748862":[],"00754823":[],"00755917":[],"00759119":6,"00759427":[],"00761224":36,"00762217":35,"00764333":[],"007658477904313023":[],"0076989":[],"00771475":37,"0077313":[],"00774376":31,"00778316":[],"00779859":35,"00781297":21,"00781659":21,"00781918":33,"00784393":[6,32],"00789262":[],"00791263":[],"00792032":[],"00798909":[],"00802302":[],"00803064":[6,32],"008043811612683473":[],"00805074":33,"00806447":[],"00809364":[],"00812487":[],"00813803":6,"00815244":35,"0081568":36,"00816675":[],"00817631":[6,32],"00818251":[],"00819774":[],"00823002":5,"00827728":[6,32],"00828121":[],"00831018":[6,32],"00834112":35,"00834567":[6,32],"00836649":31,"00838255":36,"00838555":[],"00848739":31,"00848904":[6,32],"0085548":[],"008560581831215528":[],"0085639":[],"00859693":[],"00860892":[],"00861518":35,"0086649156":[0,30],"008675369724975977":5,"0086885":21,"00869259":21,"00870208":[],"00871959":35,"008753288788081405":[],"00877737":[],"00881939":[],"00885858":[],"00889027":[],"00889475":[],"00891702":[],"0089214":35,"00894639":5,"00898223":36,"00901661":[],"00903778":[],"00905423":[6,32],"00908537":[],"009134699065945493":5,"009163470508352218":5,"009164545680330616":[6,33],"00917248":[6,32],"00919984":[],"009211602191395454":[],"00923082":36,"00923474":31,"00925406":35,"00930146":[],"0093262":35,"009338082195270294":[],"00934327e":31,"00934499":[6,32],"00935742":[],"00939407":[],"009396472959497925":[],"00940611":[],"00942574":[],"00943959":[],"00951885":[],"00954206":35,"00955125":[],"00956827":[],"00958615":[],"0096208":[6,32],"00963683":[],"00964129":[],"00966192":21,"00966668":21,"0096667":31,"00969623":31,"00972948":[],"00974758":[],"00979357":[],"00982052":[],"009880124918446542":31,"00988356":31,"00988992":31,"00989118":36,"00989834e":[],"00990475":5,"00992331":[6,32],"00996754":[6,32],"00996762":[],"00997502":35,"01":[0,1,2,5,6,9,11,13,17,21,29,30,31,32,35,36,37],"010018312644137363":[6,33],"01003519":[],"01006":35,"01006224":31,"01006984":[],"0100706":[6,32],"01008116":[],"01009321":[],"01013849":[],"01014331":[],"010148621093080332":31,"01016493":36,"01018089":[],"01020588":35,"01024875":[],"01031":35,"01032298":[],"01032533":[],"010331721306655127":[6,33],"010348289064969316":[],"01035006":[],"01039879":[],"01044475":[],"01045576":[],"010516485576645508":[6,33],"01059242":31,"01060492":[],"010612904886352397":[],"01066519":[6,32],"01066897":35,"01067432":[],"01070103":[],"01074379":21,"0107497":21,"01075018":[],"01076611":5,"01076897":35,"01078008":31,"01080465e":[],"01084359":[],"01085571":[],"01087815":[],"01089212":36,"01091589":35,"01093529":[],"01093553":[],"01094916":31,"01097287":31,"01098247":[],"0110":27,"01107333":[],"011076219011379514":[6,33],"011156605304609659":[],"01119357":36,"01119504":[],"01119738":[],"01119981":[],"011208613520466846":[],"011225":2,"01123792e":[],"01127138":[],"01129731":[],"0113104":[6,32],"01131771":[],"01133903":[],"01141119":35,"01146857":[],"01150437":31,"01151556":31,"01161645":[],"01163942":31,"0116753":35,"01178583":27,"01178857":[],"01179128":[],"01179415":[],"01179792":[6,32],"011818646101922625":[],"011886":[],"01191824":5,"01194492":21,"01195336":21,"01196506":31,"01199434":36,"01199741":[],"01205039":37,"01206221":[],"012073649446193166":[6,33],"0121289":[],"01214076":[],"01214862":[],"01216231":[],"0121766":[],"01218403":31,"01219292":[6,32],"01220505":35,"01222822":31,"01222875":[],"01223198":[6,32],"01223754":[],"01229102":[],"01229692":[],"01231917":[6,32],"01232366":31,"0123263":36,"01234":[],"01234261":[],"01241284":[],"012423940191689783":11,"01244297":[],"01247909":[],"01248754":35,"01249445":[],"01250964":[],"01260207":[],"01261048":[],"01265755":31,"012658":31,"01266999":[],"01267007":32,"0126711":[],"01268737":[],"01280793":[],"01288787":[],"01290947":[6,32],"0129191":[],"01295356":5,"01305415":35,"013121574015585152":[6,33],"013121574015585155":[6,33],"01315875":[],"01316233":[],"01316638":[],"01318643":[6,32],"0132081":36,"01323341":31,"01323523":[],"01327148e":[],"01327475":21,"01328972":21,"01329403":[],"01332832":[],"01333573":[],"01335628":35,"0134113":[],"01346122":35,"01347916":[6,32],"01348565":[6,32],"01349244":[],"01353638":[],"01355882":[],"01357366":36,"01359774":[],"01367553":[6,32],"0137297":35,"01373484":[],"01376216":[],"01377545":[],"01393496":[],"01396231":35,"01397146":[6,32],"01399457":[],"01405935":[6,32],"01406777":[],"01408975":[],"01409478":[],"01416528":[6,32],"01418766":23,"01425384":31,"01427864":[],"01428546":35,"01433809":5,"014436800088904942":[6,33],"01444013":[],"0144623":[],"01449782":[6,32],"01454469":36,"01455304":[],"01456865":31,"01458337":[6,32],"014586":31,"01458611":31,"0146081":[6,32],"01462254":[],"01463049":[6,32],"01464686":[],"01473588":21,"01473759":[],"01476927":21,"01480256":[],"01480927":31,"01493365":35,"014934":35,"01499192":[],"01506354":[],"01507238889517706":[6,32],"01507238889517717":[6,32],"01509793":[],"01511937":35,"01512884":31,"01520159":[],"01522108":[],"01527928":35,"01530321":[],"01531845":[6,32],"01532738":[],"01543076":[],"01546126":31,"01548486":[],"01549377":[6,32],"01551724":[],"01551775":[],"015518":[],"01551815":[],"01552874":[],"01558197":5,"01568403":[],"01572":35,"01573062":[],"01573768":[],"01575266":[],"01584129":[],"01594452":33,"01597256":35,"01600363":[],"01604235":[],"01615836":36,"01620955":[],"01624447":[],"01625794":[],"01628578269596628":[6,33],"01630755":21,"01633913":[6,32],"01634224":35,"01639344":[],"01639489":21,"01640891":6,"01641044":[],"01643795":[],"01647074":31,"0164974":[],"01654574":[],"01655318":[6,32],"01655384":[],"016587414993043573":[6,33],"01674956":[],"01679297":[],"01681173":[],"01681612":[],"0168171":31,"01682652":35,"01691985":[6,32],"0169643":5,"01699169":[],"01700897":[],"01701429":31,"01706166":[],"01708375":35,"01708781":[6,32],"01708852":[6,32],"01713366":[6,32],"01717549":[],"01722503":[],"01724499":5,"017355848195593347":[6,33],"01735584819559336":[6,33],"01737634":[],"01740381":31,"01747915":35,"01748034":[],"01756114":[],"01759442":[],"01759974":[],"01760144":[],"01761069":[],"017665":5,"01772779":[],"01779091e":[],"01783096":[],"01783414e":31,"0178462":[],"01789589":21,"01793261":[],"01793972":27,"0179826":[],"01811279":[],"01813363":31,"01814351":21,"01817048":[],"01817739":23,"0182116":[],"018232":31,"01826811e":[],"01827225":35,"01827302":[],"01830039":[],"01831050e":[6,32],"01831190e":[6,32],"01844584":[],"01844822":[],"01846605":[],"01863203":[],"01866537":[6,32],"01869515":35,"01872002":[],"01873344":11,"01873869":5,"01881237":[],"01882218":31,"01882264":37,"01897462":[],"01898383":[],"01898855":[6,32],"01905384":[],"01905883":[6,32],"01908936":[6,32],"01915337":[],"01918426":21,"01922269":[],"0193075":[],"0195302":[],"01954342":35,"01963611":[6,32],"01968447":[],"01969093":[],"01969145":[6,32],"01975006":[],"01975416527185249":[6,33],"01975848":[6,32],"01979808":[],"01991068":21,"01999575":35,"02":[0,4,6,7,12,30,32,34,36,37],"0200041":[],"02014577":[],"02016185":[],"02024962":[6,32],"02025574":31,"02026756":[],"02031987":[],"02032056":[],"02034655":[],"02054837e":[6,32],"02056537":21,"0206033":[],"02068067":[6,32],"02073509":5,"02077431":32,"02079913":[],"02084474":[],"02087411":[],"02088307":31,"02090304":35,"02091662":[],"02092464":[],"02098261":[6,32],"02102403":[],"02103315":35,"02104639":31,"0211429":[],"02117843":[],"02118344":[],"02123176":[6,32],"02124568":30,"02126205":[],"02134409":21,"02137508":[],"02138683":35,"02141849":[],"02143946e":36,"02146636":31,"02148021":35,"02151521":[],"021544346900318832":32,"02156196":[],"02156565":[],"021592704588025022":[6,33],"021592704588025025":[6,33],"02164667":[],"02169399":[],"02175561":[],"02177725":27,"02183817":[],"02189606":[],"02189863":[],"02189994":[],"02198702e":[6,32],"02198703e":[6,32],"02199232":[],"022":[],"02204591":21,"02207054":[],"02208512":[6,32],"02214409916811925":[],"02218045":[],"02218076":[],"02228115":[6,32],"02229529":[6,32],"02235723":35,"02239876":31,"02252765":5,"02265404":[],"02281004":[],"02286267":[],"02287468":35,"02288069":21,"02296298":35,"022999498260366312":[6,33],"0231353":[],"0232":[],"0232101":[],"02322297":[],"02322594":[],"02322786":[],"023295599127611474":[],"02330799":[],"02334754":[],"02338085":[],"02342235":[],"02345858":[],"02348765":[6,32],"02352663":[],"02354386":[],"02355756":[],"02356004":[],"02358547":[],"02361665":[],"02363304":21,"02365049":[6,32],"02369044":31,"02374496":[],"02386932":[],"02387182":31,"0239126":35,"02391906":[],"024":[],"024011020121022356":[],"02404706":[],"02409835":27,"0241039":[],"02413786":[],"02424794":33,"02432309":[],"02441422":[],"02444266":31,"02446604":35,"02447063e":[],"0244965108017645":5,"02452792":21,"02454051":[],"0245528":[6,32],"02456":35,"024562":5,"02456235":5,"02459084":35,"02472936":[],"02474828":[],"024792624800382218":[],"02492265":5,"02496085":35,"02498282":[],"02498832":[6,32],"02500488":[],"02502325":[],"02503392":[],"02503753":[6,32],"02506901":31,"02511518":6,"02519009":[],"02521917":[],"02522069":6,"02527621":[],"02529207":30,"0253208":[],"02533443":21,"02540212":[],"02544154":[],"02545":35,"02546675":33,"0255141":[],"02552966":[],"02553865":23,"02557617":35,"02564828":[],"02566356":[],"025709":[11,31],"02572685":[],"02576358":[],"02576685":[],"02584233":[],"02586427":[6,32],"02594314":[],"02597067":[],"02599188":30,"02601643":[],"0260906":[6,32],"02612988e":[],"02616812":35,"02622039":[],"0262517":[],"02625193":8,"02629144":35,"02629373":21,"0263106":[],"02631244":23,"02631942":[],"02632742":[],"02635861":31,"02636268":[],"02646648":21,"02649469":[],"026495":[],"02651857":[],"02654585":[],"02660572763718093":[6,33],"026605727637180936":[6,33],"02664408":[],"02667406":31,"02692965":31,"02693015":[],"02693858":32,"02707227":5,"0271583":21,"02723445":[6,32],"0272743":31,"02729375":[],"02731808":[],"02732402":[],"02735547":35,"02754248":[],"027609773491022525":[6,33],"02760977349102253":[6,33],"02766946":[],"02769274":[],"02780107":[],"02784266":[],"02787184":[],"02793082":[],"02797154":[],"0279886":35,"02806268":[],"02808229":[],"02809972":[],"02813369":[],"02818667":21,"028188673105960467":30,"0284405":31,"02846506":31,"02850506e":[],"02857":4,"02859759":[],"028638258927275215":[],"02876848":[],"02895918":32,"02900153e":35,"029003":[],"02901273e":[],"02909574":[],"02911348":21,"02920675":[],"02923006":[],"0292555":[],"02925855":35,"02928194":[],"02930753":[],"02940083":37,"02944152":[],"02944974":23,"02946852":[],"029483":5,"02962583":[],"02963147":[],"02965159":[],"02970225":[],"029733":31,"02973733":[],"02976145":[6,32],"02980537":[],"02987496":31,"02988432":31,"02993573":35,"02994311":5,"02f":[6,24],"03":[1,6,31,32],"03000689":[],"03003891":[],"03008641":[],"03015288036252618":[],"03016341":[],"030164788184997":9,"03021588":21,"03032441e":[6,32],"03033791":[],"0303586629618948":[],"0304378":31,"03057995":[],"030645975175292262":[],"03076019":[],"03077640549":4,"03092729":31,"03099776":5,"031":[5,32,33],"03115122":[],"0311613":[],"03119062":[],"03120942":21,"03158013":[],"0316146":[],"03166546":[],"0317606":[],"03177331":[],"03188133":[],"03196357":[6,32],"03201179e":[],"03201217":[],"03201832":35,"03201922":31,"03205795":[],"03206757":[],"03207075e":37,"03212854":[],"032142":[],"03214247":[],"03214829":[],"0321956":[],"032196":[],"03230611":[],"03235719":[],"03239118":21,"03239393":[],"03244944":[],"03246707":31,"03247316":[],"03251863":5,"03254179":[],"03254614":31,"03256632e":1,"03261373":[],"03267527":[6,32],"03274273":[],"03279636":[6,32],"03285784":[],"0328643":35,"0330308045183194":[6,32],"0330308045187757":[6,32],"03306538":35,"03308408":5,"03309191e":[],"03311432":[],"03313259e":[],"03317599":[],"03318519":[],"0332335":[],"033233504714921":[],"03345624":21,"03358833":[],"03361037":[],"03365012":[],"033657685071527665":[6,33],"0337609":[],"03382942":[],"03396658":[],"034":[],"03400724e":[],"03404758":[],"034048":[],"03409194":[],"03412067":31,"0342028":[],"0342458":35,"03426412":31,"03430385":27,"03447512":[6,32],"034476":[],"03447649":[],"034557":31,"03455885":[],"03472308":21,"03474443":[],"03476611e":[],"03479236":[],"03479936":[],"03484266":[],"03511387":[],"03529083":[],"03529801":[],"03538463":[],"03538673e":[],"03558034":[],"03559176":[],"03562355":[6,32],"03563709":23,"03568439":[6,32],"03573214":[],"03578526":[],"03586482":21,"0359565":5,"03596557":[],"03624103":21,"03624411":[],"0362483569261072":[],"03630548":[6,32],"03642173":[],"03648711":[],"036527092051294":[],"03656288":21,"03662823":35,"03664879":[],"03680811":[],"03681479262838276":[],"03692132794542241":27,"0369544130635358":[],"03701105":[],"03703391":[],"03707133":11,"0370757046153366":27,"03722287":21,"03736678":[],"03742586":[],"03745816":31,"03778607":[],"037813671417389005":[6,33],"03781367141738902":[6,33],"03796359":[],"03796582":[],"03798785":[],"03814292":[6,32],"03815288":[6,32],"03820746":31,"0382721":[],"038300":[11,31],"03837":35,"03844073":[],"0384468":21,"03846169":32,"03853213":[],"03853268":[],"03853313":[],"03858916":31,"03868372":[],"03872795610436844":[],"03873507":[],"03887801":[],"039039":5,"03906948":31,"03916813":[],"0394226":[],"03948301":[],"03960002":[],"039732":5,"03973227":5,"03973359":[],"039764":[],"03976851":35,"03976976e":36,"03979291":[],"0398603":[],"03990261":21,"039967668952797":[6,32],"0399676689527975":[6,32],"04":[1,6,11,32],"04000457":[],"040102":5,"04010697":[6,32],"04018043":[],"04018705":[],"04018985":[],"04025059":[],"04033524":[],"04038595":[],"04046513":[],"04061345":[],"04063602":[6,32],"040684":[],"04072235":[],"04073097":[],"0408223":[],"0409646":[],"04097813":[],"041":9,"04101344":[],"04108038":35,"04110474":[],"0411487294305088":[6,32],"0411487294305226":[6,32],"04121466":21,"04150522":[],"04158557":[],"04161572":[],"0417409":37,"04186033":31,"04191323":[],"04193203":31,"042060":[],"04206048":[],"042136":[],"04216532":[],"0422":[],"04220758":[6,32],"04224929":[],"04238763":[],"04262217":[],"04277528":21,"04293545":[],"04295726":[],"04295757":33,"043":9,"043072":[],"04307275":[],"04315108":5,"04315855":[],"04322019":[],"04323936e":[],"04328852":[],"04330558":[],"04330907":[],"04346721":5,"04353549":[],"04355062":[],"04355837":[6,32],"04362":9,"043637":[],"04369752":[],"04372067685794603":30,"0437499":2,"043839":[],"04389027":[6,32],"044014":[],"04401421":[],"04413243":[],"04418179":21,"04421197":[],"04423486":[6,32],"04426744e":31,"04431557":27,"044334":31,"04443985":[],"04452918":31,"044613":[6,32],"04487298":[],"0449":[],"04495752":[],"04501146":[],"04504728e":[],"045161":[],"04516434":23,"045258":[],"04532405":[],"04537385":[6,32],"04543942":[6,32],"045630":[],"04564589":[],"04566964":[6,32],"04575775":31,"0458":9,"04585476":21,"04588592":[],"04592382":37,"045963":[],"0462999":[],"04640695":[],"04641529":[],"04646338":[],"04648225":[],"04648335":5,"04652794":[],"04655574":[],"04657426":[],"04664255":6,"046663":[],"046678":[],"046764":[],"04683565":5,"04686491":30,"04688012":[],"04719868":[],"047299":[],"04736252":21,"0473916":[],"047447724189861":[],"0474753":35,"047489":[],"04757138":[],"047760":[],"04776242":[],"04784395":[6,32],"04794409":[],"048020":[],"04808723":[],"0481872773043029":[6,33],"048194":[],"04832356":[],"04838148":[],"04852743":[],"04877931":[],"048781":[],"0488139":[],"04892055":[6,32],"04899367":[],"049060":[],"04909093":[6,32],"04912436":6,"04915593":21,"049196":[],"04922273":[],"04926746":33,"049276":[],"04933083":[],"049380":[],"04939861":[],"049479":[],"049481":[],"049556996627824":[6,32],"0495569966278269":[6,32],"04955942":[],"04963309":[],"049677":[],"04984743":[],"04999052":[],"05":[1,4,6,9,24,31,32,35,36,37],"050015":[],"05002471":[],"05005634426334421":[],"05006037":[],"05006956":[],"05009826":[6,32],"05013368":[],"05029018":[],"05029453":[],"050315327923114654":[],"05034088e":[],"05040878":[],"05043958":31,"05045":[],"05054319":[],"05060379":[],"05068486":[],"05077224":21,"050796":[],"05080769":30,"05087018":[],"05097344":31,"05098714":[],"05100875":[6,32],"051021":[],"051042":[],"05135047":35,"051368":[],"05141614":[],"051418":5,"05144177":[],"05148401":23,"051554":[],"05159088":[],"051598":[],"051645":[],"051649":[11,31],"05169046":21,"0517473":5,"05176711":[],"051787":[],"052010":[],"05201041":[],"05224117":[],"0522653":[],"052279218012056844":[6,33],"05227921801205686":[6,33],"052305":31,"05233008":[],"052370":[],"05240397":[],"052427":[],"0524497":[],"0525733":[],"05263":9,"052692":[],"05269476":21,"052738":[],"052856":[],"05285677":35,"05293756":[],"05296475":[],"05302":9,"053036":[],"05336637":[],"053387":[],"053417":31,"053462":[],"05347795":[],"053599":[],"05363722":31,"05364579":31,"05364854":8,"05376358":[],"053787":[],"05383795":[6,32],"05383947":[],"05384858":[],"053849":5,"053854":[],"05395761":[],"05401912":[],"05415968":[],"054197":[],"054286":[],"05442743":21,"054434":[],"05447415":[6,32],"054609":[],"054617":31,"054655":31,"05476114":35,"05484773":[],"054932":[],"055000":[],"05505310046363":2,"055091049054481":[],"05509105":[],"05519999":32,"0552878":[],"055314":[],"05533":9,"055477":[],"05549529":[],"05563358":[],"055653":[],"055676":31,"055734":31,"055737":[],"05574159":[],"05577845931438246":[],"055876":[],"055910":31,"055987":31,"056026":[],"056041":[],"0560663":[],"05614483":5,"0562":[],"05623":9,"056287":[],"056328":[],"05638246":21,"05641352":[],"056414":[],"05648":9,"05648118":23,"05648836":21,"05651951":[6,32],"05665429e":[],"05667":9,"05668052":[],"056683":31,"056717":[],"056826":[],"056856":[],"05696574":31,"05716368155342608":[6,33],"057216":[],"057287":[],"057300":31,"057316":[],"05737289":[],"05738629":36,"057387":[],"057393":31,"057418":31,"057420":[],"057457":31,"05747369":[],"05749111":31,"057514":[],"057607":[],"057609":[],"05761244":35,"05767":37,"057722":31,"0578214":[],"057835":31,"05785343":[6,32],"05785974":36,"05788748":[],"05789007":[6,32],"05791283":[],"057913350391706":[],"057929":[],"05792927":[],"057951":[],"057961":[],"05796251":[6,32],"057964":[],"05804539":[],"05804744e":35,"05807125":[6,32],"058133":[],"058152":[],"058234":[],"058245":[],"058254":[],"05831017":[],"05834577":21,"058361":[],"058422":[],"058427":[],"058503":5,"05850899":[],"05853984":31,"058552":31,"058582":[],"058593":[],"058641":[],"058645":31,"0586484":35,"05867956":[],"058721":[],"058770":[],"05883":9,"05884":9,"058854":31,"05888195":[],"058952":31,"058967":[],"058970":[],"058996":31,"058997":[],"059031":31,"05914563":[],"059181":[],"059201":[],"059243":[],"059340":[],"05941988e":[],"059624":[],"059669":[],"059761":[],"05978512":[],"059807":31,"059876":[],"05992237":30,"059951":31,"059956":[],"05996":35,"059977":[],"05999":9,"059992":[],"059993":31,"06":[6,31,32,35,36,37],"060071":[],"060083":31,"060085":[],"060087":[],"060171":[],"06019833":31,"06020264":[],"06020587":[6,32],"06021793":[],"060251":[],"060254":31,"060275":[],"060288":[],"060312":[],"06043581":[6,32],"060453":[],"060470":[],"060471":[],"060475":[],"0604888":[],"060490":[],"060547":[],"06055507":21,"060565":5,"06061276":30,"060629":[],"060631":[],"060652":[],"0606958":[],"060716":31,"06072":35,"060726":[],"060734":[],"060735":[],"060756":31,"060870":[],"060872":31,"060898":[],"060994":[],"061025":[],"06110658":[],"061154":[],"061163":31,"061284":[],"061319":[],"061359":31,"061386":[],"061443":31,"061452":31,"06146873":[],"06151386":31,"06155151":[],"061588":[],"061614":31,"061637":[],"061656":[],"061706":[],"061724":[],"061772005077293704":27,"061848":[],"061862":[],"061898":[],"061921":[],"06199119":[],"06200174":5,"06200455":31,"062016":31,"062053":[],"062058":[],"06208238634231949":[6,33],"06210358":[],"062161":[],"06216141":[],"062173":[],"0621855":[],"062199":[],"062216":[],"062231":[],"062260":[],"062263":[],"062282":[],"06228382":[],"062292565":4,"062300":[],"062337":31,"062356":[],"062429":[],"062520":[],"0625462":21,"062599":31,"06260611":[],"062616":[],"062624":31,"06263176":[],"062637":[],"06267057":35,"062691":[],"062693":5,"062700":[],"062705":5,"062719":5,"06277313":[],"062797":[],"062853":[],"062874":31,"06287939":[],"062932":[],"063017":[],"063019":31,"063048":[],"063061":31,"063064":[],"063080":31,"063130":[],"063133":[],"063161":[],"063163":[],"06318287":27,"063197":[],"063206":[],"06320757":[],"063260":31,"063294":[],"063332":[],"063354":[],"063395":[],"063518":[],"063525":[],"063526":[],"063536":[],"063545":[],"063549":[],"063554":5,"063560":[],"063637":[],"063653":31,"063673":[],"0637712":[],"063781":[],"063786":[],"063791":[],"063802":[],"063809":5,"0638484":35,"063862":[],"063894":31,"06392846":[],"063933":[],"063954":[],"06395476":[],"063959":[],"063977":[],"063995":[],"064000":[],"064074":31,"064077":[],"06410638":[],"064107":[],"06416459":[],"064166":[],"06418809":35,"064189":[],"064202":[],"064218":[],"06423317":23,"064294":[],"06430789":[],"06432267":[],"064382":[],"064427":[],"064428":[],"06443054":23,"06444":9,"06444224":[],"064501":31,"064505":[],"064507":[],"06453579006728324":[6,33],"064547":[],"064573":[],"064604":[],"064606":31,"064609":31,"064615":[],"064668":[],"064690":[],"064695":[],"064699":31,"064728":[],"064739":[],"064793":31,"064820":[],"064834":[],"064845":5,"064873":[],"064878":[],"06491455":21,"06491736":[6,32],"064924":5,"064954":5,"064978":[],"065001":[],"065007":[],"065028":[],"06505375":[],"065062":[],"065077":31,"065096":[],"065108":[],"065121":[],"065149":[],"065212":[],"065217":[],"065352":[],"065358":[],"06536971":[],"065378":31,"065390":31,"065410":31,"06547790180152355":[6,33],"06547790180152359":[6,33],"065482":[],"065556":[],"065616":[],"065619":[],"065654":[],"065679":[],"065778":5,"065788":[],"065818":[],"065821":[],"065830":[],"06590458":[],"065949":[],"065963":[],"065989":5,"06603447":[],"066044":5,"066054":[],"066059":[],"066066":31,"066127":[],"066145":[],"066153":[],"066199":[],"066205":[],"06622369":[],"066256":[],"066286":[],"066358":[],"0663596":[],"06637":9,"066425":[],"066458":[],"066474":31,"066500":31,"06659997":[],"066612":31,"06662069e":[],"06662675":[],"066633":[],"066647":31,"066653":[],"0666807":2,"066686":[],"06674611e":[],"066763":[],"066766":[],"06677444e":[],"066778":[],"066787":31,"066824":[],"066837":[11,31],"066838":[],"06684886":[],"06685171":[],"066854":31,"066855":[],"066865":[],"06687898":[],"06690071":[],"066912":[],"066948":[],"06698472":[],"066988":[],"066997":[],"066999":31,"067000":[],"067003":[],"06704902":21,"067074":[],"067077":5,"067141":[],"067164":[],"067168":[],"067224":5,"06724062":5,"067270675787016":[35,36],"067273":5,"067288":5,"067367":[],"067374":[],"067380":[],"067400":[],"067431":[],"067511":[],"067515":[],"067539":[],"067623":5,"067637":31,"067671":[],"067707":31,"067764":[],"06777772":[],"067793":[],"067809":[],"067843":[],"067922":[],"067948":[],"067967":[],"067974":[],"0680225":30,"06804775":[],"06808421":[],"068088":5,"068116":[],"068206":[],"068215":[],"068229":5,"068264":31,"068268":[],"06828347":[],"068307":31,"068324":5,"068353":[],"068360":[],"068364":5,"068369":[],"068394":[],"068408":[],"068441":31,"06844519414009445":[6,33],"06844519414009446":[6,33],"068446":[],"06849372":[],"068494":[],"068504":[],"068512":[],"068533":[],"068539":[],"068587":[],"068592":[],"068607":[],"068629":31,"068680":[],"068684":[],"068727":31,"068758":[],"068775":[],"068827":[],"068843":[],"068897":[],"068903":[],"068906":31,"068912":[],"068924":[],"0689303":31,"068967":[],"068977":[],"068985":[],"06901081":[],"069028":31,"069045":[],"06908518":35,"069129":[],"06913112":21,"069179":[],"069203":[],"06926192":[],"069270":[],"069293":[],"069317":[],"069320":[],"069322":[],"069391":5,"069399":[],"06942115e":[],"0694226":[],"069427":[],"069439":[],"069452":31,"069484":[],"069486":[],"069584":31,"06958788":21,"069637":5,"069676":5,"06970419":[],"069711":5,"069802":[],"069811":[],"06984502":[],"069866":[],"069873":[],"069885":[],"069907":[],"0699274":[],"069970":5,"069978":[],"069979":[],"07":[6,31,32,35,37],"070024":[],"070027":[],"070043":31,"07006502":[],"070095":[],"070098":[],"070135":[],"070146":31,"070150":[],"07016":9,"07017":9,"070183":[],"070213":31,"070274":[],"070275":[],"07027791":[],"07039":9,"070432":[],"070441":[],"070457":31,"070462":[],"070485":5,"070514":[],"070527":5,"070531":[],"070547":[],"070552":[],"070556":[],"070558":[],"070582":31,"070600":[],"070605":[],"070622":[],"07062318":[6,32],"070630":[],"070655":[],"070667":5,"070696":[],"070712":[],"070730":5,"070737":31,"070747":5,"070769":5,"070772":[],"070780":[],"070805":[],"07084394":[],"070855":[],"070859":[],"070886":[],"070889":[11,31],"070891":[],"070898":[],"070916":[],"070918":[],"070950":[],"070980":[],"070986":31,"071049":[],"071055":[],"07106891":[],"071103":[],"07115":9,"071173":[],"071186":[],"071191":[],"071208":[],"07123177":[],"071252":[],"071279":[],"071291":[],"071294":[],"0713":[0,30],"071314":[],"071356":[],"071379":[],"071433":[],"071436":[],"071437":[],"071449":[],"07145103":11,"07147935":[],"071530":[],"071560":[],"071572":[],"071578":[],"071580":[],"071588":5,"07160048164233102":[6,33],"07160048164233104":[6,33],"071608":[],"071638":[],"071643":[],"071655":[],"071656":[],"071680":[],"07172932":31,"07173249":37,"071758":[],"071789":5,"071803":[],"071831":[],"0718316":35,"071868":[],"07187601":21,"071921":[],"0719267":[],"071935":[],"071937":[],"072000":31,"072015":[],"072031":[],"072037":[],"07204042":[],"072083":5,"072092":[],"072111":31,"072132":31,"072147":[],"07218473624441492":[],"072200":[],"072209":[],"072223":5,"072241":5,"072286":[],"072290639572326":[],"07229064":[],"072304":[],"072344":[],"07235641":35,"072380":[],"072404":5,"07241855":[],"072476":31,"072500":[],"0725872":[],"072590":[],"072591":[],"072621":31,"072638":[],"072684":[],"072689":[],"072697":[],"072728":[],"072752":[],"072817":[],"072824":[],"072826":[],"072843":[],"072849":[],"07285":3,"072863":[],"07292363":31,"072946":5,"072947":[],"072961":[],"072973":5,"072997":[],"073048":[],"073071":5,"073102":[],"073109":[],"073115":5,"073198":5,"073253":[],"073258":[],"073260":5,"073262":[],"073288":[],"07332248":[],"073339":[],"073405":[],"073408":[],"073415":[],"073422":[],"073499":[],"073514":[],"073528":[],"073576975500551":[],"073598":[11,31],"073612":[],"073644":31,"073647":[],"073672":[],"073685":[],"07373479":[],"07376699":[],"07378525":[],"073791":[],"073800":[],"073841":5,"073858":[],"073866":[],"073882":[],"073911":[],"073923":[],"07405556":[],"074067":[11,31],"074084":31,"074112":[],"074114":[],"074115":[],"074130":[],"074134":5,"07415258":27,"074210":31,"07421084":5,"074221":[],"07429886e":[],"074323":31,"074368":[],"074374":[],"074417":[],"074454":[],"0744881":[],"074531":[],"074561":[],"07456491":5,"07459764":21,"074622":5,"07468007":31,"074688":11,"07469645":[],"074787":11,"074807":[],"074824":[],"074859":[],"074866":5,"07487128":31,"074882":11,"074892":[],"07489511":36,"07490892":[6,32],"074928":5,"074971":[],"074976":11,"075070":11,"07517385":[],"075176":[],"075177":[],"075198":[],"075239":[],"075289":[],"075298":[],"075302":[],"07531349":[],"075334":5,"075356":[],"075385":[],"075392":[],"075463":[],"075513":[],"075522":[],"07555537":[],"075557":[],"075562":5,"075602":[],"075609":5,"075615":[],"075712":5,"075771":[],"075794":[],"075816":31,"075822":[],"075823":5,"075842":[],"075864":5,"075876":[],"075885":[],"075889":31,"075909":[],"0759216":[],"075956":[],"07597049":[],"075978":[],"07600369":[],"076066":[],"076071":[],"076091":[],"076138":[],"076150":31,"076161":[],"076167":[],"076232":[],"076244":[],"076259":[],"076321":[],"076333":[],"076334":5,"076351":[],"076389":[],"076393":[],"076396":[],"076418":[],"07641937":33,"076434":[],"076435":[],"076436":[],"076448":[],"076459":[],"076479":[],"0764924":[6,32],"076508":[],"076542":[],"076543":5,"0765856870687196":27,"07658569":27,"076618":[],"076638":[],"076648":[],"076679":[],"07668538":[],"076693":[],"076776262573027":[],"076777":5,"07678":9,"076833":[],"076857":[],"076859":[],"0768805855280187":[],"07692307692307693":9,"076934":[],"076938":[11,31],"076947":[],"076951":11,"076968":[],"077035":[],"07705051":21,"07712197e":[],"07712724":30,"077131":11,"077141":[],"077168":31,"077226":[],"077248":[],"077254":5,"077280":[],"077301":[],"077304":[],"077310":11,"077329":[],"077341":[],"0773554":[],"077382":[],"077391":[],"07740964":[],"077411":[],"07745579":[],"077460":31,"0774777":[],"077485":[],"077486":[],"077490":11,"077516":[],"077529":[],"077539":[],"077541":5,"077553":[],"077567":[],"077601":[],"077608":5,"077613":[],"077653":[],"0776532":[],"077672":11,"077683":[],"077736":[],"077745":[],"07776381":[],"077764":[],"07777777777777778":1,"077782":5,"077813":[],"077839":[],"077906":[],"077941":[],"077965":[],"078035":[],"078044":[],"078067":5,"078071":[],"07808426989543932":[],"078110":31,"078118":[],"078123":[],"078146":[],"078170":5,"07820":9,"078210":[],"078238":[],"078268":[],"078282":[],"078284":[],"078313":[],"078324":[],"078336":31,"078359":[],"078363":[],"078386":[],"078447":[],"078454":5,"078540":31,"078541":[],"078544":5,"078557":[],"078573":[],"078588":[],"078636":[],"07864":9,"078684":[],"078688":[],"07871":9,"078731":[],"078753":5,"078898":5,"07890044":[],"078945":[],"078974":31,"078981":[],"078986":31,"079002":[],"079027":[],"079030":[],"079074":[],"079080":5,"079089":[],"079107":[],"07911268":[],"079174":[],"07919041":[],"079202":[],"079240":[],"079334":[],"079347":[],"079391":[],"079420":[],"07944154":[23,30],"079444":[],"07950356694388497":[],"079510":[],"079518":5,"079670":[],"0796891867672603":[6,33],"07969087":[],"07971187802560528":5,"079739":[],"079747":[],"07974741":[],"07978850553011713":[],"079887":[],"079903":[],"079946":31,"079947":[],"079953":[],"079959":[],"07996807":21,"079976":[],"079977":[],"079982":5,"07998756":[],"079989":[],"079998":[],"08":[9,27,31,35,36,37],"080082":[],"080094":[],"08009874":30,"08010965":11,"080110":11,"080171":[],"080205":[],"080222":[],"08023512":35,"080286":5,"080316":[],"08032505":[],"080345":[],"08043851":5,"080453":[],"080549":[],"080555":[],"080559":11,"080616":31,"080630":[],"080657":[],"080702":[],"080706":[],"080747":[],"080764":31,"080793":5,"080832":[],"080849":5,"080875":5,"080903":[],"080947":[],"080987":[],"081038":[],"081103":[],"081195":[],"081217":[],"081221":[],"081235":[],"081252":[],"081276":31,"081296":5,"08131003":6,"0813156":[],"081405":5,"081431":[],"081457":[],"081494":[],"081527":[],"081530":5,"08153923":[],"081544":[],"08156108":[6,32],"08165104":31,"081655":31,"081681":5,"081686":[],"081728":[],"081730":11,"08179906":[],"081835":[],"081871":[],"081955":[],"081978":[],"082002":11,"0820185":[],"082115":[],"082126":[],"082170":[],"082173":[],"082174":[],"082249":11,"08227057":[],"08227668":[],"082303":[],"08233627":[],"082361":5,"082464":[],"082478":11,"082482":[],"08251519":[6,32],"082518":[],"082519":[],"082533":[],"08259753":21,"082653":31,"08266769":[],"082742":[],"082764":[],"082784":[],"082785":[],"08280012":[],"082803":[],"082857":[],"082971":[],"08299273e":[6,32],"083016":[],"083119":[],"0831367":[],"083179":[],"083182":[],"08318298e":1,"08319383":[],"083248":[],"083259":[],"083260":[],"083268":[],"083288":[],"08332537":[],"08333333333333333":[1,9],"083342":[],"08336233266":4,"083446":[],"083465":[],"083471":[],"083479":[],"083499":[],"083501":[],"083527":31,"083547":[],"083548":[],"083564":[],"083596":5,"083645":5,"083734":[],"083765":[],"08376632":[6,31,32],"083766322923899":[6,31,32],"0837663229239043":[6,31,32],"083793":[],"083864":[],"083900":[],"08398399377155011":[],"084018":[],"084042":[],"084076":31,"084091":[],"084122":[],"084127":5,"08418956":[],"084209":11,"084218":[],"08421808":[],"084255":[],"08426840630693411":[6,33],"08426840630693413":[6,33],"084312":[],"084319":[],"084340":5,"084358":[],"084376":[],"084406":[],"084423":5,"084434":[],"084514":[],"08455":9,"084550":11,"08458591":[],"084619":[],"084637":[],"0846409":[],"084695":[],"084702":[],"084712":[],"08472879":31,"08474":9,"084809":31,"08487999":27,"084910":[],"084915":[],"084963":[],"084967":[],"084976":11,"084996":[],"085079":[],"085120":[],"085139":[],"085145":[],"085197":5,"085222":[],"085294":[],"085353":[],"08536248571780691":[],"085378":11,"085390":[],"08539155":35,"085392":[],"08539583":[],"085436":[],"085455":[],"085463":5,"08551306":[6,32],"085518":[],"085548":[],"085592":[],"085655":11,"085690":11,"085712":11,"085716":11,"085722":11,"08572513":21,"085747":11,"085764":11,"08576932":6,"085790":11,"085819":11,"085833":11,"085853":11,"08587209":[],"085902":11,"085918":[],"08593216":[6,32],"085935":11,"085970":11,"085973":[],"085996":[],"086021":11,"086026":[],"086068":[],"08609047":[],"086092":11,"086095":[],"086096":[],"08611111111111111":1,"086125":[],"086212":[],"08622478":[],"086230":[],"086239":[],"08624193":[],"086250":[],"086286":[],"086318":[],"086346":[],"086364":[],"086428":[],"086471":5,"086483":[],"086489":5,"08660891":[],"08667591":[],"086694":[],"086712":[],"086730":[],"086797":5,"086799":[],"086808":[],"086809":[],"08687303":35,"08690":9,"08690184845323":[],"086913":5,"086970":[],"08699295e":[],"08700526":27,"087020":11,"08702578":[],"08705631913312815":11,"087210":[],"087424":[],"087429":[],"08747795":[],"0875061":[],"08758":9,"08758013":[],"087585":5,"087864":[],"087871":[],"087876":11,"08793554992813543":[],"087988":[],"088023":[],"088029":[],"088030":[],"088038":[],"088058":5,"088102":[],"088127":[],"0881981":5,"088199":[],"08824304e":[],"08826182458028335":[],"08826256":[],"088375":[],"08839544":[],"08854388":21,"088574":[],"08858739":31,"088599":11,"08860502":[],"088650":11,"088651":[],"088694":5,"08871404":5,"08881497884574564":31,"08888888888888889":1,"088970":[],"08902":9,"089052":5,"089311":11,"08931169286872433":[],"08935132374099551":[],"089354":11,"089376":[],"089386":11,"0894015":[],"089404":5,"089408":11,"089421":11,"08946029":[],"08947292":[],"0895043":[],"0895387":31,"089539":31,"089548":[],"089576":11,"089578":[],"089600":[],"08961438":[],"089619":[],"089626":[],"089639":11,"089653":11,"089690":11,"089704":11,"089708":11,"089714":11,"089718":[],"089726":11,"089730":11,"089738":11,"089748":11,"089760":11,"089763":11,"089769":11,"089783":11,"089786":11,"089790":11,"089795":11,"089800":11,"089826":11,"089858":5,"089872":11,"089940":11,"089949":11,"08996":9,"089996":[],"09":[1,31],"090002":11,"090033":[],"090038":[],"09007789":[],"090081":11,"090114":5,"09014451":27,"090204":11,"09024373":[],"09028702":[],"090302":5,"090319":11,"090429":11,"090439":[],"090440":[],"090468":[],"090476":11,"09048717285916912":[],"090561":5,"090624":[],"09070064":[],"09078672":[],"0907958":[],"090985":[],"091015":[],"091068":[],"091159":[],"09135059e":[],"091362":[],"091365":[],"091388":[],"09156055":[],"09163947":6,"091653":11,"09166666666666666":1,"0917":9,"09171886":[],"091731":[],"09189665":21,"09209032":21,"09224244":21,"092252":[],"092347":[],"092401":[],"09242193":21,"09246293455466892":[],"092486":[],"09251":9,"092533":5,"092607":[],"092608577084595":[],"092689":11,"092746":5,"09291556244521161":[],"09291806":[],"092956":[],"09296935":[],"092982":[],"09300398":[],"0930438":[],"093094":[],"09346106":[],"093554":[],"09360113":[],"09368":35,"0938492":[],"09397626":[],"09398153":[],"094044":[],"0940821989627646e":[6,32],"0940821989652176e":[6,32],"094099":[],"094254":[],"094362":[],"094439":[],"09444444444444444":1,"09469095":[],"094697":11,"094797":11,"094849":11,"094857":11,"09487358":[],"09491833":21,"094941":11,"095037":11,"095090":11,"095106":5,"09515455":[],"095178":11,"095278":11,"09529067":[],"095425":11,"095465":[],"095710":11,"09572047":[],"095805":[],"09584387":23,"09590269e":[],"095915":11,"09604976":[],"096078":11,"09609807":5,"09610694":[],"096203":11,"09621323":30,"09622593":[],"096270":[],"096287":11,"096365":[],"09637807":[],"096511363983559":[],"09651792":[],"096570":11,"096700":11,"096811":11,"097017":11,"097060":11,"097380":11,"0973900819831327":[],"09740532e":[],"0974119":[],"09744":9,"09755017":[],"097667":11,"09780":9,"09790216282081063":[],"09791":9,"09808149":36,"09808622":[],"09821823":30,"09829902":[],"0983565":[],"098414":[],"09846933":[],"09851247":21,"09861229":[23,30],"098803":11,"09903804":8,"09913654":[],"09919198949275869":[6,33],"09928714":[],"09930135":23,"09941275e":36,"09951287404314545":1,"099588":11,"0n":[0,30],"0x0006":[3,4,14],"0x1174af160":[],"0x11753f700":[],"0x117715eb0":[],"0x117893340":[],"0x117c17be0":[],"0x117edb760":[],"0x11975e550":[],"0x11b160a60":[],"0x11bc3a1f0":[],"0x11bcee130":36,"0x11bdd4640":36,"0x11f13fb20":[],"0x120cc1b20":[],"0x121cf68e0":[],"0x124b30190":[],"0x124b96d60":[],"0x126431130":[],"0x1273ffac0":[],"0x1279bd460":[],"0x12aaa0b20":35,"0x12b14fa90":35,"0x12e13a850":[],"0x145270160":21,"0x1452d6eb0":21,"1":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,21,23,25,26,27,28,29,32,33,34,35,36],"10":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,21,23,24,26,27,28,30,31,32,33,34,35,36,37],"100":[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,17,21,23,27,28,30,31,32,33,34,35,36,37],"1000":[0,1,2,4,5,8,11,13,14,21,22,27,30,31,34,35,36],"10000":[2,5,6,10,11,13,27,32,33],"100000":8,"10001":10,"100083":[],"10008326":[],"1000911":[],"1001":[9,27],"1002":27,"100209":11,"10029389":35,"1003":27,"10030":9,"10036694":[],"10041812":32,"1004727":[],"10047943":27,"1005":27,"100523":11,"10068448":[],"1007":33,"1007711427354898":[6,33],"1009":27,"10100211":23,"101008878523571":11,"10107914":[],"1011":27,"101150":[],"10115017":[],"10116149":[],"101263":[],"101292":11,"1013":27,"1013904243":27,"10141413e":[6,32],"1015":27,"1015491":35,"10158754":[],"1015am":30,"10175169":21,"102209":11,"1023":27,"10230":9,"1024":3,"10242458":[],"1026":27,"10261093":[],"1027":27,"10276112":[],"103":1,"1030":27,"1033455":[],"10340":9,"10340733":[],"10348862":[],"10365224":[],"1037":27,"10378326e":1,"1038":27,"10391807":[6,32],"10398646080125032":[6,33],"10398646080125035":[6,33],"1040":27,"10405456":11,"10426556":[],"10430":9,"104411":31,"10453899":36,"1047":27,"10499357":35,"105":32,"10520":9,"10537416":27,"10539984":[],"105400":[],"10541723644166373":[],"10555555555555556":1,"10556487":[],"10560458":21,"10572":33,"10587277":[],"10589577":5,"10595991":[],"10598715e":37,"10604579e":[],"106095":[11,31],"1064601390492845":[],"10646014":[],"10688434":23,"10719554":[],"10719859":[],"10738656":5,"107387":5,"10747579":[],"107476":[],"1074792":[],"10754764":[],"1079":33,"10790125813226321":31,"108":[6,9],"10801706":23,"1080176":[],"10837392":[],"10854118":[],"10888197":[],"10898643":[],"10907699":21,"10908858":[],"10913":6,"10931453":[6,32],"10960":9,"10994958":[],"10995472e":37,"10th":9,"10x":[0,30],"11":[0,2,5,6,7,8,9,10,11,12,13,15,16,21,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"1100":27,"11006373":27,"1101":27,"11022302e":[5,36,37],"11042239":[],"11052859":[],"11081083":[],"1108407":[],"111":[1,7,12,34,36,37],"11100":9,"11113486":[],"111135":[],"1112416":27,"11129947":[],"11131389":[],"11147544":[],"11163239":[],"11164003":30,"11171148":[],"1118933":[],"11202337":33,"11204514":37,"112383":[11,31],"1124":9,"112619":[],"11261935":[],"11265643e":[],"11277166":[],"112772":[],"11320323":27,"11320726":21,"11382896":32,"11388888888888889":1,"11390":9,"11416086":23,"11433693":[],"114384":[],"11438414":[],"11439407":[],"11449867":27,"114550":33,"11462415":5,"11482289e":[6,32],"1148541":[],"11507992e":1,"115356":[],"11535632":[],"11547777218872497":[6,33],"11548661":[],"11571507":[],"115822":6,"1158848":[],"11590":9,"11596834":[],"11597515":[],"11620886":[],"11660":9,"11666666666666667":1,"11675128":23,"11683558":[],"1169204":30,"1169242":[],"11692966":21,"11694":24,"117":8,"11715109e":[],"11725761":[],"11744554e":[6,32],"11747908":[],"11780":9,"118":[0,2,7,34],"11822173":[],"11830757":32,"118318":31,"1184":33,"11840":9,"11844773":[],"11861803":30,"11868033":[],"11890":9,"11891833e":[],"119":[0,2,7,34],"11922031":[],"11930916":[],"11935351":23,"11969984":[],"1198891":[],"11992194":[],"119922":[],"119936":2,"12":[0,1,2,3,4,5,6,7,8,9,11,12,21,23,25,27,29,30,31,33,34,35,36],"120":[0,2,3,7,34],"1203":9,"1203284":8,"120435":[],"12043521":[],"12044974":31,"120450":31,"12068251":[],"12081773":35,"121":[8,9,10],"12123488":[],"121292":[],"12135727":21,"12155483":[],"1215pm":[28,30],"12166797":[],"12182967":[6,32],"122":[2,8,9,10],"12206013":[],"12206812":30,"12208052":27,"12220276":[],"12222222222222222":1,"12235593":[],"123":2,"12318726e":[6,32],"12329646":[],"12330033":31,"12333649":[6,32],"12363332":[],"123711":6,"12380":9,"12382443":[],"123928000581825":11,"124":[0,30],"12400":9,"1242":8,"124228866018077":[],"124325":[],"12466453":[],"12498355":[],"1251681":37,"12534765":21,"12536737":35,"12544009":[],"12552073e":[6,32],"12591227":31,"126":9,"12600095":[],"1261":9,"12618549":5,"1265":9,"12667402":[],"127":4,"1271":6,"12733892":[],"12777777777777777":1,"12790":9,"128":[3,4,13,35,36],"12829994e":[],"12846660e":[],"12871842":31,"12873424":[],"12893778":[],"129":6,"129012":6,"12922837":[],"12952339":32,"12957454":[],"1297":9,"1298":9,"129963":33,"12it":[],"12pm":[28,30],"13":[0,2,5,6,7,9,11,12,18,21,23,25,27,30,31,33,34,35,36],"130":9,"13003291":[6,32],"13009402":21,"13024288":[],"13035147135400782":[],"13037395":[],"13040489":[],"13055555555555556":1,"13055762":[],"13059483":0,"130694":31,"13069442":31,"131":9,"13107995":[],"13134148011170077":[],"13137881":[],"131379":[],"13152828":[],"13164176":[],"132":9,"13217667":21,"13220608e":[6,32],"1325":6,"1326":9,"13260573":[],"1326197715":30,"13280":9,"13298019":23,"133":[7,34],"1332":33,"13337992":[],"134":32,"13437168":21,"134534":5,"13453411":5,"13455019":30,"13457622":[],"135":9,"1350":33,"13531906":21,"13535942":[6,32],"13564988":[],"1356995":21,"136":[0,7,34],"13600596":[],"13607502":[],"13646574":5,"13659941":[],"13661243e":[6,32],"13663125":[],"13675593":[],"136756":[],"13679863":[6,32],"13684661":[],"13699574":[],"136996":[],"137":[0,7,34],"13729154":[],"13738633":[],"13740":9,"137652":[11,31],"138":[0,7,34],"13819592e":[],"13820":35,"13825388":[],"13845051":[],"13847167":[],"1385":6,"1385510301651882":[],"13865173":5,"13866942":[],"138775":[11,31],"13878649":[],"1388888888888889":1,"13890":9,"13896095":[],"139":[0,6,7,34],"13911934":[],"13913033":[],"139224":[],"1392559585020426e":[6,32],"139255958997547e":[6,32],"1393548":[],"13945974":21,"13956654":[],"13it":[],"14":[0,2,4,5,6,7,8,9,10,11,12,21,23,27,29,31,33,34,35,36],"140":[0,2,7,9,34],"14021063":[6,32],"14046224e":[],"14084366":[],"141":[0,2,7,34],"14100":9,"14104212":[],"1412":[21,35,36],"14122256":[],"1416398":[6,32],"14174745":[6,32],"1418":9,"14187173":[],"142":[0,7,9,34],"14213876":[],"1424112":[],"14249052":23,"14250":9,"14260706":[],"14277718e":31,"143":[0,2,7,9,34],"14309433":[],"14369927":[],"1437":1,"14373934e":37,"144":[0,7,34],"14400":9,"14404536":21,"1440501043841336":1,"1441031":[],"14433067":[],"14437776":[],"14440":9,"14452678":[],"1446729567":4,"145":2,"14523337e":[],"14550854":[],"145509":[],"14568914":32,"14599499":[],"146":2,"14605929":[],"146141":6,"14629156":33,"14638":35,"14643345e":[],"14708":[],"14710":9,"14716":6,"14721582":[],"14722222222222223":1,"147400":[11,31],"147420":[11,31],"147545":[],"1477190177681485":[],"147836":[],"14783612":[],"1479":9,"148":[3,4,14],"14812206":6,"14815202":[],"14824254":[],"14825560e":[],"14828178":[],"14829228":[],"14841322":[],"148776":6,"14880915":[],"1488598":[],"14890012":[],"149063":[],"149111":33,"14913555":[],"149266":[],"14934258650797513":[],"149353":[],"149388":[],"149433":[],"149466":[],"149483":[],"14949972":21,"149904":[],"149921":[],"14g":[6,33],"14it":[],"15":[0,2,4,6,7,8,9,12,13,15,16,17,21,27,30,33,34,35,36,37],"150":[3,4,8,9,14],"15005476":5,"1502":37,"150527":[],"15079545":[],"15098090e":[6,32],"151":[3,4,14],"15126318":[],"15130074e":[6,32],"151522":[],"15173932":[],"152":9,"15200":9,"15202654":[],"152149":6,"15215415":[],"15242624e":21,"152494":[],"1527777777777778":1,"15283463":[],"153":[3,4,14],"153036":31,"15313054":33,"15351626":[],"15361856":[],"15384615384615385":9,"15388662":23,"154":[3,4,14],"15422927":27,"1547556":[],"15489318":[],"155":[3,4,9,14],"15527976":[],"15546887":[],"15593478":[],"156":[3,4,14],"15605625":[],"15670921":35,"1567286":[],"156956":5,"157":[3,4,14],"15709522":[],"157128":[],"1571284":[],"1575":9,"1575046":[],"15751952":[],"1576057":30,"158":9,"15830902":[],"15833751":[],"15847501":[],"1587":9,"1590":9,"15924557e":[],"15951871":35,"15970814":[],"1598058":[],"15990":9,"15991124e":[],"15am":30,"15g":[6,33],"15it":[],"16":[1,2,3,4,5,6,8,9,10,19,21,23,27,30,31,32,33,35,36,37],"16013842":[],"1602625":21,"1603":3,"16039162":[],"16063661":[],"16111111111111112":1,"16118615":[],"16158074":[],"161581":[],"16172219e":[],"16180248":[],"16188604":[],"16201555":[],"16209264e":[],"16211139":5,"16220":9,"162246":5,"16231451":4,"1625":9,"16257872":[],"1628":9,"16292908":[],"16304863":31,"163049":31,"1630775253":1,"16312434e":[],"16342407":5,"16343471":[6,32],"1636508":[],"16384":3,"16407038":[],"16411163":[],"164112":[],"16413938":[],"16431956":[],"16437294":[],"16445858":[],"16469725":[],"16486151":[],"16500":9,"165272":[],"16532977":[],"16535252":[],"16567361":[],"166":9,"1660497e":36,"16617445":[],"1664372":[],"166540":[],"16654048":[],"16710567":[],"16744759":[],"16777789":[],"167787":5,"16791183":[],"168":9,"16805821e":[6,32],"16879134":[],"16925937":23,"169299":30,"17":[1,2,5,6,7,8,9,13,21,27,31,33,34,35,36,37],"17021424":[],"1709":9,"171":32,"171525":31,"1715252":31,"17168028":[],"17174962e":1,"17214545":[],"17214797":[],"17222222222222222":1,"17222494":[],"17249725":[],"17253354":[],"1726":9,"17260271":[],"17272182":[],"173":[21,36],"17300":9,"1731":9,"1732863504708044":[],"17359583e":[],"17367225":[],"17377547":[],"17405911e":[],"17418673":30,"17446471":6,"17483760":33,"175":33,"17501258":37,"1752":9,"175300":31,"17547294e":[],"17563274":[],"17567503":[],"17641709":[6,32],"17643975e":[],"17669259":[],"176762":[],"17676247":[],"1767857":[],"17739525":[],"17748881e":35,"17757295":[],"17777777777777778":1,"177786562639708":27,"17801022":5,"17801827":[],"17806281e":36,"17827738":[],"17834506e":[],"17856374":[],"17861098":6,"17861414":[],"17865868":23,"17869861e":[],"179":[],"17913653":[],"17917768":5,"1792":6,"1793417":[],"17934801":[],"17949575":5,"17953942":11,"17968231":[],"1797":[1,3],"18":[2,6,7,8,9,10,13,21,27,30,33,34,35,36],"180":[],"1801709":32,"18019623e":[],"18029127":5,"18043393":[],"1807":4,"1808228":[],"18085537":[],"1809":9,"18093549":[],"18094575":[],"181":9,"1810415856976313":[],"18118338":[],"1812":9,"18120973":[],"181210":[],"18147009":[],"181766185664273":[],"182086698929565":[],"1821":9,"18234308":[],"18277213":[],"18285689e":[],"18307821":32,"18333333333333332":1,"18383522":31,"18388":6,"184":9,"1840":33,"18409254":[],"18418938":[],"184519":31,"18485685":[],"184866696796263":[],"18497496":[],"184975":[],"185":32,"18501900e":[],"18510775":[],"18522369":[],"18551655":[],"1860":9,"18611111111111112":1,"18613217e":[6,32],"1863889":[],"18646225":30,"18660":9,"18670072e":31,"18673098":11,"18702469":[],"18711407":[],"18712313":30,"18742521":[],"18816387":[],"18824338":[],"18840034e":[],"18925625":[],"189496":31,"18956157":[],"189622":31,"18it":6,"19":[2,6,9,15,21,27,30,33,35,36],"19001247":23,"19009085621304586":[],"190529":[],"19052935":[],"19069576e":35,"19126179":[],"19166666666666668":1,"19180036e":36,"191833":[],"192":33,"19207979":5,"19220":9,"19299283":[],"19336703":23,"19371605e":37,"1940":0,"194042826649355e":[6,32],"194042826815211e":[6,32],"1943":[12,36,37],"19433318":[],"1944":6,"19547923":[],"19559737e":[],"1956":9,"19569961":[6,31,32],"19583547":[],"19588651":35,"19661197":35,"19677112":[],"1970":[23,30],"1973":9,"197370":[11,31],"19740":9,"1979":[6,33],"19791352":[],"197914":[],"19800":9,"19848482":27,"19849513":[],"19852045":[],"1989":37,"1991":37,"19920353":[],"19945294":23,"19951849":[],"199824":11,"19982428":11,"1999":25,"1_1":[12,36],"1_2":[12,36],"1_3":[12,36],"1cm":[0,8,10,27,30,37],"1d":[1,2,3],"1e":[1,2,4,13,14,21,35,36],"1e10":14,"1e4":6,"1f":1,"1k":23,"1n":[0,30],"1x":[0,30],"2":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,21,22,23,24,26,27,29,33,34,35,36],"20":[0,1,2,6,7,8,9,13,19,21,27,28,30,32,33,34,35,36,37],"200":[0,2,3,4,8,9,10],"2000":[0,31],"20015436":6,"20020163":37,"2004":[13,34],"20051449":[],"2006":29,"2008":30,"2010":[1,37],"2011":1,"20135691":[],"2014":4,"2015":1,"20158083":[],"201581":[],"2016":[0,30],"20173175":27,"2018":[0,6,31,33],"2019":[8,9],"2021":[6,14,31,32,34],"20218457":[],"2022":[25,30,37],"20224027":23,"20228273":[],"2023":24,"2024":[15,16,17,18,19,20,21,25,30,31,32,33,34],"202698":[],"2026985":[],"2027":9,"20277777777777778":1,"20288581":[],"20300793":30,"2032806":30,"20336784":[],"20347912":[],"20357736":[],"20367355":[],"20375464":[],"20393534":[],"204049":[],"20404927":[],"20480187":[],"204802":[],"20500":9,"20519189":[],"20527785":30,"20539421":27,"2060":9,"20601797e":[],"20608548e":[],"20651434":[],"206664":[],"20666447":[],"2069":9,"2072382":[],"20728198":[],"207545":[11,31],"20755569":[],"2077068":[],"20775115":[],"20833333333333334":1,"20834188":[],"2084894":[],"20867052175034223":[6,33],"20912557":[],"20916295":31,"20980":9,"21":[0,1,2,5,6,7,9,12,13,21,23,27,30,31,33,34,35,36,37],"210340":[11,31],"21058097":5,"21061589":30,"21070843":[],"21093775":6,"211":[],"21130":9,"2116753732":4,"21169159e":[6,32],"21181534":23,"21192602e":[],"212":[],"21277816e":[],"213":[],"213103":[11,31],"2131067":[],"21332621":[],"21333766":[],"21344077":[],"213743":[11,31],"21390371e":[],"21392756":[],"2142385":[],"21430643e":35,"21444055":[],"21457724":[],"21517262":6,"21531156":[],"21565007e":[],"21596432":6,"2160073466353432":[],"216290":[11,31],"21631786":[],"21635399":23,"21641173":23,"21655059e":[],"216683":[11,31],"21680864":[],"21699817":[],"21752693":[],"21776599":[],"21805426":[],"21813899e":[],"21817966":[],"21833102":23,"21941484e":[],"21949761":21,"21998973":[],"22":[0,1,2,5,6,9,12,13,21,23,27,30,31,33,35,36],"22013655":[],"22044605e":[5,31,36,37],"221":8,"221180":31,"2212296":[],"22128142":[],"2216":9,"221666864828611":[],"22169087":[],"2218":9,"221805":2,"221921":5,"22217237e":[],"22226881":[],"222400":31,"22370461988004753":23,"22388052":[],"22467274":33,"22481166":[],"225":4,"22528536":[],"2257449":[],"22592946e":[],"226014":[],"22601408":[],"22623421":[],"22667819":[],"22688898":[],"22690428":5,"22706777":23,"22715479":23,"22755839e":[],"22756518":21,"22809974":27,"22810365":[],"228104":[],"22835717e":36,"22842468702219465":[6,33],"2284246870221947":[6,33],"22847924":5,"22849742":[],"22871":35,"22897303":[],"22919456":[],"2293":[],"2294":[],"22946401":30,"2296":[],"2297":[],"22977659964799":[],"2297766":[],"22it":[],"23":[1,2,6,9,12,15,20,21,23,30,33,36,37],"23002365e":[6,32],"23007231e":37,"23040825":[],"23076923076923078":9,"23077255":[],"23093598e":[],"2311959":30,"23139242":[],"23164401":[],"23167717":5,"232435":31,"23262877":[],"23303727":[],"23333333333333334":1,"23344210e":[],"2338675":31,"233868":31,"234":6,"23407025":[],"23423987":[],"234332597247826e":9,"234496":[],"23449607":[],"23472994":[],"23481471":[],"23499549":[],"23499891":23,"2351":6,"23526911":[],"23528337":33,"235969":[],"23596934":[],"23616967":[],"2364":9,"23663482":[],"2373286546935638":[],"23794815":[],"23847441":[],"239":33,"23950884":[],"2397":9,"23971032":31,"23994188e":[],"24":[0,1,2,6,9,21,23,27,30,33,35,36],"2401":24,"24032019":[],"24071032":[],"24106503":35,"24140":9,"24149532":30,"24159785":31,"2416":9,"24175744e":[6,32],"24185931":[],"2419":9,"24224776e":[],"24225043":[],"24254071":[],"24284399":[],"2430":9,"24335376":36,"24344979e":[],"24346138":[],"24369936":[],"24377554":[],"243776":[],"24390":9,"24398826":[],"244293":5,"24429334":5,"24433117":[],"24444444444444444":1,"24454968":[],"24485814":35,"24493666":33,"245781":5,"24578123":5,"24582593":23,"246":2,"24602146":[],"24613581":[],"24640494":35,"2468382":27,"24688853":[],"24692014":[],"24719968":35,"2475908482537097":[],"24759085":[],"24768421e":35,"24780663":[],"24816468":21,"2481902":[],"24829908":5,"24856992e":[],"24906604e":[6,32],"24999088":[],"24it":[],"25":[2,3,4,5,6,8,9,11,21,24,31,33,35,36,37],"250":[2,4,7,9,34],"25000":0,"25003261":21,"25018094":[],"25068519":30,"25111821":[],"25185716":32,"251879":31,"252008":[],"25200841":[],"25233253":[],"252333":[],"252436":31,"25294371":30,"25337053":[],"25343155":33,"25354173":[],"25386687":[],"253891":[],"25389111":[],"25458506e":[],"2546186":[],"254619":[],"2546817701709956":[],"255":3,"255001":31,"25512598":[],"25555619":[],"256":[2,4],"25617655e":[6,32],"25617658e":[6,32],"25646067":30,"25659561":27,"25673276":[],"256733":[],"25680702":30,"25695398":33,"257":33,"25705685":[],"2572":9,"25729558":[],"2575":9,"25816519":23,"25849623":[],"25879315330607":[],"259153":[11,31],"2597":9,"25970297":[],"25986026":[],"25989189":[],"26":[2,6,9,16,21,33,35,36],"26001134":[],"26048873":[],"26083712":[],"26113912":[],"26120167":21,"26124692":6,"26128189":[],"26152075":[],"26254957e":[],"262648":[],"26264849":[],"26280614":35,"26281735":35,"26292364":33,"26297455":31,"26301436":5,"26307235":[],"2630723514841553":[],"26321660e":[],"26378176e":[],"26402837":[],"26409315307910025":[6,32],"2640931530791004":[6,32],"26464303e":[],"26479234":[],"2650":9,"265109911":4,"26527089":[],"26536626e":[],"2654":9,"265868":[],"26586817":[],"26604611":36,"2662452":[],"26639089e":36,"26646852":[],"2666905":[],"26674792":[],"26680052":[],"266801":[],"26692247":[],"26710969":5,"26715191":[],"26775644":[],"26780278":5,"2679757":[],"268":9,"26814548":6,"26817703":[],"26821199":[],"2694078":[],"26995402":31,"27":[0,1,2,6,20,21,33,36],"27037635":30,"27065633":32,"27108866":23,"27124938":[],"271260217275557":[],"27126022":[],"27182417":[],"27186049":27,"27231287":[],"2729933":21,"27336592":37,"27352535e":[],"27403356":23,"27425372":[],"274394546800107":27,"27439455":27,"27458376":35,"27470622":35,"27482829e":[],"2750":9,"2751616":[],"27530242":23,"27597777e":[],"27600259":[],"27602210e":[],"27623637":[],"276263":[11,31],"27633474":[],"2765068":23,"27693602e":[36,37],"27698328":[],"27700":9,"27750534":21,"27760":9,"2781456":[],"27861634e":[],"27924636":5,"27933134":[],"27it":[],"27n_":27,"28":[1,2,3,4,6,9,21,33,35,36],"28000355":[],"280004":[],"28021598":[],"2802234e":36,"280464e":[],"280573":5,"280647":[11,31],"28093636":[],"28109198":[],"2813829":[],"28164443e":[],"28183460e":[],"28205578e":31,"28225179":[],"2822642":[],"28253033":[],"282727":[11,31],"28276275":[],"28306304e":[],"2830637392":4,"28316949":[],"28336218e":[6,32],"28358004":21,"28364423":[],"28390":9,"28391978":31,"28399125":[],"28415767":[],"28443039":33,"28457291":[],"28475098":8,"28496213":[],"28542801":[],"2861":27,"28614301":23,"2863391":30,"28709718":[],"2871":9,"2873":9,"2876045":[],"28766899":[],"28776411":[],"28793787":[],"2882":27,"28844641e":36,"2885519":[],"2886":27,"28886314":36,"2890":[0,30],"28902948":[],"2890577":27,"2892":27,"28923":[],"28956161":[],"2895786617507":[],"28it":[],"29":[2,6,9,21,33,35,36],"29015871":[],"29033075e":[],"29078236":23,"29100624e":[],"291056":[],"2915":27,"29162184":[],"29167186":5,"29223521":[],"29234681":36,"29238145":[],"29253213e":[],"29306584e":[],"2931":30,"29350":35,"29390668":[],"29398019":[],"29474356":23,"29491144e":[],"29541992e":[],"29560433":21,"29593305":30,"29620357":[],"29627774":[],"29633608":[],"29653038":35,"2965315":[],"29669411":36,"29678339":36,"2968":30,"297648":[],"29764815":[],"2976637":[],"2980":30,"298037":[],"29803738":[],"29822833":[6,32],"29860173":35,"2986082":[],"29861395":[],"29881308":[],"2990":30,"29902518":[],"29950088":35,"299748":31,"29it":6,"2_":[12,36],"2_1":[12,36],"2_2":[12,36],"2_3":[12,36],"2_i":[12,36],"2_m":[6,27,33],"2_t":[13,35,36],"2_x":27,"2b":27,"2c8f433990d1":[35,36],"2cm":8,"2d":[1,3,11,12,22,30,36,37],"2e":[6,33],"2f":[0,7,9,10,11,12,30,31,34,36,37],"2g":2,"2g_i":2,"2k":3,"2m":[6,33],"2n":[0,2,3,30,31],"2nd":[9,36],"2p":[27,37],"2pm":28,"2pt":4,"2x":[0,3,8,13,30,35,36,37],"2x_ix_jy_iy_j":8,"2x_j":8,"2xb":37,"2y_i":10,"2y_j":8,"3":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,21,22,23,24,25,26,27,28,32,33,34,35,36],"30":[0,1,2,4,6,7,9,10,13,16,21,28,31,33,34,35],"300":[21,36,37],"30000":[0,30],"30000613":[],"30005983":[],"30010":9,"30013135":30,"300231":[],"30023144":[],"30043041":[],"30069427":[],"30117681":[],"30119421":8,"30124108":[],"30134885":[],"30141906":[],"30190897":[],"301909":[],"302":33,"30258509":[23,30],"30269539":[],"30283188":32,"303":6,"30306759":35,"30334592e":[],"30387411e":[],"30400113":[],"30442002e":36,"30442964":31,"30466214e":[6,32],"30493151":[],"30506075e":[],"30607268":35,"30637636":[],"3072":3,"3075371":23,"3076923076923077":9,"30787294":6,"30894285":23,"30915293":[],"309153":[],"30916402":[],"30916988":[],"309170":[],"30917499e":[],"30940":9,"3096154":[],"30982436":[],"3099":33,"30it":[],"31":[2,12,23,27,36],"31008026":[],"310579":31,"3105791":31,"310957":[],"31095745":[],"31096156":21,"31160886":[],"31162122":[],"31175179":35,"312":32,"31227657e":[],"3123314713548606":[6,33],"31248425":35,"31276579e":[6,32],"31286143":[],"313":32,"313155":[],"31315504":[],"31318084":5,"31362428":21,"31363366":[],"31367041":[],"31453949":[],"31457796":5,"314869":[],"31486917":[],"315":[6,32],"31541884":[],"3155":[0,5,6,32,33,34],"31555734196707536":[],"31571995":[],"316":32,"31601423":[],"31607059":27,"31664443e":35,"31702609":[],"31718909":11,"31727523":[],"317367":11,"31758645":[],"317799":5,"31779928":5,"31812561":[],"31849289":[],"31876431e":[],"31896852":8,"31897935":36,"31936237":[],"31938579":27,"3194467":[],"31it":[],"32":[0,2,3,4,6,8,12,13,23,27,35,36],"3200":1,"32003025":[],"32007041":[],"320656":[],"32065614":[],"32068736":[],"3207":33,"32084559e":[],"32149601703519115":[6,33],"3214960170351912":[6,33],"3215":9,"32265127e":36,"323059":[],"32305911":[],"323184775146844":[],"32318478":[],"32393078":[],"324":2,"32419549":[],"3241988":[],"32422234e":[],"3245":2,"32450054":31,"3250":1,"32513272":27,"325228546249804":[],"32522855":[],"3260513":[],"32606139":[],"3262":6,"326238":31,"32641434":[],"32651488":[],"32683063":[],"32684035":[],"32717946":30,"32733949":[],"32738537":30,"32798457e":36,"32799141":[],"3280928":[],"328093":[],"32825214":[],"32906581":[],"32932635":[],"32941912":[],"32972613":27,"32it":6,"33":[2,9,12,23,28,36],"33000573":[],"33006628":[],"33025801":[],"33049619":[],"33062878":[],"330629":[],"33066907e":[5,31],"33095972":30,"33096549":[],"33107417":[],"331075":[],"33145794":[],"33149531":[],"33163086":11,"331631":11,"33166055e":5,"331939":31,"33212971":[],"33217312":[],"33220123":[],"33235647":[],"33241952":[],"33266422":[],"333":[7,34],"33329216":36,"33435637":23,"33477019":[],"33528448":[],"33532886":[],"33596404":[],"33615742":[],"33675308":[],"33734605":[],"33742926":[],"33826500e":[],"3388112":[],"33978889":35,"33it":[],"34":[2,9,23,36],"340071371496255":31,"34023682":5,"340237":5,"34026086":[],"3403":9,"3404509":5,"34061974":5,"340620":5,"340782":[11,31],"34098895":23,"34112554":30,"34114547":5,"34131583":30,"34134773":23,"34139775e":37,"34182884":[],"34225662":[],"342680":31,"34271514":[],"34332677":[],"34346829":[],"3436":[0,30],"34367970":6,"3437":[0,30],"34412923":31,"344176915013831":[],"34427423":[],"34478594":30,"34483937":[],"34483955":[],"34568909":[],"34569596":5,"34569632":[],"34577375":[],"34582863":36,"34598722":[],"34599467e":[],"34599598":[],"346000154268618":[],"34620097":[],"34654596":[],"346546":[],"34661376":[],"346614":[],"34704885":23,"34726166":5,"347262":5,"34759233":[],"3480527":[],"34862407":36,"34871778":[],"34904819":[],"35":[0,2,6,17,24,28,30],"3500312e":36,"35018806":[],"35098705":[],"35140":9,"3514835":[],"351636":[11,31],"35182854":5,"35196964":[],"35243372":[],"35275513":[],"35320952":[],"35354073":[],"35388766e":36,"35432563":[],"3544313922":6,"35468713e":21,"35470445e":[5,31],"35506347e":[],"35520169":[],"35533773":6,"35537114e":[],"355734685106391":27,"35587321":[],"35613536e":[],"356399":31,"356673":[],"35667342":[],"35689303":[],"35713539":36,"35714377":[],"35731585":[],"35736":35,"357508":31,"3577615":[],"3581341341":4,"35823372e":[],"35870701":[],"3587467":23,"359":[5,32],"35957915":[],"35966688":[],"35980374":[],"35986305":[],"35it":[],"36":[0,2,5,6,24,27,37],"360":1,"36014743":36,"36091273":[],"3613":9,"361541":[],"36154104":[],"361556":31,"36161658":30,"36185989":[],"3621311":5,"36219301":36,"36235052e":[],"36255393":27,"36278226":36,"36303682e":[],"3632959111950474e":[6,32],"363295916366933e":[6,32],"36339156":[],"36353321":[],"36401981":[],"36482524":[],"36545697e":[],"3655222":5,"366375489616074":[],"367":[2,9],"36754671":[],"36841864":30,"36880327":[],"368818":11,"36881837":11,"36895644":33,"369139":[11,31],"36it":[],"37":[2,9,24,34,35],"37013105":[],"37055062":[],"37057274":[],"370782966":4,"37093787":[],"37135473":[],"37137157":30,"37153115":[],"37175575":35,"37180834e":36,"37215356":36,"37239927e":31,"37255873":[],"3727791":[],"37354121":[],"37396662":[6,32],"37415625e":[],"37449168":[],"37454707":[],"374675":[],"37467515":[],"37507799e":[],"37532078":[],"37582891":[],"375829":[],"37600869":[],"37685349":[],"37700967e":[],"37717637":30,"377372":31,"37737221":31,"3777801602":6,"378271":[],"37827145":[],"37837864":[],"37900111":[6,32],"37919989":[],"38":[2,9,24,27],"380":9,"38102552":[],"38123077":[],"38135733e":[6,32],"3817475779":[6,33],"38198866":[],"38203725":[],"38259084":35,"38298234e":[],"38337498":[],"38381781":[],"38399622":[],"38440469":[],"38445171":[],"38460453":[],"38461538461538464":9,"38461539":35,"38592549":[],"386":9,"38612299e":[],"386161":[],"38616125":[],"38618024":[],"38629436":[23,30],"387":33,"38713573":23,"387620":[],"38762019":[],"3882273":[],"38827994":6,"38865681e":[],"38916861e":[6,32],"3892":33,"38934047":[],"38962192e":[6,32],"38992371":[],"39":[0,2,9,25,28,30,36,37],"390334838933238":[],"39033484":[],"39039235":[],"3908470004999506":[],"39090680e":[],"3910042":[],"39197698":31,"391977":31,"39214397":31,"392144":31,"39223923":[],"39279291":[],"39292847":[],"3939184e":[],"39398622":[],"394":9,"39517073":[],"39525059":[],"39540235":[],"39579407":5,"395980256477532":[],"39598026":[],"39614949":[],"39621036e":[],"39692815":[],"39706038":5,"397700":[11,31],"39789527":[23,30],"3983":6,"39855569":[],"39865452":[],"39914635":23,"39922082":[],"39929428":[],"39931051e":31,"39952356":[],"399836":31,"39991048":30,"3d":[2,3,4,6,13,24,33,35],"3f":[1,3,9],"3n":23,"3x":[2,8],"3x_0x_1":37,"3x_i":2,"3y":8,"3yk470mj5p931p9dtkk0y6jw0000gn":[1,6,30,33],"4":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,23,24,27,30,32,33,34,35,36,37],"40":[1,6,9,24,25,28,30,33,37],"400":4,"4000":[9,30],"40030606e":36,"40037367e":[],"40072098":[],"4008393":30,"40093324":[],"40140374":[],"401842":[11,31],"40184681":[],"40266454":[],"40354798e":[],"40415979e":[],"40418675":[],"404783":[],"40478305":[],"405":9,"4050":[29,30],"405163":5,"4051634":5,"40558184":[],"405890":[11,31],"405964":[],"40596423":[],"40605118":[],"40620066":31,"406201":31,"40632663":[],"4069157":[],"407":9,"408":9,"40800396":[],"40833375":[],"40848657":30,"4087":9,"4087793":5,"40927184e":[6,32],"40961688":30,"40it":[],"41":[2,9,23,25],"4107":9,"41146753":[],"4121966338442804":[],"41229845":[],"41259788":23,"41310208":[],"41366128e":[],"41396339":30,"41408221":[],"41433969":5,"41487642":[],"41511965e":1,"41532521":[],"4155":[2,15],"4162706317":6,"41636775":[],"41664613":[],"4166666666666667":9,"41675053":[],"41744203":[],"41764479":[],"417644792969273":[],"41794469":23,"41820116":[],"41842093e":[],"41847686e":[],"418506":[11,31],"418656":30,"41869784":[],"41882037e":[6,32],"41925189":[],"419718":5,"41971814":5,"41987877":[],"4198932":[],"42":[1,2,4,8,9,10,23,25],"42013616e":36,"42083463e":[],"42095725":[],"42124182":[],"4215795":[],"42197297e":[],"42305151":[],"4230769230769231":9,"42310878":[],"423646":[],"42364634":[],"42392359":[],"424274":[],"4242743":[],"42441033":5,"42450":9,"42497724":[],"42553096":[],"42575338":[],"42592679":30,"426":[6,9],"42644801":[],"42699034":37,"42774546":[],"42793344e":[],"42873361":[],"429":33,"42945319":[],"43":[0,1,2,7,9,23,34],"43054282":5,"4310":30,"433":33,"43330971e":[6,32],"43373107":[],"435163":31,"43563433":[],"43579948e":[6,32],"43639284e":31,"436462435":4,"43703545":[],"43724406":30,"43727575":[],"43766686":11,"43779698e":[],"438060758":6,"438136":31,"439230":6,"43962226":[],"43976975777097144":[],"43984553e":[],"43it":[],"44":[0,1,2,23],"44089210e":[5,31],"441":[3,4,14],"442":[3,4,14],"44239442":27,"44255455":[],"442600":[11,31],"44286735":[],"443":[3,4,14],"443217":31,"44395301":32,"444":[3,4,9,14],"44418124":35,"44454123":[],"445":[3,4,14],"445128":23,"44536331":[],"44563226":[],"446033":33,"44624525e":31,"44658658e":[],"44767398":[],"4477214":[],"44830934":[],"44838546":[],"44867801":[],"44970586e":1,"44995924":[],"44it":6,"45":[0,2,9,28,30],"450":9,"450257":[11,31],"4504":9,"45053025":[],"45054585":27,"45193407":[],"45430236":[],"455173":33,"45560415":[],"45568883":27,"4557763":11,"455947":31,"456":9,"45620975":[],"457":2,"457311":[],"45731144":[],"45731379":[],"4576811":[],"45781905e":35,"458027":31,"458078":[11,31],"4580854":[],"4591127":[],"45915671e":31,"45960079":5,"45it":6,"46":[2,9,28,30],"460":[9,11],"4601":9,"46065811":[],"46069873e":36,"46086448":[],"46107913":[],"46134248e":[],"46153846153846156":9,"46170878e":35,"4619526":[],"462":[7,34],"462295":5,"46229544":5,"46318204":[],"46342934":[],"4635149":[],"4636751":23,"46383925e":[6,32],"46383926e":[6,32],"46387965":[],"46415522":[],"46415888336127775":32,"46544987":[],"46593404":[],"46660941e":[],"46713267":32,"46736215":33,"4676059":31,"467606":31,"46891823":[],"46911594e":[],"46954702e":[],"46963249":[],"46984559":[],"46984697e":[6,32],"47":[2,9,28,30],"47042744":5,"47051432":33,"47052809":[],"470714":31,"47075725":6,"47116868e":[6,32],"47125748":5,"47132891":5,"4725246793626128":[],"4729218":[],"47297587e":[],"47308061":23,"47313680":33,"47334547e":[],"4735968":[],"47433659":[],"4745474":[],"47478922e":[],"47609206":31,"47610036":6,"4761747":[],"47729832":[],"47757553":[],"47815203":11,"47823856":35,"47892661":[],"47910545":[],"479465113":4,"47989224":[],"47991892":[],"47it":6,"48":[2,9,33],"48004784":[],"48062913":[],"48151166":[],"48170743":[],"481979":6,"48200792":[],"48233952":[],"48257387":[28,30],"48268005e":[],"48306473":[],"48307405":[],"4831139":[],"48326853":[],"48399942":[],"48420061":[],"4843772":[],"48476997":11,"484905":[],"48490503":[],"48494803":32,"48511333":30,"48521055":[],"48697869":[],"486979":[],"4870934":[],"48786826e":[],"48826894e":[],"48827791":[],"48843174e":[],"48867802":[],"48900413":[],"48931464":[],"489315":[],"48994188":5,"48it":[],"49":[5,6,9,11,24,31,35,36],"49074536":[],"49077038e":36,"49123502e":[],"49152":3,"49156266e":[],"49211524":[],"49224801":[],"49285045e":[],"49312535":30,"4937346":[],"49381549":[],"49392067e":[],"4940954":[0,30],"49470005":[],"49513019":[],"4951301940723654":[],"49584063e":[],"4959161509357395e":[6,32],"4959161509366685e":[6,32],"49608088":[],"49611541":[],"49761526":31,"49897504e":37,"4990":27,"49910481e":[],"4992":27,"49939493":[],"499394932852416":[],"4997":27,"49it":[],"4c4c7f":[9,10],"4d":3,"4f":6,"4pm":[28,30],"4y":8,"4y_i":10,"5":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,21,23,24,27,30,31,32,33,34,35,36,37],"50":[1,2,3,4,6,7,8,9,10,13,21,30,31,33,34,35,36,37],"500":[1,3,4,6,9,10,13,33,34,35,36],"50000000e":[36,37],"50000455":5,"50000553":5,"50000718":5,"50000855":5,"50000969":5,"50001063":5,"50001142":5,"50001207":5,"50001261":5,"50001306":5,"50001343":5,"50001374":5,"500014":5,"50001414":5,"50001422":5,"50001439":5,"50001454":5,"50001466":5,"50001476":5,"50001485":5,"50001492":5,"50001498":5,"50001502":5,"50001506":5,"5000151":5,"50001512":5,"50001515":5,"50001517":5,"50001518":5,"50001519":5,"50001521":5,"50001522":5,"50001523":5,"50001524":5,"50001525":5,"50100007":23,"5018":27,"5020612":[],"50227564e":[6,32],"50233673":30,"50258788e":[],"502698":[],"50269821":[],"50306335":[],"50321091":5,"50327198":[],"50352245":30,"50427787":33,"50482139":[],"50530832":33,"506":0,"50600514e":[],"50610071e":35,"506553":31,"50655336":31,"50655379":5,"50667812":[],"50714096e":[],"5076963":[],"507d50":[9,10],"50846111e":[6,32],"50846112e":[6,32],"50850373":[],"50887105":[],"50895251":23,"50911289":[],"50it":6,"50j":[13,35],"50x10":1,"51":10,"510":1,"5105332296929628":[],"51069279":[],"51104913":[],"51136852":[],"51154388":[],"5116375":[],"511888":5,"51262599":30,"51317506":[],"51364117":[],"51374050":33,"514219":31,"5142856":[],"51437058e":[],"51447004":[],"51512235":[],"51532469":23,"51546825":[],"51564682":[],"51611732":[],"51615779":30,"51643579":[],"51659846":35,"51709529":[],"51728978":[],"5177783846":4,"51808934e":37,"51858116":[],"5187643":31,"51914183e":[],"51928402":[],"51937727":[],"52":[34,35,36],"52031552e":[],"52074297":23,"52087499":[],"521422502348998":[],"521558":[],"52155823":[],"52173381":[],"52211567":11,"522116":11,"5222222222222223":1,"52228066e":36,"5223261":23,"52284329e":[],"52301447e":[],"52317963":[],"52362157e":31,"52397611":[],"52407775":30,"52446101":[],"52480767":23,"5257011":[],"52573336":[],"52606333":30,"5260801":11,"52635761":[],"52654886":[],"52657934":[],"526744":[11,31],"52694246e":36,"52698542":[],"527024":5,"52702419":5,"52706754":[],"527068":[],"52732966":[],"52780600":33,"52789388":23,"52874252":5,"52876551":[],"52888979":[],"52927353":23,"52989287e":[],"52it":6,"53":[9,34,35],"5303329":11,"53052247":[],"5305555555555556":1,"53105728":[],"53125507":[],"531280":31,"53149078":[],"532":[],"5321613":[],"53269627e":[],"53285379":[],"532854":[],"533":[],"53312817":[],"534":[],"53480404":30,"535":[],"53512750e":[],"53534008":[],"53585173":[],"535852":[],"53629564":[],"53640693":[],"53684024":21,"537":[],"53703498":6,"53723188":[],"53729411e":[],"53732988":[],"53738247":33,"5378811":11,"538":[],"5384615384615384":9,"539":[],"539261":[11,31],"53942728":[],"53996947":[],"5399913":[],"53it":[],"54":[6,9,27],"540":9,"54011398":[],"54039921":5,"54041041e":5,"54057582":[],"54150298":37,"541605":31,"54175461":35,"54222783":30,"5426270409877345":[],"543939":31,"54393936":31,"5443909":[],"544421":[],"544439":31,"54490887":[],"54637219":33,"54725976":[],"54760497":[],"54811237":[],"548263635652985":[],"54843215":[],"548432150659993":[],"54856099":[],"54873252":[],"54880148":[],"54921401":[],"54928947e":37,"54935794":[],"54it":6,"55":[1,9],"55020405":[],"55020649":[],"55042779":[],"55094784":30,"551023":[],"55102329":[],"55179339":[],"55196383":[],"55225408":30,"55386681":[],"55460327e":[],"55542568":[],"5555555555555556":1,"55582742":[],"5567":6,"55688514":[],"557795":[11,31],"55838":35,"55854694":11,"55916434":[],"559791959661649":[],"55996153":[],"55it":[],"56":[1,9],"56033697":5,"560379":11,"56037913":11,"56042437":[],"56072658":[],"56102529":27,"56108455":21,"561410":[],"56141009":[],"56198284":5,"56342158":[],"564":9,"56408898":30,"56423957":[],"56423957069263":[],"564374":[11,31],"56453869":[],"564759":[],"56475921":[],"56476512e":[],"565":9,"5653087":[],"56536":[0,30],"56541622e":[],"56589683":33,"566":9,"56636616e":[6,32],"567":9,"56763673":[],"56778296":11,"567783":11,"56783103":[],"56790195e":[],"568":[9,33],"56804783":[],"56832496e":[],"56857739e":[],"569":[1,9],"56912044e":[6,32],"56922102":[],"56939714":5,"56947078":[],"56965674":33,"56967917":[],"56977352":[],"56990537":27,"56it":[],"57":[0,8,9,28,30],"570":9,"57016227":23,"57080764":23,"571":[5,32],"571105947979344e":[6,32],"571105947979412e":[6,32],"57192197":[],"57201944e":[6,32],"57212292":27,"57252451e":[],"57261202":[],"57293306":23,"57331229":31,"5736973":23,"574465":[11,31],"57468142":[],"57492326":[],"57521514":[],"57584612":[],"575870409023631":[],"576":33,"5769230769230769":9,"57735536":21,"57803254":[],"57819238e":[],"57833531":23,"57847325":[],"57852915":23,"57881465":[],"57886743":[],"57914918":[],"57933547":[],"58":[9,10,28,30],"58013829":[],"58084123":[],"58202531":23,"58257727":21,"582987":11,"58298728":11,"5833333333333334":9,"583595":31,"58379362":[],"5847256":[],"58492636e":31,"58493493":[],"58493681":[],"58583003":[],"58589719":[],"58735893":[],"58827236":6,"5888888888888889":1,"58890784":[],"58914105":[],"589841":[],"59":9,"59009792":[],"59030403":30,"59078383":[],"590784":[],"591317992":4,"59184268":[],"59188296":30,"59215613":[],"59244881":[],"592766658048914":23,"59348521":[],"59354079":6,"59355752e":[],"59372982":[],"59391196":11,"593912":11,"59411814":5,"594241":[],"59424119":[],"5944444444444444":1,"59465457e":[],"59491404e":[],"59630232e":[],"5965161e":37,"59683811":[],"59698459":[],"59730078":[],"59741748e":36,"59779819":35,"598549916355722":27,"59854992":27,"59875207":[],"59884169":[],"59908884":[],"59963873":[],"59971727":[],"5cm":27,"5f":[8,35],"5x":8,"5y":8,"6":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,23,25,27,28,30,31,32,33,34,35,36,37],"60":[1,3,6,9],"60000":4,"60026673":[],"60041459e":[],"600529":[],"60052901":[],"60116388":11,"601164":11,"60151468":[],"60160003e":[],"6019067271":4,"60193996":27,"6029291":[],"60293962":5,"60321647":23,"60342978":33,"60375434":[],"6038642":[],"60418171":[],"60420593":5,"60451189e":[],"60543038":31,"60552651":[],"60570744":[],"60575887":23,"60588173":[],"60605083e":[],"606251":[],"60625144":[],"60664448":[],"60673226":11,"606760":5,"60737006e":37,"60762863":[],"6087346":30,"60921896":[],"60929685":33,"60940356":[],"60943791":[23,30],"60999067":[],"61":[],"61069681":[],"61083596e":[],"61106937e":[],"6111111111111112":1,"61113781":[],"61130099":11,"611301":11,"61192203":[],"61192712":[],"61209378e":37,"612939":31,"61321722e":[],"61325173":[],"613579":31,"61382924":[],"613893902124586":[],"61395701":[],"61414743":[],"61468323":[],"614808":[11,31],"6153846153846154":9,"61564092":[],"6156409232714415":[],"61602014e":[],"6161104":36,"61621902":[],"61774362":[],"61775176":33,"618746":[],"61883807":[],"618982":31,"61979664e":[],"62":2,"6200":30,"6201":30,"6202":30,"6203":30,"6204":30,"62113349e":[],"621584":[],"62158409":[],"62242138e":[],"62275788":35,"62286539":[],"62288579":30,"62323175":37,"62351789":[],"62373464":11,"625":[7,34],"62551462":[],"62573269":[],"62617788":[],"62620041e":[],"626635268":[6,33],"626678":[],"6266783":[],"6267112":[],"62671667":[],"62714703":37,"62716271":[],"62725226":32,"628":6,"62863106e":[],"62886648":[],"62894215":5,"62905281e":[],"62908496":[],"62918713":[],"62954328e":[],"63":[0,1,2,6,9,33],"63025821e":[6,32],"63030526":[],"63031478":[],"630315":[],"63037846":6,"63042739":[],"63046054":[],"63071772":[],"63142399":[],"63142731":[],"63162342":31,"63207408":[],"63209435":[],"63249532e":[6,32],"63307537":30,"63309898":[],"6333349473431832":[],"63347711":[],"63371136e":[],"63490568":[],"63498144":5,"63546236":[],"63555267e":[],"63615006":27,"63619709":[],"63693246":30,"63760101e":36,"63801791":30,"6380763200092493":[],"63833441e":[],"6383903":[],"63896182":[],"638962":[],"6389681":[],"63898112e":[],"63919355":[],"639194":[],"63980912":30,"64":[1,2,3,4,13,23,30,35,36],"64009263":[],"64012627":5,"6401576":[],"640567":5,"6405671":5,"6407249":[],"640x480":[6,13],"64192473":[],"64316192":33,"64322974":[],"64361375":[],"64362404":[],"64373221":[],"64373635e":35,"64399916":[],"64411666":[],"64412879":[],"6441397":[],"64425744":[],"64505146":27,"64516328":[],"64564368e":[],"646283":[11,31],"64689773":23,"64713979":[],"64721597":36,"64742912e":[6,32],"647473":[11,31],"64796751":[],"64857542":[],"64885265":[],"649":[],"64909048":[],"64911288":27,"649382":[11,31],"64952115":23,"64976691":[],"64x50":1,"65":[1,8,9],"650":[],"65082441":[],"651":[],"65183066":[],"651831":[],"652":[],"65243388e":21,"65259487":27,"65293772":[],"653":[],"6533977":[],"653398":[],"6536392":31,"654":[],"65410649":36,"65442354":31,"654424":31,"65475653":[],"65476419":27,"655":[],"65525178":23,"65532045":11,"65543115":[],"65554958":[],"65571174e":31,"65591748":[],"65593984":[],"65599456":31,"656":[],"65641173":[],"6568154596723088":[],"6568686180915178":[],"65686862":[],"65720152e":[],"6572612e":37,"65738717e":[],"65743689":31,"65751456":30,"65759901":[],"658":2,"65833132":31,"65870313":11,"65885453":5,"65889641e":[],"65891389":31,"658914":31,"659":2,"65900052e":[],"65917558":[],"65944342":35,"65it":6,"66":[],"660":2,"66003032":30,"66018725e":[],"66063786":[],"66064822":31,"66080313":31,"66204648":6,"66215333":27,"662153330760193":27,"662836197064178":[],"66289235":[],"66294408":31,"6629598":[],"662960":[],"66342634e":[],"66363129":23,"66365453e":[],"6638":9,"664314":[],"66431407":[],"66456459":[],"66487438":[],"66498292":[],"6652177":31,"66560":9,"66575697":30,"6663569":[],"66694492":37,"667":9,"6671767":[],"66729685":[],"66757105e":[],"66809369":[],"668172":31,"66841959":35,"6690108":[],"66951679":[],"67":9,"67015946e":[],"6702":[],"67047975e":[6,32],"67088558":[],"67100236":[],"67199457":30,"67231298":[],"67238764e":[],"672721":31,"672759":[],"67275915":[],"67313212":[],"67314874e":5,"67374815":[],"674":33,"67435043":[],"67464946":[],"67490857":35,"67495943":[],"67511113":30,"67524588":[],"67561021":[],"67819487e":[],"67834752":[],"67875366":[],"678754":[],"67925887":30,"67it":[],"68":[],"6801":[],"68072161":[],"6809195":[],"680920":[],"68092237e":[],"68110474":[],"6816947":[],"68192193":5,"68257097":[],"68258595":27,"68281739":23,"68286725":31,"6831505":[],"68352799":[],"68402334":37,"68534263e":[6,32],"68542204":5,"68591105":[],"68637642":[],"68640031":30,"68655456":[],"6869":9,"68735473":[],"68822559":[],"688226":[],"68824222":23,"68826552":[],"68827947":30,"68830164":23,"68857788":[],"6887363571":4,"68879472":[],"68929213e":[6,32],"689519":[11,31],"68953877":11,"689539":11,"68989446":30,"69":[9,27],"690":9,"690617":31,"69069n_":27,"69089532":[],"691":1,"691364":[],"69136414":[],"69182892e":[],"69227923":[],"69230769":35,"6923076923076923":9,"69247718":[],"6927554":[],"69303453":[],"693035":[],"69311221":23,"6932681":36,"69391797":[],"69417174":[],"69435454":[],"69438869":[],"69463406":23,"69465386":[],"69484813e":5,"69484973":30,"69504801":6,"69515531":[],"69566966":[],"69634577e":[6,32],"69695259":5,"697346":[],"69734609":[],"69756791":[],"69768266":[],"6980":[21,35,36],"69824402":23,"6988905":[],"69903406":[],"69925648":23,"69978197":5,"699782":5,"69983227":[],"6999536":11,"69it":[],"6n_":27,"6pm":30,"7":[0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,21,23,25,26,27,29,30,31,32,33,34,35,36],"70":[1,6,7,9,34],"7002164":[],"70037324e":31,"70039784":[],"70135856":30,"701370":5,"70159137":23,"70241548":[],"7026722043092946":[],"7026908764394864":11,"7029975":[],"70301068":[],"70362677":[],"70408202":23,"70469324":[],"70474145":[],"70499955":[],"70514808":[],"70587399":[],"705946":[],"70594608":[],"70630967":[],"70653767":4,"70665448":[],"70704566":[],"7070883":[],"70710678":[5,31],"70711022":[],"7074705":[],"70811405e":37,"70832814":5,"70857635":[],"7086067479626619":31,"70928399":[],"709284":[],"71":1,"71129677":21,"71142161":31,"711422":31,"7119":9,"712018":[11,31],"71261809":[],"71263851e":37,"7127128":[],"71332117":[],"713763":[],"71376303":[],"71380438":23,"71384267e":35,"71441086":[],"71460518":23,"71469351":[],"7150195":[],"71505132e":[],"71507714e":[],"71524686":[],"71582784":[],"7163835161938888":23,"71672742e":36,"71737253":31,"71761101":31,"718165":5,"71838601":[],"71860732":[],"71957514":23,"7198234":[],"72033728":23,"7204561":23,"720889407643293":[],"72174172":11,"72236654":[],"72271878e":[6,32],"7228852":[],"72288611":[],"72309979e":[],"72364915":30,"7236674":5,"724":3,"72427854":[],"7249499":[],"72521196":5,"725212":5,"725256":[],"7252563":[],"726017":[],"72601722":[],"72602818":[],"72710494":[],"727132":11,"7271324":11,"72744372":[],"72770687":[],"727707":[],"72771857":[],"72848736":[],"72859758":5,"72952595":[],"72962885":[],"72964493e":[],"72981762":8,"72992196":[],"73":[6,9,33],"73018893":[],"73031999":[],"73062648":[],"73063053":[],"73068535":[],"73071831":[],"731000":31,"73122034":[],"73176319":[],"73203674":[],"73204357":36,"73252708":[],"73265885":[],"73305640e":[],"733096":31,"73337355":[],"73374853e":37,"73397147":30,"73578772":[],"73594414e":36,"73595198":[],"736282":11,"73628249":11,"73646130e":[],"73690387":35,"737184":[],"73718419":[],"73741131e":[],"73785069":[],"737851":[],"73853838":[],"73958682":[],"73986200e":[],"73994248":[],"74":[6,33,35,36],"740":9,"74028787e":[],"7403629637766833":[],"74038232":[],"74075864":[],"74081822":8,"74101067e":36,"74171049":[],"74180248":30,"74259663":[],"742597":[],"74272285e":[],"74291603e":[],"74384949":31,"74607851":31,"74613334":[],"74724414e":[],"74724774":35,"74761815":23,"74829661":31,"74840212":5,"7487814387207385":[],"74878144":[],"74883972":[],"74900488":[],"74957448":[],"749765":31,"75":[5,6,8,9,11,24,31,33,36,37],"75018686":[],"750187":[],"75025744":[],"750445":31,"75050135":31,"75080943":[],"7509571":[],"7510197":[],"7511273":[],"75131415":[],"75138064":[],"751699":[11,31],"75170092":5,"75216828e":35,"75269037":31,"75300068":[],"75345893":27,"7539148284817965":[],"75406226e":[],"75424998":[],"75433448":[],"7546022135629743":11,"7546682196464342":[],"75532041":[],"75576555":31,"75600095":[],"756352":31,"75654448":[],"75674251":30,"75677341":[],"756828":[],"75682834":[],"75737136":23,"75760403":[],"7577":33,"75770568":31,"7577113351177733":[],"75956617":[],"76":[2,9,28,30,34,35],"76030841":36,"76120718":[],"761574":[],"76157429":[],"76190591":32,"76262775":[],"76277254":[],"76329289":[],"7642448":[],"764245":[],"76426396":30,"765":[7,34],"76527062":[],"76533281":[],"765333":[],"76542156e":[],"7658599":[],"76612827":[],"766163196245293":[],"7663967":23,"76686148":[],"76690383":33,"76692036e":[],"767367275553824":[],"76790092":[],"76807288":[],"76855921":[],"76887316e":[],"7692307692307693":9,"76936315":5,"76940759":[],"76942272":[],"7694444444444445":1,"76996262e":[],"77":[2,9,28,30,35,36],"77014839":23,"77030637":[],"77039278":30,"77106886":[],"771128":[],"77152076":5,"77152924":[],"7718":9,"77199379e":[],"772588722239781":[35,36],"77352152e":[],"77354301":[],"774498":[],"77449804":[],"77465911":[],"77482712":[],"77507653":[],"7755649":11,"775565":11,"77559615":[],"77594586":30,"77596142":23,"77635684e":[],"77636e":[35,36],"77652198e":[],"77659961":[],"7766443":[],"777112373675558":30,"77714169":8,"77725472":[],"777255":[],"77803692":[],"7782028952":4,"77829399":21,"77845284":[],"77873845e":[],"77959897":[],"78":2,"78009660e":31,"78010668":[],"78156479e":5,"78184120e":[6,32],"78186404":[],"78254537":[],"78278086":[],"78326199e":[],"78340902e":[],"78385675":30,"78459458":[],"78671736":[],"78745927":[],"78758569":[],"78762558":36,"78876155e":[],"78892891":[],"78941903":5,"78945959":23,"79":2,"79010601":23,"79086674":23,"79111643":5,"79135536e":[],"79171202":[],"79247398":[],"79280475":[],"793167":31,"794282":[11,31],"79469098":[],"79503363":[],"7953443":32,"79622905":[],"79623487":[],"796235":[],"79633065":33,"79718864":[],"79778008":6,"79787194":[],"797872":[],"797e":6,"79849321":[],"79866484":[],"79870689e":[],"7989356":[],"79898903":[],"7d7d58":[9,10],"8":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,21,23,24,25,27,30,31,32,33,34,35,36,37],"80":[0,1,2,5,6,8,9,31,32,33],"800":[4,7,34],"80011603e":[],"80056922":[],"80072356":11,"800724":11,"800782161095708":5,"801356":[],"8030191":[],"80354994":6,"80374623":23,"80410179":[],"80413696":[],"80460179":33,"80469739":5,"8055555555555556":1,"80576215":[],"80609615e":[6,32],"80609616e":[6,32],"80637385":[],"80740939":[],"80847477e":[6,32],"80848093e":36,"8084934":[],"80853029":27,"80855691":[],"808557":[],"80907609":[],"80979265":[],"81":[1,2],"81006889":27,"81007381":[],"810150":11,"81015037":11,"81035098":[],"81042619e":[],"81048318e":[6,32],"8110093e":36,"81160425":5,"81208109":27,"81218742e":[],"81246697":[],"81283649":[],"81318307":[],"8133":[],"81333808":6,"813957":5,"81395716":5,"81425129e":[],"81478187":30,"81479491":[],"81506255":[],"81559586":[],"815am":[28,30],"81622636":[],"81633628":11,"816454":31,"816847":31,"81684805":36,"81707832":30,"81826799":23,"81839897":[],"81889188":[],"81919129":[],"81924504":21,"819253":[],"81925302":[],"81931348":[],"81947005":[],"81979166":[],"81987609":11,"82":2,"82060913e":[],"8207274870895702":[],"82079885":[],"82121282":[],"82130663":[],"82146046":[],"82161167":[],"82198978":5,"82242798":[],"82259916":23,"8227":[],"8232102961414203":[],"823417":[],"82341746":[],"82376174e":[],"82418008":[],"82418352":[],"8244":[],"8250103":[],"82533209":[],"82551764":[],"82559478":[],"82623709e":[],"8265786":5,"82688363":[],"82802004":[],"82832579":[],"82844656":30,"82914126":[],"829252":[],"82925222":[],"83":2,"83020679":[],"8305555555555556":1,"83146596":33,"83220985":23,"83231208e":36,"83363025":[],"83369175":[],"83377498e":36,"83463634e":[],"83466807":[],"83512277":5,"8352834":[],"83641435":[],"83655756":[],"83718206":[],"83741078":23,"83816147":[],"83823317e":[],"83824223":[],"83870189":6,"8387133":[],"83884553e":[],"839957":[],"83995705":[],"84":2,"84019294":21,"84155431":30,"84159992":[],"842":[0,7,34],"8423144":[],"842436":31,"84254917":[],"843":[0,7,34],"84351715":[],"84355903e":1,"844":[0,7,34],"84401886":[],"84443254e":1,"84478178":35,"84605507":[],"8461538461538461":9,"84661230e":[],"84668873":[],"84707251e":[],"84711297":[],"84726382":[],"8475889":30,"84767088":[],"8476874":[],"84780262":6,"84789579e":[],"8485":[],"84858":33,"84862355":[],"8488":[],"84907109":30,"84923989e":[6,32],"84972787":[],"84985833":30,"84994524":5,"85":[1,2,9],"85005989":[],"85014487":[],"850164":5,"85035562":27,"85043503":11,"8505072899794293":[],"85064942":[],"85068028":36,"85079059":[],"85108001":[],"85112594":[],"8517571":[],"85222243":[],"85259666e":[],"85263220":6,"85276538":[],"85278920e":5,"8529175":30,"85293303e":[],"85298956":21,"853":33,"85378708":[],"85408468e":35,"85422602":[],"85427641":27,"85437905":[],"85551266e":[],"85601992":5,"85613835":5,"85625134":[],"85703369":[],"85711016":[],"85777073":[],"857771":[],"858":9,"8583333333333333":1,"85866294e":[],"85871255":[],"85945208e":[],"85975973e":21,"86":2,"86009093":[],"86013055e":36,"86016288":[],"86062977":6,"86066395":[],"86067818":[],"86117291":5,"86123808e":[],"86134827":5,"86143379":[],"86145244":11,"86174943":[],"86192682e":[],"86197958":[],"86240935":[],"86247117":[],"86267497":[],"862675":[],"86273371":32,"8638888888888889":1,"86416941":[],"86434639":30,"86445334":[],"86458368e":37,"86459987":[],"865":[0,7,34],"86519139":[],"866":[0,7,34],"86602331":[],"86629161":[],"86630":9,"86639832e":[],"86643649":[],"8666666666666667":1,"867":[0,7,34],"86737671":[],"86757762":[],"86799623":35,"86810":9,"86861591e":36,"86867512":[],"86868711":35,"86891741":[],"8691787":[],"86943859":[],"86978877":[],"87":[0,9],"87020155":[],"8702784034":4,"870337":[],"87068171":32,"87070464":[],"870704644539707":[],"87072815e":31,"87093752":[],"87148597":[],"87169607e":[],"87186187":[],"8720648":[],"8722222222222222":1,"87238538":[],"87340054":[],"87381451":5,"87399194":[],"8746702":27,"87473452":[],"87494456e":[],"875":1,"87584434":[],"8759":[35,36],"87627342":33,"87637891":23,"87696461":[],"877":6,"87732748":[],"87740526":[],"87788573":[],"87818331":[],"87878356":[],"87884833":[],"87981676":[],"88":[2,30,35,36],"88046261":5,"8805555555555555":1,"88064505":[],"88135577e":[],"88157423":[],"88168312e":[6,32],"8817842e":[],"88182591":31,"88236598e":[],"8825782":[],"88289263":[],"882972378790114":27,"88297238":27,"88323026":31,"88336879":5,"8834":[],"88377332":[],"884669":31,"88501323":[],"88529063e":[6,32],"88551766e":[],"88594444":[],"88613493":31,"88614317":[],"88632765":36,"88639567":[],"88653291":[],"88738394e":[],"88809826":[],"88860399":[],"8888888888888888":1,"88960947":[],"8896094720230128":[],"89":[2,9],"890033":[],"89003324":[],"8901199":36,"89017198e":[],"89044267":[],"89058005":[],"8905826":[],"89069029":[],"89126914e":31,"89155606":30,"891559":5,"89155934":5,"8917148":[],"891715":[],"89184351":[],"89229722":[],"89288636":11,"8931686":35,"89408972":[],"89410423":5,"8944444444444445":1,"89457785":[],"89463761e":[],"89527291":11,"89533642":[],"89540936":[],"89543945":[],"89563074":37,"8962":[],"89654756":[],"89692576":30,"89710385e":[],"89724282":[],"89755794":27,"89766337e":[],"8978":[],"89845198":[],"89961861":23,"8f":[6,33],"8g":[6,33],"8n":23,"8x8":1,"9":[0,1,2,3,4,5,6,7,8,9,11,12,13,14,18,21,23,24,26,27,28,30,31,32,34,35,36,37],"90":[1,2,6,9],"90075537":5,"9011":6,"90114639":[],"90135464e":[],"90137221":[],"90137794":30,"90140097":[],"90168941":23,"90220243":5,"90266948":5,"9027777777777778":1,"90281987":36,"90300219":[],"90304177e":[],"9040":9,"90475506e":[6,32],"9054":33,"9055555555555556":1,"906589":[],"9065894":[],"906747":5,"90717653":[],"907177":[],"90842732":[],"90860768":[],"90894281":[],"90903158":23,"91":[28,30],"910":9,"91099021":[],"91100141e":35,"9111111111111111":1,"91114704":[],"91128596":5,"91247848e":37,"91270333":[],"91312563":[],"91365263":[],"91410559e":[],"91416944e":[],"91433102":30,"91434750e":[],"914672":11,"91467223":11,"91492986e":[6,32],"91546928":[],"91648657":[],"91650453":36,"9166666666666666":9,"91669165":[],"916692":[],"91672129":[],"91722512e":[],"91744988":[],"91752854":[],"91760278":5,"91811422":[],"91812702":5,"91854134":[],"91864509":23,"918785":[],"918992":31,"91933003":[],"919503":[],"9195033":[],"91961463":[],"92":[6,9,28,30],"92003207":[],"92080432":30,"92192012":[],"9225384545636204":[],"9230769230769231":9,"92308585":21,"92308867":[],"92313548e":37,"92319842":[],"92326255":[],"92341148":[],"92370959":[],"92376655":[],"92458892":36,"924e":6,"925":1,"92507116e":1,"92512799":[],"92527681e":[],"92578916":5,"92599642":[],"92604454":[],"92622842":[],"92661467e":35,"92665802":30,"92678221":30,"9271707090281667":[],"92756256":32,"9277777777777778":1,"92779167e":36,"9288904":[],"92921498":[],"92929225e":36,"92991181":30,"93019783":30,"9305555555555556":1,"9306628":30,"93074023":[],"931":[0,30],"93155188":5,"93158979":5,"93237862":[],"932382":[],"93277949":27,"93289669":[],"93293067":[],"933":[5,32],"93325371e":37,"93366198":[],"933662":[],"93397254e":[],"93492130e":[6,32],"93597168":[],"935972":[],"93601008e":31,"93619369":[],"93668828":[],"936877889972962":[],"937":27,"937057":[],"937082":31,"93709777e":36,"93787605":[],"93799826":5,"938":27,"9387":9,"93891335e":[],"939":[0,27,30],"93900569e":[],"93909866":[],"93937564":[],"93942872":[],"93968601":[],"93970238":[],"93989887":[],"94":[9,27],"94027059":23,"94092702":[],"94099173":[],"94114646":30,"94141801":[],"94221383":[],"94226022e":[6,32],"94255277":[],"94272259":30,"94273542":31,"94284104":5,"94285762":[],"94291287":[],"94320205":5,"94335":11,"9434":[],"94388948":[],"94419718":[],"9444444444444444":1,"94466211":23,"94484047e":[36,37],"94485679":0,"94495682":36,"94499279":35,"9450635":[],"94591015":[23,30],"946167":[],"94616709":[],"94623184":[],"94625725":[],"946276":[],"94627617":[],"946372":[],"94637206":[],"94639099":11,"946957":5,"94704941e":[],"9472222222222222":1,"947607":[],"94766419e":[],"94781064":32,"9482527":5,"9485531":[],"9495484":[],"94973606":[],"95":[1,9,11,33],"95008046":6,"95033155e":[],"950423":[],"95053694e":[],"95115528":[],"95166920e":[],"952063":11,"95206335":11,"95226607":[],"95231424":5,"952387":31,"9527777777777777":1,"95284275":5,"953065564":1,"95338273":[],"95343966":[],"95351665":5,"95354276":[],"95395895":[],"953959":[],"954":27,"95400323":[],"95482298":11,"954823":11,"95497813":21,"95511792":31,"955118":31,"95518112":[],"9555555555555556":1,"95563211":[],"955820c21e8b":4,"95611042":35,"95647867":[],"956563":[11,31],"95684892":5,"95703":[35,36],"95715036":[],"95743466e":[],"95745476":27,"95766504e":36,"95770298":36,"95776346":27,"95793988e":[],"958228616652075":5,"95842106":36,"95845431":[],"95872127":[],"95881375":27,"95882223":36,"95890587":[],"95906059":35,"959076":[],"95935439":[],"96":[6,9,11,33],"960":27,"9601304850035702e":[6,32],"9601304850073734e":[6,32],"96015381":[],"96024953":5,"96075051":35,"96080358":[],"96084663":5,"961":27,"96164155":23,"962":27,"96231225":[],"96251859":[],"96301764":[],"96305058":[],"963187":[],"9637117593816477":[6,32],"96379806e":[],"96385798":11,"963858":11,"96391888":[],"9640435":5,"96414331":[],"96432396":[],"96461948":[],"9647801":[],"9649652536":4,"965548":31,"96581896":21,"96585824":[],"96631321":31,"96660465":23,"96688672":5,"967":[],"9674916":5,"967809":[11,31],"96799937":27,"96826039":[],"96850191":[],"96853248":[],"968650":[],"96865004":[],"96866031":[],"968704":[],"96870431":[],"96894842":[],"96916206":[],"969190":[],"96919021":[],"96919836":[],"9692":[],"969413":5,"96961052":23,"96963458":37,"96991192":[],"97005689":5,"97065359":33,"970827":[],"97082748":[],"97108e":[35,36],"97120565":[],"9712983":[],"97206657":[],"972067":[],"972149":[],"9722222222222222":1,"97228653":[],"9722865317690382":[],"97235642":23,"97243128":5,"97243946":[],"972533":[],"97253307":[],"97272223":[],"97300836":5,"973118":5,"97311824":5,"973663":11,"97366347":11,"97435908":[],"97480604":[],"97482498":[],"974825":[],"97486336":[],"97497404e":[6,32],"97498674":[],"975":1,"97507735":5,"97512176":[],"975484":[],"97548406":[],"97570392":[],"97626519":[],"97630233":33,"9767506308987675":[],"97680846":30,"977":[],"97705827":5,"97716508":[],"97758848":5,"9777777777777777":1,"978":33,"97802245":31,"9780387310732":29,"9780387848570":29,"9781098134174":30,"9781492032632":29,"9781801819312":30,"97836358":[],"978553":5,"97898392":[6,31,32],"97906022e":31,"9792":[],"97926491":5,"97935648":[],"9794096":23,"979656":11,"97965627":11,"97979891":6,"98":[0,1,9,37],"980":9,"9805555555555555":1,"98091621":5,"98108401":30,"981321":31,"98139097":5,"98140006e":[],"98190064":[],"98232596":[],"98246764":[],"98261559e":36,"98271562":[],"98275501":5,"98281205":35,"983310":31,"9833205":30,"98338288":[],"983383":[],"983450":[],"9834505":[],"9838929":[],"98413059":5,"98413606":[],"9841870203276504":[],"98454786":5,"98473694":[],"985":27,"98566191":5,"985725":27,"985725003240627":27,"986":27,"9861111111111112":1,"98619989":[],"98636199":[],"986362":[],"98654811":[],"986699":5,"98680716":5,"98716878":5,"98723376":[],"98740373":[],"98770503":[],"9878":6,"98808176":5,"98822371":6,"9888888888888889":1,"989":[6,27],"9890348":5,"9893447":5,"98947674e":[],"98947894":31,"9898ff":[9,10],"99":[6,9,11,13,21,33,35,36],"990":9,"99003341":[],"99009525":5,"9904314810719695":[],"99072374":[],"99088801":5,"991":27,"991047":[],"99104747":[],"99114739e":[],"99115119":5,"99176998":5,"99194201":[],"992":27,"99201684e":[],"99242921":5,"99265097":5,"99294056":[],"993":27,"9930742":[],"99316252":5,"99318183":[],"99360578e":[],"99368326":[],"99370678":[],"99371056":5,"99389612":5,"99415296":[],"99427512":[],"9943201":5,"99434472":[],"994345":[],"994474":[],"99447418":[],"99456598":35,"99458998":23,"99475306":35,"9947756":5,"9948998579029953":[],"99492986":5,"99498272":[],"9950019477819025":31,"9951059931014423":[],"99512017":[],"9952183728736417":[],"9952505213910134":[],"9952537939995855":[],"99528218":5,"99539415":5,"995522":21,"9955318336036834":[],"99562995":[],"99566069":5,"995702810640425":31,"99578809":5,"9958589197366403":[],"9958983289118531":[],"9959308805732706":[],"9959739":[],"996":[5,32,33],"99607299":36,"99608161":5,"9960887274532307":31,"99619572":[],"9963961":5,"99647992e":[],"99650061":5,"996626":[],"99662602":[],"99663433":21,"9967458":5,"9969461173312454":[],"9969513794144311":[],"99700706":5,"99709215":5,"99723951":[],"997252717901263":[],"99729015":21,"99729756":5,"99751458":5,"99753321e":[],"99758326":5,"99762142":32,"9976783":36,"997746":[],"99774602":[],"99775587":5,"99793613":5,"99799099":5,"99802696":35,"99812668e":[],"99813653":5,"99828624":5,"9983295":5,"99835783":35,"99845267":5,"99848215":[],"99848815":35,"99854557":31,"998577":5,"99861053":5,"99862019":31,"99869482":31,"99871521":5,"99876945":31,"99881845":5,"99883628":31,"99884384":5,"99884409":31,"99884986":32,"99887767":[],"99891093":31,"99891873":31,"99893323":5,"99895448":21,"99898558":31,"999":[9,21,27,35,36],"99901896":5,"99903755":5,"99906023":31,"9990927157696581":32,"99911427":5,"99912709":31,"99913489":31,"99916114":35,"99918546":5,"99919837":5,"99920175":31,"99926459":5,"99927642":31,"9993237":5,"99933188":5,"9993511":31,"99938942":5,"99941797":31,"99942911":[],"99943837":[],"9994385":5,"99944272":5,"9994574":[],"99949266":31,"99949306":5,"99952851":21,"99953381":5,"99953475":5,"99954278":[],"99954434":[],"99954925":35,"99956033":[],"99956181":[],"99956735":31,"99957911":5,"99959609":21,"99961294":5,"99965056":5,"99966798":36,"99967865":5,"99968451":[],"99969576":[],"99970894":31,"99970988":5,"9997332":5,"99975636":36,"99975913":5,"99977375":[],"99977849":5,"99977853":[],"99978365":31,"99979896":[],"99980002":5,"9998161":5,"99984732":5,"99984836":21,"99985591":[],"99985884":36,"99987324":5,"99989103":35,"99989296":[],"99989476":5,"99990413":[],"99990706":[],"99991245":[],"99991263":5,"99991295":[],"99992107":[],"99992746":5,"99993978":5,"99994537":36,"99995":5,"999955585168597":[6,32],"99996755":[],"99997356":36,"99997644":[],"99998727":[],"9x":[6,24],"9y":[6,24],"\u00f8yvind":[6,31,32],"abstract":[1,20,35],"boolean":4,"break":[0,4,6,11,14,30],"byte":[23,30],"case":[0,1,2,3,4,5,6,7,11,12,13,14,16,21,22,23,24,25,30,33,36,37],"catch":0,"class":[0,1,3,4,6,7,8,9,11,12,13,27,30,33,35,36],"default":[0,1,2,4,6,7,8,16,23,24,25,30,31,32,34,37],"do":[0,2,3,4,5,6,8,9,10,11,12,13,14,15,16,21,23,24,25,30,31,34],"ekstr\u00f8m":4,"export":9,"f\u00f8470":[28,30],"final":[0,1,2,3,4,5,6,7,8,9,10,11,13,14,16,18,19,20,24,26,27,28,30,33,34],"float":[0,3,4,5,9,11,13,14,23,30,31,35,36],"function":[2,3,4,5,9,14,15,16,17,18,19,22,23],"import":[0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,24,27,33,34,35],"int":[0,1,2,3,4,5,6,11,13,14,21,23,27,31,33,35,36],"long":[0,1,3,4,12,13,30,34,35,36,37],"m\u00f8svatn":[6,24],"new":[0,1,2,3,5,6,7,8,9,10,11,13,14,17,21,23,30,31,34,35,36],"public":[0,22,30],"return":[0,1,2,3,4,5,6,7,8,9,11,13,14,21,23,24,27,30,31,32,33,34,35,36,37],"sch\u00f8yen":[6,31,32],"short":[4,5,20,24,25,32,33],"super":[5,31,32],"switch":0,"throw":[3,6,27,33],"true":[0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,19,23,24,25,27,30,31,32,33,34,35,36,37],"try":[0,1,2,4,5,6,7,8,9,10,11,13,14,15,16,22,23,24,25,27,30,31,32,33,34,35,36,37],"var":[1,5,6,10,11,18,19,24,27,30,31,32,33],"while":[0,1,3,4,5,6,7,8,9,11,12,13,27,30,31,32,33,34,35,36,37],A:[2,3,5,6,7,10,11,12,13,16,18,20,22,23,24,25,26,27,28,29,31,35],AND:2,And:[0,3,4,5,6,9,13,20,22,24,25,27],As:[0,1,2,3,4,5,6,8,10,12,13,16,23,24,25,27,30,31,32,33,34,35,36,37],At:[0,4,6,13,24,30,35],BE:[0,30],Be:[2,22,30],Being:[13,35],But:[0,1,2,3,5,6,9,10,25,27,31,32,33,37],By:[0,3,5,6,12,13,17,23,30,31,32,33,34,35,36],For:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,26,27,29,30,32,33,34,35,36,37],IF:[6,32],IN:29,If:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,21,22,23,24,25,27,30,31,32,33,34,35,36,37],In:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,22,23,24,25,27,29,30,31,32,33,34,35,36],Is:11,Ising:[5,12,31,36,37],It:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,23,24,25,27,30,31,32,33,34,35,36,37],Its:[1,2,4,11],NO:[9,11],No:[0,6,7,9,30,32,34,36],Not:[0,1,5,6,31,32,33,36,37],OR:27,Of:27,On:[0,3,9,15,24,26,27,28,29,30],One:[0,1,3,4,5,6,7,8,11,12,13,17,21,24,27,31,33,34,35,36,37],Or:[0,1,6,24,30,34,37],Such:[0,6,12,16,27,33,34,35,36,37],That:[0,5,7,10,11,12,14,19,24,27,30,32,33,34,37],The:[4,10,13,14,15,16,18,19,20,21,23,24,25,26,27,28,29],Their:[],Then:[0,1,6,8,9,10,11,12,13,14,23,24,30,33,34,35,36,37],There:[0,3,4,5,6,8,9,11,12,14,23,24,26,27,28,30,31,32,34,35,36,37],These:[0,3,4,5,8,9,10,11,12,13,14,15,16,23,24,25,27,28,30,31,32,35,36,37],To:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,21,23,25,27,32,33,34,35,36,37],With:[0,5,6,8,9,10,11,12,14,18,23,24,25,27,30,31,33,36,37],_0:[5,8,10,11,13,31,34,35],_1:[2,5,6,8,10,11,12,13,14,23,31,32,34,35,36,37],_2:[2,5,8,11,12,13,23,31,35,36],_3:23,_4:23,_9:[13,35,36],_:[0,1,2,4,5,6,7,8,9,10,11,12,13,17,18,19,21,23,24,30,31,32,33,34,35,36],__array_function__:[],__class__:10,__doc__:[6,33],__enter__:[0,7,34],__future__:[8,9,37],__getattr__:32,__getattribute__:30,__getitem__:[0,7,34],__init__:[0,1,3,4,7,14,32,34,36],__main__:[2,36],__mul__:2,__name__:[2,10,32,36],__rtruediv__:[],_accessor:30,_auto10:[6,12,36],_auto11:[6,36],_auto12:[6,36],_auto1:[2,3,4,5,6,7,12,13,21,23,27,31,34,35,36,37],_auto2:[2,3,4,5,6,12,13,23,27,35,36,37],_auto3:[3,4,5,6,12,13,23,35,36,37],_auto4:[4,6,12,13,23,35,36],_auto5:[4,6,12,13,23,35,36],_auto6:[4,6,12,23,36],_auto7:[4,6,12,23,36],_auto8:[6,12,36],_auto9:[6,12,36],_base:8,_build:[0,17,19,22,24,29,30],_c:1,_can_hold_identifiers_and_holds_nam:30,_check_optimize_result:[9,11],_class:8,_compon:11,_coordinate_desc:6,_depth:9,_fraction:9,_generatorcontextmanag:[0,7,34],_i:[0,1,2,5,6,7,8,11,12,13,15,16,17,19,24,30,31,32,33,34,35,36,37],_info_axi:30,_j:[0,1,2,3,5,6,8,13,17,19,24,31,32,33,35],_k:[13,34,35,36],_l:[12,36,37],_lambda:[6,30],_leaf:9,_ll:[3,4,14],_logist:[9,11],_m:10,_make_vjp:2,_multilayer_perceptron:1,_n:[2,5,8,11,13,31,34,35],_node:[2,9],_np:[],_o:[3,4,14],_open_file_or_url:[0,7,34],_p:[5,8,31],_plugin_dir:[3,4,14],_ratio:11,_rc_params_in_fil:[0,7,34],_s:[3,4,14],_sampl:9,_split:[6,9,24],_src:[21,36],_t:[13,21,35,36],_test:[6,24],_tf_getinputpropertieslist:[3,4,14],_trace:2,_valu:2,_varianc:11,_weight:9,_wrapreduct:[],a0:3,a0faa0:[9,10],a1:[0,30],a2:[0,30],a3:[0,30],a4:[0,30],a_0:[0,21,25,30,37],a_1:37,a_1a:[0,30],a_1x:[21,25],a_2:37,a_2a:[0,30],a_2x:[21,25],a_3:[0,30],a_3a:[0,30],a_4:[0,30],a_4a:[0,30],a_:[0,1,16,23,30,31,37],a_h:1,a_i:[0,1,2,12,30,37],a_j:[1,12,37],a_k:[0,1,12,37],aaron:29,ab:[0,2,5,13,14,21,24,30,31,32,35,36,37],ab_channel:[22,36,37],abandon:[1,37],abbrevi:26,abid:27,abil:[0,10],abl:[0,1,4,5,6,7,10,12,13,16,24,31,34,35,36,37],about:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,22,23,24,25,28,32,33,34,35,36,37],abov:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,23,24,25,27,29,30,31,33,34,35,36],abovement:[6,30,33],abscissa:[13,34,35],absolut:[0,2,5,6,13,30,31,32,33,35,36],absorb:[31,32],acceler:[13,21,35,36],accept:[0,3,6,9,24,30,31],access:[0,3,11,27,30],accid:[4,6,33,34],accompani:[0,30,31],accomplish:[8,9,13,35,36],accord:[0,1,2,5,6,9,12,13,14,15,16,27,30,32,33,34,35,36,37],accordingli:11,account:[0,3,5,13,15,27,30,32,33,35,36],accumul:[12,13,21,27,35,36,37],accur:[0,3,4,6,10,13,33,35,36],accuraci:[0,1,3,4,5,6,7,9,10,11,12,25,30,31,34,36,37],accuracy_scor:[0,1,10,30],accuracy_score_numpi:1,achiev:[0,1,5,6,8,12,23,30,32,33,36,37],aco:27,acquaint:22,acquir:[1,22,30,37],acr:0,across:[1,3,6,9,22,30,33],act:[1,3,23],action:27,activ:[0,2,3,4,9,26,28,30,34,35],actual:[0,1,4,5,6,8,11,16,23,27,30,31,32,33,37],ad:[1,3,4,5,8,13,15,16,23,32,33,34,35],ada_clf:10,adaboostclassifi:10,adadelta:[13,35,36],adagrad:[25,37],adam:[1,3,4,25,28,30,37],adap:37,adapt:[4,6,13,29,33,34,37],add:[0,1,2,3,4,5,6,8,10,11,12,15,16,17,21,24,25,27,30,31,32,33,35,37],add_outgrad:2,add_subplot:[1,7,12,14,24,34,35,36,37],addendum:5,addit:[0,2,3,5,6,7,8,9,10,12,13,15,17,21,22,23,24,27,28,29,30,31,32,33,34,35,36,37],addition:[12,13,34,35,36,37],address:[1,9,11,13,30,35,36,37],adjac:[3,12,36,37],adjoint:[5,31,32],adjust:[0,5,12,13,34,35,36],admir:[0,30],advanc:[4,6,12,29,30,33,37],advantag:[1,3,5,6,10,13,23,32,33,34,35,36],adversari:30,afecionado:30,affect:3,affin:[0,3,8,11,31,37],afford:3,aficionado:30,aforement:14,african:0,after:[0,1,2,4,5,6,9,11,12,13,15,21,22,23,24,25,27,30,31,32,33,35,36,37],afterward:[0,30],ag:[0,7,26,30,31,34],ag_0:2,again:[0,1,4,5,6,7,8,10,11,12,13,15,16,21,24,25,27,30,31,32,33,35,36,37],against:[1,4,7,10,21,25,34],agegroup:[7,34],agegroupmean:[7,34],aggreg:[9,10],agorithm:10,agre:[5,6,27,32,33],agreement:[13,21,35,36],ahead:9,ai:[0,25,29],aid:[11,20],aim:[0,1,4,6,7,11,14,15,16,22,23,24,25,31,33,34,37],ainv:5,airplan:3,aka:[5,32,33],al:[0,2,4,15,16,17,24,25,29,30,31,32,33,34,35,37],alarm:[5,7,32,33],aldo:31,algebra:[0,3,5,13,21,22,31,32,33,35,36],algorithm:[0,1,2,4,5,6,7,8,13,14,22,23,24,27,29,30,32,33,34],align:[0,2,5,6,7,8,13,24,27,30,31,32,33,34,35],all:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],allevi:[1,13,34,35,37],alloc:[3,23],allow:[0,1,2,3,5,6,8,10,13,15,16,22,23,24,30,31,32,33,34,35,36,37],almost:[0,1,6,8,11,13,21,27,33,34,35,36,37],alon:[2,9],along:[2,3,4,5,6,9,10,11,22,23,30,31,32,33,34],alpha:[0,1,2,3,4,6,7,8,9,10,13,14,27,30,31,33,34,35,37],alpha_0:3,alpha_1:3,alpha_2:3,alpha_:10,alpha_i:[3,13,35],alpha_k:[13,35],alpha_m:10,alpha_n:3,alpha_opt:[13,35],alreadi:[2,3,4,5,6,10,12,22,23,27,30,31,32,33,36,37],also:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,30,31,32,33,34,35,36,37],alter:1,altern:[0,1,4,5,6,8,9,11,13,23,24,30,31,32,33,34,35],although:[0,1,5,6,8,10,13,16,21,30,32,33,35,36,37],alwai:[0,3,5,6,12,13,16,21,24,27,30,31,32,33,34,35,36,37],am:4,ambit:37,ame2016:[0,30],american:0,among:[0,3,5,9,10,12,23,30,31,32,36,37],amongst:[5,32,33],amount:[0,1,3,4,6,8,10,14,22,33,37],amp:[36,37],an:[1,2,3,5,6,7,8,9,11,12,13,14,15,16,17,19,20,21,22,23,24,25,27,28,29,31,32,33,34,35,36],an_:27,anaconda:[0,1,15,22,24,30],analog:[13,35,36],analys:[6,32,33],analysi:[1,3,4,7,14,15,16,17,19,21,23,29,34],analyt:[2,3,5,6,7,12,13,15,22,24,25,30,31,32,33,34,35,36,37],analytical_gradi:[21,36],analyz:[0,1,3,4,5,6,16,17,24,25,27,31,32],andrew:[1,37],angl:[0,3,9,31],anharmon:3,ani:[0,1,2,3,4,5,6,7,8,9,10,12,14,18,27,30,31,32,33,36,37],anim:[4,12,36,37],ann:[12,36,37],annot:[0,1,3,7,8,30,34],announc:30,anoth:[0,1,3,4,5,6,7,8,10,11,12,13,23,24,25,27,30,31,34,35,36,37],anp:2,ans_vspac:2,ansatz:[0,30],answer:[0,1,3,5,6,23,24,25,28,30,32,33],antialias:[2,6,24],anticip:4,anymor:[1,8,37],anyon:[4,8],anyth:[1,27,37],anytim:[28,30],apach:1,apart:[11,13,34,35],api:[1,22,30],appar:2,appear:[0,1,3,13,16,23,27,35,36,37],append:[1,3,4,8,9,13,21,30,35,36],appendix:24,appli:[0,1,2,3,4,6,7,8,9,10,11,12,13,15,16,24,25,27,29,30,31,32,33,34,35,36,37],applic:[0,1,3,4,5,6,7,9,12,13,21,23,24,27,29,30,31,33,34,35,36,37],apply_gradi:4,approach:[1,2,4,5,6,9,10,11,12,13,17,21,22,27,29,31,34,37],appropri:[2,6,9,12,13,22,27,33,35,36],approv:30,approx:[0,2,3,6,10,11,13,27,30,33,34,35,36],approxim:[0,1,2,3,4,5,6,7,10,11,13,18,19,24,27,30,31,32,33,34,35,36],apt:[0,15,22,24,30],aq:27,ar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aragorn:30,arang:[1,3,4,6,7,9,10,12,13,24,30,34,35,36,37],arbitrari:[1,4,6,8,12,13,27,33,34,35,36,37],arbitrarili:[0,1,11,30],arc:[6,24],architectur:[3,4,12,37],archiv:25,area:[0,3,6,9,24,29,30],arg:2,argmax:[1,11],argmin:[4,10,14],argnum:2,argnum_0:[],argnum_1:[],argsort:11,argu:[1,13,35,36,37],argument:[0,2,3,5,6,11,12,13,21,30,31,32,33,37],argval:2,aris:[0,6,12,13,27,30,33,34,35],arithmet:[0,13,23,30,35,36],arm:[6,32],armadillo:23,arnulf:37,around:[0,1,4,5,6,11,27,30,32,33,37],arr:2,arr_list:[],arrai:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,21,22,24,27,31,32,33,34,35,36,37],arrang:[3,30],arraybox:[2,13,35],arriv:[0,6,9,11,23,27,30,33],arrow:[12,36,37],arrowprop:8,art3d:35,art:[0,1,15,22,30,37],articl:[0,3,4,6,10,18,24,25,30,31,32,33],artifici:[0,2,7,12,29,30,34],artificialneuron:[12,36,37],arug:[13,35,36],arxiv:[3,4,21,24,35,36,37],asarrai:[0,2,6,9,21,31,32,35,36],asid:31,ask:[5,6,11,12,24,32,33,37],aspect:[0,6,22,24,30,31,32,37],assembl:[0,3,30],assert:4,assess:[0,6,24,30,31,32,33],assici:4,assign:[0,7,8,9,12,13,14,26,28,29,30,34,35,36,37],associ:[0,6,9,12,14,27,30,33,36,37],assum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,23,24,27,30,31,32,33,34,35,36,37],assumpt:[0,3,5,6,9,11,18,24,27,30,31],ast:[0,5,6,18,24,30,32,33,34],astronomi:[30,32,34,35,36],astyp:[4,9,10],asymmetri:[0,30],asymptot:[4,6,33],atleast_2d:[],atom:[0,30],attempt:[0,4,6,7,8,10,30,32,34,37],attend:26,attent:[0,23,30],attr:32,attract:[0,10,30],attribut:[0,9,25,30,32],attributeerror:[30,32],audi:[0,30],audio:[3,4],august:[15,16,30],aurelien:[0,15,26,29,30],austfjel:[6,24],author:[0,1,10,27,37],authour:30,auto:[8,9,10,27],auto_exampl:[24,32],autocor:27,autocorrelation_tim:27,autocorrelform:27,autocovari:27,autoencod:[4,22,30],autoencond:22,autograd:[22,25,30,37],autom:[0,22,29,30],automac:23,automag:30,automat:[0,1,2,3,4,11,16,22,23,30],automobil:3,autonom:4,avail:[0,1,4,6,7,10,11,15,20,21,22,23,24,25,26,28,29,30,33,34,36],averag:[0,1,3,6,9,10,13,14,21,27,28,30,31,32,33,34,35,36],avoid:[0,4,5,6,9,11,13,21,23,30,31,33,34,35,36],awai:[2,3,6,31,32,37],awar:[2,10],award:[28,30],ax:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,23,24,25,30,33,34,35,36,37],axes3d:[2,6,13,24,34,35],axes_grid1:6,axhlin:8,axi:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,21,23,24,27,30,31,32,33,34,35,36,37],axiom:[5,32,33],axis_arg:[],axlabel:[0,30],axvlin:[4,8],axvspan:4,b1:8,b2:8,b3:8,b:[0,1,3,4,5,6,8,9,10,12,13,14,15,16,21,27,28,30,31,32,33,34,36,37],b_0:[0,37],b_1:[0,2,12,13,35,36,37],b_2:[0,13,35,37],b_5:[13,35,36],b_:[0,1,23,37],b_group:9,b_i:[0,1,2,12,30,36,37],b_ia_:[0,30],b_ia_i:0,b_index:9,b_j:[1,12,36,37],b_k:[0,1,12,13,35,36,37],b_m:[12,36],b_score:9,b_valu:9,babcock:30,bachelor:[26,28],back:[0,3,4,5,6,8,9,10,15,23,25,27,30,31,32,34,35,36],backbon:23,backend:[0,1,4,7,21,34,36],background:[29,30,31,37],backpropag:[1,37],backtrack:9,backup:23,backward:[1,2,4,12,23,37],backward_pass:2,bad:[6,31,32],badli:27,bag:[9,22,30],bag_clf:10,baggin:30,baggingboot:10,baggingclassifi:10,baggingtre:10,balanc:[6,33,34],band:23,bandwidth:23,bar:[0,6,11,15,16,24,30],barber:29,bare:[4,10],base:[0,1,3,4,5,7,8,9,10,14,22,27,28,29,30,31,32,34,37],basi:[5,7,8,10,11,12,13,23,31,32,34,35,36,37],basic:[2,6,8,12,13,14,22,24,27,30,35,36],batch:[3,4,11,12,13,21,25,34],batch_shap:4,batch_siz:[1,3,4],batchnorm:4,bay:[7,34],baydin:37,bayesian:[5,22,29,30,32,33],beam:[30,34,35,36],becattini:28,becaus:[0,1,2,3,4,5,6,8,9,12,13,14,30,32,33,34,35,36,37],becom:[0,1,2,5,6,7,9,12,13,21,27,30,31,32,33,34,35,36,37],been:[0,1,2,3,4,5,6,11,12,13,22,23,24,25,30,31,32,33,35,36,37],befor:[0,1,2,3,4,5,6,7,8,12,13,14,20,23,24,25,27,30,31,32,33,34,35,36,37],beforehand:[0,27,30],begin:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,21,23,24,27,28,30,31,32,33,34,35,36,37],behav:[1,6,13,33,34,35,37],behavior:[0,1,13,30,34,35,36,37],behaviour:[12,36,37],behind:[0,1,6,8,13,30,34,35],being:[0,1,2,3,4,5,7,8,10,11,12,13,17,27,30,31,32,33,34,35,36,37],believ:[9,23],belong:[7,8,9,13,14,34,35],below:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,23,24,25,27,30,31,32,33,34,35,36,37],benchmark:10,benefici:[1,13,35,36],benefit:[0,1,4,11,13,15,22,30,34,35,36],bengio:[1,21,25,26,29,30,31,35,36],benign:[1,7,9,34],benno:37,berner:37,besid:[4,5,32],bessel:[5,31,32,33],best:[0,1,2,3,4,5,6,7,8,9,10,12,13,24,25,28,30,31,33,34,35,37],best_estimator_:34,beta1:[21,35,36],beta2:[21,35,36],beta:[0,1,3,5,6,7,10,11,13,16,17,18,19,21,24,30,31,34,35,36],beta_0:[0,1,3,5,6,7,13,30,31,32,34,35],beta_0x_:[0,30,31],beta_1:[0,1,3,5,6,7,10,13,30,31,32,34,35,36],beta_1x_0:[0,30],beta_1x_1:[0,7,30,34],beta_1x_2:[0,30],beta_1x_:[0,30,31],beta_1x_i:[7,13,31,34,35],beta_2:[0,3,13,30,31,35,36],beta_2x_0:[0,30],beta_2x_1:[0,30],beta_2x_2:[0,7,30,34],beta_2x_:[0,30,31],beta_2x_i:31,beta_3:3,beta_3x_i:31,beta_4x_i:31,beta_:[0,3,6,7,13,30,31,32,34,35,36],beta_i:[0,3,5,30,31,32],beta_j:[0,5,6,13,18,24,30,31,32,33,35,36],beta_k:[13,34,35],beta_lasso:36,beta_linreg:[13,21,34,35,36],beta_logreg:36,beta_m:10,beta_mg_m:10,beta_n:3,beta_ol:36,beta_p:[7,34],beta_px_p:[7,34],beta_ridg:36,betavalu:5,better:[0,1,2,3,4,6,9,10,11,12,13,21,30,31,32,33,35],between:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,17,21,24,25,27,30,31,32,33,34,35,36,37],beyond:[0,1,5,6,8,13,21,24,30,31,34,35,36,37],bf:[13,14,23,27,34,35],bg:30,bgd:[13,35,36],bia:[0,1,2,3,5,8,9,10,12,13,19,30,31,32,34,35,36,37],bias:[1,2,3,5,6,9,12,25,32,36],bibliographi:24,big:[0,1,2,5,6,14,18,32,33],bigger:[1,6,31,32,37],bigr:[12,36],bike:9,bilbo:30,billion:[3,12,22,36,37],bin:[0,7,27,34],binari:[0,2,3,5,7,9,10,12,25,30,32,33,34],binarycrossentropi:4,bind:[0,31],binomi:[22,27,30],binsboot:[6,33],bioinformat:0,biolog:[1,12,36,37],bios1100:[22,30],bird:[0,3],birth:30,bishop:[26,29,30],bit:[1,4,23,27,30,37],bitwis:27,bivari:2,bk:[0,13,35,36],bla:[23,30],black:[8,9,14,21,36],blob:[16,20,24,34,35,36],block:[6,10,22,23,27,30,33],blog:[25,30],blogpost:4,blue:[0,3],bmatrix:[0,1,3,5,7,8,11,13,23,30,31,32,34,35,37],bmi:1,bn:[],bodi:[0,1,4,12,30,36,37],bold:1,boldfac:[0,5,16,31,32],boldsymbol:[0,1,2,3,5,6,7,8,10,11,13,14,15,16,17,18,19,21,24,30,34,35,36,37],boltzmann:[12,22,30,36,37],book1:29,book:[19,24,25,29,30,31,33],boost:[1,9,22,30,37],boostrap:10,bootstrap:[1,13,19,22,24,25,30,34,35,36,37],borrow:30,boston_dataset:0,bot:8,both:[0,1,4,5,6,8,9,10,13,14,15,16,22,23,24,25,27,28,30,31,32,33,34,35,36,37],bottl:[7,34],bound:[0,8,12,35,36,37],boundari:[2,4,8,11,12],box:[2,4,9],boxed_arg:2,boyd:[8,13,34,35],bracket:[4,27],brain:[1,7,12,34,36,37],branch:9,breast:[5,7,11,25,32,33,34],breat:25,breviti:[13,21,35,36],brew:[0,15,22,24,30],brg:8,brief:[24,25,31],briefli:[0,30],bring:[0,5,6,10,25,31,32],broad:0,broadcast_idx:[],brought:[13,21,22,30,35,36],brownle:4,browser:30,brute:[3,5,11,31,32,34,37],bs:[8,9,10],buffer_s:4,bui:4,build:[0,4,5,6,10,23,27,30,32,33,34,35,36,37],built:[0,1,3,4,6,33],bunch:11,busi:0,bxe2t:[36,37],c1:[8,11],c2:[8,11],c:[0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,19,22,23,27,28,29,31,32,33,34,35,36,37],c_0:27,c_1:[12,36],c_2:[12,36],c_3:[12,36],c_4:[12,36],c_:[0,8,9,10,13,21,27,34,35,36],c_i:[12,13,35,36],c_k:27,ca:[1,30,37],cach:10,cal:[0,8,10,12,13,15,16,30,34,35,37],calcul:[0,1,2,4,5,6,8,9,10,11,12,13,14,15,16,18,21,23,25,27,30,32,33,34,35,36,37],california:25,call:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,18,19,21,22,23,24,25,27,28,30,31,32,33,34,35,36,37],calor:[0,31],cambridg:[13,29,34,35,37],can:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,27,28,29,31,32,34],cancel:[0,13,30,31,35,36],cancer:[5,10,25,32,33],cancerpd:[7,34],candid:[8,9,10,35],cannot:[0,1,4,5,6,7,8,9,26,27,31,32,34],canopi:[0,15,22,24,30],canva:[24,25,30],cap:[5,32,33],capabl:[0,1,8,13,22,30,35,36],capac:[2,28],capita:0,caption:[24,25],captur:[4,11,12,36,37],car:[3,4],card:[0,7,30,34],cardin:[1,37],care:[11,34],carefulli:[13,35],carlo:[0,6,22,27,29,30,33],carri:[2,6,7,24,33,34],cart:10,casella:29,cast:[1,37],cat:[3,4],categor:[0,1,3,9,11,30],categori:[0,1,3,7,10,12,14,30,34,36,37],categorical_crossentropi:[1,3],caus:[0,5,6,7,27,30,31,32,33,34],causal:0,causat:[0,30],cax:1,cb:[6,30],cbar:1,cc:[0,1,5,13,25,30,31,32,34,35,37],ccc:[5,12,32,36],cd_fast:6,cdf:27,cdot:[0,2,6,12,13,14,23,27,30,33,34,35,36],celebr:[13,34,35],cell:[0,1,2,3,4,6,7,8,9,10,13,14,24,32,34],center:[0,1,6,7,8,9,11,14,24,27,30,32,33,34,37],central:[0,3,5,6,8,16,23,25,30,31,32,37],centroid:[14,27],centroid_differ:14,centuri:3,certain:[0,3,6,7,9,27,30,31,33,34],certainti:33,cg:[13,35],cha:0,chain:[0,1,13,22,27,30,35,36],challeng:[35,36,37],chanc:[1,5,13,27,32,33,35,36],chang:[0,1,2,3,4,5,6,8,9,11,12,13,14,21,23,24,25,27,30,31,32,33,34,35,36,37],channel:3,chap4:37,chapter3:[0,19,24],chapter:[0,6,10,11,16,18,21,23,24,25,29,30,31,32,33,34,35,36,37],charact:[0,3,5,8,30,31],character:[8,9,10,12,27,36,37],characterist:[0,1,3,10,13,21,30,35,36],charg:[0,30],charl:0,chase:4,chatgpt:24,chd:[7,34],chddata:[7,34],cheap:[5,31],cheaper:[1,13,35,36,37],check:[0,1,3,4,5,6,11,13,23,30,35,36,37],checkmark:3,checkpoint:4,checkpoint_dir:4,checkpoint_prefix:4,chen:10,cheng:31,chiaramont:2,choic:[0,1,2,3,4,6,9,12,13,14,19,23,25,30,31,33,34,35,36],choleski:[5,23,31],choos:[2,3,6,9,10,11,13,14,24,25,33,34,35,36],chosen:[0,1,2,6,8,9,10,13,16,21,25,27,30,33,34,35,36,37],chosen_datapoint:1,christian:29,christoph:[26,29,30],cifar10:3,cifar:3,circ:[1,12,37],circl:[0,8,12,31,36,37],circuit:3,circumfer:9,circumv:[1,5,13,31,35,36,37],cite:24,ckpt:4,clariti:27,class_nam:[3,9],class_val:9,class_valu:9,classic:[7,9,13,34,35,36,37],classif:[0,3,5,6,7,8,11,12,22,24,29,30,31,32,33,35,37],classifi:[0,1,4,7,9,10,11,25,30],classificaton:1,classifii:10,clean:1,clear:[1,5,10,12,13,21,35,36],clearli:[0,3,5,6,7,8,18,27,31,32,33,34],clever:[1,10],clf3:0,clf:[0,6,8,9,10,30,31],clf_lasso:6,clf_ridg:[6,30],clip:[3,27],clone:28,close:[0,1,2,4,6,8,9,11,12,13,14,24,27,29,30,33,34,35,36,37],closer:[3,5,13,31,35,36],closest:[8,11,13,14,35],closur:[22,30],cloud:[22,30],cluster:[0,1,4,6,11,22,30,33],cluster_label:14,cm:[1,2,3,6,8,9,13,24,34,35],cmap:[0,1,2,3,4,6,8,9,10,24,30],cmap_arg:6,cmb:26,cmd:9,cn_:27,cnn:[12,36,37],cnn_kera:3,cntk:[22,30],co:[0,2,3,6,9,13,21,30,33,35,36],code:[3,4,6,7,8,15,16,17,19,22,23,24,27,29],coef0:8,coef:[0,30],coef_:[0,5,6,8,9,13,30,31,32,34,35],coeff:5,coeffici:[0,3,5,6,7,8,9,13,15,16,23,30,31,32,33,34,35,36],coerc:[0,6,30,33],coin:[10,27],coin_toss:10,col:[0,11,30,31],colab:[22,30],cold:9,colinear:0,collabor:[24,25],collaps:8,collect:[0,2,6,10,11,21,22,27,29,30,33,36,37],collinear:[5,31,32],color:[0,3,4,6,8,9,10,21,24,27,35,36],color_channel:3,color_cod:6,colorbar:[1,6,24],colsample_bytre:10,colsaobject:10,column:[0,1,2,5,6,7,8,9,11,12,17,23,30,31,32,33,34,36,37],columntransform:9,com:[4,6,16,20,21,22,24,25,29,30,33,34,35,36,37],combin:[1,2,5,6,7,10,27,32,33,34,35,36,37],come:[0,1,3,4,5,12,13,14,15,25,30,31,32,33,35,36,37],command:[0,1,30],comment:[0,4,5,6,15,16,24,25,30,31],commerci:[0,15,22,24,30],commod:[0,30],common:[0,1,3,5,6,7,9,11,13,14,24,25,27,30,31,33,34,35,36,37],commonli:[0,1,4,6,7,9,13,14,31,33,34,35,36],commun:[0,12,24,36,37],commut:3,commutatitav:3,compact:[0,1,3,5,6,7,9,11,12,13,14,30,31,32,33,35,36],compair:0,compar:[0,3,4,5,6,11,13,15,16,21,23,24,25,30,31,32,33,34,35,36,37],comparison:[2,4,13,25,35,36],compat:[7,34],compet:0,competit:10,compil:[0,1,3,4,13,15,21,22,23,30,35,36],complet:[0,2,3,4,9,12,30,36],completenn:[12,36],complex:[1,5,8,9,11,12,13,15,16,19,25,30,33,35,36,37],complic:[0,1,9,13,30,33,34],compoment:31,compon:[0,1,3,4,5,6,7,9,14,16,22,30,31,32,33,34,37],components_:11,compos:[9,12,13,14,21,22,30,35,36,37],compphys:[0,6,16,17,19,20,22,24,26,28,29,30,34,35,36],compress:[0,30,31],compris:[6,34],compromis:[5,31],compulsori:[22,30],comput:[0,1,2,3,4,5,6,7,8,10,11,12,13,15,16,17,21,22,23,24,25,26,27,29,30,31,32,33,34,37],computation:[0,3,6,9,13,27,30,34,35,36,37],computationalscienceuio:30,computerlab:[24,25],con:25,concaten:[2,4,6,14],concatenate_arg:[],concav:[1,9,13,31,34,35],concentr:[0,10],concept:[0,2,22,30,31],conceptu:[12,13,34,35,36,37],concern:[0,1,4,7,30,34],concic:30,conclud:[0,5,13,21,32,33,35,36],conclus:1,cond:2,conda:[0,1,15,22,24,30],condis:31,condit:[0,2,4,5,6,8,9,11,13,27,30,31,36],conduct:22,condwav:2,confid:[0,5,6,7,8,18,24,30,31,32,34],configur:[3,21,36],confirm:[5,12,32,33,36],confus:[5,6,7,10,23,31,32,33],confusion_matrix:9,congruenti:27,conjug:[4,8],conjugaci:[13,35],conjunct:3,connect:[0,1,3,4,9,11,12,13,23,30,31,34,35,36,37],consequ:[5,6,8,10,12,13,31,32,33,34,35,36],conserv:[5,14,31],consid:[0,1,2,3,5,6,7,8,9,10,12,13,16,19,21,23,24,25,27,30,31,32,33,34,35,36,37],consider:[0,1,5,13,30,31,32,33,34,35],consist:[0,1,2,3,4,6,12,13,19,21,24,25,27,31,33,34,35,36,37],constant:[0,2,4,5,6,8,12,13,27,30,31,32,33,34,35,36,37],constitu:[0,30],constitut:[2,6,33,34],constrain:[1,3,5,7,11,32,34],constraint:[5,6,8,13,31,32,33,35,36],construct:[0,1,2,3,5,6,7,8,9,10,11,23,27,30,31,32,33,34],consult:25,contact:[0,30],contain:[0,2,3,4,5,6,7,8,9,11,12,13,17,19,21,23,24,25,27,29,30,31,32,33,34,35,36,37],contemporari:30,content:[1,22,23,30],context:[6,10,13,24,33,34,35,36,37],contextlib:[0,7,34],contigu:23,continu:[0,1,2,3,4,5,6,7,8,9,10,12,13,17,18,21,23,24,25,27,30,31,32,33,34,35,37],contour:[9,10,13,35],contourf:[8,9,10],contrast:[1,4,9,10,12,36,37],contribut:[0,3,5,13,21,27,30,31,32,35,36],contributor:[0,24],control:[0,1,3,9,13,15,22,30,35,36],conv2d:[3,4],conv2dtranspos:4,conv:[3,4],convei:30,conveni:[0,5,6,12,13,23,24,25,30,32,33,34,35,36],convent:[12,31],converg:[1,2,4,5,6,8,9,11,13,14,21,25,31,32,34,35,36,37],convergencewarn:[1,6,8,9,11],convert:[0,1,4,5,9,11,13,23,30,31,35,36],converttomatrix:4,convex:[4,5,7,31],convinc:[13,34,35],convolut:[1,4,22,30],cook:24,cool:[4,9],coolwarm:[6,24],coordin:[5,12,14,31,32,36],coorel:0,copi:[0,1,2,14,31],copyright:25,core:[0,2,7,10,30,34],corel:30,coronari:[7,34],corr:[0,5,7,11,31,34],correalt:[11,22],correct:[0,1,2,3,4,5,7,13,23,27,30,31,32,33,35,36],correctli:[1,2,6,7,10,24,25],correl:[0,1,3,5,6,7,10,12,13,21,22,27,30,32,33,35,36,37],correlation_matrix:[0,5,7,11,31,34],correspond:[0,3,5,6,8,9,11,12,15,16,17,22,23,24,27,30,31,32,33,36,37],cortex:[12,36,37],cosin:[3,6,33],cost:[0,2,3,5,6,7,8,9,12,13,16,17,19,21,24,25,30,36],cost_deep_grad:2,cost_funct:2,cost_function_deep:2,cost_function_deep_grad:2,cost_function_grad:2,cost_grad:2,cost_sum:2,costol:[13,21,35,36],could:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,17,23,24,25,27,30,31,32,33,34,35,36,37],coulomb:[0,30],count:[0,9,26,27,28,30],countor:[13,35],coupl:[4,5,6,32,33],cours:[0,1,3,5,11,24,25,26,28,31,33],courvil:[21,25,26,29,30,31,35,36],cov:[5,6,11,23,27,30,31,32,33],cov_xi:[5,11,31],cov_xx:[5,11,31],cov_yi:[5,11,31],covari:[0,7,22,23,30,32,34],covariance_matrix:[5,11,14,31],cover:[0,5,17,22,28,29,31,32],covert:[0,30],covxi:27,covxx:27,covxz:27,covyi:27,covyz:27,covzz:27,cpu:1,cqofi41lfdw:37,craft:3,creat:[1,2,3,4,5,9,10,11,12,22,30,32,34,35,36,37],create_biases_and_weight:1,create_convolutional_neural_network_kera:3,create_neural_network_kera:1,create_x:[5,11,31],credit:[0,7,28,30,34],crim:0,crime:0,criteria:[0,4,9,10,14,27,30],criterion:[9,10,13,34,35,37],critic:[6,24,31,32],critiqu:[24,25],cross:[0,1,3,7,9,10,13,22,25,27,30,31,32,35,36,37],cross_entropi:4,cross_val_scor:[6,33,34],cross_valid:[7,10,34],crossvalid:[6,33],crucial:[1,27,37],cs231:3,cs:[26,28],csr_matrix:[23,30],csv:[0,4,6,7,9,30,33,34],ctnk:1,cube:37,cubic:0,cumbersom:[5,32,33],cumsum:[10,11,30],cumul:[7,10,27],cumulative_heads_ratio:10,cup:[5,32,33],current:[1,2,3,4,13,14,21,29,34,35,36,37],curs:[0,31],curv:[6,7,10,12,24,34,36,37],curvatur:[13,34,35,36],custom:[6,14,24],custom_cmap2:[9,10],custom_cmap:[9,10],cutpoint:9,cv:[6,7,10,33,34],cvxbook:[13,34],cvxopt:[5,8,31],cybenko:37,cycl:[1,12,36,37],cyclotron:32,d2_g_t:2,d:[1,2,3,4,5,6,7,8,9,10,11,13,14,23,27,28,30,31,32,33,34,35,36,37],d_f:[13,34,35],d_g_t:2,d_net_out:2,da:[3,37],dagger:[5,23,31],dai:[1,9,22],damp:3,daniel:28,darget:9,darkr:27,dat:[0,30],dat_id:[0,6,7,9,30,31,33,34],data1:14,data2:14,data3:14,data4:14,data:[2,4,5,8,10,12,13,14,17,18,19,21,23,25,29,33,35,36],data_id:[0,6,7,9,30,31,33,34],data_indic:1,data_panda:30,data_path:[0,6,7,9,30,31,33,34],databas:1,datafil:[0,6,7,9,24,30,31,33,34],datafram:[0,4,5,7,9,11,30,31,34],datapoint:[1,5,6,7,11,13,31,33,34,35,36],dataset:[0,4,6,7,8,9,10,11,13,14,15,16,19,24,25,30,33,34,35,36,37],datatyp:4,date:[15,16,17,18,19,20,21,24,25,30,31,32,33,34,35,36,37],daughter:10,david:[29,30],davison:33,db:37,dbh:1,dbo:1,dc5e85cd93c3:25,dcomposit:23,ddot:2,dead:[1,37],deadlin:[16,17,18,19,20,21,26],deal:[0,1,3,5,6,8,11,13,14,17,18,23,24,27,30,31,32,34,35,36,37],dealt:0,debt:[7,34],debug:[0,5,6,32,33,34],decad:[0,3,36],decai:[0,13,27,30],decemb:[26,28,30],decent:10,decid:[0,2,3,5,6,9,24,32,33,34],decim:[0,30],decis:[0,1,8,11,22,29,30],decision_funct:8,decision_tre:9,decisiontreeclassifi:[9,10],decisiontreeregressor:[0,9,10],decisiontreeregressordecisiontreeregressor:9,declar:[0,4,23,30],decompos:[5,6,23,31,37],decomposit:[0,6,12,24,30,32,36,37],decompost:[5,31],deconvolut:3,decorrel:[10,13,21,35,36],decreas:[1,2,4,5,6,10,11,13,32,33,34,35,36],deduc:[0,30],deep:[3,7,12,13,21,22,25,26,29,31,35,36],deep_neural_network:2,deep_param:2,deep_tree_clf1:9,deep_tree_clf2:9,deep_tree_clf:[9,10],deepen:[5,22,30],deeper:[0,3,4,30],deeplearningbook:[25,29,30,32],deer:3,def:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,21,24,27,30,31,32,33,34,35,36,37],def_covari:27,default_tim:4,defect:[5,31],defici:[5,31],defin:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,27,31,32,33,34,35,36],definit:[1,2,5,6,7,8,10,11,12,13,17,23,27,31,32,33,34,35],defint:27,defvjp:2,defvjp_argnum:[],degre:[3,5,6,8,9,10,11,15,16,17,19,24,27,30,32,33,34],deisenroth:31,del:1,delet:6,delimit:4,deliv:[26,30],delta:[0,2,3,6,8,12,13,14,21,30,35,36,37],delta_0:[3,37],delta_1:[3,37],delta_2:[3,37],delta_2a_1:37,delta_3:3,delta_4:3,delta_5:3,delta_:[1,23,37],delta_h:[0,1,30],delta_i:37,delta_j:[3,12,37],delta_k:[12,37],delta_l:[1,3],delta_momentum:[13,21,35,36],delta_n:[0,3,30],delug:22,delv:0,demand:[13,34,35],demonstr:[0,3,5,6,7,11,12,22,30,31,32,33,34],demystifi:[36,37],den:4,denomin:[1,5,32,33],denot:[1,2,6,7,13,27,34,35,36],dens:[1,3,4],densiti:[0,2,6,27,30,33],depart:[25,28,30,31,32,33,34,35,36,37],depend:[0,1,2,4,5,6,7,8,11,12,13,15,21,22,23,24,27,30,31,32,33,34,35,36,37],depict:27,deploy:[0,15,22,24,30],deprec:2,depth:[0,3,9,10,23,33],deriv:[0,1,2,6,7,8,10,11,13,16,17,19,21,22,24,30,36],derivati:[13,35,36],derivative_fn:[13,35],derivb1:37,derivb2:37,derivw1:37,derivw2:37,descend:[5,9,11,31,32],descent:[0,1,3,7,8,12,30,31,37],descent_i:[21,36],descent_x:[21,36],describ:[0,2,4,5,6,8,10,11,12,13,18,21,23,24,25,30,32,33,35,36,37],descript:[0,8,9,25,30],design:[0,1,3,4,5,6,7,10,11,12,13,15,16,17,18,19,24,25,30,32,33,34,35,36,37],designmatrix:[0,30],desir:[0,2,4,5,13,14,30,31,34,35],despit:[1,12,36,37],destroi:23,det:[5,23,31],detail:[0,6,11,13,14,23,24,25,31,34,35],detect:[3,8,12,36,37],determin:[0,2,3,4,5,6,8,9,10,11,12,13,16,23,27,30,31,32,33,34,35,36,37],determinist:[7,13,27,34,35,36,37],deternin:37,dev:[1,24,37],develop:[0,3,5,8,10,11,12,21,22,23,24,25,30,31,32,33,36,37],deviat:[0,1,2,4,5,6,19,24,27,30,31,32,33,37],devic:[3,4,14],devis:[12,36,37],df1:30,df:[4,8,11,13,30,35,37],di:0,diag:[5,8,31,32],diagnost:[1,10,37],diagon:[0,5,7,13,18,21,23,24,27,30,31,32,34,35,36],diagonaliz:[5,31],diagram:10,diagsvd:6,dice:[6,27,33],dict:[6,8,34],dictionari:0,did:[0,1,5,6,7,10,11,14,24,25,30,32,33,34,35],die:[1,37],diff1:2,diff2:2,diff:[2,37],diff_ag:2,diffeent:8,differ:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,21,22,23,24,27,29,30,31,32,33,34,37],different:37,differenti:[0,3,16,21,22,23,30,31,34],differential_oper:2,difficult:[0,1,6,10,13,21,24,27,30,33,35,36,37],difficulti:[0,1,13,30,34,35,36,37],diffonedim:2,digit:[0,1,3,4,6,24,25,26,28,30],digress:37,dilemma:[13,35,36],dilut:[1,37],dim:[4,11,14,23],dimens:[0,1,2,3,4,5,8,9,11,14,16,17,23,30,31,32,37],dimension:[0,4,5,6,9,11,13,14,19,21,22,23,25,30,32,33,34,35,36],dimensionless:[0,3,30],diment:23,dimnsion:4,diod:3,direct:[0,1,2,4,7,11,12,13,14,21,30,31,34,35,36,37],directli:[1,4,5,6,27,31],directori:[0,7,34],disadvantag:[0,30],disappear:[3,6,33],disc_loss:4,disc_tap:4,discard:[6,11,33,34],disciplin:[0,3,12,36,37],disclaim:27,discontinu:37,discord:30,discourag:[13,34,35],discov:[0,30],discover:[5,32],discret:[1,3,5,7,13,32,33,34,35,36,37],discrimin:[4,7,10,11,34],discriminator_loss:4,discriminator_loss_list:4,discriminator_model:4,discriminator_optim:4,discuss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,35,36,37],diseas:[7,34],disguis:[6,31,32],disord:[1,7,34],dispai:[36,37],displai:[0,1,3,4,5,6,7,8,9,10,11,12,14,24,27,30,31,33,34,36,37],displaystyl:[0,5,17,30,31,32],disregard:[0,30],dissimilar:[11,14],dist:14,distanc:[0,8,9,11,14,27],distance_list:9,distinct:[3,7,8,9,10,14,34],distinctli:8,distinguish:[0,4,7,8,27,30,34],distplot:0,distribut:[0,1,4,6,7,10,11,13,14,15,16,18,19,22,23,24,25,30,31,34,35,37],distrubut:[0,15,22,24,30],dive:[0,8,23,30],diverg:[1,13,34,35,36,37],divid:[0,1,2,3,5,6,7,8,9,11,12,25,27,30,31,32,33,34,36,37],divis:[6,8,9,13,21,23,27,33,34,35,36,37],dlopen:[3,4,14],dna:[7,34],dnn1:4,dnn2_gru2:4,dnn:[0,1,2,4,12,30,36,37],dnn_kera:1,dnn_model:1,dnn_numpi:1,dnn_scikit:[0,1,30],doamin:[32,33],doc:[0,6,16,17,19,20,22,24,25,26,28,29,30,34,35,36],document:[4,9,11,13,34],doe:[0,1,2,3,4,5,6,8,10,11,12,13,14,16,21,23,24,27,30,33,34,35],doesn:[3,9,12,37],dog:[1,3,4],domain:[5,8,13,24,25,32,33,34,35],domin:[0,30],don:[0,1,3,5,6,7,8,11,13,15,21,22,24,25,30,31,34,35,36,37],done:[0,2,3,4,5,6,9,10,11,13,17,23,24,30,31,32,33,34,35,37],dot:[0,2,3,5,6,7,8,9,10,11,12,13,21,23,24,27,30,31,32,33,34,36,37],doubl:[3,4,23,30],doubli:[1,37],doubt:24,down:[0,3,6,9,11,12,13,21,34,35,36],download:[0,1,3,5,6,23,24,29,30],downsampl:3,dozen:[1,37],dq:[6,33],drag:[13,35,36],dramat:11,drastic:4,draw:[4,6,10,13,33,34,35],drawback:[0,1,3,13,31,34,35,36,37],drawn:[1,4,6,7,11,27,30,33,34,37],drive:[3,4],driven:3,drop:[0,1,5,6,11,13,21,27,30,31,32,33,35,36,37],dropna:[0,6,30,33],dropout:4,dt:[2,3,13,27,35,36,37],dtype:[0,1,2,3,4,14,21,23,30,31,36,37],dual:8,dualiti:6,dub:[0,30],due:[1,2,5,6,8,10,12,13,28,30,31,33,34,35,36,37],dummi:0,dure:[0,1,3,4,8,9,11,17,20,22,24,30,33,35,36,37],dwell:0,dwh:1,dwo:1,dx:[2,3,8,27,37],dx_1:27,dx_1p:[6,33],dx_2p:[6,33],dx_mp:[6,33],dx_n:27,dxp:[6,33],dy:[1,8,27,37],dylib:[3,4,14],dynam:4,dz:8,e:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,19,21,27,28,30,31,32,33,34,35,36,37],e_:[0,2,30],each:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,22,23,25,26,27,28,30,31,32,33,35,36,37],eager:33,eapprox:[0,30],earli:[1,13,21,35,36],earlier:[0,5,7,8,9,11,12,13,20,21,30,31,34,35,36,37],earthexplor:[6,24],eas:[6,9,14,33],easi:[0,5,6,7,8,9,10,11,12,13,18,21,22,23,25,30,31,32,33,34,35,36,37],easier:[5,6,8,9,13,25,27,30,31,33,35,36],easiest:[13,34,35],easili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,23,24,30,31,32,33,34,35,37],eastern:[28,30],ebind:[0,30],eblock:9,econometr:30,economi:5,ecosystem:[22,30],ect:26,edg:3,edgecolor:[6,33],edu:[13,25,34],educ:[0,24,25,30,34],eff:27,effect:[1,4,10,13,27,35,36,37],effic:1,effici:[0,3,10,13,22,23,27,30,34,35,36,37],efron:[6,33],egrad:[13,35,36],eig:[5,11,13,21,23,27,30,31,34,35,36],eigen:27,eigenpair:[5,11,31],eigenvalu:[0,5,8,11,13,21,23,30,31,32,34,35,36],eigenvector:[5,11,13,17,31,32,35],eight:[23,30],eigval:[23,27,30],eigvalu:[11,13,21,34,35,36],eigvec:[23,27,30],eigvector:[11,13,21,34,35,36],eispack:[23,30],either:[1,5,6,7,8,9,10,11,13,15,16,24,25,27,30,31,32,33,34,35,37],elabor:27,elarn:3,electr:[0,3,12,30,36,37],electron:30,eleg:11,element:[1,2,3,4,5,6,7,8,11,12,13,17,18,20,21,22,23,24,25,26,29,31,32,33,34,37],elementari:[10,13,23,35,36,37],elementwis:[3,13,35,36],elementwise_grad:[2,13,35,36],elessar:30,elif:[14,21,36],elim:23,elimin:[3,8],els:[1,2,3,4,7,9,12,13,14,23,34,35,36,37],elu:1,elus:[0,30],email:[26,28,30],embark:37,embed:[0,11,31],embodi:[6,19,24,33],emit:27,emner:29,emphas:[0,10,22,30],emphasi:[0,22,29,30],empir:[1,11,27,37],emploi:[0,1,5,6,11,13,24,25,27,30,31,32,33,34,35],employ:0,empti:[6,10,33],emul:[12,36,37],en:[22,29],enabl:[11,21,36],enbodi:[6,33],encod:[0,3,5,7,9,11,14,17,30,31,32,34],encompass:[0,24,27],encount:[0,1,5,6,7,13,21,27,30,31,33,34,35,36,37],encourag:[24,25],end:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,21,23,24,27,28,30,31,32,33,34,35,36,37],end_box:2,end_nod:2,end_valu:2,endpoint:[3,6],energi:[0,4,6,31,33],enet_coordinate_desc:6,enforc:[12,36,37],eng:29,engin:[0,1,3,4,22,30,37],english:[24,25],enocurag:24,enoent:[3,4,14],enorm:3,enough:[0,6,13,30,33,34,35],ensembl:[1,9,37],ensur:[0,1,2,3,5,6,11,13,21,27,31,32,33,34,35,36,37],entail:30,enter:[5,6,17,31,32],enthought:[0,15,22,24,30],entir:[1,3,7,9,22,27,30,34,35,36,37],entiti:[9,12,23,30],entri:[0,5,8,11,12,23,30,31,32,33],entropi:[1,3,7,10,13,30,35,36],enumer:[0,1,2,3,4,6,8,30,31,32],env:[0,1,2,3,4,6,7,8,9,11,14,21,27,30,32,34,36],environ:[2,9,21,22,24,36],eo:[0,6,30,33],eol:[0,30],eosfit:[0,30],epoch:[0,1,3,4,12,13,21,25,30,35,36],epsilon:[0,5,6,7,13,19,24,30,31,32,33,34,35,36,37],epsilon_0:[0,30],epsilon_1:[0,30],epsilon_2:[0,30],epsilon_:[0,30],epsilon_i:[0,30,31],eq:[3,13,14,23,27,34,35],eqnarrai:[3,5,6,32,33],equal:[0,1,2,3,4,5,6,8,9,11,12,13,14,15,23,24,25,27,30,31,32,33,34,35,36,37],equat:[1,3,4,5,6,7,8,9,10,11,13,14,16,17,18,19,21,23,24,27,33,36],equilibrium:[2,12,36,37],equiv:[3,13,23,27,34,35],equival:[0,1,5,7,8,11,13,21,22,23,30,31,32,33,35,36],erf:27,eriador:30,eridg:30,err:[0,7,10,34],err_:[6,33],err_sqr:2,errat:[13,34,35],errno:[0,3,4,7,14,34],erron:2,error:[1,2,4,5,6,7,9,11,12,13,15,16,17,18,19,21,22,23,24,25,27,32,34,35,36,37],error_estimate_corr_tim:27,error_hidden:1,error_output:1,escap:[13,34,35,36],especi:[1,3,9,12,13,24,25,35,36,37],essenti:[0,5,6,9,10,12,14,24,25,27,31,36,37],establish:[0,6,10,11,15,24,25,30],estim:[0,1,5,6,7,10,11,13,22,27,30,31,34,35,36,37],estimated_mse_fold:[6,33,34],estimated_mse_kfold:[6,33,34],estimated_mse_sklearn:[6,33,34],et:[0,2,4,15,16,17,24,25,29,30,31,32,33,34,35,37],eta0:[8,13,34,35],eta:[0,1,3,8,12,13,21,25,30,34,35,36,37],eta_:[13,21,35,36],eta_t:[13,35,36],eta_v:[0,1,3,30],etc:[0,1,3,5,7,8,9,11,12,13,14,15,21,22,23,24,25,27,31,34,35,36],ethic:22,etsim:33,euclidean:[0,14,31],evalu:[0,2,3,4,5,6,9,13,24,27,30,31,32,33,34,35,36],evaluationform:[20,24,35,36],evaluationgrad:[20,24,35,36],evalut:[13,35,36],even:[0,1,3,4,5,6,8,9,10,11,12,13,14,22,23,27,30,31,32,33,34,35,36,37],evenli:4,event:[5,7,10,27,32,33,34],eventu:[0,5,6,11,12,13,24,25,28,31,32,33,34,35,36,37],everi:[0,1,2,3,4,5,6,9,10,11,12,13,14,22,27,28,30,31,32,33,34,35,36,37],everyth:[4,12,21,37],everywher:[4,13,34,35],evolv:0,exact:[0,2,5,11,12,13,23,27,30,31,35,37],exactli:[0,3,4,6,12,22,24,31,33,36,37],exam:30,examin:[6,33],exampl:[5,11,12,13,15,16,19,20,22,23,24,25,27,29],exce:[1,12,13,21,35,36,37],excel:[0,1,4,5,10,25,30,31,37],except:[0,3,4,6,7,8,9,23,34],excess:[0,30],excit:0,exclud:[1,6,12,24,31,32,33,34,36,37],exclus:[0,1,3,6,27,30,33,34,37],execut:[2,5,13,31,35,36],exemplifi:[13,35,36],exercic:[28,30],exercis:[5,22,24,25,26,28,32,33,34,35,36],exercisesweek35:17,exhaust:[6,33,34],exhibit:[0,5,6,8,30,31,33],exist:[0,1,2,3,4,5,6,7,8,9,13,14,18,23,24,25,30,31,32,33,34,35,37],exit:[5,23,31],exp:[0,1,2,5,6,7,8,10,11,12,13,15,16,21,24,27,30,31,32,33,34,35,36,37],exp_term:1,expand:[5,7,11,13,31,34,35],expandus:[0,7,34],expans:[0,3,5,8,10,12,13,30,31,34,35,37],expect:[0,1,5,6,7,11,12,13,15,16,19,21,22,24,25,30,31,34,35,36,37],expectation_value_of_h_wrt_p:27,expens:[6,10,13,34,35,36],experi:[0,1,6,8,13,22,24,30,31,33,34,35,36],experiment:[0,4,6,9,27,30,33],expert:[1,9,37],explain:[0,6,9,10,11,13,19,24,30,34,35],explained_variance_ratio_:11,explan:25,explanatori:[0,30],explicit:[0,3,6,13,21,23,24,30,31,32,35,36],explicitli:[0,4,8,21,36],explod:1,exploit:[0,3,12,13,30,35,36,37],explor:[1,4,6,8,13,22,24,25,34,35,36,37],expon:1,exponenti:[0,1,5,6,10,13,24,27,30,32,33,34,35,36,37],export_graphviz:9,export_text:9,exporttext:9,expos:22,expr:37,express:[0,2,3,5,6,7,10,12,13,16,21,23,24,25,27,30,32,33,36],exptmean:27,exptvari:27,extend:[0,2,7,11,13,17,22,30],extens:[0,12,15,22,30,36,37],extent:[0,1,6,29,33],extern:[3,6,9],extra:[1,3,5,28,30,31],extract:[0,3,5,6,7,8,11,13,23,30,31,34,35,37],extrapol:[0,30],extrem:[0,1,4,5,6,7,8,9,13,16,23,31,32,33,34,35,36,37],extremum:[13,34,35],extrins:11,ey:[0,5,6,13,14,23,30,32,34,35,36],f11:[0,30],f12:[0,30],f13:[0,30],f1:[13,35,36],f1_grad:[13,35,36],f1d:[13,35],f2:[13,35,36],f2_grad_x1:[13,35,36],f2_grad_x1_analyt:[13,35,36],f2_grad_x2:[13,35,36],f2_grad_x2_analyt:[13,35,36],f3:[13,35,36],f3_grad:[13,35,36],f3_grad_analyt:[13,35,36],f4:[13,35,36],f4_grad:[13,35,36],f4_grad_analyt:[13,35,36],f5:[13,35,36],f5_grad:[13,35,36],f6:[13,35,36],f6_for:[13,35,36],f6_for_grad:[13,35,36],f6_grad_analyt:[13,35,36],f6_while:[13,35,36],f6_while_grad:[13,35,36],f7:[13,35,36],f7_grad:[13,35,36],f7_grad_analyt:[13,35,36],f8:[13,35],f8_grad:[13,35],f9:[0,13,30,35],f9_altern:[13,35],f9_alternative_grad:[13,35],f9_grad:[13,35],f:[0,1,2,3,4,5,6,7,8,10,12,13,14,16,18,19,21,23,27,28,30,31,32,33,34,35,36,37],f_0:[3,10],f_1:[10,13,34,35],f_2:[12,13,34,35,36],f_3:[12,36],f_:10,f_d:27,f_grad:[13,35,36],f_grad_analyt:[13,35,36],f_i:[0,6,12,16,33,36],f_m:[3,10],f_n:3,f_raw:2,f_vec:2,f_wrap:2,face:[13,34,35,36],facecolor:[6,8,27,33],facil:[0,15,22,30,34,35,36],facilit:[12,36,37],fact:[0,1,3,5,9,11,12,13,30,31,32,33,34,35,36,37],factor:[0,1,3,5,6,9,10,11,13,23,27,30,31,32,33,35,36],factori:[13,35,36],fade:6,fafab0:[9,10],fahimeh:[28,30],fail:[0,6,8,9,11,13,28,30,33,34,35,37],fail_on_error:[0,7,34],failur:[7,34],fairli:[1,2,27,37],faisal:[16,31],fake:4,fake_loss:4,fake_output:4,fale:25,fall:[8,9,26],fals:[0,1,2,3,4,5,6,7,9,10,14,23,24,30,31,32,33,34,35,36],famili:[0,7,8,27,34],familiar:[0,3,5,6,8,15,22,23,24,27,30,32,33,37],famou:[6,12],far:[0,3,4,5,6,8,11,12,13,14,30,31,34,35,36,37],fashion:[0,9,10,30],fast:[1,3,6,10,12,13,22,27,30,33,34,35,37],faster:[1,11,13,35,36,37],fastest:[13,23,34,35],favor:[7,34],favorit:27,fc:3,fd:[0,7,34],featur:[0,1,3,5,6,7,8,10,11,12,13,18,22,24,25,27,30,32,33,34,35,36,37],feature_nam:[0,1,7,9,34],feautur:9,fed:[1,37],feed:[0,2,3,11,22,25,30],feed_forward:1,feed_forward_out:1,feed_forward_train:1,feedback:[4,20,30],feeddorward:4,feedforward:[1,4,12,37],feel:[0,5,6,11,13,15,16,21,22,24,25,28,30,32,35,36,37],feet:0,felt:[24,25],fetch:[6,24],few:[1,3,4,5,9,27,30,35,37],fewer:[0,9,11,30],ffnn:[1,12,25,36,37],field:[0,3,6,12,22,36,37],fifteen:37,fifth:[0,6,15,16,24,30],fig:[0,1,2,3,4,6,7,12,13,14,24,30,34,35,36,37],fig_id:[0,6,7,9,30,31,33,34],figaxi:27,figsiz:[0,1,2,3,4,6,7,8,9,10,30,33,34],figur:[0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,21,22,24,25,30,31,32,33,34,35,36,37],figure_id:[0,6,7,9,30,31,33,34],figurefil:[0,6,7,9,30,31,33,34],file:[0,2,3,4,5,6,7,9,14,24,25,30,31,32,33,34],file_prefix:4,filenam:30,filenotfounderror:[0,7,34],fill:[5,9,31],filter:[0,3,4,7,34],financ:0,find:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,21,22,24,25,27,30,31,32,34,36,37],fine:[0,14,15,30],finish:2,finit:[3,5,6,12,13,17,27,31,32,33,35,36,37],first:[0,1,2,3,5,6,7,8,9,10,11,13,14,15,16,17,21,23,24,27,28,29,33,36],first_moment:[21,35,36],first_term:[21,35,36],firsteigvector:11,fit:[1,3,4,5,6,7,8,9,11,12,13,15,16,17,21,24,25,27,31,33,34,35,36,37],fit_beta:[6,31,32],fit_intercept:[0,5,6,31,32,33],fit_mod:9,fit_transform:[0,6,8,9,11,33,34],fiti:[0,30],five:[0,9,17,24,30,31,34,37],fix:[0,3,4,6,10,11,12,13,21,24,25,30,33,34,35,36],fixedloc:6,flag:4,flat:[3,4,12,13,14,21,34,35,36],flatten:[1,3,4,5,23],flexibl:[1,6,8,10,12,25,30,33,36,37],flip:[28,30],float32:[4,9,21,36],float64:[4,21,23,30,31,36,37],floor:[],flop:[5,23,31],flow:[1,4,12,36,37],fluctuat:[5,32],fly:11,fm:[0,30],fmax:3,fmesh:[13,35],fn:7,fname:[0,7,34],focu:[0,3,4,5,6,15,22,25,29,30,31,32,33],focus:[1,6,7,23,31,32,34],fold:[6,9,24],folder:[0,1,3,4,6,14,24,25,30,33],follow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],font:[0,7,27,30,34],fontdict:27,fontsiz:[1,6,8,9,10,27],fontweight:1,footprint:3,foral:[8,31,37],forc:[0,5,6,10,11,30,31,32,34,37],forcast:4,forecast:[4,12,36,37],forest:[0,1,9,22,30,37],forget:11,form:[0,3,4,5,6,7,8,9,11,12,13,17,21,22,23,24,25,27,30,31,32,33,34,35,36,37],formal:[3,4,14,27,37],format:[0,1,3,4,6,7,8,9,10,11,22,27,29,31,32,33,34,36,37],format_data:4,formatstrformatt:[6,13,24,34,35],formul:[4,6,11,14],formula:[3,13,27,34,35,36,37],forth:[4,12,36],fortran2003:[22,30],fortran2008:[24,25],fortran90:27,fortran:[0,15,22,23,30],fortun:[0,11,31],forward:[0,3,6,22,23,25,30,33],forwardpropag:37,foster:30,found:[1,2,3,4,5,6,12,13,14,19,20,24,25,30,31,32,33,35,36,37],foundat:[22,30],four:[4,5,6,8,12,23,24,26,28,30,32,36,37],fourier:[0,30,37],fourierdef1:3,fourierdef2:3,fourierseriessign:3,fourth:[12,30,31],fp:7,frac:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,23,24,25,27,30,31,32,33,34,35,36,37],fractal:9,fraction:9,frame:[7,34],framework:[1,3,4,8,10,14,27],frank:[5,11,21,25],frankefunct:[5,6,11,24,31],fredli:[28,30],free:[0,6,11,13,15,16,21,22,23,24,25,27,28,29,30,35,36,37],freecodecamp:22,freedom:[5,32],freeli:[0,24],frequenc:[3,6,7,27,33,34],frequent:[0,8,9,13,34,35,36],frequentist:22,fresh:10,fridai:[16,17,18,19,20,21,28,30],friedman:[6,18,24,26,29,30],friendli:4,frodo:30,frog:3,from:[0,1,2,3,4,6,7,8,9,11,13,14,16,17,18,19,22,23,24,27,28,29,30],from_cod:9,from_logit:[3,4],from_tensor_slic:4,fromnumer:2,front:[0,4,5,15,16,30,31,32],fulfil:[2,5,12,31,36,37],full:[0,1,3,5,7,9,10,13,27,30,31,34,35,36],full_matric:[5,31],fulli:[3,6,12,26,27,33,34,36,37],fun:[2,22,30],fun_nam:[],func:2,functionali:11,fundament:[0,6,22,30,33],funtion:2,furthemor:37,further:[2,7,9,30,37],furthermor:[0,3,5,6,7,11,12,13,17,22,24,30,31,32,33,34,35,36,37],futur:[0,4,8,9,30],futurewarn:8,fy:[15,24,25,26,28,29,30],fys4155:[24,25],fys5419:[29,30],fys5429:[29,30],g0:2,g:[0,1,2,3,4,6,8,9,10,11,13,27,30,32,33,34,35,36,37],g_0:2,g_1:[2,10],g_2:[2,10],g_3:37,g_:[2,9,10],g_analyt:2,g_dnn_ag:2,g_euler:2,g_i:[2,37],g_j:37,g_m:[3,10],g_n:3,g_re:2,g_t:2,g_t_d2t:2,g_t_d2x:2,g_t_dt:2,g_t_hessian:2,g_t_hessian_func:2,g_t_jacobian:2,g_t_jacobian_func:2,g_trial:2,g_trial_deep:2,g_vec:2,gain:[1,5,7,9,10,13,31,32,33,35,36],galleri:[0,30],game:4,gamge:30,gamma1:8,gamma2:8,gamma:[0,2,8,9,10,11,13,21,30,34,35,36],gamma_0:10,gamma_1:10,gamma_1x:10,gamma_:[0,30],gamma_i:[0,8,27,30],gamma_j:[13,35,36],gamma_k:[13,34,35],gamma_m:10,gamma_x:[0,30],gap:[6,8],gate:[4,12],gather:[0,1,12,31,36,37],gaug:[12,36,37],gaussbacksub:23,gaussian:[4,5,6,8,14,27,32,33],gaussian_point:14,gaussian_rbf:8,gave:[13,35,36],gavra:30,gbc:[26,30],gca:[2,6,8,13],gd:[1,25,34,37],gd_clf:10,gdclassiffiercgain:10,gdclassiffierconfus:10,gdclassiffierroc:10,gdfit:36,gdm:[13,21,35,36],gdregress:10,ge:[1,5,7,27,31,34,37],gen:[0,7,34],gen_loss:4,gen_tap:4,gender:[0,30],genener:4,gener:[0,1,2,3,5,6,8,10,11,12,13,14,15,16,17,19,20,21,23,24,27,29,31,32,33,34,35,36],generallay:[12,36],generate_and_save_imag:4,generate_imag:4,generate_latent_point:4,generate_simple_clustering_dataset:14,generated_imag:4,generator_loss:4,generator_loss_list:4,generator_model:4,generator_optim:4,genom:22,geodes:11,geometr:[0,13,30],geometri:[5,32,33],georg:29,geotif:[6,24],geq:[2,5,8,9,13,31,32,34,35],geron:[0,15,21,26,29,30,35,36],get:[0,1,2,3,4,5,6,7,9,10,11,13,15,20,22,23,24,25,27,28,30,31,32,33,34,35],get_dummi:9,get_paramet:2,get_split:9,get_yaxi:8,get_yticklabel:6,getattr:[],gg:30,gibb:[22,30],gif:4,gini:10,gini_index:9,ginvers:13,git:[0,15,22,30],giter:[13,21,35,36],github:[0,6,9,15,16,17,19,20,21,22,24,25,26,28,29,30,31,34,35,36,37],gitlab:[0,15,22,24,25,30],gitta:37,give:[0,1,2,3,5,6,7,8,9,10,12,13,14,17,22,24,25,27,30,31,32,33,34,35,36,37],given:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,23,24,25,27,30,31,32,33,34,35,36,37],global:[6,7,13,24,34,35,36],gloriou:25,glorot:1,gnew:13,go:[0,1,3,5,6,8,9,11,12,13,24,30,31,32,33,34,35,37],goal:[0,7,9,30,34],goe:[0,1,2,5,6,13,14,18,23,30,31,32,33,34,35,36],golden:[13,35],gone:[5,31,32],gong:1,good:[1,3,4,5,6,9,10,11,13,17,21,22,27,29,31,32,33,34,35,36,37],goodfellow:[4,25,26,29,30,31,32,34,35,37],googl:[1,4,21,22,30,36],got:[1,6,13,24],gotcha:[21,36],gotten:30,gov:[6,24],gp:29,gpu:[1,13,21,22,30,35,36],grad:[2,13,21,35,36],grad_analyt:[13,35,36],grad_concatenate_arg:[],grade:[24,26],gradient:[0,3,4,7,8,9,12,22,30,31],gradient_desc:[21,35,36],gradientboostingclassifi:10,gradientboostingregressor:10,gradients_of_discrimin:4,gradients_of_gener:4,gradienttap:4,gradual:[1,14,37],grai:[4,6,24],graph:[1,9,11,12,13,34,35,36,37],graph_from_dot_data:9,graphic:[0,1,9,30],grasp:0,gray_r:[1,3],grayscal:3,great:[5,13,34,35,37],greater:[1,7,27,34,37],greatli:[13,35,36],greedi:[9,34],green:[0,3,9,27],grei:4,grid:[1,3,6,7,8,12,27,31,32,33,36,37],gridsearch:34,gridsearchcv:34,groh:37,grossli:[13,34,35],ground:[0,30],group:[0,6,7,9,14,22,24,25,26,28,30,33],groupbi:[0,30],grow:[1,3,9,10,37],growth:[0,30],gru:4,guarante:[0,4,13,27,30,31,34,35],guess:[1,4,10,13,14,21,25,34,35,36],guestrin:10,guid:1,guidanc:24,guidelin:[20,35,36],h1:2,h:[0,1,5,6,8,13,16,18,21,24,27,28,29,30,31,34,35,36],h_1:[2,13,34,35],h_2:[2,13,34,35],h_:[0,13,30,34,35],h_m:10,ha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,21,23,24,25,27,30,31,32,33,34,35,36,37],haa:28,habit:[0,31],had:[0,1,6,7,13,30,33,34,35,37],hadamard:[1,12,13,21,35,36,37],half:[1,8,9,37],halv:10,hand:[0,1,2,3,5,11,12,13,15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],handi:[3,24,25],handl:[0,1,2,5,9,11,22,32,37],handle_unknown:9,handsid:[12,37],handwrit:[12,36,37],handwritten:[1,5],handwrittennot:[34,36],happen:[1,2,3,4,5,6,10,13,27,31,35,36,37],hard:[1,7,8,10,13,34,35,37],hardcopi:[22,30],harder:[0,1,31,37],harmon:3,hasn:1,hassl:[0,15,22,30],hast:[22,30],hasti:[0,6,15,16,17,18,24,26,29,30,31,33,34],hat:[0,1,5,6,7,9,10,11,12,13,17,18,23,24,31,32,33,35,36,37],have:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,27,28,30,31,32,33,34,35,36,37],haven:1,he:[7,34],head:[0,4,10,27],header:[0,30],heads_proba:10,health:[0,31],hear:[0,13,30,35,36],heart:[0,7,30,34],heatmap:[0,1,3,7,30,34],heavili:0,heavisid:1,height:[1,3,6,31,32],held:[13,21,35,36],help:[0,1,4,12,13,16,21,24,25,30,35,36,37],helper:[4,14],henc:[0,5,6,8,9,10,12,13,18,24,30,31,32,33,34,35,36],henrik:[28,30],her:[7,34],here:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,27,30,31,32,33,34,35,36,37],hereaft:[0,8,12,30],hermitian:23,hessenberg:23,hessian:[0,2,5,13,16,21,32,36],heterogen:[9,10],hi:[7,34],hidden:[1,3,4,12,25,36],hidden_bia:1,hidden_bias_gradi:[1,37],hidden_layer_s:[0,1,30],hidden_neuron:4,hidden_weight:1,hidden_weights_gradi:[1,37],hierarch:[5,31,32],high:[0,1,2,3,4,5,6,9,10,11,13,14,21,22,23,24,30,31,33,34,35,36,37],higher:[0,1,3,5,6,8,13,21,24,25,30,31,32,33,34,35,36],highest:[1,2],highli:[0,3,4,10,18,22,23,25,29,30,31,32,33],highwai:0,hing:8,hint:[13,16,25,31,32,34,35],hip:22,hire:0,hist:[4,6,7,27,33,34],histogram:[0,6,7,27,34],histor:[7,11,34],histori:[3,4,12,36,37],hitherto:[5,32],hjorth:[28,30,31,32,33,34,35,36,37],hobbi:27,hoc:[5,31],hoff:29,hold:[1,3,6,13,14,21,33,34,35,36],holder:[0,30],holomorphic_grad:2,home:0,homepag:[24,25,30],homework:[6,13],homogen:[1,3,9,10,13,21,35,36],honchar:2,hopefulli:[0,11,27,30,36],horizont:11,hornik:37,hors:[3,7,34],hot:[1,9],hour:[1,22,26,27,28,30],how:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,21,22,23,24,25,27,30,31,32,33,35,36,37],howev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,23,24,25,27,30,31,32,33,34,35,36,37],hspace:[0,4,8,10,27,30,37],hstack:1,htf:[26,30],html:[0,9,11,17,19,22,24,25,26,28,29,30,32,37],http:[0,3,4,6,9,11,13,16,17,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37],huang:[0,30],huber:[0,30],huge:[1,3,4,22,37],human:[0,1,3,6,9,12,31,32,36,37],humid:9,hundr:[1,37],hungri:[1,37],huse:30,hvae:36,hybrid:26,hydrogen:[0,30],hyper:[21,25],hyperbol:[1,4,12],hyperparam:8,hyperparamat:37,hyperparamet:[3,4,5,6,9,13,17,30,31,32,34,35,36],hyperplan:11,i0:[0,30],i1:[0,6,8,12,30,31,32,36],i2:[0,8,12,30,36],i3:[0,12,30,36],i5:[0,30],i:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,27,28,30,31,32,33,34,35,36,37],i_1:[5,6,32,33],i_2:[5,6,32,33],i_:[13,34,35],ian:29,ic:[1,25],id:[7,13,34,35,36],ida:[28,30],idea:[0,1,2,3,4,6,9,10,12,13,23,24,25,31,32,33,34,35,36,37],ideal:[0,2,6,8,13,27,30,33,36],idem:[6,33],ident:[5,6,12,13,17,23,24,31,35,36],identical:[32,33],identifi:[0,1,7,9,11,12,13,14,30,31,34,35,36],ieor:27,ifi:29,ifs:[22,30],ignor:[0,1,3,9,31,37],ii:[23,27],iii:[23,30],ij:[0,1,3,6,8,12,14,16,18,23,24,27,30,31,32,36,37],ik:[0,23,30,31],ilg3ggewq5u:37,illustr:[5,7,10,12,13,14,22,30,33,34,35],ilsvrc:[35,36],im:6,imag:[1,3,4,6,9,11,12,14,25,29,30,36,37],image_at_epoch_:4,image_batch:4,image_height:3,image_path:[0,6,7,9,30,31,33,34],image_width:3,imageio:[6,24],images_from_seed_imag:4,imagin:[1,37],immedi:[0,3,4,6,15,22,30],implement:[0,2,3,4,5,6,8,9,10,11,12,13,14,17,21,24,25,27,30,31,32,34,35,37],impli:[3,5,6,7,13,23,31,32,33,34,35],implicit:3,implicitli:[11,27],importantli:3,impos:[0,6,11,12,30,36,37],imposs:[0,5,30,31],impress:[0,12,30,36,37],improv:[0,4,5,9,10,11,13,21,24,25,31,36],impur:9,imread:[6,24],imshow:[1,3,4,6,24],in1:[],in2:[],in3050:[29,30],in3310:30,in4080:[29,30],in4300:[29,30],in4310:29,in5400:3,in5550:29,in_out_neuron:4,inaccur:[13,34,35],inact:[12,36,37],inadequ:[0,30],inch:[6,31,32],includ:[0,1,2,3,4,5,6,7,11,12,15,16,17,20,22,24,25,27,28,29,30,31,32,33],include_bia:[6,9,33],inclus:[17,36],incom:[12,36,37],incorrect:1,incoveni:8,increas:[0,1,3,4,5,6,8,9,11,12,13,21,24,27,30,31,32,33,35,36,37],increasingli:27,increment:35,ind:6,inde:[0,2,4,5,6,13,30,31,37],indefinit:4,independ:[0,5,6,7,8,12,13,27,30,31,34,35,36],index:[0,1,3,4,10,14,22,23,25,27,29,30],index_col:[0,30],indic:[0,1,3,4,5,6,9,10,11,13,16,21,24,25,30,31,35,36,37],indispens:[6,33],individu:[1,6,7,10,12,27,30,31,33,34,36,37],indu:0,indx1:2,indx2:2,indx3:2,indx:23,ineffici:[3,13,35,36],inequ:[8,13],inequaltii:[34,35],inertia:[13,21,35,36],inf1000:[22,30],inf1100:[22,30],inf1100l:[22,30],inf1110:[22,30],inf3000:30,infeas:9,infer:[0,1,4,6,29,30,33],inferenc:1,infil:[0,6,7,9,30,33,34],infin:[5,6,7,11,18,31,32,33,34,37],infinit:3,infinitesim:27,influenc:[6,10,33,34],influenti:1,info:30,inform:[0,1,3,4,6,9,11,12,13,14,21,23,24,25,29,30,33,34,35,36,37],infti:[3,6,13,27,33,34,35,37],ingeni:[13,34,35,36],ingrad:2,ingredi:[0,9,30],inher:[6,33],inherit:[23,30],initi:[0,1,2,6,10,13,14,23,25,27,30,33,34,35,36,37],inject:14,inlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,24,27,30,31,32,33,34,35,36,37],inner:[0,13,31,35],inp:4,inplac:13,inpput:37,input:[0,1,3,4,5,6,7,8,12,13,14,21,24,25,27,30,31,32,33,34,35,36],input_dim:1,input_shap:[3,4],inputs:1,inputs_shuffl:[0,1,31],insert:[3,5,6,8,10,27,31,32,33],insid:[0,4,7,34],insight:[0,1,5,21,22,25,30,31,32,33],insist:[6,13,31,32,35],inspect:34,inspir:[0,1,12,25,30,36,37],instabl:2,instal:[0,1,5,6,9,15],instanc:[0,1,2,4,6,9,11,13,30,31,33,34,35],instanti:10,instead:[0,1,2,3,4,5,6,8,9,11,13,14,21,23,24,27,30,31,33,34,35,36],institut:1,instruct:[0,1,15,16,30],int32:10,int_0:27,int_:[3,6,27,33,37],int_a:27,intak:[0,31],integ:[1,2,13,14,23,27,30,35,36],integer_vector:1,integr:[3,6,27,30,33],intellig:[0,14,29,30],intend:10,intens:[1,37],intention:14,interact:[0,6,9,12,22,24,25,30,36,37],intercept:[0,6,8,11,13,16,24,30,32,33,34,35,36],intercept_:[0,6,8,9,13,30,31,32,34,35],interchang:[5,12,23,32,33,36,37],interconnect:[1,37],interest:[0,1,2,3,4,5,6,7,8,9,12,21,22,24,25,27,30,31,32,33,34,35,36,37],interfac:[0,1,23,31],interior:[0,9,30],intermedi:[23,31],intern:[1,10,12,36,37],interpol:[1,3,4,6,12,24,36,37],interpr:[5,31,32],interpret:[0,1,6,9,10,12,13,17,19,23,24,25,27,37],interv:[0,3,5,6,7,13,18,24,27,30,31,32,34,35],intial:[13,34,35],intract:[0,4,31],intrins:[3,11,23,27,30],intro:[22,29,30],introduc:[0,1,5,6,8,10,12,17,23,24,27,30,33,34,37],introduct:[1,2,4,13,17,20,29,31,34,35],introductori:[0,4,23,29,30,31],intuit:[0,5,6,8,12,13,21,24,30,32,33,35,36,37],inv:[0,5,13,21,30,31,32,34,35,36],invalid:[1,8],invalu:[0,13,15,22,30,34,35],invari:1,invd:[5,32],inver:[8,36,37],invers:[0,3,6,13,15,16,17,21,24,25,30,31,34,35,36],inverse_transform:8,invert:[0,5,7,10,13,21,30,32,34,35,36],invh:[13,21,35,36],invok:[0,8],involv:[0,2,6,7,11,12,31,33,34,35,36,37],io:[0,17,19,22,24,26,28,29,30,31],ion:36,ip:[0,8,27,30],ipca:11,ipykernel_12550:[],ipykernel_12588:[],ipykernel_1323:[],ipykernel_1390:[],ipykernel_1539:[],ipykernel_1579:[],ipykernel_22411:1,ipykernel_22458:6,ipykernel_22556:30,ipykernel_22575:33,ipykernel_58656:[],ipykernel_58739:[],ipykernel_58840:[],ipykernel_58862:[],ipykernel_6316:[],ipykernel_6403:[],ipykernel_6690:[],ipykernel_6729:[],ipykernel_95354:[],ipykernel_95419:[],ipykernel_95519:[],ipykernel_95542:[],ipynb:[22,24,30],ipython:[0,5,7,9,11,14,15,22,24,25,30,31,34],iq:[6,33],iri:[8,9],irreduc:[6,33],irrelev:[5,31],irrespect:[0,30],irvin:25,isbox:2,iscomplexobj:[],iseffici:[35,36],isn:[5,32,33],isnul:0,isomap:11,isotop:[30,34,35],issu:[1,9,23,32,37],it_arrai:[13,35],item:[0,13,30,35],items:[23,30],iter:[1,2,4,6,8,9,11,13,14,21,27,33,34,36,37],its:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,18,22,23,24,25,27,30,32,33,34,35,36,37],itself:[5,6,12,19,24,25,27,31,32,33,37],j1:23,j:[0,1,2,3,4,5,6,8,9,11,12,13,14,16,17,18,19,23,24,27,29,30,31,32,33,34,35,36,37],j_:6,j_lasso_sk:6,j_ridge_sk:6,j_sk:6,jackknif:[6,22,30,33],jacobian:[2,13,34,35],jacobian_shap:2,jakobsen:28,jason:4,jax:[22,25,30,37],jax_descend_i:[21,36],jax_descend_x:[21,36],jax_enable_x64:[21,36],jax_grad:[21,36],jensen:[28,30,31,32,33,34,35,36,37],jentzen:37,jerom:[18,24,29],ji:[12,23,37],jit:[13,35],jj:[0,5,6,30,32,33],jk:[0,1,6,12,23,30,36,37],jl:[0,30],jm:23,jnp:[13,21,35,36],job:[2,8,10],johansen:30,join:[0,3,4,6,7,9,14,30,31,33,34],joint:[4,5,32,33],judg:[13,34,35],judgement:[6,24],julia:[22,23,24],juliu:37,jump:[24,27],junk:4,jupit:30,jupyt:[0,9,15,19,22,24,29,30,37],just:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,24,25,27,30,31,32,33,34,35,36,37],justif:0,justifi:[3,10],k0:[7,34],k1:[7,34],k:[0,1,3,5,6,7,8,9,10,11,12,13,14,22,23,24,27,28,30,31,32,35,36],kaggl:[6,24,25],kappa_d:27,karl:[28,30],karush:8,katrin:[28,30],keep:[0,1,4,5,6,11,13,14,23,24,25,30,31,32,33,34,35,36,37],keepdim:[1,6,10,23,33],kei:[0,1,3,6,12,31,36],kept:[4,6,14,33],kera:[0,4,22,24,25,30],kernel:[0,1,3,4,14,22,30,31],kernel_librari:[3,4,14],kernel_regular:[1,3],kernel_s:4,kernelpca:11,kev:[0,30],kevin:[29,30],keyboardinterrupt:2,keyerror:[],keyword:[6,13,23,30],kfold:[6,33,34],kg:1,ki:23,kick:[1,13,35,36,37],kiener:2,kilomet:[6,31,32],kind:[0,2,3,4,8,12,13,14,30,31,35,36,37],kj:[6,12,23,31,32,37],kjm:[22,30],kkt:8,kl:27,km:[12,30,36],kmean:14,kmeanspoint:14,kn_k:14,know:[0,1,2,5,6,8,13,22,30,31,32,34,35,36,37],knowledg:[0,22,30],known:[1,3,4,5,6,7,8,9,12,23,24,25,27,29,31,32,33,34,36,37],kondev:[0,30],kp:27,kpca:11,kroneck:14,kuckuck:37,kuhn:8,kutyniok:37,kvalsund:[28,30],kwarg:2,kwown:[0,30],l0:[7,34],l1:[0,1,3,7,30,34],l1_l2:[1,3],l1regl:5,l2:[1,3],l:[0,1,2,3,5,6,7,8,10,11,12,13,19,23,24,27,30,31,34,35,36],l_1:[7,34,37],l_2:[7,13,25,34,35,37],l_:23,l_j:[12,37],la:[13,35],la_i:[12,37],la_k:[12,37],lab:[20,22,24,30],label:[0,1,2,3,4,5,6,7,8,9,10,12,13,14,21,22,23,24,25,27,30,31,32,33,34,35,36,37],label_prob:[35,36],labelencod:[7,10,34],labels:[6,8,9],labels_shuffl:[0,1,31],laboratori:[26,32],lack:[0,30],lagari:2,lagrang:[8,11],lambda:[0,1,2,3,5,6,7,8,10,12,13,17,18,21,24,25,27,30,31,32,33,35,36,37],lambda_0:11,lambda_1:[5,8,11,31],lambda_2:[8,11],lambda_:11,lambda_i:[8,11],lambda_iy_i:8,lambda_jy_iy_j:8,lambda_k:8,lambda_n:[5,8,31],lamda:1,land:[0,8],landmark:8,landscap:[13,21,34,35,36],langl:[0,6,11,27,30,31],languag:[0,1,4,8,15,22,23,24,25,29,30,37],lapack:[23,30],laplac:[5,32,33],laptop:22,larg:[0,1,2,4,5,6,8,9,10,11,13,15,22,23,24,27,29,30,31,33,34,35,36,37],larger:[0,3,5,6,8,10,11,13,17,27,30,31,32,33,34,35,36],largest:[4,8,11],lass:25,lasso:[0,7,22,25,30],lasso_sk:6,last:[0,1,2,3,4,5,6,7,8,10,12,13,14,17,18,23,24,27,28,30,32,33,35],latent:4,latent_dim:4,latent_point:4,latent_space_value_rang:4,later:[0,1,4,7,8,12,13,14,15,22,24,25,30,34,35,36,37],latest:[4,22],latest_checkpoint:4,latex:30,latter:[0,3,6,7,8,11,13,16,23,24,27,30,31,32,33,34,35,36,37],lattic:[12,36,37],law:0,lax_numpi:[21,36],layer:[0,4,13,21,25,30,35,36],lbfg:[7,9,10,11,34],lcc:[5,6,32,33],lda:11,ldot:[0,6,11,19,24,30,33,34],le:[5,7,10,13,17,21,27,31,32,34,35,36],lead:[0,1,3,5,6,7,8,9,10,11,12,13,16,17,23,27,30,31,32,33,34,35,36,37],leaf:9,leaki:[1,25,37],leakyrelu:4,lear:[13,34,35],learn:[3,4,5,6,7,8,9,10,12,18,23,26,28,29],learnabl:3,learner:10,learnig:30,learning_r:[8,10,21,36],learning_rate_init:[0,1,30],learning_schedul:[13,21,35,36],learnt:[24,25],least:[0,2,7,8,10,11,15,16,17,19,21,22,23,25,27,33,34],leat:[13,21,35,36],leav:[0,1,3,5,6,9,11,30,32,33,34,37],lectur:[0,1,5,10,11,12,13,15,17,21,22,23,24,25,26,28,29],lecturenot:[0,17,19,22,24,29,30],left:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,16,17,19,23,24,27,30,31,32,33,34,35,36,37],leftarrow:[8,12,37],legend:[0,2,3,4,5,6,7,8,9,10,13,30,31,32,33,34,35,36],len:[0,1,2,3,4,5,6,8,9,10,11,12,23,30,31,32,33,35,36,37],length:[0,1,2,3,4,8,9,13,16,22,30,31,34,35,36],length_of_sequ:4,leq:[0,5,7,8,13,14,27,30,31,32,34,35],less:[0,1,3,4,5,6,8,9,13,22,27,30,31,32,33,34,35,36],lessen:[1,37],let:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,23,27,30,31,32,33,34,35,36,37],letter:[0,16,23,27,30,31],level:[0,1,5,6,9,22,23,24,25,26,28,30,33,37],li:[8,11],lib:[0,1,2,3,4,6,7,8,9,11,14,21,30,32,34,36],liblinear:[8,10],libmetal_plugin:[3,4,14],librari:[0,1,2,3,4,5,6,7,9,10,11,14,15,21,23,24,25,27,29,31,32,34],library_loc:[3,4,14],licens:[0,1,15,22,24,25,30],lie:[0,6,11,27,30,31,33],life:[0,1,8,12,30,36,37],lifetim:[13,35,36],like:[0,1,2,3,4,5,6,7,9,10,11,12,13,15,16,21,22,23,24,25,27,30,31,32,33,34,35,36,37],likelihood:[0,1,5,9,30,31,35,36],lim_:27,lima:28,limit:[0,5,6,8,9,11,12,21,23,24,25,30,31],lin_clf:8,lin_model:0,lin_reg:9,linalg:[0,2,5,6,8,11,13,21,23,27,30,31,32,34,35,36,37],line1:8,line2:8,line2d:[21,35,36],line3:8,line:[0,1,2,3,4,6,7,8,10,11,13,14,21,24,30,31,32,33,34,35,36,37],linear:[1,3,5,6,7,9,10,11,12,17,18,21,22,24,27,33,35,36,37],linear_model:[0,5,6,7,8,9,10,11,13,30,31,32,33,34,35,36,37],linear_regress:[6,33],linearli:[5,31],linearloc:[6,13,24,34,35],linearregress:[0,6,7,9,30,31,32,33,34],linearsvc:8,lineat:32,liner:[1,3],linerar:10,linewidth:[0,2,4,6,8,9,10,24,33],link:[0,4,9,12,22,24,25,28,30,37],linlag:[5,32],linpack:[23,30],linreg:[0,30],linspac:[0,2,3,4,6,8,9,10,13,15,16,21,23,27,30,31,32,33,35,36],linu:4,linux:[0,1,15,22,24,30],liquid:[0,30],list:[0,1,2,3,4,7,9,22,24,25,30,31,34,35,36],listcomp:2,listedcolormap:[9,10],literatur:[1,7,14,29,33,34,37],littl:[1,3,9,12,37],live:8,ll:[0,27,30,31],lle:[0,31],lloyd:[4,14],lmb:[0,2,5,6,32,33,34],lmbd:[0,1,3,30],lmbd_val:[0,1,3,30],lmbda:[13,34,35],ln:[1,13,34,35],load:[0,1,3,4,6,7,9,10,14,24,34],load_boston:0,load_breast_canc:[1,7,9,10,11,34],load_data:[3,4],load_digit:[1,3],load_iri:[8,9],load_librari:[3,4,14],load_pluggable_device_librari:[3,4,14],loc:[0,3,6,7,8,9,10,30,33,34],local:[0,1,2,3,7,12,13,31,34,35,36,37],locat:[2,3,8],log10:[0,5,6,32,33,34],log:[0,1,2,4,5,6,7,9,10,11,13,23,24,25,30,31,32,33,34,35,36],log_:[0,30],log_clf:10,logaddexp2:[],logaddexp:[],logarithm:[0,5,7,23,30,32,33,34],logbook:[24,25],logic:[0,1,9,30,37],logist:[0,1,2,8,9,10,11,12,13,21,22,31],logistic_predict:[35,36],logisticregress:[7,9,10,11,34,36,37],logit:[7,34],logreg:[7,9,10,11,34,36,37],logspac:[0,1,3,5,6,30,32,33,34],longer:[2,3,8,10,14,23,25,27,30],loocv:[6,33,34],look:[0,1,2,3,4,5,6,7,8,9,10,11,13,16,18,21,23,24,25,27,30,31,32,33,34,35,36,37],loop:[1,4,6,10,12,14,22,23,30,33],lose:1,loss:[0,1,3,4,5,6,7,8,10,11,13,23,24,25,30,32,33,36,37],loss_fil:4,lossfil:4,lost:4,lot:[0,1,4,6,33,35,36,37],low:[0,6,9,10,11,24,30,31,33],lower:[0,1,3,6,9,10,16,23,31,37],lowercas:[23,30],lowest:[9,13,27,35,36],lr:[1,3,4,10],lstat:0,lstm:4,lstm_2layer:4,lstsq:[0,30,31],lt:[6,33],lu:[0,5,30,31],lubksb:23,luckili:2,ludcmp:23,lux:23,lvert:1,lw:[0,30],m:[0,1,2,3,5,6,8,9,10,11,12,13,21,23,26,27,28,29,30,31,32,33,34,35,36,37],m_1:14,m_:[9,12,37],m_h:[0,30],m_k:14,m_l:[12,37],m_n:[0,30],m_p:[0,30],m_t:[13,35,36],ma:11,machin:[1,3,4,5,6,7,9,10,11,12,15,21,23,26,29,31,32,33,36,37],machinelearn:[0,6,16,17,19,20,22,24,26,28,29,30,34,35,36],mackai:29,made:[0,1,3,4,5,6,7,9,11,12,18,24,25,30,31,34,36,37],mae:[0,30],magic:4,magnitud:[1,6,7,13,31,32,34,35,36,37],mai:[0,1,2,3,5,6,7,8,9,11,12,13,18,21,22,23,24,25,27,30,31,32,33,34,35,36,37],mail:[26,28],main:[0,1,3,4,5,6,7,9,23,24,25,29,31,34,37],mainli:[0,5,6,7,9,30,31,32,33,34],maintain:[6,33],major:[1,6,9,10,13,23,30,33,34,35,36],make:[1,2,3,4,5,6,7,8,11,12,13,21,22,23,24,25,27,29,32,33,34,35,36,37],make_axes_locat:6,make_classif:[36,37],make_moon:[8,9,10],make_pipelin:[0,6,10,31,33],make_vjp:2,makedir:[0,6,7,9,30,31,33,34],makeplot:[0,30],malcondit:23,malign:[1,7,9,34],mammographi:[5,32,33],manag:[0,2,3,15,22,24,30],mandatori:[28,30],mani:[0,1,3,4,5,6,7,8,9,11,13,14,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],manifold:11,manner:3,manual:[6,31,32,34],map:[0,1,2,6,7,8,11,12,14,24,27,30,34,36],marc:31,margin:[0,5,8],marit:[0,30],mark:30,marker:[0,7,21,23,30,34,36],markov:[22,30],marsaglia:27,mass:[0,1,5,13,31,35,36],massag:[0,30],masses2016:[0,30],masses2016ol:[0,30],masses2016tre:0,masseval2016:[0,30],master:[6,16,20,24,26,28,34,35,36],mat1100:[22,30],mat1110:[22,30],mat1120:[22,30],mat:[22,30],match:[1,4,5,13,14,31,34,35,36,37],match_complex:[],materi:[4,5,7,13,17,23,28,35,36],math:[3,7,12,13,21,23,27,29,30,34,35,36,37],mathbb:[0,4,5,6,7,8,11,12,13,14,17,18,19,23,24,27,30,31,32,33,34,35,36,37],mathbf:[0,5,6,7,8,13,18,19,21,23,24,30,31,32,33,34,35,36,37],mathcal:[1,5,6,7,13,19,24,32,33,34,35],matheemat:3,mathemat:[0,6,11,12,13,17,22,23,27,29,30,32,34],mathemati:30,mathmlbook:16,mathrm:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,24,27,30,31,32,33,34,35,36,37],matmul:[1,2,5,32,37],matnat:29,matplotlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,21,22,23,24,27,30,31,32,33,34,35,36,37],matric:[0,1,3,4,6,7,8,11,13,16,17,22,31,34,35,37],matrix:[0,2,3,4,6,7,8,10,13,15,16,17,18,19,21,24,25,27,33,37],matshow:1,matter:[2,3,13,31,34,35,36,37],max:[0,1,2,3,4,9,10,12,13,21,28,30,34,35,36,37],max_depth:[0,9,10],max_diff1:2,max_diff2:2,max_diff:2,max_it:[0,1,8,9,11,13,30,34,35,36,37],max_iter:14,max_leaf_nod:10,max_sampl:10,maxdegre:[0,6,10,31,33],maxdepth:10,maxim:[1,4,5,7,8,11,32,33,34],maximum:[0,1,2,3,5,7,8,9,10,13,14,30,31,35,36],maxpolydegre:[5,6,32,33,34],maxpooling2d:3,mbox:[5,6,18,24,31,32,33],mcculloch:[12,36,37],md:[11,20,24,35,36],mdoel:4,mean:[1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,27,30,33,35,36,37],mean_absolute_error:[0,30],mean_divisor:14,mean_i:27,mean_matrix:14,mean_squared_error:[0,4,6,7,10,30,31,33,34],mean_squared_log_error:[0,30],mean_vector:14,mean_x:27,meaning:[0,4,7,30,34],meansquarederror:[0,30],meant:[2,3,7,10,13,34,35,36,37],measur:[0,1,2,5,6,9,11,12,14,19,24,25,27,30,31,32,33,37],mechan:[0,4,27,30],median:[0,30,31],medicin:[12,36,37],medium:[4,8,13,25,35,36],medv:0,meet:[0,28],mehta:[0,30,31,32],memori:[3,4,11,12,13,21,23,35,36,37],mention:[0,12,13,24,25,27,30,34,35,36,37],mere:[0,15,25,30],meshgrid:[2,5,6,8,9,10,11,24,31],messag:[5,13,35,36],messi:2,met:[0,3,8,31],metadata:2,meteorolog:9,meter:[6,31,32],method:[0,1,2,3,4,5,7,8,11,12,14,16,17,18,19,22,23,25,27,29,31,32,37],metion:[6,24],metric:[0,1,3,6,7,9,10,14,15,16,30,31,33,34],metropoli:[22,30],mev:[0,27,30],mgd:[13,35,36],mglearn:[22,30],mgrid:[13,35],mhjensen:[1,2,3,4,6,8,9,11,14,21,36],mi:10,mia:[28,30],michael:[25,37],michigan:[30,32,34,35,36],microsoft:29,mid:1,midel:4,midnight:[16,17,18,19,20,21],midpoint:9,might:[0,1,2,4,6,9,13,31,32,34,35,36,37],mild:9,millimet:[6,31,32],million:[0,30,31,35,36],mimic:[12,36,37],min:[0,2,5,8,9],min_:[0,2,5,14,17,30,31,32],min_samples_leaf:9,mind:[0,6,13,24,30,31,32,33,34,35],mindboard:4,mine:[22,30],mini:[1,11,12,13,21,25,34,37],minibatch:[1,11,13],minibathc:[13,35,36],miniforge3:[0,1,2,3,4,6,7,8,9,11,14,21,30,32,34,36],minim:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,17,18,21,24,31,32,33,35,36,37],minima:[0,1,7,13,30,34,35,36],minimum:[0,1,2,6,8,9,11,13,31,33,34,35,36],minmaxscal:[0,31],minor:27,minst:1,minu:[7,34],mirjalili:30,mirror:9,misc:[6,24],misclassif:[8,9,10],misclassifi:[8,10],miser:0,mismatch:[1,37],miss:[0,7,10],mistak:4,mit:29,mix:[1,2,30,37],mixtur:[13,21,35,36],mk:[9,23],mkdir:[0,6,7,9,30,31,33,34],ml:[0,1,10,13,23,24,25,31,34,35,36,37],mlab:27,mlbook:30,mle:[5,7,34],mlp:[1,36,37],mlpclassifi:[1,36,37],mlpregressor:[0,30],mm:23,mml:31,mn:[12,27,36],mnist:[1,11,25,37],mod:27,mode:[26,28,30],model:[2,3,5,7,8,9,10,11,13,14,15,16,18,19,21,22,24,27,29,31,32,33,34,35],model_select:[0,1,3,5,6,7,9,10,11,30,31,32,33,34],moder:10,modern:[0,6,7,22,30,33,34,37],modif:[2,12,13,35,36],modifi:[0,1,3,5,7,8,10,12,13,30,31,32,34,35,36,37],modul:[0,9,11,23,30,32],modular:27,modulo:27,moe:[11,31],moment:[5,6,13,21,27,32,33],momentum:[25,37],mondai:30,monitor:[13,21,35,36],monoton:[5,12,27,32,33,36,37],mont:[0,6,22,27,29,30,33],moor:[5,6,32],more:[0,1,2,4,5,7,8,9,10,11,12,13,14,18,22,25,27],moreov:[0,3],morten:[28,30,31,32,33,34,35,36,37],most:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,24,27,30,31,32,33,34,35,36,37],mostli:[1,11,37],motion:[0,13,35,36],motiv:[1,4,37],move:[0,4,5,6,7,9,12,13,14,21,24,27,31,32,33,34,35,36,37],mpl:[0,7,30,34],mpl_toolkit:[2,6,13,24,34,35],mplot3d:[2,6,13,24,34,35],mplregressor:1,mse:[0,4,5,6,9,10,15,16,17,19,24,25,30,31,32,33,34],mse_simpletre:10,mselassopredict:[5,32],mselassotrain:[5,32],mseownridgepredict:[6,32],msepredict:[5,32],mseridgepredict:[0,5,6,32,34],msetrain:[5,32],msle:[0,30],mt:[7,12,34,36,37],mu0:27,mu1:27,mu2:27,mu:[0,6,11,13,27,30,33,35,36],mu_1:31,mu_:[6,27,31,32,33],mu_i:[6,31,32],mu_n:11,mu_x:27,much:[0,1,2,3,4,5,6,8,9,10,11,12,13,23,24,27,30,31,32,33,35,36,37],multi:[0,1,3,7,22,30,34],multiclass:[1,7,34],multidimension:[11,12,30,36,37],multilay:1,multinomi:[7,34],multipl:[2,4,5,6,7,12,13,27,31,33,34,35,36,37],multipli:[2,3,5,6,11,13,23,27,31,32,35],multiplum:8,multivari:[0,2,10,11,22,27,30],multivariate_norm:[11,14],murphi:[11,29,30],must:[1,2,5,6,8,10,12,13,14,27,31,33,34,35,36,37],mutat:[7,34],mutual:[1,3,6,13,33,34,35,37],mx_:27,myenv:[0,1,2,3,4,6,7,8,9,11,14,21,30,32,34,36],myriad:[0,15,22,30],mz1:27,mz2:27,n1:23,n2:23,n:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,21,23,24,25,27,30,31,32,33,34,35,36,37],n_0:[12,27,36],n_:[1,2,3,8,12,27,36],n_boostrap:[6,10,33],n_bootstrap:[6,33],n_categori:[1,3],n_cluster:14,n_compon:11,n_data:36,n_epoch:[13,21,35,36],n_estim:10,n_examples_to_gener:4,n_featur:[1,37],n_filter:3,n_hidden:2,n_hidden_neuron:[0,1,30,37],n_i:27,n_input:[0,1,3,31,37],n_instanc:9,n_iter:[34,35],n_iter_i:[9,11],n_job:10,n_k:14,n_l:[12,27,36],n_layer:1,n_m:9,n_neuron:1,n_neurons_connect:3,n_neurons_layer1:1,n_neurons_layer2:1,n_output:37,n_point:14,n_sampl:[6,8,9,10,14,33,36,37],n_split:[6,33,34],n_step:4,n_t:2,n_x:2,nabla:[1,13,34,35],nabla_:[2,13,21,34,35,36],nabla_w:[13,35,36],nag:[13,35,36],naimi:[0,30],naiv:[7,34],naive_kmean:14,najafi:[28,30],name:[0,1,3,4,5,6,7,8,9,10,12,13,14,15,22,23,24,27,28,30,31,32,33,34,35,36,37],nameerror:[10,24],namespac:[3,4,14],narrow:[13,35,36],nary_f:2,nary_op_arg:2,nary_op_kwarg:2,nary_oper:2,nation:[1,5,32,33],nativ:[22,30],natur:[0,1,4,8,9,12,13,24,25,27,29,30,34,35,36,37],navier:[12,36,37],nb:27,nb_:23,nbconvert:30,nbviewer:9,nd:14,ndarrai:[2,6],ndim:[],ne:[9,10,23,27,31],nearest:[1,3,6,11],nearli:[13,34,35],neat:30,neatli:[],neccesari:[6,33],necess:2,necessari:[0,1,3,4,8,14,30,37],necessarili:[0,4,11,27,30],necesserali:[5,32,33],neck:[7,34],need:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,23,25,27,31,32,33,34,35,36,37],neg:[0,1,3,5,6,7,10,13,23,27,30,32,33,34,35,36,37],neg_mean_squared_error:[6,33,34],neglect:27,neglig:27,neighbor:[3,6,11],neither:[4,13,35,36],neq:[13,14,27,34,35],nervou:[12,36,37],nest:[2,9,12,36],nesterov:[13,35,36],net:[2,4,12,36,37],netlib:[23,30],network:[0,9,13,21,22,29,31,35],neural:[0,13,21,22,29,31,34,35],neural_network:[0,1,2,30,36,37],neuralnetwork:1,neuralnetworksanddeeplearn:[25,37],neuron:[1,2,3,4,12],neutral:[0,30],neutron:[0,30],never:[1,4,6,9,27,33,37],new_box:2,new_chang:[13,21,35,36],new_hobbit:30,new_root:2,new_trac:2,newaxi:[0,3,6,9,33,34],newli:[0,30],newton:[1,7,8,13,27,37],next:[0,1,2,3,4,5,6,7,8,9,13,14,21,30,31,32,34,35,36,37],next_guess:[13,35],next_input:4,ng:[1,37],ngini:9,ni:14,nice:[0,1,5,11,30,31,32,33],nielsen:[25,37],nine:37,niter:[13,21,34,35,36],nitric:0,nlambda:[0,5,6,32,33,34],nlp:29,nm:27,nm_n:[0,30],nmse:[6,33],nn:[2,5,6,12,23,32,33,36],nn_model:1,nnmin:2,node:[1,2,3,9,10,12,25,36],node_constructor:2,nois:[0,4,5,6,8,9,10,13,15,16,19,24,30,31,32,33,34,35],noise_dimens:4,noisi:[1,6,19,24,33],non:[0,1,3,5,6,7,9,10,11,12,13,14,21,23,27,30,31,32,33,34,35,36,37],noncommerci:25,none:[0,1,2,4,5,9,10,13,27,30,31,32,33,34,37],nonlinear:[3,6,8,9,11,12,33,36,37],nonneg:[6,9,13,33,34,35],nonparametr:6,nonsens:27,nonsingular:23,nonumb:[3,7,8,13,21,23,34,35,36],nor:[1,4,13,35,36,37],norm:[0,1,5,6,8,11,13,17,30,31,32,33,34,35,36,37],normal:[3,4,5,6,7,8,9,10,11,12,13,15,16,18,19,21,22,23,24,25,27,30,31,32,34,35,36],normali:[23,30],norwai:[6,24,25,30,33,36],notat:[0,2,5,6,13,14,21,27,30,31,32,33,35,37],note:[0,1,2,3,4,5,6,7,8,11,12,13,14,15,16,22,23,25,27,29,30,33,34,35,37],notebook:[0,1,3,9,15,22,24,25,30,37],notesseptember16:34,notesseptember30:36,notfounderror:[3,4,14],noth:[1,2,5,8,12,14,27,31,32,36,37],notic:[4,5,12,13,23,27,30,32,35,36,37],notimplementederror:[],notion:3,novel:[3,6,10,34],novemb:[1,26,28,30],now:[0,2,4,5,6,7,8,10,11,12,14,15,16,17,22,23,24,25,27,30,31,34,37],nowadai:[0,1,3,9,22,30,37],nox:0,np:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,21,23,24,27,30,31,32,33,34,35,36,37],npr:2,nsampl:[6,9,33,34],nt:2,ntrained_model:[6,32],nu:27,nuclear:[5,31],nuclei:[0,27,30],nucleon:[0,30],nucleu:[0,30],num:4,num_coordin:2,num_featur:36,num_hidden_neuron:2,num_it:2,num_iter:[21,36],num_neuron:2,num_neurons_hidden:2,num_point:2,num_tre:10,num_valu:2,number:[1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,23,24,25,26,28,30,32,33,34],numberid:[7,34],numberparamet:3,numer:[0,5,6,9,10,11,12,13,17,21,22,23,29,30,31,32,33,34,35,36,37],numpi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,22,24,27,31,32,33,34,37],numpy_box:2,numpy_vjp:2,numpy_wrapp:2,nunmpi:[5,31],nvalu:9,nx:2,nx_test:[6,32],nx_train:[6,32],nx_train_mean:[6,32],ny:27,ny_pr:[6,32],ny_train:[6,32],ny_train_mean:[6,32],o:[0,6,7,8,9,11,15,21,23,28,29,30,34,36],obei:[6,11,13,31,32,35],obj:[],object:[0,1,2,4,6,8,10,23,30,35,37],obliqu:[5,31],observ:[0,1,3,5,6,7,8,9,10,11,12,13,14,27,32,33,34,35,36],obtain:[0,1,5,6,7,8,9,10,12,13,14,17,21,23,24,25,27,30,31,32,33,34,35,36,37],obviou:[5,6,11,27,31],obviouli:30,obvious:[0,4,5,6,21,23,25,30,32,33],oc:31,occupi:0,occur:[0,6,8,9,23,27,30],oct:25,octob:[21,26,28,30,36],od:0,odd:[0,3,7,30,31,34],odenum:2,odesi:2,odin:30,oen:0,off:[1,3,4,5,9,13,19,27,32,33,35,36],offer:[6,11,22,23,26,28,30,33],offic:[28,30],offici:[26,30],often:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,16,22,23,24,27,30,31,33,34,35,36,37],ofter:[23,30],ol:[0,13,15,16,17,18,25,30,31],old:[1,5,10,13,32,33,34,35],ols_sk:6,ols_svd:6,olsbeta:[0,5,32],omega:[2,3,6],omega_0:3,omit:[0,5,30,31,32,33],omlmp_kkie0:34,onc:[1,6,9,11,13,33,34,35,36,37],one:[0,1,3,4,5,6,7,8,9,10,11,13,14,19,21,22,23,24,25,27,28,30,31,32,33,36],onehot:1,onehot_vector:1,onehotencod:9,ones:[0,2,5,6,8,9,10,11,13,21,23,24,30,31,32,33,34,35],ones_lik:4,ong:31,onl:3,onli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,19,21,23,24,25,27,30,31,32,33,34,35,36,37],onlin:[11,26,37],onto:[5,11,31],open:[0,1,4,6,7,9,15,22,24,26,28,30,33,34],oper:[0,1,3,5,6,10,11,12,13,15,22,27,30,31,32,33,35,36],operation:27,oplu:27,opmiz:[13,35,36],opportun:0,oppos:[6,13,35,36],opposit:[1,5,8,31,37],opt:[1,5,25,30,32,37],optim:[0,2,3,4,5,6,7,9,10,11,14,15,16,17,18,19,21,24,25,32,33],optimis:[1,3],option:[0,1,3,5,6,8,9,11,21,23,24,25,31,32,33,36],optmiz:[1,8,13,21,31,35,36,37],oral:30,orang:0,order:[0,1,2,3,5,6,7,8,9,10,11,12,15,16,23,24,25,27,30,31,32,33,34,37],ordinari:[0,2,3,7,11,13,15,16,17,19,21,22,25,33,34,35,36],oreilli:[29,30],org:[0,3,4,9,11,21,22,23,24,25,29,30,32,35,36,37],organ:[6,7,10,23,33,34],orgin:37,orient:[1,5,27,31,32],origin:[0,3,5,6,8,11,12,13,23,30,31,33,35,36],orthogn:[5,31],orthogon:[0,5,6,8,11,13,17,23,30,31,32,35],orthonorm:[5,31,32],os:[0,1,4,5,6,7,8,9,28,30,31,32,33,34],oscar:[1,37],oscil:[3,13,35,36],oserror:[0,3,4,7,14,34],oslo:[0,15,22,24,25,26,28,30,31,32,33,34,35,36,37],osx:[0,15,22,24,30],other:[0,1,2,3,5,6,7,8,10,13,14,15,19,22,25,26,27,28,29,32,33,35],otherwis:[0,1,4,7,13,21,23,25,30,34,35,36],ouput:[5,7,12,32,33,34],our:[1,2,3,6,7,8,9,10,12,14,15,16,17,18,19,21,22,23,24,25,27,32,33,36],ourmodel:0,ourselv:[0,5,6,8,11,13,30,31,32,33,34,35],out1:[],out2:[],out:[0,1,2,4,5,6,7,8,9,10,11,12,13,16,21,22,23,24,25,27,30,31,32,33,34,35,36,37],out_fil:9,outcom:[0,7,9,10,12,27,31,34],outdoor:9,outer:[6,12,13],outfil:4,outgrad:2,outlier:[0,8,30,31],outlin:[6,10,11,33],outlook:9,outperform:10,output:[0,1,3,4,5,6,7,8,9,10,12,13,16,23,24,25,27,30,31,32,33,34,35,36],output_bia:1,output_bias_gradi:[1,37],output_shap:4,output_weight:1,output_weights_gradi:[1,37],outputlayer1:[12,36],outputlayer2:[12,36],outsid:4,over1:[13,35,36],over:[0,1,3,4,5,6,9,10,12,13,21,23,24,30,31,32,33,34,35,36],overal:[1,10],overcast:9,overcom:[12,13,35,36,37],overdetermin:[0,30],overfit:[0,1,3,6,9,10,13,21,33,35,36,37],overflow:[1,5,32,33],overhead:[12,37],overlap:[3,7,8,9,34],overlin:[0,5,6,9,10,11,14,23,30,31,32],overst:0,overtrain:4,overview:[3,34],own:[4,5,6,8,12,13,21,22,23,24,32,35,36,37],owner:0,ownmsepredict:0,ownmsetrain:0,ownridgebeta:[0,6,32],ownypredictridg:0,ownytilderidg:0,oxid:0,p0:2,p1:2,p:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,17,23,27,30,31,32,33,34,35,37],p_:[2,4,8,9],p_hidden:2,p_i:[5,27,32,33],p_j:27,p_n:27,p_output:2,p_x:27,pa:37,pack:[0,30],packag:[0,1,2,3,4,5,6,7,8,9,11,13,14,15,21,22,24,25,27,31,32,34,35,36],packtpub:30,packtpublish:30,pad:[3,4],page:[0,9,22,30,32,33,34,35],pai:[0,1,9,13,35,36,37],pair:[0,2,3,9,22,27,30],panda:[0,4,5,6,7,9,11,15,22,24,32,33,34],panel:30,paper:1,paradigm:[0,30],parallel:[10,13,21,22,23,30,35,36],param:2,param_distribut:34,param_grid:34,paramat:2,paramet:[0,1,2,3,4,5,6,7,8,9,10,12,13,16,17,18,19,21,24,25,27,32,33],parameter:[0,6,10,24,30,31],parametr:[0,6,15,16,30,31,33],paramt:[3,5,32,33,37],parent:[2,37],parent_argnum:[],part:[0,1,3,5,6,10,17,18,21,23,26,27,28,30,32,33,36],partial:[0,1,5,6,7,8,10,11,12,13,16,27,30,31,32,34,35,37],particip:[22,26,28,30],particl:[0,4,13,27,30,35,36],particular:[0,1,2,3,5,6,9,10,11,12,13,16,24,27,29,30,31,32,33,34,35,36,37],particularli:[5,6,8,11,13,21,27,31,33,34,35,36],partit:[1,4,9],partli:[6,30,33],pass:[2,3,12,14,34,37],passkwarg:[],password:[24,25],past:[10,27],patch:[6,27,33],path:[0,3,4,6,7,9,14,15,22,30,31,33,34],pathcollect:[21,36],patient:[7,34],patter:4,pattern:[0,3,4,12,26,29,30,36,37],pauli:[0,30],pc:[11,22],pca:[0,7,22,30,31,34],pd:[0,4,5,6,7,9,11,30,31,32,33,34],pde:2,pdf:[0,3,4,5,6,9,16,20,24,25,29,30,32,33,34,36],pedagog:[0,30,31],penal:[6,31,32],penalti:[6,13,24,31,32,34,35],penros:[5,6,32],pentagon:[13,34,35],peopl:[0,1,9,13,22,35,36,37],per:[0,1,6,26,28,30,33,37],percentag:[0,10,11,28],perceptron:[0,1,7,30,34],peregrin:30,perfect:[0,1,13,21,30,35,36],perfectli:[4,6,33],perform:[0,2,3,4,5,6,8,10,11,12,13,14,15,16,17,19,21,22,23,24,25,27,30,31,32,33,34,35,36,37],performac:4,perhap:[0,5,13,30,31,32,34,35],perimet:[1,9],period:[1,4,27],permut:11,persist:[13,35,36],person:[5,6,7,26,28,30,31,32,33,34],perspect:29,pertin:[12,25,30,37],petal:[8,9],peter:[29,31],petersen:37,phantom:27,phase:[6,12,36,37],phenomena:27,phi:8,phi_k:8,philipp:37,philosophi:[13,35],phone:[28,30],photo:4,php:25,phrase:[0,30],physic:[0,1,4,7,12,13,25,27,28,29,30,31,32,33,34,35,36,37],pi:[2,3,5,6,7,9,12,13,27,32,33,34,35,36,37],pick:[1,9,10,11,13,14,35,36],pickl:1,pictur:[0,30],pie:[22,30],piec:[11,14],pillow:[0,15,22,24,30],pinv:[5,6,13,21,31,32,35,36,37],pip3:[0,1,15,24,30],pip:[0,1,15,22,24,30],pipelin:[0,6,8,10,31,33],pippin:30,pit:4,pitfal:[6,31,32],pitt:[12,36,37],pixel:[1,3,4],pixel_height:[1,3],pixel_width:[1,3],place:[0,4,6,8,13,23,24,30,33,34,35],plai:[0,3,4,5,6,8,11,22,30,31,32,33,34,37],plain:[8,10,12,13,14,21,25,34,35,37],plan:[6,9,28,29,30],plane:[8,9],plateau:[5,32],platform:[22,30],plausibl:[12,36,37],pleas:[9,11,13,24,25,28,30,35,36],plenti:[1,37],plethora:[3,12,36,37],pliahhy2ibx9hdharr6b7xevztgzra1p:[36,37],plot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,21,22,23,24,25,27,30,31,32,35,36,37],plot_all_sc:[24,32],plot_confusion_matrix:[7,10,34],plot_count:6,plot_cumulative_gain:[7,10,34],plot_data:1,plot_dataset:8,plot_decision_boundari:[9,10],plot_import:10,plot_max:4,plot_min:4,plot_model:4,plot_numb:4,plot_predict:8,plot_regression_predict:9,plot_result:4,plot_roc:[7,10,34],plot_surfac:[2,6,13,24,35],plot_train:9,plot_tre:[9,10],plqvvvaa0qudcjd5baw2dxe6of2tius3v3:[36,37],plt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,24,27,30,31,32,33,34,35,36,37],plu:[0,3,5,7,30,31,32,34],pluggabl:[3,4,14],plugin:[3,4,14],pm:[8,33],pmatrix:2,pml:29,pn:3,png:[0,4,6,7,9,30,31,33,34],point:[0,1,2,3,5,6,7,8,9,10,11,13,14,15,16,17,19,21,23,24,27,28,30,31,33,34,35,36],point_1:4,point_2:4,poisson:[22,27,30],poli:[6,8,33,34],poly100_kernel_svm_clf:8,poly3:0,poly3_plot:0,poly3dcollect:35,poly_featur:[8,9],poly_features10:9,poly_fit10:9,poly_fit:9,poly_kernel_svm_clf:8,polydegre:[0,5,6,10,31,32,33],polygon:[13,34,35],polym:[12,36,37],polymi:24,polynomi:[0,5,6,7,8,9,10,11,15,16,17,19,21,24,25,30,31,33,34,36,37],polynomial_featur:[6,33],polynomial_svm_clf:8,polynomialfeatur:[0,6,8,9,31,33,34],polytrop:[0,6,30,33],pool:3,pool_siz:3,poor:[1,13,21,34,35,36,37],poorli:[0,31],pop:2,popul:[0,5,30,31,32,33],popular:[0,1,3,6,7,8,9,11,12,15,22,23,24,27,31,34,36,37],popularli:[0,30],portabl:10,portion:[11,13,21,35,36],pose:[0,4,5,6,11,27,30,33],posit:[0,1,2,3,5,7,8,10,11,13,14,23,27,30,31,32,33,34,35,36,37],possibl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,19,21,22,23,24,25,27,28,30,31,32,33,34,35,36,37],posterior:[5,32,33],postpon:[0,30,31],postscript:[24,25],postul:[5,32,33],potenti:[0,3,5,6,12,13,30,31,32,33,35,36,37],pott:[12,36,37],power:[0,1,5,6,8,9,12,13,30,31,33,35,36,37],pp:[5,6,18,32,33,34,37],practic:[0,5,6,7,8,24,25,27,31,32,33,34],practition:[0,1,3,30,37],pre:30,precalcul:37,preced:[1,11,12,27,36],preceed:4,preceq:8,precis:[0,2,5,11,13,23,24,25,27,30,31,32,33,35,36,37],pred:[6,33,35,36],predicit:0,predict:[0,1,5,6,7,8,9,10,15,16,22,24,29,30,31,32,33,34,36,37],predict_prob:1,predict_proba:[7,10,34,36,37],predictor:[0,5,6,7,9,10,11,30,31,32],prefer:[0,1,6,8,9,11,13,15,22,24,25,30,37],prepar:[0,6,23,24,25,30,31],preprocess:[0,4,6,7,8,9,10,11,24,32,33,34],prerequisit:0,prescript:[24,25],presenc:[13,35,36],present:[0,5,6,7,9,12,13,21,23,24,25,27,30,31,32,35,36,37],preserv:[3,11,23],press:[13,29,34,35,37],pretrain:[1,4,37],pretti:[0,4,8,9,15,22,24,30],prev_centroid:14,prevent:[13,27,35,36],previou:[0,1,2,3,4,5,6,8,10,11,12,13,21,23,24,25,27,31,34,35,36,37],previous:[2,3,9,10,27],price:[0,4,9,13,35,36],primal:8,primari:[0,7,30,34],prime:27,primit:2,princip:[0,5,7,22,30,31,34],principl:[0,6,7,8,14,30,33,34],print:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,21,23,27,30,31,32,33,34,35,36,37],print_funct:[8,9],printout:[0,30],prior:[0,5,6,30,32,33],privat:0,pro:25,prob:[1,27],probabilist:[0,29,30,31],probabl:[0,1,3,4,6,7,10,13,22,30,31,34,35,36,37],problem:[0,3,4,5,6,7,8,9,10,11,12,16,17,22,23,24,25,27,33],probml:29,proce:[0,5,6,7,8,9,10,11,13,23,30,31,32,33,35,37],procedur:[2,4,5,6,8,10,11,13,21,24,31,32,33,34,35,36],proceed:23,process:[0,2,4,6,9,10,12,13,15,21,22,23,24,27,29,30,33,34,35,36,37],prod:29,prod_:[1,5,7,32,33,34],produc:[0,3,4,5,6,9,10,11,12,13,22,23,24,27,30,31,32,33,35,36,37],product:[0,1,3,5,6,7,8,12,13,16,21,22,23,30,31,32,33,34,36,37],profess:[0,30],progag:25,program:[0,1,4,5,6,8,12,14,15,16,21,22,23,26,27,28,30,31,36],programm:23,progress:[1,4,14,35,37],prohibit:[6,33],project1:[6,24],project:[0,1,2,3,5,11,13,17,18,19,20,21,22,26,28,31,32,33,35,36,37],project_root_dir:[0,6,7,9,30,31,33,34],projectwrit:24,promin:[12,36,37],promis:8,promot:[28,30],prone:[9,37],pronounc:[13,22,30,35,36],proof:[0,11,12,13,30,33,34,35,37],propag:[2,3,13,25,35,36],proper:[0,2,6,7,24,33],properli:[1,6,8,10,13,21,24,25,35,36,37],properti:[0,1,3,12,13,16,17,23,30,33,35,36,37],propgag:37,proport:[0,1,5,9,11,13,16,27,30,31,35,36],propos:[1,4,6,10,24,25,30,37],propto:[5,13,32,33,34,35,36],proton:[0,30],prove:[3,13,34,35,36],provid:[0,1,3,4,5,6,8,9,10,12,13,15,21,22,23,24,25,27,30,31,32,33,34,35,36,37],proxi:[1,13,21,35,36,37],prune:9,pseudo:[23,27,35],pseudocod:[24,25],pseudoinv:[5,32],pseudoinvers:[5,6,32],pseudorandom:[6,27,33],psycholog:[0,30],pt:[13,35],publish:37,punish:[0,1,30],pure:[3,9,27],purest:9,puriti:9,purpos:[0,3,10,12,14,30,36,37],put:1,py:[0,1,2,3,4,5,6,7,8,9,11,14,21,30,32,33,34,36],py_tf:[3,4,14],pycod:30,pydata:22,pydot:9,pyhton2:30,pylab:[0,7,30,34],pypi:22,pyplot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,24,27,30,31,32,33,34,35,36,37],pythagora:[5,32,33],python2:[0,15,24,30],python3:[0,1,2,3,4,6,7,8,9,11,14,15,21,22,24,30,32,34,36],python:[1,2,3,4,5,6,8,11,12,13,14,16,21,24,25,27,31,32,35,36,37],pytorch:[0,22,24,25,30,37],q:[5,6,8,11,27,31,33],qp:8,qquad:[2,11,13,23,35,36],qr:[5,6,23,31],quad:[1,13,23,35],quadrat:[0,8,9,13,15,16,30,35],qualit:[4,9,24,25,27],qualiti:[0,9,15,16,22,30,31,37],quantifi:[1,37],quantil:10,quantit:[0,6,9,24,25,30,33],quantiti:[0,2,5,6,7,9,10,11,12,14,16,23,27,30,31,32,33,34,37],quantum:[4,12,29,30,36,37],quartil:[0,31],quasi:37,quench:5,queri:9,question:[0,5,6,9,11,12,13,24,28,30,31,32,33,35,36,37],qugan:4,quick:[4,27],quickli:[1,3,9,11,13,34,35,37],quit:[1,5,6,9,10,12,31,33,36,37],quot:4,r2:[0,5,6,25,30,31,32,34],r2_score:[0,30],r2score:[0,30],r:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,22,23,24,27,31,32,33,34,35,36,37],r_1:9,r_2:9,r_j:9,r_m:9,rad:0,radial:[0,8,12,36,37],radioact:27,radiu:[0,1,9,31],rag:2,rain:9,rais:[0,2,3,4,7,14,32,34],ramp:[1,37],ran0:27,ran1:27,ran2:27,ran3:27,rand:[0,4,5,6,9,10,13,15,16,21,23,30,31,32,33,34,35,36],randint:[6,9,13,21,33,35,36],randn:[0,1,2,5,6,9,11,13,15,16,21,30,31,32,33,34,35,36,37],random:[0,1,2,3,4,5,6,8,9,13,14,15,16,21,22,23,24,30,31,32,33,35,36,37],random_forest_model:10,random_index:[13,21,35,36],random_indic:[1,3],random_st:[0,7,8,9,10,11,34,36,37],randomforestclassifi:10,randomizedsearchcv:34,randomli:[1,6,9,13,14,21,33,34,35,36],randuniform:34,rang:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,21,23,27,30,31,32,33,34,35,36,37],rangl:[0,6,11,27,30,31],rangle_x:27,rank:[5,31],rankdir:4,raphson:[1,8,13],rapidli:0,rare:[1,13,30,34,35,36,37],raschka:[25,30,31,32,33,34,35,36],rasckha:30,rashcka:37,rashkca:37,rate:[0,1,2,3,4,8,9,10,12,13,25,34,37],rather:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,23,27,30,31,32,33,34,35,36,37],ratio:[4,7,9,10,11,34],rational:[0,30],ravel:[5,6,7,8,9,10,11,13,23,31,33,34,35],raw:3,rbf:[8,11,12,36,37],rbf_kernel_svm_clf:8,rbf_pca:11,rc:[0,27],rc_temp:[0,7,34],rcond:[0,30,31],rcparam:[0,1,3,7,8,9,10,27,30,34],re:[2,4,13,34,35],reach:[1,4,5,6,9,10,11,12,13,14,32,33,34,35,36,37],read:[0,2,3,4,5,6,7,8,11,12,16,21,23,24,25,26,27,29,32,35],read_csv:[0,6,7,9,30,33,34],read_fwf:[0,30],reader:[0,6,23,27,30,31,32],readi:[0,1,5,6,8,10,11,12,23,24,30,32,33,37],readili:1,readthedoc:22,real:[0,1,2,4,7,10,11,12,23,31,33,34,36],real_loss:4,real_output:4,realist:8,realiti:27,realiz:[1,12,36],realli:[0,1,30,37],rearrang:[13,35,36],reason:[0,1,3,4,10,13,29,30,34,35,36,37],reassign:1,recal:[5,6,9,10,11,12,23,27,30,31,32,33,34,35,37],recast:3,receiv:[1,3,10,12,27,36,37],recent:[0,2,3,4,6,7,10,13,14,21,24,29,30,32,33,34,35,36,37],recept:[3,12,36,37],receptive_field:3,recip:[0,6,7,23,24,25,30,31,34],reciproc:[5,32],recogn:[0,4,5,10,30,32,33],recognit:[0,1,3,12,26,29,30,36,37],recommen:30,recommend:[0,2,3,4,5,6,8,13,15,18,21,22,23,24,25,29,32,33,35,36],reconsid:9,reconstruct:11,record:[10,24,25,26,28,30,35,36],rectangl:[9,13,34,35],rectangular:[5,31],rectifi:[1,3,12,36,37],recur:[0,22,30],recurr:[0,1,22,30],recurs:[9,22,23,30],red:[0,3,4,6,8,9,21,33,35,36],redefin:[0,10,30,31],redefinit:32,reduc:[1,3,5,6,9,10,11,13,21,30,32,33,34,35,36],reduct:[0,10,11,22,27,30,31],refer:[0,1,2,3,5,6,9,11,12,13,14,20,23,25,29,30,31,33,34,35,36,37],referenc:[2,37],refin:[12,36,37],refit:[6,33],reflect:[0,1,4,5,24,25,27,30],refresh:[22,30],refreshprogrammingskil:30,reg:[10,11],regard:[1,9,13,35,37],regardless:[12,36,37],region:[3,4,6,9,12,24,36,37],regist:[6,24,27],reglasso:[5,32],regr_1:[0,9],regr_2:[0,9],regr_3:[0,9],regress:[1,8,11,12,15,16,21,22,23],regressor:[0,7,10,30,34],regridg:[0,5,6,32,34],regular:[0,3,4,5,6,7,9,13,17,25,28,30,31,32,33,35,36,37],regularis:6,reilli:[0,15,29,30],reinforc:[0,8,22,30],reiter:1,reject:7,rel:[0,4,6,7,9,12,13,27,30,31,33,34,35,36,37],relat:[0,1,3,4,5,11,13,14,23,27,30,32,33,35,36,37],relationship:[0,4,9,30],relativeerror:[0,30,31],releas:[1,22,25,30],relev:[0,1,5,7,11,15,21,22,24,25,27,30,32],reli:[0,6,8],reliabilti:[24,25],reliabl:[7,27,34],relu:[3,4,25,30],remain:[1,2,4,6,12,23,27,31,32,33,34,36,37],remaind:27,reman:2,remark:[1,37],rememb:[0,8,13,23,24,25,30,35,36],remind:[0,5,11,13,23,27,31,32,33],remov:[0,4,5,6,31,32],render:[0,9,30,31],reorder:[5,7,31,32,34],reorgan:[0,30],repeat:[0,1,3,4,5,6,9,10,11,13,14,21,23,24,25,27,30,32,33,34,35,36,37],repeated:30,repeatedli:[0,6,10,13,33,35,36],repet:3,repetit:[6,30,31,33,34,35],rephras:[13,34,35],replac:[0,1,3,4,5,6,10,12,14,15,16,21,22,24,25,30,31,32,33,34,37],replica:[6,33],repo:[24,25],report:[20,30,35,36],reportexampl:[20,24],reportsampl:20,repositori:[0,4,24,25,30],repres:[0,1,2,3,4,5,6,7,8,9,10,12,13,25,27,30,31,32,33,34,35,36,37],represent:[0,1,3,6,9,27,30,33,34],representd:3,reproduc:[0,5,6,9,12,15,16,22,24,27,30,31,37],repuls:[0,30],request:[0,13,21,35,36],requir:[0,1,3,4,5,6,8,9,11,12,13,17,23,30,31,32,33,34,35,36,37],rerun:9,res1:2,res2:2,res3:2,res_analyt:2,res_analytical1:2,res_analytical2:2,res_analytical3:2,resaml:[6,24],resampl:[0,7,10,19,22,30,31,34,35],rescal:[0,11,12,31,36],rescu:[5,32,33],reseach:[6,24],research:[0,4,13,21,22,29,30,35,36],resembl:[6,27,33],reserv:[1,5,6,27,32,33],reshap:[0,1,2,3,4,6,8,9,10,15,16,23,30,31,33],residenti:0,residu:[0,5,13,30,35],resiz:[5,31],resourc:30,respect:[0,1,2,3,5,6,7,8,10,11,12,13,14,16,17,21,24,27,30,31,32,33,34,35,36,37],respond:[12,36,37],respons:[0,7,9,12,30,31,34,36,37],rest:[0,5,31],restat:[0,12,30],restor:4,restored_discrimin:4,restored_gener:4,restrict:[0,3,9,12,30,36,37],result:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,22,23,24,25,27,30,33,34,35,36],retail:0,retain:[5,6,31,33,34],rethink:33,retriev:30,return_data:14,return_sequ:4,return_x_i:9,reus:[1,3,6,18,19,20,24,25,37],reveal:[0,12,30,36,37],revers:[1,23],review:[22,23],revisit:[14,37],revolut:30,reward:[0,4,30],rewrit:[0,3,5,6,7,8,10,11,12,13,19,23,24,27,32,34,35,36,37],rewritten:[2,6,8,10,27,33],rewrot:[13,34,35],rf:10,rgb:3,rgoj5yh7evk:22,rh:[6,33],rho:[0,10,13,21,30,35,36],rho_1:10,rho_2:10,rho_m:10,rich:[0,30],ride:9,rideclass:9,ridedata:9,ridg:[7,11,13,21,22,25,30],ridge_sk:6,ridgebeta:[5,32],ridgecv:34,right:[0,1,2,3,5,6,7,8,9,10,12,13,14,16,17,19,23,24,27,30,31,32,33,34,35,36,37],right_sid:2,rightarrow:[0,1,5,6,8,11,12,13,27,30,31,33,34,35,36,37],rigor:[0,30],ring:6,rise:[0,30],risk:[0,13,15,16,30,34,35,36],rival:4,river:0,rlm:30,rm:[0,27],rmse:0,rmsporp:[13,21,35,36],rmsprop:[1,3,4,13,25,37],rnd_clf:10,rng:27,rnn1:4,rnn2:4,rnn:[4,12,36,37],rnn_2layer:4,rnn_input:4,rnn_output:4,rnn_train:4,rntrick1:27,rntrick2:27,rntrick3:27,rntrick4:27,ro:[0,13,21,30,34,35,36],robert:[18,24,29],robust:[0,30],robustscal:[0,31],roc:[7,10],role:[0,2,5,6,8,22,30,31,32,33,34,37],roll:6,room:[0,28,30],root:[0,5,9,13,27,31,32,34,35,36],rot:30,rotat:[1,8,9,10],rotation_matrix:9,roughli:[1,3,37],round:[0,7,9,13,34,35,36],routin:[13,23,30,34,35],row:[0,1,2,5,6,9,11,23,30,31,32,33],row_stack:[],rr:[5,31],rrr:[5,31],rug:[13,34,35,36],rule:[0,1,5,6,13,24,30,31,32,33,35,36],run:[0,1,2,4,5,6,8,9,11,13,15,21,22,24,25,30,31,32,33,34,35,36],runtim:[1,6,14,37],runtimewarn:[1,6,33],rust:[0,15,22,23,30],rvert:1,rvert_2:1,s:[0,1,2,3,4,5,6,7,9,11,12,13,16,17,18,22,23,24,25,27,30,31,32,37],s_1:6,s_:[3,6],s_i:[6,7,34],s_j:6,s_k:6,saddl:[13,34,35,36],sai:[0,1,2,3,4,5,6,7,8,9,10,11,12,23,24,27,30,31,32,33,34,37],said:[6,9,13,34,35],sake:[0,5,7,11,30,31,32,34,37],sale:[0,30],sam:30,same:[0,1,2,3,4,5,6,8,9,11,12,14,17,23,24,27,30,31,32,34,37],samm:10,sampl:[0,1,2,3,4,5,6,7,8,9,10,13,14,15,16,19,21,22,23,24,27,30,31,32,33,34,35,36,37],sample_vari:14,sampleexptvari:27,samwis:30,sastri:11,satisfactori:[0,30],satisfi:[1,2,3,6,8,13,23,27,33,34,35],satur:[1,6,33,37],save:[0,4,6,7,9,13,21,30,31,33,34,35,36],save_fig:[0,6,7,9,10,30,31,33,34],savefig:[0,4,6,7,9,27,30,31,33,34],savetxt:4,saw:[5,31],scalabl:10,scalar:[2,5,6,10,31,32,33,37],scale:[0,1,3,5,6,7,8,9,10,11,12,13,15,16,17,21,22,23,24,25,28,30,32,34,35,36,37],scale_mean:4,scale_std:4,scaler:[0,7,8,9,10,11,24,31,32],scan:[5,7,32,33,34],scari:[5,32,33],scatter:[0,1,6,7,8,9,14,21,30,31,32,33,34,36],scenario:[6,13,34,35,36],schedul:[13,28,35,36],scheme:[1,13,34,35,36,37],schrage:27,scienc:[0,1,10,12,13,22,26,27,28,29,34,35,36,37],scientif:[0,15,22,24,25,30,35,36],scientist:[0,30],scikit:[3,5,6,8,9,10,13,21,22,23,24,25,26,29,36,37],scikit_learn:[0,16],scikitlearn:30,scikitplot:[7,10,34],scipi:[0,3,5,6,13,15,22,23,24,30,31,32,33,34,35],scl:6,score:[0,1,3,6,7,9,10,11,15,16,24,25,28,30,31,33,34,35,36,37],scores_kfold:[6,33,34],scratch:[1,13,36,37],sdg:[13,21,35,36],sdv4f4s2sb8:36,seaborn:[0,1,3,6,7,21,25,30,34],seamless:[0,15,22,24,30],search:[0,1,3,5,9,13,30,32,35,36,37],sebastian:[30,37],sebastianraschka:[25,30],sec:6,second:[0,2,3,4,5,6,7,8,9,11,12,14,15,16,22,23,24,25,27,28,30,31,33,34,37],second_mo:[21,35,36],second_term:[21,35,36],secondeigvector:11,secondli:[12,37],section:[4,11,16,17,23,24,27,31,32,34,35,36],sector:0,see:[0,1,2,3,4,5,6,7,8,10,11,12,13,15,16,17,18,21,22,23,24,25,27,30,31,32,33,34,35,36,37],seed:[0,1,2,3,4,5,6,8,9,11,13,14,15,16,21,24,27,30,31,32,33,34,35,36,37],seed_imag:4,seek:[1,2,8,37],seem:[1,3,4,35,36,37],seemingli:[0,30],seen:[0,1,3,5,10,12,17,27,30],segment:[13,34,35],seismic:6,seldomli:[0,30],select:[1,5,6,8,9,10,11,17,24,25,26,27,28,29,30,31,32,33],self:[0,1,2,5,7,21,30,31,32,34,36],sell:4,semest:[7,26,34],semi:[8,13,34,35],semilogx:6,send:[5,12,13,28,30,35,36,37],senior:[26,28],sens:[0,4,6,8,24,30,33],sensibl:3,sensit:[0,5,6,9,13,30,31,32,33,36],sent:[2,37],sentdex:[36,37],sentenc:[4,12,36,37],separ:[0,1,2,4,6,8,9,12,14,15,22,24,27,30,33,36,37],septemb:[17,18,19,20,24,30],sequenc:[2,3,4,7,9,10,12,13,22,23,27,30,34,35,36,37],sequenti:[1,3,4,10,12,27,36,37],seri:[0,1,2,3,4,5,6,10,11,12,13,23,30,31,32,33,34,35,36,37],serif:[0,7,27,30,34],serv:[0,1,2,3,5,7,13,21,24,29,30,31,32,33,34,35,36,37],servic:[24,25],session:[1,20,24,26,28,30],set:[1,4,5,6,7,8,10,11,13,14,16,17,21,22,23,24,25,27,28,32,33,35,36],set_major_formatt:[6,24],set_major_loc:[6,24],set_tick:[1,6,8],set_ticklabel:[1,6],set_titl:[0,1,2,3,7,12,14,30,34,36,37],set_xlabel:[0,1,2,3,7,12,30,34,36,37],set_xlim:[7,12,34,36,37],set_xticklabel:1,set_ylabel:[0,1,2,3,7,30,34],set_ylim:[7,12,34,36,37],set_ytick:[7,34],set_yticklabel:[1,6],set_zlim:[6,24],seth:4,setminu:[6,34],setosa:[8,9],setosa_or_versicolor:8,setp:[6,33],setup:[1,4,6,8,21,22,25,30,31,37],sever:[0,3,5,6,7,8,9,11,12,13,21,22,23,25,27,30,31,32,33,34,35,36,37],sgd:[1,3,21,25,34],sgd_clf:8,sgdclassifi:8,sgdreg:[13,34,35],sgdregressor:[13,34,35],sgn:[5,31,32],shallow:[13,35,36],shape:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,23,30,31,32,33,34,35,36,37],shape_bas:2,share:[1,3,30,37],she:[7,34],shell:[21,36],shift:[1,6,12,27,32,36,37],ship:3,shire:30,shortcom:[13,34,35,36],shorten:4,shorter:27,shorthand:[30,33],shortli:[23,30],should:[0,2,3,5,6,8,9,11,12,15,16,21,23,24,25,27,30,31,32,33],show:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,21,23,24,27,30,31,32,33,34,35,36,37],show_shap:4,shown:[0,4,5,8,9,11,12,13,21,23,31,34,35,36,37],shrink:[3,5,6,8,11,24,31,32],shrinkag:[5,6,31,32],shrunk:11,shuffl:[0,1,4,6,13,21,31,33,34,35,36],sickit:37,side:[0,2,5,8,12,13,23,25,30,32,33,34,35,36,37],sigh:[22,30],sigma0:27,sigma1:27,sigma2:27,sigma:[0,1,5,6,7,10,11,12,13,17,18,19,23,24,27,30,31,32,33,34,35,36,37],sigma_0:[5,31,32],sigma_1:[5,31,32,37],sigma_2:[5,31,32,37],sigma_:[5,23,30,31,32,33],sigma_fn:[7,12,34,36,37],sigma_i:[0,5,30,31,32],sigma_j:[5,17,31,32],sigma_m:[6,27,33],sigma_n:[11,27],sigma_t:[13,35,36],sigma_x:27,sigmoid:[1,2,4,7,8,10,12,25,34,35,36],sigmundson:[6,31,32],sign:[1,2,7,8,10,27,28,34,36],signal:[1,3,10,12,36,37],signifi:4,signific:[1,37],significantli:[1,13,21,27,34,35,36,37],sigurd:30,sim:[4,5,6,13,18,24,27,32,33,35,36],similar:[0,1,2,3,4,5,6,7,8,9,10,11,14,17,22,23,24,25,30,32,33,34,37],similarli:[0,1,3,5,8,10,13,20,27,30,31,32,37],simpl:[1,2,3,5,6,7,8,10,11,12,14,15,16,17,19,21,22,23,24,25,27,33],simplepredict:10,simpler:[0,1,5,6,7,13,16,19,21,22,24,25,30,32,35,36],simplernn:4,simplest:[0,1,3,4,9,10,12,14,30,36,37],simpletre:10,simpli:[0,1,2,4,5,6,8,9,10,11,12,15,22,23,24,25,27,30,31,32,33,36,37],simplic:[2,5,6,7,8,9,10,11,12,14,31,32,34,36,37],simplicti:[5,31],simplif:37,simplifi:[0,6,9,15,22,24,30,31,32,33,37],simplist:[3,6,27,33],simul:[6,33],simultan:[6,33],sin:[0,1,2,3,4,9,12,13,21,23,30,35,36,37],sinc:[0,1,2,3,5,6,7,8,9,10,11,13,21,23,25,27,29,30,31,32,33,34,35,36,37],sine:[3,12,36,37],singl:[0,1,2,3,5,6,7,8,9,12,13,23,25,27,30,31,32,33,34,35],singular:[0,6,13,23,24,30,32,33,34,35],sinusoid:3,site:[0,1,2,3,4,6,7,8,9,11,14,21,24,25,26,30,32,34,36],situat:[0,4,5,7,13,21,27,30,31,34,35,36],six:[3,27,37],size:[0,1,2,3,4,5,6,8,9,10,11,13,21,23,24,25,27,30,32,33,34,35,36,37],sketch:10,ski:9,skill:0,skip:11,skl:[0,6,30,31,32],sklearn:[0,1,3,5,6,7,8,9,10,11,13,14,30,31,32,33,34,35,36,37],skplt:[7,10,34],sl:[6,32,34],slack:8,slice:[2,23,30],slide:[0,3,15,16,24,25,27,30,31,33,35,37],slight:[6,13,33,35,36],slightli:[1,2,3,5,6,7,10,27,31,32,33,34,37],slope:[8,11,12,36],slow:[0,2,8,13,31,34,35,36],slower:[5,23,30,31,32],slowest:23,slowli:12,slp:1,small:[0,1,2,3,5,6,8,9,10,11,12,13,21,22,23,24,27,30,31,32,33,34,35,36,37],smaller:[0,1,2,5,6,8,9,11,13,27,30,31,32,33,34,35,36,37],smallest:[0,4,14,15,16,30,34],smallest_row_index:14,smooth:[0,3,6,9,13,24,30,34,35],sn:[0,1,3,6,7,30,34],sne:11,sneak:30,so:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,18,19,21,22,23,24,25,27,28,30,31,32,33,34,35,36,37],soar:6,social:0,soft:[1,7,10,12,34,36,37],soften:8,softmax:[3,7,34,37],softwar:[0,8,15,22,23,37],sol:8,sole:[0,6,30],solid:[0,7,34],solut:[0,1,2,3,5,6,8,10,11,13,17,18,23,24,25,27,30,31,32,33,34,35,36,37],solution_ev:35,soluton:2,solv:[0,1,3,5,6,8,10,11,12,13,23,24,25,30,31,36,37],solve_expdec:2,solve_ode_deep_neural_network:2,solve_ode_neural_network:2,solve_pde_deep_neural_network:2,solveod:2,solveode_popul:2,solver:[2,7,8,9,10,11,21,23,30,34,36],some:[0,1,2,3,4,5,6,7,8,9,10,11,12,14,24,27,30,32,33,36],some_model:[6,31,32],somehow:4,someth:[0,1,3,4,7,9,11,24,25,27,30,31,34,37],sometim:[0,1,11,12,13,14,30,31,35,36,37],somewhat:[36,37],soon:[23,28,31],sophist:[0,30],sopt:[13,35],sort:[5,6,9,11,27,31,33],sound:[3,5,32,33],sourc:[0,1,3,6,15,22,23,24,25,27,30,33],space:[0,1,4,5,8,9,11,12,13,14,21,27,31,32,33,34,35,36,37],span:[0,3,5,9,11,23,30,31],spare:[1,37],spars:[3,6,23,30],sparse_mtx:[23,30],sparsecategoricalcrossentropi:3,sparsiti:10,spatial:[1,2,3,12,36,37],speak:27,special:[6,7,10,12,13,23,27,30,31,32,34,35,37],specif:[0,1,2,3,4,5,6,7,8,9,11,12,16,22,23,24,25,27,29,30,31,32,33,34,36,37],specifi:[0,3,5,6,7,9,11,13,14,21,24,27,30,32,33,34,35,36],specifici:[0,10,30],spectacular:3,spectral:1,speech:[0,1,3,4,12,36,37],speed:[1,2,4,13,35,36,37],spend:27,spent:[24,25],sphere:[0,31],spin:6,spite:0,spline:8,split:[1,3,4,5,6,8,9,10,11,14,17,24,27,32,33,34],splite:0,splitter:[1,10],spontan:27,spot:3,spread:[0,11,27,30,31],springer:[18,24,29,30,33],spuriou:[13,21,35,36],sqquar:32,sqrsignal:3,sqrt:[0,3,4,5,6,8,10,11,13,17,21,27,31,32,33,35,36,37],squar:[1,2,3,4,7,8,9,11,13,14,15,16,17,19,21,22,23,25,27,33,34,35,36,37],squarederror:10,squaredeuclidean:14,squash:[12,36,37],srtm:[6,24],srtm_data_norway_1:[6,24],stabil:[5,24,25],stabl:[0,4,5,6,9,11,22,24,30,31,32],stack:[2,3,4],stage:[5,13,21,24,25,35,36,37],stai:[0,2,4,5,11,17,30,31],stand:[0,5,9,12,30,31,32,36],standadscal:31,standard:[0,1,4,5,6,7,8,10,12,15,16,17,19,21,23,24,25,27,30,32,34,36,37],standard_basi:2,standardscal:[0,6,7,8,9,10,11,31,32],stanford:[13,34],start:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,20,23,25,27,28,30,31,33,34,35,37],start_box:2,start_nod:2,start_tim:14,starting_point:[21,36],stat:[6,33,34],state:[1,2,4,5,6,7,8,10,11,12,13,22,25,27,31,32,33,34,35,36,37],statement:[0,7,23,30,34],stationari:[34,35],statist:[0,1,3,4,7,9,10,11,12,13,14,18,23,24,26,29,31,34,35,36,37],statu:[0,7,9,11,30,34],stavang:[6,24],std:[0,4,6,30,31,33],steep:[13,21,34,35,36],steepest:36,step:[0,1,2,4,6,7,9,10,11,12,13,14,21,23,24,30,37],step_fn:[7,12,34,36,37],step_length:[13,35,36],step_siz:35,steps_list:9,stereo:3,still:[0,2,3,5,6,11,13,17,27,33,34,35,36,37],stimuli:[12,36,37],stk2100:[29,30],stk3155:[15,24,25,26,28],stk4021:[29,30],stk4051:[29,30],stk4155:[26,28],stk5000:29,stk:[29,30],stochast:[0,1,5,6,8,11,12,15,16,24,30,32,33,34,37],stock:4,stoke:[12,36,37],stone:[0,7,24,34,37],stop:[1,4,9,11,13,14,21,34,37],stopiter:[0,7,34],storag:[5,31],store:[0,1,2,3,6,11,13,24,27,30,35,36],storehaug:[28,30],str:[1,3,4],straight:[0,6,8,13,30,33,34,35],straightforward:[0,2,3,5,6,8,9,10,13,23,30,31,32,33,34,35],strategi:[0,1,9,30],stratifi:[6,33],strength:[0,5,14,31],stretch:11,strict:[8,13,34,35],strictli:[8,13,34,35],stride:[4,23],strike:6,string:1,stroke:[7,34],strong:[3,6,9,10,12,23,27,33,36,37],strongli:[0,8,22,23,25],stronli:0,structur:[0,1,2,3,6,9,10,12,22,30,33,34,35,36],stuck:[1,13,34,35,36,37],student:[0,24,25,26,28,29,30],studi:[0,3,4,5,6,7,8,11,12,13,17,19,21,22,24,25,29,30,31,32,35,36,37],studier:29,style:[0,7,9,23,30,34],sub:[9,12,36,37],subarg:2,subdivid:[0,23,30],subfield:0,subject:[6,8,27],submit:30,subplot:[0,1,3,4,6,7,8,9,10,14,30,33,34],subplots_adjust:[8,27],subprogram:[23,30],subract:[0,31],subroutin:[0,30],subscript:1,subsequ:[1,4,5,6,12,23,27,31,33,36,37],subset:[1,6,9,12,13,22,30,33,34,35,36,37],subspac:[0,8,11,31],substanti:[9,10],substep:11,substitut:[3,6,12,23,33,36],subsubset:9,subtask:6,subtl:[1,37],subtract:[0,2,4,5,6,11,13,17,21,23,24,27,32,33,35,36],subtre:9,subval:2,succeed:[0,4,30],success:[3,7,9,13,27,34,35],successfulli:[4,9],sudo:[0,15,22,24,30],suffer:[0,1,2,5,10,30,31,32,37],suffici:[1,6,8,11,13,33,34,35],suggest:[1,13,24,25,29,35,37],suit:[8,12,36,37],suitabl:[0,27,31],sum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,24,27,30,31,32,34,35,36],sum_:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,23,24,25,27,30,31,32,33,34,35,36,37],sum_i:[0,2,5,6,8,13,17,19,24,31,32,33,35,36],sum_j:6,sum_ja_:0,sum_k:[6,8,12,23,37],sum_logist:[13,35],sum_m:3,sum_n:3,sum_nx_:3,summar:[5,6,9,25,32,33,34,36],summari:[1,3,4,10,21,25,26,32],summat:[0,3,16,31],sunni:9,superconduct:32,superfici:3,superscript:[1,12,36,37],supervis:[0,5,6,7,9,12,22,30,31,33,34,36],supplement:[7,24,34],support:[0,1,9,10,11,13,22,30,31,35,37],suppos:[0,5,6,7,8,10,11,12,13,23,30,31,32,33,34,35,36,37],suppress:[5,8,13,32,35,36],sure:[0,1,4,6,24,37],surf:[6,24],surfac:[0,6,24,30],surpass:6,surpris:[0,30],surround:[3,22],survei:[0,5,6,30,31,32,33],svc:[8,9,10],svd:[0,6,11,17,30,33],svdinv:[5,32],svm:[8,9,10,11],svm_clf:[8,10],swath:[5,31],sy:[13,34,35],symbol:[1,3,4,5,11,13,14,22,27,30,31,32,35,36,37],symmeteri:1,symmetr:[0,5,8,11,12,13,23,30,31,35,36,37],symmetri:[6,9],sympi:[0,15,22,24,30,37],synonim:27,syntax:[1,13],syntaxerror:[1,8],system:[0,1,3,4,6,7,9,10,12,13,15,22,23,24,30,34,35,36,37],systemat:[4,6,33],t0:[3,6,13,21,35,36],t1:[2,13,21,35,36],t2:2,t3:2,t:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,27,28,30,33,34,35,36,37],t_0:[2,9,13,35,36],t_1:[13,35,36],t_:2,t_b:10,t_i:[1,2,5,12,25,31],t_j:12,t_k:9,tabl:[9,24,25,27,28,30,36,37],tabul:[0,30],tabular:30,tackl:4,tag:[2,3,4,5,6,7,12,13,14,21,23,27,31,34,35,36,37],tagrget:37,taht:[0,30],tail:27,tailor:[2,8,11,30,37],taiwan:[0,30],take:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,16,21,22,23,27,30,31,32,33,34,35,36,37],taken:[0,1,3,6,10,13,23,30,33,35],tan:3,tangent:[1,4,12,13,34,35,36,37],tanh:[1,4,7,8,12,34,35,36,37],target:[0,1,2,3,4,5,6,7,8,9,10,11,12,25,30,31,32,33,34,35,36,37],target_iscomplex:[],target_meta:2,target_nam:9,target_ndim:[],target_shap:[],task:[0,1,3,6,9,11,12,14,20,24,30,33,36,37],tau:[3,5,27,32,33],taught:30,tax:0,taylor:[2,13,34,35,37],taylornr:[13,34,35],tba:[],tc:8,td:[1,6,30,33],teach:30,team:1,teaser:0,technic:[0,5,6,13,15,24,30,31,35,36],techniqu:[0,1,8,10,13,22,27,29,30,31,33,34,35,36,37],technolog:[0,1],tell:[0,4,6,10,11,13,27,33,35,36],temp1:1,temp2:1,temp:1,temperatur:[0,9,30],temporarili:[1,37],ten:[3,17,30,37],tend:[3,5,6,8,9,10,12,13,14,21,31,32,33,35,36],tendenc:[0,30],tension:[6,33],tensor:3,tensordot:[],tensordot_adjoint_0:[],tensordot_adjoint_1:[],tensorflow:[0,2,4,8,14,15,22,23,24,25,26,29,30,31],term1:[5,6,11,24,31],term2:[5,6,11,24,31],term3:[5,6,11,24,31],term4:[5,6,11,24,31],term:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,24,27,30,31,32,34,35,36],termin:[0,4,5,9,10,13,15,21,30,31,35,36],terrain1:[6,24],terrain:[6,21,24,25],test:[3,4,5,6,7,8,9,10,13,17,19,21,23,24,27,33,34,35,36,37],test_acc:3,test_accuraci:[1,3],test_error:6,test_imag:[3,4],test_ind:[6,33,34],test_input:4,test_label:[3,4],test_loss:3,test_pr:1,test_predict:1,test_rnn:4,test_scor:[7,10,34],test_siz:[0,1,3,5,6,10,30,31,32,33,34],test_split:9,tester:32,testerror:[0,6,31,33],testi:4,testpredict:4,testx:4,text:[0,1,2,4,5,8,9,11,13,15,21,23,25,27,29,31,33,34,35,36],textbook:[16,17,21,24,25,31,33],textual:9,textur:[1,9],tf:[1,3,4,13,14,34,35],tf_loadlibrari:[3,4,14],th:[0,1,2,5,6,7,9,12,13,14,15,16,23,24,27,30,31,32,33,34,35,36,37],than:[0,1,2,3,4,5,6,7,9,10,11,12,13,17,22,25,27,30,31,32,33,36,37],thank:[4,6,31,32],theano:[1,22,30],thei:[0,1,2,3,4,5,6,7,8,9,11,12,13,23,24,27,30,31,32,33,34,35,36,37],them:[0,1,3,4,6,8,9,10,11,12,13,23,24,25,30,31,32,35,36,37],theme:[0,30,35],themselv:[0,27,30],thenc:[6,33],theorem:[2,6,7,31,34,36],theoret:[0,4,10,30],theori:[0,1,3,8,9,12,13,18,22,24,29,30,32,35,36,37],thereaft:[0,5,6,11,12,15,16,17,23,24,25,30,33,37],therebi:[0,5,7,11,30,31,32,34,37],therefor:[0,1,2,3,4,6,7,8,11,13,27,30,31,33,34,35,36],therein:11,thereof:[0,6,13,30,33,35,36],theta:[1,4,13,21,27,35,36,37],theta_:[1,13,35,36],theta_i:1,theta_linreg:[13,21,35,36],theta_t:[13,35,36],thetaand:[36,37],thetaor:[36,37],thetaxor:[36,37],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,22,23,24,25,26,27,29,31,32,33,34,35,36],thing:[0,1,2,4,5,7,9,27,30,32,33,34,37],think:[0,1,3,4,6,9,12,13,14,27,30,33,34,35,36,37],third:[0,3,6,13,21,28,30,34,35,36],thirti:[7,34],thorughout:30,those:[0,3,5,6,8,9,10,11,21,23,24,25,26,30,31,33,37],though:[1,2,3,4,13,23,27,35,36],thought:[6,14,24,25,27,33],thousand:[0,1,24,31,35,36,37],three:[0,1,3,5,6,8,9,12,15,23,24,26,27,28,30,31,32,33,34,36],threshold:[1,3,9,10,11,12,13,35,36,37],through:[0,1,2,3,4,5,6,8,11,12,13,14,22,23,27,30,31,32,33,34,35,36],throughout:[0,4,5,14,22,23,27,30],thu:[0,1,2,5,6,7,8,10,11,12,13,21,24,28,30,31,32,33,34,35,36,37],thumb:[0,6,24,30,31],thursdai:[28,31],tibshirani:[6,18,24,26,29,30,33],tick:6,tick_param:6,ticker:[6,13,24,27,34,35],tif:[6,24],tight_layout:[1,7,34],tightli:11,tild:[0,5,6,7,11,15,16,17,18,19,24,27,30,31,32,33,37],till:[0,4,7,8,9,10,12,23,30,31,32,34,37],time:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,21,22,23,24,25,27,30,31,32,33,34,37],timeit:4,timer:4,tini:[1,37],tip:3,titl:[0,1,2,3,4,6,7,8,9,10,13,21,24,27,30,33,34,35,36,37],tmp:[13,35,36],tn:[2,3,7],to_categor:[1,3,4],to_categorical_numpi:1,to_numer:[0,6,30,33],todai:3,togeth:[0,3,6,8,11,13,21,22,30,35,36],toi:[14,35,36],told:[13,35],toler:[2,6,14],tolist:4,tomographi:[12,36,37],too:[0,2,4,5,6,9,11,13,15,27,29,30,31,33,34,35,36],took:[8,30],tool:[0,1,3,6,13,22,31,33,35,36,37],toolbox:8,top:[0,3,5,6,9,10,18,22,30,32,33],topic:[0,5,6,7,8,22,24,25,31,32,34],topograph:24,topolog:[1,3,12,36,37],toposort:2,torkjellsdatt:[28,30],toss:[10,27],total:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,23,25,27,28,30,31,33,34,35,37],total_loss:4,totalclustervari:14,totalscatt:14,toward:[1,2,7,12,13,24,34,35],towardsdatasci:[35,36],town:0,tp:[4,7],tpng:9,tpu:[13,21,22,30,35,36],tqdm:6,tr:31,trace:2,trace_stack:2,traceback:[0,2,3,4,6,7,10,13,14,24,30,32,34],tracer:2,track:[3,13,14,23,31,34,35,36],tract:0,tractabl:[0,30,31],trade:[5,9,19,32,33],tradeoff:[0,5,19,24,30,31,32,34],tradit:[0,1,4,6,30,33],train:[2,3,5,6,8,9,10,11,12,13,17,19,21,24,25,32,33,34,35,36],train_accuraci:[0,1,3,30],train_dataset:4,train_end:[0,1,31],train_error:6,train_imag:[3,4],train_ind:[6,33,34],train_label:[3,4],train_pr:1,train_siz:[0,1,3,31],train_step:4,train_test_split:[0,1,3,5,6,7,9,10,11,30,31,32,33,34],train_test_split_numpi:[0,1,31],trainable_vari:4,trained_model:[6,31,32],trainerror:[0,31],traini:4,training_checkpoint:4,training_dataset:4,training_gradi:[13,21,35,36],training_gradient_fun:[35,36],training_loss:[35,36],trainingerror:[6,33],trainpredict:4,trainscor:4,trainx:4,trait:[0,30],trajectori:4,trajectory_i:[21,36],trajectory_x:[21,36],transfer:9,transform:[0,5,6,7,8,9,10,11,12,13,21,22,23,30,31,32,33,34,35,36,37],transit:[6,12,36,37],translat:[1,4,6,10,30,31,32],transpos:[1,5,11,23,31,32],travers:[0,5],treat:[0,1,3,6,12,13,27,30,31,32,33,34,35,36,37],tree:[0,1,6,22,24,30,37],tree_clf:[9,10],tree_clf_:9,tree_clf_sr:9,tree_reg1:9,tree_reg2:9,tree_reg:9,trend:27,treue:7,trevor:[18,24,29],tri:[2,3,4,9,13,34,35],triain:0,trial:[0,2,4,6,13,27,30,33,34,35],triangl:[13,34,35],triangular:23,trick:[3,4,8,11,13,21,27,35,36],trickier:27,tridiagon:23,trigger:[0,7,34],trillion:22,trivial:[0,1,5,11,27,30,32],troubl:[0,8,12,31,37],truck:3,true_beta:[6,31,32],true_divid:1,true_fun:[6,33],truncat:[21,36,37],trust:9,tucker:8,tuesdai:[28,30,33,34,35],tumor:[7,9,25,34],tumour:[7,34],tunabl:[1,21,25],tune:[4,9,13,21,23,25,30,34,35,36],tup:[],tupl:2,turn:[0,1,5,6,7,8,9,10,11,12,13,19,23,24,27,30,31,33,34,35,36,37],tutori:[1,4],tv:2,tveito:2,tvw1zdmznwm:36,tweak:[1,4,10,27,37],twice:[13,34,35],twist:11,two:[0,1,2,4,5,6,7,9,10,11,12,13,15,16,23,26,27,29,30,32,33,35,36],tx:[13,34,35,36,37],tx_1:[13,34,35],txt:4,ty:[13,34,35],type:[0,1,3,6,8,10,13,16,23,24,27,31,32,33,34,35],typeerror:[2,6,13],typic:[0,1,2,3,4,5,7,9,10,12,13,21,25,27,30,31,32,33,34,35,36,37],typo:[24,25],u:[0,2,5,6,8,10,11,12,17,23,30,31,32,36,37],u_:23,u_i:[12,36],u_m:10,ua:[0,30],ubuntu:[0,15,22,24,30],uci:[0,25],ufunc:2,uio:[24,25,28,29],un:14,unabl:9,unari:[23,30],unary_f:2,unary_oper:2,unary_to_nari:2,unbalanc:[6,9,33,34],unbias:[0,5,6,30,32,33],unbroadcast:2,unbroadcast_f:2,uncent:[6,32],uncertainti:[0,5,30,32,33],uncertitud:27,unchang:[1,3,37],uncorrel:[10,27],undefin:[5,31],under:[0,1,5,6,10,13,15,16,22,24,25,30,31,32,33,34,35],underdetermin:[0,30],underfit:[1,6,33,37],underflowproblem:[5,32,33],undergo:[5,32,33],undergradu:[26,28],underli:[0,1,9,13,27,30,35,36,37],underset:[4,14],understand:[0,1,3,5,6,10,13,14,21,22,30,31,32,34,35,36,37],understood:[8,13,35,36],undesir:8,undetermin:[5,8,32,33],undo:4,unexpect:[6,13,33],unexpected:27,unfair:[6,31,32],unfortun:[1,8,9,10,37],unicode_liter:[8,9],uniform:[0,1,5,6,11,13,15,16,24,27,30,31,34,35],uniformli:[13,27,34,35,36],unifrompdf:27,unimport:[13,34,35],union:[5,6,32,33,34],uniqu:[0,2,6,13,14,23,30,33,34,35],unique_cluster_label:14,unit:[0,1,3,4,5,10,12,27,30,31,32,36,37],unitari:[5,6,23,31],unitarili:[23,30],uniti:27,univari:27,univers:[0,1,2,13,15,22,24,25,26,28,30,31,32,33,34,35,36],unix:1,unknow:[0,23,30],unknown:[0,1,3,4,5,6,8,10,13,16,21,23,30,31,32,33,35,36,37],unknowwn:12,unlabel:[1,37],unless:[0,3,6,11,13,24,25,30,33,34,35,37],unlik:[1,3,8,13,34,35,36,37],unnecessarili:9,unord:3,unravel:1,unrol:[3,11],unseen:[0,7,9,34],unstabl:[1,37],unsupervis:[0,1,4,12,22,30,36,37],unsymmetr:[23,30],until:[1,2,4,9,12,13,14,34,35,36,37],untouch:0,unusu:[12,36,37],up:[1,3,4,5,6,8,10,11,13,14,16,18,22,23,24,25,27,28,32,35],updat:[1,2,10,12,13,14,21,35,36],uploa:30,upload:[22,24,25,29],upon:[0,1,6,7,11,23,24,37],upper:[0,8,9,16,23,31],uppercas:[23,30],upsampl:4,upscal:4,uptad:37,url:[0,7,30,31,34,36],us:[4,5,6,8,9,10,11,12,14,15,16,17,18,19,23,26,27,29,32,33],usa:[30,36],usag:[0,8,22,30,31,36,37],usd10000:0,usd:0,use_bia:4,usecol:[0,30],useless:1,user:[0,1,2,3,4,6,7,8,9,11,14,15,21,22,23,24,30,31,32,34,36],usernam:[24,25],userwarn:[6,21,36],usetex:27,usg:[6,24],usr:27,usual:[0,3,4,7,12,13,14,30,34,35,36,37],ut:[5,32],utf:[0,7,34],util:[1,3,4,6,7,10,14,25,30,33,34,37],ux:23,v0:27,v1:27,v2:27,v8xr:[36,37],v:[2,4,5,6,11,13,17,21,22,31,32,35,36,37],v_0:11,va:1,vahid:30,val:[13,35,36],val_accuraci:3,val_loss:4,vale:2,valid:[0,1,4,7,9,10,13,21,22,25,27,30,31,35,36,37],validation_data:3,validation_split:4,valu:[0,1,2,3,4,6,7,8,9,10,12,13,14,15,16,19,21,22,23,24,30,35,36,37],valuat:9,valueerror:2,valy:4,van:[0,18,24,30,31,32,33],vandenbergh:[8,13,34,35],vandermond:[0,30],vanilla:[0,6,11,14,31,32],vanish:[1,4,13,27,34,35],var_x:27,varabl:8,varepsilon:[5,6,18,24,32,33],varepsilon_:[5,6,32,33],varepsilon_i:[5,6,32,33],vari:[0,1,3,5,6,10,15,16,30,33,37],variabl:[0,1,2,5,6,7,8,10,11,12,13,14,21,23,30,31,32,33,36,37],varianc:[0,1,5,7,9,10,11,13,14,18,19,21,22,23,27,30,31,34,35,36,37],variance_i:[5,11,31],variance_x:[5,11,31],variant:[0,1,6,8,12,13,30,31,34,35,36,37],variat:[3,4,11,30],varieti:[0,3,12,15,22,24,30,36,37],variou:[1,3,5,6,7,8,9,11,12,13,16,18,21,22,23,24,27,31,32,35,36,37],varydimens:4,vastli:3,vaue:1,vault:0,vdot:[2,13,34,35],ve:[24,25],vec:[6,33],vector:[0,1,2,3,4,5,6,7,9,10,11,13,14,16,17,21,22,32,33,34,35,37],vector_mean:14,ventur:[0,8,15,22,30],verbos:[1,3,4],veri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,24,25,27,29,30,31,32,33,34,35,36,37],verifi:[3,11,23,30],versatil:[8,30],versicolor:[8,9],version:[0,3,10,13,14,15,22,23,24,25,27,30,35],versu:[1,37],vert:[0,1,5,6,7,8,9,11,13,17,30,31,32,33,34,35,37],vert_1:[5,6,31,32,33],vert_2:[5,6,11,17,31,32,33],via:[0,5,6,7,8,9,10,11,12,15,19,22,23,24,26,27,28,30,31,32,33,34,36,37],vidal:11,video:[0,1,12,22,26,28,30,31,32,33,37],view:[1,3,5,6,12,13,21,27,29,30,32,33,35,36],violat:8,virginica:9,viridi:[0,1,2,3,30],virtual:[1,37],viscos:[13,35,36],viscou:[13,35,36],visibledeprecationwarn:2,vision:[0,3],visual:[0,3,11,12,15,22,30,31,36,37],visualis:1,viz:[6,8,27],vjp:2,vjp_0:2,vjp_0_fun:2,vjp_1:2,vjp_1_fun:2,vjp_argnum:2,vjpfun:[],vjpmaker:[],vjpnode:2,vjps_dict:2,vmap:[13,35],vmax:[1,6],vmh0zpt0tli:36,vmin:[1,6],voic:3,volum:[0,3,30],von:37,vote:10,voting_clf:10,votingclassifi:10,votingsimpl:10,vs:[0,4,6,35],vspace:2,vstack:[5,11,23,27,30,31],vt:[5,31,32],w1:8,w2:[8,11],w3:8,w:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,23,27,30,31,33,34,35,36,37],w_0:37,w_1:[8,23,37],w_1a_0:37,w_1x:37,w_1x_1:8,w_1x_:8,w_2:[8,23,37],w_2a_1:37,w_2x_2:8,w_2x_:8,w_3:23,w_4:23,w_:[1,12,36,37],w_hidden:2,w_i:[1,2,10,37],w_ix_i:[12,36,37],w_j:23,w_m:23,w_output:2,w_px_:8,w_px_p:8,wa:[0,1,3,4,5,6,7,10,11,12,14,17,23,24,30,31,32,33,34,36,37],wai:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,17,23,25,27,30,31,32,34,35],walk:9,walker:27,wang:[0,30],want:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,22,24,25,27,30,31,32,33,34,35,36,37],warn:[1,4,8],warrant:[6,33,34],wast:[3,35,36],watch:[22,36,37],wave:3,wavelet:8,we:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,22,23,24,25,26,27,28,29,31,32,33,34],weak:[9,10,14],weather:[1,12,36,37],web:[22,26,28,30],weblink:25,webpag:30,websit:[6,23,24,26,30],wedg:[8,27,37],wednesdai:[28,30,33,34,35],wee:11,week:[0,5,6,7,24,25,26,28],weekli:[16,22,24,28,29,30,36],weierstrass:37,weight:[0,1,2,3,6,7,9,10,12,13,24,25,27,34,35,36,37],weigth:2,welchlab:[36,37],welcom:[8,22],well:[0,1,2,3,4,5,6,7,8,9,10,12,13,15,16,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],went:8,were:[0,1,3,4,5,6,7,8,10,11,12,14,27,30,31,33,34,36,37],wessel:[0,18,24,30,31,32,33],what:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,19,22,23,24,25,27,34,35,36,37],whatev:3,when:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,21,23,24,25,27,30,31,32,33,34,37],whenev:[13,21,27,35,36,37],where:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,27,28,30,31,32,33,34,35,36,37],wherea:[6,27,33],wherefrom:24,wherein:[1,12,36,37],whether:[0,3,5,7,9,24,25,27,30,32,34],which:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,22,23,24,25,26,27,28,30,31,32,33,34],whichev:[1,3],white:9,whiteboard:[32,33,34,35,36,37],who:[0,26],whole:[1,3,4,5,9,11,13,32,33,35,36],whose:[0,6,10,27,31,33],whow:[11,31],why:[0,1,3,6,13,21,24,32,34,35],wide:[0,1,3,6,7,12,15,22,23,24,30,33,34,36,37],widehat:[6,33],width:[0,3,8,9,30],wieringen:[0,18,24,30,31,32,33],win:10,wind:9,wing:[28,30],winther:2,wiothout:[6,31],wiscons:[7,34],wisconsin:[10,25],wisdom:[6,32],wise:[0,1,5,12,13,31,35,36],wish:[0,2,5,7,8,11,13,14,23,24,25,30,31,34,35,37],with_std:[0,31],wither:6,within:[0,2,3,4,7,9,12,13,14,27,29,30,34,35],withinclust:14,without:[0,1,5,6,8,9,11,12,13,21,25,30,31,32,33,35,36,37],wo5dmep_bbi:[36,37],won:[0,30,37],wonder:8,word:[0,1,3,4,5,6,7,14,27,30,31,32,33],work:[0,1,4,6,7,8,9,13,15,21,22,24,25,26,27,28,30,31,33,34,35,36,37],workshop:30,world:[0,8,31],worldwid:[0,30],wors:[0,1,3,4,6,30,33,37],worst:9,worth:9,worthi:[24,25],would:[0,1,3,5,6,7,8,9,10,11,12,13,23,24,25,27,30,31,32,33,34,35,36,37],wrap:[6,23,30],wrap_util:2,write:[0,1,2,3,5,6,7,8,12,13,15,16,17,20,21,23,30,31,33,34,35,36,37],written:[0,2,3,5,11,12,13,16,22,23,24,25,27,30,31,32,33,34,35,36,37],wrong:[1,8,37],wrongli:10,wrote:[5,11,31],wrt:[10,13,21,35,36,37],wth:[10,13,21,35,36],wurstemberg:37,www:[22,23,24,25,29,30,32,36,37],wx_1:8,x0:8,x1:[4,8,9,10,13,35,36],x1_exampl:8,x1d:8,x2:[8,9,10,13,35,36],x2d:[8,11],x2d_train:11,x2dsl:11,x3:[8,9],x4:9,x:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,27,30,33,34,35,36,37],x_0:[0,5,11,23,30,31,32,33,37],x_1:[0,2,5,6,7,8,9,10,11,13,23,27,30,31,32,33,34,35,36,37],x_2:[0,2,5,6,7,8,9,10,11,13,23,27,30,31,33,34,35,36,37],x_3:[8,23,27,37],x_4:[23,37],x_5:37,x_:[0,2,3,5,6,8,10,11,13,14,18,23,24,27,30,31,32,33,34,35,37],x_center:11,x_data:1,x_data_ful:1,x_hidden:2,x_i:[0,1,2,5,6,7,8,9,10,11,12,13,14,17,23,27,30,31,32,33,34,35,36,37],x_input:2,x_ix_:[0,30],x_iy_i:8,x_j:[0,2,8,9,12,16,27,31,36,37],x_jy_j:8,x_k:[12,14,23,27,31,36],x_l:[27,37],x_m:[6,12,23,27,33,36],x_n:[0,2,3,6,8,11,12,13,23,27,30,33,34,35,36,37],x_new:[9,10],x_offset:[6,31,32],x_output:2,x_p:[3,7,9,34],x_poli:9,x_poly10:9,x_pred:4,x_prev:2,x_reduc:11,x_scale:8,x_small:[13,35],x_test:[0,1,3,5,6,7,9,10,11,30,31,32,33,34],x_test_own:6,x_test_scal:[0,6,7,9,10,11,31,32],x_tot:4,x_train:[0,1,3,4,5,6,7,9,10,11,30,31,32,33,34],x_train_mean:[6,31,32],x_train_own:6,x_train_scal:[0,6,7,9,10,11,31,32],x_val:1,xarrai:[22,30],xavier:[1,37],xbkjd4ccgq:30,xbnew:[13,34,35],xcode:[0,15,22,24,30],xdclassiffierconfus:10,xdclassiffierroc:10,xg_clf:10,xgb:10,xgbclassifi:10,xgboost:9,xgboot:10,xgbregressor:10,xgparam:10,xgtree:10,xi:[8,13,21,35,36],xi_1:8,xi_:8,xi_i:8,xinv:[32,36,37],xk:8,xla:[13,21,22,30,35,36],xlabel:[0,1,2,3,4,5,6,7,8,9,10,13,21,24,27,30,32,33,34,35,36],xlim:[6,10,33],xm:9,xmesh:[13,35],xnew:[0,13,21,30,34,35,36],xp:27,xpanda:[0,31],xpd:[5,11,31],xplot:0,xs:9,xscale:[0,31],xsr:9,xt_x:[13,21,34,35,36],xtest:[6,33,34],xtick:[3,6,8,9,33],xtrain:[6,33,34],xu:[0,30],xx:[0,23,30],xy:[0,6,8,23,24,30],xytext:8,xz:[23,30],y1:4,y2:4,y3:4,y:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,27,30,31,32,33,34,35,36,37],y_0:[0,5,11,23,30,31,32,33],y_1:[0,5,8,9,11,13,23,30,31,32,33,34,35],y_1y_1:8,y_1y_1k:8,y_1y_2:8,y_1y_2k:8,y_1y_n:8,y_1y_nk:8,y_2:[0,5,8,9,11,23,30,31],y_2y_1:8,y_2y_1k:8,y_2y_2:8,y_2y_2k:8,y_3:[0,9,23],y_4:23,y_:[0,1,5,6,10,11,23,30,31,32,33],y_data:[0,1,5,6,30,31,32,34],y_data_ful:1,y_decis:8,y_fit:[0,31],y_i:[0,1,5,6,7,8,9,10,11,12,13,15,16,17,18,19,23,24,25,30,31,32,33,34,35,36,37],y_if_:10,y_ix_:[0,30],y_ix_i:[7,8,13,31,34,35],y_iy_jk:8,y_j:[6,8,12,19,24,33,36,37],y_k:[12,36],y_m:23,y_model:[0,4,5,6,30,31,32,34],y_n:[8,13,34,35],y_ny_1:8,y_ny_1k:8,y_ny_2:8,y_ny_2k:8,y_ny_n:8,y_ny_nk:8,y_offset:[6,31,32],y_plot:9,y_pred1:9,y_pred2:9,y_pred:[0,1,4,6,7,8,9,10,31,32,33,34],y_pred_rf:10,y_pred_tre:10,y_predict:36,y_proba:[7,10,34],y_scaler:[6,32],y_test:[0,1,3,4,5,6,7,9,10,11,30,31,32,33,34],y_test_onehot:1,y_test_predict:0,y_tot:4,y_train:[0,1,3,4,5,6,7,9,10,11,30,31,32,33,34],y_train_mean:[6,31,32],y_train_onehot:1,y_train_predict:0,y_train_scal:[6,32],y_val:1,yand:[36,37],ye:[3,6,7,33,34],year:[0,22,30],yet:[0,1,6,8,11,13,30,34,35,37],yi:[13,21,35,36],yield:[0,2,5,6,7,8,10,12,13,14,23,27,30,32,33,34,35,36,37],yk:8,ylabel:[0,1,2,3,4,5,6,7,8,9,10,13,21,24,27,30,32,33,34,35,36],ylim:[3,6,33],ym:9,ymesh:[13,35],yn:0,yo:[8,9,10],yor:[36,37],yoshua:[1,29,37],you:[0,1,2,3,4,5,6,8,9,10,11,13,15,16,17,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37],young:0,your:[1,2,4,5,6,8,11,13,17,19,20,21,22,23,24,32,33,34,35,36,37],yourself:[11,13,30,35],youtu:[34,36],youtub:[22,36,37],ypred:[6,33,34],ypredict2:[13,21,34,35,36],ypredict:[0,13,21,30,31,34,35,36],ypredictlasso:[5,32],ypredictol:[0,5,32],ypredictown:[6,31,32],ypredictownridg:[6,32],ypredictridg:[0,5,6,32,34],ypredictskl:[6,31,32],yridg:30,ys:9,ytest:[6,33,34],ytick:[3,6,8,9,33],ytild:[0,6,30,31,33],ytildelasso:[5,32],ytildenp:[0,30,31],ytildeol:[0,5,32],ytildeownridg:[6,32],ytilderidg:[5,6,32],ytrain:[6,33,34],yuxi:30,yx:[23,30],yxor:[36,37],yy:[23,30],yz:[23,30],z:[0,1,2,3,4,5,6,7,8,9,11,12,13,23,24,27,30,31,33,34,35,36,37],z_0:[23,30,37],z_1:[23,30,37],z_2:[23,30,37],z_:[1,2,12,23,30,37],z_c:1,z_h:1,z_hidden:2,z_i:[1,12,36],z_j:[1,12],z_k:[12,31,37],z_m:1,z_mod:9,z_o:1,z_output:2,zaman:27,zaxi:[6,24],zero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,21,23,24,27,30,31,32,33,34,35,36,37],zeros_lik:4,zeroth:31,zfill:4,zip:[2,4,6],zm_h:[0,30],zn:0,zone:0,zoom:30,zx:[23,30],zy:[23,30],zz:[23,30]},titles:["3. Linear Regression","14. Building a Feed Forward Neural Network","15. Solving Differential Equations with Deep Learning","16. Convolutional Neural Networks","17. Recurrent neural networks: Overarching view","4. Ridge and Lasso Regression","5. Resampling Methods","6. Logistic Regression","8. Support Vector Machines, overarching aims","9. Decision trees, overarching aims","10. Ensemble Methods: From a Single Tree to Many Trees and Extreme Boosting, Meet the Jungle of Methods","11. Basic ideas of the Principal Component Analysis (PCA)","13. Neural networks","7. Optimization, the central part of any Machine Learning algortithm","12. Clustering and Unsupervised Learning","Exercises week 34","Exercises week 35","Exercises week 36","Exercises week 37","Exercises week 38","Exercises week 39","Exercises week 41","Applied Data Analysis and Machine Learning","2. Linear Algebra, Handling of Arrays and more Python Features","Project 1 on Machine Learning, deadline October 7 (midnight), 2024","Project 2 on Machine Learning, deadline November 4 (Midnight)","Teaching schedule with links to material","1. Elements of Probability Theory and Statistical Data Analysis","Teachers and Grading","Textbooks","Week 34: Introduction to the course, Logistics and Practicalities","Week 35: From Ordinary Linear Regression to Ridge and Lasso Regression","Week 36: Linear Regression and Statistical interpretations","Week 37: Statistical interpretations and Resampling Methods","Week 38: Logistic Regression and Optimization","Week 39: Optimization and Gradient Methods","Week 40: Gradient descent methods (continued) and start Neural networks","Week 41 Neural networks and constructing a neural network code"],titleterms:{"1":[0,15,16,17,18,24,30,31,37],"11":37,"16":34,"2":[0,15,16,17,18,25,30,31,32,37],"2023":28,"2024":[24,35,36,37],"21":[],"23":35,"26":31,"27":35,"3":[0,15,16,30,31,37],"30":36,"34":[15,30],"35":[16,31],"36":[17,32],"37":[18,33],"38":[19,34],"39":[20,21,35],"4":[0,25,31],"40":[21,36],"41":[21,37],"5":0,"7":[24,37],"9":33,"case":[8,10,27,31,32,34,35],"class":[34,37],"do":[1,32,33,35,36,37],"final":[12,21,25,31,32,35,36,37],"float":37,"function":[0,1,6,7,8,10,11,12,13,21,24,25,27,30,31,32,33,34,35,36,37],"import":[5,21,23,30,31,32,36,37],"new":[4,32,33,37],A:[0,1,4,8,9,21,30,32,33,34,36,37],AND:[36,37],And:[21,30,31,32,34,35,36],But:[21,35,36],For:31,In:[28,37],Is:37,Ising:6,OR:[36,37],The:[0,1,2,3,5,6,7,8,9,11,12,17,22,30,31,32,33,34,35,36,37],To:[30,31],With:[4,32],about:[30,31],abov:[32,37],activ:[1,12,25,32,36,37],ad:[0,6,17,24,30,31,36,37],adaboost:10,adagrad:[13,21,35,36],adam:[13,21,35,36],adapt:[10,21,35,36],adjust:1,advanc:[21,36],adversari:4,again:[3,9,34],ai:[24,30],aim:[8,9,17,18,19,20,21,30],aka:[30,31],al:[21,36],algebra:[23,30],algorithm:[9,10,11,12,21,25,31,35,36,37],algortithm:[13,34,35],all:[8,37],an:[0,4,10,30,37],analys:[5,31],analysi:[0,5,6,11,22,24,25,27,30,31,32,33,37],analyt:[0,16,17,21],analyz:37,ani:[13,34,35],anoth:[9,32,33],appli:22,approach:[0,8,14,30,33,35,36],approxim:[12,37],architectur:1,argument:[35,36],arrai:[23,30],artifici:[36,37],assist:28,assumpt:[32,33],august:31,autocorrel:27,autograd:[2,13,21,35,36],automat:[13,21,35,36,37],avoid:[],b:[17,24,25,35],back:[1,11,12,37],background:[22,24,25,33],bag:10,base:[13,21,33,35,36],basic:[0,5,7,9,10,11,23,31,32,33,34,37],batch:[1,35,36,37],bay:[5,32,33],befor:11,bengio:37,beta:[32,33],better:[8,36,37],bia:[6,24,33],bias:37,binari:1,bind:30,bird:10,boldsymbol:[31,32,33],book:37,boost:10,bootstrap:[6,10,33],boston:0,breast:1,brief:[30,33,34,35],bring:[12,37],build:[1,3,9],c:[24,25,30],calcul:31,can:[21,30,33,35,36,37],cancer:[1,7,9,11,34],cart:9,center:31,central:[13,22,27,33,34,35],chain:[12,37],challeng:34,chang:10,channel:30,chi:[0,30],choic:37,choos:1,cifar01:3,classic:11,classif:[1,9,10,25,34],classifi:[8,34],clip:[1,37],cluster:14,cnn:3,code:[0,1,2,5,9,11,12,13,14,21,25,30,31,32,33,34,35,36,37],collect:[1,3],come:34,commun:30,compact:[34,37],compar:[2,10],comparison:32,compet:[21,35,36],complet:[31,37],complex:[0,6,24,31],complic:[6,35,36,37],compon:11,comput:[9,35,36],computation:33,computerlab:30,con:9,concept:27,condit:[32,33,34,35],confid:33,conjug:[13,35],consider:37,construct:37,continu:36,contn:30,convex:[8,13,34,35],convolut:[3,12,36,37],correctli:[32,33],correl:[11,31,34],correspond:[34,35],cost:[1,10,31,32,33,34,35,37],count:37,cours:[22,29,30],covari:[5,11,27,31],cover:30,critic:25,cross:[6,24,33,34],cython:30,d:[24,25],data:[0,1,3,6,7,9,11,15,16,22,24,27,30,31,32,34,37],dataset:[1,3],deadlin:[24,25,30],decai:[2,35,36],decis:[9,10],decomposit:[5,11,17,23,31],deep:[1,2,30,34,37],defin:[1,30,37],definit:37,degre:[0,31],deliveri:[24,25],delta:33,dens:[0,30],deriv:[5,12,31,32,33,34,35,37],descent:[2,10,13,21,25,34,35,36],descript:24,design:31,detail:[3,30],develop:1,diagon:11,differ:[8,25,35,36],different:21,differenti:[2,13,35,36,37],diffus:2,dimension:[2,3,8,24,31],directli:[35,36],disadvantag:9,discret:27,discuss:34,distribut:[5,27,32,33],distrubut:33,doe:[31,32,36,37],domain:27,dot:35,down:[1,37],dropout:[1,37],e:[24,25],each:34,economi:31,electron:[24,25],element:[0,27,30,35,36],elimin:23,elu:37,energi:30,ensembl:10,entri:37,entropi:[9,34],environ:[0,15,30],equat:[0,2,12,30,31,32,34,35,37],error:[0,10,30,31,33],essenti:30,estim:[32,33],et:[21,36],etc:30,euler:2,evalu:[1,25,37],exampl:[0,1,2,3,4,6,7,8,9,10,21,30,31,32,33,34,35,36,37],exercis:[0,6,15,16,17,18,19,20,21,30,31,37],expect:[18,27,32,33],expens:33,experi:27,explicit:37,explod:37,explor:[0,15,16,30],exponenti:2,express:[17,18,31,34,35,37],extend:[34,35,37],extrapol:4,extrem:[10,30],ey:10,f:[24,25],fall:28,famili:[1,30,31,37],famou:23,fantast:31,featur:[9,23,31],feed:[1,12,36,37],find:[33,35],fine:[1,37],first:[4,12,25,30,31,32,34,35,37],fit:[0,10,30,32],fix:31,fold:[33,34],forc:3,forest:10,format:[24,25,30],forward:[1,2,12,36,37],fourier:3,frank:[6,24,31],freedom:[0,31],frequent:31,frequentist:[0,30],fridai:[],from:[5,10,12,21,25,31,32,33,34,35,36,37],full:2,funtion:37,further:[3,5,31],g:24,gan:4,gate:[36,37],gaussian:23,gd:[13,21,35,36],gener:[4,9,30,37],geometr:[11,34,35],get:[21,36,37],gini:9,glorot:37,good:[0,30],goodfellow:[21,36],grade:[28,30],gradient:[1,2,10,13,21,25,34,35,36,37],grid:34,group:34,growth:2,ha:22,hand:37,handl:[23,30,31],happen:[32,33],hessian:[31,34,35],hidden:[2,37],histogram:33,homework:[34,35],homogen:37,hous:0,how:34,hyperbol:[36,37],hyperparamet:[1,37],hyperplan:8,i:1,id3:9,idea:11,ideal:[34,35],ident:[32,33],identifi:33,ii:30,iid:[32,33],illustr:[32,36,37],implement:[1,36],implic:[5,31],improv:[1,35],includ:[13,21,34,35,36,37],increment:11,independ:[32,33],index:9,inform:28,ingredi:37,input:[2,37],insight:37,instal:[22,24,30],instructor:28,intercept:31,intermedi:37,interpret:[5,11,30,31,32,33,34,35],interv:33,introduc:[11,13,21,31,35,36],introduct:[0,6,22,23,24,25,30,36,37],invers:[5,23,32],invert:31,iter:[10,35],its:31,jacobian:31,jax:[13,21,35,36],job:[36,37],julia:30,jungl:10,k:[33,34,37],kera:[1,3],kernel:[8,11],l:37,lab:[33,34,35,36],lagrangian:8,lambda:34,lasso:[5,6,24,31,32,33,34,36],last:[31,34,36,37],later:[5,31],layer:[1,2,3,12,37],layout:37,learn:[0,1,2,11,13,14,15,16,21,22,24,25,30,31,32,33,34,35,36,37],least:[5,6,18,24,30,31,32],lectur:[30,31,32,33,34,35,36,37],level:10,librari:[22,30],likelihood:[7,32,33,34],limit:[1,13,27,33,34,35,36,37],linear:[0,8,13,23,25,30,31,32,34],link:[5,11,26,29,31,32,33],list:37,literatur:[24,25],logist:[7,25,30,34,35,36,37],loop:[35,36],loss:[31,34,35],lu:23,machin:[0,8,13,22,24,25,30,34,35],made:[32,33],main:[27,30],make:[0,9,10,15,16,30,31],mani:[10,12],manipul:31,margin:[32,33],mass:30,materi:[24,26,30,31,32,33,34,37],math:[5,31],mathemat:[3,5,8,31,35,36,37],matric:[5,23,30,32],matrix:[1,5,11,12,23,30,31,32,34,35,36],matter:[0,30],max:31,maximum:[32,33,34],mean:[0,31,32,34],measur:34,meet:[5,10,27,30,31],mercer:8,method:[6,9,10,13,21,24,30,33,34,35,36],midnight:[24,25],min:31,mini:[35,36],minibatch:[21,35,36],minim:[30,34],ml:30,mle:[32,33],mlp:12,mnist:[3,4],mode:37,model:[0,1,4,6,12,30,36,37],moment:[35,36],momentum:[13,21,35,36],mondai:[31,32,33,34,35,36,37],moon:[8,9],more:[3,6,21,23,24,30,31,32,33,34,35,36,37],multi:[36,37],multilay:[12,36,37],multipl:[1,3],multipli:8,multivari:37,need:[24,30],network:[1,2,3,4,7,12,25,30,34,36,37],neural:[1,2,3,4,7,12,25,30,36,37],neuron:[36,37],newton:[21,34,35,36],nn:37,node:37,noen:21,non:8,none:[35,36],normal:[0,1,33,37],notat:[12,36],note:[21,24,31,32,36],novemb:25,now:[1,9,13,21,32,33,35,36],nuclear:[0,30],nueral:34,numba:30,number:[0,2,21,27,31,35,36,37],numer:[2,24,25,27],numpi:[21,23,30,35,36],object:3,observ:37,obtain:11,octob:[24,37],od:2,off:[6,24],ol:[5,6,21,24,32,33,35,36],one:[2,12,34,35,37],ones:[36,37],oper:[23,37],optim:[1,8,13,22,30,31,34,35,36,37],order:[13,21,35,36],ordinari:[5,6,18,24,30,31,32],organ:[0,30],orient:[],oslo:29,other:[4,9,11,12,23,24,30,31,34,36,37],ouput:37,our:[0,4,5,11,13,30,31,34,35,37],outcom:[22,30],output:[2,37],over:37,overarch:[0,4,8,9,17,18,19,20,21,30,31,37],overview:[10,30,35,36],own:[0,10,11,15,16,25,30,31],packag:[23,30],panda:[30,31],paper:[24,37],parallel:37,paramet:[30,31,34,35,36,37],part:[13,22,24,25,31,34,35,37],partial:2,pass:1,pca:11,pdf:27,pencil:24,percepetron:37,perceptron:[12,36,37],perform:[1,9],period:3,perspect:[1,37],plan:[31,32,33,34,35,36,37],plot:[33,34],point:[4,37],poisson:2,polynomi:[3,32],popul:2,popular:30,practic:[13,21,28,30,35,36],pre:[1,3],preambl:24,predict:4,predictor:34,preprocess:31,prerequisit:[3,22,30],princip:11,principl:3,pro:9,probabl:[5,27,32,33],problem:[1,2,13,21,30,31,32,34,35,36,37],procedur:[9,30],process:[1,3],product:35,program:[2,13,24,25,34,35,37],project:[6,24,25,30,34],prop:[13,35,36],propag:[1,12,37],properti:[5,27,31,34],python:[0,9,15,22,23,30],quick:8,r:30,random:[10,11,27,34],raphson:[34,35],rate:[21,35,36],read:[9,30,31,33,34,36,37],real:[6,24,30,37],recommend:[30,31,37],rectangular:32,recurr:[4,12,36,37],recurs:[35,36],reduc:[0,31,37],reduct:3,refer:24,reformul:2,regress:[0,5,6,7,9,10,13,17,18,24,25,30,31,32,33,34,35,36,37],regular:[1,34],relat:31,relev:[29,31,34,36,37],relu:[1,37],remark:3,remind:[6,8,30,34,35,37],repeat:31,replac:[13,35,36],report:[24,25],repositori:33,repres:[],requir:[2,22],resampl:[6,24,33],rescal:[6,32],residu:31,resourc:2,result:[31,32,37],revers:37,revisit:[13,34,35],rewrit:[30,31,33],rewritten:34,ridg:[0,5,6,17,18,24,31,32,33,34,35,36],rm:[13,35,36],rmsprop:[21,35,36],root:37,rule:[12,37],s:[8,10,21,33,34,35,36],same:[13,21,33,35,36],sampl:11,scale:31,schedul:[26,30],schemat:9,scheme:2,scienc:30,scikit:[0,1,11,15,16,30,31,32,33,34,35],search:34,second:[13,21,35,36],select:34,semest:28,sensit:[34,35],septemb:[32,33,34,35,36],seriou:37,session:[31,32,33,34,35,36,37],set:[0,2,3,9,12,15,30,31,34,37],sgd:[13,35,36],should:[1,37],sigmoid:37,similar:[13,21,35,36],simpl:[0,4,9,13,30,31,32,34,35,36,37],simpler:37,singl:[10,36,37],singular:[5,11,17,31],size:31,slightli:[35,36],smarter:37,soft:8,softmax:1,softwar:[24,30],solv:[2,32,34,35],solver:13,some:[13,23,31,34,35,37],specifi:2,split:[0,15,16,30,31],squar:[0,5,6,10,18,24,30,31,32],standard:[13,31,33,35],start:[21,36],state:[0,30],statist:[5,6,22,27,30,32,33],steepest:[10,13,34,35],step:[25,33,34,35,36],still:31,stochast:[13,21,25,27,35,36],stop:[35,36],strongli:30,studi:34,subtract:31,suggest:[30,34,36],sum:[33,37],summari:[28,30,36],superposit:3,supervis:[1,37],support:8,svd:[5,31,32],syntax:35,systemat:3,t:[31,32],taken:[21,36],teach:[26,28],teacher:[28,30],technic:32,techniqu:[6,11,24],technolog:22,tensorflow:[1,3],tent:30,term:[33,37],test:[0,1,15,16,25,30,31,32],text:30,textbook:[29,30],than:[34,35],theorem:[5,8,11,12,27,32,33,37],theori:27,thi:[17,18,19,20,21,30,37],think:31,three:37,through:37,thursdai:[],time:[35,36],tip:[13,21,35,36],togeth:[12,37],tool:[24,30],top:[1,37],topic:30,toward:11,trade:[6,24],tradeoff:[6,33],train:[0,1,4,15,16,30,31,37],transform:3,tree:[9,10],tuesdai:[32,36,37],tune:[1,37],two:[3,8,22,24,31,34,37],type:[2,4,12,30,36,37],uio:30,understand:33,univers:[12,29,37],unsupervis:14,unsupport:35,up:[0,2,9,12,15,21,30,31,33,34,36,37],updat:37,us:[0,1,2,3,7,13,21,22,24,25,30,31,34,35,36,37],usag:[32,33],valid:[6,24,33,34],valu:[5,11,17,18,27,31,32,33,34],vanish:37,vari:[21,35,36],variabl:[27,34,35],varianc:[6,24,32,33],variou:[0,15,25,30,33,34],vector:[8,12,23,30,31,36],video:[34,35,36],view:[0,4,10,31,37],visual:[1,9],vs:3,wai:[9,21,33,36,37],warm:[21,36],wave:2,we:[21,30,35,36,37],wednesdai:[32,36,37],week:[15,16,17,18,19,20,21,30,31,32,33,34,35,36,37],weekend:34,weekli:26,weight:[],what:[0,30,31,32,33],when:[35,36],which:[1,21,35,36,37],why:[30,31,33,36,37],wisconsin:[7,34],word:37,wrap:[31,33],write:[4,11,24,25,32],x:[31,32],xgboost:10,xor:[36,37],yet:32,your:[0,10,15,16,25,30,31],yourself:34,z_j:37}}) \ No newline at end of file +Search.setIndex({docnames:["chapter1","chapter10","chapter11","chapter12","chapter13","chapter2","chapter3","chapter4","chapter5","chapter6","chapter7","chapter8","chapter9","chapteroptimization","clustering","exercisesweek34","exercisesweek35","exercisesweek36","exercisesweek37","exercisesweek38","exercisesweek39","exercisesweek41","exercisesweek42","intro","linalg","project1","project2","schedule","statistics","teachers","textbooks","week34","week35","week36","week37","week38","week39","week40","week41","week42"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["chapter1.ipynb","chapter10.ipynb","chapter11.ipynb","chapter12.ipynb","chapter13.ipynb","chapter2.ipynb","chapter3.ipynb","chapter4.ipynb","chapter5.ipynb","chapter6.ipynb","chapter7.ipynb","chapter8.ipynb","chapter9.ipynb","chapteroptimization.ipynb","clustering.ipynb","exercisesweek34.ipynb","exercisesweek35.ipynb","exercisesweek36.ipynb","exercisesweek37.ipynb","exercisesweek38.ipynb","exercisesweek39.ipynb","exercisesweek41.ipynb","exercisesweek42.ipynb","intro.md","linalg.ipynb","project1.ipynb","project2.ipynb","schedule.md","statistics.ipynb","teachers.md","textbooks.md","week34.ipynb","week35.ipynb","week36.ipynb","week37.ipynb","week38.ipynb","week39.ipynb","week40.ipynb","week41.ipynb","week42.ipynb"],objects:{},objnames:{},objtypes:{},terms:{"0":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,24,25,26,28,29,31,32,33,34,35,36,37,38],"00":[0,1,5,6,9,11,31,32,33,37,38,39],"000":[1,3,9,39],"0000":9,"00000":[9,11,36],"000000":[5,11,32],"00000000e":[5,32,37,38],"00001":36,"00001572":[],"00001716":[],"00002":36,"00002276":37,"00002585e":[],"00002833":37,"00003":36,"00003645":[],"00003828":[],"00005":36,"00006114":[],"00007":36,"00007706":[],"00007738":[],"00008335":[],"00009":36,"00009004":37,"0001":[1,17],"00010067":36,"00010366":[],"0001079":37,"00011562":37,"00011577":[],"00012":36,"00012565":37,"00013464":37,"000137":[],"00013938":[38,39],"00013955":[],"00014166":[],"00014631":37,"00015678":37,"00016062":[],"00016449":[],"00016535":[],"00016719":36,"00017038":37,"00017733":[],"00018":36,"00018053":[],"00018212":[],"00018256":37,"00018651":[],"00019258":[],"0001984":37,"00019998":5,"0002065":[],"00021147":[],"00021259":37,"00021270681344726395":[],"00021771":[38,39],"00021916":[],"000225":36,"00022969":[],"00023":36,"00023102":37,"00023414":[],"00023813":[],"00023978":[],"00024087":5,"00024755":37,"00024929":36,"00025662":36,"00026549":[],"000269":37,"00027188":[],"0002762":36,"00027746":36,"00028":36,"00028167":36,"00028825":37,"00029012":5,"0002926":[],"00030102":[],"00030601":36,"00030827":[],"00031208":36,"00031321":37,"00031535148309577417":[6,33],"0003153514830958095":[6,33],"00033415":32,"00033562":37,"00033679":[],"00033904":36,"00034006":[38,39],"00034132":[],"00034209":37,"00034576":36,"00034688149480437765":[],"00034944":5,"00034953":[],"00035483":21,"00036464":37,"0003701342170783489":[],"00037564":36,"00037737":[],"00038309":36,"000387":[],"00039072":37,"00039632":[],"00040218":[],"00041619":36,"000417932":2,"00042089":5,"00042093":36,"00042436":37,"00042444":36,"00042721":[],"00043701":21,"0004388":[],"00044":36,"00044937":[],"00045472":37,"00046006":36,"00046111":36,"000464088":2,"00046631":[],"00047025":36,"00048158":[],"00048474":21,"00048499":21,"00049344":37,"00049636":[],"00049754":[],"00050694":5,"00050952":[],"00051088":36,"00051916":[],"00052102":36,"00052874":37,"00053001":[],"00053118":[38,39],"00053122":[],"00053797":21,"00053824":21,"00056414":[],"00056603":36,"00057256":37,"00057726":36,"00057772":[],"00058016":[6,33],"00059703":21,"00059734":21,"00060":36,"00060704":6,"00061058":5,"00061352":37,"00062592":6,"00062668":[],"000626681519836":[],"00062713":36,"00063362":34,"00063866":34,"00063957":36,"00063965":[],"00065505":[],"00066091":37,"00066259":21,"00066293":21,"00066668":[6,33],"00067008":36,"00068091":34,"00068734":[6,33],"00069":36,"00069123":6,"00069482":36,"00070819":37,"0007086":36,"00072527":[],"00073534":21,"00073541":5,"00073571":21,"00074274":[],"00075296":37,"00075590":34,"00076202":36,"00076495":[6,33],"00076521":32,"00076908":6,"00076983":36,"0007698473260556325":[6,33],"0007698473260556343":[6,33],"000783":[],"00078324":[],"00078509":36,"00079125":6,"00079904":34,"00079968":5,"00080497":[],"00080683":37,"00081607":21,"00081649":21,"00082235":[],"00082916":37,"0008297":[38,39],"0008297120772365539":[],"00083355":34,"00084215":[],"00084707":6,"00085292":36,"00085892":6,"00086984":36,"00087697":[6,33],"00088573":5,"00088848":37,"00089193":34,"00090567":21,"00090614":21,"00091307":37,"00092678":6,"00092898":34,"00093243":[],"00093356":[],"00094499":36,"00095488":[],"00095624":[],"00096314":5,"00096373":36,"00097416":[],"00097839":37,"00099778":[],"001":[1,2,8,13,17,33,35,36],"00100081":[],"00100202":32,"00100511":21,"00100519":[6,33],"00100546":37,"00100563":21,"00100913":[],"00103819":[],"00103867":[],"001047":36,"0010479245693919886":[6,34],"00105081":[6,33],"00105724":[],"00106677":5,"00106776":36,"00107405":[6,33],"00107739":37,"00108":36,"0010827":[],"00108471":[],"00109354":[],"001106660107757":28,"00110721":37,"00111547":21,"00111605":21,"00111756":[6,33],"00114401":[],"00114451":[],"00114855":[],"0011526":[6,33],"00115455":[],"00115508":[],"00115631":36,"00115999":5,"00116001":36,"00116737":[],"00118302":36,"00118584":6,"00118642":37,"00119688":34,"00119876":[],"00121925":37,"00122762":[],"00123795":21,"00123858":21,"00125057":[],"00126053":36,"001268544905013411":9,"00128394":[],"00128453":[],"00128479":5,"00128523":36,"00129599":[38,39],"0013052":[],"00130648":37,"00130885":[],"00131072":36,"001323":[6,33],"00133638":[],"00134264":37,"00134424":[],"00135237":[],"00135922":[],"00136125":[],"00137387":21,"00137458":21,"00137814":6,"0013839":21,"00139195":[],"00139705":5,"0014028":32,"00140846":34,"00141727":36,"00142396":36,"00142784":[],"00142849":[],"00143013":[],"00143869":37,"00144539":36,"00144622":21,"0014522":36,"0014593":[],"001468":[],"00146807":[],"0014785":37,"00149311":[6,33],"00149679":[],"00149956":[6,33],"00151204":[],"00151416":[],"00151426":[],"00152117":[6,33],"00152471":21,"0015255":21,"00154115":[],"00154733":5,"00154853":34,"00156374":6,"00157766":36,"00157826":[],"00158":36,"00158427":37,"00158786":[],"00158859":[],"00160895":36,"00161463":[],"00162812":37,"00162921":[],"00163159":[],"00163548":[],"00167329":36,"00168251":5,"00168745":[],"00169":36,"00169056":[],"00169212":21,"00169299":21,"00170579":[],"00170809":[],"00171171":[],"00172865":[],"00174276":[6,33],"00174459":37,"00174738":[],"00174743":[],"00174795":36,"00175331":[6,33],"00176582":[],"00176663":[],"00178263":36,"00178952":[],"00179288":37,"001795":[],"00180673":36,"00181885":[],"00182423":[],"0018310257999764163":[],"00186347":5,"00187032":[],"00187791":21,"00187888":21,"0018798":[],"001880":5,"00189016":[],"00191076":[],"00192114":37,"00192154":[],"00193661":36,"0019575":[],"00196372":[],"00196462":[],"00197431":37,"00197505":36,"00198129":[],"00200":8,"00202433":[38,39],"00202624":5,"00202756":[6,33],"00202904":[],"00203961":[],"0020489":[],"00206234":[],"00208188":36,"0020841":21,"00208517":21,"00209403":[],"00211332":[],"00211418":[],"00211555":37,"00211924":[],"00212766":[],"00213888":[],"00214559":36,"00216458":[],"0021741":37,"00217499":[6,33],"00217968":[],"00218381":[],"00218481":[],"00218823":36,"00219195":34,"00220013":[],"00223857":[],"00224413":5,"00224638":[],"00225842":36,"0022626":[],"00228042":[],"00228740":6,"00229111":[],"00230059":[],"00230805":[],"00231293":21,"00231412":21,"00232963":37,"0023548":[6,33],"00236284":[],"00236918":[],"00237699":36,"002381316302584885":[6,33],"0023813163025848865":[6,33],"0023941":37,"00242441":36,"0024271":[],"00242856":[],"00242954":34,"00242967":[],"00242999":6,"00243186":[6,33],"00243835":[],"0024401":5,"002446":[],"00248232":[],"00248779":37,"00249435":[6,33],"00250787":[],"00251359":[],"00254671":[],"00254966":[],"00254973":[],"00256001":[],"00256537":37,"00256622":[],"00256688":21,"0025682":21,"00259997":[],"00260839":[],"00263296":36,"00263638":37,"00263755":[],"00263812":[],"00264":36,"00264181":[],"00266858":2,"00268602":36,"00270073":[],"00270197":[],"00270244":5,"00270262":[],"00272337":[],"00274212":32,"00274676":[],"00274989":[6,33],"00275768":[],"00279722":[],"00282226":[],"00282302":36,"00282498":37,"00284871":21,"00285017":21,"00285068":[],"00288656":[],"00289724":[6,33],"00290316":37,"00290613":[],"00291535":36,"0029276":[],"00292882":[],"00293758":[],"00293838":5,"00295372":[],"00295713":[],"00297571":36,"00298783":[],"00300342":[],"00300479":[],"0030094":[],"00302509":[],"00302547":[],"00309418":[],"00310113":2,"00311085":37,"00312361":[6,33],"00315593":6,"00316149":21,"003162":[38,39],"00316311":21,"00318725":[],"00319695":37,"00319887":[],"0032153180657605116":[6,34],"00322456":36,"00323332":[6,33],"0032542":5,"00325450":34,"00326986":[],"00327104":[],"00327797":[],"00329616":36,"00329927":[],"00330046":[],"003301":[6,33],"00330245":[],"00331927":[],"00334002":[],"00334047":[],"00334155":[],"00334797":[],"00335101":[],"00335174":[],"0033955154592040936":[6,34],"00340452":32,"00342565":37,"0034318":36,"00347534":[],"00348246":[],"00348281":37,"00348553":[],"0035086":21,"00351039":21,"00352046":37,"00352878":36,"00353823":5,"00353938":[],"00355323":32,"00355614":36,"00356356":[],"00359628":[],"0036237":[6,33],"0036367":[6,33],"00363823":[],"00364159":[],"00364235":[],"00364967":36,"00365819":[],"00369201":32,"00369236":[],"00369758":[6,33],"00369852":[],"00371435":[],"00371605":[],"00371656":[],"0037314":[],"00377231":37,"00379682":[],"00380258":[],"0038287":[],"0038335":[6,33],"00387671":37,"00389038":36,"00389382":21,"00389577":21,"003909404072811226":[6,34],"00391839":5,"0039259":[],"00392639":[],"0039455":[],"00398429":[],"00399521":[],"0039987":[6,33],"00399972":[],"004":[5,33,34],"00403677":36,"00405581":[],"0040792":[],"00408":36,"004091940707753939":[6,34],"00410183":32,"00410387":[6,33],"00410478":6,"004113634617443131":[6,32,33],"00411363461744314":[6,32,33],"004113634617443147":[6,32,33],"0041148":[],"00412":36,"0041283":[],"00413064":[],"00413253":[],"00415405":37,"00415497":[],"00415598634586135":[6,34],"00416103":36,"00416704":[],"00418347":[],"00418664":[],"00420072":34,"00424909":2,"00424967":[6,33],"00426027":5,"00426902":37,"00429456":[],"0042992":36,"00432129":21,"00432337":21,"00432864":[],"00433417":11,"00434043":[],"0043587":[],"00437846":[],"00438318":[],"00440346":[6,33],"00441097":36,"004423":[],"00443743":[6,33],"0044505":36,"00445186":36,"0044547":[],"00445655":11,"0045162":[],"00455966":[],"00457441":37,"004579219539673834":[6,34],"00458631":[],"00458878":[6,33],"00459357":[],"00459568":[],"004610275230656212":[6,34],"00461571":[],"00462287":[6,33],"00462662":[],"00463124":32,"00464677":[],"00465099":34,"0046544":[],"00468914":[],"00470102":37,"00471617":[],"00471782":5,"00472199":6,"00472276":[],"00472512":[6,33],"00474898":[],"00476012":36,"00478417":[],"0047956":21,"00479764":21,"00480881":[],"00483858":[],"00487029":36,"00493903":[38,39],"0049544":[6,33],"00497837":33,"00498065":[],"00498243":[],"004999999999999991":[],"004999999999999996":0,"005":[],"005000000000000001":[],"00500716":[],"00502886":[],"00503732":37,"00503932":[],"00507531":[],"00509128":36,"00510839":[],"00511073":[],"00512599":[],"00512927":5,"00513051":[],"00515181":[],"00515889":[],"00516067":[],"00517114":[6,33],"00517673":37,"00519717":[],"00520911":36,"00521014":[],"00522055":[],"00526348":[6,33],"00527578":[],"00528252":32,"0053018":[6,33],"00531268":[],"00532167":21,"00532314":21,"00537955":[],"00539563":[],"00544547":36,"00546503":[],"00547113":[],"00551372":36,"00552462":[],"00554202":[],"00554552":[6,33],"00554707":37,"00556826":[6,33],"0055687":[],"00556946":[],"0055715":36,"00557893":[],"0055997":[],"00560098":[],"00561212":32,"00561262":[],"005643":[],"00564344":[],"00564365":36,"00566707":[],"0056799":5,"00568091":[],"00568352":[],"00569512":[],"00570059":37,"00570321":[],"0057065":[],"00571608":[],"00571884":32,"00572613":[],"00573661":[],"00573727":[],"00574735":[],"00575681":32,"00576997":[],"00578809":[],"00579953":[6,33],"0058243":36,"00585143":[],"00586355":[],"00588657":[6,33],"00588836":32,"00590379":21,"00590456":21,"0059267":[],"00593362":[],"0059591":36,"00597698":[],"00598464":[],"00606382":[],"00607783":6,"0061084":37,"006162":[6,33],"00617221":[],"00617499":5,"0062202":[],"00622617":[],"00622949":36,"00623535":[],"00625051":[],"00625672":[],"00627115":[],"00627746":37,"00630331":[6,33],"00631759":[],"00632049":[],"00632251":[],"00633289":[],"00634299":[],"00634575":[],"00635016":[],"00637188":[],"00637367":36,"0063878":[],"00641423":[],"00642221":[6,33],"00642737":[],"00644":36,"0064472":33,"00645121":[],"00647029":[],"00654058":21,"00654835":[],"00654864":21,"00657601":32,"00659604":[],"00660427":[6,33],"00666287":36,"00667611":[],"00672505":32,"00672607":[6,33],"00672654":37,"00673407":[6,33],"00674158":[],"00676256":[],"00676387":[6,33],"00677215":32,"00679013":[],"0068011":[6,33],"00681708":36,"00683748":5,"00683875021199284":[],"00683964":[6,33],"00685287":[],"00687309":[],"00688012":[],"00688182":[],"00689214":36,"00691012":[],"00691271":37,"00694315":[],"00696127":[],"0069668":[],"00697033":[],"007024126888938232":[6,34],"00702562":[],"00702721":[],"00702885":[],"0071129":[],"00712219":[],"0071264":36,"00715512":[],"00719176":[6,33],"00721287":[],"00722437":21,"00725498":21,"00727646693":[0,31],"00729134":36,"00731392e":[],"007315":32,"00732665":[],"0073544":32,"00736737":32,"007370297974992432":32,"00737863":32,"00740723":37,"0074331":5,"00746317":[],"00747773":[],"00748862":[],"00754823":[],"00755917":[],"00759119":6,"00759427":[],"00761224":37,"00762217":36,"0076268":22,"00764333":[],"007658477904313023":[],"0076989":[],"00771475":[38,39],"0077313":[],"00774376":32,"00778316":[],"00779859":36,"00781297":[],"00781659":[],"00781918":34,"00784393":[6,33],"00789262":[],"00791263":[],"00791445":21,"00792032":[],"00798909":[],"00801346":21,"00802302":[],"00803064":[6,33],"008043811612683473":[],"00805074":34,"00806447":[],"00809364":[],"00812487":[],"00813803":6,"00815244":36,"0081568":37,"00816675":[],"00817631":[6,33],"00818251":[],"00819774":[],"00823002":5,"00827728":[6,33],"00828121":[],"00831018":[6,33],"00834112":36,"00834567":[6,33],"00836649":32,"00838255":37,"00838555":[],"00847367":21,"00848739":32,"00848904":[6,33],"0085548":[],"008560581831215528":[],"0085639":[],"00859693":[],"00860892":[],"00861518":36,"0086649156":[0,31],"008675369724975977":5,"0086885":[],"00869259":[],"00870208":[],"00871959":36,"008753288788081405":[],"00877737":[],"00877892":21,"00881939":[],"00885858":[],"00889027":[],"00889475":[],"00891702":[],"0089214":36,"00894639":5,"00898223":37,"00901661":[],"00903778":[],"00905423":[6,33],"0090724":21,"00908537":[],"009134699065945493":5,"009163470508352218":5,"009164545680330616":[6,34],"00917248":[6,33],"00919984":[],"009211602191395454":[],"00923082":37,"00923474":32,"00925406":36,"00930146":[],"0093262":36,"009338082195270294":[],"00934327e":32,"00934499":[6,33],"00935742":[],"00939407":[],"009396472959497925":[],"00939922":21,"00940611":[],"00942574":[],"00943959":[],"00951885":[],"00954206":36,"00955125":[],"00956827":[],"00958615":[],"0096208":[6,33],"00963683":[],"00964129":[],"00966192":[],"00966668":[],"0096667":32,"00969623":32,"00971344":21,"00972948":[],"00974758":[],"00979357":[],"00982052":[],"009880124918446542":32,"00988356":32,"00988992":32,"00989118":37,"00989834e":[],"00990475":5,"00992331":[6,33],"00996754":[6,33],"00996762":[],"00997502":36,"01":[0,1,2,5,6,9,11,13,17,21,30,31,32,33,36,37,38,39],"010018312644137363":[6,34],"01003519":[],"01006":36,"01006224":32,"01006335":21,"01006984":[],"0100706":[6,33],"01008116":[],"01009321":[],"01013849":[],"01014331":[],"010148621093080332":32,"01016493":37,"01018089":[],"01020588":36,"01024875":[],"01031":36,"01032298":[],"01032533":[],"010331721306655127":[6,34],"010348289064969316":[],"01035006":[],"01039879":[],"01039977":21,"01044475":[],"01045576":[],"010516485576645508":[6,34],"01059242":32,"01060492":[],"010612904886352397":[],"01066519":[6,33],"01066897":36,"01067432":[],"01070103":[],"01074379":[],"0107497":[],"01075018":[],"01076611":5,"01076897":36,"0107744":21,"01078008":32,"01080465e":[],"01084359":[],"01085571":[],"01087815":[],"01089212":37,"01091589":36,"01093529":[],"01093553":[],"01094916":32,"01097287":32,"01098247":[],"0110":28,"01107333":[],"011076219011379514":[6,34],"0111346":21,"011156605304609659":[],"01119357":37,"01119504":[],"01119738":[],"01119981":[],"011208613520466846":[],"011225":2,"01123792e":[],"01127138":[],"01129731":[],"0113104":[6,33],"01131771":[],"01133846":21,"01133903":[],"01141119":36,"01146857":[],"01150437":32,"01151556":32,"0115357":21,"01161645":[],"01163942":32,"0116753":36,"01178583":28,"01178857":[],"01179128":[],"01179415":[],"01179792":[6,33],"011818646101922625":[],"011886":[],"01191824":5,"01192135":21,"01194492":[],"01195336":[],"01196506":32,"01199434":37,"01199741":[],"01205039":[38,39],"01206221":[],"012073649446193166":[6,34],"0121289":[],"01214076":[],"01214862":[],"01216231":[],"0121766":[],"01218403":32,"01219292":[6,33],"01220505":36,"01222822":32,"01222875":[],"01223198":[6,33],"01223754":[],"01229102":[],"01229692":[],"01231917":[6,33],"01232366":32,"0123263":37,"01234":[],"01234261":[],"01235079":21,"01241284":[],"012423940191689783":11,"01244297":[],"01247909":[],"01248754":36,"01249445":[],"01250964":[],"01260207":[],"01261048":[],"01265755":32,"012658":32,"01266999":[],"01267007":33,"0126711":[],"01268737":[],"01276369":21,"01280793":[],"01288787":[],"01290947":[6,33],"0129191":[],"01295356":5,"01305415":36,"013121574015585152":[6,34],"013121574015585155":[6,34],"01315875":[],"01316233":[],"01316638":[],"01318643":[6,33],"0132081":37,"01322347":21,"01323341":32,"01323523":[],"01327148e":[],"01327475":[],"01328972":[],"01329403":[],"01332832":[],"01333573":[],"01335628":36,"0134113":[],"01346122":36,"01347916":[6,33],"01348565":[6,33],"01349244":[],"01353638":[],"01355882":[],"01357366":37,"01359774":[],"01366555":21,"01367553":[6,33],"0137297":36,"01373484":[],"01376216":[],"01377545":[],"01393496":[],"01396231":36,"01397146":[6,33],"01399457":[],"01405935":[6,33],"01406777":[],"01408975":[],"01409478":[],"01415781":21,"01416528":[6,33],"01418766":24,"01425384":32,"01427864":[],"01428546":36,"01433809":5,"014436800088904942":[6,34],"01444013":[],"0144623":[],"01449782":[6,33],"01454469":37,"01455304":[],"01456865":32,"01458337":[6,33],"014586":32,"01458611":32,"0146081":[6,33],"01462254":[],"01463049":[6,33],"01463112":21,"01464686":[],"01473588":[],"01473759":[],"01476927":[],"01480256":[],"01480927":32,"01493365":36,"014934":36,"01499192":[],"01506354":[],"01507238889517706":[6,33],"01507238889517717":[6,33],"01509793":[],"01511937":36,"01512884":32,"01515818":21,"01520159":[],"01522108":[],"01527928":36,"01530321":[],"01531845":[6,33],"01532738":[],"01543076":[],"01546126":32,"01548486":[],"01549377":[6,33],"01551724":[],"01551775":[],"015518":[],"01551815":[],"01552874":[],"01558197":5,"01566493":21,"01568403":[],"01572":36,"01573062":[],"01573768":[],"01575266":[],"01584129":[],"01594452":34,"01597256":36,"01600363":[],"01604235":[],"01615836":37,"01620955":[],"01622922":21,"01624447":[],"01625794":[],"01628578269596628":[6,34],"01630755":[],"01633913":[6,33],"01634224":36,"01639344":[],"01639489":[],"01640891":6,"01641044":[],"01643795":[],"01647074":32,"0164974":[],"01654574":[],"01655318":[6,33],"01655384":[],"016587414993043573":[6,34],"01674956":[],"01677178":21,"01679297":[],"01681173":[],"01681612":[],"0168171":32,"01682652":36,"01691985":[6,33],"0169643":5,"01699169":[],"01700897":[],"01701429":32,"01706166":[],"01708375":36,"01708781":[6,33],"01708852":[6,33],"01713366":[6,33],"01717549":[],"01722503":[],"01724499":5,"017355848195593347":[6,34],"01735584819559336":[6,34],"01737595":21,"01737634":[],"01740381":32,"01747915":36,"01748034":[],"01756114":[],"01759442":[],"01759974":[],"01760144":[],"01761069":[],"017665":5,"01772779":[],"01779091e":[],"01783096":[],"01783414e":32,"0178462":[],"01789589":[],"01793261":[],"01793972":28,"01795684":21,"0179826":[],"01811279":[],"01813363":32,"01814351":[],"01817048":[],"01817739":24,"0182116":[],"018232":32,"01826811e":[],"01827225":36,"01827302":[],"01830039":[],"01831050e":[6,33],"01831190e":[6,33],"01844584":[],"01844822":[],"01846605":[],"0186037":21,"01863203":[],"01866537":[6,33],"01869515":36,"01872002":[],"01873344":11,"01873869":5,"01881237":[],"01882218":32,"01882264":[38,39],"01897462":[],"01898383":[],"01898855":[6,33],"01905384":[],"01905883":[6,33],"01908936":[6,33],"01915337":[],"01918426":[],"01922269":[],"01922564":21,"0193075":[],"0195302":[],"01954342":36,"01963611":[6,33],"01968447":[],"01969093":[],"01969145":[6,33],"01975006":[],"01975416527185249":[6,34],"01975848":[6,33],"01979808":[],"01991068":[],"01991819":21,"01999575":36,"02":[0,4,6,7,12,31,33,35,37,38,39],"0200041":[],"02014577":[],"02016185":[],"02024962":[6,33],"02025574":32,"02026756":[],"02031987":[],"02032056":[],"02034655":[],"02054837e":[6,33],"02056537":[],"02058408":21,"0206033":[],"02068067":[6,33],"02073509":5,"02077431":33,"02079913":[],"02084474":[],"02087411":[],"02088307":32,"02090304":36,"02091662":[],"02092464":[],"02098261":[6,33],"02102403":[],"02103315":36,"02104639":32,"0211429":[],"02117843":[],"02118344":[],"02123176":[6,33],"02124568":31,"02126205":[],"02132557":21,"02134409":[],"02137508":[],"02138683":36,"02141849":[],"02143946e":37,"02146636":32,"02148021":36,"02151521":[],"021544346900318832":33,"02156196":[],"02156565":[],"021592704588025022":[6,34],"021592704588025025":[6,34],"02164667":[],"02169399":[],"02175561":[],"02177725":28,"02183817":[],"02189606":[],"02189863":[],"02189994":[],"02198702e":[6,33],"02198703e":[6,33],"02199232":[],"022":[],"02203851":21,"02204591":[],"02207054":[],"02208512":[6,33],"02214409916811925":[],"02218045":[],"02218076":[],"02228115":[6,33],"02229529":[6,33],"02235723":36,"02239876":32,"02252765":5,"02265404":[],"02281004":[],"0228324":21,"02286267":[],"02287468":36,"02288069":[],"02296298":36,"022999498260366312":[6,34],"0231353":[],"0232":[],"0232101":[],"02322297":[],"02322594":[],"02322786":[],"023295599127611474":[],"02330799":[],"02334754":[],"02338085":[],"02342235":[],"02345858":[],"02348765":[6,33],"02352663":[],"02354386":[],"02355756":[],"02356004":[],"02358547":[],"02359571":21,"02361665":[],"02363304":[],"02365049":[6,33],"02369044":32,"02374496":[],"02386932":[],"02387182":32,"0239126":36,"02391906":[],"024":[],"024011020121022356":[],"02404706":[],"02409835":28,"0241039":[],"02413786":[],"02424794":34,"02432309":[],"02441422":[],"02444266":32,"02444569":21,"02446604":36,"02447063e":[],"0244965108017645":5,"02452792":[],"02454051":[],"0245528":[6,33],"02456":36,"024562":5,"02456235":5,"02459084":36,"02472936":[],"02474828":[],"024792624800382218":[],"02492265":5,"02496085":36,"02498282":[],"02498832":[6,33],"02500488":[],"02502325":[],"02503392":[],"02503753":[6,33],"02506901":32,"02511518":6,"02519009":[],"02521917":[],"02522069":6,"02526293":21,"02527621":[],"02529207":31,"0253208":[],"02533443":[],"02540212":[],"02544154":[],"02545":36,"02546675":34,"0255141":[],"02552966":[],"02553865":24,"02557617":36,"02564828":[],"02566356":[],"025709":[11,32],"02572685":[],"02576358":[],"02576685":[],"02584233":[],"02586427":[6,33],"02594314":[],"02597067":[],"02599188":31,"02601643":[],"0260906":[6,33],"02612988e":[],"02616812":36,"02617297":21,"02622039":[],"0262517":[],"02625193":8,"02629144":36,"02629373":[],"0263106":[],"02631244":24,"02631942":[],"02632742":[],"02635861":32,"02636268":[],"02646648":[],"02649469":[],"026495":[],"02651857":[],"02654585":[],"02660572763718093":[6,34],"026605727637180936":[6,34],"02664408":[],"02667406":32,"02692965":32,"02693015":[],"02693858":33,"02704796":21,"02707227":5,"0271583":[],"02723445":[6,33],"0272743":32,"02729375":[],"02731808":[],"02732402":[],"02735547":36,"02754248":[],"027609773491022525":[6,34],"02760977349102253":[6,34],"02766946":[],"02769274":[],"02780107":[],"02784266":[],"02787184":[],"02793082":[],"02797154":[],"0279886":36,"0280223":21,"02806268":[],"02808229":[],"02809972":[],"02813369":[],"02818667":[],"028188673105960467":31,"0284405":32,"02846506":32,"02850506e":[],"02857":4,"02859759":[],"028638258927275215":[],"02876848":[],"02895911":21,"02895918":33,"02900153e":36,"029003":[],"02901273e":[],"02909574":[],"02911348":[],"02920675":[],"02923006":[],"0292555":[],"02925855":36,"02928194":[],"02930753":[],"02940083":[38,39],"02944152":[],"02944974":24,"02946852":[],"029483":5,"02962583":[],"02963147":[],"02965159":[],"02970225":[],"029733":32,"02973733":[],"02976145":[6,33],"02980537":[],"02987496":32,"02988432":32,"02993573":36,"02994311":5,"02f":[6,25],"03":[1,6,32,33,39],"0300023":21,"03000689":[],"03003891":[],"03008641":[],"03015288036252618":[],"03016341":[],"030164788184997":9,"03021588":[],"03032441e":[6,33],"03033791":[],"0303586629618948":[],"0304378":32,"03057995":[],"030645975175292262":[],"03076019":[],"03077640549":4,"03092729":32,"03099776":5,"031":[5,33,34],"03100531":21,"03112129":21,"03115122":[],"0311613":[],"03119062":[],"03120942":[],"03158013":[],"0316146":[],"03166546":[],"0317606":[],"03177331":[],"03188133":[],"03196357":[6,33],"03201179e":[],"03201217":[],"03201832":36,"03201922":32,"03205795":[],"03206757":[],"03207075e":[38,39],"0321222":21,"03212854":[],"032142":[],"03214247":[],"03214829":[],"0321956":[],"032196":[],"03230611":[],"03235719":[],"03239118":[],"03239393":[],"03244944":[],"03246707":32,"03247316":[],"03251863":5,"03254179":[],"03254614":32,"03256632e":[1,39],"03261373":[],"03267527":[6,33],"03274273":[],"03279636":[6,33],"03285784":[],"0328643":36,"0330308045183194":[6,33],"0330308045187757":[6,33],"03306538":36,"03308408":5,"03309191e":[],"03311432":[],"03313259e":[],"03317599":[],"03318519":[],"03319608":21,"0332335":[],"033233504714921":[],"03345624":[],"03358833":[],"03361037":[],"03365012":[],"033657685071527665":[6,34],"0337609":[],"03382942":[],"03396658":[],"034":[],"03400724e":[],"03404758":[],"034048":[],"03409194":[],"03412067":32,"0342028":[],"0342458":36,"03426412":32,"03430385":28,"03439189":21,"03447512":[6,33],"034476":[],"03447649":[],"034557":32,"03455885":[],"03472308":[],"03474443":[],"03476611e":[],"03479236":[],"03479936":[],"03484266":[],"03511387":[],"03529083":[],"03529801":[],"03538463":[],"03538673e":[],"03554165":21,"03558034":[],"03559176":[],"03562355":[6,33],"03563709":24,"03568439":[6,33],"03573214":[],"03578526":[],"03586482":[],"0359565":5,"03596557":[],"03624103":[],"03624411":[],"0362483569261072":[],"03630548":[6,33],"03642173":[],"03648711":[],"036527092051294":[],"03656288":[],"03662823":36,"03664879":[],"03680811":[],"03681479262838276":[],"03682195":21,"03692132794542241":28,"0369544130635358":[],"03701105":[],"03703391":[],"03707133":11,"0370757046153366":28,"03722287":[],"03736678":[],"03742586":[],"03745816":32,"03778607":[],"037813671417389005":[6,34],"03781367141738902":[6,34],"03796359":[],"03796582":[],"03798785":[],"03805295":21,"03814292":[6,33],"03815288":[6,33],"03820746":32,"0382721":[],"038300":[11,32],"03837":36,"03844073":[],"0384468":[],"03846169":33,"03853213":[],"03853268":[],"03853313":[],"03858916":32,"03868372":[],"03872795610436844":[],"03873507":[],"03887801":[],"039039":5,"03906948":32,"03916813":[],"0394226":[],"03942371":21,"03948301":[],"03960002":[],"039732":5,"03973227":5,"03973359":[],"039764":[],"03976851":36,"03976976e":37,"03979291":[],"0398603":[],"03990261":[],"039967668952797":[6,33],"0399676689527975":[6,33],"04":[1,6,11,33,39],"04000457":[],"040102":5,"04010697":[6,33],"04015455":21,"04018043":[],"04018705":[],"04018985":[],"04025059":[],"04033524":[],"04038595":[],"04046513":[],"04061345":[],"04063602":[6,33],"040684":[],"04072235":[],"04073097":[],"04074169":21,"0408223":[],"0409646":[],"04097813":[],"041":9,"04101344":[],"04108038":36,"04110474":[],"0411487294305088":[6,33],"0411487294305226":[6,33],"04121466":[],"04150522":[],"04158557":[],"04161572":[],"0417409":[38,39],"04186033":32,"04191323":[],"04193203":32,"042060":[],"04206048":[],"042136":[],"04216532":[],"0422":[],"04220758":[6,33],"04220931":21,"04224929":[],"04238763":[],"04262217":[],"04277528":[],"04293545":[],"04295726":[],"04295757":34,"043":9,"043072":[],"04307275":[],"04315108":5,"04315855":[],"04322019":[],"04323936e":[],"04328852":[],"04330558":[],"04330907":[],"04346721":5,"04353549":[],"04355062":[],"04355837":[6,33],"04362":9,"04362042":21,"043637":[],"04369752":[],"04372067685794603":31,"0437499":2,"043839":[],"04389027":[6,33],"044014":[],"04401421":[],"04413243":[],"04418179":[],"04421197":[],"04423486":[6,33],"04426744e":32,"04431557":28,"044334":32,"04443985":[],"04452918":32,"044613":[6,33],"04487298":[],"0449":[],"04495752":[],"04501146":[],"04504728e":[],"045161":[],"04516434":24,"04519174":21,"045258":[],"04532405":[],"04537385":[6,33],"04543942":[6,33],"045630":[],"04564589":[],"04566964":[6,33],"04575775":32,"0458":9,"04585476":[],"04588592":[],"04592382":[38,39],"045963":[],"0462999":[],"04640695":[],"04641529":[],"04646338":[],"04648225":[],"04648335":5,"04652794":[],"04655574":[],"04657426":[],"04664255":6,"046663":[],"046678":[],"04670255":21,"046764":[],"04683565":5,"04686491":31,"04688012":[],"04719868":[],"047299":[],"04736252":[],"0473916":[],"047447724189861":[],"0474753":36,"047489":[],"04757138":[],"047760":[],"04776242":[],"04784395":[6,33],"04794409":[],"048020":[],"04808723":[],"0481872773043029":[6,34],"048194":[],"04832356":[],"04838148":[],"04838489":21,"04852743":[],"04877931":[],"048781":[],"0488139":[],"04881585":21,"04892055":[6,33],"04899367":[],"049060":[],"04909093":[6,33],"04912436":6,"04915593":[],"049196":[],"04922273":[],"04926746":34,"049276":[],"04933083":[],"049380":[],"04939861":[],"049479":[],"049481":[],"049556996627824":[6,33],"0495569966278269":[6,33],"04955942":[],"04963309":[],"049677":[],"04984743":[],"04999052":[],"05":[1,4,6,9,25,32,33,36,37,38,39],"05000245":21,"050015":[],"05002471":[],"05005634426334421":[],"05006037":[],"05006956":[],"05009826":[6,33],"05013368":[],"05029018":[],"05029453":[],"050315327923114654":[],"05034088e":[],"05040878":[],"05043958":32,"05045":[],"05054319":[],"05060379":[],"05068486":[],"05077224":[],"050796":[],"05080769":31,"05087018":[],"05097344":32,"05098714":[],"05100875":[6,33],"051021":[],"051042":[],"05135047":36,"051368":[],"05141614":[],"051418":5,"05144177":[],"05148401":24,"051554":[],"05159088":[],"051598":[],"051645":[],"051649":[11,32],"05169046":[],"0517473":5,"05176711":[],"051787":[],"05180367":21,"052010":[],"05201041":[],"05224117":[],"0522653":[],"052279218012056844":[6,34],"05227921801205686":[6,34],"052305":32,"05233008":[],"052370":[],"05240397":[],"052427":[],"0524497":[],"0525733":[],"05263":9,"052692":[],"05269476":[],"052738":[],"052856":[],"05285677":36,"05293756":[],"05296475":[],"05302":9,"053036":[],"05336637":[],"053387":[],"053417":32,"053462":[],"05347795":[],"05353553":21,"053599":[],"05363722":32,"05364579":32,"05364854":8,"05376358":[],"053787":[],"05383795":[6,33],"05383947":[],"05384858":[],"053849":5,"053854":[],"05395761":[],"05401912":[],"05415968":[],"054197":[],"054286":[],"05442743":[],"054434":[],"05447415":[6,33],"054609":[],"054617":32,"054655":32,"05476114":36,"05484773":[],"054932":[],"055000":[],"05505310046363":2,"055091049054481":[],"05509105":[],"05519999":33,"0552878":[],"055314":[],"05533":9,"05546402":21,"055477":[],"05549529":[],"05563358":[],"055653":[],"055676":32,"055734":32,"055737":[],"05574159":[],"05577845931438246":[],"055876":[],"055910":32,"055987":32,"056026":[],"056041":[],"0560663":[],"05614483":5,"0562":[],"05623":9,"056287":[],"056328":[],"05638246":[],"05641352":[],"056414":[],"05648":9,"05648118":24,"05648836":[],"05651951":[6,33],"05665429e":[],"05667":9,"05668052":[],"056683":32,"056717":[],"056826":[],"056856":[],"05696574":32,"05716368155342608":[6,34],"057216":[],"057287":[],"057300":32,"057316":[],"05731824":21,"05737289":[],"05738629":37,"057387":[],"057393":32,"057418":32,"057420":[],"057457":32,"05747369":[],"05749111":32,"05750493e":21,"057514":[],"057607":[],"057609":[],"05761244":36,"05767":38,"057722":32,"0578214":[],"057835":32,"05785343":[6,33],"05785974":37,"05788748":[],"05789007":[6,33],"05791283":[],"057913350391706":[],"057929":[],"05792927":[],"057951":[],"057961":[],"05796251":[6,33],"057964":[],"05804539":[],"05804744e":36,"05807125":[6,33],"058133":[],"058152":[],"058234":[],"058245":[],"058254":[],"05831017":[],"05834577":[],"058361":[],"058422":[],"058427":[],"058503":5,"05850899":[],"05853984":32,"058552":32,"058582":[],"058593":[],"058641":[],"058645":32,"0586484":36,"05867956":[],"058721":[],"058770":[],"05883":9,"05884":9,"058854":32,"05888195":[],"058952":32,"058967":[],"058970":[],"058996":32,"058997":[],"059031":32,"05914563":[],"059181":[],"059201":[],"059243":[],"059340":[],"05938299":21,"05941988e":[],"059624":[],"059669":[],"059761":[],"05978512":[],"059807":32,"059876":[],"05992237":31,"059951":32,"059956":[],"05996":36,"059977":[],"05998413e":21,"05999":9,"059992":[],"059993":32,"06":[6,32,33,36,37,38,39],"060071":[],"060083":32,"060085":[],"060087":[],"060171":[],"06019833":32,"06020264":[],"06020587":[6,33],"06021793":[],"060251":[],"060254":32,"060275":[],"060288":[],"060312":[],"06043581":[6,33],"060453":[],"060470":[],"060471":[],"060475":[],"0604888":[],"060490":[],"060547":[],"06055507":[],"060565":5,"06061276":31,"060629":[],"060631":[],"060652":[],"0606958":[],"060716":32,"06072":36,"060726":[],"060734":[],"060735":[],"060756":32,"060870":[],"060872":32,"060898":[],"060994":[],"061025":[],"06110658":[],"061154":[],"061163":32,"061284":[],"061319":[],"061359":32,"06136823":21,"061386":[],"061443":32,"061452":32,"06146873":[],"06151386":32,"06155151":[],"061588":[],"061614":32,"061637":[],"061656":[],"061706":[],"061724":[],"061772005077293704":28,"061848":[],"061862":[],"061898":[],"061921":[],"06199119":[],"06200174":5,"06200455":32,"062016":32,"062053":[],"062058":[],"06208238634231949":[6,34],"06210358":[],"062161":[],"06216141":[],"062173":[],"0621855":[],"062199":[],"062216":[],"062231":[],"062260":[],"062263":[],"062282":[],"06228382":[],"062292565":4,"062300":[],"062337":32,"062356":[],"062429":[],"062520":[],"0625462":[],"062599":32,"06260611":[],"062616":[],"062624":32,"06263176":[],"062637":[],"06267057":36,"062691":[],"062693":5,"062700":[],"062705":5,"062719":5,"06277313":[],"062797":[],"062853":[],"062874":32,"06287939":[],"062932":[],"063017":[],"063019":32,"063048":[],"063061":32,"063064":[],"063080":32,"063130":[],"063133":[],"063161":[],"063163":[],"06318287":28,"063197":[],"063206":[],"06320757":[],"063260":32,"063294":[],"063332":[],"063354":[],"063395":[],"063518":[],"063525":[],"063526":[],"063536":[],"063545":[],"063549":[],"063554":5,"063560":[],"06357887":21,"063637":[],"063653":32,"063673":[],"0637712":[],"063781":[],"063786":[],"063791":[],"063802":[],"063809":5,"0638484":36,"063862":[],"063894":32,"06392846":[],"063933":[],"063954":[],"06395476":[],"063959":[],"063977":[],"063995":[],"064000":[],"064074":32,"064077":[],"06410638":[],"064107":[],"06416459":[],"064166":[],"06418809":36,"064189":[],"064202":[],"064218":[],"06423317":24,"064294":[],"06430789":[],"06432267":[],"064382":[],"064427":[],"064428":[],"06443054":24,"06444":9,"06444224":[],"064501":32,"064505":[],"064507":[],"06453579006728324":[6,34],"064547":[],"064573":[],"064604":[],"064606":32,"064609":32,"064615":[],"064668":[],"064690":[],"064695":[],"064699":32,"064728":[],"064739":[],"064793":32,"064820":[],"064834":[],"064845":5,"064873":[],"064878":[],"06491455":[],"06491736":[6,33],"064924":5,"064954":5,"064978":[],"065001":[],"065007":[],"065028":[],"06505375":[],"065062":[],"065077":32,"065096":[],"065108":[],"065121":[],"065149":[],"065212":[],"065217":[],"065352":[],"065358":[],"06536971":[],"065378":32,"065390":32,"065410":32,"06547790180152355":[6,34],"06547790180152359":[6,34],"065482":[],"065556":[],"065616":[],"065619":[],"065654":[],"065679":[],"065778":5,"065788":[],"065818":[],"065821":[],"065830":[],"06590458":[],"065949":[],"065963":[],"065989":5,"06603447":[],"066044":5,"066054":[],"066059":[],"066066":32,"066127":[],"066145":[],"066153":[],"066199":[],"066205":[],"06622369":[],"066256":[],"066286":[],"066358":[],"0663596":[],"06637":9,"066425":[],"066458":[],"066474":32,"066500":32,"06659997":[],"066612":32,"06662069e":[],"06662675":[],"066633":[],"066647":32,"066653":[],"0666807":2,"066686":[],"06674611e":[],"066763":[],"066766":[],"06677444e":[],"066778":[],"066787":32,"066824":[],"066837":[11,32],"066838":[],"06684886":[],"06685171":[],"066854":32,"066855":[],"066865":[],"06687898":[],"06690071":[],"066912":[],"066948":[],"06698472":[],"066988":[],"066997":[],"066999":32,"067000":[],"067003":[],"06704902":[],"067074":[],"067077":5,"067141":[],"067164":[],"067168":[],"067224":5,"06724062":5,"067270675787016":[36,37],"067273":5,"067288":5,"067367":[],"067374":[],"067380":[],"067400":[],"067431":[],"067511":[],"067515":[],"067539":[],"067623":5,"067637":32,"067671":[],"067707":32,"067764":[],"06777772":[],"067793":[],"067809":[],"067843":[],"067922":[],"067948":[],"067967":[],"067974":[],"0680225":31,"06804775":[],"06807123":21,"06808421":[],"068088":5,"068116":[],"068206":[],"068215":[],"068229":5,"068264":32,"068268":[],"06828347":[],"068307":32,"068324":5,"068353":[],"068360":[],"068364":5,"068369":[],"068394":[],"068408":[],"068441":32,"06844519414009445":[6,34],"06844519414009446":[6,34],"068446":[],"06849372":[],"068494":[],"068504":[],"068512":[],"068533":[],"068539":[],"068587":[],"068592":[],"068607":[],"068629":32,"068680":[],"068684":[],"068727":32,"068758":[],"068775":[],"068827":[],"068843":[],"068897":[],"068903":[],"068906":32,"068912":[],"068924":[],"0689303":32,"068967":[],"068977":[],"068985":[],"06901081":[],"069028":32,"069045":[],"06908518":36,"069129":[],"06913112":[],"069179":[],"069203":[],"06926192":[],"069270":[],"069293":[],"069317":[],"069320":[],"069322":[],"069391":5,"069399":[],"06942115e":[],"0694226":[],"069427":[],"069439":[],"069452":32,"069484":[],"069486":[],"069584":32,"06958788":[],"069637":5,"069676":5,"06970419":[],"069711":5,"069802":[],"069811":[],"06984502":[],"069866":[],"069873":[],"069885":[],"069907":[],"0699274":[],"069970":5,"069978":[],"069979":[],"07":[6,32,33,36,38,39],"070024":[],"070027":[],"070043":32,"07006502":[],"070095":[],"070098":[],"070135":[],"070146":32,"070150":[],"07016":9,"07017":9,"070183":[],"070213":32,"070274":[],"070275":[],"07027791":[],"07039":9,"070432":[],"070441":[],"070457":32,"070462":[],"070485":5,"070514":[],"070527":5,"070531":[],"070547":[],"070552":[],"070556":[],"070558":[],"070582":32,"070600":[],"070605":[],"070622":[],"07062318":[6,33],"070630":[],"070655":[],"070667":5,"070696":[],"070712":[],"070730":5,"070737":32,"070747":5,"070769":5,"070772":[],"070780":[],"070805":[],"07084394":[],"070855":[],"070859":[],"070886":[],"070889":[11,32],"070891":[],"070898":[],"070916":[],"070918":[],"070950":[],"070980":[],"070986":32,"071049":[],"071055":[],"07106891":[],"071103":[],"07115":9,"071173":[],"071186":[],"071191":[],"071208":[],"07123177":[],"071252":[],"071279":[],"071291":[],"071294":[],"0713":[0,31],"071314":[],"071356":[],"071379":[],"071433":[],"071436":[],"071437":[],"071449":[],"07145103":11,"07147935":[],"071530":[],"071560":[],"071572":[],"071578":[],"071580":[],"071588":5,"07160048164233102":[6,34],"07160048164233104":[6,34],"071608":[],"071638":[],"071643":[],"071655":[],"071656":[],"071680":[],"07172932":32,"07173249":[38,39],"071758":[],"071789":5,"071803":[],"071831":[],"0718316":36,"071868":[],"07187601":[],"071921":[],"0719267":[],"071935":[],"071937":[],"072000":32,"072015":[],"072031":[],"072037":[],"07204042":[],"072083":5,"072092":[],"072111":32,"072132":32,"072147":[],"07218473624441492":[],"072200":[],"072209":[],"072223":5,"072241":5,"072286":[],"072290639572326":[],"07229064":[],"072304":[],"072344":[],"07235641":36,"072380":[],"072404":5,"07241855":[],"072476":32,"072500":[],"0725872":[],"072590":[],"072591":[],"072621":32,"072638":[],"072684":[],"072689":[],"072697":[],"072728":[],"072752":[],"072817":[],"072824":[],"072826":[],"072843":[],"072849":[],"07285":3,"072863":[],"07292363":32,"072946":5,"072947":[],"072961":[],"072973":5,"072997":[],"073048":[],"073071":5,"073102":[],"073109":[],"073115":5,"073198":5,"073253":[],"073258":[],"073260":5,"073262":[],"073288":[],"07332248":[],"073339":[],"073405":[],"073408":[],"073415":[],"073422":[],"073499":[],"073514":[],"073528":[],"073576975500551":[],"073598":[11,32],"073612":[],"073644":32,"073647":[],"073672":[],"073685":[],"07373479":[],"07376699":[],"07378525":[],"073791":[],"073800":[],"073841":5,"073858":[],"073866":[],"073882":[],"073911":[],"073923":[],"07405556":[],"074067":[11,32],"074084":32,"074112":[],"074114":[],"074115":[],"074130":[],"074134":5,"07415258":28,"074210":32,"07421084":5,"074221":[],"07429886e":[],"074323":32,"074368":[],"074374":[],"074417":[],"074454":[],"0744881":[],"074531":[],"074561":[],"07456491":5,"07459764":[],"074622":5,"07468007":32,"074688":11,"07469645":[],"074787":11,"074807":[],"074824":[],"074859":[],"074866":5,"07487128":32,"074882":11,"074892":[],"07489511":37,"07490892":[6,33],"074928":5,"074971":[],"074976":11,"075070":11,"07517385":[],"075176":[],"075177":[],"075198":[],"075239":[],"075289":[],"075298":[],"075302":[],"07531349":[],"075334":5,"075356":[],"075385":[],"075392":[],"075463":[],"075513":[],"075522":[],"07555537":[],"075557":[],"075562":5,"075602":[],"075609":5,"075615":[],"075712":5,"075771":[],"075794":[],"075816":32,"075822":[],"075823":5,"075842":[],"075864":5,"075876":[],"075885":[],"075889":32,"075909":[],"0759216":[],"075956":[],"07597049":[],"075978":[],"07600369":[],"076066":[],"076071":[],"076091":[],"076138":[],"076150":32,"076161":[],"076167":[],"076232":[],"076244":[],"076259":[],"076321":[],"076333":[],"076334":5,"076351":[],"076389":[],"076393":[],"076396":[],"076418":[],"07641937":34,"076434":[],"076435":[],"076436":[],"076448":[],"076459":[],"076479":[],"0764924":[6,33],"076508":[],"076542":[],"076543":5,"0765856870687196":28,"07658569":28,"076618":[],"076638":[],"076648":[],"076679":[],"07668538":[],"076693":[],"076776262573027":[],"076777":5,"07678":9,"076833":[],"076857":[],"076859":[],"0768805855280187":[],"07692307692307693":9,"076934":[],"076938":[11,32],"076947":[],"076951":11,"076968":[],"077035":[],"07705051":[],"07712197e":[],"07712724":31,"077131":11,"077141":[],"077168":32,"077226":[],"077248":[],"077254":5,"077280":[],"077301":[],"077304":[],"077310":11,"077329":[],"077341":[],"0773554":[],"077382":[],"077391":[],"07740964":[],"077411":[],"07745579":[],"077460":32,"0774777":[],"077485":[],"077486":[],"077490":11,"077516":[],"077529":[],"077539":[],"077541":5,"077553":[],"077567":[],"077601":[],"077608":5,"077613":[],"077653":[],"0776532":[],"077672":11,"077683":[],"077736":[],"077745":[],"07776381":[],"077764":[],"07777777777777778":1,"077782":5,"077813":[],"077839":[],"077906":[],"077941":[],"077965":[],"078035":[],"078044":[],"078067":5,"078071":[],"07808426989543932":[],"078110":32,"078118":[],"078123":[],"078146":[],"078170":5,"07820":9,"078210":[],"078238":[],"078268":[],"078282":[],"078284":[],"078313":[],"078324":[],"078336":32,"078359":[],"078363":[],"078386":[],"078447":[],"078454":5,"078540":32,"078541":[],"078544":5,"078557":[],"078573":[],"078588":[],"078636":[],"07864":9,"078684":[],"078688":[],"07871":9,"078731":[],"078753":5,"078898":5,"07890044":[],"078945":[],"078974":32,"078981":[],"078986":32,"079002":[],"079027":[],"079030":[],"079074":[],"079080":5,"079089":[],"079107":[],"07911268":[],"079174":[],"07919041":[],"079202":[],"079240":[],"079334":[],"079347":[],"079391":[],"079420":[],"07944154":[24,31],"079444":[],"07950356694388497":[],"079510":[],"079518":5,"079670":[],"0796891867672603":[6,34],"07969087":[],"07971187802560528":5,"079739":[],"079747":[],"07974741":[],"07978850553011713":[],"079887":[],"079903":[],"079946":32,"079947":[],"079953":[],"079959":[],"07996807":[],"079976":[],"079977":[],"079982":5,"07998756":[],"079989":[],"079998":[],"08":[9,28,32,36,37,38,39],"080082":[],"080094":[],"08009874":31,"08010965":11,"080110":11,"080171":[],"080205":[],"080222":[],"08023512":36,"080286":5,"080316":[],"08032505":[],"080345":[],"08043851":5,"080453":[],"080549":[],"080555":[],"080559":11,"080616":32,"080630":[],"080657":[],"080702":[],"080706":[],"080747":[],"080764":32,"080793":5,"080832":[],"080849":5,"080875":5,"080903":[],"080947":[],"080987":[],"081038":[],"081103":[],"081195":[],"081217":[],"081221":[],"081235":[],"081252":[],"081276":32,"081296":5,"08131003":6,"0813156":[],"081405":5,"081431":[],"081457":[],"081494":[],"081527":[],"081530":5,"08153923":[],"081544":[],"08156108":[6,33],"08165104":32,"081655":32,"081681":5,"081686":[],"081728":[],"081730":11,"08179906":[],"081835":[],"081871":[],"081955":[],"081978":[],"082002":11,"0820185":[],"082115":[],"082126":[],"082170":[],"082173":[],"082174":[],"082249":11,"08227057":[],"08227668":[],"082303":[],"08233627":[],"082361":5,"082464":[],"082478":11,"082482":[],"08251519":[6,33],"082518":[],"082519":[],"082533":[],"08259753":[],"082653":32,"08266769":[],"082742":[],"082764":[],"082784":[],"082785":[],"08280012":[],"082803":[],"082857":[],"082971":[],"08299273e":[6,33],"083016":[],"083119":[],"0831367":[],"083179":[],"083182":[],"08318298e":[1,39],"08319383":[],"083248":[],"083259":[],"083260":[],"083268":[],"083288":[],"08332537":[],"08333333333333333":[1,9],"083342":[],"08336233266":4,"083446":[],"083465":[],"083471":[],"083479":[],"083499":[],"083501":[],"083527":32,"083547":[],"083548":[],"083564":[],"083596":5,"083645":5,"083734":[],"083765":[],"08376632":[6,32,33],"083766322923899":[6,32,33],"0837663229239043":[6,32,33],"083793":[],"083864":[],"083900":[],"08398399377155011":[],"084018":[],"084042":[],"084076":32,"084091":[],"084122":[],"084127":5,"08418956":[],"084209":11,"084218":[],"08421808":[],"084255":[],"08426840630693411":[6,34],"08426840630693413":[6,34],"084312":[],"084319":[],"084340":5,"084358":[],"084376":[],"084406":[],"084423":5,"084434":[],"084514":[],"08455":9,"084550":11,"08458591":[],"084619":[],"084637":[],"0846409":[],"084695":[],"084702":[],"084712":[],"08472879":32,"08474":9,"084809":32,"08487999":28,"084910":[],"084915":[],"084963":[],"084967":[],"084976":11,"084996":[],"085079":[],"085120":[],"085139":[],"085145":[],"085197":5,"085222":[],"085294":[],"085353":[],"08536248571780691":[],"085378":11,"085390":[],"08539155":36,"085392":[],"08539583":[],"085436":[],"085455":[],"085463":5,"08551306":[6,33],"085518":[],"085548":[],"085592":[],"085655":11,"085690":11,"085712":11,"085716":11,"085722":11,"08572513":[],"085747":11,"085764":11,"08576932":6,"085790":11,"085819":11,"085833":11,"085853":11,"08587209":[],"085902":11,"085918":[],"08593216":[6,33],"085935":11,"085970":11,"085973":[],"085996":[],"086021":11,"086026":[],"086068":[],"08609047":[],"086092":11,"086095":[],"086096":[],"08611111111111111":1,"086125":[],"086212":[],"08622478":[],"086230":[],"086239":[],"08624193":[],"086250":[],"086286":[],"086318":[],"086346":[],"086364":[],"086428":[],"086471":5,"086483":[],"086489":5,"08660891":[],"08667591":[],"086694":[],"086712":[],"086730":[],"086797":5,"086799":[],"086808":[],"086809":[],"08687303":36,"08690":9,"08690184845323":[],"086913":5,"086970":[],"08699295e":[],"08700526":28,"087020":11,"08702578":[],"08705631913312815":11,"087210":[],"087424":[],"087429":[],"08747795":[],"0875061":[],"08758":9,"08758013":[],"087585":5,"087864":[],"087871":[],"087876":11,"08793554992813543":[],"087988":[],"088023":[],"088029":[],"088030":[],"088038":[],"088058":5,"088102":[],"088127":[],"0881981":5,"088199":[],"08824304e":[],"08826182458028335":[],"08826256":[],"088375":[],"08839544":[],"08854388":[],"088574":[],"08858739":32,"088599":11,"08860502":[],"088650":11,"088651":[],"088694":5,"08871404":5,"08881497884574564":32,"08888888888888889":1,"088970":[],"08902":9,"089052":5,"089311":11,"08931169286872433":[],"08935132374099551":[],"089354":11,"089376":[],"089386":11,"0894015":[],"089404":5,"089408":11,"089421":11,"08946029":[],"08947292":[],"0895043":[],"0895387":32,"089539":32,"089548":[],"089576":11,"089578":[],"089600":[],"08961438":[],"089619":[],"089626":[],"089639":11,"089653":11,"089690":11,"089704":11,"089708":11,"089714":11,"089718":[],"089726":11,"089730":11,"089738":11,"089748":11,"089760":11,"089763":11,"089769":11,"089783":11,"089786":11,"089790":11,"089795":11,"089800":11,"089826":11,"089858":5,"089872":11,"089940":11,"089949":11,"08996":9,"089996":[],"09":[1,32,39],"090002":11,"090033":[],"090038":[],"09007789":[],"090081":11,"090114":5,"09014451":28,"090204":11,"09024373":[],"09028702":[],"090302":5,"090319":11,"090429":11,"090439":[],"090440":[],"090468":[],"090476":11,"09048717285916912":[],"090561":5,"090624":[],"09070064":[],"09078672":[],"0907958":[],"090985":[],"091015":[],"091068":[],"091159":[],"09135059e":[],"091362":[],"091365":[],"091388":[],"09156055":[],"09163947":6,"091653":11,"09166666666666666":1,"0917":9,"09171886":[],"091731":[],"09189665":[],"09209032":[],"09224244":[],"092252":[],"092347":[],"092401":[],"09242193":[],"09246293455466892":[],"092486":[],"09251":9,"092533":5,"092607":[],"092608577084595":[],"092689":11,"092746":5,"09291556244521161":[],"09291806":[],"092956":[],"09296935":[],"092982":[],"09300398":[],"0930438":[],"093094":[],"09346106":[],"093554":[],"09360113":[],"09368":36,"0938492":[],"09397626":[],"09398153":[],"094044":[],"0940821989627646e":[6,33],"0940821989652176e":[6,33],"094099":[],"094254":[],"094362":[],"094439":[],"09444444444444444":1,"09469095":[],"094697":11,"094797":11,"094849":11,"094857":11,"09487358":[],"09491833":[],"094941":11,"095037":11,"095090":11,"095106":5,"09515455":[],"095178":11,"095278":11,"09529067":[],"095425":11,"095465":[],"095710":11,"09572047":[],"095805":[],"09584387":24,"09590269e":[],"095915":11,"09604976":[],"096078":11,"09609807":5,"09610694":[],"096203":11,"09621323":31,"09622593":[],"096270":[],"096287":11,"096365":[],"09637807":[],"096511363983559":[],"09651792":[],"096570":11,"096700":11,"096811":11,"097017":11,"097060":11,"097380":11,"0973900819831327":[],"09740532e":[],"0974119":[],"09744":9,"09755017":[],"097667":11,"09780":9,"09790216282081063":[],"09791":9,"09808149":37,"09808622":[],"09821823":31,"09829902":[],"0983565":[],"098414":[],"09846933":[],"09851247":[],"09861229":[24,31],"098803":11,"09903804":8,"09913654":[],"09919198949275869":[6,34],"09928714":[],"09930135":24,"09941275e":37,"09951287404314545":1,"099588":11,"0n":[0,31],"0s":39,"0x0006":[3,4,14],"0x1174af160":[],"0x11753f700":[],"0x117715eb0":[],"0x117893340":[],"0x117c17be0":[],"0x117edb760":[],"0x11975e550":[],"0x11b160a60":[],"0x11bc3a1f0":[],"0x11bcee130":37,"0x11bdd4640":37,"0x11f13fb20":[],"0x120cc1b20":[],"0x121cf68e0":[],"0x124b30190":[],"0x124b96d60":[],"0x126431130":[],"0x1273ffac0":[],"0x1279bd460":[],"0x12aaa0b20":36,"0x12b14fa90":36,"0x12e13a850":[],"0x135f8b1f0":21,"0x1360ef5e0":21,"0x145270160":[],"0x1452d6eb0":[],"1":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,21,24,26,27,28,29,30,33,34,35,36,37],"10":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,21,22,24,25,27,28,29,31,32,33,34,35,36,37,38,39],"100":[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,17,21,24,28,29,31,32,33,34,35,36,37,38,39],"1000":[0,1,2,4,5,8,11,13,14,21,23,28,31,32,35,36,37,39],"10000":[2,5,6,10,11,13,28,33,34],"100000":8,"10001":10,"100083":[],"10008326":[],"1000911":[],"1001":[9,28],"1002":28,"100209":11,"10029389":36,"1003":28,"10030":9,"10036694":[],"10041812":33,"1004727":[],"10047943":28,"1005":28,"100523":11,"10068448":[],"1007":34,"1007711427354898":[6,34],"1009":28,"10100211":24,"101008878523571":11,"10107914":[],"1011":28,"101150":[],"10115017":[],"10116149":[],"101263":[],"101292":11,"1013":28,"1013904243":28,"10141413e":[6,33],"1015":28,"1015491":36,"10158754":[],"1015am":31,"10175169":[],"102209":11,"1023":28,"10230":9,"1024":3,"10242458":[],"1026":28,"10261093":[],"1027":28,"10276112":[],"103":[1,39],"1030":28,"1033455":[],"10340":9,"10340733":[],"10348862":[],"10365224":[],"1037":28,"10378326e":[1,39],"1038":28,"10391807":[6,33],"10398646080125032":[6,34],"10398646080125035":[6,34],"1040":28,"10405456":11,"10426556":[],"10430":9,"104411":32,"10453899":37,"1047":28,"10499357":36,"105":33,"10520":9,"10537416":28,"10539984":[],"105400":[],"10541723644166373":[],"10555555555555556":1,"10556487":[],"10560458":[],"10572":34,"10587277":[],"10589577":5,"10595991":[],"10598715e":[38,39],"10604579e":[],"106095":[11,32],"1064601390492845":[],"10646014":[],"10688434":24,"10719554":[],"10719859":[],"10738656":5,"107387":5,"10747579":[],"107476":[],"1074792":[],"10754764":[],"1079":34,"10790125813226321":32,"108":[6,9],"10801706":24,"1080176":[],"10837392":[],"10854118":[],"10888197":[],"10898643":[],"10907699":[],"10908858":[],"10913":6,"10931453":[6,33],"10960":9,"10994958":[],"10995472e":[38,39],"10e":39,"10th":9,"10x":[0,31],"11":[0,2,5,6,7,8,9,10,11,12,13,15,16,21,24,25,26,27,28,29,30,31,32,33,34,35,36,37,39],"1100":28,"11006373":28,"1101":28,"11022302e":[5,37,38],"11042239":[],"11052859":[],"11081083":[],"1108407":[],"111":[1,7,12,35,37,38,39],"11100":9,"11113486":[],"111135":[],"1112416":28,"11129947":[],"11131389":[],"11147544":[],"11163239":[],"11164003":31,"11171148":[],"1118933":[],"11202337":34,"11204514":[38,39],"112383":[11,32],"1124":9,"112619":[],"11261935":[],"11265643e":[],"11277166":[],"112772":[],"11320323":28,"11320726":[],"11382896":33,"11388888888888889":1,"11390":9,"11416086":24,"11433693":[],"114384":[],"11438414":[],"11439407":[],"11449867":28,"114550":34,"11462415":5,"11482289e":[6,33],"1148541":[],"11507992e":[1,39],"115356":[],"11535632":[],"11547777218872497":[6,34],"11548661":[],"11570114e":21,"11571507":[],"115822":6,"1158848":[],"11590":9,"11596834":[],"11597515":[],"11620886":[],"11660":9,"11666666666666667":1,"11675128":24,"11683558":[],"1169204":31,"1169242":[],"11692966":[],"11694":25,"117":8,"11715109e":[],"11725761":[],"11744554e":[6,33],"11747908":[],"11780":9,"118":[0,2,7,35],"11822173":[],"11830757":33,"118318":32,"1184":34,"11840":9,"11844773":[],"11861803":31,"11868033":[],"11890":9,"11891833e":[],"119":[0,2,7,35],"11922031":[],"11930916":[],"11935351":24,"11969984":[],"1198891":[],"11992194":[],"119922":[],"119936":2,"12":[0,1,2,3,4,5,6,7,8,9,11,12,21,22,24,26,28,30,31,32,34,35,36,37,39],"120":[0,2,3,7,35],"1203":9,"1203284":8,"120435":[],"12043521":[],"12044974":32,"120450":32,"12068251":[],"12081773":36,"121":[8,9,10],"12123488":[],"121292":[],"12135727":[],"12155483":[],"1215pm":[29,31],"12166797":[],"12182967":[6,33],"122":[2,8,9,10],"12206013":[],"12206812":31,"12208052":28,"12220276":[],"12222222222222222":1,"12235593":[],"123":2,"12318726e":[6,33],"12329646":[],"12330033":32,"12333649":[6,33],"12363332":[],"123711":6,"12380":9,"12382443":[],"123928000581825":11,"124":[0,31],"12400":9,"1242":8,"124228866018077":[],"124325":[],"12466453":[],"12498355":[],"1251681":[38,39],"12534765":[],"12536737":36,"12544009":[],"12552073e":[6,33],"125757":21,"12591227":32,"126":9,"12600095":[],"1261":9,"12618549":5,"1265":9,"12667402":[],"127":4,"1271":6,"12733892":[],"12777777777777777":1,"12790":9,"128":[3,4,13,36,37],"12829994e":[],"12840176":21,"12846660e":[],"12871842":32,"12873424":[],"12893778":[],"129":6,"129012":6,"12922837":[],"12952339":33,"12957454":[],"1297":9,"1298":9,"129963":34,"12it":[],"12pm":[29,31],"13":[0,2,5,6,7,9,11,12,18,21,24,26,28,31,32,34,35,36,37],"130":9,"13003291":[6,33],"13009402":[],"13024288":[],"13035147135400782":[],"13037395":[],"13040489":[],"13055555555555556":1,"13055762":[],"13059483":0,"130694":32,"13069442":32,"131":9,"13107995":[],"13134148011170077":[],"13137881":[],"131379":[],"13152828":[],"13164176":[],"132":9,"13217667":[],"13220608e":[6,33],"1325":6,"1326":9,"13260573":[],"1326197715":31,"13280":9,"13298019":24,"133":[7,35],"1332":34,"13337992":[],"134":33,"13437168":[],"134534":5,"13453411":5,"13455019":31,"13457622":[],"135":9,"1350":34,"13531906":[],"13535942":[6,33],"13564988":[],"1356995":[],"136":[0,7,35],"13600596":[],"13607502":[],"13646574":5,"13659941":[],"13661243e":[6,33],"13663125":[],"13675593":[],"136756":[],"13679863":[6,33],"13684661":[],"13699574":[],"136996":[],"137":[0,7,35],"13729154":[],"13738633":[],"13740":9,"137652":[11,32],"138":[0,7,35],"13819592e":[],"13820":36,"13825388":[],"13845051":[],"13847167":[],"1385":6,"1385510301651882":[],"13865173":5,"13866942":[],"138775":[11,32],"13878649":[],"1388888888888889":1,"13890":9,"13896095":[],"139":[0,6,7,35],"13911934":[],"13913033":[],"139224":[],"1392559585020426e":[6,33],"139255958997547e":[6,33],"1393548":[],"13945974":[],"13956654":[],"13it":[],"14":[0,2,4,5,6,7,8,9,10,11,12,21,22,24,28,30,32,34,35,36,37],"140":[0,2,7,9,35],"14021063":[6,33],"14046224e":[],"14084366":[],"141":[0,2,7,35],"14100":9,"14104212":[],"1412":[21,36,37],"14122256":[],"1416398":[6,33],"14174745":[6,33],"1418":9,"14187173":[],"142":[0,7,9,35],"14213876":[],"1424112":[],"14249052":24,"14250":9,"14260706":[],"14277718e":32,"143":[0,2,7,9,35],"14309433":[],"14369927":[],"1437":[1,39],"14373934e":[38,39],"144":[0,7,35],"14400":9,"14404536":[],"1440501043841336":[1,39],"1441031":[],"14433067":[],"14437776":[],"14440":9,"14452678":[],"1446729567":4,"145":2,"14523337e":[],"14550854":[],"145509":[],"14568914":33,"14599499":[],"146":2,"14605929":[],"146141":6,"14629156":34,"14638":36,"14643345e":[],"14708":[],"14710":9,"14716":6,"14721582":[],"14722222222222223":1,"147400":[11,32],"147420":[11,32],"147545":[],"1477190177681485":[],"147836":[],"14783612":[],"1479":9,"148":[3,4,14],"14812206":6,"14815202":[],"14824254":[],"14825560e":[],"14828178":[],"14829228":[],"14841322":[],"148776":6,"14880915":[],"1488598":[],"14890012":[],"149063":[],"149111":34,"14913555":[],"149266":[],"14934258650797513":[],"149353":[],"149388":[],"149433":[],"149466":[],"149483":[],"14949972":[],"149904":[],"149921":[],"14g":[6,34],"14it":[],"15":[0,2,4,6,7,8,9,12,13,15,16,17,21,28,31,34,35,36,37,38,39],"150":[3,4,8,9,14,22],"15005476":5,"1502":38,"150527":[],"15079545":[],"15098090e":[6,33],"151":[3,4,14],"15126318":[],"15130074e":[6,33],"151522":[],"15173932":[],"152":9,"15200":9,"15202654":[],"152149":6,"15215415":[],"15242624e":[],"152494":[],"1527777777777778":1,"15283463":[],"153":[3,4,14],"153036":32,"15313054":34,"15351626":[],"15361856":[],"15384615384615385":9,"15388662":24,"154":[3,4,14],"15422927":28,"1547556":[],"15489318":[],"155":[3,4,9,14],"15527976":[],"15546887":[],"15593478":[],"156":[3,4,14],"15605625":[],"15670921":36,"1567286":[],"15690073":21,"156956":5,"157":[3,4,14],"15709522":[],"157128":[],"1571284":[],"1575":9,"1575046":[],"15751952":[],"1576057":31,"158":9,"15830902":[],"15833751":[],"15847501":[],"1587":9,"1590":9,"15924557e":[],"15951871":36,"15970814":[],"1598058":[],"15990":9,"15991124e":[],"15am":31,"15g":[6,34],"15it":[],"16":[1,2,3,4,5,6,8,9,10,19,21,22,24,28,31,32,33,34,36,37,38,39],"16013842":[],"1602625":[],"1603":3,"16039162":[],"16063661":[],"16111111111111112":1,"16118615":[],"16158074":[],"161581":[],"16172219e":[],"16180248":[],"16188604":[],"16201555":[],"16209264e":[],"16211139":5,"16220":9,"162246":5,"16231451":4,"1625":9,"16257872":[],"1628":9,"16292908":[],"16304863":32,"163049":32,"1630775253":1,"16312434e":[],"16342407":5,"16343471":[6,33],"1636508":[],"16384":3,"16407038":[],"16411163":[],"164112":[],"16413938":[],"16431956":[],"16437294":[],"16445858":[],"16469725":[],"16486151":[],"16500":9,"165272":[],"16532977":[],"16535252":[],"16567361":[],"166":9,"1660497e":37,"16617445":[],"1664372":[],"166540":[],"16654048":[],"16710567":[],"16744759":[],"16777789":[],"167787":5,"16791183":[],"168":9,"16805821e":[6,33],"16879134":[],"16925937":24,"169299":31,"17":[1,2,5,6,7,8,9,13,21,28,32,34,35,36,37,38,39],"17021424":[],"1709":9,"171":33,"171525":32,"1715252":32,"17168028":[],"17174962e":[1,39],"17214545":[],"17214797":[],"17222222222222222":1,"17222494":[],"17249725":[],"17253354":[],"1726":9,"17260271":[],"17272182":[],"173":[21,37],"17300":9,"1731":9,"1732863504708044":[],"17359583e":[],"17367225":[],"17377547":[],"17405911e":[],"17418673":31,"17446471":6,"17483760":34,"175":34,"17501258":[38,39],"1752":9,"175300":32,"17547294e":[],"17563274":[],"17567503":[],"17641709":[6,33],"17643975e":[],"17669259":[],"176762":[],"17676247":[],"1767857":[],"17739525":[],"17748881e":36,"17757295":[],"17777777777777778":1,"177786562639708":28,"17801022":5,"17801827":[],"17806281e":37,"17827738":[],"17834506e":[],"17856374":[],"17861098":6,"17861414":[],"17865868":24,"17869861e":[],"179":[],"17913653":[],"17917768":5,"1792":6,"1793417":[],"17934801":[],"17949575":5,"17953942":11,"17968231":[],"1797":[1,3,39],"18":[2,6,7,8,9,10,13,21,22,28,31,34,35,36,37,39],"180":[],"1801709":33,"18019623e":[],"18029127":5,"18043393":[],"1807":4,"1808228":[],"18085537":[],"1809":9,"18093549":[],"18094575":[],"181":9,"1810415856976313":[],"18118338":[],"1812":9,"18120973":[],"181210":[],"18147009":[],"181766185664273":[],"182086698929565":[],"1821":9,"18234308":[],"18277213":[],"18285689e":[],"18307821":33,"18333333333333332":1,"18383522":32,"18388":6,"184":9,"1840":34,"18409254":[],"18418938":[],"184519":32,"18485685":[],"184866696796263":[],"18497496":[],"184975":[],"185":33,"18501900e":[],"18510775":[],"18522369":[],"18551655":[],"1860":9,"18611111111111112":1,"18613217e":[6,33],"1863889":[],"18646225":31,"18660":9,"18670072e":32,"18673098":11,"18702469":[],"18711407":[],"18712313":31,"18742521":[],"18816387":[],"18824338":[],"18840034e":[],"18925625":[],"189496":32,"18956157":[],"189622":32,"18it":6,"19":[2,6,9,15,21,28,31,34,36,37],"19001247":24,"19009085621304586":[],"190529":[],"19052935":[],"19069576e":36,"19126179":[],"19166666666666668":1,"19180036e":37,"191833":[],"192":34,"19207979":5,"19220":9,"19299283":[],"19336703":24,"19371605e":[38,39],"1940":0,"194042826649355e":[6,33],"194042826815211e":[6,33],"1943":[12,37,38],"19433318":[],"1944":6,"19547923":[],"19559737e":[],"1956":9,"19569961":[6,32,33],"19583547":[],"19588651":36,"19661197":36,"19677112":[],"1970":[24,31],"1973":9,"197370":[11,32],"19740":9,"1979":[6,34],"19791352":[],"197914":[],"19800":9,"19848482":28,"19849513":[],"19852045":[],"1989":38,"1991":38,"19920353":[],"19945294":24,"19951849":[],"199824":11,"19982428":11,"1999":26,"1_1":[12,37],"1_2":[12,37],"1_3":[12,37],"1cm":[0,8,10,28,31,38,39],"1d":[1,2,3,39],"1e":[1,2,4,13,14,21,36,37,39],"1e10":14,"1e4":6,"1f":[1,39],"1k":24,"1n":[0,31],"1s":39,"1x":[0,31],"2":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,21,23,24,25,27,28,30,34,35,36,37],"20":[0,1,2,6,7,8,9,13,19,21,28,29,31,33,34,35,36,37,38,39],"200":[0,2,3,4,8,9,10],"2000":[0,32],"20015436":6,"20020163":[38,39],"2004":[13,35],"20051449":[],"2006":30,"2008":31,"2010":[1,38,39],"2011":[1,39],"20135691":[],"2014":4,"2015":[1,39],"20158083":[],"201581":[],"2016":[0,31],"20173175":28,"2018":[0,6,32,34],"2019":[8,9],"2021":[6,14,32,33,35],"20218457":[],"2022":[26,31,38,39],"20224027":24,"20228273":[],"2023":[25,39],"2024":[15,16,17,18,19,20,21,22,26,31,32,33,34,35],"202698":[],"2026985":[],"2027":9,"20277777777777778":1,"20288581":[],"20300793":31,"2032806":31,"20336784":[],"20347912":[],"20357736":[],"20367355":[],"20375464":[],"20393534":[],"204049":[],"20404927":[],"20480187":[],"204802":[],"20500":9,"20519189":[],"20527785":31,"20539421":28,"2060":9,"20601797e":[],"20608548e":[],"20651434":[],"206664":[],"20666447":[],"2069":9,"2072382":[],"20728198":[],"207545":[11,32],"20755569":[],"2077068":[],"20775115":[],"20833333333333334":1,"20834188":[],"2084894":[],"20867052175034223":[6,34],"20867716":21,"20912557":[],"20916295":32,"20980":9,"21":[0,1,2,5,6,7,9,12,13,21,24,28,31,32,34,35,36,37,38,39],"210340":[11,32],"21058097":5,"21061589":31,"21070843":[],"21093775":6,"211":[],"21130":9,"2116753732":4,"21169159e":[6,33],"21181534":24,"21192602e":[],"212":[],"21277816e":[],"213":[],"213103":[11,32],"2131067":[],"21332621":[],"21333766":[],"21344077":[],"213743":[11,32],"21390371e":[],"21392756":[],"2142385":[],"21430643e":36,"21444055":[],"21457724":[],"21517262":6,"21531156":[],"21565007e":[],"21596432":6,"2160073466353432":[],"216290":[11,32],"21631786":[],"21635399":24,"21641173":24,"21655059e":[],"216683":[11,32],"21680864":[],"21699817":[],"21752693":[],"21776599":[],"21805426":[],"21813899e":[],"21817966":[],"21833102":24,"21941484e":[],"21949761":[],"21998973":[],"22":[0,1,2,5,6,9,12,13,21,24,28,31,32,34,36,37,39],"22013655":[],"22044605e":[5,32,37,38],"221":8,"221180":32,"2212296":[],"22128142":[],"2216":9,"221666864828611":[],"22169087":[],"2218":9,"221805":2,"221921":5,"22217237e":[],"22226881":[],"222400":32,"22370461988004753":24,"22388052":[],"22467274":34,"22481166":[],"225":4,"22528536":[],"2257449":[],"22592946e":[],"226014":[],"22601408":[],"22623421":[],"22667819":[],"22688898":[],"22690428":5,"22706777":24,"22715479":24,"22755839e":[],"22756518":[],"22809974":28,"22810365":[],"228104":[],"22835717e":37,"22842468702219465":[6,34],"2284246870221947":[6,34],"22847924":5,"22849742":[],"22871":36,"22897303":[],"22919456":[],"2293":[],"2294":[],"22946401":31,"2296":[],"2297":[],"22977659964799":[],"2297766":[],"22it":[],"23":[1,2,6,9,12,15,20,21,24,31,34,37,38,39],"23002365e":[6,33],"23007231e":[38,39],"23040825":[],"23076923076923078":9,"23077255":[],"23093598e":[],"2311959":31,"23139242":[],"23164401":[],"23167717":5,"232435":32,"23262877":[],"23303727":[],"23333333333333334":1,"23344210e":[],"2338675":32,"233868":32,"234":6,"23407025":[],"23423987":[],"234332597247826e":9,"234496":[],"23449607":[],"23472994":[],"23481471":[],"23499549":[],"23499891":24,"2351":6,"23526911":[],"23528337":34,"235969":[],"23596934":[],"23616967":[],"2364":9,"23663482":[],"2373286546935638":[],"23794815":[],"23847441":[],"239":34,"23950884":[],"2397":9,"23971032":32,"23994188e":[],"24":[0,1,2,6,9,21,24,28,31,34,36,37,39],"2401":25,"24032019":[],"24071032":[],"24106503":36,"24140":9,"24149532":31,"24159785":32,"2416":9,"24175744e":[6,33],"24185931":[],"2419":9,"24224776e":[],"24225043":[],"24254071":[],"24284399":[],"2430":9,"24335376":37,"24344979e":[],"24346138":[],"24369936":[],"24377554":[],"243776":[],"24390":9,"24398826":[],"244293":5,"24429334":5,"24433117":[],"24444444444444444":1,"24454968":[],"24485814":36,"24493666":34,"245781":5,"24578123":5,"24582593":24,"246":2,"24602146":[],"24613581":[],"24640494":36,"2468382":28,"24688853":[],"24692014":[],"24719968":36,"2475908482537097":[],"24759085":[],"24768421e":36,"24780663":[],"24816468":[],"2481902":[],"24829908":5,"24856992e":[],"24906604e":[6,33],"24999088":[],"24it":[],"25":[2,3,4,5,6,8,9,11,21,25,32,34,36,37,38],"250":[2,4,7,9,35],"25000":0,"25003261":[],"25018094":[],"25068519":31,"25111821":[],"25185716":33,"251879":32,"252008":[],"25200841":[],"25233253":[],"252333":[],"252436":32,"25294371":31,"25337053":[],"25343155":34,"25354173":[],"25386687":[],"253891":[],"25389111":[],"25458506e":[],"2546186":[],"254619":[],"2546817701709956":[],"255":3,"255001":32,"25512598":[],"25555619":[],"256":[2,4],"25617655e":[6,33],"25617658e":[6,33],"25646067":31,"25659561":28,"25673276":[],"256733":[],"25680702":31,"25695398":34,"257":34,"25705685":[],"2572":9,"25729558":[],"2575":9,"25816519":24,"25849623":[],"25879315330607":[],"259153":[11,32],"2597":9,"25970297":[],"25986026":[],"25989189":[],"26":[2,6,9,16,21,34,36,37],"26001134":[],"26024513":21,"26048873":[],"26083712":[],"26113912":[],"26120167":[],"26124692":6,"26128189":[],"26152075":[],"26254957e":[],"262648":[],"26264849":[],"26280614":36,"26281735":36,"26292364":34,"26297455":32,"26301436":5,"26307235":[],"2630723514841553":[],"26321660e":[],"26378176e":[],"26402837":[],"26409315307910025":[6,33],"2640931530791004":[6,33],"26464303e":[],"26479234":[],"2650":9,"265109911":4,"26527089":[],"26536626e":[],"2654":9,"265868":[],"26586817":[],"26604611":37,"2662452":[],"26639089e":37,"26646852":[],"2666905":[],"26674792":[],"26680052":[],"266801":[],"26692247":[],"26710969":5,"26715191":[],"26775644":[],"26780278":5,"2679757":[],"268":9,"26814548":6,"26817703":[],"26821199":[],"2694078":[],"26995402":32,"27":[0,1,2,6,20,21,34,37,39],"27037635":31,"27065633":33,"27108866":24,"27124938":[],"271260217275557":[],"27126022":[],"27182417":[],"27186049":28,"27227895":21,"27231287":[],"2729933":[],"27336592":[38,39],"27352535e":[],"27403356":24,"27425372":[],"274394546800107":28,"27439455":28,"27458376":36,"27470622":36,"27482829e":[],"2750":9,"2751616":[],"27530242":24,"27597777e":[],"27600259":[],"27602210e":[],"27623637":[],"276263":[11,32],"27633474":[],"2765068":24,"27693602e":[37,38],"27698328":[],"27700":9,"27750534":[],"27760":9,"2781456":[],"27861634e":[],"27924636":5,"27933134":[],"27it":[],"27n_":28,"28":[1,2,3,4,6,9,21,34,36,37,39],"28000355":[],"280004":[],"28021598":[],"2802234e":37,"280464e":[],"280573":5,"280647":[11,32],"2809076":21,"28093636":[],"28109198":[],"2813829":[],"28164443e":[],"28183460e":[],"28205578e":32,"28225179":[],"2822642":[],"28244905":21,"28253033":[],"282727":[11,32],"28276275":[],"28306304e":[],"2830637392":4,"28316949":[],"28336218e":[6,33],"28358004":[],"28364423":[],"28390":9,"28391978":32,"28399125":[],"28415767":[],"28443039":34,"28457291":[],"28475098":8,"28496213":[],"28542801":[],"2861":28,"28614301":24,"2863391":31,"28709718":[],"2871":9,"2873":9,"2876045":[],"28766899":[],"28776411":[],"28793787":[],"2882":28,"28844641e":37,"2885519":[],"2886":28,"28886314":37,"2890":[0,31],"28902948":[],"2890577":28,"2892":28,"28923":[],"28956161":[],"2895786617507":[],"28it":[],"29":[2,6,9,21,34,36,37],"29015871":[],"29033075e":[],"29078236":24,"29100624e":[],"291056":[],"2915":28,"29162184":[],"29167186":5,"29223521":[],"29234681":37,"29238145":[],"29253213e":[],"29306584e":[],"2931":31,"29350":36,"29390668":[],"29398019":[],"29474356":24,"29491144e":[],"29541992e":[],"29560433":[],"29593305":31,"29620357":[],"29627774":[],"29633608":[],"29653038":36,"2965315":[],"29669411":37,"29678339":37,"2968":31,"297648":[],"29764815":[],"2976637":[],"2980":31,"298037":[],"29803738":[],"29822833":[6,33],"29860173":36,"2986082":[],"29861395":[],"29881308":[],"2990":31,"29902518":[],"29950088":36,"299748":32,"29it":6,"2_":[12,37],"2_1":[12,37],"2_2":[12,37],"2_3":[12,37],"2_i":[12,37],"2_m":[6,28,34],"2_t":[13,36,37],"2_x":28,"2b":28,"2c8f433990d1":[36,37],"2cm":8,"2d":[1,3,11,12,23,31,37,38,39],"2e":[6,34],"2f":[0,7,9,10,11,12,31,32,35,37,38],"2g":2,"2g_i":2,"2k":3,"2m":[6,34],"2n":[0,2,3,31,32],"2nd":[9,37],"2p":[28,38],"2pm":29,"2pt":4,"2x":[0,3,8,13,31,36,37,38],"2x_ix_jy_iy_j":8,"2x_j":8,"2xb":38,"2y_i":10,"2y_j":8,"3":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,21,23,24,25,26,27,28,29,33,34,35,36,37],"30":[0,1,2,4,6,7,9,10,13,16,21,29,32,34,35,36,39],"300":[21,37,38],"30000":[0,31],"30000613":[],"30005983":[],"30010":9,"30013135":31,"300231":[],"30023144":[],"30043041":[],"30069427":[],"30117681":[],"30119421":8,"30124108":[],"30134885":[],"30141906":[],"30190897":[],"301909":[],"302":34,"30258509":[24,31],"30269539":[],"30283188":33,"303":6,"30306759":36,"30334592e":[],"30387411e":[],"30400113":[],"30442002e":37,"30442964":32,"30450049":21,"30466214e":[6,33],"30493151":[],"30506075e":[],"30607268":36,"30637636":[],"3072":3,"3075371":24,"3076923076923077":9,"30787294":6,"30894285":24,"30915293":[],"309153":[],"30916402":[],"30916988":[],"309170":[],"30917499e":[],"30940":9,"3096154":[],"30982436":[],"3099":34,"30it":[],"31":[2,12,24,28,37],"31008026":[],"310579":32,"3105791":32,"310957":[],"31095745":[],"31096156":[],"31160886":[],"31162122":[],"31175179":36,"312":33,"31227657e":[],"3123314713548606":[6,34],"31248425":36,"31276579e":[6,33],"31286143":[],"313":33,"313155":[],"31315504":[],"31318084":5,"31362428":[],"31363366":[],"31367041":[],"31381731":21,"31453949":[],"31457796":5,"314869":[],"31486917":[],"315":[6,33],"31541884":[],"3155":[0,5,6,33,34,35],"31555734196707536":[],"31571995":[],"316":33,"31601423":[],"31607059":28,"31664443e":36,"31702609":[],"31718909":11,"31727523":[],"317367":11,"31758645":[],"317799":5,"31779928":5,"31812561":[],"31849289":[],"31876431e":[],"31896852":8,"31897935":37,"31936237":[],"31938579":28,"3194467":[],"31it":[],"32":[0,2,3,4,6,8,12,13,24,28,36,37],"3200":[1,39],"32003025":[],"32007041":[],"320656":[],"32065614":[],"32068736":[],"3207":34,"32084559e":[],"32149601703519115":[6,34],"3214960170351912":[6,34],"3215":9,"32265127e":37,"323059":[],"32305911":[],"323184775146844":[],"32318478":[],"32393078":[],"324":2,"32411274":21,"32419549":[],"3241988":[],"32422234e":[],"3245":2,"32450054":32,"3250":[1,39],"32513272":28,"325228546249804":[],"32522855":[],"3260513":[],"32606139":[],"3262":6,"326238":32,"32641434":[],"32651488":[],"32683063":[],"32684035":[],"32717946":31,"32733949":[],"32738537":31,"32798457e":37,"32799141":[],"3280928":[],"328093":[],"32825214":[],"32906581":[],"32932635":[],"32941912":[],"32972613":28,"32it":6,"33":[2,9,12,24,29,37],"33000573":[],"33006628":[],"33025801":[],"33045013":21,"33049619":[],"33062878":[],"330629":[],"33066907e":[5,32],"33095972":31,"33096549":[],"33107417":[],"331075":[],"33145794":[],"33149531":[],"33163086":11,"331631":11,"33166055e":5,"331939":32,"33212971":[],"33217312":[],"33220123":[],"33235647":[],"33241952":[],"33266422":[],"333":[7,35],"33329216":37,"33435637":24,"33477019":[],"33528448":[],"33532886":[],"33596404":[],"33615742":[],"33675308":[],"33734605":[],"33742926":[],"33826500e":[],"3388112":[],"33978889":36,"33it":[],"34":[2,9,24,37],"340071371496255":32,"34023682":5,"340237":5,"34026086":[],"3403":9,"3404509":5,"34061974":5,"340620":5,"340782":[11,32],"34098895":24,"34112554":31,"34114547":5,"34131583":31,"34134773":24,"34139775e":[38,39],"34182884":[],"34225662":[],"342680":32,"34271514":[],"34332677":[],"34346829":[],"3436":[0,31],"34367970":6,"3437":[0,31],"34412923":32,"344176915013831":[],"34427423":[],"34478594":31,"34483937":[],"34483955":[],"34568909":[],"34569596":5,"34569632":[],"34577375":[],"34582863":37,"34598722":[],"34599467e":[],"34599598":[],"346000154268618":[],"34620097":[],"34654596":[],"346546":[],"34661376":[],"346614":[],"34704885":24,"34726166":5,"347262":5,"34759233":[],"3480527":[],"34862407":37,"34871778":[],"34904819":[],"35":[0,2,6,17,25,29,31],"3500312e":37,"35018806":[],"35098705":[],"35140":9,"3514835":[],"351636":[11,32],"35182854":5,"35196964":[],"35243372":[],"35275513":[],"35320952":[],"35354073":[],"35388766e":37,"35432563":[],"3544313922":6,"35468713e":[],"35470445e":[5,32],"35506347e":[],"35520169":[],"35533773":6,"35537114e":[],"355734685106391":28,"35587321":[],"35613536e":[],"356399":32,"356673":[],"35667342":[],"35689303":[],"35713539":37,"35714377":[],"35731585":[],"35736":36,"357508":32,"3577615":[],"3581341341":4,"35823372e":[],"35870701":[],"3587467":24,"359":[5,33],"35957915":[],"35966688":[],"35980374":[],"35986305":[],"35it":[],"36":[0,2,5,6,25,28,38,39],"360":[1,39],"36014743":37,"36091273":[],"3613":9,"361541":[],"36154104":[],"361556":32,"36161658":31,"36185989":[],"3621311":5,"36219301":37,"36235052e":[],"36255393":28,"36278226":37,"36303682e":[],"3632959111950474e":[6,33],"363295916366933e":[6,33],"36339156":[],"36353321":[],"36401981":[],"36482524":[],"36545697e":[],"3655222":5,"366375489616074":[],"367":[2,9],"36754671":[],"36841864":31,"36880327":[],"368818":11,"36881837":11,"36895644":34,"369139":[11,32],"36it":[],"37":[2,9,25,35,36,39],"37007195":21,"37013105":[],"37055062":[],"37057274":[],"370782966":4,"37093787":[],"37135473":[],"37137157":31,"37153115":[],"37175575":36,"37175588":21,"37180834e":37,"37215356":37,"37239927e":32,"37255873":[],"3727791":[],"37354121":[],"37396662":[6,33],"37415625e":[],"37449168":[],"37454707":[],"374675":[],"37467515":[],"37507799e":[],"37532078":[],"37582891":[],"375829":[],"37600869":[],"37685349":[],"37700967e":[],"37717637":31,"377372":32,"37737221":32,"3777801602":6,"378271":[],"37827145":[],"37837864":[],"37900111":[6,33],"37919989":[],"38":[2,9,25,28,39],"380":9,"38102552":[],"38123077":[],"38135733e":[6,33],"3817475779":[6,34],"38198866":[],"38203725":[],"3824865":21,"38259084":36,"38298234e":[],"38337498":[],"38381781":[],"38399622":[],"38440469":[],"38445171":[],"38460453":[],"38461538461538464":9,"38461539":36,"38592549":[],"386":9,"38612299e":[],"386161":[],"38616125":[],"38618024":[],"38629436":[24,31],"387":34,"38713573":24,"387620":[],"38762019":[],"3882273":[],"38827994":6,"38865681e":[],"38916861e":[6,33],"3892":34,"38934047":[],"38962192e":[6,33],"38992371":[],"39":[0,2,9,26,29,31,37,38],"390334838933238":[],"39033484":[],"39039235":[],"3908470004999506":[],"39090680e":[],"3910042":[],"39197698":32,"391977":32,"39214397":32,"392144":32,"39223923":[],"39279291":[],"39292847":[],"3939184e":[],"39398622":[],"394":9,"39517073":[],"39525059":[],"39540235":[],"39579407":5,"395980256477532":[],"39598026":[],"39614949":[],"39621036e":[],"39692815":[],"39706038":5,"397700":[11,32],"39789527":[24,31],"3983":6,"39855569":[],"39865452":[],"39914635":24,"39922082":[],"39929428":[],"39931051e":32,"39952356":[],"399836":32,"39991048":31,"3d":[2,3,4,6,13,25,34,36],"3f":[1,3,9,39],"3n":24,"3x":[2,8],"3x_0x_1":38,"3x_i":2,"3y":8,"3yk470mj5p931p9dtkk0y6jw0000gn":[1,6,31,34,39],"4":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,24,25,28,31,33,34,35,36,37,38],"40":[1,6,9,25,26,29,31,34,38,39],"400":4,"4000":[9,31],"40030606e":37,"40037367e":[],"40072098":[],"4008393":31,"40093324":[],"40140374":[],"401842":[11,32],"40184681":[],"40266454":[],"40354798e":[],"40415979e":[],"40418675":[],"404783":[],"40478305":[],"405":9,"4050":[30,31],"405163":5,"4051634":5,"40558184":[],"405890":[11,32],"405964":[],"40596423":[],"40605118":[],"40620066":32,"406201":32,"40632663":[],"4069157":[],"407":9,"408":9,"40800396":[],"40833375":[],"40848657":31,"4087":9,"4087793":5,"40927184e":[6,33],"40961688":31,"40it":[],"41":[2,9,24,26,39],"4107":9,"41146753":[],"4121966338442804":[],"41229845":[],"41259788":24,"41310208":[],"41366128e":[],"41396339":31,"41408221":[],"41433969":5,"41487642":[],"41511965e":[1,39],"41532521":[],"4155":[2,15],"4162706317":6,"41636775":[],"41664613":[],"4166666666666667":9,"41675053":[],"41744203":[],"41764479":[],"417644792969273":[],"41794469":24,"41820116":[],"41842093e":[],"41847686e":[],"418506":[11,32],"418656":31,"41869784":[],"41882037e":[6,33],"41925189":[],"419718":5,"41971814":5,"41987877":[],"4198932":[],"42":[1,2,4,8,9,10,24,26],"42013616e":37,"42083463e":[],"42095725":[],"42124182":[],"4215795":[],"42197297e":[],"42305151":[],"4230769230769231":9,"42310878":[],"423646":[],"42364634":[],"42392359":[],"424274":[],"4242743":[],"42441033":5,"42450":9,"42497724":[],"42553096":[],"42575338":[],"42592679":31,"426":[6,9],"42644801":[],"42699034":[38,39],"42774546":[],"42793344e":[],"42873361":[],"429":34,"42945319":[],"43":[0,1,2,7,9,24,35],"43054282":5,"4310":31,"433":34,"43330971e":[6,33],"43373107":[],"435163":32,"43563433":[],"43579948e":[6,33],"43639284e":32,"436462435":4,"43703545":[],"43724406":31,"43727575":[],"43766686":11,"43779698e":[],"438060758":6,"438136":32,"439230":6,"43962226":[],"43976975777097144":[],"43984553e":[],"43it":[],"44":[0,1,2,24],"44089210e":[5,32],"441":[3,4,14],"442":[3,4,14],"44239442":28,"44255455":[],"442600":[11,32],"44286735":[],"443":[3,4,14],"443217":32,"44395301":33,"444":[3,4,9,14],"44418124":36,"44454123":[],"445":[3,4,14],"445128":24,"44536331":[],"44563226":[],"446033":34,"44624525e":32,"44658658e":[],"44767398":[],"4477214":[],"44830934":[],"44838546":[],"44867801":[],"44970586e":[1,39],"44995924":[],"44it":6,"45":[0,2,9,29,31],"450":9,"450257":[11,32],"4504":9,"45053025":[],"45054585":28,"45193407":[],"45430236":[],"455173":34,"45560415":[],"45568883":28,"4557763":11,"455947":32,"456":9,"45620975":[],"457":2,"457311":[],"45731144":[],"45731379":[],"4576811":[],"45781905e":36,"458027":32,"458078":[11,32],"4580854":[],"4591127":[],"45915671e":32,"45960079":5,"45it":6,"46":[2,9,29,31],"460":[9,11],"4601":9,"46065811":[],"46069873e":37,"46086448":[],"46107913":[],"46134248e":[],"46153846153846156":9,"46170878e":36,"4619526":[],"462":[7,35],"462295":5,"46229544":5,"46318204":[],"46342934":[],"4635149":[],"4636751":24,"46383925e":[6,33],"46383926e":[6,33],"46387965":[],"46415522":[],"46415888336127775":33,"46544987":[],"46593404":[],"46660941e":[],"46713267":33,"46736215":34,"4676059":32,"467606":32,"46891823":[],"46911594e":[],"46954702e":[],"46963249":[],"46984559":[],"46984697e":[6,33],"47":[2,9,29,31],"47042744":5,"47051432":34,"47052809":[],"470714":32,"47075725":6,"47116868e":[6,33],"47125748":5,"47132891":5,"4725246793626128":[],"4729218":[],"47297587e":[],"47308061":24,"47313680":34,"47334547e":[],"4735968":[],"47433659":[],"4745474":[],"47478922e":[],"47609206":32,"47610036":6,"4761747":[],"47729832":[],"47757553":[],"47815203":11,"47823856":36,"47892661":[],"47910545":[],"479465113":4,"47989224":[],"47991892":[],"47it":6,"48":[2,9,34],"48004784":[],"48062913":[],"48151166":[],"48170743":[],"481979":6,"48200792":[],"48233952":[],"48257387":[29,31],"48268005e":[],"48306473":[],"48307405":[],"4831139":[],"48326853":[],"48399942":[],"48420061":[],"4843772":[],"48441798":21,"48476997":11,"484905":[],"48490503":[],"48494803":33,"48511333":31,"48521055":[],"48697869":[],"486979":[],"4870934":[],"48786826e":[],"48826894e":[],"48827791":[],"48843174e":[],"48867802":[],"48900413":[],"48931464":[],"489315":[],"48994188":5,"48it":[],"49":[5,6,9,11,25,32,36,37],"49074536":[],"49077038e":37,"49123502e":[],"49152":3,"49156266e":[],"49211524":[],"49224801":[],"49285045e":[],"49312535":31,"4937346":[],"49381549":[],"49392067e":[],"4940954":[0,31],"49470005":[],"49513019":[],"4951301940723654":[],"49584063e":[],"4959161509357395e":[6,33],"4959161509366685e":[6,33],"49608088":[],"49611541":[],"49761526":32,"49897504e":[38,39],"4990":28,"49910481e":[],"4992":28,"49939493":[],"499394932852416":[],"4997":28,"49it":[],"4c4c7f":[9,10],"4d":3,"4f":6,"4pm":[29,31],"4y":8,"4y_i":10,"5":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,21,24,25,28,31,32,33,34,35,36,37,38,39],"50":[1,2,3,4,6,7,8,9,10,13,21,31,32,34,35,36,37,38,39],"500":[1,3,4,6,9,10,13,34,35,36,37,39],"50000000e":[37,38],"50000455":5,"50000553":5,"50000718":5,"50000855":5,"50000969":5,"50001063":5,"50001142":5,"50001207":5,"50001261":5,"50001306":5,"50001343":5,"50001374":5,"500014":5,"50001414":5,"50001422":5,"50001439":5,"50001454":5,"50001466":5,"50001476":5,"50001485":5,"50001492":5,"50001498":5,"50001502":5,"50001506":5,"5000151":5,"50001512":5,"50001515":5,"50001517":5,"50001518":5,"50001519":5,"50001521":5,"50001522":5,"50001523":5,"50001524":5,"50001525":5,"50100007":24,"5018":28,"5020612":[],"50227564e":[6,33],"50233673":31,"50258788e":[],"502698":[],"50269821":[],"50306335":[],"50321091":5,"50327198":[],"50352245":31,"50427787":34,"50482139":[],"50516278":21,"50530832":34,"506":0,"50600514e":[],"50610071e":36,"506553":32,"50655336":32,"50655379":5,"50667812":[],"50714096e":[],"5076963":[],"507d50":[9,10],"50846111e":[6,33],"50846112e":[6,33],"50850373":[],"50887105":[],"50895251":24,"50911289":[],"50it":6,"50j":[13,36],"50x10":[1,39],"51":10,"510":[1,39],"5105332296929628":[],"51069279":[],"51104913":[],"51136852":[],"51154388":[],"5116375":[],"511888":5,"51262599":31,"51317506":[],"51364117":[],"51374050":34,"514219":32,"5142856":[],"51437058e":[],"51447004":[],"51512235":[],"51532469":24,"51546825":[],"51564682":[],"51611732":[],"51615779":31,"51643579":[],"51659846":36,"51709529":[],"51728978":[],"5177783846":4,"51808934e":[38,39],"51858116":[],"5187643":32,"51914183e":[],"51928402":[],"51937727":[],"52":[35,36,37],"52031552e":[],"52074297":24,"52087499":[],"521422502348998":[],"521558":[],"52155823":[],"52173381":[],"52211567":11,"522116":11,"5222222222222223":1,"52228066e":37,"5223261":24,"52284329e":[],"52301447e":[],"52317963":[],"52362157e":32,"52397611":[],"52407775":31,"52446101":[],"52480767":24,"5257011":[],"52573336":[],"52606333":31,"5260801":11,"52635761":[],"52654886":[],"52657934":[],"526744":[11,32],"52694246e":37,"52698542":[],"527024":5,"52702419":5,"52706754":[],"527068":[],"52732966":[],"52780600":34,"52789388":24,"52874252":5,"52876551":[],"52888979":[],"52927353":24,"52989287e":[],"52it":6,"53":[9,35,36,39],"5303329":11,"53052247":[],"5305555555555556":1,"53105728":[],"53125507":[],"531280":32,"53149078":[],"532":[],"5321613":[],"53269627e":[],"53285379":[],"532854":[],"533":[],"53312817":[],"534":[],"53480404":31,"535":[],"53512750e":[],"53534008":[],"53585173":[],"535852":[],"53629564":[],"53640693":[],"53684024":[],"537":[],"53703498":6,"53723188":[],"53729411e":[],"53732988":[],"53738247":34,"5378811":11,"538":[],"5384615384615384":9,"539":[],"539261":[11,32],"53942728":[],"53996947":[],"5399913":[],"53it":[],"54":[6,9,28,39],"540":9,"54011398":[],"54039921":5,"54041041e":5,"54057582":[],"54150298":[38,39],"541605":32,"54175461":36,"54222783":31,"5426270409877345":[],"543939":32,"54393936":32,"5443909":[],"544421":[],"544439":32,"54490887":[],"54637219":34,"54725976":[],"54760497":[],"54811237":[],"548263635652985":[],"54843215":[],"548432150659993":[],"54856099":[],"54873252":[],"54880148":[],"54921401":[],"54928947e":[38,39],"54935794":[],"54it":6,"55":[1,9,39],"55020405":[],"55020649":[],"55042779":[],"55094784":31,"551023":[],"55102329":[],"55179339":[],"55196383":[],"55225408":31,"55386681":[],"55460327e":[],"55542568":[],"5555555555555556":1,"55582742":[],"5567":6,"55688514":[],"557795":[11,32],"55838":36,"55854694":11,"55916434":[],"559791959661649":[],"55996153":[],"55it":[],"56":[1,9,39],"56033697":5,"560379":11,"56037913":11,"56042437":[],"56072658":[],"56102529":28,"56108455":[],"561410":[],"56141009":[],"56198284":5,"56342158":[],"564":9,"56408898":31,"56423957":[],"56423957069263":[],"564374":[11,32],"56453869":[],"56469864":22,"564759":[],"56475921":[],"56476512e":[],"565":9,"5653087":[],"56536":[0,31],"56541622e":[],"56589683":34,"566":9,"56636616e":[6,33],"567":9,"56763673":[],"56778296":11,"567783":11,"56783103":[],"56790195e":[],"568":[9,34],"56804783":[],"56832496e":[],"56857739e":[],"569":[1,9,39],"56912044e":[6,33],"56922102":[],"56939714":5,"56947078":[],"56965674":34,"56967917":[],"56977352":[],"56990537":28,"56it":[],"57":[0,8,9,29,31],"570":9,"57016227":24,"57080764":24,"571":[5,33],"571105947979344e":[6,33],"571105947979412e":[6,33],"57192197":[],"57201944e":[6,33],"57212292":28,"57252451e":[],"57261202":[],"57293306":24,"57331229":32,"5736973":24,"574465":[11,32],"57468142":[],"57492326":[],"57521514":[],"57584612":[],"575870409023631":[],"576":34,"5769230769230769":9,"57735536":[],"57803254":[],"57819238e":[],"57833531":24,"57847325":[],"57852915":24,"57881465":[],"57886743":[],"57914918":[],"57933547":[],"58":[9,10,29,31,39],"58013829":[],"58084123":[],"58202531":24,"58257727":[],"582987":11,"58298728":11,"5833333333333334":9,"583595":32,"58379362":[],"5847256":[],"58492636e":32,"58493493":[],"58493681":[],"58583003":[],"58589719":[],"58735893":[],"58827236":6,"5888888888888889":1,"58890784":[],"58914105":[],"589841":[],"59":[9,39],"59009792":[],"59030403":31,"59078383":[],"590784":[],"591317992":4,"59184268":[],"59188296":31,"59215613":[],"59244881":[],"592766658048914":24,"59348521":[],"59354079":6,"59355752e":[],"59372982":[],"59391196":11,"593912":11,"59411814":5,"594241":[],"59424119":[],"5944444444444444":1,"59465457e":[],"59491404e":[],"59630232e":[],"5965161e":[38,39],"59683811":[],"59698459":[],"59730078":[],"59741748e":37,"59779819":36,"598549916355722":28,"59854992":28,"59875207":[],"59884169":[],"59908884":[],"59963873":[],"59971727":[],"5cm":28,"5f":[8,36],"5x":8,"5y":8,"6":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,22,24,26,28,29,31,32,33,34,35,36,37,38,39],"60":[1,3,6,9,39],"60000":4,"60026673":[],"60041459e":[],"600529":[],"60052901":[],"60116388":11,"601164":11,"60151468":[],"60160003e":[],"6019067271":4,"60193996":28,"6029291":[],"60293962":5,"60321647":24,"60342978":34,"60375434":[],"6038642":[],"60418171":[],"60420593":5,"60451189e":[],"60543038":32,"60552651":[],"60570744":[],"60575887":24,"60588173":[],"60605083e":[],"60610368":22,"606251":[],"60625144":[],"60664448":[],"60673226":11,"606760":5,"60737006e":[38,39],"60762863":[],"6087346":31,"60921896":[],"60929685":34,"60940356":[],"60943791":[24,31],"60999067":[],"61":[],"61069681":[],"61083596e":[],"61106937e":[],"6111111111111112":1,"61113781":[],"61130099":11,"611301":11,"61192203":[],"61192712":[],"61209378e":[38,39],"612939":32,"61321722e":[],"61325173":[],"613579":32,"61382924":[],"613893902124586":[],"61395701":[],"61414743":[],"61468323":[],"614808":[11,32],"61501312":21,"6153846153846154":9,"61564092":[],"6156409232714415":[],"61602014e":[],"6161104":37,"61621902":[],"61774362":[],"61775176":34,"618746":[],"61883807":[],"618982":32,"61979664e":[],"62":2,"6200":31,"6201":31,"6202":31,"6203":31,"6204":31,"62113349e":[],"621584":[],"62158409":[],"62242138e":[],"62275788":36,"62286539":[],"62288579":31,"62323175":[38,39],"62351789":[],"62373464":11,"625":[7,35],"62551462":[],"62573269":[],"62617788":[],"62620041e":[],"626635268":[6,34],"626678":[],"6266783":[],"6267112":[],"62671667":[],"62714703":[38,39],"62716271":[],"62725226":33,"628":6,"62863106e":[],"62886648":[],"62894215":5,"62905281e":[],"62908496":[],"62918713":[],"62954328e":[],"63":[0,1,2,6,9,34,39],"63025821e":[6,33],"63030526":[],"63031478":[],"630315":[],"63037846":6,"63042739":[],"63046054":[],"63071772":[],"63142399":[],"63142731":[],"63162342":32,"63207408":[],"63209435":[],"63249532e":[6,33],"63307537":31,"63309898":[],"6333349473431832":[],"63347711":[],"63371136e":[],"63490568":[],"63498144":5,"63546236":[],"63555267e":[],"63615006":28,"63619709":[],"63693246":31,"63760101e":37,"63801791":31,"6380763200092493":[],"63833441e":[],"6383903":[],"63896182":[],"638962":[],"6389681":[],"63898112e":[],"63919355":[],"639194":[],"63980912":31,"64":[1,2,3,4,13,24,31,36,37,39],"64009263":[],"64012627":5,"6401576":[],"640567":5,"6405671":5,"6407249":[],"640x480":[6,13],"64192473":[],"64291046":21,"64316192":34,"64322974":[],"64361375":[],"64362404":[],"64373221":[],"64373635e":36,"64399916":[],"64411666":[],"64412879":[],"6441397":[],"64425744":[],"64505146":28,"64516328":[],"64564368e":[],"646283":[11,32],"64689773":24,"64713979":[],"64721597":37,"64742912e":[6,33],"647473":[11,32],"64796751":[],"64857542":[],"64885265":[],"649":[],"64909048":[],"64911288":28,"649382":[11,32],"64952115":24,"64976691":[],"64x50":[1,39],"65":[1,8,9,39],"650":[],"65082441":[],"651":[],"65183066":[],"651831":[],"652":[],"65243388e":[],"65259487":28,"65293772":[],"653":[],"6533977":[],"653398":[],"6536392":32,"654":[],"65410649":37,"65442354":32,"654424":32,"65475653":[],"65476419":28,"655":[],"65525178":24,"65532045":11,"65543115":[],"65554958":[],"65571174e":32,"65591748":[],"65593984":[],"65599456":32,"656":[],"65641173":[],"6568154596723088":[],"6568686180915178":[],"65686862":[],"65720152e":[],"6572612e":[38,39],"65738717e":[],"65743689":32,"65751456":31,"65759901":[],"658":2,"65833132":32,"65870313":11,"65885453":5,"65889641e":[],"65891389":32,"658914":32,"659":2,"65900052e":[],"65917558":[],"65944342":36,"65it":6,"66":[],"660":2,"66003032":31,"66018725e":[],"66063786":[],"66064822":32,"66080313":32,"66204648":6,"66215333":28,"662153330760193":28,"662836197064178":[],"66289235":[],"66294408":32,"6629598":[],"662960":[],"66342634e":[],"66363129":24,"66365453e":[],"6638":9,"664314":[],"66431407":[],"66456459":[],"66487438":[],"66498292":[],"6652177":32,"66560":9,"66575697":31,"6663569":[],"66694492":[38,39],"667":9,"6671767":[],"66729685":[],"66757105e":[],"66809369":[],"668172":32,"66841959":36,"6690108":[],"66951679":[],"67":9,"67015946e":[],"6702":[],"67047975e":[6,33],"67088558":[],"67100236":[],"67199457":31,"67231298":[],"67238764e":[],"672721":32,"672759":[],"67275915":[],"67313212":[],"67314874e":5,"67374815":[],"674":34,"67435043":[],"67464946":[],"67490857":36,"67495943":[],"67511113":31,"67524588":[],"67561021":[],"67819487e":[],"67834752":[],"67875366":[],"678754":[],"67925887":31,"67it":[],"68":[],"6801":[],"6805151":21,"68072161":[],"6809195":[],"680920":[],"68092237e":[],"68110474":[],"6816947":[],"68192193":5,"68257097":[],"68258595":28,"68281739":24,"68286725":32,"6831505":[],"68352799":[],"68402334":[38,39],"68534263e":[6,33],"68542204":5,"68591105":[],"68637642":[],"68640031":31,"68655456":[],"6869":9,"68735473":[],"68822559":[],"688226":[],"68824222":24,"68826552":[],"68827947":31,"68830164":24,"68857788":[],"6887363571":4,"68879472":[],"68929213e":[6,33],"689519":[11,32],"68953877":11,"689539":11,"68989446":31,"69":[9,28],"690":9,"690617":32,"69069n_":28,"69089532":[],"691":1,"691364":[],"69136414":[],"69182892e":[],"69227923":[],"69230769":36,"6923076923076923":9,"69247718":[],"6927554":[],"69303453":[],"693035":[],"69311221":24,"6932681":37,"69391797":[],"69417174":[],"69435454":[],"69438869":[],"69463406":24,"69465386":[],"69484813e":5,"69484973":31,"69504801":6,"69515531":[],"6955259":21,"69566966":[],"69634577e":[6,33],"69695259":5,"697346":[],"69734609":[],"69756791":[],"69768266":[],"6980":[21,36,37],"69824402":24,"6988905":[],"69903406":[],"69925648":24,"69978197":5,"699782":5,"69983227":[],"6999536":11,"69it":[],"6n_":28,"6pm":31,"7":[0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,21,24,26,27,28,30,31,32,33,34,35,36,37,39],"70":[1,6,7,9,35,39],"7002164":[],"70037324e":32,"70039784":[],"70135856":31,"701370":5,"70159137":24,"70241548":[],"7026722043092946":[],"7026908764394864":11,"7029975":[],"70301068":[],"70362677":[],"70408202":24,"70469324":[],"70474145":[],"70499955":[],"70514808":[],"70587399":[],"705946":[],"70594608":[],"70630967":[],"70653767":4,"70665448":[],"70704566":[],"7070883":[],"70710678":[5,32],"70711022":[],"7074705":[],"70811405e":[38,39],"70832814":5,"70857635":[],"7086067479626619":32,"70928399":[],"709284":[],"71":[1,39],"71129677":[],"71142161":32,"711422":32,"7119":9,"712018":[11,32],"71261809":[],"71263851e":[38,39],"7127128":[],"71332117":[],"713763":[],"71376303":[],"71380438":24,"71384267e":36,"71441086":[],"71460518":24,"71469351":[],"7150195":[],"71505132e":[],"71507714e":[],"71524686":[],"71582784":[],"7163835161938888":24,"71640303e":21,"71672742e":37,"71737253":32,"71761101":32,"718165":5,"71838601":[],"71860732":[],"71957514":24,"7198234":[],"72033728":24,"7204561":24,"720889407643293":[],"72174172":11,"72236654":[],"72271878e":[6,33],"7228852":[],"72288611":[],"72309979e":[],"72364915":31,"7236674":5,"724":3,"72427854":[],"7249499":[],"72521196":5,"725212":5,"725256":[],"7252563":[],"726017":[],"72601722":[],"72602818":[],"72710494":[],"727132":11,"7271324":11,"72744372":[],"72770687":[],"727707":[],"72771857":[],"72848736":[],"72859758":5,"72952595":[],"72962885":[],"72964493e":[],"72981762":8,"72992196":[],"73":[6,9,34],"73018893":[],"73031999":[],"73062648":[],"73063053":[],"73068535":[],"73071831":[],"731000":32,"73122034":[],"73176319":[],"73203674":[],"73204357":37,"73252708":[],"73265885":[],"73305640e":[],"733096":32,"73337355":[],"73374853e":[38,39],"73397147":31,"73578772":[],"73594414e":37,"73595198":[],"736282":11,"73628249":11,"73646130e":[],"73690387":36,"737184":[],"73718419":[],"73741131e":[],"73785069":[],"737851":[],"73853838":[],"73958682":[],"73986200e":[],"73994248":[],"74":[6,34,36,37],"740":9,"74028787e":[],"7403629637766833":[],"74038232":[],"74075864":[],"74081822":8,"74101067e":37,"74171049":[],"74180248":31,"74259663":[],"742597":[],"74272285e":[],"74291603e":[],"74384949":32,"74607851":32,"74613334":[],"74724414e":[],"74724774":36,"74761815":24,"74829661":32,"74840212":5,"7487814387207385":[],"74878144":[],"74883972":[],"74900488":[],"74957448":[],"749765":32,"75":[5,6,8,9,11,25,32,34,37,38],"75018686":[],"750187":[],"75025744":[],"750445":32,"75050135":32,"75080943":[],"7509571":[],"7510197":[],"7511273":[],"75131415":[],"75138064":[],"751699":[11,32],"75170092":5,"75216828e":36,"75269037":32,"75300068":[],"75345893":28,"7539148284817965":[],"75406226e":[],"75424998":[],"75433448":[],"7546022135629743":11,"7546682196464342":[],"75532041":[],"75576555":32,"75600095":[],"756352":32,"75654448":[],"75674251":31,"75677341":[],"756828":[],"75682834":[],"75737136":24,"75760403":[],"7577":34,"75770568":32,"7577113351177733":[],"75956617":[],"75978215":21,"76":[2,9,29,31,35,36],"76030841":37,"76120718":[],"761574":[],"76157429":[],"76190591":33,"76262775":[],"76277254":[],"76329289":[],"7642448":[],"764245":[],"76426396":31,"765":[7,35],"76527062":[],"76533281":[],"765333":[],"76542156e":[],"7658599":[],"76612827":[],"766163196245293":[],"7663967":24,"76686148":[],"76690383":34,"76692036e":[],"767367275553824":[],"76790092":[],"76807288":[],"76855921":[],"76887316e":[],"7692307692307693":9,"76936315":5,"76940759":[],"76942272":[],"7694444444444445":1,"76996262e":[],"77":[2,9,29,31,36,37],"77014839":24,"77030637":[],"77039278":31,"77106886":[],"771128":[],"77152076":5,"77152924":[],"7718":9,"77199379e":[],"772588722239781":[36,37],"77352152e":[],"77354301":[],"774498":[],"77449804":[],"77465911":[],"77482712":[],"77507653":[],"7755649":11,"775565":11,"77559615":[],"77594586":31,"77596142":24,"77635684e":[],"77636e":[36,37],"77652198e":[],"77659961":[],"7766443":[],"777112373675558":31,"77714169":8,"77725472":[],"777255":[],"77803692":[],"7782028952":4,"77829399":[],"77845284":[],"77873845e":[],"77959897":[],"78":2,"78009660e":32,"78010668":[],"78156479e":5,"78184120e":[6,33],"78186404":[],"78254537":[],"78278086":[],"78326199e":[],"78340902e":[],"78385675":31,"78459458":[],"78671736":[],"78745927":[],"78758569":[],"78762558":37,"78876155e":[],"78892891":[],"78941903":5,"78945959":24,"79":2,"79010601":24,"79086674":24,"79111643":5,"79135536e":[],"79171202":[],"79247398":[],"79280475":[],"793167":32,"794282":[11,32],"79469098":[],"79503363":[],"7953443":33,"79622905":[],"79623487":[],"796235":[],"79633065":34,"79718864":[],"79778008":6,"79787194":[],"797872":[],"797e":6,"79849321":[],"79866484":[],"79870689e":[],"7989356":[],"79898903":[],"7d7d58":[9,10],"8":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,21,22,24,25,26,28,31,32,33,34,35,36,37,38,39],"80":[0,1,2,5,6,8,9,32,33,34,39],"800":[4,7,35],"80011603e":[],"80056922":[],"80072356":11,"800724":11,"800782161095708":5,"801356":[],"8030191":[],"80354994":6,"80374623":24,"80410179":[],"80413696":[],"80460179":34,"80469739":5,"8055555555555556":1,"80576215":[],"80609615e":[6,33],"80609616e":[6,33],"80637385":[],"80740939":[],"80847477e":[6,33],"80848093e":37,"8084934":[],"80853029":28,"80855691":[],"808557":[],"80907609":[],"80979265":[],"81":[1,2,39],"81006889":28,"81007381":[],"810150":11,"81015037":11,"81035098":[],"81042619e":[],"81048318e":[6,33],"8110093e":37,"81160425":5,"81208109":28,"81218742e":[],"81246697":[],"81283649":[],"81318307":[],"8133":[],"81333808":6,"813957":5,"81395716":5,"81425129e":[],"81478187":31,"81479491":[],"81506255":[],"81559586":[],"815am":[29,31],"81622636":[],"81633628":11,"816454":32,"816847":32,"81684805":37,"81707832":31,"81818338":21,"81826799":24,"81839897":[],"81889188":[],"81919129":[],"81924504":[],"819253":[],"81925302":[],"81931348":[],"81947005":[],"81979166":[],"81987609":11,"82":2,"82060913e":[],"8207274870895702":[],"82079885":[],"82121282":[],"82130663":[],"82146046":[],"82161167":[],"82198978":5,"82242798":[],"82259916":24,"8227":[],"8232102961414203":[],"823417":[],"82341746":[],"82376174e":[],"82418008":[],"82418352":[],"8244":[],"8250103":[],"82533209":[],"82551764":[],"82559478":[],"82623709e":[],"8265786":5,"82688363":[],"82802004":[],"82832579":[],"82844656":31,"82914126":[],"829252":[],"82925222":[],"83":2,"83020679":[],"8305555555555556":1,"83146596":34,"83220985":24,"83231208e":37,"83363025":[],"83369175":[],"83377498e":37,"83463634e":[],"83466807":[],"83512277":5,"8352834":[],"83641435":[],"83655756":[],"83718206":[],"83741078":24,"83816147":[],"83823317e":[],"83824223":[],"83870189":6,"8387133":[],"83884553e":[],"839957":[],"83995705":[],"84":2,"84019294":[],"84155431":31,"84159992":[],"842":[0,7,35],"8423144":[],"842436":32,"84254917":[],"843":[0,7,35],"84351715":[],"84355903e":[1,39],"844":[0,7,35],"84401886":[],"84443254e":[1,39],"84478178":36,"84605507":[],"8461538461538461":9,"84661230e":[],"84668873":[],"84707251e":[],"84711297":[],"84726382":[],"8475889":31,"84767088":[],"8476874":[],"84780262":6,"84789579e":[],"8485":[],"84858":34,"84862355":[],"8488":[],"84907109":31,"84923989e":[6,33],"84972787":[],"84985833":31,"84994524":5,"85":[1,2,9,39],"85005989":[],"85014487":[],"850164":5,"85035562":28,"85043503":11,"8505072899794293":[],"85064942":[],"85068028":37,"85079059":[],"85108001":[],"85112594":[],"8517571":[],"85222243":[],"85259666e":[],"85263220":6,"85276538":[],"85278920e":5,"8529175":31,"85293303e":[],"85298956":[],"853":34,"85378708":[],"85408468e":36,"85422602":[],"85427641":28,"85437905":[],"85551266e":[],"85601992":5,"85613835":5,"85625134":[],"85703369":[],"85711016":[],"85777073":[],"857771":[],"858":9,"8583333333333333":1,"85866294e":[],"85871255":[],"85945208e":[],"85975973e":[],"86":2,"86009093":[],"86013055e":37,"86016288":[],"86062977":6,"86066395":[],"86067818":[],"86117291":5,"86123808e":[],"86134827":5,"86143379":[],"86145244":11,"86174943":[],"86192682e":[],"86197958":[],"86240935":[],"86247117":[],"86267497":[],"862675":[],"86273371":33,"8638888888888889":1,"86416941":[],"86434639":31,"86445334":[],"86458368e":[38,39],"86459987":[],"865":[0,7,35],"86519139":[],"866":[0,7,35],"86602331":[],"86629161":[],"86630":9,"86639832e":[],"86643649":[],"8666666666666667":1,"867":[0,7,35],"86737671":[],"86757762":[],"86799623":36,"86810":9,"86861591e":37,"86867512":[],"86868711":36,"86891741":[],"8691787":[],"86943859":[],"86978877":[],"87":[0,9],"87020155":[],"8702784034":4,"870337":[],"87068171":33,"87070464":[],"870704644539707":[],"87072815e":32,"87093752":[],"87148597":[],"87169607e":[],"87186187":[],"8720648":[],"8722222222222222":1,"87238538":[],"87340054":[],"87381451":5,"87399194":[],"8746702":28,"87473452":[],"87494456e":[],"875":1,"87584434":[],"8759":[36,37],"87627342":34,"87637891":24,"87696461":[],"877":6,"87732748":[],"87740526":[],"87788573":[],"87818331":[],"87878356":[],"87884833":[],"87981676":[],"88":[2,31,36,37],"88046261":5,"8805555555555555":1,"88064505":[],"88135577e":[],"88157423":[],"88168312e":[6,33],"8817842e":[],"88182591":32,"88236598e":[],"8825782":[],"88289263":[],"882972378790114":28,"88297238":28,"88323026":32,"88336879":5,"8834":[],"88377332":[],"884669":32,"88501323":[],"88529063e":[6,33],"88551766e":[],"88594444":[],"88613493":32,"88614317":[],"88632765":37,"88639567":[],"88653291":[],"88738394e":[],"88809826":[],"88860399":[],"8888888888888888":1,"88960947":[],"8896094720230128":[],"89":[2,9],"890033":[],"89003324":[],"8901199":37,"89017198e":[],"89044267":[],"89058005":[],"8905826":[],"89069029":[],"89126914e":32,"89155606":31,"891559":5,"89155934":5,"8917148":[],"891715":[],"89184351":[],"89229722":[],"89288636":11,"8931686":36,"89408972":[],"89410423":5,"8944444444444445":1,"89457785":[],"89463761e":[],"89527291":11,"89533642":[],"89540936":[],"89543945":[],"89563074":[38,39],"8962":[],"89654756":[],"89692576":31,"89710385e":[],"89724282":[],"89755794":28,"89766337e":[],"89770892":21,"8978":[],"89845198":[],"89961861":24,"8f":[6,34],"8g":[6,34],"8n":24,"8x8":[1,39],"9":[0,1,2,3,4,5,6,7,8,9,11,12,13,14,18,21,24,25,27,28,29,31,32,33,35,36,37,38,39],"90":[1,2,6,9,39],"90075537":5,"9011":6,"90114639":[],"90135464e":[],"90137221":[],"90137794":31,"90140097":[],"90168941":24,"90220243":5,"90266948":5,"9027777777777778":1,"90281987":37,"90300219":[],"90304177e":[],"9040":9,"90475506e":[6,33],"9054":34,"9055555555555556":1,"906589":[],"9065894":[],"906747":5,"90717653":[],"907177":[],"90842732":[],"90860768":[],"90885733e":21,"90894281":[],"90903158":24,"91":[29,31],"910":9,"91099021":[],"91100141e":36,"9111111111111111":1,"91114704":[],"91128596":5,"91247848e":[38,39],"91270333":[],"91312563":[],"91365263":[],"91410559e":[],"91416944e":[],"91433102":31,"91434750e":[],"914672":11,"91467223":11,"91492986e":[6,33],"91546928":[],"91648657":[],"91650453":37,"9166666666666666":9,"91669165":[],"916692":[],"91672129":[],"91722512e":[],"91744988":[],"91752854":[],"91760278":5,"91811422":[],"91812702":5,"91854134":[],"91864509":24,"918785":[],"918992":32,"91933003":[],"919503":[],"9195033":[],"91961463":[],"92":[6,9,29,31],"92003207":[],"92080432":31,"92192012":[],"9225384545636204":[],"9230769230769231":9,"92308585":[],"92308867":[],"92313548e":[38,39],"92319842":[],"92326255":[],"92341148":[],"92370959":[],"92376655":[],"92452609":21,"92458892":37,"924e":6,"925":1,"92507116e":[1,39],"92512799":[],"92527681e":[],"92578916":5,"92599642":[],"92604454":[],"92622842":[],"92661467e":36,"92665802":31,"92678221":31,"9271707090281667":[],"92756256":33,"9277777777777778":1,"92779167e":37,"9288904":[],"92901115":21,"92921498":[],"92929225e":37,"92991181":31,"93019783":31,"9305555555555556":1,"93059014":21,"9306628":31,"93074023":[],"931":[0,31],"93155188":5,"93158979":5,"93237862":[],"932382":[],"93277949":28,"93289669":[],"93293067":[],"933":[5,33],"93325371e":[38,39],"93366198":[],"933662":[],"93397254e":[],"93492130e":[6,33],"93597168":[],"935972":[],"93601008e":32,"93619369":[],"93668828":[],"936877889972962":[],"937":28,"937057":[],"937082":32,"93709777e":37,"93787605":[],"93799826":5,"938":28,"9387":9,"93891335e":[],"939":[0,28,31],"93900569e":[],"93909866":[],"93937564":[],"93942872":[],"93968601":[],"93970238":[],"93989887":[],"94":[9,28],"94027059":24,"94092702":[],"94099173":[],"94114646":31,"94141801":[],"94221383":[],"94226022e":[6,33],"94255277":[],"94272259":31,"94273542":32,"94284104":5,"94285762":[],"94291287":[],"94320205":5,"94335":11,"9434":[],"94388948":[],"94419718":[],"9444444444444444":1,"94466211":24,"94484047e":[37,38],"94485679":0,"94495682":37,"94499279":36,"9450635":[],"94591015":[24,31],"946167":[],"94616709":[],"94623184":[],"94625725":[],"946276":[],"94627617":[],"946372":[],"94637206":[],"94639099":11,"946957":5,"94704941e":[],"9472222222222222":1,"947607":[],"94766419e":[],"94781064":33,"9482527":5,"9485531":[],"9495484":[],"94973606":[],"95":[1,9,11,34,39],"95008046":6,"95033155e":[],"950423":[],"95053694e":[],"95115528":[],"95166920e":[],"952063":11,"95206335":11,"95226607":[],"95231424":5,"952387":32,"9527777777777777":1,"95284275":5,"953065564":[1,39],"95338273":[],"95343966":[],"95351665":5,"95354276":[],"95395895":[],"953959":[],"954":28,"95400323":[],"95482298":11,"954823":11,"95497813":[],"95511792":32,"955118":32,"95518112":[],"9555555555555556":1,"95563211":[],"955820c21e8b":4,"95611042":36,"95647867":[],"956563":[11,32],"95684892":5,"95703":[36,37],"95715036":[],"95743466e":[],"95745476":28,"95745651":21,"95766504e":37,"95770298":37,"95776346":28,"95793988e":[],"958228616652075":5,"95842106":37,"95845431":[],"95872127":[],"95881375":28,"95882223":37,"95890587":[],"95906059":36,"959076":[],"95935439":[],"96":[6,9,11,34],"960":28,"9601304850035702e":[6,33],"9601304850073734e":[6,33],"96015381":[],"96024953":5,"96057795e":21,"96075051":36,"96080358":[],"96084663":5,"961":28,"96164155":24,"962":28,"96231225":[],"96251859":[],"96301764":[],"96305058":[],"963187":[],"9637117593816477":[6,33],"96379806e":[],"96385798":11,"963858":11,"96391888":[],"9640435":5,"96414331":[],"96432396":[],"96461948":[],"9647801":[],"9649652536":4,"96547946":21,"965548":32,"96581896":[],"96585824":[],"96631321":32,"96660465":24,"96688672":5,"967":[],"96745096":21,"9674916":5,"967809":[11,32],"96799937":28,"96826039":[],"96850191":[],"96853248":[],"968650":[],"96865004":[],"96866031":[],"968704":[],"96870431":[],"96894842":[],"96916206":[],"969190":[],"96919021":[],"96919836":[],"9692":[],"969413":5,"96961052":24,"96963458":[38,39],"96991192":[],"97005689":5,"97065359":34,"970827":[],"97082748":[],"97108e":[36,37],"97120565":[],"9712983":[],"97206657":[],"972067":[],"972149":[],"9722222222222222":1,"97228653":[],"9722865317690382":[],"97235642":24,"97243128":5,"97243946":[],"972533":[],"97253307":[],"97272223":[],"97300836":5,"973118":5,"97311824":5,"973663":11,"97366347":11,"97435908":[],"97480604":[],"97482498":[],"974825":[],"97486336":[],"97497404e":[6,33],"97498674":[],"975":1,"97507735":5,"97512176":[],"975484":[],"97548406":[],"97570392":[],"97626519":[],"97630233":34,"9767506308987675":[],"97680846":31,"977":[],"97705827":5,"97716508":[],"97758848":5,"9777777777777777":1,"978":34,"97802245":32,"9780387310732":30,"9780387848570":30,"9781098134174":31,"9781492032632":30,"9781801819312":31,"97836358":[],"978553":5,"97898392":[6,32,33],"97906022e":32,"9792":[],"97926491":5,"97935648":[],"9794096":24,"979656":11,"97965627":11,"97979891":6,"98":[0,1,9,38,39],"980":9,"9805555555555555":1,"98091621":5,"98108401":31,"981321":32,"98139097":5,"98140006e":[],"98190064":[],"98232596":[],"98246764":[],"98261559e":37,"98271562":[],"98275501":5,"98281205":36,"983310":32,"9833205":31,"98338288":[],"983383":[],"983450":[],"9834505":[],"9838929":[],"98413059":5,"98413606":[],"9841870203276504":[],"98454786":5,"98473694":[],"985":28,"98556236":21,"98566191":5,"985725":28,"985725003240627":28,"986":28,"9861111111111112":1,"98619989":[],"98636199":[],"986362":[],"98654811":[],"986699":5,"98680716":5,"98716878":5,"98723376":[],"98740373":[],"98751068":21,"98770503":[],"9878":6,"98808176":5,"98822371":6,"9888888888888889":1,"989":[6,28],"9890348":5,"9893447":5,"98947674e":[],"98947894":32,"9898ff":[9,10],"99":[6,9,11,13,21,34,36,37],"990":9,"99003341":[],"99009525":5,"9904314810719695":[],"99072374":[],"99088801":5,"991":28,"991047":[],"99104747":[],"99114739e":[],"99115119":5,"99176998":5,"99194201":[],"992":28,"99201684e":[],"99242921":5,"99265097":5,"99294056":[],"993":28,"9930742":[],"99316252":5,"99318183":[],"99360578e":[],"99368326":[],"99370678":[],"99371056":5,"99389612":5,"99415296":[],"99427512":[],"9943201":5,"99434472":[],"994345":[],"994474":[],"99447418":[],"99456598":36,"99458998":24,"99475306":36,"9947756":5,"9948998579029953":[],"99492986":5,"99498272":[],"9950019477819025":32,"9951059931014423":[],"99512017":[],"9952183728736417":[],"9952505213910134":[],"9952537939995855":[],"99528218":5,"99539415":5,"995522":[],"9955318336036834":[],"99562995":[],"99566069":5,"995702810640425":32,"99578809":5,"9958589197366403":[],"9958983289118531":[],"9959308805732706":[],"9959739":[],"996":[5,33,34],"99607299":37,"99608161":5,"9960887274532307":32,"99619572":[],"9963961":5,"99647992e":[],"99650061":5,"996626":[],"99662602":[],"99663433":[],"9967458":5,"9969461173312454":[],"9969513794144311":[],"99700706":5,"99709215":5,"99723951":[],"997252717901263":[],"99729015":[],"99729756":5,"99751458":5,"99753321e":[],"99757634":21,"99758326":5,"99759503":21,"99762142":33,"9976783":37,"997746":[],"99774602":[],"99775587":5,"99793613":5,"99799099":5,"99802696":36,"99812668e":[],"99813653":5,"99828624":5,"9983289":21,"9983295":5,"99835783":36,"99839581":21,"99845267":5,"99848215":[],"99848815":36,"99854557":32,"998577":5,"99861053":5,"99861193":21,"99862019":32,"99869482":32,"99871521":5,"99876945":32,"99881845":5,"99883628":32,"99884384":5,"99884409":32,"99884986":33,"99887767":[],"99891093":32,"99891873":32,"99893323":5,"99895448":[],"99898558":32,"999":[9,21,28,36,37,39],"99901896":5,"99903755":5,"99906023":32,"9990927157696581":33,"99911427":5,"99912709":32,"99913489":32,"99916114":36,"99918546":5,"99919837":5,"99920175":32,"99926459":5,"99927642":32,"9993237":5,"99933188":5,"9993511":32,"99938942":5,"99941797":32,"99942911":[],"99943837":[],"9994385":5,"99944272":5,"9994574":[],"99949266":32,"99949306":5,"99952851":[],"99953381":5,"99953475":5,"99954278":[],"99954434":[],"99954925":36,"99956033":[],"99956181":[],"99956735":32,"99957911":5,"99959609":[],"99961294":5,"99963172":21,"99965056":5,"99966798":37,"99967865":5,"99968451":[],"99969576":[],"99970894":32,"99970988":5,"9997332":5,"99974365":21,"99975636":37,"99975913":5,"99977375":[],"99977849":5,"99977853":[],"99978365":32,"99979896":[],"99980002":5,"9998161":5,"99984732":5,"99984836":[],"99985591":[],"99985884":37,"99987324":5,"99989103":36,"99989296":[],"99989476":5,"99990413":[],"99990706":[],"99991245":[],"99991263":5,"99991295":[],"99992107":[],"99992746":5,"99993596":21,"99993978":5,"99994537":37,"99995":5,"999955585168597":[6,33],"99996755":[],"99997356":37,"99997644":[],"99998727":[],"9x":[6,25],"9y":[6,25],"\u00f8yvind":[6,32,33],"\u03b4":39,"abstract":[1,20,36,39],"boolean":4,"break":[0,4,6,11,14,31],"byte":[24,31],"case":[0,1,2,3,4,5,6,7,11,12,13,14,16,21,22,23,24,25,26,31,34,37,38,39],"catch":0,"class":[0,1,3,4,6,7,8,9,11,12,13,22,28,31,34,36,37,39],"default":[0,1,2,4,6,7,8,16,24,25,26,31,32,33,35,38,39],"do":[0,2,3,4,5,6,8,9,10,11,12,13,14,15,16,21,22,24,25,26,31,32,35],"ekstr\u00f8m":4,"export":9,"f\u00f8470":[29,31],"final":[0,1,2,3,4,5,6,7,8,9,10,11,13,14,16,18,19,20,22,25,27,28,29,31,34,35],"float":[0,3,4,5,9,11,13,14,24,31,32,36,37,39],"function":[2,3,4,5,9,14,15,16,17,18,19,22,23,24],"import":[0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,22,25,28,34,35,36],"int":[0,1,2,3,4,5,6,11,13,14,21,24,28,32,34,36,37,39],"long":[0,1,3,4,12,13,22,31,35,36,37,38,39],"m\u00f8svatn":[6,25],"new":[0,1,2,3,5,6,7,8,9,10,11,13,14,17,21,22,24,31,32,35,36,37,39],"public":[0,23,31],"return":[0,1,2,3,4,5,6,7,8,9,11,13,14,21,22,24,25,28,31,32,33,34,35,36,37,38,39],"sch\u00f8yen":[6,32,33],"short":[4,5,20,25,26,33,34,39],"super":[5,32,33,39],"switch":[0,39],"throw":[3,6,28,34],"true":[0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,19,22,24,25,26,28,31,32,33,34,35,36,37,38,39],"try":[0,1,2,4,5,6,7,8,9,10,11,13,14,15,16,22,23,24,25,26,28,31,32,33,34,35,36,37,38,39],"var":[1,5,6,10,11,18,19,25,28,31,32,33,34,39],"while":[0,1,3,4,5,6,7,8,9,11,12,13,21,28,31,32,33,34,35,36,37,38,39],A:[2,3,5,6,7,10,11,12,13,16,18,20,23,24,25,26,27,28,29,30,32,36],AND:2,And:[0,3,4,5,6,9,13,20,23,25,26,28],As:[0,1,2,3,4,5,6,8,10,12,13,16,24,25,26,28,31,32,33,34,35,36,37,38,39],At:[0,4,6,13,25,31,36],BE:[0,31],Be:[2,23,31],Being:[13,36],But:[0,1,2,3,5,6,9,10,26,28,32,33,34,38,39],By:[0,3,5,6,12,13,17,24,31,32,33,34,35,36,37],For:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,23,24,25,26,27,28,30,31,33,34,35,36,37,38,39],IF:[6,33],IN:30,If:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,21,22,23,24,25,26,28,31,32,33,34,35,36,37,38,39],In:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,23,24,25,26,28,30,31,32,33,34,35,36,37,39],Is:11,Ising:[5,12,32,37,38],It:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],Its:[1,2,4,11,39],NO:[9,11],No:[0,6,7,9,22,31,33,35,37,39],Not:[0,1,5,6,32,33,34,37,38,39],OR:28,Of:28,On:[0,3,9,15,25,27,28,29,30,31],One:[0,1,3,4,5,6,7,8,11,12,13,17,21,25,28,32,34,35,36,37,38,39],Or:[0,1,6,25,31,35,38,39],Such:[0,6,12,16,28,34,35,36,37,38,39],TO:[22,39],That:[0,5,7,10,11,12,14,19,25,28,31,33,34,35,38,39],The:[4,10,13,14,15,16,18,19,20,21,22,24,25,26,27,28,29,30],Their:[],Then:[0,1,6,8,9,10,11,12,13,14,24,25,31,34,35,36,37,38,39],There:[0,3,4,5,6,8,9,11,12,14,22,24,25,27,28,29,31,32,33,35,36,37,38],These:[0,3,4,5,8,9,10,11,12,13,14,15,16,24,25,26,28,29,31,32,33,36,37,38,39],To:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,21,22,24,26,28,33,34,35,36,37,38,39],With:[0,5,6,8,9,10,11,12,14,18,24,25,26,28,31,32,34,37,38,39],_0:[5,8,10,11,13,32,35,36],_1:[2,5,6,8,10,11,12,13,14,24,32,33,35,36,37,38,39],_2:[2,5,8,11,12,13,24,32,36,37],_3:24,_4:24,_9:[13,36,37],_:[0,1,2,4,5,6,7,8,9,10,11,12,13,17,18,19,21,22,24,25,31,32,33,34,35,36,37,39],__array_function__:[],__class__:[10,39],__doc__:[6,34],__enter__:[0,7,35],__future__:[8,9,38],__getattr__:33,__getattribute__:31,__getitem__:[0,7,35],__init__:[0,1,3,4,7,14,33,35,37,39],__main__:[2,37],__mul__:2,__name__:[2,10,33,37,39],__rtruediv__:[],_accessor:31,_accuraci:39,_auto10:[6,12,37],_auto11:[6,37],_auto12:[6,37],_auto1:[2,3,4,5,6,7,12,13,21,24,28,32,35,36,37,38,39],_auto2:[2,3,4,5,6,12,13,24,28,36,37,38,39],_auto3:[3,4,5,6,12,13,24,36,37,38,39],_auto4:[4,6,12,13,24,36,37],_auto5:[4,6,12,13,24,36,37],_auto6:[4,6,12,24,37],_auto7:[4,6,12,24,37],_auto8:[6,12,37],_auto9:[6,12,37],_backpropag:39,_base:8,_build:[0,17,19,23,25,30,31],_c:[1,39],_can_hold_identifiers_and_holds_nam:31,_check_optimize_result:[9,11],_class:8,_compon:11,_coordinate_desc:6,_depth:9,_feedforward:39,_format:39,_fraction:9,_generatorcontextmanag:[0,7,35],_i:[0,1,2,5,6,7,8,11,12,13,15,16,17,19,25,31,32,33,34,35,36,37,38,39],_info_axi:31,_j:[0,1,2,3,5,6,8,13,17,19,25,32,33,34,36,39],_k:[13,35,36,37,39],_l:[12,37,38,39],_lambda:[6,31],_leaf:9,_ll:[3,4,14],_logist:[9,11],_m:10,_make_vjp:2,_multilayer_perceptron:1,_n:[2,5,8,11,13,32,35,36],_node:[2,9],_np:[],_o:[3,4,14],_open_file_or_url:[0,7,35],_p:[5,8,32],_plugin_dir:[3,4,14],_progress_bar:39,_ratio:11,_rc_params_in_fil:[0,7,35],_s:[3,4,14],_sampl:9,_set_classif:39,_split:[6,9,25],_src:[21,37],_t:[13,21,36,37],_test:[6,25],_tf_getinputpropertieslist:[3,4,14],_trace:2,_valu:2,_varianc:11,_weight:9,_wrapreduct:[],a0:3,a0faa0:[9,10],a1:[0,22,31],a2:[0,22,31],a3:[0,31],a4:[0,31],a_0:[0,21,26,31,38,39],a_1:[38,39],a_1a:[0,31],a_1x:[21,26],a_2:[38,39],a_2a:[0,31],a_2x:[21,26],a_3:[0,31],a_3a:[0,31],a_4:[0,31],a_4a:[0,31],a_:[0,1,16,24,31,32,38,39],a_h:[1,39],a_i:[0,1,2,12,31,38,39],a_j:[1,12,38,39],a_k:[0,1,12,38,39],a_matric:39,aaron:30,ab:[0,2,5,13,14,21,25,31,32,33,36,37,38],ab_channel:[23,37,38,39],abandon:[1,38,39],abbrevi:27,abid:28,abil:[0,10],abl:[0,1,4,5,6,7,10,12,13,16,25,32,35,36,37,38,39],about:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,23,24,25,26,29,33,34,35,36,37,38,39],abov:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,24,25,26,28,30,31,32,34,35,36,37],abovement:[6,31,34],abscissa:[13,35,36],absolut:[0,2,5,6,13,31,32,33,34,36,37],absorb:[32,33],acceler:[13,21,36,37],accept:[0,3,6,9,22,25,31,32],access:[0,3,11,28,31],accid:[4,6,34,35],accompani:[0,31,32],accomplish:[8,9,13,36,37],accord:[0,1,2,5,6,9,12,13,14,15,16,28,31,33,34,35,36,37,38,39],accordingli:11,account:[0,3,5,13,15,28,31,33,34,36,37],accumul:[12,13,21,28,36,37,38,39],accur:[0,3,4,6,10,13,34,36,37],accuraci:[0,1,3,4,5,6,7,9,10,11,12,22,26,31,32,35,37,38,39],accuracy_scor:[0,1,10,31,39],accuracy_score_numpi:[1,39],achiev:[0,1,5,6,8,12,24,31,33,34,37,38,39],aco:28,acquaint:23,acquir:[1,23,31,38,39],acr:0,across:[1,3,6,9,23,31,34,39],act:[1,3,24,39],act_func:39,act_func_deriv:39,action:28,activ:[0,2,3,4,9,22,27,29,31,35,36],activation_func:22,actual:[0,1,4,5,6,8,11,16,22,24,28,31,32,33,34,38,39],ad:[1,3,4,5,8,13,15,16,24,33,34,35,36],ada_clf:10,adaboostclassifi:10,adadelta:[13,36,37],adagrad:[26,38,39],adagradmomentum:39,adam:[1,3,4,26,29,31,38,39],adam_schedul:39,adap:38,adapt:[4,6,13,30,34,35,38],add:[0,1,2,3,4,5,6,8,10,11,12,15,16,17,21,22,25,26,28,31,32,33,34,36,38,39],add_outgrad:2,add_subplot:[1,7,12,14,25,35,36,37,38,39],addendum:5,addit:[0,2,3,5,6,7,8,9,10,12,13,15,17,21,23,24,25,28,29,30,31,32,33,34,35,36,37,38,39],addition:[12,13,35,36,37,38],address:[1,9,11,13,31,36,37,38,39],adjac:[3,12,37,38],adjoint:[5,32,33],adjust:[0,5,12,13,35,36,37],admir:[0,31],advanc:[4,6,12,30,31,34,38],advantag:[1,3,5,6,10,13,24,33,34,35,36,37,39],adversari:31,afecionado:31,affect:[3,39],affin:[0,3,8,11,32,38],afford:3,aficionado:31,aforement:14,african:0,after:[0,1,2,4,5,6,9,11,12,13,15,21,23,24,25,26,28,31,32,33,34,36,37,38,39],afterward:[0,31],ag:[0,7,27,31,32,35],ag_0:2,again:[0,1,4,5,6,7,8,10,11,12,13,15,16,21,25,26,28,31,32,33,34,36,37,38,39],against:[1,4,7,10,21,26,35,39],agegroup:[7,35],agegroupmean:[7,35],aggreg:[9,10],agorithm:10,agre:[5,6,28,33,34],agreement:[13,21,36,37],ahead:9,ai:[0,26,30],aid:[11,20],aim:[0,1,4,6,7,11,14,15,16,23,24,25,26,32,34,35,38,39],ainv:5,airplan:3,aka:[5,33,34],al:[0,2,4,15,16,17,25,26,30,31,32,33,34,35,36,38,39],alarm:[5,7,33,34],aldo:32,algebra:[0,3,5,13,21,23,32,33,34,36,37],algorithm:[0,1,2,4,5,6,7,8,13,14,23,24,25,28,30,31,33,34,35],align:[0,2,5,6,7,8,13,25,28,31,32,33,34,35,36],all:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],allclos:22,allevi:[1,13,35,36,38,39],alloc:[3,24],allow:[0,1,2,3,5,6,8,10,13,15,16,23,24,25,31,32,33,34,35,36,37,38,39],almost:[0,1,6,8,11,13,21,28,34,35,36,37,38,39],alon:[2,9],along:[2,3,4,5,6,9,10,11,22,23,24,31,32,33,34,35,39],alpha:[0,1,2,3,4,6,7,8,9,10,13,14,28,31,32,34,35,36,38,39],alpha_0:3,alpha_1:3,alpha_2:3,alpha_:10,alpha_i:[3,13,36],alpha_k:[13,36],alpha_m:10,alpha_n:3,alpha_opt:[13,36],alreadi:[2,3,4,5,6,10,12,23,24,28,31,32,33,34,37,38],also:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,31,32,33,34,35,36,37,38,39],alter:[1,39],altern:[0,1,4,5,6,8,9,11,13,24,25,31,32,33,34,35,36,39],although:[0,1,5,6,8,10,13,16,21,31,33,34,36,37,38,39],alwai:[0,3,5,6,12,13,16,21,25,28,31,32,33,34,35,36,37,38],am:4,ambit:[38,39],ame2016:[0,31],american:0,among:[0,3,5,9,10,12,24,31,32,33,37,38],amongst:[5,33,34],amount:[0,1,3,4,6,8,10,14,23,34,38,39],amp:[37,38,39],an:[1,2,3,5,6,7,8,9,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,28,29,30,32,33,34,35,36,37,39],an_:28,anaconda:[0,1,15,23,25,31,39],analog:[13,36,37],analys:[6,33,34],analysi:[1,3,4,7,14,15,16,17,19,21,24,30,35,39],analyt:[2,3,5,6,7,12,13,15,23,25,26,31,32,33,34,35,36,37,38],analytical_gradi:[21,37],analyz:[0,1,3,4,5,6,16,17,25,26,28,32,33],andrew:[1,38,39],angl:[0,3,9,32],anharmon:3,ani:[0,1,2,3,4,5,6,7,8,9,10,12,14,18,22,28,31,32,33,34,37,38,39],anim:[4,12,37,38],ann:[12,37,38],annot:[0,1,3,7,8,31,35,39],announc:31,anoth:[0,1,3,4,5,6,7,8,10,11,12,13,24,25,26,28,31,32,35,36,37,38,39],anp:2,ans_vspac:2,ansatz:[0,31],answer:[0,1,3,5,6,24,25,26,29,31,33,34,39],antialias:[2,6,25],anticip:4,anymor:[1,8,38,39],anyon:[4,8],anyth:[1,28,38,39],anytim:[29,31],apach:[1,39],apart:[11,13,35,36],api:[1,23,31,39],appar:2,appear:[0,1,3,13,16,24,28,36,37,38,39],append:[1,3,4,8,9,13,21,22,31,36,37,39],appendix:25,appli:[0,1,2,3,4,6,7,8,9,10,11,12,13,15,16,25,26,28,30,31,32,33,34,35,36,37,38,39],applic:[0,1,3,4,5,6,7,9,12,13,21,24,25,28,30,31,32,34,35,36,37,38,39],apply_gradi:4,approach:[1,2,4,5,6,9,10,11,12,13,17,21,23,28,30,32,35,38,39],appropri:[2,6,9,12,13,23,28,34,36,37],approv:31,approx:[0,2,3,6,10,11,13,28,31,34,35,36,37],approxim:[0,1,2,3,4,5,6,7,10,11,13,18,19,25,28,31,32,33,34,35,36,37,39],apt:[0,15,23,25,31],aq:28,ar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],aragorn:31,arang:[1,3,4,6,7,9,10,12,13,25,31,35,36,37,38,39],arbitrari:[1,4,6,8,12,13,28,34,35,36,37,38,39],arbitrarili:[0,1,11,31,39],arc:[6,25],architectur:[3,4,12,38],archiv:26,area:[0,3,6,9,25,30,31],arg:2,argmax:[1,11,39],argmin:[4,10,14],argnum:2,argnum_0:[],argnum_1:[],argsort:11,argu:[1,13,36,37,38,39],argument:[0,2,3,5,6,11,12,13,21,31,32,33,34,38,39],argval:2,aris:[0,6,12,13,28,31,34,35,36],arithmet:[0,13,24,31,36,37],arm:[6,33],armadillo:24,arnulf:[38,39],around:[0,1,4,5,6,11,28,31,33,34,38,39],arr:2,arr_list:[],arrai:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,21,22,23,25,28,32,33,34,35,36,37,38,39],arrang:[3,31],arraybox:[2,13,36],arriv:[0,6,9,11,24,28,31,34],arrow:[12,37,38,39],arrowprop:8,art3d:36,art:[0,1,15,23,31,38,39],articl:[0,3,4,6,10,18,25,26,31,32,33,34],artifici:[0,2,7,12,30,31,35],artificialneuron:[12,37,38],arug:[13,36,37],arxiv:[3,4,21,25,36,37,38],asarrai:[0,2,6,9,21,32,33,36,37],asid:32,ask:[5,6,11,12,25,33,34,38,39],aspect:[0,6,23,25,31,32,33,38,39],assembl:[0,3,31],assert:[4,39],assess:[0,6,25,31,32,33,34],assici:4,assign:[0,7,8,9,12,13,14,27,29,30,31,35,36,37,38,39],associ:[0,6,9,12,14,28,31,34,37,38],assum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,24,25,28,31,32,33,34,35,36,37,38,39],assumpt:[0,3,5,6,9,11,18,25,28,31,32],ast:[0,5,6,18,25,31,33,34,35],astronomi:[31,33,35,36,37,39],astyp:[4,9,10],asymmetri:[0,31],asymptot:[4,6,34],atleast_2d:[],atom:[0,31],attempt:[0,4,6,7,8,10,31,33,35,38,39],attend:27,attent:[0,24,31],attr:33,attract:[0,10,31],attribut:[0,9,26,31,33,39],attributeerror:[31,33],audi:[0,31],audio:[3,4],august:[15,16,31],aurelien:[0,15,27,30,31],austfjel:[6,25],author:[0,1,10,28,38,39],authour:31,auto:[8,9,10,28,39],auto_exampl:[22,25,33],autocor:28,autocorrelation_tim:28,autocorrelform:28,autocovari:28,autoencod:[4,23,31],autoencond:23,autograd:[22,23,26,31,38,39],autom:[0,23,30,31],automac:24,automag:31,automat:[0,1,2,3,4,11,16,23,24,31,39],automobil:3,autonom:4,avail:[0,1,4,6,7,10,11,15,20,21,23,24,25,26,27,29,30,31,34,35,37,39],averag:[0,1,3,6,9,10,13,14,21,28,29,31,32,33,34,35,36,37,39],avoid:[0,4,5,6,9,11,13,21,22,24,31,32,34,35,36,37,39],awai:[2,3,6,32,33,38],awar:[2,10],award:[29,31],ax:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,22,24,25,26,31,34,35,36,37,38,39],axes3d:[2,6,13,25,35,36],axes_grid1:6,axhlin:8,axi:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,21,24,25,28,31,32,33,34,35,36,37,38,39],axiom:[5,33,34],axis_arg:[],axlabel:[0,31],axvlin:[4,8],axvspan:4,b1:[8,22],b2:[8,22],b3:8,b:[0,1,3,4,5,6,8,9,10,12,13,14,15,16,21,22,28,29,31,32,33,34,35,37,38,39],b_0:[0,38,39],b_1:[0,2,12,13,36,37,38,39],b_2:[0,13,36,38,39],b_5:[13,36,37],b_:[0,1,24,38,39],b_group:9,b_i:[0,1,2,12,31,37,38,39],b_ia_:[0,31],b_ia_i:0,b_index:9,b_j:[1,12,37,38,39],b_k:[0,1,12,13,36,37,38,39],b_m:[12,37],b_score:9,b_valu:9,babcock:31,bachelor:[27,29],back:[0,3,4,5,6,8,9,10,15,24,26,28,31,32,33,35,36,37],backbon:24,backend:[0,1,4,7,21,35,37,39],background:[30,31,32,38,39],backpropag:[1,22,38,39],backtrack:9,backup:24,backward:[1,2,4,12,24,38,39],backward_pass:2,bad:[6,32,33,39],badli:28,bag:[9,23,31],bag_clf:10,baggin:31,baggingboot:10,baggingclassifi:10,baggingtre:10,balanc:[6,34,35],band:24,bandwidth:24,bar:[0,6,11,15,16,25,31,39],barber:30,bare:[4,10],base:[0,1,3,4,5,7,8,9,10,14,23,28,29,30,31,32,33,35,38,39],basi:[5,7,8,10,11,12,13,24,32,33,35,36,37,38],basic:[2,6,8,12,13,14,23,25,28,31,36,37,39],batch:[3,4,11,12,13,21,26,35],batch_shap:4,batch_siz:[1,3,4,39],batchnorm:4,bay:[7,35],baydin:38,bayesian:[5,23,30,31,33,34],beam:[31,35,36,37,39],becattini:29,becaus:[0,1,2,3,4,5,6,8,9,12,13,14,31,33,34,35,36,37,38,39],becom:[0,1,2,5,6,7,9,12,13,21,28,31,32,33,34,35,36,37,38,39],been:[0,1,2,3,4,5,6,11,12,13,23,24,25,26,31,32,33,34,36,37,38,39],befor:[0,1,2,3,4,5,6,7,8,12,13,14,20,22,24,25,26,28,31,32,33,34,35,36,37,38,39],beforehand:[0,28,31],begin:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,21,24,25,28,29,31,32,33,34,35,36,37,38,39],behav:[1,6,13,34,35,36,38,39],behavior:[0,1,13,31,35,36,37,38,39],behaviour:[12,37,38,39],behind:[0,1,6,8,13,31,35,36,39],being:[0,1,2,3,4,5,7,8,10,11,12,13,17,28,31,32,33,34,35,36,37,38,39],believ:[9,24],belong:[7,8,9,13,14,35,36,39],below:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,22,24,25,26,28,31,32,33,34,35,36,37,38,39],benchmark:10,benefici:[1,13,36,37,39],benefit:[0,1,4,11,13,15,23,31,35,36,37,39],bengio:[1,21,26,27,30,31,32,36,37],benign:[1,7,9,35,39],benno:[38,39],berner:[38,39],besid:[4,5,33],bessel:[5,32,33,34],best:[0,1,2,3,4,5,6,7,8,9,10,12,13,25,26,29,31,32,34,35,36,38,39],best_estimator_:35,beta1:[21,36,37],beta2:[21,36,37],beta:[0,1,3,5,6,7,10,11,13,16,17,18,19,21,25,31,32,35,36,37,39],beta_0:[0,1,3,5,6,7,13,31,32,33,35,36,39],beta_0x_:[0,31,32],beta_1:[0,1,3,5,6,7,10,13,31,32,33,35,36,37,39],beta_1x_0:[0,31],beta_1x_1:[0,7,31,35],beta_1x_2:[0,31],beta_1x_:[0,31,32],beta_1x_i:[7,13,32,35,36],beta_2:[0,3,13,31,32,36,37],beta_2x_0:[0,31],beta_2x_1:[0,31],beta_2x_2:[0,7,31,35],beta_2x_:[0,31,32],beta_2x_i:32,beta_3:3,beta_3x_i:32,beta_4x_i:32,beta_:[0,3,6,7,13,31,32,33,35,36,37],beta_i:[0,3,5,31,32,33],beta_j:[0,5,6,13,18,25,31,32,33,34,36,37],beta_k:[13,35,36],beta_lasso:37,beta_linreg:[13,21,35,36,37],beta_logreg:37,beta_m:10,beta_mg_m:10,beta_n:3,beta_ol:37,beta_p:[7,35],beta_px_p:[7,35],beta_ridg:37,betavalu:5,better:[0,1,2,3,4,6,9,10,11,12,13,21,31,32,33,34,36,39],between:[0,1,2,3,4,5,6,7,8,9,11,12,13,14,17,21,25,26,28,31,32,33,34,35,36,37,38,39],beyond:[0,1,5,6,8,13,21,25,31,32,35,36,37,38,39],bf:[13,14,24,28,35,36],bg:31,bgd:[13,36,37],bia:[0,1,2,3,5,8,9,10,12,13,19,22,31,32,33,35,36,37,38,39],bias:[1,2,3,5,6,9,12,22,26,33,37],bibliographi:25,big:[0,1,2,5,6,14,18,33,34,39],bigger:[1,6,32,33,38,39],bigr:[12,37],bike:9,bilbo:31,billion:[3,12,23,37,38],bin:[0,7,28,35],binari:[0,2,3,5,7,9,10,12,26,31,33,34,35],binarycrossentropi:4,bind:[0,32],binomi:[23,28,31],binsboot:[6,34],bioinformat:0,biolog:[1,12,37,38,39],bios1100:[23,31],bird:[0,3],birth:31,bishop:[27,30,31],bit:[1,4,24,28,31,38,39],bitwis:28,bivari:2,bk:[0,13,36,37],bla:[24,31],black:[8,9,14,21,37],blob:[16,20,25,35,36,37],block:[6,10,23,24,28,31,34],blog:[26,31],blogpost:4,blue:[0,3],bmatrix:[0,1,3,5,7,8,11,13,24,31,32,33,35,36,38,39],bmi:[1,39],bn:[],bodi:[0,1,4,12,31,37,38,39],bold:[1,39],boldfac:[0,5,16,32,33],boldsymbol:[0,1,2,3,5,6,7,8,10,11,13,14,15,16,17,18,19,21,25,31,35,36,37,38,39],boltzmann:[12,23,31,37,38],book1:30,book:[19,25,26,30,31,32,34],boost:[1,9,23,31,38,39],boostrap:10,bootstrap:[1,13,19,23,25,26,31,35,36,37,38,39],borrow:31,boston_dataset:0,bot:8,both:[0,1,4,5,6,8,9,10,13,14,15,16,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],bottl:[7,35],bound:[0,8,12,36,37,38,39],boundari:[2,4,8,11,12],box:[2,4,9],boxed_arg:2,boyd:[8,13,35,36],bracket:[4,28],brain:[1,7,12,35,37,38,39],branch:9,breast:[5,7,11,26,33,34,35],breat:26,breviti:[13,21,36,37],brew:[0,15,23,25,31],brg:8,brief:[25,26,32],briefli:[0,31],bring:[0,5,6,10,26,32,33],broad:0,broadcast_idx:[],brought:[13,21,23,31,36,37],brownle:4,browser:31,brute:[3,5,11,32,33,35,38],bs:[8,9,10],buffer_s:4,bui:4,build:[0,4,5,6,10,24,28,31,33,34,35,36,37,38],built:[0,1,3,4,6,34,39],bunch:11,busi:0,bxe2t:[37,38,39],c1:[8,11],c2:[8,11],c:[0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,19,22,23,24,28,29,30,32,33,34,35,36,37,38,39],c_0:28,c_1:[12,37],c_2:[12,37],c_3:[12,37],c_4:[12,37],c_:[0,8,9,10,13,21,28,35,36,37],c_i:[12,13,36,37],c_k:28,ca:[1,31,38,39],cach:10,cal:[0,8,10,12,13,15,16,31,35,36,38,39],calcul:[0,1,2,4,5,6,8,9,10,11,12,13,14,15,16,18,21,24,26,28,31,33,34,35,36,37,38,39],california:26,call:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,18,19,21,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],callabl:39,calor:[0,32],cambridg:[13,30,35,36,38,39],can:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,28,29,30,32,33,35,39],cancel:[0,13,31,32,36,37],cancer:[5,10,26,33,34],cancerpd:[7,35],candid:[8,9,10,36],cannot:[0,1,4,5,6,7,8,9,27,28,32,33,35,39],canopi:[0,15,23,25,31],canva:[25,26,31],cap:[5,33,34],capabl:[0,1,8,13,23,31,36,37,39],capac:[2,29],capita:0,caption:[25,26],captur:[4,11,12,37,38],car:[3,4],card:[0,7,31,35],cardin:[1,38,39],care:[11,35],carefulli:[13,36],carlo:[0,6,23,28,30,31,34],carri:[2,6,7,25,34,35],cart:10,casella:30,cast:[1,38,39],cat:[3,4],categor:[0,1,3,9,11,31,39],categori:[0,1,3,7,10,12,14,31,35,37,38,39],categorical_crossentropi:[1,3,39],caus:[0,5,6,7,28,31,32,33,34,35],causal:0,causat:[0,31],cax:[1,39],cb:[6,31],cbar:[1,39],cc:[0,1,5,13,26,31,32,33,35,36,38,39],ccc:[5,12,33,37],cd_fast:6,cdf:28,cdot:[0,2,6,12,13,14,24,28,31,34,35,36,37],celebr:[13,35,36],cell:[0,1,2,3,4,6,7,8,9,10,13,14,22,25,33,35,39],center:[0,1,6,7,8,9,11,14,25,28,31,33,34,35,38,39],central:[0,3,5,6,8,16,24,26,31,32,33,38,39],centroid:[14,28],centroid_differ:14,centuri:3,certain:[0,3,6,7,9,28,31,32,34,35],certainti:34,cg:[13,36],cha:0,chain:[0,1,13,23,28,31,36,37],challeng:[36,37,38],chanc:[1,5,13,28,33,34,36,37,39],chang:[0,1,2,3,4,5,6,8,9,11,12,13,14,21,22,24,25,26,28,31,32,33,34,35,36,37,38,39],channel:3,chap4:[38,39],chapter3:[0,19,25],chapter:[0,6,10,11,16,18,21,24,25,26,30,31,32,33,34,35,36,37,38,39],charact:[0,3,5,8,31,32],character:[8,9,10,12,28,37,38,39],characterist:[0,1,3,10,13,21,31,36,37,39],charg:[0,31],charl:0,chase:4,chatgpt:25,chd:[7,35],chddata:[7,35],cheap:[5,32],cheaper:[1,13,36,37,38,39],check:[0,1,3,4,5,6,11,13,22,24,31,36,37,38,39],checkmark:3,checkpoint:4,checkpoint_dir:4,checkpoint_prefix:4,chen:10,cheng:32,chiaramont:2,choic:[0,1,2,3,4,6,9,12,13,14,19,24,26,31,32,34,35,36,37],choleski:[5,24,32],choos:[2,3,6,9,10,11,13,14,25,26,34,35,36,37],chosen:[0,1,2,6,8,9,10,13,16,21,26,28,31,34,35,36,37,38,39],chosen_datapoint:[1,39],christian:30,christoph:[27,30,31],cifar10:3,cifar:3,circ:[1,12,38,39],circl:[0,8,12,32,37,38],circuit:3,circumfer:9,circumv:[1,5,13,32,36,37,38,39],cite:25,ckpt:4,clariti:28,class_nam:[3,9],class_val:9,class_valu:9,classic:[7,9,13,35,36,37,38],classif:[0,3,5,6,7,8,11,12,22,23,25,30,31,32,33,34,36,38],classifi:[0,1,4,7,9,10,11,26,31,39],classificaton:[1,39],classifii:10,clean:[1,39],clear:[1,5,10,12,13,21,36,37,39],clearli:[0,3,5,6,7,8,18,28,32,33,34,35],clever:[1,10,39],clf3:0,clf:[0,6,8,9,10,31,32],clf_lasso:6,clf_ridg:[6,31],clip:[3,28],clone:29,close:[0,1,2,4,6,8,9,11,12,13,14,25,28,30,31,34,35,36,37,38,39],closer:[3,5,13,32,36,37],closest:[8,11,13,14,36],closur:[23,31],cloud:[23,31],cluster:[0,1,4,6,11,23,31,34,39],cluster_label:14,cm:[1,2,3,6,8,9,13,25,35,36,39],cmap:[0,1,2,3,4,6,8,9,10,25,31,39],cmap_arg:6,cmb:27,cmd:9,cn_:28,cnn:[12,37,38],cnn_kera:3,cntk:[23,31],co:[0,2,3,6,9,13,21,31,34,36,37],code:[3,4,6,7,8,15,16,17,19,22,23,24,25,28,30],codebas:39,coef0:8,coef:[0,31],coef_:[0,5,6,8,9,13,31,32,33,35,36],coeff:5,coeffici:[0,3,5,6,7,8,9,13,15,16,24,31,32,33,34,35,36,37],coerc:[0,6,31,34],coin:[10,28],coin_toss:10,col:[0,11,31,32],colab:[22,23,31],cold:9,colinear:0,collabor:[25,26],collaps:8,collect:[0,2,6,10,11,21,23,28,30,31,34,37,38],collinear:[5,32,33],color:[0,3,4,6,8,9,10,21,25,28,36,37],color_channel:3,color_cod:6,colorbar:[1,6,25,39],coloumn:39,colsample_bytre:10,colsaobject:10,column:[0,1,2,5,6,7,8,9,11,12,17,24,31,32,33,34,35,37,38,39],columntransform:9,com:[4,6,16,20,21,23,25,26,30,31,34,35,36,37,38,39],combin:[1,2,5,6,7,10,28,33,34,35,36,37,38,39],come:[0,1,3,4,5,12,13,14,15,26,31,32,33,34,36,37,38,39],command:[0,1,31,39],comment:[0,4,5,6,15,16,25,26,31,32],commerci:[0,15,23,25,31],commod:[0,31],common:[0,1,3,5,6,7,9,11,13,14,25,26,28,31,32,34,35,36,37,38,39],commonli:[0,1,4,6,7,9,13,14,32,34,35,36,37,39],commun:[0,12,25,37,38],commut:3,commutatitav:3,compact:[0,1,3,5,6,7,9,11,12,13,14,31,32,33,34,36,37],compair:0,compar:[0,3,4,5,6,11,13,15,16,21,24,25,26,31,32,33,34,35,36,37,38],comparison:[2,4,13,26,36,37],compat:[7,35],compet:0,competit:10,compil:[0,1,3,4,13,15,21,23,24,31,36,37,39],compl:22,complet:[0,2,3,4,9,12,22,31,37],completenn:[12,37],complex:[1,5,8,9,11,12,13,15,16,19,26,31,34,36,37,38,39],complic:[0,1,9,13,31,34,35,39],compoment:32,compon:[0,1,3,4,5,6,7,9,14,16,23,31,32,33,34,35,38,39],components_:11,compos:[9,12,13,14,21,23,31,36,37,38],compphys:[0,6,16,17,19,20,23,25,27,29,30,31,35,36,37],compress:[0,31,32],compris:[6,35],compromis:[5,32],compulsori:[23,31],comput:[0,1,2,3,4,5,6,7,8,10,11,12,13,15,16,17,21,22,23,24,25,26,27,28,30,31,32,33,34,35,38,39],computation:[0,3,6,9,13,28,31,35,36,37,38],computationalscienceuio:31,computerlab:[25,26],con:26,concaten:[2,4,6,14],concatenate_arg:[],concav:[1,9,13,32,35,36,39],concentr:[0,10],concept:[0,2,23,31,32],conceptu:[12,13,35,36,37,38],concern:[0,1,4,7,31,35,39],concic:31,conclud:[0,5,13,21,33,34,36,37],conclus:[1,39],cond:2,conda:[0,1,15,23,25,31,39],condis:32,condit:[0,2,4,5,6,8,9,11,13,28,31,32,37],conduct:23,condwav:2,confid:[0,5,6,7,8,18,25,31,32,33,35],configur:[3,21,37],confirm:[5,12,22,33,34,37],confus:[5,6,7,10,24,32,33,34],confusion_matrix:9,congruenti:28,conjug:[4,8],conjugaci:[13,36],conjunct:3,connect:[0,1,3,4,9,11,12,13,24,31,32,35,36,37,38,39],consequ:[5,6,8,10,12,13,32,33,34,35,36,37],conserv:[5,14,32],consid:[0,1,2,3,5,6,7,8,9,10,12,13,16,19,21,24,25,26,28,31,32,33,34,35,36,37,38,39],consider:[0,1,5,13,31,32,33,34,35,36],consist:[0,1,2,3,4,6,12,13,19,21,25,26,28,32,34,35,36,37,38,39],constant:[0,2,4,5,6,8,12,13,28,31,32,33,34,35,36,37,38,39],constitu:[0,31],constitut:[2,6,34,35],constrain:[1,3,5,7,11,33,35,39],constraint:[5,6,8,13,32,33,34,36,37],construct:[0,1,2,3,5,6,7,8,9,10,11,24,28,31,32,33,34,35],consult:26,contact:[0,31],contain:[0,2,3,4,5,6,7,8,9,11,12,13,17,19,21,22,24,25,26,28,30,31,32,33,34,35,36,37,38,39],contemporari:31,content:[1,23,24,31,39],context:[6,10,13,25,34,35,36,37,38],contextlib:[0,7,35],contigu:24,continu:[0,1,2,3,4,5,6,7,8,9,10,12,13,17,18,21,24,25,26,28,31,32,33,34,35,36,38,39],contour:[9,10,13,36],contourf:[8,9,10],contrast:[1,4,9,10,12,37,38,39],contribut:[0,3,5,13,21,28,31,32,33,36,37],contributor:[0,25],control:[0,1,3,9,13,15,23,31,36,37,39],conv2d:[3,4],conv2dtranspos:4,conv:[3,4],convei:31,conveni:[0,5,6,12,13,24,25,26,31,33,34,35,36,37,39],convent:[12,32],converg:[1,2,4,5,6,8,9,11,13,14,21,26,32,33,35,36,37,38,39],convergencewarn:[1,6,8,9,11],convert:[0,1,4,5,9,11,13,24,31,32,36,37,39],converttomatrix:4,convex:[4,5,7,32],convinc:[13,35,36],convolut:[1,4,23,31,39],cook:25,cool:[4,9],coolwarm:[6,25],coordin:[5,12,14,32,33,37],coorel:0,copi:[0,1,2,14,32,39],copyright:26,core:[0,2,7,10,31,35],corel:31,coronari:[7,35],corr:[0,5,7,11,32,35],correalt:[11,23],correct:[0,1,2,3,4,5,7,13,22,24,28,31,32,33,34,36,37,39],correctli:[1,2,6,7,10,22,25,26,39],correl:[0,1,3,5,6,7,10,12,13,21,23,28,31,33,34,36,37,38,39],correlation_matrix:[0,5,7,11,32,35],correspond:[0,3,5,6,8,9,11,12,15,16,17,23,24,25,28,31,32,33,34,37,38],cortex:[12,37,38],cosin:[3,6,34],cost:[0,2,3,5,6,7,8,9,12,13,16,17,19,21,25,26,31,37],cost_deep_grad:2,cost_func:39,cost_func_deriv:39,cost_funct:2,cost_function_deep:2,cost_function_deep_grad:2,cost_function_grad:2,cost_function_train:39,cost_function_v:39,cost_grad:2,cost_sum:2,costcrossentropi:39,costlogreg:39,costol:[13,21,36,37,39],could:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,17,24,25,26,28,31,32,33,34,35,36,37,38,39],coulomb:[0,31],count:[0,9,27,28,29,31],countor:[13,36],coupl:[4,5,6,33,34],cours:[0,1,3,5,11,25,26,27,29,32,34,39],courvil:[21,26,27,30,31,32,36,37],cov:[5,6,11,24,28,31,32,33,34],cov_xi:[5,11,32],cov_xx:[5,11,32],cov_yi:[5,11,32],covari:[0,7,23,24,31,33,35],covariance_matrix:[5,11,14,32],cover:[0,5,17,23,29,30,32,33],covert:[0,31],covxi:28,covxx:28,covxz:28,covyi:28,covyz:28,covzz:28,cpu:[1,39],cqofi41lfdw:[38,39],craft:3,creat:[1,2,3,4,5,9,10,11,12,22,23,31,33,35,36,37,38,39],create_biases_and_weight:[1,39],create_convolutional_neural_network_kera:3,create_lay:22,create_layers_4:22,create_neural_network_kera:[1,39],create_x:[5,11,32,39],credit:[0,7,29,31,35],crim:0,crime:0,criteria:[0,4,9,10,14,28,31],criterion:[9,10,13,35,36,38],critic:[6,25,32,33],critiqu:[25,26],cross:[0,1,3,7,9,10,13,22,23,26,28,31,32,33,36,37,38,39],cross_entropi:4,cross_val_scor:[6,34,35],cross_valid:[7,10,35],crossvalid:[6,34],crucial:[1,28,38,39],cs231:3,cs:[27,29],csr_matrix:[24,31],csv:[0,4,6,7,9,31,34,35],ctnk:[1,39],cube:38,cubic:0,cumbersom:[5,33,34],cumsum:[10,11,31],cumul:[7,10,28],cumulative_heads_ratio:10,cup:[5,33,34],current:[1,2,3,4,13,14,21,30,35,36,37,38,39],curs:[0,32],curv:[6,7,10,12,25,35,37,38,39],curvatur:[13,35,36,37],custom:[6,14,25],custom_cmap2:[9,10],custom_cmap:[9,10],cutpoint:9,cv:[6,7,10,34,35],cvxbook:[13,35],cvxopt:[5,8,32],cybenko:38,cycl:[1,12,37,38,39],cyclotron:33,d2_g_t:2,d:[1,2,3,4,5,6,7,8,9,10,11,13,14,22,24,28,29,31,32,33,34,35,36,37,38,39],d_f:[13,35,36],d_g_t:2,d_net_out:2,da:[3,38],dagger:[5,24,32],dai:[1,9,23,39],damp:3,daniel:29,darget:9,darkr:28,dat:[0,31],dat_id:[0,6,7,9,31,32,34,35],data1:14,data2:14,data3:14,data4:14,data:[2,4,5,8,10,12,13,14,17,18,19,21,22,24,26,30,34,36,37],data_id:[0,6,7,9,31,32,34,35],data_indic:[1,39],data_panda:31,data_path:[0,6,7,9,31,32,34,35],databas:[1,39],datafil:[0,6,7,9,25,31,32,34,35],datafram:[0,4,5,7,9,11,31,32,35],datapoint:[1,5,6,7,11,13,32,34,35,36,37,39],dataset:[0,4,6,7,8,9,10,11,13,14,15,16,19,22,25,26,31,34,35,36,37,38],datatyp:4,date:[15,16,17,18,19,20,21,22,25,26,31,32,33,34,35,36,37,38,39],daughter:10,david:[30,31],davison:34,db:38,dbh:[1,39],dbo:[1,39],dc5e85cd93c3:26,dcomposit:24,ddot:2,dead:[1,38,39],deadlin:[16,17,18,19,20,21,22,27],deal:[0,1,3,5,6,8,11,13,14,17,18,24,25,28,31,32,33,35,36,37,38,39],dealt:0,debt:[7,35],debug:[0,5,6,33,34,35,39],decad:[0,3,37],decai:[0,13,28,31],decemb:[27,29,31],decent:10,decid:[0,2,3,5,6,9,25,33,34,35,39],decim:[0,31,39],decis:[0,1,8,11,23,30,31,39],decision_funct:8,decision_tre:9,decisiontreeclassifi:[9,10],decisiontreeregressor:[0,9,10],decisiontreeregressordecisiontreeregressor:9,declar:[0,4,24,31],decompos:[5,6,24,32,38],decomposit:[0,6,12,25,31,33,37,38],decompost:[5,32],deconvolut:3,decorrel:[10,13,21,36,37],decreas:[1,2,4,5,6,10,11,13,33,34,35,36,37,39],deduc:[0,31],deep:[3,7,12,13,21,23,26,27,30,32,36,37],deep_neural_network:2,deep_param:2,deep_tree_clf1:9,deep_tree_clf2:9,deep_tree_clf:[9,10],deepcopi:39,deepen:[5,23,31],deeper:[0,3,4,31],deeplearningbook:[26,30,31,33],deer:3,def:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,21,22,25,28,31,32,33,34,35,36,37,38,39],def_covari:28,default_tim:4,defect:[5,32],defici:[5,32],defin:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,24,25,26,28,32,33,34,35,36,37],definit:[1,2,5,6,7,8,10,11,12,13,17,24,28,32,33,34,35,36],defint:28,defualt:39,defvjp:2,defvjp_argnum:[],degre:[3,5,6,8,9,10,11,15,16,17,19,25,28,31,33,34,35],deisenroth:32,del:[1,39],delet:6,delimit:4,deliv:[27,31],delta:[0,2,3,6,8,12,13,14,21,31,36,37,38,39],delta_0:[3,38,39],delta_1:[3,38,39],delta_2:[3,38,39],delta_2a_1:[38,39],delta_3:3,delta_4:3,delta_5:3,delta_:[1,24,38,39],delta_h:[0,1,31,39],delta_i:[38,39],delta_j:[3,12,38,39],delta_k:[12,38,39],delta_l:[1,3,39],delta_matrix:39,delta_momentum:[13,21,36,37],delta_n:[0,3,31],delug:23,delv:0,demand:[13,35,36],demonstr:[0,3,5,6,7,11,12,23,31,32,33,34,35,39],demystifi:[37,38,39],den:4,denomin:[1,5,33,34,39],denot:[1,2,6,7,13,28,35,36,37,39],dens:[1,3,4,39],densiti:[0,2,6,28,31,34],depart:[26,29,31,32,33,34,35,36,37,38,39],depend:[0,1,2,4,5,6,7,8,11,12,13,15,21,23,24,25,28,31,32,33,34,35,36,37,38,39],depict:28,deploy:[0,15,23,25,31],deprec:2,depth:[0,3,9,10,24,34,39],deriv:[0,1,2,6,7,8,10,11,13,16,17,19,21,23,25,31,37],derivati:[13,36,37],derivative_fn:[13,36],derivb1:[38,39],derivb2:[38,39],derivw1:[38,39],derivw2:[38,39],descend:[5,9,11,32,33],descent:[0,1,3,7,8,12,22,31,32,38,39],descent_i:[21,37],descent_x:[21,37],describ:[0,2,4,5,6,8,10,11,12,13,18,21,24,25,26,31,33,34,36,37,38,39],descript:[0,8,9,26,31,39],design:[0,1,3,4,5,6,7,10,11,12,13,15,16,17,18,19,25,26,31,33,34,35,36,37,38,39],designmatrix:[0,31],desir:[0,2,4,5,13,14,31,32,35,36,39],despit:[1,12,37,38,39],destroi:24,det:[5,24,32],detail:[0,6,11,13,14,24,25,26,32,35,36,39],detect:[3,8,12,37,38],determin:[0,2,3,4,5,6,8,9,10,11,12,13,16,24,28,31,32,33,34,35,36,37,38,39],determinist:[7,13,28,35,36,37,38],deternin:38,dev:[1,25,38,39],develop:[0,3,5,8,10,11,12,21,23,24,25,26,31,32,33,34,37,38],deviat:[0,1,2,4,5,6,19,25,28,31,32,33,34,38,39],devic:[3,4,14],devis:[12,37,38],df1:31,df:[4,8,11,13,31,36,38],di:0,diag:[5,8,32,33],diagnost:[1,10,38,39],diagon:[0,5,7,13,18,21,24,25,28,31,32,33,35,36,37,39],diagonaliz:[5,32],diagram:10,diagsvd:6,dice:[6,28,34],dict:[6,8,35,39],dictionari:[0,39],did:[0,1,5,6,7,10,11,14,22,25,26,31,33,34,35,36,39],die:[1,38,39],diff1:2,diff2:2,diff:[2,38],diff_ag:2,diffeent:8,differ:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,21,22,23,24,25,28,30,31,32,33,34,35,38,39],different:[38,39],differenti:[0,3,16,21,23,24,31,32,35,39],differential_oper:2,difficult:[0,1,6,10,13,21,25,28,31,34,36,37,38,39],difficulti:[0,1,13,31,35,36,37,38,39],diffonedim:2,digit:[0,1,3,4,6,25,26,27,29,31,39],digress:38,dilemma:[13,36,37],dilut:[1,38,39],dim:[4,11,14,24,39],dimens:[0,1,2,3,4,5,8,9,11,14,16,17,24,31,32,33,38,39],dimension:[0,4,5,6,9,11,13,14,19,21,23,24,26,31,33,34,35,36,37],dimensionless:[0,3,31],diment:24,dimnsion:4,diod:3,direct:[0,1,2,4,7,11,12,13,14,21,31,32,35,36,37,38,39],directli:[1,4,5,6,28,32,39],directori:[0,7,35],disadvantag:[0,31],disappear:[3,6,34],disc_loss:4,disc_tap:4,discard:[6,11,34,35],disciplin:[0,3,12,37,38],disclaim:28,discontinu:38,discord:31,discourag:[13,35,36],discov:[0,31],discover:[5,33],discret:[1,3,5,7,13,33,34,35,36,37,38,39],discrimin:[4,7,10,11,35],discriminator_loss:4,discriminator_loss_list:4,discriminator_model:4,discriminator_optim:4,discuss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23,24,25,26,28,30,31,32,33,34,36,37,38,39],diseas:[7,35],disguis:[6,32,33],disord:[1,7,35,39],dispai:[37,38],displai:[0,1,3,4,5,6,7,8,9,10,11,12,14,25,28,31,32,34,35,37,38,39],displaystyl:[0,5,17,31,32,33],disregard:[0,31],dissimilar:[11,14],dist:14,distanc:[0,8,9,11,14,28],distance_list:9,distinct:[3,7,8,9,10,14,35],distinctli:8,distinguish:[0,4,7,8,28,31,35],distplot:0,distribut:[0,1,4,6,7,10,11,13,14,15,16,18,19,23,24,25,26,31,32,35,36,38,39],distrubut:[0,15,23,25,31],dive:[0,8,24,31],diverg:[1,13,35,36,37,38,39],divid:[0,1,2,3,5,6,7,8,9,11,12,26,28,31,32,33,34,35,37,38,39],divis:[6,8,9,13,21,24,28,34,35,36,37,38,39],dlopen:[3,4,14],dna:[7,35],dnn1:4,dnn2_gru2:4,dnn:[0,1,2,4,12,31,37,38,39],dnn_kera:[1,39],dnn_model:[1,39],dnn_numpi:[1,39],dnn_scikit:[0,1,31,39],doamin:[33,34],doc:[0,6,16,17,19,20,23,25,26,27,29,30,31,35,36,37],document:[4,9,11,13,35],doe:[0,1,2,3,4,5,6,8,10,11,12,13,14,16,21,24,25,28,31,34,35,36,39],doesn:[3,9,12,38,39],dog:[1,3,4,39],domain:[5,8,13,25,26,33,34,35,36],domin:[0,31],don:[0,1,3,5,6,7,8,11,13,15,21,23,25,26,31,32,35,36,37,38,39],done:[0,2,3,4,5,6,9,10,11,13,17,24,25,31,32,33,34,35,36,38,39],dot:[0,2,3,5,6,7,8,9,10,11,12,13,21,24,25,28,31,32,33,34,35,37,38,39],doubl:[3,4,24,31],doubli:[1,38,39],doubt:25,down:[0,3,6,9,11,12,13,21,35,36,37],download:[0,1,3,5,6,24,25,30,31,39],downsampl:3,dozen:[1,38,39],dq:[6,34],drag:[13,36,37],dramat:11,drastic:4,draw:[4,6,10,13,34,35,36],drawback:[0,1,3,13,32,35,36,37,38,39],drawn:[1,4,6,7,11,28,31,34,35,38,39],drive:[3,4],driven:3,drop:[0,1,5,6,11,13,21,28,31,32,33,34,36,37,38,39],dropna:[0,6,31,34],dropout:4,dt:[2,3,13,28,36,37,38],dtype:[0,1,2,3,4,14,21,24,31,32,37,38,39],dual:8,dualiti:6,dub:[0,31],due:[1,2,5,6,8,10,12,13,29,31,32,34,35,36,37,38,39],dummi:0,dure:[0,1,3,4,8,9,11,17,20,23,25,31,34,36,37,38,39],dwell:0,dwh:[1,39],dwo:[1,39],dx:[2,3,8,28,38],dx_1:28,dx_1p:[6,34],dx_2p:[6,34],dx_mp:[6,34],dx_n:28,dxp:[6,34],dy:[1,8,28,38,39],dylib:[3,4,14],dynam:4,dz:8,e:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,19,21,22,28,29,31,32,33,34,35,36,37,38,39],e_:[0,2,31],each:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,22,23,24,26,27,28,29,31,32,33,34,36,37,38,39],eager:34,eapprox:[0,31],earli:[1,13,21,36,37,39],earlier:[0,5,7,8,9,11,12,13,20,21,22,31,32,35,36,37,38,39],earthexplor:[6,25],eas:[6,9,14,34],easi:[0,5,6,7,8,9,10,11,12,13,18,21,22,23,24,26,31,32,33,34,35,36,37,38,39],easier:[5,6,8,9,13,26,28,31,32,34,36,37],easiest:[13,35,36],easili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,24,25,31,32,33,34,35,36,38,39],eastern:[29,31],ebind:[0,31],eblock:9,econometr:31,economi:5,ecosystem:[23,31],ect:27,edg:3,edgecolor:[6,34],edit:22,edu:[13,26,35],educ:[0,25,26,31,35],eff:28,effect:[1,4,10,13,28,36,37,38,39],effic:[1,39],effici:[0,3,10,13,23,24,28,31,35,36,37,38],efron:[6,34],egrad:[13,36,37],eig:[5,11,13,21,24,28,31,32,35,36,37],eigen:28,eigenpair:[5,11,32],eigenvalu:[0,5,8,11,13,21,24,31,32,33,35,36,37],eigenvector:[5,11,13,17,32,33,36],eight:[24,31],eigval:[24,28,31],eigvalu:[11,13,21,35,36,37],eigvec:[24,28,31],eigvector:[11,13,21,35,36,37],eispack:[24,31],either:[1,5,6,7,8,9,10,11,13,15,16,25,26,28,31,32,33,34,35,36,38,39],elabor:28,elarn:3,electr:[0,3,12,31,37,38],electron:31,eleg:11,element:[1,2,3,4,5,6,7,8,11,12,13,17,18,20,21,23,24,25,26,27,30,32,33,34,35,38,39],elementari:[10,13,24,36,37,38],elementwis:[3,13,36,37],elementwise_grad:[2,13,36,37,39],elessar:31,elif:[14,21,37,39],elim:24,elimin:[3,8],els:[1,2,3,4,7,9,12,13,14,24,35,36,37,38,39],elu:1,elus:[0,31],email:[27,29,31],embark:38,embed:[0,11,32],embodi:[6,19,25,34],emit:28,emner:30,emphas:[0,10,23,31],emphasi:[0,23,30,31],empir:[1,11,28,38,39],emploi:[0,1,5,6,11,13,25,26,28,31,32,33,34,35,36,39],employ:0,empti:[6,10,34,39],emul:[12,37,38],en:[23,30],enabl:[11,21,37,39],enbodi:[6,34],encod:[0,3,5,7,9,11,14,17,31,32,33,35],encompass:[0,25,28],encount:[0,1,5,6,7,13,21,28,31,32,34,35,36,37,38,39],encourag:[25,26],end:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,21,24,25,28,29,31,32,33,34,35,36,37,38,39],end_box:2,end_nod:2,end_valu:2,endpoint:[3,6],energi:[0,4,6,32,34],enet_coordinate_desc:6,enforc:[12,37,38],eng:30,engin:[0,1,3,4,23,31,38,39],english:[25,26],enocurag:25,enoent:[3,4,14],enorm:3,enough:[0,6,13,31,34,35,36],ensembl:[1,9,38,39],ensur:[0,1,2,3,5,6,11,13,21,28,32,33,34,35,36,37,38,39],entail:31,enter:[5,6,17,32,33],enthought:[0,15,23,25,31],entir:[1,3,7,9,23,28,31,35,36,37,38,39],entiti:[9,12,24,31],entri:[0,5,8,11,12,24,31,32,33,34],entropi:[1,3,7,10,13,22,31,36,37,39],enumer:[0,1,2,3,4,6,8,31,32,33,39],env:[0,1,2,3,4,6,7,8,9,11,14,21,28,31,33,35,37],environ:[2,9,21,22,23,25,37],eo:[0,6,31,34],eol:[0,31],eosfit:[0,31],epoch:[0,1,3,4,12,13,21,26,31,36,37,39],epsilon:[0,5,6,7,13,19,25,31,32,33,34,35,36,37,38],epsilon_0:[0,31],epsilon_1:[0,31],epsilon_2:[0,31],epsilon_:[0,31],epsilon_i:[0,31,32],eq:[3,13,14,24,28,35,36],eqnarrai:[3,5,6,33,34],equal:[0,1,2,3,4,5,6,8,9,11,12,13,14,15,24,25,26,28,31,32,33,34,35,36,37,38,39],equat:[1,3,4,5,6,7,8,9,10,11,13,14,16,17,18,19,21,24,25,28,34,37],equilibrium:[2,12,37,38],equiv:[3,13,24,28,35,36],equival:[0,1,5,7,8,11,13,21,23,24,31,32,33,34,36,37,39],erf:28,eriador:31,eric:39,eridg:31,err:[0,7,10,35],err_:[6,34],err_sqr:2,errat:[13,35,36],errno:[0,3,4,7,14,35],erron:2,error:[1,2,4,5,6,7,9,11,12,13,15,16,17,18,19,21,22,23,24,25,26,28,33,35,36,37,38,39],error_estimate_corr_tim:28,error_hidden:[1,39],error_output:[1,39],escap:[13,35,36,37],especi:[1,3,9,12,13,25,26,36,37,38,39],essenti:[0,5,6,9,10,12,14,25,26,28,32,37,38,39],establish:[0,6,10,11,15,25,26,31],estim:[0,1,5,6,7,10,11,13,23,28,31,32,35,36,37,38,39],estimated_mse_fold:[6,34,35],estimated_mse_kfold:[6,34,35],estimated_mse_sklearn:[6,34,35],et:[0,2,4,15,16,17,25,26,30,31,32,33,34,35,36,38,39],eta0:[8,13,35,36],eta:[0,1,3,8,12,13,21,26,31,35,36,37,38,39],eta_:[13,21,36,37],eta_t:[13,36,37],eta_v:[0,1,3,31,39],etc:[0,1,3,5,7,8,9,11,12,13,14,15,21,23,24,25,26,28,32,35,36,37,39],ethic:23,etsim:34,euclidean:[0,14,32],evalu:[0,2,3,4,5,6,9,13,22,25,28,31,32,33,34,35,36,37],evaluationform:[20,25,36,37],evaluationgrad:[20,25,36,37],evalut:[13,36,37],even:[0,1,3,4,5,6,8,9,10,11,12,13,14,23,24,28,31,32,33,34,35,36,37,38,39],evenli:4,event:[5,7,10,28,33,34,35],eventu:[0,5,6,11,12,13,25,26,29,32,33,34,35,36,37,38],everi:[0,1,2,3,4,5,6,9,10,11,12,13,14,22,23,28,29,31,32,33,34,35,36,37,38,39],everyth:[4,12,21,22,38,39],everywher:[4,13,35,36],evolv:0,exact:[0,2,5,11,12,13,24,28,31,32,36,38,39],exactli:[0,3,4,6,12,23,25,32,34,37,38,39],exam:31,examin:[6,34],exampl:[5,11,12,13,15,16,19,20,23,24,25,26,28,30],exce:[1,12,13,21,36,37,38,39],excel:[0,1,4,5,10,26,31,32,38,39],except:[0,3,4,6,7,8,9,24,35,39],excess:[0,31],excit:0,exclud:[1,6,12,25,32,33,34,35,37,38,39],exclus:[0,1,3,6,28,31,34,35,38,39],execut:[2,5,13,32,36,37],exemplifi:[13,36,37],exercic:[29,31],exercis:[5,23,25,26,27,29,33,34,35,36,37,39],exercisesweek35:17,exhaust:[6,34,35],exhibit:[0,5,6,8,31,32,34],exist:[0,1,2,3,4,5,6,7,8,9,13,14,18,24,25,26,31,32,33,34,35,36,38,39],exit:[5,24,32],exp:[0,1,2,5,6,7,8,10,11,12,13,15,16,21,25,28,31,32,33,34,35,36,37,38,39],exp_term:[1,39],expand:[5,7,11,13,32,35,36],expandus:[0,7,35],expans:[0,3,5,8,10,12,13,31,32,35,36,38],expect:[0,1,5,6,7,11,12,13,15,16,19,21,22,23,25,26,31,32,35,36,37,38,39],expectation_value_of_h_wrt_p:28,expens:[6,10,13,35,36,37],experi:[0,1,6,8,13,23,25,31,32,34,35,36,37,39],experiment:[0,4,6,9,28,31,34],expert:[1,9,38,39],explain:[0,6,9,10,11,13,19,25,31,35,36],explained_variance_ratio_:11,explan:26,explanatori:[0,31],explicit:[0,3,6,13,21,24,25,31,32,33,36,37],explicitli:[0,4,8,21,22,37],explod:1,exploit:[0,3,12,13,31,36,37,38],explor:[1,4,6,8,13,23,25,26,35,36,37,38,39],expon:[1,39],exponenti:[0,1,5,6,10,13,25,28,31,33,34,35,36,37,38,39],export_graphviz:9,export_text:9,exporttext:9,expos:23,expr:38,express:[0,2,3,5,6,7,10,12,13,16,21,24,25,26,28,31,33,34,37],exptmean:28,exptvari:28,extend:[0,2,7,11,13,17,23,31],extens:[0,12,15,23,31,37,38],extent:[0,1,6,30,34,39],extern:[3,6,9],extra:[1,3,5,29,31,32,39],extract:[0,3,5,6,7,8,11,13,24,31,32,35,36,38],extrapol:[0,31],extrem:[0,1,4,5,6,7,8,9,13,16,24,32,33,34,35,36,37,38,39],extremum:[13,35,36],extrins:11,ey:[0,5,6,13,14,24,31,33,35,36,37],f11:[0,31],f12:[0,31],f13:[0,31],f1:[13,36,37],f1_grad:[13,36,37],f1d:[13,36],f2:[13,36,37],f2_grad_x1:[13,36,37],f2_grad_x1_analyt:[13,36,37],f2_grad_x2:[13,36,37],f2_grad_x2_analyt:[13,36,37],f3:[13,36,37],f3_grad:[13,36,37],f3_grad_analyt:[13,36,37],f4:[13,36,37],f4_grad:[13,36,37],f4_grad_analyt:[13,36,37],f5:[13,36,37],f5_grad:[13,36,37],f6:[13,36,37],f6_for:[13,36,37],f6_for_grad:[13,36,37],f6_grad_analyt:[13,36,37],f6_while:[13,36,37],f6_while_grad:[13,36,37],f7:[13,36,37],f7_grad:[13,36,37],f7_grad_analyt:[13,36,37],f8:[13,36],f8_grad:[13,36],f9:[0,13,31,36],f9_altern:[13,36],f9_alternative_grad:[13,36],f9_grad:[13,36],f:[0,1,2,3,4,5,6,7,8,10,12,13,14,16,18,19,21,24,28,29,31,32,33,34,35,36,37,38,39],f_0:[3,10],f_1:[10,13,35,36],f_2:[12,13,35,36,37],f_3:[12,37],f_:10,f_d:28,f_grad:[13,36,37],f_grad_analyt:[13,36,37],f_i:[0,6,12,16,34,37],f_m:[3,10],f_n:3,f_raw:2,f_vec:2,f_wrap:2,face:[13,35,36,37],facecolor:[6,8,28,34],facil:[0,15,23,31,35,36,37,39],facilit:[12,37,38],fact:[0,1,3,5,9,11,12,13,31,32,33,34,35,36,37,38,39],factor:[0,1,3,5,6,9,10,11,13,24,28,31,32,33,34,36,37,39],factori:[13,36,37],fade:6,fafab0:[9,10],fahimeh:[29,31],fail:[0,6,8,9,11,13,29,31,34,35,36,38],fail_on_error:[0,7,35],failur:[7,35],fairli:[1,2,28,38,39],faisal:[16,32],fake:4,fake_loss:4,fake_output:4,fale:26,fall:[8,9,27],fals:[0,1,2,3,4,5,6,7,9,10,14,24,25,31,32,33,34,35,36,37,39],famili:[0,7,8,28,35],familiar:[0,3,5,6,8,15,23,24,25,28,31,33,34,38],famou:[6,12,39],far:[0,3,4,5,6,8,11,12,13,14,22,31,32,35,36,37,38],fashion:[0,9,10,31],fast:[1,3,6,10,12,13,23,28,31,34,35,36,38,39],faster:[1,11,13,36,37,38,39],fastest:[13,24,35,36],favor:[7,35],favorit:28,fc:3,fd:[0,7,35],featur:[0,1,3,5,6,7,8,10,11,12,13,18,22,23,25,26,28,31,33,34,35,36,37,38,39],feature_nam:[0,1,7,9,22,35,39],feautur:9,fed:[1,38,39],feed:[0,2,3,11,22,23,26,31],feed_forward:[1,22,39],feed_forward_4:22,feed_forward_out:[1,39],feed_forward_train:[1,39],feedback:[4,20,31],feeddorward:4,feedforward:[1,4,12,38,39],feel:[0,5,6,11,13,15,16,21,22,23,25,26,29,31,33,36,37,38],feet:0,felt:[25,26],fetch:[6,25],few:[1,3,4,5,9,28,31,36,38,39],fewer:[0,9,11,31],ffnn:[1,12,26,37,38,39],field:[0,3,6,12,23,37,38],fifteen:38,fifth:[0,6,15,16,25,31],fig:[0,1,2,3,4,6,7,12,13,14,25,31,35,36,37,38,39],fig_id:[0,6,7,9,31,32,34,35],figaxi:28,figsiz:[0,1,2,3,4,6,7,8,9,10,31,34,35,39],figur:[0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,21,23,25,26,31,32,33,34,35,36,37,38,39],figure_id:[0,6,7,9,31,32,34,35],figurefil:[0,6,7,9,31,32,34,35],file:[0,2,3,4,5,6,7,9,14,22,25,26,31,32,33,34,35],file_prefix:4,filenam:31,filenotfounderror:[0,7,35],fill:[5,9,32,39],filter:[0,3,4,7,35],financ:0,find:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,21,23,25,26,28,31,32,33,35,37,38,39],fine:[0,14,15,31],finicki:22,finish:[2,39],finit:[3,5,6,12,13,17,28,32,33,34,36,37,38],first:[0,1,2,3,5,6,7,8,9,10,11,13,14,15,16,17,21,22,24,25,28,29,30,34,37],first_moment:[21,36,37],first_term:[21,36,37],firsteigvector:11,fit:[1,3,4,5,6,7,8,9,11,12,13,15,16,17,21,25,26,28,32,34,35,36,37,38,39],fit_beta:[6,32,33],fit_intercept:[0,5,6,32,33,34],fit_mod:9,fit_transform:[0,6,8,9,11,34,35],fiti:[0,31],five:[0,9,17,25,31,32,35,38],fix:[0,3,4,6,10,11,12,13,21,25,26,31,34,35,36,37],fixedloc:6,flag:4,flat:[3,4,12,13,14,21,35,36,37],flatten:[1,3,4,5,24,39],flexibl:[1,6,8,10,12,26,31,34,37,38,39],flip:[29,31],float32:[4,9,21,37,39],float64:[4,21,24,31,32,37,38,39],floatingpointerror:39,floor:39,flop:[5,24,32],flow:[1,4,12,37,38,39],flower:22,fluctuat:[5,33],flush:39,fly:11,fm:[0,31],fmax:3,fmesh:[13,36],fn:7,fname:[0,7,35],focu:[0,3,4,5,6,15,23,26,30,31,32,33,34],focus:[1,6,7,24,32,33,35,39],fold:[6,9,25],folder:[0,1,3,4,6,14,25,26,31,34,39],follow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],font:[0,7,28,31,35],fontdict:28,fontsiz:[1,6,8,9,10,28,39],fontweight:[1,39],footprint:3,foral:[8,32,38],forc:[0,5,6,10,11,31,32,33,35,38],forcast:4,forecast:[4,12,37,38],forest:[0,1,9,23,31,38,39],forget:11,form:[0,3,4,5,6,7,8,9,11,12,13,17,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],formal:[3,4,14,28,38],format:[0,1,3,4,6,7,8,9,10,11,23,28,30,32,33,34,35,37,38,39],format_data:4,formatstrformatt:[6,13,25,35,36],formul:[4,6,11,14],formula:[3,13,28,35,36,37,38],forth:[4,12,37],fortran2003:[23,31],fortran2008:[25,26],fortran90:28,fortran:[0,15,23,24,31],fortun:[0,11,32],forward:[0,3,6,22,23,24,26,31,34],forwardpropag:[38,39],foster:31,found:[1,2,3,4,5,6,12,13,14,19,20,25,26,31,32,33,34,36,37,38,39],foundat:[23,31],four:[4,5,6,8,12,22,24,25,27,29,31,33,37,38,39],fourier:[0,31,38],fourierdef1:3,fourierdef2:3,fourierseriessign:3,fourth:[12,31,32],fp:7,frac:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,24,25,26,28,31,32,33,34,35,36,37,38,39],fractal:9,fraction:9,frame:[7,35],framework:[1,3,4,8,10,14,28,39],frank:[5,11,21,26],frankefunct:[5,6,11,25,32],fredli:[29,31],free:[0,6,11,13,15,16,21,23,24,25,26,28,29,30,31,36,37,38],freecodecamp:23,freedom:[5,33],freeli:[0,25],frequenc:[3,6,7,28,34,35],frequent:[0,8,9,13,35,36,37],frequentist:23,fresh:10,fridai:[16,17,18,19,20,21,22,29,31],friedman:[6,18,25,27,30,31],friendli:4,frodo:31,frog:3,from:[0,1,2,3,4,6,7,8,9,11,13,14,16,17,18,19,22,23,24,25,28,29,30,31],from_cod:9,from_logit:[3,4],from_tensor_slic:4,fromnumer:2,front:[0,4,5,15,16,31,32,33],fulfil:[2,5,12,32,37,38,39],full:[0,1,3,5,7,9,10,13,22,28,31,32,35,36,37],full_matric:[5,32],fulli:[3,6,12,27,28,34,35,37,38],fun:[2,23,31],fun_nam:[],func:[2,39],functionali:11,fundament:[0,6,23,31,34],funtion:2,furthemor:38,further:[2,7,9,31,38],furthermor:[0,3,5,6,7,11,12,13,17,23,25,31,32,33,34,35,36,37,38,39],futur:[0,4,8,9,31],futurewarn:8,fy:[15,25,26,27,29,30,31],fys4155:[25,26],fys5419:[30,31],fys5429:[30,31],g0:2,g:[0,1,2,3,4,6,8,9,10,11,13,28,31,33,34,35,36,37,38,39],g_0:2,g_1:[2,10],g_2:[2,10],g_3:38,g_:[2,9,10],g_analyt:2,g_dnn_ag:2,g_euler:2,g_i:[2,38],g_j:38,g_m:[3,10],g_n:3,g_re:2,g_t:[2,39],g_t_d2t:2,g_t_d2x:2,g_t_dt:2,g_t_hessian:2,g_t_hessian_func:2,g_t_invers:39,g_t_jacobian:2,g_t_jacobian_func:2,g_trial:2,g_trial_deep:2,g_vec:2,gain:[1,5,7,9,10,13,32,33,34,36,37,39],galleri:[0,31],game:4,gamge:31,gamma1:8,gamma2:8,gamma:[0,2,8,9,10,11,13,21,31,35,36,37],gamma_0:10,gamma_1:10,gamma_1x:10,gamma_:[0,31],gamma_i:[0,8,28,31],gamma_j:[13,36,37],gamma_k:[13,35,36],gamma_m:10,gamma_x:[0,31],gap:[6,8],gate:[4,12],gather:[0,1,12,32,37,38,39],gaug:[12,37,38],gaussbacksub:24,gaussian:[4,5,6,8,14,28,33,34],gaussian_point:14,gaussian_rbf:8,gave:[13,36,37],gavra:31,gbc:[27,31],gca:[2,6,8,13],gd:[1,26,35,38,39],gd_clf:10,gdclassiffiercgain:10,gdclassiffierconfus:10,gdclassiffierroc:10,gdfit:37,gdm:[13,21,36,37],gdregress:10,ge:[1,5,7,28,32,35,38,39],gen:[0,7,35],gen_loss:4,gen_tap:4,gender:[0,31],genener:4,gener:[0,1,2,3,5,6,8,10,11,12,13,14,15,16,17,19,20,21,24,25,28,30,32,33,34,35,36,37,39],generaliz:39,generallay:[12,37],generate_and_save_imag:4,generate_imag:4,generate_latent_point:4,generate_simple_clustering_dataset:14,generated_imag:4,generator_loss:4,generator_loss_list:4,generator_model:4,generator_optim:4,genom:23,geodes:11,geometr:[0,13,31],geometri:[5,33,34],georg:30,geotif:[6,25],geq:[2,5,8,9,13,32,33,35,36],geron:[0,15,21,27,30,31,36,37],get:[0,1,2,3,4,5,6,7,9,10,11,13,15,20,22,23,24,25,26,28,29,31,32,33,34,35,36,39],get_dummi:9,get_paramet:2,get_split:9,get_yaxi:8,get_yticklabel:6,getattr:[],gg:31,gibb:[23,31],gif:4,gini:10,gini_index:9,ginvers:13,git:[0,15,23,31],giter:[13,21,36,37],github:[0,6,9,15,16,17,19,20,21,23,25,26,27,29,30,31,32,35,36,37,38,39],gitlab:[0,15,23,25,26,31],gitta:[38,39],give:[0,1,2,3,5,6,7,8,9,10,12,13,14,17,23,25,26,28,31,32,33,34,35,36,37,38,39],given:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24,25,26,28,31,32,33,34,35,36,37,38,39],global:[6,7,13,25,35,36,37],gloriou:26,glorot:1,gnew:13,go:[0,1,3,5,6,8,9,11,12,13,25,31,32,33,34,35,36,38,39],goal:[0,7,9,31,35],goe:[0,1,2,5,6,13,14,18,24,31,32,33,34,35,36,37,39],golden:[13,36],gone:[5,32,33],gong:[1,39],good:[1,3,4,5,6,9,10,11,13,17,21,23,28,30,32,33,34,35,36,37,38,39],goodfellow:[4,26,27,30,31,32,33,35,36,38,39],googl:[1,4,21,22,23,31,37,39],got:[1,6,13,22,25,39],gotcha:[21,37],gotten:[31,39],gov:[6,25],gp:30,gpu:[1,13,21,23,31,36,37,39],grad:[2,13,21,22,36,37,39],grad_analyt:[13,36,37],grad_concatenate_arg:[],grade:[25,27],gradient:[0,3,4,7,8,9,12,22,23,31,32],gradient_bia:39,gradient_desc:[21,36,37],gradient_weight:39,gradientboostingclassifi:10,gradientboostingregressor:10,gradients_of_discrimin:4,gradients_of_gener:4,gradienttap:4,gradual:[1,14,38,39],grai:[4,6,25],graph:[1,9,11,12,13,35,36,37,38,39],graph_from_dot_data:9,graphic:[0,1,9,31,39],grasp:0,gray_r:[1,3,39],grayscal:3,great:[5,13,35,36,38],greater:[1,7,28,35,38,39],greatli:[13,36,37],greedi:[9,35],green:[0,3,9,28],gregor:39,grei:4,grid:[1,3,6,7,8,12,28,32,33,34,37,38,39],gridsearch:35,gridsearchcv:35,groh:[38,39],grossli:[13,35,36],ground:[0,31],group:[0,6,7,9,14,22,23,25,26,27,29,31,34],groupbi:[0,31],grow:[1,3,9,10,38,39],growth:[0,31],gru:4,guarante:[0,4,13,28,31,32,35,36],guess:[1,4,10,13,14,21,26,35,36,37,39],guestrin:10,guid:[1,39],guidanc:25,guidelin:[20,36,37],h1:2,h:[0,1,5,6,8,13,16,18,21,25,28,29,30,31,32,35,36,37,39],h_1:[2,13,35,36],h_2:[2,13,35,36],h_:[0,13,31,35,36],h_m:10,ha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,21,22,24,25,26,28,31,32,33,34,35,36,37,38,39],haa:29,habit:[0,32],had:[0,1,6,7,13,31,34,35,36,38,39],hadamard:[1,12,13,21,36,37,38,39],half:[1,8,9,38,39],halv:10,hand:[0,1,2,3,5,11,12,13,15,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],handi:[3,25,26],handl:[0,1,2,5,9,11,23,33,38,39],handle_unknown:9,handsid:[12,38,39],handwrit:[12,37,38],handwritten:[1,5,39],handwrittennot:[35,37],happen:[1,2,3,4,5,6,10,13,28,32,36,37,38,39],hard:[1,7,8,10,13,35,36,38,39],hardcopi:[23,31],harder:[0,1,32,38,39],harmon:3,hasn:1,hassl:[0,15,23,31],hast:[23,31],hasti:[0,6,15,16,17,18,25,27,30,31,32,34,35],hat:[0,1,5,6,7,9,10,11,12,13,17,18,24,25,32,33,34,36,37,38],have:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],haven:[1,39],he:[7,35],head:[0,4,10,28],header:[0,31],heads_proba:10,health:[0,32],hear:[0,13,31,36,37],heart:[0,7,31,35],heatmap:[0,1,3,7,31,35,39],heavili:0,heavisid:[1,39],height:[1,3,6,32,33,39],held:[13,21,36,37],help:[0,1,4,12,13,16,21,25,26,31,36,37,38,39],helper:[4,14],henc:[0,5,6,8,9,10,12,13,18,25,31,32,33,34,35,36,37],henrik:[29,31],her:[7,35],here:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],hereaft:[0,8,12,31],hermitian:24,hessenberg:24,hessian:[0,2,5,13,16,21,33,37],heterogen:[9,10],hi:[7,35],hidden:[1,3,4,12,26,37],hidden_bia:[1,39],hidden_bias_gradi:[1,38,39],hidden_deriv:39,hidden_func:39,hidden_layer_s:[0,1,31,39],hidden_neuron:4,hidden_nodes1:39,hidden_nodes2:39,hidden_weight:[1,39],hidden_weights_gradi:[1,38,39],hierarch:[5,32,33],high:[0,1,2,3,4,5,6,9,10,11,13,14,21,23,24,25,31,32,34,35,36,37,38,39],higher:[0,1,3,5,6,8,13,21,25,26,31,32,33,34,35,36,37,39],highest:[1,2,39],highli:[0,3,4,10,18,23,24,26,30,31,32,33,34],highwai:0,hing:8,hint:[13,16,26,32,33,35,36],hip:23,hire:0,hist:[4,6,7,28,34,35],histogram:[0,6,7,28,35],histor:[7,11,35],histori:[3,4,12,37,38],hitherto:[5,33],hjorth:[29,31,32,33,34,35,36,37,38,39],hobbi:28,hoc:[5,32],hoff:30,hold:[1,3,6,13,14,21,34,35,36,37,39],holder:[0,31],holomorphic_grad:2,home:0,homepag:[25,26,31],homework:[6,13],homogen:[1,3,9,10,13,21,36,37],honchar:2,hopefulli:[0,11,22,28,31,37],horizont:11,hornik:38,hors:[3,7,35],hot:[1,9,22,39],hour:[1,23,27,28,29,31,39],how:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,21,22,23,24,25,26,28,31,32,33,34,36,37,38,39],howev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,23,24,25,26,28,31,32,33,34,35,36,37,38,39],hspace:[0,4,8,10,28,31,38,39],hstack:[1,39],htf:[27,31],html:[0,9,11,17,19,22,23,25,26,27,29,30,31,33,38,39],http:[0,3,4,6,9,11,13,16,17,19,20,21,22,23,24,25,26,27,29,30,31,32,33,34,35,36,37,38,39],huang:[0,31],huber:[0,31],huge:[1,3,4,23,38,39],human:[0,1,3,6,9,12,32,33,37,38,39],humid:9,hundr:[1,38,39],hungri:[1,38,39],huse:31,hvae:37,hybrid:27,hydrogen:[0,31],hyper:[21,26],hyperbol:[1,4,12],hyperparam:8,hyperparamat:38,hyperparamet:[3,4,5,6,9,13,17,31,32,33,35,36,37],hyperplan:11,i0:[0,31],i1:[0,6,8,12,31,32,33,37],i2:[0,8,12,31,37],i3:[0,12,31,37],i5:[0,31],i:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,24,25,26,28,29,31,32,33,34,35,36,37,38,39],i_1:[5,6,33,34],i_2:[5,6,33,34],i_:[13,35,36],i_siz:22,ian:30,ic:[1,26,39],id:[7,13,35,36,37],ida:[29,31],idea:[0,1,2,3,4,6,9,10,12,13,24,25,26,32,33,34,35,36,37,38,39],ideal:[0,2,6,8,13,28,31,34,37,39],idem:[6,34],ident:[5,6,12,13,17,24,25,32,36,37,39],identical:[33,34],identifi:[0,1,7,9,11,12,13,14,31,32,35,36,37,39],ieor:28,ifi:30,ifs:[23,31],ignor:[0,1,3,9,32,38,39],ii:[24,28,39],iii:[24,31,39],ij:[0,1,3,6,8,12,14,16,18,24,25,28,31,32,33,37,38,39],ik:[0,24,31,32],ilg3ggewq5u:[38,39],illustr:[5,7,10,12,13,14,23,31,34,35,36,39],ilsvrc:[36,37],im:6,imag:[1,3,4,6,9,11,12,14,26,30,31,37,38,39],image_at_epoch_:4,image_batch:4,image_height:3,image_path:[0,6,7,9,31,32,34,35],image_width:3,imageio:[6,25],images_from_seed_imag:4,imagin:[1,38,39],immedi:[0,3,4,6,15,23,31],implement:[0,2,3,4,5,6,8,9,10,11,12,13,14,17,21,22,25,26,28,31,32,33,35,36,38],impli:[3,5,6,7,13,24,32,33,34,35,36],implicit:3,implicitli:[11,28],importantli:3,impos:[0,6,11,12,31,37,38,39],imposs:[0,5,31,32],impress:[0,12,31,37,38],improv:[0,4,5,9,10,11,13,21,25,26,32,37],impur:9,imread:[6,25],imshow:[1,3,4,6,25,39],in1:[],in2:[],in3050:[30,31],in3310:31,in4080:[30,31],in4300:[30,31],in4310:30,in5400:3,in5550:30,in_out_neuron:4,inaccur:[13,35,36],inact:[12,37,38,39],inadequ:[0,31],inch:[6,32,33],includ:[0,1,2,3,4,5,6,7,11,12,15,16,17,20,22,23,25,26,28,29,30,31,32,33,34,39],include_bia:[6,9,34],inclus:[17,37],incom:[12,37,38],incorrect:[1,39],incoveni:8,increas:[0,1,3,4,5,6,8,9,11,12,13,21,25,28,31,32,33,34,36,37,38,39],increasingli:28,increment:36,ind:6,inde:[0,2,4,5,6,13,31,32,38],indefinit:4,independ:[0,5,6,7,8,12,13,28,31,32,35,36,37],index:[0,1,3,4,10,14,23,24,26,28,30,31,39],index_col:[0,31],indic:[0,1,3,4,5,6,9,10,11,13,16,21,25,26,31,32,36,37,38,39],indispens:[6,34],individu:[1,6,7,10,12,28,31,32,34,35,37,38,39],indu:0,indx1:2,indx2:2,indx3:2,indx:24,ineffici:[3,13,36,37],inequ:[8,13],inequaltii:[35,36],inertia:[13,21,36,37],inf1000:[23,31],inf1100:[23,31],inf1100l:[23,31],inf1110:[23,31],inf3000:31,infeas:9,infer:[0,1,4,6,30,31,34,39],inferenc:[1,39],infil:[0,6,7,9,31,34,35],infin:[5,6,7,11,18,32,33,34,35,38,39],infinit:3,infinitesim:28,influenc:[6,10,34,35],influenti:[1,39],info:31,inform:[0,1,3,4,6,9,11,12,13,14,21,24,25,26,30,31,34,35,36,37,38,39],infti:[3,6,13,28,34,35,36,38],ingeni:[13,35,36,37],ingrad:2,ingredi:[0,9,31],inher:[6,34],inherit:[24,31],init:39,initi:[0,1,2,6,10,13,14,24,26,28,31,34,35,36,37,38,39],inititi:39,inject:14,inlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,24,25,28,31,32,33,34,35,36,37,38,39],inner:[0,13,32,36],inp:4,inplac:13,inpput:38,input:[0,1,3,4,5,6,7,8,12,13,14,21,22,25,26,28,31,32,33,34,35,36,37],input_dim:[1,39],input_nod:39,input_shap:[3,4],inputs:[1,39],inputs_shuffl:[0,1,32,39],insert:[3,5,6,8,10,28,32,33,34],insid:[0,4,7,35],insight:[0,1,5,21,23,26,31,32,33,34],insist:[6,13,32,33,36],inspect:35,inspir:[0,1,12,26,31,37,38,39],instabl:2,instal:[0,1,5,6,9,15,39],instanc:[0,1,2,4,6,9,11,13,31,32,34,35,36,39],instanti:10,instead:[0,1,2,3,4,5,6,8,9,11,13,14,21,22,24,25,28,31,32,34,35,36,37,39],institut:[1,39],instruct:[0,1,15,16,31,39],int32:10,int_0:28,int_:[3,6,28,34,38],int_a:28,intak:[0,32],integ:[1,2,13,14,24,28,31,36,37,39],integer_vector:[1,39],integr:[3,6,28,31,34],intellig:[0,14,30,31],intend:10,intens:[1,38,39],intention:14,interact:[0,6,9,12,23,25,26,31,37,38],intercept:[0,6,8,11,13,16,25,31,33,34,35,36,37],intercept_:[0,6,8,9,13,31,32,33,35,36],interchang:[5,12,24,33,34,37,38],interconnect:[1,38,39],interest:[0,1,2,3,4,5,6,7,8,9,12,21,23,25,26,28,31,32,33,34,35,36,37,38,39],interfac:[0,1,24,32,39],interior:[0,9,31],intermedi:[22,24,32],intermediari:22,intern:[1,10,12,37,38,39],interpol:[1,3,4,6,12,25,37,38,39],interpr:[5,32,33],interpret:[0,1,6,9,10,12,13,17,19,24,25,26,28,38,39],interv:[0,3,5,6,7,13,18,25,28,31,32,33,35,36],intial:[13,35,36],intract:[0,4,32],intrins:[3,11,24,28,31],intro:[23,30,31],introduc:[0,1,5,6,8,10,12,17,24,25,28,31,34,35,38,39],introduct:[1,2,4,13,17,20,30,32,35,36,39],introductori:[0,4,24,30,31,32],intuit:[0,5,6,8,12,13,21,25,31,33,34,36,37,38,39],inv:[0,5,13,21,31,32,33,35,36,37],invalid:[1,8],invalu:[0,13,15,23,31,35,36],invari:[1,39],invd:[5,33],inver:[8,37,38],invers:[0,3,6,13,15,16,17,21,25,26,31,32,35,36,37],inverse_transform:8,invert:[0,5,7,10,13,21,31,33,35,36,37],invh:[13,21,36,37],invok:[0,8],involv:[0,2,6,7,11,12,32,34,35,36,37,38,39],io:[0,17,19,23,25,27,29,30,31,32],ion:37,ip:[0,8,28,31],ipca:11,ipykernel_12550:[],ipykernel_12588:[],ipykernel_1323:[],ipykernel_1390:[],ipykernel_1539:[],ipykernel_1579:[],ipykernel_22411:1,ipykernel_22458:6,ipykernel_22556:31,ipykernel_22575:34,ipykernel_47048:39,ipykernel_58656:[],ipykernel_58739:[],ipykernel_58840:[],ipykernel_58862:[],ipykernel_6316:[],ipykernel_6403:[],ipykernel_6690:[],ipykernel_6729:[],ipykernel_95354:[],ipykernel_95419:[],ipykernel_95519:[],ipykernel_95542:[],ipynb:[23,25,31],ipython:[0,5,7,9,11,14,15,23,25,26,31,32,35],iq:[6,34],iri:[8,9,22],irreduc:[6,34],irrelev:[5,32],irrespect:[0,31],irvin:26,isbox:2,iscomplexobj:[],iseffici:[36,37],isn:[5,33,34],isnan:39,isnul:0,isomap:11,isotop:[31,35,36,39],issu:[1,9,24,33,38,39],it_arrai:[13,36],item:[0,13,31,36],items:[24,31],iter:[1,2,4,6,8,9,11,13,14,21,28,34,35,37,38,39],its:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,18,23,24,25,26,28,31,33,34,35,36,37,38,39],itself:[5,6,12,19,25,26,28,32,33,34,38],iv:39,ix:39,j1:24,j:[0,1,2,3,4,5,6,8,9,11,12,13,14,16,17,18,19,24,25,28,30,31,32,33,34,35,36,37,38,39],j_:6,j_lasso_sk:6,j_ridge_sk:6,j_sk:6,jackknif:[6,23,31,34],jacobian:[2,13,35,36],jacobian_shap:2,jakobsen:29,jason:4,jax:[23,26,31,38],jax_descend_i:[21,37],jax_descend_x:[21,37],jax_enable_x64:[21,37],jax_grad:[21,37],jensen:[29,31,32,33,34,35,36,37,38,39],jentzen:[38,39],jerom:[18,25,30],ji:[12,24,38,39],jit:[13,36],jj:[0,5,6,31,33,34],jk:[0,1,6,12,24,31,37,38,39],jl:[0,31],jm:24,jnp:[13,21,36,37],job:[2,8,10],johansen:31,join:[0,3,4,6,7,9,14,31,32,34,35],joint:[4,5,33,34],judg:[13,35,36],judgement:[6,25],julia:[23,24,25],juliu:[38,39],jump:[25,28],junk:4,jupit:31,jupyt:[0,9,15,19,23,25,30,31,38,39],just:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,23,25,26,28,31,32,33,34,35,36,37,38,39],justif:0,justifi:[3,10],k0:[7,35],k1:[7,35],k:[0,1,3,5,6,7,8,9,10,11,12,13,14,23,24,25,28,29,31,32,33,36,37],kaggl:[6,25,26],kajda:39,kappa_d:28,karl:[29,31],karush:8,katrin:[29,31],keep:[0,1,4,5,6,11,13,14,22,24,25,26,31,32,33,34,35,36,37,38,39],keepdim:[1,6,10,24,34,39],kei:[0,1,3,6,12,32,37,39],kept:[4,6,14,34],kera:[0,4,23,25,26,31],kernel:[0,1,3,4,14,23,31,32,39],kernel_librari:[3,4,14],kernel_regular:[1,3,39],kernel_s:4,kernelpca:11,kev:[0,31],kevin:[30,31],keyboardinterrupt:[2,39],keyerror:[],keyword:[6,13,24,31,39],kfold:[6,34,35],kg:[1,39],ki:24,kick:[1,13,36,37,38,39],kiener:2,kilomet:[6,32,33],kind:[0,2,3,4,8,12,13,14,31,32,36,37,38,39],kj:[6,12,24,32,33,38,39],kjm:[23,31],kkt:8,kl:28,km:[12,31,37],kmean:14,kmeanspoint:14,kn_k:14,know:[0,1,2,5,6,8,13,23,31,32,33,35,36,37,38,39],knowledg:[0,23,31],known:[1,3,4,5,6,7,8,9,12,24,25,26,28,30,32,33,34,35,37,38,39],kondev:[0,31],kp:28,kpca:11,kroneck:14,kuckuck:[38,39],kuhn:8,kutyniok:[38,39],kvalsund:[29,31],kwarg:[2,39],kwown:[0,31],l0:[7,35],l1:[0,1,3,7,31,35,39],l1_l2:[1,3,39],l1regl:5,l2:[1,3,39],l:[0,1,2,3,5,6,7,8,10,11,12,13,19,24,25,28,31,32,35,36,37],l_1:[7,35,38],l_2:[7,13,26,35,36,38],l_:24,l_j:[12,38,39],l_ja:39,la:[13,36],la_i:[12,38,39],la_k:[12,38],lab:[20,23,25,31],label:[0,1,2,3,4,5,6,7,8,9,10,12,13,14,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],label_prob:[36,37],labelencod:[7,10,35],labels:[6,8,9],labels_shuffl:[0,1,32,39],laboratori:[27,33],lack:[0,31],lagari:2,lagrang:[8,11],lam:39,lambda:[0,1,2,3,5,6,7,8,10,12,13,17,18,21,25,26,28,31,32,33,34,36,37,38,39],lambda_0:11,lambda_1:[5,8,11,32],lambda_2:[8,11],lambda_:11,lambda_i:[8,11],lambda_iy_i:8,lambda_jy_iy_j:8,lambda_k:8,lambda_n:[5,8,32],lamda:[1,39],land:[0,8],landmark:8,landscap:[13,21,35,36,37],langl:[0,6,11,28,31,32],languag:[0,1,4,8,15,23,24,25,26,30,31,38,39],lapack:[24,31],laplac:[5,33,34],laptop:23,larg:[0,1,2,4,5,6,8,9,10,11,13,15,23,24,25,28,30,31,32,34,35,36,37,38,39],larger:[0,3,5,6,8,10,11,13,17,28,31,32,33,34,35,36,37],largest:[4,8,11],lass:26,lasso:[0,7,23,26,31],lasso_sk:6,last:[0,1,2,3,4,5,6,7,8,10,12,13,14,17,18,24,25,28,29,31,33,34,36],latent:4,latent_dim:4,latent_point:4,latent_space_value_rang:4,later:[0,1,4,7,8,12,13,14,15,22,23,25,26,31,35,36,37,38],latest:[4,23],latest_checkpoint:4,latex:31,latter:[0,3,6,7,8,11,13,16,24,25,28,31,32,33,34,35,36,37,38],lattic:[12,37,38],law:0,lax_numpi:[21,37],layer:[0,4,13,21,22,26,31,36,37],lbfg:[7,9,10,11,35],lcc:[5,6,33,34],lda:11,ldot:[0,6,11,19,25,31,34,35],le:[5,7,10,13,17,21,28,32,33,35,36,37],lead:[0,1,3,5,6,7,8,9,10,11,12,13,16,17,24,28,31,32,33,34,35,36,37,38,39],leaf:9,leaki:[1,26,38,39],leakyrelu:4,lear:[13,35,36],learn:[3,4,5,6,7,8,9,10,12,18,22,24,27,29,30],learnabl:3,learner:10,learnig:31,learning_r:[8,10,21,37],learning_rate_init:[0,1,31,39],learning_schedul:[13,21,36,37],learnt:[25,26],least:[0,2,7,8,10,11,15,16,17,19,21,23,24,26,28,34,35],leat:[13,21,36,37],leav:[0,1,3,5,6,9,11,22,31,33,34,35,38,39],lectur:[0,1,5,10,11,12,13,15,17,21,23,24,25,26,27,29,30],lecturenot:[0,17,19,23,25,30,31],left:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,16,17,19,24,25,28,31,32,33,34,35,36,37,38,39],leftarrow:[8,12,38,39],legend:[0,2,3,4,5,6,7,8,9,10,13,22,31,32,33,34,35,36,37],legend_el:22,len:[0,1,2,3,4,5,6,8,9,10,11,12,24,31,32,33,34,36,37,38,39],length:[0,1,2,3,4,8,9,13,16,22,23,31,32,35,36,37,39],length_of_sequ:4,leq:[0,5,7,8,13,14,28,31,32,33,35,36],less:[0,1,3,4,5,6,8,9,13,23,28,31,32,33,34,35,36,37,39],lessen:[1,38,39],let:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,24,28,31,32,33,34,35,36,37,38,39],letter:[0,16,24,28,31,32],level:[0,1,5,6,9,23,24,25,26,27,29,31,34,38,39],li:[8,11],lib:[0,1,2,3,4,6,7,8,9,11,14,21,31,33,35,37],liblinear:[8,10],libmetal_plugin:[3,4,14],librari:[0,1,2,3,4,5,6,7,9,10,11,14,15,21,24,25,26,28,30,32,33,35,39],library_loc:[3,4,14],licens:[0,1,15,23,25,26,31,39],lie:[0,6,11,28,31,32,34],life:[0,1,8,12,31,37,38,39],lifetim:[13,36,37],like:[0,1,2,3,4,5,6,7,9,10,11,12,13,15,16,21,22,23,24,25,26,28,31,32,33,34,35,36,37,38,39],likelihood:[0,1,5,9,31,32,36,37,39],lim_:28,lima:29,limit:[0,5,6,8,9,11,12,21,24,25,26,31,32],lin_clf:8,lin_model:0,lin_reg:9,linalg:[0,2,5,6,8,11,13,21,24,28,31,32,33,35,36,37,38],line1:8,line2:8,line2d:[21,36,37],line3:8,line:[0,1,2,3,4,6,7,8,10,11,13,14,21,25,31,32,33,34,35,36,37,38,39],linear:[1,3,5,6,7,9,10,11,12,17,18,21,23,25,28,34,36,37,38,39],linear_model:[0,5,6,7,8,9,10,11,13,31,32,33,34,35,36,37,38],linear_regress:[6,34,39],linearli:[5,32],linearloc:[6,13,25,35,36],linearregress:[0,6,7,9,31,32,33,34,35],linearsvc:8,lineat:33,liner:[1,3,39],linerar:10,linewidth:[0,2,4,6,8,9,10,25,34],link:[0,4,9,12,22,23,25,26,29,31,38],linlag:[5,33],linpack:[24,31],linreg:[0,31],linspac:[0,2,3,4,6,8,9,10,13,15,16,21,24,28,31,32,33,34,36,37],linu:4,linux:[0,1,15,23,25,31,39],liquid:[0,31],list:[0,1,2,3,4,7,9,22,23,25,26,31,32,35,36,37],listcomp:2,listedcolormap:[9,10],literatur:[1,7,14,30,34,35,38,39],littl:[1,3,9,12,38,39],live:8,ll:[0,28,31,32],lle:[0,32],lloyd:[4,14],lmb:[0,2,5,6,33,34,35],lmbd:[0,1,3,31,39],lmbd_val:[0,1,3,31,39],lmbda:[13,35,36],ln:[1,13,35,36,39],load:[0,1,3,4,6,7,9,10,14,22,25,35,39],load_boston:0,load_breast_canc:[1,7,9,10,11,35,39],load_data:[3,4],load_digit:[1,3,39],load_iri:[8,9,22],load_librari:[3,4,14],load_pluggable_device_librari:[3,4,14],loc:[0,3,6,7,8,9,10,22,31,34,35],local:[0,1,2,3,7,12,13,22,32,35,36,37,38,39],locat:[2,3,8],log10:[0,5,6,33,34,35,39],log:[0,1,2,4,5,6,7,9,10,11,13,24,25,26,31,32,33,34,35,36,37,39],log_:[0,31],log_clf:10,logaddexp2:[],logaddexp:[],logarithm:[0,5,7,24,31,33,34,35],logbook:[25,26],logic:[0,1,9,31,38,39],logist:[0,1,2,8,9,10,11,12,13,21,23,32],logistic_predict:[36,37],logistic_regress:39,logisticregress:[7,9,10,11,35,37,38],logit:[7,35],logreg:[7,9,10,11,35,37,38],logspac:[0,1,3,5,6,31,33,34,35,39],longer:[2,3,8,10,14,24,26,28,31],loocv:[6,34,35],look:[0,1,2,3,4,5,6,7,8,9,10,11,13,16,18,21,24,25,26,28,31,32,33,34,35,36,37,38,39],loop:[1,4,6,10,12,14,22,23,24,31,34,39],lose:[1,39],loss:[0,1,3,4,5,6,7,8,10,11,13,22,24,25,26,31,33,34,37,38,39],loss_fil:4,lossfil:4,lost:4,lot:[0,1,4,6,22,34,36,37,38,39],low:[0,6,9,10,11,25,31,32,34],lower:[0,1,3,6,9,10,16,22,24,32,38,39],lowercas:[24,31],lowest:[9,13,28,36,37],lr:[1,3,4,10,39],lrelu:39,lstat:0,lstm:4,lstm_2layer:4,lstsq:[0,31,32],lt:[6,34],lu:[0,5,31,32],lubksb:24,luckili:2,ludcmp:24,lux:24,lvert:[1,39],lw:[0,31],m:[0,1,2,3,5,6,8,9,10,11,12,13,21,24,27,28,29,30,31,32,33,34,35,36,37,38,39],m_1:14,m_:[9,12,38,39],m_h:[0,31],m_k:14,m_l:[12,38,39],m_n:[0,31],m_p:[0,31],m_t:[13,36,37],ma:11,machin:[1,3,4,5,6,7,9,10,11,12,15,21,24,27,30,32,33,34,37,38,39],machinelearn:[0,6,16,17,19,20,23,25,27,29,30,31,35,36,37],mackai:30,made:[0,1,3,4,5,6,7,9,11,12,18,25,26,31,32,35,37,38,39],mae:[0,31],magic:4,magnitud:[1,6,7,13,32,33,35,36,37,38,39],mai:[0,1,2,3,5,6,7,8,9,11,12,13,18,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],mail:[27,29],main:[0,1,3,4,5,6,7,9,24,25,26,30,32,35,38,39],mainli:[0,5,6,7,9,31,32,33,34,35],maintain:[6,34],major:[1,6,9,10,13,24,31,34,35,36,37,39],make:[1,2,3,4,5,6,7,8,11,12,13,21,22,23,24,25,26,28,30,33,34,35,36,37,38,39],make_axes_locat:6,make_classif:[37,38],make_moon:[8,9,10],make_pipelin:[0,6,10,32,34],make_vjp:2,makedir:[0,6,7,9,31,32,34,35],makeplot:[0,31],malcondit:24,malign:[1,7,9,35,39],mammographi:[5,33,34],manag:[0,2,3,15,23,25,31],mandatori:[29,31],mani:[0,1,3,4,5,6,7,8,9,11,13,14,21,22,23,24,25,26,28,30,31,32,33,34,35,36,37,38,39],manifold:11,manner:3,manual:[6,32,33,35],map:[0,1,2,6,7,8,11,12,14,25,28,31,35,37,39],marc:32,margin:[0,5,8],marit:[0,31],mark:31,marker:[0,7,21,24,31,35,37],markov:[23,31],marsaglia:28,mass:[0,1,5,13,32,36,37,39],massag:[0,31],masses2016:[0,31],masses2016ol:[0,31],masses2016tre:0,masseval2016:[0,31],master:[6,16,20,25,27,29,35,36,37],mat1100:[23,31],mat1110:[23,31],mat1120:[23,31],mat:[23,31],match:[1,4,5,13,14,32,35,36,37,38,39],match_complex:[],materi:[4,5,7,13,17,24,29,36,37],math:[3,7,12,13,21,24,28,30,31,35,36,37,38,39],mathbb:[0,4,5,6,7,8,11,12,13,14,17,18,19,24,25,28,31,32,33,34,35,36,37,38],mathbf:[0,5,6,7,8,13,18,19,21,24,25,31,32,33,34,35,36,37,38],mathcal:[1,5,6,7,13,19,25,33,34,35,36,39],matheemat:3,mathemat:[0,6,11,12,13,17,23,24,28,30,31,33,35],mathemati:31,mathmlbook:16,mathrm:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,25,28,31,32,33,34,35,36,37,38,39],matmul:[1,2,5,33,38,39],matnat:30,matplotlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,21,22,23,24,25,28,31,32,33,34,35,36,37,38,39],matric:[0,1,3,4,6,7,8,11,13,16,17,23,32,35,36,38,39],matrix:[0,2,3,4,6,7,8,10,13,15,16,17,18,19,21,25,26,28,34,38],matshow:[1,39],matter:[2,3,13,32,35,36,37,38],max:[0,1,2,3,4,9,10,12,13,21,29,31,35,36,37,38,39],max_depth:[0,9,10],max_diff1:2,max_diff2:2,max_diff:2,max_it:[0,1,8,9,11,13,31,35,36,37,38,39],max_iter:14,max_leaf_nod:10,max_sampl:10,maxdegre:[0,6,10,32,34],maxdepth:10,maxim:[1,4,5,7,8,11,33,34,35,39],maximum:[0,1,2,3,5,7,8,9,10,13,14,31,32,36,37],maxpolydegre:[5,6,33,34,35],maxpooling2d:3,mbox:[5,6,18,25,32,33,34],mcculloch:[12,37,38],md:[11,20,25,36,37],mdoel:4,mean:[1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,19,21,23,24,25,26,28,31,34,36,37,38,39],mean_absolute_error:[0,31],mean_divisor:14,mean_i:28,mean_matrix:14,mean_squared_error:[0,4,6,7,10,31,32,34,35],mean_squared_log_error:[0,31],mean_vector:14,mean_x:28,meaning:[0,4,7,31,35],meansquarederror:[0,31],meant:[2,3,7,10,13,35,36,37,38],measur:[0,1,2,5,6,9,11,12,14,19,25,26,28,31,32,33,34,38,39],mechan:[0,4,28,31],median:[0,31,32],medicin:[12,37,38],medium:[4,8,13,26,36,37],medv:0,meet:[0,29],mehta:[0,31,32,33],memori:[3,4,11,12,13,21,24,36,37,38],mention:[0,12,13,25,26,28,31,35,36,37,38],mere:[0,15,26,31],meshgrid:[2,5,6,8,9,10,11,25,32,39],mess:22,messag:[5,13,36,37],messi:2,met:[0,3,8,32],metadata:2,meteorolog:9,meter:[6,32,33],method:[0,1,2,3,4,5,7,8,11,12,14,16,17,18,19,23,24,26,28,30,32,33,38],metion:[6,25],metric:[0,1,3,6,7,9,10,14,15,16,31,32,34,35,39],metropoli:[23,31],mev:[0,28,31],mgd:[13,36,37],mglearn:[23,31],mgrid:[13,36],mhjensen:[1,2,3,4,6,8,9,11,14,21,37],mi:10,mia:[29,31],michael:[26,38,39],michigan:[31,33,35,36,37,39],microsoft:30,mid:[1,39],midel:4,midnight:[16,17,18,19,20,21,22],midpoint:9,might:[0,1,2,4,6,9,13,32,33,35,36,37,38,39],mild:9,millimet:[6,32,33],million:[0,31,32,36,37],mimic:[12,37,38],min:[0,2,5,8,9],min_:[0,2,5,14,17,31,32,33],min_samples_leaf:9,mind:[0,6,13,25,31,32,33,34,35,36],mindboard:4,mine:[23,31],mini:[1,11,12,13,21,26,35,38,39],minibatch:[1,11,13,39],minibathc:[13,36,37],miniforge3:[0,1,2,3,4,6,7,8,9,11,14,21,31,33,35,37],minim:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,17,18,21,25,32,33,34,36,37,38,39],minima:[0,1,7,13,31,35,36,37,39],minimum:[0,1,2,6,8,9,11,13,32,34,35,36,37,39],minmaxscal:[0,32,39],minor:28,minst:[1,39],minu:[7,35],mirjalili:31,mirror:9,misc:[6,25],misclassif:[8,9,10],misclassifi:[8,10],miser:0,mismatch:[1,38,39],miss:[0,7,10],mistak:4,mit:30,mix:[1,2,31,38,39],mixtur:[13,21,36,37],mk:[9,24],mkdir:[0,6,7,9,31,32,34,35],ml:[0,1,10,13,24,25,26,32,35,36,37,38,39],mlab:28,mlbook:31,mle:[5,7,35],mlp:[1,37,38,39],mlpclassifi:[1,37,38,39],mlpregressor:[0,31],mm:24,mml:32,mn:[12,28,37],mnist:[1,11,26,38,39],mod:28,mode:[27,29,31,39],model:[2,3,5,7,8,9,10,11,13,14,15,16,18,19,21,23,25,28,30,32,33,34,35,36],model_select:[0,1,3,5,6,7,9,10,11,31,32,33,34,35,39],moder:10,modern:[0,6,7,23,31,34,35,38,39],modif:[2,12,13,36,37],modifi:[0,1,3,5,7,8,10,12,13,31,32,33,35,36,37,38,39],modul:[0,9,11,24,31,33],modular:28,modulo:28,moe:[11,32],moment:[5,6,13,21,28,33,34,39],moment_correct:39,momentum:[26,38,39],momentum_schedul:39,mondai:31,monitor:[13,21,36,37],monoton:[5,12,28,33,34,37,38,39],mont:[0,6,23,28,30,31,34],moor:[5,6,33],more:[0,1,2,4,5,7,8,9,10,11,12,13,14,18,23,26,28],moreov:[0,3],morten:[29,31,32,33,34,35,36,37,38,39],most:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,23,25,28,31,32,33,34,35,36,37,38,39],mostli:[1,11,38,39],motion:[0,13,36,37],motiv:[1,4,38,39],move:[0,4,5,6,7,9,12,13,14,21,25,28,32,33,34,35,36,37,38,39],mpl:[0,7,31,35],mpl_toolkit:[2,6,13,25,35,36],mplot3d:[2,6,13,25,35,36],mplregressor:[1,39],mse:[0,4,5,6,9,10,15,16,17,19,25,26,31,32,33,34,35,39],mse_simpletre:10,mselassopredict:[5,33],mselassotrain:[5,33],mseownridgepredict:[6,33],msepredict:[5,33],mseridgepredict:[0,5,6,33,35],msetrain:[5,33],msle:[0,31],mt:[7,12,35,37,38,39],mu0:28,mu1:28,mu2:28,mu:[0,6,11,13,28,31,34,36,37],mu_1:32,mu_:[6,28,32,33,34],mu_i:[6,32,33],mu_n:11,mu_x:28,much:[0,1,2,3,4,5,6,8,9,10,11,12,13,24,25,28,31,32,33,34,36,37,38,39],multi:[0,1,3,7,23,31,35],multiclass:[1,7,35],multidimension:[11,12,31,37,38],multilay:[1,39],multinomi:[7,35],multipl:[2,4,5,6,7,12,13,22,28,32,34,35,36,37,38],multipli:[2,3,5,6,11,13,24,28,32,33,36],multiplum:8,multivari:[0,2,10,11,23,28,31],multivariate_norm:[11,14],murphi:[11,30,31],must:[1,2,5,6,8,10,12,13,14,28,32,34,35,36,37,38,39],mutat:[7,35],mutual:[1,3,6,13,34,35,36,38,39],mx_:28,myenv:[0,1,2,3,4,6,7,8,9,11,14,21,31,33,35,37],myriad:[0,15,23,31],mz1:28,mz2:28,n1:24,n2:24,n:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,21,24,25,26,28,31,32,33,34,35,36,37,38,39],n_0:[12,28,37],n_:[1,2,3,8,12,28,37,39],n_boostrap:[6,10,34],n_bootstrap:[6,34],n_categori:[1,3,39],n_cluster:14,n_compon:11,n_data:37,n_epoch:[13,21,36,37,39],n_estim:10,n_examples_to_gener:4,n_featur:[1,38,39],n_filter:3,n_hidden:2,n_hidden_neuron:[0,1,31,38,39],n_i:28,n_input:[0,1,3,32,38,39],n_instanc:9,n_iter:[35,36],n_iter_i:[9,11],n_job:10,n_k:14,n_l:[12,28,37],n_layer:[1,39],n_m:9,n_neuron:[1,39],n_neurons_connect:3,n_neurons_layer1:[1,39],n_neurons_layer2:[1,39],n_output:[38,39],n_point:14,n_sampl:[6,8,9,10,14,34,37,38],n_split:[6,34,35],n_step:4,n_t:2,n_x:2,nabla:[1,13,35,36,39],nabla_:[2,13,21,35,36,37],nabla_w:[13,36,37],nafter:39,nag:[13,36,37],naimi:[0,31],naiv:[7,35],naive_kmean:14,najafi:[29,31],name:[0,1,3,4,5,6,7,8,9,10,12,13,14,15,23,24,25,28,29,31,32,33,34,35,36,37,38,39],nameerror:[10,25],namespac:[3,4,14],nan:39,narrow:[13,36,37],nary_f:2,nary_op_arg:2,nary_op_kwarg:2,nary_oper:2,nation:[1,5,33,34,39],nativ:[23,31],natur:[0,1,4,8,9,12,13,25,26,28,30,31,35,36,37,38,39],navier:[12,37,38],nb:28,nb_:24,nbconvert:31,nbviewer:9,nd:14,ndarrai:[2,6,39],nderiv:39,ndim:[],ne:[9,10,24,28,32],nearest:[1,3,6,11,39],nearli:[13,35,36],neat:31,neatli:[],neccesari:[6,34],necess:2,necessari:[0,1,3,4,8,14,31,38,39],necessarili:[0,4,11,28,31],necesserali:[5,33,34],neck:[7,35],need:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,21,22,24,26,28,32,33,34,35,36,37,38,39],neg:[0,1,3,5,6,7,10,13,24,28,31,33,34,35,36,37,38,39],neg_mean_squared_error:[6,34,35],neglect:28,neglig:28,neighbor:[3,6,11],neither:[4,13,36,37],neq:[13,14,28,35,36],nerual:39,nervou:[12,37,38],nest:[2,9,12,37],nesterov:[13,36,37],net:[2,4,12,37,38],netlib:[24,31],network:[0,9,13,21,22,23,30,32,36],network_input_s:22,neural:[0,13,21,22,23,30,32,35,36],neural_network:[0,1,2,31,37,38,39],neuralnetwork:[1,39],neuralnetworksanddeeplearn:[26,38,39],neuron:[1,2,3,4,12,39],neutal:22,neutral:[0,31],neutron:[0,31],never:[1,4,6,9,28,34,38,39],new_box:2,new_chang:[13,21,36,37],new_hobbit:31,new_root:2,new_trac:2,newaxi:[0,3,6,9,34,35],newli:[0,31],newton:[1,7,8,13,28,38,39],next:[0,1,2,3,4,5,6,7,8,9,13,14,21,22,31,32,33,35,36,37,38,39],next_guess:[13,36],next_input:4,ng:[1,38,39],ngini:9,nhow:39,ni:[14,21],nice:[0,1,5,11,31,32,33,34,39],nielsen:[26,38,39],nine:[38,39],niter:[13,21,35,36,37],nitric:0,nlambda:[0,5,6,33,34,35],nlp:30,nm:28,nm_n:[0,31],nmse:[6,34],nn:[2,5,6,12,24,33,34,37],nn_model:[1,39],nnmin:2,node:[1,2,3,9,10,12,26,37],node_constructor:2,nois:[0,4,5,6,8,9,10,13,15,16,19,25,31,32,33,34,35,36],noise_dimens:4,noisi:[1,6,19,25,34,39],non:[0,1,3,5,6,7,9,10,11,12,13,14,21,24,28,31,32,33,34,35,36,37,38,39],noncommerci:26,none:[0,1,2,4,5,9,10,13,28,31,32,33,34,35,38,39],nonlinear:[3,6,8,9,11,12,34,37,38],nonneg:[6,9,13,34,35,36],nonparametr:6,nonsens:28,nonsingular:24,nonumb:[3,7,8,13,21,24,35,36,37],nor:[1,4,13,36,37,38,39],norm:[0,1,5,6,8,11,13,17,31,32,33,34,35,36,37,38,39],normal:[3,4,5,6,7,8,9,10,11,12,13,15,16,18,19,21,23,24,25,26,28,31,32,33,35,36,37],normali:[24,31],norwai:[6,25,26,31,34,37],notat:[0,2,5,6,13,14,21,28,31,32,33,34,36,38,39],note:[0,1,2,3,4,5,6,7,8,11,12,13,14,15,16,23,24,26,28,30,31,34,35,36,38,39],notebook:[0,1,3,9,15,22,23,25,26,31,38,39],notesseptember16:35,notesseptember30:37,notfounderror:[3,4,14],noth:[1,2,5,8,12,14,28,32,33,37,38,39],notic:[4,5,12,13,24,28,31,33,36,37,38,39],notimplementederror:39,notion:3,noutput:39,novel:[3,6,10,35],novemb:[1,27,29,31,39],now:[0,2,4,5,6,7,8,10,11,12,14,15,16,17,23,24,25,26,28,31,32,35,38],nowadai:[0,1,3,9,23,31,38,39],nox:0,np:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,21,22,24,25,28,31,32,33,34,35,36,37,38,39],npr:2,nsampl:[6,9,34,35],nt:2,ntrained_model:[6,33],nu:28,nuclear:[5,32],nuclei:[0,28,31],nucleon:[0,31],nucleu:[0,31],num:4,num_coordin:2,num_equ:39,num_featur:37,num_hidden_neuron:2,num_it:2,num_iter:[21,37],num_neuron:2,num_neurons_hidden:2,num_not:39,num_point:2,num_tre:10,num_valu:2,number:[1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,24,25,26,27,29,31,33,34,35,39],numberid:[7,35],numberparamet:3,numer:[0,5,6,9,10,11,12,13,17,21,23,24,30,31,32,33,34,35,36,37,38],numpi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,22,23,25,28,32,33,34,35,38,39],numpy_box:2,numpy_vjp:2,numpy_wrapp:2,nunmpi:[5,32],nvalu:9,nx:2,nx_test:[6,33],nx_train:[6,33],nx_train_mean:[6,33],ny:[28,39],ny_pr:[6,33],ny_train:[6,33],ny_train_mean:[6,33],o:[0,6,7,8,9,11,15,21,24,29,30,31,35,37],obei:[6,11,13,32,33,36],obj:[],object:[0,1,2,4,6,8,10,24,31,36,38],obliqu:[5,32],observ:[0,1,3,5,6,7,8,9,10,11,12,13,14,28,33,34,35,36,37],obtain:[0,1,5,6,7,8,9,10,12,13,14,17,21,24,25,26,28,31,32,33,34,35,36,37,38,39],obviou:[5,6,11,28,32],obviouli:31,obvious:[0,4,5,6,21,24,26,31,33,34],oc:32,occupi:0,occur:[0,6,8,9,24,28,31],oct:26,octob:[21,22,27,29,31,37],od:0,odd:[0,3,7,31,32,35],odenum:2,odesi:2,odin:31,oen:0,off:[1,3,4,5,9,13,19,22,28,33,34,36,37,39],offer:[6,11,23,24,27,29,31,34],offic:[29,31],offici:[27,31],often:[0,1,3,4,5,6,7,8,9,10,11,12,13,14,16,22,23,24,25,28,31,32,34,35,36,37,38,39],ofter:[24,31],og:39,ol:[0,13,15,16,17,18,26,31,32],old:[1,5,10,13,22,33,34,35,36,39],ols_sk:6,ols_svd:6,olsbeta:[0,5,33],omega:[2,3,6],omega_0:3,omit:[0,5,31,32,33,34],omlmp_kkie0:35,onc:[1,6,9,11,13,34,35,36,37,38,39],one:[0,1,3,4,5,6,7,8,9,10,11,13,14,19,21,22,23,24,25,26,28,29,31,32,33,34,37],onehot:[1,39],onehot_vector:[1,39],onehotencod:9,ones:[0,2,5,6,8,9,10,11,13,21,22,24,25,31,32,33,34,35,36],ones_lik:4,ong:32,onl:3,onli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,19,21,22,24,25,26,28,31,32,33,34,35,36,37,38,39],onlin:[11,27,38,39],onto:[5,11,32],open:[0,1,4,6,7,9,15,23,25,27,29,31,34,35,39],oper:[0,1,3,5,6,10,11,12,13,15,23,28,31,32,33,34,36,37,39],operation:28,oplu:28,opmiz:[13,36,37],opportun:0,oppos:[6,13,36,37],opposit:[1,5,8,32,38,39],opt:[1,5,26,31,33,38,39],optim:[0,2,3,4,5,6,7,9,10,11,14,15,16,17,18,19,21,22,25,26,33,34],optimis:[1,3,39],option:[0,1,3,5,6,8,9,11,21,24,25,26,32,33,34,37,39],optmiz:[1,8,13,21,32,36,37,38,39],oral:31,orang:0,order:[0,1,2,3,5,6,7,8,9,10,11,12,15,16,22,24,25,26,28,31,32,33,34,35,38,39],ordinari:[0,2,3,7,11,13,15,16,17,19,21,23,26,34,35,36,37],oreilli:[30,31],org:[0,3,4,9,11,21,22,23,24,25,26,30,31,33,36,37,38],organ:[6,7,10,24,34,35],orgin:38,orient:[1,5,28,32,33],origin:[0,3,5,6,8,11,12,13,24,31,32,34,36,37],orthogn:[5,32],orthogon:[0,5,6,8,11,13,17,24,31,32,33,36],orthonorm:[5,32,33],os:[0,1,4,5,6,7,8,9,29,31,32,33,34,35,39],oscar:[1,38,39],oscil:[3,13,36,37],oserror:[0,3,4,7,14,35],oslo:[0,15,23,25,26,27,29,31,32,33,34,35,36,37,38,39],osx:[0,15,23,25,31],other:[0,1,2,3,5,6,7,8,10,13,14,15,19,22,23,26,27,28,29,30,33,34,36],otherwis:[0,1,4,7,13,21,24,26,31,35,36,37,39],ouput:[5,7,12,33,34,35],our:[1,2,3,6,7,8,9,10,12,14,15,16,17,18,19,21,22,23,24,25,26,28,33,34,37],ourmodel:0,ourselv:[0,5,6,8,11,13,31,32,33,34,35,36],out1:[],out2:[],out:[0,1,2,4,5,6,7,8,9,10,11,12,13,16,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],out_deriv:39,out_fil:9,outcom:[0,7,9,10,12,28,32,35],outdoor:9,outer:[6,12,13,39],outfil:4,outgrad:2,outlier:[0,8,31,32],outlin:[6,10,11,34],outlook:9,outperform:10,output:[0,1,3,4,5,6,7,8,9,10,12,13,16,22,24,25,26,28,31,32,33,34,35,36,37],output_bia:[1,39],output_bias_gradi:[1,38,39],output_func:39,output_nod:39,output_s:22,output_shap:4,output_weight:[1,39],output_weights_gradi:[1,38,39],outputlayer1:[12,37],outputlayer2:[12,37],outsid:4,over1:[13,36,37],over:[0,1,3,4,5,6,9,10,12,13,21,22,24,25,31,32,33,34,35,36,37],overal:[1,10,39],overcast:9,overcom:[12,13,36,37,38],overdetermin:[0,31],overfit:[0,1,3,6,9,10,13,21,34,36,37,38,39],overflow:[1,5,33,34,39],overflowerror:39,overhead:[12,38,39],overlap:[3,7,8,9,35],overlin:[0,5,6,9,10,11,14,24,31,32,33],overst:0,overtrain:4,overview:[3,35],overwritten:39,own:[4,5,6,8,12,13,21,23,24,25,33,36,37,38,39],owner:0,ownmsepredict:0,ownmsetrain:0,ownridgebeta:[0,6,33],ownypredictridg:0,ownytilderidg:0,oxid:0,p0:2,p1:2,p:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,17,24,28,31,32,33,34,35,36,38,39],p_:[2,4,8,9],p_hidden:2,p_i:[5,28,33,34],p_j:28,p_n:28,p_output:2,p_x:28,pa:38,pack:[0,31],packag:[0,1,2,3,4,5,6,7,8,9,11,13,14,15,21,22,23,25,26,28,32,33,35,36,37,39],packtpub:31,packtpublish:31,pad:[3,4],page:[0,9,23,31,33,34,35,36],pai:[0,1,9,13,36,37,38,39],pair:[0,2,3,9,23,28,31],panda:[0,4,5,6,7,9,11,15,23,25,33,34,35],panel:31,paper:1,paradigm:[0,31],parallel:[10,13,21,23,24,31,36,37],param:2,param_distribut:35,param_grid:35,paramat:2,paramet:[0,1,2,3,4,5,6,7,8,9,10,12,13,16,17,18,19,21,22,25,26,28,33,34],parameter:[0,6,10,25,31,32],parametr:[0,6,15,16,31,32,34],paramt:[3,5,33,34,38],parent:[2,38],parent_argnum:[],part:[0,1,3,5,6,10,17,18,21,22,24,27,28,29,31,33,34,37],partial:[0,1,5,6,7,8,10,11,12,13,16,28,31,32,33,35,36,38,39],particip:[23,27,29,31],particl:[0,4,13,28,31,36,37],particular:[0,1,2,3,5,6,9,10,11,12,13,16,25,28,30,31,32,33,34,35,36,37,38,39],particularli:[5,6,8,11,13,21,28,32,34,35,36,37],partit:[1,4,9,39],partli:[6,31,34],pass:[2,3,12,14,22,35,38],passkwarg:[],password:[25,26],past:[10,28],patch:[6,28,34],path:[0,3,4,6,7,9,14,15,23,31,32,34,35],pathcollect:[21,37],patient:[7,35],patter:4,pattern:[0,3,4,12,27,30,31,37,38],pauli:[0,31],pc:[11,23],pca:[0,7,23,31,32,35],pd:[0,4,5,6,7,9,11,31,32,33,34,35],pde:2,pdf:[0,3,4,5,6,9,16,20,25,26,30,31,33,34,35,37],pedagog:[0,31,32],penal:[6,32,33],penalti:[6,13,25,32,33,35,36],penros:[5,6,33],pentagon:[13,35,36],peopl:[0,1,9,13,23,36,37,38,39],per:[0,1,6,27,29,31,34,38,39],perc_print:39,percentag:[0,10,11,29,39],perceptron:[0,1,7,31,35],peregrin:31,perfect:[0,1,13,21,31,36,37,39],perfectli:[4,6,34],perform:[0,2,3,4,5,6,8,10,11,12,13,14,15,16,17,19,21,22,23,24,25,26,28,31,32,33,34,35,36,37,38],performac:4,perhap:[0,5,13,31,32,33,35,36],perimet:[1,9,39],period:[1,4,28,39],permut:11,persist:[13,36,37],person:[5,6,7,27,29,31,32,33,34,35],perspect:30,pertin:[12,26,31,38,39],petal:[8,9],peter:[30,32],petersen:[38,39],phantom:28,phase:[6,12,37,38],phenomena:28,phi:8,phi_k:8,philipp:[38,39],philosophi:[13,36],phone:[29,31],photo:4,php:26,phrase:[0,31],physic:[0,1,4,7,12,13,26,28,29,30,31,32,33,34,35,36,37,38,39],pi:[2,3,5,6,7,9,12,13,28,33,34,35,36,37,38,39],pick:[1,9,10,11,13,14,36,37,39],pickl:[1,39],pictur:[0,31],pie:[23,31],piec:[11,14,22],pillow:[0,15,23,25,31],pinv:[5,6,13,21,32,33,36,37,38],pip3:[0,1,15,25,31,39],pip:[0,1,15,23,25,31,39],pipelin:[0,6,8,10,32,34],pippin:31,pit:4,pitfal:[6,32,33],pitt:[12,37,38],pixel:[1,3,4,39],pixel_height:[1,3,39],pixel_width:[1,3,39],place:[0,4,6,8,13,24,25,31,34,35,36],plai:[0,3,4,5,6,8,11,23,31,32,33,34,35,38,39],plain:[8,10,12,13,14,21,26,35,36,38,39],plan:[6,9,29,30,31],plane:[8,9],plateau:[5,33],platform:[23,31],plausibl:[12,37,38,39],pleas:[9,11,13,25,26,29,31,36,37],plenti:[1,38,39],plethora:[3,12,37,38],pliahhy2ibx9hdharr6b7xevztgzra1p:[37,38,39],plot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,21,22,23,24,25,26,28,31,32,33,36,37,38,39],plot_all_sc:[25,33],plot_confusion_matrix:[7,10,35],plot_count:6,plot_cumulative_gain:[7,10,35],plot_data:[1,39],plot_dataset:8,plot_decision_boundari:[9,10],plot_import:10,plot_iris_dataset:22,plot_max:4,plot_min:4,plot_model:4,plot_numb:4,plot_predict:8,plot_regression_predict:9,plot_result:4,plot_roc:[7,10,35],plot_surfac:[2,6,13,25,36],plot_train:9,plot_tre:[9,10],plqvvvaa0qudcjd5baw2dxe6of2tius3v3:[37,38,39],plt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,24,25,28,31,32,33,34,35,36,37,38,39],plu:[0,3,5,7,31,32,33,35],pluggabl:[3,4,14],plugin:[3,4,14],pm:[8,34],pmatrix:2,pml:30,pn:3,png:[0,4,6,7,9,31,32,34,35],point:[0,1,2,3,5,6,7,8,9,10,11,13,14,15,16,17,19,21,22,24,25,28,29,31,32,34,35,36,37,39],point_1:4,point_2:4,poisson:[23,28,31],poli:[6,8,34,35],poly100_kernel_svm_clf:8,poly3:0,poly3_plot:0,poly3dcollect:36,poly_degre:39,poly_featur:[8,9],poly_features10:9,poly_fit10:9,poly_fit:9,poly_kernel_svm_clf:8,polydegre:[0,5,6,10,32,33,34],polygon:[13,35,36],polym:[12,37,38],polymi:25,polynomi:[0,5,6,7,8,9,10,11,15,16,17,19,21,25,26,31,32,34,35,37,38],polynomial_featur:[6,34],polynomial_svm_clf:8,polynomialfeatur:[0,6,8,9,32,34,35],polytrop:[0,6,31,34],pool:3,pool_siz:3,poor:[1,13,21,35,36,37,38,39],poorli:[0,32],pop:2,popul:[0,5,31,32,33,34],popular:[0,1,3,6,7,8,9,11,12,15,23,24,25,28,32,35,37,38,39],popularli:[0,31],portabl:10,portion:[11,13,21,36,37],pose:[0,4,5,6,11,28,31,34],posit:[0,1,2,3,5,7,8,10,11,13,14,24,28,31,32,33,34,35,36,37,38,39],possibl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,19,21,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],posterior:[5,33,34],postpon:[0,31,32],postscript:[25,26],postul:[5,33,34],potenti:[0,3,5,6,12,13,31,32,33,34,36,37,38],pott:[12,37,38],power:[0,1,5,6,8,9,12,13,31,32,34,36,37,38,39],pp:[5,6,18,33,34,35,38,39],practic:[0,5,6,7,8,25,26,28,32,33,34,35],practition:[0,1,3,31,38,39],pre:31,precalcul:38,preced:[1,11,12,28,37,39],preceed:[4,39],preceq:8,precis:[0,2,5,11,13,24,25,26,28,31,32,33,34,36,37,38],pred:[6,34,36,37],pred_train:39,pred_val:39,predicit:0,prediciton:39,predict:[0,1,5,6,7,8,9,10,15,16,22,23,25,30,31,32,33,34,35,37,38,39],predict_prob:[1,39],predict_proba:[7,10,35,37,38],predictor:[0,5,6,7,9,10,11,31,32,33],prefer:[0,1,6,8,9,11,13,15,23,25,26,31,38,39],prepar:[0,6,24,25,26,31,32],preprocess:[0,4,6,7,8,9,10,11,25,33,34,35,39],prerequisit:0,prescript:[25,26],presenc:[13,36,37],present:[0,5,6,7,9,12,13,21,24,25,26,28,31,32,33,36,37,38,39],preserv:[3,11,24],press:[13,30,35,36,38,39],pretrain:[1,4,38,39],pretti:[0,4,8,9,15,22,23,25,31],prev_centroid:14,prevent:[13,28,36,37],previou:[0,1,2,3,4,5,6,8,10,11,12,13,21,22,24,25,26,28,32,35,36,37,38,39],previous:[2,3,9,10,28],price:[0,4,9,13,36,37],primal:8,primari:[0,7,31,35],prime:28,primit:2,princip:[0,5,7,23,31,32,35],principl:[0,6,7,8,14,31,34,35],print:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,21,22,24,28,31,32,33,34,35,36,37,38,39],print_funct:[8,9],print_length:39,printout:[0,31],prior:[0,5,6,31,33,34],privat:0,pro:26,prob:[1,28,39],probabilist:[0,30,31,32],probabl:[0,1,3,4,6,7,10,13,23,31,32,35,36,37,38,39],problem:[0,3,4,5,6,7,8,9,10,11,12,16,17,23,24,25,26,28,34],probml:30,proce:[0,5,6,7,8,9,10,11,13,24,31,32,33,34,36,38],procedur:[2,4,5,6,8,10,11,13,21,25,32,33,34,35,36,37],proceed:24,process:[0,2,4,6,9,10,12,13,15,21,23,24,25,28,30,31,34,35,36,37,38],prod:30,prod_:[1,5,7,33,34,35,39],produc:[0,3,4,5,6,9,10,11,12,13,23,24,25,28,31,32,33,34,36,37,38],product:[0,1,3,5,6,7,8,12,13,16,21,23,24,31,32,33,34,35,37,38,39],profess:[0,31],progag:26,program:[0,1,4,5,6,8,12,14,15,16,21,23,24,27,28,29,31,32,37,39],programm:24,progress:[1,4,14,36,38,39],prohibit:[6,34],project1:[6,25],project:[0,1,2,3,5,11,13,17,18,19,20,21,23,27,29,32,33,34,36,37,38,39],project_root_dir:[0,6,7,9,31,32,34,35],projectwrit:25,promin:[12,37,38],promis:8,promot:[29,31],prone:[9,22,38],pronounc:[13,23,31,36,37],proof:[0,11,12,13,31,34,35,36,38],prop:39,propag:[2,3,13,26,36,37],proper:[0,2,6,7,25,34],properli:[1,6,8,10,13,21,25,26,36,37,38,39],properti:[0,1,3,12,13,16,17,24,31,34,36,37,38,39],propgag:38,proport:[0,1,5,9,11,13,16,28,31,32,36,37,39],propos:[1,4,6,10,25,26,31,38,39],propto:[5,13,33,34,35,36,37],proton:[0,31],prove:[3,13,35,36,37],provid:[0,1,3,4,5,6,8,9,10,12,13,15,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],proxi:[1,13,21,36,37,38,39],prune:9,pseudo:[24,28,36],pseudocod:[25,26],pseudoinv:[5,33],pseudoinvers:[5,6,33],pseudorandom:[6,28,34],psycholog:[0,31],pt:[13,36],publish:[38,39],punish:[0,1,31,39],pure:[3,9,28],purest:9,puriti:9,purpos:[0,3,10,12,14,31,37,38],put:[1,39],py:[0,1,2,3,4,5,6,7,8,9,11,14,21,31,33,34,35,37,39],py_tf:[3,4,14],pycod:31,pydata:23,pydot:9,pyhton2:31,pylab:[0,7,31,35],pypi:23,pyplot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,22,24,25,28,31,32,33,34,35,36,37,38,39],pythagora:[5,33,34],python2:[0,15,25,31],python3:[0,1,2,3,4,6,7,8,9,11,14,15,21,23,25,31,33,35,37],python:[1,2,3,4,5,6,8,11,12,13,14,16,21,22,25,26,28,32,33,36,37,38,39],pytorch:[0,22,23,25,26,31,38,39],q:[5,6,8,11,28,32,34,39],qp:8,qquad:[2,11,13,24,36,37],qr:[5,6,24,32],quad:[1,13,24,36,39],quadrat:[0,8,9,13,15,16,31,36],qualit:[4,9,25,26,28],qualiti:[0,9,15,16,23,31,32,38],quantifi:[1,38,39],quantil:10,quantit:[0,6,9,25,26,31,34],quantiti:[0,2,5,6,7,9,10,11,12,14,16,24,28,31,32,33,34,35,38,39],quantum:[4,12,30,31,37,38],quartil:[0,32],quasi:38,quench:5,queri:9,question:[0,5,6,9,11,12,13,25,29,31,32,33,34,36,37,38,39],qugan:4,quick:[4,28],quickli:[1,3,9,11,13,35,36,38,39],quit:[1,5,6,9,10,12,32,34,37,38,39],quot:4,r2:[0,5,6,26,31,32,33,35],r2_score:[0,31],r2score:[0,31],r:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,23,24,25,28,32,33,34,35,36,37,38,39],r_1:9,r_2:9,r_j:9,r_m:9,rad:0,radial:[0,8,12,37,38],radioact:28,radiu:[0,1,9,32,39],rag:2,rain:9,rais:[0,2,3,4,7,14,33,35,39],ramp:[1,38,39],ran0:28,ran1:28,ran2:28,ran3:28,rand:[0,4,5,6,9,10,13,15,16,21,22,24,31,32,33,34,35,36,37,39],randint:[6,9,13,21,34,36,37],randn:[0,1,2,5,6,9,11,13,15,16,21,22,31,32,33,34,35,36,37,38,39],random:[0,1,2,3,4,5,6,8,9,13,14,15,16,21,22,23,24,25,31,32,33,34,36,37,38,39],random_forest_model:10,random_index:[13,21,36,37],random_indic:[1,3,39],random_st:[0,7,8,9,10,11,35,37,38],randomforestclassifi:10,randomizedsearchcv:35,randomli:[1,6,9,13,14,21,34,35,36,37,39],randuniform:35,rang:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,21,24,28,31,32,33,34,35,36,37,38,39],rangl:[0,6,11,28,31,32],rangle_x:28,rank:[5,32],rankdir:4,raphson:[1,8,13,39],rapidli:0,rare:[1,13,31,35,36,37,38,39],raschka:[26,31,32,33,34,35,36,37],rasckha:31,rashcka:[38,39],rashkca:[38,39],rate:[0,1,2,3,4,8,9,10,12,13,26,35,38],rather:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,24,28,31,32,33,34,35,36,37,38,39],ratio:[4,7,9,10,11,35],rational:[0,31],ravel:[5,6,7,8,9,10,11,13,24,32,34,35,36,39],raw:3,rbf:[8,11,12,37,38],rbf_kernel_svm_clf:8,rbf_pca:11,rc:[0,28],rc_temp:[0,7,35],rcond:[0,31,32],rcparam:[0,1,3,7,8,9,10,28,31,35,39],re:[2,4,13,35,36],reach:[1,4,5,6,9,10,11,12,13,14,33,34,35,36,37,38,39],read:[0,2,3,4,5,6,7,8,11,12,16,21,24,25,26,27,28,30,33,36],read_csv:[0,6,7,9,31,34,35],read_fwf:[0,31],reader:[0,6,24,28,31,32,33],readi:[0,1,5,6,8,10,11,12,24,25,31,33,34,38,39],readili:[1,39],readthedoc:23,real:[0,1,2,4,7,10,11,12,24,32,34,35,37,39],real_loss:4,real_output:4,realist:8,realiti:28,realiz:[1,12,37,39],realli:[0,1,31,38,39],rearrang:[13,36,37],reason:[0,1,3,4,10,13,30,31,35,36,37,38,39],reassign:[1,39],reat:39,reber:39,recal:[5,6,9,10,11,12,24,28,31,32,33,34,35,36,38,39],recast:3,receiv:[1,3,10,12,28,37,38,39],recent:[0,2,3,4,6,7,10,13,14,21,25,30,31,33,34,35,36,37,38,39],recept:[3,12,37,38],receptive_field:3,recip:[0,6,7,24,25,26,31,32,35],reciproc:[5,33],recogn:[0,4,5,10,31,33,34],recognit:[0,1,3,12,27,30,31,37,38,39],recommen:31,recommend:[0,2,3,4,5,6,8,13,15,18,21,22,23,24,25,26,30,33,34,36,37],reconsid:9,reconstruct:11,record:[10,25,26,27,29,31,36,37],rectangl:[9,13,35,36],rectangular:[5,32],rectifi:[1,3,12,37,38,39],recur:[0,23,31],recurr:[0,1,23,31,39],recurs:[9,23,24,31],red:[0,3,4,6,8,9,21,34,36,37],redefin:[0,10,31,32],redefinit:33,reduc:[1,3,5,6,9,10,11,13,21,31,33,34,35,36,37,39],reduct:[0,10,11,23,28,31,32],refer:[0,1,2,3,5,6,9,11,12,13,14,20,24,26,30,31,32,34,35,36,37,38,39],referenc:[2,38,39],refin:[12,37,38],refit:[6,34],reflect:[0,1,4,5,25,26,28,31,39],refresh:[23,31],refreshprogrammingskil:31,reg:[10,11],regard:[1,9,13,36,38,39],regardless:[12,37,38,39],region:[3,4,6,9,12,25,37,38],regist:[6,25,28],reglasso:[5,33],regr_1:[0,9],regr_2:[0,9],regr_3:[0,9],regress:[1,8,11,12,15,16,21,23,24,39],regressor:[0,7,10,31,35,39],regridg:[0,5,6,33,35],regular:[0,3,4,5,6,7,9,13,17,26,29,31,32,33,34,36,37,38],regularis:6,reilli:[0,15,30,31],reinforc:[0,8,23,31],reiniti:39,reiter:[1,39],reject:7,rel:[0,4,6,7,9,12,13,28,31,32,34,35,36,37,38,39],relat:[0,1,3,4,5,11,13,14,24,28,31,33,34,36,37,38,39],relationship:[0,4,9,31],relativeerror:[0,31,32],releas:[1,23,26,31,39],relev:[0,1,5,7,11,15,21,23,25,26,28,31,33],reli:[0,6,8],reliabilti:[25,26],reliabl:[7,28,35],relu:[3,4,22,26,31],remain:[1,2,4,6,12,24,28,32,33,34,35,37,38,39],remaind:28,reman:2,remark:[1,38,39],rememb:[0,8,13,24,25,26,31,36,37],remind:[0,5,11,13,24,28,32,33,34],remov:[0,4,5,6,32,33],render:[0,9,31,32],reorder:[5,7,32,33,35],reorgan:[0,31],repeat:[0,1,3,4,5,6,9,10,11,13,14,21,24,25,26,28,31,33,34,35,36,37,38,39],repeated:31,repeatedli:[0,6,10,13,34,36,37],repet:3,repetit:[6,31,32,34,35,36],rephras:[13,35,36],replac:[0,1,3,4,5,6,10,12,14,15,16,21,23,25,26,31,32,33,34,35,38,39],replica:[6,34],repo:[25,26],report:[20,31,36,37],reportexampl:[20,25],reportsampl:20,repositori:[0,4,25,26,31],repres:[0,1,2,3,4,5,6,7,8,9,10,12,13,26,28,31,32,33,34,35,36,37,38,39],represent:[0,1,3,6,9,28,31,34,35,39],representd:3,reproduc:[0,5,6,9,12,15,16,23,25,28,31,32,38,39],repuls:[0,31],request:[0,13,21,36,37],requir:[0,1,3,4,5,6,8,9,11,12,13,17,24,31,32,33,34,35,36,37,38,39],rerun:[9,39],res1:2,res2:2,res3:2,res_analyt:2,res_analytical1:2,res_analytical2:2,res_analytical3:2,resaml:[6,25],resampl:[0,7,10,19,23,31,32,35,36,39],rescal:[0,11,12,32,37],rescu:[5,33,34],reseach:[6,25],research:[0,4,13,21,23,30,31,36,37],resembl:[6,28,34],reserv:[1,5,6,28,33,34,39],reset:39,reset_weight:39,reshap:[0,1,2,3,4,6,8,9,10,15,16,24,31,32,34,39],residenti:0,residu:[0,5,13,31,36],resiz:[5,32],resourc:31,respect:[0,1,2,3,5,6,7,8,10,11,12,13,14,16,17,21,25,28,31,32,33,34,35,36,37,38,39],respond:[12,37,38],respons:[0,7,9,12,31,32,35,37,38],rest:[0,5,32],restat:[0,12,31],restor:4,restored_discrimin:4,restored_gener:4,restrict:[0,3,9,12,31,37,38,39],result:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,23,24,25,26,28,31,34,35,36,37],retail:0,retain:[5,6,32,34,35],rethink:34,retriev:31,return_data:14,return_sequ:4,return_x_i:9,reus:[1,3,6,18,19,20,25,26,38,39],reveal:[0,12,31,37,38],revers:[1,24,39],review:[23,24],revisit:[14,38],revolut:31,reward:[0,4,31],rewrit:[0,3,5,6,7,8,10,11,12,13,19,24,25,28,33,35,36,37,38,39],rewritten:[2,6,8,10,28,34],rewrot:[13,35,36],rf:10,rgb:3,rgoj5yh7evk:23,rh:[6,34],rho2:39,rho:[0,10,13,21,31,36,37,39],rho_1:10,rho_2:10,rho_m:10,rich:[0,31],ride:9,rideclass:9,ridedata:9,ridg:[7,11,13,21,23,26,31],ridge_sk:6,ridgebeta:[5,33],ridgecv:35,right:[0,1,2,3,5,6,7,8,9,10,12,13,14,16,17,19,22,24,25,28,31,32,33,34,35,36,37,38,39],right_sid:2,rightarrow:[0,1,5,6,8,11,12,13,28,31,32,34,35,36,37,38,39],rigor:[0,31],ring:6,rise:[0,31],risk:[0,13,15,16,31,35,36,37],rival:4,river:0,rlm:31,rm:[0,28,39],rms_prop:39,rmse:0,rmsporp:[13,21,36,37],rmsprop:[1,3,4,13,26,38,39],rnd_clf:10,rng:28,rnn1:4,rnn2:4,rnn:[4,12,37,38],rnn_2layer:4,rnn_input:4,rnn_output:4,rnn_train:4,rntrick1:28,rntrick2:28,rntrick3:28,rntrick4:28,ro:[0,13,21,31,35,36,37],robert:[18,25,30],robust:[0,31],robustscal:[0,32],roc:[7,10],role:[0,2,5,6,8,23,31,32,33,34,35,38,39],roll:6,room:[0,29,31],root:[0,5,9,13,28,32,33,35,36,37],rot:31,rotat:[1,8,9,10,39],rotation_matrix:9,roughli:[1,3,38,39],round:[0,7,9,13,35,36,37,39],routin:[13,24,31,35,36],row:[0,1,2,5,6,9,11,24,31,32,33,34,39],row_stack:[],rr:[5,32],rrr:[5,32],rug:[13,35,36,37],rule:[0,1,5,6,13,25,31,32,33,34,36,37],run:[0,1,2,4,5,6,8,9,11,13,15,21,22,23,25,26,31,32,33,34,35,36,37,39],runtim:[1,6,14,38,39],runtimewarn:[1,6,34,39],rust:[0,15,23,24,31],rvert:[1,39],rvert_2:[1,39],s:[0,1,2,3,4,5,6,7,9,11,12,13,16,17,18,23,24,25,26,28,31,32,33,38,39],s_1:6,s_:[3,6],s_i:[6,7,35],s_j:6,s_k:6,saddl:[13,35,36,37],sai:[0,1,2,3,4,5,6,7,8,9,10,11,12,24,25,28,31,32,33,34,35,38,39],said:[6,9,13,35,36],sake:[0,5,7,11,31,32,33,35,38,39],sale:[0,31],sam:31,same:[0,1,2,3,4,5,6,8,9,11,12,14,17,22,24,25,28,31,32,33,35,38,39],samm:10,sampl:[0,1,2,3,4,5,6,7,8,9,10,13,14,15,16,19,21,23,24,25,28,31,32,33,34,35,36,37,38,39],sample_vari:14,sampleexptvari:28,samwis:31,sastri:11,satisfactori:[0,31],satisfi:[1,2,3,6,8,13,24,28,34,35,36,39],satur:[1,6,34,38,39],save:[0,4,6,7,9,13,21,31,32,34,35,36,37],save_fig:[0,6,7,9,10,31,32,34,35],savefig:[0,4,6,7,9,28,31,32,34,35],savetxt:4,saw:[5,32],scalabl:10,scalar:[2,5,6,10,32,33,34,38,39],scale:[0,1,3,5,6,7,8,9,10,11,12,13,15,16,17,21,23,24,25,26,29,31,33,35,36,37,38,39],scale_mean:4,scale_std:4,scaler:[0,7,8,9,10,11,25,32,33,39],scan:[5,7,33,34,35],scari:[5,33,34],scatter:[0,1,6,7,8,9,14,21,22,31,32,33,34,35,37,39],scenario:[6,13,35,36,37],schedul:[13,29,36,37],scheduler_arg:39,schedulers_bia:39,schedulers_weight:39,scheme:[1,13,35,36,37,38,39],schrage:28,scienc:[0,1,10,12,13,23,27,28,29,30,35,36,37,38,39],scientif:[0,15,23,25,26,31,36,37],scientist:[0,31],scikit:[3,5,6,8,9,10,13,21,22,23,24,25,26,27,30,37,38],scikit_learn:[0,16],scikitlearn:31,scikitplot:[7,10,35],scipi:[0,3,5,6,13,15,22,23,24,25,31,32,33,34,35,36],scl:6,score:[0,1,3,6,7,9,10,11,15,16,25,26,29,31,32,34,35,36,37,38,39],scores_kfold:[6,34,35],scratch:[1,13,37,38,39],sdg:[13,21,36,37],sdv4f4s2sb8:37,seaborn:[0,1,3,6,7,21,26,31,35,39],seamless:[0,15,23,25,31],seamlessli:39,search:[0,1,3,5,9,13,31,33,36,37,38,39],sebastian:[31,38,39],sebastianraschka:[26,31],sec:6,second:[0,2,3,4,5,6,7,8,9,11,12,14,15,16,22,23,24,25,26,28,29,31,32,34,35,38,39],second_correct:39,second_mo:[21,36,37],second_term:[21,36,37],secondeigvector:11,secondli:[12,38,39],section:[4,11,16,17,24,25,28,32,33,35,36,37],sector:0,see:[0,1,2,3,4,5,6,7,8,10,11,12,13,15,16,17,18,21,23,24,25,26,28,31,32,33,34,35,36,37,38,39],seed:[0,1,2,3,4,5,6,8,9,11,13,14,15,16,21,22,25,28,31,32,33,34,35,36,37,38,39],seed_imag:4,seek:[1,2,8,38,39],seem:[1,3,4,36,37,38,39],seemingli:[0,31],seen:[0,1,3,5,10,12,17,28,31,39],segment:[13,35,36,39],seismic:6,seldomli:[0,31],select:[1,5,6,8,9,10,11,17,25,26,27,28,29,30,31,32,33,34,39],self:[0,1,2,5,7,21,31,32,33,35,37,39],sell:4,semest:[7,27,35],semi:[8,13,35,36],semilogx:6,send:[5,12,13,29,31,36,37,38],senior:[27,29],sens:[0,4,6,8,25,31,34],sensibl:3,sensit:[0,5,6,9,13,31,32,33,34,37],sent:[2,38,39],sentdex:[37,38,39],sentenc:[4,12,37,38],separ:[0,1,2,4,6,8,9,12,14,15,22,23,25,28,31,34,37,38,39],septemb:[17,18,19,20,25,31],sequenc:[2,3,4,7,9,10,12,13,23,24,28,31,35,36,37,38],sequenti:[1,3,4,10,12,28,37,38,39],seri:[0,1,2,3,4,5,6,10,11,12,13,24,31,32,33,34,35,36,37,38,39],serif:[0,7,28,31,35],serv:[0,1,2,3,5,7,13,21,25,30,31,32,33,34,35,36,37,38,39],servic:[25,26],session:[1,20,22,25,27,29,31],set:[1,4,5,6,7,8,10,11,13,14,16,17,21,22,23,24,25,26,28,29,33,34,36,37],set_major_formatt:[6,25],set_major_loc:[6,25],set_tick:[1,6,8,39],set_ticklabel:[1,6,39],set_titl:[0,1,2,3,7,12,14,31,35,37,38,39],set_xlabel:[0,1,2,3,7,12,31,35,37,38,39],set_xlim:[7,12,35,37,38,39],set_xticklabel:[1,39],set_ylabel:[0,1,2,3,7,31,35,39],set_ylim:[7,12,35,37,38,39],set_ytick:[7,35],set_yticklabel:[1,6,39],set_zlim:[6,25],seth:4,setminu:[6,35],setosa:[8,9],setosa_or_versicolor:8,setp:[6,34],setup:[1,4,6,8,21,23,26,31,32,38,39],sever:[0,3,5,6,7,8,9,11,12,13,21,22,23,24,26,28,31,32,33,34,35,36,37,38],sgd:[1,3,21,26,35,39],sgd_clf:8,sgdclassifi:8,sgdreg:[13,35,36],sgdregressor:[13,35,36],sgn:[5,32,33],shallow:[13,36,37],shape:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,22,24,31,32,33,34,35,36,37,38,39],shape_bas:2,share:[1,3,31,38,39],she:[7,35],shell:[21,37],shift:[1,6,12,28,33,37,38,39],ship:3,shire:31,shortcom:[13,35,36,37],shorten:4,shorter:28,shorthand:[31,34],shortli:[24,31],should:[0,2,3,5,6,8,9,11,12,15,16,21,22,24,25,26,28,31,32,33,34],show:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,21,22,24,25,28,31,32,33,34,35,36,37,38,39],show_shap:4,shown:[0,4,5,8,9,11,12,13,21,24,32,35,36,37,38,39],shrink:[3,5,6,8,11,25,32,33],shrinkag:[5,6,32,33],shrunk:11,shuffl:[0,1,4,6,13,21,32,34,35,36,37,39],sickit:[38,39],side:[0,2,5,8,12,13,24,26,31,33,34,35,36,37,38,39],sigh:[23,31],sigma0:28,sigma1:28,sigma2:28,sigma:[0,1,5,6,7,10,11,12,13,17,18,19,24,25,28,31,32,33,34,35,36,37,38,39],sigma_0:[5,32,33],sigma_1:[5,32,33,38,39],sigma_2:[5,32,33,38,39],sigma_:[5,24,31,32,33,34],sigma_fn:[7,12,35,37,38,39],sigma_i:[0,5,31,32,33],sigma_j:[5,17,32,33],sigma_m:[6,28,34],sigma_n:[11,28],sigma_t:[13,36,37],sigma_x:28,sigmoid:[1,2,4,7,8,10,12,26,35,36,37],sigmundson:[6,32,33],sign:[1,2,7,8,10,28,29,35,37,39],signal:[1,3,10,12,37,38,39],signifi:4,signific:[1,38,39],significantli:[1,13,21,28,35,36,37,38,39],sigurd:31,sim:[4,5,6,13,18,25,28,33,34,36,37],similar:[0,1,2,3,4,5,6,7,8,9,10,11,14,17,23,24,25,26,31,33,34,35,38,39],similarli:[0,1,3,5,8,10,13,20,28,31,32,33,38,39],similiar:39,simpl:[1,2,3,5,6,7,8,10,11,12,14,15,16,17,19,21,22,23,24,25,26,28,34],simplefilt:39,simplepredict:10,simpler:[0,1,5,6,7,13,16,19,21,23,25,26,31,33,36,37,39],simplernn:4,simplest:[0,1,3,4,9,10,12,14,31,37,38,39],simpletre:10,simpli:[0,1,2,4,5,6,8,9,10,11,12,15,23,24,25,26,28,31,32,33,34,37,38,39],simplic:[2,5,6,7,8,9,10,11,12,14,32,33,35,37,38,39],simplicti:[5,32],simplif:38,simplifi:[0,6,9,15,23,25,31,32,33,34,38],simplist:[3,6,28,34],simul:[6,34],simultan:[6,34],sin:[0,1,2,3,4,9,12,13,21,24,31,36,37,38,39],sinc:[0,1,2,3,5,6,7,8,9,10,11,13,21,24,26,28,30,31,32,33,34,35,36,37,38,39],sine:[3,12,37,38,39],singl:[0,1,2,3,5,6,7,8,9,12,13,22,24,26,28,31,32,33,34,35,36,39],singular:[0,6,13,24,25,31,33,34,35,36],sinusoid:3,site:[0,1,2,3,4,6,7,8,9,11,14,21,25,26,27,31,33,35,37],situat:[0,4,5,7,13,21,28,31,32,35,36,37],six:[3,28,38],size:[0,1,2,3,4,5,6,8,9,10,11,13,21,22,24,25,26,28,31,33,34,35,36,37,38,39],sketch:10,ski:9,skill:0,skip:11,skl:[0,6,31,32,33],sklearn:[0,1,3,5,6,7,8,9,10,11,13,14,22,31,32,33,34,35,36,37,38,39],skplt:[7,10,35],skrankefunct:39,sl:[6,33,35],slack:8,slice:[2,24,31],slide:[0,3,15,16,25,26,28,31,32,34,36,38,39],slight:[6,13,34,36,37],slightli:[1,2,3,5,6,7,10,28,32,33,34,35,38,39],slope:[8,11,12,37],slow:[0,2,8,13,32,35,36,37],slower:[5,24,31,32,33],slowest:24,slowli:12,slp:[1,39],small:[0,1,2,3,5,6,8,9,10,11,12,13,21,23,24,25,28,31,32,33,34,35,36,37,38,39],smaller:[0,1,2,5,6,8,9,11,13,28,31,32,33,34,35,36,37,38,39],smallest:[0,4,14,15,16,31,35],smallest_row_index:14,smooth:[0,3,6,9,13,25,31,35,36],sn:[0,1,3,6,7,31,35,39],sne:11,sneak:31,so:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,18,19,21,22,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],soar:6,social:0,soft:[1,7,10,12,35,37,38,39],soften:8,softmax:[3,7,22,35,38],softwar:[0,8,15,23,24,38],sol1:22,sol:8,sole:[0,6,31],solid:[0,7,35],solut:[0,1,2,3,5,6,8,10,11,13,17,18,24,25,26,28,31,32,33,34,35,36,37,38,39],solution_ev:36,soluton:2,solv:[0,1,3,5,6,8,10,11,12,13,24,25,26,31,32,37,38,39],solve_expdec:2,solve_ode_deep_neural_network:2,solve_ode_neural_network:2,solve_pde_deep_neural_network:2,solveod:2,solveode_popul:2,solver:[2,7,8,9,10,11,21,24,31,35,37],some:[0,1,2,3,4,5,6,7,8,9,10,11,12,14,22,25,28,31,33,34,37,39],some_model:[6,32,33],somehow:4,someth:[0,1,3,4,7,9,11,25,26,28,31,32,35,38,39],sometim:[0,1,11,12,13,14,31,32,36,37,38,39],somewhat:[37,38],soon:[24,29,32],sophist:[0,31],sopt:[13,36],sort:[5,6,9,11,22,28,32,34],sound:[3,5,33,34],sourc:[0,1,3,6,15,23,24,25,26,28,31,34,39],space:[0,1,4,5,8,9,11,12,13,14,21,28,32,33,34,35,36,37,38,39],span:[0,3,5,9,11,24,31,32],spare:[1,38,39],spars:[3,6,24,31],sparse_mtx:[24,31],sparsecategoricalcrossentropi:3,sparsiti:10,spatial:[1,2,3,12,37,38,39],speak:28,special:[6,7,10,12,13,22,24,28,31,32,33,35,36,38,39],specif:[0,1,2,3,4,5,6,7,8,9,11,12,16,23,24,25,26,28,30,31,32,33,34,35,37,38,39],specifi:[0,3,5,6,7,9,11,13,14,21,25,28,31,33,34,35,36,37,39],specifici:[0,10,31],spectacular:3,spectral:[1,39],speech:[0,1,3,4,12,37,38,39],speed:[1,2,4,13,36,37,38,39],spend:28,spent:[25,26],sphere:[0,32],spin:6,spite:0,spline:8,split:[1,3,4,5,6,8,9,10,11,14,17,25,28,33,34,35,39],splite:0,splitter:[1,10,39],spontan:28,spot:3,spread:[0,11,28,31,32],spring:39,springer:[18,25,30,31,34],spuriou:[13,21,36,37],sqquar:33,sqrsignal:3,sqrt:[0,3,4,5,6,8,10,11,13,17,21,28,32,33,34,36,37,38,39],squar:[1,2,3,4,7,8,9,11,13,14,15,16,17,19,21,23,24,26,28,34,35,36,37,38,39],squarederror:10,squaredeuclidean:14,squash:[12,37,38,39],srtm:[6,25],srtm_data_norway_1:[6,25],stabil:[5,25,26],stabl:[0,4,5,6,9,11,23,25,31,32,33],stack:[2,3,4],stage:[5,13,21,25,26,36,37,38,39],stai:[0,2,4,5,11,17,31,32,39],stand:[0,5,9,12,31,32,33,37],standadscal:32,standard:[0,1,4,5,6,7,8,10,12,15,16,17,19,21,24,25,26,28,31,33,35,37,38,39],standard_basi:2,standardscal:[0,6,7,8,9,10,11,32,33],stanford:[13,35],start:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,20,22,24,26,28,29,31,32,34,35,36,38,39],start_box:2,start_nod:2,start_tim:14,starting_point:[21,37],stat:[6,34,35],state:[1,2,4,5,6,7,8,10,11,12,13,23,26,28,32,33,34,35,36,37,38,39],statement:[0,7,24,31,35],stationari:[35,36],statist:[0,1,3,4,7,9,10,11,12,13,14,18,24,25,27,30,32,35,36,37,38,39],statu:[0,7,9,11,31,35],stavang:[6,25],std:[0,4,6,31,32,34],stdout:39,steep:[13,21,35,36,37],steepest:37,step:[0,1,2,4,6,7,9,10,11,12,13,14,21,24,25,31,38,39],step_fn:[7,12,35,37,38,39],step_length:[13,36,37],step_siz:36,steps_list:9,stereo:3,still:[0,2,3,5,6,11,13,17,28,34,35,36,37,38],stimuli:[12,37,38],stk2100:[30,31],stk3155:[15,25,26,27,29],stk4021:[30,31],stk4051:[30,31],stk4155:[27,29],stk5000:30,stk:[30,31],stochast:[0,1,5,6,8,11,12,15,16,25,31,33,34,35,38,39],stock:4,stoke:[12,37,38],stone:[0,7,25,35,38],stop:[1,4,9,11,13,14,21,35,38,39],stopiter:[0,7,35],storag:[5,32],store:[0,1,2,3,6,11,13,25,28,31,36,37,39],storehaug:[29,31],str:[1,3,4,39],straight:[0,6,8,13,31,34,35,36],straightforward:[0,2,3,5,6,8,9,10,13,24,31,32,33,34,35,36],strategi:[0,1,9,31,39],stratifi:[6,34],strength:[0,5,14,32],stretch:11,strict:[8,13,35,36],strictli:[8,13,35,36],stride:[4,24],strike:6,string:[1,39],stroke:[7,35],strong:[3,6,9,10,12,24,28,34,37,38],strongli:[0,8,23,24,26,39],stronli:0,structur:[0,1,2,3,6,9,10,12,23,31,34,35,36,37,39],stuck:[1,13,35,36,37,38,39],student:[0,25,26,27,29,30,31],studi:[0,3,4,5,6,7,8,11,12,13,17,19,21,23,25,26,30,31,32,33,36,37,38,39],studier:30,style:[0,7,9,24,31,35],sub:[9,12,37,38],subarg:2,subdivid:[0,24,31],subfield:0,subject:[6,8,28],submit:31,subplot:[0,1,3,4,6,7,8,9,10,14,22,31,34,35,39],subplots_adjust:[8,28],subprogram:[24,31],subract:[0,32],subroutin:[0,31],subscript:[1,39],subsequ:[1,4,5,6,12,24,28,32,34,37,38,39],subset:[1,6,9,12,13,23,31,34,35,36,37,38,39],subspac:[0,8,11,32],substanti:[9,10],substep:11,substitut:[3,6,12,24,34,37],subsubset:9,subtask:6,subtl:[1,38,39],subtract:[0,2,4,5,6,11,13,17,21,24,25,28,33,34,36,37,39],subtre:9,subval:2,succeed:[0,4,31],success:[3,7,9,13,28,35,36],successfulli:[4,9],sudo:[0,15,23,25,31],suffer:[0,1,2,5,10,31,32,33,38,39],suffici:[1,6,8,11,13,34,35,36,39],suggest:[1,13,25,26,30,36,38,39],suit:[8,12,37,38],suitabl:[0,28,32],sum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,21,24,25,28,31,32,33,35,36,37],sum_:[0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,25,26,28,31,32,33,34,35,36,37,38,39],sum_i:[0,2,5,6,8,13,17,19,25,32,33,34,36,37],sum_j:6,sum_ja_:0,sum_k:[6,8,12,24,38,39],sum_logist:[13,36],sum_m:3,sum_n:3,sum_nx_:3,summar:[5,6,9,26,33,34,35,37],summari:[1,3,4,10,21,26,27,33,39],summat:[0,3,16,32],sunni:9,superconduct:33,superfici:3,superscript:[1,12,37,38,39],supervis:[0,5,6,7,9,12,23,31,32,34,35,37],supplement:[7,25,35],support:[0,1,9,10,11,13,22,23,31,32,36,38,39],suppos:[0,5,6,7,8,10,11,12,13,24,31,32,33,34,35,36,37,38],suppress:[5,8,13,33,36,37],sure:[0,1,4,6,22,25,38,39],surf:[6,25],surfac:[0,6,25,31],surpass:6,surpris:[0,31],surround:[3,23],survei:[0,5,6,31,32,33,34],svc:[8,9,10],svd:[0,6,11,17,31,34],svdinv:[5,33],svm:[8,9,10,11],svm_clf:[8,10],swath:[5,32],sy:[13,35,36,39],symbol:[1,3,4,5,11,13,14,23,28,31,32,33,36,37,38,39],symmeteri:[1,39],symmetr:[0,5,8,11,12,13,24,31,32,36,37,38],symmetri:[6,9],sympi:[0,15,23,25,31,38],synonim:28,syntax:[1,13],syntaxerror:[1,8],system:[0,1,3,4,6,7,9,10,12,13,15,23,24,25,31,35,36,37,38,39],systemat:[4,6,34],t0:[3,6,13,21,36,37],t1:[2,13,21,36,37],t2:2,t3:2,t:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,23,24,25,26,28,29,31,34,35,36,37,38,39],t_0:[2,9,13,36,37],t_1:[13,36,37],t_:2,t_b:10,t_batch:39,t_i:[1,2,5,12,26,32,39],t_j:12,t_k:9,t_test:39,t_train:39,t_val:39,tabl:[9,25,26,28,29,31,37,38],tabul:[0,31],tabular:31,tackl:4,tag:[2,3,4,5,6,7,12,13,14,21,24,28,32,35,36,37,38,39],tagrget:38,taht:[0,31],tail:28,tailor:[2,8,11,31,38],taiwan:[0,31],take:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,16,21,22,23,24,28,31,32,33,34,35,36,37,38,39],taken:[0,1,3,6,10,13,24,31,34,36,39],tan:3,tangent:[1,4,12,13,35,36,37,38,39],tanh:[1,4,7,8,12,35,36,37,38,39],target:[0,1,2,3,4,5,6,7,8,9,10,11,12,22,26,31,32,33,34,35,36,37,38,39],target_iscomplex:[],target_meta:2,target_nam:[9,22],target_ndim:[],target_shap:[],task:[0,1,3,6,9,11,12,14,20,25,31,34,37,38,39],tau:[3,5,28,33,34],taught:31,tax:0,taylor:[2,13,35,36,38],taylornr:[13,35,36],tba:[],tc:8,td:[1,6,31,34,39],teach:31,team:[1,39],teaser:0,technic:[0,5,6,13,15,22,25,31,32,36,37],techniqu:[0,1,8,10,13,23,28,30,31,32,34,35,36,37,38,39],technolog:[0,1,39],tell:[0,4,6,10,11,13,28,34,36,37],temp1:[1,39],temp2:[1,39],temp:[1,39],temperatur:[0,9,31],temporarili:[1,38,39],ten:[3,17,31,38],tend:[3,5,6,8,9,10,12,13,14,21,32,33,34,36,37],tendenc:[0,31],tension:[6,34],tensor:3,tensordot:[],tensordot_adjoint_0:[],tensordot_adjoint_1:[],tensorflow:[0,2,4,8,14,15,23,24,25,26,27,30,31,32],term1:[5,6,11,25,32],term2:[5,6,11,25,32],term3:[5,6,11,25,32],term4:[5,6,11,25,32],term:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,25,28,31,32,33,35,36,37],termin:[0,4,5,9,10,13,15,21,31,32,36,37],terrain1:[6,25],terrain:[6,21,25,26],test:[3,4,5,6,7,8,9,10,13,17,19,21,22,24,25,28,34,35,36,37,38],test_acc:3,test_accuraci:[1,3,39],test_error:6,test_imag:[3,4],test_ind:[6,34,35],test_input:4,test_label:[3,4],test_loss:3,test_pr:[1,39],test_predict:[1,39],test_rnn:4,test_scor:[7,10,35],test_siz:[0,1,3,5,6,10,31,32,33,34,35,39],test_split:9,tester:33,testerror:[0,6,32,34],testi:4,testpredict:4,testx:4,text:[0,1,2,4,5,8,9,11,13,15,21,24,26,28,30,32,34,35,36,37,39],textbook:[16,17,21,25,26,32,34],textual:9,textur:[1,9,39],tf:[1,3,4,13,14,35,36,39],tf_loadlibrari:[3,4,14],th:[0,1,2,5,6,7,9,12,13,14,15,16,24,25,28,31,32,33,34,35,36,37,38,39],than:[0,1,2,3,4,5,6,7,9,10,11,12,13,17,23,26,28,31,32,33,34,37,38,39],thank:[4,6,32,33],thats:39,theano:[1,23,31,39],thei:[0,1,2,3,4,5,6,7,8,9,11,12,13,24,25,28,31,32,33,34,35,36,37,38,39],them:[0,1,3,4,6,8,9,10,11,12,13,24,25,26,31,32,33,36,37,38,39],theme:[0,31,36],themselv:[0,28,31],thenc:[6,34],theorem:[2,6,7,32,35,37,39],theoret:[0,4,10,31],theori:[0,1,3,8,9,12,13,18,23,25,30,31,33,36,37,38,39],thereaft:[0,5,6,11,12,15,16,17,24,25,26,31,34,38,39],therebi:[0,5,7,11,31,32,33,35,38],therefor:[0,1,2,3,4,6,7,8,11,13,28,31,32,34,35,36,37,39],therein:11,thereof:[0,6,13,31,34,36,37],theta:[1,4,13,21,28,36,37,38,39],theta_:[1,13,36,37,39],theta_i:[1,39],theta_linreg:[13,21,36,37],theta_t:[13,36,37],thetaand:[37,38],thetaor:[37,38],thetaxor:[37,38],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,23,24,25,26,27,28,30,32,33,34,35,36,37,39],thing:[0,1,2,4,5,7,9,28,31,33,34,35,38,39],think:[0,1,3,4,6,9,12,13,14,28,31,34,35,36,37,38,39],third:[0,3,6,13,21,29,31,35,36,37],thirti:[7,35],thorughout:31,those:[0,3,5,6,8,9,10,11,21,24,25,26,27,31,32,34,38],though:[1,2,3,4,13,22,24,28,36,37,39],thought:[6,14,25,26,28,34],thousand:[0,1,25,32,36,37,38,39],three:[0,1,3,5,6,8,9,12,15,24,25,27,28,29,31,32,33,34,35,37],threshold:[1,3,9,10,11,12,13,36,37,38,39],through:[0,1,2,3,4,5,6,8,11,12,13,14,23,24,28,31,32,33,34,35,36,37,39],throughout:[0,4,5,14,23,24,28,31,39],thu:[0,1,2,5,6,7,8,10,11,12,13,21,25,29,31,32,33,34,35,36,37,38,39],thumb:[0,6,25,31,32],thursdai:[29,32],tibshirani:[6,18,25,27,30,31,34],tick:6,tick_param:6,ticker:[6,13,25,28,35,36],tif:[6,25],tight_layout:[1,7,35,39],tightli:11,tild:[0,5,6,7,11,15,16,17,18,19,25,28,31,32,33,34,38,39],till:[0,4,7,8,9,10,12,24,31,32,33,35,38,39],time:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,21,22,23,24,25,26,28,31,32,33,34,35,38,39],timeit:4,timer:4,tini:[1,38,39],tip:3,titl:[0,1,2,3,4,6,7,8,9,10,13,21,22,25,28,31,34,35,36,37,38,39],tmp:[13,36,37],tn:[2,3,7],to_categor:[1,3,4,39],to_categorical_numpi:[1,39],to_numer:[0,6,31,34],todai:3,togeth:[0,3,6,8,11,13,21,23,31,36,37],toi:[14,36,37],told:[13,36],toler:[2,6,14],tolist:4,tomographi:[12,37,38],too:[0,2,4,5,6,9,11,13,15,28,30,31,32,34,35,36,37],took:[8,31],tool:[0,1,3,6,13,23,32,34,36,37,38,39],toolbox:8,top:[0,3,5,6,9,10,18,23,31,33,34],topic:[0,5,6,7,8,23,25,26,32,33,35],topograph:25,topolog:[1,3,12,37,38,39],toposort:2,torkjellsdatt:[29,31],toss:[10,28],total:[0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,24,26,28,29,31,32,34,35,36,38,39],total_loss:4,totalclustervari:14,totalscatt:14,toward:[1,2,7,12,13,25,35,36,39],towardsdatasci:[36,37],town:0,tp:[4,7],tpng:9,tpu:[13,21,23,31,36,37],tqdm:6,tr:32,trace:2,trace_stack:2,traceback:[0,2,3,4,6,7,10,13,14,25,31,33,35,39],tracer:2,track:[3,13,14,24,32,35,36,37],tract:0,tractabl:[0,31,32],trade:[5,9,19,33,34],tradeoff:[0,5,19,25,31,32,33,35],tradit:[0,1,4,6,31,34,39],train:[2,3,5,6,8,9,10,11,12,13,17,19,21,22,25,26,33,34,35,36,37],train_acc:39,train_accuraci:[0,1,3,31,39],train_dataset:4,train_end:[0,1,32,39],train_error:[6,39],train_imag:[3,4],train_ind:[6,34,35],train_label:[3,4],train_pr:[1,39],train_siz:[0,1,3,32,39],train_step:4,train_test_split:[0,1,3,5,6,7,9,10,11,31,32,33,34,35,39],train_test_split_numpi:[0,1,32,39],trainable_vari:4,trained_model:[6,32,33],trainerror:[0,32],traini:4,training_checkpoint:4,training_dataset:4,training_gradi:[13,21,36,37],training_gradient_fun:[36,37],training_loss:[36,37],trainingerror:[6,34],trainpredict:4,trainscor:4,trainx:4,trait:[0,31],trajectori:4,trajectory_i:[21,37],trajectory_x:[21,37],transfer:9,transform:[0,5,6,7,8,9,10,11,12,13,21,23,24,31,32,33,34,35,36,37,38,39],transit:[6,12,37,38],translat:[1,4,6,10,31,32,33,39],transpos:[1,5,11,24,32,33,39],travers:[0,5],treat:[0,1,3,6,12,13,28,31,32,33,34,35,36,37,38,39],tree:[0,1,6,23,25,31,38,39],tree_clf:[9,10],tree_clf_:9,tree_clf_sr:9,tree_reg1:9,tree_reg2:9,tree_reg:9,trend:28,treue:7,trevor:[18,25,30],tri:[2,3,4,9,13,35,36],triain:0,trial:[0,2,4,6,13,28,31,34,35,36],triangl:[13,35,36],triangular:24,trick:[3,4,8,11,13,21,28,36,37],trickier:28,tridiagon:24,trigger:[0,7,35],trillion:23,trivial:[0,1,5,11,28,31,33,39],troubl:[0,8,12,22,32,38,39],truck:3,true_beta:[6,32,33],true_divid:1,true_fun:[6,34],truncat:[21,37,38],trust:9,tucker:8,tuesdai:[29,31,34,35,36],tumor:[7,9,26,35],tumour:[7,35],tunabl:[1,21,26,39],tune:[4,9,13,21,24,26,31,35,36,37],tup:[],tupl:[2,22,39],turn:[0,1,5,6,7,8,9,10,11,12,13,19,24,25,28,31,32,34,35,36,37,38,39],tutori:[1,4,39],tv:2,tveito:2,tvw1zdmznwm:37,tweak:[1,4,10,28,38,39],twice:[13,35,36],twist:11,two:[0,1,2,4,5,6,7,9,10,11,12,13,15,16,24,27,28,30,31,33,34,36,37],tx:[13,35,36,37,38],tx_1:[13,35,36],txt:4,ty:[13,35,36],type:[0,1,3,6,8,10,13,16,22,24,25,28,32,33,34,35,36,39],typeerror:[2,6,13],typic:[0,1,2,3,4,5,7,9,10,12,13,21,26,28,31,32,33,34,35,36,37,38,39],typo:[25,26],u:[0,2,5,6,8,10,11,12,17,24,31,32,33,37,38],u_:24,u_i:[12,37],u_m:10,ua:[0,31],ubuntu:[0,15,23,25,31],uci:[0,26],ufunc:2,uio:[25,26,29,30],un:14,unabl:9,unari:[24,31],unary_f:2,unary_oper:2,unary_to_nari:2,unbalanc:[6,9,34,35],unbias:[0,5,6,31,33,34],unbroadcast:2,unbroadcast_f:2,uncent:[6,33],uncertainti:[0,5,31,33,34],uncertitud:28,unchang:[1,3,38,39],uncorrel:[10,28],undefin:[5,32],under:[0,1,5,6,10,13,15,16,23,25,26,31,32,33,34,35,36,39],underdetermin:[0,31],underfit:[1,6,34,38,39],underflowproblem:[5,33,34],undergo:[5,33,34],undergradu:[27,29],underli:[0,1,9,13,28,31,36,37,38,39],underset:[4,14],understand:[0,1,3,5,6,10,13,14,21,23,31,32,33,35,36,37,38,39],understood:[8,13,36,37],undesir:8,undetermin:[5,8,33,34],undo:4,unexpect:[6,13,34],unexpected:28,unfair:[6,32,33],unfortun:[1,8,9,10,38,39],unicode_liter:[8,9],uniform:[0,1,5,6,11,13,15,16,25,28,31,32,35,36,39],uniformli:[13,28,35,36,37],unifrompdf:28,unimport:[13,35,36],union:[5,6,33,34,35],uniqu:[0,2,6,13,14,24,31,34,35,36],unique_cluster_label:14,unit:[0,1,3,4,5,10,12,28,31,32,33,37,38,39],unitari:[5,6,24,32],unitarili:[24,31],uniti:28,univari:28,univers:[0,1,2,13,15,23,25,26,27,29,31,32,33,34,35,36,37,39],unix:[1,39],unknow:[0,24,31],unknown:[0,1,3,4,5,6,8,10,13,16,21,24,31,32,33,34,36,37,38,39],unknowwn:12,unlabel:[1,38,39],unless:[0,3,6,11,13,22,25,26,31,34,35,36,38],unlik:[1,3,8,13,35,36,37,38,39],unnecessarili:9,unord:3,unravel:[1,39],unrol:[3,11],unseen:[0,7,9,35],unstabl:[1,38,39],unsupervis:[0,1,4,12,23,31,37,38,39],unsymmetr:[24,31],until:[1,2,4,9,12,13,14,35,36,37,38,39],untouch:0,unusu:[12,37,38],up:[1,3,4,5,6,8,10,11,13,14,16,18,22,23,24,25,26,28,29,33,36],updat:[1,2,10,12,13,14,21,22,36,37],update_chang:39,update_matrix:39,uploa:31,upload:[23,25,26,30],upon:[0,1,6,7,11,24,25,38,39],upper:[0,8,9,16,24,32],uppercas:[24,31],upsampl:4,upscal:4,uptad:38,ur:39,url:[0,7,31,32,35,37],us:[4,5,6,8,9,10,11,12,14,15,16,17,18,19,22,24,27,28,30,33,34],usa:[31,37],usag:[0,8,23,31,32,37,38],usd10000:0,usd:0,use_bia:4,usecol:[0,31],useless:[1,39],user:[0,1,2,3,4,6,7,8,9,11,14,15,21,23,24,25,31,32,33,35,37,39],usernam:[25,26],userwarn:[6,21,37],usetex:28,usg:[6,25],usr:28,usual:[0,3,4,7,12,13,14,31,35,36,37,38],ut:[5,33],utf:[0,7,35],util:[1,3,4,6,7,10,14,26,31,34,35,38,39],ux:24,v0:28,v1:28,v2:28,v8xr:[37,38,39],v:[2,4,5,6,11,13,17,21,23,32,33,36,37,38,39],v_0:11,va:[1,39],vahid:31,val:[13,36,37],val_acc:39,val_accuraci:3,val_error:39,val_loss:4,val_set:39,vale:2,valid:[0,1,4,7,9,10,13,21,23,26,28,31,32,36,37,38,39],validation_data:3,validation_split:4,valu:[0,1,2,3,4,6,7,8,9,10,12,13,14,15,16,19,21,22,23,24,25,31,36,37,38,39],valuat:9,valued_at_a:39,valued_at_z:39,valueerror:2,valy:4,van:[0,18,25,31,32,33,34],vandenbergh:[8,13,35,36],vandermond:[0,31],vanilla:[0,6,11,14,32,33],vanish:[1,4,13,28,35,36],var_x:28,varabl:8,varepsilon:[5,6,18,25,33,34],varepsilon_:[5,6,33,34],varepsilon_i:[5,6,33,34],vari:[0,1,3,5,6,10,15,16,22,31,34,38,39],variabl:[0,1,2,5,6,7,8,10,11,12,13,14,21,22,24,31,32,33,34,37,38,39],varianc:[0,1,5,7,9,10,11,13,14,18,19,21,23,24,28,31,32,35,36,37,38,39],variance_i:[5,11,32],variance_x:[5,11,32],variant:[0,1,6,8,12,13,31,32,35,36,37,38,39],variat:[3,4,11,31],varieti:[0,3,12,15,23,25,31,37,38],variou:[1,3,5,6,7,8,9,11,12,13,16,18,21,23,24,25,28,32,33,36,37,38,39],varydimens:4,vastli:3,vaue:[1,39],vault:0,vdot:[2,13,35,36],ve:[25,26],vec:[6,34],vector:[0,1,2,3,4,5,6,7,9,10,11,13,14,16,17,21,22,23,33,34,35,36,38,39],vector_mean:14,ventur:[0,8,15,23,31],verbos:[1,3,4,39],veri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,25,26,28,30,31,32,33,34,35,36,37,38,39],verifi:[3,11,24,31],versatil:[8,31],versicolor:[8,9],version:[0,3,10,13,14,15,23,24,25,26,28,31,36],versu:[1,38,39],vert:[0,1,5,6,7,8,9,11,13,17,31,32,33,34,35,36,38,39],vert_1:[5,6,32,33,34],vert_2:[5,6,11,17,32,33,34],vi:39,via:[0,5,6,7,8,9,10,11,12,15,19,23,24,25,27,28,29,31,32,33,34,35,37,38,39],vidal:11,video:[0,1,12,23,27,29,31,32,33,34,38,39],view:[1,3,5,6,12,13,21,28,30,31,33,34,36,37,39],vii:39,viii:39,violat:8,virginica:9,viridi:[0,1,2,3,31,39],virtual:[1,38,39],viscos:[13,36,37],viscou:[13,36,37],visibledeprecationwarn:2,vision:[0,3],visual:[0,3,11,12,15,23,31,32,37,38],visualis:[1,39],viz:[6,8,28],vjp:2,vjp_0:2,vjp_0_fun:2,vjp_1:2,vjp_1_fun:2,vjp_argnum:2,vjpfun:[],vjpmaker:[],vjpnode:2,vjps_dict:2,vmap:[13,36],vmax:[1,6,39],vmh0zpt0tli:37,vmin:[1,6,39],voic:3,volum:[0,3,31],von:[38,39],vote:10,voting_clf:10,votingclassifi:10,votingsimpl:10,vs:[0,4,6,36],vscode:22,vspace:2,vstack:[5,11,24,28,31,32,39],vt:[5,32,33],w1:[8,22],w2:[8,11,22],w3:8,w:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,22,24,28,31,32,34,35,36,37,38,39],w_0:[38,39],w_1:[8,24,38,39],w_1a_0:[38,39],w_1x:[38,39],w_1x_1:8,w_1x_:8,w_2:[8,24,38,39],w_2a_1:[38,39],w_2x_2:8,w_2x_:8,w_3:24,w_4:24,w_:[1,12,37,38,39],w_hidden:2,w_i:[1,2,10,38,39],w_ix_i:[12,37,38],w_j:24,w_m:24,w_output:2,w_px_:8,w_px_p:8,wa:[0,1,3,4,5,6,7,10,11,12,14,17,24,25,31,32,33,34,35,37,38,39],wai:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,17,22,24,26,28,31,32,33,35,36,39],walk:9,walker:28,wang:[0,31],want:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,22,23,25,26,28,31,32,33,34,35,36,37,38,39],warn:[1,4,8,39],warrant:[6,34,35],wast:[3,36,37],watch:[23,37,38,39],wave:3,wavelet:8,we:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,22,23,24,25,26,27,28,29,30,32,33,34,35],weak:[9,10,14],weather:[1,12,37,38,39],web:[23,27,29,31],weblink:26,webpag:31,websit:[6,24,25,27,31],wedg:[8,28,38,39],wednesdai:[29,31,34,35,36],wee:11,week:[0,5,6,7,25,26,27,29],weekli:[16,23,25,29,30,31,37],weierstrass:38,weight:[0,1,2,3,6,7,9,10,12,13,22,25,26,28,35,36,37,38],weight_arrai:39,weigth:2,welchlab:[37,38,39],welcom:[8,23],well:[0,1,2,3,4,5,6,7,8,9,10,12,13,15,16,19,20,21,22,23,24,25,26,28,30,31,32,33,34,35,36,37,38,39],went:8,were:[0,1,3,4,5,6,7,8,10,11,12,14,28,31,32,34,35,37,38,39],wessel:[0,18,25,31,32,33,34],what:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,19,23,24,25,26,28,35,36,37,38,39],whatev:3,when:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,21,24,25,26,28,31,32,33,34,35,38,39],whenev:[13,21,28,36,37,38],where:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25,26,28,29,31,32,33,34,35,36,37,38,39],wherea:[6,28,34],wherefrom:25,wherein:[1,12,37,38,39],whether:[0,3,5,7,9,25,26,28,31,33,35],which:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,22,23,24,25,26,27,28,29,31,32,33,34,35],whichev:[1,3,39],white:9,whiteboard:[33,34,35,36,37,38,39],who:[0,27],whole:[1,3,4,5,9,11,13,33,34,36,37,39],whose:[0,6,10,28,32,34],whow:[11,32],why:[0,1,3,6,13,21,25,33,35,36,39],wide:[0,1,3,6,7,12,15,23,24,25,31,34,35,37,38,39],widehat:[6,34],width:[0,3,8,9,22,31],wieringen:[0,18,25,31,32,33,34],win:10,wind:9,wing:[29,31],winther:2,wiothout:[6,32],wiscons:[7,35],wisconsin:[10,26,39],wisdom:[6,33],wise:[0,1,5,12,13,32,36,37,39],wish:[0,2,5,7,8,11,13,14,24,25,26,31,32,35,36,38,39],with_std:[0,32],wither:6,within:[0,2,3,4,7,9,12,13,14,28,30,31,35,36],withinclust:14,without:[0,1,5,6,8,9,11,12,13,21,26,31,32,33,34,36,37,38,39],wo5dmep_bbi:[37,38,39],won:[0,31,38],wonder:8,word:[0,1,3,4,5,6,7,14,28,31,32,33,34,39],work:[0,1,4,6,7,8,9,13,15,21,22,23,25,26,27,28,29,31,32,34,35,36,37,38,39],workshop:31,world:[0,8,32],worldwid:[0,31],wors:[0,1,3,4,6,31,34,38,39],worst:9,worth:9,worthi:[25,26],would:[0,1,3,5,6,7,8,9,10,11,12,13,24,25,26,28,31,32,33,34,35,36,37,38,39],wrap:[6,24,31],wrap_util:2,write:[0,1,2,3,5,6,7,8,12,13,15,16,17,20,21,22,24,31,32,34,35,36,37,38],written:[0,2,3,5,11,12,13,16,23,24,25,26,28,31,32,33,34,35,36,37,38,39],wrong:[1,8,38,39],wrongli:10,wrote:[5,11,32],wrt:[10,13,21,22,36,37,38,39],wth:[10,13,21,36,37],wurstemberg:[38,39],www:[23,24,25,26,30,31,33,37,38,39],wx_1:8,x0:8,x1:[4,8,9,10,13,36,37],x1_exampl:8,x1d:8,x2:[8,9,10,13,36,37],x2d:[8,11],x2d_train:11,x2dsl:11,x3:[8,9],x4:9,x:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,24,25,26,28,31,34,35,36,37,38,39],x_0:[0,5,11,24,31,32,33,34,38,39],x_1:[0,2,5,6,7,8,9,10,11,13,24,28,31,32,33,34,35,36,37,38,39],x_2:[0,2,5,6,7,8,9,10,11,13,24,28,31,32,34,35,36,37,38],x_3:[8,24,28,38],x_4:[24,38],x_5:38,x_:[0,2,3,5,6,8,10,11,13,14,18,24,25,28,31,32,33,34,35,36,38],x_batch:39,x_center:11,x_data:[1,39],x_data_ful:[1,39],x_hidden:2,x_i:[0,1,2,5,6,7,8,9,10,11,12,13,14,17,24,28,31,32,33,34,35,36,37,38,39],x_input:2,x_ix_:[0,31],x_iy_i:8,x_j:[0,2,8,9,12,16,28,32,37,38],x_jy_j:8,x_k:[12,14,24,28,32,37],x_l:[28,38],x_m:[6,12,24,28,34,37],x_n:[0,2,3,6,8,11,12,13,24,28,31,34,35,36,37,38],x_new:[9,10],x_offset:[6,32,33],x_output:2,x_p:[3,7,9,35],x_poli:9,x_poly10:9,x_pred:4,x_prev:2,x_reduc:11,x_scale:8,x_small:[13,36],x_test:[0,1,3,5,6,7,9,10,11,31,32,33,34,35,39],x_test_own:6,x_test_scal:[0,6,7,9,10,11,32,33],x_tot:4,x_train:[0,1,3,4,5,6,7,9,10,11,31,32,33,34,35,39],x_train_mean:[6,32,33],x_train_own:6,x_train_scal:[0,6,7,9,10,11,32,33],x_val:[1,39],xarrai:[23,31],xavier:[1,38,39],xbkjd4ccgq:31,xbnew:[13,35,36],xcode:[0,15,23,25,31],xdclassiffierconfus:10,xdclassiffierroc:10,xg_clf:10,xgb:10,xgbclassifi:10,xgboost:9,xgboot:10,xgbregressor:10,xgparam:10,xgtree:10,xi:[8,13,21,36,37],xi_1:8,xi_:8,xi_i:8,xinv:[33,37,38],xk:8,xla:[13,21,23,31,36,37],xlabel:[0,1,2,3,4,5,6,7,8,9,10,13,21,22,25,28,31,33,34,35,36,37,39],xlim:[6,10,34],xm:9,xmesh:[13,36],xnew:[0,13,21,31,35,36,37],xp:28,xpanda:[0,32],xpd:[5,11,32],xplot:0,xs:9,xscale:[0,32],xsr:9,xt_x:[13,21,35,36,37],xtest:[6,34,35],xtick:[3,6,8,9,34],xtrain:[6,34,35],xu:[0,31],xx:[0,24,31],xy:[0,6,8,24,25,31],xytext:8,xz:[24,31],y1:4,y2:4,y3:4,y:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,24,25,28,31,32,33,34,35,36,37,38,39],y_0:[0,5,11,24,31,32,33,34],y_1:[0,5,8,9,11,13,24,31,32,33,34,35,36],y_1y_1:8,y_1y_1k:8,y_1y_2:8,y_1y_2k:8,y_1y_n:8,y_1y_nk:8,y_2:[0,5,8,9,11,24,31,32],y_2y_1:8,y_2y_1k:8,y_2y_2:8,y_2y_2k:8,y_3:[0,9,24],y_4:24,y_:[0,1,5,6,10,11,24,31,32,33,34,39],y_data:[0,1,5,6,31,32,33,35,39],y_data_ful:[1,39],y_decis:8,y_fit:[0,32],y_i:[0,1,5,6,7,8,9,10,11,12,13,15,16,17,18,19,24,25,26,31,32,33,34,35,36,37,38,39],y_if_:10,y_ix_:[0,31],y_ix_i:[7,8,13,32,35,36],y_iy_jk:8,y_j:[6,8,12,19,25,34,37,38,39],y_k:[12,37],y_m:24,y_model:[0,4,5,6,31,32,33,35],y_n:[8,13,35,36],y_ny_1:8,y_ny_1k:8,y_ny_2:8,y_ny_2k:8,y_ny_n:8,y_ny_nk:8,y_offset:[6,32,33],y_plot:9,y_pred1:9,y_pred2:9,y_pred:[0,1,4,6,7,8,9,10,32,33,34,35,39],y_pred_rf:10,y_pred_tre:10,y_predict:37,y_proba:[7,10,35],y_scaler:[6,33],y_test:[0,1,3,4,5,6,7,9,10,11,31,32,33,34,35,39],y_test_onehot:[1,39],y_test_predict:0,y_tot:4,y_train:[0,1,3,4,5,6,7,9,10,11,31,32,33,34,35,39],y_train_mean:[6,32,33],y_train_onehot:[1,39],y_train_predict:0,y_train_scal:[6,33],y_val:[1,39],yand:[37,38],ye:[3,6,7,34,35],year:[0,23,31],yet:[0,1,6,8,11,13,31,35,36,38,39],yi:[13,21,36,37],yield:[0,2,5,6,7,8,10,12,13,14,24,28,31,33,34,35,36,37,38,39],yk:8,ylabel:[0,1,2,3,4,5,6,7,8,9,10,13,21,22,25,28,31,33,34,35,36,37,39],ylim:[3,6,34],ym:9,ymesh:[13,36],yn:0,yo:[8,9,10],yor:[37,38],yoshua:[1,30,38,39],you:[0,1,2,3,4,5,6,8,9,10,11,13,15,16,17,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37,38,39],young:0,your:[1,2,4,5,6,8,11,13,17,19,20,21,22,23,24,25,33,34,35,36,37,38,39],yourself:[11,13,31,36],youtu:[35,37],youtub:[23,37,38,39],ypred:[6,34,35],ypredict2:[13,21,35,36,37],ypredict:[0,13,21,31,32,35,36,37],ypredictlasso:[5,33],ypredictol:[0,5,33],ypredictown:[6,32,33],ypredictownridg:[6,33],ypredictridg:[0,5,6,33,35],ypredictskl:[6,32,33],yridg:31,ys:9,ytest:[6,34,35],ytick:[3,6,8,9,34],ytild:[0,6,31,32,34],ytildelasso:[5,33],ytildenp:[0,31,32],ytildeol:[0,5,33],ytildeownridg:[6,33],ytilderidg:[5,6,33],ytrain:[6,34,35],yuxi:31,yx:[24,31],yxor:[37,38,39],yy:[24,31],yz:[24,31],z1:22,z2:22,z:[0,1,2,3,4,5,6,7,8,9,11,12,13,22,24,25,28,31,32,34,35,36,37,38,39],z_0:[24,31,38,39],z_1:[24,31,38,39],z_2:[24,31,38,39],z_:[1,2,12,24,31,38,39],z_c:[1,39],z_h:[1,39],z_hidden:2,z_i:[1,12,37,39],z_j:[1,12],z_k:[12,32,38,39],z_m:[1,39],z_matric:39,z_mod:9,z_o:[1,39],z_output:2,zaman:28,zaxi:[6,25],zero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,21,24,25,28,31,32,33,34,35,36,37,38,39],zeros_lik:4,zeroth:32,zfill:4,zip:[2,4,6,22],zm_h:[0,31],zn:0,zone:0,zoom:31,zx:[24,31],zy:[24,31],zz:[24,31]},titles:["3. Linear Regression","14. Building a Feed Forward Neural Network","15. Solving Differential Equations with Deep Learning","16. Convolutional Neural Networks","17. Recurrent neural networks: Overarching view","4. Ridge and Lasso Regression","5. Resampling Methods","6. Logistic Regression","8. Support Vector Machines, overarching aims","9. Decision trees, overarching aims","10. Ensemble Methods: From a Single Tree to Many Trees and Extreme Boosting, Meet the Jungle of Methods","11. Basic ideas of the Principal Component Analysis (PCA)","13. Neural networks","7. Optimization, the central part of any Machine Learning algortithm","12. Clustering and Unsupervised Learning","Exercises week 34","Exercises week 35","Exercises week 36","Exercises week 37","Exercises week 38","Exercises week 39","Exercises week 41","Exercises week 42","Applied Data Analysis and Machine Learning","2. Linear Algebra, Handling of Arrays and more Python Features","Project 1 on Machine Learning, deadline October 7 (midnight), 2024","Project 2 on Machine Learning, deadline November 4 (Midnight)","Teaching schedule with links to material","1. Elements of Probability Theory and Statistical Data Analysis","Teachers and Grading","Textbooks","Week 34: Introduction to the course, Logistics and Practicalities","Week 35: From Ordinary Linear Regression to Ridge and Lasso Regression","Week 36: Linear Regression and Statistical interpretations","Week 37: Statistical interpretations and Resampling Methods","Week 38: Logistic Regression and Optimization","Week 39: Optimization and Gradient Methods","Week 40: Gradient descent methods (continued) and start Neural networks","Week 41 Neural networks and constructing a neural network code","Week 42 Constructing a Neural Network code with examples"],titleterms:{"0":39,"1":[0,15,16,17,18,22,25,31,32,38,39],"11":38,"14":39,"16":35,"2":[0,15,16,17,18,22,26,31,32,33,38,39],"2023":29,"2024":[25,36,37,38,39],"21":[],"23":36,"26":32,"27":36,"3":[0,15,16,22,31,32,38,39],"30":37,"34":[15,31],"35":[16,32],"36":[17,33],"37":[18,34],"38":[19,35],"39":[20,21,36],"4":[0,22,26,32,39],"40":[21,37],"41":[21,38],"42":[22,39],"5":[0,22],"7":[25,38],"9":34,"case":[8,10,28,32,33,35,36],"class":[35,38],"do":[1,33,34,36,37,38,39],"final":[12,21,26,32,33,36,37,38,39],"float":38,"function":[0,1,6,7,8,10,11,12,13,21,25,26,28,31,32,33,34,35,36,37,38,39],"import":[5,21,24,31,32,33,37,38,39],"new":[4,33,34,38],A:[0,1,4,8,9,21,31,33,34,35,37,38,39],AND:[37,38],And:[21,31,32,33,35,36,37],But:[21,36,37],For:32,In:[29,38],Is:[38,39],Ising:6,OR:[37,38],The:[0,1,2,3,5,6,7,8,9,11,12,17,23,31,32,33,34,35,36,37,38,39],To:[31,32],With:[4,33],about:[31,32],abov:[33,38,39],activ:[1,12,26,33,37,38,39],ad:[0,6,17,25,31,32,37,38,39],adaboost:10,adagrad:[13,21,36,37],adam:[13,21,36,37],adapt:[10,21,36,37],adjust:[1,39],advanc:[21,37],adversari:4,again:[3,9,35],ai:[25,31],aim:[8,9,17,18,19,20,21,22,31],aka:[31,32],al:[21,37],algebra:[24,31],algorithm:[9,10,11,12,21,26,32,36,37,38,39],algortithm:[13,35,36],all:[8,38,39],an:[0,4,10,31,38],analys:[5,32],analysi:[0,5,6,11,23,25,26,28,31,32,33,34,38],analyt:[0,16,17,21],analyz:[38,39],ani:[13,35,36],anoth:[9,33,34],appli:23,approach:[0,8,14,31,34,36,37],approxim:[12,38],architectur:[1,39],argument:[36,37],arrai:[24,31],artifici:[37,38],assist:29,assumpt:[33,34],august:32,autocorrel:28,autograd:[2,13,21,36,37],automat:[13,21,36,37,38],avoid:[],b:[17,25,26,36],back:[1,11,12,38,39],background:[23,25,26,34],bag:10,base:[13,21,34,36,37],basic:[0,5,7,9,10,11,24,32,33,34,35,38],batch:[1,36,37,38,39],bay:[5,33,34],befor:11,bengio:[38,39],beta:[33,34],better:[8,37,38],bia:[6,25,34],bias:[38,39],binari:[1,39],bind:31,bird:10,boldsymbol:[32,33,34],book:[38,39],boost:10,bootstrap:[6,10,34],boston:0,breast:[1,39],brief:[31,34,35,36],bring:[12,38,39],build:[1,3,9,39],c:[25,26,31],calcul:32,can:[21,31,34,36,37,38],cancer:[1,7,9,11,35,39],cart:9,center:32,central:[13,23,28,34,35,36],chain:[12,38,39],challeng:35,chang:10,channel:31,chi:[0,31],choic:[38,39],choos:[1,39],cifar01:3,classic:11,classif:[1,9,10,26,35,39],classifi:[8,35],clip:[1,38,39],cluster:14,cnn:3,code:[0,1,2,5,9,11,12,13,14,21,26,31,32,33,34,35,36,37,38,39],collect:[1,3,39],come:35,commun:31,compact:[35,38,39],compar:[2,10],comparison:33,compet:[21,36,37],complet:[32,38,39],complex:[0,6,25,32],complic:[6,36,37,38],compon:11,comput:[9,36,37],computation:34,computerlab:31,con:9,concept:28,condit:[33,34,35,36],confid:34,conjug:[13,36],consider:[38,39],construct:[38,39],continu:37,contn:31,convex:[8,13,35,36],convolut:[3,12,37,38],correctli:[33,34],correl:[11,32,35],correspond:[35,36],cost:[1,10,32,33,34,35,36,38,39],count:38,cours:[23,30,31],covari:[5,11,28,32],cover:31,critic:26,cross:[6,25,34,35],cython:31,d:[25,26],data:[0,1,3,6,7,9,11,15,16,23,25,28,31,32,33,35,38,39],dataset:[1,3,39],deadlin:[25,26,31],decai:[2,36,37],decis:[9,10],decomposit:[5,11,17,24,32],deep:[1,2,31,35,38,39],defin:[1,31,38,39],definit:[38,39],degre:[0,32],deliveri:[25,26],delta:34,dens:[0,31],deriv:[5,12,32,33,34,35,36,38,39],descent:[2,10,13,21,26,35,36,37],descript:25,design:32,detail:[3,31],develop:[1,39],diagon:11,differ:[8,26,36,37],different:21,differenti:[2,13,36,37,38],diffus:2,dimension:[2,3,8,25,32],directli:[36,37],disadvantag:9,discret:28,discuss:35,distribut:[5,28,33,34],distrubut:34,doe:[32,33,37,38],domain:28,dot:36,down:[1,38,39],dropout:[1,38,39],e:[25,26],each:35,economi:32,electron:[25,26],element:[0,28,31,36,37],elimin:24,elu:[38,39],energi:31,ensembl:10,entri:[38,39],entropi:[9,35],environ:[0,15,31],equat:[0,2,12,31,32,33,35,36,38,39],error:[0,10,31,32,34],essenti:31,estim:[33,34],et:[21,37],etc:31,euler:2,evalu:[1,26,38,39],exampl:[0,1,2,3,4,6,7,8,9,10,21,31,32,33,34,35,36,37,38,39],exercis:[0,6,15,16,17,18,19,20,21,22,31,32,38],expect:[18,28,33,34],expens:34,experi:28,explicit:[38,39],explod:[38,39],explor:[0,15,16,31],exponenti:2,express:[17,18,32,35,36,38,39],extend:[35,36,38],extrapol:4,extrem:[10,31],ey:10,f:[25,26],fall:29,famili:[1,31,32,38,39],famou:24,fantast:32,featur:[9,24,32],feed:[1,12,37,38,39],find:[34,36],fine:[1,38,39],first:[4,12,26,31,32,33,35,36,38,39],fit:[0,10,31,33],fix:32,fold:[34,35],forc:3,forest:10,format:[25,26,31],forward:[1,2,12,37,38,39],fourier:3,frank:[6,25,32],freedom:[0,32],frequent:32,frequentist:[0,31],fridai:[],from:[5,10,12,21,26,32,33,34,35,36,37,38,39],full:[2,39],funtion:[38,39],further:[3,5,32],g:25,gan:4,gate:[37,38,39],gaussian:24,gd:[13,21,36,37],gener:[4,9,31,38],geometr:[11,35,36],get:[21,37,38],gini:9,glorot:[38,39],good:[0,31],goodfellow:[21,37],grade:[29,31],gradient:[1,2,10,13,21,26,35,36,37,38,39],grid:35,group:35,growth:2,ha:23,hand:[38,39],handl:[24,31,32],happen:[33,34],hard:22,hessian:[32,35,36],hidden:[2,38,39],histogram:34,homework:[35,36],homogen:[38,39],hous:0,how:35,hyperbol:[37,38,39],hyperparamet:[1,38,39],hyperplan:8,i:1,id3:9,idea:11,ideal:[35,36],ident:[33,34],identifi:34,ii:31,iid:[33,34],illustr:[33,37,38],implement:[1,37,39],implic:[5,32],improv:[1,36,39],includ:[13,21,35,36,37,38],increment:11,independ:[33,34],index:9,inform:29,ingredi:38,input:[2,38,39],insight:[38,39],instal:[23,25,31],instructor:29,intercept:32,intermedi:38,interpret:[5,11,31,32,33,34,35,36],interv:34,introduc:[11,13,21,32,36,37],introduct:[0,6,23,24,25,26,31,37,38],invers:[5,24,33],invert:32,iter:[10,36],its:32,jacobian:32,jax:[13,21,36,37],job:[37,38],julia:31,jungl:10,k:[34,35,38,39],kera:[1,3,39],kernel:[8,11],l:[38,39],lab:[34,35,36,37],lagrangian:8,lambda:35,lasso:[5,6,25,32,33,34,35,37],last:[32,35,37,38,39],later:[5,32,39],layer:[1,2,3,12,38,39],layout:[38,39],learn:[0,1,2,11,13,14,15,16,21,23,25,26,31,32,33,34,35,36,37,38,39],least:[5,6,18,25,31,32,33],lectur:[31,32,33,34,35,36,37,38,39],level:10,librari:[23,31],likelihood:[7,33,34,35],limit:[1,13,28,34,35,36,37,38,39],linear:[0,8,13,24,26,31,32,33,35],link:[5,11,27,30,32,33,34],list:[38,39],literatur:[25,26],logist:[7,26,31,35,36,37,38,39],loop:[36,37],loss:[32,35,36],lu:24,machin:[0,8,13,23,25,26,31,35,36],made:[33,34],main:[28,31],make:[0,9,10,15,16,31,32],mani:[10,12],manipul:32,margin:[33,34],mass:31,materi:[25,27,31,32,33,34,35,38,39],math:[5,32],mathemat:[3,5,8,32,36,37,38,39],matric:[5,24,31,33],matrix:[1,5,11,12,24,31,32,33,35,36,37,39],matter:[0,31],max:32,maximum:[33,34,35],mean:[0,32,33,35],measur:35,meet:[5,10,28,31,32],mercer:8,method:[6,9,10,13,21,25,31,34,35,36,37,39],midnight:[25,26],min:32,mini:[36,37],minibatch:[21,36,37],minim:[31,35],ml:31,mle:[33,34],mlp:12,mnist:[3,4],mode:38,model:[0,1,4,6,12,31,37,38,39],moment:[36,37],momentum:[13,21,36,37],mondai:[32,33,34,35,36,37,38],moon:[8,9],more:[3,6,21,24,25,31,32,33,34,35,36,37,38,39],multi:[37,38,39],multiclass:39,multilay:[12,37,38],multipl:[1,3,39],multipli:8,multivari:38,need:[25,31],network:[1,2,3,4,7,12,26,31,35,37,38,39],neural:[1,2,3,4,7,12,26,31,37,38,39],neuron:[37,38],newton:[21,35,36,37],nn:[38,39],node:[38,39],noen:21,non:8,none:[36,37],normal:[0,1,34,38,39],notat:[12,37],note:[21,25,32,33,37],novemb:26,now:[1,9,13,21,33,34,36,37,39],nuclear:[0,31],nueral:35,numba:31,number:[0,2,21,28,32,36,37,38],numer:[2,25,26,28],numpi:[21,24,31,36,37],object:[3,39],observ:[38,39],obtain:11,octob:[25,38,39],od:2,off:[6,25],ol:[5,6,21,25,33,34,36,37],one:[2,12,35,36,38,39],ones:[37,38,39],oper:[24,38],optim:[1,8,13,23,31,32,35,36,37,38,39],option:22,order:[13,21,36,37],ordinari:[5,6,18,25,31,32,33],organ:[0,31],orient:39,oslo:30,other:[4,9,11,12,24,25,31,32,35,37,38,39],ouput:[38,39],our:[0,4,5,11,13,31,32,35,36,38,39],outcom:[23,31],output:[2,38,39],over:[38,39],overarch:[0,4,8,9,17,18,19,20,21,22,31,32,38],overview:[10,31,36,37],own:[0,10,11,15,16,26,31,32],packag:[24,31],panda:[31,32],paper:[25,38,39],parallel:38,paramet:[31,32,35,36,37,38,39],part:[13,23,25,26,32,35,36,38,39],partial:2,pass:[1,39],pca:11,pdf:28,pencil:25,percepetron:[38,39],perceptron:[12,37,38,39],perform:[1,9,39],period:3,perspect:[1,38,39],plan:[32,33,34,35,36,37,38],plot:[34,35],point:[4,38],poisson:2,polynomi:[3,33],popul:2,popular:31,practic:[13,21,29,31,36,37],pre:[1,3,39],preambl:25,predict:4,predictor:35,preprocess:32,prerequisit:[3,23,31],princip:11,principl:3,pro:9,probabl:[5,28,33,34],problem:[1,2,13,21,31,32,33,35,36,37,38,39],procedur:[9,31],process:[1,3,39],product:36,program:[2,13,25,26,35,36,38],project:[6,25,26,31,35],prop:[13,36,37],propag:[1,12,38,39],properti:[5,28,32,35],python:[0,9,15,23,24,31],quick:8,r:31,random:[10,11,28,35],raphson:[35,36],rate:[21,36,37,39],read:[9,31,32,34,35,37,38,39],real:[6,25,31,38],recommend:[31,32,38,39],rectangular:33,recurr:[4,12,37,38],recurs:[36,37],reduc:[0,32,38],reduct:3,refer:25,reformul:2,regress:[0,5,6,7,9,10,13,17,18,25,26,31,32,33,34,35,36,37,38],regular:[1,35,39],relat:32,relev:[30,32,35,37,38,39],relu:[1,38,39],remark:3,remind:[6,8,31,35,36,38,39],repeat:32,replac:[13,36,37],report:[25,26],repositori:34,repres:[],requir:[2,23],resampl:[6,25,34],rescal:[6,33],residu:32,resourc:2,result:[32,33,38,39],revers:38,revisit:[13,35,36],rewrit:[31,32,34],rewritten:35,ridg:[0,5,6,17,18,25,32,33,34,35,36,37],rm:[13,36,37],rmsprop:[21,36,37],root:[38,39],rule:[12,38,39],s:[8,10,21,34,35,36,37],same:[13,21,34,36,37],sampl:11,scale:32,schedul:[27,31,39],schemat:9,scheme:2,scienc:31,scikit:[0,1,11,15,16,31,32,33,34,35,36,39],search:35,second:[13,21,36,37],select:35,semest:29,sensit:[35,36],septemb:[33,34,35,36,37],seriou:38,session:[32,33,34,35,36,37,38,39],set:[0,2,3,9,12,15,31,32,35,38,39],sgd:[13,36,37],should:[1,38,39],sigmoid:[38,39],similar:[13,21,36,37],simpl:[0,4,9,13,31,32,33,35,36,37,38,39],simpler:38,singl:[10,37,38],singular:[5,11,17,32],size:32,slightli:[36,37],smarter:38,soft:8,softmax:[1,39],softwar:[25,31],solv:[2,33,35,36],solver:13,some:[13,24,32,35,36,38],specifi:2,split:[0,15,16,31,32],squar:[0,5,6,10,18,25,31,32,33],standard:[13,32,34,36],start:[21,37],state:[0,31],statist:[5,6,23,28,31,33,34],steepest:[10,13,35,36],step:[26,34,35,36,37],still:32,stochast:[13,21,26,28,36,37],stop:[36,37],strongli:31,studi:35,subtract:32,suggest:[31,35,37],sum:[34,38,39],summari:[29,31,37],superposit:3,supervis:[1,38,39],support:8,svd:[5,32,33],syntax:36,systemat:3,t:[32,33],taken:[21,37],teach:[27,29],teacher:[29,31],technic:33,techniqu:[6,11,25],technolog:23,tensorflow:[1,3,39],tent:31,term:[34,38,39],test:[0,1,15,16,26,31,32,33,39],text:31,textbook:[30,31],than:[35,36],theorem:[5,8,11,12,28,33,34,38],theori:28,thi:[17,18,19,20,21,22,31,38],think:32,three:[38,39],through:38,thursdai:[],time:[36,37],tip:[13,21,36,37],togeth:[12,38,39],tool:[25,31],top:[1,38,39],topic:31,toward:11,trade:[6,25],tradeoff:[6,34],train:[0,1,4,15,16,31,32,38,39],transform:3,tree:[9,10],tuesdai:[33,37,38,39],tune:[1,38,39],two:[3,8,23,25,32,35,38,39],type:[2,4,12,31,37,38],uio:31,understand:34,univers:[12,30,38],unsupervis:14,unsupport:36,up:[0,2,9,12,15,21,31,32,34,35,37,38,39],updat:[38,39],us:[0,1,2,3,7,13,21,23,25,26,31,32,35,36,37,38,39],usag:[33,34,39],valid:[6,25,34,35],valu:[5,11,17,18,28,32,33,34,35],vanish:[38,39],vari:[21,36,37],variabl:[28,35,36],varianc:[6,25,33,34],variou:[0,15,26,31,34,35],vector:[8,12,24,31,32,37],veri:22,video:[35,36,37],view:[0,4,10,32,38],visual:[1,9,39],vs:3,wai:[9,21,34,37,38],warm:[21,37],wave:2,we:[21,31,36,37,38,39],wednesdai:[33,37,38,39],week:[15,16,17,18,19,20,21,22,31,32,33,34,35,36,37,38,39],weekend:35,weekli:27,weight:39,what:[0,31,32,33,34],when:[36,37],which:[1,21,36,37,38,39],why:[31,32,34,37,38],wisconsin:[7,35],word:38,wrap:[32,34],write:[4,11,25,26,33,39],x:[32,33],xgboost:10,xor:[37,38,39],yet:33,your:[0,10,15,16,26,31,32],yourself:35,z_j:[38,39]}}) \ No newline at end of file diff --git a/doc/LectureNotes/_build/html/week42.html b/doc/LectureNotes/_build/html/week42.html new file mode 100644 index 000000000..17e394128 --- /dev/null +++ b/doc/LectureNotes/_build/html/week42.html @@ -0,0 +1,5223 @@ + + + + + + + + Week 42 Constructing a Neural Network code with examples — Applied Data Analysis and Machine Learning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + +
    +
    + + + + + + + + +
    + +
    +
    + +
    + + + + + + + + + + + + + + +
    + + +
    + +
    + Contents +
    + +
    +
    +
    +
    +
    + +
    +

    Week 42 Constructing a Neural Network code with examples

    + +
    +
    + +
    +

    Contents

    +
    + +
    +
    +
    + +
    + + +
    +

    Week 42 Constructing a Neural Network code with examples

    +

    Morten Hjorth-Jensen, Department of Physics, University of Oslo and Department of Physics and Astronomy and Facility for Rare Isotope Beams, Michigan State University

    +

    Date: October 14-18, 2024

    +
    +

    Lecture October 14, 2024

    +
      +
    1. Building our own Feed-forward Neural Network and discussion of project 2

    2. +
    +

    Readings and videos.

    +
      +
    1. These lecture notes

    2. +
    + + +
      +
    1. For a more in depth discussion on neural networks we recommend Goodfellow et al chapters 6 and 7.

    2. +
    3. Neural Networks demystified at https://www.youtube.com/watch?v=bxe2T-V8XRs&amp;list=PLiaHhY2iBX9hdHaRr6b7XevZtgZRa1PoU&amp;ab_channel=WelchLabs

    4. +
    5. Building Neural Networks from scratch at https://www.youtube.com/watch?v=Wo5dMEP_BbI&amp;list=PLQVvvaa0QuDcjD5BAw2DxE6OF2tius3V3&amp;ab_channel=sentdex

    6. +
    7. Video on Neural Networks at https://www.youtube.com/watch?v=CqOfi41LfDw

    8. +
    9. Video on the back propagation algorithm at https://www.youtube.com/watch?v=Ilg3gGewQ5U

    10. +
    +

    I also recommend Michael Nielsen’s intuitive approach to the neural networks and the universal approximation theorem, see the slides at http://neuralnetworksanddeeplearning.com/chap4.html.

    +
    +
    +

    Material for the active learning sessions on Tuesday and Wednesday

    +
      +
    • Exercise on starting to write a code for neural networks, feed forward part. We will also continue ur discussions of gradient descent methods from last week. If you have time, start considering the back-propagation part as well (exercises for next week)

    • +
    • Discussion of project 2

    • +
    +

    Note: some of the codes will also be discussed next week in connection with the solution of differential equations.

    +
    +
    +

    Writing a code which implements a feed-forward neural network

    +

    Last week we discussed the basics of neural networks and deep learning +and the basics of automatic differentiation. We looked also at +examples on how compute the parameters of a simple network with scalar +inputs and ouputs and no or just one hidden layers.

    +

    We ended our discussions with the derivation of the equations for a +neural network with one hidden layers and two input variables and two +hidden nodes but only one output node.

    +
    + +
    +

    Reminder on books with hands-on material and codes

    + +
    +
    +

    Reading recommendations

    +
      +
    1. Rashkca et al., chapter 11, jupyter-notebook sent separately, from GitHub

    2. +
    3. Goodfellow et al, chapter 6 and 7 contain most of the neural network background.

    4. +
    +
    +
    +

    First network example, simple percepetron with one input

    +

    As yet another example we define now a simple perceptron model with +all quantities given by scalars. We consider only one input variable +\(x\) and one target value \(y\). We define an activation function +\(\sigma_1\) which takes as input

    +
    +\[ +z_1 = w_1x+b_1, +\]
    +

    where \(w_1\) is the weight and \(b_1\) is the bias. These are the +parameters we want to optimize. The output is \(a_1=\sigma(z_1)\) (see +graph from whiteboard notes). This output is then fed into the +cost/loss function, which we here for the sake of simplicity just +define as the squared error

    +
    +\[ +C(x;w_1,b_1)=\frac{1}{2}(a_1-y)^2. +\]
    +
    +
    +

    Layout of a simple neural network with no hidden layer

    + + +

    Figure 1:

    +
    +
    +

    Optimizing the parameters

    +

    In setting up the feed forward and back propagation parts of the +algorithm, we need now the derivative of the various variables we want +to train.

    +

    We need

    +
    +\[ +\frac{\partial C}{\partial w_1} \hspace{0.1cm}\mathrm{and}\hspace{0.1cm}\frac{\partial C}{\partial b_1}. +\]
    +

    Using the chain rule we find

    +
    +\[ +\frac{\partial C}{\partial w_1}=\frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial w_1}=(a_1-y)\sigma_1'x, +\]
    +

    and

    +
    +\[ +\frac{\partial C}{\partial b_1}=\frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial b_1}=(a_1-y)\sigma_1', +\]
    +

    which we later will just define as

    +
    +\[ +\frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}=\delta_1. +\]
    +
    +
    +

    Adding a hidden layer

    +

    We change our simple model to (see graph) +a network with just one hidden layer but with scalar variables only.

    +

    Our output variable changes to \(a_2\) and \(a_1\) is now the output from the hidden node and \(a_0=x\). +We have then

    +
    +\[ +z_1 = w_1a_0+b_1 \hspace{0.1cm} \wedge a_1 = \sigma_1(z_1), +\]
    +
    +\[ +z_2 = w_2a_1+b_2 \hspace{0.1cm} \wedge a_2 = \sigma_2(z_2), +\]
    +

    and the cost function

    +
    +\[ +C(x;\boldsymbol{\Theta})=\frac{1}{2}(a_2-y)^2, +\]
    +

    with \(\boldsymbol{\Theta}=[w_1,w_2,b_1,b_2]\).

    +
    +
    +

    Layout of a simple neural network with one hidden layer

    + + +

    Figure 1:

    +
    +
    +

    The derivatives

    +

    The derivatives are now, using the chain rule again

    +
    +\[ +\frac{\partial C}{\partial w_2}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial w_2}=(a_2-y)\sigma_2'a_1=\delta_2a_1, +\]
    +
    +\[ +\frac{\partial C}{\partial b_2}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial b_2}=(a_2-y)\sigma_2'=\delta_2, +\]
    +
    +\[ +\frac{\partial C}{\partial w_1}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial w_1}=(a_2-y)\sigma_2'a_1\sigma_1'a_0, +\]
    +
    +\[ +\frac{\partial C}{\partial b_1}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial b_1}=(a_2-y)\sigma_2'\sigma_1'=\delta_1. +\]
    +

    Can you generalize this to more than one hidden layer?

    +
    +
    +

    Important observations

    +

    From the above equations we see that the derivatives of the activation +functions play a central role. If they vanish, the training may +stop. This is called the vanishing gradient problem, see discussions below. If they become +large, the parameters \(w_i\) and \(b_i\) may simply go to infinity. This +is referenced as the exploding gradient problem.

    +
    +
    +

    The training

    +

    The training of the parameters is done through various gradient descent approximations with

    +
    +\[ +w_{i}\leftarrow w_{i}- \eta \delta_i a_{i-1}, +\]
    +

    and

    +
    +\[ +b_i \leftarrow b_i-\eta \delta_i, +\]
    +

    with \(\eta\) is the learning rate.

    +

    One iteration consists of one feed forward step and one back-propagation step. Each back-propagation step does one update of the parameters \(\boldsymbol{\Theta}\).

    +

    For the first hidden layer \(a_{i-1}=a_0=x\) for this simple model.

    +
    +
    +

    Code example

    +

    The code here implements the above model with one hidden layer and +scalar variables for the same function we studied in the previous +example. The code is however set up so that we can add multiple +inputs \(x\) and target values \(y\). Note also that we have the +possibility of defining a feature matrix \(\boldsymbol{X}\) with more than just +one column for the input values. This will turn useful in our next example. We have also defined matrices and vectors for all of our operations although it is not necessary here.

    +
    +
    +
    import numpy as np
    +# We use the Sigmoid function as activation function
    +def sigmoid(z):
    +    return 1.0/(1.0+np.exp(-z))
    +
    +def forwardpropagation(x):
    +    # weighted sum of inputs to the hidden layer
    +    z_1 = np.matmul(x, w_1) + b_1
    +    # activation in the hidden layer
    +    a_1 = sigmoid(z_1)
    +    # weighted sum of inputs to the output layer
    +    z_2 = np.matmul(a_1, w_2) + b_2
    +    a_2 = z_2
    +    return a_1, a_2
    +
    +def backpropagation(x, y):
    +    a_1, a_2 = forwardpropagation(x)
    +    # parameter delta for the output layer, note that a_2=z_2 and its derivative wrt z_2 is just 1
    +    delta_2 = a_2 - y
    +    print(0.5*((a_2-y)**2))
    +    # delta for  the hidden layer
    +    delta_1 = np.matmul(delta_2, w_2.T) * a_1 * (1 - a_1)
    +    # gradients for the output layer
    +    output_weights_gradient = np.matmul(a_1.T, delta_2)
    +    output_bias_gradient = np.sum(delta_2, axis=0)
    +    # gradient for the hidden layer
    +    hidden_weights_gradient = np.matmul(x.T, delta_1)
    +    hidden_bias_gradient = np.sum(delta_1, axis=0)
    +    return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient
    +
    +
    +# ensure the same random numbers appear every time
    +np.random.seed(0)
    +# Input variable
    +x = np.array([4.0],dtype=np.float64)
    +# Target values
    +y = 2*x+1.0 
    +
    +# Defining the neural network, only scalars here
    +n_inputs = x.shape
    +n_features = 1
    +n_hidden_neurons = 1
    +n_outputs = 1
    +
    +# Initialize the network
    +# weights and bias in the hidden layer
    +w_1 = np.random.randn(n_features, n_hidden_neurons)
    +b_1 = np.zeros(n_hidden_neurons) + 0.01
    +
    +# weights and bias in the output layer
    +w_2 = np.random.randn(n_hidden_neurons, n_outputs)
    +b_2 = np.zeros(n_outputs) + 0.01
    +
    +eta = 0.1
    +for i in range(50):
    +    # calculate gradients
    +    derivW2, derivB2, derivW1, derivB1 = backpropagation(x, y)
    +    # update weights and biases
    +    w_2 -= eta * derivW2
    +    b_2 -= eta * derivB2
    +    w_1 -= eta * derivW1
    +    b_1 -= eta * derivB1
    +
    +
    +
    +
    +
    [36.89563074]
    +[23.62323175]
    +[15.1251681]
    +[9.68402334]
    +[6.20020163]
    +[3.96963458]
    +[2.54150298]
    +[1.62714703]
    +[1.0417409]
    +[0.66694492]
    +[0.42699034]
    +[0.27336592]
    +[0.17501258]
    +[0.11204514]
    +[0.07173249]
    +[0.04592382]
    +[0.02940083]
    +[0.01882264]
    +[0.01205039]
    +[0.00771475]
    +[0.00493903]
    +[0.003162]
    +[0.00202433]
    +[0.00129599]
    +[0.0008297]
    +[0.00053118]
    +[0.00034006]
    +[0.00021771]
    +[0.00013938]
    +[8.92313548e-05]
    +[5.71263851e-05]
    +[3.6572612e-05]
    +[2.34139775e-05]
    +[1.49897504e-05]
    +[9.5965161e-06]
    +[6.14373934e-06]
    +[3.93325371e-06]
    +[2.51808934e-06]
    +[1.61209378e-06]
    +[1.03207075e-06]
    +[6.60737006e-07]
    +[4.23007231e-07]
    +[2.70811405e-07]
    +[1.73374853e-07]
    +[1.10995472e-07]
    +[7.10598715e-08]
    +[4.54928947e-08]
    +[2.91247848e-08]
    +[1.86458368e-08]
    +[1.19371605e-08]
    +
    +
    +
    +
    +

    We see that after some few iterations (the results do depend on the learning rate however), we get an error which is rather small.

    +
    +
    +

    Simple neural network and the back propagation equations

    +

    Let us now try to increase our level of ambition and attempt at setting +up the equations for a neural network with two input nodes, one hidden +layer with two hidden nodes and one output layer with one output node/neuron only (see graph)..

    +

    We need to define the following parameters and variables with the input layer (layer \((0)\)) +where we label the nodes \(x_0\) and \(x_1\)

    +
    +\[ +x_0 = a_0^{(0)} \wedge x_1 = a_1^{(0)}. +\]
    +

    The hidden layer (layer \((1)\)) has nodes which yield the outputs \(a_0^{(1)}\) and \(a_1^{(1)}\)) with weight \(\boldsymbol{w}\) and bias \(\boldsymbol{b}\) parameters

    +
    +\[ +w_{ij}^{(1)}=\left\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)}\right\} \wedge b^{(1)}=\left\{b_0^{(1)},b_1^{(1)}\right\}. +\]
    +
    +
    +

    Layout of a simple neural network with two input nodes, one hidden layer and one output node

    + + +

    Figure 1:

    +
    +
    +

    The ouput layer

    +

    Finally, we have the ouput layer given by layer label \((2)\) with output \(a^{(2)}\) and weights and biases to be determined given by the variables

    +
    +\[ +w_{i}^{(2)}=\left\{w_{0}^{(2)},w_{1}^{(2)}\right\} \wedge b^{(2)}. +\]
    +

    Our output is \(\tilde{y}=a^{(2)}\) and we define a generic cost function \(C(a^{(2)},y;\boldsymbol{\Theta})\) where \(y\) is the target value (a scalar here). +The parameters we need to optimize are given by

    +
    +\[ +\boldsymbol{\Theta}=\left\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)},w_{0}^{(2)},w_{1}^{(2)},b_0^{(1)},b_1^{(1)},b^{(2)}\right\}. +\]
    +
    +
    +

    Compact expressions

    +

    We can define the inputs to the activation functions for the various layers in terms of various matrix-vector multiplications and vector additions. +The inputs to the first hidden layer are

    +
    +\[\begin{split} +\begin{bmatrix}z_0^{(1)} \\ z_1^{(1)} \end{bmatrix}=\left(\begin{bmatrix}w_{00}^{(1)} & w_{01}^{(1)}\\ w_{10}^{(1)} &w_{11}^{(1)} \end{bmatrix}\right)^{T}\begin{bmatrix}a_0^{(0)} \\ a_1^{(0)} \end{bmatrix}+\begin{bmatrix}b_0^{(1)} \\ b_1^{(1)} \end{bmatrix}, +\end{split}\]
    +

    with outputs

    +
    +\[\begin{split} +\begin{bmatrix}a_0^{(1)} \\ a_1^{(1)} \end{bmatrix}=\begin{bmatrix}\sigma^{(1)}(z_0^{(1)}) \\ \sigma^{(1)}(z_1^{(1)}) \end{bmatrix}. +\end{split}\]
    +
    +
    +

    Output layer

    +

    For the final output layer we have the inputs to the final activation function

    +
    +\[ +z^{(2)} = w_{0}^{(2)}a_0^{(1)} +w_{1}^{(2)}a_1^{(1)}+b^{(2)}, +\]
    +

    resulting in the output

    +
    +\[ +a^{(2)}=\sigma^{(2)}(z^{(2)}). +\]
    +
    +
    +

    Explicit derivatives

    +

    In total we have nine parameters which we need to train. Using the +chain rule (or just the back-propagation algorithm) we can find all +derivatives. Since we will use automatic differentiation in reverse +mode, we start with the derivatives of the cost function with respect +to the parameters of the output layer, namely

    +
    +\[ +\frac{\partial C}{\partial w_{i}^{(2)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial w_{i}^{(2)}}=\delta^{(2)}a_i^{(1)}, +\]
    +

    with

    +
    +\[ +\delta^{(2)}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}} +\]
    +

    and finally

    +
    +\[ +\frac{\partial C}{\partial b^{(2)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial b^{(2)}}=\delta^{(2)}. +\]
    +
    +
    +

    Derivatives of the hidden layer

    +

    Using the chain rule we have the following expressions for say one of the weight parameters (it is easy to generalize to the other weight parameters)

    +
    +\[ +\frac{\partial C}{\partial w_{00}^{(1)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}} +\frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}= \delta^{(2)}\frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}, +\]
    +

    which, noting that

    +
    +\[ +z^{(2)} =w_0^{(2)}a_0^{(1)}+w_1^{(2)}a_1^{(1)}+b^{(2)}, +\]
    +

    allows us to rewrite

    +
    +\[ +\frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}=w_0^{(2)}\frac{\partial a_0^{(1)}}{\partial z_0^{(1)}}a_0^{(1)}. +\]
    +
    +
    +

    Final expression

    +

    Defining

    +
    +\[ +\delta_0^{(1)}=w_0^{(2)}\frac{\partial a_0^{(1)}}{\partial z_0^{(1)}}\delta^{(2)}, +\]
    +

    we have

    +
    +\[ +\frac{\partial C}{\partial w_{00}^{(1)}}=\delta_0^{(1)}a_0^{(1)}. +\]
    +

    Similarly, we obtain

    +
    +\[ +\frac{\partial C}{\partial w_{01}^{(1)}}=\delta_0^{(1)}a_1^{(1)}. +\]
    +
    +
    +

    Completing the list

    +

    Similarly, we find

    +
    +\[ +\frac{\partial C}{\partial w_{10}^{(1)}}=\delta_1^{(1)}a_0^{(1)}, +\]
    +

    and

    +
    +\[ +\frac{\partial C}{\partial w_{11}^{(1)}}=\delta_1^{(1)}a_1^{(1)}, +\]
    +

    where we have defined

    +
    +\[ +\delta_1^{(1)}=w_1^{(2)}\frac{\partial a_1^{(1)}}{\partial z_1^{(1)}}\delta^{(2)}. +\]
    +
    +
    +

    Final expressions for the biases of the hidden layer

    +

    For the sake of completeness, we list the derivatives of the biases, which are

    +
    +\[ +\frac{\partial C}{\partial b_{0}^{(1)}}=\delta_0^{(1)}, +\]
    +

    and

    +
    +\[ +\frac{\partial C}{\partial b_{1}^{(1)}}=\delta_1^{(1)}. +\]
    +

    As we will see below, these expressions can be generalized in a more compact form.

    +
    +
    +

    Gradient expressions

    +

    For this specific model, with just one output node and two hidden +nodes, the gradient descent equations take the following form for output layer

    +
    +\[ +w_{i}^{(2)}\leftarrow w_{i}^{(2)}- \eta \delta^{(2)} a_{i}^{(1)}, +\]
    +

    and

    +
    +\[ +b^{(2)} \leftarrow b^{(2)}-\eta \delta^{(2)}, +\]
    +

    and

    +
    +\[ +w_{ij}^{(1)}\leftarrow w_{ij}^{(1)}- \eta \delta_{i}^{(1)} a_{j}^{(0)}, +\]
    +

    and

    +
    +\[ +b_{i}^{(1)} \leftarrow b_{i}^{(1)}-\eta \delta_{i}^{(1)}, +\]
    +

    where \(\eta\) is the learning rate.

    +
    +
    +

    Setting up the equations for a neural network

    +

    The questions we want to ask are how do changes in the biases and the +weights in our network change the cost function and how can we use the +final output to modify the weights and biases?

    +

    To derive these equations let us start with a plain regression problem +and define our cost function as

    +
    +\[ +{\cal C}(\boldsymbol{\Theta}) = \frac{1}{2}\sum_{i=1}^n\left(y_i - \tilde{y}_i\right)^2, +\]
    +

    where the \(y_i\)s are our \(n\) targets (the values we want to +reproduce), while the outputs of the network after having propagated +all inputs \(\boldsymbol{x}\) are given by \(\boldsymbol{\tilde{y}}_i\).

    +
    +
    +

    Layout of a neural network with three hidden layers (last later = \(l=L=4\), first layer \(l=0\))

    + + +

    Figure 1:

    +
    +
    +

    Definitions

    +

    With our definition of the targets \(\boldsymbol{y}\), the outputs of the +network \(\boldsymbol{\tilde{y}}\) and the inputs \(\boldsymbol{x}\) we +define now the activation \(z_j^l\) of node/neuron/unit \(j\) of the +\(l\)-th layer as a function of the bias, the weights which add up from +the previous layer \(l-1\) and the forward passes/outputs +\(\boldsymbol{a}^{l-1}\) from the previous layer as

    +
    +\[ +z_j^l = \sum_{i=1}^{M_{l-1}}w_{ij}^la_i^{l-1}+b_j^l, +\]
    +

    where \(b_k^l\) are the biases from layer \(l\). Here \(M_{l-1}\) +represents the total number of nodes/neurons/units of layer \(l-1\). The +figure in the whiteboard notes illustrates this equation. We can rewrite this in a more +compact form as the matrix-vector products we discussed earlier,

    +
    +\[ +\boldsymbol{z}^l = \left(\boldsymbol{W}^l\right)^T\boldsymbol{a}^{l-1}+\boldsymbol{b}^l. +\]
    +
    +
    +

    Inputs to the activation function

    +

    With the activation values \(\boldsymbol{z}^l\) we can in turn define the +output of layer \(l\) as \(\boldsymbol{a}^l = \sigma(\boldsymbol{z}^l)\) where \(\sigma\) is our +activation function. In the examples here we will use the sigmoid +function discussed in our logistic regression lectures. We will also use the same activation function \(\sigma\) for all layers +and their nodes. It means we have

    +
    +\[ +a_j^l = \sigma(z_j^l) = \frac{1}{1+\exp{-(z_j^l)}}. +\]
    +
    +
    +

    Layout of input to first hidden layer \(l=1\) from input layer \(l=0\)

    + + +

    Figure 1:

    +
    +
    +

    Derivatives and the chain rule

    +

    From the definition of the input variable to the activation function, that is \(z_j^l\) we have

    +
    +\[ +\frac{\partial z_j^l}{\partial w_{ij}^l} = a_i^{l-1}, +\]
    +

    and

    +
    +\[ +\frac{\partial z_j^l}{\partial a_i^{l-1}} = w_{ji}^l. +\]
    +

    With our definition of the activation function we have that (note that this function depends only on \(z_j^l\))

    +
    +\[ +\frac{\partial a_j^l}{\partial z_j^{l}} = a_j^l(1-a_j^l)=\sigma(z_j^l)(1-\sigma(z_j^l)). +\]
    +
    +
    +

    Derivative of the cost function

    +

    With these definitions we can now compute the derivative of the cost function in terms of the weights.

    +

    Let us specialize to the output layer \(l=L\). Our cost function is

    +
    +\[ +{\cal C}(\boldsymbol{\Theta}^L) = \frac{1}{2}\sum_{i=1}^n\left(y_i - \tilde{y}_i\right)^2=\frac{1}{2}\sum_{i=1}^n\left(a_i^L - y_i\right)^2, +\]
    +

    The derivative of this function with respect to the weights is

    +
    +\[ +\frac{\partial{\cal C}(\boldsymbol{\Theta}^L)}{\partial w_{ij}^L} = \left(a_j^L - y_j\right)\frac{\partial a_j^L}{\partial w_{ij}^{L}}, +\]
    +

    The last partial derivative can easily be computed and reads (by applying the chain rule)

    +
    +\[ +\frac{\partial a_j^L}{\partial w_{ij}^{L}} = \frac{\partial a_j^L}{\partial z_{j}^{L}}\frac{\partial z_j^L}{\partial w_{ij}^{L}}=a_j^L(1-a_j^L)a_i^{L-1}. +\]
    +
    +
    +

    The back propagation equations for a neural network

    +

    We have thus

    +
    +\[ +\frac{\partial{\cal C}((\boldsymbol{\Theta}^L)}{\partial w_{ij}^L} = \left(a_j^L - y_j\right)a_j^L(1-a_j^L)a_i^{L-1}, +\]
    +

    Defining

    +
    +\[ +\delta_j^L = a_j^L(1-a_j^L)\left(a_j^L - y_j\right) = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}, +\]
    +

    and using the Hadamard product of two vectors we can write this as

    +
    +\[ +\boldsymbol{\delta}^L = \sigma'(\boldsymbol{z}^L)\circ\frac{\partial {\cal C}}{\partial (\boldsymbol{a}^L)}. +\]
    +
    +
    +

    Analyzing the last results

    +

    This is an important expression. The second term on the right handside +measures how fast the cost function is changing as a function of the \(j\)th +output activation. If, for example, the cost function doesn’t depend +much on a particular output node \(j\), then \(\delta_j^L\) will be small, +which is what we would expect. The first term on the right, measures +how fast the activation function \(f\) is changing at a given activation +value \(z_j^L\).

    +
    +
    +

    More considerations

    +

    Notice that everything in the above equations is easily computed. In +particular, we compute \(z_j^L\) while computing the behaviour of the +network, and it is only a small additional overhead to compute +\(\sigma'(z^L_j)\). The exact form of the derivative with respect to the +output depends on the form of the cost function. +However, provided the cost function is known there should be little +trouble in calculating

    +
    +\[ +\frac{\partial {\cal C}}{\partial (a_j^L)} +\]
    +

    With the definition of \(\delta_j^L\) we have a more compact definition of the derivative of the cost function in terms of the weights, namely

    +
    +\[ +\frac{\partial{\cal C}}{\partial w_{ij}^L} = \delta_j^La_i^{L-1}. +\]
    +
    +
    +

    Derivatives in terms of \(z_j^L\)

    +

    It is also easy to see that our previous equation can be written as

    +
    +\[ +\delta_j^L =\frac{\partial {\cal C}}{\partial z_j^L}= \frac{\partial {\cal C}}{\partial a_j^L}\frac{\partial a_j^L}{\partial z_j^L}, +\]
    +

    which can also be interpreted as the partial derivative of the cost function with respect to the biases \(b_j^L\), namely

    +
    +\[ +\delta_j^L = \frac{\partial {\cal C}}{\partial b_j^L}\frac{\partial b_j^L}{\partial z_j^L}=\frac{\partial {\cal C}}{\partial b_j^L}, +\]
    +

    That is, the error \(\delta_j^L\) is exactly equal to the rate of change of the cost function as a function of the bias.

    +
    +
    +

    Bringing it together

    +

    We have now three equations that are essential for the computations of the derivatives of the cost function at the output layer. These equations are needed to start the algorithm and they are

    + +
    +
    +\[ +\begin{equation} +\frac{\partial{\cal C}(\boldsymbol{W^L})}{\partial w_{ij}^L} = \delta_j^La_i^{L-1}, +\label{_auto1} \tag{1} +\end{equation} +\]
    +

    and

    + +
    +
    +\[ +\begin{equation} +\delta_j^L = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}, +\label{_auto2} \tag{2} +\end{equation} +\]
    +

    and

    + +
    +
    +\[ +\begin{equation} +\delta_j^L = \frac{\partial {\cal C}}{\partial b_j^L}, +\label{_auto3} \tag{3} +\end{equation} +\]
    +
    +
    +

    Final back propagating equation

    +

    We have that (replacing \(L\) with a general layer \(l\))

    +
    +\[ +\delta_j^l =\frac{\partial {\cal C}}{\partial z_j^l}. +\]
    +

    We want to express this in terms of the equations for layer \(l+1\).

    +
    +
    +

    Using the chain rule and summing over all \(k\) entries

    +

    We obtain

    +
    +\[ +\delta_j^l =\sum_k \frac{\partial {\cal C}}{\partial z_k^{l+1}}\frac{\partial z_k^{l+1}}{\partial z_j^{l}}=\sum_k \delta_k^{l+1}\frac{\partial z_k^{l+1}}{\partial z_j^{l}}, +\]
    +

    and recalling that

    +
    +\[ +z_j^{l+1} = \sum_{i=1}^{M_{l}}w_{ij}^{l+1}a_i^{l}+b_j^{l+1}, +\]
    +

    with \(M_l\) being the number of nodes in layer \(l\), we obtain

    +
    +\[ +\delta_j^l =\sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l), +\]
    +

    This is our final equation.

    +

    We are now ready to set up the algorithm for back propagation and learning the weights and biases.

    +
    +
    +

    Setting up the back propagation algorithm

    +

    The four equations provide us with a way of computing the gradient of the cost function. Let us write this out in the form of an algorithm.

    +

    First, we set up the input data \(\boldsymbol{x}\) and the activations +\(\boldsymbol{z}_1\) of the input layer and compute the activation function and +the pertinent outputs \(\boldsymbol{a}^1\).

    +

    Secondly, we perform then the feed forward till we reach the output +layer and compute all \(\boldsymbol{z}_l\) of the input layer and compute the +activation function and the pertinent outputs \(\boldsymbol{a}^l\) for +\(l=1,2,3,\dots,L\).

    +

    Notation: The first hidden layer has \(l=1\) as label and the final output layer has \(l=L\).

    +
    +
    +

    Setting up the back propagation algorithm, part 2

    +

    Thereafter we compute the ouput error \(\boldsymbol{\delta}^L\) by computing all

    +
    +\[ +\delta_j^L = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}. +\]
    +

    Then we compute the back propagate error for each \(l=L-1,L-2,\dots,1\) as

    +
    +\[ +\delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l). +\]
    +
    +
    +

    Setting up the Back propagation algorithm, part 3

    +

    Finally, we update the weights and the biases using gradient descent +for each \(l=L-1,L-2,\dots,1\) (the first hidden layer) and update the weights and biases +according to the rules

    +
    +\[ +w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +\]
    +
    +\[ +b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +\]
    +

    with \(\eta\) being the learning rate.

    +
    +
    +

    Updating the gradients

    +

    With the back propagate error for each \(l=L-1,L-2,\dots,1\) as

    +
    +\[ +\delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l), +\]
    +

    we update the weights and the biases using gradient descent for each \(l=L-1,L-2,\dots,1\) and update the weights and biases according to the rules

    +
    +\[ +w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +\]
    +
    +\[ +b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +\]
    +
    +

    Activation functions

    +

    A property that characterizes a neural network, other than its +connectivity, is the choice of activation function(s). As described +in, the following restrictions are imposed on an activation function +for a FFNN to fulfill the universal approximation theorem

    +
      +
    • Non-constant

    • +
    • Bounded

    • +
    • Monotonically-increasing

    • +
    • Continuous

    • +
    +
    +
    +

    Activation functions, Logistic and Hyperbolic ones

    +

    The second requirement excludes all linear functions. Furthermore, in +a MLP with only linear activation functions, each layer simply +performs a linear transformation of its inputs.

    +

    Regardless of the number of layers, the output of the NN will be +nothing but a linear function of the inputs. Thus we need to introduce +some kind of non-linearity to the NN to be able to fit non-linear +functions Typical examples are the logistic Sigmoid

    +
    +\[ +\sigma(x) = \frac{1}{1 + e^{-x}}, +\]
    +

    and the hyperbolic tangent function

    +
    +\[ +\sigma(x) = \tanh(x) +\]
    +
    +
    +

    Relevance

    +

    The sigmoid function are more biologically plausible because the +output of inactive neurons are zero. Such activation function are +called one-sided. However, it has been shown that the hyperbolic +tangent performs better than the sigmoid for training MLPs. has +become the most popular for deep neural networks

    +
    +
    +
    %matplotlib inline
    +
    +"""The sigmoid function (or the logistic curve) is a 
    +function that takes any real number, z, and outputs a number (0,1).
    +It is useful in neural networks for assigning weights on a relative scale.
    +The value z is the weighted sum of parameters involved in the learning algorithm."""
    +
    +import numpy
    +import matplotlib.pyplot as plt
    +import math as mt
    +
    +z = numpy.arange(-5, 5, .1)
    +sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))
    +sigma = sigma_fn(z)
    +
    +fig = plt.figure()
    +ax = fig.add_subplot(111)
    +ax.plot(z, sigma)
    +ax.set_ylim([-0.1, 1.1])
    +ax.set_xlim([-5,5])
    +ax.grid(True)
    +ax.set_xlabel('z')
    +ax.set_title('sigmoid function')
    +
    +plt.show()
    +
    +"""Step Function"""
    +z = numpy.arange(-5, 5, .02)
    +step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)
    +step = step_fn(z)
    +
    +fig = plt.figure()
    +ax = fig.add_subplot(111)
    +ax.plot(z, step)
    +ax.set_ylim([-0.5, 1.5])
    +ax.set_xlim([-5,5])
    +ax.grid(True)
    +ax.set_xlabel('z')
    +ax.set_title('step function')
    +
    +plt.show()
    +
    +"""Sine Function"""
    +z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)
    +t = numpy.sin(z)
    +
    +fig = plt.figure()
    +ax = fig.add_subplot(111)
    +ax.plot(z, t)
    +ax.set_ylim([-1.0, 1.0])
    +ax.set_xlim([-2*mt.pi,2*mt.pi])
    +ax.grid(True)
    +ax.set_xlabel('z')
    +ax.set_title('sine function')
    +
    +plt.show()
    +
    +"""Plots a graph of the squashing function used by a rectified linear
    +unit"""
    +z = numpy.arange(-2, 2, .1)
    +zero = numpy.zeros(len(z))
    +y = numpy.max([zero, z], axis=0)
    +
    +fig = plt.figure()
    +ax = fig.add_subplot(111)
    +ax.plot(z, y)
    +ax.set_ylim([-2.0, 2.0])
    +ax.set_xlim([-2.0, 2.0])
    +ax.grid(True)
    +ax.set_xlabel('z')
    +ax.set_title('Rectified linear unit')
    +
    +plt.show()
    +
    +
    +
    +
    +_images/week42_173_0.png +_images/week42_173_1.png +_images/week42_173_2.png +_images/week42_173_3.png +
    +
    +
    +
    +
    +

    Fine-tuning neural network hyperparameters

    +

    The flexibility of neural networks is also one of their main +drawbacks: there are many hyperparameters to tweak. Not only can you +use any imaginable network topology (how neurons/nodes are +interconnected), but even in a simple FFNN you can change the number +of layers, the number of neurons per layer, the type of activation +function to use in each layer, the weight initialization logic, the +stochastic gradient optmized and much more. How do you know what +combination of hyperparameters is the best for your task?

    +
      +
    • You can use grid search with cross-validation to find the right hyperparameters.

    • +
    +

    However,since there are many hyperparameters to tune, and since +training a neural network on a large dataset takes a lot of time, you +will only be able to explore a tiny part of the hyperparameter space.

    +
      +
    • You can use randomized search.

    • +
    • Or use tools like Oscar, which implements more complex algorithms to help you find a good set of hyperparameters quickly.

    • +
    +
    +
    +

    Hidden layers

    +

    For many problems you can start with just one or two hidden layers and +it will work just fine. For the MNIST data set you ca easily get a +high accuracy using just one hidden layer with a few hundred neurons. +You can reach for this data set above 98% accuracy using two hidden +layers with the same total amount of neurons, in roughly the same +amount of training time.

    +

    For more complex problems, you can gradually ramp up the number of +hidden layers, until you start overfitting the training set. Very +complex tasks, such as large image classification or speech +recognition, typically require networks with dozens of layers and they +need a huge amount of training data. However, you will rarely have to +train such networks from scratch: it is much more common to reuse +parts of a pretrained state-of-the-art network that performs a similar +task.

    +
    +
    +

    Vanishing gradients

    +

    The Back propagation algorithm we derived above works by going from +the output layer to the input layer, propagating the error gradient on +the way. Once the algorithm has computed the gradient of the cost +function with regards to each parameter in the network, it uses these +gradients to update each parameter with a Gradient Descent (GD) step.

    +

    Unfortunately for us, the gradients often get smaller and smaller as +the algorithm progresses down to the first hidden layers. As a result, +the GD update leaves the lower layer connection weights virtually +unchanged, and training never converges to a good solution. This is +known in the literature as the vanishing gradients problem.

    +
    +
    +

    Exploding gradients

    +

    In other cases, the opposite can happen, namely the the gradients can +grow bigger and bigger. The result is that many of the layers get +large updates of the weights the algorithm diverges. This is the +exploding gradients problem, which is mostly encountered in +recurrent neural networks. More generally, deep neural networks suffer +from unstable gradients, different layers may learn at widely +different speeds

    +
    +
    +

    Is the Logistic activation function (Sigmoid) our choice?

    +

    Although this unfortunate behavior has been empirically observed for +quite a while (it was one of the reasons why deep neural networks were +mostly abandoned for a long time), it is only around 2010 that +significant progress was made in understanding it.

    +

    A paper titled Understanding the Difficulty of Training Deep +Feedforward Neural Networks by Xavier Glorot and Yoshua Bengio found that +the problems with the popular logistic +sigmoid activation function and the weight initialization technique +that was most popular at the time, namely random initialization using +a normal distribution with a mean of 0 and a standard deviation of +1.

    +
    +
    +

    Logistic function as the root of problems

    +

    They showed that with this activation function and this +initialization scheme, the variance of the outputs of each layer is +much greater than the variance of its inputs. Going forward in the +network, the variance keeps increasing after each layer until the +activation function saturates at the top layers. This is actually made +worse by the fact that the logistic function has a mean of 0.5, not 0 +(the hyperbolic tangent function has a mean of 0 and behaves slightly +better than the logistic function in deep networks).

    +
    +
    +

    The derivative of the Logistic funtion

    +

    Looking at the logistic activation function, when inputs become large +(negative or positive), the function saturates at 0 or 1, with a +derivative extremely close to 0. Thus when backpropagation kicks in, +it has virtually no gradient to propagate back through the network, +and what little gradient exists keeps getting diluted as +backpropagation progresses down through the top layers, so there is +really nothing left for the lower layers.

    +

    In their paper, Glorot and Bengio propose a way to significantly +alleviate this problem. We need the signal to flow properly in both +directions: in the forward direction when making predictions, and in +the reverse direction when backpropagating gradients. We don’t want +the signal to die out, nor do we want it to explode and saturate. For +the signal to flow properly, the authors argue that we need the +variance of the outputs of each layer to be equal to the variance of +its inputs, and we also need the gradients to have equal variance +before and after flowing through a layer in the reverse direction.

    +
    +
    +

    Insights from the paper by Glorot and Bengio

    +

    One of the insights in the 2010 paper by Glorot and Bengio was that +the vanishing/exploding gradients problems were in part due to a poor +choice of activation function. Until then most people had assumed that +if Nature had chosen to use roughly sigmoid activation functions in +biological neurons, they must be an excellent choice. But it turns out +that other activation functions behave much better in deep neural +networks, in particular the ReLU activation function, mostly because +it does not saturate for positive values (and also because it is quite +fast to compute).

    +
    +
    +

    The RELU function family

    +

    The ReLU activation function suffers from a problem known as the dying +ReLUs: during training, some neurons effectively die, meaning they +stop outputting anything other than 0.

    +

    In some cases, you may find that half of your network’s neurons are +dead, especially if you used a large learning rate. During training, +if a neuron’s weights get updated such that the weighted sum of the +neuron’s inputs is negative, it will start outputting 0. When this +happen, the neuron is unlikely to come back to life since the gradient +of the ReLU function is 0 when its input is negative.

    +
    +
    +

    ELU function

    +

    To solve this problem, nowadays practitioners use a variant of the +ReLU function, such as the leaky ReLU discussed above or the so-called +exponential linear unit (ELU) function

    +
    +\[\begin{split} +ELU(z) = \left\{\begin{array}{cc} \alpha\left( \exp{(z)}-1\right) & z < 0,\\ z & z \ge 0.\end{array}\right. +\end{split}\]
    +
    +
    +

    Which activation function should we use?

    +

    In general it seems that the ELU activation function is better than +the leaky ReLU function (and its variants), which is better than +ReLU. ReLU performs better than \(\tanh\) which in turn performs better +than the logistic function.

    +

    If runtime performance is an issue, then you may opt for the leaky +ReLU function over the ELU function If you don’t want to tweak yet +another hyperparameter, you may just use the default \(\alpha\) of +\(0.01\) for the leaky ReLU, and \(1\) for ELU. If you have spare time and +computing power, you can use cross-validation or bootstrap to evaluate +other activation functions.

    +
    +
    +

    More on activation functions, output layers

    +

    In most cases you can use the ReLU activation function in the hidden +layers (or one of its variants).

    +

    It is a bit faster to compute than other activation functions, and the +gradient descent optimization does in general not get stuck.

    +

    For the output layer:

    +
      +
    • For classification the softmax activation function is generally a good choice for classification tasks (when the classes are mutually exclusive).

    • +
    • For regression tasks, you can simply use no activation function at all.

    • +
    +
    +
    +

    Batch Normalization

    +

    Batch Normalization aims to address the vanishing/exploding gradients +problems, and more generally the problem that the distribution of each +layer’s inputs changes during training, as the parameters of the +previous layers change.

    +

    The technique consists of adding an operation in the model just before +the activation function of each layer, simply zero-centering and +normalizing the inputs, then scaling and shifting the result using two +new parameters per layer (one for scaling, the other for shifting). In +other words, this operation lets the model learn the optimal scale and +mean of the inputs for each layer. In order to zero-center and +normalize the inputs, the algorithm needs to estimate the inputs’ mean +and standard deviation. It does so by evaluating the mean and standard +deviation of the inputs over the current mini-batch, from this the +name batch normalization.

    +
    +
    +

    Dropout

    +

    It is a fairly simple algorithm: at every training step, every neuron +(including the input neurons but excluding the output neurons) has a +probability \(p\) of being temporarily dropped out, meaning it will be +entirely ignored during this training step, but it may be active +during the next step.

    +

    The hyperparameter \(p\) is called the dropout rate, and it is typically +set to 50%. After training, the neurons are not dropped anymore. It +is viewed as one of the most popular regularization techniques.

    +
    +
    +

    Gradient Clipping

    +

    A popular technique to lessen the exploding gradients problem is to +simply clip the gradients during backpropagation so that they never +exceed some threshold (this is mostly useful for recurrent neural +networks).

    +

    This technique is called Gradient Clipping.

    +

    In general however, Batch +Normalization is preferred.

    +
    +
    +

    A top-down perspective on Neural networks

    +

    The first thing we would like to do is divide the data into two or +three parts. A training set, a validation or dev (development) set, +and a test set. The test set is the data on which we want to make +predictions. The dev set is a subset of the training data we use to +check how well we are doing out-of-sample, after training the model on +the training dataset. We use the validation error as a proxy for the +test error in order to make tweaks to our model. It is crucial that we +do not use any of the test data to train the algorithm. This is a +cardinal sin in ML. Then:

    +
      +
    1. Estimate optimal error rate

    2. +
    3. Minimize underfitting (bias) on training data set.

    4. +
    5. Make sure you are not overfitting.

    6. +
    +
    +
    +

    More top-down perspectives

    +

    If the validation and test sets are drawn from the same distributions, +then a good performance on the validation set should lead to similarly +good performance on the test set.

    +

    However, sometimes +the training data and test data differ in subtle ways because, for +example, they are collected using slightly different methods, or +because it is cheaper to collect data in one way versus another. In +this case, there can be a mismatch between the training and test +data. This can lead to the neural network overfitting these small +differences between the test and training sets, and a poor performance +on the test set despite having a good performance on the validation +set. To rectify this, Andrew Ng suggests making two validation or dev +sets, one constructed from the training data and one constructed from +the test data. The difference between the performance of the algorithm +on these two validation sets quantifies the train-test mismatch. This +can serve as another important diagnostic when using DNNs for +supervised learning.

    +
    +
    +

    Limitations of supervised learning with deep networks

    +

    Like all statistical methods, supervised learning using neural +networks has important limitations. This is especially important when +one seeks to apply these methods, especially to physics problems. Like +all tools, DNNs are not a universal solution. Often, the same or +better performance on a task can be achieved by using a few +hand-engineered features (or even a collection of random +features).

    +
    +
    +

    Limitations of NNs

    +

    Here we list some of the important limitations of supervised neural network based models.

    +
      +
    • Need labeled data. All supervised learning methods, DNNs for supervised learning require labeled data. Often, labeled data is harder to acquire than unlabeled data (e.g. one must pay for human experts to label images).

    • +
    • Supervised neural networks are extremely data intensive. DNNs are data hungry. They perform best when data is plentiful. This is doubly so for supervised methods where the data must also be labeled. The utility of DNNs is extremely limited if data is hard to acquire or the datasets are small (hundreds to a few thousand samples). In this case, the performance of other methods that utilize hand-engineered features can exceed that of DNNs.

    • +
    +
    +
    +

    Homogeneous data

    +
      +
    • Homogeneous data. Almost all DNNs deal with homogeneous data of one type. It is very hard to design architectures that mix and match data types (i.e. some continuous variables, some discrete variables, some time series). In applications beyond images, video, and language, this is often what is required. In contrast, ensemble models like random forests or gradient-boosted trees have no difficulty handling mixed data types.

    • +
    +
    +
    +

    More limitations

    +
      +
    • Many problems are not about prediction. In natural science we are often interested in learning something about the underlying distribution that generates the data. In this case, it is often difficult to cast these ideas in a supervised learning setting. While the problems are related, it is possible to make good predictions with a wrong model. The model might or might not be useful for understanding the underlying science.

    • +
    +

    Some of these remarks are particular to DNNs, others are shared by all supervised learning methods. This motivates the use of unsupervised methods which in part circumvent these problems.

    +
    +
    +

    Setting up the back-propagation algorithm

    +

    Let us write this out in the form of an algorithm.

    +

    First, we set up the input data \(\boldsymbol{x}\) and the activations +\(\boldsymbol{z}_1\) of the input layer and compute the activation function and +the pertinent outputs \(\boldsymbol{a}^1\).

    +

    Secondly, we perform then the feed forward till we reach the output +layer and compute all \(\boldsymbol{z}_l\) of the input layer and compute the +activation function and the pertinent outputs \(\boldsymbol{a}^l\) for +\(l=2,3,\dots,L\).

    +

    Thereafter we compute the ouput error \(\boldsymbol{\delta}^L\) by computing all

    +
    +\[ +\delta_j^L = f'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}. +\]
    +

    Then we compute the back propagate error for each \(l=L-1,L-2,\dots,2\) as

    +
    +\[ +\delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l). +\]
    +

    Finally, we update the weights and the biases using gradient descent for each \(l=L-1,L-2,\dots,2\) and update the weights and biases according to the rules

    +
    +\[ +w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +\]
    +
    +\[ +b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +\]
    +

    The parameter \(\eta\) is the learning parameter discussed in connection with the gradient descent methods. +Here it is convenient to use stochastic gradient descent (see the examples below) with mini-batches with an outer loop that steps through multiple epochs of training.

    +
    +
    +

    Setting up a Multi-layer perceptron model for classification

    +

    We are now gong to develop an example based on the MNIST data +base. This is a classification problem and we need to use our +cross-entropy function we discussed in connection with logistic +regression. The cross-entropy defines our cost function for the +classificaton problems with neural networks.

    +

    In binary classification with two classes \((0, 1)\) we define the +logistic/sigmoid function as the probability that a particular input +is in class \(0\) or \(1\). This is possible because the logistic +function takes any input from the real numbers and inputs a number +between 0 and 1, and can therefore be interpreted as a probability. It +also has other nice properties, such as a derivative that is simple to +calculate.

    +

    For an input \(\boldsymbol{a}\) from the hidden layer, the probability that the input \(\boldsymbol{x}\) +is in class 0 or 1 is just. We let \(\theta\) represent the unknown weights and biases to be adjusted by our equations). The variable \(x\) +represents our activation values \(z\). We have

    +
    +\[ +P(y = 0 \mid \boldsymbol{x}, \boldsymbol{\theta}) = \frac{1}{1 + \exp{(- \boldsymbol{x}})} , +\]
    +

    and

    +
    +\[ +P(y = 1 \mid \boldsymbol{x}, \boldsymbol{\theta}) = 1 - P(y = 0 \mid \boldsymbol{x}, \boldsymbol{\theta}) , +\]
    +

    where \(y \in \{0, 1\}\) and \(\boldsymbol{\theta}\) represents the weights and biases +of our network.

    +
    +
    +

    Defining the cost function

    +

    Our cost function is given as (see the Logistic regression lectures)

    +
    +\[ +\mathcal{C}(\boldsymbol{\theta}) = - \ln P(\mathcal{D} \mid \boldsymbol{\theta}) = - \sum_{i=1}^n +y_i \ln[P(y_i = 0)] + (1 - y_i) \ln [1 - P(y_i = 0)] = \sum_{i=1}^n \mathcal{L}_i(\boldsymbol{\theta}) . +\]
    +

    This last equality means that we can interpret our cost function as a sum over the loss function +for each point in the dataset \(\mathcal{L}_i(\boldsymbol{\theta})\).
    +The negative sign is just so that we can think about our algorithm as minimizing a positive number, rather +than maximizing a negative number.

    +

    In multiclass classification it is common to treat each integer label as a so called one-hot vector:

    +

    \(y = 5 \quad \rightarrow \quad \boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,\) and

    +

    \(y = 1 \quad \rightarrow \quad \boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,\)

    +

    i.e. a binary bit string of length \(C\), where \(C = 10\) is the number of classes in the MNIST dataset (numbers from \(0\) to \(9\))..

    +

    If \(\boldsymbol{x}_i\) is the \(i\)-th input (image), \(y_{ic}\) refers to the \(c\)-th component of the \(i\)-th +output vector \(\boldsymbol{y}_i\).
    +The probability of \(\boldsymbol{x}_i\) being in class \(c\) will be given by the softmax function:

    +
    +\[ +P(y_{ic} = 1 \mid \boldsymbol{x}_i, \boldsymbol{\theta}) = \frac{\exp{((\boldsymbol{a}_i^{hidden})^T \boldsymbol{w}_c)}} +{\sum_{c'=0}^{C-1} \exp{((\boldsymbol{a}_i^{hidden})^T \boldsymbol{w}_{c'})}} , +\]
    +

    which reduces to the logistic function in the binary case.
    +The likelihood of this \(C\)-class classifier +is now given as:

    +
    +\[ +P(\mathcal{D} \mid \boldsymbol{\theta}) = \prod_{i=1}^n \prod_{c=0}^{C-1} [P(y_{ic} = 1)]^{y_{ic}} . +\]
    +

    Again we take the negative log-likelihood to define our cost function:

    +
    +\[ +\mathcal{C}(\boldsymbol{\theta}) = - \log{P(\mathcal{D} \mid \boldsymbol{\theta})}. +\]
    +

    See the logistic regression lectures for a full definition of the cost function.

    +

    The back propagation equations need now only a small change, namely the definition of a new cost function. We are thus ready to use the same equations as before!

    +
    +
    +

    Example: binary classification problem

    +

    As an example of the above, relevant for project 2 as well, let us consider a binary class. As discussed in our logistic regression lectures, we defined a cost function in terms of the parameters \(\beta\) as

    +
    +\[ +\mathcal{C}(\boldsymbol{\beta}) = - \sum_{i=1}^n \left(y_i\log{p(y_i \vert x_i,\boldsymbol{\beta})}+(1-y_i)\log{1-p(y_i \vert x_i,\boldsymbol{\beta})}\right), +\]
    +

    where we had defined the logistic (sigmoid) function

    +
    +\[ +p(y_i =1\vert x_i,\boldsymbol{\beta})=\frac{\exp{(\beta_0+\beta_1 x_i)}}{1+\exp{(\beta_0+\beta_1 x_i)}}, +\]
    +

    and

    +
    +\[ +p(y_i =0\vert x_i,\boldsymbol{\beta})=1-p(y_i =1\vert x_i,\boldsymbol{\beta}). +\]
    +

    The parameters \(\boldsymbol{\beta}\) were defined using a minimization method like gradient descent or Newton-Raphson’s method.

    +

    Now we replace \(x_i\) with the activation \(z_i^l\) for a given layer \(l\) and the outputs as \(y_i=a_i^l=f(z_i^l)\), with \(z_i^l\) now being a function of the weights \(w_{ij}^l\) and biases \(b_i^l\). +We have then

    +
    +\[ +a_i^l = y_i = \frac{\exp{(z_i^l)}}{1+\exp{(z_i^l)}}, +\]
    +

    with

    +
    +\[ +z_i^l = \sum_{j}w_{ij}^l a_j^{l-1}+b_i^l, +\]
    +

    where the superscript \(l-1\) indicates that these are the outputs from layer \(l-1\). +Our cost function at the final layer \(l=L\) is now

    +
    +\[ +\mathcal{C}(\boldsymbol{W}) = - \sum_{i=1}^n \left(t_i\log{a_i^L}+(1-t_i)\log{(1-a_i^L)}\right), +\]
    +

    where we have defined the targets \(t_i\). The derivatives of the cost function with respect to the output \(a_i^L\) are then easily calculated and we get

    +
    +\[ +\frac{\partial \mathcal{C}(\boldsymbol{W})}{\partial a_i^L} = \frac{a_i^L-t_i}{a_i^L(1-a_i^L)}. +\]
    +

    In case we use another activation function than the logistic one, we need to evaluate other derivatives.

    +
    +
    +

    The Softmax function

    +

    In case we employ the more general case given by the Softmax equation, we need to evaluate the derivative of the activation function with respect to the activation \(z_i^l\), that is we need

    +
    +\[ +\frac{\partial f(z_i^l)}{\partial w_{jk}^l} = +\frac{\partial f(z_i^l)}{\partial z_j^l} \frac{\partial z_j^l}{\partial w_{jk}^l}= \frac{\partial f(z_i^l)}{\partial z_j^l}a_k^{l-1}. +\]
    +

    For the Softmax function we have

    +
    +\[ +f(z_i^l) = \frac{\exp{(z_i^l)}}{\sum_{m=1}^K\exp{(z_m^l)}}. +\]
    +

    Its derivative with respect to \(z_j^l\) gives

    +
    +\[ +\frac{\partial f(z_i^l)}{\partial z_j^l}= f(z_i^l)\left(\delta_{ij}-f(z_j^l)\right), +\]
    +

    which in case of the simply binary model reduces to having \(i=j\).

    +
    +
    +

    Developing a code for doing neural networks with back propagation

    +

    One can identify a set of key steps when using neural networks to solve supervised learning problems:

    +
      +
    1. Collect and pre-process data

    2. +
    3. Define model and architecture

    4. +
    5. Choose cost function and optimizer

    6. +
    7. Train the model

    8. +
    9. Evaluate model performance on test data

    10. +
    11. Adjust hyperparameters (if necessary, network architecture)

    12. +
    +
    +
    +

    Collect and pre-process data

    +

    Here we will be using the MNIST dataset, which is readily available through the scikit-learn +package. You may also find it for example here.
    +The MNIST (Modified National Institute of Standards and Technology) database is a large database +of handwritten digits that is commonly used for training various image processing systems.
    +The MNIST dataset consists of 70 000 images of size \(28\times 28\) pixels, each labeled from 0 to 9.
    +The scikit-learn dataset we will use consists of a selection of 1797 images of size \(8\times 8\) collected and processed from this database.

    +

    To feed data into a feed-forward neural network we need to represent +the inputs as a design/feature matrix \(X = (n_{inputs}, n_{features})\). Each +row represents an input, in this case a handwritten digit, and +each column represents a feature, in this case a pixel. The +correct answers, also known as labels or targets are +represented as a 1D array of integers +\(Y = (n_{inputs}) = (5, 3, 1, 8,...)\).

    +

    As an example, say we want to build a neural network using supervised learning to predict Body-Mass Index (BMI) from +measurements of height (in m)
    +and weight (in kg). If we have measurements of 5 people the design/feature matrix could be for example:

    +
    +\[\begin{split} X = \begin{bmatrix} +1.85 & 81\\ +1.71 & 65\\ +1.95 & 103\\ +1.55 & 42\\ +1.63 & 56 +\end{bmatrix} ,\end{split}\]
    +

    and the targets would be:

    +
    +\[ Y = (23.7, 22.2, 27.1, 17.5, 21.1) \]
    +

    Since each input image is a 2D matrix, we need to flatten the image +(i.e. “unravel” the 2D matrix into a 1D array) to turn the data into a +design/feature matrix. This means we lose all spatial information in the +image, such as locality and translational invariance. More complicated +architectures such as Convolutional Neural Networks can take advantage +of such information, and are most commonly applied when analyzing +images.

    +
    +
    +
    # import necessary packages
    +import numpy as np
    +import matplotlib.pyplot as plt
    +from sklearn import datasets
    +
    +
    +# ensure the same random numbers appear every time
    +np.random.seed(0)
    +
    +# display images in notebook
    +%matplotlib inline
    +plt.rcParams['figure.figsize'] = (12,12)
    +
    +
    +# download MNIST dataset
    +digits = datasets.load_digits()
    +
    +# define inputs and labels
    +inputs = digits.images
    +labels = digits.target
    +
    +print("inputs = (n_inputs, pixel_width, pixel_height) = " + str(inputs.shape))
    +print("labels = (n_inputs) = " + str(labels.shape))
    +
    +
    +# flatten the image
    +# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64
    +n_inputs = len(inputs)
    +inputs = inputs.reshape(n_inputs, -1)
    +print("X = (n_inputs, n_features) = " + str(inputs.shape))
    +
    +
    +# choose some random images to display
    +indices = np.arange(n_inputs)
    +random_indices = np.random.choice(indices, size=5)
    +
    +for i, image in enumerate(digits.images[random_indices]):
    +    plt.subplot(1, 5, i+1)
    +    plt.axis('off')
    +    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')
    +    plt.title("Label: %d" % digits.target[random_indices[i]])
    +plt.show()
    +
    +
    +
    +
    +
    inputs = (n_inputs, pixel_width, pixel_height) = (1797, 8, 8)
    +labels = (n_inputs) = (1797,)
    +X = (n_inputs, n_features) = (1797, 64)
    +
    +
    +_images/week42_242_1.png +
    +
    +
    +
    +

    Train and test datasets

    +

    Performing analysis before partitioning the dataset is a major error, that can lead to incorrect conclusions.

    +

    We will reserve \(80 \%\) of our dataset for training and \(20 \%\) for testing.

    +

    It is important that the train and test datasets are drawn randomly from our dataset, to ensure +no bias in the sampling.
    +Say you are taking measurements of weather data to predict the weather in the coming 5 days. +You don’t want to train your model on measurements taken from the hours 00.00 to 12.00, and then test it on data +collected from 12.00 to 24.00.

    +
    +
    +
    from sklearn.model_selection import train_test_split
    +
    +# one-liner from scikit-learn library
    +train_size = 0.8
    +test_size = 1 - train_size
    +X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,
    +                                                    test_size=test_size)
    +
    +# equivalently in numpy
    +def train_test_split_numpy(inputs, labels, train_size, test_size):
    +    n_inputs = len(inputs)
    +    inputs_shuffled = inputs.copy()
    +    labels_shuffled = labels.copy()
    +    
    +    np.random.shuffle(inputs_shuffled)
    +    np.random.shuffle(labels_shuffled)
    +    
    +    train_end = int(n_inputs*train_size)
    +    X_train, X_test = inputs_shuffled[:train_end], inputs_shuffled[train_end:]
    +    Y_train, Y_test = labels_shuffled[:train_end], labels_shuffled[train_end:]
    +    
    +    return X_train, X_test, Y_train, Y_test
    +
    +#X_train, X_test, Y_train, Y_test = train_test_split_numpy(inputs, labels, train_size, test_size)
    +
    +print("Number of training images: " + str(len(X_train)))
    +print("Number of test images: " + str(len(X_test)))
    +
    +
    +
    +
    +
    Number of training images: 1437
    +Number of test images: 360
    +
    +
    +
    +
    +
    +
    +

    Define model and architecture

    +

    Our simple feed-forward neural network will consist of an input layer, a single hidden layer and an output layer. The activation \(y\) of each neuron is a weighted sum of inputs, passed through an activation function. In case of the simple perceptron model we have

    +
    +\[ z = \sum_{i=1}^n w_i a_i ,\]
    +
    +\[ y = f(z) ,\]
    +

    where \(f\) is the activation function, \(a_i\) represents input from neuron \(i\) in the preceding layer +and \(w_i\) is the weight to input \(i\).
    +The activation of the neurons in the input layer is just the features (e.g. a pixel value).

    +

    The simplest activation function for a neuron is the Heaviside function:

    +
    +\[\begin{split} f(z) = +\begin{cases} +1, & z > 0\\ +0, & \text{otherwise} +\end{cases} +\end{split}\]
    +

    A feed-forward neural network with this activation is known as a perceptron.
    +For a binary classifier (i.e. two classes, 0 or 1, dog or not-dog) we can also use this in our output layer.
    +This activation can be generalized to \(k\) classes (using e.g. the one-against-all strategy), +and we call these architectures multiclass perceptrons.

    +

    However, it is now common to use the terms Single Layer Perceptron (SLP) (1 hidden layer) and
    +Multilayer Perceptron (MLP) (2 or more hidden layers) to refer to feed-forward neural networks with any activation function.

    +

    Typical choices for activation functions include the sigmoid function, hyperbolic tangent, and Rectified Linear Unit (ReLU).
    +We will be using the sigmoid function \(\sigma(x)\):

    +
    +\[ f(x) = \sigma(x) = \frac{1}{1 + e^{-x}} ,\]
    +

    which is inspired by probability theory (see logistic regression) and was most commonly used until about 2011. See the discussion below concerning other activation functions.

    +
    +
    +

    Layers

    +
      +
    • Input

    • +
    +

    Since each input image has 8x8 = 64 pixels or features, we have an input layer of 64 neurons.

    +
      +
    • Hidden layer

    • +
    +

    We will use 50 neurons in the hidden layer receiving input from the neurons in the input layer.
    +Since each neuron in the hidden layer is connected to the 64 inputs we have 64x50 = 3200 weights to the hidden layer.

    +
      +
    • Output

    • +
    +

    If we were building a binary classifier, it would be sufficient with a single neuron in the output layer, +which could output 0 or 1 according to the Heaviside function. This would be an example of a hard classifier, meaning it outputs the class of the input directly. However, if we are dealing with noisy data it is often beneficial to use a soft classifier, which outputs the probability of being in class 0 or 1.

    +

    For a soft binary classifier, we could use a single neuron and interpret the output as either being the probability of being in class 0 or the probability of being in class 1. Alternatively we could use 2 neurons, and interpret each neuron as the probability of being in each class.

    +

    Since we are doing multiclass classification, with 10 categories, it is natural to use 10 neurons in the output layer. We number the neurons \(j = 0,1,...,9\). The activation of each output neuron \(j\) will be according to the softmax function:

    +
    +\[ P(\text{class $j$} \mid \text{input $\boldsymbol{a}$}) = \frac{\exp{(\boldsymbol{a}^T \boldsymbol{w}_j)}} +{\sum_{c=0}^{9} \exp{(\boldsymbol{a}^T \boldsymbol{w}_c)}} ,\]
    +

    i.e. each neuron \(j\) outputs the probability of being in class \(j\) given an input from the hidden layer \(\boldsymbol{a}\), with \(\boldsymbol{w}_j\) the weights of neuron \(j\) to the inputs.
    +The denominator is a normalization factor to ensure the outputs (probabilities) sum up to 1.
    +The exponent is just the weighted sum of inputs as before:

    +
    +\[ z_j = \sum_{i=1}^n w_ {ij} a_i+b_j.\]
    +

    Since each neuron in the output layer is connected to the 50 inputs from the hidden layer we have 50x10 = 500 +weights to the output layer.

    +
    +
    +

    Weights and biases

    +

    Typically weights are initialized with small values distributed around zero, drawn from a uniform +or normal distribution. Setting all weights to zero means all neurons give the same output, making the network useless.

    +

    Adding a bias value to the weighted sum of inputs allows the neural network to represent a greater range +of values. Without it, any input with the value 0 will be mapped to zero (before being passed through the activation). The bias unit has an output of 1, and a weight to each neuron \(j\), \(b_j\):

    +
    +\[ z_j = \sum_{i=1}^n w_ {ij} a_i + b_j.\]
    +

    The bias weights \(\boldsymbol{b}\) are often initialized to zero, but a small value like \(0.01\) ensures all neurons have some output which can be backpropagated in the first training cycle.

    +
    +
    +
    # building our neural network
    +
    +n_inputs, n_features = X_train.shape
    +n_hidden_neurons = 50
    +n_categories = 10
    +
    +# we make the weights normally distributed using numpy.random.randn
    +
    +# weights and bias in the hidden layer
    +hidden_weights = np.random.randn(n_features, n_hidden_neurons)
    +hidden_bias = np.zeros(n_hidden_neurons) + 0.01
    +
    +# weights and bias in the output layer
    +output_weights = np.random.randn(n_hidden_neurons, n_categories)
    +output_bias = np.zeros(n_categories) + 0.01
    +
    +
    +
    +
    +
    +
    +

    Feed-forward pass

    +

    Denote \(F\) the number of features, \(H\) the number of hidden neurons and \(C\) the number of categories.
    +For each input image we calculate a weighted sum of input features (pixel values) to each neuron \(j\) in the hidden layer \(l\):

    +
    +\[ z_{j}^{l} = \sum_{i=1}^{F} w_{ij}^{l} x_i + b_{j}^{l},\]
    +

    this is then passed through our activation function

    +
    +\[ a_{j}^{l} = f(z_{j}^{l}) .\]
    +

    We calculate a weighted sum of inputs (activations in the hidden layer) to each neuron \(j\) in the output layer:

    +
    +\[ z_{j}^{L} = \sum_{i=1}^{H} w_{ij}^{L} a_{i}^{l} + b_{j}^{L}.\]
    +

    Finally we calculate the output of neuron \(j\) in the output layer using the softmax function:

    +
    +\[ a_{j}^{L} = \frac{\exp{(z_j^{L})}} +{\sum_{c=0}^{C-1} \exp{(z_c^{L})}} .\]
    +
    +
    +

    Matrix multiplications

    +

    Since our data has the dimensions \(X = (n_{inputs}, n_{features})\) and our weights to the hidden +layer have the dimensions
    +\(W_{hidden} = (n_{features}, n_{hidden})\), +we can easily feed the network all our training data in one go by taking the matrix product

    +
    +\[ X W^{h} = (n_{inputs}, n_{hidden}),\]
    +

    and obtain a matrix that holds the weighted sum of inputs to the hidden layer +for each input image and each hidden neuron.
    +We also add the bias to obtain a matrix of weighted sums to the hidden layer \(Z^{h}\):

    +
    +\[ \boldsymbol{z}^{l} = \boldsymbol{X} \boldsymbol{W}^{l} + \boldsymbol{b}^{l} ,\]
    +

    meaning the same bias (1D array with size equal number of hidden neurons) is added to each input image.
    +This is then passed through the activation:

    +
    +\[ \boldsymbol{a}^{l} = f(\boldsymbol{z}^l) .\]
    +

    This is fed to the output layer:

    +
    +\[ \boldsymbol{z}^{L} = \boldsymbol{a}^{L} \boldsymbol{W}^{L} + \boldsymbol{b}^{L} .\]
    +

    Finally we receive our output values for each image and each category by passing it through the softmax function:

    +
    +\[ output = softmax (\boldsymbol{z}^{L}) = (n_{inputs}, n_{categories}) .\]
    +
    +
    +
    # setup the feed-forward pass, subscript h = hidden layer
    +
    +def sigmoid(x):
    +    return 1/(1 + np.exp(-x))
    +
    +def feed_forward(X):
    +    # weighted sum of inputs to the hidden layer
    +    z_h = np.matmul(X, hidden_weights) + hidden_bias
    +    # activation in the hidden layer
    +    a_h = sigmoid(z_h)
    +    
    +    # weighted sum of inputs to the output layer
    +    z_o = np.matmul(a_h, output_weights) + output_bias
    +    # softmax output
    +    # axis 0 holds each input and axis 1 the probabilities of each category
    +    exp_term = np.exp(z_o)
    +    probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)
    +    
    +    return probabilities
    +
    +probabilities = feed_forward(X_train)
    +print("probabilities = (n_inputs, n_categories) = " + str(probabilities.shape))
    +print("probability that image 0 is in category 0,1,2,...,9 = \n" + str(probabilities[0]))
    +print("probabilities sum up to: " + str(probabilities[0].sum()))
    +print()
    +
    +# we obtain a prediction by taking the class with the highest likelihood
    +def predict(X):
    +    probabilities = feed_forward(X)
    +    return np.argmax(probabilities, axis=1)
    +
    +predictions = predict(X_train)
    +print("predictions = (n_inputs) = " + str(predictions.shape))
    +print("prediction for image 0: " + str(predictions[0]))
    +print("correct label for image 0: " + str(Y_train[0]))
    +
    +
    +
    +
    +
    probabilities = (n_inputs, n_categories) = (1437, 10)
    +probability that image 0 is in category 0,1,2,...,9 = 
    +[5.41511965e-04 2.17174962e-03 8.84355903e-03 1.44970586e-03
    + 1.10378326e-04 5.08318298e-09 2.03256632e-04 1.92507116e-03
    + 9.84443254e-01 3.11507992e-04]
    +probabilities sum up to: 1.0
    +
    +predictions = (n_inputs) = (1437,)
    +prediction for image 0: 8
    +correct label for image 0: 6
    +
    +
    +
    +
    +
    +
    +

    Choose cost function and optimizer

    +

    To measure how well our neural network is doing we need to introduce a cost function.
    +We will call the function that gives the error of a single sample output the loss function, and the function +that gives the total error of our network across all samples the cost function. +A typical choice for multiclass classification is the cross-entropy loss, also known as the negative log likelihood.

    +

    In multiclass classification it is common to treat each integer label as a so called one-hot vector:

    +
    +\[ y = 5 \quad \rightarrow \quad \boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,\]
    +
    +\[ y = 1 \quad \rightarrow \quad \boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,\]
    +

    i.e. a binary bit string of length \(C\), where \(C = 10\) is the number of classes in the MNIST dataset.

    +

    Let \(y_{ic}\) denote the \(c\)-th component of the \(i\)-th one-hot vector.
    +We define the cost function \(\mathcal{C}\) as a sum over the cross-entropy loss for each point \(\boldsymbol{x}_i\) in the dataset.

    +

    In the one-hot representation only one of the terms in the loss function is non-zero, namely the +probability of the correct category \(c'\)
    +(i.e. the category \(c'\) such that \(y_{ic'} = 1\)). This means that the cross entropy loss only punishes you for how wrong +you got the correct label. The probability of category \(c\) is given by the softmax function. The vector \(\boldsymbol{\theta}\) represents the parameters of our network, i.e. all the weights and biases.

    +
    +
    +

    Optimizing the cost function

    +

    The network is trained by finding the weights and biases that minimize the cost function. One of the most widely used classes of methods is gradient descent and its generalizations. The idea behind gradient descent +is simply to adjust the weights in the direction where the gradient of the cost function is large and negative. This ensures we flow toward a local minimum of the cost function.
    +Each parameter \(\theta\) is iteratively adjusted according to the rule

    +
    +\[ \theta_{i+1} = \theta_i - \eta \nabla \mathcal{C}(\theta_i) ,\]
    +

    where \(\eta\) is known as the learning rate, which controls how big a step we take towards the minimum.
    +This update can be repeated for any number of iterations, or until we are satisfied with the result.

    +

    A simple and effective improvement is a variant called Batch Gradient Descent.
    +Instead of calculating the gradient on the whole dataset, we calculate an approximation of the gradient +on a subset of the data called a minibatch.
    +If there are \(N\) data points and we have a minibatch size of \(M\), the total number of batches +is \(N/M\).
    +We denote each minibatch \(B_k\), with \(k = 1, 2,...,N/M\). The gradient then becomes:

    +
    +\[ \nabla \mathcal{C}(\theta) = \frac{1}{N} \sum_{i=1}^N \nabla \mathcal{L}_i(\theta) \quad \rightarrow \quad +\frac{1}{M} \sum_{i \in B_k} \nabla \mathcal{L}_i(\theta) ,\]
    +

    i.e. instead of averaging the loss over the entire dataset, we average over a minibatch.

    +

    This has two important benefits:

    +
      +
    1. Introducing stochasticity decreases the chance that the algorithm becomes stuck in a local minima.

    2. +
    3. It significantly speeds up the calculation, since we do not have to use the entire dataset to calculate the gradient.

    4. +
    +

    The various optmization methods, with codes and algorithms, are discussed in our lectures on Gradient descent approaches.

    +
    +
    +

    Regularization

    +

    It is common to add an extra term to the cost function, proportional +to the size of the weights. This is equivalent to constraining the +size of the weights, so that they do not grow out of control. +Constraining the size of the weights means that the weights cannot +grow arbitrarily large to fit the training data, and in this way +reduces overfitting.

    +

    We will measure the size of the weights using the so called L2-norm, meaning our cost function becomes:

    +
    +\[ \mathcal{C}(\theta) = \frac{1}{N} \sum_{i=1}^N \mathcal{L}_i(\theta) \quad \rightarrow \quad +\frac{1}{N} \sum_{i=1}^N \mathcal{L}_i(\theta) + \lambda \lvert \lvert \boldsymbol{w} \rvert \rvert_2^2 += \frac{1}{N} \sum_{i=1}^N \mathcal{L}(\theta) + \lambda \sum_{ij} w_{ij}^2,\]
    +

    i.e. we sum up all the weights squared. The factor \(\lambda\) is known as a regularization parameter.

    +

    In order to train the model, we need to calculate the derivative of +the cost function with respect to every bias and weight in the +network. In total our network has \((64 + 1)\times 50=3250\) weights in +the hidden layer and \((50 + 1)\times 10=510\) weights to the output +layer (\(+1\) for the bias), and the gradient must be calculated for +every parameter. We use the backpropagation algorithm discussed +above. This is a clever use of the chain rule that allows us to +calculate the gradient efficently.

    +
    +
    +

    Matrix multiplication

    +

    To more efficently train our network these equations are implemented using matrix operations.
    +The error in the output layer is calculated simply as, with \(\boldsymbol{t}\) being our targets,

    +
    +\[ \delta_L = \boldsymbol{t} - \boldsymbol{y} = (n_{inputs}, n_{categories}) .\]
    +

    The gradient for the output weights is calculated as

    +
    +\[ \nabla W_{L} = \boldsymbol{a}^T \delta_L = (n_{hidden}, n_{categories}) ,\]
    +

    where \(\boldsymbol{a} = (n_{inputs}, n_{hidden})\). This simply means that we are summing up the gradients for each input.
    +Since we are going backwards we have to transpose the activation matrix.

    +

    The gradient with respect to the output bias is then

    +
    +\[ \nabla \boldsymbol{b}_{L} = \sum_{i=1}^{n_{inputs}} \delta_L = (n_{categories}) .\]
    +

    The error in the hidden layer is

    +
    +\[ \Delta_h = \delta_L W_{L}^T \circ f'(z_{h}) = \delta_L W_{L}^T \circ a_{h} \circ (1 - a_{h}) = (n_{inputs}, n_{hidden}) ,\]
    +

    where \(f'(a_{h})\) is the derivative of the activation in the hidden layer. The matrix products mean +that we are summing up the products for each neuron in the output layer. The symbol \(\circ\) denotes +the Hadamard product, meaning element-wise multiplication.

    +

    This again gives us the gradients in the hidden layer:

    +
    +\[ \nabla W_{h} = X^T \delta_h = (n_{features}, n_{hidden}) ,\]
    +
    +\[ \nabla b_{h} = \sum_{i=1}^{n_{inputs}} \delta_h = (n_{hidden}) .\]
    +
    +
    +
    # to categorical turns our integer vector into a onehot representation
    +from sklearn.metrics import accuracy_score
    +
    +# one-hot in numpy
    +def to_categorical_numpy(integer_vector):
    +    n_inputs = len(integer_vector)
    +    n_categories = np.max(integer_vector) + 1
    +    onehot_vector = np.zeros((n_inputs, n_categories))
    +    onehot_vector[range(n_inputs), integer_vector] = 1
    +    
    +    return onehot_vector
    +
    +#Y_train_onehot, Y_test_onehot = to_categorical(Y_train), to_categorical(Y_test)
    +Y_train_onehot, Y_test_onehot = to_categorical_numpy(Y_train), to_categorical_numpy(Y_test)
    +
    +def feed_forward_train(X):
    +    # weighted sum of inputs to the hidden layer
    +    z_h = np.matmul(X, hidden_weights) + hidden_bias
    +    # activation in the hidden layer
    +    a_h = sigmoid(z_h)
    +    
    +    # weighted sum of inputs to the output layer
    +    z_o = np.matmul(a_h, output_weights) + output_bias
    +    # softmax output
    +    # axis 0 holds each input and axis 1 the probabilities of each category
    +    exp_term = np.exp(z_o)
    +    probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)
    +    
    +    # for backpropagation need activations in hidden and output layers
    +    return a_h, probabilities
    +
    +def backpropagation(X, Y):
    +    a_h, probabilities = feed_forward_train(X)
    +    
    +    # error in the output layer
    +    error_output = probabilities - Y
    +    # error in the hidden layer
    +    error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h)
    +    
    +    # gradients for the output layer
    +    output_weights_gradient = np.matmul(a_h.T, error_output)
    +    output_bias_gradient = np.sum(error_output, axis=0)
    +    
    +    # gradient for the hidden layer
    +    hidden_weights_gradient = np.matmul(X.T, error_hidden)
    +    hidden_bias_gradient = np.sum(error_hidden, axis=0)
    +
    +    return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient
    +
    +print("Old accuracy on training data: " + str(accuracy_score(predict(X_train), Y_train)))
    +
    +eta = 0.01
    +lmbd = 0.01
    +for i in range(1000):
    +    # calculate gradients
    +    dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot)
    +    
    +    # regularization term gradients
    +    dWo += lmbd * output_weights
    +    dWh += lmbd * hidden_weights
    +    
    +    # update weights and biases
    +    output_weights -= eta * dWo
    +    output_bias -= eta * dBo
    +    hidden_weights -= eta * dWh
    +    hidden_bias -= eta * dBh
    +
    +print("New accuracy on training data: " + str(accuracy_score(predict(X_train), Y_train)))
    +
    +
    +
    +
    +
    Old accuracy on training data: 0.1440501043841336
    +
    +
    +
    /var/folders/td/3yk470mj5p931p9dtkk0y6jw0000gn/T/ipykernel_47048/953065564.py:4: RuntimeWarning: overflow encountered in exp
    +  return 1/(1 + np.exp(-x))
    +
    +
    +
    ---------------------------------------------------------------------------
    +KeyboardInterrupt                         Traceback (most recent call last)
    +Cell In[7], line 56
    +     53 lmbd = 0.01
    +     54 for i in range(1000):
    +     55     # calculate gradients
    +---> 56     dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot)
    +     58     # regularization term gradients
    +     59     dWo += lmbd * output_weights
    +
    +Cell In[7], line 38, in backpropagation(X, Y)
    +     36 error_output = probabilities - Y
    +     37 # error in the hidden layer
    +---> 38 error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h)
    +     40 # gradients for the output layer
    +     41 output_weights_gradient = np.matmul(a_h.T, error_output)
    +
    +KeyboardInterrupt: 
    +
    +
    +
    +
    +
    +
    +

    Improving performance

    +

    As we can see the network does not seem to be learning at all. It seems to be just guessing the label for each image.
    +In order to obtain a network that does something useful, we will have to do a bit more work.

    +

    The choice of hyperparameters such as learning rate and regularization parameter is hugely influential for the performance of the network. Typically a grid-search is performed, wherein we test different hyperparameters separated by orders of magnitude. For example we could test the learning rates \(\eta = 10^{-6}, 10^{-5},...,10^{-1}\) with different regularization parameters \(\lambda = 10^{-6},...,10^{-0}\).

    +

    Next, we haven’t implemented minibatching yet, which introduces stochasticity and is though to act as an important regularizer on the weights. We call a feed-forward + backward pass with a minibatch an iteration, and a full training period +going through the entire dataset (\(n/M\) batches) an epoch.

    +

    If this does not improve network performance, you may want to consider altering the network architecture, adding more neurons or hidden layers.
    +Andrew Ng goes through some of these considerations in this video. You can find a summary of the video here.

    +
    +
    +

    Full object-oriented implementation

    +

    It is very natural to think of the network as an object, with specific instances of the network +being realizations of this object with different hyperparameters. An implementation using Python classes provides a clean structure and interface, and the full implementation of our neural network is given below.

    +
    +
    +
    class NeuralNetwork:
    +    def __init__(
    +            self,
    +            X_data,
    +            Y_data,
    +            n_hidden_neurons=50,
    +            n_categories=10,
    +            epochs=10,
    +            batch_size=100,
    +            eta=0.1,
    +            lmbd=0.0):
    +
    +        self.X_data_full = X_data
    +        self.Y_data_full = Y_data
    +
    +        self.n_inputs = X_data.shape[0]
    +        self.n_features = X_data.shape[1]
    +        self.n_hidden_neurons = n_hidden_neurons
    +        self.n_categories = n_categories
    +
    +        self.epochs = epochs
    +        self.batch_size = batch_size
    +        self.iterations = self.n_inputs // self.batch_size
    +        self.eta = eta
    +        self.lmbd = lmbd
    +
    +        self.create_biases_and_weights()
    +
    +    def create_biases_and_weights(self):
    +        self.hidden_weights = np.random.randn(self.n_features, self.n_hidden_neurons)
    +        self.hidden_bias = np.zeros(self.n_hidden_neurons) + 0.01
    +
    +        self.output_weights = np.random.randn(self.n_hidden_neurons, self.n_categories)
    +        self.output_bias = np.zeros(self.n_categories) + 0.01
    +
    +    def feed_forward(self):
    +        # feed-forward for training
    +        self.z_h = np.matmul(self.X_data, self.hidden_weights) + self.hidden_bias
    +        self.a_h = sigmoid(self.z_h)
    +
    +        self.z_o = np.matmul(self.a_h, self.output_weights) + self.output_bias
    +
    +        exp_term = np.exp(self.z_o)
    +        self.probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)
    +
    +    def feed_forward_out(self, X):
    +        # feed-forward for output
    +        z_h = np.matmul(X, self.hidden_weights) + self.hidden_bias
    +        a_h = sigmoid(z_h)
    +
    +        z_o = np.matmul(a_h, self.output_weights) + self.output_bias
    +        
    +        exp_term = np.exp(z_o)
    +        probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)
    +        return probabilities
    +
    +    def backpropagation(self):
    +        error_output = self.probabilities - self.Y_data
    +        error_hidden = np.matmul(error_output, self.output_weights.T) * self.a_h * (1 - self.a_h)
    +
    +        self.output_weights_gradient = np.matmul(self.a_h.T, error_output)
    +        self.output_bias_gradient = np.sum(error_output, axis=0)
    +
    +        self.hidden_weights_gradient = np.matmul(self.X_data.T, error_hidden)
    +        self.hidden_bias_gradient = np.sum(error_hidden, axis=0)
    +
    +        if self.lmbd > 0.0:
    +            self.output_weights_gradient += self.lmbd * self.output_weights
    +            self.hidden_weights_gradient += self.lmbd * self.hidden_weights
    +
    +        self.output_weights -= self.eta * self.output_weights_gradient
    +        self.output_bias -= self.eta * self.output_bias_gradient
    +        self.hidden_weights -= self.eta * self.hidden_weights_gradient
    +        self.hidden_bias -= self.eta * self.hidden_bias_gradient
    +
    +    def predict(self, X):
    +        probabilities = self.feed_forward_out(X)
    +        return np.argmax(probabilities, axis=1)
    +
    +    def predict_probabilities(self, X):
    +        probabilities = self.feed_forward_out(X)
    +        return probabilities
    +
    +    def train(self):
    +        data_indices = np.arange(self.n_inputs)
    +
    +        for i in range(self.epochs):
    +            for j in range(self.iterations):
    +                # pick datapoints with replacement
    +                chosen_datapoints = np.random.choice(
    +                    data_indices, size=self.batch_size, replace=False
    +                )
    +
    +                # minibatch training data
    +                self.X_data = self.X_data_full[chosen_datapoints]
    +                self.Y_data = self.Y_data_full[chosen_datapoints]
    +
    +                self.feed_forward()
    +                self.backpropagation()
    +
    +
    +
    +
    +
    +
    +

    Evaluate model performance on test data

    +

    To measure the performance of our network we evaluate how well it does it data it has never seen before, i.e. the test data.
    +We measure the performance of the network using the accuracy score.
    +The accuracy is as you would expect just the number of images correctly labeled divided by the total number of images. A perfect classifier will have an accuracy score of \(1\).

    +
    +\[ \text{Accuracy} = \frac{\sum_{i=1}^n I(\tilde{y}_i = y_i)}{n} ,\]
    +

    where \(I\) is the indicator function, \(1\) if \(\tilde{y}_i = y_i\) and \(0\) otherwise.

    +
    +
    +
    epochs = 100
    +batch_size = 100
    +
    +dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,
    +                    n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)
    +dnn.train()
    +test_predict = dnn.predict(X_test)
    +
    +# accuracy score from scikit library
    +print("Accuracy score on test set: ", accuracy_score(Y_test, test_predict))
    +
    +# equivalent in numpy
    +def accuracy_score_numpy(Y_test, Y_pred):
    +    return np.sum(Y_test == Y_pred) / len(Y_test)
    +
    +#print("Accuracy score on test set: ", accuracy_score_numpy(Y_test, test_predict))
    +
    +
    +
    +
    +
    +
    +

    Adjust hyperparameters

    +

    We now perform a grid search to find the optimal hyperparameters for the network.
    +Note that we are only using 1 layer with 50 neurons, and human performance is estimated to be around \(98\%\) (\(2\%\) error rate).

    +
    +
    +
    eta_vals = np.logspace(-5, 1, 7)
    +lmbd_vals = np.logspace(-5, 1, 7)
    +# store the models for later use
    +DNN_numpy = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)
    +
    +# grid search
    +for i, eta in enumerate(eta_vals):
    +    for j, lmbd in enumerate(lmbd_vals):
    +        dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,
    +                            n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)
    +        dnn.train()
    +        
    +        DNN_numpy[i][j] = dnn
    +        
    +        test_predict = dnn.predict(X_test)
    +        
    +        print("Learning rate  = ", eta)
    +        print("Lambda = ", lmbd)
    +        print("Accuracy score on test set: ", accuracy_score(Y_test, test_predict))
    +        print()
    +
    +
    +
    +
    +
    +
    +

    Visualization

    +
    +
    +
    # visual representation of grid search
    +# uses seaborn heatmap, you can also do this with matplotlib imshow
    +import seaborn as sns
    +
    +sns.set()
    +
    +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +
    +for i in range(len(eta_vals)):
    +    for j in range(len(lmbd_vals)):
    +        dnn = DNN_numpy[i][j]
    +        
    +        train_pred = dnn.predict(X_train) 
    +        test_pred = dnn.predict(X_test)
    +
    +        train_accuracy[i][j] = accuracy_score(Y_train, train_pred)
    +        test_accuracy[i][j] = accuracy_score(Y_test, test_pred)
    +
    +        
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Training Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Test Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +
    +
    +
    +
    +
    +

    scikit-learn implementation

    +

    scikit-learn focuses more +on traditional machine learning methods, such as regression, +clustering, decision trees, etc. As such, it has only two types of +neural networks: Multi Layer Perceptron outputting continuous values, +MPLRegressor, and Multi Layer Perceptron outputting labels, +MLPClassifier. We will see how simple it is to use these classes.

    +

    scikit-learn implements a few improvements from our neural network, +such as early stopping, a varying learning rate, different +optimization methods, etc. We would therefore expect a better +performance overall.

    +
    +
    +
    from sklearn.neural_network import MLPClassifier
    +# store models for later use
    +DNN_scikit = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)
    +
    +for i, eta in enumerate(eta_vals):
    +    for j, lmbd in enumerate(lmbd_vals):
    +        dnn = MLPClassifier(hidden_layer_sizes=(n_hidden_neurons), activation='logistic',
    +                            alpha=lmbd, learning_rate_init=eta, max_iter=epochs)
    +        dnn.fit(X_train, Y_train)
    +        
    +        DNN_scikit[i][j] = dnn
    +        
    +        print("Learning rate  = ", eta)
    +        print("Lambda = ", lmbd)
    +        print("Accuracy score on test set: ", dnn.score(X_test, Y_test))
    +        print()
    +
    +
    +
    +
    +
    +
    +

    Visualization

    +
    +
    +
    # optional
    +# visual representation of grid search
    +# uses seaborn heatmap, could probably do this in matplotlib
    +import seaborn as sns
    +
    +sns.set()
    +
    +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +
    +for i in range(len(eta_vals)):
    +    for j in range(len(lmbd_vals)):
    +        dnn = DNN_scikit[i][j]
    +        
    +        train_pred = dnn.predict(X_train) 
    +        test_pred = dnn.predict(X_test)
    +
    +        train_accuracy[i][j] = accuracy_score(Y_train, train_pred)
    +        test_accuracy[i][j] = accuracy_score(Y_test, test_pred)
    +
    +        
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Training Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Test Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +
    +
    +
    +
    +
    +

    Building neural networks in Tensorflow and Keras

    +

    Now we want to build on the experience gained from our neural network implementation in NumPy and scikit-learn +and use it to construct a neural network in Tensorflow. Once we have constructed a neural network in NumPy +and Tensorflow, building one in Keras is really quite trivial, though the performance may suffer.

    +

    In our previous example we used only one hidden layer, and in this we will use two. From this it should be quite +clear how to build one using an arbitrary number of hidden layers, using data structures such as Python lists or +NumPy arrays.

    +
    +
    +

    Tensorflow

    +

    Tensorflow is an open source library machine learning library +developed by the Google Brain team for internal use. It was released +under the Apache 2.0 open source license in November 9, 2015.

    +

    Tensorflow is a computational framework that allows you to construct +machine learning models at different levels of abstraction, from +high-level, object-oriented APIs like Keras, down to the C++ kernels +that Tensorflow is built upon. The higher levels of abstraction are +simpler to use, but less flexible, and our choice of implementation +should reflect the problems we are trying to solve.

    +

    Tensorflow uses so-called graphs to represent your computation +in terms of the dependencies between individual operations, such that you first build a Tensorflow graph +to represent your model, and then create a Tensorflow session to run the graph.

    +

    In this guide we will analyze the same data as we did in our NumPy and +scikit-learn tutorial, gathered from the MNIST database of images. We +will give an introduction to the lower level Python Application +Program Interfaces (APIs), and see how we use them to build our graph. +Then we will build (effectively) the same graph in Keras, to see just +how simple solving a machine learning problem can be.

    +

    To install tensorflow on Unix/Linux systems, use pip as

    +
    +
    +
    pip3 install tensorflow
    +
    +
    +
    +
    +

    and/or if you use anaconda, just write (or install from the graphical user interface) +(current release of CPU-only TensorFlow)

    +
    +
    +
    conda create -n tf tensorflow
    +conda activate tf
    +
    +
    +
    +
    +

    To install the current release of GPU TensorFlow

    +
    +
    +
    conda create -n tf-gpu tensorflow-gpu
    +conda activate tf-gpu
    +
    +
    +
    +
    +
    +
    +

    Using Keras

    +

    Keras is a high level neural network +that supports Tensorflow, CTNK and Theano as backends.
    +If you have Anaconda installed you may run the following command

    +
    +
    +
    conda install keras
    +
    +
    +
    +
    +

    You can look up the instructions here for more information.

    +

    We will to a large extent use keras in this course.

    +
    +
    +

    Collect and pre-process data

    +

    Let us look again at the MINST data set.

    +
    +
    +
    # import necessary packages
    +import numpy as np
    +import matplotlib.pyplot as plt
    +import tensorflow as tf
    +from sklearn import datasets
    +
    +
    +# ensure the same random numbers appear every time
    +np.random.seed(0)
    +
    +# display images in notebook
    +%matplotlib inline
    +plt.rcParams['figure.figsize'] = (12,12)
    +
    +
    +# download MNIST dataset
    +digits = datasets.load_digits()
    +
    +# define inputs and labels
    +inputs = digits.images
    +labels = digits.target
    +
    +print("inputs = (n_inputs, pixel_width, pixel_height) = " + str(inputs.shape))
    +print("labels = (n_inputs) = " + str(labels.shape))
    +
    +
    +# flatten the image
    +# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64
    +n_inputs = len(inputs)
    +inputs = inputs.reshape(n_inputs, -1)
    +print("X = (n_inputs, n_features) = " + str(inputs.shape))
    +
    +
    +# choose some random images to display
    +indices = np.arange(n_inputs)
    +random_indices = np.random.choice(indices, size=5)
    +
    +for i, image in enumerate(digits.images[random_indices]):
    +    plt.subplot(1, 5, i+1)
    +    plt.axis('off')
    +    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')
    +    plt.title("Label: %d" % digits.target[random_indices[i]])
    +plt.show()
    +
    +
    +
    +
    +
    +
    +
    from tensorflow.keras.layers import Input
    +from tensorflow.keras.models import Sequential      #This allows appending layers to existing models
    +from tensorflow.keras.layers import Dense           #This allows defining the characteristics of a particular layer
    +from tensorflow.keras import optimizers             #This allows using whichever optimiser we want (sgd,adam,RMSprop)
    +from tensorflow.keras import regularizers           #This allows using whichever regularizer we want (l1,l2,l1_l2)
    +from tensorflow.keras.utils import to_categorical   #This allows using categorical cross entropy as the cost function
    +
    +from sklearn.model_selection import train_test_split
    +
    +# one-hot representation of labels
    +labels = to_categorical(labels)
    +
    +# split into train and test data
    +train_size = 0.8
    +test_size = 1 - train_size
    +X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,
    +                                                    test_size=test_size)
    +
    +
    +
    +
    +
    +
    +
    epochs = 100
    +batch_size = 100
    +n_neurons_layer1 = 100
    +n_neurons_layer2 = 50
    +n_categories = 10
    +eta_vals = np.logspace(-5, 1, 7)
    +lmbd_vals = np.logspace(-5, 1, 7)
    +def create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, eta, lmbd):
    +    model = Sequential()
    +    model.add(Dense(n_neurons_layer1, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))
    +    model.add(Dense(n_neurons_layer2, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))
    +    model.add(Dense(n_categories, activation='softmax'))
    +    
    +    sgd = optimizers.SGD(lr=eta)
    +    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
    +    
    +    return model
    +
    +
    +
    +
    +
    +
    +
    DNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)
    +        
    +for i, eta in enumerate(eta_vals):
    +    for j, lmbd in enumerate(lmbd_vals):
    +        DNN = create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories,
    +                                         eta=eta, lmbd=lmbd)
    +        DNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0)
    +        scores = DNN.evaluate(X_test, Y_test)
    +        
    +        DNN_keras[i][j] = DNN
    +        
    +        print("Learning rate = ", eta)
    +        print("Lambda = ", lmbd)
    +        print("Test accuracy: %.3f" % scores[1])
    +        print()
    +
    +
    +
    +
    +
    +
    +
    # optional
    +# visual representation of grid search
    +# uses seaborn heatmap, could probably do this in matplotlib
    +import seaborn as sns
    +
    +sns.set()
    +
    +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))
    +
    +for i in range(len(eta_vals)):
    +    for j in range(len(lmbd_vals)):
    +        DNN = DNN_keras[i][j]
    +
    +        train_accuracy[i][j] = DNN.evaluate(X_train, Y_train)[1]
    +        test_accuracy[i][j] = DNN.evaluate(X_test, Y_test)[1]
    +
    +        
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Training Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +fig, ax = plt.subplots(figsize = (10, 10))
    +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis")
    +ax.set_title("Test Accuracy")
    +ax.set_ylabel("$\eta$")
    +ax.set_xlabel("$\lambda$")
    +plt.show()
    +
    +
    +
    +
    +
    +
    +

    The Breast Cancer Data, now with Keras

    +
    +
    +
    import tensorflow as tf
    +from tensorflow.keras.layers import Input
    +from tensorflow.keras.models import Sequential      #This allows appending layers to existing models
    +from tensorflow.keras.layers import Dense           #This allows defining the characteristics of a particular layer
    +from tensorflow.keras import optimizers             #This allows using whichever optimiser we want (sgd,adam,RMSprop)
    +from tensorflow.keras import regularizers           #This allows using whichever regularizer we want (l1,l2,l1_l2)
    +from tensorflow.keras.utils import to_categorical   #This allows using categorical cross entropy as the cost function
    +import numpy as np
    +import matplotlib.pyplot as plt
    +import seaborn as sns
    +from sklearn.model_selection import train_test_split as splitter
    +from sklearn.datasets import load_breast_cancer
    +import pickle
    +import os 
    +
    +
    +"""Load breast cancer dataset"""
    +
    +np.random.seed(0)        #create same seed for random number every time
    +
    +cancer=load_breast_cancer()      #Download breast cancer dataset
    +
    +inputs=cancer.data                     #Feature matrix of 569 rows (samples) and 30 columns (parameters)
    +outputs=cancer.target                  #Label array of 569 rows (0 for benign and 1 for malignant)
    +labels=cancer.feature_names[0:30]
    +
    +print('The content of the breast cancer dataset is:')      #Print information about the datasets
    +print(labels)
    +print('-------------------------')
    +print("inputs =  " + str(inputs.shape))
    +print("outputs =  " + str(outputs.shape))
    +print("labels =  "+ str(labels.shape))
    +
    +x=inputs      #Reassign the Feature and Label matrices to other variables
    +y=outputs
    +
    +#%% 
    +
    +# Visualisation of dataset (for correlation analysis)
    +
    +plt.figure()
    +plt.scatter(x[:,0],x[:,2],s=40,c=y,cmap=plt.cm.Spectral)
    +plt.xlabel('Mean radius',fontweight='bold')
    +plt.ylabel('Mean perimeter',fontweight='bold')
    +plt.show()
    +
    +plt.figure()
    +plt.scatter(x[:,5],x[:,6],s=40,c=y, cmap=plt.cm.Spectral)
    +plt.xlabel('Mean compactness',fontweight='bold')
    +plt.ylabel('Mean concavity',fontweight='bold')
    +plt.show()
    +
    +
    +plt.figure()
    +plt.scatter(x[:,0],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)
    +plt.xlabel('Mean radius',fontweight='bold')
    +plt.ylabel('Mean texture',fontweight='bold')
    +plt.show()
    +
    +plt.figure()
    +plt.scatter(x[:,2],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)
    +plt.xlabel('Mean perimeter',fontweight='bold')
    +plt.ylabel('Mean compactness',fontweight='bold')
    +plt.show()
    +
    +
    +# Generate training and testing datasets
    +
    +#Select features relevant to classification (texture,perimeter,compactness and symmetery) 
    +#and add to input matrix
    +
    +temp1=np.reshape(x[:,1],(len(x[:,1]),1))
    +temp2=np.reshape(x[:,2],(len(x[:,2]),1))
    +X=np.hstack((temp1,temp2))      
    +temp=np.reshape(x[:,5],(len(x[:,5]),1))
    +X=np.hstack((X,temp))       
    +temp=np.reshape(x[:,8],(len(x[:,8]),1))
    +X=np.hstack((X,temp))       
    +
    +X_train,X_test,y_train,y_test=splitter(X,y,test_size=0.1)   #Split datasets into training and testing
    +
    +y_train=to_categorical(y_train)     #Convert labels to categorical when using categorical cross entropy
    +y_test=to_categorical(y_test)
    +
    +del temp1,temp2,temp
    +
    +# %%
    +
    +# Define tunable parameters"
    +
    +eta=np.logspace(-3,-1,3)                    #Define vector of learning rates (parameter to SGD optimiser)
    +lamda=0.01                                  #Define hyperparameter
    +n_layers=2                                  #Define number of hidden layers in the model
    +n_neuron=np.logspace(0,3,4,dtype=int)       #Define number of neurons per layer
    +epochs=100                                   #Number of reiterations over the input data
    +batch_size=100                              #Number of samples per gradient update
    +
    +# %%
    +
    +"""Define function to return Deep Neural Network model"""
    +
    +def NN_model(inputsize,n_layers,n_neuron,eta,lamda):
    +    model=Sequential()      
    +    for i in range(n_layers):       #Run loop to add hidden layers to the model
    +        if (i==0):                  #First layer requires input dimensions
    +            model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda),input_dim=inputsize))
    +        else:                       #Subsequent layers are capable of automatic shape inferencing
    +            model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda)))
    +    model.add(Dense(2,activation='softmax'))  #2 outputs - ordered and disordered (softmax for prob)
    +    sgd=optimizers.SGD(lr=eta)
    +    model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])
    +    return model
    +
    +    
    +Train_accuracy=np.zeros((len(n_neuron),len(eta)))      #Define matrices to store accuracy scores as a function
    +Test_accuracy=np.zeros((len(n_neuron),len(eta)))       #of learning rate and number of hidden neurons for 
    +
    +for i in range(len(n_neuron)):     #run loops over hidden neurons and learning rates to calculate 
    +    for j in range(len(eta)):      #accuracy scores 
    +        DNN_model=NN_model(X_train.shape[1],n_layers,n_neuron[i],eta[j],lamda)
    +        DNN_model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=1)
    +        Train_accuracy[i,j]=DNN_model.evaluate(X_train,y_train)[1]
    +        Test_accuracy[i,j]=DNN_model.evaluate(X_test,y_test)[1]
    +               
    +
    +def plot_data(x,y,data,title=None):
    +
    +    # plot results
    +    fontsize=16
    +
    +
    +    fig = plt.figure()
    +    ax = fig.add_subplot(111)
    +    cax = ax.matshow(data, interpolation='nearest', vmin=0, vmax=1)
    +    
    +    cbar=fig.colorbar(cax)
    +    cbar.ax.set_ylabel('accuracy (%)',rotation=90,fontsize=fontsize)
    +    cbar.set_ticks([0,.2,.4,0.6,0.8,1.0])
    +    cbar.set_ticklabels(['0%','20%','40%','60%','80%','100%'])
    +
    +    # put text on matrix elements
    +    for i, x_val in enumerate(np.arange(len(x))):
    +        for j, y_val in enumerate(np.arange(len(y))):
    +            c = "${0:.1f}\\%$".format( 100*data[j,i])  
    +            ax.text(x_val, y_val, c, va='center', ha='center')
    +
    +    # convert axis vaues to to string labels
    +    x=[str(i) for i in x]
    +    y=[str(i) for i in y]
    +
    +
    +    ax.set_xticklabels(['']+x)
    +    ax.set_yticklabels(['']+y)
    +
    +    ax.set_xlabel('$\\mathrm{learning\\ rate}$',fontsize=fontsize)
    +    ax.set_ylabel('$\\mathrm{hidden\\ neurons}$',fontsize=fontsize)
    +    if title is not None:
    +        ax.set_title(title)
    +
    +    plt.tight_layout()
    +
    +    plt.show()
    +    
    +plot_data(eta,n_neuron,Train_accuracy, 'training')
    +plot_data(eta,n_neuron,Test_accuracy, 'testing')
    +
    +
    +
    +
    +
    +
    +

    Building a neural network code

    +

    Here we present a flexible object oriented codebase +for a feed forward neural network, along with a demonstration of how +to use it. Before we get into the details of the neural network, we +will first present some implementations of various schedulers, cost +functions and activation functions that can be used together with the +neural network.

    +

    The codes here were developed by Eric Reber and Gregor Kajda during spring 2023.

    +
    +

    Learning rate methods

    +

    The code below shows object oriented implementations of the Constant, +Momentum, Adagrad, AdagradMomentum, RMS prop and Adam schedulers. All +of the classes belong to the shared abstract Scheduler class, and +share the update_change() and reset() methods allowing for any of the +schedulers to be seamlessly used during the training stage, as will +later be shown in the fit() method of the neural +network. Update_change() only has one parameter, the gradient +(\(δ^l_ja^{l−1}_k\)), and returns the change which will be subtracted +from the weights. The reset() function takes no parameters, and resets +the desired variables. For Constant and Momentum, reset does nothing.

    +
    +
    +
    import autograd.numpy as np
    +
    +class Scheduler:
    +    """
    +    Abstract class for Schedulers
    +    """
    +
    +    def __init__(self, eta):
    +        self.eta = eta
    +
    +    # should be overwritten
    +    def update_change(self, gradient):
    +        raise NotImplementedError
    +
    +    # overwritten if needed
    +    def reset(self):
    +        pass
    +
    +
    +class Constant(Scheduler):
    +    def __init__(self, eta):
    +        super().__init__(eta)
    +
    +    def update_change(self, gradient):
    +        return self.eta * gradient
    +    
    +    def reset(self):
    +        pass
    +
    +
    +class Momentum(Scheduler):
    +    def __init__(self, eta: float, momentum: float):
    +        super().__init__(eta)
    +        self.momentum = momentum
    +        self.change = 0
    +
    +    def update_change(self, gradient):
    +        self.change = self.momentum * self.change + self.eta * gradient
    +        return self.change
    +
    +    def reset(self):
    +        pass
    +
    +
    +class Adagrad(Scheduler):
    +    def __init__(self, eta):
    +        super().__init__(eta)
    +        self.G_t = None
    +
    +    def update_change(self, gradient):
    +        delta = 1e-8  # avoid division ny zero
    +
    +        if self.G_t is None:
    +            self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))
    +
    +        self.G_t += gradient @ gradient.T
    +
    +        G_t_inverse = 1 / (
    +            delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))
    +        )
    +        return self.eta * gradient * G_t_inverse
    +
    +    def reset(self):
    +        self.G_t = None
    +
    +
    +class AdagradMomentum(Scheduler):
    +    def __init__(self, eta, momentum):
    +        super().__init__(eta)
    +        self.G_t = None
    +        self.momentum = momentum
    +        self.change = 0
    +
    +    def update_change(self, gradient):
    +        delta = 1e-8  # avoid division ny zero
    +
    +        if self.G_t is None:
    +            self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))
    +
    +        self.G_t += gradient @ gradient.T
    +
    +        G_t_inverse = 1 / (
    +            delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))
    +        )
    +        self.change = self.change * self.momentum + self.eta * gradient * G_t_inverse
    +        return self.change
    +
    +    def reset(self):
    +        self.G_t = None
    +
    +
    +class RMS_prop(Scheduler):
    +    def __init__(self, eta, rho):
    +        super().__init__(eta)
    +        self.rho = rho
    +        self.second = 0.0
    +
    +    def update_change(self, gradient):
    +        delta = 1e-8  # avoid division ny zero
    +        self.second = self.rho * self.second + (1 - self.rho) * gradient * gradient
    +        return self.eta * gradient / (np.sqrt(self.second + delta))
    +
    +    def reset(self):
    +        self.second = 0.0
    +
    +
    +class Adam(Scheduler):
    +    def __init__(self, eta, rho, rho2):
    +        super().__init__(eta)
    +        self.rho = rho
    +        self.rho2 = rho2
    +        self.moment = 0
    +        self.second = 0
    +        self.n_epochs = 1
    +
    +    def update_change(self, gradient):
    +        delta = 1e-8  # avoid division ny zero
    +
    +        self.moment = self.rho * self.moment + (1 - self.rho) * gradient
    +        self.second = self.rho2 * self.second + (1 - self.rho2) * gradient * gradient
    +
    +        moment_corrected = self.moment / (1 - self.rho**self.n_epochs)
    +        second_corrected = self.second / (1 - self.rho2**self.n_epochs)
    +
    +        return self.eta * moment_corrected / (np.sqrt(second_corrected + delta))
    +
    +    def reset(self):
    +        self.n_epochs += 1
    +        self.moment = 0
    +        self.second = 0
    +
    +
    +
    +
    +
    +
    +

    Usage of the above learning rate schedulers

    +

    To initalize a scheduler, simply create the object and pass in the +necessary parameters such as the learning rate and the momentum as +shown below. As the Scheduler class is an abstract class it should not +called directly, and will raise an error upon usage.

    +
    +
    +
    momentum_scheduler = Momentum(eta=1e-3, momentum=0.9)
    +adam_scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)
    +
    +
    +
    +
    +

    Here is a small example for how a segment of code using schedulers +could look. Switching out the schedulers is simple.

    +
    +
    +
    weights = np.ones((3,3))
    +print(f"Before scheduler:\n{weights=}")
    +
    +epochs = 10
    +for e in range(epochs):
    +    gradient = np.random.rand(3, 3)
    +    change = adam_scheduler.update_change(gradient)
    +    weights = weights - change
    +    adam_scheduler.reset()
    +
    +print(f"\nAfter scheduler:\n{weights=}")
    +
    +
    +
    +
    +
    +
    +

    Cost functions

    +

    Here we discuss cost functions that can be used when creating the +neural network. Every cost function takes the target vector as its +parameter, and returns a function valued only at \(x\) such that it may +easily be differentiated.

    +
    +
    +
    import autograd.numpy as np
    +
    +def CostOLS(target):
    +    
    +    def func(X):
    +        return (1.0 / target.shape[0]) * np.sum((target - X) ** 2)
    +
    +    return func
    +
    +
    +def CostLogReg(target):
    +
    +    def func(X):
    +        
    +        return -(1.0 / target.shape[0]) * np.sum(
    +            (target * np.log(X + 10e-10)) + ((1 - target) * np.log(1 - X + 10e-10))
    +        )
    +
    +    return func
    +
    +
    +def CostCrossEntropy(target):
    +    
    +    def func(X):
    +        return -(1.0 / target.size) * np.sum(target * np.log(X + 10e-10))
    +
    +    return func
    +
    +
    +
    +
    +

    Below we give a short example of how these cost function may be used +to obtain results if you wish to test them out on your own using +AutoGrad’s automatics differentiation.

    +
    +
    +
    from autograd import grad
    +
    +target = np.array([[1, 2, 3]]).T
    +a = np.array([[4, 5, 6]]).T
    +
    +cost_func = CostCrossEntropy
    +cost_func_derivative = grad(cost_func(target))
    +
    +valued_at_a = cost_func_derivative(a)
    +print(f"Derivative of cost function {cost_func.__name__} valued at a:\n{valued_at_a}")
    +
    +
    +
    +
    +
    +
    +

    Activation functions

    +

    Finally, before we look at the neural network, we will look at the +activation functions which can be specified between the hidden layers +and as the output function. Each function can be valued for any given +vector or matrix X, and can be differentiated via derivate().

    +
    +
    +
    import autograd.numpy as np
    +from autograd import elementwise_grad
    +
    +def identity(X):
    +    return X
    +
    +
    +def sigmoid(X):
    +    try:
    +        return 1.0 / (1 + np.exp(-X))
    +    except FloatingPointError:
    +        return np.where(X > np.zeros(X.shape), np.ones(X.shape), np.zeros(X.shape))
    +
    +
    +def softmax(X):
    +    X = X - np.max(X, axis=-1, keepdims=True)
    +    delta = 10e-10
    +    return np.exp(X) / (np.sum(np.exp(X), axis=-1, keepdims=True) + delta)
    +
    +
    +def RELU(X):
    +    return np.where(X > np.zeros(X.shape), X, np.zeros(X.shape))
    +
    +
    +def LRELU(X):
    +    delta = 10e-4
    +    return np.where(X > np.zeros(X.shape), X, delta * X)
    +
    +
    +def derivate(func):
    +    if func.__name__ == "RELU":
    +
    +        def func(X):
    +            return np.where(X > 0, 1, 0)
    +
    +        return func
    +
    +    elif func.__name__ == "LRELU":
    +
    +        def func(X):
    +            delta = 10e-4
    +            return np.where(X > 0, 1, delta)
    +
    +        return func
    +
    +    else:
    +        return elementwise_grad(func)
    +
    +
    +
    +
    +

    Below follows a short demonstration of how to use an activation +function. The derivative of the activation function will be important +when calculating the output delta term during backpropagation. Note +that derivate() can also be used for cost functions for a more +generalized approach.

    +
    +
    +
    z = np.array([[4, 5, 6]]).T
    +print(f"Input to activation function:\n{z}")
    +
    +act_func = sigmoid
    +a = act_func(z)
    +print(f"\nOutput from {act_func.__name__} activation function:\n{a}")
    +
    +act_func_derivative = derivate(act_func)
    +valued_at_z = act_func_derivative(a)
    +print(f"\nDerivative of {act_func.__name__} activation function valued at z:\n{valued_at_z}")
    +
    +
    +
    +
    +
    +
    +

    The Neural Network

    +

    Now that we have gotten a good understanding of the implementation of +some important components, we can take a look at an object oriented +implementation of a feed forward neural network. The feed forward +neural network has been implemented as a class named FFNN, which can +be initiated as a regressor or classifier dependant on the choice of +cost function. The FFNN can have any number of input nodes, hidden +layers with any amount of hidden nodes, and any amount of output nodes +meaning it can perform multiclass classification as well as binary +classification and regression problems. Although there is a lot of +code present, it makes for an easy to use and generalizeable interface +for creating many types of neural networks as will be demonstrated +below.

    +
    +
    +
    import math
    +import autograd.numpy as np
    +import sys
    +import warnings
    +from autograd import grad, elementwise_grad
    +from random import random, seed
    +from copy import deepcopy, copy
    +from typing import Tuple, Callable
    +from sklearn.utils import resample
    +
    +warnings.simplefilter("error")
    +
    +
    +class FFNN:
    +    """
    +    Description:
    +    ------------
    +        Feed Forward Neural Network with interface enabling flexible design of a
    +        nerual networks architecture and the specification of activation function
    +        in the hidden layers and output layer respectively. This model can be used
    +        for both regression and classification problems, depending on the output function.
    +
    +    Attributes:
    +    ------------
    +        I   dimensions (tuple[int]): A list of positive integers, which specifies the
    +            number of nodes in each of the networks layers. The first integer in the array
    +            defines the number of nodes in the input layer, the second integer defines number
    +            of nodes in the first hidden layer and so on until the last number, which
    +            specifies the number of nodes in the output layer.
    +        II  hidden_func (Callable): The activation function for the hidden layers
    +        III output_func (Callable): The activation function for the output layer
    +        IV  cost_func (Callable): Our cost function
    +        V   seed (int): Sets random seed, makes results reproducible
    +    """
    +
    +    def __init__(
    +        self,
    +        dimensions: tuple[int],
    +        hidden_func: Callable = sigmoid,
    +        output_func: Callable = lambda x: x,
    +        cost_func: Callable = CostOLS,
    +        seed: int = None,
    +    ):
    +        self.dimensions = dimensions
    +        self.hidden_func = hidden_func
    +        self.output_func = output_func
    +        self.cost_func = cost_func
    +        self.seed = seed
    +        self.weights = list()
    +        self.schedulers_weight = list()
    +        self.schedulers_bias = list()
    +        self.a_matrices = list()
    +        self.z_matrices = list()
    +        self.classification = None
    +
    +        self.reset_weights()
    +        self._set_classification()
    +
    +    def fit(
    +        self,
    +        X: np.ndarray,
    +        t: np.ndarray,
    +        scheduler: Scheduler,
    +        batches: int = 1,
    +        epochs: int = 100,
    +        lam: float = 0,
    +        X_val: np.ndarray = None,
    +        t_val: np.ndarray = None,
    +    ):
    +        """
    +        Description:
    +        ------------
    +            This function performs the training the neural network by performing the feedforward and backpropagation
    +            algorithm to update the networks weights.
    +
    +        Parameters:
    +        ------------
    +            I    X (np.ndarray) : training data
    +            II   t (np.ndarray) : target data
    +            III  scheduler (Scheduler) : specified scheduler (algorithm for optimization of gradient descent)
    +            IV   scheduler_args (list[int]) : list of all arguments necessary for scheduler
    +
    +        Optional Parameters:
    +        ------------
    +            V    batches (int) : number of batches the datasets are split into, default equal to 1
    +            VI   epochs (int) : number of iterations used to train the network, default equal to 100
    +            VII  lam (float) : regularization hyperparameter lambda
    +            VIII X_val (np.ndarray) : validation set
    +            IX   t_val (np.ndarray) : validation target set
    +
    +        Returns:
    +        ------------
    +            I   scores (dict) : A dictionary containing the performance metrics of the model.
    +                The number of the metrics depends on the parameters passed to the fit-function.
    +
    +        """
    +
    +        # setup 
    +        if self.seed is not None:
    +            np.random.seed(self.seed)
    +
    +        val_set = False
    +        if X_val is not None and t_val is not None:
    +            val_set = True
    +
    +        # creating arrays for score metrics
    +        train_errors = np.empty(epochs)
    +        train_errors.fill(np.nan)
    +        val_errors = np.empty(epochs)
    +        val_errors.fill(np.nan)
    +
    +        train_accs = np.empty(epochs)
    +        train_accs.fill(np.nan)
    +        val_accs = np.empty(epochs)
    +        val_accs.fill(np.nan)
    +
    +        self.schedulers_weight = list()
    +        self.schedulers_bias = list()
    +
    +        batch_size = X.shape[0] // batches
    +
    +        X, t = resample(X, t)
    +
    +        # this function returns a function valued only at X
    +        cost_function_train = self.cost_func(t)
    +        if val_set:
    +            cost_function_val = self.cost_func(t_val)
    +
    +        # create schedulers for each weight matrix
    +        for i in range(len(self.weights)):
    +            self.schedulers_weight.append(copy(scheduler))
    +            self.schedulers_bias.append(copy(scheduler))
    +
    +        print(f"{scheduler.__class__.__name__}: Eta={scheduler.eta}, Lambda={lam}")
    +
    +        try:
    +            for e in range(epochs):
    +                for i in range(batches):
    +                    # allows for minibatch gradient descent
    +                    if i == batches - 1:
    +                        # If the for loop has reached the last batch, take all thats left
    +                        X_batch = X[i * batch_size :, :]
    +                        t_batch = t[i * batch_size :, :]
    +                    else:
    +                        X_batch = X[i * batch_size : (i + 1) * batch_size, :]
    +                        t_batch = t[i * batch_size : (i + 1) * batch_size, :]
    +
    +                    self._feedforward(X_batch)
    +                    self._backpropagate(X_batch, t_batch, lam)
    +
    +                # reset schedulers for each epoch (some schedulers pass in this call)
    +                for scheduler in self.schedulers_weight:
    +                    scheduler.reset()
    +
    +                for scheduler in self.schedulers_bias:
    +                    scheduler.reset()
    +
    +                # computing performance metrics
    +                pred_train = self.predict(X)
    +                train_error = cost_function_train(pred_train)
    +
    +                train_errors[e] = train_error
    +                if val_set:
    +                    
    +                    pred_val = self.predict(X_val)
    +                    val_error = cost_function_val(pred_val)
    +                    val_errors[e] = val_error
    +
    +                if self.classification:
    +                    train_acc = self._accuracy(self.predict(X), t)
    +                    train_accs[e] = train_acc
    +                    if val_set:
    +                        val_acc = self._accuracy(pred_val, t_val)
    +                        val_accs[e] = val_acc
    +
    +                # printing progress bar
    +                progression = e / epochs
    +                print_length = self._progress_bar(
    +                    progression,
    +                    train_error=train_errors[e],
    +                    train_acc=train_accs[e],
    +                    val_error=val_errors[e],
    +                    val_acc=val_accs[e],
    +                )
    +        except KeyboardInterrupt:
    +            # allows for stopping training at any point and seeing the result
    +            pass
    +
    +        # visualization of training progression (similiar to tensorflow progression bar)
    +        sys.stdout.write("\r" + " " * print_length)
    +        sys.stdout.flush()
    +        self._progress_bar(
    +            1,
    +            train_error=train_errors[e],
    +            train_acc=train_accs[e],
    +            val_error=val_errors[e],
    +            val_acc=val_accs[e],
    +        )
    +        sys.stdout.write("")
    +
    +        # return performance metrics for the entire run
    +        scores = dict()
    +
    +        scores["train_errors"] = train_errors
    +
    +        if val_set:
    +            scores["val_errors"] = val_errors
    +
    +        if self.classification:
    +            scores["train_accs"] = train_accs
    +
    +            if val_set:
    +                scores["val_accs"] = val_accs
    +
    +        return scores
    +
    +    def predict(self, X: np.ndarray, *, threshold=0.5):
    +        """
    +         Description:
    +         ------------
    +             Performs prediction after training of the network has been finished.
    +
    +         Parameters:
    +        ------------
    +             I   X (np.ndarray): The design matrix, with n rows of p features each
    +
    +         Optional Parameters:
    +         ------------
    +             II  threshold (float) : sets minimal value for a prediction to be predicted as the positive class
    +                 in classification problems
    +
    +         Returns:
    +         ------------
    +             I   z (np.ndarray): A prediction vector (row) for each row in our design matrix
    +                 This vector is thresholded if regression=False, meaning that classification results
    +                 in a vector of 1s and 0s, while regressions in an array of decimal numbers
    +
    +        """
    +
    +        predict = self._feedforward(X)
    +
    +        if self.classification:
    +            return np.where(predict > threshold, 1, 0)
    +        else:
    +            return predict
    +
    +    def reset_weights(self):
    +        """
    +        Description:
    +        ------------
    +            Resets/Reinitializes the weights in order to train the network for a new problem.
    +
    +        """
    +        if self.seed is not None:
    +            np.random.seed(self.seed)
    +
    +        self.weights = list()
    +        for i in range(len(self.dimensions) - 1):
    +            weight_array = np.random.randn(
    +                self.dimensions[i] + 1, self.dimensions[i + 1]
    +            )
    +            weight_array[0, :] = np.random.randn(self.dimensions[i + 1]) * 0.01
    +
    +            self.weights.append(weight_array)
    +
    +    def _feedforward(self, X: np.ndarray):
    +        """
    +        Description:
    +        ------------
    +            Calculates the activation of each layer starting at the input and ending at the output.
    +            Each following activation is calculated from a weighted sum of each of the preceeding
    +            activations (except in the case of the input layer).
    +
    +        Parameters:
    +        ------------
    +            I   X (np.ndarray): The design matrix, with n rows of p features each
    +
    +        Returns:
    +        ------------
    +            I   z (np.ndarray): A prediction vector (row) for each row in our design matrix
    +        """
    +
    +        # reset matrices
    +        self.a_matrices = list()
    +        self.z_matrices = list()
    +
    +        # if X is just a vector, make it into a matrix
    +        if len(X.shape) == 1:
    +            X = X.reshape((1, X.shape[0]))
    +
    +        # Add a coloumn of zeros as the first coloumn of the design matrix, in order
    +        # to add bias to our data
    +        bias = np.ones((X.shape[0], 1)) * 0.01
    +        X = np.hstack([bias, X])
    +
    +        # a^0, the nodes in the input layer (one a^0 for each row in X - where the
    +        # exponent indicates layer number).
    +        a = X
    +        self.a_matrices.append(a)
    +        self.z_matrices.append(a)
    +
    +        # The feed forward algorithm
    +        for i in range(len(self.weights)):
    +            if i < len(self.weights) - 1:
    +                z = a @ self.weights[i]
    +                self.z_matrices.append(z)
    +                a = self.hidden_func(z)
    +                # bias column again added to the data here
    +                bias = np.ones((a.shape[0], 1)) * 0.01
    +                a = np.hstack([bias, a])
    +                self.a_matrices.append(a)
    +            else:
    +                try:
    +                    # a^L, the nodes in our output layers
    +                    z = a @ self.weights[i]
    +                    a = self.output_func(z)
    +                    self.a_matrices.append(a)
    +                    self.z_matrices.append(z)
    +                except Exception as OverflowError:
    +                    print(
    +                        "OverflowError in fit() in FFNN\nHOW TO DEBUG ERROR: Consider lowering your learning rate or scheduler specific parameters such as momentum, or check if your input values need scaling"
    +                    )
    +
    +        # this will be a^L
    +        return a
    +
    +    def _backpropagate(self, X, t, lam):
    +        """
    +        Description:
    +        ------------
    +            Performs the backpropagation algorithm. In other words, this method
    +            calculates the gradient of all the layers starting at the
    +            output layer, and moving from right to left accumulates the gradient until
    +            the input layer is reached. Each layers respective weights are updated while
    +            the algorithm propagates backwards from the output layer (auto-differentation in reverse mode).
    +
    +        Parameters:
    +        ------------
    +            I   X (np.ndarray): The design matrix, with n rows of p features each.
    +            II  t (np.ndarray): The target vector, with n rows of p targets.
    +            III lam (float32): regularization parameter used to punish the weights in case of overfitting
    +
    +        Returns:
    +        ------------
    +            No return value.
    +
    +        """
    +        out_derivative = derivate(self.output_func)
    +        hidden_derivative = derivate(self.hidden_func)
    +
    +        for i in range(len(self.weights) - 1, -1, -1):
    +            # delta terms for output
    +            if i == len(self.weights) - 1:
    +                # for multi-class classification
    +                if (
    +                    self.output_func.__name__ == "softmax"
    +                ):
    +                    delta_matrix = self.a_matrices[i + 1] - t
    +                # for single class classification
    +                else:
    +                    cost_func_derivative = grad(self.cost_func(t))
    +                    delta_matrix = out_derivative(
    +                        self.z_matrices[i + 1]
    +                    ) * cost_func_derivative(self.a_matrices[i + 1])
    +
    +            # delta terms for hidden layer
    +            else:
    +                delta_matrix = (
    +                    self.weights[i + 1][1:, :] @ delta_matrix.T
    +                ).T * hidden_derivative(self.z_matrices[i + 1])
    +
    +            # calculate gradient
    +            gradient_weights = self.a_matrices[i][:, 1:].T @ delta_matrix
    +            gradient_bias = np.sum(delta_matrix, axis=0).reshape(
    +                1, delta_matrix.shape[1]
    +            )
    +
    +            # regularization term
    +            gradient_weights += self.weights[i][1:, :] * lam
    +
    +            # use scheduler
    +            update_matrix = np.vstack(
    +                [
    +                    self.schedulers_bias[i].update_change(gradient_bias),
    +                    self.schedulers_weight[i].update_change(gradient_weights),
    +                ]
    +            )
    +
    +            # update weights and bias
    +            self.weights[i] -= update_matrix
    +
    +    def _accuracy(self, prediction: np.ndarray, target: np.ndarray):
    +        """
    +        Description:
    +        ------------
    +            Calculates accuracy of given prediction to target
    +
    +        Parameters:
    +        ------------
    +            I   prediction (np.ndarray): vector of predicitons output network
    +                (1s and 0s in case of classification, and real numbers in case of regression)
    +            II  target (np.ndarray): vector of true values (What the network ideally should predict)
    +
    +        Returns:
    +        ------------
    +            A floating point number representing the percentage of correctly classified instances.
    +        """
    +        assert prediction.size == target.size
    +        return np.average((target == prediction))
    +    def _set_classification(self):
    +        """
    +        Description:
    +        ------------
    +            Decides if FFNN acts as classifier (True) og regressor (False),
    +            sets self.classification during init()
    +        """
    +        self.classification = False
    +        if (
    +            self.cost_func.__name__ == "CostLogReg"
    +            or self.cost_func.__name__ == "CostCrossEntropy"
    +        ):
    +            self.classification = True
    +
    +    def _progress_bar(self, progression, **kwargs):
    +        """
    +        Description:
    +        ------------
    +            Displays progress of training
    +        """
    +        print_length = 40
    +        num_equals = int(progression * print_length)
    +        num_not = print_length - num_equals
    +        arrow = ">" if num_equals > 0 else ""
    +        bar = "[" + "=" * (num_equals - 1) + arrow + "-" * num_not + "]"
    +        perc_print = self._format(progression * 100, decimals=5)
    +        line = f"  {bar} {perc_print}% "
    +
    +        for key in kwargs:
    +            if not np.isnan(kwargs[key]):
    +                value = self._format(kwargs[key], decimals=4)
    +                line += f"| {key}: {value} "
    +        sys.stdout.write("\r" + line)
    +        sys.stdout.flush()
    +        return len(line)
    +
    +    def _format(self, value, decimals=4):
    +        """
    +        Description:
    +        ------------
    +            Formats decimal numbers for progress bar
    +        """
    +        if value > 0:
    +            v = value
    +        elif value < 0:
    +            v = -10 * value
    +        else:
    +            v = 1
    +        n = 1 + math.floor(math.log10(v))
    +        if n >= decimals - 1:
    +            return str(round(value))
    +        return f"{value:.{decimals-n-1}f}"
    +
    +
    +
    +
    +

    Before we make a model, we will quickly generate a dataset we can use +for our linear regression problem as shown below

    +
    +
    +
    import autograd.numpy as np
    +from sklearn.model_selection import train_test_split
    +
    +def SkrankeFunction(x, y):
    +    return np.ravel(0 + 1*x + 2*y + 3*x**2 + 4*x*y + 5*y**2)
    +
    +def create_X(x, y, n):
    +    if len(x.shape) > 1:
    +        x = np.ravel(x)
    +        y = np.ravel(y)
    +
    +    N = len(x)
    +    l = int((n + 1) * (n + 2) / 2)  # Number of elements in beta
    +    X = np.ones((N, l))
    +
    +    for i in range(1, n + 1):
    +        q = int((i) * (i + 1) / 2)
    +        for k in range(i + 1):
    +            X[:, q + k] = (x ** (i - k)) * (y**k)
    +
    +    return X
    +
    +step=0.5
    +x = np.arange(0, 1, step)
    +y = np.arange(0, 1, step)
    +x, y = np.meshgrid(x, y)
    +target = SkrankeFunction(x, y)
    +target = target.reshape(target.shape[0], 1)
    +
    +poly_degree=3
    +X = create_X(x, y, poly_degree)
    +
    +X_train, X_test, t_train, t_test = train_test_split(X, target)
    +
    +
    +
    +
    +

    Now that we have our dataset ready for the regression, we can create +our regressor. Note that with the seed parameter, we can make sure our +results stay the same every time we run the neural network. For +inititialization, we simply specify the dimensions (we wish the amount +of input nodes to be equal to the datapoints, and the output to +predict one value).

    +
    +
    +
    input_nodes = X_train.shape[1]
    +output_nodes = 1
    +
    +linear_regression = FFNN((input_nodes, output_nodes), output_func=identity, cost_func=CostOLS, seed=2023)
    +
    +
    +
    +
    +

    We then fit our model with our training data using the scheduler of our choice.

    +
    +
    +
    linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +
    +scheduler = Constant(eta=1e-3)
    +scores = linear_regression.fit(X_train, t_train, scheduler)
    +
    +
    +
    +
    +

    Due to the progress bar we can see the MSE (train_error) throughout +the FFNN’s training. Note that the fit() function has some optional +parameters with defualt arguments. For example, the regularization +hyperparameter can be left ignored if not needed, and equally the FFNN +will by default run for 100 epochs. These can easily be changed, such +as for example:

    +
    +
    +
    linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +
    +scores = linear_regression.fit(X_train, t_train, scheduler, lam=1e-4, epochs=1000)
    +
    +
    +
    +
    +

    We see that given more epochs to train on, the regressor reaches a lower MSE.

    +

    Let us then switch to a binary classification. We use a binary +classification dataset, and follow a similar setup to the regression +case.

    +
    +
    +
    from sklearn.datasets import load_breast_cancer
    +from sklearn.preprocessing import MinMaxScaler
    +
    +wisconsin = load_breast_cancer()
    +X = wisconsin.data
    +target = wisconsin.target
    +target = target.reshape(target.shape[0], 1)
    +
    +X_train, X_val, t_train, t_val = train_test_split(X, target)
    +
    +scaler = MinMaxScaler()
    +scaler.fit(X_train)
    +X_train = scaler.transform(X_train)
    +X_val = scaler.transform(X_val)
    +
    +
    +
    +
    +
    +
    +
    input_nodes = X_train.shape[1]
    +output_nodes = 1
    +
    +logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)
    +
    +
    +
    +
    +

    We will now make use of our validation data by passing it into our fit function as a keyword argument

    +
    +
    +
    logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +
    +scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)
    +scores = logistic_regression.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)
    +
    +
    +
    +
    +

    Finally, we will create a neural network with 2 hidden layers with activation functions.

    +
    +
    +
    input_nodes = X_train.shape[1]
    +hidden_nodes1 = 100
    +hidden_nodes2 = 30
    +output_nodes = 1
    +
    +dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)
    +
    +neural_network = FFNN(dims, hidden_func=RELU, output_func=sigmoid, cost_func=CostLogReg, seed=2023)
    +
    +
    +
    +
    +
    +
    +
    neural_network.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +
    +scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)
    +scores = neural_network.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)
    +
    +
    +
    +
    +
    +
    +

    Multiclass classification

    +

    Finally, we will demonstrate the use case of multiclass classification +using our FFNN with the famous MNIST dataset, which contain images of +digits between the range of 0 to 9.

    +
    +
    +
    from sklearn.datasets import load_digits
    +
    +def onehot(target: np.ndarray):
    +    onehot = np.zeros((target.size, target.max() + 1))
    +    onehot[np.arange(target.size), target] = 1
    +    return onehot
    +
    +digits = load_digits()
    +
    +X = digits.data
    +target = digits.target
    +target = onehot(target)
    +
    +input_nodes = 64
    +hidden_nodes1 = 100
    +hidden_nodes2 = 30
    +output_nodes = 10
    +
    +dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)
    +
    +multiclass = FFNN(dims, hidden_func=LRELU, output_func=softmax, cost_func=CostCrossEntropy)
    +
    +multiclass.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +
    +scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)
    +scores = multiclass.fit(X, target, scheduler, epochs=1000)
    +
    +
    +
    +
    +
    +
    +
    +

    Testing the XOR gate and other gates

    +

    Let us now use our code to test the XOR gate.

    +
    +
    +
    X = np.array([ [0, 0], [0, 1], [1, 0],[1, 1]],dtype=np.float64)
    +
    +# The XOR gate
    +yXOR = np.array( [[ 0], [1] ,[1], [0]])
    +
    +input_nodes = X.shape[1]
    +output_nodes = 1
    +
    +logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)
    +logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights
    +scheduler = Adam(eta=1e-1, rho=0.9, rho2=0.999)
    +scores = logistic_regression.fit(X, yXOR, scheduler, epochs=1000)
    +
    +
    +
    +
    +

    Not bad, but the results depend strongly on the learning reate. Try different learning rates.

    +
    +
    + + + + +
    + + + + + +
    +
    +
    +

    + + By Morten Hjorth-Jensen
    + + © Copyright 2021.
    +

    +
    +
    + + +
    +
    + + + + + \ No newline at end of file diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb index 1a9bd516a..ea16c3166 100644 --- a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb +++ b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb @@ -103,20 +103,20 @@ "output_type": "stream", "text": [ "Own inversion\n", - "[[3.96581896]\n", - " [3.03624103]]\n", - "Eigenvalues of Hessian Matrix:[0.26120167 4.71129677]\n", + "[[4.04881585]\n", + " [2.96745096]]\n", + "Eigenvalues of Hessian Matrix:[0.37175588 4.15690073]\n", "theta from own gd\n", - "[[3.96581896]\n", - " [3.03624103]]\n", + "[[4.04881585]\n", + " [2.96745096]]\n", "theta from own sdg\n", - "[[3.99729015]\n", - " [3.02646648]]\n" + "[[4.04015455]\n", + " [2.95745651]]\n" ] }, { "data": { - "image/png": "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IiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNcUEQ//+97+RkpKCiIgItGvXDlu2bPF3k4iIiCgAKCIY+vzzzzFlyhS89NJL2L17N3r06IGBAwfi9OnT/m4aERERKZwkhBD+boQ9nTp1Qtu2bfHuu++at6WmpmLYsGGYO3eu3efn5+cjOjoaeXl5iIqK8mZTiYiIyEN89f0t+56h4uJi/Pbbb+jfv7/F9v79+2Pr1q1+ahUREREFihB/N8CeS5cuQa/Xo27duhbb69ati9zcXKvPKSoqQlFRkflxXl4eAGOESURERMpg+t729iCW7IMhE0mSLB4LISpsM5k7dy5mz55dYbtGo/FK24iIiMh7Ll++jOjoaK+dX/bBUO3atREcHFyhF+jChQsVeotMZsyYgWnTppkfX7t2DfXr18fp06e9+mbKTX5+PjQaDXJyclSVK8Xr5nWrAa+b160GeXl5qFevHmJiYrz6OrIPhsLCwtCuXTusX78ew4cPN29fv349hg4davU54eHhCA8Pr7A9OjpaVR8ik6ioKF63ivC61YXXrS5qve6gIO+mOMs+GAKAadOmYfTo0Wjfvj26dOmC9957D6dPn8aTTz7p76YRERGRwikiGHrooYdw+fJlvPLKKzh//jzS0tLw9ddfo379+v5uGhERESmcIoIhAHj66afx9NNPu/Tc8PBwzJw50+rQWSDjdfO61YDXzetWA163d69bEUUXiYiIiLxF9kUXiYiIiLyJwRARERGpGoMhIiIiUjUGQ0RERKRqigyG/v3vfyMlJQURERFo164dtmzZUunxmzZtQrt27RAREYEGDRpgyZIlFY5ZsWIFmjVrhvDwcDRr1gwrV670VvNd5sx1Z2Zmol+/fqhTpw6ioqLQpUsXfPfddxbHLFu2DJIkVfgpLCz09qU4xZnr3rhxo9VrOnz4sMVxgfb7Hjt2rNXrbt68ufkYJfy+N2/eDK1Wi4SEBEiShFWrVtl9TiDc385ed6Dc385ed6Dc385ed6Dc33PnzkWHDh0QGRmJ2NhYDBs2DEeOHLH7PF/c44oLhj7//HNMmTIFL730Enbv3o0ePXpg4MCBOH36tNXjs7Ozcd9996FHjx7YvXs3XnzxRUyePBkrVqwwH7Nt2zY89NBDGD16NH7//XeMHj0aDz74IH755RdfXZZdzl735s2b0a9fP3z99df47bff0KdPH2i1WuzevdviuKioKJw/f97iJyIiwheX5BBnr9vkyJEjFtfUuHFj875A/H2/+eabFtebk5ODmJgYPPDAAxbHyf33XVBQgFatWmHx4sUOHR8o97ez1x0o97ez122i9Pvb2esOlPt706ZNmDBhArZv347169ejtLQU/fv3R0FBgc3n+OweFwrTsWNH8eSTT1psa9q0qZg+fbrV4//+97+Lpk2bWmwbP3686Ny5s/nxgw8+KO69916LYwYMGCAefvhhD7Xafc5etzXNmjUTs2fPNj9eunSpiI6O9lQTvcLZ687KyhIAxNWrV22eUw2/75UrVwpJksTJkyfN25Tw+y4LgFi5cmWlxwTK/V2WI9dtjRLv77Icue5Aub/LcuX3HQj3txBCXLhwQQAQmzZtsnmMr+5xRfUMFRcX47fffkP//v0ttvfv3x9bt261+pxt27ZVOH7AgAHYuXMnSkpKKj3G1jl9zZXrLs9gMOD69esVFru7ceMG6tevj6SkJAwePLjCX5b+5M51t2nTBvHx8ejbty+ysrIs9qnh9/3BBx/gnnvuqVClXc6/b1cEwv3tCUq8v92h5PvbEwLl/s7LywOAShdh9dU9rqhg6NKlS9Dr9RVWq69bt26FVe1NcnNzrR5fWlqKS5cuVXqMrXP6mivXXd4bb7yBgoICPPjgg+ZtTZs2xbJly7BmzRosX74cERER6NatG44dO+bR9rvKleuOj4/He++9hxUrViAzMxNNmjRB3759sXnzZvMxgf77Pn/+PL755hs8/vjjFtvl/vt2RSDc356gxPvbFYFwf7srUO5vIQSmTZuG7t27Iy0tzeZxvrrHFbMcR1mSJFk8FkJU2Gbv+PLbnT2nP7jaxuXLl2PWrFlYvXo1YmNjzds7d+6Mzp07mx9369YNbdu2xdtvv4233nrLcw13kzPX3aRJEzRp0sT8uEuXLsjJycHrr7+Onj17unROf3G1jcuWLUONGjUwbNgwi+1K+X07K1Dub1cp/f52RiDd364KlPt74sSJ2Lt3L3766Se7x/riHldUz1Dt2rURHBxcIdq7cOFChajQJC4uzurxISEhqFWrVqXH2Dqnr7ly3Saff/45HnvsMXzxxRe45557Kj02KCgIHTp0kM1fEu5cd1mdO3e2uKZA/n0LIfC///0Po0ePRlhYWKXHyu337YpAuL/doeT721OUdn+7I1Du70mTJmHNmjXIyspCUlJSpcf66h5XVDAUFhaGdu3aYf369Rbb169fj65du1p9TpcuXSoc//3336N9+/YIDQ2t9Bhb5/Q1V64bMP7FOHbsWGRkZGDQoEF2X0cIgT179iA+Pt7tNnuCq9dd3u7duy2uKVB/34Bxtsbx48fx2GOP2X0duf2+XREI97erlH5/e4rS7m93KP3+FkJg4sSJyMzMxIYNG5CSkmL3OT67xx1OtZaJzz77TISGhooPPvhAHDx4UEyZMkVUq1bNnFU/ffp0MXr0aPPxf/zxh6hataqYOnWqOHjwoPjggw9EaGio+Oqrr8zH/PzzzyI4OFj861//EocOHRL/+te/REhIiNi+fbvPr88WZ687IyNDhISEiHfeeUecP3/e/HPt2jXzMbNmzRLffvutOHHihNi9e7cYN26cCAkJEb/88ovPr88WZ6974cKFYuXKleLo0aNi//79Yvr06QKAWLFihfmYQPx9mzzyyCOiU6dOVs+phN/39evXxe7du8Xu3bsFALFgwQKxe/ducerUKSFE4N7fzl53oNzfzl53oNzfzl63idLv76eeekpER0eLjRs3Wnxub968aT7GX/e44oIhIYR45513RP369UVYWJho27atxbS8MWPGiF69elkcv3HjRtGmTRsRFhYmkpOTxbvvvlvhnF9++aVo0qSJCA0NFU2bNrW4ueTCmevu1auXAFDhZ8yYMeZjpkyZIurVqyfCwsJEnTp1RP/+/cXWrVt9eEWOcea6582bJxo2bCgiIiJEzZo1Rffu3cW6desqnDPQft9CCHHt2jVRpUoV8d5771k9nxJ+36ap07Y+t4F6fzt73YFyfzt73YFyf7vyOQ+E+9vaNQMQS5cuNR/jr3tcut1AIiIiIlVSVM4QERERkacxGCIiIiJVYzBEREREqsZgiIiIiFSNwRARERGpGoMhIiIiUjUGQ0RERKRqDIaIiIhI1RgMERERkaoxGCIiIiJVYzBERIq0fPlyRERE4OzZs+Ztjz/+OFq2bIm8vDw/toyIlIZrkxGRIgkh0Lp1a/To0QOLFy/G7Nmz8f7772P79u1ITEz0d/OISEFC/N0AIiJXSJKEOXPmYMSIEUhISMCbb76JLVu2MBAiIqexZ4iIFK1t27Y4cOAAvv/+e/Tq1cvfzSEiBWLOEBEp1nfffYfDhw9Dr9ejbt26/m4OESkUe4aISJF27dqF3r1745133sFnn32GqlWr4ssvv/R3s4hIgZgzRESKc/LkSQwaNAjTp0/H6NGj0axZM3To0AG//fYb2rVr5+/mEZHCsGeIiBTlypUr6NatG3r27In//Oc/5u1Dhw5FUVERvv32Wz+2joiUiMEQERERqRoTqImIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESq9v8BAPFOpB6joZUAAAAASUVORK5CYII=", + "image/png": "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fkP1ueeee/DNN9/gzTffxI0bNxAXF4dHHnkEL730kkuOi8gXqYQQwtOFICIiIvIU9hkiIiIiRWMwRERERIrGYIiIiIgUjcEQERERKRqDISIiIlI0BkNERESkaIrIM6TX63Hu3Dk0atTIYjp7IiIikh8hBK5fv47Y2Fj4+bmu/kYRwdC5c+eQkJDg6WIQERGRA/Lz8xEfH++y/SsiGGrUqBEAw8kMCwvzcGmIiIjIFiUlJUhISDDdx11FEcGQsWksLCyMwRAREZGXcXUXF3agJiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkXzeDC0ZcsWjBo1CrGxsVCpVFizZo3VbZ9++mmoVCosXrzYbeUjIiIi3+bxYKisrAydO3fG0qVL69xuzZo1+OmnnxAbG+umkhEREZESBHi6ACNGjMCIESPq3KagoABTpkzBd999B7Va7aaSERERkRJ4vGaoPnq9HhMmTMALL7yADh06eLo4RERE5GM8XjNUn9deew0BAQGYNm2aza+pqKhARUWF6XlJSYkrikZEREQ+QNY1Qz///DOWLFmC5cuXQ6VS2fy6BQsWIDw83PRISEhwYSmJiIjIm8k6GNq6dSuKiorQokULBAQEICAgAKdPn8bzzz+PxMREq6+bPXs2iouLTY/8/Hz3FZqIiIi8iqybySZMmIDBgwebLRs2bBgmTJiAxx57zOrrgoODERwc7OriERERkQ/weDBUWlqK48ePm57n5eXhl19+QUREBFq0aIHIyEiz7QMDAxEdHY127dq5u6hERETkgzweDO3atQvp6emm5zNmzAAATJw4EcuXL/dQqYiIiEgpPB4MpaWlQQhh8/anTp1yXWGIiIhIcWTdgZqIiIjI1RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMhIiIiUjQGQ0RERKRoDIaIiIhI0RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMhIiIiUjQGQ0RERKRoDIaIiIhI0RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMh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", "text/plain": [ "
    " ] @@ -156,7 +156,7 @@ "eta = 1.0/np.max(EigValues)\n", "Niterations = 1000\n", "\n", - "\n", + "#while (iter <= Ni... or test)\n", "for iter in range(Niterations):\n", " gradients = 2.0/n*X.T @ ((X @ theta)-y)\n", " theta -= eta*gradients\n", @@ -338,9 +338,9 @@ "output_type": "stream", "text": [ "Own inversion\n", - "[[4.03656288]\n", - " [2.95497813]]\n", - "Eigenvalues of Hessian Matrix:[0.29560433 4.58257727]\n" + "[[3.37007195]\n", + " [3.48441798]]\n", + "Eigenvalues of Hessian Matrix:[0.32411274 4.30450049]\n" ] }, { @@ -348,13 +348,13 @@ "output_type": "stream", "text": [ "theta from own gd\n", - "[[4.03656288]\n", - " [2.95497813]]\n" + "[[3.37007195]\n", + " [3.48441798]]\n" ] }, { "data": { - "image/png": "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IiIiVWMwRERERKrGYIiIiIhUjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVWMwRERERKrGYIiIiIhUjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVWMwRERERKrm82Bo+/btGDVqFGJiYiBJEtatW2feV1FRgVdeeQX33nsv6tevj5iYGDz22GO4ePGi7xpMREREfsXnwVBJSQk6dOiAJUuW1NhXWlqK/fv347XXXsP+/fuRnZ2NkydP4le/+pUPWkpERET+SBJCCF83oookSVi7di3GjBlj85g9e/age/fuOHv2LFq2bOnQeYuLixEREQG9Xo/w8HA3tZaIiIg8yVv37yCPndlD9Ho9JElCo0aNbB5TXl6O8vJy88/FxcVeaBkREREpkc+HyZxRVlaGmTNnYsKECbVGiPPnz0dERIT5ER8f78VWEhERkZIoJhiqqKjAww8/DKPRiHfffbfWY2fNmgW9Xm9+5Ofne6mVREREZJXBAOTmAqtWmf5rMPi6RWaKGCarqKjAuHHjkJeXh61bt9odN9RoNNBoNF5qHREREdUqOxuYPh04f/7Otrg4YNEiIDPTd+36hex7hqoCoVOnTmHz5s1o0qSJr5tEREREjsrOBsaOtQyEAODCBdP27GzftOsuPu8ZunnzJn788Ufzz3l5eTh48CAiIyMRExODsWPHYv/+/Vi/fj0MBgMKCgoAAJGRkQgJCfFVs4mIiMgeg8HUI2Rt4roQgCQBWVnA6NFAYKDXm1fF51Prc3NzMXDgwBrbJ02ahDlz5iAxMdHq83JycjBgwACHXoNT64mIiHwgNxewco+vIScHsHJPV83U+gEDBqC2eExGZZCIiIjIGZcuufc4D5F9zhAREREpVHS0e4/zEJ/3DBEREZFCGQzAjh2mnp3oaKBvX8vcn759TbPGLlywnjckSab9fft6r81WsGeIiIiInJedDSQkmHKCJkww/TchwXJ2WGCgafo8YAp87lb188KFPk2eBhgMERERkbOcmS6fmQmsXg3ExloeGxdn2i6DOkM+n03mDZxNRkRE5CYGg6kHqHogVKVq6Csvz7LHx96QmhWqmU1GRERECrJjh+1ACDDlBuXnm467e7p8YKDV6fNywGEyIiIicpxCpss7g8EQEREROU4h0+Wd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Z0LJsdJzZiYwerT82kVERLLBYEiOlDgTSs5LiXiqJAIREfkFDpPJkdJmQrHSMxERKRiDITlS0kwoLiVCREQKx2BIjpQ0E8qZSs9EREQyxGBIrpQyE0qJ+U1ERER3YQK1nClhJpTS8puIiIiqYTAkd3KfCWVvKZGq1eHlkN9ERERkBYfJqG6UlN9ERERkBYMhXzEYgNxcYNUq03+VPNtKKflNREREVnCYzBfkXKDQVUrIbyIiIrJCEsJaood/KS4uRkREBPR6PcLDw33bmKoChdXf9qohJfakEBERAfDe/ZvDZN7EAoVERESyw2DIm1igkIiISHYYDHkTCxQSERHJDoMhb2KBQiIiItlhMORNSlqAlYiISCUYDHkTCxQSERHJDoMhb2OBQiIiIllh0UVfYIFCIiIi2WAw5CtyX4CViIhIJThMRkRERKrGYIiIiIhUjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVWMwRERERKrGYIiIiIhUjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVZN9MDR//nx069YNDRs2RFRUFMaMGYMTJ074ullERETkJ2QfDG3btg1Tp07F7t27sWnTJlRWVmLo0KEoKSnxddOIiIjID0hCCOHrRjjj8uXLiIqKwrZt29CvXz+HnlNcXIyIiAjo9XqEh4d7uIVERETkDt66fwd57MweotfrAQCRkZE2jykvL0d5ebn55+LiYo+3i4iIiJRJ9sNkdxNCYMaMGejTpw/S09NtHjd//nxERESYH/Hx8V5sJRERESmJoobJpk6dCp1Oh2+++QZxcXE2j7PWMxQfH89hMiIiIgXhMFk1L7zwAr744gts37691kAIADQaDTQajZdaRkREREom+2BICIEXXngBa9euRW5uLhITE33dJCIiIvIjsg+Gpk6dipUrV+Lzzz9Hw4YNUVBQAACIiIhAvXr1fNw6IiIiUjrZ5wxJkmR1+7JlyzB58mSHzsGp9URERMrDnKFfyDxWIyIiIoVT1NR6IiIiIndjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGqKCYbeffddJCYmIjQ0FF26dMGOHTt83SQiIiLyA4oIhj755BNkZWXh1VdfxYEDB9C3b1+MGDEC586d83XTiIiISOEkIYTwdSPs6dGjBzp37oy///3v5m0pKSkYM2YM5s+fb/f5xcXFiIiIgF6vR3h4uCebSkRERG7irfu37HuGbt++jX379mHo0KEW24cOHYqdO3f6qFVERETkL4J83QB7ioqKYDAY0Lx5c4vtzZs3R0FBgdXnlJeXo7y83PyzXq8HYIowiYiISBmq7tueHsSSfTBURZIki5+FEDW2VZk/fz7mzp1bY3t8fLxH2kZERESec+XKFURERHjs/LIPhpo2bYrAwMAavUCFhYU1eouqzJo1CzNmzDD/fP36dbRq1Qrnzp3z6JspN8XFxYiPj0d+fr6qcqV43bxuNeB187rVQK/Xo2XLloiMjPTo68g+GAoJCUGXLl2wadMmPPDAA+btmzZtwujRo60+R6PRQKPR1NgeERGhqn9EVcLDw3ndKsLrVhdet7qo9boDAjyb4iz7YAgAZsyYgYkTJ6Jr167o1asX3nvvPZw7dw7PPPOMr5tGRERECqeIYOihhx7ClStX8Mc//hGXLl1Ceno6NmzYgFatWvm6aURERKRwigiGAOC5557Dc88959JzNRoNZs+ebXXozJ/xunndasDr5nWrAa/bs9etiKKLRERERJ4i+6KLRERERJ7EYIiIiIhUjcEQERERqRqDISIiIlI1RQZD7777LhITExEaGoouXbpgx44dtR6/bds2dOnSBaGhoWjdujWWLl1a45g1a9YgNTUVGo0GqampWLt2raea7zJnrjs7OxtDhgxBs2bNEB4ejl69emHjxo0WxyxfvhySJNV4lJWVefpSnOLMdefm5lq9puPHj1sc52+f9+TJk61ed1pamvkYJXze27dvx6hRoxATEwNJkrBu3Tq7z/GH77ez1+0v329nr9tfvt/OXre/fL/nz5+Pbt26oWHDhoiKisKYMWNw4sQJu8/zxndcccHQJ598gqysLLz66qs4cOAA+vbtixEjRuDcuXNWj8/Ly8PIkSPRt29fHDhwAP/3f/+HadOmYc2aNeZjdu3ahYceeggTJ07E999/j4kTJ2LcuHH47rvvvHVZdjl73du3b8eQIUOwYcMG7Nu3DwMHDsSoUaNw4MABi+PCw8Nx6dIli0doaKg3Lskhzl53lRMnTlhcU9u2bc37/PHzXrRokcX15ufnIzIyEg8++KDFcXL/vEtKStChQwcsWbLEoeP95fvt7HX7y/fb2euuovTvt7PX7S/f723btmHq1KnYvXs3Nm3ahMrKSgwdOhQlJSU2n+O177hQmO7du4tnnnnGYltycrKYOXOm1eN/97vfieTkZIttTz/9tOjZs6f553Hjxonhw4dbHDNs2DDx8MMPu6nVdefsdVuTmpoq5s6da/552bJlIiIiwl1N9AhnrzsnJ0cAENeuXbN5TjV83mvXrhWSJIkzZ86Ytynh874bALF27dpaj/GX7/fdHLlua5T4/b6bI9ftL9/vu7nyefvD91sIIQoLCwUAsW3bNpvHeOs7rqieodu3b2Pfvn0YOnSoxfahQ4di586dVp+za9euGscPGzYMe/fuRUVFRa3H2Dqnt7ly3dUZjUbcuHGjxmJ3N2/eRKtWrRAXF4eMjIwaf1n6Ul2uu1OnToiOjsagQYOQk5NjsU8Nn/f777+PwYMH16jSLufP2xX+8P12ByV+v+tCyd9vd/CX77derweAWhdh9dZ3XFHBUFFREQwGQ43V6ps3b15jVfsqBQUFVo+vrKxEUVFRrcfYOqe3uXLd1f31r39FSUkJxo0bZ96WnJyM5cuX44svvsCqVasQGhqK3r1749SpU25tv6tcue7o6Gi89957WLNmDbKzs5GUlIRBgwZh+/bt5mP8/fO+dOkSvvzySzz55JMW2+X+ebvCH77f7qDE77cr/OH7XVf+8v0WQmDGjBno06cP0tPTbR7nre+4YpbjuJskSRY/CyFqbLN3fPXtzp7TF1xt46pVqzBnzhx8/vnniIqKMm/v2bMnevbsaf65d+/e6Ny5M/72t79h8eLF7mt4HTlz3UlJSUhKSjL/3KtXL+Tn5+Mvf/kL+vXr59I5fcXVNi5fvhyNGjXCmDFjLLYr5fN2lr98v12l9O+3M/zp++0qf/l+P//88/jhhx/wzTff2D3WG99xRfUMNW3aFIGBgTWivcLCwhpRYZUWLVpYPT4oKAhNmjSp9Rhb5/Q2V667yieffIInnngCn376KQYPHlzrsQEBAejWrZts/pKoy3XfrWfPnhbX5M+ftxAC//73vzFx4kSEhITUeqzcPm9X+MP3uy6U/P12F6V9v+vCX77fL7zwAr744gvk5OQgLi6u1mO99R1XVDAUEhKCLl26YNOmTRbbN23ahPvuu8/qc3r16lXj+K+//hpdu3ZFcHBwrcfYOqe3uXLdgOkvxsmTJ2PlypXQarV2X0cIgYMHDyI6OrrObXYHV6+7ugMHDlhck79+3oBptsaPP/6IJ554wu7ryO3zdoU/fL9dpfTvt7so7ftdF0r/fgsh8PzzzyM7Oxtbt25FYmKi3ed47TvucKq1THz88cciODhYvP/+++Lo0aMiKytL1K9f35xVP3PmTDFx4kTz8T/99JMICwsTL774ojh69Kh4//33RXBwsFi9erX5mG+//VYEBgaKP//5z+LYsWPiz3/+swgKChK7d+/2+vXZ4ux1r1y5UgQFBYl33nlHXLp0yfy4fv26+Zg5c+aIr776Spw+fVocOHBATJkyRQQFBYnvvvvO69dni7PX/fbbb4u1a9eKkydPisOHD4uZM2cKAGLNmjXmY/zx867y6KOPih49elg9pxI+7xs3bogDBw6IAwcOCADirbfeEgcOHBBnz54VQvjv99vZ6/aX77ez1+0v329nr7uK0r/fzz77rIiIiBC5ubkW/25LS0vNx/jqO664YEgIId555x3RqlUrERISIjp37mwxLW/SpEmif//+Fsfn5uaKTp06iZCQEJGQkCD+/ve/1zjnZ599JpKSkkRwcLBITk62+HLJhTPX3b9/fwGgxmPSpEnmY7KyskTLli1FSEiIaNasmRg6dKjYuXOnF6/IMc5c95tvvinatGkjQkNDRePGjUWfPn2ETqercU5/+7yFEOL69euiXr164r333rN6PiV83lVTp239u/XX77ez1+0v329nr9tfvt+u/Dv3h++3tWsGIJYtW2Y+xlffcemXBhIRERGpkqJyhoiIiIjcjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVWMwRERERKrGYIiIiIhUjcEQERERqRqDISJSpFWrViE0NBQXLlwwb3vyySfRvn176PV6H7aMiJSGa5MRkSIJIdCxY0f07dsXS5Yswdy5c/Gvf/0Lu3fvRmxsrK+bR0QKEuTrBhARuUKSJMybNw9jx45FTEwMFi1ahB07djAQIiKnsWeIiBStc+fOOHLkCL7++mv079/f180hIgVizhARKdbGjRtx/PhxGAwGNG/e3NfNISKFYs8QESnS/v37MWDAALzzzjv4+OOPERYWhs8++8zXzSIiBWLOEBEpzpkzZ6DVajFz5kxMnDgRqamp6NatG/bt24cuXbr4unlEpDDsGSIiRbl69Sp69+6Nfv364R//+Id5++jRo1FeXo6vvvrKh60jIiViMERERESqxgRqIiIiUjUGQ0RERKRqDIaIiIhI1RgMERERkaoxGCIiIiJVYzBEREREqsZgiIiIiFSNwRARERGpGoMhIiIiUjUGQ0RERKRqDIaIiIhI1RgMERERkar9fyG0bL25DTIKAAAAAElFTkSuQmCC", + "image/png": "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bgpPvr4dwVuu77KyMgBodBFWV13jHhUMnT59Gnq9vsFq9eHh4Q1WtTc4fvy42f1rampw+vTpRvexdExXs+e863vrrbdQUVGBCRMmGLd16dIFy5YtwxdffIGMjAwEBQVh8ODBOHjwoEPbby97zjsyMhIffPABsrKyoNPp0LlzZ9x0003YsmWLcR9v/75LSkrw9ddf46GHHjLZrvbv2x7ecH07gide3/bwhuu7qbzl+hZCYNq0aRgyZAh69OhhcT9XXeMesxxHXZIkmTwWQjTYZm3/+tttPaY72NvGjIwMzJkzB2vXrkVYWJhx+8CBAzFw4EDj48GDB+OGG27Au+++i3/84x+Oa3gT2XLenTt3RufOnY2P4+PjUVRUhDfffBNDhw6165juYm8bly1bhquuugpjx4412e4p37etvOX6tpenX9+28Kbr217ecn0/8cQT2L17N77//nur+7riGveonqG2bdvC19e3QbR38uTJBlGhQUREhNn9/fz80KZNm0b3sXRMV7PnvA1WrFiBBx98ECtXrsTw4cMb3dfHxwf9+/dXzV8STTnvugYOHGhyTt78fQsh8PHHH2PSpEkICAhodF+1fd/28Ibruyk8+fp2FE+7vpvCW67vJ598El988QWys7MRExPT6L6uusY9KhgKCAhA3759sWHDBpPtGzZswKBBg8y+Jj4+vsH+69evR79+/eDv79/oPpaO6Wr2nDcg/8V4//33Y/ny5Rg1apTV9xFCoKCgAJGRkU1usyPYe9715efnm5yTt37fgDxb49ChQ3jwwQetvo/avm97eMP1bS9Pv74dxdOu76bw9OtbCIEnnngCOp0OmzZtQseOHa2+xmXXuOJUa5XIzMwU/v7+4qOPPhJ79uwRaWlpokWLFsas+hkzZohJkyYZ9//9999F8+bNxdNPPy327NkjPvroI+Hv7y9WrVpl3OeHH34Qvr6+4u9//7vYu3ev+Pvf/y78/PzEtm3bXH5+lth63suXLxd+fn7ivffeEyUlJcafP//807jPnDlzxDfffCN+++03kZ+fLx544AHh5+cnfvrpJ5efnyW2nvc777wjVq9eLQ4cOCB++eUXMWPGDAFAZGVlGffxxu/b4N577xU33nij2WN6wvd97tw5kZ+fL/Lz8wUA8fbbb4v8/Hxx5MgRIYT3Xt+2nre3XN+2nre3XN+2nreBp1/fjz32mAgJCRE5OTkmv7cXLlww7uOua9zjgiEhhHjvvfdEhw4dREBAgLjhhhtMpuVNnjxZDBs2zGT/nJwc0adPHxEQECDi4uLEP//5zwbH/Pzzz0Xnzp2Fv7+/6NKli8nFpRa2nPewYcMEgAY/kydPNu6TlpYm2rdvLwICAkS7du3EyJEjxdatW114RsrYct7z588X11xzjQgKChKtW7cWQ4YMEevWrWtwTG/7voUQ4s8//xTNmjUTH3zwgdnjecL3bZg6ben31luvb1vP21uub1vP21uub3t+z73h+jZ3zgDE0qVLjfu46xqXLjeQiIiISJM8KmeIiIiIyNEYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIo+UkZGBoKAgFBcXG7c99NBD6NmzJ8rKytzYMiLyNFybjIg8khACvXv3RkJCAhYvXoz09HT861//wrZt2xAdHe3u5hGRB/FzdwOIiOwhSRJee+01jBs3DlFRUVi0aBFyc3MZCBGRzdgzREQe7YYbbsCvv/6K9evXY9iwYe5uDhF5IOYMEZHH+vbbb7Fv3z7o9XqEh4e7uzlE5KHYM0REHmnnzp1ITEzEe++9h8zMTDRv3hyff/65u5tFRB6IOUNE5HEOHz6MUaNGYcaMGZg0aRK6deuG/v37Y8eOHejbt6+7m0dEHoY9Q0TkUUpLSzF48GAMHToU//d//2fcPmbMGFRVVeGbb75xY+uIyBMxGCIiIiJNYwI1ERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNP+HyKTAN3zbiBYAAAAAElFTkSuQmCC", "text/plain": [ "
    " ] @@ -440,73 +440,73 @@ "Own inversion\n", "[[4.]\n", " [3.]]\n", - "Eigenvalues of Hessian Matrix:[0.27750534 4.13217667]\n", - "0 [-10.24816468] [-11.05638246]\n", - "1 [-0.1602625] [0.14404536]\n", - "2 [-0.14949972] [0.13437168]\n", - "3 [-0.13945974] [0.12534765]\n", - "4 [-0.13009402] [0.11692966]\n", - "5 [-0.12135727] [0.10907699]\n", - "6 [-0.11320726] [0.10175169]\n", - "7 [-0.10560458] [0.09491833]\n", - "8 [-0.09851247] [0.08854388]\n", - "9 [-0.09189665] [0.08259753]\n", - "10 [-0.08572513] [0.07705051]\n", - "11 [-0.07996807] [0.07187601]\n", - "12 [-0.07459764] [0.06704902]\n", - "13 [-0.06958788] [0.0625462]\n", - "14 [-0.06491455] [0.05834577]\n", - "15 [-0.06055507] [0.05442743]\n", - "16 [-0.05648836] [0.05077224]\n", - "17 [-0.05269476] [0.04736252]\n", - "18 [-0.04915593] [0.04418179]\n", - "19 [-0.04585476] [0.04121466]\n", - "20 [-0.04277528] [0.0384468]\n", - "21 [-0.03990261] [0.03586482]\n", - "22 [-0.03722287] [0.03345624]\n", - "23 [-0.03472308] [0.03120942]\n", - "24 [-0.03239118] [0.02911348]\n", - "25 [-0.03021588] [0.0271583]\n", - "26 [-0.02818667] [0.02533443]\n", - "27 [-0.02629373] [0.02363304]\n", - "28 [-0.02452792] [0.02204591]\n", - "29 [-0.02288069] [0.02056537]\n", + "Eigenvalues of Hessian Matrix:[0.27227895 4.125757 ]\n", + "0 [-11.75978215] [-12.89770892]\n", + "1 [-0.06807123] [0.06136823]\n", + "2 [-0.06357887] [0.05731824]\n", + "3 [-0.05938299] [0.05353553]\n", + "4 [-0.05546402] [0.05000245]\n", + "5 [-0.05180367] [0.04670255]\n", + "6 [-0.04838489] [0.04362042]\n", + "7 [-0.04519174] [0.04074169]\n", + "8 [-0.04220931] [0.03805295]\n", + "9 [-0.03942371] [0.03554165]\n", + "10 [-0.03682195] [0.03319608]\n", + "11 [-0.03439189] [0.03100531]\n", + "12 [-0.0321222] [0.02895911]\n", + "13 [-0.0300023] [0.02704796]\n", + "14 [-0.0280223] [0.02526293]\n", + "15 [-0.02617297] [0.02359571]\n", + "16 [-0.02444569] [0.02203851]\n", + "17 [-0.0228324] [0.02058408]\n", + "18 [-0.02132557] [0.01922564]\n", + "19 [-0.01991819] [0.01795684]\n", + "20 [-0.0186037] [0.01677178]\n", + "21 [-0.01737595] [0.01566493]\n", + "22 [-0.01622922] [0.01463112]\n", + "23 [-0.01515818] [0.01366555]\n", + "24 [-0.01415781] [0.01276369]\n", + "25 [-0.01322347] [0.01192135]\n", + "26 [-0.01235079] [0.0111346]\n", + "27 [-0.0115357] [0.01039977]\n", + "28 [-0.0107744] [0.00971344]\n", + "29 [-0.01006335] [0.0090724]\n", "theta from own gd\n", - "[[3.92308585]\n", - " [3.06913112]]\n", - "0 [-0.02134409] [0.01918426]\n", - "1 [-0.01991068] [0.01789589]\n", - "2 [-0.01814351] [0.01630755]\n", - "3 [-0.01639489] [0.01473588]\n", - "4 [-0.01476927] [0.01327475]\n", - "5 [-0.01328972] [0.01194492]\n", - "6 [-0.01195336] [0.01074379]\n", - "7 [-0.0107497] [0.00966192]\n", - "8 [-0.00966668] [0.0086885]\n", - "9 [-0.00869259] [0.00781297]\n", - "10 [-0.00781659] [0.00702562]\n", - "11 [-0.00702885] [0.00631759]\n", - "12 [-0.00632049] [0.00568091]\n", - "13 [-0.00568352] [0.00510839]\n", - "14 [-0.00511073] [0.00459357]\n", - "15 [-0.00459568] [0.00413064]\n", - "16 [-0.00413253] [0.00371435]\n", - "17 [-0.00371605] [0.00334002]\n", - "18 [-0.00334155] [0.00300342]\n", - "19 [-0.00300479] [0.00270073]\n", - "20 [-0.00270197] [0.00242856]\n", - "21 [-0.00242967] [0.00218381]\n", - "22 [-0.00218481] [0.00196372]\n", - "23 [-0.00196462] [0.00176582]\n", - "24 [-0.00176663] [0.00158786]\n", - "25 [-0.00158859] [0.00142784]\n", - "26 [-0.00142849] [0.00128394]\n", - "27 [-0.00128453] [0.00115455]\n", - "28 [-0.00115508] [0.00103819]\n", - "29 [-0.00103867] [0.00093356]\n", + "[[3.96547946]\n", + " [3.03112129]]\n", + "0 [-0.00939922] [0.00847367]\n", + "1 [-0.00877892] [0.00791445]\n", + "2 [-0.00801346] [0.00722437]\n", + "3 [-0.00725498] [0.00654058]\n", + "4 [-0.00654864] [0.00590379]\n", + "5 [-0.00590456] [0.00532314]\n", + "6 [-0.00532167] [0.00479764]\n", + "7 [-0.0047956] [0.00432337]\n", + "8 [-0.00432129] [0.00389577]\n", + "9 [-0.00389382] [0.00351039]\n", + "10 [-0.0035086] [0.00316311]\n", + "11 [-0.00316149] [0.00285017]\n", + "12 [-0.00284871] [0.0025682]\n", + "13 [-0.00256688] [0.00231412]\n", + "14 [-0.00231293] [0.00208517]\n", + "15 [-0.0020841] [0.00187888]\n", + "16 [-0.00187791] [0.00169299]\n", + "17 [-0.00169212] [0.0015255]\n", + "18 [-0.00152471] [0.00137458]\n", + "19 [-0.00137387] [0.00123858]\n", + "20 [-0.00123795] [0.00111605]\n", + "21 [-0.00111547] [0.00100563]\n", + "22 [-0.00100511] [0.00090614]\n", + "23 [-0.00090567] [0.00081649]\n", + "24 [-0.00081607] [0.00073571]\n", + "25 [-0.00073534] [0.00066293]\n", + "26 [-0.00066259] [0.00059734]\n", + "27 [-0.00059703] [0.00053824]\n", + "28 [-0.00053797] [0.00048499]\n", + "29 [-0.00048474] [0.00043701]\n", "theta from own gd wth momentum\n", - "[[3.99663433]\n", - " [3.00302509]]\n" + "[[3.99839581]\n", + " [3.00144622]]\n" ] } ], @@ -585,17 +585,17 @@ "output_type": "stream", "text": [ "Own inversion\n", - "[[3.81924504]\n", - " [3.09224244]]\n", - "Eigenvalues of Hessian Matrix:[0.31096156 4.57735536]\n", - "0 [-15.77829399] [-18.53684024]\n", - "1 [-3.15242624e-15] [-1.65243388e-16]\n", - "2 [3.85975973e-17] [5.35468713e-17]\n", - "3 [3.85975973e-17] [5.35468713e-17]\n", - "4 [3.85975973e-17] [5.35468713e-17]\n", + "[[3.81818338]\n", + " [3.12840176]]\n", + "Eigenvalues of Hessian Matrix:[0.26024513 4.64291046]\n", + "0 [-16.3824865] [-20.20867716]\n", + "1 [9.71640303e-15] [1.05750493e-14]\n", + "2 [-2.05998413e-17] [-2.11570114e-16]\n", + "3 [6.96057795e-17] [1.90885733e-16]\n", + "4 [6.96057795e-17] [1.90885733e-16]\n", "beta from own Newton code\n", - "[[3.81924504]\n", - " [3.09224244]]\n" + "[[3.81818338]\n", + " [3.12840176]]\n" ] } ], @@ -660,30 +660,24 @@ "output_type": "stream", "text": [ "Own inversion\n", - "[[3.84019294]\n", - " [3.22756518]]\n", - "Eigenvalues of Hessian Matrix:[0.2729933 4.56108455]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "[[3.6955259]\n", + " [3.2809076]]\n", + "Eigenvalues of Hessian Matrix:[0.31381731 4.50516278]\n", "theta from own gd\n", - "[[3.84019294]\n", - " [3.22756518]]\n" + "[[3.6955259]\n", + " [3.2809076]]\n" ] }, { "data": { - "image/png": "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jcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBEREZGqMRgiIiIiVWMwRERERKrmNcHQO++8g4SEBISEhKBjx47YunWrp4tEREREPsArgqHVq1dj2rRpeP7557Fr1y706tULAwcOxIkTJzxdNCIiIvJykhBCeLoQtnTp0gUdOnTAu+++a1qWmJiIYcOGYf78+Tb3LyoqQlhYGAoLCxEaGurKohIREZFM3PX8VnzN0PXr1/H777+jf//+Zsv79++PX375xUOlIiIiIl8R4OkC2HLu3DnodDpERUWZLY+KikJ+fr7FfUpLS1FaWmp6XVhYCMAQYRIREZF3MD63Xd2IpfhgyEiSJLPXQogqy4zmz5+PuXPnVlkeHx/vkrIRERGR65w/fx5hYWEuO77ig6GGDRvC39+/Si1QQUFBldoio1mzZiEtLc30+tKlS2jatClOnDjh0jdTaYqKihAfH4/c3FxV9ZXidfO61YDXzetWg8LCQjRp0gTh4eEuPY/ig6GgoCB07NgRGzZswPDhw03LN2zYgNTUVIv7BAcHIzg4uMrysLAwVX2JjEJDQ3ndKsLrVhdet7qo9br9/FzbxVnxwRAApKWlYezYsejUqRO6deuGZcuW4cSJE/jHP/7h6aIRERGRl/OKYOj+++/H+fPn8eKLLyIvLw9JSUn49ttv0bRpU08XjYiIiLycVwRDADBx4kRMnDjRqX2Dg4Mxe/Zsi01nvozXzetWA143r1sNeN2uvW6vmHSRiIiIyFUUP+kiERERkSsxGCIiIiJVYzBEREREqsZgiIiIiFTNK4Ohd955BwkJCQgJCUHHjh2xdevWarffvHkzOnbsiJCQENxyyy147733qmyTnp6OVq1aITg4GK1atcKaNWtcVXynOXLdWq0Wd999Nxo1aoTQ0FB069YNP/zwg9k2y5cvhyRJVX5KSkpcfSkOceS6MzMzLV7TwYMHzbbztc97woQJFq+7devWpm284fPesmULhg4dipiYGEiShLVr19rcxxfub0ev21fub0ev21fub0ev21fu7/nz5+OOO+5AvXr1EBkZiWHDhuHQoUM293PHPe51wdDq1asxbdo0PP/889i1axd69eqFgQMH4sSJExa3z8nJwaBBg9CrVy/s2rULzz33HKZOnYr09HTTNtu3b8f999+PsWPHYs+ePRg7dixGjRqFX3/9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", + "image/png": "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Cy+8UGN7fHy8R9pGREREnnPp0iWEh4d77PyKD4aaNGkCf3//Gr1A+fn5NXqLTNLS0jB79mzzz1evXkWLFi1w6tQpj76ZSlNYWIj4+Hjk5uZqKleK183r1gJeN69bCwoKCpCQkICIiAiPvo7ig6GgoCB0794dmzZtwvjx483bN23ahLFjx1p9TnBwMIKDg2tsDw8P19QvkUlYWBivW0N43drC69YWrV63n59nU5wVHwwBwOzZszF58mT06NEDffr0wYoVK3Dq1Ck88sgjcjeNiIiIVE4VwdDdd9+NS5cu4R//+AfOnTuHTp064auvvkKLFi3kbhoRERGpnCqCIQCYPn06pk+f7tJzg4ODMW/ePKtDZ76M183r1gJeN69bC3jdnr1uVRRdJCIiIvIUxRddJCIiIvIkBkNERESkaQyGiIiISNMYDBEREZGmqTIYevvtt5GYmIiQkBB0794d27dvr/X4rVu3onv37ggJCUGrVq2wfPnyGsfodDp06NABwcHB6NChA9auXeup5rvMmevOyMjA8OHD0bRpU4SFhaFPnz745ptvLI5ZtWoVJEmq8SgpKfH0pTjFmevOysqyek2HDx+2OM7XPu/777/f6nV37NjRfIwaPu9t27ZhzJgxiI2NhSRJWLdund3n+ML329nr9pXvt7PX7Svfb2ev21e+3wsXLkTPnj3RsGFDREVFYdy4cThy5Ijd53njO666YOjTTz/FrFmz8Oyzz2LPnj0YMGAARo4ciVOnTlk9PicnB3fccQcGDBiAPXv24G9/+xueeOIJ6HQ68zE7duzA3XffjcmTJ2Pfvn2YPHkyJkyYgJ9++slbl2WXs9e9bds2DB8+HF999RV++eUXDBkyBGPGjMGePXssjgsLC8O5c+csHiEhId64JIc4e90mR44csbim1q1bm/f54uf9+uuvW1xvbm4uIiIicNddd1kcp/TPu6ioCF26dMGyZcscOt5Xvt/OXrevfL+dvW4TtX+/nb1uX/l+b926FTNmzMDOnTuxadMmVFRUYMSIESgqKrL5HK99x4XK9OrVSzzyyCMW29q1ayfmzp1r9fi//vWvol27dhbbpk2bJnr37m3+ecKECeL222+3OOa2224T99xzj5taXXfOXrc1HTp0EC+88IL555UrV4rw8HB3NdEjnL3uzMxMAUBcuXLF5jm18HmvXbtWSJIkTpw4Yd6mhs+7KgBi7dq1tR7jK9/vqhy5bmvU+P2uypHr9pXvd1WufN6+8P0WQoj8/HwBQGzdutXmMd76jquqZ6isrAy//PILRowYYbF9xIgR+PHHH60+Z8eOHTWOv+222/Dzzz+jvLy81mNsndPbXLnu6gwGA65du1Zjsbvr16+jRYsWiIuLw+jRo2v8ZSmnulx3t27dEBMTg6FDhyIzM9NinxY+7/feew/Dhg2rUaVdyZ+3K3zh++0Oavx+14Wav9/u4Cvf74KCAgCodRFWb33HVRUMXbx4EXq9vsZq9dHR0TVWtTfJy8uzenxFRQUuXrxY6zG2zultrlx3da+88gqKioowYcIE87Z27dph1apV2LBhA9asWYOQkBD069cPx44dc2v7XeXKdcfExGDFihXQ6XTIyMhA27ZtMXToUGzbts18jK9/3ufOncN///tfPPjggxbblf55u8IXvt/uoMbvtyt84ftdV77y/RZCYPbs2ejfvz86depk8zhvfcdVsxxHVZIkWfwshKixzd7x1bc7e045uNrGNWvWYP78+Vi/fj2ioqLM23v37o3evXubf+7Xrx9uueUWvPnmm3jjjTfc1/A6cua627Zti7Zt25p/7tOnD3Jzc7FkyRIMHDjQpXPKxdU2rlq1Co0aNcK4ceMstqvl83aWr3y/XaX277czfOn77Spf+X4/9thjyM7Oxvfff2/3WG98x1XVM9SkSRP4+/vXiPby8/NrRIUmzZo1s3p8QEAAIiMjaz3G1jm9zZXrNvn000/xl7/8BZ999hmGDRtW67F+fn7o2bOnYv6SqMt1V9W7d2+La/Llz1sIgf/7v//D5MmTERQUVOuxSvu8XeEL3++6UPP3213U9v2uC1/5fj/++OPYsGEDMjMzERcXV+ux3vqOqyoYCgoKQvfu3bFp0yaL7Zs2bULfvn2tPqdPnz41jv/222/Ro0cPBAYG1nqMrXN6myvXDRj/Yrz//vuxevVqjBo1yu7rCCGwd+9exMTE1LnN7uDqdVe3Z88ei2vy1c8bMM7WOH78OP7yl7/YfR2lfd6u8IXvt6vU/v12F7V9v+tC7d9vIQQee+wxZGRkYMuWLUhMTLT7HK99xx1OtVaITz75RAQGBor33ntPHDx4UMyaNUuEhoaas+rnzp0rJk+ebD7+999/F/Xr1xdPPvmkOHjwoHjvvfdEYGCgSE9PNx/zww8/CH9/f/Hyyy+LQ4cOiZdfflkEBASInTt3ev36bHH2ulevXi0CAgLEW2+9Jc6dO2d+XL161XzM/Pnzxddffy1+++03sWfPHjF16lQREBAgfvrpJ69fny3OXvdrr70m1q5dK44ePSoOHDgg5s6dKwAInU5nPsYXP2+Te++9V9x6661Wz6mGz/vatWtiz549Ys+ePQKAePXVV8WePXvEyZMnhRC++/129rp95fvt7HX7yvfb2es2Ufv3+9FHHxXh4eEiKyvL4ve2uLjYfIxc33HVBUNCCPHWW2+JFi1aiKCgIHHLLbdYTMubMmWKGDRokMXxWVlZolu3biIoKEi0bNlSvPPOOzXO+fnnn4u2bduKwMBA0a5dO4svl1I4c92DBg0SAGo8pkyZYj5m1qxZIiEhQQQFBYmmTZuKESNGiB9//NGLV+QYZ6570aJF4qabbhIhISGicePGon///mLjxo01zulrn7cQQly9elXUq1dPrFixwur51PB5m6ZO2/q99dXvt7PX7Svfb2ev21e+3678nvvC99vaNQMQK1euNB8j13dc+qOBRERERJqkqpwhIiIiIndjMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiFRpzZo1CAkJwZkzZ8zbHnzwQSQlJaGgoEDGlhGR2nBtMiJSJSEEunbtigEDBmDZsmV44YUX8J///Ac7d+5E8+bN5W4eEalIgNwNICJyhSRJWLBgAVJTUxEbG4vXX38d27dvZyBERE5jzxARqdott9yCX3/9Fd9++y0GDRokd3OISIWYM0REqvXNN9/g8OHD0Ov1iI6Olrs5RKRS7BkiIlXavXs3Bg8ejLfeeguffPIJ6tevj88//1zuZhGRCjFniIhU58SJExg1ahTmzp2LyZMno0OHDujZsyd++eUXdO/eXe7mEZHKsGeIiFTl8uXL6NevHwYOHIh///vf5u1jx45FaWkpvv76axlbR0RqxGCIiIiINI0J1ERERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJN+38QUSereiPytAAAAABJRU5ErkJggg==", "text/plain": [ "
    " ] }, "metadata": { "filenames": { - "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_2.png" + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_1.png" } }, "output_type": "display_data" @@ -693,8 +687,8 @@ "output_type": "stream", "text": [ "theta from own sdg\n", - "[[3.85298956]\n", - " [3.28358004]]\n" + "[[3.6805151 ]\n", + " [3.33045013]]\n" ] } ], @@ -793,15 +787,15 @@ "output_type": "stream", "text": [ "Own inversion\n", - "[[4.1356995 ]\n", - " [3.09209032]]\n", - "Eigenvalues of Hessian Matrix:[0.31362428 4.21949761]\n", + "[[3.98751068]\n", + " [2.92901115]]\n", + "Eigenvalues of Hessian Matrix:[0.28244905 4.61501312]\n", "theta from own gd\n", - "[[4.13531906]\n", - " [3.09242193]]\n", + "[[3.98556236]\n", + " [2.93059014]]\n", "theta from own sdg with momentum\n", - "[[4.25003261]\n", - " [3.05169046]]\n" + "[[4.01133846]\n", + " [2.92452609]]\n" ] } ], @@ -918,9 +912,9 @@ "output_type": "stream", "text": [ "theta from own AdaGrad\n", - "[[2.00006114]\n", - " [2.99959609]\n", - " [4.00040218]]\n" + "[[1.99974365]\n", + " [3.0013839 ]\n", + " [3.99861193]]\n" ] } ], @@ -1026,9 +1020,9 @@ "output_type": "stream", "text": [ "theta from own RMSprop\n", - "[[1.99952851]\n", - " [3.00380258]\n", - " [3.995522 ]]\n" + "[[1.99757634]\n", + " [2.9983289 ]\n", + " [3.99759503]]\n" ] } ], @@ -1132,9 +1126,9 @@ "output_type": "stream", "text": [ "theta from own ADAM\n", - "[[1.99984836]\n", - " [3.00097416]\n", - " [3.99895448]]\n" + "[[1.99993596]\n", + " [3.00035483]\n", + " [3.99963172]]\n" ] } ], @@ -1262,7 +1256,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 11, @@ -1338,7 +1332,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 12, diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.py b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.py index 442066eb7..3cf3b7ea0 100644 --- a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.py +++ b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.py @@ -92,7 +92,7 @@ theta = np.random.randn(2,1) eta = 1.0/np.max(EigValues) Niterations = 1000 - +#while (iter <= Ni... or test) for iter in range(Niterations): gradients = 2.0/n*X.T @ ((X @ theta)-y) theta -= eta*gradients diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_16_2.png b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_16_2.png index e9439ac0aa6c8808be6433aa47866b2d0bb71f53..0d1102c6be52b2eabab4bbf97bae20965c52662e 100644 GIT binary patch literal 22302 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 al)p(3Ya8}Z*$Y;!n5CHwEz8vT%s&C`p}gP# literal 21978 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%0AP!~Y&f;rQm+KKjtORDsLi#AD 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 diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_1.png b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_1.png index 63a694a365d630555eeb7df1a452ffa33b2bc604..7f7f05923cdf78570b1fa43d3d456c4bfe491532 100644 GIT binary patch literal 22492 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 literal 20216 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 diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_5_1.png b/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_5_1.png index 088571c87a8b367d701bb9c9ae7767823a7f75b5..bc123afa507d9de44aee00c4744f4dca68004e42 100644 GIT binary patch literal 22024 zcmdSBWmsKJur9c9clRKH;1Jvi9z29VaJK-#-2=g$5Q1BR1$TE1!9s9%clYW2ednAx zGjs2AXYRk@d3Lhdd#zsG)zwvRRlP-+sOAKC#42~z)C_OFg?hK;FA;n zhc57+fV1>_=eKs|&TdAIW)LMKXL}nvXB#WyXRc7t39_@> z{?`R;c8(V8JQX!R!5}F1a#~Ih2$m7_1ydlFZv}z8b9pWGO5Hu}V8O#1&+HNDSjAKF z$7e!$70XxAUma;fbW7&xkachp3C1q88>Dm*CKnK#;}YM&_n4d*Pf#s?Kx>S8hRmAf zkM_xN2|+&lOVy9hUwJ)z{kntllxE2jOyh5w4a%CIaU~3JB`9vCZe5EqQ3pYAaB$)z zZaf+xQs5_}+b|UT;74^}gU=aB1F30fXwO>h4MXLEzp@)(Cd!+6!o$Nqqo+s261{#FO(C>d;W(5oM8uT%%jD~K|@2(%TDn-S`+!Lg@aZb~UGV9Wj0b`%h zh!h8Z4Gx~%pN-@yB(Wi5VaZBK!QYV%{>?R# zWi_4`8W|}iBZD}cE~L3Py)~S!V@(wn7Uq6FCTo4*G@hsAemcN_LqZZ(Ud|zW+E4p} znOV}vh`Kk5ECjr0fsp-f$1_#6w6v_-JXg|3^sW*R~D;Sx1nC@9w2*h@-mWTCcK|y;Wv*vNW*aM1#gG0T` z9%1X#qnD|v>2iXKXa{YKuyHL`iAF@aklX4;l0h$p+k61nlvTI3JBny>flnGG+At8_ zkMp5pxw5$`nWFD&J`gwyQV_D~S`r4q_+!JG^hS1owQ_o0+MFLPQF&b*_M{0omHXVe z+AOtFfH~(K_&r=`{>~5~V{bXf?dpP8pB>$|0=XsB)#7o*=@9rbMtCQ*pG()8d+(FtXG zpN2u6x$aL>GchywTMm6?$doOGO=+sr7Jy-5^^@k-}s z^P{sKA_HWI@l2&zo*Ao7Ej|V*H#V3z59=M+UU&!&9v`A)$7yH@$gh z+*W_+sy5Jw*zh6UH)mTz(LTdz0yURom1YW@4y)bTcWHtyMKi8ot8pORInoiozq;-G zk#^pj96A?fXIFugdp;s!QQBzp+DvocP*JgmM??%=3Yh)E$HB#=Db;PD3BsmfV337i z!y%#|Uam|O$A`Z!s(eVS^^5qpVA{dn#f*-QY7a^1H9Ei2)lJ*+aCCeLk@PDF#vq&2 z{>bvy=dk5UziKO8(4}(k;;SV$Y1LNm%fg9W?LpR-n3}UXvq8dbXTdK?NhaU`UoRZ_ zhJZVBii&=n6AL)f0b^ES(uY~)vk26uW-%Yg{(X}xtNBpM=lOZv`DTyt6%%?jCSbE) zUhd>)8Uv#;U2TPz;d^UEF6fMmC2}4+!wU=sG2ch>)z#JGo2^WfyUT;=1}BEc;}Ef| z=H})}QCeDBYgRN&Ox^{lGW{0R7X6s*?QQM330>ElQ!^l_EUhYY^Fd%cb8>U7c_x4d z_$Gpdidy8<@Z(fR?d)5mlG89e;^mhKHGz`!Hl4bU+11tfN$dtP@7@tC`rg^XBO<1V z$V8K)KPoz+uHU@VOx9jix|@Tmusp_vK3vd+T*43zDj|^k>PV8L-XZ+~X4xPHJm9 zX_=bR6%`fPpR7t(`O6^(baqP2yG-d}CUy{f3Jhe;z|*`asc?P#^y!m*AB7uK5gs2O zzi}AB(yL_HI8eQQ{n~tlb;BJM1EZ(eU$t`g<$o?QcFS|gk=8s z3e?m^B}Wf4)6c zMs<626l0O$fe74Tz3+oyG?iHN)8kbeZ&WZaQbgRO7=kXlLG(%~%cI$nP%k!`uR>Mj z`(DbF0^kI8E|*<(7QIG%_O|<%P;m%fPMf@7V(Pp*YKw^xdn7K=uIVh+ss5um4G&pUoLS5SZ&DmJB)mz1H957|A zw?#AMo+@4|pNUk})II^Lymm2VAPZc^N#@f%Qm$-_>%g5-@=Jt`jg4=-wxr?V;b6K* zmNnW?fmJKX%cHs;Ek;3Q?RPV1psKDO1bkhtQYvqrujEC;R)*K{5Z}@=cy&jS@nI7Y zg~(ERzym)QuMi#4PgEF$-8ugG8F103_?IOAH$3(~2Xf*4T;Hem91iCNfcEwq3wnV& zEav-!zmy%HVX2f)&Tc#xCy|12h;12h;=D-lNI~W*XuTe+zIRT?6Q7 zXlM3T;6eR_&!0b+lau3E=+l$N>4>ec0@@x4MUiny4lYDQu37Zp8UGC|{?8}(zd)J) zA8$N!=coquG?J7DwW6W|0G{_%=1~*2nZOzX+rXmVJZ-xH3=PfF=7}M2mFNJb^a6Lh zH~(=ch36XBPi!)>y}WoR;>CprP?c6DvK{#K-TAz%EXdnD#SUPEk!rLL{^Jt&X7d73 zaOm;q72DC+oBe?!ac|@Y=5gIbSf5Khb4uR}0|o{Ls6xt6Sz$qeIIvVZ9>5JVhs%Jg zM8zk0B*mWYxxTV!L6u4JhuX}2BLW)XGhyNRb0A-PBgQZw?bHE5;@L(QW~e#=JOTAw z&z?c@RWf_eM#N&eyQO}XrHXj*0yn7?bARuBMUVo-)*N1(IzX@Z&A%fMDV3EBoL%TI zP~^P32TULiIr;wXDs-V($L<{J+S=i3eKDySTN@iINd~^J0BF{(whZX+m#aE}gM-7N zponrkm~Ch(fG#djm=gV9wgwG&%)Biw^WPANVj4frU=sV4Y9V;C93%K17_nE#MrW7# z%IS`JM$k_kOcw&66YHP&pM@0Q%m2Mt|ZRBHvw@7yv*?@JR)TTeSC}Kz^agZ4GLLp;o52 zn1x)#6aQ+_s|-nA9_(AI-18vp47Q*+`5&FT6F&iFBK|qIKi_}{JWKb^cs>-Xre5j* z!v>5tJ`oWu3yWgTA6%d!%nf^w6w8$&O>zznoa#&jqr(=xu5Q<4WN*&_w0A*W z5S-#u^GdAX$beA*kYW=O0)eus5CPGIdWZG}X8-x4MlR+%4@Hz%ZTF{W;Cdk52ym_O z)!{<_@NlqlJ~X(30DB4x0=x_+UT_+2kYlh)Muvu@Jv}{3Ht-mfyXPC60Msx&aS;#@ zkW)~o+7aQe&H(bidtq+rqpeN48{TL71@WK9#!f}jL#>M=!vDJv`hQPt372JCXwlNxP;2jDy4G;My9-V9T=+>;yKTcOGy87Vg9S5Sf^- zb~n2n&}4<&VKa4CRhwAs*UcR@{-7bK+Bt5*kz{N{|KomiZ{&h48ve;r&}oXsuV@|q zV{8TzV@%z@3jMP!jvKW9tIHe0m66srVVN~aA6-oUCSgJErPrf_?kpqTb59TOh_@(4 zj2;1YjEs!0+}-(s>BS)=+}v5k#)&KAqL(lBh~VM1t&r)XKWy}?N{$2*mv8;{;!XIb zD9OK*dv2icR+Wnj!=5f4CVBq&(9;2_M=QJy6&CoEgn>2KO6R->Ija?O~OK21Nk?LmFlJQJf~d z5RSj7J-xlgAeZt@z=g?Dvf$tmd1%3-NwJ6_Jf((xgT~Kb^O#%kg=lK8ch~qGEIdt-G{) zh6Uy2*pSg?52vaPFfYE6D$|Zn2p|E(CxVNMtE;UH?1jUnGtKZX*bJ}XQ{UCKfCi_% zQUX}?y{!?q%F(upd;>L~^fuOHQN7B%*7&OD*Sj|d?!`kI-SB$7Spx%@2YvdLn8A_i zJTz9+QYB^+Lm&sy)6+9S4GeQm+*k98&rV0$k)^nsSCy1kYQMN~SlRCpwmD57F zzbA*6CiEIjALoaMCuG|OyHZUYIbRs_rO*d0KT7+Q-@E(ahnd&I9a_!Axp3f9P+&l6 zJ_G=d|6zjg9T7QsBuEKWA%SDRus=YeZh)5{k0AUcj7?xR=Vj2kKY#4y^@*QWN62sL zN5=3(oxGjVnwZ;K!^hMy-WOO0!3;*dQ&!W?HDpXULA3!M-^N6U$PAVOn?GT14Vu7d zsq{gksqJk`o9S{Gy(U)#$b6#Em;87XLLE?T&qQPC6u8kIMf7fx@0* zK`|9^l@L*8KhRU0@o$25&QL5J<>9%6 zcbJg07^OY^ppPIyKDQHC%}aNlE_7cg5VpK7V}nQ&_UJQy8RW z*RgdR5rIYb@Ce?j{kR7X#x>3Hh@ZBvLE^850bM62jPxISZ#AQzr4Oq*IX^a2`|mA1 zxhBloZAquG`lHswyu%_u#g5p@X=@KP@{CMdB;?d9zPhOC)w{C$$2huhx=JDb4kTCL z8l7vj^$Ei;aEEzcKYH?V4zK&&5tn+*FS5jIhZz`CKVOVGUy;zBcW)sO-w9ZnwWlIc zozLwdRQC78?cXDSX*xBu0g#l-fRf6f>9Y5$t?g@@`VWatUAs{}e*Uvzlu;u@?6r*8 zjqcmHqCUGw!lTAyDW4a`Z=Ljxdq=F?n?B%DwlnFf@o>%QC&ohFndglM#0piI1D)t6 zbm1YJsVc!&dSCnNS5ebZ41xsv@m`W__QSDorJK}h{vS;2iCyKCA~qw_KSq`^cP88C z_(6ROMt2?+2~CGflt zSVTUXYpa@Nhm@6W<&%UMlD(ske9@g(zZYkEjda1~M@2NGw8{357n?6Ey%&zQ(WGJy zm?@+hmbjZlG2P;p8vYSoAg(gr82qAZdHX>XtEj!-V(!^v=_O=V;VmVJG03O44rZ8R z(70Jm7C+kV&tR7CH0i(7|9n72DSm08nf<_niNrJu3FRwMLGKR{yrJV>lZfMePCy;y zHS<8Z7!KUt4ZVWT^VKzsba@JjQboGYDd|7c7fPd#Za1Q>-d}A}TecxgroZlZH#Sop zCRSwcHVtEWtN;0S$NhWc2aLqb#IPZsdrxDe4>YGDlfkSyq^L^kAA60CT+Bk1<;rcR zn-Y&2SCUb$*2Ma|-;bXnPY^^}dLXB~VM6y}Lr{t*oifnJ(pUM-MMn)(2vuzSUt&TUbp-Fv2VPlj zP#ZD;{)n^V93J3yEndN@`7vC`J3Jt@{$XS4SH(^GL;qtA`mE&Z{-2F_?df?Jj2(U1 zJKlu5A*suU3_{PIt-IO>!G?uw>*U1lh2;)}_VWpFFyO@rrOoLfAFSq%enjpK?o^)_ zFR;?%_!YP4O!e1_FDqjf^)+1a`UA{&iW~zf#xe$>cs@tVmLM<_#xGbFzn>pvm;Eu> zYQvJaJ5uOhoFMo5NS|5~b0LJ~GG{Vs3U4x6RfrsgT2sk@R=fd$Md#sD+l0igdRB6I z&<0YY{8I^XV-kHEc@Y7Ih{9aTunCD+b#0>{INv7m#7b7bNpgv9ojSzyVawtToQ@eXI+{0WF>fq%w2*e z$r;>3735iuNt;(EsgA@T$fLvDlqSZ7l<=P;QBhxsUAMOPZDmz5F{8QfG6Jk|whXNhf_?k~lNIF~5-!{fK`_TYe;%WUF?260c% zhq;aQZ$C)wryf$FVitOFL4Tk;nZk*RiazM$qFh(ZvfO&dQr6@>Q_jYP*WWL`vPk27 zw~1ppg=GBDfcZk2Z#*xc{&RJxk17_+XHQ3(L-N0<;>=g%f%5~x9<(4MC)XOu^UA=_ zcKb;ck3l~%T5ZdDe8>MQ>)!7_ERZkod|j$-QP)dD(dK(O4{U~}d%2_cY}kRB2mUe@ zQM$T@>^&(!c1Z7wP>Nn7cPV+^I(JngwmK)c@_B7$RmOA9FxxI@A2|~+K~@Ne#vsA; z)sz@m6600KyL~yMw%%UX2;6RxuUgW6L&Zl!b5m$tZ?Dwq3GPqkGpUcH=;Lw|$DD0T z|Fo^l2vO73q^C95rDZr%L2H z?htctDursLJg)T4lLU&vih zshZo}=j3DwDVa&p#s2=;z7Kl>rA0+gy7Y9!wOo}KcVc!KgTvWr^?Q#)VDEvfQmiA_ z`8WI-UQaYT?tRU^Tv?SK+%wZ4OR9TLHCv}5kvfMhkR+G`OP%L}@g|sh>@J&9Eg)`u z_F1Vcg-?dffVl05fU7Bgg9uM9kM&P)?9>4|U>N%c-&>b*MoVyF{|$(gt0OqSp__$Varh^HVkTDCHeN8K0Y4^ii$(|$j)h>2)M<6@uOA>;Gr7uLeS zgv93qO*)7vTi0?RSYto>tvFX(_uN0OgTpJEXgbLSeHLq&+RF>xRrd%Ya+@+KTTp6f zy85bs$Cvn07d3^>#X(C;aUTPh;x)JB?>-Y-Pi)!2^^f|zHE7VW+5P-(9(NPrbSj;v zOcfw&*)|<~W%J#6b(gevgQ=sGR#D!1IuKi>J)zI!0gZbemh>_?QzneZSi1~6cT*FLLQG-@sb#g@JWxISbL zOoZrzI9_dnH0OdXCL7KS3QG(Y!xg%V3QV=WVor{`3j}BAuS17SQEBr@A$BW+TZ+nW z$>b)^jrL*>7~i5(I4s~P4 z+0x8w@D9|UrJU66jgM_gp?$NElRyu~?~Vv|{1wce$<=Vt6kEjp8T|~BXuvFc_~&8t zF&}*3M8AC|g#;f|o`eWFLUXox{w9-4xsRHfH-Rw-e+Wx{ zZEs7lbJz2A@p~g34~^miFR@-LN){j2$vhAHfGVMpFuw=is(L=p5X(@tDjN8;JmST3 zKjWQ;1{yo-R)xWpn)Scld#JeFCm@l=dS_TrS*g~1{zrj^lk-hbP*CXi?{v^AcJ}zr zuHT6rF*>6^trLVX9d|gnq@(W(Bj!~|MZ}kmWX{+U66^+!*pi|G+&QsnhQ~kbvd&ia z1sWA555r;kvv!0APaYvJT2z^C?(Xmno~Vu2O*6R=CEIR5Ihl=ymR8!;wYGn75YNE( z=12Wnv{3hIPlW9vQXn-#tPX}hpK7N-Rb6hyPrpP3z1+3n;hHIB1H31XkE!n8Cp5+s z-AvE=CWfH)F?q}G7|7rx|Wux1k*7A z@1jq#m&BK~;J>Bxg~H`C*0Xounp4z?mJdx&=(z zx5CMfEmX516A%+uP^DC>6)-U5T!@swRJ-cTcxT}HhPsm_@pis8-1wD9BPyy7WT>{k z(4^^oyOR&{ArdSGt@FFqATdk}`RiFe5*u?S9->y3|J})azhA&CoSU{WviUo0aj6=^ zW8J;~H!cp@b4&Lu4TszZ)Sflly3k^xx`_BsxGF?bbpxi{S$u{_yGz}DeG!1pkizP< zk*FyJcC5HHuen(lq<~W?Z*FeTgTHi=Rn>T={25OELeXcoh*SGLOUkshTu*q?Ji_wO zEnDN{5OsllGjAhQFOvelQGQN#J0AYaxnwuWzW75b8Q;hDk&zLbWKab>_iUM%f)Z2s z`KKqqUd6vU3!FNcblSA66l6?AGMmP^yzU+E*Y`x7Wpy(=ON=g%vKwy{vZs(V!4l^x z#)X1G=X}hMjCfkhISotwoFD@%6Gi$N&_BoMq^!ScHf%#V<9eEup# zt>>iHX;X31hEdjeAd7att_33#&u*OB8X1@mnD{l~)O#q`OFDM(y9# z;TOi{Zio9@nlC~^vEm<`$)WXIgQr`~V*M6UX=!PYjq8!b5(#R1IIu%TMXj`=N{bHc z50T@U`u4-0iMpfJV1qJ+Fn7CMx>(N}e#ZKtqV*ZVb7Z~}H1X$%+%rf+{Vf}l?BbzQQwvz2%#1i{pL|rY$)ARI8?U{YkojBKobb$_4 z@a-Z5-Gdilg|%~Unk?=LKv$hhXg-u)?P|=S) z9<`#)`?aMbDX)|5?{eXjl7@q_u^}kQB4c2|;fj=dgf8o$Uqkh#aF;!#B>h*3t;KmKT6^c` zi#Dpb)cS)*TNSk&D!=d=a_RD#13eYjcl& zA=q+#F-U9t7)$QpmTT~ts_3^qZeb%Gef2DphSJ>|T>+1YN5|=u>x!J5!-L2e_O>sZ z_t>x7L3$-bCcy`sVfURMNu!{i+k!h|BxSl=oni+}A0KM-mef))QxT7|A$>^X@Mev~9THrTfkC&Un=@H;8zSfeVS)%URA#46h+qL=wIcxU@{Q*L^%+h;n zmTe`E|JQ_!#^(bQsnmJ(k≶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 literal 22046 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

    0!=p8gEG%&L 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 diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.ipynb b/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.ipynb new file mode 100644 index 000000000..5409481e4 --- /dev/null +++ b/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.ipynb @@ -0,0 +1,498 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4b4c06bc", + "metadata": {}, + "source": [ + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "bcb25e64", + "metadata": {}, + "source": [ + "# Exercises week 42\n", + "\n", + "**October 14-18, 2024**\n", + "\n", + "Date: **Deadline is Friday October 18 at midnight**\n" + ] + }, + { + "cell_type": "markdown", + "id": "bb01f126", + "metadata": {}, + "source": [ + "# Overarching aims of the exercises this week\n", + "\n", + "The aim of the exercises this week is to get started with implementing a neural network. There are a lot of technical and finicky parts of implementing a neutal network, so take your time.\n", + "\n", + "This week, you will implement only the feed-forward pass. Next week, you will implement backpropagation. We recommend that you do the exercises this week by editing and running this notebook file, as it includes several checks along the way that you have implemented the pieces of the feed-forward pass correctly. If you have trouble running a notebook, or importing pytorch, you can run this notebook in google colab instead: (LINK TO COLAB), though we recommend that you set up VSCode and your python environment to run code like this locally.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c6f61b09", + "metadata": {}, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from autograd import grad" + ] + }, + { + "cell_type": "markdown", + "id": "6248ec53", + "metadata": {}, + "source": [ + "# Exercise 1\n", + "\n", + "Complete the following parts to compute the activation of the first layer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "37f30740", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(2024)\n", + "\n", + "\n", + "def ReLU(z):\n", + " return np.where(z > 0, z, 0)\n", + "\n", + "\n", + "x = np.random.randn(2) # network input\n", + "W1 = np.random.randn(4, 2) # first layer weights" + ] + }, + { + "cell_type": "markdown", + "id": "edf7217b", + "metadata": {}, + "source": [ + "**a)** Define the bias of the first layer, `b1`with the correct shape\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2129c19f", + "metadata": {}, + "outputs": [], + "source": [ + "b1 = np.random.randn(4)" + ] + }, + { + "cell_type": "markdown", + "id": "09e8d453", + "metadata": {}, + "source": [ + "**b)** Compute the intermediary `z1` for the first layer\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6837119b", + "metadata": {}, + "outputs": [], + "source": [ + "z1 = W1 @ x + b1" + ] + }, + { + "cell_type": "markdown", + "id": "6f71374e", + "metadata": {}, + "source": [ + "**c)** Compute the activation `a1` for the first layer using the ReLU activation function defined earlier.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8d41ed19", + "metadata": {}, + "outputs": [], + "source": [ + "a1 = ReLU(z1)" + ] + }, + { + "cell_type": "markdown", + "id": "088710c0", + "metadata": {}, + "source": [ + "Confirm that you got the correct activation with the test below.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4d2f54b4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "sol1 = np.array([0.60610368, 4.0076268, 0.0, 0.56469864])\n", + "\n", + "print(np.allclose(a1, sol1))" + ] + }, + { + "cell_type": "markdown", + "id": "7fb0cf46", + "metadata": {}, + "source": [ + "# Exercise 2\n", + "\n", + "Compute the activation of the second layer with an output of length 8 and ReLU activation.\n", + "\n", + "**a)** Define the weight and bias of the second layer with the right shapes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "00063acf", + "metadata": {}, + "outputs": [], + "source": [ + "W2 = np.random.randn(8, 4)\n", + "b2 = np.random.randn(8)" + ] + }, + { + "cell_type": "markdown", + "id": "5bd7d84b", + "metadata": {}, + "source": [ + "**b)** Compute intermediary `z2` and activation `a2` for the second layer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "2fd0383d", + "metadata": {}, + "outputs": [], + "source": [ + "z2 = W2 @ a1\n", + "a2 = ReLU(z2)" + ] + }, + { + "cell_type": "markdown", + "id": "1b5daae5", + "metadata": {}, + "source": [ + "Confirm that you got the correct activation shape with the test below.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f7f2f8a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "print(a2.shape == (8,))" + ] + }, + { + "cell_type": "markdown", + "id": "3759620d", + "metadata": {}, + "source": [ + "# Exercise 3\n", + "\n", + "We often want our neural networks to have many layers of varying sizes. To avoid writing very long and error-prone code where we explicitly define and evaluate each layer we should keep all our layers in a single variable which is easy to create and use.\n", + "\n", + "**a)** Complete the function below so that it returns a list `layers` of weight and bias tuples `(W, b)` for each layer, in order, with the correct shapes that we can use later as our network parameters.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "c58f10f9", + "metadata": {}, + "outputs": [], + "source": [ + "def create_layers(network_input_size, output_sizes):\n", + " layers = []\n", + "\n", + " i_size = network_input_size\n", + " for output_size in output_sizes:\n", + " W = np.random.rand(output_size, i_size)\n", + " b = np.random.rand(output_size)\n", + " layers.append((W, b))\n", + "\n", + " i_size = output_size\n", + " return layers" + ] + }, + { + "cell_type": "markdown", + "id": "bdc0cda2", + "metadata": {}, + "source": [ + "**b)** Comple the function below so that it evaluates the intermediate `z` and activation `a` for each layer, and returns the final activation `a`. This is the complete feed-forward pass, a full neural network!\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5262df05", + "metadata": {}, + "outputs": [], + "source": [ + "def feed_forward(layers, input):\n", + " a = input\n", + " for W, b in layers:\n", + " z = W @ a + b\n", + " a = ReLU(z)\n", + " return a" + ] + }, + { + "cell_type": "markdown", + "id": "245adbcb", + "metadata": {}, + "source": [ + "**c)** Create a network with input size 8 and layers with output sizes 10, 16, 6, 2. Evaluate it and make sure that you get the correct size vectors along the way.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89a8f70d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "306d8b7c", + "metadata": {}, + "source": [ + "# Exercise 4\n" + ] + }, + { + "cell_type": "markdown", + "id": "221c7b6c", + "metadata": {}, + "source": [ + "So far, every layer has used the same activation, ReLU. We often want to use other types of activation however, so we need to update our code to support multiple types of activation. Make sure that you have completed every previous exercise before trying this one.\n", + "\n", + "**a)** Make the `create_layers` function also accept a list of activation functions, which is used to add activation functions to each of the tuples in `layers`. Make new functions to not mess with the old ones.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "9df82312", + "metadata": {}, + "outputs": [], + "source": [ + "def create_layers_4(network_input_size, output_sizes, activation_funcs):\n", + " layers = []\n", + "\n", + " i_size = network_input_size\n", + " for output_size, activation in zip(output_sizes, activation_funcs):\n", + " W = np.random.rand(output_size, i_size)\n", + " b = np.random.rand(output_size)\n", + " layers.append((W, b, activation))\n", + "\n", + " i_size = output_size\n", + " return layers" + ] + }, + { + "cell_type": "markdown", + "id": "10896d06", + "metadata": {}, + "source": [ + "**b)** Update the `feed_forward` function to support this change.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "de062369", + "metadata": {}, + "outputs": [], + "source": [ + "def feed_forward_4(layers, input):\n", + " a = input\n", + " for W, b, activation in layers:\n", + " z = W @ a + b\n", + " a = activation(z)\n", + " return a" + ] + }, + { + "cell_type": "markdown", + "id": "efd07b4e", + "metadata": {}, + "source": [ + "**c)** Create and evaluate a neural network with 4 inputs and layers with output sizes 12, 10, 3 and activations ReLU, ReLU, softmax.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ce6fcc2f", + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.special import softmax\n", + "\n", + "network_input_size = 4\n", + "output_sizes = [12, 10, 3]\n", + "activation_funcs = [ReLU, ReLU, softmax]\n", + "layers = create_layers_4(network_input_size, output_sizes, activation_funcs)\n", + "\n", + "x = np.random.randn(network_input_size)\n", + "predict = feed_forward_4(layers, x)" + ] + }, + { + "cell_type": "markdown", + "id": "54d5fde7", + "metadata": {}, + "source": [ + "The final exercise will hopefully be very simple if everything has worked so far. You will evaluate your neural network on the iris data set (https://scikit-learn.org/1.5/auto_examples/datasets/plot_iris_dataset.html).\n", + "\n", + "This dataset contains data on 150 flowers of 3 different types which can be separated pretty well using the four features given for each flower, which includes the width and length of their leaves. You are not expected to do any training of the network or actual classification, unless you feel like it, in that case you can do exercise 5.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "6bd4c148", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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d999R9WqVdm3bx8JCQlYLBYGDRpE9eq2kd3MxylOCjXBGTFiBD///DN//PEHISEhnDp1CoCwsDACAgIA2ymmmJgYpk+3XWEzYcIEatSoQePGjUlLS+PHH39k1qxZzJo1q9COQ3hG820FZZdD0u+o1FWABXxaoAXeg2aunu3+nmharjwrhz3E77t3svzQQVKtFppXqMiQJs2oHVG0P2FnVSO8FEuHPpCjauJPt21Pt5q1+XnHNnafPUOA2YfedeoyoEEjgp0shKaZKkGZPyF5ASplAah4MNVGCxyM5htZwEd4fQnxL029OguJPj4DkucQZIrjsrUMvkF307z+QHT9+pirpGm+EP4FpP2HSvoNjBjQy6IFDAC/brK4Yy5ljnzk9PT377//zoQJEzhw4IA96ch6luH555/n4Ycf5ocffqB79+7ceeed1K5tG4kdOXIkTzzxBEuWLKF79+7cfvvtNGvWDIDNmzezYsUK+4hOVgcPHqRnz55069aNpk2b0qtXL3r27Mkdd9xBqVLOFwS9bqlCxJXFGBy+pk6dam8zbNgwddNNN9lvjxs3TtWuXVv5+/urUqVKqY4dO6r58+d73GdcXJwCVFxcXD4eiRBCCG9LTk5Wu3btUsnJyYUax/nz55Wmaeq9995z2w5Qc+bMUUoptXbtWmUymdQ777yjNm7cqPbt26fefvttFRYW5rDP3r171ccff6x69OihfH191ezZs+33HTt2TE2ePFkNHDhQ+fj4qEmTJimllOrdu7caNGiQ2r9//zVfCQkJSimlDMNQ//77rxozZoxq2rSpKlu2rDp06FD+/VByyd3vNKfv34Wa4BQGSXCEEKJ4KCoJjlK2pKJy5cr2BCKrixcvKqUcE5zx48erWrVqObR76KGHrklwsho8eLDq16+f0/teeeUV1bRpU6WUUqNHj1b169dX6enpHsVusVhU5cqV1UcffeRR+4KUnwmOzCAUQggh8uiLL77AarXStm1bZs2axf79+9m9ezeTJk2iffv217SvU6cOx44dY+bMmRw8eJBJkyYxZ84c+/3Jyck89dRTrFy5kqNHj7JmzRo2btxIw4a2+XfPPvssixcv5vDhw2zZsoW///7bft+IESO4cOEC99xzDxs2bODQoUMsWbKEBx98EKvVyvr163nvvffYtGkTx44dY/bs2Zw9e9a+f3EhJ1yFEEKI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5RZCQ0MJCQmhU6dOHDx4ELBN+H/77bepUqUKfn5+REZGsmjRIrfHtWrVKtq2bYufnx8VK1bklVdecYi5S5cuPPXUUzz//POUKVOGHj165OnnmB1JcIQQRYZ/2KPomvPTR1ZDIyHdj0bVHstTHw9EtnT6pga25MbfbOauxk3z1Ico+jaejLlm5CYrBcQmXGZjAZyuvPPOOzl37hwrVqywb7t48SKLFy9myJAhLF68mKFDhzJy5Eh27drFl19+ybRp03j33XcdHueNN96gf//+bN++nQcffJDXX3+dXbt2sXDhQnbv3s3kyZNdnpKKiYmhc+fO+Pv78/fff7N582YefPBBe0IyceJEPvroI8aPH8+2bdvo1asXt912G/v3Ox/ViomJoW/fvrRp04atW7cyefJkvv32W9555x2Hdt9//z1ms5k1a9bw5Zdf5uXHmK2iM1YlhCjxGlXqw/r9u2gV/CWGsl0mrpTtzSbJ6sNp3wnU98/bHILG5cozvkcfXly6ELhyJVVmcvNNv4GUDQzK66GIIu5MouvkJjftciIiIoLevXvz888/061bNwB+++03IiIi6NatG127duWVV16xj+bUqlWL//3vf7z00ku88cYb9se59957efDBB+23jx07RosWLWjdujUANdyMRH7++eeEhYUxc+ZMfHx8AKhXr579/vHjx/Pyyy8zePBgAMaNG8eKFSuYMGECn3/++TWP98UXX1C1alU+++wzNE2jQYMGnDx5kpdffpkxY8ag67bxlDp16vDBBx/k5seWY5LgCCGKlBvqvsCx892IOfMV4foerJi5zI00rPIY9YMq5ksfAxo0pGXFivy8YxubYmIw6zqdqtfg7sZNKRMYmC99iKKtXFBwvrbLqSFDhvDoo4/yxRdf4Ofnx08//cTgwYMxmUxs3ryZjRs3OozYWK1WUlJSSEpKIjDjOZqZyGR64oknuP3229myZQs9e/ZkwIAB3HjjjU77j46OplOnTvbkJqv4+HhOnjxJhw4dHLZ36NCBrVudX2G4e/du2rdvj5bl9G+HDh1ISEjgxIkTVKtWzWnMBUkSHCFEkVOtdCTVSn9RsH2EhfNKh84F2ocoutpUqkyF4GBOJyQ4PWWpARWCQ2hTqXKB9N+vXz8Mw2D+/Pm0adOGf/75h48//hiwzX956623GDRo0DX7Za2wHRTkONLYp08f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", + "text/plain": [ + "

    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek42_34_0.png" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Loading and plotting iris dataset\n", + "from sklearn import datasets\n", + "import matplotlib.pyplot as plt\n", + "\n", + "iris = datasets.load_iris()\n", + "\n", + "_, ax = plt.subplots()\n", + "scatter = ax.scatter(iris.data[:, 0], iris.data[:, 1], c=iris.target)\n", + "ax.set(xlabel=iris.feature_names[0], ylabel=iris.feature_names[1])\n", + "_ = ax.legend(\n", + " scatter.legend_elements()[0], iris.target_names, loc=\"lower right\", title=\"Classes\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c528846f", + "metadata": {}, + "source": [ + "**c)** Loop over the iris dataset(`iris.data`) and evaluate the network for each data point.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2efc507d", + "metadata": {}, + "outputs": [], + "source": [ + "# No need to change this cell! Just make sure it works!\n", + "for x in iris.data:\n", + " prediction = feed_forward_4(layers, x)" + ] + }, + { + "cell_type": "markdown", + "id": "334560b6", + "metadata": {}, + "source": [ + "# Exercise 5 (Very optional and very hard :)\n" + ] + }, + { + "cell_type": "markdown", + "id": "ea0a8fe0", + "metadata": {}, + "source": [ + "**a)** Make the iris target values into one-hot vectors.\n", + "\n", + "**b)** Define the cross-entropy loss function to evaluate the performance of your network on the data set.\n", + "\n", + "**c)** Use the autograd package to take the gradient of the cross entropy wrt. the weights and biases of the network.\n", + "\n", + "**d)** Use gradient descent of some sort to optimize the parameters.\n", + "\n", + "**e)** Evaluate the accuracy of the network.\n", + "\n", + "**e)** Show off how you did in a group session!\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.py b/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.py new file mode 100644 index 000000000..c6282b034 --- /dev/null +++ b/doc/LectureNotes/_build/jupyter_execute/exercisesweek42.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python +# coding: utf-8 + +# +# +# + +# # Exercises week 42 +# +# **October 14-18, 2024** +# +# Date: **Deadline is Friday October 18 at midnight** +# + +# # Overarching aims of the exercises this week +# +# The aim of the exercises this week is to get started with implementing a neural network. There are a lot of technical and finicky parts of implementing a neutal network, so take your time. +# +# This week, you will implement only the feed-forward pass. Next week, you will implement backpropagation. We recommend that you do the exercises this week by editing and running this notebook file, as it includes several checks along the way that you have implemented the pieces of the feed-forward pass correctly. If you have trouble running a notebook, or importing pytorch, you can run this notebook in google colab instead: (LINK TO COLAB), though we recommend that you set up VSCode and your python environment to run code like this locally. +# + +# In[1]: + + +import autograd.numpy as np +from autograd import grad + + +# # Exercise 1 +# +# Complete the following parts to compute the activation of the first layer. +# + +# In[2]: + + +np.random.seed(2024) + + +def ReLU(z): + return np.where(z > 0, z, 0) + + +x = np.random.randn(2) # network input +W1 = np.random.randn(4, 2) # first layer weights + + +# **a)** Define the bias of the first layer, `b1`with the correct shape +# + +# In[3]: + + +b1 = np.random.randn(4) + + +# **b)** Compute the intermediary `z1` for the first layer +# + +# In[4]: + + +z1 = W1 @ x + b1 + + +# **c)** Compute the activation `a1` for the first layer using the ReLU activation function defined earlier. +# + +# In[5]: + + +a1 = ReLU(z1) + + +# Confirm that you got the correct activation with the test below. +# + +# In[6]: + + +sol1 = np.array([0.60610368, 4.0076268, 0.0, 0.56469864]) + +print(np.allclose(a1, sol1)) + + +# # Exercise 2 +# +# Compute the activation of the second layer with an output of length 8 and ReLU activation. +# +# **a)** Define the weight and bias of the second layer with the right shapes. +# + +# In[7]: + + +W2 = np.random.randn(8, 4) +b2 = np.random.randn(8) + + +# **b)** Compute intermediary `z2` and activation `a2` for the second layer. +# + +# In[8]: + + +z2 = W2 @ a1 +a2 = ReLU(z2) + + +# Confirm that you got the correct activation shape with the test below. +# + +# In[9]: + + +print(a2.shape == (8,)) + + +# # Exercise 3 +# +# We often want our neural networks to have many layers of varying sizes. To avoid writing very long and error-prone code where we explicitly define and evaluate each layer we should keep all our layers in a single variable which is easy to create and use. +# +# **a)** Complete the function below so that it returns a list `layers` of weight and bias tuples `(W, b)` for each layer, in order, with the correct shapes that we can use later as our network parameters. +# + +# In[10]: + + +def create_layers(network_input_size, output_sizes): + layers = [] + + i_size = network_input_size + for output_size in output_sizes: + W = np.random.rand(output_size, i_size) + b = np.random.rand(output_size) + layers.append((W, b)) + + i_size = output_size + return layers + + +# **b)** Comple the function below so that it evaluates the intermediate `z` and activation `a` for each layer, and returns the final activation `a`. This is the complete feed-forward pass, a full neural network! +# + +# In[11]: + + +def feed_forward(layers, input): + a = input + for W, b in layers: + z = W @ a + b + a = ReLU(z) + return a + + +# **c)** Create a network with input size 8 and layers with output sizes 10, 16, 6, 2. Evaluate it and make sure that you get the correct size vectors along the way. +# + +# In[ ]: + + + + + +# # Exercise 4 +# + +# So far, every layer has used the same activation, ReLU. We often want to use other types of activation however, so we need to update our code to support multiple types of activation. Make sure that you have completed every previous exercise before trying this one. +# +# **a)** Make the `create_layers` function also accept a list of activation functions, which is used to add activation functions to each of the tuples in `layers`. Make new functions to not mess with the old ones. +# + +# In[12]: + + +def create_layers_4(network_input_size, output_sizes, activation_funcs): + layers = [] + + i_size = network_input_size + for output_size, activation in zip(output_sizes, activation_funcs): + W = np.random.rand(output_size, i_size) + b = np.random.rand(output_size) + layers.append((W, b, activation)) + + i_size = output_size + return layers + + +# **b)** Update the `feed_forward` function to support this change. +# + +# In[13]: + + +def feed_forward_4(layers, input): + a = input + for W, b, activation in layers: + z = W @ a + b + a = activation(z) + return a + + +# **c)** Create and evaluate a neural network with 4 inputs and layers with output sizes 12, 10, 3 and activations ReLU, ReLU, softmax. +# + +# In[14]: + + +from scipy.special import softmax + +network_input_size = 4 +output_sizes = [12, 10, 3] +activation_funcs = [ReLU, ReLU, softmax] +layers = create_layers_4(network_input_size, output_sizes, activation_funcs) + +x = np.random.randn(network_input_size) +predict = feed_forward_4(layers, x) + + +# The final exercise will hopefully be very simple if everything has worked so far. You will evaluate your neural network on the iris data set (https://scikit-learn.org/1.5/auto_examples/datasets/plot_iris_dataset.html). +# +# This dataset contains data on 150 flowers of 3 different types which can be separated pretty well using the four features given for each flower, which includes the width and length of their leaves. You are not expected to do any training of the network or actual classification, unless you feel like it, in that case you can do exercise 5. +# + +# In[15]: + + +# Loading and plotting iris dataset +from sklearn import datasets +import matplotlib.pyplot as plt + +iris = datasets.load_iris() + +_, ax = plt.subplots() +scatter = ax.scatter(iris.data[:, 0], iris.data[:, 1], c=iris.target) +ax.set(xlabel=iris.feature_names[0], ylabel=iris.feature_names[1]) +_ = ax.legend( + scatter.legend_elements()[0], iris.target_names, loc="lower right", title="Classes" +) + + +# **c)** Loop over the iris dataset(`iris.data`) and evaluate the network for each data point. +# + +# In[16]: + + +# No need to change this cell! Just make sure it works! +for x in iris.data: + prediction = feed_forward_4(layers, x) + + +# # Exercise 5 (Very optional and very hard :) +# + +# **a)** Make the iris target values into one-hot vectors. +# +# **b)** Define the cross-entropy loss function to evaluate the performance of your network on the data set. +# +# **c)** Use the autograd package to take the gradient of the cross entropy wrt. the weights and biases of the network. +# +# **d)** Use gradient descent of some sort to optimize the parameters. +# +# **e)** Evaluate the accuracy of the network. +# +# **e)** Show off how you did in a group session! +# diff --git a/doc/LectureNotes/_build/jupyter_execute/exercisesweek42_34_0.png b/doc/LectureNotes/_build/jupyter_execute/exercisesweek42_34_0.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d5908e0bbfa047af6c8e9602a7623d7c755e7f GIT binary patch literal 40673 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/jupyter_execute/week42.ipynb b/doc/LectureNotes/_build/jupyter_execute/week42.ipynb new file mode 100644 index 000000000..f5f67eb6c --- /dev/null +++ b/doc/LectureNotes/_build/jupyter_execute/week42.ipynb @@ -0,0 +1,6414 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "474b773e", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "a8ac8249", + "metadata": { + "editable": true + }, + "source": [ + "# Week 42 Constructing a Neural Network code with examples\n", + "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and Facility for Rare Isotope Beams, Michigan State University\n", + "\n", + "Date: **October 14-18, 2024**" + ] + }, + { + "cell_type": "markdown", + "id": "c8760378", + "metadata": { + "editable": true + }, + "source": [ + "## Lecture October 14, 2024\n", + "1. Building our own Feed-forward Neural Network and discussion of project 2\n", + "\n", + "**Readings and videos.**\n", + "\n", + "1. These lecture notes\n", + "\n", + "\n", + "\n", + "2. For a more in depth discussion on neural networks we recommend Goodfellow et al chapters 6 and 7. \n", + "\n", + "3. Neural Networks demystified at \n", + "\n", + "4. Building Neural Networks from scratch at \n", + "\n", + "5. Video on Neural Networks at \n", + "\n", + "6. Video on the back propagation algorithm at \n", + "\n", + "I also recommend Michael Nielsen's intuitive approach to the neural networks and the universal approximation theorem, see the slides at ." + ] + }, + { + "cell_type": "markdown", + "id": "76c6895d", + "metadata": { + "editable": true + }, + "source": [ + "## Material for the active learning sessions on Tuesday and Wednesday\n", + " * Exercise on starting to write a code for neural networks, feed forward part. We will also continue ur discussions of gradient descent methods from last week. If you have time, start considering the back-propagation part as well (exercises for next week)\n", + "\n", + " * Discussion of project 2\n", + "\n", + " \n", + "\n", + "**Note**: some of the codes will also be discussed next week in connection with the solution of differential equations." + ] + }, + { + "cell_type": "markdown", + "id": "ebb39354", + "metadata": { + "editable": true + }, + "source": [ + "## Writing a code which implements a feed-forward neural network\n", + "\n", + "Last week we discussed the basics of neural networks and deep learning\n", + "and the basics of automatic differentiation. We looked also at\n", + "examples on how compute the parameters of a simple network with scalar\n", + "inputs and ouputs and no or just one hidden layers.\n", + "\n", + "We ended our discussions with the derivation of the equations for a\n", + "neural network with one hidden layers and two input variables and two\n", + "hidden nodes but only one output node." + ] + }, + { + "cell_type": "markdown", + "id": "cfb26b1b", + "metadata": { + "editable": true + }, + "source": [ + "## Mathematics of deep learning\n", + "\n", + "**Two recent books online.**\n", + "\n", + "1. [The Modern Mathematics of Deep Learning, by Julius Berner, Philipp Grohs, Gitta Kutyniok, Philipp Petersen](https://arxiv.org/abs/2105.04026), published as [Mathematical Aspects of Deep Learning, pp. 1-111. Cambridge University Press, 2022](https://doi.org/10.1017/9781009025096.002)\n", + "\n", + "2. [Mathematical Introduction to Deep Learning: Methods, Implementations, and Theory, Arnulf Jentzen, Benno Kuckuck, Philippe von Wurstemberger](https://doi.org/10.48550/arXiv.2310.20360)" + ] + }, + { + "cell_type": "markdown", + "id": "28f60678", + "metadata": { + "editable": true + }, + "source": [ + "## Reminder on books with hands-on material and codes\n", + "* [Sebastian Rashcka et al, Machine learning with Sickit-Learn and PyTorch](https://sebastianraschka.com/blog/2022/ml-pytorch-book.html)" + ] + }, + { + "cell_type": "markdown", + "id": "3c7f8f61", + "metadata": { + "editable": true + }, + "source": [ + "## Reading recommendations\n", + "\n", + "1. Rashkca et al., chapter 11, jupyter-notebook sent separately, from [GitHub](https://github.com/rasbt/machine-learning-book)\n", + "\n", + "2. Goodfellow et al, chapter 6 and 7 contain most of the neural network background." + ] + }, + { + "cell_type": "markdown", + "id": "9ee5faa5", + "metadata": { + "editable": true + }, + "source": [ + "## First network example, simple percepetron with one input\n", + "\n", + "As yet another example we define now a simple perceptron model with\n", + "all quantities given by scalars. We consider only one input variable\n", + "$x$ and one target value $y$. We define an activation function\n", + "$\\sigma_1$ which takes as input" + ] + }, + { + "cell_type": "markdown", + "id": "e82fbb01", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1x+b_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1b4862d", + "metadata": { + "editable": true + }, + "source": [ + "where $w_1$ is the weight and $b_1$ is the bias. These are the\n", + "parameters we want to optimize. The output is $a_1=\\sigma(z_1)$ (see\n", + "graph from whiteboard notes). This output is then fed into the\n", + "**cost/loss** function, which we here for the sake of simplicity just\n", + "define as the squared error" + ] + }, + { + "cell_type": "markdown", + "id": "f7b41bcb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;w_1,b_1)=\\frac{1}{2}(a_1-y)^2.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2825a689", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with no hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "1853d23c", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the parameters\n", + "\n", + "In setting up the feed forward and back propagation parts of the\n", + "algorithm, we need now the derivative of the various variables we want\n", + "to train.\n", + "\n", + "We need" + ] + }, + { + "cell_type": "markdown", + "id": "1625a8c3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1} \\hspace{0.1cm}\\mathrm{and}\\hspace{0.1cm}\\frac{\\partial C}{\\partial b_1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7427a24a", + "metadata": { + "editable": true + }, + "source": [ + "Using the chain rule we find" + ] + }, + { + "cell_type": "markdown", + "id": "d4911a64", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_1-y)\\sigma_1'x,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0f290988", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "4cbbad95", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_1-y)\\sigma_1',\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cc8122a6", + "metadata": { + "editable": true + }, + "source": [ + "which we later will just define as" + ] + }, + { + "cell_type": "markdown", + "id": "39f03825", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3eeb7a29", + "metadata": { + "editable": true + }, + "source": [ + "## Adding a hidden layer\n", + "\n", + "We change our simple model to (see graph)\n", + "a network with just one hidden layer but with scalar variables only.\n", + "\n", + "Our output variable changes to $a_2$ and $a_1$ is now the output from the hidden node and $a_0=x$.\n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "33e1d35f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1a_0+b_1 \\hspace{0.1cm} \\wedge a_1 = \\sigma_1(z_1),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e846a441", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_2 = w_2a_1+b_2 \\hspace{0.1cm} \\wedge a_2 = \\sigma_2(z_2),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fbb3f1ff", + "metadata": { + "editable": true + }, + "source": [ + "and the cost function" + ] + }, + { + "cell_type": "markdown", + "id": "40200643", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;\\boldsymbol{\\Theta})=\\frac{1}{2}(a_2-y)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a2e96689", + "metadata": { + "editable": true + }, + "source": [ + "with $\\boldsymbol{\\Theta}=[w_1,w_2,b_1,b_2]$." + ] + }, + { + "cell_type": "markdown", + "id": "1a014316", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with one hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "06a0b720", + "metadata": { + "editable": true + }, + "source": [ + "## The derivatives\n", + "\n", + "The derivatives are now, using the chain rule again" + ] + }, + { + "cell_type": "markdown", + "id": "48581ce4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial w_2}=(a_2-y)\\sigma_2'a_1=\\delta_2a_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "58f46792", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial b_2}=(a_2-y)\\sigma_2'=\\delta_2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc5aa924", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_2-y)\\sigma_2'a_1\\sigma_1'a_0,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "407690af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_2-y)\\sigma_2'\\sigma_1'=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8f5cacad", + "metadata": { + "editable": true + }, + "source": [ + "Can you generalize this to more than one hidden layer?" + ] + }, + { + "cell_type": "markdown", + "id": "79f592c1", + "metadata": { + "editable": true + }, + "source": [ + "## Important observations\n", + "\n", + "From the above equations we see that the derivatives of the activation\n", + "functions play a central role. If they vanish, the training may\n", + "stop. This is called the vanishing gradient problem, see discussions below. If they become\n", + "large, the parameters $w_i$ and $b_i$ may simply go to infinity. This\n", + "is referenced as the exploding gradient problem." + ] + }, + { + "cell_type": "markdown", + "id": "412247f9", + "metadata": { + "editable": true + }, + "source": [ + "## The training\n", + "\n", + "The training of the parameters is done through various gradient descent approximations with" + ] + }, + { + "cell_type": "markdown", + "id": "83c09361", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}\\leftarrow w_{i}- \\eta \\delta_i a_{i-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d341a3c7", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2bb5b78f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_i \\leftarrow b_i-\\eta \\delta_i,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3d6558a8", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ is the learning rate.\n", + "\n", + "One iteration consists of one feed forward step and one back-propagation step. Each back-propagation step does one update of the parameters $\\boldsymbol{\\Theta}$.\n", + "\n", + "For the first hidden layer $a_{i-1}=a_0=x$ for this simple model." + ] + }, + { + "cell_type": "markdown", + "id": "f55c404e", + "metadata": { + "editable": true + }, + "source": [ + "## Code example\n", + "\n", + "The code here implements the above model with one hidden layer and\n", + "scalar variables for the same function we studied in the previous\n", + "example. The code is however set up so that we can add multiple\n", + "inputs $x$ and target values $y$. Note also that we have the\n", + "possibility of defining a feature matrix $\\boldsymbol{X}$ with more than just\n", + "one column for the input values. This will turn useful in our next example. We have also defined matrices and vectors for all of our operations although it is not necessary here." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "076950d8", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[36.89563074]\n", + "[23.62323175]\n", + "[15.1251681]\n", + "[9.68402334]\n", + "[6.20020163]\n", + "[3.96963458]\n", + "[2.54150298]\n", + "[1.62714703]\n", + "[1.0417409]\n", + "[0.66694492]\n", + "[0.42699034]\n", + "[0.27336592]\n", + "[0.17501258]\n", + "[0.11204514]\n", + "[0.07173249]\n", + "[0.04592382]\n", + "[0.02940083]\n", + "[0.01882264]\n", + "[0.01205039]\n", + "[0.00771475]\n", + "[0.00493903]\n", + "[0.003162]\n", + "[0.00202433]\n", + "[0.00129599]\n", + "[0.0008297]\n", + "[0.00053118]\n", + "[0.00034006]\n", + "[0.00021771]\n", + "[0.00013938]\n", + "[8.92313548e-05]\n", + "[5.71263851e-05]\n", + "[3.6572612e-05]\n", + "[2.34139775e-05]\n", + "[1.49897504e-05]\n", + "[9.5965161e-06]\n", + "[6.14373934e-06]\n", + "[3.93325371e-06]\n", + "[2.51808934e-06]\n", + "[1.61209378e-06]\n", + "[1.03207075e-06]\n", + "[6.60737006e-07]\n", + "[4.23007231e-07]\n", + "[2.70811405e-07]\n", + "[1.73374853e-07]\n", + "[1.10995472e-07]\n", + "[7.10598715e-08]\n", + "[4.54928947e-08]\n", + "[2.91247848e-08]\n", + "[1.86458368e-08]\n", + "[1.19371605e-08]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "# We use the Sigmoid function as activation function\n", + "def sigmoid(z):\n", + " return 1.0/(1.0+np.exp(-z))\n", + "\n", + "def forwardpropagation(x):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_1 = np.matmul(x, w_1) + b_1\n", + " # activation in the hidden layer\n", + " a_1 = sigmoid(z_1)\n", + " # weighted sum of inputs to the output layer\n", + " z_2 = np.matmul(a_1, w_2) + b_2\n", + " a_2 = z_2\n", + " return a_1, a_2\n", + "\n", + "def backpropagation(x, y):\n", + " a_1, a_2 = forwardpropagation(x)\n", + " # parameter delta for the output layer, note that a_2=z_2 and its derivative wrt z_2 is just 1\n", + " delta_2 = a_2 - y\n", + " print(0.5*((a_2-y)**2))\n", + " # delta for the hidden layer\n", + " delta_1 = np.matmul(delta_2, w_2.T) * a_1 * (1 - a_1)\n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_1.T, delta_2)\n", + " output_bias_gradient = np.sum(delta_2, axis=0)\n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(x.T, delta_1)\n", + " hidden_bias_gradient = np.sum(delta_1, axis=0)\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "# Input variable\n", + "x = np.array([4.0],dtype=np.float64)\n", + "# Target values\n", + "y = 2*x+1.0 \n", + "\n", + "# Defining the neural network, only scalars here\n", + "n_inputs = x.shape\n", + "n_features = 1\n", + "n_hidden_neurons = 1\n", + "n_outputs = 1\n", + "\n", + "# Initialize the network\n", + "# weights and bias in the hidden layer\n", + "w_1 = np.random.randn(n_features, n_hidden_neurons)\n", + "b_1 = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "w_2 = np.random.randn(n_hidden_neurons, n_outputs)\n", + "b_2 = np.zeros(n_outputs) + 0.01\n", + "\n", + "eta = 0.1\n", + "for i in range(50):\n", + " # calculate gradients\n", + " derivW2, derivB2, derivW1, derivB1 = backpropagation(x, y)\n", + " # update weights and biases\n", + " w_2 -= eta * derivW2\n", + " b_2 -= eta * derivB2\n", + " w_1 -= eta * derivW1\n", + " b_1 -= eta * derivB1" + ] + }, + { + "cell_type": "markdown", + "id": "b5a2150f", + "metadata": { + "editable": true + }, + "source": [ + "We see that after some few iterations (the results do depend on the learning rate however), we get an error which is rather small." + ] + }, + { + "cell_type": "markdown", + "id": "cb93f2d2", + "metadata": { + "editable": true + }, + "source": [ + "## Simple neural network and the back propagation equations\n", + "\n", + "Let us now try to increase our level of ambition and attempt at setting \n", + "up the equations for a neural network with two input nodes, one hidden\n", + "layer with two hidden nodes and one output layer with one output node/neuron only (see graph)..\n", + "\n", + "We need to define the following parameters and variables with the input layer (layer $(0)$) \n", + "where we label the nodes $x_0$ and $x_1$" + ] + }, + { + "cell_type": "markdown", + "id": "893b1b33", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "x_0 = a_0^{(0)} \\wedge x_1 = a_1^{(0)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1554902", + "metadata": { + "editable": true + }, + "source": [ + "The hidden layer (layer $(1)$) has nodes which yield the outputs $a_0^{(1)}$ and $a_1^{(1)}$) with weight $\\boldsymbol{w}$ and bias $\\boldsymbol{b}$ parameters" + ] + }, + { + "cell_type": "markdown", + "id": "e01cd011", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)}\\right\\} \\wedge b^{(1)}=\\left\\{b_0^{(1)},b_1^{(1)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "691e42c5", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with two input nodes, one hidden layer and one output node\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "57573a8a", + "metadata": { + "editable": true + }, + "source": [ + "## The ouput layer\n", + "\n", + "Finally, we have the ouput layer given by layer label $(2)$ with output $a^{(2)}$ and weights and biases to be determined given by the variables" + ] + }, + { + "cell_type": "markdown", + "id": "91ff8dfb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}=\\left\\{w_{0}^{(2)},w_{1}^{(2)}\\right\\} \\wedge b^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "315f787f", + "metadata": { + "editable": true + }, + "source": [ + "Our output is $\\tilde{y}=a^{(2)}$ and we define a generic cost function $C(a^{(2)},y;\\boldsymbol{\\Theta})$ where $y$ is the target value (a scalar here).\n", + "The parameters we need to optimize are given by" + ] + }, + { + "cell_type": "markdown", + "id": "612ebd67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\Theta}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)},w_{0}^{(2)},w_{1}^{(2)},b_0^{(1)},b_1^{(1)},b^{(2)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c28762dc", + "metadata": { + "editable": true + }, + "source": [ + "## Compact expressions\n", + "\n", + "We can define the inputs to the activation functions for the various layers in terms of various matrix-vector multiplications and vector additions.\n", + "The inputs to the first hidden layer are" + ] + }, + { + "cell_type": "markdown", + "id": "b4d0309d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}z_0^{(1)} \\\\ z_1^{(1)} \\end{bmatrix}=\\left(\\begin{bmatrix}w_{00}^{(1)} & w_{01}^{(1)}\\\\ w_{10}^{(1)} &w_{11}^{(1)} \\end{bmatrix}\\right)^{T}\\begin{bmatrix}a_0^{(0)} \\\\ a_1^{(0)} \\end{bmatrix}+\\begin{bmatrix}b_0^{(1)} \\\\ b_1^{(1)} \\end{bmatrix},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f3c715f1", + "metadata": { + "editable": true + }, + "source": [ + "with outputs" + ] + }, + { + "cell_type": "markdown", + "id": "5db82289", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}a_0^{(1)} \\\\ a_1^{(1)} \\end{bmatrix}=\\begin{bmatrix}\\sigma^{(1)}(z_0^{(1)}) \\\\ \\sigma^{(1)}(z_1^{(1)}) \\end{bmatrix}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6b2ad78", + "metadata": { + "editable": true + }, + "source": [ + "## Output layer\n", + "\n", + "For the final output layer we have the inputs to the final activation function" + ] + }, + { + "cell_type": "markdown", + "id": "dcefdba1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} = w_{0}^{(2)}a_0^{(1)} +w_{1}^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d554c6ce", + "metadata": { + "editable": true + }, + "source": [ + "resulting in the output" + ] + }, + { + "cell_type": "markdown", + "id": "651ff447", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a^{(2)}=\\sigma^{(2)}(z^{(2)}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f171ceaa", + "metadata": { + "editable": true + }, + "source": [ + "## Explicit derivatives\n", + "\n", + "In total we have nine parameters which we need to train. Using the\n", + "chain rule (or just the back-propagation algorithm) we can find all\n", + "derivatives. Since we will use automatic differentiation in reverse\n", + "mode, we start with the derivatives of the cost function with respect\n", + "to the parameters of the output layer, namely" + ] + }, + { + "cell_type": "markdown", + "id": "609bb2dd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{i}^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial w_{i}^{(2)}}=\\delta^{(2)}a_i^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "da1d696b", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "d21d62cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta^{(2)}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fb9dd90f", + "metadata": { + "editable": true + }, + "source": [ + "and finally" + ] + }, + { + "cell_type": "markdown", + "id": "9026fb2d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial b^{(2)}}=\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2d20d5d1", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives of the hidden layer\n", + "\n", + "Using the chain rule we have the following expressions for say one of the weight parameters (it is easy to generalize to the other weight parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "e6fbb9b5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}= \\delta^{(2)}\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "781a7ac8", + "metadata": { + "editable": true + }, + "source": [ + "which, noting that" + ] + }, + { + "cell_type": "markdown", + "id": "3ee09d8f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} =w_0^{(2)}a_0^{(1)}+w_1^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65f44692", + "metadata": { + "editable": true + }, + "source": [ + "allows us to rewrite" + ] + }, + { + "cell_type": "markdown", + "id": "0b84b7af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c138bd", + "metadata": { + "editable": true + }, + "source": [ + "## Final expression\n", + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "3f81bb3f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_0^{(1)}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}\\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eb6783b2", + "metadata": { + "editable": true + }, + "source": [ + "we have" + ] + }, + { + "cell_type": "markdown", + "id": "1c754dbb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\delta_0^{(1)}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e0b9760c", + "metadata": { + "editable": true + }, + "source": [ + "Similarly, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "b1efb446", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{01}^{(1)}}=\\delta_0^{(1)}a_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2cf7b43f", + "metadata": { + "editable": true + }, + "source": [ + "## Completing the list\n", + "\n", + "Similarly, we find" + ] + }, + { + "cell_type": "markdown", + "id": "262b517f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{10}^{(1)}}=\\delta_1^{(1)}a_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "59285e3f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2813790f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{11}^{(1)}}=\\delta_1^{(1)}a_1^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a56b94b4", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined" + ] + }, + { + "cell_type": "markdown", + "id": "a3ed9010", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_1^{(1)}=w_1^{(2)}\\frac{\\partial a_1^{(1)}}{\\partial z_1^{(1)}}\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "03a5562c", + "metadata": { + "editable": true + }, + "source": [ + "## Final expressions for the biases of the hidden layer\n", + "\n", + "For the sake of completeness, we list the derivatives of the biases, which are" + ] + }, + { + "cell_type": "markdown", + "id": "025bd04f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{0}^{(1)}}=\\delta_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1ef6c2f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "157d7580", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{1}^{(1)}}=\\delta_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "389a7e2d", + "metadata": { + "editable": true + }, + "source": [ + "As we will see below, these expressions can be generalized in a more compact form." + ] + }, + { + "cell_type": "markdown", + "id": "bccf9918", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient expressions\n", + "\n", + "For this specific model, with just one output node and two hidden\n", + "nodes, the gradient descent equations take the following form for output layer" + ] + }, + { + "cell_type": "markdown", + "id": "ab05945c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}\\leftarrow w_{i}^{(2)}- \\eta \\delta^{(2)} a_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cb2ef195", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "da672f61", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b^{(2)} \\leftarrow b^{(2)}-\\eta \\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "95dd3d2b", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "532b99a2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}\\leftarrow w_{ij}^{(1)}- \\eta \\delta_{i}^{(1)} a_{j}^{(0)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5d5f45cc", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2333cfb1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_{i}^{(1)} \\leftarrow b_{i}^{(1)}-\\eta \\delta_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4b555f81", + "metadata": { + "editable": true + }, + "source": [ + "where $\\eta$ is the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "20c0952f", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the equations for a neural network\n", + "\n", + "The questions we want to ask are how do changes in the biases and the\n", + "weights in our network change the cost function and how can we use the\n", + "final output to modify the weights and biases?\n", + "\n", + "To derive these equations let us start with a plain regression problem\n", + "and define our cost function as" + ] + }, + { + "cell_type": "markdown", + "id": "5a155f81", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ff1fc071", + "metadata": { + "editable": true + }, + "source": [ + "where the $y_i$s are our $n$ targets (the values we want to\n", + "reproduce), while the outputs of the network after having propagated\n", + "all inputs $\\boldsymbol{x}$ are given by $\\boldsymbol{\\tilde{y}}_i$." + ] + }, + { + "cell_type": "markdown", + "id": "63576478", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a neural network with three hidden layers (last later = $l=L=4$, first layer $l=0$)\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "3410ad89", + "metadata": { + "editable": true + }, + "source": [ + "## Definitions\n", + "\n", + "With our definition of the targets $\\boldsymbol{y}$, the outputs of the\n", + "network $\\boldsymbol{\\tilde{y}}$ and the inputs $\\boldsymbol{x}$ we\n", + "define now the activation $z_j^l$ of node/neuron/unit $j$ of the\n", + "$l$-th layer as a function of the bias, the weights which add up from\n", + "the previous layer $l-1$ and the forward passes/outputs\n", + "$\\boldsymbol{a}^{l-1}$ from the previous layer as" + ] + }, + { + "cell_type": "markdown", + "id": "c71d887c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^l = \\sum_{i=1}^{M_{l-1}}w_{ij}^la_i^{l-1}+b_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ffeae21c", + "metadata": { + "editable": true + }, + "source": [ + "where $b_k^l$ are the biases from layer $l$. Here $M_{l-1}$\n", + "represents the total number of nodes/neurons/units of layer $l-1$. The\n", + "figure in the whiteboard notes illustrates this equation. We can rewrite this in a more\n", + "compact form as the matrix-vector products we discussed earlier," + ] + }, + { + "cell_type": "markdown", + "id": "2fe917a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{z}^l = \\left(\\boldsymbol{W}^l\\right)^T\\boldsymbol{a}^{l-1}+\\boldsymbol{b}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65404bec", + "metadata": { + "editable": true + }, + "source": [ + "## Inputs to the activation function\n", + "\n", + "With the activation values $\\boldsymbol{z}^l$ we can in turn define the\n", + "output of layer $l$ as $\\boldsymbol{a}^l = \\sigma(\\boldsymbol{z}^l)$ where $\\sigma$ is our\n", + "activation function. In the examples here we will use the sigmoid\n", + "function discussed in our logistic regression lectures. We will also use the same activation function $\\sigma$ for all layers\n", + "and their nodes. It means we have" + ] + }, + { + "cell_type": "markdown", + "id": "a6c0c8b6", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_j^l = \\sigma(z_j^l) = \\frac{1}{1+\\exp{-(z_j^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2454faec", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of input to first hidden layer $l=1$ from input layer $l=0$\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "e5b67040", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives and the chain rule\n", + "\n", + "From the definition of the input variable to the activation function, that is $z_j^l$ we have" + ] + }, + { + "cell_type": "markdown", + "id": "aaec49a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial w_{ij}^l} = a_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e8ad40d3", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "e04a4d28", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial a_i^{l-1}} = w_{ji}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9b121a33", + "metadata": { + "editable": true + }, + "source": [ + "With our definition of the activation function we have that (note that this function depends only on $z_j^l$)" + ] + }, + { + "cell_type": "markdown", + "id": "3bf7d884", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^l}{\\partial z_j^{l}} = a_j^l(1-a_j^l)=\\sigma(z_j^l)(1-\\sigma(z_j^l)).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7d58918c", + "metadata": { + "editable": true + }, + "source": [ + "## Derivative of the cost function\n", + "\n", + "With these definitions we can now compute the derivative of the cost function in terms of the weights.\n", + "\n", + "Let us specialize to the output layer $l=L$. Our cost function is" + ] + }, + { + "cell_type": "markdown", + "id": "d21dce97", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}^L) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2=\\frac{1}{2}\\sum_{i=1}^n\\left(a_i^L - y_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc143bea", + "metadata": { + "editable": true + }, + "source": [ + "The derivative of this function with respect to the weights is" + ] + }, + { + "cell_type": "markdown", + "id": "49415a06", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4398e11e", + "metadata": { + "editable": true + }, + "source": [ + "The last partial derivative can easily be computed and reads (by applying the chain rule)" + ] + }, + { + "cell_type": "markdown", + "id": "da3fca7e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}} = \\frac{\\partial a_j^L}{\\partial z_{j}^{L}}\\frac{\\partial z_j^L}{\\partial w_{ij}^{L}}=a_j^L(1-a_j^L)a_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9055bc57", + "metadata": { + "editable": true + }, + "source": [ + "## The back propagation equations for a neural network\n", + "\n", + "We have thus" + ] + }, + { + "cell_type": "markdown", + "id": "c7995e73", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}((\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)a_j^L(1-a_j^L)a_i^{L-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d142f966", + "metadata": { + "editable": true + }, + "source": [ + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "d5dc5f9f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = a_j^L(1-a_j^L)\\left(a_j^L - y_j\\right) = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5f598e3e", + "metadata": { + "editable": true + }, + "source": [ + "and using the Hadamard product of two vectors we can write this as" + ] + }, + { + "cell_type": "markdown", + "id": "9769b50e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\delta}^L = \\sigma'(\\boldsymbol{z}^L)\\circ\\frac{\\partial {\\cal C}}{\\partial (\\boldsymbol{a}^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5a8851ae", + "metadata": { + "editable": true + }, + "source": [ + "## Analyzing the last results\n", + "\n", + "This is an important expression. The second term on the right handside\n", + "measures how fast the cost function is changing as a function of the $j$th\n", + "output activation. If, for example, the cost function doesn't depend\n", + "much on a particular output node $j$, then $\\delta_j^L$ will be small,\n", + "which is what we would expect. The first term on the right, measures\n", + "how fast the activation function $f$ is changing at a given activation\n", + "value $z_j^L$." + ] + }, + { + "cell_type": "markdown", + "id": "b455efff", + "metadata": { + "editable": true + }, + "source": [ + "## More considerations\n", + "\n", + "Notice that everything in the above equations is easily computed. In\n", + "particular, we compute $z_j^L$ while computing the behaviour of the\n", + "network, and it is only a small additional overhead to compute\n", + "$\\sigma'(z^L_j)$. The exact form of the derivative with respect to the\n", + "output depends on the form of the cost function.\n", + "However, provided the cost function is known there should be little\n", + "trouble in calculating" + ] + }, + { + "cell_type": "markdown", + "id": "8b430778", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7fb2cea5", + "metadata": { + "editable": true + }, + "source": [ + "With the definition of $\\delta_j^L$ we have a more compact definition of the derivative of the cost function in terms of the weights, namely" + ] + }, + { + "cell_type": "markdown", + "id": "6c77ac74", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "708f42bb", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives in terms of $z_j^L$\n", + "\n", + "It is also easy to see that our previous equation can be written as" + ] + }, + { + "cell_type": "markdown", + "id": "40f66bf5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L =\\frac{\\partial {\\cal C}}{\\partial z_j^L}= \\frac{\\partial {\\cal C}}{\\partial a_j^L}\\frac{\\partial a_j^L}{\\partial z_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21b9ebbe", + "metadata": { + "editable": true + }, + "source": [ + "which can also be interpreted as the partial derivative of the cost function with respect to the biases $b_j^L$, namely" + ] + }, + { + "cell_type": "markdown", + "id": "665ad548", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L}\\frac{\\partial b_j^L}{\\partial z_j^L}=\\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c182abd9", + "metadata": { + "editable": true + }, + "source": [ + "That is, the error $\\delta_j^L$ is exactly equal to the rate of change of the cost function as a function of the bias." + ] + }, + { + "cell_type": "markdown", + "id": "aa70c6cf", + "metadata": { + "editable": true + }, + "source": [ + "## Bringing it together\n", + "\n", + "We have now three equations that are essential for the computations of the derivatives of the cost function at the output layer. These equations are needed to start the algorithm and they are" + ] + }, + { + "cell_type": "markdown", + "id": "db460a07", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{W^L})}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1},\n", + "\\label{_auto1} \\tag{1}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3af036d6", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5662288a", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "\\label{_auto2} \\tag{2}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6a8a1ac", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "dda8fce0", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "\\label{_auto3} \\tag{3}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1957ab0", + "metadata": { + "editable": true + }, + "source": [ + "## Final back propagating equation\n", + "\n", + "We have that (replacing $L$ with a general layer $l$)" + ] + }, + { + "cell_type": "markdown", + "id": "31c8f2c9", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\frac{\\partial {\\cal C}}{\\partial z_j^l}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bba8d29e", + "metadata": { + "editable": true + }, + "source": [ + "We want to express this in terms of the equations for layer $l+1$." + ] + }, + { + "cell_type": "markdown", + "id": "af4922ec", + "metadata": { + "editable": true + }, + "source": [ + "## Using the chain rule and summing over all $k$ entries\n", + "\n", + "We obtain" + ] + }, + { + "cell_type": "markdown", + "id": "f43f0f87", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\frac{\\partial {\\cal C}}{\\partial z_k^{l+1}}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}}=\\sum_k \\delta_k^{l+1}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eba489e4", + "metadata": { + "editable": true + }, + "source": [ + "and recalling that" + ] + }, + { + "cell_type": "markdown", + "id": "82610f92", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^{l+1} = \\sum_{i=1}^{M_{l}}w_{ij}^{l+1}a_i^{l}+b_j^{l+1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "62513d62", + "metadata": { + "editable": true + }, + "source": [ + "with $M_l$ being the number of nodes in layer $l$, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "ca381ec8", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bdf32ad4", + "metadata": { + "editable": true + }, + "source": [ + "This is our final equation.\n", + "\n", + "We are now ready to set up the algorithm for back propagation and learning the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "764448ea", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm\n", + "\n", + "The four equations provide us with a way of computing the gradient of the cost function. Let us write this out in the form of an algorithm.\n", + "\n", + "**First**, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "**Secondly**, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=1,2,3,\\dots,L$.\n", + "\n", + "**Notation**: The first hidden layer has $l=1$ as label and the final output layer has $l=L$." + ] + }, + { + "cell_type": "markdown", + "id": "989c3082", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm, part 2\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "9d14949a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4ee118b1", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "ba89ad67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1f840c5", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the Back propagation algorithm, part 3\n", + "\n", + "Finally, we update the weights and the biases using gradient descent\n", + "for each $l=L-1,L-2,\\dots,1$ (the first hidden layer) and update the weights and biases\n", + "according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "9f06bcfc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7063f2be", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3e299445", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ being the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "28921878", + "metadata": { + "editable": true + }, + "source": [ + "## Updating the gradients\n", + "\n", + "With the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "90f5404c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c2dfbd", + "metadata": { + "editable": true + }, + "source": [ + "we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,1$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "03805799", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4f8f9c02", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9bf86f9c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "A property that characterizes a neural network, other than its\n", + "connectivity, is the choice of activation function(s). As described\n", + "in, the following restrictions are imposed on an activation function\n", + "for a FFNN to fulfill the universal approximation theorem\n", + "\n", + " * Non-constant\n", + "\n", + " * Bounded\n", + "\n", + " * Monotonically-increasing\n", + "\n", + " * Continuous" + ] + }, + { + "cell_type": "markdown", + "id": "eeaed73c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions, Logistic and Hyperbolic ones\n", + "\n", + "The second requirement excludes all linear functions. Furthermore, in\n", + "a MLP with only linear activation functions, each layer simply\n", + "performs a linear transformation of its inputs.\n", + "\n", + "Regardless of the number of layers, the output of the NN will be\n", + "nothing but a linear function of the inputs. Thus we need to introduce\n", + "some kind of non-linearity to the NN to be able to fit non-linear\n", + "functions Typical examples are the logistic *Sigmoid*" + ] + }, + { + "cell_type": "markdown", + "id": "0786aaf0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\frac{1}{1 + e^{-x}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "aa76601b", + "metadata": { + "editable": true + }, + "source": [ + "and the *hyperbolic tangent* function" + ] + }, + { + "cell_type": "markdown", + "id": "e1bca915", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\tanh(x)\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1832a8c4", + "metadata": { + "editable": true + }, + "source": [ + "### Relevance\n", + "\n", + "The *sigmoid* function are more biologically plausible because the\n", + "output of inactive neurons are zero. Such activation function are\n", + "called *one-sided*. However, it has been shown that the hyperbolic\n", + "tangent performs better than the sigmoid for training MLPs. has\n", + "become the most popular for *deep neural networks*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5c689736", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "data": { + "image/png": "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XkWkiWVlZTFs2DASEhJ49tlnOXz4cNX3WrZsaWIyz5eamsro0aPp168fAwcO5NVXXyUzM5OJEyeaHc3r3Hnnnbz77rt8+umnhIWFVc3biYiIICgoyOR03iMsLKxG4QgJCSEqKsqjiwiojIiXW7JkCbt27WLXrl01iqB2Gp5Zo0aNIj8/n2nTppGdnU337t1ZtGgRbdu2NTua1zlxevWwYcOqLX/jjTcYN25c0wcSr6PDNCIiImIqzdITERERU6mMiIiIiKlURkRERMRUKiMiIiJiKpURERERMZXKiIiIiJhKZURERERMpTIiIiIiplIZEREREVOpjIiIiIipVEZExBR79+7FYrHU+Prt/VFExPPpRnkiYor4+Hiys7OrHufk5HDhhRdy3nnnmZhKRMygG+WJiOnKysoYNmwY0dHRfPrpp/j4aKetiDfRnhERMd348eMpKioiPT1dRUTEC6mMiIipnnzySRYvXsxPP/1EWFiY2XFExAQ6TCMipvnwww+54YYb+PLLL7ngggvMjiMiJlEZERFTbNq0iQEDBpCamsqdd95ZtTwgIIDIyEgTk4lIU1MZERFTzJ07l1tuuaXG8qFDh/Ldd981fSARMY3KiIiIiJhK09ZFRETEVCojIiIiYiqVERERETGVyoiIiIiYSmVERERETKUyIiIiIqZSGRERERFTqYyIiIiIqVRGRERExFQqIyIiImIqlRERERExlcqIiIiImOr/AbSpzJqxOet0AAAAAElFTkSuQmCC", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/week42_173_0.png" + } + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAHFCAYAAAD/kYOsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA4kUlEQVR4nO3de3SU1b3/8c8EwoQIiQYkCW0IlEWBAAoEyYWCREwQBNGKQLVRFLAssIKpy5p6A/Q0R2slgILSQ02R67ER0BqRYA3gIVCBBKun8gMPGIRELkqGi5kMyfP7QzMwTghJZZjJnvdrrVn67Nnz5LvZTvj47OdisyzLEgAAgEFC/F0AAADApUbAAQAAxiHgAAAA4xBwAACAcQg4AADAOAQcAABgHAIOAAAwDgEHAAAYh4ADAACMQ8ABcFErVqxQbm6uX2v46quvNGHCBHXo0EE2m0233nqrX+v5/e9/r7Vr13q1FxUVyWazqaio6LLXBOAcG49qAHAxo0aN0scff6wDBw74rYaHHnpICxcu1J///Gd17dpVUVFR+ulPf+q3etq0aaOxY8cqLy/Po93hcOh///d/lZCQoIiICP8UB0At/V0AADTGxx9/rK5du+quu+7ydykNioiIUHJysr/LAIIeS1RAkDt69Kjuv/9+xcXFyW636+qrr9agQYO0ceNGSdLQoUP19ttv6/PPP5fNZnO/6lRXV+uZZ55Rjx493J+/9957dfToUY+f07lzZ40aNUpr1qzRNddco7CwMP3kJz/R/PnzG6zvwIEDstls2rhxo/71r3+5f35RUdEFl4PqPnP+0ZWJEyeqTZs22rdvn0aOHKk2bdooLi5Ov/nNb+R0Oj0+73Q6NWfOHPXs2VNhYWFq166d0tLStHXrVkmSzWbT6dOn9Ze//MVdz9ChQyVdeInqzTffVEpKisLDw9W2bVulp6eruLjYo8+sWbNks9n0ySef6Be/+IUiIyMVHR2t++67T5WVlQ3+OQHwxBEcIMhlZmZq165d+o//+A/99Kc/1YkTJ7Rr1y4dP35ckrRw4ULdf//9+uyzz7RmzRqPz9bW1mrMmDHasmWLHnnkEaWmpurzzz/XU089paFDh2rHjh1q3bq1u39paalmzpypWbNmKSYmRsuXL9eMGTNUXV2thx9+uN76YmNjVVxcrGnTpqmyslLLly+XJCUkJGjXrl1NGqvL5dItt9yiSZMm6Te/+Y02b96sp59+WpGRkXryySclSWfPntWIESO0ZcsWzZw5UzfccIPOnj2rbdu2qaysTKmpqSouLtYNN9ygtLQ0PfHEE5LU4HLUihUrdNdddykjI0MrV66U0+nUc889p6FDh+q9997Tz372M4/+t99+u8aPH69Jkybpn//8p7KzsyVJf/7zn5s0XiCoWQCCWps2bayZM2c22Ofmm2+24uPjvdpXrlxpSbLy8/M92j/88ENLkrVw4UJ3W3x8vGWz2azS0lKPvunp6VZERIR1+vTpBmu4/vrrrV69enm0vf/++5Yk6/333/do379/vyXJevXVV91t99xzjyXJ+u///m+PviNHjrS6d+/u3l66dKklyfrTn/7UYD1XXHGFdc8993i1f7+mmpoaq2PHjlafPn2smpoad7+TJ09aHTp0sFJTU91tTz31lCXJeu655zz2OW3aNCssLMyqra1tsCYA57BEBQS5gQMHKi8vT88884y2bdsml8vV6M/+7W9/05VXXqnRo0fr7Nmz7lffvn0VExPjtUzTq1cvXXvttR5td955pxwOR5OPxvw7bDabRo8e7dF2zTXX6PPPP3dvv/POOwoLC9N99913SX7mnj17dPjwYWVmZiok5Nyv3DZt2uj222/Xtm3bdObMGY/P3HLLLV41VlVV6ciRI5ekJiAYEHCAILd69Wrdc889+q//+i+lpKQoKipKd999tyoqKi762S+//FInTpxQq1atFBoa6vGqqKjQsWPHPPrHxMR47aOurW5JzJfCw8MVFhbm0Wa321VVVeXePnr0qDp27OgRRn6IunHFxsZ6vdexY0fV1tbq66+/9mhv166dV42S9M0331ySmoBgwDk4QJBr3769cnNzlZubq7KyMr355pt69NFHdeTIEa1fv/6in23Xrt0F+7Vt29Zju77QVNf2/b/UG6MurHz/JOHvB6umuPrqq/XBBx+otrb2koScunGVl5d7vXf48GGFhIToqquu+sE/B4AnjuAAcOvUqZMeeOABpaeneywZ2e32eo8ejBo1SsePH1dNTY0GDBjg9erevbtH/08++US7d+/2aFuxYoXatm2r/v37N7nezp07S5I++ugjj/Y333yzyfuqM2LECFVVVXnd3+b7LvRn8n3du3fXj370I61YsULWebcdO336tPLz891XVgG4tDiCAwSxyspKpaWl6c4771SPHj3Utm1bffjhh1q/fr1+/vOfu/v16dNHb7zxhhYtWqTExESFhIRowIABmjBhgpYvX66RI0dqxowZGjhwoEJDQ/XFF1/o/fff15gxY3Tbbbe599OxY0fdcsstmjVrlmJjY7Vs2TIVFhbq2Wef/bf+ko+JidGNN96onJwcXXXVVYqPj9d7772nN95449/+M/nFL36hV199VVOnTtWePXuUlpam2tpabd++XT179tSECRPcfyZFRUV66623FBsbq7Zt23oFOkkKCQnRc889p7vuukujRo3Sr371KzmdTv3hD3/QiRMn9J//+Z//dq0AGuDvs5wB+E9VVZU1depU65prrrEiIiKs1q1bW927d7eeeuopj6uavvrqK2vs2LHWlVdeadlsNuv8Xx0ul8t6/vnnrWuvvdYKCwuz2rRpY/Xo0cP61a9+Ze3du9fdLz4+3rr55putv/71r1avXr2sVq1aWZ07d7ZeeOGFRtVa31VUlmVZ5eXl1tixY62oqCgrMjLS+uUvf2nt2LGj3quorrjiCq/P1125dL5vvvnGevLJJ61u3bpZrVq1stq1a2fdcMMN1tatW919SktLrUGDBlnh4eGWJOv666+3LOvCV3atXbvWSkpKssLCwqwrrrjCGjZsmPU///M/9dZy9OhRj/ZXX33VkmTt37+/EX9SACzLsnhUA4DLonPnzurdu7f+9re/+bsUAEGAc3AAAIBxCDgAAMA4LFEBAADj+PQIzubNmzV69Gh17NhRNptNa9eubbB/3UPqvv/69NNPPfrl5+crISFBdrtdCQkJXs/HAQAAwc2nAef06dO69tpr9eKLLzbpc3v27FF5ebn71a1bN/d7xcXFGj9+vDIzM7V7925lZmZq3Lhx2r59+6UuHwAANFOXbYnKZrNpzZo1uvXWWy/Yp6ioSGlpafr666915ZVX1ttn/Pjxcjgceuedd9xtN910k6666iqtXLnyElcNAACao4C80V+/fv1UVVWlhIQEPf7440pLS3O/V1xcrIceesij//Dhw5Wbm3vB/TmdTo9budfW1uqrr75Su3btZLPZLnn9AADg0rMsSydPnmzU8+ICKuDExsZq8eLFSkxMlNPp1GuvvaZhw4apqKhIQ4YMkfTtc2uio6M9PhcdHd3ggwFzcnI0e/Zsn9YOAAAuj4MHD+rHP/5x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", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/week42_173_1.png" + } + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/week42_173_2.png" + } + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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4+Nv6Hk9PT01ZcqUMpezzIy+6dsZ0Dd9OwP6rti+y30zMgAAQHXBh3oCAADTIugAAADTIugAAADTIugAAADTqvZB58CBA3rssccUHh4ub29vNW3aVFOmTFFBQcFVjzMMQ/Hx8apfv768vb0VFRWlnTt3VlLVFeOll15St27d5OPjc93vIjlixAhZLJYSX126dLFvoRXsRvo2w3yfPn1aw4YNk5+fn/z8/DRs2DCdOXPmqsdUx/meN2+ewsPD5eXlpcjISP3www9XHb9mzRpFRkbKy8tLTZo00fz58yup0opVnr6TkpJKzavFYtGePXsqseKbt3btWvXv31/169eXxWLRV199dc1jzDDf5e3bDPM9ffp0derUSb6+vgoMDNT999+v1NTUax5XEfNd7YPOnj17VFxcrLfffls7d+7U66+/rvnz52vy5MlXPW7GjBmaOXOm5syZo02bNik4OFi9evVSbm5uJVV+8woKCjRo0CA9+eST5TquT58+ysjIsH0tX77cThXax430bYb5jo2NVUpKilauXKmVK1cqJSVFw4YNu+Zx1Wm+Fy9erPHjx+vZZ59VcnKyunfvrr59+yo9Pb3M8WlpaerXr5+6d++u5ORkTZ48WePGjdOSJUsqufKbU96+L0lNTS0xt7feemslVVwxzp07p3bt2mnOnDnXNd4s813evi+pzvO9Zs0ajR49Whs2bFBiYqIKCwsVExOjc+fOXfGYCptvw4RmzJhhhIeHX/Hx4uJiIzg42Hj55Zdt+y5cuGD4+fkZ8+fPr4wSK9TChQsNPz+/6xo7fPhwY8CAAXatp7Jcb99mmO9du3YZkowNGzbY9q1fv96QZOzZs+eKx1W3+b799tuNkSNHltjXokUL45lnnilz/MSJE40WLVqU2PfnP//Z6NKli91qtIfy9r169WpDknH69OlKqK5ySDKWLl161TFmme/fup6+zTjfx48fNyQZa9asueKYiprvan9FpyzZ2dmqW7fuFR9PS0tTZmamYmJibPs8PT3Vs2dPrVu3rjJKdKikpCQFBgaqWbNmeuKJJ3T8+HFHl2RXZpjv9evXy8/PT507d7bt69Kli/z8/K7ZQ3WZ74KCAv38888l5kmSYmJirtjj+vXrS43v3bu3Nm/eLKvVardaK9KN9H1JRESEQkJCdNddd2n16tX2LLNKMMN83wwzzfelT0S42t/qippv0wWdX375RW+++aZGjhx5xTGXPm8rKCioxP6goKBSn8VlNn379tXHH3+s77//Xq+99po2bdqkO++8s8QnwJuNGeY7MzNTgYGBpfYHBgZetYfqNN8nT55UUVFRueYpMzOzzPGFhYU6efKk3WqtSDfSd0hIiN555x0tWbJEX375pZo3b6677rpLa9eurYySHcYM830jzDbfhmEoLi5Od9xxh1q3bn3FcRU131U26MTHx5d589VvvzZv3lzimKNHj6pPnz4aNGiQHn/88Ws+h8ViKbFtGEapfZXtRvouj8GDB+uee+5R69at1b9/f61YsUJ79+7Vt99+W4FdlJ+9+5aq/3yXVeu1eqiq83015Z2nssaXtb+qK0/fzZs31xNPPKEOHTqoa9eumjdvnu655x69+uqrlVGqQ5llvsvDbPM9ZswYbdu2TZ988sk1x1bEfNvts65u1pgxYzRkyJCrjgkLC7P999GjRxUdHa2uXbvqnXfeuepxwcHBki6mxZCQENv+48ePl0qPla28fd+skJAQhYaGat++fRV2zhthz77NMN/btm3TsWPHSj124sSJcvVQVea7LAEBAXJ1dS11FeNq8xQcHFzmeDc3N/n7+9ut1op0I32XpUuXLvroo48qurwqxQzzXVGq63yPHTtWy5Yt09q1a0t94PflKmq+q2zQCQgIUEBAwHWNPXLkiKKjoxUZGamFCxfKxeXqF6rCw8MVHBysxMRERURESLq4Tr5mzRq98sorN137zShP3xUhKytLhw4dKhEAHMGefZthvrt27ars7Gxt3LhRt99+uyTpp59+UnZ2trp163bdz1dV5rssHh4eioyMVGJioh544AHb/sTERA0YMKDMY7p27apvvvmmxL5Vq1apY8eOcnd3t2u9FeVG+i5LcnJylZzXimSG+a4o1W2+DcPQ2LFjtXTpUiUlJSk8PPyax1TYfJfr1uUq6MiRI8Ytt9xi3Hnnncbhw4eNjIwM29dvNW/e3Pjyyy9t2y+//LLh5+dnfPnll8b27duNoUOHGiEhIUZOTk5lt3DDDh48aCQnJxtTp041atasaSQnJxvJyclGbm6ubcxv+87NzTWefvppY926dUZaWpqxevVqo2vXrkaDBg1M3bdhmGO++/TpY7Rt29ZYv369sX79eqNNmzbGvffeW2JMdZ/vTz/91HB3dzcWLFhg7Nq1yxg/frxRo0YN48CBA4ZhGMYzzzxjDBs2zDb+119/NXx8fIynnnrK2LVrl7FgwQLD3d3d+OKLLxzVwg0pb9+vv/66sXTpUmPv3r3Gjh07jGeeecaQZCxZssRRLdyQ3Nxc2++vJGPmzJlGcnKycfDgQcMwzDvf5e3bDPP95JNPGn5+fkZSUlKJv9N5eXm2Mfaa72ofdBYuXGhIKvPrtyQZCxcutG0XFxcbU6ZMMYKDgw1PT0+jR48exvbt2yu5+pszfPjwMvtevXq1bcxv+87LyzNiYmKMevXqGe7u7kbjxo2N4cOHG+np6Y5p4AaVt2/DMMd8Z2VlGQ8//LDh6+tr+Pr6Gg8//HCpl5uaYb7nzp1rhIaGGh4eHkaHDh1KvPx0+PDhRs+ePUuMT0pKMiIiIgwPDw8jLCzMeOuttyq54opRnr5feeUVo2nTpoaXl5dRp04d44477jC+/fZbB1R9cy69bPryr+HDhxuGYd75Lm/fZpjvK/2d/u2/0/aab8v/FQAAAGA6VfZVVwAAADeLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAMAAEyLoAOgyjtw4IAsFkupr6ioKEeXBqCKc3N0AQBwLY0aNVJGRoZtOzMzU3fffbd69OjhwKoAVAd8qCeAauXChQuKiopSvXr19PXXX8vFhQvTAK6MKzoAqpXHHntMubm5SkxMJOQAuCaCDoBq4x//+IdWrlypjRs3ytfX19HlAKgGWLoCUC0sWbJEQ4cO1YoVK3TXXXc5uhwA1QRBB0CVt2PHDnXu3FlxcXEaPXq0bb+Hh4fq1q3rwMoAVHUEHQBVXkJCgh599NFS+3v27KmkpKTKLwhAtUHQAQAApsVLFgAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGkRdAAAgGn9P+9K8z/xjo0MAAAAAElFTkSuQmCC", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/week42_173_3.png" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "\n", + "\"\"\"The sigmoid function (or the logistic curve) is a \n", + "function that takes any real number, z, and outputs a number (0,1).\n", + "It is useful in neural networks for assigning weights on a relative scale.\n", + "The value z is the weighted sum of parameters involved in the learning algorithm.\"\"\"\n", + "\n", + "import numpy\n", + "import matplotlib.pyplot as plt\n", + "import math as mt\n", + "\n", + "z = numpy.arange(-5, 5, .1)\n", + "sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))\n", + "sigma = sigma_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, sigma)\n", + "ax.set_ylim([-0.1, 1.1])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sigmoid function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Step Function\"\"\"\n", + "z = numpy.arange(-5, 5, .02)\n", + "step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)\n", + "step = step_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, step)\n", + "ax.set_ylim([-0.5, 1.5])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('step function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Sine Function\"\"\"\n", + "z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)\n", + "t = numpy.sin(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, t)\n", + "ax.set_ylim([-1.0, 1.0])\n", + "ax.set_xlim([-2*mt.pi,2*mt.pi])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sine function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Plots a graph of the squashing function used by a rectified linear\n", + "unit\"\"\"\n", + "z = numpy.arange(-2, 2, .1)\n", + "zero = numpy.zeros(len(z))\n", + "y = numpy.max([zero, z], axis=0)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, y)\n", + "ax.set_ylim([-2.0, 2.0])\n", + "ax.set_xlim([-2.0, 2.0])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('Rectified linear unit')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "0b3a4c95", + "metadata": { + "editable": true + }, + "source": [ + "## Fine-tuning neural network hyperparameters\n", + "\n", + "The flexibility of neural networks is also one of their main\n", + "drawbacks: there are many hyperparameters to tweak. Not only can you\n", + "use any imaginable network topology (how neurons/nodes are\n", + "interconnected), but even in a simple FFNN you can change the number\n", + "of layers, the number of neurons per layer, the type of activation\n", + "function to use in each layer, the weight initialization logic, the\n", + "stochastic gradient optmized and much more. How do you know what\n", + "combination of hyperparameters is the best for your task?\n", + "\n", + "* You can use grid search with cross-validation to find the right hyperparameters.\n", + "\n", + "However,since there are many hyperparameters to tune, and since\n", + "training a neural network on a large dataset takes a lot of time, you\n", + "will only be able to explore a tiny part of the hyperparameter space.\n", + "\n", + "* You can use randomized search.\n", + "\n", + "* Or use tools like [Oscar](http://oscar.calldesk.ai/), which implements more complex algorithms to help you find a good set of hyperparameters quickly." + ] + }, + { + "cell_type": "markdown", + "id": "9955a636", + "metadata": { + "editable": true + }, + "source": [ + "## Hidden layers\n", + "\n", + "For many problems you can start with just one or two hidden layers and\n", + "it will work just fine. For the MNIST data set you ca easily get a\n", + "high accuracy using just one hidden layer with a few hundred neurons.\n", + "You can reach for this data set above 98% accuracy using two hidden\n", + "layers with the same total amount of neurons, in roughly the same\n", + "amount of training time.\n", + "\n", + "For more complex problems, you can gradually ramp up the number of\n", + "hidden layers, until you start overfitting the training set. Very\n", + "complex tasks, such as large image classification or speech\n", + "recognition, typically require networks with dozens of layers and they\n", + "need a huge amount of training data. However, you will rarely have to\n", + "train such networks from scratch: it is much more common to reuse\n", + "parts of a pretrained state-of-the-art network that performs a similar\n", + "task." + ] + }, + { + "cell_type": "markdown", + "id": "f1aa77e9", + "metadata": { + "editable": true + }, + "source": [ + "## Vanishing gradients\n", + "\n", + "The Back propagation algorithm we derived above works by going from\n", + "the output layer to the input layer, propagating the error gradient on\n", + "the way. Once the algorithm has computed the gradient of the cost\n", + "function with regards to each parameter in the network, it uses these\n", + "gradients to update each parameter with a Gradient Descent (GD) step.\n", + "\n", + "Unfortunately for us, the gradients often get smaller and smaller as\n", + "the algorithm progresses down to the first hidden layers. As a result,\n", + "the GD update leaves the lower layer connection weights virtually\n", + "unchanged, and training never converges to a good solution. This is\n", + "known in the literature as **the vanishing gradients problem**." + ] + }, + { + "cell_type": "markdown", + "id": "3703bb33", + "metadata": { + "editable": true + }, + "source": [ + "## Exploding gradients\n", + "\n", + "In other cases, the opposite can happen, namely the the gradients can\n", + "grow bigger and bigger. The result is that many of the layers get\n", + "large updates of the weights the algorithm diverges. This is the\n", + "**exploding gradients problem**, which is mostly encountered in\n", + "recurrent neural networks. More generally, deep neural networks suffer\n", + "from unstable gradients, different layers may learn at widely\n", + "different speeds" + ] + }, + { + "cell_type": "markdown", + "id": "43b1aa26", + "metadata": { + "editable": true + }, + "source": [ + "## Is the Logistic activation function (Sigmoid) our choice?\n", + "\n", + "Although this unfortunate behavior has been empirically observed for\n", + "quite a while (it was one of the reasons why deep neural networks were\n", + "mostly abandoned for a long time), it is only around 2010 that\n", + "significant progress was made in understanding it.\n", + "\n", + "A paper titled [Understanding the Difficulty of Training Deep\n", + "Feedforward Neural Networks by Xavier Glorot and Yoshua Bengio](http://proceedings.mlr.press/v9/glorot10a.html) found that\n", + "the problems with the popular logistic\n", + "sigmoid activation function and the weight initialization technique\n", + "that was most popular at the time, namely random initialization using\n", + "a normal distribution with a mean of 0 and a standard deviation of\n", + "1." + ] + }, + { + "cell_type": "markdown", + "id": "463f4f64", + "metadata": { + "editable": true + }, + "source": [ + "## Logistic function as the root of problems\n", + "\n", + "They showed that with this activation function and this\n", + "initialization scheme, the variance of the outputs of each layer is\n", + "much greater than the variance of its inputs. Going forward in the\n", + "network, the variance keeps increasing after each layer until the\n", + "activation function saturates at the top layers. This is actually made\n", + "worse by the fact that the logistic function has a mean of 0.5, not 0\n", + "(the hyperbolic tangent function has a mean of 0 and behaves slightly\n", + "better than the logistic function in deep networks)." + ] + }, + { + "cell_type": "markdown", + "id": "6c9ea582", + "metadata": { + "editable": true + }, + "source": [ + "## The derivative of the Logistic funtion\n", + "\n", + "Looking at the logistic activation function, when inputs become large\n", + "(negative or positive), the function saturates at 0 or 1, with a\n", + "derivative extremely close to 0. Thus when backpropagation kicks in,\n", + "it has virtually no gradient to propagate back through the network,\n", + "and what little gradient exists keeps getting diluted as\n", + "backpropagation progresses down through the top layers, so there is\n", + "really nothing left for the lower layers.\n", + "\n", + "In their paper, Glorot and Bengio propose a way to significantly\n", + "alleviate this problem. We need the signal to flow properly in both\n", + "directions: in the forward direction when making predictions, and in\n", + "the reverse direction when backpropagating gradients. We don’t want\n", + "the signal to die out, nor do we want it to explode and saturate. For\n", + "the signal to flow properly, the authors argue that we need the\n", + "variance of the outputs of each layer to be equal to the variance of\n", + "its inputs, and we also need the gradients to have equal variance\n", + "before and after flowing through a layer in the reverse direction." + ] + }, + { + "cell_type": "markdown", + "id": "80c83d2c", + "metadata": { + "editable": true + }, + "source": [ + "## Insights from the paper by Glorot and Bengio\n", + "\n", + "One of the insights in the 2010 paper by Glorot and Bengio was that\n", + "the vanishing/exploding gradients problems were in part due to a poor\n", + "choice of activation function. Until then most people had assumed that\n", + "if Nature had chosen to use roughly sigmoid activation functions in\n", + "biological neurons, they must be an excellent choice. But it turns out\n", + "that other activation functions behave much better in deep neural\n", + "networks, in particular the ReLU activation function, mostly because\n", + "it does not saturate for positive values (and also because it is quite\n", + "fast to compute)." + ] + }, + { + "cell_type": "markdown", + "id": "55a1ad5d", + "metadata": { + "editable": true + }, + "source": [ + "## The RELU function family\n", + "\n", + "The ReLU activation function suffers from a problem known as the dying\n", + "ReLUs: during training, some neurons effectively die, meaning they\n", + "stop outputting anything other than 0.\n", + "\n", + "In some cases, you may find that half of your network’s neurons are\n", + "dead, especially if you used a large learning rate. During training,\n", + "if a neuron’s weights get updated such that the weighted sum of the\n", + "neuron’s inputs is negative, it will start outputting 0. When this\n", + "happen, the neuron is unlikely to come back to life since the gradient\n", + "of the ReLU function is 0 when its input is negative." + ] + }, + { + "cell_type": "markdown", + "id": "b7fafe4a", + "metadata": { + "editable": true + }, + "source": [ + "## ELU function\n", + "\n", + "To solve this problem, nowadays practitioners use a variant of the\n", + "ReLU function, such as the leaky ReLU discussed above or the so-called\n", + "exponential linear unit (ELU) function" + ] + }, + { + "cell_type": "markdown", + "id": "46e10153", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "ELU(z) = \\left\\{\\begin{array}{cc} \\alpha\\left( \\exp{(z)}-1\\right) & z < 0,\\\\ z & z \\ge 0.\\end{array}\\right.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0930ba50", + "metadata": { + "editable": true + }, + "source": [ + "## Which activation function should we use?\n", + "\n", + "In general it seems that the ELU activation function is better than\n", + "the leaky ReLU function (and its variants), which is better than\n", + "ReLU. ReLU performs better than $\\tanh$ which in turn performs better\n", + "than the logistic function.\n", + "\n", + "If runtime performance is an issue, then you may opt for the leaky\n", + "ReLU function over the ELU function If you don’t want to tweak yet\n", + "another hyperparameter, you may just use the default $\\alpha$ of\n", + "$0.01$ for the leaky ReLU, and $1$ for ELU. If you have spare time and\n", + "computing power, you can use cross-validation or bootstrap to evaluate\n", + "other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "5c0c59af", + "metadata": { + "editable": true + }, + "source": [ + "## More on activation functions, output layers\n", + "\n", + "In most cases you can use the ReLU activation function in the hidden\n", + "layers (or one of its variants).\n", + "\n", + "It is a bit faster to compute than other activation functions, and the\n", + "gradient descent optimization does in general not get stuck.\n", + "\n", + "**For the output layer:**\n", + "\n", + "* For classification the softmax activation function is generally a good choice for classification tasks (when the classes are mutually exclusive).\n", + "\n", + "* For regression tasks, you can simply use no activation function at all." + ] + }, + { + "cell_type": "markdown", + "id": "582e4df4", + "metadata": { + "editable": true + }, + "source": [ + "## Batch Normalization\n", + "\n", + "Batch Normalization aims to address the vanishing/exploding gradients\n", + "problems, and more generally the problem that the distribution of each\n", + "layer’s inputs changes during training, as the parameters of the\n", + "previous layers change.\n", + "\n", + "The technique consists of adding an operation in the model just before\n", + "the activation function of each layer, simply zero-centering and\n", + "normalizing the inputs, then scaling and shifting the result using two\n", + "new parameters per layer (one for scaling, the other for shifting). In\n", + "other words, this operation lets the model learn the optimal scale and\n", + "mean of the inputs for each layer. In order to zero-center and\n", + "normalize the inputs, the algorithm needs to estimate the inputs’ mean\n", + "and standard deviation. It does so by evaluating the mean and standard\n", + "deviation of the inputs over the current mini-batch, from this the\n", + "name batch normalization." + ] + }, + { + "cell_type": "markdown", + "id": "ea360013", + "metadata": { + "editable": true + }, + "source": [ + "## Dropout\n", + "\n", + "It is a fairly simple algorithm: at every training step, every neuron\n", + "(including the input neurons but excluding the output neurons) has a\n", + "probability $p$ of being temporarily dropped out, meaning it will be\n", + "entirely ignored during this training step, but it may be active\n", + "during the next step.\n", + "\n", + "The hyperparameter $p$ is called the dropout rate, and it is typically\n", + "set to 50%. After training, the neurons are not dropped anymore. It\n", + "is viewed as one of the most popular regularization techniques." + ] + }, + { + "cell_type": "markdown", + "id": "fee98b12", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient Clipping\n", + "\n", + "A popular technique to lessen the exploding gradients problem is to\n", + "simply clip the gradients during backpropagation so that they never\n", + "exceed some threshold (this is mostly useful for recurrent neural\n", + "networks).\n", + "\n", + "This technique is called Gradient Clipping.\n", + "\n", + "In general however, Batch\n", + "Normalization is preferred." + ] + }, + { + "cell_type": "markdown", + "id": "c9f175b0", + "metadata": { + "editable": true + }, + "source": [ + "## A top-down perspective on Neural networks\n", + "\n", + "The first thing we would like to do is divide the data into two or\n", + "three parts. A training set, a validation or dev (development) set,\n", + "and a test set. The test set is the data on which we want to make\n", + "predictions. The dev set is a subset of the training data we use to\n", + "check how well we are doing out-of-sample, after training the model on\n", + "the training dataset. We use the validation error as a proxy for the\n", + "test error in order to make tweaks to our model. It is crucial that we\n", + "do not use any of the test data to train the algorithm. This is a\n", + "cardinal sin in ML. Then:\n", + "\n", + "1. Estimate optimal error rate\n", + "\n", + "2. Minimize underfitting (bias) on training data set.\n", + "\n", + "3. Make sure you are not overfitting." + ] + }, + { + "cell_type": "markdown", + "id": "f6f04fbb", + "metadata": { + "editable": true + }, + "source": [ + "## More top-down perspectives\n", + "\n", + "If the validation and test sets are drawn from the same distributions,\n", + "then a good performance on the validation set should lead to similarly\n", + "good performance on the test set. \n", + "\n", + "However, sometimes\n", + "the training data and test data differ in subtle ways because, for\n", + "example, they are collected using slightly different methods, or\n", + "because it is cheaper to collect data in one way versus another. In\n", + "this case, there can be a mismatch between the training and test\n", + "data. This can lead to the neural network overfitting these small\n", + "differences between the test and training sets, and a poor performance\n", + "on the test set despite having a good performance on the validation\n", + "set. To rectify this, Andrew Ng suggests making two validation or dev\n", + "sets, one constructed from the training data and one constructed from\n", + "the test data. The difference between the performance of the algorithm\n", + "on these two validation sets quantifies the train-test mismatch. This\n", + "can serve as another important diagnostic when using DNNs for\n", + "supervised learning." + ] + }, + { + "cell_type": "markdown", + "id": "d4184eee", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of supervised learning with deep networks\n", + "\n", + "Like all statistical methods, supervised learning using neural\n", + "networks has important limitations. This is especially important when\n", + "one seeks to apply these methods, especially to physics problems. Like\n", + "all tools, DNNs are not a universal solution. Often, the same or\n", + "better performance on a task can be achieved by using a few\n", + "hand-engineered features (or even a collection of random\n", + "features)." + ] + }, + { + "cell_type": "markdown", + "id": "82d314da", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of NNs\n", + "\n", + "Here we list some of the important limitations of supervised neural network based models. \n", + "\n", + "* **Need labeled data**. All supervised learning methods, DNNs for supervised learning require labeled data. Often, labeled data is harder to acquire than unlabeled data (e.g. one must pay for human experts to label images).\n", + "\n", + "* **Supervised neural networks are extremely data intensive.** DNNs are data hungry. They perform best when data is plentiful. This is doubly so for supervised methods where the data must also be labeled. The utility of DNNs is extremely limited if data is hard to acquire or the datasets are small (hundreds to a few thousand samples). In this case, the performance of other methods that utilize hand-engineered features can exceed that of DNNs." + ] + }, + { + "cell_type": "markdown", + "id": "abc6640b", + "metadata": { + "editable": true + }, + "source": [ + "## Homogeneous data\n", + "\n", + "* **Homogeneous data.** Almost all DNNs deal with homogeneous data of one type. It is very hard to design architectures that mix and match data types (i.e. some continuous variables, some discrete variables, some time series). In applications beyond images, video, and language, this is often what is required. In contrast, ensemble models like random forests or gradient-boosted trees have no difficulty handling mixed data types." + ] + }, + { + "cell_type": "markdown", + "id": "bb7d1f89", + "metadata": { + "editable": true + }, + "source": [ + "## More limitations\n", + "\n", + "* **Many problems are not about prediction.** In natural science we are often interested in learning something about the underlying distribution that generates the data. In this case, it is often difficult to cast these ideas in a supervised learning setting. While the problems are related, it is possible to make good predictions with a *wrong* model. The model might or might not be useful for understanding the underlying science.\n", + "\n", + "Some of these remarks are particular to DNNs, others are shared by all supervised learning methods. This motivates the use of unsupervised methods which in part circumvent these problems." + ] + }, + { + "cell_type": "markdown", + "id": "442b1b5e", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back-propagation algorithm\n", + "\n", + "Let us write this out in the form of an algorithm.\n", + "\n", + "First, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "Secondly, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=2,3,\\dots,L$.\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "0005e340", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = f'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2b27751b", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,2$ as" + ] + }, + { + "cell_type": "markdown", + "id": "dd544b4b", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "57a7d213", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,2$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "932510f4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bf80ed99", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f682bf76", + "metadata": { + "editable": true + }, + "source": [ + "The parameter $\\eta$ is the learning parameter discussed in connection with the gradient descent methods.\n", + "Here it is convenient to use stochastic gradient descent (see the examples below) with mini-batches with an outer loop that steps through multiple epochs of training." + ] + }, + { + "cell_type": "markdown", + "id": "ad2b26a4", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up a Multi-layer perceptron model for classification\n", + "\n", + "We are now gong to develop an example based on the MNIST data\n", + "base. This is a classification problem and we need to use our\n", + "cross-entropy function we discussed in connection with logistic\n", + "regression. The cross-entropy defines our cost function for the\n", + "classificaton problems with neural networks.\n", + "\n", + "In binary classification with two classes $(0, 1)$ we define the\n", + "logistic/sigmoid function as the probability that a particular input\n", + "is in class $0$ or $1$. This is possible because the logistic\n", + "function takes any input from the real numbers and inputs a number\n", + "between 0 and 1, and can therefore be interpreted as a probability. It\n", + "also has other nice properties, such as a derivative that is simple to\n", + "calculate.\n", + "\n", + "For an input $\\boldsymbol{a}$ from the hidden layer, the probability that the input $\\boldsymbol{x}$\n", + "is in class 0 or 1 is just. We let $\\theta$ represent the unknown weights and biases to be adjusted by our equations). The variable $x$\n", + "represents our activation values $z$. We have" + ] + }, + { + "cell_type": "markdown", + "id": "a08331b2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = \\frac{1}{1 + \\exp{(- \\boldsymbol{x}})} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9ebfde52", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "531dfa25", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 1 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = 1 - P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8941d38c", + "metadata": { + "editable": true + }, + "source": [ + "where $y \\in \\{0, 1\\}$ and $\\boldsymbol{\\theta}$ represents the weights and biases\n", + "of our network." + ] + }, + { + "cell_type": "markdown", + "id": "7ae7e222", + "metadata": { + "editable": true + }, + "source": [ + "## Defining the cost function\n", + "\n", + "Our cost function is given as (see the Logistic regression lectures)" + ] + }, + { + "cell_type": "markdown", + "id": "cbb157cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\ln P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = - \\sum_{i=1}^n\n", + "y_i \\ln[P(y_i = 0)] + (1 - y_i) \\ln [1 - P(y_i = 0)] = \\sum_{i=1}^n \\mathcal{L}_i(\\boldsymbol{\\theta}) .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0178770c", + "metadata": { + "editable": true + }, + "source": [ + "This last equality means that we can interpret our *cost* function as a sum over the *loss* function\n", + "for each point in the dataset $\\mathcal{L}_i(\\boldsymbol{\\theta})$. \n", + "The negative sign is just so that we can think about our algorithm as minimizing a positive number, rather\n", + "than maximizing a negative number. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$ and\n", + "\n", + "$y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset (numbers from $0$ to $9$).. \n", + "\n", + "If $\\boldsymbol{x}_i$ is the $i$-th input (image), $y_{ic}$ refers to the $c$-th component of the $i$-th\n", + "output vector $\\boldsymbol{y}_i$. \n", + "The probability of $\\boldsymbol{x}_i$ being in class $c$ will be given by the softmax function:" + ] + }, + { + "cell_type": "markdown", + "id": "cb69f3df", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y_{ic} = 1 \\mid \\boldsymbol{x}_i, \\boldsymbol{\\theta}) = \\frac{\\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_c)}}\n", + "{\\sum_{c'=0}^{C-1} \\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_{c'})}} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "11aa1335", + "metadata": { + "editable": true + }, + "source": [ + "which reduces to the logistic function in the binary case. \n", + "The likelihood of this $C$-class classifier\n", + "is now given as:" + ] + }, + { + "cell_type": "markdown", + "id": "a225e57a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = \\prod_{i=1}^n \\prod_{c=0}^{C-1} [P(y_{ic} = 1)]^{y_{ic}} .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "569dd3f2", + "metadata": { + "editable": true + }, + "source": [ + "Again we take the negative log-likelihood to define our cost function:" + ] + }, + { + "cell_type": "markdown", + "id": "f8e84cae", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\log{P(\\mathcal{D} \\mid \\boldsymbol{\\theta})}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1dd303e8", + "metadata": { + "editable": true + }, + "source": [ + "See the logistic regression lectures for a full definition of the cost function.\n", + "\n", + "The back propagation equations need now only a small change, namely the definition of a new cost function. We are thus ready to use the same equations as before!" + ] + }, + { + "cell_type": "markdown", + "id": "33494270", + "metadata": { + "editable": true + }, + "source": [ + "## Example: binary classification problem\n", + "\n", + "As an example of the above, relevant for project 2 as well, let us consider a binary class. As discussed in our logistic regression lectures, we defined a cost function in terms of the parameters $\\beta$ as" + ] + }, + { + "cell_type": "markdown", + "id": "01bd6a05", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\beta}) = - \\sum_{i=1}^n \\left(y_i\\log{p(y_i \\vert x_i,\\boldsymbol{\\beta})}+(1-y_i)\\log{1-p(y_i \\vert x_i,\\boldsymbol{\\beta})}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "60f16a47", + "metadata": { + "editable": true + }, + "source": [ + "where we had defined the logistic (sigmoid) function" + ] + }, + { + "cell_type": "markdown", + "id": "ab0c42b3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =1\\vert x_i,\\boldsymbol{\\beta})=\\frac{\\exp{(\\beta_0+\\beta_1 x_i)}}{1+\\exp{(\\beta_0+\\beta_1 x_i)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dcfb2e28", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5076b392", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =0\\vert x_i,\\boldsymbol{\\beta})=1-p(y_i =1\\vert x_i,\\boldsymbol{\\beta}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9d6001f4", + "metadata": { + "editable": true + }, + "source": [ + "The parameters $\\boldsymbol{\\beta}$ were defined using a minimization method like gradient descent or Newton-Raphson's method. \n", + "\n", + "Now we replace $x_i$ with the activation $z_i^l$ for a given layer $l$ and the outputs as $y_i=a_i^l=f(z_i^l)$, with $z_i^l$ now being a function of the weights $w_{ij}^l$ and biases $b_i^l$. \n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "d0245c18", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_i^l = y_i = \\frac{\\exp{(z_i^l)}}{1+\\exp{(z_i^l)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "030ac014", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "bdc01c83", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_i^l = \\sum_{j}w_{ij}^l a_j^{l-1}+b_i^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1a77b25c", + "metadata": { + "editable": true + }, + "source": [ + "where the superscript $l-1$ indicates that these are the outputs from layer $l-1$.\n", + "Our cost function at the final layer $l=L$ is now" + ] + }, + { + "cell_type": "markdown", + "id": "1f169ed1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{W}) = - \\sum_{i=1}^n \\left(t_i\\log{a_i^L}+(1-t_i)\\log{(1-a_i^L)}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "6bc460e2", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined the targets $t_i$. The derivatives of the cost function with respect to the output $a_i^L$ are then easily calculated and we get" + ] + }, + { + "cell_type": "markdown", + "id": "fe1f92c0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial \\mathcal{C}(\\boldsymbol{W})}{\\partial a_i^L} = \\frac{a_i^L-t_i}{a_i^L(1-a_i^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "78cf6843", + "metadata": { + "editable": true + }, + "source": [ + "In case we use another activation function than the logistic one, we need to evaluate other derivatives." + ] + }, + { + "cell_type": "markdown", + "id": "81ed1ccc", + "metadata": { + "editable": true + }, + "source": [ + "## The Softmax function\n", + "In case we employ the more general case given by the Softmax equation, we need to evaluate the derivative of the activation function with respect to the activation $z_i^l$, that is we need" + ] + }, + { + "cell_type": "markdown", + "id": "2a16cf53", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial w_{jk}^l} =\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l} \\frac{\\partial z_j^l}{\\partial w_{jk}^l}= \\frac{\\partial f(z_i^l)}{\\partial z_j^l}a_k^{l-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21988141", + "metadata": { + "editable": true + }, + "source": [ + "For the Softmax function we have" + ] + }, + { + "cell_type": "markdown", + "id": "b37cc0cd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "f(z_i^l) = \\frac{\\exp{(z_i^l)}}{\\sum_{m=1}^K\\exp{(z_m^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "259618c5", + "metadata": { + "editable": true + }, + "source": [ + "Its derivative with respect to $z_j^l$ gives" + ] + }, + { + "cell_type": "markdown", + "id": "af5a331e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l}= f(z_i^l)\\left(\\delta_{ij}-f(z_j^l)\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "208ab286", + "metadata": { + "editable": true + }, + "source": [ + "which in case of the simply binary model reduces to having $i=j$." + ] + }, + { + "cell_type": "markdown", + "id": "8f30fbc3", + "metadata": { + "editable": true + }, + "source": [ + "## Developing a code for doing neural networks with back propagation\n", + "\n", + "One can identify a set of key steps when using neural networks to solve supervised learning problems: \n", + "\n", + "1. Collect and pre-process data \n", + "\n", + "2. Define model and architecture \n", + "\n", + "3. Choose cost function and optimizer \n", + "\n", + "4. Train the model \n", + "\n", + "5. Evaluate model performance on test data \n", + "\n", + "6. Adjust hyperparameters (if necessary, network architecture)" + ] + }, + { + "cell_type": "markdown", + "id": "09538ef9", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Here we will be using the MNIST dataset, which is readily available through the **scikit-learn**\n", + "package. You may also find it for example [here](http://yann.lecun.com/exdb/mnist/). \n", + "The *MNIST* (Modified National Institute of Standards and Technology) database is a large database\n", + "of handwritten digits that is commonly used for training various image processing systems. \n", + "The MNIST dataset consists of 70 000 images of size $28\\times 28$ pixels, each labeled from 0 to 9. \n", + "The scikit-learn dataset we will use consists of a selection of 1797 images of size $8\\times 8$ collected and processed from this database. \n", + "\n", + "To feed data into a feed-forward neural network we need to represent\n", + "the inputs as a design/feature matrix $X = (n_{inputs}, n_{features})$. Each\n", + "row represents an *input*, in this case a handwritten digit, and\n", + "each column represents a *feature*, in this case a pixel. The\n", + "correct answers, also known as *labels* or *targets* are\n", + "represented as a 1D array of integers \n", + "$Y = (n_{inputs}) = (5, 3, 1, 8,...)$.\n", + "\n", + "As an example, say we want to build a neural network using supervised learning to predict Body-Mass Index (BMI) from\n", + "measurements of height (in m) \n", + "and weight (in kg). If we have measurements of 5 people the design/feature matrix could be for example: \n", + "\n", + "$$ X = \\begin{bmatrix}\n", + "1.85 & 81\\\\\n", + "1.71 & 65\\\\\n", + "1.95 & 103\\\\\n", + "1.55 & 42\\\\\n", + "1.63 & 56\n", + "\\end{bmatrix} ,$$ \n", + "\n", + "and the targets would be: \n", + "\n", + "$$ Y = (23.7, 22.2, 27.1, 17.5, 21.1) $$ \n", + "\n", + "Since each input image is a 2D matrix, we need to flatten the image\n", + "(i.e. \"unravel\" the 2D matrix into a 1D array) to turn the data into a\n", + "design/feature matrix. This means we lose all spatial information in the\n", + "image, such as locality and translational invariance. More complicated\n", + "architectures such as Convolutional Neural Networks can take advantage\n", + "of such information, and are most commonly applied when analyzing\n", + "images." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ced37e42", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "inputs = (n_inputs, pixel_width, pixel_height) = (1797, 8, 8)\n", + "labels = (n_inputs) = (1797,)\n", + "X = (n_inputs, n_features) = (1797, 64)\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7YAAADICAYAAADcOn20AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAQx0lEQVR4nO3dbWydZRkH8OuMjklYaEHMxla3ji46/KBdiItodB2oEUVXDNMYois6QgLCkKkhEGwHGDCaWIxODY510SUuJmSdZr4AdjUmxPBWEhaNjlBEzSYOOl+SbQwfPxhqN9Y68G7rdc7vl/QDZz3/c5+T6z7P899zOKtVVVUFAAAAJDVrphcAAAAA/wvFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgtYYptv39/VGr1eLhhx8ukler1eLTn/50kazxmb29va/6/nv37o2Pf/zjsWjRojjttNOivb09brjhhjhw4EC5RZJSvc9/b29v1Gq1CX++//3vF10r+dgD9kAjq/f5f+aZZ+LSSy+Nc889N04//fRobm6O5cuXx9e//vU4evRo0XWSj/lvHE0zvQDKePbZZ+Ntb3tbnHHGGXHbbbfFokWL4rHHHouenp4YHByMRx55JGbNapi/x6DBrFu3Lt73vve97PYrr7wynnzyyRP+GdQTe4BG9o9//CPOOOOMuOWWW2LRokVx5MiR2LVrV1x77bUxPDwc3/nOd2Z6iTBlzP9/KLZ1YmBgIA4cOBDbt2+Piy66KCIiVq1aFYcPH46bbropHn/88Vi+fPkMrxKmRmtra7S2th5z28jISOzZsycuv/zyaGlpmZmFwTSxB2hky5Yti61btx5z28UXXxx//vOfY+vWrfGNb3wj5syZM0Org6ll/v/DJbxxDh06FBs2bIiOjo5obm6Os846Ky644IIYGBiY8D7f/va34w1veEPMmTMn3vSmN53w41779u2Lq666KlpbW+PUU0+NJUuWxMaNG4t+PGD27NkREdHc3HzM7S+dzLzmNa8p9ljUp8zzfyL33HNPVFUV69atm9LHoX7YAzSyepv/iIjXve51MWvWrDjllFOm/LHIzfzXB1dsxzl8+HA899xz8dnPfjYWLlwYR44cifvvvz8+/OEPx5YtW+ITn/jEMb+/c+fOGBwcjFtvvTVOP/302LRpU3zsYx+LpqamuOyyyyLi3wO9YsWKmDVrVnzhC1+I9vb2ePDBB+P222+PkZGR2LJly6Rramtri4h//837ZLq6umLRokWxYcOG2LRpUyxevDgeffTRuPPOO+ODH/xgnHfeea/6daExZJ7/4/3zn/+M/v7+WLp0aaxcufIV3ZfGZQ/QyOph/quqihdffDH+9re/xc9+9rPo7++PDRs2RFOT010mZ/7rRNUgtmzZUkVE9dBDD530fY4ePVq98MIL1ac+9alq+fLlx/xZRFSnnXZatW/fvmN+f9myZdXSpUvHbrvqqququXPnVk8//fQx9//KV75SRUS1Z8+eYzJ7enqO+b329vaqvb39pNb7pz/9qbrggguqiBj7WbNmTXXo0KGTfcrUqUaY//F+/OMfVxFR3XHHHa/4vtQne4BG1ijzf8cdd4yd/9Rqtermm28+6ftSv8x/4/BR5OP84Ac/iHe84x0xd+7caGpqitmzZ8fmzZvj17/+9ct+96KLLop58+aN/fcpp5wSH/3oR2Pv3r3xhz/8ISIifvSjH8WqVatiwYIFcfTo0bGfiy++OCIihoaGJl3P3r17Y+/evf913c8//3ysXr06/vrXv8a2bdviF7/4RWzatCl++ctfxoc+9KGG+1Y0Xp2s83+8zZs3R1NTU3R3d7/i+9LY7AEaWfb57+7ujoceeih++tOfxuc///n48pe/HNdee+1J35/GZv7za6Br0//dvffeGx/5yEdizZo18bnPfS7mz58fTU1N8c1vfjPuueeel/3+/PnzJ7ztwIED0draGvv3748f/vCHY/8P7PH+8pe/FFn7l770pRgeHo6nn346zjnnnIiIeOc73xnLli2LCy+8MLZt2xZr164t8ljUp8zzf3zmzp074wMf+MAJ1wgTsQdoZPUw//Pnzx9bw3vf+94488wz48Ybb4xPfvKTvkCTSZn/+qDYjvO9730vlixZEtu3b49arTZ2++HDh0/4+/v27Zvwtte+9rUREXH22WfHm9/85vjiF794wowFCxb8r8uOiIjh4eFYuHDhWKl9yVvf+taIiHjiiSeKPA71K/P8j/fd7343jhw54gtzeMXsARpZvcz/eCtWrIiIiN/+9rcNc2LPq2P+64NiO06tVotTTz31mIHet2/fhN+I9sADD8T+/fvHPorw4osvxvbt26O9vX3sn1245JJLYteuXdHe3h5nnnnmlK19wYIF8cADD8Qf//jHWLhw4djtDz74YETEy/4ZCDhe5vkfb/PmzbFgwYKxj/rAybIHaGT1Mv/jDQ4ORkTE0qVLp/2xycX814eGK7Y///nPT/jtYu9///vjkksuiXvvvTeuvvrquOyyy+KZZ56J2267Lc4555z43e9+97L7nH322XHhhRfGLbfcMvaNaL/5zW+O+brvW2+9Ne677754+9vfHtddd1288Y1vjEOHDsXIyEjs2rUrvvWtb01aOl8axv/2Gftrrrkmtm3bFu95z3vixhtvjNe//vXxxBNPxO233x7z5s2Lyy+//CRfIepZvc7/S371q1/Fnj174qabbmqor7fn5NkDNLJ6nf+enp7Yv39/vOtd74qFCxfG6Oho/OQnP4m777471qxZE+eff/5JvkLUM/PfAGb626umy0vfiDbRz1NPPVVVVVXdeeedVVtbWzVnzpzqvPPOq+6+++6qp6enOv6liojqmmuuqTZt2lS1t7dXs2fPrpYtW1Zt27btZY/97LPPVtddd121ZMmSavbs2dVZZ51VnX/++dXNN99c/f3vfz8m8/hvRFu8eHG1ePHik3qOjz76aHXppZdWra2t1Zw5c6pzzz23WrduXfX73//+Fb1W1J9GmP+qqqorr7yyqtVq1ZNPPnnS96Ex2AM0snqf/507d1bvfve7q3nz5lVNTU3V3LlzqxUrVlRf+9rXqhdeeOEVv17UF/PfOGpVVVWlyzIAAABMF//cDwAAAKkptgAAAKSm2AIAAJCaYgsAAEBqii0AAACpKbYAAACkptgCAACQWtNML6CU/v7+onm9vb1F81paWormRUT09fUVzevs7Cyax/TZvXt30bzS+2nHjh1F8yIiDh48WDRvcHCwaJ79NL0GBgaK5q1fv75o3lQove/b2tqK5jGxkZGRonmlzwdKHwNKv19HRDQ3NxfNGx4eLppnP01udHS0aN7/+x4o/XwjzOyJuGILAABAaootAAAAqSm2AAAApKbYAgAAkJpiCwAAQGqKLQAAAKkptgAAAKSm2AIAAJCaYgsAAEBqii0AAACpKbYAAACkptgCAACQmmILAABAaootAAAAqSm2AAAApKbYAgAAkJpiCwAAQGqKLQAAAKk1zdQD7969u2jeFVdcUTRv9erVRfNaWlqK5kVEdHV1Fc0bHR0tmsf0uf7664vmlZ6F7u7uonkREXfddVfRvKnYo0xsZGSkaF7p98MMduzYUTSv9PsIE/t/f623bt1aNG9wcLBoXkT5Y4BzoOlV+vUu/X5Y+phSen0REf39/UXzent7i+bNBFdsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUalVVVTPxwNdff33RvJGRkaJ5O3bsKJrX2dlZNC8ioqWlpWhe6efM9Ck9/6Vna2hoqGheRMTatWuL5o2OjhbNY3r19fUVzevo6Ciat2rVqqJ5ERErV64smrd79+6iefCS0ud8ERHDw8NF88w/U2kqekDp41Tp4+hMcMUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEitaaYeuK2trWjeyMhI0bze3t6ieUNDQ0XzIiIee+yx4pnkNDo6WjSv9H7q6ekpmhcR0dLSUjSv9HMu/R7H5Lq7u4vmlT4GTIXSx5XSzznDa8j06OjoKJ7Z399fNK/0cbT0MYrJlT6Gd3V1Fc2bCn19fTO9hP87rtgCAACQmmILAABAaootAAAAqSm2AAAApKbYAgAAkJpiCwAAQGqKLQAAAKkptgAAAKSm2AIAAJCaYgsAAEBqii0AAACpKbYAAACkptgCAACQmmILAABAaootAAAAqSm2AAAApKbYAgAAkJpiCwAAQGqKLQAAAKnVqqqqZnoRJXR0dBTNe/zxx4vmrV27tmheRER/f3/xTKbHwMBA0byurq6ieY2op6enaF5vb2/RvHozPDxcNK+zs7No3sGDB4vmTYXSx5XSM9vW1lY0D8YrPV+lj6N9fX1F85hcIx5TtmzZUjSvu7u7aN5McMUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACC1WlVV1UwvooSOjo6ZXsKkWlpaimeWfs59fX1F85jY7t27i+bt2LGjaN7w8HDRvJGRkaJ5EeXXOBV7lImV3gOrVq0qmlfa6tWri2eW3veQSWdn50wvYVKl3+Pqzejo6EwvYVKlzwmmYl5Ln1tNxbnadHPFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABIrWmmF1BKS0tL0bzOzs6ieb29vUXzIso/59JrLL2+elJ6vg4ePFg0r7+/v2heV1dX0bwI85Vd6T2wfv36onl33XVX0bwrrriiaB6MNzAwUDRv8eLFRfOGh4eL5k1F5lScpzGxoaGhonk9PT1F8zZu3Fg0r7u7u2heRPnjyujoaNG8mThPc8UWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEitaaYXUMpnPvOZonldXV1F8zZu3Fg0LyJi9erVRfNaWlqK5jF9nn/++aJ5Bw8eLJrX3d1dNA+m2lve8paieaXfr2G8r371q0XzhoaGiuY1NzcXzYsof1xxnJpeK1euLJrX2dlZNK/0nhodHS2aFxGxfv36onn10ANcsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUlNsAQAASE2xBQAAIDXFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1BRbAAAAUqtVVVXN9CIAAADg1XLFFgAAgNQUWwAAAFJTbAEAAEhNsQUAACA1xRYAAIDUFFsAAABSU2wBAABITbEFAAAgNcUWAACA1P4F8SqxxH5w1EMAAAAASUVORK5CYII=", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "filenames": { + "image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/week42_242_1.png" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "ebabb274", + "metadata": { + "editable": true + }, + "source": [ + "## Train and test datasets\n", + "\n", + "Performing analysis before partitioning the dataset is a major error, that can lead to incorrect conclusions. \n", + "\n", + "We will reserve $80 \\%$ of our dataset for training and $20 \\%$ for testing. \n", + "\n", + "It is important that the train and test datasets are drawn randomly from our dataset, to ensure\n", + "no bias in the sampling. \n", + "Say you are taking measurements of weather data to predict the weather in the coming 5 days.\n", + "You don't want to train your model on measurements taken from the hours 00.00 to 12.00, and then test it on data\n", + "collected from 12.00 to 24.00." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2c87b9f9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of training images: 1437\n", + "Number of test images: 360\n" + ] + } + ], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-liner from scikit-learn library\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)\n", + "\n", + "# equivalently in numpy\n", + "def train_test_split_numpy(inputs, labels, train_size, test_size):\n", + " n_inputs = len(inputs)\n", + " inputs_shuffled = inputs.copy()\n", + " labels_shuffled = labels.copy()\n", + " \n", + " np.random.shuffle(inputs_shuffled)\n", + " np.random.shuffle(labels_shuffled)\n", + " \n", + " train_end = int(n_inputs*train_size)\n", + " X_train, X_test = inputs_shuffled[:train_end], inputs_shuffled[train_end:]\n", + " Y_train, Y_test = labels_shuffled[:train_end], labels_shuffled[train_end:]\n", + " \n", + " return X_train, X_test, Y_train, Y_test\n", + "\n", + "#X_train, X_test, Y_train, Y_test = train_test_split_numpy(inputs, labels, train_size, test_size)\n", + "\n", + "print(\"Number of training images: \" + str(len(X_train)))\n", + "print(\"Number of test images: \" + str(len(X_test)))" + ] + }, + { + "cell_type": "markdown", + "id": "0c186fec", + "metadata": { + "editable": true + }, + "source": [ + "## Define model and architecture\n", + "\n", + "Our simple feed-forward neural network will consist of an *input* layer, a single *hidden* layer and an *output* layer. The activation $y$ of each neuron is a weighted sum of inputs, passed through an activation function. In case of the simple perceptron model we have \n", + "\n", + "$$ z = \\sum_{i=1}^n w_i a_i ,$$\n", + "\n", + "$$ y = f(z) ,$$\n", + "\n", + "where $f$ is the activation function, $a_i$ represents input from neuron $i$ in the preceding layer\n", + "and $w_i$ is the weight to input $i$. \n", + "The activation of the neurons in the input layer is just the features (e.g. a pixel value). \n", + "\n", + "The simplest activation function for a neuron is the *Heaviside* function:\n", + "\n", + "$$ f(z) = \n", + "\\begin{cases}\n", + "1, & z > 0\\\\\n", + "0, & \\text{otherwise}\n", + "\\end{cases}\n", + "$$\n", + "\n", + "A feed-forward neural network with this activation is known as a *perceptron*. \n", + "For a binary classifier (i.e. two classes, 0 or 1, dog or not-dog) we can also use this in our output layer. \n", + "This activation can be generalized to $k$ classes (using e.g. the *one-against-all* strategy), \n", + "and we call these architectures *multiclass perceptrons*. \n", + "\n", + "However, it is now common to use the terms Single Layer Perceptron (SLP) (1 hidden layer) and \n", + "Multilayer Perceptron (MLP) (2 or more hidden layers) to refer to feed-forward neural networks with any activation function. \n", + "\n", + "Typical choices for activation functions include the sigmoid function, hyperbolic tangent, and Rectified Linear Unit (ReLU). \n", + "We will be using the sigmoid function $\\sigma(x)$: \n", + "\n", + "$$ f(x) = \\sigma(x) = \\frac{1}{1 + e^{-x}} ,$$\n", + "\n", + "which is inspired by probability theory (see logistic regression) and was most commonly used until about 2011. See the discussion below concerning other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "2cbece98", + "metadata": { + "editable": true + }, + "source": [ + "## Layers\n", + "\n", + "* Input \n", + "\n", + "Since each input image has 8x8 = 64 pixels or features, we have an input layer of 64 neurons. \n", + "\n", + "* Hidden layer\n", + "\n", + "We will use 50 neurons in the hidden layer receiving input from the neurons in the input layer. \n", + "Since each neuron in the hidden layer is connected to the 64 inputs we have 64x50 = 3200 weights to the hidden layer. \n", + "\n", + "* Output\n", + "\n", + "If we were building a binary classifier, it would be sufficient with a single neuron in the output layer,\n", + "which could output 0 or 1 according to the Heaviside function. This would be an example of a *hard* classifier, meaning it outputs the class of the input directly. However, if we are dealing with noisy data it is often beneficial to use a *soft* classifier, which outputs the probability of being in class 0 or 1. \n", + "\n", + "For a soft binary classifier, we could use a single neuron and interpret the output as either being the probability of being in class 0 or the probability of being in class 1. Alternatively we could use 2 neurons, and interpret each neuron as the probability of being in each class. \n", + "\n", + "Since we are doing multiclass classification, with 10 categories, it is natural to use 10 neurons in the output layer. We number the neurons $j = 0,1,...,9$. The activation of each output neuron $j$ will be according to the *softmax* function: \n", + "\n", + "$$ P(\\text{class $j$} \\mid \\text{input $\\boldsymbol{a}$}) = \\frac{\\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_j)}}\n", + "{\\sum_{c=0}^{9} \\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_c)}} ,$$ \n", + "\n", + "i.e. each neuron $j$ outputs the probability of being in class $j$ given an input from the hidden layer $\\boldsymbol{a}$, with $\\boldsymbol{w}_j$ the weights of neuron $j$ to the inputs. \n", + "The denominator is a normalization factor to ensure the outputs (probabilities) sum up to 1. \n", + "The exponent is just the weighted sum of inputs as before: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i+b_j.$$ \n", + "\n", + "Since each neuron in the output layer is connected to the 50 inputs from the hidden layer we have 50x10 = 500\n", + "weights to the output layer." + ] + }, + { + "cell_type": "markdown", + "id": "442935af", + "metadata": { + "editable": true + }, + "source": [ + "## Weights and biases\n", + "\n", + "Typically weights are initialized with small values distributed around zero, drawn from a uniform\n", + "or normal distribution. Setting all weights to zero means all neurons give the same output, making the network useless. \n", + "\n", + "Adding a bias value to the weighted sum of inputs allows the neural network to represent a greater range\n", + "of values. Without it, any input with the value 0 will be mapped to zero (before being passed through the activation). The bias unit has an output of 1, and a weight to each neuron $j$, $b_j$: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i + b_j.$$ \n", + "\n", + "The bias weights $\\boldsymbol{b}$ are often initialized to zero, but a small value like $0.01$ ensures all neurons have some output which can be backpropagated in the first training cycle." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "07fbb18c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# building our neural network\n", + "\n", + "n_inputs, n_features = X_train.shape\n", + "n_hidden_neurons = 50\n", + "n_categories = 10\n", + "\n", + "# we make the weights normally distributed using numpy.random.randn\n", + "\n", + "# weights and bias in the hidden layer\n", + "hidden_weights = np.random.randn(n_features, n_hidden_neurons)\n", + "hidden_bias = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "output_weights = np.random.randn(n_hidden_neurons, n_categories)\n", + "output_bias = np.zeros(n_categories) + 0.01" + ] + }, + { + "cell_type": "markdown", + "id": "6a3ea326", + "metadata": { + "editable": true + }, + "source": [ + "## Feed-forward pass\n", + "\n", + "Denote $F$ the number of features, $H$ the number of hidden neurons and $C$ the number of categories. \n", + "For each input image we calculate a weighted sum of input features (pixel values) to each neuron $j$ in the hidden layer $l$: \n", + "\n", + "$$ z_{j}^{l} = \\sum_{i=1}^{F} w_{ij}^{l} x_i + b_{j}^{l},$$\n", + "\n", + "this is then passed through our activation function \n", + "\n", + "$$ a_{j}^{l} = f(z_{j}^{l}) .$$ \n", + "\n", + "We calculate a weighted sum of inputs (activations in the hidden layer) to each neuron $j$ in the output layer: \n", + "\n", + "$$ z_{j}^{L} = \\sum_{i=1}^{H} w_{ij}^{L} a_{i}^{l} + b_{j}^{L}.$$ \n", + "\n", + "Finally we calculate the output of neuron $j$ in the output layer using the softmax function: \n", + "\n", + "$$ a_{j}^{L} = \\frac{\\exp{(z_j^{L})}}\n", + "{\\sum_{c=0}^{C-1} \\exp{(z_c^{L})}} .$$" + ] + }, + { + "cell_type": "markdown", + "id": "525624c4", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplications\n", + "\n", + "Since our data has the dimensions $X = (n_{inputs}, n_{features})$ and our weights to the hidden\n", + "layer have the dimensions \n", + "$W_{hidden} = (n_{features}, n_{hidden})$,\n", + "we can easily feed the network all our training data in one go by taking the matrix product \n", + "\n", + "$$ X W^{h} = (n_{inputs}, n_{hidden}),$$ \n", + "\n", + "and obtain a matrix that holds the weighted sum of inputs to the hidden layer\n", + "for each input image and each hidden neuron. \n", + "We also add the bias to obtain a matrix of weighted sums to the hidden layer $Z^{h}$: \n", + "\n", + "$$ \\boldsymbol{z}^{l} = \\boldsymbol{X} \\boldsymbol{W}^{l} + \\boldsymbol{b}^{l} ,$$\n", + "\n", + "meaning the same bias (1D array with size equal number of hidden neurons) is added to each input image. \n", + "This is then passed through the activation: \n", + "\n", + "$$ \\boldsymbol{a}^{l} = f(\\boldsymbol{z}^l) .$$ \n", + "\n", + "This is fed to the output layer: \n", + "\n", + "$$ \\boldsymbol{z}^{L} = \\boldsymbol{a}^{L} \\boldsymbol{W}^{L} + \\boldsymbol{b}^{L} .$$\n", + "\n", + "Finally we receive our output values for each image and each category by passing it through the softmax function: \n", + "\n", + "$$ output = softmax (\\boldsymbol{z}^{L}) = (n_{inputs}, n_{categories}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "32d0a43f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "probabilities = (n_inputs, n_categories) = (1437, 10)\n", + "probability that image 0 is in category 0,1,2,...,9 = \n", + "[5.41511965e-04 2.17174962e-03 8.84355903e-03 1.44970586e-03\n", + " 1.10378326e-04 5.08318298e-09 2.03256632e-04 1.92507116e-03\n", + " 9.84443254e-01 3.11507992e-04]\n", + "probabilities sum up to: 1.0\n", + "\n", + "predictions = (n_inputs) = (1437,)\n", + "prediction for image 0: 8\n", + "correct label for image 0: 6\n" + ] + } + ], + "source": [ + "# setup the feed-forward pass, subscript h = hidden layer\n", + "\n", + "def sigmoid(x):\n", + " return 1/(1 + np.exp(-x))\n", + "\n", + "def feed_forward(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " return probabilities\n", + "\n", + "probabilities = feed_forward(X_train)\n", + "print(\"probabilities = (n_inputs, n_categories) = \" + str(probabilities.shape))\n", + "print(\"probability that image 0 is in category 0,1,2,...,9 = \\n\" + str(probabilities[0]))\n", + "print(\"probabilities sum up to: \" + str(probabilities[0].sum()))\n", + "print()\n", + "\n", + "# we obtain a prediction by taking the class with the highest likelihood\n", + "def predict(X):\n", + " probabilities = feed_forward(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + "predictions = predict(X_train)\n", + "print(\"predictions = (n_inputs) = \" + str(predictions.shape))\n", + "print(\"prediction for image 0: \" + str(predictions[0]))\n", + "print(\"correct label for image 0: \" + str(Y_train[0]))" + ] + }, + { + "cell_type": "markdown", + "id": "da2ede88", + "metadata": { + "editable": true + }, + "source": [ + "## Choose cost function and optimizer\n", + "\n", + "To measure how well our neural network is doing we need to introduce a cost function. \n", + "We will call the function that gives the error of a single sample output the *loss* function, and the function\n", + "that gives the total error of our network across all samples the *cost* function.\n", + "A typical choice for multiclass classification is the *cross-entropy* loss, also known as the negative log likelihood. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$$ y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$$ \n", + "\n", + "$$ y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset. \n", + "\n", + "Let $y_{ic}$ denote the $c$-th component of the $i$-th one-hot vector. \n", + "We define the cost function $\\mathcal{C}$ as a sum over the cross-entropy loss for each point $\\boldsymbol{x}_i$ in the dataset.\n", + "\n", + "In the one-hot representation only one of the terms in the loss function is non-zero, namely the\n", + "probability of the correct category $c'$ \n", + "(i.e. the category $c'$ such that $y_{ic'} = 1$). This means that the cross entropy loss only punishes you for how wrong\n", + "you got the correct label. The probability of category $c$ is given by the softmax function. The vector $\\boldsymbol{\\theta}$ represents the parameters of our network, i.e. all the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "069a250d", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the cost function\n", + "\n", + "The network is trained by finding the weights and biases that minimize the cost function. One of the most widely used classes of methods is *gradient descent* and its generalizations. The idea behind gradient descent\n", + "is simply to adjust the weights in the direction where the gradient of the cost function is large and negative. This ensures we flow toward a *local* minimum of the cost function. \n", + "Each parameter $\\theta$ is iteratively adjusted according to the rule \n", + "\n", + "$$ \\theta_{i+1} = \\theta_i - \\eta \\nabla \\mathcal{C}(\\theta_i) ,$$\n", + "\n", + "where $\\eta$ is known as the *learning rate*, which controls how big a step we take towards the minimum. \n", + "This update can be repeated for any number of iterations, or until we are satisfied with the result. \n", + "\n", + "A simple and effective improvement is a variant called *Batch Gradient Descent*. \n", + "Instead of calculating the gradient on the whole dataset, we calculate an approximation of the gradient\n", + "on a subset of the data called a *minibatch*. \n", + "If there are $N$ data points and we have a minibatch size of $M$, the total number of batches\n", + "is $N/M$. \n", + "We denote each minibatch $B_k$, with $k = 1, 2,...,N/M$. The gradient then becomes: \n", + "\n", + "$$ \\nabla \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\nabla \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{M} \\sum_{i \\in B_k} \\nabla \\mathcal{L}_i(\\theta) ,$$\n", + "\n", + "i.e. instead of averaging the loss over the entire dataset, we average over a minibatch. \n", + "\n", + "This has two important benefits: \n", + "1. Introducing stochasticity decreases the chance that the algorithm becomes stuck in a local minima. \n", + "\n", + "2. It significantly speeds up the calculation, since we do not have to use the entire dataset to calculate the gradient. \n", + "\n", + "The various optmization methods, with codes and algorithms, are discussed in our lectures on [Gradient descent approaches](https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html)." + ] + }, + { + "cell_type": "markdown", + "id": "29ab6ee7", + "metadata": { + "editable": true + }, + "source": [ + "## Regularization\n", + "\n", + "It is common to add an extra term to the cost function, proportional\n", + "to the size of the weights. This is equivalent to constraining the\n", + "size of the weights, so that they do not grow out of control.\n", + "Constraining the size of the weights means that the weights cannot\n", + "grow arbitrarily large to fit the training data, and in this way\n", + "reduces *overfitting*.\n", + "\n", + "We will measure the size of the weights using the so called *L2-norm*, meaning our cost function becomes: \n", + "\n", + "$$ \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) + \\lambda \\lvert \\lvert \\boldsymbol{w} \\rvert \\rvert_2^2 \n", + "= \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\theta) + \\lambda \\sum_{ij} w_{ij}^2,$$ \n", + "\n", + "i.e. we sum up all the weights squared. The factor $\\lambda$ is known as a regularization parameter.\n", + "\n", + "In order to train the model, we need to calculate the derivative of\n", + "the cost function with respect to every bias and weight in the\n", + "network. In total our network has $(64 + 1)\\times 50=3250$ weights in\n", + "the hidden layer and $(50 + 1)\\times 10=510$ weights to the output\n", + "layer ($+1$ for the bias), and the gradient must be calculated for\n", + "every parameter. We use the *backpropagation* algorithm discussed\n", + "above. This is a clever use of the chain rule that allows us to\n", + "calculate the gradient efficently." + ] + }, + { + "cell_type": "markdown", + "id": "b7c4a178", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplication\n", + "\n", + "To more efficently train our network these equations are implemented using matrix operations. \n", + "The error in the output layer is calculated simply as, with $\\boldsymbol{t}$ being our targets, \n", + "\n", + "$$ \\delta_L = \\boldsymbol{t} - \\boldsymbol{y} = (n_{inputs}, n_{categories}) .$$ \n", + "\n", + "The gradient for the output weights is calculated as \n", + "\n", + "$$ \\nabla W_{L} = \\boldsymbol{a}^T \\delta_L = (n_{hidden}, n_{categories}) ,$$\n", + "\n", + "where $\\boldsymbol{a} = (n_{inputs}, n_{hidden})$. This simply means that we are summing up the gradients for each input. \n", + "Since we are going backwards we have to transpose the activation matrix. \n", + "\n", + "The gradient with respect to the output bias is then \n", + "\n", + "$$ \\nabla \\boldsymbol{b}_{L} = \\sum_{i=1}^{n_{inputs}} \\delta_L = (n_{categories}) .$$ \n", + "\n", + "The error in the hidden layer is \n", + "\n", + "$$ \\Delta_h = \\delta_L W_{L}^T \\circ f'(z_{h}) = \\delta_L W_{L}^T \\circ a_{h} \\circ (1 - a_{h}) = (n_{inputs}, n_{hidden}) ,$$ \n", + "\n", + "where $f'(a_{h})$ is the derivative of the activation in the hidden layer. The matrix products mean\n", + "that we are summing up the products for each neuron in the output layer. The symbol $\\circ$ denotes\n", + "the *Hadamard product*, meaning element-wise multiplication. \n", + "\n", + "This again gives us the gradients in the hidden layer: \n", + "\n", + "$$ \\nabla W_{h} = X^T \\delta_h = (n_{features}, n_{hidden}) ,$$ \n", + "\n", + "$$ \\nabla b_{h} = \\sum_{i=1}^{n_{inputs}} \\delta_h = (n_{hidden}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4142969e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Old accuracy on training data: 0.1440501043841336\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/td/3yk470mj5p931p9dtkk0y6jw0000gn/T/ipykernel_47048/953065564.py:4: RuntimeWarning: overflow encountered in exp\n", + " return 1/(1 + np.exp(-x))\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[7], line 56\u001b[0m\n\u001b[1;32m 53\u001b[0m lmbd \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.01\u001b[39m\n\u001b[1;32m 54\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m1000\u001b[39m):\n\u001b[1;32m 55\u001b[0m \u001b[38;5;66;03m# calculate gradients\u001b[39;00m\n\u001b[0;32m---> 56\u001b[0m dWo, dBo, dWh, dBh \u001b[38;5;241m=\u001b[39m \u001b[43mbackpropagation\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mY_train_onehot\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 58\u001b[0m \u001b[38;5;66;03m# regularization term gradients\u001b[39;00m\n\u001b[1;32m 59\u001b[0m dWo \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m lmbd \u001b[38;5;241m*\u001b[39m output_weights\n", + "Cell \u001b[0;32mIn[7], line 38\u001b[0m, in \u001b[0;36mbackpropagation\u001b[0;34m(X, Y)\u001b[0m\n\u001b[1;32m 36\u001b[0m error_output \u001b[38;5;241m=\u001b[39m probabilities \u001b[38;5;241m-\u001b[39m Y\n\u001b[1;32m 37\u001b[0m \u001b[38;5;66;03m# error in the hidden layer\u001b[39;00m\n\u001b[0;32m---> 38\u001b[0m error_hidden \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmatmul\u001b[49m\u001b[43m(\u001b[49m\u001b[43merror_output\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moutput_weights\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mT\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m*\u001b[39m a_h \u001b[38;5;241m*\u001b[39m (\u001b[38;5;241m1\u001b[39m \u001b[38;5;241m-\u001b[39m a_h)\n\u001b[1;32m 40\u001b[0m \u001b[38;5;66;03m# gradients for the output layer\u001b[39;00m\n\u001b[1;32m 41\u001b[0m output_weights_gradient \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mmatmul(a_h\u001b[38;5;241m.\u001b[39mT, error_output)\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "# to categorical turns our integer vector into a onehot representation\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# one-hot in numpy\n", + "def to_categorical_numpy(integer_vector):\n", + " n_inputs = len(integer_vector)\n", + " n_categories = np.max(integer_vector) + 1\n", + " onehot_vector = np.zeros((n_inputs, n_categories))\n", + " onehot_vector[range(n_inputs), integer_vector] = 1\n", + " \n", + " return onehot_vector\n", + "\n", + "#Y_train_onehot, Y_test_onehot = to_categorical(Y_train), to_categorical(Y_test)\n", + "Y_train_onehot, Y_test_onehot = to_categorical_numpy(Y_train), to_categorical_numpy(Y_test)\n", + "\n", + "def feed_forward_train(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " # for backpropagation need activations in hidden and output layers\n", + " return a_h, probabilities\n", + "\n", + "def backpropagation(X, Y):\n", + " a_h, probabilities = feed_forward_train(X)\n", + " \n", + " # error in the output layer\n", + " error_output = probabilities - Y\n", + " # error in the hidden layer\n", + " error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h)\n", + " \n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_h.T, error_output)\n", + " output_bias_gradient = np.sum(error_output, axis=0)\n", + " \n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(X.T, error_hidden)\n", + " hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "print(\"Old accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))\n", + "\n", + "eta = 0.01\n", + "lmbd = 0.01\n", + "for i in range(1000):\n", + " # calculate gradients\n", + " dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot)\n", + " \n", + " # regularization term gradients\n", + " dWo += lmbd * output_weights\n", + " dWh += lmbd * hidden_weights\n", + " \n", + " # update weights and biases\n", + " output_weights -= eta * dWo\n", + " output_bias -= eta * dBo\n", + " hidden_weights -= eta * dWh\n", + " hidden_bias -= eta * dBh\n", + "\n", + "print(\"New accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))" + ] + }, + { + "cell_type": "markdown", + "id": "4d79c3b3", + "metadata": { + "editable": true + }, + "source": [ + "## Improving performance\n", + "\n", + "As we can see the network does not seem to be learning at all. It seems to be just guessing the label for each image. \n", + "In order to obtain a network that does something useful, we will have to do a bit more work. \n", + "\n", + "The choice of *hyperparameters* such as learning rate and regularization parameter is hugely influential for the performance of the network. Typically a *grid-search* is performed, wherein we test different hyperparameters separated by orders of magnitude. For example we could test the learning rates $\\eta = 10^{-6}, 10^{-5},...,10^{-1}$ with different regularization parameters $\\lambda = 10^{-6},...,10^{-0}$. \n", + "\n", + "Next, we haven't implemented minibatching yet, which introduces stochasticity and is though to act as an important regularizer on the weights. We call a feed-forward + backward pass with a minibatch an *iteration*, and a full training period\n", + "going through the entire dataset ($n/M$ batches) an *epoch*.\n", + "\n", + "If this does not improve network performance, you may want to consider altering the network architecture, adding more neurons or hidden layers. \n", + "Andrew Ng goes through some of these considerations in this [video](https://youtu.be/F1ka6a13S9I). You can find a summary of the video [here](https://kevinzakka.github.io/2016/09/26/applying-deep-learning/)." + ] + }, + { + "cell_type": "markdown", + "id": "58012d93", + "metadata": { + "editable": true + }, + "source": [ + "## Full object-oriented implementation\n", + "\n", + "It is very natural to think of the network as an object, with specific instances of the network\n", + "being realizations of this object with different hyperparameters. An implementation using Python classes provides a clean structure and interface, and the full implementation of our neural network is given below." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ea4b7741", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "class NeuralNetwork:\n", + " def __init__(\n", + " self,\n", + " X_data,\n", + " Y_data,\n", + " n_hidden_neurons=50,\n", + " n_categories=10,\n", + " epochs=10,\n", + " batch_size=100,\n", + " eta=0.1,\n", + " lmbd=0.0):\n", + "\n", + " self.X_data_full = X_data\n", + " self.Y_data_full = Y_data\n", + "\n", + " self.n_inputs = X_data.shape[0]\n", + " self.n_features = X_data.shape[1]\n", + " self.n_hidden_neurons = n_hidden_neurons\n", + " self.n_categories = n_categories\n", + "\n", + " self.epochs = epochs\n", + " self.batch_size = batch_size\n", + " self.iterations = self.n_inputs // self.batch_size\n", + " self.eta = eta\n", + " self.lmbd = lmbd\n", + "\n", + " self.create_biases_and_weights()\n", + "\n", + " def create_biases_and_weights(self):\n", + " self.hidden_weights = np.random.randn(self.n_features, self.n_hidden_neurons)\n", + " self.hidden_bias = np.zeros(self.n_hidden_neurons) + 0.01\n", + "\n", + " self.output_weights = np.random.randn(self.n_hidden_neurons, self.n_categories)\n", + " self.output_bias = np.zeros(self.n_categories) + 0.01\n", + "\n", + " def feed_forward(self):\n", + " # feed-forward for training\n", + " self.z_h = np.matmul(self.X_data, self.hidden_weights) + self.hidden_bias\n", + " self.a_h = sigmoid(self.z_h)\n", + "\n", + " self.z_o = np.matmul(self.a_h, self.output_weights) + self.output_bias\n", + "\n", + " exp_term = np.exp(self.z_o)\n", + " self.probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + "\n", + " def feed_forward_out(self, X):\n", + " # feed-forward for output\n", + " z_h = np.matmul(X, self.hidden_weights) + self.hidden_bias\n", + " a_h = sigmoid(z_h)\n", + "\n", + " z_o = np.matmul(a_h, self.output_weights) + self.output_bias\n", + " \n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " return probabilities\n", + "\n", + " def backpropagation(self):\n", + " error_output = self.probabilities - self.Y_data\n", + " error_hidden = np.matmul(error_output, self.output_weights.T) * self.a_h * (1 - self.a_h)\n", + "\n", + " self.output_weights_gradient = np.matmul(self.a_h.T, error_output)\n", + " self.output_bias_gradient = np.sum(error_output, axis=0)\n", + "\n", + " self.hidden_weights_gradient = np.matmul(self.X_data.T, error_hidden)\n", + " self.hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " if self.lmbd > 0.0:\n", + " self.output_weights_gradient += self.lmbd * self.output_weights\n", + " self.hidden_weights_gradient += self.lmbd * self.hidden_weights\n", + "\n", + " self.output_weights -= self.eta * self.output_weights_gradient\n", + " self.output_bias -= self.eta * self.output_bias_gradient\n", + " self.hidden_weights -= self.eta * self.hidden_weights_gradient\n", + " self.hidden_bias -= self.eta * self.hidden_bias_gradient\n", + "\n", + " def predict(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + " def predict_probabilities(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return probabilities\n", + "\n", + " def train(self):\n", + " data_indices = np.arange(self.n_inputs)\n", + "\n", + " for i in range(self.epochs):\n", + " for j in range(self.iterations):\n", + " # pick datapoints with replacement\n", + " chosen_datapoints = np.random.choice(\n", + " data_indices, size=self.batch_size, replace=False\n", + " )\n", + "\n", + " # minibatch training data\n", + " self.X_data = self.X_data_full[chosen_datapoints]\n", + " self.Y_data = self.Y_data_full[chosen_datapoints]\n", + "\n", + " self.feed_forward()\n", + " self.backpropagation()" + ] + }, + { + "cell_type": "markdown", + "id": "04860b2c", + "metadata": { + "editable": true + }, + "source": [ + "## Evaluate model performance on test data\n", + "\n", + "To measure the performance of our network we evaluate how well it does it data it has never seen before, i.e. the test data. \n", + "We measure the performance of the network using the *accuracy* score. \n", + "The accuracy is as you would expect just the number of images correctly labeled divided by the total number of images. A perfect classifier will have an accuracy score of $1$. \n", + "\n", + "$$ \\text{Accuracy} = \\frac{\\sum_{i=1}^n I(\\tilde{y}_i = y_i)}{n} ,$$ \n", + "\n", + "where $I$ is the indicator function, $1$ if $\\tilde{y}_i = y_i$ and $0$ otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b52d4df3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "epochs = 100\n", + "batch_size = 100\n", + "\n", + "dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + "dnn.train()\n", + "test_predict = dnn.predict(X_test)\n", + "\n", + "# accuracy score from scikit library\n", + "print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + "\n", + "# equivalent in numpy\n", + "def accuracy_score_numpy(Y_test, Y_pred):\n", + " return np.sum(Y_test == Y_pred) / len(Y_test)\n", + "\n", + "#print(\"Accuracy score on test set: \", accuracy_score_numpy(Y_test, test_predict))" + ] + }, + { + "cell_type": "markdown", + "id": "6dce68ff", + "metadata": { + "editable": true + }, + "source": [ + "## Adjust hyperparameters\n", + "\n", + "We now perform a grid search to find the optimal hyperparameters for the network. \n", + "Note that we are only using 1 layer with 50 neurons, and human performance is estimated to be around $98\\%$ ($2\\%$ error rate)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "65caeb78", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "# store the models for later use\n", + "DNN_numpy = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "# grid search\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + " dnn.train()\n", + " \n", + " DNN_numpy[i][j] = dnn\n", + " \n", + " test_predict = dnn.predict(X_test)\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "0c44c38e", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fbdc64f1", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# visual representation of grid search\n", + "# uses seaborn heatmap, you can also do this with matplotlib imshow\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_numpy[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e07e69e3", + "metadata": { + "editable": true + }, + "source": [ + "## scikit-learn implementation\n", + "\n", + "**scikit-learn** focuses more\n", + "on traditional machine learning methods, such as regression,\n", + "clustering, decision trees, etc. As such, it has only two types of\n", + "neural networks: Multi Layer Perceptron outputting continuous values,\n", + "*MPLRegressor*, and Multi Layer Perceptron outputting labels,\n", + "*MLPClassifier*. We will see how simple it is to use these classes.\n", + "\n", + "**scikit-learn** implements a few improvements from our neural network,\n", + "such as early stopping, a varying learning rate, different\n", + "optimization methods, etc. We would therefore expect a better\n", + "performance overall." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f48eaa77", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.neural_network import MLPClassifier\n", + "# store models for later use\n", + "DNN_scikit = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = MLPClassifier(hidden_layer_sizes=(n_hidden_neurons), activation='logistic',\n", + " alpha=lmbd, learning_rate_init=eta, max_iter=epochs)\n", + " dnn.fit(X_train, Y_train)\n", + " \n", + " DNN_scikit[i][j] = dnn\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", dnn.score(X_test, Y_test))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "ac3c7bcb", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2d81262e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_scikit[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8f5f8f4b", + "metadata": { + "editable": true + }, + "source": [ + "## Building neural networks in Tensorflow and Keras\n", + "\n", + "Now we want to build on the experience gained from our neural network implementation in NumPy and scikit-learn\n", + "and use it to construct a neural network in Tensorflow. Once we have constructed a neural network in NumPy\n", + "and Tensorflow, building one in Keras is really quite trivial, though the performance may suffer. \n", + "\n", + "In our previous example we used only one hidden layer, and in this we will use two. From this it should be quite\n", + "clear how to build one using an arbitrary number of hidden layers, using data structures such as Python lists or\n", + "NumPy arrays." + ] + }, + { + "cell_type": "markdown", + "id": "6ec638b9", + "metadata": { + "editable": true + }, + "source": [ + "## Tensorflow\n", + "\n", + "Tensorflow is an open source library machine learning library\n", + "developed by the Google Brain team for internal use. It was released\n", + "under the Apache 2.0 open source license in November 9, 2015.\n", + "\n", + "Tensorflow is a computational framework that allows you to construct\n", + "machine learning models at different levels of abstraction, from\n", + "high-level, object-oriented APIs like Keras, down to the C++ kernels\n", + "that Tensorflow is built upon. The higher levels of abstraction are\n", + "simpler to use, but less flexible, and our choice of implementation\n", + "should reflect the problems we are trying to solve.\n", + "\n", + "[Tensorflow uses](https://www.tensorflow.org/guide/graphs) so-called graphs to represent your computation\n", + "in terms of the dependencies between individual operations, such that you first build a Tensorflow *graph*\n", + "to represent your model, and then create a Tensorflow *session* to run the graph.\n", + "\n", + "In this guide we will analyze the same data as we did in our NumPy and\n", + "scikit-learn tutorial, gathered from the MNIST database of images. We\n", + "will give an introduction to the lower level Python Application\n", + "Program Interfaces (APIs), and see how we use them to build our graph.\n", + "Then we will build (effectively) the same graph in Keras, to see just\n", + "how simple solving a machine learning problem can be.\n", + "\n", + "To install tensorflow on Unix/Linux systems, use pip as" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6443ca72", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "pip3 install tensorflow" + ] + }, + { + "cell_type": "markdown", + "id": "a8918d58", + "metadata": { + "editable": true + }, + "source": [ + "and/or if you use **anaconda**, just write (or install from the graphical user interface)\n", + "(current release of CPU-only TensorFlow)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "20e9a0f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf tensorflow\n", + "conda activate tf" + ] + }, + { + "cell_type": "markdown", + "id": "1381a34b", + "metadata": { + "editable": true + }, + "source": [ + "To install the current release of GPU TensorFlow" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "80e92af9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf-gpu tensorflow-gpu\n", + "conda activate tf-gpu" + ] + }, + { + "cell_type": "markdown", + "id": "074ac69f", + "metadata": { + "editable": true + }, + "source": [ + "## Using Keras\n", + "\n", + "Keras is a high level [neural network](https://en.wikipedia.org/wiki/Application_programming_interface)\n", + "that supports Tensorflow, CTNK and Theano as backends. \n", + "If you have Anaconda installed you may run the following command" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0d710bd3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda install keras" + ] + }, + { + "cell_type": "markdown", + "id": "7adbcab8", + "metadata": { + "editable": true + }, + "source": [ + "You can look up the [instructions here](https://keras.io/) for more information.\n", + "\n", + "We will to a large extent use **keras** in this course." + ] + }, + { + "cell_type": "markdown", + "id": "e17c7253", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Let us look again at the MINST data set." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "5ae741f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorflow as tf\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "4f7ef6bb", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-hot representation of labels\n", + "labels = to_categorical(labels)\n", + "\n", + "# split into train and test data\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "7b74e049", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "epochs = 100\n", + "batch_size = 100\n", + "n_neurons_layer1 = 100\n", + "n_neurons_layer2 = 50\n", + "n_categories = 10\n", + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "def create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, eta, lmbd):\n", + " model = Sequential()\n", + " model.add(Dense(n_neurons_layer1, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_neurons_layer2, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_categories, activation='softmax'))\n", + " \n", + " sgd = optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])\n", + " \n", + " return model" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "eaa25983", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "DNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + " \n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " DNN = create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories,\n", + " eta=eta, lmbd=lmbd)\n", + " DNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0)\n", + " scores = DNN.evaluate(X_test, Y_test)\n", + " \n", + " DNN_keras[i][j] = DNN\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Test accuracy: %.3f\" % scores[1])\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "949eca1f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " DNN = DNN_keras[i][j]\n", + "\n", + " train_accuracy[i][j] = DNN.evaluate(X_train, Y_train)[1]\n", + " test_accuracy[i][j] = DNN.evaluate(X_test, Y_test)[1]\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "bb8b8ac1", + "metadata": { + "editable": true + }, + "source": [ + "## The Breast Cancer Data, now with Keras" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "9d5ebbb2", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "import tensorflow as tf\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.model_selection import train_test_split as splitter\n", + "from sklearn.datasets import load_breast_cancer\n", + "import pickle\n", + "import os \n", + "\n", + "\n", + "\"\"\"Load breast cancer dataset\"\"\"\n", + "\n", + "np.random.seed(0) #create same seed for random number every time\n", + "\n", + "cancer=load_breast_cancer() #Download breast cancer dataset\n", + "\n", + "inputs=cancer.data #Feature matrix of 569 rows (samples) and 30 columns (parameters)\n", + "outputs=cancer.target #Label array of 569 rows (0 for benign and 1 for malignant)\n", + "labels=cancer.feature_names[0:30]\n", + "\n", + "print('The content of the breast cancer dataset is:') #Print information about the datasets\n", + "print(labels)\n", + "print('-------------------------')\n", + "print(\"inputs = \" + str(inputs.shape))\n", + "print(\"outputs = \" + str(outputs.shape))\n", + "print(\"labels = \"+ str(labels.shape))\n", + "\n", + "x=inputs #Reassign the Feature and Label matrices to other variables\n", + "y=outputs\n", + "\n", + "#%% \n", + "\n", + "# Visualisation of dataset (for correlation analysis)\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,2],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean perimeter',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,5],x[:,6],s=40,c=y, cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean compactness',fontweight='bold')\n", + "plt.ylabel('Mean concavity',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean texture',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,2],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean perimeter',fontweight='bold')\n", + "plt.ylabel('Mean compactness',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "# Generate training and testing datasets\n", + "\n", + "#Select features relevant to classification (texture,perimeter,compactness and symmetery) \n", + "#and add to input matrix\n", + "\n", + "temp1=np.reshape(x[:,1],(len(x[:,1]),1))\n", + "temp2=np.reshape(x[:,2],(len(x[:,2]),1))\n", + "X=np.hstack((temp1,temp2)) \n", + "temp=np.reshape(x[:,5],(len(x[:,5]),1))\n", + "X=np.hstack((X,temp)) \n", + "temp=np.reshape(x[:,8],(len(x[:,8]),1))\n", + "X=np.hstack((X,temp)) \n", + "\n", + "X_train,X_test,y_train,y_test=splitter(X,y,test_size=0.1) #Split datasets into training and testing\n", + "\n", + "y_train=to_categorical(y_train) #Convert labels to categorical when using categorical cross entropy\n", + "y_test=to_categorical(y_test)\n", + "\n", + "del temp1,temp2,temp\n", + "\n", + "# %%\n", + "\n", + "# Define tunable parameters\"\n", + "\n", + "eta=np.logspace(-3,-1,3) #Define vector of learning rates (parameter to SGD optimiser)\n", + "lamda=0.01 #Define hyperparameter\n", + "n_layers=2 #Define number of hidden layers in the model\n", + "n_neuron=np.logspace(0,3,4,dtype=int) #Define number of neurons per layer\n", + "epochs=100 #Number of reiterations over the input data\n", + "batch_size=100 #Number of samples per gradient update\n", + "\n", + "# %%\n", + "\n", + "\"\"\"Define function to return Deep Neural Network model\"\"\"\n", + "\n", + "def NN_model(inputsize,n_layers,n_neuron,eta,lamda):\n", + " model=Sequential() \n", + " for i in range(n_layers): #Run loop to add hidden layers to the model\n", + " if (i==0): #First layer requires input dimensions\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda),input_dim=inputsize))\n", + " else: #Subsequent layers are capable of automatic shape inferencing\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda)))\n", + " model.add(Dense(2,activation='softmax')) #2 outputs - ordered and disordered (softmax for prob)\n", + " sgd=optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])\n", + " return model\n", + "\n", + " \n", + "Train_accuracy=np.zeros((len(n_neuron),len(eta))) #Define matrices to store accuracy scores as a function\n", + "Test_accuracy=np.zeros((len(n_neuron),len(eta))) #of learning rate and number of hidden neurons for \n", + "\n", + "for i in range(len(n_neuron)): #run loops over hidden neurons and learning rates to calculate \n", + " for j in range(len(eta)): #accuracy scores \n", + " DNN_model=NN_model(X_train.shape[1],n_layers,n_neuron[i],eta[j],lamda)\n", + " DNN_model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=1)\n", + " Train_accuracy[i,j]=DNN_model.evaluate(X_train,y_train)[1]\n", + " Test_accuracy[i,j]=DNN_model.evaluate(X_test,y_test)[1]\n", + " \n", + "\n", + "def plot_data(x,y,data,title=None):\n", + "\n", + " # plot results\n", + " fontsize=16\n", + "\n", + "\n", + " fig = plt.figure()\n", + " ax = fig.add_subplot(111)\n", + " cax = ax.matshow(data, interpolation='nearest', vmin=0, vmax=1)\n", + " \n", + " cbar=fig.colorbar(cax)\n", + " cbar.ax.set_ylabel('accuracy (%)',rotation=90,fontsize=fontsize)\n", + " cbar.set_ticks([0,.2,.4,0.6,0.8,1.0])\n", + " cbar.set_ticklabels(['0%','20%','40%','60%','80%','100%'])\n", + "\n", + " # put text on matrix elements\n", + " for i, x_val in enumerate(np.arange(len(x))):\n", + " for j, y_val in enumerate(np.arange(len(y))):\n", + " c = \"${0:.1f}\\\\%$\".format( 100*data[j,i]) \n", + " ax.text(x_val, y_val, c, va='center', ha='center')\n", + "\n", + " # convert axis vaues to to string labels\n", + " x=[str(i) for i in x]\n", + " y=[str(i) for i in y]\n", + "\n", + "\n", + " ax.set_xticklabels(['']+x)\n", + " ax.set_yticklabels(['']+y)\n", + "\n", + " ax.set_xlabel('$\\\\mathrm{learning\\\\ rate}$',fontsize=fontsize)\n", + " ax.set_ylabel('$\\\\mathrm{hidden\\\\ neurons}$',fontsize=fontsize)\n", + " if title is not None:\n", + " ax.set_title(title)\n", + "\n", + " plt.tight_layout()\n", + "\n", + " plt.show()\n", + " \n", + "plot_data(eta,n_neuron,Train_accuracy, 'training')\n", + "plot_data(eta,n_neuron,Test_accuracy, 'testing')" + ] + }, + { + "cell_type": "markdown", + "id": "f1baeb0b", + "metadata": { + "editable": true + }, + "source": [ + "## Building a neural network code\n", + "\n", + "Here we present a flexible object oriented codebase\n", + "for a feed forward neural network, along with a demonstration of how\n", + "to use it. Before we get into the details of the neural network, we\n", + "will first present some implementations of various schedulers, cost\n", + "functions and activation functions that can be used together with the\n", + "neural network.\n", + "\n", + "The codes here were developed by Eric Reber and Gregor Kajda during spring 2023." + ] + }, + { + "cell_type": "markdown", + "id": "6549fa13", + "metadata": { + "editable": true + }, + "source": [ + "### Learning rate methods\n", + "\n", + "The code below shows object oriented implementations of the Constant,\n", + "Momentum, Adagrad, AdagradMomentum, RMS prop and Adam schedulers. All\n", + "of the classes belong to the shared abstract Scheduler class, and\n", + "share the update_change() and reset() methods allowing for any of the\n", + "schedulers to be seamlessly used during the training stage, as will\n", + "later be shown in the fit() method of the neural\n", + "network. Update_change() only has one parameter, the gradient\n", + "($δ^l_ja^{l−1}_k$), and returns the change which will be subtracted\n", + "from the weights. The reset() function takes no parameters, and resets\n", + "the desired variables. For Constant and Momentum, reset does nothing." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "21062ebc", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "class Scheduler:\n", + " \"\"\"\n", + " Abstract class for Schedulers\n", + " \"\"\"\n", + "\n", + " def __init__(self, eta):\n", + " self.eta = eta\n", + "\n", + " # should be overwritten\n", + " def update_change(self, gradient):\n", + " raise NotImplementedError\n", + "\n", + " # overwritten if needed\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Constant(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + "\n", + " def update_change(self, gradient):\n", + " return self.eta * gradient\n", + " \n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Momentum(Scheduler):\n", + " def __init__(self, eta: float, momentum: float):\n", + " super().__init__(eta)\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " self.change = self.momentum * self.change + self.eta * gradient\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Adagrad(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " return self.eta * gradient * G_t_inverse\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class AdagradMomentum(Scheduler):\n", + " def __init__(self, eta, momentum):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " self.change = self.change * self.momentum + self.eta * gradient * G_t_inverse\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class RMS_prop(Scheduler):\n", + " def __init__(self, eta, rho):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.second = 0.0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + " self.second = self.rho * self.second + (1 - self.rho) * gradient * gradient\n", + " return self.eta * gradient / (np.sqrt(self.second + delta))\n", + "\n", + " def reset(self):\n", + " self.second = 0.0\n", + "\n", + "\n", + "class Adam(Scheduler):\n", + " def __init__(self, eta, rho, rho2):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.rho2 = rho2\n", + " self.moment = 0\n", + " self.second = 0\n", + " self.n_epochs = 1\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " self.moment = self.rho * self.moment + (1 - self.rho) * gradient\n", + " self.second = self.rho2 * self.second + (1 - self.rho2) * gradient * gradient\n", + "\n", + " moment_corrected = self.moment / (1 - self.rho**self.n_epochs)\n", + " second_corrected = self.second / (1 - self.rho2**self.n_epochs)\n", + "\n", + " return self.eta * moment_corrected / (np.sqrt(second_corrected + delta))\n", + "\n", + " def reset(self):\n", + " self.n_epochs += 1\n", + " self.moment = 0\n", + " self.second = 0" + ] + }, + { + "cell_type": "markdown", + "id": "f965b277", + "metadata": { + "editable": true + }, + "source": [ + "### Usage of the above learning rate schedulers\n", + "\n", + "To initalize a scheduler, simply create the object and pass in the\n", + "necessary parameters such as the learning rate and the momentum as\n", + "shown below. As the Scheduler class is an abstract class it should not\n", + "called directly, and will raise an error upon usage." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "35ab935b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "momentum_scheduler = Momentum(eta=1e-3, momentum=0.9)\n", + "adam_scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)" + ] + }, + { + "cell_type": "markdown", + "id": "b26972b4", + "metadata": { + "editable": true + }, + "source": [ + "Here is a small example for how a segment of code using schedulers\n", + "could look. Switching out the schedulers is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3df9caac", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "weights = np.ones((3,3))\n", + "print(f\"Before scheduler:\\n{weights=}\")\n", + "\n", + "epochs = 10\n", + "for e in range(epochs):\n", + " gradient = np.random.rand(3, 3)\n", + " change = adam_scheduler.update_change(gradient)\n", + " weights = weights - change\n", + " adam_scheduler.reset()\n", + "\n", + "print(f\"\\nAfter scheduler:\\n{weights=}\")" + ] + }, + { + "cell_type": "markdown", + "id": "1c07f6da", + "metadata": { + "editable": true + }, + "source": [ + "### Cost functions\n", + "\n", + "Here we discuss cost functions that can be used when creating the\n", + "neural network. Every cost function takes the target vector as its\n", + "parameter, and returns a function valued only at $x$ such that it may\n", + "easily be differentiated." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "743aa0bd", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "def CostOLS(target):\n", + " \n", + " def func(X):\n", + " return (1.0 / target.shape[0]) * np.sum((target - X) ** 2)\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostLogReg(target):\n", + "\n", + " def func(X):\n", + " \n", + " return -(1.0 / target.shape[0]) * np.sum(\n", + " (target * np.log(X + 10e-10)) + ((1 - target) * np.log(1 - X + 10e-10))\n", + " )\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostCrossEntropy(target):\n", + " \n", + " def func(X):\n", + " return -(1.0 / target.size) * np.sum(target * np.log(X + 10e-10))\n", + "\n", + " return func" + ] + }, + { + "cell_type": "markdown", + "id": "c78bdc16", + "metadata": { + "editable": true + }, + "source": [ + "Below we give a short example of how these cost function may be used\n", + "to obtain results if you wish to test them out on your own using\n", + "AutoGrad's automatics differentiation." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4ec3a28c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from autograd import grad\n", + "\n", + "target = np.array([[1, 2, 3]]).T\n", + "a = np.array([[4, 5, 6]]).T\n", + "\n", + "cost_func = CostCrossEntropy\n", + "cost_func_derivative = grad(cost_func(target))\n", + "\n", + "valued_at_a = cost_func_derivative(a)\n", + "print(f\"Derivative of cost function {cost_func.__name__} valued at a:\\n{valued_at_a}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5c924e11", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "Finally, before we look at the neural network, we will look at the\n", + "activation functions which can be specified between the hidden layers\n", + "and as the output function. Each function can be valued for any given\n", + "vector or matrix X, and can be differentiated via derivate()." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "87402ee9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from autograd import elementwise_grad\n", + "\n", + "def identity(X):\n", + " return X\n", + "\n", + "\n", + "def sigmoid(X):\n", + " try:\n", + " return 1.0 / (1 + np.exp(-X))\n", + " except FloatingPointError:\n", + " return np.where(X > np.zeros(X.shape), np.ones(X.shape), np.zeros(X.shape))\n", + "\n", + "\n", + "def softmax(X):\n", + " X = X - np.max(X, axis=-1, keepdims=True)\n", + " delta = 10e-10\n", + " return np.exp(X) / (np.sum(np.exp(X), axis=-1, keepdims=True) + delta)\n", + "\n", + "\n", + "def RELU(X):\n", + " return np.where(X > np.zeros(X.shape), X, np.zeros(X.shape))\n", + "\n", + "\n", + "def LRELU(X):\n", + " delta = 10e-4\n", + " return np.where(X > np.zeros(X.shape), X, delta * X)\n", + "\n", + "\n", + "def derivate(func):\n", + " if func.__name__ == \"RELU\":\n", + "\n", + " def func(X):\n", + " return np.where(X > 0, 1, 0)\n", + "\n", + " return func\n", + "\n", + " elif func.__name__ == \"LRELU\":\n", + "\n", + " def func(X):\n", + " delta = 10e-4\n", + " return np.where(X > 0, 1, delta)\n", + "\n", + " return func\n", + "\n", + " else:\n", + " return elementwise_grad(func)" + ] + }, + { + "cell_type": "markdown", + "id": "45ddd0bc", + "metadata": { + "editable": true + }, + "source": [ + "Below follows a short demonstration of how to use an activation\n", + "function. The derivative of the activation function will be important\n", + "when calculating the output delta term during backpropagation. Note\n", + "that derivate() can also be used for cost functions for a more\n", + "generalized approach." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "77034679", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "z = np.array([[4, 5, 6]]).T\n", + "print(f\"Input to activation function:\\n{z}\")\n", + "\n", + "act_func = sigmoid\n", + "a = act_func(z)\n", + "print(f\"\\nOutput from {act_func.__name__} activation function:\\n{a}\")\n", + "\n", + "act_func_derivative = derivate(act_func)\n", + "valued_at_z = act_func_derivative(a)\n", + "print(f\"\\nDerivative of {act_func.__name__} activation function valued at z:\\n{valued_at_z}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9fd8140f", + "metadata": { + "editable": true + }, + "source": [ + "### The Neural Network\n", + "\n", + "Now that we have gotten a good understanding of the implementation of\n", + "some important components, we can take a look at an object oriented\n", + "implementation of a feed forward neural network. The feed forward\n", + "neural network has been implemented as a class named FFNN, which can\n", + "be initiated as a regressor or classifier dependant on the choice of\n", + "cost function. The FFNN can have any number of input nodes, hidden\n", + "layers with any amount of hidden nodes, and any amount of output nodes\n", + "meaning it can perform multiclass classification as well as binary\n", + "classification and regression problems. Although there is a lot of\n", + "code present, it makes for an easy to use and generalizeable interface\n", + "for creating many types of neural networks as will be demonstrated\n", + "below." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7540d755", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import math\n", + "import autograd.numpy as np\n", + "import sys\n", + "import warnings\n", + "from autograd import grad, elementwise_grad\n", + "from random import random, seed\n", + "from copy import deepcopy, copy\n", + "from typing import Tuple, Callable\n", + "from sklearn.utils import resample\n", + "\n", + "warnings.simplefilter(\"error\")\n", + "\n", + "\n", + "class FFNN:\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Feed Forward Neural Network with interface enabling flexible design of a\n", + " nerual networks architecture and the specification of activation function\n", + " in the hidden layers and output layer respectively. This model can be used\n", + " for both regression and classification problems, depending on the output function.\n", + "\n", + " Attributes:\n", + " ------------\n", + " I dimensions (tuple[int]): A list of positive integers, which specifies the\n", + " number of nodes in each of the networks layers. The first integer in the array\n", + " defines the number of nodes in the input layer, the second integer defines number\n", + " of nodes in the first hidden layer and so on until the last number, which\n", + " specifies the number of nodes in the output layer.\n", + " II hidden_func (Callable): The activation function for the hidden layers\n", + " III output_func (Callable): The activation function for the output layer\n", + " IV cost_func (Callable): Our cost function\n", + " V seed (int): Sets random seed, makes results reproducible\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " dimensions: tuple[int],\n", + " hidden_func: Callable = sigmoid,\n", + " output_func: Callable = lambda x: x,\n", + " cost_func: Callable = CostOLS,\n", + " seed: int = None,\n", + " ):\n", + " self.dimensions = dimensions\n", + " self.hidden_func = hidden_func\n", + " self.output_func = output_func\n", + " self.cost_func = cost_func\n", + " self.seed = seed\n", + " self.weights = list()\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + " self.classification = None\n", + "\n", + " self.reset_weights()\n", + " self._set_classification()\n", + "\n", + " def fit(\n", + " self,\n", + " X: np.ndarray,\n", + " t: np.ndarray,\n", + " scheduler: Scheduler,\n", + " batches: int = 1,\n", + " epochs: int = 100,\n", + " lam: float = 0,\n", + " X_val: np.ndarray = None,\n", + " t_val: np.ndarray = None,\n", + " ):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " This function performs the training the neural network by performing the feedforward and backpropagation\n", + " algorithm to update the networks weights.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray) : training data\n", + " II t (np.ndarray) : target data\n", + " III scheduler (Scheduler) : specified scheduler (algorithm for optimization of gradient descent)\n", + " IV scheduler_args (list[int]) : list of all arguments necessary for scheduler\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " V batches (int) : number of batches the datasets are split into, default equal to 1\n", + " VI epochs (int) : number of iterations used to train the network, default equal to 100\n", + " VII lam (float) : regularization hyperparameter lambda\n", + " VIII X_val (np.ndarray) : validation set\n", + " IX t_val (np.ndarray) : validation target set\n", + "\n", + " Returns:\n", + " ------------\n", + " I scores (dict) : A dictionary containing the performance metrics of the model.\n", + " The number of the metrics depends on the parameters passed to the fit-function.\n", + "\n", + " \"\"\"\n", + "\n", + " # setup \n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " val_set = False\n", + " if X_val is not None and t_val is not None:\n", + " val_set = True\n", + "\n", + " # creating arrays for score metrics\n", + " train_errors = np.empty(epochs)\n", + " train_errors.fill(np.nan)\n", + " val_errors = np.empty(epochs)\n", + " val_errors.fill(np.nan)\n", + "\n", + " train_accs = np.empty(epochs)\n", + " train_accs.fill(np.nan)\n", + " val_accs = np.empty(epochs)\n", + " val_accs.fill(np.nan)\n", + "\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + "\n", + " batch_size = X.shape[0] // batches\n", + "\n", + " X, t = resample(X, t)\n", + "\n", + " # this function returns a function valued only at X\n", + " cost_function_train = self.cost_func(t)\n", + " if val_set:\n", + " cost_function_val = self.cost_func(t_val)\n", + "\n", + " # create schedulers for each weight matrix\n", + " for i in range(len(self.weights)):\n", + " self.schedulers_weight.append(copy(scheduler))\n", + " self.schedulers_bias.append(copy(scheduler))\n", + "\n", + " print(f\"{scheduler.__class__.__name__}: Eta={scheduler.eta}, Lambda={lam}\")\n", + "\n", + " try:\n", + " for e in range(epochs):\n", + " for i in range(batches):\n", + " # allows for minibatch gradient descent\n", + " if i == batches - 1:\n", + " # If the for loop has reached the last batch, take all thats left\n", + " X_batch = X[i * batch_size :, :]\n", + " t_batch = t[i * batch_size :, :]\n", + " else:\n", + " X_batch = X[i * batch_size : (i + 1) * batch_size, :]\n", + " t_batch = t[i * batch_size : (i + 1) * batch_size, :]\n", + "\n", + " self._feedforward(X_batch)\n", + " self._backpropagate(X_batch, t_batch, lam)\n", + "\n", + " # reset schedulers for each epoch (some schedulers pass in this call)\n", + " for scheduler in self.schedulers_weight:\n", + " scheduler.reset()\n", + "\n", + " for scheduler in self.schedulers_bias:\n", + " scheduler.reset()\n", + "\n", + " # computing performance metrics\n", + " pred_train = self.predict(X)\n", + " train_error = cost_function_train(pred_train)\n", + "\n", + " train_errors[e] = train_error\n", + " if val_set:\n", + " \n", + " pred_val = self.predict(X_val)\n", + " val_error = cost_function_val(pred_val)\n", + " val_errors[e] = val_error\n", + "\n", + " if self.classification:\n", + " train_acc = self._accuracy(self.predict(X), t)\n", + " train_accs[e] = train_acc\n", + " if val_set:\n", + " val_acc = self._accuracy(pred_val, t_val)\n", + " val_accs[e] = val_acc\n", + "\n", + " # printing progress bar\n", + " progression = e / epochs\n", + " print_length = self._progress_bar(\n", + " progression,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " except KeyboardInterrupt:\n", + " # allows for stopping training at any point and seeing the result\n", + " pass\n", + "\n", + " # visualization of training progression (similiar to tensorflow progression bar)\n", + " sys.stdout.write(\"\\r\" + \" \" * print_length)\n", + " sys.stdout.flush()\n", + " self._progress_bar(\n", + " 1,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " sys.stdout.write(\"\")\n", + "\n", + " # return performance metrics for the entire run\n", + " scores = dict()\n", + "\n", + " scores[\"train_errors\"] = train_errors\n", + "\n", + " if val_set:\n", + " scores[\"val_errors\"] = val_errors\n", + "\n", + " if self.classification:\n", + " scores[\"train_accs\"] = train_accs\n", + "\n", + " if val_set:\n", + " scores[\"val_accs\"] = val_accs\n", + "\n", + " return scores\n", + "\n", + " def predict(self, X: np.ndarray, *, threshold=0.5):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs prediction after training of the network has been finished.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " II threshold (float) : sets minimal value for a prediction to be predicted as the positive class\n", + " in classification problems\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " This vector is thresholded if regression=False, meaning that classification results\n", + " in a vector of 1s and 0s, while regressions in an array of decimal numbers\n", + "\n", + " \"\"\"\n", + "\n", + " predict = self._feedforward(X)\n", + "\n", + " if self.classification:\n", + " return np.where(predict > threshold, 1, 0)\n", + " else:\n", + " return predict\n", + "\n", + " def reset_weights(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Resets/Reinitializes the weights in order to train the network for a new problem.\n", + "\n", + " \"\"\"\n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " self.weights = list()\n", + " for i in range(len(self.dimensions) - 1):\n", + " weight_array = np.random.randn(\n", + " self.dimensions[i] + 1, self.dimensions[i + 1]\n", + " )\n", + " weight_array[0, :] = np.random.randn(self.dimensions[i + 1]) * 0.01\n", + "\n", + " self.weights.append(weight_array)\n", + "\n", + " def _feedforward(self, X: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates the activation of each layer starting at the input and ending at the output.\n", + " Each following activation is calculated from a weighted sum of each of the preceeding\n", + " activations (except in the case of the input layer).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " \"\"\"\n", + "\n", + " # reset matrices\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + "\n", + " # if X is just a vector, make it into a matrix\n", + " if len(X.shape) == 1:\n", + " X = X.reshape((1, X.shape[0]))\n", + "\n", + " # Add a coloumn of zeros as the first coloumn of the design matrix, in order\n", + " # to add bias to our data\n", + " bias = np.ones((X.shape[0], 1)) * 0.01\n", + " X = np.hstack([bias, X])\n", + "\n", + " # a^0, the nodes in the input layer (one a^0 for each row in X - where the\n", + " # exponent indicates layer number).\n", + " a = X\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(a)\n", + "\n", + " # The feed forward algorithm\n", + " for i in range(len(self.weights)):\n", + " if i < len(self.weights) - 1:\n", + " z = a @ self.weights[i]\n", + " self.z_matrices.append(z)\n", + " a = self.hidden_func(z)\n", + " # bias column again added to the data here\n", + " bias = np.ones((a.shape[0], 1)) * 0.01\n", + " a = np.hstack([bias, a])\n", + " self.a_matrices.append(a)\n", + " else:\n", + " try:\n", + " # a^L, the nodes in our output layers\n", + " z = a @ self.weights[i]\n", + " a = self.output_func(z)\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(z)\n", + " except Exception as OverflowError:\n", + " print(\n", + " \"OverflowError in fit() in FFNN\\nHOW TO DEBUG ERROR: Consider lowering your learning rate or scheduler specific parameters such as momentum, or check if your input values need scaling\"\n", + " )\n", + "\n", + " # this will be a^L\n", + " return a\n", + "\n", + " def _backpropagate(self, X, t, lam):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs the backpropagation algorithm. In other words, this method\n", + " calculates the gradient of all the layers starting at the\n", + " output layer, and moving from right to left accumulates the gradient until\n", + " the input layer is reached. Each layers respective weights are updated while\n", + " the algorithm propagates backwards from the output layer (auto-differentation in reverse mode).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each.\n", + " II t (np.ndarray): The target vector, with n rows of p targets.\n", + " III lam (float32): regularization parameter used to punish the weights in case of overfitting\n", + "\n", + " Returns:\n", + " ------------\n", + " No return value.\n", + "\n", + " \"\"\"\n", + " out_derivative = derivate(self.output_func)\n", + " hidden_derivative = derivate(self.hidden_func)\n", + "\n", + " for i in range(len(self.weights) - 1, -1, -1):\n", + " # delta terms for output\n", + " if i == len(self.weights) - 1:\n", + " # for multi-class classification\n", + " if (\n", + " self.output_func.__name__ == \"softmax\"\n", + " ):\n", + " delta_matrix = self.a_matrices[i + 1] - t\n", + " # for single class classification\n", + " else:\n", + " cost_func_derivative = grad(self.cost_func(t))\n", + " delta_matrix = out_derivative(\n", + " self.z_matrices[i + 1]\n", + " ) * cost_func_derivative(self.a_matrices[i + 1])\n", + "\n", + " # delta terms for hidden layer\n", + " else:\n", + " delta_matrix = (\n", + " self.weights[i + 1][1:, :] @ delta_matrix.T\n", + " ).T * hidden_derivative(self.z_matrices[i + 1])\n", + "\n", + " # calculate gradient\n", + " gradient_weights = self.a_matrices[i][:, 1:].T @ delta_matrix\n", + " gradient_bias = np.sum(delta_matrix, axis=0).reshape(\n", + " 1, delta_matrix.shape[1]\n", + " )\n", + "\n", + " # regularization term\n", + " gradient_weights += self.weights[i][1:, :] * lam\n", + "\n", + " # use scheduler\n", + " update_matrix = np.vstack(\n", + " [\n", + " self.schedulers_bias[i].update_change(gradient_bias),\n", + " self.schedulers_weight[i].update_change(gradient_weights),\n", + " ]\n", + " )\n", + "\n", + " # update weights and bias\n", + " self.weights[i] -= update_matrix\n", + "\n", + " def _accuracy(self, prediction: np.ndarray, target: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates accuracy of given prediction to target\n", + "\n", + " Parameters:\n", + " ------------\n", + " I prediction (np.ndarray): vector of predicitons output network\n", + " (1s and 0s in case of classification, and real numbers in case of regression)\n", + " II target (np.ndarray): vector of true values (What the network ideally should predict)\n", + "\n", + " Returns:\n", + " ------------\n", + " A floating point number representing the percentage of correctly classified instances.\n", + " \"\"\"\n", + " assert prediction.size == target.size\n", + " return np.average((target == prediction))\n", + " def _set_classification(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Decides if FFNN acts as classifier (True) og regressor (False),\n", + " sets self.classification during init()\n", + " \"\"\"\n", + " self.classification = False\n", + " if (\n", + " self.cost_func.__name__ == \"CostLogReg\"\n", + " or self.cost_func.__name__ == \"CostCrossEntropy\"\n", + " ):\n", + " self.classification = True\n", + "\n", + " def _progress_bar(self, progression, **kwargs):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Displays progress of training\n", + " \"\"\"\n", + " print_length = 40\n", + " num_equals = int(progression * print_length)\n", + " num_not = print_length - num_equals\n", + " arrow = \">\" if num_equals > 0 else \"\"\n", + " bar = \"[\" + \"=\" * (num_equals - 1) + arrow + \"-\" * num_not + \"]\"\n", + " perc_print = self._format(progression * 100, decimals=5)\n", + " line = f\" {bar} {perc_print}% \"\n", + "\n", + " for key in kwargs:\n", + " if not np.isnan(kwargs[key]):\n", + " value = self._format(kwargs[key], decimals=4)\n", + " line += f\"| {key}: {value} \"\n", + " sys.stdout.write(\"\\r\" + line)\n", + " sys.stdout.flush()\n", + " return len(line)\n", + "\n", + " def _format(self, value, decimals=4):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Formats decimal numbers for progress bar\n", + " \"\"\"\n", + " if value > 0:\n", + " v = value\n", + " elif value < 0:\n", + " v = -10 * value\n", + " else:\n", + " v = 1\n", + " n = 1 + math.floor(math.log10(v))\n", + " if n >= decimals - 1:\n", + " return str(round(value))\n", + " return f\"{value:.{decimals-n-1}f}\"" + ] + }, + { + "cell_type": "markdown", + "id": "5ee996ef", + "metadata": { + "editable": true + }, + "source": [ + "Before we make a model, we will quickly generate a dataset we can use\n", + "for our linear regression problem as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "183b180b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "def SkrankeFunction(x, y):\n", + " return np.ravel(0 + 1*x + 2*y + 3*x**2 + 4*x*y + 5*y**2)\n", + "\n", + "def create_X(x, y, n):\n", + " if len(x.shape) > 1:\n", + " x = np.ravel(x)\n", + " y = np.ravel(y)\n", + "\n", + " N = len(x)\n", + " l = int((n + 1) * (n + 2) / 2) # Number of elements in beta\n", + " X = np.ones((N, l))\n", + "\n", + " for i in range(1, n + 1):\n", + " q = int((i) * (i + 1) / 2)\n", + " for k in range(i + 1):\n", + " X[:, q + k] = (x ** (i - k)) * (y**k)\n", + "\n", + " return X\n", + "\n", + "step=0.5\n", + "x = np.arange(0, 1, step)\n", + "y = np.arange(0, 1, step)\n", + "x, y = np.meshgrid(x, y)\n", + "target = SkrankeFunction(x, y)\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "poly_degree=3\n", + "X = create_X(x, y, poly_degree)\n", + "\n", + "X_train, X_test, t_train, t_test = train_test_split(X, target)" + ] + }, + { + "cell_type": "markdown", + "id": "21a48508", + "metadata": { + "editable": true + }, + "source": [ + "Now that we have our dataset ready for the regression, we can create\n", + "our regressor. Note that with the seed parameter, we can make sure our\n", + "results stay the same every time we run the neural network. For\n", + "inititialization, we simply specify the dimensions (we wish the amount\n", + "of input nodes to be equal to the datapoints, and the output to\n", + "predict one value)." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "37eba90c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "linear_regression = FFNN((input_nodes, output_nodes), output_func=identity, cost_func=CostOLS, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "58a6b726", + "metadata": { + "editable": true + }, + "source": [ + "We then fit our model with our training data using the scheduler of our choice." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "046d7076", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Constant(eta=1e-3)\n", + "scores = linear_regression.fit(X_train, t_train, scheduler)" + ] + }, + { + "cell_type": "markdown", + "id": "981e95ce", + "metadata": { + "editable": true + }, + "source": [ + "Due to the progress bar we can see the MSE (train_error) throughout\n", + "the FFNN's training. Note that the fit() function has some optional\n", + "parameters with defualt arguments. For example, the regularization\n", + "hyperparameter can be left ignored if not needed, and equally the FFNN\n", + "will by default run for 100 epochs. These can easily be changed, such\n", + "as for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6da23296", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scores = linear_regression.fit(X_train, t_train, scheduler, lam=1e-4, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ba0fea41", + "metadata": { + "editable": true + }, + "source": [ + "We see that given more epochs to train on, the regressor reaches a lower MSE.\n", + "\n", + "Let us then switch to a binary classification. We use a binary\n", + "classification dataset, and follow a similar setup to the regression\n", + "case." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "1bd5c3e5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "wisconsin = load_breast_cancer()\n", + "X = wisconsin.data\n", + "target = wisconsin.target\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "X_train, X_val, t_train, t_val = train_test_split(X, target)\n", + "\n", + "scaler = MinMaxScaler()\n", + "scaler.fit(X_train)\n", + "X_train = scaler.transform(X_train)\n", + "X_val = scaler.transform(X_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "9923ffbf", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "95431510", + "metadata": { + "editable": true + }, + "source": [ + "We will now make use of our validation data by passing it into our fit function as a keyword argument" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "9d71cef9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "acfee190", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we will create a neural network with 2 hidden layers with activation functions." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "c834fb60", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 1\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "neural_network = FFNN(dims, hidden_func=RELU, output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0c557301", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "neural_network.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = neural_network.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "750490a3", + "metadata": { + "editable": true + }, + "source": [ + "### Multiclass classification\n", + "\n", + "Finally, we will demonstrate the use case of multiclass classification\n", + "using our FFNN with the famous MNIST dataset, which contain images of\n", + "digits between the range of 0 to 9." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "5318d06b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_digits\n", + "\n", + "def onehot(target: np.ndarray):\n", + " onehot = np.zeros((target.size, target.max() + 1))\n", + " onehot[np.arange(target.size), target] = 1\n", + " return onehot\n", + "\n", + "digits = load_digits()\n", + "\n", + "X = digits.data\n", + "target = digits.target\n", + "target = onehot(target)\n", + "\n", + "input_nodes = 64\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 10\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "multiclass = FFNN(dims, hidden_func=LRELU, output_func=softmax, cost_func=CostCrossEntropy)\n", + "\n", + "multiclass.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = multiclass.fit(X, target, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ff519831", + "metadata": { + "editable": true + }, + "source": [ + "## Testing the XOR gate and other gates\n", + "\n", + "Let us now use our code to test the XOR gate." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "57e3fb33", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "X = np.array([ [0, 0], [0, 1], [1, 0],[1, 1]],dtype=np.float64)\n", + "\n", + "# The XOR gate\n", + "yXOR = np.array( [[ 0], [1] ,[1], [0]])\n", + "\n", + "input_nodes = X.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)\n", + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "scheduler = Adam(eta=1e-1, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X, yXOR, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "e4c08bad", + "metadata": { + "editable": true + }, + "source": [ + "Not bad, but the results depend strongly on the learning reate. Try different learning rates." + ] + } + ], + "metadata": { + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/doc/LectureNotes/_build/jupyter_execute/week42.py b/doc/LectureNotes/_build/jupyter_execute/week42.py new file mode 100644 index 000000000..7fa538895 --- /dev/null +++ b/doc/LectureNotes/_build/jupyter_execute/week42.py @@ -0,0 +1,3636 @@ +#!/usr/bin/env python +# coding: utf-8 + +# +# + +# # Week 42 Constructing a Neural Network code with examples +# **Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and Facility for Rare Isotope Beams, Michigan State University +# +# Date: **October 14-18, 2024** + +# ## Lecture October 14, 2024 +# 1. Building our own Feed-forward Neural Network and discussion of project 2 +# +# **Readings and videos.** +# +# 1. These lecture notes +# +# +# +# 2. For a more in depth discussion on neural networks we recommend Goodfellow et al chapters 6 and 7. +# +# 3. Neural Networks demystified at +# +# 4. Building Neural Networks from scratch at +# +# 5. Video on Neural Networks at +# +# 6. Video on the back propagation algorithm at +# +# I also recommend Michael Nielsen's intuitive approach to the neural networks and the universal approximation theorem, see the slides at . + +# ## Material for the active learning sessions on Tuesday and Wednesday +# * Exercise on starting to write a code for neural networks, feed forward part. We will also continue ur discussions of gradient descent methods from last week. If you have time, start considering the back-propagation part as well (exercises for next week) +# +# * Discussion of project 2 +# +# +# +# **Note**: some of the codes will also be discussed next week in connection with the solution of differential equations. + +# ## Writing a code which implements a feed-forward neural network +# +# Last week we discussed the basics of neural networks and deep learning +# and the basics of automatic differentiation. We looked also at +# examples on how compute the parameters of a simple network with scalar +# inputs and ouputs and no or just one hidden layers. +# +# We ended our discussions with the derivation of the equations for a +# neural network with one hidden layers and two input variables and two +# hidden nodes but only one output node. + +# ## Mathematics of deep learning +# +# **Two recent books online.** +# +# 1. [The Modern Mathematics of Deep Learning, by Julius Berner, Philipp Grohs, Gitta Kutyniok, Philipp Petersen](https://arxiv.org/abs/2105.04026), published as [Mathematical Aspects of Deep Learning, pp. 1-111. Cambridge University Press, 2022](https://doi.org/10.1017/9781009025096.002) +# +# 2. [Mathematical Introduction to Deep Learning: Methods, Implementations, and Theory, Arnulf Jentzen, Benno Kuckuck, Philippe von Wurstemberger](https://doi.org/10.48550/arXiv.2310.20360) + +# ## Reminder on books with hands-on material and codes +# * [Sebastian Rashcka et al, Machine learning with Sickit-Learn and PyTorch](https://sebastianraschka.com/blog/2022/ml-pytorch-book.html) + +# ## Reading recommendations +# +# 1. Rashkca et al., chapter 11, jupyter-notebook sent separately, from [GitHub](https://github.com/rasbt/machine-learning-book) +# +# 2. Goodfellow et al, chapter 6 and 7 contain most of the neural network background. + +# ## First network example, simple percepetron with one input +# +# As yet another example we define now a simple perceptron model with +# all quantities given by scalars. We consider only one input variable +# $x$ and one target value $y$. We define an activation function +# $\sigma_1$ which takes as input + +# $$ +# z_1 = w_1x+b_1, +# $$ + +# where $w_1$ is the weight and $b_1$ is the bias. These are the +# parameters we want to optimize. The output is $a_1=\sigma(z_1)$ (see +# graph from whiteboard notes). This output is then fed into the +# **cost/loss** function, which we here for the sake of simplicity just +# define as the squared error + +# $$ +# C(x;w_1,b_1)=\frac{1}{2}(a_1-y)^2. +# $$ + +# ## Layout of a simple neural network with no hidden layer +# +# +# +# +#

    Figure 1:

    +# + +# ## Optimizing the parameters +# +# In setting up the feed forward and back propagation parts of the +# algorithm, we need now the derivative of the various variables we want +# to train. +# +# We need + +# $$ +# \frac{\partial C}{\partial w_1} \hspace{0.1cm}\mathrm{and}\hspace{0.1cm}\frac{\partial C}{\partial b_1}. +# $$ + +# Using the chain rule we find + +# $$ +# \frac{\partial C}{\partial w_1}=\frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial w_1}=(a_1-y)\sigma_1'x, +# $$ + +# and + +# $$ +# \frac{\partial C}{\partial b_1}=\frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial b_1}=(a_1-y)\sigma_1', +# $$ + +# which we later will just define as + +# $$ +# \frac{\partial C}{\partial a_1}\frac{\partial a_1}{\partial z_1}=\delta_1. +# $$ + +# ## Adding a hidden layer +# +# We change our simple model to (see graph) +# a network with just one hidden layer but with scalar variables only. +# +# Our output variable changes to $a_2$ and $a_1$ is now the output from the hidden node and $a_0=x$. +# We have then + +# $$ +# z_1 = w_1a_0+b_1 \hspace{0.1cm} \wedge a_1 = \sigma_1(z_1), +# $$ + +# $$ +# z_2 = w_2a_1+b_2 \hspace{0.1cm} \wedge a_2 = \sigma_2(z_2), +# $$ + +# and the cost function + +# $$ +# C(x;\boldsymbol{\Theta})=\frac{1}{2}(a_2-y)^2, +# $$ + +# with $\boldsymbol{\Theta}=[w_1,w_2,b_1,b_2]$. + +# ## Layout of a simple neural network with one hidden layer +# +# +# +# +#

    Figure 1:

    +# + +# ## The derivatives +# +# The derivatives are now, using the chain rule again + +# $$ +# \frac{\partial C}{\partial w_2}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial w_2}=(a_2-y)\sigma_2'a_1=\delta_2a_1, +# $$ + +# $$ +# \frac{\partial C}{\partial b_2}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial b_2}=(a_2-y)\sigma_2'=\delta_2, +# $$ + +# $$ +# \frac{\partial C}{\partial w_1}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial w_1}=(a_2-y)\sigma_2'a_1\sigma_1'a_0, +# $$ + +# $$ +# \frac{\partial C}{\partial b_1}=\frac{\partial C}{\partial a_2}\frac{\partial a_2}{\partial z_2}\frac{\partial z_2}{\partial a_1}\frac{\partial a_1}{\partial z_1}\frac{\partial z_1}{\partial b_1}=(a_2-y)\sigma_2'\sigma_1'=\delta_1. +# $$ + +# Can you generalize this to more than one hidden layer? + +# ## Important observations +# +# From the above equations we see that the derivatives of the activation +# functions play a central role. If they vanish, the training may +# stop. This is called the vanishing gradient problem, see discussions below. If they become +# large, the parameters $w_i$ and $b_i$ may simply go to infinity. This +# is referenced as the exploding gradient problem. + +# ## The training +# +# The training of the parameters is done through various gradient descent approximations with + +# $$ +# w_{i}\leftarrow w_{i}- \eta \delta_i a_{i-1}, +# $$ + +# and + +# $$ +# b_i \leftarrow b_i-\eta \delta_i, +# $$ + +# with $\eta$ is the learning rate. +# +# One iteration consists of one feed forward step and one back-propagation step. Each back-propagation step does one update of the parameters $\boldsymbol{\Theta}$. +# +# For the first hidden layer $a_{i-1}=a_0=x$ for this simple model. + +# ## Code example +# +# The code here implements the above model with one hidden layer and +# scalar variables for the same function we studied in the previous +# example. The code is however set up so that we can add multiple +# inputs $x$ and target values $y$. Note also that we have the +# possibility of defining a feature matrix $\boldsymbol{X}$ with more than just +# one column for the input values. This will turn useful in our next example. We have also defined matrices and vectors for all of our operations although it is not necessary here. + +# In[1]: + + +import numpy as np +# We use the Sigmoid function as activation function +def sigmoid(z): + return 1.0/(1.0+np.exp(-z)) + +def forwardpropagation(x): + # weighted sum of inputs to the hidden layer + z_1 = np.matmul(x, w_1) + b_1 + # activation in the hidden layer + a_1 = sigmoid(z_1) + # weighted sum of inputs to the output layer + z_2 = np.matmul(a_1, w_2) + b_2 + a_2 = z_2 + return a_1, a_2 + +def backpropagation(x, y): + a_1, a_2 = forwardpropagation(x) + # parameter delta for the output layer, note that a_2=z_2 and its derivative wrt z_2 is just 1 + delta_2 = a_2 - y + print(0.5*((a_2-y)**2)) + # delta for the hidden layer + delta_1 = np.matmul(delta_2, w_2.T) * a_1 * (1 - a_1) + # gradients for the output layer + output_weights_gradient = np.matmul(a_1.T, delta_2) + output_bias_gradient = np.sum(delta_2, axis=0) + # gradient for the hidden layer + hidden_weights_gradient = np.matmul(x.T, delta_1) + hidden_bias_gradient = np.sum(delta_1, axis=0) + return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient + + +# ensure the same random numbers appear every time +np.random.seed(0) +# Input variable +x = np.array([4.0],dtype=np.float64) +# Target values +y = 2*x+1.0 + +# Defining the neural network, only scalars here +n_inputs = x.shape +n_features = 1 +n_hidden_neurons = 1 +n_outputs = 1 + +# Initialize the network +# weights and bias in the hidden layer +w_1 = np.random.randn(n_features, n_hidden_neurons) +b_1 = np.zeros(n_hidden_neurons) + 0.01 + +# weights and bias in the output layer +w_2 = np.random.randn(n_hidden_neurons, n_outputs) +b_2 = np.zeros(n_outputs) + 0.01 + +eta = 0.1 +for i in range(50): + # calculate gradients + derivW2, derivB2, derivW1, derivB1 = backpropagation(x, y) + # update weights and biases + w_2 -= eta * derivW2 + b_2 -= eta * derivB2 + w_1 -= eta * derivW1 + b_1 -= eta * derivB1 + + +# We see that after some few iterations (the results do depend on the learning rate however), we get an error which is rather small. + +# ## Simple neural network and the back propagation equations +# +# Let us now try to increase our level of ambition and attempt at setting +# up the equations for a neural network with two input nodes, one hidden +# layer with two hidden nodes and one output layer with one output node/neuron only (see graph).. +# +# We need to define the following parameters and variables with the input layer (layer $(0)$) +# where we label the nodes $x_0$ and $x_1$ + +# $$ +# x_0 = a_0^{(0)} \wedge x_1 = a_1^{(0)}. +# $$ + +# The hidden layer (layer $(1)$) has nodes which yield the outputs $a_0^{(1)}$ and $a_1^{(1)}$) with weight $\boldsymbol{w}$ and bias $\boldsymbol{b}$ parameters + +# $$ +# w_{ij}^{(1)}=\left\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)}\right\} \wedge b^{(1)}=\left\{b_0^{(1)},b_1^{(1)}\right\}. +# $$ + +# ## Layout of a simple neural network with two input nodes, one hidden layer and one output node +# +# +# +# +#

    Figure 1:

    +# + +# ## The ouput layer +# +# Finally, we have the ouput layer given by layer label $(2)$ with output $a^{(2)}$ and weights and biases to be determined given by the variables + +# $$ +# w_{i}^{(2)}=\left\{w_{0}^{(2)},w_{1}^{(2)}\right\} \wedge b^{(2)}. +# $$ + +# Our output is $\tilde{y}=a^{(2)}$ and we define a generic cost function $C(a^{(2)},y;\boldsymbol{\Theta})$ where $y$ is the target value (a scalar here). +# The parameters we need to optimize are given by + +# $$ +# \boldsymbol{\Theta}=\left\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)},w_{0}^{(2)},w_{1}^{(2)},b_0^{(1)},b_1^{(1)},b^{(2)}\right\}. +# $$ + +# ## Compact expressions +# +# We can define the inputs to the activation functions for the various layers in terms of various matrix-vector multiplications and vector additions. +# The inputs to the first hidden layer are + +# $$ +# \begin{bmatrix}z_0^{(1)} \\ z_1^{(1)} \end{bmatrix}=\left(\begin{bmatrix}w_{00}^{(1)} & w_{01}^{(1)}\\ w_{10}^{(1)} &w_{11}^{(1)} \end{bmatrix}\right)^{T}\begin{bmatrix}a_0^{(0)} \\ a_1^{(0)} \end{bmatrix}+\begin{bmatrix}b_0^{(1)} \\ b_1^{(1)} \end{bmatrix}, +# $$ + +# with outputs + +# $$ +# \begin{bmatrix}a_0^{(1)} \\ a_1^{(1)} \end{bmatrix}=\begin{bmatrix}\sigma^{(1)}(z_0^{(1)}) \\ \sigma^{(1)}(z_1^{(1)}) \end{bmatrix}. +# $$ + +# ## Output layer +# +# For the final output layer we have the inputs to the final activation function + +# $$ +# z^{(2)} = w_{0}^{(2)}a_0^{(1)} +w_{1}^{(2)}a_1^{(1)}+b^{(2)}, +# $$ + +# resulting in the output + +# $$ +# a^{(2)}=\sigma^{(2)}(z^{(2)}). +# $$ + +# ## Explicit derivatives +# +# In total we have nine parameters which we need to train. Using the +# chain rule (or just the back-propagation algorithm) we can find all +# derivatives. Since we will use automatic differentiation in reverse +# mode, we start with the derivatives of the cost function with respect +# to the parameters of the output layer, namely + +# $$ +# \frac{\partial C}{\partial w_{i}^{(2)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial w_{i}^{(2)}}=\delta^{(2)}a_i^{(1)}, +# $$ + +# with + +# $$ +# \delta^{(2)}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}} +# $$ + +# and finally + +# $$ +# \frac{\partial C}{\partial b^{(2)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial b^{(2)}}=\delta^{(2)}. +# $$ + +# ## Derivatives of the hidden layer +# +# Using the chain rule we have the following expressions for say one of the weight parameters (it is easy to generalize to the other weight parameters) + +# $$ +# \frac{\partial C}{\partial w_{00}^{(1)}}=\frac{\partial C}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}} +# \frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}= \delta^{(2)}\frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}, +# $$ + +# which, noting that + +# $$ +# z^{(2)} =w_0^{(2)}a_0^{(1)}+w_1^{(2)}a_1^{(1)}+b^{(2)}, +# $$ + +# allows us to rewrite + +# $$ +# \frac{\partial z^{(2)}}{\partial z_0^{(1)}}\frac{\partial z_0^{(1)}}{\partial w_{00}^{(1)}}=w_0^{(2)}\frac{\partial a_0^{(1)}}{\partial z_0^{(1)}}a_0^{(1)}. +# $$ + +# ## Final expression +# Defining + +# $$ +# \delta_0^{(1)}=w_0^{(2)}\frac{\partial a_0^{(1)}}{\partial z_0^{(1)}}\delta^{(2)}, +# $$ + +# we have + +# $$ +# \frac{\partial C}{\partial w_{00}^{(1)}}=\delta_0^{(1)}a_0^{(1)}. +# $$ + +# Similarly, we obtain + +# $$ +# \frac{\partial C}{\partial w_{01}^{(1)}}=\delta_0^{(1)}a_1^{(1)}. +# $$ + +# ## Completing the list +# +# Similarly, we find + +# $$ +# \frac{\partial C}{\partial w_{10}^{(1)}}=\delta_1^{(1)}a_0^{(1)}, +# $$ + +# and + +# $$ +# \frac{\partial C}{\partial w_{11}^{(1)}}=\delta_1^{(1)}a_1^{(1)}, +# $$ + +# where we have defined + +# $$ +# \delta_1^{(1)}=w_1^{(2)}\frac{\partial a_1^{(1)}}{\partial z_1^{(1)}}\delta^{(2)}. +# $$ + +# ## Final expressions for the biases of the hidden layer +# +# For the sake of completeness, we list the derivatives of the biases, which are + +# $$ +# \frac{\partial C}{\partial b_{0}^{(1)}}=\delta_0^{(1)}, +# $$ + +# and + +# $$ +# \frac{\partial C}{\partial b_{1}^{(1)}}=\delta_1^{(1)}. +# $$ + +# As we will see below, these expressions can be generalized in a more compact form. + +# ## Gradient expressions +# +# For this specific model, with just one output node and two hidden +# nodes, the gradient descent equations take the following form for output layer + +# $$ +# w_{i}^{(2)}\leftarrow w_{i}^{(2)}- \eta \delta^{(2)} a_{i}^{(1)}, +# $$ + +# and + +# $$ +# b^{(2)} \leftarrow b^{(2)}-\eta \delta^{(2)}, +# $$ + +# and + +# $$ +# w_{ij}^{(1)}\leftarrow w_{ij}^{(1)}- \eta \delta_{i}^{(1)} a_{j}^{(0)}, +# $$ + +# and + +# $$ +# b_{i}^{(1)} \leftarrow b_{i}^{(1)}-\eta \delta_{i}^{(1)}, +# $$ + +# where $\eta$ is the learning rate. + +# ## Setting up the equations for a neural network +# +# The questions we want to ask are how do changes in the biases and the +# weights in our network change the cost function and how can we use the +# final output to modify the weights and biases? +# +# To derive these equations let us start with a plain regression problem +# and define our cost function as + +# $$ +# {\cal C}(\boldsymbol{\Theta}) = \frac{1}{2}\sum_{i=1}^n\left(y_i - \tilde{y}_i\right)^2, +# $$ + +# where the $y_i$s are our $n$ targets (the values we want to +# reproduce), while the outputs of the network after having propagated +# all inputs $\boldsymbol{x}$ are given by $\boldsymbol{\tilde{y}}_i$. + +# ## Layout of a neural network with three hidden layers (last later = $l=L=4$, first layer $l=0$) +# +# +# +# +#

    Figure 1:

    +# + +# ## Definitions +# +# With our definition of the targets $\boldsymbol{y}$, the outputs of the +# network $\boldsymbol{\tilde{y}}$ and the inputs $\boldsymbol{x}$ we +# define now the activation $z_j^l$ of node/neuron/unit $j$ of the +# $l$-th layer as a function of the bias, the weights which add up from +# the previous layer $l-1$ and the forward passes/outputs +# $\boldsymbol{a}^{l-1}$ from the previous layer as + +# $$ +# z_j^l = \sum_{i=1}^{M_{l-1}}w_{ij}^la_i^{l-1}+b_j^l, +# $$ + +# where $b_k^l$ are the biases from layer $l$. Here $M_{l-1}$ +# represents the total number of nodes/neurons/units of layer $l-1$. The +# figure in the whiteboard notes illustrates this equation. We can rewrite this in a more +# compact form as the matrix-vector products we discussed earlier, + +# $$ +# \boldsymbol{z}^l = \left(\boldsymbol{W}^l\right)^T\boldsymbol{a}^{l-1}+\boldsymbol{b}^l. +# $$ + +# ## Inputs to the activation function +# +# With the activation values $\boldsymbol{z}^l$ we can in turn define the +# output of layer $l$ as $\boldsymbol{a}^l = \sigma(\boldsymbol{z}^l)$ where $\sigma$ is our +# activation function. In the examples here we will use the sigmoid +# function discussed in our logistic regression lectures. We will also use the same activation function $\sigma$ for all layers +# and their nodes. It means we have + +# $$ +# a_j^l = \sigma(z_j^l) = \frac{1}{1+\exp{-(z_j^l)}}. +# $$ + +# ## Layout of input to first hidden layer $l=1$ from input layer $l=0$ +# +# +# +# +#

    Figure 1:

    +# + +# ## Derivatives and the chain rule +# +# From the definition of the input variable to the activation function, that is $z_j^l$ we have + +# $$ +# \frac{\partial z_j^l}{\partial w_{ij}^l} = a_i^{l-1}, +# $$ + +# and + +# $$ +# \frac{\partial z_j^l}{\partial a_i^{l-1}} = w_{ji}^l. +# $$ + +# With our definition of the activation function we have that (note that this function depends only on $z_j^l$) + +# $$ +# \frac{\partial a_j^l}{\partial z_j^{l}} = a_j^l(1-a_j^l)=\sigma(z_j^l)(1-\sigma(z_j^l)). +# $$ + +# ## Derivative of the cost function +# +# With these definitions we can now compute the derivative of the cost function in terms of the weights. +# +# Let us specialize to the output layer $l=L$. Our cost function is + +# $$ +# {\cal C}(\boldsymbol{\Theta}^L) = \frac{1}{2}\sum_{i=1}^n\left(y_i - \tilde{y}_i\right)^2=\frac{1}{2}\sum_{i=1}^n\left(a_i^L - y_i\right)^2, +# $$ + +# The derivative of this function with respect to the weights is + +# $$ +# \frac{\partial{\cal C}(\boldsymbol{\Theta}^L)}{\partial w_{ij}^L} = \left(a_j^L - y_j\right)\frac{\partial a_j^L}{\partial w_{ij}^{L}}, +# $$ + +# The last partial derivative can easily be computed and reads (by applying the chain rule) + +# $$ +# \frac{\partial a_j^L}{\partial w_{ij}^{L}} = \frac{\partial a_j^L}{\partial z_{j}^{L}}\frac{\partial z_j^L}{\partial w_{ij}^{L}}=a_j^L(1-a_j^L)a_i^{L-1}. +# $$ + +# ## The back propagation equations for a neural network +# +# We have thus + +# $$ +# \frac{\partial{\cal C}((\boldsymbol{\Theta}^L)}{\partial w_{ij}^L} = \left(a_j^L - y_j\right)a_j^L(1-a_j^L)a_i^{L-1}, +# $$ + +# Defining + +# $$ +# \delta_j^L = a_j^L(1-a_j^L)\left(a_j^L - y_j\right) = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}, +# $$ + +# and using the Hadamard product of two vectors we can write this as + +# $$ +# \boldsymbol{\delta}^L = \sigma'(\boldsymbol{z}^L)\circ\frac{\partial {\cal C}}{\partial (\boldsymbol{a}^L)}. +# $$ + +# ## Analyzing the last results +# +# This is an important expression. The second term on the right handside +# measures how fast the cost function is changing as a function of the $j$th +# output activation. If, for example, the cost function doesn't depend +# much on a particular output node $j$, then $\delta_j^L$ will be small, +# which is what we would expect. The first term on the right, measures +# how fast the activation function $f$ is changing at a given activation +# value $z_j^L$. + +# ## More considerations +# +# Notice that everything in the above equations is easily computed. In +# particular, we compute $z_j^L$ while computing the behaviour of the +# network, and it is only a small additional overhead to compute +# $\sigma'(z^L_j)$. The exact form of the derivative with respect to the +# output depends on the form of the cost function. +# However, provided the cost function is known there should be little +# trouble in calculating + +# $$ +# \frac{\partial {\cal C}}{\partial (a_j^L)} +# $$ + +# With the definition of $\delta_j^L$ we have a more compact definition of the derivative of the cost function in terms of the weights, namely + +# $$ +# \frac{\partial{\cal C}}{\partial w_{ij}^L} = \delta_j^La_i^{L-1}. +# $$ + +# ## Derivatives in terms of $z_j^L$ +# +# It is also easy to see that our previous equation can be written as + +# $$ +# \delta_j^L =\frac{\partial {\cal C}}{\partial z_j^L}= \frac{\partial {\cal C}}{\partial a_j^L}\frac{\partial a_j^L}{\partial z_j^L}, +# $$ + +# which can also be interpreted as the partial derivative of the cost function with respect to the biases $b_j^L$, namely + +# $$ +# \delta_j^L = \frac{\partial {\cal C}}{\partial b_j^L}\frac{\partial b_j^L}{\partial z_j^L}=\frac{\partial {\cal C}}{\partial b_j^L}, +# $$ + +# That is, the error $\delta_j^L$ is exactly equal to the rate of change of the cost function as a function of the bias. + +# ## Bringing it together +# +# We have now three equations that are essential for the computations of the derivatives of the cost function at the output layer. These equations are needed to start the algorithm and they are + +# +#
    +# +# $$ +# \begin{equation} +# \frac{\partial{\cal C}(\boldsymbol{W^L})}{\partial w_{ij}^L} = \delta_j^La_i^{L-1}, +# \label{_auto1} \tag{1} +# \end{equation} +# $$ + +# and + +# +#
    +# +# $$ +# \begin{equation} +# \delta_j^L = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}, +# \label{_auto2} \tag{2} +# \end{equation} +# $$ + +# and + +# +#
    +# +# $$ +# \begin{equation} +# \delta_j^L = \frac{\partial {\cal C}}{\partial b_j^L}, +# \label{_auto3} \tag{3} +# \end{equation} +# $$ + +# ## Final back propagating equation +# +# We have that (replacing $L$ with a general layer $l$) + +# $$ +# \delta_j^l =\frac{\partial {\cal C}}{\partial z_j^l}. +# $$ + +# We want to express this in terms of the equations for layer $l+1$. + +# ## Using the chain rule and summing over all $k$ entries +# +# We obtain + +# $$ +# \delta_j^l =\sum_k \frac{\partial {\cal C}}{\partial z_k^{l+1}}\frac{\partial z_k^{l+1}}{\partial z_j^{l}}=\sum_k \delta_k^{l+1}\frac{\partial z_k^{l+1}}{\partial z_j^{l}}, +# $$ + +# and recalling that + +# $$ +# z_j^{l+1} = \sum_{i=1}^{M_{l}}w_{ij}^{l+1}a_i^{l}+b_j^{l+1}, +# $$ + +# with $M_l$ being the number of nodes in layer $l$, we obtain + +# $$ +# \delta_j^l =\sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l), +# $$ + +# This is our final equation. +# +# We are now ready to set up the algorithm for back propagation and learning the weights and biases. + +# ## Setting up the back propagation algorithm +# +# The four equations provide us with a way of computing the gradient of the cost function. Let us write this out in the form of an algorithm. +# +# **First**, we set up the input data $\boldsymbol{x}$ and the activations +# $\boldsymbol{z}_1$ of the input layer and compute the activation function and +# the pertinent outputs $\boldsymbol{a}^1$. +# +# **Secondly**, we perform then the feed forward till we reach the output +# layer and compute all $\boldsymbol{z}_l$ of the input layer and compute the +# activation function and the pertinent outputs $\boldsymbol{a}^l$ for +# $l=1,2,3,\dots,L$. +# +# **Notation**: The first hidden layer has $l=1$ as label and the final output layer has $l=L$. + +# ## Setting up the back propagation algorithm, part 2 +# +# Thereafter we compute the ouput error $\boldsymbol{\delta}^L$ by computing all + +# $$ +# \delta_j^L = \sigma'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}. +# $$ + +# Then we compute the back propagate error for each $l=L-1,L-2,\dots,1$ as + +# $$ +# \delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l). +# $$ + +# ## Setting up the Back propagation algorithm, part 3 +# +# Finally, we update the weights and the biases using gradient descent +# for each $l=L-1,L-2,\dots,1$ (the first hidden layer) and update the weights and biases +# according to the rules + +# $$ +# w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +# $$ + +# $$ +# b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +# $$ + +# with $\eta$ being the learning rate. + +# ## Updating the gradients +# +# With the back propagate error for each $l=L-1,L-2,\dots,1$ as + +# $$ +# \delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l), +# $$ + +# we update the weights and the biases using gradient descent for each $l=L-1,L-2,\dots,1$ and update the weights and biases according to the rules + +# $$ +# w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +# $$ + +# $$ +# b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +# $$ + +# ### Activation functions +# +# A property that characterizes a neural network, other than its +# connectivity, is the choice of activation function(s). As described +# in, the following restrictions are imposed on an activation function +# for a FFNN to fulfill the universal approximation theorem +# +# * Non-constant +# +# * Bounded +# +# * Monotonically-increasing +# +# * Continuous + +# ### Activation functions, Logistic and Hyperbolic ones +# +# The second requirement excludes all linear functions. Furthermore, in +# a MLP with only linear activation functions, each layer simply +# performs a linear transformation of its inputs. +# +# Regardless of the number of layers, the output of the NN will be +# nothing but a linear function of the inputs. Thus we need to introduce +# some kind of non-linearity to the NN to be able to fit non-linear +# functions Typical examples are the logistic *Sigmoid* + +# $$ +# \sigma(x) = \frac{1}{1 + e^{-x}}, +# $$ + +# and the *hyperbolic tangent* function + +# $$ +# \sigma(x) = \tanh(x) +# $$ + +# ### Relevance +# +# The *sigmoid* function are more biologically plausible because the +# output of inactive neurons are zero. Such activation function are +# called *one-sided*. However, it has been shown that the hyperbolic +# tangent performs better than the sigmoid for training MLPs. has +# become the most popular for *deep neural networks* + +# In[2]: + + +get_ipython().run_line_magic('matplotlib', 'inline') + +"""The sigmoid function (or the logistic curve) is a +function that takes any real number, z, and outputs a number (0,1). +It is useful in neural networks for assigning weights on a relative scale. +The value z is the weighted sum of parameters involved in the learning algorithm.""" + +import numpy +import matplotlib.pyplot as plt +import math as mt + +z = numpy.arange(-5, 5, .1) +sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z))) +sigma = sigma_fn(z) + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.plot(z, sigma) +ax.set_ylim([-0.1, 1.1]) +ax.set_xlim([-5,5]) +ax.grid(True) +ax.set_xlabel('z') +ax.set_title('sigmoid function') + +plt.show() + +"""Step Function""" +z = numpy.arange(-5, 5, .02) +step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0) +step = step_fn(z) + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.plot(z, step) +ax.set_ylim([-0.5, 1.5]) +ax.set_xlim([-5,5]) +ax.grid(True) +ax.set_xlabel('z') +ax.set_title('step function') + +plt.show() + +"""Sine Function""" +z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1) +t = numpy.sin(z) + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.plot(z, t) +ax.set_ylim([-1.0, 1.0]) +ax.set_xlim([-2*mt.pi,2*mt.pi]) +ax.grid(True) +ax.set_xlabel('z') +ax.set_title('sine function') + +plt.show() + +"""Plots a graph of the squashing function used by a rectified linear +unit""" +z = numpy.arange(-2, 2, .1) +zero = numpy.zeros(len(z)) +y = numpy.max([zero, z], axis=0) + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.plot(z, y) +ax.set_ylim([-2.0, 2.0]) +ax.set_xlim([-2.0, 2.0]) +ax.grid(True) +ax.set_xlabel('z') +ax.set_title('Rectified linear unit') + +plt.show() + + +# ## Fine-tuning neural network hyperparameters +# +# The flexibility of neural networks is also one of their main +# drawbacks: there are many hyperparameters to tweak. Not only can you +# use any imaginable network topology (how neurons/nodes are +# interconnected), but even in a simple FFNN you can change the number +# of layers, the number of neurons per layer, the type of activation +# function to use in each layer, the weight initialization logic, the +# stochastic gradient optmized and much more. How do you know what +# combination of hyperparameters is the best for your task? +# +# * You can use grid search with cross-validation to find the right hyperparameters. +# +# However,since there are many hyperparameters to tune, and since +# training a neural network on a large dataset takes a lot of time, you +# will only be able to explore a tiny part of the hyperparameter space. +# +# * You can use randomized search. +# +# * Or use tools like [Oscar](http://oscar.calldesk.ai/), which implements more complex algorithms to help you find a good set of hyperparameters quickly. + +# ## Hidden layers +# +# For many problems you can start with just one or two hidden layers and +# it will work just fine. For the MNIST data set you ca easily get a +# high accuracy using just one hidden layer with a few hundred neurons. +# You can reach for this data set above 98% accuracy using two hidden +# layers with the same total amount of neurons, in roughly the same +# amount of training time. +# +# For more complex problems, you can gradually ramp up the number of +# hidden layers, until you start overfitting the training set. Very +# complex tasks, such as large image classification or speech +# recognition, typically require networks with dozens of layers and they +# need a huge amount of training data. However, you will rarely have to +# train such networks from scratch: it is much more common to reuse +# parts of a pretrained state-of-the-art network that performs a similar +# task. + +# ## Vanishing gradients +# +# The Back propagation algorithm we derived above works by going from +# the output layer to the input layer, propagating the error gradient on +# the way. Once the algorithm has computed the gradient of the cost +# function with regards to each parameter in the network, it uses these +# gradients to update each parameter with a Gradient Descent (GD) step. +# +# Unfortunately for us, the gradients often get smaller and smaller as +# the algorithm progresses down to the first hidden layers. As a result, +# the GD update leaves the lower layer connection weights virtually +# unchanged, and training never converges to a good solution. This is +# known in the literature as **the vanishing gradients problem**. + +# ## Exploding gradients +# +# In other cases, the opposite can happen, namely the the gradients can +# grow bigger and bigger. The result is that many of the layers get +# large updates of the weights the algorithm diverges. This is the +# **exploding gradients problem**, which is mostly encountered in +# recurrent neural networks. More generally, deep neural networks suffer +# from unstable gradients, different layers may learn at widely +# different speeds + +# ## Is the Logistic activation function (Sigmoid) our choice? +# +# Although this unfortunate behavior has been empirically observed for +# quite a while (it was one of the reasons why deep neural networks were +# mostly abandoned for a long time), it is only around 2010 that +# significant progress was made in understanding it. +# +# A paper titled [Understanding the Difficulty of Training Deep +# Feedforward Neural Networks by Xavier Glorot and Yoshua Bengio](http://proceedings.mlr.press/v9/glorot10a.html) found that +# the problems with the popular logistic +# sigmoid activation function and the weight initialization technique +# that was most popular at the time, namely random initialization using +# a normal distribution with a mean of 0 and a standard deviation of +# 1. + +# ## Logistic function as the root of problems +# +# They showed that with this activation function and this +# initialization scheme, the variance of the outputs of each layer is +# much greater than the variance of its inputs. Going forward in the +# network, the variance keeps increasing after each layer until the +# activation function saturates at the top layers. This is actually made +# worse by the fact that the logistic function has a mean of 0.5, not 0 +# (the hyperbolic tangent function has a mean of 0 and behaves slightly +# better than the logistic function in deep networks). + +# ## The derivative of the Logistic funtion +# +# Looking at the logistic activation function, when inputs become large +# (negative or positive), the function saturates at 0 or 1, with a +# derivative extremely close to 0. Thus when backpropagation kicks in, +# it has virtually no gradient to propagate back through the network, +# and what little gradient exists keeps getting diluted as +# backpropagation progresses down through the top layers, so there is +# really nothing left for the lower layers. +# +# In their paper, Glorot and Bengio propose a way to significantly +# alleviate this problem. We need the signal to flow properly in both +# directions: in the forward direction when making predictions, and in +# the reverse direction when backpropagating gradients. We don’t want +# the signal to die out, nor do we want it to explode and saturate. For +# the signal to flow properly, the authors argue that we need the +# variance of the outputs of each layer to be equal to the variance of +# its inputs, and we also need the gradients to have equal variance +# before and after flowing through a layer in the reverse direction. + +# ## Insights from the paper by Glorot and Bengio +# +# One of the insights in the 2010 paper by Glorot and Bengio was that +# the vanishing/exploding gradients problems were in part due to a poor +# choice of activation function. Until then most people had assumed that +# if Nature had chosen to use roughly sigmoid activation functions in +# biological neurons, they must be an excellent choice. But it turns out +# that other activation functions behave much better in deep neural +# networks, in particular the ReLU activation function, mostly because +# it does not saturate for positive values (and also because it is quite +# fast to compute). + +# ## The RELU function family +# +# The ReLU activation function suffers from a problem known as the dying +# ReLUs: during training, some neurons effectively die, meaning they +# stop outputting anything other than 0. +# +# In some cases, you may find that half of your network’s neurons are +# dead, especially if you used a large learning rate. During training, +# if a neuron’s weights get updated such that the weighted sum of the +# neuron’s inputs is negative, it will start outputting 0. When this +# happen, the neuron is unlikely to come back to life since the gradient +# of the ReLU function is 0 when its input is negative. + +# ## ELU function +# +# To solve this problem, nowadays practitioners use a variant of the +# ReLU function, such as the leaky ReLU discussed above or the so-called +# exponential linear unit (ELU) function + +# $$ +# ELU(z) = \left\{\begin{array}{cc} \alpha\left( \exp{(z)}-1\right) & z < 0,\\ z & z \ge 0.\end{array}\right. +# $$ + +# ## Which activation function should we use? +# +# In general it seems that the ELU activation function is better than +# the leaky ReLU function (and its variants), which is better than +# ReLU. ReLU performs better than $\tanh$ which in turn performs better +# than the logistic function. +# +# If runtime performance is an issue, then you may opt for the leaky +# ReLU function over the ELU function If you don’t want to tweak yet +# another hyperparameter, you may just use the default $\alpha$ of +# $0.01$ for the leaky ReLU, and $1$ for ELU. If you have spare time and +# computing power, you can use cross-validation or bootstrap to evaluate +# other activation functions. + +# ## More on activation functions, output layers +# +# In most cases you can use the ReLU activation function in the hidden +# layers (or one of its variants). +# +# It is a bit faster to compute than other activation functions, and the +# gradient descent optimization does in general not get stuck. +# +# **For the output layer:** +# +# * For classification the softmax activation function is generally a good choice for classification tasks (when the classes are mutually exclusive). +# +# * For regression tasks, you can simply use no activation function at all. + +# ## Batch Normalization +# +# Batch Normalization aims to address the vanishing/exploding gradients +# problems, and more generally the problem that the distribution of each +# layer’s inputs changes during training, as the parameters of the +# previous layers change. +# +# The technique consists of adding an operation in the model just before +# the activation function of each layer, simply zero-centering and +# normalizing the inputs, then scaling and shifting the result using two +# new parameters per layer (one for scaling, the other for shifting). In +# other words, this operation lets the model learn the optimal scale and +# mean of the inputs for each layer. In order to zero-center and +# normalize the inputs, the algorithm needs to estimate the inputs’ mean +# and standard deviation. It does so by evaluating the mean and standard +# deviation of the inputs over the current mini-batch, from this the +# name batch normalization. + +# ## Dropout +# +# It is a fairly simple algorithm: at every training step, every neuron +# (including the input neurons but excluding the output neurons) has a +# probability $p$ of being temporarily dropped out, meaning it will be +# entirely ignored during this training step, but it may be active +# during the next step. +# +# The hyperparameter $p$ is called the dropout rate, and it is typically +# set to 50%. After training, the neurons are not dropped anymore. It +# is viewed as one of the most popular regularization techniques. + +# ## Gradient Clipping +# +# A popular technique to lessen the exploding gradients problem is to +# simply clip the gradients during backpropagation so that they never +# exceed some threshold (this is mostly useful for recurrent neural +# networks). +# +# This technique is called Gradient Clipping. +# +# In general however, Batch +# Normalization is preferred. + +# ## A top-down perspective on Neural networks +# +# The first thing we would like to do is divide the data into two or +# three parts. A training set, a validation or dev (development) set, +# and a test set. The test set is the data on which we want to make +# predictions. The dev set is a subset of the training data we use to +# check how well we are doing out-of-sample, after training the model on +# the training dataset. We use the validation error as a proxy for the +# test error in order to make tweaks to our model. It is crucial that we +# do not use any of the test data to train the algorithm. This is a +# cardinal sin in ML. Then: +# +# 1. Estimate optimal error rate +# +# 2. Minimize underfitting (bias) on training data set. +# +# 3. Make sure you are not overfitting. + +# ## More top-down perspectives +# +# If the validation and test sets are drawn from the same distributions, +# then a good performance on the validation set should lead to similarly +# good performance on the test set. +# +# However, sometimes +# the training data and test data differ in subtle ways because, for +# example, they are collected using slightly different methods, or +# because it is cheaper to collect data in one way versus another. In +# this case, there can be a mismatch between the training and test +# data. This can lead to the neural network overfitting these small +# differences between the test and training sets, and a poor performance +# on the test set despite having a good performance on the validation +# set. To rectify this, Andrew Ng suggests making two validation or dev +# sets, one constructed from the training data and one constructed from +# the test data. The difference between the performance of the algorithm +# on these two validation sets quantifies the train-test mismatch. This +# can serve as another important diagnostic when using DNNs for +# supervised learning. + +# ## Limitations of supervised learning with deep networks +# +# Like all statistical methods, supervised learning using neural +# networks has important limitations. This is especially important when +# one seeks to apply these methods, especially to physics problems. Like +# all tools, DNNs are not a universal solution. Often, the same or +# better performance on a task can be achieved by using a few +# hand-engineered features (or even a collection of random +# features). + +# ## Limitations of NNs +# +# Here we list some of the important limitations of supervised neural network based models. +# +# * **Need labeled data**. All supervised learning methods, DNNs for supervised learning require labeled data. Often, labeled data is harder to acquire than unlabeled data (e.g. one must pay for human experts to label images). +# +# * **Supervised neural networks are extremely data intensive.** DNNs are data hungry. They perform best when data is plentiful. This is doubly so for supervised methods where the data must also be labeled. The utility of DNNs is extremely limited if data is hard to acquire or the datasets are small (hundreds to a few thousand samples). In this case, the performance of other methods that utilize hand-engineered features can exceed that of DNNs. + +# ## Homogeneous data +# +# * **Homogeneous data.** Almost all DNNs deal with homogeneous data of one type. It is very hard to design architectures that mix and match data types (i.e. some continuous variables, some discrete variables, some time series). In applications beyond images, video, and language, this is often what is required. In contrast, ensemble models like random forests or gradient-boosted trees have no difficulty handling mixed data types. + +# ## More limitations +# +# * **Many problems are not about prediction.** In natural science we are often interested in learning something about the underlying distribution that generates the data. In this case, it is often difficult to cast these ideas in a supervised learning setting. While the problems are related, it is possible to make good predictions with a *wrong* model. The model might or might not be useful for understanding the underlying science. +# +# Some of these remarks are particular to DNNs, others are shared by all supervised learning methods. This motivates the use of unsupervised methods which in part circumvent these problems. + +# ## Setting up the back-propagation algorithm +# +# Let us write this out in the form of an algorithm. +# +# First, we set up the input data $\boldsymbol{x}$ and the activations +# $\boldsymbol{z}_1$ of the input layer and compute the activation function and +# the pertinent outputs $\boldsymbol{a}^1$. +# +# Secondly, we perform then the feed forward till we reach the output +# layer and compute all $\boldsymbol{z}_l$ of the input layer and compute the +# activation function and the pertinent outputs $\boldsymbol{a}^l$ for +# $l=2,3,\dots,L$. +# +# Thereafter we compute the ouput error $\boldsymbol{\delta}^L$ by computing all + +# $$ +# \delta_j^L = f'(z_j^L)\frac{\partial {\cal C}}{\partial (a_j^L)}. +# $$ + +# Then we compute the back propagate error for each $l=L-1,L-2,\dots,2$ as + +# $$ +# \delta_j^l = \sum_k \delta_k^{l+1}w_{kj}^{l+1}\sigma'(z_j^l). +# $$ + +# Finally, we update the weights and the biases using gradient descent for each $l=L-1,L-2,\dots,2$ and update the weights and biases according to the rules + +# $$ +# w_{ij}^l\leftarrow = w_{ij}^l- \eta \delta_j^la_i^{l-1}, +# $$ + +# $$ +# b_j^l \leftarrow b_j^l-\eta \frac{\partial {\cal C}}{\partial b_j^l}=b_j^l-\eta \delta_j^l, +# $$ + +# The parameter $\eta$ is the learning parameter discussed in connection with the gradient descent methods. +# Here it is convenient to use stochastic gradient descent (see the examples below) with mini-batches with an outer loop that steps through multiple epochs of training. + +# ## Setting up a Multi-layer perceptron model for classification +# +# We are now gong to develop an example based on the MNIST data +# base. This is a classification problem and we need to use our +# cross-entropy function we discussed in connection with logistic +# regression. The cross-entropy defines our cost function for the +# classificaton problems with neural networks. +# +# In binary classification with two classes $(0, 1)$ we define the +# logistic/sigmoid function as the probability that a particular input +# is in class $0$ or $1$. This is possible because the logistic +# function takes any input from the real numbers and inputs a number +# between 0 and 1, and can therefore be interpreted as a probability. It +# also has other nice properties, such as a derivative that is simple to +# calculate. +# +# For an input $\boldsymbol{a}$ from the hidden layer, the probability that the input $\boldsymbol{x}$ +# is in class 0 or 1 is just. We let $\theta$ represent the unknown weights and biases to be adjusted by our equations). The variable $x$ +# represents our activation values $z$. We have + +# $$ +# P(y = 0 \mid \boldsymbol{x}, \boldsymbol{\theta}) = \frac{1}{1 + \exp{(- \boldsymbol{x}})} , +# $$ + +# and + +# $$ +# P(y = 1 \mid \boldsymbol{x}, \boldsymbol{\theta}) = 1 - P(y = 0 \mid \boldsymbol{x}, \boldsymbol{\theta}) , +# $$ + +# where $y \in \{0, 1\}$ and $\boldsymbol{\theta}$ represents the weights and biases +# of our network. + +# ## Defining the cost function +# +# Our cost function is given as (see the Logistic regression lectures) + +# $$ +# \mathcal{C}(\boldsymbol{\theta}) = - \ln P(\mathcal{D} \mid \boldsymbol{\theta}) = - \sum_{i=1}^n +# y_i \ln[P(y_i = 0)] + (1 - y_i) \ln [1 - P(y_i = 0)] = \sum_{i=1}^n \mathcal{L}_i(\boldsymbol{\theta}) . +# $$ + +# This last equality means that we can interpret our *cost* function as a sum over the *loss* function +# for each point in the dataset $\mathcal{L}_i(\boldsymbol{\theta})$. +# The negative sign is just so that we can think about our algorithm as minimizing a positive number, rather +# than maximizing a negative number. +# +# In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: +# +# $y = 5 \quad \rightarrow \quad \boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$ and +# +# $y = 1 \quad \rightarrow \quad \boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$ +# +# i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset (numbers from $0$ to $9$).. +# +# If $\boldsymbol{x}_i$ is the $i$-th input (image), $y_{ic}$ refers to the $c$-th component of the $i$-th +# output vector $\boldsymbol{y}_i$. +# The probability of $\boldsymbol{x}_i$ being in class $c$ will be given by the softmax function: + +# $$ +# P(y_{ic} = 1 \mid \boldsymbol{x}_i, \boldsymbol{\theta}) = \frac{\exp{((\boldsymbol{a}_i^{hidden})^T \boldsymbol{w}_c)}} +# {\sum_{c'=0}^{C-1} \exp{((\boldsymbol{a}_i^{hidden})^T \boldsymbol{w}_{c'})}} , +# $$ + +# which reduces to the logistic function in the binary case. +# The likelihood of this $C$-class classifier +# is now given as: + +# $$ +# P(\mathcal{D} \mid \boldsymbol{\theta}) = \prod_{i=1}^n \prod_{c=0}^{C-1} [P(y_{ic} = 1)]^{y_{ic}} . +# $$ + +# Again we take the negative log-likelihood to define our cost function: + +# $$ +# \mathcal{C}(\boldsymbol{\theta}) = - \log{P(\mathcal{D} \mid \boldsymbol{\theta})}. +# $$ + +# See the logistic regression lectures for a full definition of the cost function. +# +# The back propagation equations need now only a small change, namely the definition of a new cost function. We are thus ready to use the same equations as before! + +# ## Example: binary classification problem +# +# As an example of the above, relevant for project 2 as well, let us consider a binary class. As discussed in our logistic regression lectures, we defined a cost function in terms of the parameters $\beta$ as + +# $$ +# \mathcal{C}(\boldsymbol{\beta}) = - \sum_{i=1}^n \left(y_i\log{p(y_i \vert x_i,\boldsymbol{\beta})}+(1-y_i)\log{1-p(y_i \vert x_i,\boldsymbol{\beta})}\right), +# $$ + +# where we had defined the logistic (sigmoid) function + +# $$ +# p(y_i =1\vert x_i,\boldsymbol{\beta})=\frac{\exp{(\beta_0+\beta_1 x_i)}}{1+\exp{(\beta_0+\beta_1 x_i)}}, +# $$ + +# and + +# $$ +# p(y_i =0\vert x_i,\boldsymbol{\beta})=1-p(y_i =1\vert x_i,\boldsymbol{\beta}). +# $$ + +# The parameters $\boldsymbol{\beta}$ were defined using a minimization method like gradient descent or Newton-Raphson's method. +# +# Now we replace $x_i$ with the activation $z_i^l$ for a given layer $l$ and the outputs as $y_i=a_i^l=f(z_i^l)$, with $z_i^l$ now being a function of the weights $w_{ij}^l$ and biases $b_i^l$. +# We have then + +# $$ +# a_i^l = y_i = \frac{\exp{(z_i^l)}}{1+\exp{(z_i^l)}}, +# $$ + +# with + +# $$ +# z_i^l = \sum_{j}w_{ij}^l a_j^{l-1}+b_i^l, +# $$ + +# where the superscript $l-1$ indicates that these are the outputs from layer $l-1$. +# Our cost function at the final layer $l=L$ is now + +# $$ +# \mathcal{C}(\boldsymbol{W}) = - \sum_{i=1}^n \left(t_i\log{a_i^L}+(1-t_i)\log{(1-a_i^L)}\right), +# $$ + +# where we have defined the targets $t_i$. The derivatives of the cost function with respect to the output $a_i^L$ are then easily calculated and we get + +# $$ +# \frac{\partial \mathcal{C}(\boldsymbol{W})}{\partial a_i^L} = \frac{a_i^L-t_i}{a_i^L(1-a_i^L)}. +# $$ + +# In case we use another activation function than the logistic one, we need to evaluate other derivatives. + +# ## The Softmax function +# In case we employ the more general case given by the Softmax equation, we need to evaluate the derivative of the activation function with respect to the activation $z_i^l$, that is we need + +# $$ +# \frac{\partial f(z_i^l)}{\partial w_{jk}^l} = +# \frac{\partial f(z_i^l)}{\partial z_j^l} \frac{\partial z_j^l}{\partial w_{jk}^l}= \frac{\partial f(z_i^l)}{\partial z_j^l}a_k^{l-1}. +# $$ + +# For the Softmax function we have + +# $$ +# f(z_i^l) = \frac{\exp{(z_i^l)}}{\sum_{m=1}^K\exp{(z_m^l)}}. +# $$ + +# Its derivative with respect to $z_j^l$ gives + +# $$ +# \frac{\partial f(z_i^l)}{\partial z_j^l}= f(z_i^l)\left(\delta_{ij}-f(z_j^l)\right), +# $$ + +# which in case of the simply binary model reduces to having $i=j$. + +# ## Developing a code for doing neural networks with back propagation +# +# One can identify a set of key steps when using neural networks to solve supervised learning problems: +# +# 1. Collect and pre-process data +# +# 2. Define model and architecture +# +# 3. Choose cost function and optimizer +# +# 4. Train the model +# +# 5. Evaluate model performance on test data +# +# 6. Adjust hyperparameters (if necessary, network architecture) + +# ## Collect and pre-process data +# +# Here we will be using the MNIST dataset, which is readily available through the **scikit-learn** +# package. You may also find it for example [here](http://yann.lecun.com/exdb/mnist/). +# The *MNIST* (Modified National Institute of Standards and Technology) database is a large database +# of handwritten digits that is commonly used for training various image processing systems. +# The MNIST dataset consists of 70 000 images of size $28\times 28$ pixels, each labeled from 0 to 9. +# The scikit-learn dataset we will use consists of a selection of 1797 images of size $8\times 8$ collected and processed from this database. +# +# To feed data into a feed-forward neural network we need to represent +# the inputs as a design/feature matrix $X = (n_{inputs}, n_{features})$. Each +# row represents an *input*, in this case a handwritten digit, and +# each column represents a *feature*, in this case a pixel. The +# correct answers, also known as *labels* or *targets* are +# represented as a 1D array of integers +# $Y = (n_{inputs}) = (5, 3, 1, 8,...)$. +# +# As an example, say we want to build a neural network using supervised learning to predict Body-Mass Index (BMI) from +# measurements of height (in m) +# and weight (in kg). If we have measurements of 5 people the design/feature matrix could be for example: +# +# $$ X = \begin{bmatrix} +# 1.85 & 81\\ +# 1.71 & 65\\ +# 1.95 & 103\\ +# 1.55 & 42\\ +# 1.63 & 56 +# \end{bmatrix} ,$$ +# +# and the targets would be: +# +# $$ Y = (23.7, 22.2, 27.1, 17.5, 21.1) $$ +# +# Since each input image is a 2D matrix, we need to flatten the image +# (i.e. "unravel" the 2D matrix into a 1D array) to turn the data into a +# design/feature matrix. This means we lose all spatial information in the +# image, such as locality and translational invariance. More complicated +# architectures such as Convolutional Neural Networks can take advantage +# of such information, and are most commonly applied when analyzing +# images. + +# In[3]: + + +# import necessary packages +import numpy as np +import matplotlib.pyplot as plt +from sklearn import datasets + + +# ensure the same random numbers appear every time +np.random.seed(0) + +# display images in notebook +get_ipython().run_line_magic('matplotlib', 'inline') +plt.rcParams['figure.figsize'] = (12,12) + + +# download MNIST dataset +digits = datasets.load_digits() + +# define inputs and labels +inputs = digits.images +labels = digits.target + +print("inputs = (n_inputs, pixel_width, pixel_height) = " + str(inputs.shape)) +print("labels = (n_inputs) = " + str(labels.shape)) + + +# flatten the image +# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64 +n_inputs = len(inputs) +inputs = inputs.reshape(n_inputs, -1) +print("X = (n_inputs, n_features) = " + str(inputs.shape)) + + +# choose some random images to display +indices = np.arange(n_inputs) +random_indices = np.random.choice(indices, size=5) + +for i, image in enumerate(digits.images[random_indices]): + plt.subplot(1, 5, i+1) + plt.axis('off') + plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') + plt.title("Label: %d" % digits.target[random_indices[i]]) +plt.show() + + +# ## Train and test datasets +# +# Performing analysis before partitioning the dataset is a major error, that can lead to incorrect conclusions. +# +# We will reserve $80 \%$ of our dataset for training and $20 \%$ for testing. +# +# It is important that the train and test datasets are drawn randomly from our dataset, to ensure +# no bias in the sampling. +# Say you are taking measurements of weather data to predict the weather in the coming 5 days. +# You don't want to train your model on measurements taken from the hours 00.00 to 12.00, and then test it on data +# collected from 12.00 to 24.00. + +# In[4]: + + +from sklearn.model_selection import train_test_split + +# one-liner from scikit-learn library +train_size = 0.8 +test_size = 1 - train_size +X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size, + test_size=test_size) + +# equivalently in numpy +def train_test_split_numpy(inputs, labels, train_size, test_size): + n_inputs = len(inputs) + inputs_shuffled = inputs.copy() + labels_shuffled = labels.copy() + + np.random.shuffle(inputs_shuffled) + np.random.shuffle(labels_shuffled) + + train_end = int(n_inputs*train_size) + X_train, X_test = inputs_shuffled[:train_end], inputs_shuffled[train_end:] + Y_train, Y_test = labels_shuffled[:train_end], labels_shuffled[train_end:] + + return X_train, X_test, Y_train, Y_test + +#X_train, X_test, Y_train, Y_test = train_test_split_numpy(inputs, labels, train_size, test_size) + +print("Number of training images: " + str(len(X_train))) +print("Number of test images: " + str(len(X_test))) + + +# ## Define model and architecture +# +# Our simple feed-forward neural network will consist of an *input* layer, a single *hidden* layer and an *output* layer. The activation $y$ of each neuron is a weighted sum of inputs, passed through an activation function. In case of the simple perceptron model we have +# +# $$ z = \sum_{i=1}^n w_i a_i ,$$ +# +# $$ y = f(z) ,$$ +# +# where $f$ is the activation function, $a_i$ represents input from neuron $i$ in the preceding layer +# and $w_i$ is the weight to input $i$. +# The activation of the neurons in the input layer is just the features (e.g. a pixel value). +# +# The simplest activation function for a neuron is the *Heaviside* function: +# +# $$ f(z) = +# \begin{cases} +# 1, & z > 0\\ +# 0, & \text{otherwise} +# \end{cases} +# $$ +# +# A feed-forward neural network with this activation is known as a *perceptron*. +# For a binary classifier (i.e. two classes, 0 or 1, dog or not-dog) we can also use this in our output layer. +# This activation can be generalized to $k$ classes (using e.g. the *one-against-all* strategy), +# and we call these architectures *multiclass perceptrons*. +# +# However, it is now common to use the terms Single Layer Perceptron (SLP) (1 hidden layer) and +# Multilayer Perceptron (MLP) (2 or more hidden layers) to refer to feed-forward neural networks with any activation function. +# +# Typical choices for activation functions include the sigmoid function, hyperbolic tangent, and Rectified Linear Unit (ReLU). +# We will be using the sigmoid function $\sigma(x)$: +# +# $$ f(x) = \sigma(x) = \frac{1}{1 + e^{-x}} ,$$ +# +# which is inspired by probability theory (see logistic regression) and was most commonly used until about 2011. See the discussion below concerning other activation functions. + +# ## Layers +# +# * Input +# +# Since each input image has 8x8 = 64 pixels or features, we have an input layer of 64 neurons. +# +# * Hidden layer +# +# We will use 50 neurons in the hidden layer receiving input from the neurons in the input layer. +# Since each neuron in the hidden layer is connected to the 64 inputs we have 64x50 = 3200 weights to the hidden layer. +# +# * Output +# +# If we were building a binary classifier, it would be sufficient with a single neuron in the output layer, +# which could output 0 or 1 according to the Heaviside function. This would be an example of a *hard* classifier, meaning it outputs the class of the input directly. However, if we are dealing with noisy data it is often beneficial to use a *soft* classifier, which outputs the probability of being in class 0 or 1. +# +# For a soft binary classifier, we could use a single neuron and interpret the output as either being the probability of being in class 0 or the probability of being in class 1. Alternatively we could use 2 neurons, and interpret each neuron as the probability of being in each class. +# +# Since we are doing multiclass classification, with 10 categories, it is natural to use 10 neurons in the output layer. We number the neurons $j = 0,1,...,9$. The activation of each output neuron $j$ will be according to the *softmax* function: +# +# $$ P(\text{class $j$} \mid \text{input $\boldsymbol{a}$}) = \frac{\exp{(\boldsymbol{a}^T \boldsymbol{w}_j)}} +# {\sum_{c=0}^{9} \exp{(\boldsymbol{a}^T \boldsymbol{w}_c)}} ,$$ +# +# i.e. each neuron $j$ outputs the probability of being in class $j$ given an input from the hidden layer $\boldsymbol{a}$, with $\boldsymbol{w}_j$ the weights of neuron $j$ to the inputs. +# The denominator is a normalization factor to ensure the outputs (probabilities) sum up to 1. +# The exponent is just the weighted sum of inputs as before: +# +# $$ z_j = \sum_{i=1}^n w_ {ij} a_i+b_j.$$ +# +# Since each neuron in the output layer is connected to the 50 inputs from the hidden layer we have 50x10 = 500 +# weights to the output layer. + +# ## Weights and biases +# +# Typically weights are initialized with small values distributed around zero, drawn from a uniform +# or normal distribution. Setting all weights to zero means all neurons give the same output, making the network useless. +# +# Adding a bias value to the weighted sum of inputs allows the neural network to represent a greater range +# of values. Without it, any input with the value 0 will be mapped to zero (before being passed through the activation). The bias unit has an output of 1, and a weight to each neuron $j$, $b_j$: +# +# $$ z_j = \sum_{i=1}^n w_ {ij} a_i + b_j.$$ +# +# The bias weights $\boldsymbol{b}$ are often initialized to zero, but a small value like $0.01$ ensures all neurons have some output which can be backpropagated in the first training cycle. + +# In[5]: + + +# building our neural network + +n_inputs, n_features = X_train.shape +n_hidden_neurons = 50 +n_categories = 10 + +# we make the weights normally distributed using numpy.random.randn + +# weights and bias in the hidden layer +hidden_weights = np.random.randn(n_features, n_hidden_neurons) +hidden_bias = np.zeros(n_hidden_neurons) + 0.01 + +# weights and bias in the output layer +output_weights = np.random.randn(n_hidden_neurons, n_categories) +output_bias = np.zeros(n_categories) + 0.01 + + +# ## Feed-forward pass +# +# Denote $F$ the number of features, $H$ the number of hidden neurons and $C$ the number of categories. +# For each input image we calculate a weighted sum of input features (pixel values) to each neuron $j$ in the hidden layer $l$: +# +# $$ z_{j}^{l} = \sum_{i=1}^{F} w_{ij}^{l} x_i + b_{j}^{l},$$ +# +# this is then passed through our activation function +# +# $$ a_{j}^{l} = f(z_{j}^{l}) .$$ +# +# We calculate a weighted sum of inputs (activations in the hidden layer) to each neuron $j$ in the output layer: +# +# $$ z_{j}^{L} = \sum_{i=1}^{H} w_{ij}^{L} a_{i}^{l} + b_{j}^{L}.$$ +# +# Finally we calculate the output of neuron $j$ in the output layer using the softmax function: +# +# $$ a_{j}^{L} = \frac{\exp{(z_j^{L})}} +# {\sum_{c=0}^{C-1} \exp{(z_c^{L})}} .$$ + +# ## Matrix multiplications +# +# Since our data has the dimensions $X = (n_{inputs}, n_{features})$ and our weights to the hidden +# layer have the dimensions +# $W_{hidden} = (n_{features}, n_{hidden})$, +# we can easily feed the network all our training data in one go by taking the matrix product +# +# $$ X W^{h} = (n_{inputs}, n_{hidden}),$$ +# +# and obtain a matrix that holds the weighted sum of inputs to the hidden layer +# for each input image and each hidden neuron. +# We also add the bias to obtain a matrix of weighted sums to the hidden layer $Z^{h}$: +# +# $$ \boldsymbol{z}^{l} = \boldsymbol{X} \boldsymbol{W}^{l} + \boldsymbol{b}^{l} ,$$ +# +# meaning the same bias (1D array with size equal number of hidden neurons) is added to each input image. +# This is then passed through the activation: +# +# $$ \boldsymbol{a}^{l} = f(\boldsymbol{z}^l) .$$ +# +# This is fed to the output layer: +# +# $$ \boldsymbol{z}^{L} = \boldsymbol{a}^{L} \boldsymbol{W}^{L} + \boldsymbol{b}^{L} .$$ +# +# Finally we receive our output values for each image and each category by passing it through the softmax function: +# +# $$ output = softmax (\boldsymbol{z}^{L}) = (n_{inputs}, n_{categories}) .$$ + +# In[6]: + + +# setup the feed-forward pass, subscript h = hidden layer + +def sigmoid(x): + return 1/(1 + np.exp(-x)) + +def feed_forward(X): + # weighted sum of inputs to the hidden layer + z_h = np.matmul(X, hidden_weights) + hidden_bias + # activation in the hidden layer + a_h = sigmoid(z_h) + + # weighted sum of inputs to the output layer + z_o = np.matmul(a_h, output_weights) + output_bias + # softmax output + # axis 0 holds each input and axis 1 the probabilities of each category + exp_term = np.exp(z_o) + probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True) + + return probabilities + +probabilities = feed_forward(X_train) +print("probabilities = (n_inputs, n_categories) = " + str(probabilities.shape)) +print("probability that image 0 is in category 0,1,2,...,9 = \n" + str(probabilities[0])) +print("probabilities sum up to: " + str(probabilities[0].sum())) +print() + +# we obtain a prediction by taking the class with the highest likelihood +def predict(X): + probabilities = feed_forward(X) + return np.argmax(probabilities, axis=1) + +predictions = predict(X_train) +print("predictions = (n_inputs) = " + str(predictions.shape)) +print("prediction for image 0: " + str(predictions[0])) +print("correct label for image 0: " + str(Y_train[0])) + + +# ## Choose cost function and optimizer +# +# To measure how well our neural network is doing we need to introduce a cost function. +# We will call the function that gives the error of a single sample output the *loss* function, and the function +# that gives the total error of our network across all samples the *cost* function. +# A typical choice for multiclass classification is the *cross-entropy* loss, also known as the negative log likelihood. +# +# In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: +# +# $$ y = 5 \quad \rightarrow \quad \boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$$ +# +# $$ y = 1 \quad \rightarrow \quad \boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$$ +# +# i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset. +# +# Let $y_{ic}$ denote the $c$-th component of the $i$-th one-hot vector. +# We define the cost function $\mathcal{C}$ as a sum over the cross-entropy loss for each point $\boldsymbol{x}_i$ in the dataset. +# +# In the one-hot representation only one of the terms in the loss function is non-zero, namely the +# probability of the correct category $c'$ +# (i.e. the category $c'$ such that $y_{ic'} = 1$). This means that the cross entropy loss only punishes you for how wrong +# you got the correct label. The probability of category $c$ is given by the softmax function. The vector $\boldsymbol{\theta}$ represents the parameters of our network, i.e. all the weights and biases. + +# ## Optimizing the cost function +# +# The network is trained by finding the weights and biases that minimize the cost function. One of the most widely used classes of methods is *gradient descent* and its generalizations. The idea behind gradient descent +# is simply to adjust the weights in the direction where the gradient of the cost function is large and negative. This ensures we flow toward a *local* minimum of the cost function. +# Each parameter $\theta$ is iteratively adjusted according to the rule +# +# $$ \theta_{i+1} = \theta_i - \eta \nabla \mathcal{C}(\theta_i) ,$$ +# +# where $\eta$ is known as the *learning rate*, which controls how big a step we take towards the minimum. +# This update can be repeated for any number of iterations, or until we are satisfied with the result. +# +# A simple and effective improvement is a variant called *Batch Gradient Descent*. +# Instead of calculating the gradient on the whole dataset, we calculate an approximation of the gradient +# on a subset of the data called a *minibatch*. +# If there are $N$ data points and we have a minibatch size of $M$, the total number of batches +# is $N/M$. +# We denote each minibatch $B_k$, with $k = 1, 2,...,N/M$. The gradient then becomes: +# +# $$ \nabla \mathcal{C}(\theta) = \frac{1}{N} \sum_{i=1}^N \nabla \mathcal{L}_i(\theta) \quad \rightarrow \quad +# \frac{1}{M} \sum_{i \in B_k} \nabla \mathcal{L}_i(\theta) ,$$ +# +# i.e. instead of averaging the loss over the entire dataset, we average over a minibatch. +# +# This has two important benefits: +# 1. Introducing stochasticity decreases the chance that the algorithm becomes stuck in a local minima. +# +# 2. It significantly speeds up the calculation, since we do not have to use the entire dataset to calculate the gradient. +# +# The various optmization methods, with codes and algorithms, are discussed in our lectures on [Gradient descent approaches](https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html). + +# ## Regularization +# +# It is common to add an extra term to the cost function, proportional +# to the size of the weights. This is equivalent to constraining the +# size of the weights, so that they do not grow out of control. +# Constraining the size of the weights means that the weights cannot +# grow arbitrarily large to fit the training data, and in this way +# reduces *overfitting*. +# +# We will measure the size of the weights using the so called *L2-norm*, meaning our cost function becomes: +# +# $$ \mathcal{C}(\theta) = \frac{1}{N} \sum_{i=1}^N \mathcal{L}_i(\theta) \quad \rightarrow \quad +# \frac{1}{N} \sum_{i=1}^N \mathcal{L}_i(\theta) + \lambda \lvert \lvert \boldsymbol{w} \rvert \rvert_2^2 +# = \frac{1}{N} \sum_{i=1}^N \mathcal{L}(\theta) + \lambda \sum_{ij} w_{ij}^2,$$ +# +# i.e. we sum up all the weights squared. The factor $\lambda$ is known as a regularization parameter. +# +# In order to train the model, we need to calculate the derivative of +# the cost function with respect to every bias and weight in the +# network. In total our network has $(64 + 1)\times 50=3250$ weights in +# the hidden layer and $(50 + 1)\times 10=510$ weights to the output +# layer ($+1$ for the bias), and the gradient must be calculated for +# every parameter. We use the *backpropagation* algorithm discussed +# above. This is a clever use of the chain rule that allows us to +# calculate the gradient efficently. + +# ## Matrix multiplication +# +# To more efficently train our network these equations are implemented using matrix operations. +# The error in the output layer is calculated simply as, with $\boldsymbol{t}$ being our targets, +# +# $$ \delta_L = \boldsymbol{t} - \boldsymbol{y} = (n_{inputs}, n_{categories}) .$$ +# +# The gradient for the output weights is calculated as +# +# $$ \nabla W_{L} = \boldsymbol{a}^T \delta_L = (n_{hidden}, n_{categories}) ,$$ +# +# where $\boldsymbol{a} = (n_{inputs}, n_{hidden})$. This simply means that we are summing up the gradients for each input. +# Since we are going backwards we have to transpose the activation matrix. +# +# The gradient with respect to the output bias is then +# +# $$ \nabla \boldsymbol{b}_{L} = \sum_{i=1}^{n_{inputs}} \delta_L = (n_{categories}) .$$ +# +# The error in the hidden layer is +# +# $$ \Delta_h = \delta_L W_{L}^T \circ f'(z_{h}) = \delta_L W_{L}^T \circ a_{h} \circ (1 - a_{h}) = (n_{inputs}, n_{hidden}) ,$$ +# +# where $f'(a_{h})$ is the derivative of the activation in the hidden layer. The matrix products mean +# that we are summing up the products for each neuron in the output layer. The symbol $\circ$ denotes +# the *Hadamard product*, meaning element-wise multiplication. +# +# This again gives us the gradients in the hidden layer: +# +# $$ \nabla W_{h} = X^T \delta_h = (n_{features}, n_{hidden}) ,$$ +# +# $$ \nabla b_{h} = \sum_{i=1}^{n_{inputs}} \delta_h = (n_{hidden}) .$$ + +# In[7]: + + +# to categorical turns our integer vector into a onehot representation +from sklearn.metrics import accuracy_score + +# one-hot in numpy +def to_categorical_numpy(integer_vector): + n_inputs = len(integer_vector) + n_categories = np.max(integer_vector) + 1 + onehot_vector = np.zeros((n_inputs, n_categories)) + onehot_vector[range(n_inputs), integer_vector] = 1 + + return onehot_vector + +#Y_train_onehot, Y_test_onehot = to_categorical(Y_train), to_categorical(Y_test) +Y_train_onehot, Y_test_onehot = to_categorical_numpy(Y_train), to_categorical_numpy(Y_test) + +def feed_forward_train(X): + # weighted sum of inputs to the hidden layer + z_h = np.matmul(X, hidden_weights) + hidden_bias + # activation in the hidden layer + a_h = sigmoid(z_h) + + # weighted sum of inputs to the output layer + z_o = np.matmul(a_h, output_weights) + output_bias + # softmax output + # axis 0 holds each input and axis 1 the probabilities of each category + exp_term = np.exp(z_o) + probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True) + + # for backpropagation need activations in hidden and output layers + return a_h, probabilities + +def backpropagation(X, Y): + a_h, probabilities = feed_forward_train(X) + + # error in the output layer + error_output = probabilities - Y + # error in the hidden layer + error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h) + + # gradients for the output layer + output_weights_gradient = np.matmul(a_h.T, error_output) + output_bias_gradient = np.sum(error_output, axis=0) + + # gradient for the hidden layer + hidden_weights_gradient = np.matmul(X.T, error_hidden) + hidden_bias_gradient = np.sum(error_hidden, axis=0) + + return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient + +print("Old accuracy on training data: " + str(accuracy_score(predict(X_train), Y_train))) + +eta = 0.01 +lmbd = 0.01 +for i in range(1000): + # calculate gradients + dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot) + + # regularization term gradients + dWo += lmbd * output_weights + dWh += lmbd * hidden_weights + + # update weights and biases + output_weights -= eta * dWo + output_bias -= eta * dBo + hidden_weights -= eta * dWh + hidden_bias -= eta * dBh + +print("New accuracy on training data: " + str(accuracy_score(predict(X_train), Y_train))) + + +# ## Improving performance +# +# As we can see the network does not seem to be learning at all. It seems to be just guessing the label for each image. +# In order to obtain a network that does something useful, we will have to do a bit more work. +# +# The choice of *hyperparameters* such as learning rate and regularization parameter is hugely influential for the performance of the network. Typically a *grid-search* is performed, wherein we test different hyperparameters separated by orders of magnitude. For example we could test the learning rates $\eta = 10^{-6}, 10^{-5},...,10^{-1}$ with different regularization parameters $\lambda = 10^{-6},...,10^{-0}$. +# +# Next, we haven't implemented minibatching yet, which introduces stochasticity and is though to act as an important regularizer on the weights. We call a feed-forward + backward pass with a minibatch an *iteration*, and a full training period +# going through the entire dataset ($n/M$ batches) an *epoch*. +# +# If this does not improve network performance, you may want to consider altering the network architecture, adding more neurons or hidden layers. +# Andrew Ng goes through some of these considerations in this [video](https://youtu.be/F1ka6a13S9I). You can find a summary of the video [here](https://kevinzakka.github.io/2016/09/26/applying-deep-learning/). + +# ## Full object-oriented implementation +# +# It is very natural to think of the network as an object, with specific instances of the network +# being realizations of this object with different hyperparameters. An implementation using Python classes provides a clean structure and interface, and the full implementation of our neural network is given below. + +# In[8]: + + +class NeuralNetwork: + def __init__( + self, + X_data, + Y_data, + n_hidden_neurons=50, + n_categories=10, + epochs=10, + batch_size=100, + eta=0.1, + lmbd=0.0): + + self.X_data_full = X_data + self.Y_data_full = Y_data + + self.n_inputs = X_data.shape[0] + self.n_features = X_data.shape[1] + self.n_hidden_neurons = n_hidden_neurons + self.n_categories = n_categories + + self.epochs = epochs + self.batch_size = batch_size + self.iterations = self.n_inputs // self.batch_size + self.eta = eta + self.lmbd = lmbd + + self.create_biases_and_weights() + + def create_biases_and_weights(self): + self.hidden_weights = np.random.randn(self.n_features, self.n_hidden_neurons) + self.hidden_bias = np.zeros(self.n_hidden_neurons) + 0.01 + + self.output_weights = np.random.randn(self.n_hidden_neurons, self.n_categories) + self.output_bias = np.zeros(self.n_categories) + 0.01 + + def feed_forward(self): + # feed-forward for training + self.z_h = np.matmul(self.X_data, self.hidden_weights) + self.hidden_bias + self.a_h = sigmoid(self.z_h) + + self.z_o = np.matmul(self.a_h, self.output_weights) + self.output_bias + + exp_term = np.exp(self.z_o) + self.probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True) + + def feed_forward_out(self, X): + # feed-forward for output + z_h = np.matmul(X, self.hidden_weights) + self.hidden_bias + a_h = sigmoid(z_h) + + z_o = np.matmul(a_h, self.output_weights) + self.output_bias + + exp_term = np.exp(z_o) + probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True) + return probabilities + + def backpropagation(self): + error_output = self.probabilities - self.Y_data + error_hidden = np.matmul(error_output, self.output_weights.T) * self.a_h * (1 - self.a_h) + + self.output_weights_gradient = np.matmul(self.a_h.T, error_output) + self.output_bias_gradient = np.sum(error_output, axis=0) + + self.hidden_weights_gradient = np.matmul(self.X_data.T, error_hidden) + self.hidden_bias_gradient = np.sum(error_hidden, axis=0) + + if self.lmbd > 0.0: + self.output_weights_gradient += self.lmbd * self.output_weights + self.hidden_weights_gradient += self.lmbd * self.hidden_weights + + self.output_weights -= self.eta * self.output_weights_gradient + self.output_bias -= self.eta * self.output_bias_gradient + self.hidden_weights -= self.eta * self.hidden_weights_gradient + self.hidden_bias -= self.eta * self.hidden_bias_gradient + + def predict(self, X): + probabilities = self.feed_forward_out(X) + return np.argmax(probabilities, axis=1) + + def predict_probabilities(self, X): + probabilities = self.feed_forward_out(X) + return probabilities + + def train(self): + data_indices = np.arange(self.n_inputs) + + for i in range(self.epochs): + for j in range(self.iterations): + # pick datapoints with replacement + chosen_datapoints = np.random.choice( + data_indices, size=self.batch_size, replace=False + ) + + # minibatch training data + self.X_data = self.X_data_full[chosen_datapoints] + self.Y_data = self.Y_data_full[chosen_datapoints] + + self.feed_forward() + self.backpropagation() + + +# ## Evaluate model performance on test data +# +# To measure the performance of our network we evaluate how well it does it data it has never seen before, i.e. the test data. +# We measure the performance of the network using the *accuracy* score. +# The accuracy is as you would expect just the number of images correctly labeled divided by the total number of images. A perfect classifier will have an accuracy score of $1$. +# +# $$ \text{Accuracy} = \frac{\sum_{i=1}^n I(\tilde{y}_i = y_i)}{n} ,$$ +# +# where $I$ is the indicator function, $1$ if $\tilde{y}_i = y_i$ and $0$ otherwise. + +# In[9]: + + +epochs = 100 +batch_size = 100 + +dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size, + n_hidden_neurons=n_hidden_neurons, n_categories=n_categories) +dnn.train() +test_predict = dnn.predict(X_test) + +# accuracy score from scikit library +print("Accuracy score on test set: ", accuracy_score(Y_test, test_predict)) + +# equivalent in numpy +def accuracy_score_numpy(Y_test, Y_pred): + return np.sum(Y_test == Y_pred) / len(Y_test) + +#print("Accuracy score on test set: ", accuracy_score_numpy(Y_test, test_predict)) + + +# ## Adjust hyperparameters +# +# We now perform a grid search to find the optimal hyperparameters for the network. +# Note that we are only using 1 layer with 50 neurons, and human performance is estimated to be around $98\%$ ($2\%$ error rate). + +# In[10]: + + +eta_vals = np.logspace(-5, 1, 7) +lmbd_vals = np.logspace(-5, 1, 7) +# store the models for later use +DNN_numpy = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object) + +# grid search +for i, eta in enumerate(eta_vals): + for j, lmbd in enumerate(lmbd_vals): + dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size, + n_hidden_neurons=n_hidden_neurons, n_categories=n_categories) + dnn.train() + + DNN_numpy[i][j] = dnn + + test_predict = dnn.predict(X_test) + + print("Learning rate = ", eta) + print("Lambda = ", lmbd) + print("Accuracy score on test set: ", accuracy_score(Y_test, test_predict)) + print() + + +# ## Visualization + +# In[11]: + + +# visual representation of grid search +# uses seaborn heatmap, you can also do this with matplotlib imshow +import seaborn as sns + +sns.set() + +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) + +for i in range(len(eta_vals)): + for j in range(len(lmbd_vals)): + dnn = DNN_numpy[i][j] + + train_pred = dnn.predict(X_train) + test_pred = dnn.predict(X_test) + + train_accuracy[i][j] = accuracy_score(Y_train, train_pred) + test_accuracy[i][j] = accuracy_score(Y_test, test_pred) + + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Training Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Test Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + + +# ## scikit-learn implementation +# +# **scikit-learn** focuses more +# on traditional machine learning methods, such as regression, +# clustering, decision trees, etc. As such, it has only two types of +# neural networks: Multi Layer Perceptron outputting continuous values, +# *MPLRegressor*, and Multi Layer Perceptron outputting labels, +# *MLPClassifier*. We will see how simple it is to use these classes. +# +# **scikit-learn** implements a few improvements from our neural network, +# such as early stopping, a varying learning rate, different +# optimization methods, etc. We would therefore expect a better +# performance overall. + +# In[12]: + + +from sklearn.neural_network import MLPClassifier +# store models for later use +DNN_scikit = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object) + +for i, eta in enumerate(eta_vals): + for j, lmbd in enumerate(lmbd_vals): + dnn = MLPClassifier(hidden_layer_sizes=(n_hidden_neurons), activation='logistic', + alpha=lmbd, learning_rate_init=eta, max_iter=epochs) + dnn.fit(X_train, Y_train) + + DNN_scikit[i][j] = dnn + + print("Learning rate = ", eta) + print("Lambda = ", lmbd) + print("Accuracy score on test set: ", dnn.score(X_test, Y_test)) + print() + + +# ## Visualization + +# In[13]: + + +# optional +# visual representation of grid search +# uses seaborn heatmap, could probably do this in matplotlib +import seaborn as sns + +sns.set() + +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) + +for i in range(len(eta_vals)): + for j in range(len(lmbd_vals)): + dnn = DNN_scikit[i][j] + + train_pred = dnn.predict(X_train) + test_pred = dnn.predict(X_test) + + train_accuracy[i][j] = accuracy_score(Y_train, train_pred) + test_accuracy[i][j] = accuracy_score(Y_test, test_pred) + + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Training Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Test Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + + +# ## Building neural networks in Tensorflow and Keras +# +# Now we want to build on the experience gained from our neural network implementation in NumPy and scikit-learn +# and use it to construct a neural network in Tensorflow. Once we have constructed a neural network in NumPy +# and Tensorflow, building one in Keras is really quite trivial, though the performance may suffer. +# +# In our previous example we used only one hidden layer, and in this we will use two. From this it should be quite +# clear how to build one using an arbitrary number of hidden layers, using data structures such as Python lists or +# NumPy arrays. + +# ## Tensorflow +# +# Tensorflow is an open source library machine learning library +# developed by the Google Brain team for internal use. It was released +# under the Apache 2.0 open source license in November 9, 2015. +# +# Tensorflow is a computational framework that allows you to construct +# machine learning models at different levels of abstraction, from +# high-level, object-oriented APIs like Keras, down to the C++ kernels +# that Tensorflow is built upon. The higher levels of abstraction are +# simpler to use, but less flexible, and our choice of implementation +# should reflect the problems we are trying to solve. +# +# [Tensorflow uses](https://www.tensorflow.org/guide/graphs) so-called graphs to represent your computation +# in terms of the dependencies between individual operations, such that you first build a Tensorflow *graph* +# to represent your model, and then create a Tensorflow *session* to run the graph. +# +# In this guide we will analyze the same data as we did in our NumPy and +# scikit-learn tutorial, gathered from the MNIST database of images. We +# will give an introduction to the lower level Python Application +# Program Interfaces (APIs), and see how we use them to build our graph. +# Then we will build (effectively) the same graph in Keras, to see just +# how simple solving a machine learning problem can be. +# +# To install tensorflow on Unix/Linux systems, use pip as + +# In[14]: + + +pip3 install tensorflow + + +# and/or if you use **anaconda**, just write (or install from the graphical user interface) +# (current release of CPU-only TensorFlow) + +# In[15]: + + +conda create -n tf tensorflow +conda activate tf + + +# To install the current release of GPU TensorFlow + +# In[16]: + + +conda create -n tf-gpu tensorflow-gpu +conda activate tf-gpu + + +# ## Using Keras +# +# Keras is a high level [neural network](https://en.wikipedia.org/wiki/Application_programming_interface) +# that supports Tensorflow, CTNK and Theano as backends. +# If you have Anaconda installed you may run the following command + +# In[17]: + + +conda install keras + + +# You can look up the [instructions here](https://keras.io/) for more information. +# +# We will to a large extent use **keras** in this course. + +# ## Collect and pre-process data +# +# Let us look again at the MINST data set. + +# In[18]: + + +# import necessary packages +import numpy as np +import matplotlib.pyplot as plt +import tensorflow as tf +from sklearn import datasets + + +# ensure the same random numbers appear every time +np.random.seed(0) + +# display images in notebook +get_ipython().run_line_magic('matplotlib', 'inline') +plt.rcParams['figure.figsize'] = (12,12) + + +# download MNIST dataset +digits = datasets.load_digits() + +# define inputs and labels +inputs = digits.images +labels = digits.target + +print("inputs = (n_inputs, pixel_width, pixel_height) = " + str(inputs.shape)) +print("labels = (n_inputs) = " + str(labels.shape)) + + +# flatten the image +# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64 +n_inputs = len(inputs) +inputs = inputs.reshape(n_inputs, -1) +print("X = (n_inputs, n_features) = " + str(inputs.shape)) + + +# choose some random images to display +indices = np.arange(n_inputs) +random_indices = np.random.choice(indices, size=5) + +for i, image in enumerate(digits.images[random_indices]): + plt.subplot(1, 5, i+1) + plt.axis('off') + plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') + plt.title("Label: %d" % digits.target[random_indices[i]]) +plt.show() + + +# In[19]: + + +from tensorflow.keras.layers import Input +from tensorflow.keras.models import Sequential #This allows appending layers to existing models +from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer +from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop) +from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2) +from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function + +from sklearn.model_selection import train_test_split + +# one-hot representation of labels +labels = to_categorical(labels) + +# split into train and test data +train_size = 0.8 +test_size = 1 - train_size +X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size, + test_size=test_size) + + +# In[20]: + + +epochs = 100 +batch_size = 100 +n_neurons_layer1 = 100 +n_neurons_layer2 = 50 +n_categories = 10 +eta_vals = np.logspace(-5, 1, 7) +lmbd_vals = np.logspace(-5, 1, 7) +def create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, eta, lmbd): + model = Sequential() + model.add(Dense(n_neurons_layer1, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd))) + model.add(Dense(n_neurons_layer2, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd))) + model.add(Dense(n_categories, activation='softmax')) + + sgd = optimizers.SGD(lr=eta) + model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy']) + + return model + + +# In[21]: + + +DNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object) + +for i, eta in enumerate(eta_vals): + for j, lmbd in enumerate(lmbd_vals): + DNN = create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, + eta=eta, lmbd=lmbd) + DNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0) + scores = DNN.evaluate(X_test, Y_test) + + DNN_keras[i][j] = DNN + + print("Learning rate = ", eta) + print("Lambda = ", lmbd) + print("Test accuracy: %.3f" % scores[1]) + print() + + +# In[22]: + + +# optional +# visual representation of grid search +# uses seaborn heatmap, could probably do this in matplotlib +import seaborn as sns + +sns.set() + +train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) +test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) + +for i in range(len(eta_vals)): + for j in range(len(lmbd_vals)): + DNN = DNN_keras[i][j] + + train_accuracy[i][j] = DNN.evaluate(X_train, Y_train)[1] + test_accuracy[i][j] = DNN.evaluate(X_test, Y_test)[1] + + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Training Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + +fig, ax = plt.subplots(figsize = (10, 10)) +sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis") +ax.set_title("Test Accuracy") +ax.set_ylabel("$\eta$") +ax.set_xlabel("$\lambda$") +plt.show() + + +# ## The Breast Cancer Data, now with Keras + +# In[23]: + + +import tensorflow as tf +from tensorflow.keras.layers import Input +from tensorflow.keras.models import Sequential #This allows appending layers to existing models +from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer +from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop) +from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2) +from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function +import numpy as np +import matplotlib.pyplot as plt +import seaborn as sns +from sklearn.model_selection import train_test_split as splitter +from sklearn.datasets import load_breast_cancer +import pickle +import os + + +"""Load breast cancer dataset""" + +np.random.seed(0) #create same seed for random number every time + +cancer=load_breast_cancer() #Download breast cancer dataset + +inputs=cancer.data #Feature matrix of 569 rows (samples) and 30 columns (parameters) +outputs=cancer.target #Label array of 569 rows (0 for benign and 1 for malignant) +labels=cancer.feature_names[0:30] + +print('The content of the breast cancer dataset is:') #Print information about the datasets +print(labels) +print('-------------------------') +print("inputs = " + str(inputs.shape)) +print("outputs = " + str(outputs.shape)) +print("labels = "+ str(labels.shape)) + +x=inputs #Reassign the Feature and Label matrices to other variables +y=outputs + +#%% + +# Visualisation of dataset (for correlation analysis) + +plt.figure() +plt.scatter(x[:,0],x[:,2],s=40,c=y,cmap=plt.cm.Spectral) +plt.xlabel('Mean radius',fontweight='bold') +plt.ylabel('Mean perimeter',fontweight='bold') +plt.show() + +plt.figure() +plt.scatter(x[:,5],x[:,6],s=40,c=y, cmap=plt.cm.Spectral) +plt.xlabel('Mean compactness',fontweight='bold') +plt.ylabel('Mean concavity',fontweight='bold') +plt.show() + + +plt.figure() +plt.scatter(x[:,0],x[:,1],s=40,c=y,cmap=plt.cm.Spectral) +plt.xlabel('Mean radius',fontweight='bold') +plt.ylabel('Mean texture',fontweight='bold') +plt.show() + +plt.figure() +plt.scatter(x[:,2],x[:,1],s=40,c=y,cmap=plt.cm.Spectral) +plt.xlabel('Mean perimeter',fontweight='bold') +plt.ylabel('Mean compactness',fontweight='bold') +plt.show() + + +# Generate training and testing datasets + +#Select features relevant to classification (texture,perimeter,compactness and symmetery) +#and add to input matrix + +temp1=np.reshape(x[:,1],(len(x[:,1]),1)) +temp2=np.reshape(x[:,2],(len(x[:,2]),1)) +X=np.hstack((temp1,temp2)) +temp=np.reshape(x[:,5],(len(x[:,5]),1)) +X=np.hstack((X,temp)) +temp=np.reshape(x[:,8],(len(x[:,8]),1)) +X=np.hstack((X,temp)) + +X_train,X_test,y_train,y_test=splitter(X,y,test_size=0.1) #Split datasets into training and testing + +y_train=to_categorical(y_train) #Convert labels to categorical when using categorical cross entropy +y_test=to_categorical(y_test) + +del temp1,temp2,temp + +# %% + +# Define tunable parameters" + +eta=np.logspace(-3,-1,3) #Define vector of learning rates (parameter to SGD optimiser) +lamda=0.01 #Define hyperparameter +n_layers=2 #Define number of hidden layers in the model +n_neuron=np.logspace(0,3,4,dtype=int) #Define number of neurons per layer +epochs=100 #Number of reiterations over the input data +batch_size=100 #Number of samples per gradient update + +# %% + +"""Define function to return Deep Neural Network model""" + +def NN_model(inputsize,n_layers,n_neuron,eta,lamda): + model=Sequential() + for i in range(n_layers): #Run loop to add hidden layers to the model + if (i==0): #First layer requires input dimensions + model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda),input_dim=inputsize)) + else: #Subsequent layers are capable of automatic shape inferencing + model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda))) + model.add(Dense(2,activation='softmax')) #2 outputs - ordered and disordered (softmax for prob) + sgd=optimizers.SGD(lr=eta) + model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy']) + return model + + +Train_accuracy=np.zeros((len(n_neuron),len(eta))) #Define matrices to store accuracy scores as a function +Test_accuracy=np.zeros((len(n_neuron),len(eta))) #of learning rate and number of hidden neurons for + +for i in range(len(n_neuron)): #run loops over hidden neurons and learning rates to calculate + for j in range(len(eta)): #accuracy scores + DNN_model=NN_model(X_train.shape[1],n_layers,n_neuron[i],eta[j],lamda) + DNN_model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=1) + Train_accuracy[i,j]=DNN_model.evaluate(X_train,y_train)[1] + Test_accuracy[i,j]=DNN_model.evaluate(X_test,y_test)[1] + + +def plot_data(x,y,data,title=None): + + # plot results + fontsize=16 + + + fig = plt.figure() + ax = fig.add_subplot(111) + cax = ax.matshow(data, interpolation='nearest', vmin=0, vmax=1) + + cbar=fig.colorbar(cax) + cbar.ax.set_ylabel('accuracy (%)',rotation=90,fontsize=fontsize) + cbar.set_ticks([0,.2,.4,0.6,0.8,1.0]) + cbar.set_ticklabels(['0%','20%','40%','60%','80%','100%']) + + # put text on matrix elements + for i, x_val in enumerate(np.arange(len(x))): + for j, y_val in enumerate(np.arange(len(y))): + c = "${0:.1f}\\%$".format( 100*data[j,i]) + ax.text(x_val, y_val, c, va='center', ha='center') + + # convert axis vaues to to string labels + x=[str(i) for i in x] + y=[str(i) for i in y] + + + ax.set_xticklabels(['']+x) + ax.set_yticklabels(['']+y) + + ax.set_xlabel('$\\mathrm{learning\\ rate}$',fontsize=fontsize) + ax.set_ylabel('$\\mathrm{hidden\\ neurons}$',fontsize=fontsize) + if title is not None: + ax.set_title(title) + + plt.tight_layout() + + plt.show() + +plot_data(eta,n_neuron,Train_accuracy, 'training') +plot_data(eta,n_neuron,Test_accuracy, 'testing') + + +# ## Building a neural network code +# +# Here we present a flexible object oriented codebase +# for a feed forward neural network, along with a demonstration of how +# to use it. Before we get into the details of the neural network, we +# will first present some implementations of various schedulers, cost +# functions and activation functions that can be used together with the +# neural network. +# +# The codes here were developed by Eric Reber and Gregor Kajda during spring 2023. + +# ### Learning rate methods +# +# The code below shows object oriented implementations of the Constant, +# Momentum, Adagrad, AdagradMomentum, RMS prop and Adam schedulers. All +# of the classes belong to the shared abstract Scheduler class, and +# share the update_change() and reset() methods allowing for any of the +# schedulers to be seamlessly used during the training stage, as will +# later be shown in the fit() method of the neural +# network. Update_change() only has one parameter, the gradient +# ($δ^l_ja^{l−1}_k$), and returns the change which will be subtracted +# from the weights. The reset() function takes no parameters, and resets +# the desired variables. For Constant and Momentum, reset does nothing. + +# In[24]: + + +import autograd.numpy as np + +class Scheduler: + """ + Abstract class for Schedulers + """ + + def __init__(self, eta): + self.eta = eta + + # should be overwritten + def update_change(self, gradient): + raise NotImplementedError + + # overwritten if needed + def reset(self): + pass + + +class Constant(Scheduler): + def __init__(self, eta): + super().__init__(eta) + + def update_change(self, gradient): + return self.eta * gradient + + def reset(self): + pass + + +class Momentum(Scheduler): + def __init__(self, eta: float, momentum: float): + super().__init__(eta) + self.momentum = momentum + self.change = 0 + + def update_change(self, gradient): + self.change = self.momentum * self.change + self.eta * gradient + return self.change + + def reset(self): + pass + + +class Adagrad(Scheduler): + def __init__(self, eta): + super().__init__(eta) + self.G_t = None + + def update_change(self, gradient): + delta = 1e-8 # avoid division ny zero + + if self.G_t is None: + self.G_t = np.zeros((gradient.shape[0], gradient.shape[0])) + + self.G_t += gradient @ gradient.T + + G_t_inverse = 1 / ( + delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1))) + ) + return self.eta * gradient * G_t_inverse + + def reset(self): + self.G_t = None + + +class AdagradMomentum(Scheduler): + def __init__(self, eta, momentum): + super().__init__(eta) + self.G_t = None + self.momentum = momentum + self.change = 0 + + def update_change(self, gradient): + delta = 1e-8 # avoid division ny zero + + if self.G_t is None: + self.G_t = np.zeros((gradient.shape[0], gradient.shape[0])) + + self.G_t += gradient @ gradient.T + + G_t_inverse = 1 / ( + delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1))) + ) + self.change = self.change * self.momentum + self.eta * gradient * G_t_inverse + return self.change + + def reset(self): + self.G_t = None + + +class RMS_prop(Scheduler): + def __init__(self, eta, rho): + super().__init__(eta) + self.rho = rho + self.second = 0.0 + + def update_change(self, gradient): + delta = 1e-8 # avoid division ny zero + self.second = self.rho * self.second + (1 - self.rho) * gradient * gradient + return self.eta * gradient / (np.sqrt(self.second + delta)) + + def reset(self): + self.second = 0.0 + + +class Adam(Scheduler): + def __init__(self, eta, rho, rho2): + super().__init__(eta) + self.rho = rho + self.rho2 = rho2 + self.moment = 0 + self.second = 0 + self.n_epochs = 1 + + def update_change(self, gradient): + delta = 1e-8 # avoid division ny zero + + self.moment = self.rho * self.moment + (1 - self.rho) * gradient + self.second = self.rho2 * self.second + (1 - self.rho2) * gradient * gradient + + moment_corrected = self.moment / (1 - self.rho**self.n_epochs) + second_corrected = self.second / (1 - self.rho2**self.n_epochs) + + return self.eta * moment_corrected / (np.sqrt(second_corrected + delta)) + + def reset(self): + self.n_epochs += 1 + self.moment = 0 + self.second = 0 + + +# ### Usage of the above learning rate schedulers +# +# To initalize a scheduler, simply create the object and pass in the +# necessary parameters such as the learning rate and the momentum as +# shown below. As the Scheduler class is an abstract class it should not +# called directly, and will raise an error upon usage. + +# In[25]: + + +momentum_scheduler = Momentum(eta=1e-3, momentum=0.9) +adam_scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999) + + +# Here is a small example for how a segment of code using schedulers +# could look. Switching out the schedulers is simple. + +# In[26]: + + +weights = np.ones((3,3)) +print(f"Before scheduler:\n{weights=}") + +epochs = 10 +for e in range(epochs): + gradient = np.random.rand(3, 3) + change = adam_scheduler.update_change(gradient) + weights = weights - change + adam_scheduler.reset() + +print(f"\nAfter scheduler:\n{weights=}") + + +# ### Cost functions +# +# Here we discuss cost functions that can be used when creating the +# neural network. Every cost function takes the target vector as its +# parameter, and returns a function valued only at $x$ such that it may +# easily be differentiated. + +# In[27]: + + +import autograd.numpy as np + +def CostOLS(target): + + def func(X): + return (1.0 / target.shape[0]) * np.sum((target - X) ** 2) + + return func + + +def CostLogReg(target): + + def func(X): + + return -(1.0 / target.shape[0]) * np.sum( + (target * np.log(X + 10e-10)) + ((1 - target) * np.log(1 - X + 10e-10)) + ) + + return func + + +def CostCrossEntropy(target): + + def func(X): + return -(1.0 / target.size) * np.sum(target * np.log(X + 10e-10)) + + return func + + +# Below we give a short example of how these cost function may be used +# to obtain results if you wish to test them out on your own using +# AutoGrad's automatics differentiation. + +# In[28]: + + +from autograd import grad + +target = np.array([[1, 2, 3]]).T +a = np.array([[4, 5, 6]]).T + +cost_func = CostCrossEntropy +cost_func_derivative = grad(cost_func(target)) + +valued_at_a = cost_func_derivative(a) +print(f"Derivative of cost function {cost_func.__name__} valued at a:\n{valued_at_a}") + + +# ### Activation functions +# +# Finally, before we look at the neural network, we will look at the +# activation functions which can be specified between the hidden layers +# and as the output function. Each function can be valued for any given +# vector or matrix X, and can be differentiated via derivate(). + +# In[29]: + + +import autograd.numpy as np +from autograd import elementwise_grad + +def identity(X): + return X + + +def sigmoid(X): + try: + return 1.0 / (1 + np.exp(-X)) + except FloatingPointError: + return np.where(X > np.zeros(X.shape), np.ones(X.shape), np.zeros(X.shape)) + + +def softmax(X): + X = X - np.max(X, axis=-1, keepdims=True) + delta = 10e-10 + return np.exp(X) / (np.sum(np.exp(X), axis=-1, keepdims=True) + delta) + + +def RELU(X): + return np.where(X > np.zeros(X.shape), X, np.zeros(X.shape)) + + +def LRELU(X): + delta = 10e-4 + return np.where(X > np.zeros(X.shape), X, delta * X) + + +def derivate(func): + if func.__name__ == "RELU": + + def func(X): + return np.where(X > 0, 1, 0) + + return func + + elif func.__name__ == "LRELU": + + def func(X): + delta = 10e-4 + return np.where(X > 0, 1, delta) + + return func + + else: + return elementwise_grad(func) + + +# Below follows a short demonstration of how to use an activation +# function. The derivative of the activation function will be important +# when calculating the output delta term during backpropagation. Note +# that derivate() can also be used for cost functions for a more +# generalized approach. + +# In[30]: + + +z = np.array([[4, 5, 6]]).T +print(f"Input to activation function:\n{z}") + +act_func = sigmoid +a = act_func(z) +print(f"\nOutput from {act_func.__name__} activation function:\n{a}") + +act_func_derivative = derivate(act_func) +valued_at_z = act_func_derivative(a) +print(f"\nDerivative of {act_func.__name__} activation function valued at z:\n{valued_at_z}") + + +# ### The Neural Network +# +# Now that we have gotten a good understanding of the implementation of +# some important components, we can take a look at an object oriented +# implementation of a feed forward neural network. The feed forward +# neural network has been implemented as a class named FFNN, which can +# be initiated as a regressor or classifier dependant on the choice of +# cost function. The FFNN can have any number of input nodes, hidden +# layers with any amount of hidden nodes, and any amount of output nodes +# meaning it can perform multiclass classification as well as binary +# classification and regression problems. Although there is a lot of +# code present, it makes for an easy to use and generalizeable interface +# for creating many types of neural networks as will be demonstrated +# below. + +# In[31]: + + +import math +import autograd.numpy as np +import sys +import warnings +from autograd import grad, elementwise_grad +from random import random, seed +from copy import deepcopy, copy +from typing import Tuple, Callable +from sklearn.utils import resample + +warnings.simplefilter("error") + + +class FFNN: + """ + Description: + ------------ + Feed Forward Neural Network with interface enabling flexible design of a + nerual networks architecture and the specification of activation function + in the hidden layers and output layer respectively. This model can be used + for both regression and classification problems, depending on the output function. + + Attributes: + ------------ + I dimensions (tuple[int]): A list of positive integers, which specifies the + number of nodes in each of the networks layers. The first integer in the array + defines the number of nodes in the input layer, the second integer defines number + of nodes in the first hidden layer and so on until the last number, which + specifies the number of nodes in the output layer. + II hidden_func (Callable): The activation function for the hidden layers + III output_func (Callable): The activation function for the output layer + IV cost_func (Callable): Our cost function + V seed (int): Sets random seed, makes results reproducible + """ + + def __init__( + self, + dimensions: tuple[int], + hidden_func: Callable = sigmoid, + output_func: Callable = lambda x: x, + cost_func: Callable = CostOLS, + seed: int = None, + ): + self.dimensions = dimensions + self.hidden_func = hidden_func + self.output_func = output_func + self.cost_func = cost_func + self.seed = seed + self.weights = list() + self.schedulers_weight = list() + self.schedulers_bias = list() + self.a_matrices = list() + self.z_matrices = list() + self.classification = None + + self.reset_weights() + self._set_classification() + + def fit( + self, + X: np.ndarray, + t: np.ndarray, + scheduler: Scheduler, + batches: int = 1, + epochs: int = 100, + lam: float = 0, + X_val: np.ndarray = None, + t_val: np.ndarray = None, + ): + """ + Description: + ------------ + This function performs the training the neural network by performing the feedforward and backpropagation + algorithm to update the networks weights. + + Parameters: + ------------ + I X (np.ndarray) : training data + II t (np.ndarray) : target data + III scheduler (Scheduler) : specified scheduler (algorithm for optimization of gradient descent) + IV scheduler_args (list[int]) : list of all arguments necessary for scheduler + + Optional Parameters: + ------------ + V batches (int) : number of batches the datasets are split into, default equal to 1 + VI epochs (int) : number of iterations used to train the network, default equal to 100 + VII lam (float) : regularization hyperparameter lambda + VIII X_val (np.ndarray) : validation set + IX t_val (np.ndarray) : validation target set + + Returns: + ------------ + I scores (dict) : A dictionary containing the performance metrics of the model. + The number of the metrics depends on the parameters passed to the fit-function. + + """ + + # setup + if self.seed is not None: + np.random.seed(self.seed) + + val_set = False + if X_val is not None and t_val is not None: + val_set = True + + # creating arrays for score metrics + train_errors = np.empty(epochs) + train_errors.fill(np.nan) + val_errors = np.empty(epochs) + val_errors.fill(np.nan) + + train_accs = np.empty(epochs) + train_accs.fill(np.nan) + val_accs = np.empty(epochs) + val_accs.fill(np.nan) + + self.schedulers_weight = list() + self.schedulers_bias = list() + + batch_size = X.shape[0] // batches + + X, t = resample(X, t) + + # this function returns a function valued only at X + cost_function_train = self.cost_func(t) + if val_set: + cost_function_val = self.cost_func(t_val) + + # create schedulers for each weight matrix + for i in range(len(self.weights)): + self.schedulers_weight.append(copy(scheduler)) + self.schedulers_bias.append(copy(scheduler)) + + print(f"{scheduler.__class__.__name__}: Eta={scheduler.eta}, Lambda={lam}") + + try: + for e in range(epochs): + for i in range(batches): + # allows for minibatch gradient descent + if i == batches - 1: + # If the for loop has reached the last batch, take all thats left + X_batch = X[i * batch_size :, :] + t_batch = t[i * batch_size :, :] + else: + X_batch = X[i * batch_size : (i + 1) * batch_size, :] + t_batch = t[i * batch_size : (i + 1) * batch_size, :] + + self._feedforward(X_batch) + self._backpropagate(X_batch, t_batch, lam) + + # reset schedulers for each epoch (some schedulers pass in this call) + for scheduler in self.schedulers_weight: + scheduler.reset() + + for scheduler in self.schedulers_bias: + scheduler.reset() + + # computing performance metrics + pred_train = self.predict(X) + train_error = cost_function_train(pred_train) + + train_errors[e] = train_error + if val_set: + + pred_val = self.predict(X_val) + val_error = cost_function_val(pred_val) + val_errors[e] = val_error + + if self.classification: + train_acc = self._accuracy(self.predict(X), t) + train_accs[e] = train_acc + if val_set: + val_acc = self._accuracy(pred_val, t_val) + val_accs[e] = val_acc + + # printing progress bar + progression = e / epochs + print_length = self._progress_bar( + progression, + train_error=train_errors[e], + train_acc=train_accs[e], + val_error=val_errors[e], + val_acc=val_accs[e], + ) + except KeyboardInterrupt: + # allows for stopping training at any point and seeing the result + pass + + # visualization of training progression (similiar to tensorflow progression bar) + sys.stdout.write("\r" + " " * print_length) + sys.stdout.flush() + self._progress_bar( + 1, + train_error=train_errors[e], + train_acc=train_accs[e], + val_error=val_errors[e], + val_acc=val_accs[e], + ) + sys.stdout.write("") + + # return performance metrics for the entire run + scores = dict() + + scores["train_errors"] = train_errors + + if val_set: + scores["val_errors"] = val_errors + + if self.classification: + scores["train_accs"] = train_accs + + if val_set: + scores["val_accs"] = val_accs + + return scores + + def predict(self, X: np.ndarray, *, threshold=0.5): + """ + Description: + ------------ + Performs prediction after training of the network has been finished. + + Parameters: + ------------ + I X (np.ndarray): The design matrix, with n rows of p features each + + Optional Parameters: + ------------ + II threshold (float) : sets minimal value for a prediction to be predicted as the positive class + in classification problems + + Returns: + ------------ + I z (np.ndarray): A prediction vector (row) for each row in our design matrix + This vector is thresholded if regression=False, meaning that classification results + in a vector of 1s and 0s, while regressions in an array of decimal numbers + + """ + + predict = self._feedforward(X) + + if self.classification: + return np.where(predict > threshold, 1, 0) + else: + return predict + + def reset_weights(self): + """ + Description: + ------------ + Resets/Reinitializes the weights in order to train the network for a new problem. + + """ + if self.seed is not None: + np.random.seed(self.seed) + + self.weights = list() + for i in range(len(self.dimensions) - 1): + weight_array = np.random.randn( + self.dimensions[i] + 1, self.dimensions[i + 1] + ) + weight_array[0, :] = np.random.randn(self.dimensions[i + 1]) * 0.01 + + self.weights.append(weight_array) + + def _feedforward(self, X: np.ndarray): + """ + Description: + ------------ + Calculates the activation of each layer starting at the input and ending at the output. + Each following activation is calculated from a weighted sum of each of the preceeding + activations (except in the case of the input layer). + + Parameters: + ------------ + I X (np.ndarray): The design matrix, with n rows of p features each + + Returns: + ------------ + I z (np.ndarray): A prediction vector (row) for each row in our design matrix + """ + + # reset matrices + self.a_matrices = list() + self.z_matrices = list() + + # if X is just a vector, make it into a matrix + if len(X.shape) == 1: + X = X.reshape((1, X.shape[0])) + + # Add a coloumn of zeros as the first coloumn of the design matrix, in order + # to add bias to our data + bias = np.ones((X.shape[0], 1)) * 0.01 + X = np.hstack([bias, X]) + + # a^0, the nodes in the input layer (one a^0 for each row in X - where the + # exponent indicates layer number). + a = X + self.a_matrices.append(a) + self.z_matrices.append(a) + + # The feed forward algorithm + for i in range(len(self.weights)): + if i < len(self.weights) - 1: + z = a @ self.weights[i] + self.z_matrices.append(z) + a = self.hidden_func(z) + # bias column again added to the data here + bias = np.ones((a.shape[0], 1)) * 0.01 + a = np.hstack([bias, a]) + self.a_matrices.append(a) + else: + try: + # a^L, the nodes in our output layers + z = a @ self.weights[i] + a = self.output_func(z) + self.a_matrices.append(a) + self.z_matrices.append(z) + except Exception as OverflowError: + print( + "OverflowError in fit() in FFNN\nHOW TO DEBUG ERROR: Consider lowering your learning rate or scheduler specific parameters such as momentum, or check if your input values need scaling" + ) + + # this will be a^L + return a + + def _backpropagate(self, X, t, lam): + """ + Description: + ------------ + Performs the backpropagation algorithm. In other words, this method + calculates the gradient of all the layers starting at the + output layer, and moving from right to left accumulates the gradient until + the input layer is reached. Each layers respective weights are updated while + the algorithm propagates backwards from the output layer (auto-differentation in reverse mode). + + Parameters: + ------------ + I X (np.ndarray): The design matrix, with n rows of p features each. + II t (np.ndarray): The target vector, with n rows of p targets. + III lam (float32): regularization parameter used to punish the weights in case of overfitting + + Returns: + ------------ + No return value. + + """ + out_derivative = derivate(self.output_func) + hidden_derivative = derivate(self.hidden_func) + + for i in range(len(self.weights) - 1, -1, -1): + # delta terms for output + if i == len(self.weights) - 1: + # for multi-class classification + if ( + self.output_func.__name__ == "softmax" + ): + delta_matrix = self.a_matrices[i + 1] - t + # for single class classification + else: + cost_func_derivative = grad(self.cost_func(t)) + delta_matrix = out_derivative( + self.z_matrices[i + 1] + ) * cost_func_derivative(self.a_matrices[i + 1]) + + # delta terms for hidden layer + else: + delta_matrix = ( + self.weights[i + 1][1:, :] @ delta_matrix.T + ).T * hidden_derivative(self.z_matrices[i + 1]) + + # calculate gradient + gradient_weights = self.a_matrices[i][:, 1:].T @ delta_matrix + gradient_bias = np.sum(delta_matrix, axis=0).reshape( + 1, delta_matrix.shape[1] + ) + + # regularization term + gradient_weights += self.weights[i][1:, :] * lam + + # use scheduler + update_matrix = np.vstack( + [ + self.schedulers_bias[i].update_change(gradient_bias), + self.schedulers_weight[i].update_change(gradient_weights), + ] + ) + + # update weights and bias + self.weights[i] -= update_matrix + + def _accuracy(self, prediction: np.ndarray, target: np.ndarray): + """ + Description: + ------------ + Calculates accuracy of given prediction to target + + Parameters: + ------------ + I prediction (np.ndarray): vector of predicitons output network + (1s and 0s in case of classification, and real numbers in case of regression) + II target (np.ndarray): vector of true values (What the network ideally should predict) + + Returns: + ------------ + A floating point number representing the percentage of correctly classified instances. + """ + assert prediction.size == target.size + return np.average((target == prediction)) + def _set_classification(self): + """ + Description: + ------------ + Decides if FFNN acts as classifier (True) og regressor (False), + sets self.classification during init() + """ + self.classification = False + if ( + self.cost_func.__name__ == "CostLogReg" + or self.cost_func.__name__ == "CostCrossEntropy" + ): + self.classification = True + + def _progress_bar(self, progression, **kwargs): + """ + Description: + ------------ + Displays progress of training + """ + print_length = 40 + num_equals = int(progression * print_length) + num_not = print_length - num_equals + arrow = ">" if num_equals > 0 else "" + bar = "[" + "=" * (num_equals - 1) + arrow + "-" * num_not + "]" + perc_print = self._format(progression * 100, decimals=5) + line = f" {bar} {perc_print}% " + + for key in kwargs: + if not np.isnan(kwargs[key]): + value = self._format(kwargs[key], decimals=4) + line += f"| {key}: {value} " + sys.stdout.write("\r" + line) + sys.stdout.flush() + return len(line) + + def _format(self, value, decimals=4): + """ + Description: + ------------ + Formats decimal numbers for progress bar + """ + if value > 0: + v = value + elif value < 0: + v = -10 * value + else: + v = 1 + n = 1 + math.floor(math.log10(v)) + if n >= decimals - 1: + return str(round(value)) + return f"{value:.{decimals-n-1}f}" + + +# Before we make a model, we will quickly generate a dataset we can use +# for our linear regression problem as shown below + +# In[32]: + + +import autograd.numpy as np +from sklearn.model_selection import train_test_split + +def SkrankeFunction(x, y): + return np.ravel(0 + 1*x + 2*y + 3*x**2 + 4*x*y + 5*y**2) + +def create_X(x, y, n): + if len(x.shape) > 1: + x = np.ravel(x) + y = np.ravel(y) + + N = len(x) + l = int((n + 1) * (n + 2) / 2) # Number of elements in beta + X = np.ones((N, l)) + + for i in range(1, n + 1): + q = int((i) * (i + 1) / 2) + for k in range(i + 1): + X[:, q + k] = (x ** (i - k)) * (y**k) + + return X + +step=0.5 +x = np.arange(0, 1, step) +y = np.arange(0, 1, step) +x, y = np.meshgrid(x, y) +target = SkrankeFunction(x, y) +target = target.reshape(target.shape[0], 1) + +poly_degree=3 +X = create_X(x, y, poly_degree) + +X_train, X_test, t_train, t_test = train_test_split(X, target) + + +# Now that we have our dataset ready for the regression, we can create +# our regressor. Note that with the seed parameter, we can make sure our +# results stay the same every time we run the neural network. For +# inititialization, we simply specify the dimensions (we wish the amount +# of input nodes to be equal to the datapoints, and the output to +# predict one value). + +# In[33]: + + +input_nodes = X_train.shape[1] +output_nodes = 1 + +linear_regression = FFNN((input_nodes, output_nodes), output_func=identity, cost_func=CostOLS, seed=2023) + + +# We then fit our model with our training data using the scheduler of our choice. + +# In[34]: + + +linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights + +scheduler = Constant(eta=1e-3) +scores = linear_regression.fit(X_train, t_train, scheduler) + + +# Due to the progress bar we can see the MSE (train_error) throughout +# the FFNN's training. Note that the fit() function has some optional +# parameters with defualt arguments. For example, the regularization +# hyperparameter can be left ignored if not needed, and equally the FFNN +# will by default run for 100 epochs. These can easily be changed, such +# as for example: + +# In[35]: + + +linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights + +scores = linear_regression.fit(X_train, t_train, scheduler, lam=1e-4, epochs=1000) + + +# We see that given more epochs to train on, the regressor reaches a lower MSE. +# +# Let us then switch to a binary classification. We use a binary +# classification dataset, and follow a similar setup to the regression +# case. + +# In[36]: + + +from sklearn.datasets import load_breast_cancer +from sklearn.preprocessing import MinMaxScaler + +wisconsin = load_breast_cancer() +X = wisconsin.data +target = wisconsin.target +target = target.reshape(target.shape[0], 1) + +X_train, X_val, t_train, t_val = train_test_split(X, target) + +scaler = MinMaxScaler() +scaler.fit(X_train) +X_train = scaler.transform(X_train) +X_val = scaler.transform(X_val) + + +# In[37]: + + +input_nodes = X_train.shape[1] +output_nodes = 1 + +logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023) + + +# We will now make use of our validation data by passing it into our fit function as a keyword argument + +# In[38]: + + +logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights + +scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999) +scores = logistic_regression.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val) + + +# Finally, we will create a neural network with 2 hidden layers with activation functions. + +# In[39]: + + +input_nodes = X_train.shape[1] +hidden_nodes1 = 100 +hidden_nodes2 = 30 +output_nodes = 1 + +dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes) + +neural_network = FFNN(dims, hidden_func=RELU, output_func=sigmoid, cost_func=CostLogReg, seed=2023) + + +# In[40]: + + +neural_network.reset_weights() # reset weights such that previous runs or reruns don't affect the weights + +scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999) +scores = neural_network.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val) + + +# ### Multiclass classification +# +# Finally, we will demonstrate the use case of multiclass classification +# using our FFNN with the famous MNIST dataset, which contain images of +# digits between the range of 0 to 9. + +# In[41]: + + +from sklearn.datasets import load_digits + +def onehot(target: np.ndarray): + onehot = np.zeros((target.size, target.max() + 1)) + onehot[np.arange(target.size), target] = 1 + return onehot + +digits = load_digits() + +X = digits.data +target = digits.target +target = onehot(target) + +input_nodes = 64 +hidden_nodes1 = 100 +hidden_nodes2 = 30 +output_nodes = 10 + +dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes) + +multiclass = FFNN(dims, hidden_func=LRELU, output_func=softmax, cost_func=CostCrossEntropy) + +multiclass.reset_weights() # reset weights such that previous runs or reruns don't affect the weights + +scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999) +scores = multiclass.fit(X, target, scheduler, epochs=1000) + + +# ## Testing the XOR gate and other gates +# +# Let us now use our code to test the XOR gate. + +# In[42]: + + +X = np.array([ [0, 0], [0, 1], [1, 0],[1, 1]],dtype=np.float64) + +# The XOR gate +yXOR = np.array( [[ 0], [1] ,[1], [0]]) + +input_nodes = X.shape[1] +output_nodes = 1 + +logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023) +logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights +scheduler = Adam(eta=1e-1, rho=0.9, rho2=0.999) +scores = logistic_regression.fit(X, yXOR, scheduler, epochs=1000) + + +# Not bad, but the results depend strongly on the learning reate. Try different learning rates. diff --git a/doc/LectureNotes/_build/jupyter_execute/week42_173_0.png b/doc/LectureNotes/_build/jupyter_execute/week42_173_0.png new file mode 100644 index 0000000000000000000000000000000000000000..492df86d67b1355f45ccca075bb5bd1b4dbe45c1 GIT binary patch literal 18573 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∓1w4JB3+UANTj2!EmqO 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

    h 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/jupyter_execute/week42_173_1.png b/doc/LectureNotes/_build/jupyter_execute/week42_173_1.png new file mode 100644 index 0000000000000000000000000000000000000000..90948aee69ae83d1e057e5881a2fcc25bb6cab2e GIT binary patch literal 14628 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 literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/jupyter_execute/week42_173_2.png b/doc/LectureNotes/_build/jupyter_execute/week42_173_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a76574b3ebd5077d9730bd5957b9bf7f4b1b518b GIT binary patch literal 31496 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 V2_H_Fz*K6KhKiPQfuhBe{{=V`u<8H+ literal 0 HcmV?d00001 diff --git a/doc/LectureNotes/_build/jupyter_execute/week42_173_3.png b/doc/LectureNotes/_build/jupyter_execute/week42_173_3.png new file mode 100644 index 0000000000000000000000000000000000000000..fc2c8902f26b17d512d53a6c2e8b355b39c41bdb GIT binary patch literal 17868 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\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "a8ac8249", + "metadata": { + "editable": true + }, + "source": [ + "# Week 42 Constructing a Neural Network code with examples\n", + "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and Facility for Rare Isotope Beams, Michigan State University\n", + "\n", + "Date: **October 14-18, 2024**" + ] + }, + { + "cell_type": "markdown", + "id": "c8760378", + "metadata": { + "editable": true + }, + "source": [ + "## Lecture October 14, 2024\n", + "1. Building our own Feed-forward Neural Network and discussion of project 2\n", + "\n", + "**Readings and videos.**\n", + "\n", + "1. These lecture notes\n", + "\n", + "\n", + "\n", + "2. For a more in depth discussion on neural networks we recommend Goodfellow et al chapters 6 and 7. \n", + "\n", + "3. Neural Networks demystified at \n", + "\n", + "4. Building Neural Networks from scratch at \n", + "\n", + "5. Video on Neural Networks at \n", + "\n", + "6. Video on the back propagation algorithm at \n", + "\n", + "I also recommend Michael Nielsen's intuitive approach to the neural networks and the universal approximation theorem, see the slides at ." + ] + }, + { + "cell_type": "markdown", + "id": "76c6895d", + "metadata": { + "editable": true + }, + "source": [ + "## Material for the active learning sessions on Tuesday and Wednesday\n", + " * Exercise on starting to write a code for neural networks, feed forward part. We will also continue ur discussions of gradient descent methods from last week. If you have time, start considering the back-propagation part as well (exercises for next week)\n", + "\n", + " * Discussion of project 2\n", + "\n", + " \n", + "\n", + "**Note**: some of the codes will also be discussed next week in connection with the solution of differential equations." + ] + }, + { + "cell_type": "markdown", + "id": "ebb39354", + "metadata": { + "editable": true + }, + "source": [ + "## Writing a code which implements a feed-forward neural network\n", + "\n", + "Last week we discussed the basics of neural networks and deep learning\n", + "and the basics of automatic differentiation. We looked also at\n", + "examples on how compute the parameters of a simple network with scalar\n", + "inputs and ouputs and no or just one hidden layers.\n", + "\n", + "We ended our discussions with the derivation of the equations for a\n", + "neural network with one hidden layers and two input variables and two\n", + "hidden nodes but only one output node." + ] + }, + { + "cell_type": "markdown", + "id": "cfb26b1b", + "metadata": { + "editable": true + }, + "source": [ + "## Mathematics of deep learning\n", + "\n", + "**Two recent books online.**\n", + "\n", + "1. [The Modern Mathematics of Deep Learning, by Julius Berner, Philipp Grohs, Gitta Kutyniok, Philipp Petersen](https://arxiv.org/abs/2105.04026), published as [Mathematical Aspects of Deep Learning, pp. 1-111. Cambridge University Press, 2022](https://doi.org/10.1017/9781009025096.002)\n", + "\n", + "2. [Mathematical Introduction to Deep Learning: Methods, Implementations, and Theory, Arnulf Jentzen, Benno Kuckuck, Philippe von Wurstemberger](https://doi.org/10.48550/arXiv.2310.20360)" + ] + }, + { + "cell_type": "markdown", + "id": "28f60678", + "metadata": { + "editable": true + }, + "source": [ + "## Reminder on books with hands-on material and codes\n", + "* [Sebastian Rashcka et al, Machine learning with Sickit-Learn and PyTorch](https://sebastianraschka.com/blog/2022/ml-pytorch-book.html)" + ] + }, + { + "cell_type": "markdown", + "id": "3c7f8f61", + "metadata": { + "editable": true + }, + "source": [ + "## Reading recommendations\n", + "\n", + "1. Rashkca et al., chapter 11, jupyter-notebook sent separately, from [GitHub](https://github.com/rasbt/machine-learning-book)\n", + "\n", + "2. Goodfellow et al, chapter 6 and 7 contain most of the neural network background." + ] + }, + { + "cell_type": "markdown", + "id": "9ee5faa5", + "metadata": { + "editable": true + }, + "source": [ + "## First network example, simple percepetron with one input\n", + "\n", + "As yet another example we define now a simple perceptron model with\n", + "all quantities given by scalars. We consider only one input variable\n", + "$x$ and one target value $y$. We define an activation function\n", + "$\\sigma_1$ which takes as input" + ] + }, + { + "cell_type": "markdown", + "id": "e82fbb01", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1x+b_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1b4862d", + "metadata": { + "editable": true + }, + "source": [ + "where $w_1$ is the weight and $b_1$ is the bias. These are the\n", + "parameters we want to optimize. The output is $a_1=\\sigma(z_1)$ (see\n", + "graph from whiteboard notes). This output is then fed into the\n", + "**cost/loss** function, which we here for the sake of simplicity just\n", + "define as the squared error" + ] + }, + { + "cell_type": "markdown", + "id": "f7b41bcb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;w_1,b_1)=\\frac{1}{2}(a_1-y)^2.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2825a689", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with no hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "1853d23c", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the parameters\n", + "\n", + "In setting up the feed forward and back propagation parts of the\n", + "algorithm, we need now the derivative of the various variables we want\n", + "to train.\n", + "\n", + "We need" + ] + }, + { + "cell_type": "markdown", + "id": "1625a8c3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1} \\hspace{0.1cm}\\mathrm{and}\\hspace{0.1cm}\\frac{\\partial C}{\\partial b_1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7427a24a", + "metadata": { + "editable": true + }, + "source": [ + "Using the chain rule we find" + ] + }, + { + "cell_type": "markdown", + "id": "d4911a64", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_1-y)\\sigma_1'x,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0f290988", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "4cbbad95", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_1-y)\\sigma_1',\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cc8122a6", + "metadata": { + "editable": true + }, + "source": [ + "which we later will just define as" + ] + }, + { + "cell_type": "markdown", + "id": "39f03825", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3eeb7a29", + "metadata": { + "editable": true + }, + "source": [ + "## Adding a hidden layer\n", + "\n", + "We change our simple model to (see graph)\n", + "a network with just one hidden layer but with scalar variables only.\n", + "\n", + "Our output variable changes to $a_2$ and $a_1$ is now the output from the hidden node and $a_0=x$.\n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "33e1d35f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_1 = w_1a_0+b_1 \\hspace{0.1cm} \\wedge a_1 = \\sigma_1(z_1),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e846a441", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_2 = w_2a_1+b_2 \\hspace{0.1cm} \\wedge a_2 = \\sigma_2(z_2),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fbb3f1ff", + "metadata": { + "editable": true + }, + "source": [ + "and the cost function" + ] + }, + { + "cell_type": "markdown", + "id": "40200643", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "C(x;\\boldsymbol{\\Theta})=\\frac{1}{2}(a_2-y)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a2e96689", + "metadata": { + "editable": true + }, + "source": [ + "with $\\boldsymbol{\\Theta}=[w_1,w_2,b_1,b_2]$." + ] + }, + { + "cell_type": "markdown", + "id": "1a014316", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with one hidden layer\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "06a0b720", + "metadata": { + "editable": true + }, + "source": [ + "## The derivatives\n", + "\n", + "The derivatives are now, using the chain rule again" + ] + }, + { + "cell_type": "markdown", + "id": "48581ce4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial w_2}=(a_2-y)\\sigma_2'a_1=\\delta_2a_1,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "58f46792", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_2}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial b_2}=(a_2-y)\\sigma_2'=\\delta_2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc5aa924", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial w_1}=(a_2-y)\\sigma_2'a_1\\sigma_1'a_0,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "407690af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_1}=\\frac{\\partial C}{\\partial a_2}\\frac{\\partial a_2}{\\partial z_2}\\frac{\\partial z_2}{\\partial a_1}\\frac{\\partial a_1}{\\partial z_1}\\frac{\\partial z_1}{\\partial b_1}=(a_2-y)\\sigma_2'\\sigma_1'=\\delta_1.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8f5cacad", + "metadata": { + "editable": true + }, + "source": [ + "Can you generalize this to more than one hidden layer?" + ] + }, + { + "cell_type": "markdown", + "id": "79f592c1", + "metadata": { + "editable": true + }, + "source": [ + "## Important observations\n", + "\n", + "From the above equations we see that the derivatives of the activation\n", + "functions play a central role. If they vanish, the training may\n", + "stop. This is called the vanishing gradient problem, see discussions below. If they become\n", + "large, the parameters $w_i$ and $b_i$ may simply go to infinity. This\n", + "is referenced as the exploding gradient problem." + ] + }, + { + "cell_type": "markdown", + "id": "412247f9", + "metadata": { + "editable": true + }, + "source": [ + "## The training\n", + "\n", + "The training of the parameters is done through various gradient descent approximations with" + ] + }, + { + "cell_type": "markdown", + "id": "83c09361", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}\\leftarrow w_{i}- \\eta \\delta_i a_{i-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d341a3c7", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2bb5b78f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_i \\leftarrow b_i-\\eta \\delta_i,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3d6558a8", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ is the learning rate.\n", + "\n", + "One iteration consists of one feed forward step and one back-propagation step. Each back-propagation step does one update of the parameters $\\boldsymbol{\\Theta}$.\n", + "\n", + "For the first hidden layer $a_{i-1}=a_0=x$ for this simple model." + ] + }, + { + "cell_type": "markdown", + "id": "f55c404e", + "metadata": { + "editable": true + }, + "source": [ + "## Code example\n", + "\n", + "The code here implements the above model with one hidden layer and\n", + "scalar variables for the same function we studied in the previous\n", + "example. The code is however set up so that we can add multiple\n", + "inputs $x$ and target values $y$. Note also that we have the\n", + "possibility of defining a feature matrix $\\boldsymbol{X}$ with more than just\n", + "one column for the input values. This will turn useful in our next example. We have also defined matrices and vectors for all of our operations although it is not necessary here." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "076950d8", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "# We use the Sigmoid function as activation function\n", + "def sigmoid(z):\n", + " return 1.0/(1.0+np.exp(-z))\n", + "\n", + "def forwardpropagation(x):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_1 = np.matmul(x, w_1) + b_1\n", + " # activation in the hidden layer\n", + " a_1 = sigmoid(z_1)\n", + " # weighted sum of inputs to the output layer\n", + " z_2 = np.matmul(a_1, w_2) + b_2\n", + " a_2 = z_2\n", + " return a_1, a_2\n", + "\n", + "def backpropagation(x, y):\n", + " a_1, a_2 = forwardpropagation(x)\n", + " # parameter delta for the output layer, note that a_2=z_2 and its derivative wrt z_2 is just 1\n", + " delta_2 = a_2 - y\n", + " print(0.5*((a_2-y)**2))\n", + " # delta for the hidden layer\n", + " delta_1 = np.matmul(delta_2, w_2.T) * a_1 * (1 - a_1)\n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_1.T, delta_2)\n", + " output_bias_gradient = np.sum(delta_2, axis=0)\n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(x.T, delta_1)\n", + " hidden_bias_gradient = np.sum(delta_1, axis=0)\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "# Input variable\n", + "x = np.array([4.0],dtype=np.float64)\n", + "# Target values\n", + "y = 2*x+1.0 \n", + "\n", + "# Defining the neural network, only scalars here\n", + "n_inputs = x.shape\n", + "n_features = 1\n", + "n_hidden_neurons = 1\n", + "n_outputs = 1\n", + "\n", + "# Initialize the network\n", + "# weights and bias in the hidden layer\n", + "w_1 = np.random.randn(n_features, n_hidden_neurons)\n", + "b_1 = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "w_2 = np.random.randn(n_hidden_neurons, n_outputs)\n", + "b_2 = np.zeros(n_outputs) + 0.01\n", + "\n", + "eta = 0.1\n", + "for i in range(50):\n", + " # calculate gradients\n", + " derivW2, derivB2, derivW1, derivB1 = backpropagation(x, y)\n", + " # update weights and biases\n", + " w_2 -= eta * derivW2\n", + " b_2 -= eta * derivB2\n", + " w_1 -= eta * derivW1\n", + " b_1 -= eta * derivB1" + ] + }, + { + "cell_type": "markdown", + "id": "b5a2150f", + "metadata": { + "editable": true + }, + "source": [ + "We see that after some few iterations (the results do depend on the learning rate however), we get an error which is rather small." + ] + }, + { + "cell_type": "markdown", + "id": "cb93f2d2", + "metadata": { + "editable": true + }, + "source": [ + "## Simple neural network and the back propagation equations\n", + "\n", + "Let us now try to increase our level of ambition and attempt at setting \n", + "up the equations for a neural network with two input nodes, one hidden\n", + "layer with two hidden nodes and one output layer with one output node/neuron only (see graph)..\n", + "\n", + "We need to define the following parameters and variables with the input layer (layer $(0)$) \n", + "where we label the nodes $x_0$ and $x_1$" + ] + }, + { + "cell_type": "markdown", + "id": "893b1b33", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "x_0 = a_0^{(0)} \\wedge x_1 = a_1^{(0)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1554902", + "metadata": { + "editable": true + }, + "source": [ + "The hidden layer (layer $(1)$) has nodes which yield the outputs $a_0^{(1)}$ and $a_1^{(1)}$) with weight $\\boldsymbol{w}$ and bias $\\boldsymbol{b}$ parameters" + ] + }, + { + "cell_type": "markdown", + "id": "e01cd011", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)}\\right\\} \\wedge b^{(1)}=\\left\\{b_0^{(1)},b_1^{(1)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "691e42c5", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a simple neural network with two input nodes, one hidden layer and one output node\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "57573a8a", + "metadata": { + "editable": true + }, + "source": [ + "## The ouput layer\n", + "\n", + "Finally, we have the ouput layer given by layer label $(2)$ with output $a^{(2)}$ and weights and biases to be determined given by the variables" + ] + }, + { + "cell_type": "markdown", + "id": "91ff8dfb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}=\\left\\{w_{0}^{(2)},w_{1}^{(2)}\\right\\} \\wedge b^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "315f787f", + "metadata": { + "editable": true + }, + "source": [ + "Our output is $\\tilde{y}=a^{(2)}$ and we define a generic cost function $C(a^{(2)},y;\\boldsymbol{\\Theta})$ where $y$ is the target value (a scalar here).\n", + "The parameters we need to optimize are given by" + ] + }, + { + "cell_type": "markdown", + "id": "612ebd67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\Theta}=\\left\\{w_{00}^{(1)},w_{01}^{(1)},w_{10}^{(1)},w_{11}^{(1)},w_{0}^{(2)},w_{1}^{(2)},b_0^{(1)},b_1^{(1)},b^{(2)}\\right\\}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c28762dc", + "metadata": { + "editable": true + }, + "source": [ + "## Compact expressions\n", + "\n", + "We can define the inputs to the activation functions for the various layers in terms of various matrix-vector multiplications and vector additions.\n", + "The inputs to the first hidden layer are" + ] + }, + { + "cell_type": "markdown", + "id": "b4d0309d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}z_0^{(1)} \\\\ z_1^{(1)} \\end{bmatrix}=\\left(\\begin{bmatrix}w_{00}^{(1)} & w_{01}^{(1)}\\\\ w_{10}^{(1)} &w_{11}^{(1)} \\end{bmatrix}\\right)^{T}\\begin{bmatrix}a_0^{(0)} \\\\ a_1^{(0)} \\end{bmatrix}+\\begin{bmatrix}b_0^{(1)} \\\\ b_1^{(1)} \\end{bmatrix},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f3c715f1", + "metadata": { + "editable": true + }, + "source": [ + "with outputs" + ] + }, + { + "cell_type": "markdown", + "id": "5db82289", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\begin{bmatrix}a_0^{(1)} \\\\ a_1^{(1)} \\end{bmatrix}=\\begin{bmatrix}\\sigma^{(1)}(z_0^{(1)}) \\\\ \\sigma^{(1)}(z_1^{(1)}) \\end{bmatrix}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6b2ad78", + "metadata": { + "editable": true + }, + "source": [ + "## Output layer\n", + "\n", + "For the final output layer we have the inputs to the final activation function" + ] + }, + { + "cell_type": "markdown", + "id": "dcefdba1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} = w_{0}^{(2)}a_0^{(1)} +w_{1}^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d554c6ce", + "metadata": { + "editable": true + }, + "source": [ + "resulting in the output" + ] + }, + { + "cell_type": "markdown", + "id": "651ff447", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a^{(2)}=\\sigma^{(2)}(z^{(2)}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f171ceaa", + "metadata": { + "editable": true + }, + "source": [ + "## Explicit derivatives\n", + "\n", + "In total we have nine parameters which we need to train. Using the\n", + "chain rule (or just the back-propagation algorithm) we can find all\n", + "derivatives. Since we will use automatic differentiation in reverse\n", + "mode, we start with the derivatives of the cost function with respect\n", + "to the parameters of the output layer, namely" + ] + }, + { + "cell_type": "markdown", + "id": "609bb2dd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{i}^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial w_{i}^{(2)}}=\\delta^{(2)}a_i^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "da1d696b", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "d21d62cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta^{(2)}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "fb9dd90f", + "metadata": { + "editable": true + }, + "source": [ + "and finally" + ] + }, + { + "cell_type": "markdown", + "id": "9026fb2d", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b^{(2)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\\frac{\\partial z^{(2)}}{\\partial b^{(2)}}=\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2d20d5d1", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives of the hidden layer\n", + "\n", + "Using the chain rule we have the following expressions for say one of the weight parameters (it is easy to generalize to the other weight parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "e6fbb9b5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\frac{\\partial C}{\\partial a^{(2)}}\\frac{\\partial a^{(2)}}{\\partial z^{(2)}}\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}= \\delta^{(2)}\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "781a7ac8", + "metadata": { + "editable": true + }, + "source": [ + "which, noting that" + ] + }, + { + "cell_type": "markdown", + "id": "3ee09d8f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z^{(2)} =w_0^{(2)}a_0^{(1)}+w_1^{(2)}a_1^{(1)}+b^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65f44692", + "metadata": { + "editable": true + }, + "source": [ + "allows us to rewrite" + ] + }, + { + "cell_type": "markdown", + "id": "0b84b7af", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z^{(2)}}{\\partial z_0^{(1)}}\\frac{\\partial z_0^{(1)}}{\\partial w_{00}^{(1)}}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c138bd", + "metadata": { + "editable": true + }, + "source": [ + "## Final expression\n", + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "3f81bb3f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_0^{(1)}=w_0^{(2)}\\frac{\\partial a_0^{(1)}}{\\partial z_0^{(1)}}\\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eb6783b2", + "metadata": { + "editable": true + }, + "source": [ + "we have" + ] + }, + { + "cell_type": "markdown", + "id": "1c754dbb", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{00}^{(1)}}=\\delta_0^{(1)}a_0^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e0b9760c", + "metadata": { + "editable": true + }, + "source": [ + "Similarly, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "b1efb446", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{01}^{(1)}}=\\delta_0^{(1)}a_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2cf7b43f", + "metadata": { + "editable": true + }, + "source": [ + "## Completing the list\n", + "\n", + "Similarly, we find" + ] + }, + { + "cell_type": "markdown", + "id": "262b517f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{10}^{(1)}}=\\delta_1^{(1)}a_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "59285e3f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2813790f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial w_{11}^{(1)}}=\\delta_1^{(1)}a_1^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a56b94b4", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined" + ] + }, + { + "cell_type": "markdown", + "id": "a3ed9010", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_1^{(1)}=w_1^{(2)}\\frac{\\partial a_1^{(1)}}{\\partial z_1^{(1)}}\\delta^{(2)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "03a5562c", + "metadata": { + "editable": true + }, + "source": [ + "## Final expressions for the biases of the hidden layer\n", + "\n", + "For the sake of completeness, we list the derivatives of the biases, which are" + ] + }, + { + "cell_type": "markdown", + "id": "025bd04f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{0}^{(1)}}=\\delta_0^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1ef6c2f", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "157d7580", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial C}{\\partial b_{1}^{(1)}}=\\delta_1^{(1)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "389a7e2d", + "metadata": { + "editable": true + }, + "source": [ + "As we will see below, these expressions can be generalized in a more compact form." + ] + }, + { + "cell_type": "markdown", + "id": "bccf9918", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient expressions\n", + "\n", + "For this specific model, with just one output node and two hidden\n", + "nodes, the gradient descent equations take the following form for output layer" + ] + }, + { + "cell_type": "markdown", + "id": "ab05945c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{i}^{(2)}\\leftarrow w_{i}^{(2)}- \\eta \\delta^{(2)} a_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "cb2ef195", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "da672f61", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b^{(2)} \\leftarrow b^{(2)}-\\eta \\delta^{(2)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "95dd3d2b", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "532b99a2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^{(1)}\\leftarrow w_{ij}^{(1)}- \\eta \\delta_{i}^{(1)} a_{j}^{(0)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5d5f45cc", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "2333cfb1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_{i}^{(1)} \\leftarrow b_{i}^{(1)}-\\eta \\delta_{i}^{(1)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4b555f81", + "metadata": { + "editable": true + }, + "source": [ + "where $\\eta$ is the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "20c0952f", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the equations for a neural network\n", + "\n", + "The questions we want to ask are how do changes in the biases and the\n", + "weights in our network change the cost function and how can we use the\n", + "final output to modify the weights and biases?\n", + "\n", + "To derive these equations let us start with a plain regression problem\n", + "and define our cost function as" + ] + }, + { + "cell_type": "markdown", + "id": "5a155f81", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ff1fc071", + "metadata": { + "editable": true + }, + "source": [ + "where the $y_i$s are our $n$ targets (the values we want to\n", + "reproduce), while the outputs of the network after having propagated\n", + "all inputs $\\boldsymbol{x}$ are given by $\\boldsymbol{\\tilde{y}}_i$." + ] + }, + { + "cell_type": "markdown", + "id": "63576478", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of a neural network with three hidden layers (last later = $l=L=4$, first layer $l=0$)\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "3410ad89", + "metadata": { + "editable": true + }, + "source": [ + "## Definitions\n", + "\n", + "With our definition of the targets $\\boldsymbol{y}$, the outputs of the\n", + "network $\\boldsymbol{\\tilde{y}}$ and the inputs $\\boldsymbol{x}$ we\n", + "define now the activation $z_j^l$ of node/neuron/unit $j$ of the\n", + "$l$-th layer as a function of the bias, the weights which add up from\n", + "the previous layer $l-1$ and the forward passes/outputs\n", + "$\\boldsymbol{a}^{l-1}$ from the previous layer as" + ] + }, + { + "cell_type": "markdown", + "id": "c71d887c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^l = \\sum_{i=1}^{M_{l-1}}w_{ij}^la_i^{l-1}+b_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "ffeae21c", + "metadata": { + "editable": true + }, + "source": [ + "where $b_k^l$ are the biases from layer $l$. Here $M_{l-1}$\n", + "represents the total number of nodes/neurons/units of layer $l-1$. The\n", + "figure in the whiteboard notes illustrates this equation. We can rewrite this in a more\n", + "compact form as the matrix-vector products we discussed earlier," + ] + }, + { + "cell_type": "markdown", + "id": "2fe917a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{z}^l = \\left(\\boldsymbol{W}^l\\right)^T\\boldsymbol{a}^{l-1}+\\boldsymbol{b}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "65404bec", + "metadata": { + "editable": true + }, + "source": [ + "## Inputs to the activation function\n", + "\n", + "With the activation values $\\boldsymbol{z}^l$ we can in turn define the\n", + "output of layer $l$ as $\\boldsymbol{a}^l = \\sigma(\\boldsymbol{z}^l)$ where $\\sigma$ is our\n", + "activation function. In the examples here we will use the sigmoid\n", + "function discussed in our logistic regression lectures. We will also use the same activation function $\\sigma$ for all layers\n", + "and their nodes. It means we have" + ] + }, + { + "cell_type": "markdown", + "id": "a6c0c8b6", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_j^l = \\sigma(z_j^l) = \\frac{1}{1+\\exp{-(z_j^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2454faec", + "metadata": { + "editable": true + }, + "source": [ + "## Layout of input to first hidden layer $l=1$ from input layer $l=0$\n", + "\n", + "\n", + "\n", + "\n", + "

    Figure 1:

    \n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "e5b67040", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives and the chain rule\n", + "\n", + "From the definition of the input variable to the activation function, that is $z_j^l$ we have" + ] + }, + { + "cell_type": "markdown", + "id": "aaec49a4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial w_{ij}^l} = a_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e8ad40d3", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "e04a4d28", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial z_j^l}{\\partial a_i^{l-1}} = w_{ji}^l.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9b121a33", + "metadata": { + "editable": true + }, + "source": [ + "With our definition of the activation function we have that (note that this function depends only on $z_j^l$)" + ] + }, + { + "cell_type": "markdown", + "id": "3bf7d884", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^l}{\\partial z_j^{l}} = a_j^l(1-a_j^l)=\\sigma(z_j^l)(1-\\sigma(z_j^l)).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7d58918c", + "metadata": { + "editable": true + }, + "source": [ + "## Derivative of the cost function\n", + "\n", + "With these definitions we can now compute the derivative of the cost function in terms of the weights.\n", + "\n", + "Let us specialize to the output layer $l=L$. Our cost function is" + ] + }, + { + "cell_type": "markdown", + "id": "d21dce97", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "{\\cal C}(\\boldsymbol{\\Theta}^L) = \\frac{1}{2}\\sum_{i=1}^n\\left(y_i - \\tilde{y}_i\\right)^2=\\frac{1}{2}\\sum_{i=1}^n\\left(a_i^L - y_i\\right)^2,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dc143bea", + "metadata": { + "editable": true + }, + "source": [ + "The derivative of this function with respect to the weights is" + ] + }, + { + "cell_type": "markdown", + "id": "49415a06", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4398e11e", + "metadata": { + "editable": true + }, + "source": [ + "The last partial derivative can easily be computed and reads (by applying the chain rule)" + ] + }, + { + "cell_type": "markdown", + "id": "da3fca7e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial a_j^L}{\\partial w_{ij}^{L}} = \\frac{\\partial a_j^L}{\\partial z_{j}^{L}}\\frac{\\partial z_j^L}{\\partial w_{ij}^{L}}=a_j^L(1-a_j^L)a_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9055bc57", + "metadata": { + "editable": true + }, + "source": [ + "## The back propagation equations for a neural network\n", + "\n", + "We have thus" + ] + }, + { + "cell_type": "markdown", + "id": "c7995e73", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}((\\boldsymbol{\\Theta}^L)}{\\partial w_{ij}^L} = \\left(a_j^L - y_j\\right)a_j^L(1-a_j^L)a_i^{L-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d142f966", + "metadata": { + "editable": true + }, + "source": [ + "Defining" + ] + }, + { + "cell_type": "markdown", + "id": "d5dc5f9f", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = a_j^L(1-a_j^L)\\left(a_j^L - y_j\\right) = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5f598e3e", + "metadata": { + "editable": true + }, + "source": [ + "and using the Hadamard product of two vectors we can write this as" + ] + }, + { + "cell_type": "markdown", + "id": "9769b50e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\boldsymbol{\\delta}^L = \\sigma'(\\boldsymbol{z}^L)\\circ\\frac{\\partial {\\cal C}}{\\partial (\\boldsymbol{a}^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "5a8851ae", + "metadata": { + "editable": true + }, + "source": [ + "## Analyzing the last results\n", + "\n", + "This is an important expression. The second term on the right handside\n", + "measures how fast the cost function is changing as a function of the $j$th\n", + "output activation. If, for example, the cost function doesn't depend\n", + "much on a particular output node $j$, then $\\delta_j^L$ will be small,\n", + "which is what we would expect. The first term on the right, measures\n", + "how fast the activation function $f$ is changing at a given activation\n", + "value $z_j^L$." + ] + }, + { + "cell_type": "markdown", + "id": "b455efff", + "metadata": { + "editable": true + }, + "source": [ + "## More considerations\n", + "\n", + "Notice that everything in the above equations is easily computed. In\n", + "particular, we compute $z_j^L$ while computing the behaviour of the\n", + "network, and it is only a small additional overhead to compute\n", + "$\\sigma'(z^L_j)$. The exact form of the derivative with respect to the\n", + "output depends on the form of the cost function.\n", + "However, provided the cost function is known there should be little\n", + "trouble in calculating" + ] + }, + { + "cell_type": "markdown", + "id": "8b430778", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7fb2cea5", + "metadata": { + "editable": true + }, + "source": [ + "With the definition of $\\delta_j^L$ we have a more compact definition of the derivative of the cost function in terms of the weights, namely" + ] + }, + { + "cell_type": "markdown", + "id": "6c77ac74", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial{\\cal C}}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "708f42bb", + "metadata": { + "editable": true + }, + "source": [ + "## Derivatives in terms of $z_j^L$\n", + "\n", + "It is also easy to see that our previous equation can be written as" + ] + }, + { + "cell_type": "markdown", + "id": "40f66bf5", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L =\\frac{\\partial {\\cal C}}{\\partial z_j^L}= \\frac{\\partial {\\cal C}}{\\partial a_j^L}\\frac{\\partial a_j^L}{\\partial z_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21b9ebbe", + "metadata": { + "editable": true + }, + "source": [ + "which can also be interpreted as the partial derivative of the cost function with respect to the biases $b_j^L$, namely" + ] + }, + { + "cell_type": "markdown", + "id": "665ad548", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L}\\frac{\\partial b_j^L}{\\partial z_j^L}=\\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c182abd9", + "metadata": { + "editable": true + }, + "source": [ + "That is, the error $\\delta_j^L$ is exactly equal to the rate of change of the cost function as a function of the bias." + ] + }, + { + "cell_type": "markdown", + "id": "aa70c6cf", + "metadata": { + "editable": true + }, + "source": [ + "## Bringing it together\n", + "\n", + "We have now three equations that are essential for the computations of the derivatives of the cost function at the output layer. These equations are needed to start the algorithm and they are" + ] + }, + { + "cell_type": "markdown", + "id": "db460a07", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\frac{\\partial{\\cal C}(\\boldsymbol{W^L})}{\\partial w_{ij}^L} = \\delta_j^La_i^{L-1},\n", + "\\label{_auto1} \\tag{1}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3af036d6", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5662288a", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)},\n", + "\\label{_auto2} \\tag{2}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b6a8a1ac", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "dda8fce0", + "metadata": { + "editable": true + }, + "source": [ + "\n", + "
    \n", + "\n", + "$$\n", + "\\begin{equation}\n", + "\\delta_j^L = \\frac{\\partial {\\cal C}}{\\partial b_j^L},\n", + "\\label{_auto3} \\tag{3}\n", + "\\end{equation}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f1957ab0", + "metadata": { + "editable": true + }, + "source": [ + "## Final back propagating equation\n", + "\n", + "We have that (replacing $L$ with a general layer $l$)" + ] + }, + { + "cell_type": "markdown", + "id": "31c8f2c9", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\frac{\\partial {\\cal C}}{\\partial z_j^l}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bba8d29e", + "metadata": { + "editable": true + }, + "source": [ + "We want to express this in terms of the equations for layer $l+1$." + ] + }, + { + "cell_type": "markdown", + "id": "af4922ec", + "metadata": { + "editable": true + }, + "source": [ + "## Using the chain rule and summing over all $k$ entries\n", + "\n", + "We obtain" + ] + }, + { + "cell_type": "markdown", + "id": "f43f0f87", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\frac{\\partial {\\cal C}}{\\partial z_k^{l+1}}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}}=\\sum_k \\delta_k^{l+1}\\frac{\\partial z_k^{l+1}}{\\partial z_j^{l}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "eba489e4", + "metadata": { + "editable": true + }, + "source": [ + "and recalling that" + ] + }, + { + "cell_type": "markdown", + "id": "82610f92", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_j^{l+1} = \\sum_{i=1}^{M_{l}}w_{ij}^{l+1}a_i^{l}+b_j^{l+1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "62513d62", + "metadata": { + "editable": true + }, + "source": [ + "with $M_l$ being the number of nodes in layer $l$, we obtain" + ] + }, + { + "cell_type": "markdown", + "id": "ca381ec8", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l =\\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bdf32ad4", + "metadata": { + "editable": true + }, + "source": [ + "This is our final equation.\n", + "\n", + "We are now ready to set up the algorithm for back propagation and learning the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "764448ea", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm\n", + "\n", + "The four equations provide us with a way of computing the gradient of the cost function. Let us write this out in the form of an algorithm.\n", + "\n", + "**First**, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "**Secondly**, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=1,2,3,\\dots,L$.\n", + "\n", + "**Notation**: The first hidden layer has $l=1$ as label and the final output layer has $l=L$." + ] + }, + { + "cell_type": "markdown", + "id": "989c3082", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back propagation algorithm, part 2\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "9d14949a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = \\sigma'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4ee118b1", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "ba89ad67", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e1f840c5", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the Back propagation algorithm, part 3\n", + "\n", + "Finally, we update the weights and the biases using gradient descent\n", + "for each $l=L-1,L-2,\\dots,1$ (the first hidden layer) and update the weights and biases\n", + "according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "9f06bcfc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "7063f2be", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "3e299445", + "metadata": { + "editable": true + }, + "source": [ + "with $\\eta$ being the learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "28921878", + "metadata": { + "editable": true + }, + "source": [ + "## Updating the gradients\n", + "\n", + "With the back propagate error for each $l=L-1,L-2,\\dots,1$ as" + ] + }, + { + "cell_type": "markdown", + "id": "90f5404c", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "53c2dfbd", + "metadata": { + "editable": true + }, + "source": [ + "we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,1$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "03805799", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "4f8f9c02", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9bf86f9c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "A property that characterizes a neural network, other than its\n", + "connectivity, is the choice of activation function(s). As described\n", + "in, the following restrictions are imposed on an activation function\n", + "for a FFNN to fulfill the universal approximation theorem\n", + "\n", + " * Non-constant\n", + "\n", + " * Bounded\n", + "\n", + " * Monotonically-increasing\n", + "\n", + " * Continuous" + ] + }, + { + "cell_type": "markdown", + "id": "eeaed73c", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions, Logistic and Hyperbolic ones\n", + "\n", + "The second requirement excludes all linear functions. Furthermore, in\n", + "a MLP with only linear activation functions, each layer simply\n", + "performs a linear transformation of its inputs.\n", + "\n", + "Regardless of the number of layers, the output of the NN will be\n", + "nothing but a linear function of the inputs. Thus we need to introduce\n", + "some kind of non-linearity to the NN to be able to fit non-linear\n", + "functions Typical examples are the logistic *Sigmoid*" + ] + }, + { + "cell_type": "markdown", + "id": "0786aaf0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\frac{1}{1 + e^{-x}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "aa76601b", + "metadata": { + "editable": true + }, + "source": [ + "and the *hyperbolic tangent* function" + ] + }, + { + "cell_type": "markdown", + "id": "e1bca915", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\sigma(x) = \\tanh(x)\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1832a8c4", + "metadata": { + "editable": true + }, + "source": [ + "### Relevance\n", + "\n", + "The *sigmoid* function are more biologically plausible because the\n", + "output of inactive neurons are zero. Such activation function are\n", + "called *one-sided*. However, it has been shown that the hyperbolic\n", + "tangent performs better than the sigmoid for training MLPs. has\n", + "become the most popular for *deep neural networks*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5c689736", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "\"\"\"The sigmoid function (or the logistic curve) is a \n", + "function that takes any real number, z, and outputs a number (0,1).\n", + "It is useful in neural networks for assigning weights on a relative scale.\n", + "The value z is the weighted sum of parameters involved in the learning algorithm.\"\"\"\n", + "\n", + "import numpy\n", + "import matplotlib.pyplot as plt\n", + "import math as mt\n", + "\n", + "z = numpy.arange(-5, 5, .1)\n", + "sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))\n", + "sigma = sigma_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, sigma)\n", + "ax.set_ylim([-0.1, 1.1])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sigmoid function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Step Function\"\"\"\n", + "z = numpy.arange(-5, 5, .02)\n", + "step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)\n", + "step = step_fn(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, step)\n", + "ax.set_ylim([-0.5, 1.5])\n", + "ax.set_xlim([-5,5])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('step function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Sine Function\"\"\"\n", + "z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)\n", + "t = numpy.sin(z)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, t)\n", + "ax.set_ylim([-1.0, 1.0])\n", + "ax.set_xlim([-2*mt.pi,2*mt.pi])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('sine function')\n", + "\n", + "plt.show()\n", + "\n", + "\"\"\"Plots a graph of the squashing function used by a rectified linear\n", + "unit\"\"\"\n", + "z = numpy.arange(-2, 2, .1)\n", + "zero = numpy.zeros(len(z))\n", + "y = numpy.max([zero, z], axis=0)\n", + "\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(111)\n", + "ax.plot(z, y)\n", + "ax.set_ylim([-2.0, 2.0])\n", + "ax.set_xlim([-2.0, 2.0])\n", + "ax.grid(True)\n", + "ax.set_xlabel('z')\n", + "ax.set_title('Rectified linear unit')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "0b3a4c95", + "metadata": { + "editable": true + }, + "source": [ + "## Fine-tuning neural network hyperparameters\n", + "\n", + "The flexibility of neural networks is also one of their main\n", + "drawbacks: there are many hyperparameters to tweak. Not only can you\n", + "use any imaginable network topology (how neurons/nodes are\n", + "interconnected), but even in a simple FFNN you can change the number\n", + "of layers, the number of neurons per layer, the type of activation\n", + "function to use in each layer, the weight initialization logic, the\n", + "stochastic gradient optmized and much more. How do you know what\n", + "combination of hyperparameters is the best for your task?\n", + "\n", + "* You can use grid search with cross-validation to find the right hyperparameters.\n", + "\n", + "However,since there are many hyperparameters to tune, and since\n", + "training a neural network on a large dataset takes a lot of time, you\n", + "will only be able to explore a tiny part of the hyperparameter space.\n", + "\n", + "* You can use randomized search.\n", + "\n", + "* Or use tools like [Oscar](http://oscar.calldesk.ai/), which implements more complex algorithms to help you find a good set of hyperparameters quickly." + ] + }, + { + "cell_type": "markdown", + "id": "9955a636", + "metadata": { + "editable": true + }, + "source": [ + "## Hidden layers\n", + "\n", + "For many problems you can start with just one or two hidden layers and\n", + "it will work just fine. For the MNIST data set you ca easily get a\n", + "high accuracy using just one hidden layer with a few hundred neurons.\n", + "You can reach for this data set above 98% accuracy using two hidden\n", + "layers with the same total amount of neurons, in roughly the same\n", + "amount of training time.\n", + "\n", + "For more complex problems, you can gradually ramp up the number of\n", + "hidden layers, until you start overfitting the training set. Very\n", + "complex tasks, such as large image classification or speech\n", + "recognition, typically require networks with dozens of layers and they\n", + "need a huge amount of training data. However, you will rarely have to\n", + "train such networks from scratch: it is much more common to reuse\n", + "parts of a pretrained state-of-the-art network that performs a similar\n", + "task." + ] + }, + { + "cell_type": "markdown", + "id": "f1aa77e9", + "metadata": { + "editable": true + }, + "source": [ + "## Vanishing gradients\n", + "\n", + "The Back propagation algorithm we derived above works by going from\n", + "the output layer to the input layer, propagating the error gradient on\n", + "the way. Once the algorithm has computed the gradient of the cost\n", + "function with regards to each parameter in the network, it uses these\n", + "gradients to update each parameter with a Gradient Descent (GD) step.\n", + "\n", + "Unfortunately for us, the gradients often get smaller and smaller as\n", + "the algorithm progresses down to the first hidden layers. As a result,\n", + "the GD update leaves the lower layer connection weights virtually\n", + "unchanged, and training never converges to a good solution. This is\n", + "known in the literature as **the vanishing gradients problem**." + ] + }, + { + "cell_type": "markdown", + "id": "3703bb33", + "metadata": { + "editable": true + }, + "source": [ + "## Exploding gradients\n", + "\n", + "In other cases, the opposite can happen, namely the the gradients can\n", + "grow bigger and bigger. The result is that many of the layers get\n", + "large updates of the weights the algorithm diverges. This is the\n", + "**exploding gradients problem**, which is mostly encountered in\n", + "recurrent neural networks. More generally, deep neural networks suffer\n", + "from unstable gradients, different layers may learn at widely\n", + "different speeds" + ] + }, + { + "cell_type": "markdown", + "id": "43b1aa26", + "metadata": { + "editable": true + }, + "source": [ + "## Is the Logistic activation function (Sigmoid) our choice?\n", + "\n", + "Although this unfortunate behavior has been empirically observed for\n", + "quite a while (it was one of the reasons why deep neural networks were\n", + "mostly abandoned for a long time), it is only around 2010 that\n", + "significant progress was made in understanding it.\n", + "\n", + "A paper titled [Understanding the Difficulty of Training Deep\n", + "Feedforward Neural Networks by Xavier Glorot and Yoshua Bengio](http://proceedings.mlr.press/v9/glorot10a.html) found that\n", + "the problems with the popular logistic\n", + "sigmoid activation function and the weight initialization technique\n", + "that was most popular at the time, namely random initialization using\n", + "a normal distribution with a mean of 0 and a standard deviation of\n", + "1." + ] + }, + { + "cell_type": "markdown", + "id": "463f4f64", + "metadata": { + "editable": true + }, + "source": [ + "## Logistic function as the root of problems\n", + "\n", + "They showed that with this activation function and this\n", + "initialization scheme, the variance of the outputs of each layer is\n", + "much greater than the variance of its inputs. Going forward in the\n", + "network, the variance keeps increasing after each layer until the\n", + "activation function saturates at the top layers. This is actually made\n", + "worse by the fact that the logistic function has a mean of 0.5, not 0\n", + "(the hyperbolic tangent function has a mean of 0 and behaves slightly\n", + "better than the logistic function in deep networks)." + ] + }, + { + "cell_type": "markdown", + "id": "6c9ea582", + "metadata": { + "editable": true + }, + "source": [ + "## The derivative of the Logistic funtion\n", + "\n", + "Looking at the logistic activation function, when inputs become large\n", + "(negative or positive), the function saturates at 0 or 1, with a\n", + "derivative extremely close to 0. Thus when backpropagation kicks in,\n", + "it has virtually no gradient to propagate back through the network,\n", + "and what little gradient exists keeps getting diluted as\n", + "backpropagation progresses down through the top layers, so there is\n", + "really nothing left for the lower layers.\n", + "\n", + "In their paper, Glorot and Bengio propose a way to significantly\n", + "alleviate this problem. We need the signal to flow properly in both\n", + "directions: in the forward direction when making predictions, and in\n", + "the reverse direction when backpropagating gradients. We don’t want\n", + "the signal to die out, nor do we want it to explode and saturate. For\n", + "the signal to flow properly, the authors argue that we need the\n", + "variance of the outputs of each layer to be equal to the variance of\n", + "its inputs, and we also need the gradients to have equal variance\n", + "before and after flowing through a layer in the reverse direction." + ] + }, + { + "cell_type": "markdown", + "id": "80c83d2c", + "metadata": { + "editable": true + }, + "source": [ + "## Insights from the paper by Glorot and Bengio\n", + "\n", + "One of the insights in the 2010 paper by Glorot and Bengio was that\n", + "the vanishing/exploding gradients problems were in part due to a poor\n", + "choice of activation function. Until then most people had assumed that\n", + "if Nature had chosen to use roughly sigmoid activation functions in\n", + "biological neurons, they must be an excellent choice. But it turns out\n", + "that other activation functions behave much better in deep neural\n", + "networks, in particular the ReLU activation function, mostly because\n", + "it does not saturate for positive values (and also because it is quite\n", + "fast to compute)." + ] + }, + { + "cell_type": "markdown", + "id": "55a1ad5d", + "metadata": { + "editable": true + }, + "source": [ + "## The RELU function family\n", + "\n", + "The ReLU activation function suffers from a problem known as the dying\n", + "ReLUs: during training, some neurons effectively die, meaning they\n", + "stop outputting anything other than 0.\n", + "\n", + "In some cases, you may find that half of your network’s neurons are\n", + "dead, especially if you used a large learning rate. During training,\n", + "if a neuron’s weights get updated such that the weighted sum of the\n", + "neuron’s inputs is negative, it will start outputting 0. When this\n", + "happen, the neuron is unlikely to come back to life since the gradient\n", + "of the ReLU function is 0 when its input is negative." + ] + }, + { + "cell_type": "markdown", + "id": "b7fafe4a", + "metadata": { + "editable": true + }, + "source": [ + "## ELU function\n", + "\n", + "To solve this problem, nowadays practitioners use a variant of the\n", + "ReLU function, such as the leaky ReLU discussed above or the so-called\n", + "exponential linear unit (ELU) function" + ] + }, + { + "cell_type": "markdown", + "id": "46e10153", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "ELU(z) = \\left\\{\\begin{array}{cc} \\alpha\\left( \\exp{(z)}-1\\right) & z < 0,\\\\ z & z \\ge 0.\\end{array}\\right.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0930ba50", + "metadata": { + "editable": true + }, + "source": [ + "## Which activation function should we use?\n", + "\n", + "In general it seems that the ELU activation function is better than\n", + "the leaky ReLU function (and its variants), which is better than\n", + "ReLU. ReLU performs better than $\\tanh$ which in turn performs better\n", + "than the logistic function.\n", + "\n", + "If runtime performance is an issue, then you may opt for the leaky\n", + "ReLU function over the ELU function If you don’t want to tweak yet\n", + "another hyperparameter, you may just use the default $\\alpha$ of\n", + "$0.01$ for the leaky ReLU, and $1$ for ELU. If you have spare time and\n", + "computing power, you can use cross-validation or bootstrap to evaluate\n", + "other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "5c0c59af", + "metadata": { + "editable": true + }, + "source": [ + "## More on activation functions, output layers\n", + "\n", + "In most cases you can use the ReLU activation function in the hidden\n", + "layers (or one of its variants).\n", + "\n", + "It is a bit faster to compute than other activation functions, and the\n", + "gradient descent optimization does in general not get stuck.\n", + "\n", + "**For the output layer:**\n", + "\n", + "* For classification the softmax activation function is generally a good choice for classification tasks (when the classes are mutually exclusive).\n", + "\n", + "* For regression tasks, you can simply use no activation function at all." + ] + }, + { + "cell_type": "markdown", + "id": "582e4df4", + "metadata": { + "editable": true + }, + "source": [ + "## Batch Normalization\n", + "\n", + "Batch Normalization aims to address the vanishing/exploding gradients\n", + "problems, and more generally the problem that the distribution of each\n", + "layer’s inputs changes during training, as the parameters of the\n", + "previous layers change.\n", + "\n", + "The technique consists of adding an operation in the model just before\n", + "the activation function of each layer, simply zero-centering and\n", + "normalizing the inputs, then scaling and shifting the result using two\n", + "new parameters per layer (one for scaling, the other for shifting). In\n", + "other words, this operation lets the model learn the optimal scale and\n", + "mean of the inputs for each layer. In order to zero-center and\n", + "normalize the inputs, the algorithm needs to estimate the inputs’ mean\n", + "and standard deviation. It does so by evaluating the mean and standard\n", + "deviation of the inputs over the current mini-batch, from this the\n", + "name batch normalization." + ] + }, + { + "cell_type": "markdown", + "id": "ea360013", + "metadata": { + "editable": true + }, + "source": [ + "## Dropout\n", + "\n", + "It is a fairly simple algorithm: at every training step, every neuron\n", + "(including the input neurons but excluding the output neurons) has a\n", + "probability $p$ of being temporarily dropped out, meaning it will be\n", + "entirely ignored during this training step, but it may be active\n", + "during the next step.\n", + "\n", + "The hyperparameter $p$ is called the dropout rate, and it is typically\n", + "set to 50%. After training, the neurons are not dropped anymore. It\n", + "is viewed as one of the most popular regularization techniques." + ] + }, + { + "cell_type": "markdown", + "id": "fee98b12", + "metadata": { + "editable": true + }, + "source": [ + "## Gradient Clipping\n", + "\n", + "A popular technique to lessen the exploding gradients problem is to\n", + "simply clip the gradients during backpropagation so that they never\n", + "exceed some threshold (this is mostly useful for recurrent neural\n", + "networks).\n", + "\n", + "This technique is called Gradient Clipping.\n", + "\n", + "In general however, Batch\n", + "Normalization is preferred." + ] + }, + { + "cell_type": "markdown", + "id": "c9f175b0", + "metadata": { + "editable": true + }, + "source": [ + "## A top-down perspective on Neural networks\n", + "\n", + "The first thing we would like to do is divide the data into two or\n", + "three parts. A training set, a validation or dev (development) set,\n", + "and a test set. The test set is the data on which we want to make\n", + "predictions. The dev set is a subset of the training data we use to\n", + "check how well we are doing out-of-sample, after training the model on\n", + "the training dataset. We use the validation error as a proxy for the\n", + "test error in order to make tweaks to our model. It is crucial that we\n", + "do not use any of the test data to train the algorithm. This is a\n", + "cardinal sin in ML. Then:\n", + "\n", + "1. Estimate optimal error rate\n", + "\n", + "2. Minimize underfitting (bias) on training data set.\n", + "\n", + "3. Make sure you are not overfitting." + ] + }, + { + "cell_type": "markdown", + "id": "f6f04fbb", + "metadata": { + "editable": true + }, + "source": [ + "## More top-down perspectives\n", + "\n", + "If the validation and test sets are drawn from the same distributions,\n", + "then a good performance on the validation set should lead to similarly\n", + "good performance on the test set. \n", + "\n", + "However, sometimes\n", + "the training data and test data differ in subtle ways because, for\n", + "example, they are collected using slightly different methods, or\n", + "because it is cheaper to collect data in one way versus another. In\n", + "this case, there can be a mismatch between the training and test\n", + "data. This can lead to the neural network overfitting these small\n", + "differences between the test and training sets, and a poor performance\n", + "on the test set despite having a good performance on the validation\n", + "set. To rectify this, Andrew Ng suggests making two validation or dev\n", + "sets, one constructed from the training data and one constructed from\n", + "the test data. The difference between the performance of the algorithm\n", + "on these two validation sets quantifies the train-test mismatch. This\n", + "can serve as another important diagnostic when using DNNs for\n", + "supervised learning." + ] + }, + { + "cell_type": "markdown", + "id": "d4184eee", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of supervised learning with deep networks\n", + "\n", + "Like all statistical methods, supervised learning using neural\n", + "networks has important limitations. This is especially important when\n", + "one seeks to apply these methods, especially to physics problems. Like\n", + "all tools, DNNs are not a universal solution. Often, the same or\n", + "better performance on a task can be achieved by using a few\n", + "hand-engineered features (or even a collection of random\n", + "features)." + ] + }, + { + "cell_type": "markdown", + "id": "82d314da", + "metadata": { + "editable": true + }, + "source": [ + "## Limitations of NNs\n", + "\n", + "Here we list some of the important limitations of supervised neural network based models. \n", + "\n", + "* **Need labeled data**. All supervised learning methods, DNNs for supervised learning require labeled data. Often, labeled data is harder to acquire than unlabeled data (e.g. one must pay for human experts to label images).\n", + "\n", + "* **Supervised neural networks are extremely data intensive.** DNNs are data hungry. They perform best when data is plentiful. This is doubly so for supervised methods where the data must also be labeled. The utility of DNNs is extremely limited if data is hard to acquire or the datasets are small (hundreds to a few thousand samples). In this case, the performance of other methods that utilize hand-engineered features can exceed that of DNNs." + ] + }, + { + "cell_type": "markdown", + "id": "abc6640b", + "metadata": { + "editable": true + }, + "source": [ + "## Homogeneous data\n", + "\n", + "* **Homogeneous data.** Almost all DNNs deal with homogeneous data of one type. It is very hard to design architectures that mix and match data types (i.e. some continuous variables, some discrete variables, some time series). In applications beyond images, video, and language, this is often what is required. In contrast, ensemble models like random forests or gradient-boosted trees have no difficulty handling mixed data types." + ] + }, + { + "cell_type": "markdown", + "id": "bb7d1f89", + "metadata": { + "editable": true + }, + "source": [ + "## More limitations\n", + "\n", + "* **Many problems are not about prediction.** In natural science we are often interested in learning something about the underlying distribution that generates the data. In this case, it is often difficult to cast these ideas in a supervised learning setting. While the problems are related, it is possible to make good predictions with a *wrong* model. The model might or might not be useful for understanding the underlying science.\n", + "\n", + "Some of these remarks are particular to DNNs, others are shared by all supervised learning methods. This motivates the use of unsupervised methods which in part circumvent these problems." + ] + }, + { + "cell_type": "markdown", + "id": "442b1b5e", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up the back-propagation algorithm\n", + "\n", + "Let us write this out in the form of an algorithm.\n", + "\n", + "First, we set up the input data $\\boldsymbol{x}$ and the activations\n", + "$\\boldsymbol{z}_1$ of the input layer and compute the activation function and\n", + "the pertinent outputs $\\boldsymbol{a}^1$.\n", + "\n", + "Secondly, we perform then the feed forward till we reach the output\n", + "layer and compute all $\\boldsymbol{z}_l$ of the input layer and compute the\n", + "activation function and the pertinent outputs $\\boldsymbol{a}^l$ for\n", + "$l=2,3,\\dots,L$.\n", + "\n", + "Thereafter we compute the ouput error $\\boldsymbol{\\delta}^L$ by computing all" + ] + }, + { + "cell_type": "markdown", + "id": "0005e340", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^L = f'(z_j^L)\\frac{\\partial {\\cal C}}{\\partial (a_j^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2b27751b", + "metadata": { + "editable": true + }, + "source": [ + "Then we compute the back propagate error for each $l=L-1,L-2,\\dots,2$ as" + ] + }, + { + "cell_type": "markdown", + "id": "dd544b4b", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\delta_j^l = \\sum_k \\delta_k^{l+1}w_{kj}^{l+1}\\sigma'(z_j^l).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "57a7d213", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we update the weights and the biases using gradient descent for each $l=L-1,L-2,\\dots,2$ and update the weights and biases according to the rules" + ] + }, + { + "cell_type": "markdown", + "id": "932510f4", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "w_{ij}^l\\leftarrow = w_{ij}^l- \\eta \\delta_j^la_i^{l-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "bf80ed99", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "b_j^l \\leftarrow b_j^l-\\eta \\frac{\\partial {\\cal C}}{\\partial b_j^l}=b_j^l-\\eta \\delta_j^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f682bf76", + "metadata": { + "editable": true + }, + "source": [ + "The parameter $\\eta$ is the learning parameter discussed in connection with the gradient descent methods.\n", + "Here it is convenient to use stochastic gradient descent (see the examples below) with mini-batches with an outer loop that steps through multiple epochs of training." + ] + }, + { + "cell_type": "markdown", + "id": "ad2b26a4", + "metadata": { + "editable": true + }, + "source": [ + "## Setting up a Multi-layer perceptron model for classification\n", + "\n", + "We are now gong to develop an example based on the MNIST data\n", + "base. This is a classification problem and we need to use our\n", + "cross-entropy function we discussed in connection with logistic\n", + "regression. The cross-entropy defines our cost function for the\n", + "classificaton problems with neural networks.\n", + "\n", + "In binary classification with two classes $(0, 1)$ we define the\n", + "logistic/sigmoid function as the probability that a particular input\n", + "is in class $0$ or $1$. This is possible because the logistic\n", + "function takes any input from the real numbers and inputs a number\n", + "between 0 and 1, and can therefore be interpreted as a probability. It\n", + "also has other nice properties, such as a derivative that is simple to\n", + "calculate.\n", + "\n", + "For an input $\\boldsymbol{a}$ from the hidden layer, the probability that the input $\\boldsymbol{x}$\n", + "is in class 0 or 1 is just. We let $\\theta$ represent the unknown weights and biases to be adjusted by our equations). The variable $x$\n", + "represents our activation values $z$. We have" + ] + }, + { + "cell_type": "markdown", + "id": "a08331b2", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = \\frac{1}{1 + \\exp{(- \\boldsymbol{x}})} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9ebfde52", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "531dfa25", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y = 1 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) = 1 - P(y = 0 \\mid \\boldsymbol{x}, \\boldsymbol{\\theta}) ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "8941d38c", + "metadata": { + "editable": true + }, + "source": [ + "where $y \\in \\{0, 1\\}$ and $\\boldsymbol{\\theta}$ represents the weights and biases\n", + "of our network." + ] + }, + { + "cell_type": "markdown", + "id": "7ae7e222", + "metadata": { + "editable": true + }, + "source": [ + "## Defining the cost function\n", + "\n", + "Our cost function is given as (see the Logistic regression lectures)" + ] + }, + { + "cell_type": "markdown", + "id": "cbb157cc", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\ln P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = - \\sum_{i=1}^n\n", + "y_i \\ln[P(y_i = 0)] + (1 - y_i) \\ln [1 - P(y_i = 0)] = \\sum_{i=1}^n \\mathcal{L}_i(\\boldsymbol{\\theta}) .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0178770c", + "metadata": { + "editable": true + }, + "source": [ + "This last equality means that we can interpret our *cost* function as a sum over the *loss* function\n", + "for each point in the dataset $\\mathcal{L}_i(\\boldsymbol{\\theta})$. \n", + "The negative sign is just so that we can think about our algorithm as minimizing a positive number, rather\n", + "than maximizing a negative number. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$ and\n", + "\n", + "$y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset (numbers from $0$ to $9$).. \n", + "\n", + "If $\\boldsymbol{x}_i$ is the $i$-th input (image), $y_{ic}$ refers to the $c$-th component of the $i$-th\n", + "output vector $\\boldsymbol{y}_i$. \n", + "The probability of $\\boldsymbol{x}_i$ being in class $c$ will be given by the softmax function:" + ] + }, + { + "cell_type": "markdown", + "id": "cb69f3df", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(y_{ic} = 1 \\mid \\boldsymbol{x}_i, \\boldsymbol{\\theta}) = \\frac{\\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_c)}}\n", + "{\\sum_{c'=0}^{C-1} \\exp{((\\boldsymbol{a}_i^{hidden})^T \\boldsymbol{w}_{c'})}} ,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "11aa1335", + "metadata": { + "editable": true + }, + "source": [ + "which reduces to the logistic function in the binary case. \n", + "The likelihood of this $C$-class classifier\n", + "is now given as:" + ] + }, + { + "cell_type": "markdown", + "id": "a225e57a", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "P(\\mathcal{D} \\mid \\boldsymbol{\\theta}) = \\prod_{i=1}^n \\prod_{c=0}^{C-1} [P(y_{ic} = 1)]^{y_{ic}} .\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "569dd3f2", + "metadata": { + "editable": true + }, + "source": [ + "Again we take the negative log-likelihood to define our cost function:" + ] + }, + { + "cell_type": "markdown", + "id": "f8e84cae", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\theta}) = - \\log{P(\\mathcal{D} \\mid \\boldsymbol{\\theta})}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1dd303e8", + "metadata": { + "editable": true + }, + "source": [ + "See the logistic regression lectures for a full definition of the cost function.\n", + "\n", + "The back propagation equations need now only a small change, namely the definition of a new cost function. We are thus ready to use the same equations as before!" + ] + }, + { + "cell_type": "markdown", + "id": "33494270", + "metadata": { + "editable": true + }, + "source": [ + "## Example: binary classification problem\n", + "\n", + "As an example of the above, relevant for project 2 as well, let us consider a binary class. As discussed in our logistic regression lectures, we defined a cost function in terms of the parameters $\\beta$ as" + ] + }, + { + "cell_type": "markdown", + "id": "01bd6a05", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{\\beta}) = - \\sum_{i=1}^n \\left(y_i\\log{p(y_i \\vert x_i,\\boldsymbol{\\beta})}+(1-y_i)\\log{1-p(y_i \\vert x_i,\\boldsymbol{\\beta})}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "60f16a47", + "metadata": { + "editable": true + }, + "source": [ + "where we had defined the logistic (sigmoid) function" + ] + }, + { + "cell_type": "markdown", + "id": "ab0c42b3", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =1\\vert x_i,\\boldsymbol{\\beta})=\\frac{\\exp{(\\beta_0+\\beta_1 x_i)}}{1+\\exp{(\\beta_0+\\beta_1 x_i)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "dcfb2e28", + "metadata": { + "editable": true + }, + "source": [ + "and" + ] + }, + { + "cell_type": "markdown", + "id": "5076b392", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "p(y_i =0\\vert x_i,\\boldsymbol{\\beta})=1-p(y_i =1\\vert x_i,\\boldsymbol{\\beta}).\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9d6001f4", + "metadata": { + "editable": true + }, + "source": [ + "The parameters $\\boldsymbol{\\beta}$ were defined using a minimization method like gradient descent or Newton-Raphson's method. \n", + "\n", + "Now we replace $x_i$ with the activation $z_i^l$ for a given layer $l$ and the outputs as $y_i=a_i^l=f(z_i^l)$, with $z_i^l$ now being a function of the weights $w_{ij}^l$ and biases $b_i^l$. \n", + "We have then" + ] + }, + { + "cell_type": "markdown", + "id": "d0245c18", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "a_i^l = y_i = \\frac{\\exp{(z_i^l)}}{1+\\exp{(z_i^l)}},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "030ac014", + "metadata": { + "editable": true + }, + "source": [ + "with" + ] + }, + { + "cell_type": "markdown", + "id": "bdc01c83", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "z_i^l = \\sum_{j}w_{ij}^l a_j^{l-1}+b_i^l,\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "1a77b25c", + "metadata": { + "editable": true + }, + "source": [ + "where the superscript $l-1$ indicates that these are the outputs from layer $l-1$.\n", + "Our cost function at the final layer $l=L$ is now" + ] + }, + { + "cell_type": "markdown", + "id": "1f169ed1", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\mathcal{C}(\\boldsymbol{W}) = - \\sum_{i=1}^n \\left(t_i\\log{a_i^L}+(1-t_i)\\log{(1-a_i^L)}\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "6bc460e2", + "metadata": { + "editable": true + }, + "source": [ + "where we have defined the targets $t_i$. The derivatives of the cost function with respect to the output $a_i^L$ are then easily calculated and we get" + ] + }, + { + "cell_type": "markdown", + "id": "fe1f92c0", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial \\mathcal{C}(\\boldsymbol{W})}{\\partial a_i^L} = \\frac{a_i^L-t_i}{a_i^L(1-a_i^L)}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "78cf6843", + "metadata": { + "editable": true + }, + "source": [ + "In case we use another activation function than the logistic one, we need to evaluate other derivatives." + ] + }, + { + "cell_type": "markdown", + "id": "81ed1ccc", + "metadata": { + "editable": true + }, + "source": [ + "## The Softmax function\n", + "In case we employ the more general case given by the Softmax equation, we need to evaluate the derivative of the activation function with respect to the activation $z_i^l$, that is we need" + ] + }, + { + "cell_type": "markdown", + "id": "2a16cf53", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial w_{jk}^l} =\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l} \\frac{\\partial z_j^l}{\\partial w_{jk}^l}= \\frac{\\partial f(z_i^l)}{\\partial z_j^l}a_k^{l-1}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "21988141", + "metadata": { + "editable": true + }, + "source": [ + "For the Softmax function we have" + ] + }, + { + "cell_type": "markdown", + "id": "b37cc0cd", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "f(z_i^l) = \\frac{\\exp{(z_i^l)}}{\\sum_{m=1}^K\\exp{(z_m^l)}}.\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "259618c5", + "metadata": { + "editable": true + }, + "source": [ + "Its derivative with respect to $z_j^l$ gives" + ] + }, + { + "cell_type": "markdown", + "id": "af5a331e", + "metadata": { + "editable": true + }, + "source": [ + "$$\n", + "\\frac{\\partial f(z_i^l)}{\\partial z_j^l}= f(z_i^l)\\left(\\delta_{ij}-f(z_j^l)\\right),\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "208ab286", + "metadata": { + "editable": true + }, + "source": [ + "which in case of the simply binary model reduces to having $i=j$." + ] + }, + { + "cell_type": "markdown", + "id": "8f30fbc3", + "metadata": { + "editable": true + }, + "source": [ + "## Developing a code for doing neural networks with back propagation\n", + "\n", + "One can identify a set of key steps when using neural networks to solve supervised learning problems: \n", + "\n", + "1. Collect and pre-process data \n", + "\n", + "2. Define model and architecture \n", + "\n", + "3. Choose cost function and optimizer \n", + "\n", + "4. Train the model \n", + "\n", + "5. Evaluate model performance on test data \n", + "\n", + "6. Adjust hyperparameters (if necessary, network architecture)" + ] + }, + { + "cell_type": "markdown", + "id": "09538ef9", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Here we will be using the MNIST dataset, which is readily available through the **scikit-learn**\n", + "package. You may also find it for example [here](http://yann.lecun.com/exdb/mnist/). \n", + "The *MNIST* (Modified National Institute of Standards and Technology) database is a large database\n", + "of handwritten digits that is commonly used for training various image processing systems. \n", + "The MNIST dataset consists of 70 000 images of size $28\\times 28$ pixels, each labeled from 0 to 9. \n", + "The scikit-learn dataset we will use consists of a selection of 1797 images of size $8\\times 8$ collected and processed from this database. \n", + "\n", + "To feed data into a feed-forward neural network we need to represent\n", + "the inputs as a design/feature matrix $X = (n_{inputs}, n_{features})$. Each\n", + "row represents an *input*, in this case a handwritten digit, and\n", + "each column represents a *feature*, in this case a pixel. The\n", + "correct answers, also known as *labels* or *targets* are\n", + "represented as a 1D array of integers \n", + "$Y = (n_{inputs}) = (5, 3, 1, 8,...)$.\n", + "\n", + "As an example, say we want to build a neural network using supervised learning to predict Body-Mass Index (BMI) from\n", + "measurements of height (in m) \n", + "and weight (in kg). If we have measurements of 5 people the design/feature matrix could be for example: \n", + "\n", + "$$ X = \\begin{bmatrix}\n", + "1.85 & 81\\\\\n", + "1.71 & 65\\\\\n", + "1.95 & 103\\\\\n", + "1.55 & 42\\\\\n", + "1.63 & 56\n", + "\\end{bmatrix} ,$$ \n", + "\n", + "and the targets would be: \n", + "\n", + "$$ Y = (23.7, 22.2, 27.1, 17.5, 21.1) $$ \n", + "\n", + "Since each input image is a 2D matrix, we need to flatten the image\n", + "(i.e. \"unravel\" the 2D matrix into a 1D array) to turn the data into a\n", + "design/feature matrix. This means we lose all spatial information in the\n", + "image, such as locality and translational invariance. More complicated\n", + "architectures such as Convolutional Neural Networks can take advantage\n", + "of such information, and are most commonly applied when analyzing\n", + "images." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ced37e42", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "ebabb274", + "metadata": { + "editable": true + }, + "source": [ + "## Train and test datasets\n", + "\n", + "Performing analysis before partitioning the dataset is a major error, that can lead to incorrect conclusions. \n", + "\n", + "We will reserve $80 \\%$ of our dataset for training and $20 \\%$ for testing. \n", + "\n", + "It is important that the train and test datasets are drawn randomly from our dataset, to ensure\n", + "no bias in the sampling. \n", + "Say you are taking measurements of weather data to predict the weather in the coming 5 days.\n", + "You don't want to train your model on measurements taken from the hours 00.00 to 12.00, and then test it on data\n", + "collected from 12.00 to 24.00." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2c87b9f9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-liner from scikit-learn library\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)\n", + "\n", + "# equivalently in numpy\n", + "def train_test_split_numpy(inputs, labels, train_size, test_size):\n", + " n_inputs = len(inputs)\n", + " inputs_shuffled = inputs.copy()\n", + " labels_shuffled = labels.copy()\n", + " \n", + " np.random.shuffle(inputs_shuffled)\n", + " np.random.shuffle(labels_shuffled)\n", + " \n", + " train_end = int(n_inputs*train_size)\n", + " X_train, X_test = inputs_shuffled[:train_end], inputs_shuffled[train_end:]\n", + " Y_train, Y_test = labels_shuffled[:train_end], labels_shuffled[train_end:]\n", + " \n", + " return X_train, X_test, Y_train, Y_test\n", + "\n", + "#X_train, X_test, Y_train, Y_test = train_test_split_numpy(inputs, labels, train_size, test_size)\n", + "\n", + "print(\"Number of training images: \" + str(len(X_train)))\n", + "print(\"Number of test images: \" + str(len(X_test)))" + ] + }, + { + "cell_type": "markdown", + "id": "0c186fec", + "metadata": { + "editable": true + }, + "source": [ + "## Define model and architecture\n", + "\n", + "Our simple feed-forward neural network will consist of an *input* layer, a single *hidden* layer and an *output* layer. The activation $y$ of each neuron is a weighted sum of inputs, passed through an activation function. In case of the simple perceptron model we have \n", + "\n", + "$$ z = \\sum_{i=1}^n w_i a_i ,$$\n", + "\n", + "$$ y = f(z) ,$$\n", + "\n", + "where $f$ is the activation function, $a_i$ represents input from neuron $i$ in the preceding layer\n", + "and $w_i$ is the weight to input $i$. \n", + "The activation of the neurons in the input layer is just the features (e.g. a pixel value). \n", + "\n", + "The simplest activation function for a neuron is the *Heaviside* function:\n", + "\n", + "$$ f(z) = \n", + "\\begin{cases}\n", + "1, & z > 0\\\\\n", + "0, & \\text{otherwise}\n", + "\\end{cases}\n", + "$$\n", + "\n", + "A feed-forward neural network with this activation is known as a *perceptron*. \n", + "For a binary classifier (i.e. two classes, 0 or 1, dog or not-dog) we can also use this in our output layer. \n", + "This activation can be generalized to $k$ classes (using e.g. the *one-against-all* strategy), \n", + "and we call these architectures *multiclass perceptrons*. \n", + "\n", + "However, it is now common to use the terms Single Layer Perceptron (SLP) (1 hidden layer) and \n", + "Multilayer Perceptron (MLP) (2 or more hidden layers) to refer to feed-forward neural networks with any activation function. \n", + "\n", + "Typical choices for activation functions include the sigmoid function, hyperbolic tangent, and Rectified Linear Unit (ReLU). \n", + "We will be using the sigmoid function $\\sigma(x)$: \n", + "\n", + "$$ f(x) = \\sigma(x) = \\frac{1}{1 + e^{-x}} ,$$\n", + "\n", + "which is inspired by probability theory (see logistic regression) and was most commonly used until about 2011. See the discussion below concerning other activation functions." + ] + }, + { + "cell_type": "markdown", + "id": "2cbece98", + "metadata": { + "editable": true + }, + "source": [ + "## Layers\n", + "\n", + "* Input \n", + "\n", + "Since each input image has 8x8 = 64 pixels or features, we have an input layer of 64 neurons. \n", + "\n", + "* Hidden layer\n", + "\n", + "We will use 50 neurons in the hidden layer receiving input from the neurons in the input layer. \n", + "Since each neuron in the hidden layer is connected to the 64 inputs we have 64x50 = 3200 weights to the hidden layer. \n", + "\n", + "* Output\n", + "\n", + "If we were building a binary classifier, it would be sufficient with a single neuron in the output layer,\n", + "which could output 0 or 1 according to the Heaviside function. This would be an example of a *hard* classifier, meaning it outputs the class of the input directly. However, if we are dealing with noisy data it is often beneficial to use a *soft* classifier, which outputs the probability of being in class 0 or 1. \n", + "\n", + "For a soft binary classifier, we could use a single neuron and interpret the output as either being the probability of being in class 0 or the probability of being in class 1. Alternatively we could use 2 neurons, and interpret each neuron as the probability of being in each class. \n", + "\n", + "Since we are doing multiclass classification, with 10 categories, it is natural to use 10 neurons in the output layer. We number the neurons $j = 0,1,...,9$. The activation of each output neuron $j$ will be according to the *softmax* function: \n", + "\n", + "$$ P(\\text{class $j$} \\mid \\text{input $\\boldsymbol{a}$}) = \\frac{\\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_j)}}\n", + "{\\sum_{c=0}^{9} \\exp{(\\boldsymbol{a}^T \\boldsymbol{w}_c)}} ,$$ \n", + "\n", + "i.e. each neuron $j$ outputs the probability of being in class $j$ given an input from the hidden layer $\\boldsymbol{a}$, with $\\boldsymbol{w}_j$ the weights of neuron $j$ to the inputs. \n", + "The denominator is a normalization factor to ensure the outputs (probabilities) sum up to 1. \n", + "The exponent is just the weighted sum of inputs as before: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i+b_j.$$ \n", + "\n", + "Since each neuron in the output layer is connected to the 50 inputs from the hidden layer we have 50x10 = 500\n", + "weights to the output layer." + ] + }, + { + "cell_type": "markdown", + "id": "442935af", + "metadata": { + "editable": true + }, + "source": [ + "## Weights and biases\n", + "\n", + "Typically weights are initialized with small values distributed around zero, drawn from a uniform\n", + "or normal distribution. Setting all weights to zero means all neurons give the same output, making the network useless. \n", + "\n", + "Adding a bias value to the weighted sum of inputs allows the neural network to represent a greater range\n", + "of values. Without it, any input with the value 0 will be mapped to zero (before being passed through the activation). The bias unit has an output of 1, and a weight to each neuron $j$, $b_j$: \n", + "\n", + "$$ z_j = \\sum_{i=1}^n w_ {ij} a_i + b_j.$$ \n", + "\n", + "The bias weights $\\boldsymbol{b}$ are often initialized to zero, but a small value like $0.01$ ensures all neurons have some output which can be backpropagated in the first training cycle." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "07fbb18c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# building our neural network\n", + "\n", + "n_inputs, n_features = X_train.shape\n", + "n_hidden_neurons = 50\n", + "n_categories = 10\n", + "\n", + "# we make the weights normally distributed using numpy.random.randn\n", + "\n", + "# weights and bias in the hidden layer\n", + "hidden_weights = np.random.randn(n_features, n_hidden_neurons)\n", + "hidden_bias = np.zeros(n_hidden_neurons) + 0.01\n", + "\n", + "# weights and bias in the output layer\n", + "output_weights = np.random.randn(n_hidden_neurons, n_categories)\n", + "output_bias = np.zeros(n_categories) + 0.01" + ] + }, + { + "cell_type": "markdown", + "id": "6a3ea326", + "metadata": { + "editable": true + }, + "source": [ + "## Feed-forward pass\n", + "\n", + "Denote $F$ the number of features, $H$ the number of hidden neurons and $C$ the number of categories. \n", + "For each input image we calculate a weighted sum of input features (pixel values) to each neuron $j$ in the hidden layer $l$: \n", + "\n", + "$$ z_{j}^{l} = \\sum_{i=1}^{F} w_{ij}^{l} x_i + b_{j}^{l},$$\n", + "\n", + "this is then passed through our activation function \n", + "\n", + "$$ a_{j}^{l} = f(z_{j}^{l}) .$$ \n", + "\n", + "We calculate a weighted sum of inputs (activations in the hidden layer) to each neuron $j$ in the output layer: \n", + "\n", + "$$ z_{j}^{L} = \\sum_{i=1}^{H} w_{ij}^{L} a_{i}^{l} + b_{j}^{L}.$$ \n", + "\n", + "Finally we calculate the output of neuron $j$ in the output layer using the softmax function: \n", + "\n", + "$$ a_{j}^{L} = \\frac{\\exp{(z_j^{L})}}\n", + "{\\sum_{c=0}^{C-1} \\exp{(z_c^{L})}} .$$" + ] + }, + { + "cell_type": "markdown", + "id": "525624c4", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplications\n", + "\n", + "Since our data has the dimensions $X = (n_{inputs}, n_{features})$ and our weights to the hidden\n", + "layer have the dimensions \n", + "$W_{hidden} = (n_{features}, n_{hidden})$,\n", + "we can easily feed the network all our training data in one go by taking the matrix product \n", + "\n", + "$$ X W^{h} = (n_{inputs}, n_{hidden}),$$ \n", + "\n", + "and obtain a matrix that holds the weighted sum of inputs to the hidden layer\n", + "for each input image and each hidden neuron. \n", + "We also add the bias to obtain a matrix of weighted sums to the hidden layer $Z^{h}$: \n", + "\n", + "$$ \\boldsymbol{z}^{l} = \\boldsymbol{X} \\boldsymbol{W}^{l} + \\boldsymbol{b}^{l} ,$$\n", + "\n", + "meaning the same bias (1D array with size equal number of hidden neurons) is added to each input image. \n", + "This is then passed through the activation: \n", + "\n", + "$$ \\boldsymbol{a}^{l} = f(\\boldsymbol{z}^l) .$$ \n", + "\n", + "This is fed to the output layer: \n", + "\n", + "$$ \\boldsymbol{z}^{L} = \\boldsymbol{a}^{L} \\boldsymbol{W}^{L} + \\boldsymbol{b}^{L} .$$\n", + "\n", + "Finally we receive our output values for each image and each category by passing it through the softmax function: \n", + "\n", + "$$ output = softmax (\\boldsymbol{z}^{L}) = (n_{inputs}, n_{categories}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "32d0a43f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# setup the feed-forward pass, subscript h = hidden layer\n", + "\n", + "def sigmoid(x):\n", + " return 1/(1 + np.exp(-x))\n", + "\n", + "def feed_forward(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " return probabilities\n", + "\n", + "probabilities = feed_forward(X_train)\n", + "print(\"probabilities = (n_inputs, n_categories) = \" + str(probabilities.shape))\n", + "print(\"probability that image 0 is in category 0,1,2,...,9 = \\n\" + str(probabilities[0]))\n", + "print(\"probabilities sum up to: \" + str(probabilities[0].sum()))\n", + "print()\n", + "\n", + "# we obtain a prediction by taking the class with the highest likelihood\n", + "def predict(X):\n", + " probabilities = feed_forward(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + "predictions = predict(X_train)\n", + "print(\"predictions = (n_inputs) = \" + str(predictions.shape))\n", + "print(\"prediction for image 0: \" + str(predictions[0]))\n", + "print(\"correct label for image 0: \" + str(Y_train[0]))" + ] + }, + { + "cell_type": "markdown", + "id": "da2ede88", + "metadata": { + "editable": true + }, + "source": [ + "## Choose cost function and optimizer\n", + "\n", + "To measure how well our neural network is doing we need to introduce a cost function. \n", + "We will call the function that gives the error of a single sample output the *loss* function, and the function\n", + "that gives the total error of our network across all samples the *cost* function.\n", + "A typical choice for multiclass classification is the *cross-entropy* loss, also known as the negative log likelihood. \n", + "\n", + "In *multiclass* classification it is common to treat each integer label as a so called *one-hot* vector: \n", + "\n", + "$$ y = 5 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 0, 0, 0, 0, 1, 0, 0, 0, 0) ,$$ \n", + "\n", + "$$ y = 1 \\quad \\rightarrow \\quad \\boldsymbol{y} = (0, 1, 0, 0, 0, 0, 0, 0, 0, 0) ,$$ \n", + "\n", + "i.e. a binary bit string of length $C$, where $C = 10$ is the number of classes in the MNIST dataset. \n", + "\n", + "Let $y_{ic}$ denote the $c$-th component of the $i$-th one-hot vector. \n", + "We define the cost function $\\mathcal{C}$ as a sum over the cross-entropy loss for each point $\\boldsymbol{x}_i$ in the dataset.\n", + "\n", + "In the one-hot representation only one of the terms in the loss function is non-zero, namely the\n", + "probability of the correct category $c'$ \n", + "(i.e. the category $c'$ such that $y_{ic'} = 1$). This means that the cross entropy loss only punishes you for how wrong\n", + "you got the correct label. The probability of category $c$ is given by the softmax function. The vector $\\boldsymbol{\\theta}$ represents the parameters of our network, i.e. all the weights and biases." + ] + }, + { + "cell_type": "markdown", + "id": "069a250d", + "metadata": { + "editable": true + }, + "source": [ + "## Optimizing the cost function\n", + "\n", + "The network is trained by finding the weights and biases that minimize the cost function. One of the most widely used classes of methods is *gradient descent* and its generalizations. The idea behind gradient descent\n", + "is simply to adjust the weights in the direction where the gradient of the cost function is large and negative. This ensures we flow toward a *local* minimum of the cost function. \n", + "Each parameter $\\theta$ is iteratively adjusted according to the rule \n", + "\n", + "$$ \\theta_{i+1} = \\theta_i - \\eta \\nabla \\mathcal{C}(\\theta_i) ,$$\n", + "\n", + "where $\\eta$ is known as the *learning rate*, which controls how big a step we take towards the minimum. \n", + "This update can be repeated for any number of iterations, or until we are satisfied with the result. \n", + "\n", + "A simple and effective improvement is a variant called *Batch Gradient Descent*. \n", + "Instead of calculating the gradient on the whole dataset, we calculate an approximation of the gradient\n", + "on a subset of the data called a *minibatch*. \n", + "If there are $N$ data points and we have a minibatch size of $M$, the total number of batches\n", + "is $N/M$. \n", + "We denote each minibatch $B_k$, with $k = 1, 2,...,N/M$. The gradient then becomes: \n", + "\n", + "$$ \\nabla \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\nabla \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{M} \\sum_{i \\in B_k} \\nabla \\mathcal{L}_i(\\theta) ,$$\n", + "\n", + "i.e. instead of averaging the loss over the entire dataset, we average over a minibatch. \n", + "\n", + "This has two important benefits: \n", + "1. Introducing stochasticity decreases the chance that the algorithm becomes stuck in a local minima. \n", + "\n", + "2. It significantly speeds up the calculation, since we do not have to use the entire dataset to calculate the gradient. \n", + "\n", + "The various optmization methods, with codes and algorithms, are discussed in our lectures on [Gradient descent approaches](https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html)." + ] + }, + { + "cell_type": "markdown", + "id": "29ab6ee7", + "metadata": { + "editable": true + }, + "source": [ + "## Regularization\n", + "\n", + "It is common to add an extra term to the cost function, proportional\n", + "to the size of the weights. This is equivalent to constraining the\n", + "size of the weights, so that they do not grow out of control.\n", + "Constraining the size of the weights means that the weights cannot\n", + "grow arbitrarily large to fit the training data, and in this way\n", + "reduces *overfitting*.\n", + "\n", + "We will measure the size of the weights using the so called *L2-norm*, meaning our cost function becomes: \n", + "\n", + "$$ \\mathcal{C}(\\theta) = \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) \\quad \\rightarrow \\quad\n", + "\\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}_i(\\theta) + \\lambda \\lvert \\lvert \\boldsymbol{w} \\rvert \\rvert_2^2 \n", + "= \\frac{1}{N} \\sum_{i=1}^N \\mathcal{L}(\\theta) + \\lambda \\sum_{ij} w_{ij}^2,$$ \n", + "\n", + "i.e. we sum up all the weights squared. The factor $\\lambda$ is known as a regularization parameter.\n", + "\n", + "In order to train the model, we need to calculate the derivative of\n", + "the cost function with respect to every bias and weight in the\n", + "network. In total our network has $(64 + 1)\\times 50=3250$ weights in\n", + "the hidden layer and $(50 + 1)\\times 10=510$ weights to the output\n", + "layer ($+1$ for the bias), and the gradient must be calculated for\n", + "every parameter. We use the *backpropagation* algorithm discussed\n", + "above. This is a clever use of the chain rule that allows us to\n", + "calculate the gradient efficently." + ] + }, + { + "cell_type": "markdown", + "id": "b7c4a178", + "metadata": { + "editable": true + }, + "source": [ + "## Matrix multiplication\n", + "\n", + "To more efficently train our network these equations are implemented using matrix operations. \n", + "The error in the output layer is calculated simply as, with $\\boldsymbol{t}$ being our targets, \n", + "\n", + "$$ \\delta_L = \\boldsymbol{t} - \\boldsymbol{y} = (n_{inputs}, n_{categories}) .$$ \n", + "\n", + "The gradient for the output weights is calculated as \n", + "\n", + "$$ \\nabla W_{L} = \\boldsymbol{a}^T \\delta_L = (n_{hidden}, n_{categories}) ,$$\n", + "\n", + "where $\\boldsymbol{a} = (n_{inputs}, n_{hidden})$. This simply means that we are summing up the gradients for each input. \n", + "Since we are going backwards we have to transpose the activation matrix. \n", + "\n", + "The gradient with respect to the output bias is then \n", + "\n", + "$$ \\nabla \\boldsymbol{b}_{L} = \\sum_{i=1}^{n_{inputs}} \\delta_L = (n_{categories}) .$$ \n", + "\n", + "The error in the hidden layer is \n", + "\n", + "$$ \\Delta_h = \\delta_L W_{L}^T \\circ f'(z_{h}) = \\delta_L W_{L}^T \\circ a_{h} \\circ (1 - a_{h}) = (n_{inputs}, n_{hidden}) ,$$ \n", + "\n", + "where $f'(a_{h})$ is the derivative of the activation in the hidden layer. The matrix products mean\n", + "that we are summing up the products for each neuron in the output layer. The symbol $\\circ$ denotes\n", + "the *Hadamard product*, meaning element-wise multiplication. \n", + "\n", + "This again gives us the gradients in the hidden layer: \n", + "\n", + "$$ \\nabla W_{h} = X^T \\delta_h = (n_{features}, n_{hidden}) ,$$ \n", + "\n", + "$$ \\nabla b_{h} = \\sum_{i=1}^{n_{inputs}} \\delta_h = (n_{hidden}) .$$" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4142969e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# to categorical turns our integer vector into a onehot representation\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# one-hot in numpy\n", + "def to_categorical_numpy(integer_vector):\n", + " n_inputs = len(integer_vector)\n", + " n_categories = np.max(integer_vector) + 1\n", + " onehot_vector = np.zeros((n_inputs, n_categories))\n", + " onehot_vector[range(n_inputs), integer_vector] = 1\n", + " \n", + " return onehot_vector\n", + "\n", + "#Y_train_onehot, Y_test_onehot = to_categorical(Y_train), to_categorical(Y_test)\n", + "Y_train_onehot, Y_test_onehot = to_categorical_numpy(Y_train), to_categorical_numpy(Y_test)\n", + "\n", + "def feed_forward_train(X):\n", + " # weighted sum of inputs to the hidden layer\n", + " z_h = np.matmul(X, hidden_weights) + hidden_bias\n", + " # activation in the hidden layer\n", + " a_h = sigmoid(z_h)\n", + " \n", + " # weighted sum of inputs to the output layer\n", + " z_o = np.matmul(a_h, output_weights) + output_bias\n", + " # softmax output\n", + " # axis 0 holds each input and axis 1 the probabilities of each category\n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " \n", + " # for backpropagation need activations in hidden and output layers\n", + " return a_h, probabilities\n", + "\n", + "def backpropagation(X, Y):\n", + " a_h, probabilities = feed_forward_train(X)\n", + " \n", + " # error in the output layer\n", + " error_output = probabilities - Y\n", + " # error in the hidden layer\n", + " error_hidden = np.matmul(error_output, output_weights.T) * a_h * (1 - a_h)\n", + " \n", + " # gradients for the output layer\n", + " output_weights_gradient = np.matmul(a_h.T, error_output)\n", + " output_bias_gradient = np.sum(error_output, axis=0)\n", + " \n", + " # gradient for the hidden layer\n", + " hidden_weights_gradient = np.matmul(X.T, error_hidden)\n", + " hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " return output_weights_gradient, output_bias_gradient, hidden_weights_gradient, hidden_bias_gradient\n", + "\n", + "print(\"Old accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))\n", + "\n", + "eta = 0.01\n", + "lmbd = 0.01\n", + "for i in range(1000):\n", + " # calculate gradients\n", + " dWo, dBo, dWh, dBh = backpropagation(X_train, Y_train_onehot)\n", + " \n", + " # regularization term gradients\n", + " dWo += lmbd * output_weights\n", + " dWh += lmbd * hidden_weights\n", + " \n", + " # update weights and biases\n", + " output_weights -= eta * dWo\n", + " output_bias -= eta * dBo\n", + " hidden_weights -= eta * dWh\n", + " hidden_bias -= eta * dBh\n", + "\n", + "print(\"New accuracy on training data: \" + str(accuracy_score(predict(X_train), Y_train)))" + ] + }, + { + "cell_type": "markdown", + "id": "4d79c3b3", + "metadata": { + "editable": true + }, + "source": [ + "## Improving performance\n", + "\n", + "As we can see the network does not seem to be learning at all. It seems to be just guessing the label for each image. \n", + "In order to obtain a network that does something useful, we will have to do a bit more work. \n", + "\n", + "The choice of *hyperparameters* such as learning rate and regularization parameter is hugely influential for the performance of the network. Typically a *grid-search* is performed, wherein we test different hyperparameters separated by orders of magnitude. For example we could test the learning rates $\\eta = 10^{-6}, 10^{-5},...,10^{-1}$ with different regularization parameters $\\lambda = 10^{-6},...,10^{-0}$. \n", + "\n", + "Next, we haven't implemented minibatching yet, which introduces stochasticity and is though to act as an important regularizer on the weights. We call a feed-forward + backward pass with a minibatch an *iteration*, and a full training period\n", + "going through the entire dataset ($n/M$ batches) an *epoch*.\n", + "\n", + "If this does not improve network performance, you may want to consider altering the network architecture, adding more neurons or hidden layers. \n", + "Andrew Ng goes through some of these considerations in this [video](https://youtu.be/F1ka6a13S9I). You can find a summary of the video [here](https://kevinzakka.github.io/2016/09/26/applying-deep-learning/)." + ] + }, + { + "cell_type": "markdown", + "id": "58012d93", + "metadata": { + "editable": true + }, + "source": [ + "## Full object-oriented implementation\n", + "\n", + "It is very natural to think of the network as an object, with specific instances of the network\n", + "being realizations of this object with different hyperparameters. An implementation using Python classes provides a clean structure and interface, and the full implementation of our neural network is given below." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ea4b7741", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "class NeuralNetwork:\n", + " def __init__(\n", + " self,\n", + " X_data,\n", + " Y_data,\n", + " n_hidden_neurons=50,\n", + " n_categories=10,\n", + " epochs=10,\n", + " batch_size=100,\n", + " eta=0.1,\n", + " lmbd=0.0):\n", + "\n", + " self.X_data_full = X_data\n", + " self.Y_data_full = Y_data\n", + "\n", + " self.n_inputs = X_data.shape[0]\n", + " self.n_features = X_data.shape[1]\n", + " self.n_hidden_neurons = n_hidden_neurons\n", + " self.n_categories = n_categories\n", + "\n", + " self.epochs = epochs\n", + " self.batch_size = batch_size\n", + " self.iterations = self.n_inputs // self.batch_size\n", + " self.eta = eta\n", + " self.lmbd = lmbd\n", + "\n", + " self.create_biases_and_weights()\n", + "\n", + " def create_biases_and_weights(self):\n", + " self.hidden_weights = np.random.randn(self.n_features, self.n_hidden_neurons)\n", + " self.hidden_bias = np.zeros(self.n_hidden_neurons) + 0.01\n", + "\n", + " self.output_weights = np.random.randn(self.n_hidden_neurons, self.n_categories)\n", + " self.output_bias = np.zeros(self.n_categories) + 0.01\n", + "\n", + " def feed_forward(self):\n", + " # feed-forward for training\n", + " self.z_h = np.matmul(self.X_data, self.hidden_weights) + self.hidden_bias\n", + " self.a_h = sigmoid(self.z_h)\n", + "\n", + " self.z_o = np.matmul(self.a_h, self.output_weights) + self.output_bias\n", + "\n", + " exp_term = np.exp(self.z_o)\n", + " self.probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + "\n", + " def feed_forward_out(self, X):\n", + " # feed-forward for output\n", + " z_h = np.matmul(X, self.hidden_weights) + self.hidden_bias\n", + " a_h = sigmoid(z_h)\n", + "\n", + " z_o = np.matmul(a_h, self.output_weights) + self.output_bias\n", + " \n", + " exp_term = np.exp(z_o)\n", + " probabilities = exp_term / np.sum(exp_term, axis=1, keepdims=True)\n", + " return probabilities\n", + "\n", + " def backpropagation(self):\n", + " error_output = self.probabilities - self.Y_data\n", + " error_hidden = np.matmul(error_output, self.output_weights.T) * self.a_h * (1 - self.a_h)\n", + "\n", + " self.output_weights_gradient = np.matmul(self.a_h.T, error_output)\n", + " self.output_bias_gradient = np.sum(error_output, axis=0)\n", + "\n", + " self.hidden_weights_gradient = np.matmul(self.X_data.T, error_hidden)\n", + " self.hidden_bias_gradient = np.sum(error_hidden, axis=0)\n", + "\n", + " if self.lmbd > 0.0:\n", + " self.output_weights_gradient += self.lmbd * self.output_weights\n", + " self.hidden_weights_gradient += self.lmbd * self.hidden_weights\n", + "\n", + " self.output_weights -= self.eta * self.output_weights_gradient\n", + " self.output_bias -= self.eta * self.output_bias_gradient\n", + " self.hidden_weights -= self.eta * self.hidden_weights_gradient\n", + " self.hidden_bias -= self.eta * self.hidden_bias_gradient\n", + "\n", + " def predict(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return np.argmax(probabilities, axis=1)\n", + "\n", + " def predict_probabilities(self, X):\n", + " probabilities = self.feed_forward_out(X)\n", + " return probabilities\n", + "\n", + " def train(self):\n", + " data_indices = np.arange(self.n_inputs)\n", + "\n", + " for i in range(self.epochs):\n", + " for j in range(self.iterations):\n", + " # pick datapoints with replacement\n", + " chosen_datapoints = np.random.choice(\n", + " data_indices, size=self.batch_size, replace=False\n", + " )\n", + "\n", + " # minibatch training data\n", + " self.X_data = self.X_data_full[chosen_datapoints]\n", + " self.Y_data = self.Y_data_full[chosen_datapoints]\n", + "\n", + " self.feed_forward()\n", + " self.backpropagation()" + ] + }, + { + "cell_type": "markdown", + "id": "04860b2c", + "metadata": { + "editable": true + }, + "source": [ + "## Evaluate model performance on test data\n", + "\n", + "To measure the performance of our network we evaluate how well it does it data it has never seen before, i.e. the test data. \n", + "We measure the performance of the network using the *accuracy* score. \n", + "The accuracy is as you would expect just the number of images correctly labeled divided by the total number of images. A perfect classifier will have an accuracy score of $1$. \n", + "\n", + "$$ \\text{Accuracy} = \\frac{\\sum_{i=1}^n I(\\tilde{y}_i = y_i)}{n} ,$$ \n", + "\n", + "where $I$ is the indicator function, $1$ if $\\tilde{y}_i = y_i$ and $0$ otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b52d4df3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "epochs = 100\n", + "batch_size = 100\n", + "\n", + "dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + "dnn.train()\n", + "test_predict = dnn.predict(X_test)\n", + "\n", + "# accuracy score from scikit library\n", + "print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + "\n", + "# equivalent in numpy\n", + "def accuracy_score_numpy(Y_test, Y_pred):\n", + " return np.sum(Y_test == Y_pred) / len(Y_test)\n", + "\n", + "#print(\"Accuracy score on test set: \", accuracy_score_numpy(Y_test, test_predict))" + ] + }, + { + "cell_type": "markdown", + "id": "6dce68ff", + "metadata": { + "editable": true + }, + "source": [ + "## Adjust hyperparameters\n", + "\n", + "We now perform a grid search to find the optimal hyperparameters for the network. \n", + "Note that we are only using 1 layer with 50 neurons, and human performance is estimated to be around $98\\%$ ($2\\%$ error rate)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "65caeb78", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "# store the models for later use\n", + "DNN_numpy = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "# grid search\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = NeuralNetwork(X_train, Y_train_onehot, eta=eta, lmbd=lmbd, epochs=epochs, batch_size=batch_size,\n", + " n_hidden_neurons=n_hidden_neurons, n_categories=n_categories)\n", + " dnn.train()\n", + " \n", + " DNN_numpy[i][j] = dnn\n", + " \n", + " test_predict = dnn.predict(X_test)\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", accuracy_score(Y_test, test_predict))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "0c44c38e", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fbdc64f1", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# visual representation of grid search\n", + "# uses seaborn heatmap, you can also do this with matplotlib imshow\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_numpy[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e07e69e3", + "metadata": { + "editable": true + }, + "source": [ + "## scikit-learn implementation\n", + "\n", + "**scikit-learn** focuses more\n", + "on traditional machine learning methods, such as regression,\n", + "clustering, decision trees, etc. As such, it has only two types of\n", + "neural networks: Multi Layer Perceptron outputting continuous values,\n", + "*MPLRegressor*, and Multi Layer Perceptron outputting labels,\n", + "*MLPClassifier*. We will see how simple it is to use these classes.\n", + "\n", + "**scikit-learn** implements a few improvements from our neural network,\n", + "such as early stopping, a varying learning rate, different\n", + "optimization methods, etc. We would therefore expect a better\n", + "performance overall." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f48eaa77", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.neural_network import MLPClassifier\n", + "# store models for later use\n", + "DNN_scikit = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + "\n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " dnn = MLPClassifier(hidden_layer_sizes=(n_hidden_neurons), activation='logistic',\n", + " alpha=lmbd, learning_rate_init=eta, max_iter=epochs)\n", + " dnn.fit(X_train, Y_train)\n", + " \n", + " DNN_scikit[i][j] = dnn\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Accuracy score on test set: \", dnn.score(X_test, Y_test))\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "ac3c7bcb", + "metadata": { + "editable": true + }, + "source": [ + "## Visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2d81262e", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " dnn = DNN_scikit[i][j]\n", + " \n", + " train_pred = dnn.predict(X_train) \n", + " test_pred = dnn.predict(X_test)\n", + "\n", + " train_accuracy[i][j] = accuracy_score(Y_train, train_pred)\n", + " test_accuracy[i][j] = accuracy_score(Y_test, test_pred)\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8f5f8f4b", + "metadata": { + "editable": true + }, + "source": [ + "## Building neural networks in Tensorflow and Keras\n", + "\n", + "Now we want to build on the experience gained from our neural network implementation in NumPy and scikit-learn\n", + "and use it to construct a neural network in Tensorflow. Once we have constructed a neural network in NumPy\n", + "and Tensorflow, building one in Keras is really quite trivial, though the performance may suffer. \n", + "\n", + "In our previous example we used only one hidden layer, and in this we will use two. From this it should be quite\n", + "clear how to build one using an arbitrary number of hidden layers, using data structures such as Python lists or\n", + "NumPy arrays." + ] + }, + { + "cell_type": "markdown", + "id": "6ec638b9", + "metadata": { + "editable": true + }, + "source": [ + "## Tensorflow\n", + "\n", + "Tensorflow is an open source library machine learning library\n", + "developed by the Google Brain team for internal use. It was released\n", + "under the Apache 2.0 open source license in November 9, 2015.\n", + "\n", + "Tensorflow is a computational framework that allows you to construct\n", + "machine learning models at different levels of abstraction, from\n", + "high-level, object-oriented APIs like Keras, down to the C++ kernels\n", + "that Tensorflow is built upon. The higher levels of abstraction are\n", + "simpler to use, but less flexible, and our choice of implementation\n", + "should reflect the problems we are trying to solve.\n", + "\n", + "[Tensorflow uses](https://www.tensorflow.org/guide/graphs) so-called graphs to represent your computation\n", + "in terms of the dependencies between individual operations, such that you first build a Tensorflow *graph*\n", + "to represent your model, and then create a Tensorflow *session* to run the graph.\n", + "\n", + "In this guide we will analyze the same data as we did in our NumPy and\n", + "scikit-learn tutorial, gathered from the MNIST database of images. We\n", + "will give an introduction to the lower level Python Application\n", + "Program Interfaces (APIs), and see how we use them to build our graph.\n", + "Then we will build (effectively) the same graph in Keras, to see just\n", + "how simple solving a machine learning problem can be.\n", + "\n", + "To install tensorflow on Unix/Linux systems, use pip as" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6443ca72", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "pip3 install tensorflow" + ] + }, + { + "cell_type": "markdown", + "id": "a8918d58", + "metadata": { + "editable": true + }, + "source": [ + "and/or if you use **anaconda**, just write (or install from the graphical user interface)\n", + "(current release of CPU-only TensorFlow)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "20e9a0f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf tensorflow\n", + "conda activate tf" + ] + }, + { + "cell_type": "markdown", + "id": "1381a34b", + "metadata": { + "editable": true + }, + "source": [ + "To install the current release of GPU TensorFlow" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "80e92af9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda create -n tf-gpu tensorflow-gpu\n", + "conda activate tf-gpu" + ] + }, + { + "cell_type": "markdown", + "id": "074ac69f", + "metadata": { + "editable": true + }, + "source": [ + "## Using Keras\n", + "\n", + "Keras is a high level [neural network](https://en.wikipedia.org/wiki/Application_programming_interface)\n", + "that supports Tensorflow, CTNK and Theano as backends. \n", + "If you have Anaconda installed you may run the following command" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0d710bd3", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "conda install keras" + ] + }, + { + "cell_type": "markdown", + "id": "7adbcab8", + "metadata": { + "editable": true + }, + "source": [ + "You can look up the [instructions here](https://keras.io/) for more information.\n", + "\n", + "We will to a large extent use **keras** in this course." + ] + }, + { + "cell_type": "markdown", + "id": "e17c7253", + "metadata": { + "editable": true + }, + "source": [ + "## Collect and pre-process data\n", + "\n", + "Let us look again at the MINST data set." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "5ae741f5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# import necessary packages\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorflow as tf\n", + "from sklearn import datasets\n", + "\n", + "\n", + "# ensure the same random numbers appear every time\n", + "np.random.seed(0)\n", + "\n", + "# display images in notebook\n", + "%matplotlib inline\n", + "plt.rcParams['figure.figsize'] = (12,12)\n", + "\n", + "\n", + "# download MNIST dataset\n", + "digits = datasets.load_digits()\n", + "\n", + "# define inputs and labels\n", + "inputs = digits.images\n", + "labels = digits.target\n", + "\n", + "print(\"inputs = (n_inputs, pixel_width, pixel_height) = \" + str(inputs.shape))\n", + "print(\"labels = (n_inputs) = \" + str(labels.shape))\n", + "\n", + "\n", + "# flatten the image\n", + "# the value -1 means dimension is inferred from the remaining dimensions: 8x8 = 64\n", + "n_inputs = len(inputs)\n", + "inputs = inputs.reshape(n_inputs, -1)\n", + "print(\"X = (n_inputs, n_features) = \" + str(inputs.shape))\n", + "\n", + "\n", + "# choose some random images to display\n", + "indices = np.arange(n_inputs)\n", + "random_indices = np.random.choice(indices, size=5)\n", + "\n", + "for i, image in enumerate(digits.images[random_indices]):\n", + " plt.subplot(1, 5, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')\n", + " plt.title(\"Label: %d\" % digits.target[random_indices[i]])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "4f7ef6bb", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# one-hot representation of labels\n", + "labels = to_categorical(labels)\n", + "\n", + "# split into train and test data\n", + "train_size = 0.8\n", + "test_size = 1 - train_size\n", + "X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size,\n", + " test_size=test_size)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "7b74e049", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "epochs = 100\n", + "batch_size = 100\n", + "n_neurons_layer1 = 100\n", + "n_neurons_layer2 = 50\n", + "n_categories = 10\n", + "eta_vals = np.logspace(-5, 1, 7)\n", + "lmbd_vals = np.logspace(-5, 1, 7)\n", + "def create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories, eta, lmbd):\n", + " model = Sequential()\n", + " model.add(Dense(n_neurons_layer1, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_neurons_layer2, activation='sigmoid', kernel_regularizer=regularizers.l2(lmbd)))\n", + " model.add(Dense(n_categories, activation='softmax'))\n", + " \n", + " sgd = optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])\n", + " \n", + " return model" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "eaa25983", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "DNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object)\n", + " \n", + "for i, eta in enumerate(eta_vals):\n", + " for j, lmbd in enumerate(lmbd_vals):\n", + " DNN = create_neural_network_keras(n_neurons_layer1, n_neurons_layer2, n_categories,\n", + " eta=eta, lmbd=lmbd)\n", + " DNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0)\n", + " scores = DNN.evaluate(X_test, Y_test)\n", + " \n", + " DNN_keras[i][j] = DNN\n", + " \n", + " print(\"Learning rate = \", eta)\n", + " print(\"Lambda = \", lmbd)\n", + " print(\"Test accuracy: %.3f\" % scores[1])\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "949eca1f", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "# optional\n", + "# visual representation of grid search\n", + "# uses seaborn heatmap, could probably do this in matplotlib\n", + "import seaborn as sns\n", + "\n", + "sns.set()\n", + "\n", + "train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals)))\n", + "\n", + "for i in range(len(eta_vals)):\n", + " for j in range(len(lmbd_vals)):\n", + " DNN = DNN_keras[i][j]\n", + "\n", + " train_accuracy[i][j] = DNN.evaluate(X_train, Y_train)[1]\n", + " test_accuracy[i][j] = DNN.evaluate(X_test, Y_test)[1]\n", + "\n", + " \n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(train_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Training Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()\n", + "\n", + "fig, ax = plt.subplots(figsize = (10, 10))\n", + "sns.heatmap(test_accuracy, annot=True, ax=ax, cmap=\"viridis\")\n", + "ax.set_title(\"Test Accuracy\")\n", + "ax.set_ylabel(\"$\\eta$\")\n", + "ax.set_xlabel(\"$\\lambda$\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "bb8b8ac1", + "metadata": { + "editable": true + }, + "source": [ + "## The Breast Cancer Data, now with Keras" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "9d5ebbb2", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "\n", + "import tensorflow as tf\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Sequential #This allows appending layers to existing models\n", + "from tensorflow.keras.layers import Dense #This allows defining the characteristics of a particular layer\n", + "from tensorflow.keras import optimizers #This allows using whichever optimiser we want (sgd,adam,RMSprop)\n", + "from tensorflow.keras import regularizers #This allows using whichever regularizer we want (l1,l2,l1_l2)\n", + "from tensorflow.keras.utils import to_categorical #This allows using categorical cross entropy as the cost function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.model_selection import train_test_split as splitter\n", + "from sklearn.datasets import load_breast_cancer\n", + "import pickle\n", + "import os \n", + "\n", + "\n", + "\"\"\"Load breast cancer dataset\"\"\"\n", + "\n", + "np.random.seed(0) #create same seed for random number every time\n", + "\n", + "cancer=load_breast_cancer() #Download breast cancer dataset\n", + "\n", + "inputs=cancer.data #Feature matrix of 569 rows (samples) and 30 columns (parameters)\n", + "outputs=cancer.target #Label array of 569 rows (0 for benign and 1 for malignant)\n", + "labels=cancer.feature_names[0:30]\n", + "\n", + "print('The content of the breast cancer dataset is:') #Print information about the datasets\n", + "print(labels)\n", + "print('-------------------------')\n", + "print(\"inputs = \" + str(inputs.shape))\n", + "print(\"outputs = \" + str(outputs.shape))\n", + "print(\"labels = \"+ str(labels.shape))\n", + "\n", + "x=inputs #Reassign the Feature and Label matrices to other variables\n", + "y=outputs\n", + "\n", + "#%% \n", + "\n", + "# Visualisation of dataset (for correlation analysis)\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,2],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean perimeter',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,5],x[:,6],s=40,c=y, cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean compactness',fontweight='bold')\n", + "plt.ylabel('Mean concavity',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,0],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean radius',fontweight='bold')\n", + "plt.ylabel('Mean texture',fontweight='bold')\n", + "plt.show()\n", + "\n", + "plt.figure()\n", + "plt.scatter(x[:,2],x[:,1],s=40,c=y,cmap=plt.cm.Spectral)\n", + "plt.xlabel('Mean perimeter',fontweight='bold')\n", + "plt.ylabel('Mean compactness',fontweight='bold')\n", + "plt.show()\n", + "\n", + "\n", + "# Generate training and testing datasets\n", + "\n", + "#Select features relevant to classification (texture,perimeter,compactness and symmetery) \n", + "#and add to input matrix\n", + "\n", + "temp1=np.reshape(x[:,1],(len(x[:,1]),1))\n", + "temp2=np.reshape(x[:,2],(len(x[:,2]),1))\n", + "X=np.hstack((temp1,temp2)) \n", + "temp=np.reshape(x[:,5],(len(x[:,5]),1))\n", + "X=np.hstack((X,temp)) \n", + "temp=np.reshape(x[:,8],(len(x[:,8]),1))\n", + "X=np.hstack((X,temp)) \n", + "\n", + "X_train,X_test,y_train,y_test=splitter(X,y,test_size=0.1) #Split datasets into training and testing\n", + "\n", + "y_train=to_categorical(y_train) #Convert labels to categorical when using categorical cross entropy\n", + "y_test=to_categorical(y_test)\n", + "\n", + "del temp1,temp2,temp\n", + "\n", + "# %%\n", + "\n", + "# Define tunable parameters\"\n", + "\n", + "eta=np.logspace(-3,-1,3) #Define vector of learning rates (parameter to SGD optimiser)\n", + "lamda=0.01 #Define hyperparameter\n", + "n_layers=2 #Define number of hidden layers in the model\n", + "n_neuron=np.logspace(0,3,4,dtype=int) #Define number of neurons per layer\n", + "epochs=100 #Number of reiterations over the input data\n", + "batch_size=100 #Number of samples per gradient update\n", + "\n", + "# %%\n", + "\n", + "\"\"\"Define function to return Deep Neural Network model\"\"\"\n", + "\n", + "def NN_model(inputsize,n_layers,n_neuron,eta,lamda):\n", + " model=Sequential() \n", + " for i in range(n_layers): #Run loop to add hidden layers to the model\n", + " if (i==0): #First layer requires input dimensions\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda),input_dim=inputsize))\n", + " else: #Subsequent layers are capable of automatic shape inferencing\n", + " model.add(Dense(n_neuron,activation='relu',kernel_regularizer=regularizers.l2(lamda)))\n", + " model.add(Dense(2,activation='softmax')) #2 outputs - ordered and disordered (softmax for prob)\n", + " sgd=optimizers.SGD(lr=eta)\n", + " model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])\n", + " return model\n", + "\n", + " \n", + "Train_accuracy=np.zeros((len(n_neuron),len(eta))) #Define matrices to store accuracy scores as a function\n", + "Test_accuracy=np.zeros((len(n_neuron),len(eta))) #of learning rate and number of hidden neurons for \n", + "\n", + "for i in range(len(n_neuron)): #run loops over hidden neurons and learning rates to calculate \n", + " for j in range(len(eta)): #accuracy scores \n", + " DNN_model=NN_model(X_train.shape[1],n_layers,n_neuron[i],eta[j],lamda)\n", + " DNN_model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=1)\n", + " Train_accuracy[i,j]=DNN_model.evaluate(X_train,y_train)[1]\n", + " Test_accuracy[i,j]=DNN_model.evaluate(X_test,y_test)[1]\n", + " \n", + "\n", + "def plot_data(x,y,data,title=None):\n", + "\n", + " # plot results\n", + " fontsize=16\n", + "\n", + "\n", + " fig = plt.figure()\n", + " ax = fig.add_subplot(111)\n", + " cax = ax.matshow(data, interpolation='nearest', vmin=0, vmax=1)\n", + " \n", + " cbar=fig.colorbar(cax)\n", + " cbar.ax.set_ylabel('accuracy (%)',rotation=90,fontsize=fontsize)\n", + " cbar.set_ticks([0,.2,.4,0.6,0.8,1.0])\n", + " cbar.set_ticklabels(['0%','20%','40%','60%','80%','100%'])\n", + "\n", + " # put text on matrix elements\n", + " for i, x_val in enumerate(np.arange(len(x))):\n", + " for j, y_val in enumerate(np.arange(len(y))):\n", + " c = \"${0:.1f}\\\\%$\".format( 100*data[j,i]) \n", + " ax.text(x_val, y_val, c, va='center', ha='center')\n", + "\n", + " # convert axis vaues to to string labels\n", + " x=[str(i) for i in x]\n", + " y=[str(i) for i in y]\n", + "\n", + "\n", + " ax.set_xticklabels(['']+x)\n", + " ax.set_yticklabels(['']+y)\n", + "\n", + " ax.set_xlabel('$\\\\mathrm{learning\\\\ rate}$',fontsize=fontsize)\n", + " ax.set_ylabel('$\\\\mathrm{hidden\\\\ neurons}$',fontsize=fontsize)\n", + " if title is not None:\n", + " ax.set_title(title)\n", + "\n", + " plt.tight_layout()\n", + "\n", + " plt.show()\n", + " \n", + "plot_data(eta,n_neuron,Train_accuracy, 'training')\n", + "plot_data(eta,n_neuron,Test_accuracy, 'testing')" + ] + }, + { + "cell_type": "markdown", + "id": "f1baeb0b", + "metadata": { + "editable": true + }, + "source": [ + "## Building a neural network code\n", + "\n", + "Here we present a flexible object oriented codebase\n", + "for a feed forward neural network, along with a demonstration of how\n", + "to use it. Before we get into the details of the neural network, we\n", + "will first present some implementations of various schedulers, cost\n", + "functions and activation functions that can be used together with the\n", + "neural network.\n", + "\n", + "The codes here were developed by Eric Reber and Gregor Kajda during spring 2023." + ] + }, + { + "cell_type": "markdown", + "id": "6549fa13", + "metadata": { + "editable": true + }, + "source": [ + "### Learning rate methods\n", + "\n", + "The code below shows object oriented implementations of the Constant,\n", + "Momentum, Adagrad, AdagradMomentum, RMS prop and Adam schedulers. All\n", + "of the classes belong to the shared abstract Scheduler class, and\n", + "share the update_change() and reset() methods allowing for any of the\n", + "schedulers to be seamlessly used during the training stage, as will\n", + "later be shown in the fit() method of the neural\n", + "network. Update_change() only has one parameter, the gradient\n", + "($δ^l_ja^{l−1}_k$), and returns the change which will be subtracted\n", + "from the weights. The reset() function takes no parameters, and resets\n", + "the desired variables. For Constant and Momentum, reset does nothing." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "21062ebc", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "class Scheduler:\n", + " \"\"\"\n", + " Abstract class for Schedulers\n", + " \"\"\"\n", + "\n", + " def __init__(self, eta):\n", + " self.eta = eta\n", + "\n", + " # should be overwritten\n", + " def update_change(self, gradient):\n", + " raise NotImplementedError\n", + "\n", + " # overwritten if needed\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Constant(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + "\n", + " def update_change(self, gradient):\n", + " return self.eta * gradient\n", + " \n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Momentum(Scheduler):\n", + " def __init__(self, eta: float, momentum: float):\n", + " super().__init__(eta)\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " self.change = self.momentum * self.change + self.eta * gradient\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " pass\n", + "\n", + "\n", + "class Adagrad(Scheduler):\n", + " def __init__(self, eta):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " return self.eta * gradient * G_t_inverse\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class AdagradMomentum(Scheduler):\n", + " def __init__(self, eta, momentum):\n", + " super().__init__(eta)\n", + " self.G_t = None\n", + " self.momentum = momentum\n", + " self.change = 0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " if self.G_t is None:\n", + " self.G_t = np.zeros((gradient.shape[0], gradient.shape[0]))\n", + "\n", + " self.G_t += gradient @ gradient.T\n", + "\n", + " G_t_inverse = 1 / (\n", + " delta + np.sqrt(np.reshape(np.diagonal(self.G_t), (self.G_t.shape[0], 1)))\n", + " )\n", + " self.change = self.change * self.momentum + self.eta * gradient * G_t_inverse\n", + " return self.change\n", + "\n", + " def reset(self):\n", + " self.G_t = None\n", + "\n", + "\n", + "class RMS_prop(Scheduler):\n", + " def __init__(self, eta, rho):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.second = 0.0\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + " self.second = self.rho * self.second + (1 - self.rho) * gradient * gradient\n", + " return self.eta * gradient / (np.sqrt(self.second + delta))\n", + "\n", + " def reset(self):\n", + " self.second = 0.0\n", + "\n", + "\n", + "class Adam(Scheduler):\n", + " def __init__(self, eta, rho, rho2):\n", + " super().__init__(eta)\n", + " self.rho = rho\n", + " self.rho2 = rho2\n", + " self.moment = 0\n", + " self.second = 0\n", + " self.n_epochs = 1\n", + "\n", + " def update_change(self, gradient):\n", + " delta = 1e-8 # avoid division ny zero\n", + "\n", + " self.moment = self.rho * self.moment + (1 - self.rho) * gradient\n", + " self.second = self.rho2 * self.second + (1 - self.rho2) * gradient * gradient\n", + "\n", + " moment_corrected = self.moment / (1 - self.rho**self.n_epochs)\n", + " second_corrected = self.second / (1 - self.rho2**self.n_epochs)\n", + "\n", + " return self.eta * moment_corrected / (np.sqrt(second_corrected + delta))\n", + "\n", + " def reset(self):\n", + " self.n_epochs += 1\n", + " self.moment = 0\n", + " self.second = 0" + ] + }, + { + "cell_type": "markdown", + "id": "f965b277", + "metadata": { + "editable": true + }, + "source": [ + "### Usage of the above learning rate schedulers\n", + "\n", + "To initalize a scheduler, simply create the object and pass in the\n", + "necessary parameters such as the learning rate and the momentum as\n", + "shown below. As the Scheduler class is an abstract class it should not\n", + "called directly, and will raise an error upon usage." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "35ab935b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "momentum_scheduler = Momentum(eta=1e-3, momentum=0.9)\n", + "adam_scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)" + ] + }, + { + "cell_type": "markdown", + "id": "b26972b4", + "metadata": { + "editable": true + }, + "source": [ + "Here is a small example for how a segment of code using schedulers\n", + "could look. Switching out the schedulers is simple." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3df9caac", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "weights = np.ones((3,3))\n", + "print(f\"Before scheduler:\\n{weights=}\")\n", + "\n", + "epochs = 10\n", + "for e in range(epochs):\n", + " gradient = np.random.rand(3, 3)\n", + " change = adam_scheduler.update_change(gradient)\n", + " weights = weights - change\n", + " adam_scheduler.reset()\n", + "\n", + "print(f\"\\nAfter scheduler:\\n{weights=}\")" + ] + }, + { + "cell_type": "markdown", + "id": "1c07f6da", + "metadata": { + "editable": true + }, + "source": [ + "### Cost functions\n", + "\n", + "Here we discuss cost functions that can be used when creating the\n", + "neural network. Every cost function takes the target vector as its\n", + "parameter, and returns a function valued only at $x$ such that it may\n", + "easily be differentiated." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "743aa0bd", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "\n", + "def CostOLS(target):\n", + " \n", + " def func(X):\n", + " return (1.0 / target.shape[0]) * np.sum((target - X) ** 2)\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostLogReg(target):\n", + "\n", + " def func(X):\n", + " \n", + " return -(1.0 / target.shape[0]) * np.sum(\n", + " (target * np.log(X + 10e-10)) + ((1 - target) * np.log(1 - X + 10e-10))\n", + " )\n", + "\n", + " return func\n", + "\n", + "\n", + "def CostCrossEntropy(target):\n", + " \n", + " def func(X):\n", + " return -(1.0 / target.size) * np.sum(target * np.log(X + 10e-10))\n", + "\n", + " return func" + ] + }, + { + "cell_type": "markdown", + "id": "c78bdc16", + "metadata": { + "editable": true + }, + "source": [ + "Below we give a short example of how these cost function may be used\n", + "to obtain results if you wish to test them out on your own using\n", + "AutoGrad's automatics differentiation." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4ec3a28c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from autograd import grad\n", + "\n", + "target = np.array([[1, 2, 3]]).T\n", + "a = np.array([[4, 5, 6]]).T\n", + "\n", + "cost_func = CostCrossEntropy\n", + "cost_func_derivative = grad(cost_func(target))\n", + "\n", + "valued_at_a = cost_func_derivative(a)\n", + "print(f\"Derivative of cost function {cost_func.__name__} valued at a:\\n{valued_at_a}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5c924e11", + "metadata": { + "editable": true + }, + "source": [ + "### Activation functions\n", + "\n", + "Finally, before we look at the neural network, we will look at the\n", + "activation functions which can be specified between the hidden layers\n", + "and as the output function. Each function can be valued for any given\n", + "vector or matrix X, and can be differentiated via derivate()." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "87402ee9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from autograd import elementwise_grad\n", + "\n", + "def identity(X):\n", + " return X\n", + "\n", + "\n", + "def sigmoid(X):\n", + " try:\n", + " return 1.0 / (1 + np.exp(-X))\n", + " except FloatingPointError:\n", + " return np.where(X > np.zeros(X.shape), np.ones(X.shape), np.zeros(X.shape))\n", + "\n", + "\n", + "def softmax(X):\n", + " X = X - np.max(X, axis=-1, keepdims=True)\n", + " delta = 10e-10\n", + " return np.exp(X) / (np.sum(np.exp(X), axis=-1, keepdims=True) + delta)\n", + "\n", + "\n", + "def RELU(X):\n", + " return np.where(X > np.zeros(X.shape), X, np.zeros(X.shape))\n", + "\n", + "\n", + "def LRELU(X):\n", + " delta = 10e-4\n", + " return np.where(X > np.zeros(X.shape), X, delta * X)\n", + "\n", + "\n", + "def derivate(func):\n", + " if func.__name__ == \"RELU\":\n", + "\n", + " def func(X):\n", + " return np.where(X > 0, 1, 0)\n", + "\n", + " return func\n", + "\n", + " elif func.__name__ == \"LRELU\":\n", + "\n", + " def func(X):\n", + " delta = 10e-4\n", + " return np.where(X > 0, 1, delta)\n", + "\n", + " return func\n", + "\n", + " else:\n", + " return elementwise_grad(func)" + ] + }, + { + "cell_type": "markdown", + "id": "45ddd0bc", + "metadata": { + "editable": true + }, + "source": [ + "Below follows a short demonstration of how to use an activation\n", + "function. The derivative of the activation function will be important\n", + "when calculating the output delta term during backpropagation. Note\n", + "that derivate() can also be used for cost functions for a more\n", + "generalized approach." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "77034679", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "z = np.array([[4, 5, 6]]).T\n", + "print(f\"Input to activation function:\\n{z}\")\n", + "\n", + "act_func = sigmoid\n", + "a = act_func(z)\n", + "print(f\"\\nOutput from {act_func.__name__} activation function:\\n{a}\")\n", + "\n", + "act_func_derivative = derivate(act_func)\n", + "valued_at_z = act_func_derivative(a)\n", + "print(f\"\\nDerivative of {act_func.__name__} activation function valued at z:\\n{valued_at_z}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9fd8140f", + "metadata": { + "editable": true + }, + "source": [ + "### The Neural Network\n", + "\n", + "Now that we have gotten a good understanding of the implementation of\n", + "some important components, we can take a look at an object oriented\n", + "implementation of a feed forward neural network. The feed forward\n", + "neural network has been implemented as a class named FFNN, which can\n", + "be initiated as a regressor or classifier dependant on the choice of\n", + "cost function. The FFNN can have any number of input nodes, hidden\n", + "layers with any amount of hidden nodes, and any amount of output nodes\n", + "meaning it can perform multiclass classification as well as binary\n", + "classification and regression problems. Although there is a lot of\n", + "code present, it makes for an easy to use and generalizeable interface\n", + "for creating many types of neural networks as will be demonstrated\n", + "below." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7540d755", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import math\n", + "import autograd.numpy as np\n", + "import sys\n", + "import warnings\n", + "from autograd import grad, elementwise_grad\n", + "from random import random, seed\n", + "from copy import deepcopy, copy\n", + "from typing import Tuple, Callable\n", + "from sklearn.utils import resample\n", + "\n", + "warnings.simplefilter(\"error\")\n", + "\n", + "\n", + "class FFNN:\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Feed Forward Neural Network with interface enabling flexible design of a\n", + " nerual networks architecture and the specification of activation function\n", + " in the hidden layers and output layer respectively. This model can be used\n", + " for both regression and classification problems, depending on the output function.\n", + "\n", + " Attributes:\n", + " ------------\n", + " I dimensions (tuple[int]): A list of positive integers, which specifies the\n", + " number of nodes in each of the networks layers. The first integer in the array\n", + " defines the number of nodes in the input layer, the second integer defines number\n", + " of nodes in the first hidden layer and so on until the last number, which\n", + " specifies the number of nodes in the output layer.\n", + " II hidden_func (Callable): The activation function for the hidden layers\n", + " III output_func (Callable): The activation function for the output layer\n", + " IV cost_func (Callable): Our cost function\n", + " V seed (int): Sets random seed, makes results reproducible\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " dimensions: tuple[int],\n", + " hidden_func: Callable = sigmoid,\n", + " output_func: Callable = lambda x: x,\n", + " cost_func: Callable = CostOLS,\n", + " seed: int = None,\n", + " ):\n", + " self.dimensions = dimensions\n", + " self.hidden_func = hidden_func\n", + " self.output_func = output_func\n", + " self.cost_func = cost_func\n", + " self.seed = seed\n", + " self.weights = list()\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + " self.classification = None\n", + "\n", + " self.reset_weights()\n", + " self._set_classification()\n", + "\n", + " def fit(\n", + " self,\n", + " X: np.ndarray,\n", + " t: np.ndarray,\n", + " scheduler: Scheduler,\n", + " batches: int = 1,\n", + " epochs: int = 100,\n", + " lam: float = 0,\n", + " X_val: np.ndarray = None,\n", + " t_val: np.ndarray = None,\n", + " ):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " This function performs the training the neural network by performing the feedforward and backpropagation\n", + " algorithm to update the networks weights.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray) : training data\n", + " II t (np.ndarray) : target data\n", + " III scheduler (Scheduler) : specified scheduler (algorithm for optimization of gradient descent)\n", + " IV scheduler_args (list[int]) : list of all arguments necessary for scheduler\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " V batches (int) : number of batches the datasets are split into, default equal to 1\n", + " VI epochs (int) : number of iterations used to train the network, default equal to 100\n", + " VII lam (float) : regularization hyperparameter lambda\n", + " VIII X_val (np.ndarray) : validation set\n", + " IX t_val (np.ndarray) : validation target set\n", + "\n", + " Returns:\n", + " ------------\n", + " I scores (dict) : A dictionary containing the performance metrics of the model.\n", + " The number of the metrics depends on the parameters passed to the fit-function.\n", + "\n", + " \"\"\"\n", + "\n", + " # setup \n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " val_set = False\n", + " if X_val is not None and t_val is not None:\n", + " val_set = True\n", + "\n", + " # creating arrays for score metrics\n", + " train_errors = np.empty(epochs)\n", + " train_errors.fill(np.nan)\n", + " val_errors = np.empty(epochs)\n", + " val_errors.fill(np.nan)\n", + "\n", + " train_accs = np.empty(epochs)\n", + " train_accs.fill(np.nan)\n", + " val_accs = np.empty(epochs)\n", + " val_accs.fill(np.nan)\n", + "\n", + " self.schedulers_weight = list()\n", + " self.schedulers_bias = list()\n", + "\n", + " batch_size = X.shape[0] // batches\n", + "\n", + " X, t = resample(X, t)\n", + "\n", + " # this function returns a function valued only at X\n", + " cost_function_train = self.cost_func(t)\n", + " if val_set:\n", + " cost_function_val = self.cost_func(t_val)\n", + "\n", + " # create schedulers for each weight matrix\n", + " for i in range(len(self.weights)):\n", + " self.schedulers_weight.append(copy(scheduler))\n", + " self.schedulers_bias.append(copy(scheduler))\n", + "\n", + " print(f\"{scheduler.__class__.__name__}: Eta={scheduler.eta}, Lambda={lam}\")\n", + "\n", + " try:\n", + " for e in range(epochs):\n", + " for i in range(batches):\n", + " # allows for minibatch gradient descent\n", + " if i == batches - 1:\n", + " # If the for loop has reached the last batch, take all thats left\n", + " X_batch = X[i * batch_size :, :]\n", + " t_batch = t[i * batch_size :, :]\n", + " else:\n", + " X_batch = X[i * batch_size : (i + 1) * batch_size, :]\n", + " t_batch = t[i * batch_size : (i + 1) * batch_size, :]\n", + "\n", + " self._feedforward(X_batch)\n", + " self._backpropagate(X_batch, t_batch, lam)\n", + "\n", + " # reset schedulers for each epoch (some schedulers pass in this call)\n", + " for scheduler in self.schedulers_weight:\n", + " scheduler.reset()\n", + "\n", + " for scheduler in self.schedulers_bias:\n", + " scheduler.reset()\n", + "\n", + " # computing performance metrics\n", + " pred_train = self.predict(X)\n", + " train_error = cost_function_train(pred_train)\n", + "\n", + " train_errors[e] = train_error\n", + " if val_set:\n", + " \n", + " pred_val = self.predict(X_val)\n", + " val_error = cost_function_val(pred_val)\n", + " val_errors[e] = val_error\n", + "\n", + " if self.classification:\n", + " train_acc = self._accuracy(self.predict(X), t)\n", + " train_accs[e] = train_acc\n", + " if val_set:\n", + " val_acc = self._accuracy(pred_val, t_val)\n", + " val_accs[e] = val_acc\n", + "\n", + " # printing progress bar\n", + " progression = e / epochs\n", + " print_length = self._progress_bar(\n", + " progression,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " except KeyboardInterrupt:\n", + " # allows for stopping training at any point and seeing the result\n", + " pass\n", + "\n", + " # visualization of training progression (similiar to tensorflow progression bar)\n", + " sys.stdout.write(\"\\r\" + \" \" * print_length)\n", + " sys.stdout.flush()\n", + " self._progress_bar(\n", + " 1,\n", + " train_error=train_errors[e],\n", + " train_acc=train_accs[e],\n", + " val_error=val_errors[e],\n", + " val_acc=val_accs[e],\n", + " )\n", + " sys.stdout.write(\"\")\n", + "\n", + " # return performance metrics for the entire run\n", + " scores = dict()\n", + "\n", + " scores[\"train_errors\"] = train_errors\n", + "\n", + " if val_set:\n", + " scores[\"val_errors\"] = val_errors\n", + "\n", + " if self.classification:\n", + " scores[\"train_accs\"] = train_accs\n", + "\n", + " if val_set:\n", + " scores[\"val_accs\"] = val_accs\n", + "\n", + " return scores\n", + "\n", + " def predict(self, X: np.ndarray, *, threshold=0.5):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs prediction after training of the network has been finished.\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Optional Parameters:\n", + " ------------\n", + " II threshold (float) : sets minimal value for a prediction to be predicted as the positive class\n", + " in classification problems\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " This vector is thresholded if regression=False, meaning that classification results\n", + " in a vector of 1s and 0s, while regressions in an array of decimal numbers\n", + "\n", + " \"\"\"\n", + "\n", + " predict = self._feedforward(X)\n", + "\n", + " if self.classification:\n", + " return np.where(predict > threshold, 1, 0)\n", + " else:\n", + " return predict\n", + "\n", + " def reset_weights(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Resets/Reinitializes the weights in order to train the network for a new problem.\n", + "\n", + " \"\"\"\n", + " if self.seed is not None:\n", + " np.random.seed(self.seed)\n", + "\n", + " self.weights = list()\n", + " for i in range(len(self.dimensions) - 1):\n", + " weight_array = np.random.randn(\n", + " self.dimensions[i] + 1, self.dimensions[i + 1]\n", + " )\n", + " weight_array[0, :] = np.random.randn(self.dimensions[i + 1]) * 0.01\n", + "\n", + " self.weights.append(weight_array)\n", + "\n", + " def _feedforward(self, X: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates the activation of each layer starting at the input and ending at the output.\n", + " Each following activation is calculated from a weighted sum of each of the preceeding\n", + " activations (except in the case of the input layer).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each\n", + "\n", + " Returns:\n", + " ------------\n", + " I z (np.ndarray): A prediction vector (row) for each row in our design matrix\n", + " \"\"\"\n", + "\n", + " # reset matrices\n", + " self.a_matrices = list()\n", + " self.z_matrices = list()\n", + "\n", + " # if X is just a vector, make it into a matrix\n", + " if len(X.shape) == 1:\n", + " X = X.reshape((1, X.shape[0]))\n", + "\n", + " # Add a coloumn of zeros as the first coloumn of the design matrix, in order\n", + " # to add bias to our data\n", + " bias = np.ones((X.shape[0], 1)) * 0.01\n", + " X = np.hstack([bias, X])\n", + "\n", + " # a^0, the nodes in the input layer (one a^0 for each row in X - where the\n", + " # exponent indicates layer number).\n", + " a = X\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(a)\n", + "\n", + " # The feed forward algorithm\n", + " for i in range(len(self.weights)):\n", + " if i < len(self.weights) - 1:\n", + " z = a @ self.weights[i]\n", + " self.z_matrices.append(z)\n", + " a = self.hidden_func(z)\n", + " # bias column again added to the data here\n", + " bias = np.ones((a.shape[0], 1)) * 0.01\n", + " a = np.hstack([bias, a])\n", + " self.a_matrices.append(a)\n", + " else:\n", + " try:\n", + " # a^L, the nodes in our output layers\n", + " z = a @ self.weights[i]\n", + " a = self.output_func(z)\n", + " self.a_matrices.append(a)\n", + " self.z_matrices.append(z)\n", + " except Exception as OverflowError:\n", + " print(\n", + " \"OverflowError in fit() in FFNN\\nHOW TO DEBUG ERROR: Consider lowering your learning rate or scheduler specific parameters such as momentum, or check if your input values need scaling\"\n", + " )\n", + "\n", + " # this will be a^L\n", + " return a\n", + "\n", + " def _backpropagate(self, X, t, lam):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Performs the backpropagation algorithm. In other words, this method\n", + " calculates the gradient of all the layers starting at the\n", + " output layer, and moving from right to left accumulates the gradient until\n", + " the input layer is reached. Each layers respective weights are updated while\n", + " the algorithm propagates backwards from the output layer (auto-differentation in reverse mode).\n", + "\n", + " Parameters:\n", + " ------------\n", + " I X (np.ndarray): The design matrix, with n rows of p features each.\n", + " II t (np.ndarray): The target vector, with n rows of p targets.\n", + " III lam (float32): regularization parameter used to punish the weights in case of overfitting\n", + "\n", + " Returns:\n", + " ------------\n", + " No return value.\n", + "\n", + " \"\"\"\n", + " out_derivative = derivate(self.output_func)\n", + " hidden_derivative = derivate(self.hidden_func)\n", + "\n", + " for i in range(len(self.weights) - 1, -1, -1):\n", + " # delta terms for output\n", + " if i == len(self.weights) - 1:\n", + " # for multi-class classification\n", + " if (\n", + " self.output_func.__name__ == \"softmax\"\n", + " ):\n", + " delta_matrix = self.a_matrices[i + 1] - t\n", + " # for single class classification\n", + " else:\n", + " cost_func_derivative = grad(self.cost_func(t))\n", + " delta_matrix = out_derivative(\n", + " self.z_matrices[i + 1]\n", + " ) * cost_func_derivative(self.a_matrices[i + 1])\n", + "\n", + " # delta terms for hidden layer\n", + " else:\n", + " delta_matrix = (\n", + " self.weights[i + 1][1:, :] @ delta_matrix.T\n", + " ).T * hidden_derivative(self.z_matrices[i + 1])\n", + "\n", + " # calculate gradient\n", + " gradient_weights = self.a_matrices[i][:, 1:].T @ delta_matrix\n", + " gradient_bias = np.sum(delta_matrix, axis=0).reshape(\n", + " 1, delta_matrix.shape[1]\n", + " )\n", + "\n", + " # regularization term\n", + " gradient_weights += self.weights[i][1:, :] * lam\n", + "\n", + " # use scheduler\n", + " update_matrix = np.vstack(\n", + " [\n", + " self.schedulers_bias[i].update_change(gradient_bias),\n", + " self.schedulers_weight[i].update_change(gradient_weights),\n", + " ]\n", + " )\n", + "\n", + " # update weights and bias\n", + " self.weights[i] -= update_matrix\n", + "\n", + " def _accuracy(self, prediction: np.ndarray, target: np.ndarray):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Calculates accuracy of given prediction to target\n", + "\n", + " Parameters:\n", + " ------------\n", + " I prediction (np.ndarray): vector of predicitons output network\n", + " (1s and 0s in case of classification, and real numbers in case of regression)\n", + " II target (np.ndarray): vector of true values (What the network ideally should predict)\n", + "\n", + " Returns:\n", + " ------------\n", + " A floating point number representing the percentage of correctly classified instances.\n", + " \"\"\"\n", + " assert prediction.size == target.size\n", + " return np.average((target == prediction))\n", + " def _set_classification(self):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Decides if FFNN acts as classifier (True) og regressor (False),\n", + " sets self.classification during init()\n", + " \"\"\"\n", + " self.classification = False\n", + " if (\n", + " self.cost_func.__name__ == \"CostLogReg\"\n", + " or self.cost_func.__name__ == \"CostCrossEntropy\"\n", + " ):\n", + " self.classification = True\n", + "\n", + " def _progress_bar(self, progression, **kwargs):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Displays progress of training\n", + " \"\"\"\n", + " print_length = 40\n", + " num_equals = int(progression * print_length)\n", + " num_not = print_length - num_equals\n", + " arrow = \">\" if num_equals > 0 else \"\"\n", + " bar = \"[\" + \"=\" * (num_equals - 1) + arrow + \"-\" * num_not + \"]\"\n", + " perc_print = self._format(progression * 100, decimals=5)\n", + " line = f\" {bar} {perc_print}% \"\n", + "\n", + " for key in kwargs:\n", + " if not np.isnan(kwargs[key]):\n", + " value = self._format(kwargs[key], decimals=4)\n", + " line += f\"| {key}: {value} \"\n", + " sys.stdout.write(\"\\r\" + line)\n", + " sys.stdout.flush()\n", + " return len(line)\n", + "\n", + " def _format(self, value, decimals=4):\n", + " \"\"\"\n", + " Description:\n", + " ------------\n", + " Formats decimal numbers for progress bar\n", + " \"\"\"\n", + " if value > 0:\n", + " v = value\n", + " elif value < 0:\n", + " v = -10 * value\n", + " else:\n", + " v = 1\n", + " n = 1 + math.floor(math.log10(v))\n", + " if n >= decimals - 1:\n", + " return str(round(value))\n", + " return f\"{value:.{decimals-n-1}f}\"" + ] + }, + { + "cell_type": "markdown", + "id": "5ee996ef", + "metadata": { + "editable": true + }, + "source": [ + "Before we make a model, we will quickly generate a dataset we can use\n", + "for our linear regression problem as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "183b180b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "import autograd.numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "def SkrankeFunction(x, y):\n", + " return np.ravel(0 + 1*x + 2*y + 3*x**2 + 4*x*y + 5*y**2)\n", + "\n", + "def create_X(x, y, n):\n", + " if len(x.shape) > 1:\n", + " x = np.ravel(x)\n", + " y = np.ravel(y)\n", + "\n", + " N = len(x)\n", + " l = int((n + 1) * (n + 2) / 2) # Number of elements in beta\n", + " X = np.ones((N, l))\n", + "\n", + " for i in range(1, n + 1):\n", + " q = int((i) * (i + 1) / 2)\n", + " for k in range(i + 1):\n", + " X[:, q + k] = (x ** (i - k)) * (y**k)\n", + "\n", + " return X\n", + "\n", + "step=0.5\n", + "x = np.arange(0, 1, step)\n", + "y = np.arange(0, 1, step)\n", + "x, y = np.meshgrid(x, y)\n", + "target = SkrankeFunction(x, y)\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "poly_degree=3\n", + "X = create_X(x, y, poly_degree)\n", + "\n", + "X_train, X_test, t_train, t_test = train_test_split(X, target)" + ] + }, + { + "cell_type": "markdown", + "id": "21a48508", + "metadata": { + "editable": true + }, + "source": [ + "Now that we have our dataset ready for the regression, we can create\n", + "our regressor. Note that with the seed parameter, we can make sure our\n", + "results stay the same every time we run the neural network. For\n", + "inititialization, we simply specify the dimensions (we wish the amount\n", + "of input nodes to be equal to the datapoints, and the output to\n", + "predict one value)." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "37eba90c", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "linear_regression = FFNN((input_nodes, output_nodes), output_func=identity, cost_func=CostOLS, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "58a6b726", + "metadata": { + "editable": true + }, + "source": [ + "We then fit our model with our training data using the scheduler of our choice." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "046d7076", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Constant(eta=1e-3)\n", + "scores = linear_regression.fit(X_train, t_train, scheduler)" + ] + }, + { + "cell_type": "markdown", + "id": "981e95ce", + "metadata": { + "editable": true + }, + "source": [ + "Due to the progress bar we can see the MSE (train_error) throughout\n", + "the FFNN's training. Note that the fit() function has some optional\n", + "parameters with defualt arguments. For example, the regularization\n", + "hyperparameter can be left ignored if not needed, and equally the FFNN\n", + "will by default run for 100 epochs. These can easily be changed, such\n", + "as for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6da23296", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "linear_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scores = linear_regression.fit(X_train, t_train, scheduler, lam=1e-4, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ba0fea41", + "metadata": { + "editable": true + }, + "source": [ + "We see that given more epochs to train on, the regressor reaches a lower MSE.\n", + "\n", + "Let us then switch to a binary classification. We use a binary\n", + "classification dataset, and follow a similar setup to the regression\n", + "case." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "1bd5c3e5", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "wisconsin = load_breast_cancer()\n", + "X = wisconsin.data\n", + "target = wisconsin.target\n", + "target = target.reshape(target.shape[0], 1)\n", + "\n", + "X_train, X_val, t_train, t_val = train_test_split(X, target)\n", + "\n", + "scaler = MinMaxScaler()\n", + "scaler.fit(X_train)\n", + "X_train = scaler.transform(X_train)\n", + "X_val = scaler.transform(X_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "9923ffbf", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "markdown", + "id": "95431510", + "metadata": { + "editable": true + }, + "source": [ + "We will now make use of our validation data by passing it into our fit function as a keyword argument" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "9d71cef9", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-3, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "acfee190", + "metadata": { + "editable": true + }, + "source": [ + "Finally, we will create a neural network with 2 hidden layers with activation functions." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "c834fb60", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "input_nodes = X_train.shape[1]\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 1\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "neural_network = FFNN(dims, hidden_func=RELU, output_func=sigmoid, cost_func=CostLogReg, seed=2023)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0c557301", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "neural_network.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = neural_network.fit(X_train, t_train, scheduler, epochs=1000, X_val=X_val, t_val=t_val)" + ] + }, + { + "cell_type": "markdown", + "id": "750490a3", + "metadata": { + "editable": true + }, + "source": [ + "### Multiclass classification\n", + "\n", + "Finally, we will demonstrate the use case of multiclass classification\n", + "using our FFNN with the famous MNIST dataset, which contain images of\n", + "digits between the range of 0 to 9." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "5318d06b", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "from sklearn.datasets import load_digits\n", + "\n", + "def onehot(target: np.ndarray):\n", + " onehot = np.zeros((target.size, target.max() + 1))\n", + " onehot[np.arange(target.size), target] = 1\n", + " return onehot\n", + "\n", + "digits = load_digits()\n", + "\n", + "X = digits.data\n", + "target = digits.target\n", + "target = onehot(target)\n", + "\n", + "input_nodes = 64\n", + "hidden_nodes1 = 100\n", + "hidden_nodes2 = 30\n", + "output_nodes = 10\n", + "\n", + "dims = (input_nodes, hidden_nodes1, hidden_nodes2, output_nodes)\n", + "\n", + "multiclass = FFNN(dims, hidden_func=LRELU, output_func=softmax, cost_func=CostCrossEntropy)\n", + "\n", + "multiclass.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "\n", + "scheduler = Adam(eta=1e-4, rho=0.9, rho2=0.999)\n", + "scores = multiclass.fit(X, target, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "ff519831", + "metadata": { + "editable": true + }, + "source": [ + "## Testing the XOR gate and other gates\n", + "\n", + "Let us now use our code to test the XOR gate." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "57e3fb33", + "metadata": { + "collapsed": false, + "editable": true + }, + "outputs": [], + "source": [ + "X = np.array([ [0, 0], [0, 1], [1, 0],[1, 1]],dtype=np.float64)\n", + "\n", + "# The XOR gate\n", + "yXOR = np.array( [[ 0], [1] ,[1], [0]])\n", + "\n", + "input_nodes = X.shape[1]\n", + "output_nodes = 1\n", + "\n", + "logistic_regression = FFNN((input_nodes, output_nodes), output_func=sigmoid, cost_func=CostLogReg, seed=2023)\n", + "logistic_regression.reset_weights() # reset weights such that previous runs or reruns don't affect the weights\n", + "scheduler = Adam(eta=1e-1, rho=0.9, rho2=0.999)\n", + "scores = logistic_regression.fit(X, yXOR, scheduler, epochs=1000)" + ] + }, + { + "cell_type": "markdown", + "id": "e4c08bad", + "metadata": { + "editable": true + }, + "source": [ + "Not bad, but the results depend strongly on the learning reate. Try different learning rates." + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +}