From 8dba68394d3296d664259e16c7563b0ce4176ab7 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Thu, 7 Apr 2022 18:00:02 +0530 Subject: [PATCH 01/76] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 8d086e0..7480ce8 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,23 @@ Feel free to use them for educational and research purposes. + + Object Detection using Sliding Window and Image Pyramid + A basic object detection implementation using sliding window and image pyramid on top of an image classifer + + + + + + + Object Detection using Selective Search + A basic object detection implementation using selective search on top of an image classifer + + + + + + From 16bf43f079a891e46f9703ba862ab24c1da67c16 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Sat, 9 Apr 2022 21:51:32 +0530 Subject: [PATCH 02/76] Update README.md Added Link to Kaggle Notebooks --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7480ce8..86ad5e5 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,8 @@ Feel free to use them for educational and research purposes. An implementation of Attention Mechanism and Positional Embeddings on a text classification task - +
+ Kaggle @@ -99,7 +100,8 @@ Feel free to use them for educational and research purposes. An implementation of Siamese Network for finding Image Similarity - +
+ Kaggle @@ -107,7 +109,8 @@ Feel free to use them for educational and research purposes. An implementation of Variational Auto Encoder to generate Augmentations for MNIST Handwritten Digits - +
+ Kaggle @@ -115,7 +118,8 @@ Feel free to use them for educational and research purposes. A basic object detection implementation using sliding window and image pyramid on top of an image classifer - +
+ Kaggle @@ -123,7 +127,8 @@ Feel free to use them for educational and research purposes. A basic object detection implementation using selective search on top of an image classifer - +
+ Kaggle From 38c19aa708b3c200870d8481d4ce67c3c58530fa Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 15 Apr 2022 16:40:18 +0100 Subject: [PATCH 03/76] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86ad5e5..792eb8a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A series of code examples for all sorts of machine learning tasks and applicatio The notebooks are meant to be minimal and easily reusable and extendable. -Feel free to use them for educational and research purposes. +You are free to use them for educational and research purposes. From 308063528f522d31d86d23f1d70b4902952ceabc Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Tue, 19 Apr 2022 22:58:35 +0530 Subject: [PATCH 04/76] Update README.md --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 792eb8a..86b2daf 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ You are free to use them for educational and research purposes. - + + + + + + + From 6aa50f282b2c5d9a7a3aa054466d095706b3549f Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:14:45 +0100 Subject: [PATCH 05/76] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 86b2daf..2fd0b89 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,8 @@ You are free to use them for educational and research purposes.
Text Classification using Attention Mechanism and Positional EmbeddingsText Classification using Transformer An implementation of Attention Mechanism and Positional Embeddings on a text classification task @@ -130,6 +130,15 @@ You are free to use them for educational and research purposes.
Kaggle
Neural Machine Translation using TransformerAn implementation of Transformer to translate human readabke dates in any format to YYYY-MM-DD format. + +
+ Kaggle
+ +If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. Reach out on [Twitter](https://twitter.com/omarsar0) if you have any questions. From 88f363caa139b2a53a022167936b30a5a2531152 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:22:43 +0100 Subject: [PATCH 06/76] Create img --- img | 1 + 1 file changed, 1 insertion(+) create mode 100644 img diff --git a/img b/img new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/img @@ -0,0 +1 @@ + From bfc2a30c28461e209f6c60f75d18dc8aac066a6a Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:22:58 +0100 Subject: [PATCH 07/76] Delete img --- img | 1 - 1 file changed, 1 deletion(-) delete mode 100644 img diff --git a/img b/img deleted file mode 100644 index 8b13789..0000000 --- a/img +++ /dev/null @@ -1 +0,0 @@ - From d425506aa925b620241f503f9eac914351e54ce7 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:25:00 +0100 Subject: [PATCH 08/76] Add files via upload --- bow.png | Bin 0 -> 53196 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 bow.png diff --git a/bow.png b/bow.png new file mode 100644 index 0000000000000000000000000000000000000000..7b17e99b02ca99fb72f062219e1e7afabe16c96b GIT binary patch literal 53196 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 )g1jZZci5KIBZ z^TD*7vE5WZcL8vx>Jq#Wc)zN}ZoM?BVO!#Fcg7IO>^Nz%y}ZZwnYbPb8k2StiEoM9 zfS*{Eh1$QXh2O1M592H6uxTTm2!z>2_>Ietf46UXwr z@zh4RL~gPB+0@QuN(<{2(@p-=cD^5K=hl|~@t)(PxPR5`Qpwqd&%Z@H_^!%HedMV( zQ2jd=UsM;mgq`Df9Fcb^ZioGD!7wOKAz)h`8b=oME_6C4_kHex;2T(GvLz(E$B449 zF~Ot2YE)1S=Sbz9M!$+x$Y}EBjq$l^o$DE;TOOsoLxR~61FkP^9WeGplyV?+rQ!Wx zSvO2DBpzJg>@fDjvCoYe&seGKTM>@cjQ4BGB6RCto5`a=Y1ruO{o&xz8QZ8rGXJwF zHv-*gV_iZ`w+}w}RX}4F*_?O2u7kD^_#jv5W1AGyu@ zYl3-l_LAwqk5JDcICsLsCz5;TJJt8SbW8za#kiifVr3SKZxErY*o?24vw*L^11va+ zwZIXK-^UvXS~-|wSk_Wa%=K5OHdNZUPJ|@GoWT~bsXc82WhiyuP^}J$H6};gqJjBx6Qma8+xCdsNa?`84(Q*E*)AYJ(*2Ntxc4VLW05 zaf{OW4dL0F7SzgX+4-E3>2b!g*mxt!bky=f%6jRQZrtJQQ0!`kTY z*!iYq;R38kb;HMoVvqWG%=4HvNh9N}NJ>G1#)c6PW~w)3z4;*p7b>_R0lrqIbP*p9 zENLWTXAVv?J6&&HBhS>{ye7O~Z2j)R)?{N3@wYk)EkbDM>#V&I%T4?-W;5VU7lt<) ze~9y@fg5?AEk!^~{#2Ppi5PZn$R2P81?RQF>w3Mo_Qj=C@R7awnm^*3R(P?d!Q3r_VQl*y) z|HRPJE4xCuckyU}9@5dy3c$$iZ!+8UGJ%`gZ7!v4rLWC})@%3@G<0su&a%0|qHu5F z%Hoqj8=};_x!&HWu`tAmtnU3rHX?a-9$k^OpLEF%l=8v2?(|r#?`Rwn2(vMFFE=y= z9T8vRgbD!x7DsAyf4M`*MY6S!?v}dDUYv zg~WY(jwA1PgAJ4B8m9NvPfmVhVzoX8zk8hs8ir37hug*hEdGuh3}Gh?5?@yc8=fFN zDMf>O6kQ52(}i?-q>&^PB5GXXPRWerP9P=!=z3Zf;yj`^^8xz=w}o}Nk(m0lI7!|I zH^FwtKdk@w%Kz#^z63vlo&RnOZ+nx<*iM8&2fg-plAPrjtc7*a`AbaAWsEi?R8A}8 zN+vS7?%;q6ax-~lf1-sMnk(16Xe;Cv(3fsq+Sl?eMvLxjYaLmP)3QxZkXNrqJt-eM ziQ4b@IIyN~$GoR0ln=$zq3cXv!Z{O6qy%5NA}}~UTVSY6NE&078qSYF=JOht(k}}& z;wWOpy2m+mG@7p|OVMV6aRc+CtnjMrm+tH@yqT3MCjxiLx5z8MoGQr5b+S|lkACPUk@RfeUdW8C~h=m zI-#qhby1RB+6~0&J`B4!qyws4JnuJtMkvlj$UFz)H(kt7=O=uStfkHxZf_>avCMRg zK^{&&+W#^{LN^X`5WE-29wNMo;&zKnhPCUPfOkOq{!=$CW9yz%Vd9a;pvUW5HiDa?e67LOx+pQnNk_FH<-_q8kQ ztfv6mgQ=Pc1N^iSGqIQJiZG`(P!_)=$>za8FiBchqba6Yp4Z!*NpULXBEeR!?^3zA zN9PekHiRA_|sA>zTASZXWg zG>g4JE+L}skmi2zchljwr5pI_D5J?xP+LQ z8jp=jbqK&|9^#w6E8#+t*w=>3z5-gKK8G6SM~^ur!0?BNc(NLXxReruy9c!9#l7Mo2Xbfv^ClI|rQ>FN_gP+KHyifSNRAYIIb{99Rqo>1be*qaG{ zuCTcCWCdJd(Jb>4ZcVs>P{8+jdH6<})^4W-|HcZDJ#m4VKH*5)$As7lj`4k&&;62WTy{W+nu<7uNGvnHY)5`EXx(YWm!YzIc`Y-I4xwsxeN zK4#_lRiJ`aTy{l}lSYD+b0!xpWPx^gligKW_wIf;3Y`F{8?D8nLlv4E_LVjoWR_A> zZ6&KZICKgsRa_U4kkpQYIq>z0cmylGbThKUxQ_wK>N#M801@DPc^nk5A}dU(Jm73Olh-REj7!9gFs8alB zH1gOpJca*9iJUt}nE)6*{598M|B#8De+H3%GTX%yz&ies<~>*e4xiHZoTnsPi@=fy zTwvNzAHdEpcc^;gevbvDj>XUr6X?aK0~2lCdOV0UDDb^V1;rkpK>!PllYw z$^x4d3nplX!ig8-3{WxzyY!9QXN|SN-)mYp|6mn>k%X|x0`@984$jAE`SKXnUv>O( z&2#$rK7zQGqk^cZE8RmB$vx?6vB87e07vIbCzE_31}rmDfPm83Ty8d7!afR}*PlyF zDdy^@_Jk~sL*^aAn)JEH zw+(IEjqz^Z&)k->q)2SUThM{Q@}SmOArm~6s2M}KZ(ZB3SdW@fnuYoLi=>J!m2hhV zR3kZLg4L_+_ericV!6@!dO!D^x2ocNTq87C$$nCu_#pNM7Po*8ZbmZ*&qZM-(=6bh z839rm=g=GjjkLF-H2>K6FHnKz7!<2HL~#Ez$zU6rNl?bG8YK14q=np<1`9U;Hvddo z7{XgSn2k3d!eJ7F(aAMP-;#Jp7GUBsVCD$JH>&kSF4i+H*ErG`6wqfvSe69MAI|KF zUvK`*BeeG9fN9-RXPgel&cJW#*+aZ<{zLnuH>c`v~~2p2BY6G&d~Zgi2eBc zY5dW5i30(_J2-1_rqA$%(gcM?#!a-}4$?kF>^yyfr`8>e`Vp-d*bv8`E5f*)tg3MQ zDj}~7_HhbS^R3P`r_IxXIsf$aJtF3zB4MwILuiv`W|QUw{x^csId!6$984R6A4V=6 zhte6OaHqK07(i`x?JsCi98ZEak;9DCB&GqMJ;Yf!W3y*r((OEc|Jt$g7e$v`$P(eS zg0)fcZ+3O=3fKCawT-%Sn3azJJQo`B+(E(7wx<;`x&1aJTa$T^&U zk@ZBP_OQ{+u;a{dQV(dds=H(g1|&DPC;pyth+szcFe~08^w8c~#uT+Lo) z2{XBI>0jK6s{&-9caUr|cGT_XRx!-Y1#}~`cP>v%=;?vG2b+pB^XhsL6jNJUIHO&K zYxp!udI$++fM~@XjXVrvghBd?jVjGw=fzQwIt)p>JPi#&18XKZmf=9>;BK(fr8C%kh(~H2d;# z)WbJzz-Zb~u!`L28A|RQ<^u=#gC$yrOP-*s7ozPh zT$tn`%{)6(#(xB!W=z8^`WL~TELFg@Sommuudca_A>3YraQ_Fu*WK}KU2@A7W1C+!=kHqrxk)(OXB2TG%~3lFP}J^D(zPSouJCeFZ0k5 zSZ{cx88C2qT)OdEW1uT3JK}XvaVMz~1-&sdhT?7Vn!2KY{V#wtD=2lLyaRWR zC})r3MQPs7NlK1*AgAaFhgVq{*#V;NvhY}nEm|4HHNV2!hXF%PzqRcZ5;ius2FOmy zjoS=0zZzx$u)+cZ8K9|P+jyEa%&g(gIcA!0qEIj${UPuz6#mNjX-))Jx|pIrgf_dq z(M`oNKbIJr3WKpl8Qf;>Q{=G`P4S`Z#<91zcQbF3>ZmWZEn3bS<-U=Xky7VJtXJ1j z188D=*NClkJUs;>f=?zYiAV4OUFS4yvk9<2?dg&xumcKW(Huul1HSlv?g$m~B(u0E zItG-%F9H%=y3OZ9-l7V4A`RU$UN9I`AYWMuD`8C&xM`6j*&zL#ijGs~UUW&N*O(UX zPD(~M-xkiE1k)0$sm6q6Ilk-Y?dY&2-%0^#in#uM@lE5vDw25M6ixgMfH+6?mJb?1vaP!u)fxHv4T2sO z<4XaT^sAkjQBs5bYkJVjhS&WdeoGz|g24}Uld)xXV^N?SpRn6?_IX&YQ5Lr(M?Hni zdIzD~H8qctVSy8?PZQX=vaDb?+2|6H@JvQkc9ep3`WiIZ7?L>f6-J|KG#Qp%q2t?# zcnf>RDLv{94bIl5OTlc)<;4YpSt>AR?Bl1vxp?`GcnQ5~k8jzwTM3xeUt!;66Ed&i zm-?4|RU5`0ibwpZJ4msOS1N}xx)+GPg0IGK;2uHlD00wBYIs&sAfUue!Hi`n4!&ph zjukG&8E@0-v^OU-IXkzP2pE_8Eb_|*7uni)Gr(fu(-wKc+m8*CAw8t?bYwQd%5Zn& zVICm`Gw=iyS%l0Y@M&KNCAulOLnODTF|FwwE~iSye@mn&KwKo>1imiaKInveVs$jb zO>_;M>KOH6eL2>F*TI0{{JD{G_`|_NPR!BQx1}H7@ob2 zCM8KCDtNI-8>5(I%VR96II{yWu zC46H_k34fIZNpTR*SzefbuhKfm6Zb!;tohs{vOJL8$n;|`L@$kr6Srt1wJ4>0H=SPqWXhTnU zQ+}gYO!!v@<1ZT?OFKIt)#YMSjkMMkZ;hfk-~~*u*)}v+H_*n4D2?|u+ z(x{obkrTL7O1H@%>i0Yw-T*c?~VDB;aFAz_U);Qo`;gdHRY%Sz^+eDZC7 zY{BSZV7qQv>mO~c7B>e0Dk)ixh-Xb^v!}beJ2_<7hLJRZ_s4t>05+olQqQAG$3@Hh z!5rytNU7yl@GOh0`=2dRMnOXr#`2ZgV@6jgf^)=9X9;&Rfjry)njx^dp*Mv+vyTc8 z_4q|BZUVF<9{AC{ek`PG+OW?J)lvk-H|3S)iX;Tr)EB0|qZYiPIVDYprV#cC_qh(x zsn$iOeqPk0vug+~5%kWAAm>mI!X%?RCKHX2tSv0$-8K#EuO&c~sJcq%H+t;zUss72vJ!?EJ_k=*Cujr&!+CA-UkTH{6-(-!nBMxxUwujJz5;-^=#vz)cH z+yj&NzvYNgv!O`i=y!a#ib;gE%7{Z*R8R3H%E~)3wr@cckO99uB(m7O5b(k7mv4E& zBNUbD0$=g)$j~_rRDvI ze-O%Ds-JRT(Qx&0^qhAqT6AkWQJ(jqZ-@!otCa+M1d@ z`vWW@L9c)aQIk2aVqKigHuPw~x9U+rMX=AKY2(3Aq2s;Hb6hxUlhp5~L)OOa1Rax9 zmstlkOZ=#*Xl_?N8MTj-q+J6)_=@Nl)ARubF$hLv;ww1Q+usi-+_IqC6r|;icQulDRutmvG6+Iw7<$Byq(6Dhlp&G=BzoS?27IqbEw>v~#_rY$dbmKb-AST* z^uN3LNC#hgQ|at*P30>lLXS6$0tTQtWswi}b&{qB<>h&Px^Qz4?nO24$CUN~mU=-d zgHQ$Jid1eJZPd(}~KVAdxsksN1O`~S!~%c!`b zCS4~45?q2i1b2tv794_W)3|GJhu}#X3GVLh*0{U72X}W1_vE`Xv+la{kJWS^-=}s} zz3;O{|JhVbPgk1wNdMsoZ5q!CT=OTXKn_^HF< z?%RVBC#p*%_??cZidHbOxL_?Rq6>jnhxIGJ_~jc@h2%q{xTu@SW5KhQD;4q5ipERQ zfQS0np^tB-g>^mBO6%sJmqQE{iNTZfPq24l*0bzH@whyihy6fkKgy{ekVx(qr}_R~ zuASgZ)Q??PZjI`gelas;F3Jt;BS_;FC4bz0WETi;c4hmm&Em%@HoVsN)%|bQ2Hm9v z7n9gJoWSQ1W_`mu>w-C)t{8Q$6K@A17UPezcX{JOan0k>F^ zcJ5Jikzc%F_h)ZrTBeR1@20VfJ{SY7hetqLjdrL!7Sud6us?JT&(v+mOolUQ-Hi|C z_=JJJKl>gD=N%%*Q*s)V6zMT;K`cpdyB3v<;@P+Fq>Z_w7QTUbd#*Ptcc&Gua^K5I z^I`t02ul{Bp3c`1Cvf0~yEm(Bp1In65rJi{4G6 zgEDP~=Vb5fL>79Z-Zh3hDvnc5?AJGXtE~A?neQ4wJUTl@;3k*grcR2RRifGs5j|tw z7z1Wg!2uuw(L!)p;sKMhN~I|V6%mYqpy@Od@>3|O@8{G|$>-RrrAh2QBku)QMAOf| z;O@jM5T!~bgx0iS`p7`)p&}o+dNkL6o~s$T^YjY8#WMkKv2qG#O2S=dqxib&-p?bH z_Xw4&zCD6Vmvz;}D!_H7O+*dLT+1h5?lSL}aPS;-;mVK83}mM5RLee9XUn54q?!5J zi05kCqWre#T{j0!*^(OW)o zAO8vqZ3)j}c+cgIyOTG(fgo595A+DLBl> zIQ#3@eZBtiI0S0%XaCi+t+}G+f>EYgygNvkpD;ssc27J1Ben zJcL7$o<$11#HqksG2{cBiM6AetdzSTS-imO^bp($SK_!y8tux3?W^+(vLlQ1~gT_~M&+BM>vuRA)X)%$^c`aKDo7zal$k3S0c!hr76Zi@Y5TLBJp5Kj|$_?+g- zXiC%A^z&KC9blQ`8cu#v-UOWDn#vRpb0B-Jm_HZCf_Ez%oD{qyk;CCUYl*U#q92IW zCZyZW+MZxj>czQNzKI)C8aKkl2ZhQfbN-a9CXad%=A@lK|MD)!C5xNgYuKXJLJLnX zoJoiEE=h&&Ex%M#k=#wS^v#qeR1Y0z_Z{HkIfxB2Cnh3gFdY5fQac~|YY$p| z?r_Y3ww0Jx9jtBI4D*y;-s)L1qED0nRHL#-E2H7UZyfky2@U6Ryssyvs24G*z4HsV z$J1Y`o-c~^hff+_RCh;HtWSfZT2A)dqE)}X_}jExm`Mchwc?G@1ijoFqb0h&pz@#6 z7xP6QFpe988vh9L&$BeVP*hIwHqKyI)s5Nw$iC#LOond{$GU2b9g z2s0-aLY}uU-k9i7l^>PuM5kGrZlOCRQl5&)Hi8>2GopUl@0%krLm%v2_ zlK#4*0um%QB!>c5hGbT*RQzVML7{No5JZPurdP#>vMp;(6jC+`xn$B|DVEB?on`p< zk=Zx*{gyxn>ovm1zqD2$mR8)eBD*y9pfRAI68M1Q1Pie;OuvL;CIelV#Ioc+Od)&s z9DKE&3dG6Uqwg;PmrN2tk`}VC*GWN!uT@(FehH-QK2}jEiRuGsZOQY_;d&mj$qLl{ z;#1Sv+Val#7q{P`B+!0yi$IpVHC^ZXguAG^`QzBL z43Et}DaGdl3sp;AWkxROE+2h)b#w<{&0wn18X>Z<-@9yO7{vN(c6+RDB4~BMebZG_ zdg4diH3^?8vxiK;^DfzoO#mw#(|x{J0@~a>`pvt??fL#3G`EtQDOBw zQd3k4Tt5_tS-EPG;UYlyni!xI?&U&e7KZvcVOa2c|;0>Tp64W(kNfJN7LR>{d(B`vfg?6Uo#-bF3(&-cs zZ=TH4Xg(0R7mhqRmkV6<+*Ggr!sN}qy+5&S@_0%VNn1w$`wdT>Ct*F{^bWfxK1fq zp=)b;9zYzI*SZgHoJrl6LkrO;yP2TS|AzvjTUCcdr4H%O$RP&H=}-Jjt~CAz=0&5#u6joSuWN;wl`!c%(ok5#hHF~eycNU3I^OEf!b#{aHZ$NR(u6xU zEP3+tUgVx7o#BJ3TNk*bl`KZTx7eb$GIX*u(CgF4m~ z1!<^!@-%clKCM&p1+9kk#KhvYITHHWGF1*1YLIcE>Ga_n%Onu-Hk5f}YiB!8wx?!k zxYC|tk%bX2iuL&SqQ3Wq!~+0tQE4z@e*z}p6x|^x)8x26H*h}xv^HQ&cj&|KQ<7i( z{rnFbmCr;Las*(WWOxC*({$K6a0|h9jT`S(-EHs^8NAN`TMcg8IUFy*9#RedGpnf| z_s_AebDpp)7k-gqt(fB6-$pj$06&)F#e%L(R+uds4exmQVRJ2}MurtPQ z&+XT^`}gTonz;RDod@x6o9lJM_B98P_1V;i@Veci`B7_v9g-MzYA2pU-oAt~{ACtw z6?B|SqQUPbpqbM$R^UCoKO17}Pd6#=_G3L}f&O_-x?Tumb$44g7Ea>38E1FaD$sS= zQG3|Q+e?~upOc|UvumTUTYuce*nPTK7m)CMj)B;qdk8Z*l?1lnhI&`WwqQA8rFo~? zQ#=IY>amIoSLeZ`%e%X_2FSw%qUy0<7i*!>w^aVFGVUi(WNjI#pNA`v?M_LiD?Hzz zOZ)7QJ!YC%4rdm1@bWO7@t5)+yFl;@E9<{8m;$OIxB*ObIdB%iYyy)hE&$|h=%2GR zQt*~l^5o3-t~u6Uz;Ro8(fexDg}G0_{~}ePQnZmv76by-N!iFvc*2oTf>^EXD}{9ODz6v2N=-LU$os9kSUblkFq#k>E9!elS) zPO0KzZ0R&T_x=8$r6^OPu;T5yJ->G2H-FDy&~{D6s-z~@X-tB?XXl8a?@ipn<)3br zfq|%;5#LcD6U@K(f`-qhHV1O6X0xh_yjngR`Hg*87;xvY>cYc1eu>)Jww;|Za6d~k z^hjvKI4*n_TmR&>lZ)A2OtPPNL3Wnwkb1jW!$)xC!~5D&V=}*bI~VLYA8(%St2=hT z#-l*!lSt4FvVHM5nEpzE{N(%RFaHj}M2eU5z4*X;uxvhH94SOLZn==~dbkIG_MQd` zm2-AJnEUnTy2U7PC)D`;X3d^{vwd#}3~-a?(&S5(`uq81wslE%fpWcy65JW;6r0VL zq(|TVtk5A0DI!Dm!=}A-hKlyTP+lI-YYUE8*k!)XftKxPxe*6EUs|%HqAf zt0SWe0|8kUK5XP4M#j4xC~uhDt-A57=_6l-Ad?E| zGPm6uajf9CW1u2iRTv~*0VI_KzUyw%ze+aA8*F`*iAHcv%HzVX-eq4T3C{Ssg08Qx z2UeP#Mt?210rq721#wi~FA;z#?253vhD|dsF~NYI%ok{({NIP6P#Z>1JjV=kFi1VD zBht^Ys^#St+2f@yA>8fu(NCA@K9IsZh7PnpGuXY&AVr)&;EH_4fNX*+{&(4>p-9!r z3p3#ZX$$D9654U8Ht7(l@2ec|)=0(>bMq;c6j56wLAm0<+M#Hh_u*`jJE`k_dY{Ou zTYKPkLc6TID5#QblDl65FZtyRM9OxRdDi%%?^rzs>6@@2dYxB5OZ1p$^=^0U@ip7O zC9G&S3fl(Wro9UvS%LjHL&FFYv^WqX@30S(Bz4K8*DL(4a2MS&Y)3zt7G$`#AkUZC zV0^$kZGY-sA33*oVtXx-gJ}ylapyKvGK%Z zh_@zVoY5N?4I3RfwkRem@5Xs{ttnQFwy!c?TiAX(poPex&34)Fle4blzh@0|Vt6`h zZ-24crRokut>EkRfdQ~%b%QzF`TP4-0p5>K>#u8nIWvHhbOck=uAN{M_QUn z3_X%!ZF#)qPyhXav{CM~Wy{Rt@Sq=d&8Svfe=4r<;)CMV4bO^c2;FjAdAsw1rs{k4 z^qNpq(>13GmVws06>2nL=L)vy7XjgUE~z3zyS)b^26~3(;tgBe!6lv69*yHln~{>g zhx2Wg`L10eeHP;Y?+&D=qR0b#6<$^DMcCWn}pNoi((A0o0C!vlLvs~JEtZO|Vr zaHF!tYnyu)9y9PAuRcw#@-kySGgxY#AxAQty;V++#kTFpfd$#^jBD-O(I@o7A|ky+ zsewgkE(OY*QXkjnj78B6u4CKJ&(1L&KyfESC-W0Wh|}%}e(mZzzStIGwxqjrH&b{e zmbeW(HQE_PC6i&a1SnmG;cxO(fb1gre!NorlTw(2O^ylhH0iz&3^w9UW8E#@L3Yt> zCxDc65f6G!YYd^qO9T*xq}vPj-k@bhgb!oD3*VeH<*^4qeXz=6eC5s&c5(1$(L!04 zHQ$q^S=}B~JvQ7r=;b(PWWf7mw<}!I`MR4@F&IkPX0NedzsDhbx3(t&o_u2UZy=~n zL*)?O|I^LE!f;R6-AV3yoE+e?Fmk`~%kcQ*at|a~Q#U{JOKOa+X4r)FOG63xzDW!X%Eifx z*TruXTW}i+owq%mrc5Qc`Lc!}bjCnPIIIPXhiNKkP#KiE1ChJ&ud-U#j7zb6&O1L8 zAaaDTE{oZb?zfU4c`<>ZoOK^5aWJ}FRpW4aut}Wx!=C@4IKA(h*SRiwy1-31cqPsP z*@$RfYTPad`VD_?4hdBV=>xwU4K|)uh4|=KDKge;J4{;qT^#p~$8nLz=n(qx8>o9r zNAMjM)?O{_4y*g?CA;LRP+Vs}Y3xoz7H{8scK)b%KC6|E2B`wI7n}XwhAF43>y;rj_9LH`Rc^1d`$t?d8&bXaoJu zk_*1mA};n@phtY7)@(LNNKmkmNc&2w!zPqfjDMZi2U|ZE#LoR-Lq~gK6Z_?1r?)%%Tg+eGOA4S~Iisr3E}KwUZ~1oMBd#Sc3mxJLvHiTnC^+#9&$r{}Rk* zas!V>eykpm4ah7WQcTA))Fk1C1H1LU-E;C0H3WZX;XC)o%mkqkSw|(70W3n zHJ|-rk0ex-(K-ASk4U}g+;Ac1KSQ6mV(T0}`1IBW2C9(w`_A@utejKWe{VDk zCYZi|QgfNig5q(sD2KRw*7o@jSHNqi!2|>><_I_B5pWpND zt;mh)nvW>@-uc-NkB{+#m|N}}ej@oi3;V4V>=pw#O>h5fr~bdX096PZQw&mkkLhG} zm2p|fWb88FL0ev&v-WA5D47DWi*=>9z#3)B~un( zxV5;V@iooOF-YsLA>(_UFgH}&Y+ATH(=6`NJ*J3~4=vY;&X(d{W^N;R!zJN%So19^ zc?Bb{X|9w@rAeg4>Y#g}W8CNA;qqwvqdD1yh=b;Jp(S@kLqtW&*%kvB(Uj8Qw#Sj-BIv zCSu+6EAB$u6XNaJ)`Z}SvD)@T+q`GI=SKTEM$>X57X#m!Nx%I+kIu?Trds@A=03%y zTH!nDb;u1R3B0lwwv@QPa?{2G)_j}y2^!Uf$?-^`& zeXD~(WAIe?S4P?rtS=ea5V-yH7sv^if!=(50-@r0rD69rP@PsNqqjw|bWi8N-R$C4 z6Ta_6+m7^m&SC4pK%Z)W5LDyszRaj9=5>ud8}Tl1ZnWHa?cUrrDDZ0(_xzpuf!T7P zh5z&q?T$a#%Q$Ax?RtROdS3>)=K9HF3YSZsZt=|HVoBkIERci^UyB;ZiZalPJp&;a z-iNoW_p~e(FT|FvKKLfm-6jU3sIx3^6NaL|c?rI})ujE|`61`ztEAKTh)Q@DCmG*wZ(=Wvd^zx06jI2oFC9 zufqI#pDv$r+tTv7#^2YWTWOGPsk!`A3ie;O;K*S*DY)93Z*P@sbDGk0x!yTq_gQkH z{%qWs@h$oJ*<5&n`<30}%hpT8=`^xEZ`eMBS?}Nn|J}3x0pfb(Fb(N=Y|Z#%y-gWN zmwYt1hrNN1*4d{lmB-Y*E#8oLQkm{x3i=SZ$fj+Y`!z;=+)-^R6TjTC2$2>02X)w& z5vFubOO-YCCxcwS>}485WoBfrfqA)K-`K(kB)L5OT7ua%9siW|ks{CCy2=NkNd6Xn8`NxN@}RhG&q z^q;R!GYT2P!~>W=;=MJv>sox=M1?hFAX1gt#uA3QH66##3V z<2xKQtLYFQRXF`GNe_(Wt@X4lzI^drQxJe0ywm5VJvm_b!!CuOMgg0%(I)xCT;6L| zS?}4|AgBzthfRJ}i+XL`=sH+g?gVN~A=wB^<&*XkwLok`Dyu}yf&Q*#RsyY0822{` zG1tZ9N}?wNlCDNe7-Osp~1{S z_gPJBfoIV4yWj9K`+9XhOFfXwHP3zZ+bMW*dYb9gYmdper@VRXJ39s)-S;128OL(EZ!Gr=9-*Uh*5N$MSE zja#TWfsWmf!@ovD-|VZA@8GmTq%5Q^tZ2L8QinuiH;UP!bA}j|g>WS=0fM_h_IL6* zpuO10wn+*|T4HhWLjaEQvOKY=_eqVdE+YP5A3BIcSG>3HgHv2{KQ?!)bycSk{-5az zy+4MQh!Z094q_i96K>_O*ar%6sq%Ya^(5R&0&tuSoW)t-`0TBm84$?Txr)nOFZzzq&F!5bhQ`}vUEu#f36 zHasyvB22vsN%C+&M>!rb54s?vV6IwVB$B;bxeK#t+=yi*0o{#v#A`pDTzS-3;HEk= zmwf}5Iz9uQrvcI+wUE#w>4w?<5d9D&&cI(1!$%A<20*bg9;idl1Ii9Gq-e0u%`DwJ zd@rgD_sySlTLsbMsC=awBgCkkB9eT6*uML3SS!b8VxGF+C*}}@_}g3uY~-Hr!`k2R zer^4BJ&}bK;vbf1kj^nAmzOV$^%Z=h_qH|2kSq{AJ#bH1mck%JYaFFtL=u_pnnYED zHW0zUfzJ^`C@gH|7;i@lP=WGY=Z??SgU1lE|$b z{V{vXmlL=VH&l=XWvD{Sk3GZmn}6k;g>=KASUR%|6J)M+fb_3|^wYGQUFXYr6!@1! zs1EBq*O$&`A#T>IcRUPKEGU{RtOJ$O7*ss|IN&D1fvmH|^suJn#3y;c%>7>JxA=OE zApW@c2Z}s*n8H^>+EBW($MkM)gIH&n#6Y5L^rPznD&J1&zIe_XvVt_%x1!m@n{N#EeMMcL&N%CmTscsBT=DA-T_h6sK{yV6Hao| zbEqre8M5*ODmlLoJv2J)+NbAqZ>tQo7KE21H-g>tf;w{6yIr2% ztDqgAQG^?KPW_Y`d^&qo1akEnrTP#Q3h+a^Kf8dr;efcK07e%)mV0dXM}k3stK&4X zqKY@DjELMBzoXpO(Q4ieS@}5ie6Cy6UulhemtRUbk;xKR8LD03?YT)90yg%9{V%V% zS?hni=0cmIbn>c3YZHgRmD)BbQEWNDP6fGLOb@GR|aL1_aKWX|k4xrZ}{*d&$<^cWi0AsGPfi z{He9Et2@p;ciQ1B0V(x-&HB_aQelBj2kVb(r0;YEeR}A`x;Q@>H86w^&I?C zKkxH1qa-x(IAgS&;N@)w z%rv)E?x;q#d4Ydd5-c$1x?M(2_jA|SCLiG<7B7dGWcZsjl zylVzO$ma|Y>jCwHhr?U-gIOOw^=imylg1_s6NXc3Y+rOhpuD0YZ305V(Tr98`OZ>xjoA0j$3D8? zn0rX?V_rjpCbU^&fSnk4S$29S-CRhqZ-r~lT0j48c^u-rVq`3YNI-$qAr*>eWc#+c zmam1bTjvKM408`>blL3#KJDABCKPk$pbBTs+ec{WE(`k=!KBW&FJXEXl>800$k$>N z+WgE!%VQrrv!YU)FCB~0d5EL=0_gM#%F3BT`3Bi^YcvIyZJFLSR63cDPKG&X&jJ64CfEII!PE4=uvg`gpyDiU@}Kk7uuZmXW|=ZMi~SpD()u_OS~pbkj$ z34ItSJ;(u$q@M0DP48|=W`!I5`r%VWI)6&QT5(=tOD^bD)*2q=*l4rITBgGVhS>I$ z6NhbvFO093yr%c&xbr?vLWIM4BnzfbP#<%t=e)g9+)F}*MW(fI-V|^Hq{f2_!osWR zvoG!5f6xpWLEZnRd`Q(U1TI$8^?cnaz!_Q0B0lA;oLoRN7BXg~#HUC2B5v?Q-1fe5 z2)IcWmpWjfI=>%;gCWXVEZpV3R z95GYS^ttKVinG<{DTIAlj|f>7+hSnPpV8cMk)`sG062;)`9!g4W7%x@oxZvBKRGuY zZ}4607qYpm2HxLWkD+l`FUhS%eudPd{+^M5?$jtG^quE{_}|Q2_-kGjKP48rxb2rs zn1Z+9+Fxk|pD02l*57m}9gUGs_EXsB@5p@o7TYmkILRZc6cUPtQh*$Kg(Vd?Y7s2= zX05Po%mN9IfPu4b>IU`9_I2XNO}04XXmvWe9GiHvRJ{C&f+QPnUe9>CDGtAh?=Q-k zNvYt{Wx!tl@}U-j1SRo}U`W0colhD;s6`IC>80v;NYo0}#n4L*A0b@$e;m#iu)4I} z)Trcf8?WnYUL6POvk$N4R*1jXq+t-0$^4aa=_IH)4dK9@&}MFQIE`Q5rLix9;Y8^! z3mA<+4Vlre)ez2i7;wtTwLw|L!$0)!JUqUL-u_ppo#FNLiG7LF=bu5M zM0dGfp9d|y980!+)!szf#%n#r+9#L7sKj;1Ovv+=I)pc<`MXSGl^``KiT0{@VkU^^ z|3WH|V@Fwl(}s2WzLVokRZca76}f4wCFY^{{nD?WCI2~p`1W@e$lJ9{t#Qpv*1HVq z7(o*mDRY0^FropU`|G=0x9XN$H)tsY<_7jB|8MIah1B~;1e-Lj4p?;&TY zEc1UK0K($_+~x4b6xNV)}mx{^wL&Tzv;^c@-_o5_v8%?#D&dkUdF)`HvI z2UBX8pBY?Z90!(4#q+DWlwsAwY@(UfbYp|&>y%^@e$YQVgZIc(9h9S)n@~^dYXa<( zi+@eSPerwwgr+Tb@(y6=3e5|uAGwArq?;lwMwPZ&Jt$UVBJ+O0XDYtI=sfK}D6F== zt$okI{tMAN#g0p6{yK=rB&*;v*8Mvzq+QFfH0V8dMOBTy>n-YQylvN%RwXKbJO|>Q z*Zq5qPHaZ;d8#$OuM~4SVQ~|^d>+IaxZzb)u`(Tpo6sH*I5|&l{(KsediE7miDvq; z&OS)#nT%K5RpFI0yJK4-=LY9o)oL&Uo-Z>_-(SsRaa5lu$}aZ+r&;RQ*AcYojvdTV zf*D8Em#(I4KsjmyzSiJK?dd6FPln9k)Kg2$=oGS2P8cE-|3m5tlTeGIYU?_M_7YpZ z@-GB-^&Z!p{HGqySYvJojSkUr-+QwrF_cbxm*?u|`f%7&bcUSc)fXDTB`fTz0*lxf zay5hvUpewEYnV-WO{aS6eQ%jw)iG+U{(ee+E+4jlrY1peU zn9};DE-izbhc6o)m#|(pvb^^31xia=1KmCf-*B#qBVi`3S>IRj06T(}yOC!2#aD9) zOEo;tXo+`@Q4FTj`c6w=l;!5xQfY7(ry5EmtdhZ-roYNswAPo5xodBd=Wg|;SJSq1 zG$2tLkjZ+Q_~VqXlIDWQt5q0hfR@+HnofGW#0K#=36=a|>p9hNHT~Is|<( z3htG)BpMueL?;WO_J2x|M#2!`B7!ko3HGV|9e9Q9B)%iNZ|gzjiZ0> zFoPMf8_hxI^nd)y|E;atmp!4j3a2^A=w!M?yP{4P>*&0X!ML4SBLg}@Wy?KY$_R#X z#js#T_tA&RF$lGq92%8~d+`98`Jd_^k=AzglO7hxz_q!*=ayVJ?ql?faLg^7U8aW1 zclF>r09th=zbv106_j}DWMhCWZF!;p%xznX4+8y!F1TDmYc*^V zJq$cpVfadbF+>a2@mi;w*sB@GVQr4pD`nQ{Pe4cU4^i-ea@H>jjPUC`WJfdSa32}X zw^H{=cgW`6h096Ri|pZSF`>5-?Uqk!ur$Y4l>DLnCeRE4Mz70oAIY@QRZV!xrKRDW zEvn8ZD~4w3qednh!)2UC1oZDBjGkOFa4rWFIHcaH}I=HOm5a?`D*TNDbo3H8p)jZozhQX^-8_ww*FGP1Gd$8 zTe_@alJ>duhPlJW;8~-gM$gn8l{b!zu=FA#miH$p+$a@CY_c(Vuz4PNuXWtQ#I_6< z1z{CvUD|yz%n}k2;UV7@wCIm{Y%7J2U%L^kJnZzW)4rp)u>aKj!mBWp2nOui8aq;Vp6cmsX~g4 z#5#k$OA6{T#HP_OXLhq!Vb$ze<7P~|TpY6TX~!ELi*llzvjw_byX@`Km^I5C%j8$L z99Hvi08GlL2RUu{-7(016TQV|lxkhmq!8Bqz(BfE(!`v z#rJ9*l}=->$Bt3rdy9Q6)mp6aXM^7;sfuSo4<<+d=qNm@DQ&$ML&+YZT%q14Iu8(lnuy-%3e#@EX;>q3x%O zHelg53b)nP!yTMe^#b0x6zi36tt!nB9J!u)rAYUZiWH-&f^VrVu{LtEg*?ZNTZM>! zG!mjTa9!@GuoOjBOQiU~*@OKv{F3wbwHN3iiXyGX$@4m8*-^u-)iPqfF!pV$ z#(Mh39O*x5m5$~v=b<)8E?+RV+XZjM$ZlZQs=+1tpw%tv8OWyDY;zCqAA~%^)NNX| zon$x!i@6C}r1+%woaL-`KL5=ED62tDA};yzZ&rtUxT`%AWEsqoa0idA<}h&i>2Upk zp1JfLXa-j4#XRn!TQchxRk$WK7Io$?Bz49w>H}vDBG3hQEYd7*7*DjqI-bMK4XW~N zwqnGxLVG~mYkgeR$1F(hW~mbX%d2sCadhbh4C2HaF!tE)br>)8q5U_ zvT%0iQ5<1`eQ2Oz^CWuinHwwTW@x!7N zOX$d9HX^2&9Zd0l%oagY;IYDQW^SQgIodRl^&qQ@9osSG`m?5m^vJ0wO4q*k{C4-F zb(6T|FDOIGdN*dyWndwaHgY8fSk9|wLWg`q5UNg+$iG+`N5hx-#Aq$KhPY56M&;_`D(ee)a7RUL7pB%Z8DSyQ;{LlR|xj&3p@Pdaw1 zPCGpt$Z-yWyHF?-&e@4!Nc$EAlh#9~HY}=|1(=Nq`IQbY!MwkR3zHcy)2DV9$U`=E_J(68Z(mOkJap!S6ir3 z0>wZOy?A9}eh>qi+V3zMvEr--5En?TQIXx^*-T|jBKj_k$1cT>YL#!nW>5P^GmbDz z%y+jTQH5fd3BxKCWrT&h?-np+E(q#HyA>YlCeVbv11LAFiMisY? zF#=+A>s3;<=-*;%5YV?cD->}T8Z1g5ExfV0smIoqdqYK__S>YX96(`UH)YGsAUAqC z_zj4fIoA1?auy|d3RB{%W%X=Z_0pk>+5eE_f1gmb-B(D(b1;;4qXCHsnznaPWR?;o z6M(U{36z`yVqjMPECnnLZ;Lr=9Zs-Hp;H;+V7x=%)Mp}aKv#4lTh`}-tc9pXvJ@2f zU@2PHplmq}ej6eE1FqhhK2?jHnw$yIgSB;Q{94MzU&j|AMxhO%_V8*5{%xE@eT{z` zFF&Sk(|dfLHZT(>8y+fj3B!+D_s9;Q{i5SE!&i_O0U!Szan|*A06k!it$@KhJUQ$0F}~RaCX6Vil7uF0R(E_9r>gJF zTN+-gF5Ptucw5);iDQ{VHiU3-i`z^&(znhCG4G(;idmu;RXf8vBnd?GcwNtmJ-e+M zkj!JcAq&(1k!n~mIgVs_*2C{HL|lgDXYfH9pW#Q-b4g+*J_ng8sz8Id-|<7Q1rf3i zJ|+vwYr*8$2>3X6<9HPZl1bXX(xLuh!y`rOq zI8n0}V`7=fUFvWGp_M}oKLhBlG`q}Ec1yxRrNu8!dZR@eF&^>3OO@^RvLt`6s0w6(%T z&}jot<&>z!EhQ!7KbL?q4}!qhinoU46DejvBvwOH1sg-L*)gTev}b?gZ;6pC$eV7! zEl!39bK_5y48^;|(yQte@IBzpZD1>XLISSBeo!Adr`JRtuxyjK3T4-?1|C-6gfQcE zTm#(K_&cSi7VyM>)(17)B95egl;2Z=rxeSitGv@Evc#j|jgl(6{d8i9c$6;AAV4KS z1022}&Hj{BCQs#cN+Pqr16k{~-$$_$XC$WfQN@aCFDcI89ZH@LW{RekPF(P6=^_@E zW?zucj8nIVgr#)Zklxn0U%yv#TIOJfL~%716)dhfi!_Oh{~*93A7 zMG!i1Ja|b<1Er%B5}cze*@=Ihr05!)NVY)>?Ca3!{is0u1=ar(d>9G-R|1X4JgO%6 z$7mj=gAiwy!xum6d)I z*Bv`!$0#(qeZ_N3GFbEL{SNtqhh4daC$1HC0189g&Z6zpitra9gH@YUx3>J8$(<{b z4m0v2Ok^G>3JlFfa$CkVVNvuIt}$@Nw^hhK{+P-Po(i5&B#XTcV19|-e$J8&Iu)UR zEACuT8; zWUw+3e@s0$GKT=7O8XXuZ&`LfZ~rnbq>D_p)W6AAKcR_@^Eg90$876 zOuL2q5y~Yn;Ih!m6Fd%QP$~#&b3zIB{D6@Vm|V*Yn#gneO<#^HyQeXzq33KTW1rXw z-F^hErtaiY<460RQF)vtIg}U>YHo0Itc|S4^r;+=ZvU%^iHTs#%iO{L7?{d;NQ{#I?l-f%0gD?BwKp{-!Tt9_*F`G-k=sD(;7+9h~zW6x`!G9gS&U0$BGk(kSOhq`Q$ z6iDoVG)M>0s@f%X3stroq!`A7((jkxpi0&D2i}4`?p9{56mOWZcofahM(3N630^Lj z0FOd#c25!Hgj?qbbIC;d_e}xf{RyTKR z+3H1TNoTzx@CQN6N5(e_% z{=9D}y{Zi!5%+6rYpHH!0eVlAPc!|$`(|2~>-u(T`*2LSmk({noh)WgFYk8GxR%2Q z*c?%{k)ef~Vr6j;0S&Xu>1PX8t9xgo>(=#8N)lqBwhoaL&WpbwV#c(sWox&ekAHEX z`sx1_a_TMn#iLH!gMp=(^-IXUqCpt7S?ovmdPV!IF1KxUtEo}a$&%2=l;bBR{os&) z8y?=ZT0TANU)N`TQvVZfY?H&Hy9X**{C7a69LwZNNU+{~=LetW1xwU<;x~}EgVl~?lpA}}>cqBep6HGa zMdHYaxcc@7D3PSK9I~TO&oiwV-HdIThRH-+ZQMQ@6Hy^u7DL9~{(`OfPkdrP$EcoBPD_$lG2^hB{9TMN=P>h-7s`_ziS?G`@PTp2j1g5wm&Hj z>t3_gy{z9g54hX5x=>NoA(u6xD| z$dv06buF~l{e=Ub;HD2e{w%?grxqmOaSd;9^2X&u=`K$i)7}-8DTz+LtdFUy$*>iN zj`%e*eZ6R{;M9fWIqz6#SUh_R>Z#Svm$-}@8rRau;B=)@aGkQ%S*fs_4|p=KXTK$3 zX^64YaE5K}tA2(*VXn{b(J;1su2Cv`qp-AdBnIW&Herk^9mtNf4_LoOD$?LJu4CG3 zVhmrUSET!<$dLbusTeggspiNLHGsl1IK*QzObCBJY_{x`tk=7i=f3YIzVWmy4JS0( zt3R37^zBu{LFg{K6U;KVUk;rNL`z@q9(C49Assamw%6B}yJf&=GSbJFUUGZ6HY+UA z)>!R3BdFYp&x7h`msZi$Wv@`UnTss

BsKC0j<+wbQRq_hm6@NZj}Eg9?+g`pcP( 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±?F^Z# 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 P@JC!k`bD15n~(no8c8KM literal 0 HcmV?d00001 From 135414b3c3617965cbf9e4c0b46932500e4aa510 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:26:04 +0100 Subject: [PATCH 09/76] Create test.md --- img/test.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 img/test.md diff --git a/img/test.md b/img/test.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/img/test.md @@ -0,0 +1 @@ + From fe8f05b3e70cddf0acfee3a4bdf09fc29f8c8616 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:26:20 +0100 Subject: [PATCH 10/76] Delete bow.png --- bow.png | Bin 53196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bow.png diff --git a/bow.png b/bow.png deleted file mode 100644 index 7b17e99b02ca99fb72f062219e1e7afabe16c96b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53196 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 )g1jZZci5KIBZ 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

BsKC0j<+wbQRq_hm6@NZj}Eg9?+g`pcP( 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±?F^Z# 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 P@JC!k`bD15n~(no8c8KM From c3650e2836a1b335811b0c2b548ca8fab50df136 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:26:34 +0100 Subject: [PATCH 11/76] Add files via upload --- img/bow.png | Bin 0 -> 53196 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/bow.png diff --git a/img/bow.png b/img/bow.png new file mode 100644 index 0000000000000000000000000000000000000000..7b17e99b02ca99fb72f062219e1e7afabe16c96b GIT binary patch literal 53196 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 )g1jZZci5KIBZ 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

BsKC0j<+wbQRq_hm6@NZj}Eg9?+g`pcP( zy|?C?kXU$Y>^`!x3w|E^`|EKld`ePN|CF#5$FiqQZbs_$Tx-CvXn^6Jo-TOr+%m!z zN2k|I2P>uSC~Qt1C?zVYu0wENcRS^juJ0-n*udahFq^xFXT%wscFr@gi=WhduM5Gk zG6FQE_Zij7%$^jo7Gz%=KW_j|0Q<85x1qymcucPa<}do}-NAHisoP4gK0m=Fj*27J zdDJM77$^XEPSCTEO=FMRuytDmiyLm0_<#!;^$QotwA}PO&2dA-$uzm=8{?CM(4z4? z6UCraL)>?Z)7O`kh?ie-m=zDdjOe%x(ta_xguQqKtJOoB=1q2(M&DAl*>cafW~0~2 zSy0Yg`l`_0qbNI#76}HWCv(CuPDup2sz#{Z5<=o7Q;BRoudE{_V%A}=$ONj)#HBh# zHD{=lzpIq5l&yFsCv@fQdI5w~Ln&K2TQ!sDv7wZ(rf)z89^3GlvPqC|c3#XXC%GDc zc#&$5>pO#F7K>k%ZrC0xXjk7=G+UJf(3=S%T@>6aDII&p^SCs+giiX}r@E{!~k)ag*ps;3%Ws-iL#(DL}9sijn# zq=ExjfV5)_U(3k1h}Mx6C$Ytsh^*AX8tX5n936W0=+~!s*nX+3AeE^&k2+a>Un*Nn z%_-jyPR`wt)wqVd8nfrd{nNh$qhx4_X5QfjPm)YQ?ysTZAn<+SF1f>KWqsIl=8$Q_ zbL)kv+SEGSKcToICkn!k*$Xt$AKdYIf~&TTO_0Ip&H~z2fi86ICNT4CRQk{v;@vgn zjM5G(EwKewCiz*z4kf1?6B*--NNC9$d1+%8ZuRa|2cw>=8eita)|(1StnzO=MowE0 ziPqV;ZVyG5=ilv-M4cW@gtd$)T+UuwO|`My=L|iHQ_8Kp3)ws6cZnu#l+z1(%sc$7 z=I8~fZnjYL#JL>X?9n2nzynt?$&qS-4?sBaRb*FbUZ)p_@e`*h?0l5zZi(1E#kUcA zXcxjFEb(~|*l?z)zAWy(iI|!JBj!=?@BC{qk_DD04r-WYbw~Z#lH8C@o!&f2=#Mk* zo&AL6vY-+twW?LhAx==DaGH~sTs#AY#h*XpCdL4YqUl!>pjlI{XxlF_D=coJ%^d$lmJePYmc+@R|C$xX&U%wT} zWgcJAla(sTVAHU`RAkkBo7kuH`O&?Zz@HNj5%ryXT7C<`fzqtUl{9=>FMoaM(b?VW zh~p{U3CTXVnNRGfw)N;eB!2WnT53GG_Ac*c-|ICBbEhe`rx+NE)RVoJ!O4k}&Tku4 zmA|?-;pRrX+tc71!kRSefOfCJOtP4?2Tt4jFie_<=D=<~FoE`qx|yG8N*W?Fl-RQjuZGYMv_NdwR2!~PS`wxRx6A~lACtD#hd*=ANjjb}gQzl{U;4EI& zs8zVDQQIpLZD0}tqY2|z5O!GHY>cZaQQ^yG31p zRN6?+R>-lsettX1!oZ)90=H)S(j-+)-A65=N6c^Qv9}wTT)Q<^*Ov3LyA)F@+LD*^ z?TI7)ujehlIN~*tBbwEIw6MwxY7LFes+4E7n-nhahdm+Zm=JbMMf?C00X<9JiWjW8&k^d)-JM%u%xs@nrBrP-Sa!Txv_9j`az2*b(Coo%z5@R ze$4sV5R;TJ#rnBfj2Yi)Lub@^)u}zl{+SHQkOFB$CGbGcZrRA$Ec+J<^azdtg=Rxi zpDFbfqz$nlErmaMnxb=rIgwvHa=fuLYF`O0+>VE~5Qp*`urhKdTfG!ElnW;v7YuiS zhX=lMg8hCkA+K+6r&vh{8_0#@jtk~B?7OkbTq#g`e7T2N+KPj(RPkLAj0>ndl(>o= zI(d`ovEx0>OpG$B(O2`FEndc?A32G(5FZMCQMnL&b+^_sSyEfnl01pSJ50tw?69Jx zj?9VCjO|)|`oTMI68j;$OY#pncZ|5~W1t{z{p-RVXJ5lS410{V(zl6hWf&g zx6oOqry^#nUy)Z>O>0)<-&!YX1`jhV(SYBW(?--e9}WT^(+*rhdkeK>TMz%q&pG{P zVuz75i-?6}Un8T8&udko0uP>iQYvoL>wP^V}-yN8tx% zrFexMbEgU7K@$XY{sK~I+A-Y(6a)oi z%|#-<5#4)Gqd}Ik52Pkm6svD5lchP_nYgbX+ns%Y(*P_d5$IL$xcd=+$;dIfZ)c>k zzml{vB%&wL5X4wrUDYcvovQ-!N~1Rivz2mLjZJP?NJ{#~ObX|=XHhDd7VvQn;eXcP zXsr$}FDU5lzipfx$5KKKo7vGD4mY$F9(6lEZO0htNx|&F`2^;qEh9tvG(;PUz%GCy3dyrSl%-sf6gIk!2 zc{uI|*nL6(_zqZie3W*b;Cn9D+7qA+r;3^PiyE|>(s&|LXf+@h(o&GK6V{d1^P-&W zAD~PivGA%zFhgrdw#duL-2p8waF^JUg;A}f?N!_}j@rR8n}VxdsVefDq~0`}1yBx} zV*0Rqjl#ca+G$!@a<|ZWZ1*i}_4kXZqP{W9DHEQ|*ol(&p6SBeX`fMHiFN_Omzpij0s9O2eRt$puCGL%M(cC2cj`91`vY)}HKVcW}TVi;q zX;lgq(>UF3c21FG9R-SUG=~dR75JvXb22Lzlaa^n3Rb@k36S#qF^MELzna?||AKX5 zA^7ILb3w8=-?Qd5;TYXRLY|9tx`R-;43xV=(o;Y~BhI(9w3O@Xfe$;+Wt-*>>gHU7V5-v-%M>YBz7@d5qv>%fsSn|^ z--sw&|4nOSdtH*YVwQh{{d?Yj33V!|OSIgEn4ii2O`LzE1W2ymoqHJn=HJB$e~3%N zE>C;^hmpUS?HlY#Dy+wtUjH{;4+z~J@G^xceK?@}7i$jy)2GcpU%FHN9^mhTg4i#| z{{Q=H2x#Qv{#5b!uWx?I{VEPS%{?x;^bbGMq+;5VMSR=9oofAUV38sfvz4OY#skse z;dfJ9NJ&Z4va?%lK=p5bqo+LWYh`8q9YX^HW`BSGwDR&HKN9X95TF0@Bj+D)i)5*5 zi{lws0rk14AYnYq<1BF~@K_ME$C{G^cZfKFLPvt*(PFv=S&3fzg9vXp9KJiR4LVDU zCdh6ve^nq;($ZSz<0F5_VHDch2n2U0w+g`R)~G9ZPk*3e);a4b`VS%(Z^8yRM4+dT zqIS10Q?&uK=EQ2-SL>vfh$g#sfz>~B<^+iHjXSRzYq5=(mTE*P`^>Z3_;_1q79>h$ z)+h73&b5T0fRZLVsCG}u9`xn=rK=-5Hvxnz^rfHgDzE`-r0Y*zj7BYq4Od4>PG?~vnoiQcarAH7=7+_rEvKlT(ce`YBu|B}>_{M3}{ z>ik_!PbYa}S(!k-=Ow8XjW%|6Q6*BOdZ%8TK$G}=(Nb8yUUM%~4FAcd_;zVy1b0aP zurpB0iUQiPbY0ddKII4B!Luh`N6brduoKHQJ;Ly_igEsXb--!?5LVvMmFnT zFMvzC7vt?;=%`X;XjI}DxoX+dmFUbE%lpdCNdr+~%BSbFY-48=g)G4<($9 zsKbYO;XBmUomDcC)RJ0AdQnKbew=MMH_)9iIUAiV*~I^Ip0D6cQsK}3)N;h;JwMq- zEu;i;0$H%o1NIjFZ4$hYVQaHH;RH$4t~YJ9$#u^$y8!`rh`y&M}vAo{jdM~0D2 zS!3G`6|Q!^lvgt!?-Y#=6WgLW7=jPV=q@Z|G?r1tlS*h6kEyj7RvM^GK!(F^1$-brq$ zs>9=Ht2|oD)*CUU0R!-MSDGi35BbY%B5QaL{J1y!jN4lo#@W@(tKj9!c@=(7&anU3 zmP+AEw1=d3Pg(>8AYsuzB=EKnWvio z?iihSyqrzzo+DjZ*uwJ-a{ZL-3kw2gMQfgd{QHD7YQoJ55jSdN^D^TtJT*17-+AqT zJc@s;rjNTN+QD*fWvF0SK=nH z&c0e$TH-vn8pUs4Uw3U=0T(M!KqT90=484UTf?hIG$QGh&|q*e^nnK>mTDDrmg4+q zqDEWP?+v4wlT-R(-#pYZV2jLYMVriF^0HnH9_7zBSN_?CtAdGq*bK~%R4|CaWmW5- ziRb#p+eOPVxsF(>LYcvnzl>!p$2uYyRi|lKeboeP?n{tpc(LMWOZFfPf}z|^OK)@U z>XOV>rwfs|I@T@fAxmDjr3CUV(Xic^a{PJi;v`}N?}jJ%Nx-zLkORh`0%5T~ohWT5 ztEgd+l?-8#)PdsjEX5!V&1{ylJE90XXZaU`wajgrJ83hk#21p^#j^u$O=aT!HdlM~ zdTtd<)2AKey*YgHQ`3QmD4=A)F=7(3=5z1H<{SRs@0I{~9*Vn3Tws~PIEuFYt-lBF zosjVA+Yea~K(X43jG+6jO*8&ojje5QBlFt`15#b?Ci3T7RZp9^JqKprMbD|l<{_4{ zNW=>6U&IP(V8lE~m2dS35~;*yI?P_=dis7leZp;GMR!1e<|cLGoY}bB!jRqVL>4po z#O{=oxSL>SjDk#WAaqlLPfDKJc9)$l_NK?6?R15CMHx-F;}d0V2)^wGf2{ehK=Spi zf?JP8L!Ib5JbwGnZy!N?k{ML6#Z_R?{b-(I9o|@B8MHmAIOh%s~3Y@|t}Br&!N^728{%5hHg8_Mzi6vZC%)&>ae9^Tui)GxkNPzRMb4 zX#JoKMPIg?%4{|lyBmq;pDXF8Z=-%i1S&ozH}OKRlKb!@g6xn=G>Tv{#46@6hOqVd zI{sbT!x6~Msh>n2hBAkK(EFqq$*t4V6=!l^;0?;pXKkH`LFwioSp)fkJg=e+eY|3< z*soMynZS`YDtrdf2~#fXEux`@*gBSr^I3d5vBDM>Mv8K&Iz+{+T@RrRBt?bwxFPgs zqeL7V`S8f~LoF4L;m;p;GPWFVS{^)2@yj00U%l_BCpQ*YbM{SKC;7`G#erQ!<>s%4 znFuDcYZtE-p1X=#a4U=Kyn*5MelsBVSHVG23Um-FBjl$R!jv^xW`6mzp~Lv)LDX~Y z?G6A(l+t|XF9B}c#@6<}sdCo@NGR9r&CT=Gj>O#h1_ol%(rEM(0+hRk%bzLb-jAk) z883)F-!AYi6FNT#KP%8lj>|0tGM2`KqrUXm$0Id5U4b1P(%WO}t^;U^KC{4Sw3grKQ7PZq zy7N5GFZ<5$ZKq%N^~-eTI}^;Il^a6V0~+>G31>U$W+On!)^x3Ef814VmU$gMpos!1 zk(>bfcyPzb!Od*6touHP(H%+mJM#KF3w)wkZ9dNuB{w|*#zc0U5j_dMW1Kgs;6 zqN%#&qCETqGs!>eZ}dgr`&cfA*+EWG$Af7KNm8k%WS9KvBcmD>tCvjWv%#+Eee1Hz z+mO=H>Agc!kDC4?r^VEWJ)S0>)#4Ct;7;2ukYCixET%50^=+MW3FAkBu*Sh+NAPTH ze0*)i$jAh{r#i@Q%TJ;Ewyi+KG){`-X3jJ(D^$bzy@}a%1oWx&j^oT$EJ)Y4$Qq?D ztR;j18!3L)d43`@QxRT0|9qVV2rX3^r#?TJ^oWB#xs(~EDwu0r17xyC&EbQthpk$i zHAnsVu{ylq4p-?ZxR1yM4p_}`++kqs0uU1zJy|t(vyMS)YFMw8&qsfKET%`Mv}JDl zQ^~k=WG7#g&E&%vTPP;XR~$oFQ*@R7ZXp#zPe21Bql$WD)VfSicP!r>bwDH7qAI*JF9(E z`Z!?laiHE-`EZ|sZmGu^sLCOf-uPcR8=dDH=xos{a`QM%g7&ypNt3#P%X~MpF^9C& z?3$94jdy^!ya_tssA)yZIG@%CpH4MudK+ndw#zIP0G2`mSc+6O-xiO=t)Qga$i zakMI|Cny!-a@eeSa%NS-k;cu|7Q>Z)-ih9UbNdW__FGXx`ug@6G}m+@^uOt|Eq#DC z5Q_d;nII*J*Zs@W zt4KO5NVc_{V?*@H_XGo$CeF|7_tQyaAe*7w zt-EZUyfgT=6H#vZWb^nvZGHSl-GN7q6#Sd@gnHe{BCh)%?iXl*^!#kq$hLzx-t}nl zas|gwBz|w2)Hc7z=^mR!X~~|{BvDS%<$FjZlB-*aMAA7)a`WTgcN@03+29!1e=lNw zwp?-M`5U(1-XT%`>g|}lZF}^a*{XFGyvqmnmA43Jz{UV0QkN^|3`EZ=n#=mWq~TN* zuYIotkRJ*ORf<>wvXcm(YW6jifwLc2e3J<6^R0-Ql|bPE5|WZJJ2kd0-=-O>-B?)a8ySqs!{^+$unAH;lOOR6u_uYTXUU#@Z)s zrkAgDMJ}3j99`1EI1n!SSOadMqH;@NZF}p{WFJJPqA5hLyVC5^K|~^^7nA?k8im75 zancEA>$st*F}CT-hAh9<-%dqR^mH@O zjeRNL)JMj-_F%>)-e|aH)8G6+^5)kWC(~O-WWc-#0cLu{OFwCwzg7ci@)bbrmbcQ) z#`@VQza+#RN6jnYRdbw?z4*bl)pl()Zy^C42Z%7m7y3GaSShr0erCf`^u97&YXp2C z8Ie$KJ&%y&KW+Pxk^HjXHo>(d@O2;J+jSsg{SUs8NevZEzPRBb@Kw4QTXtK=QM!9f(81O3xwx&XA)kIm2pVI|w4;~fbP9yzV%5>kmpC2*JrWc1B6=kq0%Gx zSkbNQr{Nz!^g8y{`>AVd^!QVs1dW^R&+pG&vIG&J2Ugm->wAQ z6@fJKUgySXi(+ex1@wI)`7aZbvC!>7*a+p_x5>}adZl?FoLH){-PHTNUeNL( zs&ZO-4fcpnT0@iduk$$|%W5I@1nQ#@NG|GIZ=S6kkPJ|L+Vqp&Q}7>u6?Eq^EI8zm z7WHNprYNC2M76M<7bu|tZl2BDYx<8+) z*ZF*(9iMkYpd;+@BMwjB3zr3YJ4sr7NcPkX*4x!Avq(~tSl+ki*E>5LBuCo#7Q*W5 z1@N|Jn?p!rsD5oEwf<1}2)*LyxuuMaFj%ZYC;BE;yGWGGJ`+4(YJauI89tVrbG(mN z7|wntL0yu;Yl~6)ciE)?g*13oEPL{L%8GaTL64?2k~xumUOha%X=ebb7@L=IPF~m%3#Gk*Ln;9rop2ck;o86_dER`@OW$ID{pvYNp&Reh-FBDmFNV zS=x3xGV}8D*+A$oI2uPYy0qAx-q@%vx8-DC=ogopR+I({AEBS(zfP^lynes9vcirgLCOK6I+imq&FYq}s`nGi z-g083EtZ`bzi1{RW`*}=*1enb_#tCa2%F*Z+s}9quZ-2ahrSoI=V*?-Rmy{z#>0++ z%jd^w+k#V>mhW)+?t*O5*81#lzPDlc))e{g_5UFY_FOpXdnz^tQ}sb|Imi>+nOrw- z@KoogerC(s4+5nXWgICrd+_{*XTG-F^&~7#;hgTSbax_DJWzVR?jKALM zFg!J0)3z}XAep%jU6wM_S$%E$GrfQQUSBS-zGXh?jC}AnP*`yj8e8OqF*x*RDV9*% z`K#8rf|yz^+aIaAwgztek{KOhQ)Y;$C3tyV8|fJ{(62DH%dNBetQZ-~qT?0CW1lx< zUUS+;=}mH5z15P^YeD|AEbDPM_5HQOw~B$04Zg%N$7>axyg=Ig)G_kOIlFJ=9s~aC zd_otY<~kdhmbxQY+4Au=i_}uOvk4GffRgvZ_CZ0w2i5Oy+*{|j3f_?a4wEinxB%eN z@pjgi4_ezhg{{!+Cl$SBj0n$k=4j7!pHgg7UYzO+#9aIK4{^NL#5pZO7i`Rq)OU0y z%x1gP$0$}nZ-%jOn`^UnGf5n9Mx^eX;$LYsFOI?HRTYdZ2PKjy=F3vWy~D#xd`D8) z9+wcFNy2GF2EpQwb0!Q3!^u>BdnbY>Q9vM=C=A{uxjb?7h*nj5XQA5*IXnAKC}Ni5 zp2_9tn>4pOz;6WHRk;X_n#90wINJ;o-vqxgjT>B)W9q33*sH>mqJ{vPp$yLgT+`aF z%M2H{_dcQdmCppngtW|Mf5@9QK;G0n*UB*fWgLaaT{Nm^^?1L@0J=}WAg6Xs55B;@ zY38yi+7-PbPPOe1ZMNtnW{93m30dJQ77ynyxG-rFl)$9X7eD2+!zhPoRZ^n4o=w*j z$;wJ!A6%&~Nug~l1|c`?-(IjKp^{+gR?U{0j90DT)dx+6QhQX>r=k%Kj>LoyqwfgQ zN9lCY++VA|eleK{FqygFnaUT~ef|CA4o*%^ggyx`iwFfGR@8$>ztD*Hbdqxo&(7EV zS^ORVC;g8q`Aaql{J+Zh^z9B4_;LI<*G2F$2<$mdEv?b-*7b&8PV-_Q0G0ncW9{`~@X`b)Rnruq;POW~aS55DtvpiA!G0cYo(iiP|y&hF#Y z2ZVk+=6#^RB-in9E@F&@{CKdjjqi9RWZ%I~=>M~)zyInbNufgPc(^sEH±?F^Z# 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 P@JC!k`bD15n~(no8c8KM literal 0 HcmV?d00001 From 0a725ab2612d3b2b88f16eb632ddcc8643c99ea3 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 19 Apr 2022 23:26:44 +0100 Subject: [PATCH 12/76] Delete test.md --- img/test.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 img/test.md diff --git a/img/test.md b/img/test.md deleted file mode 100644 index 8b13789..0000000 --- a/img/test.md +++ /dev/null @@ -1 +0,0 @@ - From 1666ec1dfba55570449dccbb46df503e331178c8 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Wed, 20 Apr 2022 20:30:05 +0530 Subject: [PATCH 13/76] Update README.md Added Feature Tokenizer Transformer (Tabular Deep Learning) --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fd0b89..1c478bb 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,15 @@ You are free to use them for educational and research purposes.
Kaggle - + + + Feature Tokenizer Transformer + An implementation of Feature Tokenizer Transformer on a regression task + + +
+ Kaggle + From 54b3634ef818b5c4521d09dd6cdba2faa05deb87 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 21 Apr 2022 17:58:56 +0200 Subject: [PATCH 14/76] added CEs --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fd0b89..980186a 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,13 @@ You are free to use them for educational and research purposes. Kaggle - + + Countefactual Explanations + A basic tutorial to learn about counterfactual explanations for explainable AI + + + + From 3c1417ecf979b7e37736fe4f5ef8a15f11dbe318 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 21 Apr 2022 18:01:02 +0200 Subject: [PATCH 15/76] fix typo about CEs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 980186a..e5462ba 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ You are free to use them for educational and research purposes. - Countefactual Explanations + Counterfactual Explanations A basic tutorial to learn about counterfactual explanations for explainable AI From 57b0704a08db0cc433eab4bb5245dcc6699c9727 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Thu, 21 Apr 2022 21:56:00 +0530 Subject: [PATCH 16/76] Update README.md Made few changes in the notebook and made public as well --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c478bb..3327ecd 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ You are free to use them for educational and research purposes. Feature Tokenizer Transformer - An implementation of Feature Tokenizer Transformer on a regression task + An implementation of Feature Tokenizer Transformer on a classification task
From 98e98839b201446804a3e86cbef3c5d405cc07c7 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Fri, 22 Apr 2022 17:42:30 +0530 Subject: [PATCH 17/76] Update README.md Added NER (Token Classification) using Transformers --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index a7b731d..ea87beb 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,16 @@ You are free to use them for educational and research purposes. + + + Named Entiry Recognition using Transformer + An implementation of Transformer to perform token classification and identify species in PubMed abstracts + + +
+ Kaggle + + From 71a8bf06c6b871f780f22d34befb812736369dd2 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 23 Apr 2022 00:26:52 +0100 Subject: [PATCH 18/76] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index ea87beb..4738f5b 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,14 @@ You are free to use them for educational and research purposes. + + Bag of Words Text Classifier + Build a simple bag of words text classifier. + + + + + Introduction to GNNs Introduction to Graph Neural Networks. Applies basic GCN to Cora dataset for node classification. From b23089d5e216d6fa67b1696a57b4283dac737270 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 23 Apr 2022 00:39:54 +0100 Subject: [PATCH 19/76] Add files via upload --- img/cbow.png | Bin 0 -> 54321 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/cbow.png diff --git a/img/cbow.png b/img/cbow.png new file mode 100644 index 0000000000000000000000000000000000000000..021c4cdbceddf275c0fc1438f10772b2f729188c GIT binary patch literal 54321 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 literal 0 HcmV?d00001 From 3a48edbae442554a08062107e482f3217c622dc6 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 23 Apr 2022 02:43:23 +0100 Subject: [PATCH 20/76] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 4738f5b..d5aef11 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,14 @@ You are free to use them for educational and research purposes. + + Continuous Bag of Words (CBOW) Text Classifier + Build a continuous bag of words text classifier. + + + + + Introduction to GNNs Introduction to Graph Neural Networks. Applies basic GCN to Cora dataset for node classification. From 3ef67990945ab81fb61348e943819e4e650e7b00 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 23 Apr 2022 03:15:00 +0100 Subject: [PATCH 21/76] Add files via upload --- img/deep_cbow.png | Bin 0 -> 65038 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/deep_cbow.png diff --git a/img/deep_cbow.png b/img/deep_cbow.png new file mode 100644 index 0000000000000000000000000000000000000000..acd04dd06c828ff5efd51c012eb3bf3b9f759269 GIT binary patch literal 65038 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

#8&U-xyVR{dgBAH}qY)psx4AS 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 Mbv=!uYxkc14^o9%82|tP literal 0 HcmV?d00001 From fdaf0418a7f7d20c963abc087770f00ec0260484 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 24 Apr 2022 02:28:25 +0100 Subject: [PATCH 22/76] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d5aef11..277649d 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,14 @@ You are free to use them for educational and research purposes. + + Deep Continuous Bag of Words (Deep CBOW) Text Classifier + Build a deep continuous bag of words text classifier. + + + + + Introduction to GNNs Introduction to Graph Neural Networks. Applies basic GCN to Cora dataset for node classification. From 598f06e2e896a26645f94e431d907ff7d0f9c559 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Sun, 24 Apr 2022 21:57:41 +0530 Subject: [PATCH 23/76] Update README.md Added Extractive Question Answering using Transformer --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 277649d..af8180b 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ You are free to use them for educational and research purposes. - Named Entiry Recognition using Transformer + Named Entity Recognition using Transformer An implementation of Transformer to perform token classification and identify species in PubMed abstracts @@ -191,7 +191,14 @@ You are free to use them for educational and research purposes. Kaggle - + + Extractive Question Answering using Transformer + An implementation of Transformer to perform extractive question answering + + +
+ Kaggle + If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. From 92b8917eac892f3f47eab5251bafe0edd240be54 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Thu, 28 Apr 2022 19:18:38 +0530 Subject: [PATCH 24/76] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index af8180b..946f123 100644 --- a/README.md +++ b/README.md @@ -199,8 +199,18 @@ You are free to use them for educational and research purposes.
Kaggle + + + Text Data Augmentation + An introduction to the most commonly used data augmentation techniques for text and their implementation + + + + + + If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. Reach out on [Twitter](https://twitter.com/omarsar0) if you have any questions. From a5850e55e8fda6528818e99db172fe80eb9e3a09 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 29 Apr 2022 14:32:39 +0100 Subject: [PATCH 25/76] Update README.md --- README.md | 147 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 946f123..9de05c1 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ # 🐙 ML Notebooks -A series of code examples for all sorts of machine learning tasks and applications. +A series of code examples for all sorts of machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. -The notebooks are meant to be minimal and easily reusable and extendable. - -You are free to use them for educational and research purposes. +## Getting Started @@ -37,6 +35,14 @@ You are free to use them for educational and research purposes. + + + + + + @@ -68,6 +74,24 @@ You are free to use them for educational and research purposes. + + + + + + + +
Counterfactual ExplanationsA basic tutorial to learn about counterfactual explanations for explainable AI + +
Logistic Regression from Scratch An implementation of logistic regression from scratch
Introduction to GNNsIntroduction to Graph Neural Networks. Applies basic GCN to Cora dataset for node classification. + +
+ + +## NLP + + + + + @@ -93,14 +117,15 @@ You are free to use them for educational and research purposes. + - - - + + - + @@ -110,6 +135,17 @@ You are free to use them for educational and research purposes. +
NameDescriptionNotebook
Introduction to GNNsIntroduction to Graph Neural Networks. Applies basic GCN to Cora dataset for node classification. + Text Data AugmentationAn introduction to the most commonly used data augmentation techniques for text and their implementation
Emotion Classification with Fine-tuned BERT
+ +## Transformers + + + + + + + + @@ -119,42 +155,6 @@ You are free to use them for educational and research purposes. Kaggle - - - - - - - - - - - - - - - - - - - - - - - - @@ -164,7 +164,6 @@ You are free to use them for educational and research purposes. Kaggle - @@ -173,14 +172,6 @@ You are free to use them for educational and research purposes.
Kaggle - - - - - - @@ -199,16 +190,54 @@ You are free to use them for educational and research purposes.
Kaggle +
NameDescriptionNotebook
Text Classification using Transformer An implementation of Attention Mechanism and Positional Embeddings on a text classification task
Siamese NetworkAn implementation of Siamese Network for finding Image Similarity - -
- Kaggle
Variational Auto EncoderAn implementation of Variational Auto Encoder to generate Augmentations for MNIST Handwritten Digits - -
- Kaggle
Object Detection using Sliding Window and Image PyramidA basic object detection implementation using sliding window and image pyramid on top of an image classifer - -
- Kaggle
Object Detection using Selective SearchA basic object detection implementation using selective search on top of an image classifer - -
- Kaggle
Neural Machine Translation using Transformer An implementation of Transformer to translate human readabke dates in any format to YYYY-MM-DD format.
Feature Tokenizer Transformer An implementation of Feature Tokenizer Transformer on a classification task
Counterfactual ExplanationsA basic tutorial to learn about counterfactual explanations for explainable AI - -
Named Entity Recognition using Transformer
+ +## Computer Vision + + + + + + + + + + + + - - - + + +
+ Kaggle + + + + + + + + + + + + -
NameDescriptionNotebook
Siamese NetworkAn implementation of Siamese Network for finding Image Similarity + +
+ Kaggle
Text Data AugmentationAn introduction to the most commonly used data augmentation techniques for text and their implementation + Variational Auto EncoderAn implementation of Variational Auto Encoder to generate Augmentations for MNIST Handwritten Digits -
Object Detection using Sliding Window and Image PyramidA basic object detection implementation using sliding window and image pyramid on top of an image classifer + +
+ Kaggle
Object Detection using Selective SearchA basic object detection implementation using selective search on top of an image classifer + +
+ Kaggle
- + + + If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. From c76fd0da60e67431f3d09875cf3b857df3e43535 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Sun, 5 Jun 2022 10:53:13 +0530 Subject: [PATCH 26/76] Added Basic GANs --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9de05c1..1739b6d 100644 --- a/README.md +++ b/README.md @@ -238,7 +238,39 @@ A series of code examples for all sorts of machine learning tasks and applicatio - +## Generative Adversarial Network + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionNotebook
Deep Convolutional GANAn Implementation of Deep Convolutional GAN to generate MNIST digits + +
+ Kaggle
Wasserstein GAN with Gradient PenaltyAn Implementation of Wasserstein GAN with Gradient Penalty to generate MNIST digits + +
+ Kaggle
Conditional GANAn Implementation of Conditional GAN to generate MNIST digits + +
+ Kaggle
If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. From fe3ef31bd73a2cdf2f27b31ff4a5c70998474ed5 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 5 Jun 2022 20:21:34 +0100 Subject: [PATCH 27/76] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1739b6d..d03d1fe 100644 --- a/README.md +++ b/README.md @@ -272,6 +272,9 @@ A series of code examples for all sorts of machine learning tasks and applicatio + +--- + If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. Reach out on [Twitter](https://twitter.com/omarsar0) if you have any questions. From 963672941b93eed587b0bc6260f2da2433a4d901 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Wed, 15 Jun 2022 21:27:36 +0100 Subject: [PATCH 28/76] new branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d03d1fe..5549e24 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🐙 ML Notebooks -A series of code examples for all sorts of machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. +Contains code examples for all sorts of machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. ## Getting Started From 97650b1ebfb8c83a29faa766028d9e71c29ec4dd Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 17 Jun 2022 22:41:35 +0000 Subject: [PATCH 29/76] computatational graphs notebook --- notebooks/comp_graphs.ipynb | 326 ++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 notebooks/comp_graphs.ipynb diff --git a/notebooks/comp_graphs.ipynb b/notebooks/comp_graphs.ipynb new file mode 100644 index 0000000..a8dce57 --- /dev/null +++ b/notebooks/comp_graphs.ipynb @@ -0,0 +1,326 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction to Computational Graphs with PyTorch\n", + "\n", + "by [Elvis Saravia](https://twitter.com/omarsar0)\n", + "\n", + "\n", + "In this notebook we provide a short introduction and overview of computational graphs using PyTorch.\n", + "\n", + "There are several materials online that cover theory on the topic of computational graphs. However, I think it's much easier to learn the concept using code. I attempt to bridge the gap here which should be useful for beginner students. \n", + "\n", + "Inspired by Olah's article [\"Calculus on Computational Graphs: Backpropagation\"](https://colah.github.io/posts/2015-08-Backprop/), I've put together a few code snippets to get you started with computationsl graphs with PyTorch. This notebook should complement that article, so refer to it for more comprehensive explanations. In fact, I've tried to simplify the explanations and refer to them here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Why Computational Graphs?\n", + "\n", + "When talking about neural networks in any context, [backpropagation](https://en.wikipedia.org/wiki/Backpropagation) is an important topic to understand because it is the algorithm used for training deep neural networks. \n", + "\n", + "Backpropagation is used to calculate derivatives which is what you need to keep optimizing parameters of the model and allowing the model to learn on the task at hand. \n", + "\n", + "Many of the deep learning frameworks today like PyTorch does the backpropagation out-of-the-box using [**automatic differentiation**](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html). \n", + "\n", + "To better understand how this is done it's important to talk about **computational graphs** which defines the flow of computations that are carried out throughout the network. Along the way we will use `torch.autograd` to demonstrate in code how this works. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Getting Started\n", + "\n", + "Inspired by Olah's article on computational graphs, let's look at the following expression $e = (a + b) * (b+1)$. It helps to break it down to the following operations:\n", + "\n", + "$$\n", + "\\begin{aligned}&c=a+b \\\\&d=b+1 \\\\&e=c * d\\end{aligned}\n", + "$$\n", + "\n", + "This is not a neural network of any sort. We are just going through a very simple example of a chain of operations which you can be represented with computational graphs. \n", + "\n", + "Let's visualize these operations using a computational graph. Computational graphs contain **nodes** which can represent and input (tensor, matrix, vector, scalar) or **operation** that can be the input to another node. The nodes are connected by **edges**, which represent a function argument, they are pointers to nodes. Note that the computation graphs are directed and acyclic. The computational graph for our example looks as follows:\n", + "\n", + "![](https://colah.github.io/posts/2015-08-Backprop/img/tree-def.png)\n", + "\n", + "*Source: Christopher Olah (2015)*\n", + "\n", + "We can evaluate the expression by setting our input variables as follows: $a=2$ and $b=1$. This will allow us to compute nodes up through the graph as shown in the computational graph above. \n", + "\n", + "Rather than doing this by hand, we can use the automatic differentation engine provided by PyTorch. \n", + "\n", + "Let's import PyTorch first:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the inputs like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "a = torch.tensor([2.], requires_grad=True)\n", + "b = torch.tensor([1.], requires_grad=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we used `requires_grad=True` to tell the autograd engine that every operation on them should be tracked. \n", + "\n", + "These are the operations in code:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "c = a + b\n", + "d = b + 1\n", + "e = c * d\n", + "\n", + "# grads populated for non-leaf nodes\n", + "c.retain_grad()\n", + "d.retain_grad()\n", + "e.retain_grad()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we used `.retain_grad()` to allow gradients to be stored for non-leaf nodes as we are interested in inpecting those as well.\n", + "\n", + "Now that we have our computational graph, we can check the result when evaluating the expression:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([6.], grad_fn=)\n" + ] + } + ], + "source": [ + "print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The output is a tensor with the value of `6.`, which verifies the results here: \n", + "\n", + "![](https://colah.github.io/posts/2015-08-Backprop/img/tree-eval.png)\n", + "*Source: Christopher Olah (2015)*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Derivatives on Computational Graphs\n", + "\n", + "Using the concept of computational graphs we are now interested in evaluating the **partial derivatives** of the edges of the graph. This will help in gathering the gradients of the graph. Remember that gradients are what we use to train the neural network and those calculations can be taken care of by the automatic differentation engine. \n", + "\n", + "The intuition is: we want to know, for example, if $a$ directly affects $c$, how does it affect it. In other words, if we change $a$ a little, how does $c$ change. This is referred to as the partial derivative of $c$ with respect to $a$.\n", + "\n", + "You can work this by hand, but the easy way to do this with PyTorch is by calling `.backward()` on $e$ and let the engine figure out the values. The `.backward()` signals the autograd engine to calculate the gradients and store them in the respective tensors’ `.grad` attribute.\n", + "\n", + "Let's do that now:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "e.backward()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let’s say we are interested in the derivative of $e$ with respect to $a$, how do we obtain this? In other words, we are looking for $\\frac{\\partial e}{\\partial a}$.\n", + "\n", + "Using PyTorch, we can do this by calling `a.grad`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([2.])\n" + ] + } + ], + "source": [ + "print(a.grad)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is important to understand the intuition behind this. Olah puts it best:\n", + "\n", + ">Let’s consider how $e$ is affected by $a$. If we change $a$ at a speed of 1, $c$ also changes at a speed of $1$. In turn, $c$ changing at a speed of $1$ causes $e$ to change at a speed of $2$. So $e$ changes at a rate of $1*2$ with respect to $a$.\n", + "\n", + "In other words, by hand this would be:\n", + "\n", + "$$\n", + "\\frac{\\partial e}{\\partial \\boldsymbol{a}}=\\frac{\\partial e}{\\partial \\boldsymbol{c}} \\frac{\\partial \\boldsymbol{c}}{\\partial \\boldsymbol{a}} = 2 * 1\n", + "$$\n", + "\n", + "You can verify that this is correct by checking the manual calculations by Olah. Since $a$ is not directly connectected to $e$, we can use some special rule which allows to sum over all paths from one node to the other in the computational graph and mulitplying the derivatives on each edge of the path together.\n", + "\n", + "![](https://colah.github.io/posts/2015-08-Backprop/img/tree-eval-derivs.png)\n", + "*Source: Christopher Olah (2015)*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To check that this holds, let look at another example. How about caluclating the derivative of $e$ with respect to $b$, i.e., $\\frac{\\partial e}{\\partial b}$?\n", + "\n", + "We can get that through `b.grad`:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([5.])\n" + ] + } + ], + "source": [ + "print(b.grad)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you work it out by hand, you are basically doing the following:\n", + "\n", + "$$\n", + "\\frac{\\partial e}{\\partial b}=1 * 2+1 * 3\n", + "$$\n", + "\n", + "It indicates how $b$ affects $e$ through $c$ and $d$. We are essentially summing over paths in the computational graph.\n", + "\n", + "Here are all the gradients collected, including non-leaf nodes:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([2.]) tensor([5.]) tensor([2.]) tensor([3.]) tensor([1.])\n" + ] + } + ], + "source": [ + "print(a.grad, b.grad, c.grad, d.grad, e.grad)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can use the computational graph above to verify that everything is correct. This is the power of computational graphs and how they are used by automatic differentation engines. It's also a very useful concept to understand when developing neural networks architectures and their correctness.\n", + "\n", + "### Next Steps\n", + "\n", + "In this notebook, I've provided a simple and intuitive explanation to the concept of computational graphs using PyTorch. I highly recommend to go through [Olah's article](https://colah.github.io/posts/2015-08-Backprop/) for more on the topic.\n", + "\n", + "In the next tutorial, I will be applying the concept of computational graphs to more advanced operations you typically see in a neural network. In fact, if you are interested in this, and you are feeling comfortable with the topic now, you can check out these two PyTorch tutorials:\n", + "\n", + "- [A gentle introduction to `torch.autograd`](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html)\n", + "- [Automatic differentation with `torch.autograd`](https://pytorch.org/tutorials/beginner/basics/autogradqs_tutorial.html)\n", + "\n", + "And here are some other useful references used to put this article together:\n", + "\n", + "- [Hacker's guide to Neural Networks\n", + "](http://karpathy.github.io/neuralnets/)\n", + "- [Backpropagation calculus](https://www.youtube.com/watch?v=tIeHLnjs5U8&ab_channel=3Blue1Brown)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.11 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 99c11cf45581ba04b37dbddbd6d452fb7cba7c1f Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 17 Jun 2022 23:00:31 +0000 Subject: [PATCH 30/76] add first shot at DL with PyTorch --- notebooks/pytorch_hello_world.ipynb | 417 ++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 notebooks/pytorch_hello_world.ipynb diff --git a/notebooks/pytorch_hello_world.ipynb b/notebooks/pytorch_hello_world.ipynb new file mode 100644 index 0000000..d60f8dd --- /dev/null +++ b/notebooks/pytorch_hello_world.ipynb @@ -0,0 +1,417 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A First Shot at Deep Learning with PyTorch\n", + "\n", + "In this notebook, we are going to take a baby step into the world of deep learning using PyTorch. There are a ton of notebooks out there that teach you the fundamentals of deep learning and PyTorch, so here the idea is to give you some basic introduction to deep learning and PyTorch at a very high level. Therefore, this notebook is targeting beginners but it can also serve as a review for more experienced developers.\n", + "\n", + "After completion of this notebook, you are expected to know the basic components of training a basic neural network with PyTorch. I have also left a couple of exercises towards the end with the intention of encouraging more research and practise of your deep learning skills. \n", + "\n", + "---\n", + "\n", + "**Author:** Elvis Saravia([Twitter](https://twitter.com/omarsar0) | [LinkedIn](https://www.linkedin.com/in/omarsar/))\n", + "\n", + "**Complete Code Walkthrough:** [Blog post](https://medium.com/dair-ai/a-first-shot-at-deep-learning-with-pytorch-4a8252d30c75)\n", + "\n", + "## Importing the libraries\n", + "\n", + "Like with any other programming exercise, the first step is to import the necessary libraries. As we are going to be using Google Colab to program our neural network, we need to install and import the necessary PyTorch libraries." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.11.0\n" + ] + } + ], + "source": [ + "## The usual imports\n", + "import torch\n", + "import torch.nn as nn\n", + "\n", + "## print out the pytorch version used\n", + "print(torch.__version__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Neural Network\n", + "\n", + "![alt text](https://drive.google.com/uc?export=view&id=1Lpi4VPBfAV3JkOLopcsGK4L8dyxmPF1b)\n", + "\n", + "Before building and training a neural network the first step is to process and prepare the data. In this notebook, we are going to use syntethic data (i.e., fake data) so we won't be using any real world data. \n", + "\n", + "For the sake of simplicity, we are going to use the following input and output pairs converted to tensors, which is how data is typically represented in the world of deep learning. The x values represent the input of dimension `(6,1)` and the y values represent the output of similar dimension. The example is taken from this [tutorial](https://github.com/lmoroney/dlaicourse/blob/master/Course%201%20-%20Part%202%20-%20Lesson%202%20-%20Notebook.ipynb). \n", + "\n", + "The objective of the neural network model that we are going to build and train is to automatically learn patterns that better characterize the relationship between the `x` and `y` values. Essentially, the model learns the relationship that exists between inputs and outputs which can then be used to predict the corresponding `y` value for any given input `x`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "## our data in tensor form\n", + "x = torch.tensor([[-1.0], [0.0], [1.0], [2.0], [3.0], [4.0]], dtype=torch.float)\n", + "y = torch.tensor([[-3.0], [-1.0], [1.0], [3.0], [5.0], [7.0]], dtype=torch.float)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([6, 1])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "## print size of the input tensor\n", + "x.size()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Neural Network Components\n", + "As said earlier, we are going to first define and build out the components of our neural network before training the model.\n", + "\n", + "### Model\n", + "\n", + "Typically, when building a neural network model, we define the layers and weights which form the basic components of the model. Below we show an example of how to define a hidden layer named `layer1` with size `(1, 1)`. For the purpose of this tutorial, we won't explicitly define the `weights` and allow the built-in functions provided by PyTorch to handle that part for us. By the way, the `nn.Linear(...)` function applies a linear transformation ($y = xA^T + b$) to the data that was provided as its input. We ignore the bias for now by setting `bias=False`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "## Neural network with 1 hidden layer\n", + "layer1 = nn.Linear(1,1, bias=False)\n", + "model = nn.Sequential(layer1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Loss and Optimizer\n", + "The loss function, `nn.MSELoss()`, is in charge of letting the model know how good it has learned the relationship between the input and output. The optimizer (in this case an `SGD`) primary role is to minimize or lower that loss value as it tunes its weights." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "## loss function\n", + "criterion = nn.MSELoss()\n", + "\n", + "## optimizer algorithm\n", + "optimizer = torch.optim.SGD(model.parameters(), lr=0.01)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training the Neural Network Model\n", + "We have all the components we need to train our model. Below is the code used to train our model. \n", + "\n", + "In simple terms, we train the model by feeding it the input and output pairs for a couple of rounds (i.e., `epoch`). After a series of forward and backward steps, the model somewhat learns the relationship between x and y values. This is notable by the decrease in the computed `loss`. For a more detailed explanation of this code check out this [tutorial](https://medium.com/dair-ai/a-simple-neural-network-from-scratch-with-pytorch-and-google-colab-c7f3830618e0). " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 | Loss: 38.4262\n", + "Epoch: 1 | Loss: 31.0058\n", + "Epoch: 2 | Loss: 25.0396\n", + "Epoch: 3 | Loss: 20.2428\n", + "Epoch: 4 | Loss: 16.3860\n", + "Epoch: 5 | Loss: 13.2852\n", + "Epoch: 6 | Loss: 10.7921\n", + "Epoch: 7 | Loss: 8.7876\n", + "Epoch: 8 | Loss: 7.1760\n", + "Epoch: 9 | Loss: 5.8802\n", + "Epoch: 10 | Loss: 4.8384\n", + "Epoch: 11 | Loss: 4.0008\n", + "Epoch: 12 | Loss: 3.3273\n", + "Epoch: 13 | Loss: 2.7858\n", + "Epoch: 14 | Loss: 2.3505\n", + "Epoch: 15 | Loss: 2.0004\n", + "Epoch: 16 | Loss: 1.7190\n", + "Epoch: 17 | Loss: 1.4927\n", + "Epoch: 18 | Loss: 1.3108\n", + "Epoch: 19 | Loss: 1.1646\n", + "Epoch: 20 | Loss: 1.0470\n", + "Epoch: 21 | Loss: 0.9524\n", + "Epoch: 22 | Loss: 0.8764\n", + "Epoch: 23 | Loss: 0.8153\n", + "Epoch: 24 | Loss: 0.7661\n", + "Epoch: 25 | Loss: 0.7266\n", + "Epoch: 26 | Loss: 0.6948\n", + "Epoch: 27 | Loss: 0.6693\n", + "Epoch: 28 | Loss: 0.6488\n", + "Epoch: 29 | Loss: 0.6322\n", + "Epoch: 30 | Loss: 0.6190\n", + "Epoch: 31 | Loss: 0.6083\n", + "Epoch: 32 | Loss: 0.5997\n", + "Epoch: 33 | Loss: 0.5928\n", + "Epoch: 34 | Loss: 0.5873\n", + "Epoch: 35 | Loss: 0.5828\n", + "Epoch: 36 | Loss: 0.5792\n", + "Epoch: 37 | Loss: 0.5763\n", + "Epoch: 38 | Loss: 0.5740\n", + "Epoch: 39 | Loss: 0.5722\n", + "Epoch: 40 | Loss: 0.5707\n", + "Epoch: 41 | Loss: 0.5695\n", + "Epoch: 42 | Loss: 0.5685\n", + "Epoch: 43 | Loss: 0.5677\n", + "Epoch: 44 | Loss: 0.5671\n", + "Epoch: 45 | Loss: 0.5666\n", + "Epoch: 46 | Loss: 0.5662\n", + "Epoch: 47 | Loss: 0.5659\n", + "Epoch: 48 | Loss: 0.5656\n", + "Epoch: 49 | Loss: 0.5654\n", + "Epoch: 50 | Loss: 0.5652\n", + "Epoch: 51 | Loss: 0.5651\n", + "Epoch: 52 | Loss: 0.5650\n", + "Epoch: 53 | Loss: 0.5649\n", + "Epoch: 54 | Loss: 0.5648\n", + "Epoch: 55 | Loss: 0.5647\n", + "Epoch: 56 | Loss: 0.5647\n", + "Epoch: 57 | Loss: 0.5647\n", + "Epoch: 58 | Loss: 0.5646\n", + "Epoch: 59 | Loss: 0.5646\n", + "Epoch: 60 | Loss: 0.5646\n", + "Epoch: 61 | Loss: 0.5646\n", + "Epoch: 62 | Loss: 0.5646\n", + "Epoch: 63 | Loss: 0.5646\n", + "Epoch: 64 | Loss: 0.5645\n", + "Epoch: 65 | Loss: 0.5645\n", + "Epoch: 66 | Loss: 0.5645\n", + "Epoch: 67 | Loss: 0.5645\n", + "Epoch: 68 | Loss: 0.5645\n", + "Epoch: 69 | Loss: 0.5645\n", + "Epoch: 70 | Loss: 0.5645\n", + "Epoch: 71 | Loss: 0.5645\n", + "Epoch: 72 | Loss: 0.5645\n", + "Epoch: 73 | Loss: 0.5645\n", + "Epoch: 74 | Loss: 0.5645\n", + "Epoch: 75 | Loss: 0.5645\n", + "Epoch: 76 | Loss: 0.5645\n", + "Epoch: 77 | Loss: 0.5645\n", + "Epoch: 78 | Loss: 0.5645\n", + "Epoch: 79 | Loss: 0.5645\n", + "Epoch: 80 | Loss: 0.5645\n", + "Epoch: 81 | Loss: 0.5645\n", + "Epoch: 82 | Loss: 0.5645\n", + "Epoch: 83 | Loss: 0.5645\n", + "Epoch: 84 | Loss: 0.5645\n", + "Epoch: 85 | Loss: 0.5645\n", + "Epoch: 86 | Loss: 0.5645\n", + "Epoch: 87 | Loss: 0.5645\n", + "Epoch: 88 | Loss: 0.5645\n", + "Epoch: 89 | Loss: 0.5645\n", + "Epoch: 90 | Loss: 0.5645\n", + "Epoch: 91 | Loss: 0.5645\n", + "Epoch: 92 | Loss: 0.5645\n", + "Epoch: 93 | Loss: 0.5645\n", + "Epoch: 94 | Loss: 0.5645\n", + "Epoch: 95 | Loss: 0.5645\n", + "Epoch: 96 | Loss: 0.5645\n", + "Epoch: 97 | Loss: 0.5645\n", + "Epoch: 98 | Loss: 0.5645\n", + "Epoch: 99 | Loss: 0.5645\n", + "Epoch: 100 | Loss: 0.5645\n", + "Epoch: 101 | Loss: 0.5645\n", + "Epoch: 102 | Loss: 0.5645\n", + "Epoch: 103 | Loss: 0.5645\n", + "Epoch: 104 | Loss: 0.5645\n", + "Epoch: 105 | Loss: 0.5645\n", + "Epoch: 106 | Loss: 0.5645\n", + "Epoch: 107 | Loss: 0.5645\n", + "Epoch: 108 | Loss: 0.5645\n", + "Epoch: 109 | Loss: 0.5645\n", + "Epoch: 110 | Loss: 0.5645\n", + "Epoch: 111 | Loss: 0.5645\n", + "Epoch: 112 | Loss: 0.5645\n", + "Epoch: 113 | Loss: 0.5645\n", + "Epoch: 114 | Loss: 0.5645\n", + "Epoch: 115 | Loss: 0.5645\n", + "Epoch: 116 | Loss: 0.5645\n", + "Epoch: 117 | Loss: 0.5645\n", + "Epoch: 118 | Loss: 0.5645\n", + "Epoch: 119 | Loss: 0.5645\n", + "Epoch: 120 | Loss: 0.5645\n", + "Epoch: 121 | Loss: 0.5645\n", + "Epoch: 122 | Loss: 0.5645\n", + "Epoch: 123 | Loss: 0.5645\n", + "Epoch: 124 | Loss: 0.5645\n", + "Epoch: 125 | Loss: 0.5645\n", + "Epoch: 126 | Loss: 0.5645\n", + "Epoch: 127 | Loss: 0.5645\n", + "Epoch: 128 | Loss: 0.5645\n", + "Epoch: 129 | Loss: 0.5645\n", + "Epoch: 130 | Loss: 0.5645\n", + "Epoch: 131 | Loss: 0.5645\n", + "Epoch: 132 | Loss: 0.5645\n", + "Epoch: 133 | Loss: 0.5645\n", + "Epoch: 134 | Loss: 0.5645\n", + "Epoch: 135 | Loss: 0.5645\n", + "Epoch: 136 | Loss: 0.5645\n", + "Epoch: 137 | Loss: 0.5645\n", + "Epoch: 138 | Loss: 0.5645\n", + "Epoch: 139 | Loss: 0.5645\n", + "Epoch: 140 | Loss: 0.5645\n", + "Epoch: 141 | Loss: 0.5645\n", + "Epoch: 142 | Loss: 0.5645\n", + "Epoch: 143 | Loss: 0.5645\n", + "Epoch: 144 | Loss: 0.5645\n", + "Epoch: 145 | Loss: 0.5645\n", + "Epoch: 146 | Loss: 0.5645\n", + "Epoch: 147 | Loss: 0.5645\n", + "Epoch: 148 | Loss: 0.5645\n", + "Epoch: 149 | Loss: 0.5645\n" + ] + } + ], + "source": [ + "## training\n", + "for ITER in range(150):\n", + " model = model.train()\n", + "\n", + " ## forward\n", + " output = model(x)\n", + " loss = criterion(output, y)\n", + " optimizer.zero_grad()\n", + "\n", + " ## backward + update model params \n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " model.eval()\n", + " print('Epoch: %d | Loss: %.4f' %(ITER, loss.detach().item()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Testing the Model\n", + "After training the model we have the ability to test the model predictive capability by passing it an input. Below is a simple example of how you could achieve this with our model. The result we obtained aligns with the results obtained in this [notebook](https://github.com/lmoroney/dlaicourse/blob/master/Course%201%20-%20Part%202%20-%20Lesson%202%20-%20Notebook.ipynb), which inspired this entire tutorial. " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17.096769332885742\n" + ] + } + ], + "source": [ + "## test the model\n", + "sample = torch.tensor([10.0], dtype=torch.float)\n", + "predicted = model(sample)\n", + "print(predicted.detach().item())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Final Words\n", + "\n", + "Congratulations! In this tutorial you learned how to train a simple neural network using PyTorch. You also learned about the basic components that make up a neural network model such as the linear transformation layer, optimizer, and loss function. We then trained the model and tested its predictive capabilities. You are well on your way to become more knowledgeable about deep learning and PyTorch. I have provided a bunch of references below if you are interested in practising and learning more. \n", + "\n", + "*I would like to thank Laurence Moroney for his excellent [tutorial](https://github.com/lmoroney/dlaicourse/blob/master/Course%201%20-%20Part%202%20-%20Lesson%202%20-%20Notebook.ipynb) which I used as an inspiration for this tutorial.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercises\n", + "- Add more examples in the input and output tensors. In addition, try to change the dimensions of the data, say by adding an extra value in each array. What needs to be changed to successfully train the network with the new data?\n", + "- The model converged really fast, which means it learned the relationship between x and y values after a couple of iterations. Do you think it makes sense to continue training? How would you automate the process of stopping the training after the model loss doesn't subtantially change?\n", + "- In our example, we used a single hidden layer. Try to take a look at the PyTorch documentation to figure out what you need to do to get a model with more layers. What happens if you add more hidden layers?\n", + "- We did not discuss the learning rate (`lr-0.001`) and the optimizer in great detail. Check out the [PyTorch documentation](https://pytorch.org/docs/stable/optim.html) to learn more about what other optimizers you can use." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "- [The Hello World of Deep Learning with Neural Networks](https://github.com/lmoroney/dlaicourse/blob/master/Course%201%20-%20Part%202%20-%20Lesson%202%20-%20Notebook.ipynb)\n", + "- [A Simple Neural Network from Scratch with PyTorch and Google Colab](https://medium.com/dair-ai/a-simple-neural-network-from-scratch-with-pytorch-and-google-colab-c7f3830618e0?source=collection_category---4------1-----------------------)\n", + "- [PyTorch Official Docs](https://pytorch.org/docs/stable/nn.html)\n", + "- [PyTorch 1.2 Quickstart with Google Colab](https://medium.com/dair-ai/pytorch-1-2-quickstart-with-google-colab-6690a30c38d)\n", + "- [A Gentle Intoduction to PyTorch](https://medium.com/dair-ai/pytorch-1-2-introduction-guide-f6fa9bb7597c)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 179dc2a6c648e172f3bc9b0a56537c955f705209 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 17 Jun 2022 23:53:16 +0000 Subject: [PATCH 31/76] add gentle intro --- .gitignore | 1 + notebooks/pytorch_gentle_intro.ipynb | 755 +++++++++++++++++++++++++++ 2 files changed, 756 insertions(+) create mode 100644 .gitignore create mode 100644 notebooks/pytorch_gentle_intro.ipynb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbb609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +notebooks/data/ diff --git a/notebooks/pytorch_gentle_intro.ipynb b/notebooks/pytorch_gentle_intro.ipynb new file mode 100644 index 0000000..1cc668a --- /dev/null +++ b/notebooks/pytorch_gentle_intro.ipynb @@ -0,0 +1,755 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Gentle Introduction to PyTorch\n", + "\n", + "In our previous PyTorch [notebook](https://medium.com/dair-ai/pytorch-1-2-quickstart-with-google-colab-6690a30c38d), we learned about how to get started quickly with PyTorch using Google Colab. In this tutorial, we are going to take a step back and review some of the basic components of building a deep learning model using PyTorch. \n", + "\n", + "This will be a brief tutorial and will avoid using jargon and overcomplicated code. That said, this is perhaps the most basic of models you can build with PyTorch. \n", + "\n", + "If fact, it is so basic that it's ideal for those starting to learn about PyTorch and deep learning. So if you have a friend or colleague that wants to jump in, I highly encourage you to refer them to this tutorial as a starting point. Let's get started!\n", + "\n", + "\n", + "**Author:** [Elvis Saravia](https://twitter.com/omarsar0)\n", + "\n", + "**Complete Code Walkthrough:** [Blog post](https://medium.com/dair-ai/pytorch-1-2-introduction-guide-f6fa9bb7597c)\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting Started\n", + "\n", + "We need to import a few modules which will be useful to obtain the necessary functions that will help us to build our deep learning model. The main ones are `torch` and `torchvision`. They contain the majority of the functions that you need to get started with PyTorch. However, as this is a deep learning tutorial we will need `torch.nn`, `torch.nn.functional` and `torchvision.transforms` which all contain utility functions to build our model. We probably won't use all the modules listed below but they are the typical modules you will be importing when starting your deep learning projects. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "## The usual imports\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torchvision\n", + "import torchvision.transforms as transforms\n", + "\n", + "## for printing image\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the Data\n", + "Let's get right into it! As with any machine learning project, you need to load your dataset. We are using the [MNIST dataset](http://yann.lecun.com/exdb/mnist/), which is the Hello World of datasets in the machine learning world. \n", + "\n", + "The data consists of number images that are of size `28 X 28`. We will discuss the images shortly, but our plan is to load data into batches of size `32`, similar to the figure below.\n", + "\n", + "\n", + "![alt text](https://drive.google.com/uc?export=view&id=19AC_WpscyXkrK_o4PaFFGpt_jG0aJm_f)\n", + "\n", + "\n", + "Here are the complete steps we are performing when importing our data:\n", + "- We will import and tranform the data into tensors using the `transforms` module\n", + "- We will use `DataLoader` to build convenient data loaders, which makes it easy to efficiently feed data in batches to deep learning models. We will get to the topic of batches in a bit but for now just think of them as subsets of your data. \n", + "- As hinted above, we will also create batches of the data by setting the `batch` parameter inside the data loader. Notice we use batches of `32` in this tutorial but you can change it to `64` if you like. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2.0%" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n", + "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./data/MNIST/raw/train-images-idx3-ubyte.gz\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100.0%\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Extracting ./data/MNIST/raw/train-images-idx3-ubyte.gz to ./data/MNIST/raw\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "102.8%\n", + "8.6%" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n", + "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./data/MNIST/raw/train-labels-idx1-ubyte.gz\n", + "Extracting ./data/MNIST/raw/train-labels-idx1-ubyte.gz to ./data/MNIST/raw\n", + "\n", + "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n", + "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw/t10k-images-idx3-ubyte.gz\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100.0%\n", + "112.7%\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Extracting ./data/MNIST/raw/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw\n", + "\n", + "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n", + "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz\n", + "Extracting ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw\n", + "\n" + ] + } + ], + "source": [ + "## parameter denoting the batch size\n", + "BATCH_SIZE = 32\n", + "\n", + "## transformations\n", + "transform = transforms.Compose(\n", + " [transforms.ToTensor()])\n", + "\n", + "## download and load training dataset\n", + "trainset = torchvision.datasets.MNIST(root='./data', train=True,\n", + " download=True, transform=transform)\n", + "trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE,\n", + " shuffle=True, num_workers=2)\n", + "\n", + "## download and load testing dataset\n", + "testset = torchvision.datasets.MNIST(root='./data', train=False,\n", + " download=True, transform=transform)\n", + "testloader = torch.utils.data.DataLoader(testset, batch_size=BATCH_SIZE,\n", + " shuffle=False, num_workers=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's inspect what the trainset and testset objects contain. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dataset MNIST\n", + " Number of datapoints: 60000\n", + " Root location: ./data\n", + " Split: Train\n", + " StandardTransform\n", + "Transform: Compose(\n", + " ToTensor()\n", + " )\n", + "Dataset MNIST\n", + " Number of datapoints: 10000\n", + " Root location: ./data\n", + " Split: Test\n", + " StandardTransform\n", + "Transform: Compose(\n", + " ToTensor()\n", + " )\n" + ] + } + ], + "source": [ + "## print the trainset and testset\n", + "print(trainset)\n", + "print(testset)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a beginner's tutorial so I will break down things a bit here:\n", + "- `BATCH_SIZE` is a parameter that denotes the batch size we will use for our model\n", + "- `transform` holds code for whatever transformations you will apply to your data. I will show you an example below to demonstrate exactly what it does to shed more light into its use\n", + "- `trainset` and `testset` contain the actual dataset object. Notice I use `train=True` to specify that this corresponds to the training dataset, and I use `train=False` to specify that this is the remainder of the dataset which we call the testset. From the portion I printed above you can see that the split of the data was 85% (60000) / 15% (10000), corresponding to the portions of samples for training set and testing set, respectively. \n", + "- `trainloader` is what holds the data loader object which takes care of shuffling the data and constructing the batches." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's look at that `transforms.Compose(...)` function and see what it does. We will use a randomized image to demonstrate its use. Let's generate an image. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "image = transforms.ToPILImage(mode='L')(torch.randn(1, 96, 96))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**And** let's render it:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "

" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(image)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Okay, we have our image sample. And now let's apply some dummy transformation to it. We are going to rotate the image by `45` degrees. The transformation below takes care of that:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD7CAYAAACscuKmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOz9d7hl2XnWi/7GGDOvvNbOqXbFruqq7uqoDmqpuxVasiWUDHLEx2BswzFc8rnmwrnACdeGy8MFfDFgkjE2DrJlS7ZyanXOoaq6qrpy7RxXDjOOcf+YWyUfLuAguSVQf8+zn6od1txzzzW+Mb7wvu8njDG8aW/am/Y/vslv9Q28aW/am/bG2JvO/qa9ad8h9qazv2lv2neIvensb9qb9h1ibzr7m/amfYfYm87+pr1p3yH2DTm7EOK9QojXhRCXhBA/9c26qTftTXvTvvkm/qh9diGEAi4A7wZWgOeB7zfGnP3m3d6b9qa9ad8ss76B174FuGSMuQIghPhV4IPAf9XZHeEaj8I38Cu/cy2eKTBda5EhiY1FqiWDxMEYgWcneCplkDrEsQUGyET+L4AA5WUU7IhuL8DbSjCWJC0qjAArNIjUILQBY0AIjABhgDQFA8axMZa4cT/aEaSBAQEizb9eLI2Yc7rsZh47YRFjBF87S1w7xZKasOlh74YY1ybzFUaCUWAEGNuAMhTcmLo1YKBd2pGPziQiEggDVilhwu1hAGMErTQgarsIDZkHKIOyNLbKCEc2dk9gJKTB17+nhCYObVSY35tRoC2YrHTwZcz1nXHcdkbmKjIXtA2FYkicKeSGBb3hG/Om/xEsZEBsIvFf+t434uyzwPLv+XwFuOc//yEhxI8DPw7gEXCPeOc38Cu/Q0wIpO+DELnzKcWVv3iCv/09H2MnLfNaf4bdqMC5jUnSRHFsboNj5Q2e3V5kebUBscTqKoQGkQACrGNd7p29zlefOMGRf9ckK3vsnCygbUH5WorTjpFxhkg0xlVkvoVINPZWD5FmJFMV0qIN2iA0dBcddu5PQBnsDQeRwe0Pv87fnf1dfrN7Bx+/dpI4tYgjCyENc402BTvm2icPMP9ba0QLdZrHXDJXkPpgLAjHM0wx48i+DT48/TLnR9M8tnqQbt/HvhAgI5h4xyp/Yd+jtLMCO0mJz28co/WZGVRoaB/TiHpMuTSiXhhy9fw0M1+BpCDZucOgSynF+pCCG7Nzdozaa4LMg7giCMc1P/GeL3Czt8rf+KU/y75P9ejvC+gsKkbTmlvvvszmsETw0xXkV1/+Vq+Q/6o9a770X/3eN+LsfyAzxvw88PMAZVF/E5v7BzBrapLWg4vEBZGfuhqS+QglDI/uHuH1J/ZjDQTeCLSCS84YdXfAZruEs27nJ7EEaygYfyV35CXKvOLMkJUylr97DLdlaJwaIlNN51CB/qyP0ICBwZxA3tIhTRXZyjjWQFC6CsFOhrsTYW+06e6b4btOngHgC1u34+0InnvhCB+4/j9TLITMVjoU7Yh5v8Ugc/n8xaPopou5KeHc/7OBcjKKhRajoYu4EmD1BRPPCdy2ZOPQAv/wwCzWxIgPHjlNOwn4Yvc4VkchhWEzqfJvLt5P+mwNewD+riYpCIoLXe6ZXuLp1UWunp/GX1WoOCX1zY1oZ3itTBgJGmeh/kqL/qEK3YOCrJzxiZWTfN6+maSk2bivhLbyTUgkgou74wx6Hoej9Fu6Nr4R+0acfRWY/z2fz+197U37Bs2UCrQPSuKqwR5IRAqVypDMCFa7ZWpnDfZQA5C5gvVjLsPUIRnZFDoCrSANDCqGwsUmZnmN4Lbb6B4IEK6mfzBFL1nYn9vBDIZkNx9lNPH1yC85POL/dcvvMtQuvz5xF6udCmG/htcRyCTD7LaAGd5Xe4XMSL4gbscaGopLkmwjoH3Q4paJNea8Ng+VzrGRVvhM91aCVYV1T5cfP/IEiVH0M49T3VleXj6CTKF8eYR1YRmntw974NE8EXDn7dcYaJcvF4+QJfk9djKf7lqJQ48PQQmimk3qK+YqHd5aucgTSwfwNhRu+2upyd4fpgVOS+J0obgSweVlnPECWVEhvZSNZjn/MdcwmMmfnxoJhIZh38UMLEQaY74Wcf13Zt+Isz8PHBZC7Cd38u8DfuCbclffoabGx9ELE4QNH3sIxhJE+yOK1SEVP+R3d07i2Slr70oglXleLjVjk120EZiRwtsxqNjciAh6NzcwJxqEY5DFCrXpULoKKja03prv1UlBoEYwmjTo8ZhqacizvYO0k4DLW2MkIxtOhAxOQOFMmcnSIbQN/8ur34NSGm0ZBrOCdN+IqfEOVujy9NUDTNS73Fa4TmIsZCixB5BqSUmOeKZ3iEevHyIcOkhliBqw/EgB+fBRiiuG6sWIsO6xnNS//oAMLG3V+UR4KyLIuP4+H20bsmoKaNovLvDT0T7k3qYQjglG4zbaNehiinAywkVNqMFIlzF5lM4BB+FHuH7CZKUHwNrlGaoXIS4J4kru/FPjHbKG5Mr3jOO/7T6mnuzBc6ff6CXyDdkf2dmNMakQ4i8CnwMU8O+MMa990+7sO9Em6jRvKaMtsPsGIwQHF9f44Zmn+PXNu3lpaZ59E03+wVt/g4KMaGcFBtrllf4Ca8MKaiApbKQ4rRjr0hpUiix/ZJrBrMbYKUSSYF0w+VSTcLrI8rtstK8pLIHdM/QrKXcevE6sLV5pzdEcBKTrAULD+97+Ij8x9hh/pvHDbMfjyBTcL5bJPIHZn5HMx/zALS/wk/Wn+ctLH+T0F29ibcqht88nQ6JCgd0zRJmkqoZc6TUQL5XxBIQTmqyccvORJW6vLvNrv/EQjU9epjR9jOWwjq+SG6ez3vBorXm4+wa855FXmXY63O5f48nBEb7yd99K4fNnGDxygp0TFuF4RmVfJ39h6CCE4dDEDtN+ly85N6Edj6hmcIOEchByV2MJgM/vztJ4ZpP+zQ12KxaZr7m9scqU2yGblbTSgMeHdzP23LdonfwR7RvK2Y0xnwY+/U26l+8ok0FAescR4qpDcK2LWN1kNFeifQRUJCguGdy24bXLs/zT8J2sb9RQmw7XsgZPVI8gheFKf4xe7LK6WyHpO5RXJG5ziAxTRKlAVisSVQ1U4zwSSAVJEXqHK6SewG0KjFI4HYMKQTia2yorPLV7gCuXpvIqu20wyvCV5cOcas6yc6VObWSQCajIkO6lsNIyeDJBCcH2qEhhxaAtRWhsGqpPOh3RTVyUMHyqdZLVTuVGFdwUUpSfsdSp0gwDRAZ6/xyZK3hyfT8lN6ZQCkm8lHDXR/UUYdvjy8uHWai2OTG3zJjVp7PPwr3jCGFFITJwdxX9YY20nLHv0BZjfp8Jr48vY4rlEYMJB13MKLkxnpUyyhwSI5EpoDWZLUhKBmzDRliim7psDsu0Qh+n950Vxr9p34DJ8QaX/iebk0euc+nTB5n7ksX27Q7vevdLvLA1j7rQINhMCLYVmTPOXGYQaUZ3n8/vJCchERQv29hdw/iuxu5r/NUmXF1FVitEhyYYTjroxRFHp7e4st0ganmM5lLWpgV2UzDxUobdS0EKtBJ4xYi/VH+Zr24fZvG3NElRsfaBhEIpwv3dCt4rgv2VlLhqIWOD00uIqjYtLbHsFFcmACxv1Tny1U3swQT9D3rc4i3zfbe+wLVDDV5Zn+ULz92KiAXKN2SBoT7ZxbEyts+Ok2xKVAobD+SbQfbkGN2q4aGHT3FbaYmfO/d2ol6Z4KqN81yV1w9X2Z4qs8/ZJn17h8uHijhNgdOFyhVN9eVt2reP86EHX+FPls7wVDjLStzgzqkVLvshtsrwrQRLaLaiIp3IR0V5rh8XJel0jOVknNuaJEkUXC3gtAUz1wbf4hX0h7c3nf0NMlWtwFgdkWaY/gBdKuSV79TJT5LMYCRMOl0qXkjXEhhLkASS1BPYQ42d6K9fUELmgvQFMgWnm2BcG3FwnrjoMJxwCKsCAYxSO3+NZSDNe9oAQhuEgcwWZK5Ea8Famp9YYcMicwRmZDEEgpS8/y7zDoAUIFKDTPKfN0bwaneej8kYs+0iegPskWY1qrLtlhmz+8iC4ZScQYYCmQpkIjAR9IcelpXlubYG7ez1zE3e6xcGdqOAdbeKEKB9jR7kPXqh4VI4ScUq5c74e0xmBjGKsIeac4NpXnB2eKxzlKVhDYCyGxJlFluDYv4eSc0wcnCTrz0fMKkgkxJtS4yWOfYAiCsOhcUFTH9AtrP7zV0sf0z2R0bQ/VGsLOrmO7XPPvzIPay8P0O1LOqn85aaVvlCrlwcIK+usf59N/HIjz7F6fYMy59axBqBfneLB+cu8btnbqV42mUwqzl0coWKO2LMHdBNPF79+M1MPz1k5aGAyYdW6YYuzc1yHrprEEYgyjFeEDNaK1K+qJCxwRrlLbrhlCAtGOLphNp4j4lin5O1VV5tzbLxW/sItjXtw5JwPMPuSNyWwG0ZqldCkoLF8rsUZiymcMajfDWjsBpinb1GfNtBrv+4ZnFyl3dNnGefs8PPXn2Y9QvjOC1FcTlfe6kv0DaMJgxZSWNEDtZBGoSXYTKJ7FgIDXJ2yEy9y06/wKDtAyCkwYSK6hkLr6kJq5KkDN62oXo5Ig0U7YM22obScobbyVh+l83dbz3Py2tz2M+UECkkuc8z+WJCcGGb/s0T7J6wiOqG4Egbx8podwOyRGIGFmokabwqqP3aS5go+hatrP+rPWu+RNc0v+mgmjftv2ZCIBwHIQRf20wHk5K7j1ziUnOMfrOB2xZUL8U4rQi108WkKewd3JbUaDv31Xunl/hzY4/z4tQ8zStT6ELGZNBlzmtzZ+EaPe3xYvFmjCUIJzP+8uKXODua5Tc5SW/gka0FqFCQFiSekzASoML8RE8KuZMlJUNaMIiRorVSoXZkxN8ce5KPe4f51/0Fgs2Y7dtc/Nk+I1XEGiq0Q36/v6etVVzRVJ9ZhSTBACLVpD2bnUIBJqCqhgR2gnHyF1kjg8zAHhoyWxCOg3G+Hr0IW+P4CUlk4XQcZATxtKTuDfYes2E4cBHrHvZA4LY0bicjKQhiIdAOxBULmRqqlxJkovEvbaN3W/i33EKYWURDm8qGRqYwGpOYveBABx4iM7gtQ+YItBEoqXHchFQprGKEUprheo26EPz3kMG/6ex/DKYmxtn5roOEDYHTzYtfrdtSHqxf4NbyKs+U97PZL7F6qoG36yDjEjKZoX1bwhFvg9e7kxTWDE5f8/j1A5StEWtLDRrrhrRgoY1kParwjzbeTW/koW3Dzi0+Joh5vHuE1bDKMHRJhg7BtsTuQ2dcUvYivEPbjBZsDCCFIYoc7BfLVC+A0zPYA8P1d80wPGI46q6x+3BEa8sBYQivl/B3JP62IdjJcJZ3UWNldBAwPt6ldXQMI+dwehpvJ6Zz0Gdsdpeb6lvUrNxBHxy/yKTf4+nL+8mueyQ29BZzyGrpKvgv70FoJWS2ReY5RFWBuLfNbKXDpfUJXjl1IM/5Y4GV5OAhY8HWIzFBKWK4UsTbVERVQRpYqBEU1zNk9rWSvmby2SFL3UPU9V50MyEI39ZjutZlu1ckHPn4r9rMfqVHOOGxSZW2guKywRoZtu417D+2zrpXA/nfB3n0TWf/47BykZ07NYW5HrvbBVRPsW//Nnd617BFxneVTrGc1vlfkw/Q2yzuJaawb3GbWbuFJTOC7RR3J2RtM+D5yj7snTxEHQwUqZH0I5eNqw2srgIF/TmD8jMu98dpRz5JbEEscTrgdjWdTFCwY07Wt3lb6UKODzeK10Zz/PYTD1J9fYi9vEO6skp5/30MtGRW9Xn30XNcmhnn6mszBOsSt2VwOxp3N0FvbCEthfBc5kptXp6p0NEOblOSOYLRpOCW2ja3lFapqtzZ7wqucldwlaVejb4zReYL9MIIqTKCZ30qT10Hx8bYFiiFDlx6h4rc/icv80ONp/jBtT9H6bICDTL7+iOPKvD+46f53vqz/M/yB0m2a6SeIa6B1RcEOzneH5FHuPapK0ycszBzk+zeXiWuwvfe9BLvK79y45rft/sXEWevUNgZo1qZBgO1l3YQnR7tIwepuUNW7TduWX2j9qazfxMse/gONu/08jyTvJ2kRobh9TLCNmSBZnmrxk9G3890qcf7J06xnlQZXi9TXJX0DyWMzXRoDX3+6ssfJWx7lI/YyAM2phAziG3svsDfialcdnnxiZvIippgqo81o+lulLDbiiwTDFIHz0o4NL3FVqlIcrmBPRA424rX7Fn68y73Fi+zmxV5pb/AlV6DpATdgz7OxCz2kSmGU4LnwwUckTHKbCyhMV5GUhSMJgw6MLhbHuNjJ0kCgXRCWlGAvW1TupaffNZee04KQ2Ykz/cPEGmLea/JjN0mTK18j8sgG1poR9A5oMjcRYLNBHelQ1YLGMz5DMcVL+7MMcoeRA8tUg8y35D6IFNysouCT50/wRPlA3TXSni/J2vVrqE/LZHjDlt3zKKdWWqvaypn2qQlF5kY3KbgF5+9n18p30mWKHQqqZ2TeWdjX4Pt23MkXelaAavZoX5Wc4Yj1M9phGMjMhcTx9/WyLo3nf0bNalYfpfLv/q+f4kUeb75WP8ov/zxd+Bfge4hMJMxaslDXvK4vDDGo++O6Ccu1bOC6qWI/kHFe+bO8Sun72Lqd1yiimD33hi3FOFLwyhycDvgLLeorytqZxy6N1U4+FeX+e76af5e/H50q4hJJP3YYbbY4f3jp7gUTvKx8gO4TSisQrDpcF2MES8otpIyj68cYNh3oa5p+oIcG6VIpiO+2LoZV2YMUwclNbKQkqSSI8dW+Kl9n+FTnZP8xuRdoAWBm7A7CCguQePlNtq1yAIbGVnYMiMxiqe39tPsB5yYWufe6lXCxMImd3bZU+hA0D8WMzhuqLzgMrVjE9VdWkcUacHQvt5gY7WG7CvSoiEeTxmb6dAdeETLAdZQUHnSwxp6lBqCpMyNzTdzDYMFQ1bQ/Pm3foUfrrzM2x7/Szi9EkYKrMhgr2dULxlUbGG3QsQwAkuhxyq0D7q87W1n6CUu208cwDqfUv3yZWpflXlNxnWRQpIlKZjsv7JQvvX2prP/IU24Lmp8DJRE7zQxUYTdE3yqcxKASFssDepENY2R+WozLQcVCbRtMNLQT1ySTBE2BL3YATLOdGbQsSKsCtKCgEyQJhZSahCGbMqw/bZp7JHB6aREFUHZighkRKM8YK3hgYGNjSrNoEA/cenFLkhIyoLUy6madhADEMiYiVKflspoxQpjK4yXofyMenmAKzOk0HgqR83UqwN6Tko79PnHK4+wPSwgXI3JBKOeh8kEVSUIpwrI1CCy/HR/YX2ea8U6rUGeWpxen+Hc9iSDjo+1CEYadDEDWyNUfipqRX4/MqfpykRgtxRGqDxaSAXovGBW8CP6syJn12Uudg+Scs4NMNLk9FnLYAoZykt5vr2PTupjNLSO2DcKjCo0lJc1RGCUQNgW8XiB0YRDXBE8t7pAlkmCOQVvPYw1ylBhhuqFyO32jff629nedPY/pKl6jd0H58lcwfjTHubKEmOvJnzKug+ZgjWEuAL7H1xhodji8SeOUz8lSYowmhAkJc3OsIBnpah7WnRjC1oeZ57fj3AMzbvSfCH3FPQUSUGDo7nl7Vf5k3/qBX5j8y7OP72ftKiZcds4IuOR6fMsVet8+dVjTDxmI7RNm4DUE5gD0DuYIesR5eKIo40tHJGxz9nhx+Yfp50FfLJ0ks1+kbdOX+VdlddoZkWuR2NE2sqhqsD9tStU1JD/4ysfoPQrJdJDHurdIwCcMwFON29dbdznEKwZqpdiClsp+rMVdgtVwgWNLmRUnvMZe6HL6rtd/uQPPgrAVzaP0Bl59Po+WagwCtKSg7YF1hAYgdsGmRiSoiBzIa5ItBEcaWzzIzc/SYbgn82/i+VWFZ1JyCQ6lZhIoQoJt82vkGrFa186wvLlw5h7NLf8qbO0Y5+1bpl2q4CKXYItQVpQYGDnVpvszh7RRsDMrxTJbMHuBwccmF3j1OoM6bZP9TWf6U/1IY6/NQvyD2FvOvvvY7JUQgQ+pCkmTjDFgDQQpJ4gmShiJzPIzBCsG9gDnIhMYMsMXyWIVGCNDJm7JyZhQO+hWgpujGtlRDs+dleSVDS6mmGS/EIyAzOSmFTgqYTbvBVOl+Y5XV1AeHl43NUeY3YPTyZ8WR7D6WlUrFGhJikpugdU3s4ygiixaMc+y0kdW2QoDEPtAKCkQRtJaGw2kwqv9aYBqNghrkxppgWG2sFuK5yldfzGNC3ySFlFYA0N4ZggGsuwuyoH7KR5Lx8MVl+QapV3J5pdrGGFxCiUyIUmbCvDcRMSYUjKDsNJh7goSEp5qO81c/KOGYr8ukNBf+TSDTw8kSCFpuYN6QQeSSbRWjIYOSRRroyhjSA1EqsP/k6KjFS+kTlAOQcFhWMeGIXb01gjTebBVLXLta6LCiUYaFQG3F+7ws6oyFJkkZQ9dKWIlALRH2Cib98w/k1QzX/LpGL4obvYul3i7Qgq11K0JQjrktQX9PZrdDWh8pLL1DM9tm8v4n1kEyUMyysNRN+idE3ib+/1jg30FiTjD68R2DEX1ydIBzbOhoW3K4irEE6mCC1QfYmMIdgQ2H3D7u2GxRNrRKlFN3SxpGam3KVsh3xg7BVOuqt8+LmfYPxXA6xBhrsbkpRdVh52iMcyKmctqlcS2gdtOicSSAXOrkJoQdzI8hC+Y2H1JW4TqldSRg1F+70D6uUhnecmKF0zBJsp/mqP3pEKq+/K1075nIU9MDTfFvHgTRd5/MnjHPy1AdGYx8Y9Nto21M6D18yIy5IkyJF4CIiqgujkkFplwL2T1zjsb3EtbLAaVvFVQsUecaU/xsWvHCBYN5SvJXibQwaLRdoHLaKagcMDPDdBSY2Shvlyi4VCiyfXD9B+rQFAVtRgwNtQ2H1uKNCM5lLecdtZSnbIKLPZDotc+dhhpr/SZPWROvX3rrE7CBhdqmBsw513XeS28gq/ce022stVrJ7E3RX4W4bxLy2hd3bRcQL6W+P0b4Jq/jAmFUIKjDZIx6Y/o7Bu7tBbKWGNcoIF5JBTf1+Pt85d4fFLt6O22kCRR6bPM9QOa2cm8Tcl1iB3CBXlHPTRmLxxsqeRQgwV1kggY5AxiFjegIjKTOB2NF4zY7Bpc22sgeslTJT7AOyOAvqxC2MwpcBx0j0nEpAZZKZvwDsLm5rCK6tgZolqNiqC8rUcFdM6qoirgsKKpLSc4W9E2KeuEByYY/veIh1lqFzS1J/bzuWpPAutBCLlRhHMSChWRjxQucijpaMIbTAyT1uQ4HY0wbUu0ckqw2lBYdUw9lKH0UyB60csZNVwU7DBQ8EFkkCS7V3YFppnggP8g/IiTktiDTPkxi6+o0i9AtZA0LML9AKNNRbi+zFFO+Kgt81L9jzdOM/5raG6cZ9xGbzdXPRCOwpLZiy4TR4ovM5Qu/zFwmFkf4iK66Ra4jsJ0dwQZWkqdkhiFEmmELEgcw3DGYOREuO7YNuINMX8HmTzt4u96ey/x6z9+9h8xwyZL7AGOR+8fWfERxbP8YnwJPbQBWA0Lkk9GG4U+OLgKNXt3KP8Xc0vnr4HIcAa5GG70zN4zTQv4EgormX0PjlNKwAOpsjxkBEemScQWuDuSlQM3k4e87eOCpKyRI0M9hWP0YSNXeughCbRkkHs8Lef/xB/a2CBFvQfBJEqrGE5F7GYjLHcjLWHHTbv3od2NSaIsbdt3HZeZBqOe2Ak2oLBlKI3G6DvP0FSNDi1AZ6TsPVIzOYDDcrnLcZfCRmNSw4fyymhV/rzOB1BYGV0soDC2JD1t1ZQsaG2R3oejiuGE7V8k9zK+fbRmM+oYeGV+4wFAzppwGvxFP96+e1cPj+DrMbctrBMJ/aRaS4h1Z938d05hIZgI8bfFpRWFMaCJPBJvYCn3uVyy62rjPl9VhYi6NqUrijsvsHtmDxEdwTaFgRr8JUv3cbnxxPqD/Q57GwQ1Q3DmyYQqWHj9CR6IuLdx85RVBGvdaY5vTvNYKlMYVVirDxCcLr5GhCWhRHfniCbN53991gyXaX1cEilPGRntwix5KFjF/iB+jM8VjmENXLQVq6ZlvoGb8uCDQt/Nz/uvWaCf8ZHW9yIAOyhxt0ZkRUdkqJFsBFTfWIdU69w/i9UGa/12DaCyLax2+pG2F6+HpN5kvbDKe88dIEvvnScyosKoxTqSF4l7+MSpYryMz5jr45YfpfPbe86j8QQZhaxttgdBaSZ4tYDl7iltMJr/Vle3ZlhJ6zjtCNUZ4Q35+QClB6EDQinUo4cWUMIQzv0EcLwfbc/zj3BZf5s8CPULiiiGnz/bE7o/vtLkyAcqlZKL/OYrnS5dCLAXbNZ+NwAkWrWHioxnNIUr0tKq/nDiasWcUVQLQ4Z9/r0M5dL4RRXTs9y4LdjOvs9XnzbIkIaLJ2H3sNxSVJwKK6lBJdaiDBCb+9isvya0nXpHDpOdMKm4Q5ZmG6yYtWwX/EIdjIKV7vI3S7J4gT9OY/ClqZ6KaW76HDprkmOOuuktZTevI1Mofo6tCyHHxx7moKI+QsbP8j2apXCuqSwrslcQVIQ2H3yiMqycpbQt6F95zq7EKiJcSgV0LUi4bhHf9pC9zO60mdsvEfRjciM4Dfbd9EdeBQb8oYaqtACu5vju+1+vtDCuk14ywgpNWY5QI0E27dZcLKCNcx3f6th4VUWSIoSigmuypgbb8E4XL8ygXVZ4fQNMsowArKOzevtCeQoLxC5TcGll+fRFjlRJBXUQkMa5G2pi80x0kwxGLpkkcLadFAxPHYoYH26jBSGqWKP3WqRcMzDVfl1VZgXEbWTo/n6iYNnpcwUO1hS83x7H8+392FCReeATVzRPNc7QGYEJPlJtrFT4XfTEzTbBWQvv5+o4WIUDKc0anqEWSngb8eEDYferCIcg4rKSLTilfYcw8RBRrnCzHBKcGBhi4Ids9ooE8Y23WaAHCjiko3IalijFKtSQCYZYhTlDidgI6qw1K+xsl1D7zo52k6ADhxEWsRIkRf8FIwmbKKqYDsucj6eRoQ5p13bOSMQYzgbzhLIiDSTIA0qypGJUUUSlwVpAKMDdaxRGTlKEZlGre2Srm9869b4f2bfsc4ulCLbP0V/3qd9SBHePEJHBnvLJht5vOfmF/lA5SX+8dp7+PWzd5J1bfrzuZMbaZCJoLCh8XdSnN28BdWfVfzcPb9EguIvm+8jbrncf/vrfHT8Of750ju4/PJcnuxLiXYNtUaPohPxXRNneEfwOj8c/wje52o4nRQ1SBCZwdtwWbbH8DoSMJSvZ0w/PsRYkuGMR+rmVM64YuUY/KUacijzCKFnGDs1QLWGrL9zgvPH5inOd/nA4hm6kUd3fpqk4CH20o24LMi8vGDQHvhUCyPeObGEJxP++csPYl3zkEVD+/YY6WQ8vnKANFWIOHd266rHIPJxTU4PlSn05hRpIGjctM1bJpb46kt34lzaJC7P0T2cQTWh6ESEmcW5a9NY2w7WUNBbUAwPxfzdA59kXvXRQGgUT44OcnE0yScu3MKOLGKNbJyuh4oN/nZOdjECrg3qXN1qYF3ysfugYo0RgrjioHwLIwR2LyUcs+nuk0R1w+qwyuP6CFZfoqKcAJMG+Xp5rHWEghUTpxbCMlgDg78xQlsBgxmIXMFO2QaT42eFgckXHOSbzv7Gm7AdZLEAloUo+BjbIvYs1B4f2/UTRqnE7uU8a1tkNGSExKATiUgEKsphmUkpz6eHE5LMtvECiVNyicuwnZUZaBezp9tetUcsWC3G/T4X/a/psoOxNY6VYQlNQUaUpKboRgyLEiMt0iCXeRYGxFChLUPUEAgtCfYAJ1oJjBTIUKMikxMyigmZtEgDC4wgHPewPQtrZAhWFX1T5vP2UZrtIgVXEJe4URlXEXjbklALGMufWyfz6WcuemTlhBMbdCLRkWTQchCZyAuMaU5IUREkASQVg4zyZwbQ6hQ4Zc3kcltpirYFppQSFCI8lWDJvD2IJgfOxCBCxcVoisTZpiRDFIaCjJhwujhOHk1pO5eCVlFedJNJhrcrOLs0DR0bL9lLqUwekfXmbDJP4LU0bisjLgpGsxmiGjPu9SnZIWlRE9YV2s5fo0LBiyvzWFbGaOBiIolMQEQJMs0FLbUDcVWDAH9dYvcMcvTtpUT7HePsqlFjdGKOpGzR2a/IHGicTSlc6tKbq5NZGYSK+vmM1M+HD4wphbuHILMGkuKyIWwIvDvaTJe7dG/2iDPFeqdA2nUQQcg/vfQOwsSCHReVCBIjCWTKpNtF1iJ0IjGxAkvjqgzPSrD3EvwDpV0ePzYDQpJUMxAGbwMKq5LBfIZ9vM/uWhEjfYTJ21YAwWsZ/rU227dN8P7jp9mKSpyemCaMLZZvtTCRYvorholfXkZXiiTjJZy6TfMohOOQOYA0jL1kqD+/ze69EwwP5Zvgczv7CFMLq2VhjUDFArdp4e0Y6mf6IAXdA0GOkU8MMjWMTgjm71plrVUhe66ENYDiEwF941M/l/O+o5Lkpn0bTPg9ilbMKLNRXor2LKzNvM2JsPiHY49QKw05Vt+kbg+YdduMWz2MAadvyHxB94BGxYLqRYO12mTuMzHZEy7DGZvOwT2ekYbEl4gP7/LnDjzNP3rmPUx+2aJ9E/ztd36CRWebzEiGxuW1m6e5XBlHNB28LUlhVVB9LE9Htm+1ScoGr6OR3SFqVEAmFuG44Z1vfxWAF//VbUw8tgnNNt9OXff/YZ1duC7CskDKnFderzCctInLguG0RruGeFkSuHuUSiMQaR7aCa1oxgHNLCMzAqHyHq0V5eG7bWWUnZC6m08GWXcjdoICBhjFNnFsYZRBC+glHheTBttxEZ3KvXvLkMowiB22ZZFmWiQyYMmMzDMYy2DX8nElWauACgXGMvhOwsDWaFvmGu9fqwMJAUre+NxXCeOlAWFq0Ru5RLaDiiTp8gqqU8Yd1hFpDXGTj1aQFTJQBiMtxCjCCg2jUS7QWPIiMi0xlkE7X2OO5aelauVMNnvKQyuFTHN+OgYKdoxtpzmVNt2rgocakWoYq5H6kGhFrC0gxhIaAejf08oTKSQjm67yWHMrDFwHV+byV0LkMtqZm0+S0RoyV2JcG9kbIHfbeO4MvfkcDZc5eWF1ttTlNu86QWVEVK6QlVIOOlvMWD3a2kFpTcGKsZyUVNqILAcM+dfbuV7fYj1/DhJ0OSAtKDIPsoLm9mLenXhJ3wbtHiQp0vMwmcYk33qE3f+QoBrhukQP3UJ/1iZz80UxmjQUjzep+CHTQRdLZry0Ps9gNwBlEEpjrbnMfyHGWIKrH5ZM7mtiSY0lNdcvTTD5ZE7d7C0K0oLG3jdgqtplttBhMdjFFhmezNFc2kh6mccvP38vxYs2di9f8J2Dkvved4rESF785AlKy5qd74r4sVuf4LdXbqX1/EQuyzQbYrsptdIQz0q5fn6KynmF29aUViLIDNpRaEfSvMkmnDA4nVxBprcIdz98jm7icf3jB6hdTCic2yK9eh117DCt2xtotdfr96F5T8L4VIednRJi18HbltQuZPRnFPf/8Es8VDnH55q3cK1fp+KMGPf6PLe+j/TJOlY/F58QGTecfTgmGU4bVCTwtw3WEKoXB6jOiOsfHqf8tk02rjcYey7nB8y8d4m5Qpsvnz2KvWHn7SzHICZCHjl8nswInl5bZDR0sZ0Uy8qwVYZnp2zsVCi85KOivJOgHUP9NUPlfI+sYBNXHcK6Yvdkzj609gqH8URKebyfI+tSReBFfNf8OUoq5F8+8TDV0xZO3+C1Mux+irPcAqVo3zZGWBf0FiGbjgiKEQu1FovFJj869hjbWYm/9u9/lJmnQrQSaFvibQ3h1ddzgZI/ZvvOAtUIgXRdevM2ncOQ+RrjaaqTPX700FM0VB9PJmRGcqSwxdp8lZd3ZtlYqt/IL2WiCZYctuIxCgtdbplY57o3hpEKKzIUl8nbYhWPrhdxvDrivuJFPJFQkiEFkbLfUjR1zMc2HmDus809eShDVKlzT+UK/czj0tWbqT25QvPmec4fnKLdD5CRAEyup+am3D2+xInCKj9z9gM0XgtRwwTVGYHWYAwmcInur+Eeb8NjNSa/uIZ62wxj782BN7WLCf5Xz5LtySZlFZ/+rESFUL2SkLmSlqWZKXaZK7VhP5x69hCVZ1dwbp5mn7fLdwebNFSfa5VxDjpb3GR3+ZXgVn52+x2olk3pqvi/qK16bY09+NqwOFCJQTUH0Gwz3Ffli8f/A++Jfozxp1PC2TKth3xmCh1Ic0GKsJ5Sm+mwWG3yzspZNtIKXxkdIWu5pMIBAZP7mvzAwvN8TN7JcDcv0LVvzShP9ul3ahTXHMgM3k5IGgSI6ZBSEKFeq1G9GHP9fYoP7T/FY1uHWH1hhrZb4EJtgimvi79mUbsUo6IMNUwRSZaDhBQ4/QxtK8xcxE/c+gQVNWTc6lFVA2ZUTGKGJGXDaNwh8XNsAAR4SsEb4Oz/LfsfwtlVtQLTE8RTJdYe8IgamvL+Fseqbc6c2Uf9BYu0UOefnHs/aT3lR+99nLuCq2zFJS52x9lYrVF6Pe+rNo+6ebEqhmBd0g8KLPk1pJPRPmJjDSX+jkGFBm/Vpt2r86yAKbfDcljj1O4MNW/EX1/4HONKk+4PWXu4TvVKSvHlVWoXivyDz3wA7Wn8Q5Le/ALpTMT6sEzYdam2yNuCoUMa2HzFPsxSvY432+fy9waABcLH2VUsfqKPag0Qe7Fv1DB07piiNy8IZIwrU0ZjFsHiHEJryDSbtxawHmjS3ipRuSpwOineRY9T/UX8qT4Hx3bRniZeHGc0ZrEaVXkhCnh6cJjrowYXnClesrucG0zjVSIiR9NVDioUeLt5YSpsCMJJnbPNXI0YSVQ8RmHJx92w+f7zP8Rw4HH1e3MNueTsGI+pBkpDUjCoUsJ4YYA2kt9tnuRqt4H7coHyrqH59ogHjlxia1Ti3166n9ZKhYVmhsgM9q5F1yogZzRL7/Ly8LqUgcwQqaTXCvDq0LrJAZXxlY0jbLRKeecgEZzbnuSq3cjJN8DOCZ/28TTnNwwqWAPB2JmU4krM7qrHl6duYrG0y33ly5wazfNXrpzMJ8d4hq07BGk1wyrHxK8EzD/p3thwv1X2P4Szi2qF3pEarZssfuoHf52PFFdIjCY0mvvP/TUmH93KT0IhGB5ucP7EFG8vnmcrKrHWLuOuOoydiRmOW2zfBUYZKq8rgk1NXLXYLhex7AxzeMCw7eE1czRWYRl8W7ATVDlTm+H0xjTmpQo7ZcPTjcM8ULjAyYUVXrOn6SZFgi+3cU/FHG5OEE4HLH004ui+dfqxy+6wgOxa+LsamRoKm5C6gh2/zJmRw1v2XeejJ59nSnU4ZIf8fOsOvvD42wnWWzcAPHEjo3mzxWguIVAxvkoI64LhQvnGs2odN/zCLb/Kz288xPInj2C3Q2qvW0Sbkt3bC8S1NsbV9Bc8RmOSjbDM86P9vNDax8aghCVz4grAZKVHWpIMqzZxajG8UsJXkuF8yrFjK1SdEQcKO6yGVZ5fuwVMgcKaYfsrM2SLCe/87pc5tTtD9qsT+LuarTsswpmUanHETKHDdljkudUFhlsFDj09wt7sMvpuj3809xn+ytL7ufr0ApVNgbszAAHejo2RNnL/gGNTm9xcXucDlZd5fnSAf/zMu1Fti6ihicZzLfzl1QZipHAykEB/s0gfqPfziKRzc8a/f8+/ITaKK/EEj7WOsHT+CO61HYLVOS5OTRBNWdxaXOHZ3UWC36pQ62Ysv1cze2yL2xor3F+6yE8l3wOu+wZ7xf+//Xfn7NLzyG6/ibjmEFzcJbt0FTKNNchwOorf2LyLzbTC/cFFZtSQ2kyH9XdN5rLCGkZjgoMy5Uo8wes7E4xWi3gpdOfzXLGwsjfitwBJUZI5GhNamFRCLFGDPG8X/t6o471TYF/Q5IrXoE8evfYyj672OFjcgWk4tf8QjbfcRFKw6C5aJAVgkHH++jRG7/G2gc6BvK3jdnJpaTDoWHF6a5rt8GHurl/nr4w9zSFvg1+8z6Y4P08aGEbbubzVaDalNNlnv7uNLTLiCkS1HNMvtEHGgk91bmMnLLBzwsKZr+TtI8DqKi5tjKM6Vs4pF7AxKHPJmSDWCktqxvwBc0GbSFv0UpcwtdnQJeI0b815O4bhlCSwYgpWXpRKtELGoEKNVrkYhfAyXJlScUOWZwVJycpHQAO9gceZnWnCxCIKHUQqiKs2QpcYbjv8bxvv4HqvRjyRoi2LVj8fLJG5uVRVElpsDovU3ApbWYnL4TjedQe3DcNpQ1oyyJFEdlR+z9uQFoFDIZXiiJ20znDKwfgx/2Tl3ZSdEdNeF4CdWxRhbRbtgHPV4/pggl/K3sJ2q0SpLEh9hfBihDBshSVelPsxscJMN7AsRbbT/JYV6/77c/ZalQvf6zN7bJOtj00xtrSKiWPc7SEV4PLnDvDa+CJXHxjnhxtP8lNHP8v1A2Mk2qKT+WgjSIzi8fYRBudqTJ4y9OZh9y0p3qrNvt/pgITLHy0jFwforotsOrl6aTNHZyVFSANB/fUMbytiA5dHyqe5PqxzSo6DhvWwzJpb432VV5ms9/lp+7084R1D1mM+fOx5mnGBZz55K+VrgrgoSH1Bf59m4h2r7A4CuueqeRVeGsxIkV2q0tqo8Ct3T/Ej732ah/w1fuYHfpEr0QQ/++Q7KZ+16R5LeOstF7iltMq7gyUu2tv8y9mH6MZ23jaLDHZP8Osv3I1TjrjnA2eItcWLj99EcVkQrIPZDlARaCvHA6ztVBnENiU3puyG3Fe/wofLr7CRFXhptMhWXKYTe/RDF29bUDs3YDBboOEOKKqIxCiGqY3dNzjtGO3axJMppcoIKQyzQYf1t7QYhDbpwIFEYjY9Otdz2LEONDIWdBcUdkNRPS147MKd9I6kvPXWC7Rjn4uL4yQjG2vDyQcxNh020hpxqpj1DvLk+gHmvjLC3uiw8iem6JfA3ZEEGwavk1G8PqS3v8DN33OZHxl/nPZNAQPt8r+/9j6u/9pBwgkYv2+dqUKX7/3QV7FFxn/8xMPs++yIcMyhPz1BUBD0F/IiYFAOMUZwsTXOqc0ZZF/RPl7F3y3iPR+Rtd509v+iyVIJWa1gXBtT8BhNFhDjEQulFq/WplHTk7k4YWZQYZYTSIzkcneMy+UJ2llApG1aScD1YZ1YW0SpxSDZWxjZnka5k+eYkEsgWwNB2HGRA4Uaifwj3huwsKedJmODTDRWR/Gl7nGWe9VcGUXCMHXYTCo00yJKaDaHZYyfYTv5mKFO4mENwG1npJ6VAzhsQ8GOCV2LfpAXhHQ5RfkpYsmisJnR3bV4PlxgXHXZTYs5H13u9cptjStTpNBkxpAYC5HkxBoZ74FVkpxZl8aKfuISawuZ5sIQaZCPh7IHYA329OEGFj3l4VgZgQ2htmlrh572iLRNpK28bSn2VGGcvPj38vYcJTdi0u/RDAvIFESmyRywizElL0KhcVXKWHHA0LVpCkgiC4YOdjcfvZQFKZkjieqSzMulr43MNQMutMYxRuA4eeErKVloS+RS1VoQpxabUZlB6FDLNCLN8vtI8k1bO3nvPSk7JEHOeQ+NzbjqMW+1KXoRoczf80TnbMVZp0VD9fO6Tj/ClQKjBKO6ZDBnMI5m2HNZHjpf07ZERQIVa2Ss+VbS4b7tnT294xArD/lE4xlHjy8z561yWCVoI+kfTlj54BzBlqZyvofVj2mcNqQlm4vTs/yL5EE2divoHRd/QzL5fISxJM2jNkkB7JAcBecCo7zf3jtcwu5nzH1lhEg1wxmPUWPvhFW5EEVxI0WFGjVMwRhmHs/4wvm3ElcFyawmK2pWelW2hiWaX55m/NUkl0C6OSXc9vnstTuw+4Kp1xPczSHNoxX6R2OsIGWzXyLTAmtyiGVp/tTBU9xWuM7fWfoBiqc3mLSn+TvjHwFlUC0rn8dWTRmdGFEoxFzsjKMRnPWv8epoH8XLirEzcb6pGdC2w3C/xvRszn3pMCqE2orGGWiadxp++N6n+NjF2xG/W8LpGfwlm7Ro0dwPgZ3wfGsfr/WmSbUkzGwSrXLQjdQMpgy7N3sU1jT+P6vQm7K5cn/uiDN9A1IQTmjee+g8lsywpKYkvz5QcTSebx6ff/EWiiuC1jH46G0v4smE3506Tn/ocXBih0OlbX7n+dsJfq5Kf8qi/0BMoRJy8OZlqs6Ii61xWp0CcWzx3PoCo6ZPOC7QTgMZG9xdmVfM5zJEJtiJbLSX8Vpzin8avZsPTrzCvf5V7pm4zqfuL2HZGa7KSLVCG0FGLj4pUo292cVZinEPjNO81QYB419yKV8N2b7dp3MspbAhqLy4jun0yLr9b5kvfXs5+17bDClvSP4OGw7hTEJ1qsePzD7JhOrxxOAIa1EVVUiJazbWSGBchQhTrPYQGTq4uxXWdyqw7eJvSUrLGv/MCtg2YX2OsCbzfvZe3USNJDLNtdpULHBWW5hmC985QFzy0BZkexNc1EijwhRhDMaS+Jsj/FVN/2CR4XROLOmHLsZA7XKG9/hZCqUTdE4YRCzxdnOWlEw0qBwYYhcSpNIMIxshwPcSil7E8WCVO93VHPjT6eFtN/BWfbTK++rCQK8O1eoAYwT9yGE3KrCdltlMyjg9g9MM9yi2Apk6OYEmk7gt9mife+o2xYzvqbzI8419bHil/MRPQUaCLJNkWtIOfXZNQKYlSarIjEBrSZblJKE0EBTXM4JXl7H707SO+2gnrz9oV6E9w5TbyTnhOueYS2FQQlNSOZAIy9zgwx/xNijIiNOVGZpugXvq17incJnfkbcRXGmDrrIbKtKCZL7Q4oC/Qzv26Y9ctBYMhi4ilsQlgZH2jU5LLA3CTxHKoJRGCUN36BElFuu1KgPPYszuMzvWJtWSKFP0EpfE5C5jFGjHQo0i9E4Ta7wC5Jp2hbUY++x1gtkj9Bck9sBg2h10f4B0bMD+lghcfFs5uxobY+sDhxhO5dM8jJWfRu6GYrBb46eufT/Gz7jp0BrzhTbqmsfMYxFxxWL7tgL2AOqvtpC9ITNPeERnHHoLkv68JqoLWkcP5E47lRM5xJKP1xQE64bglMEaJbg7I+QowQyGoBStIx679ySojoW3JYjLgs4RB3AI1vIhEOXrEe7VHcrnUtxmkbhqsXuskssde4bkLTfROqJY3L+RO8yCR5xJVt6m0JlFtpNhXwowQAqkRUNxfwclDL+2cTe/Ke7AaQmYaICEwoohqgr6xyOCcsiBSo+GN+D1nQm6GyX6Q5fHgpu40mtgDQ0i1YTTBaKaIqznIaysx8h3DekMXdzf8Clc7pDFZWZUxk/Of5n/+Kfvpx35bPWLKC0peRGuSokyl0Hk0FsvMfacwh/lEFmhQY1SVKRxmiOMMWhHko4leKWI9bf7qKGLsTJ+4fR9jNe7vHP6Aud7k5x68jB2VzBcSHFqIUF9SPTRDDdT/MzL70UIg+/HuHbKxcEEGsHkfIvXf2wMuyepv2LI3BJPO4vEUxa3VVd4ZOIsn9k4waVTc6AMzfeN8p36WgGnBdXzAv9Jm/YhReHhLTIt2b1cJwkFv5LeyQtj+3BUykKpycsbc8jHqvQceOnDLT7Y2MU+1uXahypUL5ZoPJqQCYG7k4OcVJgTo8oXe9iDAirSZEcWyAo2zZtctC2Y/moTfer8G+pf31bOLooBzds104e2qXkjynbIs1cWKbzsYw3Ba0FSsFgZqzJfaONtC9yXLsEdh9i608HuCeqnJWIU4b5yFTfLSN9/jO7xFKcUc3hym8CKqdghqZE82j2GaVv4TU355XVI0nxmV6Yhy8CxGU4KTh5e5uz6JFmnSBoYisdauHbKtjOGvyUJthROrw/NNvaFEG+sTuYsElZFjribdwmnM07WV3FlHtYGMuZksIQnEn7y6R8gOO/num0awjEJ+/NBgxe3xolDi1IfdMkDcpGMzFEszu3cCIEBzjOB3VIkeFzsjrPTLxDEBrQmKUpGY5K0kNcoCoWQHz30FOtxlS9bb4XtJqRVKtLjvf6Q9y5+kfVsyC+272QtqrIVFeknLsYI4tjC3VZMfHUd02yhRyFog6yUEP6eXp82aFviFiNmah2oddBGcO36ONZlj81MwDTsjIpMPqsJ1kdsvqXIYLZA7eQm/8vBz/Kftu7l1c8fzSOlIxKKITthAYBD1R0O3bvD01f2U3k8hw9fubXAZqXEA5WLfLB4mdO9OZY6C0Q1zQ8ff5Yxq8c/6H03TsumtJzgPfU62rqZkjci0Yp+U+K0oe+UOD1ymB7rcN/EVaLIYt8LIzJXsvJIFdnQ3Da1yimp6SY16r6LEeD0QNsCmeZtXrmyTXGjhW6UGewvM2ooWnekCC+jdqGIc+qN9a9vqbPLUglZLJDum2DrriJRDayxPpmWOWupa2N38jfSKEFSgLgsONDY5a2Vizzln8TECdoWxPUMoxRpycUeBeiJGtrLqYzekkNcs1h2q2RaEl4tYfUljSVDsJNilKD9lplc2cUTNzjr2hKMFhJirSj4Me2FGDJBe72MyAROP8eKb91hY95y9EbhziiIKxqjDIXVfIqK05T87vlbyCKF2rXRjuHmk9c5VNrGaEFUA2PtyU0rQ3ilQp8K1kjgJIJgSyMHEXKUoLoxUKQ5CNgpFWlFAYPUYdD3UICzq1jamcMaCOrNHMiR55hg9wV6w6bXL/OveIA0VfhlQXjbIv41mxNP/BkWxlp8z/RLXBxN8vHn70L1JftvX+Xh8Qv8wtl78J4rokLYees0Mpv6ep+/KMg8cWPuetQwFLwe3dCj/VoDtynwfHIabdvmV87chUkl4kGBSAOyQgq2JjOCr3aPYglN8e4dugMPdblA2ve5Uqpy0TWYsZi5yRaFYsi1D5YxynDs4ApHylv81ubt/NyltxMlNsnhEbXygGm7TVUNmV/YYcWpsWl71CrH6e6TtJo1pDSEcwnhpABX51TmvXU62+iw9MgMMhWEV6b465sfRVkZlqUZzaUsf3iKpGgQx3pkmSB6zSW4aHJuhutgbAUib9UWL+VYAHe3+4bPh/vWOnulTDrXYOO+Ih/5kUeZtDt8evsWVrtl/PMejbMpUQmiWr544nIuyvi2xkU+XLzOTxcMOozQjsQbHxE6LknZQkY+/X0BUUWiIqi9rhlMSbqlArJncehjQ9TFFdAGjKb/0E1s3CvQxYzSRB/PTql5I3wrYTKzGKU2E8U+89U211o19NM1nG5evc4cqLx1k3917JdRGDIE21mB32rexdKwxmvZImok8bZBbPn4O5rac+voks+5H9nH8v4qRueFK+Nn2KWYpO0y9lyucorJhzAGK0NEu4cJI0ynSzE5zFrPZ7NSYqlVYzRw0D0bZcDfFEw93kEOQrAURkpkZlCJQbbBaYO2FOlyDSnz57t9h0vjXEbxd2K2757jX32gQLtZ4NAvJ1idEVs3+Xx/5UX+detBDv/mMoPjU1z/IKjiHgRUGCqlIXU/pOEN2Bc06aYeV3pjLO3UWPh8jPPMedofvIWtu8DdURRe9RjMCv7sRz/H3f5Vfn7jQV5vjpNmisc3DnK8scEvnvgFvjg4xi996rupv9REFx20q9i63WfjnjL7J3b52+/7FcblkM2syFZW4hPP38HsFwW9uyQffuQZFtwmB50tbJHyvfMvsD5Z5dHJw6zur0MqEOsFjKc5dGCDmjvk7NYUg7ZPpnPi0lvGrqPft8TF3gRXP36QyjXB5lsU2ZE+s4s73HTbFgt+kw+WX+ZyMs7PfP4HCQBsC+O7aDc/dKyRYfyVGDXKUKs7vNHg2TfU2YVtY03O5KFymmJ8FyMEamR4bPsQvpVw9toM9Cx8A4MJhba/3m7RVn4qfI0SmnkGa3aapCDJ0rxHElYV4BEX81aNTPJF7nYMwZV8Fvpwxscu7sfskUGG4yrvLXsC18pwVMZGr0SaSaLQIRspUAZpafTApmhyck3YMKRFzbjKeH60SFUNmbVaJMbKq80iQ6b5eObMFmh3jzsexUitKV6rMYyrCC+HlaIFSddBjiRxRZAGiricc7b9iSKFuWBvZrlhOK7wghzoUQ1G+E5Cz3WJA4eeZ6OiMvagRLCRoBLNYFIxmM2vpe2cuKKiHCbqtPNTR43ytpCxoOKHZDXBzi017IFHyV3nYlJD+BmD41NEVYW3KvNBkzMhrp+itaQbejS8AbNui6IKaMUBzcAnbAS4M5MAON3ciYZTgqihGWYuW1kJKQy+nZJqSZJJtsMin+mf4KnWAeyBRkQxwlYIkWPO9000OVjeQaEZGovXolmWogYiyvX0crxDhUDF2CLFEymJUYyyPYEJZTACjNRIL8VVKZbQ+cCJoWJzs8KnRzczUe7z3dNnSIqKc2MHsIeKuJ6xWO3SGXk8duUQtcqA/Qe36GmfcEyQ3LwvV8+Jsjyk39NNyLsie2e6EG/ouKg31NmzokP3nnncZoLVj/MKsYDSSsbuJ3MRwX2XElSYsH6fonlfjOzYuLv5KN00MKTlDFtk9HSGHo/pvGWWwaQk6TmQCbr7JYNYohV55TUEFWkql2PGH90lnahw8YcCgrkQW2VYSrO7VKX8uoXIFM6BfL8dna3ibwqKTYPXzjcXIxVJIOktQDhmqJ7c4a6JZc61J/l/n343E5U+j0yfA2CQumgjsbuCwkZKf0YxrO9NHI0T9M4us78aIgKflQ/N0r8zgh2X4nVJ6kP3WIJVSvjIsVe4r3iJJ3uHOdWaZabQ4a7yNSJt80JnH8PU4aGpi8w5TTIkyd7MYfUew5nBDI996nYKK4bm3Ql33nSNg8Ud3lq8wKnRAr/42j3Eux71c1C61EN7FmnFJ2wI3j95kYoasTS/h03ILH5p+z6mp1qs/FAZ+4LN/o/tkhUcLvwZH786oN0uoAc2BSfm8NQGoe0QqIiKHfLYrQ3i4mSu63ZB0z4imXzbKiUn4lx/itf7k8RaMRH0aEUBSeZycXOc187O4zQV+zZGiDhBJA5SCUYTmn9y8NfJEFyMJ1hLavzHa29ht1XEGgoGkzkR54WVebYbRT5QfplxFbMVl3m9N0kvzNswykspBBG+kxBYMRpB0nEJVhVeU1LYUGycrDD/g49xh3+NZ+5cZHuxxD0HrvPu+ln+z+e+m0M/r+ktNPj//tDDLJRbDE6EXJl2qZ4X1F8bgRDYg3RvDQmMLXMRFcvOtfPeoKr8G+rs2oJRXWINFdZA5DPB/Dyf8XfyGdlOO0JEGcJ4+Unq5EqgOdkZRCo4N5hhyuogpGE0JknKILwME6kbuSnq6wAYNKgwRW/toGwLoQsoqZks9ZjwezzVDch8CyOhPfBzkEgGyJyxZfdTUk+RBTIHbeyNFE4zSTfx6Ecu0cBhWxR5xt0PQDv0GUQOKgSRmlyosqRJA4lQe+qjWQZphoxBRwqV5eAYbQOWQSpNpC26mUek87eqZIXc5l2nrQNe6i6QGklJhUzZHVaTGutxlZIKWXB2GHf6JCVNXJUoP8OR+UaZGAtbZBQLIe1YEVZc3IZP5ki0k7cC+6lLIGMWvR20kTzXWWRzmMNiXTchVQYxGKG0xuoU6VYCjBHgaAI7xhMJIQ6rUY3tsEjm5mIbTjcf+IiGOFOMUptUS6QwWEIjhcYYQZop0lhhdxRORyCjFLQhrXpEDQddSanLjJ4RbKcllqI67Z6P7tpIkU/lybw9cI1WKAw25Cd7mo+sRhpsO2OsOMC3EgpWTKIVIhFYI3DbhmBthDdfYjstE8gI305w/YS6M2Tc6qLsfMyXMDCMHPqJS6k8YuSkRJtFMm9vTeq8MKptCcaQjVWQrg3tLtnO7hvif2/syR4YmrdriuuglrcY3ruPrTsU7q5g7HSETDRRzUU7eR86u+STFgzxeIbqKcpXQKaSR1fu5EvenZixjPbbQqbHOnz3zGt8fuMY/NY4/lKP5u01hlP50D5rlCGiJCfDbO+y/7erjMbLXPyAx8kTq9y7eI3V8QpLG3WKXygjDLQfCCne3WH75UlqZ13aR2Hx3mVaoU/82hhWX5A81uBM3GA4bWAqJrtcZPfjhVzkIjOUNUCKsQTDGcPJOy7zcmERPVFDlgpsPTjJaDwfcVR/zqZ7AMbeuUZr6JO+XkVddXjii3fzXO8uVGyQseHLxxc49c5ZAjtmZ5hXpnvVvEr/T199B/VP+cRFQX9fvth1I2E4rclGiqdfPcxzg6N8vPs2wjHNW+66wOzsRfrHXEaZzfMr+4hXChg74+Mv3YlwMmr1PkoatjcriJ6FGuUyVMEuhAfHkalm9qspacFl63tC/sbdn6Wh+hREzGf7t/KZz96N3ROIqmGwoIl6AnuQ9/iz/zjB1piEh1vMV9t5HztTNAcBw54LPRu7l6vtykEEWnPtAz73ve013hns8Hw0waVoik+u3cpOv4C5XsDvCkYHY6ZncwfSRjAddHFFRgZ0U49elJ/qjpewUG/x4/OPYYuU6/E4K3ENNZAU1zSF1RC5tEllwuNfnn+AWmHEVqtEluabfGhsPnT0VR7/WwfJ9IBAGIaJw0f2v8p+d4u/F3+A3paLPTS4rbwQHFUUqSdYfcgmGfeZ+OoU1V9+7g053X9fZxdCzAO/CEySn5M/b4z5p0KIOvBrwCJwDfioMab137qWsjVWY4SRHrrXJ/Uk0USGTCxkkquYpAWZywdlBqebnzIiSNGRxBoK7KHGa+Xh0MZ9gsWpXY5VNrmncIlThVmarQpidRPrWAWh813195oehbjnV3E2y6w/WAdgwW+yGOyy3StSWrERxhAGMXePL/GJ2lieO0+k/OTClzkzmuffXH0Iq68obOQDHDLXJhkXOG1B7cUtxGC093QV8cIYUcMmLRjuqi5xoTFBWvZQrk1/XhBNJ5TO2wTbmt5+yd1j13mtM83VQQ1/2zD+fAdxfT2/ntEYdRMrt9ZwvRitJUppRplNZiTpjkf9uW2yegEVF4hqknAqZbzWY+3aGN6mhbcD5aWU9iGLsfsH3F28ykl3lYYy/G/WO/h8epSk52BvWxjLoi0NUhlk28Lp5lBYa5CPpE6K+YCL4HoHhGALj4eCi4RGERrFTlykdBWcvmb7doEup6RYIMBtQfVsD2ehwFZsoY1gmNiEsU0Y2piRhQrFDZgv2oClEPND/v7Mp1nOilyJJ1iNqmx2SoRdF78nsIcQuxkn6uu0Y5/tsIirUobGAp0ySF2SNE91LCsfGXXU2QRgOy2j0KgY7F4+tNH0+jjthOFWgbDkoPeUdGOtSIzF8WCVg4tbLEUNvrx+hDC12OfucK9/nWp1QFzx9tpyuV5gLmIpyOZH3LlvmddfP0JNijcERfv7KtUIIaaBaWPMS0KIEvAi8CHgR4CmMeZnhBA/BdSMMf/3/9a1gsMzZu6n/zzlTxdpvNJh544KuycNWAZja1AGO0hy8MPVAsG6oHso48iJFaLMYqtbJEkUyciGVBLUh0xVerSGPu1WIWeP7X3IgUJGAmuYn5zFFU390WsAhDfPElcsBpN5ISyqGdKJvK0mIgWpwO7vCU92yUcb3Z7xdx78JD3t8ZmNE7RCn+7AI4ktrGsepat5kcvt6Lz1VspDfsjTiZ17Mn7s/q9yeTjOV68cIgstyPJprXZLYXfFDa00q08unjBMkalGZAYRp4g4pXu8ztqD5KnPWr5oGw+u8wPzz/Gb63dw6cI0IhWIJJeykmMRtp2RXikSrAsK65rK612at1a49SdPcVtpicdbh9kYlLm+PIazbpNUNP5MH9dOqQX5xnVto4Hu2jk1z9L4Vx0WPp1X/HXBQ/sWW3cV6C1qCgc6/ODBF/jM+nEGvzqNTGD4kQ7vXLjApy8cR1wObrQ3s4Kmtq+FrTStl8YprNzQvPh6Sib20htH0Lt7xMl9K9xc3uDtxfN8oXuC33zqLVhdidPJ+QtJkEeRZg/XbmxDVs6lt4hzhGNpusetE+usDiosb9XJRgp7y8YaCMZPpQRXu8jeANPqoA/Ps/yeCnHZkI4nWH7KLXOr3FO7xq9euZP0yTpGQFzJf6eKc+x+OJ1SnurRu15h6qk8JUw9gbZy8pN2oXE6wnn01Tx3/yYU674hpRpjzDqwvvf/nhDiHDALfBB4aO/H/gPwKPDfdHbIC5BRRTCaKZD6ezv35JC/cfKLTFltAHra5+8MP4xYdTC+5r7GVcbsHof3b6CRvDRcZCspsTaqsBsWaG2UGXvaoj8v+Ok//Yvc427wwxe/n0tXJ0nzUV9oy6FWKoCSdBcckpKgcSbCu7LN8Ogkuze7DOY073jraTqJx5V/f4SxUz0G8wHDcQkamlmBihrxPTMvodBU1RAlNH99+4cYf75NPFagfdghKQjCCYO2DG5T5qQSLw/THqye56/d/wU2siJ/9fRH6W2USGoZSQ2qpyxmPnkdMxph4gRhWSTH9xFNOlijHIuvLYHdFchIUD+XIRPD6okKO9Mlvmf6JaYWOrw6XOC3r91KGNsksUU0tPH6ubS010oRq9t4c0UirehnHs9d3I+96lBsC5yOoXNEcP/cNar2EG0EkbbpRS4tWaBcGjJd6nGutw+5to3p9TG3HiIt2kw8P2D6qzEr76nx6vhcDurJ8hrE2+au8DfGH+WV3TnWLwck0zFvO3oRbSQr/So7/QKNM4baM2voYkBWdsk8i7hiEVUk7Vs0shqjI8XL5xZJjyo+Wn0eW2Q4TYnT/vr6rlzRBFsJaaCIKjlOwwpzOG9vXhFXgGm4p3KVX9i9h9oXPfxmRrDURQ5CxGCECcM8r7ctRJQRbBhUKOiNgeMmpEaxFZfon69x6J+/iqxV2Xl4AW3D+BNb6OsrXP1f7+B/efjz/KzzMOnL4/lIrzQvGNfODlA7XUx/gBYy3+H+mGe7/6FydiHEInA78CwwubcRAGyQh/n/pdf8OPDjANZYhSS2SGcNacHG7kP9NWgnBU4dnGfVqXG6M8POqIhq5rdm71r82sU7mK11+LH5x0iMxX+6dBfD9SIiEshY4CR7bZyJDE8k9IzgyvoYxQsO/YMJhw5tcL1Q5zqTIGA4n4IyFFctvCinG2ZuPvf7hY15RpFNo6sRowSnk6JVzh474GzTzgL+w9J9hKnFu2Ze56i/howEYhhhrCLDSUHmGzI3B8cM59J87FNlxPnBJNfDOq+N5hikLoGTkDRGhLs+VkeRlKD59vk89TB5QbO7mJM2rKGFNXJICpBUM+RIENZy7rtt54vk1GCezw5PsNYv014ro4YSb1ui9uitAMMJi+SBA4Q1yZPP3MwT9jEKSwq7azBWjm3PChlzXotIW3xh7SjDyGaq0mNxoUnFDqnaQ67MN2i98wBuJ0OFOk/DsjwWFSlsh0VGA4d6J9+QPvPCrby0b46dVomsnt/vi2vzpKkibnnIkcSpCrp3TOeRTAZpIAlr+cQV9hh4/pKNt2N4rTBNcy5g2ulg39JhOHLy4RxaIp4JKC1lZK4kswUqMVjDXE9e24qkqNGRzeOtQ3m78CYY9C0KjTL2sIQ9yBlqdj9FdULShn9Dbvtrop5nrs9wejRPdVkg6zVM4OH0dU7LrQTIxXkQ8FJ/H5bUbBzPJamtYR59yCzAl4L04DhxxcLbjrGeP4cOwz+MS/6h7A/s7EKIIvCbwF8xxnSF+PpOaowxQoj/YgxijPl54OcB3H1zJhta1I42mSj2WfvUPsY+/hr+g0d57uQCnpWy/uoUTksQ7Cn4FJYE4nqJa4sl1qZqJEZhf6nCTU+2v/YLaN5aZeuhmLHJLoGM2M58vLM+s1/u8vr+gP/zwMdJ9iu27yoTmzzXWkuq/KdX3kN5kKtPZL5BpNA/V8vz0I0RsjfANQa767B1Z5G7vTUeHS6y/eQ0The++t6Msbk+1khAq4O2xgj3R1huhu7nvdybDq1xT+Mar3WneXVzljixiAYOwtIcntniQGWXp3cP420LwjFDfNsIZWlsO8WzUx6ZuspBb5uLowlWhlVaUcB2r8iw7zJsesgEfDcmM5JnNxbonmtgDQXVnXwCTeP5bdhuEt62SHdfzhUYLia464oj/7aF3G2jG1V0YNM6VqS/IFCVHMr76nCBzqkGTlcw/YFV/tbMZxgYi572KB6O+LWP3MFoO2D2SxbBanjD2VUEG90SpukSrPRRuz0OdWok5RrqfovSLS3azQLZmQr2CMqbOUy4t1/QPibwthTBVj6LfTRp0CpX9RUji6lnItynzxNXTrJ6d42b3DV+4bZfwBaakkgJjeRPrP81ph8NEUUrr/logdPe0+BzbbJGgg4tXry6gF+IOX7fFUapzcWVibxWMJDIROGvO5SXXDInRwXmjpArEZde8ph4YYjQMelsHSME/laEkblWfzYXYAQ8tn6IshfytredoZe4nNuapN93McIjdQu0jko40UOfL3LwfAm+1c4uhLDJHf2XjTEf3/vyphBi2hizvpfXb/2+F9rL99qtAu12gYKC+M5D9OYUrsxhkl+bJGL3Tc4WUiKfnaZzPLk2+ee5smr+EVUFfiXEsVL+w9YDDDIHawjatVBDyed7tzDMHNajClFmEWYWzbCAPTDg2Hk7be/NlEm+WEWqIc1I6gGDGZe0nLGdOfS0T1IyCC3Y3K3wMXM7dg9EuUTmSkhBW/mwAKTBUylFFTJMHXrtfLyIUBohDVv9Is1RgBzmJ7R2DYvjLbQRNAcBSaroJR5Nq0BRRewv7FJzcmTfuioTOl6e1+7ts8bkijdmL8dNCjA8UMWeyFtAblcznFIEjSGjuEg8UcC2FeFMQFxUDGYFo9mUoh/zdP8QF3vjyCS/Zjv2WU6rDLTLQDs5GaXSY8MIevMlUtfPe8h7iLyw66FCQVJ2wRhkqnE6Cd6OTXu9jNVWuM28zuH09yKCJC+oJmVDLyBHDyZg7UVwMs05687NB0gLhuvRGCuiTjMtoNBMOF20kchI5GOeDLjdnEw1nMlPZxWCve6QFjW6mGEMBFZMmFk5PLsn9+C+hszLowpt5UMgjQDRV4wyHy/MkY1G7bUrPcVw3CJz8qEVmQtJLSXNJK2hT2uYt3QBLDclrhiGkUTbhrjn4scCxmsoKdDN9h+Lms0fpBovgH8LnDPG/OPf861PAv8T8DN7/37i9/1ldkahElL47TKNF3a5/iGP+v9+nToQZxbbo0Iuh6TyinFwboN4YYzOAQ8j4YizgScSBvOaVrvIaEIQ1Q16YcT3HDzDczv7OPNzt1BYiymMaVpHfAorgl/++DtwOlC+luUiAolBpYZGswPVMmkgyZxc0sjq5W0/1YswYcjGPT7+w9vcUuzxm+27GGqHI3ddZ7NfxP3cGMFZieck9I9PElYl9o4kcxWUMqST4ewNmbi606D0iks4ZqjfuYUxgt1T43hNQWkEKjbocsrfXPwcr44W+JfPPIQcKL468AiCiAdmr/K+2isURExVjnh0eBP//PXvQoVfj7BcO6UdaLQrSIu5rLJ5b4+CGzP8xCRTX9ykuzjFnzhwmitTYzyfHkFGDsyPqJY7PDx5nYcr5/jY9l38xlfvRYUi7/37cHFznH9m3ok2AmMEDW/Ae6fOkkwqnmgcpBe7nGyscSTY4Bcv34N4poFMYecWFxU51F+PsHeHTD2VMfGCApGLPghjEInG2JKw7oGQmJM9fuToM/zW8kmiT0/gtnL5bJEalh4J2PkB8J0Wn12/mZXNGrUnXKwQwkbuZKWmobcvwNtNqL2wTbhY4+pHJCJImfqUYP5TTTYfaNC8w5CmCo1ge1Bg+nFBYXnI1t0F+guGpGjoz+XVd7Mnllu5oJCJxO4bRpPuDR393pyi8l3rHKttcKywTl31+WLrZl7dnKV3rcrkM5AUBKO3RVRrA0ZHDYODCnHNZ/wxG6ENu3c2sIc1Kk9d/2OZEfcHOdnfCvxp4LQQ4pW9r/0/yJ3814UQPwpcBz76+11ICY3v5CNzRHdA5jV4V+McO0mJlzrzOW7G1WSeInMFxrbIXEka5As3NHauwlLUhA0rh6uOJYxX+8w5LV4QC5SWI9wr2ySlGcKqQEbgbefzwf2tCBmlec82zTC+g64EZM5eBVhzY8hBVvGw9BjhmOH+8RUGqcsr7TmkMBTtiJFn000Mdi8mnPAI6/lMM5kYjBDoRKClYjcssBzWCbsu5V1D6gvKToQQhiZ76jGpuVF1rqs+RRVClp9madehn0h2xgo5l1rEBDLFE8meKmr+bG2RYcucfIPMowThZ9wxucK01+G3qlPg2HkFHImvEmhEpLGiVhxR9kJm3DYH7W18lWANRL6R7EUKcd9hya5hqwzbylBS5yo5QNGOsKTmkL/F3f4VPuGfZFuDVhCP5yF4vG6hBjYySlG9EF1wSSouWgjk3igr9gpYvh/xcPEsL1fmOWdN5GtnkCDiFG37TJQGDGOb7W4RWg7BTq5BaA9yeHXiC8K6QGYW7o5LGkjsSoTnx9hDC1Y2sEYNsDRK6XzEl5bYgwyrGyLSHL+AzP+Gr9nXBkZYYV51j4syZyru6d/NFdvcFGxym7fEuBrwmjfHOWsKmUBhIyaq2mAEjpXhO/mAjY0ND5HlHIuols+Rr3h/POKUf5Bq/BN8ffbIf25/qIkPtsw4XNvm/PcJLrx/nFplh8/v3Iw2glhbFJ2I/Tevk2SK1kmf9VEFxw0p+R2mpOb/c/3dAMwu7pAuSCbdiJIdMhe0qagBBTumU7BwCj4yMTh9kxe0ioJuXbL1FhcZe1QulrAHhrAuSYqAAW+HHGkX5xpz1/9vmsWxIe8oLbPPa/Ifzt1D5dMFtAPtI7lEcfG9HYYfGbHTM4y6HoQSu6OwQkFh1ULFhu2zc3zJmWPmsqby0gbcP8Wx6gY3B2u8+I4mm6MyZ588wPjLGmvL5pd276eXeniNEaHr4C65OF2LF/qHuLzQQEmDrTI2m2XGThvcbsbO/Tb73B3KbrjXxszwSxEFL2bS7TLttJl51zIXToyhWxm/85v3kxYMav8AqQx8pk66kvHv3j7LY3ceYpg4uMfb9Ds+pVe8fMBFyyFzHDr7Mhr7W7y+OsmVxxaxhlBYN6jY8K+P7OdnZ1JwM+yTAyqlEe+ePc9QO3xi+g781RJOJ68l9PYJ7NtbZJlkuFVAhnlFXUXgWinzKuJDYy9z7ZE6W9tljCoRbCZMvKjJzkwgigKrIhAurD2gUaHN/Bdj3OUW1//UFKUHtsiEoScMg0iT7BTJ1n0menl4HNYFi/u2qTghJTukXhiyeUsdb6pOlMMvUCOBt2v2Wn/i65uryQuno5kUb8uidNXgtg0vfvkozwU3IabDG12Leyav8+lmkaRokQQCJ4iZKPRZCFqMOz0uV3a4drxBYMfMF9qc3p0mPlVDXr3+h3GtP5C9oQg6JQxjbp8fPniVcavHk93DvLQ9h5KawE5wVcrRyiY1a0jFGhLImEjbDLXDhcEkj189iDGC+/Zf4WhhE40gM5KKNcQROfEkcwXaz8Oir/VctQVRTbNwdJNhYtMJx3A6ktGEISun2LsWwbr4ehXchp84/gQ/WXudZyOb0+E8cdtl/PGcrZYENUZTikfuPs9fHHuMX+/ezuc3j7HarKC7RWQMwZbG6e21UgwES12yy9dwT4wzYfc47q5wq7tMV3v8+coiKjZYQ8Gl3jgAgRehtcDuuwQbmsxVNFX1xrO0W4rCRowapWSZpKoGBFacy1U5mkphRMUNCVQOXf3A1CnCSYt/8eKDjH/WMJhU9A8akBn1cxHqsVepTryFS7PjlAohh+o7XBUNSDycXo4fEAaSsiRdkJiOw9jpDLeZ4l3ZhjDC7u+ju2vRPSTZf+smx6ob/KXGUyTAKwfmuO6MkWzbpIEgOhDyt45+gZ72+WT1JFv9Ir0LNVQksFVGSVrc7K7z/rkzPFdY5NrYAeyBorA8xNrukkxX6S/49Gck+tYBSWShQo1ZXiMpTfLRhZfY5+xwm7vGo8ND/B/rH8BtSmSUgRRkfj5bz5K5ym3BjgnH89FaX1O5lSnYwz3y0h77UOj8e3HFUJrp0U8qFJdEPnTjYj7iuTf0aVVd/MMpB8a28QsRmWujbYFtZwRWzIzb5oC7xTF/FW8soSxD9lldfqtwK5+svBP3j4Ek84Y6e6cX8LtP3cHk4R1O1Dd47NpBuFBAJoJuCEnRkD4guaO2TD/LBQ0/uXoLm6cn89lpxQxVSJl0exxwt/iHrz9C/2wdeaDP37zlCxws7vDKwwdwtyrUXtcEmzHdBY/w1hHFQshUoUuY2nSPeAyGDtaGg3fVzme/vbPNcOAhlvOi188+9i5+1nnHHioDKq/ZkGWkJZfusXxiSc0e8nrS4PHdQ1y5NIW3YTFxJnfw4bhkNG5TOx/hLbUxno246wQig1/62Dv5t42Hue8t57mrco2J/bssf1ed6nSTe+rX2I5LbPRK6EwS1QwgkTGULuTV5aSUh5HX3mdjXIu7Zi6xnZY5VNgmPSzxVMqY22crKvFvn3g7zq660TaqroDdj/BtQf98EYzAbrUwUjCaEDx88CLPrO3j/OcOY2yI3hLSU4bKVz3qr4eMveowXKtRKAvWH9AYy4JsBqHB7kqsIVh9wcVzs1woTPLC9AKW1KztVvIIaltQfz0lruYST0tRg0uvzuHuSoIwD5U32mU+PZzkc81b+PJLN6MGCrsMrZsUw/EiTq+AUeIGgEVfKaKAnVvBPng7aVHzmc3j1NwhT/ktnt/ZR+WsRbCliesO6V2HsLvw1SdOkFUyZuZzaK01PyCeVuhYYVKB2XVwO3vTYvc4EZmTo+DcpmB4sUqwK7BGGis0eDsxacFi9z7DycPLSKF5onkQpTQb9+YFRnGmwstUeME/gnYMh4+v8vf3f4JAJiQIZuwWS++VlA7dx/RTPczzp79p/veGOrvTM8w+CquMkR5QcKnA5AsZTifFXWoSz9ZYOVHlluoanTSfFrJ+cZzDH+sTTvqsPqQwQcq00+GAs0XnUo0jv9ph+b1Vesc9jvrrvP/el7jUG2drdR/VV7okJY/vvunMDVoswFzQppu6PLt6nMrljMFBzb+49Zd5dniIn+NB9JbLwmcguN4nmigQ1SyCrRHECWnR5vjRZd4zfhaA89E0FzbGKV20KC1ryo9egnqV1p+cJKoZxk5rsguXkSeP0by5SLCTsvhz56FR46n6AcrHQt4ze47Kwogxq8uC3eS1aJYnzf6cEFLN0K6kdFVSuZoQVRT9GUk4YfjIQ89yb/Ey22mJ7bTEEX+Dt5YuAJAZyefbtzD3RUHp8UuIwMtVeB0b7dqIzFA/6+Za8u0+GRCNaX5s4lGeXP4zLP7WDsP9Fe7/4Au8s/waf+XVn8De6OFcHlHu9ui892ZOfug891Sucn9wEU9k/NCrf4bRqzXsgaCwJtGWS7swhbYhncrAywg2DcWXVvAPLBIam9VRlbGXBaXlkMGMQ1QWhC2PL7RO8NXLh5n7gsAozcZ9gqyeMOpbecjfyUNsmRjKl3Mn7Nyk0ZUUhOHy8gTS1pxxpwk3Chw4HWI3R7ROVBiN2XhNw9yXMzqLNutOlaAUcdvsKhV7xJnmNM1eAaMc3GZy4zTXjqQ/46Ad8HYNXhOsUZ7DO50U59I6drXE+DT8vYVP8vM7D/Lo9UP4bszRu65zZadB7deLFJb34NQCLvzwDJOHRigBPa2YsVt83wNPc/7kJCvtQ9Se/+b53xsrXmFyyWJ/w2KXGpaCnRMW9tDCn5siqkqmKzsUVcRXNo+wulNFpIKN+0skBcjqEYUgJpARCoOcCtm+u8JwWrOTlIiUTdkKmQ06XDoEMhtHxvA7z9/+9aqDMkg/r5B7/XyXxtKoPd0QszcddTCpMKqMNdQE6xF2a4QJI4Q2lO2QihrwXO8ga6MySdsjiPN0QS9Ok/l2jprTApEaZKGA9m20A1FZ4R6eI/Ms7Osun4lPUGwMmSr3OF5dZ7baYjWq0X+9htsWpH4OdlFRzje3LYHbEhhL8MTmAdbDCuvDMr3IJUos4sRiptbhz84/iSsTMlsgAo9svEJScZFRhholJEWL1hEJEtzmBJ7rgBZ8pX9zXjy8o05SEHzs3B38jn+CYGMvfN0/wWhijv6M5Nlri5wrTfBsYz8FK2IwcshKBpHlDzvzYDifYdwMu5CgLE3zFpv/H3X/HWTpdd534p9z3vzefDvn7skziAMiEiAJkCAFgqRIilSwgq1gyQorWSvZK9u19lpri1suy16v1pZkSzJFSRRlUSRFKlCkSBAACSIDMwAmp+7pHG73zfeN5/z+OI2hasuULMuF8u9WTRWm0HP7hvd5zznP8/1+vnFtnvatCVPOHhN+i9PjAvCMhz8wqOuXtqbIE0nzsElhFalG7jlY+2O4pKoYzOSgBTKSaEvhT/QoBjHbyzW8NZt4JMeZiUhqCZt3BrhtD5mAv6dJizAYdYiGNX7BnOOfuzyPziV+KSb0Y3YnA7buDHDamvJSYpq4wmz2BiOCpKqNIi6y8BsWY60hkJLtpYB/En6QfupSDGLi1Obixgjprk9Na5RvEdUd0lBidTU/evm7UAgGqYMUmsliy+TVf7NO2X/n4w0n1VixYuR0ijorWHuL5v5vfYVO5rHcqVK3M949doaiFbHyyjhTTyjW7hc8/H3PECuHy51hXCunavVxhOI7T7zIUyMHGLVTrvaGKTkRtxZXmHZ3GbzNYeVNVaI/m+TE/7nPabNtdOjTO1wnKUkDgywKLNfMeXMEKpMIS7N3AlqpxdQTGu+F86hcobMUmSom/BbjdounN+bYXa4SrNk4PU1aEGzeXTbxTRsKO1am+z86TFT1SAuCpCToTRaxYph+PMZpxTRurbA8V2X1pgqP3P4qr7UnWfjDPs71HbYfnqU7JXC6CqcdYw0snI5NsGezHYzxTGEEf0fidKC6lFE4v83Wg1Ns/nSFoh2bOXGtRPNYke60pLCqqZ3PGYzYHH/4EiN+lyc5SeXyiDliXL4LKTW9D7XpbhWY/y0HfyVC5DsAbNwTUHvnOu21OsN/HiCzgNPjw2QhpOMZzviAVAX425KkonnHna8x7e+xOBiil7nce/wa94SXKcmEqsyIlMOnbj5Jf8I1K6gWWF1J95UhqOUUH9qkH7vYL9fw1syRCmBwrM8f3P1rRNrmxWieVFs3ejy/9OqjzHy5z8Y9IfVjfQ4PbTN0uMd2VOTqJw8z+lKf5YdDxh9YxZU5np1xZWeIiT92CDcSrny4wOHbt1m4ZRf/9oxnF+fxPuPh9BRa7GsJjg9499GzSKGQQvPU+gF2O0OE2xmTj0t2vz7L1r2au09e4tTqFO7LRQpdc5VFQw47t1jEkymFKw7Rv5s0i+AgYzDscvq7itwysfY/vPbe0GLXErJA7t8djUhBCkXd7RNUUwIrpbKvN0ebAAeZQzsLjI478bCl4kI0QaItrg9qtAY+BDARGGrLpYFR7QZWymShxa6YRO01wXGQ5RIodeN5s4IwJJhM8Lu797I2qCAdhfIUVt+4ruKqhX/LYUSaI/sx/ZrDa81JwPQgZCTNWUztN3L2DR7G8y5QroX0XWOKEd/4GWUZb7NyTISw3Yde2+fp3iHWO2UqnoUuGTKNlZgzY1L1TEc4N3nxuafJi4ok2xd9rAJbDbzWKIvRELGyb/D7rAScrmk+dudC4qpgpVOllQSkJUV3WqI8Rb/nERZi5mp7XM0lcaWI0/H358mCtATDQZcNv0zuu+iM/VhsM+orhDHNoktSkeSBZi8xx7ErrWF6icObKtc5YPfZVjYvxeNciCaw3Zy0mBsjkhI4TYm7J1CWRZzaZLncj68yuyctwfdSFhxFrCN6eo1IO0TKpSN88qJiMOqRlkxOvNKCxc4Q2z0jpJJRaqjFVmYiuUWO2J+ji0zhNiUXN0eYqre4vbZCEMYoxzewFfZfR2KxkxSIMode5rLbLDC6T6MxVCWB9nKm/CZn3THY7+IPhsz1LzRYbQtvT+NvDtCORVI2q32WmpFt7oI9PobuD8jb7b9x/b2x8ApX0JrfTz+xQFuKp1YOcGCowd+bepySjOgon0ZWJB9OaB70sHvwla/e8hcKSfObK8NIJ8e55lNYgaXbFN/24CkWoyE+/eydWH3J5C2b3DW8xKkARLEAI3Xax+tkviCqSvIAurfEHJzZ4uorU7z8C3fQmbEYeWQLVRPkLwxTuRqz+K02t/70Zc7sTrC6PITsCMqfmeXxdAZ3VJgRVmxEMSZZxby3aEiaAsHHdyRpwfxdpibPXAvYudlBOQ5WbFJYChddfnfrrQig86BAZj7erjkf9scEzaMu/rZg6FxCXJYcv+8a3zJyhpIcYAnNP//sd3D4CQuvlfOFK8fRSjDSM9bhyqltqknK5junSH5gl/ZOifHfGiLONXww5uZ7lzi1OkW6VkCHCd86dprWcMAn//YdLHYC8vUQpyOIpxJ2owKV0oC9twgsS7Ew0qDu9SnYJjl2pVpldapC1vM59dwhrL6gsGo62x/71ns4efsin9q9ky++fLNx79UHBKNdNEYFmK9XGTkVMxhxaEZDhpGfmJtKXNdkBc1NNeOmLgqHW9w2PaV5KZ6kpzweeNM5Lh0c4WDQ51Bpm6fWD+D+Vp3h5QF2cwcRp3jNCst7VUIvZSjs4Vg5rXmLNAwZez7D+YrD8sNT3PTIOpbQpIFAZobl5/SheM7lpY2jhOuC+rmYA7HC6ndQvsPmnQ7RXMKDN13gB4eeYjMu87JXIwtA397Fd1OCz9eY++Mushcj2j26J6dZ/e6EMOyS7YVcvTxOMCLYeP8BqpcSnCdP/43z3d/4lT00sTva0iaIsO/SLhr4goWikwe08gLC0mSh6c76O6ZQXv93qivRwiHYEBTXMzoLRvkQKwenZeF0BKkywhHlakQhJKsE9EalGc3t02CCUsSB0g6LyTSlsztoa4hECyypEANwuilUND808iRf8m/mM9lt7FChsKFx2zlZ4N4ImVC22WK+vsLn3j5ltiCRqWPihRzjshQZJrIpMKgt0TSjG6dj6K9pAXpzGQhwWzZWrI1YpKaw+xbKMs91vLzBg+FFKjLHF4L/vZyDJUFp0shGK7F/zhSITo98dw8tp7h3bJEn0kOEWyDjnLCQ8Pb6ea42h2jsU3xmnQaR7XDb8BrrhTIXGSEueNhBRi9xURoKYYznZEyFLYa9rhH27DdCbZlzMRsh25V4LSitZti9nK2Wz3ZeZqlbx90yN37qRv0n92W/nRzcvQjlSuy+RFniBsE2d0EVM0I7IdYK9RcYram2iJXDbLBH2Y7xZIonM+LMYvhiGy4uIobq6NAHDWlik1hmG+7YOf2KRmaC8rUU99Ia3h0H6WUeuRZIa19g87oNuW92TMX1HP/0/jGxUgRZJA80fjmm7vRwhMKR+1gzB0bKXYpuTKNfQ15bM0pCYXiJxyY3qboDnto6jN200LYR2mQFC+d/QP298cVeNI6w17PNdGyxdHmUn3n+BwBIy0YF5m/YRt/umMJxO1C5kmJHudFgC4hrNoMhgy36t0+9C+Eq5GxE7mTcM7rEzcEKnzgQsf3gNJ05wfhbVklzi61TY7hNQXS1zBe3b8HWsPz+UWQM7h8Mk0rozwv2biogdjXf+fmfwNuxKC3CkITOtABhYfc15avQnYb2sQy7aVNa5IbqTFmwc1KjShqrMKBcHLC3XaL2goPTg+olhVDQHxYkFSNOqV7s050NyN40IPQT8otDuF2F05WkHbOdTUsWaVHgy5Sm8vjHS49ydnWcylkbahW60y6PnniJWNm88MJteLsBVmEcMTNCFgie25qj6Mfs/UyO72T8+Oyz3Oot860zr/JCcY75YoOe8nixN89XnrwVty2o3rvNw0dP8aW1o+xcreM1LCqXFDKH06VhskCQvq3F3zr8IltxkXNbY/T3AooJ+9tXC1G1IM755MadNPoFkokUtCDreER9Fz9McOz8BnBkMGyT3dUhTWxqX/YJGjm9KcnYZBOAj7VupZWFXOyOkilJxY2QaJ64chhr0SediXnoyEW0FsTDAZ6eY+XBGr0ZRV5OcYSmEkQ8MHQFNSR4pTLFWrfClhhnlEmsGB579Tj2no0f77tQBShL0DqiGDuyTcMdo/KMi44TxCBGCkH1QpFeu8QfXbqHzxTvwu5LvBxkDxqPT7CXwchajCiXUKWAvOTTG7OY3c8z8FcdCisar6OwB4pwuYtSf/OZ+xte7LmnUYFG2/vfaCYI1m2mnhwgMk17wSctSF7vxLwOpbQiTeHcJrrZMtQSy4K7DtIfs7B7UD7rENegdvcmBysNbglXmHT2mBhusXMgID/c5/86+GmuZ3X+0aXvwt2zCLYFbNnEQ5reiRjvmsf059bQluT8T44xeniHvZdGqD8v8RspwdVd0rEyKw+HZIGmegHCrZzWEYtDhza4tjFMvhHckL5qC7zZLndOXafqDBhyenzRPUbv9DhCKQqrMVY/ISmWGYwJI6y5tEYQzFIr9ZkqtrgohrBivU9/NStcGhi6qiNyIu3w6pVpKqdciqs5uuATVwUfrL9AT3l8vXwbWWiRlizTQ3Bgp1lkYazBR4//NnO2S0clRFrz1uJ5FrxtACLtsNgfonYOgt0M78GIHx36Oi/uztLdsigtaYa+fA3V6yN8H1EMOXd4HA5DO/HptwJEz76xIqcF8z2KVHJldwitBX4lJkstspaZBCS2Qkp9o9iTouCB2aus9is0e7OEawOQBWbLxiz0fHOe7UGR65tG8jY10qToxsgln5GXFdvKo3PAbL3Ssg2EtG9KOXlskbVuhd12SGCn3BYuUZIRby2eZzsr83PT383gumuaZksmAVdmpk/CPn/QHuvzvXPP8YtL7wbHhjQ1DAIhKKynWLFt0N2pJilpeuOmb1I/l+H0Mux2jA48A/gcdknKps/UyTy8PSiuZbitBKsbI3c7qP8BKJs3tNjtAdTOCLqzkqQqTLplZDK9rX6Gci16E5K4rm+o2ZKhjOJ4l93rZYZeqyKLIdv31eiPCbRtsMi5r8krGVaYUXZjEmXx9dYhXrTmKXsR/ZMNhND89PnvpBt5WANzZo/GMqxKQhjGDBX6LLs1Vt87ZbbiYUpn4JmtVFmQeQ5xddQEIXj78EAbE4rwOj+ya1O5lpEGko2HDIN+ttrEkznNNGAjKpMrSfugojsj2L7TQ1su2ssQriLa9iDLsAYZ27vmZwejmoZwSEuQFhXxkKZ7LEe4ik9du53PWrcipKZ9OEcmktIVo/xaTEawhGIwkdOMzOsqLPewkoB2N2C9MsO3XP1p7ELKTVPrTIdNntuaZXuzQnWoy7tmz7MdFU3ohRB4VkZJSIQwWvCkLGi/eR6RG2di7hgfwu9fPUnZjzl5aIm9OOT6UB3VswkXDb9A+zmT5TaOlVN0YrYHRa72xiAxk5A0tVDDmq27y3TnNZmWuDJn75gkqhdxWoIXXjxsGna5IC9nzC1s41kZO/2QRjck9zWtBYu0rNgeFAFo3GRhDSystuLlc/MmT85RrLYqfHT9AZQ2DctO36ewLHH3ZbVWIrEHmsKascgORl1yR1AIEm7xl5lZ2Gbt0SncjibcTNG2YPUtNmoqwj8bMHQ2u3HsUg6052ysxMJrudh9RXfSuA2Vq/nKszcjUwgdaM/baOGALFC5UiJotdFJYjDs/7319zcp3r/2L+skjDy1hbZG0ZbAbQm8XY3fVMh+Qu4F9KcU7lSPPJMoJblteo0fn3qMX66/ncbj81iJh/ehTf7XhSf4+No9nL8+TrXW480TiwA3OqQv7IwyGLjcO3+Nn575c3517UEu/+FhnBjyEXNWPnB4g/dNfCODZ7le5+u1BfqxizNwGfQ8pAVJ1RgVshDTSbfNLFm5Yh8zZHYhVtei9MoGyUyNNx1f5u9OfJXTg1mWozrrgzKrrQpSKiaOblHzB/zY9Fc45uzwB+2TPLs3z9mlw+jE3M31VpWGBj0Z053AILdywdhkkx898CSv9qb54z+7B68h4LaIhePrrO1Mo4WZ7V+JRqk5PcLpLm23QHlRIC8vE16G8BnLoIzDgLxa5ML7DnJ6NqF8xmX+bMLObXVeLU+y1SkS5Oa9+VZKWfrI/WKPK9CdkftQh/2RWQzpqRq9k7v8o6N/SqQdTk/OcaE/zhdaJrlWFjKOVzcYdToc8jc4M5jm2uowxBKdSTJhoSdimuMQlmJyLfDtFHFLm2bXo3TKY/QlhUw0dpSzfZvPm+++ypS3x384+zYG2yGEiu6hHBlmNHohQmjkyRZxbOOeKRBcFPQnBdFESi8KeXFnARFJStcsCh1NcTXFacbYHUlgCaxeilzZQrgOaWmKpCiphgPudBP+zuzT/Oq738rOXoHgTIAW8O6Hn+fvj3yFd/GTcM4xO1rfLEyv6+69XYk9kHQWFGNHtti4NsT8Z82kaOtOj/YByOsJXikmC0rMvlJC93rkSfLfLaN9Y7fxjk0yVaE3abq6MnEp9s0Lj6ZKRDUbVUmpFAZs75ZQHYdW4qOQlN0BS5MWMpOMuCbbGwAB7W7AY0uH8d2UQ/UdfDul0wyR2y4vOLN4Mme5XSOua+yewGuAvyO4Wh7n45FPNRgwFnSQQnG4uk07CTjdmMFq2tiDfcWsZXoMKEMbkZnx1SdFc9O6fGECrydovHmcwZAkUDYv9ed5Yvswq63KjcQWPEV1uIsjFaf7czS9Apf7o+xGBTNWK5dISz6qkBMGCVHfRaUW1q6D2xRsuWX8gylSaPwdw5TrHLGxhSKuK5o3lYhrgic2DxE6KWlqgavIfBtRKJDNDNM6GOL2FMWzDWSUGNJr6JD5sHfUpT+uKDoxlSBi+0ANK4E3hU0UGlsaxp6RxwqUp4kncoSXI9c87BY0N0v8yubbqTgDprw9AishLyjSooVWgsXuEE4ppywjQpmgYwu7L8k1KFti9SR2TzIouTyTzGNZmjwXSDenP6HJPdtwBxKHpAKfuXwbvpuSZRJZShEbHl5DklRsOmMSJ0hZGNkF4NKuj7Ys4nqOVczIIwuraSNTk+CrLEHuOlhTNoXNnPB6h7zo0X77QbRlRGFWom+kxZSsAfWgT3fg7WvoYbE3xFPFeWw3p3kgQGYQrpvdYBaYnaDdN0w6LM1ceY/tSpm06BqS0lSOO9bHlRohNNGwZu+BWYLtFPfZ86he77+r/t7QYk+LkrU3+wy9eYP3Tb3Kfxy8neDrGdGQzcbdLklNcXRug7niLl9cvpniVZvlcp2NmQoTfpun7hugc8GtYZu1tEacm5dvXQ0YelHRnbBIvrPJbGEX/7LH6Msp3YslvjZxG0ldUbl1l+ZegclfUzgXVhl9YYJouMrWwWEuH8uoTrb5xZs/SSMvcu5rB6id1cQ1QVICLTXK1Vh9QbhurKzRkCCuCWoXFNVPtdl4W507//5LFOyYr20e4He274LTZUpLmlJmLpLemEvzjiLdwOe3W3cjhCZNbFQu8BNI58fozPqMTDWYLe/x0rVZZMdm+JRm6GsrrHxgBu6BXu4xfDrGv7DOzq1zBiZxZJvenEt/t4B4fJymgORQghOmRDWXbGaYxfcV+Mi3f5zfWH2A5OfH8a7vUr2c4u9abN6fc99tlyjYCSNuh7lwl51Hd5Bovq32AgqFb6VkocZtCiqLOVFFMnR3gzcNL/Mnu28i2AJvz+bUK7fQndZ8yzteour0cUf69GUAieSVxSmyOcn31Z/mihVhN238bYGyjYa/eimn8to2WTWkOxcS1QR7d2QUhvocunedg8VtYmWy3L9y5TDzv+wglE3rBwW3zq9y7fmDTH/6Ov0T42y9yaM/Y/Edt73AMW+Nj5ffzIXWKLZQWFJxcX2U8KyLltCby9GFjPpwh+FCj+U/n2Pu6S36Dx7i7v/tBRyR88WP3UftUkovNf3xIavL4fI2vdSlYZewI3j1wgxXdoYohhGlR9qsvjTB4V/fMGy7egXl2uRll8y32L3d4ttHXkBpwbmFoygHHr33RT5Yf4Hf2HgrpzcmGb51i/H72rx8aY4T14ZR1/7/oNiVA/GIwrMzWlmASAUyyZH7RYuGTuKZs2JizB95ItnNimRKEoQJWSZZ7NTZi0O2OkV0Km/IM5FQdk0jLA80SXHfF2+BtjWBm9K2NVacozsdZDSCzLTJKN+2aIUhHWVEILmv9zO9Dbkm9w2tVUujh5apiUnKCqZxI1tdRF7jeGGNgox5Uh8kSWyCgUEp631Bjcg1omeRKYEoamwnRymBSi2yUNOZDxgMS+K+z4qomuBDXk8SMWO4r7SO8druBGGS33jfnpXRxSVNbYhMmKSWMIgsMsfsgpRtVqOO8hlkDnamQJlsdjuWiEyQackgd9hOSkbw5PTwZMZyOkSk2lxv1wzSu2fGj8oWCKBoxShPkYa20dsnxnXYy10Kdky1OGBXCbLERieSzW6JL3VPcKY7eYO397o8VCggzZBRhh0pnJ6F1bLo2T5yWDHj77KXFdhOSqhU4m50IFfovIZvp4aIJPdFWSnIWLKS1CnImG7morQgQ6KUQApN5u9foLmAVJLmJjteKCDLyB3BvcUrSKH4gnUfMlH0Y4f1PKGZD3/jAn9d3qqEYetJTU+AFQvo9NBJinYsVOiQ+SbeWSSCl/tzbPTKhpDjmLGlI3Ij+tnPjn+9PvgLOLi/7uMNLfZiMTJBCRfnWHl2iuELYHdiglwzpH3SUNBsjLNTGCPs7quVujaP7RxFaWHGRZ2Q1qcm0dcznDkbd9IU3Mp7csrDbb535GnmnSZ7j4ScuXeCeb/LVNBkeVDj1Y0J8rZDHoI7McbGPRVaRzTFRcH0VyKahzw+Mvxu5iu7PPTAq/AAPP7ErYw/o2gesMgOpahMEG5prChn56RD+WCTdqNOaWmILBRcGoxRtGIcqfD9lCyEuCwZjAgG4worgvIli6xgMfXOdd4ycpk/Wb2JjfUahdt2edMjizy3NYvzqWGsTojzJkk6mrLzJpvmkXH8XcG5j9yCkxhxSXzXNNlkzNHSJp957S5m/1QhlEaLjDyQZkxXsPBapuCnnkj59Zc+iNvKcC4to/McLUZQtqB2RnDu+lHSEsSjGSLImZ1s4FkZn3j6XvwNm9J1zeSVAVY3wdpu4kwPcXmnwsXCKPXpJp1qQJZY6IGNLKSs9QwK7Pvnn2bS2ePX197Ka9emaL0yxCd/912kBUF+m6I/mkFk0ljQFmm4b6AJzC5q+ss5Mhe8/IEF3NtyTq9NkV8pUlkWiO4W2nchluxFIZ1DOcsfmrmRJuvtSD7+J28DCSIFmQvSkiIvmq388FvXaXRDSl+r4O8ItKzSEVXGFyOwLLN9FwqlDTffaSfE10r80/H3GdxY6rHbDW/ctErjHU6MbPL8s0coPQtTOzHCdcmnR1h6b4V4OMcaGBRZYVnwpV+831CDQ0DAn105zpmhCSyhmKk2OXN5isFzY8xs5ei9Fmbo/9cn0b6xxW5F3FFd5nT3IMUljH1QCESucNsZVixRjtiXX+7HIGkTpWRLhW9nCKGpXk3xn7mIco8RDdmkdcX83DYHSg1m7BYjUvBI5VWOBeuM2B1G7DZP2sc4vTaFyAS5I9GhTzQkkJN98vUC7kaHQtFmebuMJRXvP/A4N7lrfLlwM95eipVY2E5GbDlYicKKcrRjUw0HrIWatGQoMFtRiZ5thBhgdhTKMbZUxmPShkv5skQoQcUbcNxf46vuITalZr66y8+Ofpl/zcNcWCrjrbXZPT5C7uQwlJPWBW7Hp/TMEghB744ZoqqFH/apOX3sjqTwygrad0mnqiBsnI7Z+VjJfqNttYO/sX0jwVb4Pto22XheS+PvKqKaRGibtCTZrZrPvrhoU7uY4W8nOOtNSFJ0r48clFEDj1YSUA8HDId92olHZ+AjpaKdeFhSccJf5U434U+CFmesCbxdQf0r18inR2icDPCLCbFw0VKSliTR8Deis+2uIFjtINt93MYUm/0S0Z5PeUPg7yqTVOu5CCUYZA6iktCd87AGhv9vJRBsGzGTkTJrZCKJlUAXMu4aXuKCN8Z6v0y4lWL3MmSSYzX7N1bSSDkopKEKpQq7J7nWrt/gymWphYXZvZX8mCm/yct9QfliG5HmaM8hK3tEUynVsQ6tVkjWtyksW9RfbJAOFdg9ESByQbzns6RqjFa7jBfayK5N/UKEvTdAZxlCin3e4F+vUfeGFntfuVzpjyBHI/akx+6dGhl4CEtjWSlJ22P8MU1xJWXpvQ43nVxkImhxNNwkx/DLzxfHee3YCYbyw6zdb3HrPZeYDpvcUVxiJanzXad+iF7PR+26WH0D9NOuxh3t8+Ejp3htdJKNZxawez778Wl0D2Vc/r5hhAZn1WKrOcLTw4egDN62hbe4gT81QS+zwFPsHXFxug7109B+bZLQEuwdcRE5nP7j49/QwAN+G0CThZrJ4SbdkstOoQTA+Z1RfrHzTkIn5djcOkutGu94/Keg6VI7JJBzw+b177lmJUggqmvO/ZN57K5k/LmcwkZGIzLnx7SW07t1kiyQ9CYstDQNJadjxmNJ1WXrrpDObWYcpSMLkQiCDcto82cUcjIi2/UpLJqmWRxViSQU+hCXLHLHw66NElclndl90IPOuLo+TKEYUfZjPCsnLHfY7YVsXhlmU8BH9Hs4VtnkQnMMy8mNGrIYgtYUr9qkO0U8JQwtKAb23YdgctsWv62OsmrITLD5xBTMpUy9f5Fu4nHxfTVULtBpzvLKEMV6n9HxBludIt3tAiKVxG2zkroto1Z8/WgnpUYKzVTY5NwDEXsnPEaft6lc7KFdB1ksYCXw0eX7yZXEa2uE1sRjGT8w/zTX4yEudkfNSNULDZth4LPUrzNy5yYrJwL6qxXqp6RRUHY0zaxMYcnGb2g6C3D5/whIOw7BovG8h4sOCIftQoENfxS3Ldm5JcBt+dSlxGr3UZvbf+1G3Rta7Elus94vM1zrEBUi3jZ9me+rf/2GvfQz7Tv48p89gL+0hz1R5D8f+BSR1vS1INIWHeUybHd4duo49sBl+KZt/t38Z/CFoCgcPtGRpM/XGFrWBI0Mu5/um00Eaw8U+Z67n+VsOM6/rB0kD+0bRNnh6SZzN+1ybmsM+6sV9K7gUnuEca+F24R8ZR23M4bWpiPcm9I4bcHkV/u4l9dpvnWBrTtM4276yx2EhsFYYOikoTS7FF9zsGKaXWpUsBeHnL4yQ7dbZvbYJg+MXuGj6/cx+kUX5Qg682I/mBCcjkmDdTrQvCXj5x/6NF9tHeX8CzfjbfdQ+2YTq5TSnvXJQkF/wozISovf0OKnRUn7loTn3/FLWAgupB4XkzH+j69/AH/JpXZ0l5889Bi/cu1tRGfHsCKN93rmoDTy5Sw00uXeDMzeu4xEc/HKBOx49KXGs3M8P2IibLPXDwhXjNHngjvJcr0KGM69ckEHLuSa0ooiDYS5sVn7/Yl9aarGjEmH79pkLOxw/ouHGX0xZWkOfuvQJylJw8G7kOZ821M/hlzyKU7GfGDiNK+UpnnRmiZKHAahB7GFTGxk8heK3TLHmxG3y7uPnWUrLnJ+6SiVi4At0YGHTDWL10dACWa7CrTGHxrwvaVFnnM36OYee3FI0waUJo5tdgZF/vbcM/xIZY2P7BzlP8cPGYDnQOB0bKpXcgrX+zTu8nn1gf/ER1tH+X+aj+LtCgprGqevyD2jX4jr0JnTuC1BsFPA822sVhv+Zy72VEm2ukVyJdHAueY4v6HeyqTX5L7CJTyR0TxkoexRknbOTy+/h/V+mY1W6cZ2Keq71K5AYT1n+fIQ/3vtUUbcLkfDDV7szJGWjWnE6Uvsfk5Ut+mPStLRBFcoHJGR+ZAWLZSnsWzFzlqF1ismOiYZN06y49UNDnmb9Cc1+k3HjPd40Wiq3ZbYzztL0WlKb1wyevsGG/4o+gULvZ+fnoUCK9JYEfjrFo+fPWoMPF6GlJpyvYcc0iytDvHr5x4i2JDYUc6gKEiP9AnDmO71Mk7L5I3nAbDfbCvYMZ1pi9wtUay1mXZ3CcKYtBSQVDXuQgeAllfE7okbr1k6OZdTH0fkNFSBSLsUqgN6sSRaqfJ/rHwbVk/iVsFKTUKM+Av+iywwnvO0nFPz+iS5CdCw+oKs4bHTt0mGLWaLe9TCAdemc2QksJo2catEXssIKhHxUM7GA3Ws1NyU/oLEne6MRsz1kZYBQopcsrY0xHoyghNotu5wcMtdPts9SKotrsUj7CYFapUe3cMZjlQ81TzI6bUpOFMCBa5rhFpOb398FgnsriQtOQxyl/WowlOvHsbZs6lvKZRn050LTdT2hOb4gWXasc9geAy35RNtO/z89t3sxEVW+xXWW2XsgUBkIJycut/jEyt38WtXPHIlCA62GfQ97MsBds/AKpkNkX3BP9l4C09vLFBYE7hNTbiVYcWKnVs8erMKGWMYBhasvdVGJg6T5QP416qws0e+t/ffVH9vbIprZtHcLWJ7GbaTc3lthIuXJimPd5g42iS0YpLbe2zM+DjbNi/9yQkKa5qpi4bsYeJvNe5mAxEljJXHea55E0ldUZpukytJNpLSK1gE2xK/Ab0JSfumhEPzm5SkwBU5WRGiqkUWaApuin2xxOzHr9K/bYaNH4q4ZWyDRyunOejs4R9usX5/FaerGT71elfbpIzItgFadBYUnz/xW3y/813knzU01O6MIC0rylcEwZ6idklQXrTJQofBiMmXu+ctr3FneZFf+dj7mPvYFfRQlcF0ic6sxY/f+iQn/FV+ovvdiL0A5ULqgBXkhuXndGkfzumPS+4eW+OYu85kuc21eoVsIuHvHfs6RSvisYljbPZLLC6O4m7a2G7OM4ODNxj8feVxYnSDtbBC74/HmfzMIt2T0yx/ixEO2X2JneobtZgWIBrLsYcjZoI9dtMCcmBuJm7bQguLtoRgKmW+uAvHYLtbQD9Vo7iqadzioEoxhekOzoGU3VaBwnMhbmtfHi0EpRMNPnf7b+Dun5f/qHuQf/8fvo3q5ZSlR+Hgm5eJc5uPLr2Z3W5IfL2IdjRvu+ss95Sv8ocbt/PC4hzeawGzf7SL9ixaR0pkvkFXA+iOgYtkRZtmGnBhd5T5T2vC8yukk3WSqsvObZLbHrzAkeIWH668wJlkkl+Y+k68lkthyeKT6b1of39e33EodYwmw/dSZgt7vPa1Qyx8rsfKQ0V+8vs+y7V4hM9deDPenhnp9sct3BZ8/st34u0KRs6lOO0Ee6uNUJr+IxM89MCrfPncMaqPu3TmBD/8vi9SkhH/Tnwrw+URymdt+J+x2FECPbDIbYVlK4SlEX6O52RY+93OPDOQf23tm2Z80LYgC2w602br7Uy5yOwbgpbclcbzLMAJEzLLZjDsYyUugxFNabhHxR1wKq5yNppCOQY0of0M303ZrWnio5N0J2wcxyxjy6lZ6UdLXa4eLBKs2QQ7RiymHAMWzEbLWJ6LKmeUpM3h8jZfu2XWrOYxyF2zhe+NmZBH5ZqxktsCtGC9X2YrKBvww8I48bBHZ9qiP64NZQaB62WkRYXTkdhdSDc8fvna2+hGHl7DQsYmlrgiY3qpaxR1wuVTK7dT8wdU3QEzxT12hgt0KWDlko9fu5uhsMdbhy/jyxRbKBwrJxqCwU2TtGdtZH1APrAQmYM90Df8+U4P8rYk1QGfd06Q52Zkp2xw90Mwk5rDhdYonpVR8/rkStIQNURuVGQj5R6+bf6fFJpmPUDZ4gbGu98N+P32raT7eWqn9qax98VX2taEdsLuIDTCq1SCr8DWbEdFztqTSKGplHt0Sj55ySMPbPrjksw3km2ZfqP5KxPBSrdKsx1S65imY1YYpT9qm/FtbrMeVfiCdTPLUZ2kqmnPWyQ1jfbM79XaSHet/TCXXAkckZMVNP2JAOXAs+0DrPSqeHsGzxYNm8wDmYLdM7DT3piNXbEoOBKRmfd7vVsDDBknDzRP7BxBCrMzUZYgmizhBjdh7XbJllbgL2nSv6HFLlLwtmxiS5PbOZVSn+Gwz2xxj5KMWFM15Jpv0ltPpEzONlgvjmAPfLozgnve8yrHChs4IidH8CtfeZjJx0FbFpmShH7M7L7P+ZIzSveww9zCNh+aepnrcZ3/69qj7PaMiaU3DYWRPgvlXby7claPlLCsmKKbstUv8amNO/CtlEfGz3DXwh/zM2e+HXW5hsjNjSJ3BN2pEOWEHJhbIdI5f3f4SY7/6Bpf2L6J7f84T2kp4vq3BHCsSymMGSl0OXd1kvnfB4TgwtwUuzMh2eE+l8Zd/PqAm8bXqbkDYuVwNppiut5k3VKolyvUz2fYL+c4vxtQApTfJ6k67L4z5IDjsLlb5sCTHZCC7M9rbE+OwQ8t8r0Tz3BXeYndAwV+85n7qf5ySOPIEOd/uMPtpRVzIUjF5FtW4C2w4A6YLezx/PYs6rFRStfNVawFBDsO6arRi/s7kqzgsHa/IKkr6hc05VNbeO1RltUU2XjCd9/+HINwl8+7k8ZPMJrw3bMmkNFCcb08xOdSm043gHUPpyNxXwv56MuP4DU15WsJQkFQzolqFrjGCru1VaH08n7oxp1b+HbG2aUJzgxmuO34Ev/wyJ/zr3knjcUhkqqg/PYNRoIep69OYzUc7J7E6Zl+yPULY7i7FnZjC5KU1kGXvVsVOsy4sDVK3Hf46rphKpSO7jF1V4tB5pDmFp3IM689FYRbOUJDI3aRQjN3Yp3lkRp52+Xrf34z3p5g4vkucpCyc7LK6K2brF8eoXLOIq5B450RaLCv+9hdgYw1V1+cQVcz7Ad26TaKrP/uPG5HU9EKLWH9fo9oHsqnKkz++g50v3n9vbEruzB3ZvbFFalvOmSdzOO1wTRX+sNmRcwwvmFA+4poyCKuK04U17gjWGTGbuOg+eXCQ1iJSViVUuE7GcN+F0co9moBbc9nstCiZJljQDvyiBMb5Su0Lah6CQU7Yba0y3ihTZJbtJIApQXpfjqALzLGrC4jhR7b1ToyE2SBMTYkVdNll0LzUlwFYN7dZiJosbXfjc9CzXS1Q93vMRm0uRyOIDMbkSucpsdOWEJIjVVKGat0uKOyTKotLvTHGOQOjswZLvbYFBWcboaz24crywjXRcyOIws2WgtsLIRUaEsikwx3JyXwJDv9AhtZBUfkDDsdRCJxr2xQKM8Q5SZ0w5ZGwOFbKb6VIYWilQZ0I49SrJFxhrYlSIEVGzaa3c+x2hHaMkSavJSjLAsRp9h9hd2xSMsWqbbIkfuxXhppK6acPXItibRD0YoYK3Vw7JztvsluDzYlhXVFsJMTnFsH20IdGyPzDTPPt1J0IvF3NcoVxKm5jHXfxuqa723e2WGs2OV6fZikqjlW3WLCb3HGm0BJB5GbKChjR7bwmoBS4NgkFYEzPEArQZoazYC7Z3Zm1XDATZV1tuISe3FIN3bJezZuT+D0c9AQ91yW+nXS3MLzUvrKJdgSeE2N7CaIPEcLCJ3UCLUs4watlPsIodlrumghsfsCtwPdomCq0qLb8wl3LLy9lN6ES1ISxEM54+NNmtUxhPUXEi3+K483tNiDUsTh+xc5e2YW/6JP7Hlcdas4HcHVlaPmBY0J4hoULzt0z4wjDuVMvmeJVFn81qV7+KR7B//g8Be5y1vF9jOimmlIzVdbTBeavLN2hpI14Fhxiq2kzFK/zq8tPoBr5cyUW1CGTt1DacFMcY+q02fY6TLh7KGQJNp8JGVpbhC/t3E3/+8rD1Kv9HjTD7zC+qDMmYvTiFgiagmen3LltSl+9s9+GGWb4lYOZA/kbL7dZmx8h9GwQ5Q7XGqPmNinEx5uRzP+dI4VWwyGLJKSYOlWl3jsEl/fOUDjk9PYETjftcn3zT7Lvwm/FXe7B3GCKJfQ5SLNExX6o5Kb/B4NNeDDR0/xBz91krQT4q07Rj32xCi/zqP0FjKqE23CVQutTMG6MieUCTcV1+kEPh9/5j6Gn7WwUo0VayqJxt+O0FLQmw6Iy2ZFdwaKxoJP6/sFxWqf75h/kWGnwy9F34JypkmKZkvuNC0+e+kWstRmeEkRrkbkPZdcSy7HYzzfnMOVOXfUlgmHE5gxVNzffPHN+DuGs64DD5HlBItNvIbPxiMeb6te5KvqGLVzHSpXbTorNdJQ4E8J0pImURZt5XO8vMHVO4aoFwe8vXYOgHz7fupnBYWNjGC9B9LEdQml0QWffHiGwW0D/tltf8qfNW7hheuz5K4yTHlPU3CMG27Y7VJ3epy+NMPcZ8BtD7C32iAlY18Y5vxLx3C6mkpPU081dj8FrUnGCuSuxO4JLl8bA0fROhljeTmW1MSZdQOQUb2kKF/ssPxIhUP3bNOsB/SHx0iKHtvviDk8vUUdYbIB7b965v6GFnvd6fPu0dc4+9os/o5G2+asV1hX1L52HR36rLxvnKSiKaxCcTWlO2vz7RMv8mp/ms9eOUkXWJkb4nZvDWkpM9ZyYcjvMeG3OOxuUpUJDjnbTpkr3WE2tisUShEzxT3DptsPAQhkgiNyanaPI+4mAAmWyV6XMTmC1U4F60KBwe0J/3TiC5xPavzM7nfQ73iUSwMKXsLeRpmpr7TJfZt4yKU3ZsH7mtw6sn5DXNPPXNqJ8VbHQ+b8O3Sqi1jZxJsbJx4J6U3bpMpiq1Nk8ukmsjNg40Mut/vXUa6GZB9r7HuookdUkyQ1I5XtKM29xcuENyWc7UzwbDiPbnhMPAXBVsIGPk1Zotb6xkWhtMBCMea0qFh93B2Lkae2EHGCbrXB89DjQ+QFl6QoiWuvs9oF0RB86NaXuL1wnbcESzjAr0/fT3e1cuP5rUQQb4eIWOA3c6xODKlHqi12swIrnSolL+b+2mWmnD3m7QYVmfKp+m1oWUU5AjwXVAzNNlacACNMOXtmHr/ZxFKK2paPqoQklTJZEXJldg1DTo8jY9uMeF1mnAYd5WP3BeFOTrDeQy6ZPDVpWQjfI5uokdRdJod3eKSwxJV4jBeYRVjKMBhchSszLBS+ZSStom9ReHUFPRiAtBC2ReWiR3HNxWonyO4AXIe84KI8m2jYJfOFMfI0bdRwyuhoCzCvWyl5g/Hv72WIi4u4b76Nij2g7EV0CkZ0dmJunR+YfIpnugc505owo0rnLy/nNzYRBpOf7q9bDL/So3k4pH3Q8LiVPYu2hIljEpCUBP1Rh8Ky4F995oMgwdGmwfNr5+7n9wt3IM8WCbcyOrMWM+EedbvHM4ODALSy0Ih4doeR6z7dXY+vNgzuSjqKv5gwPVZvc8fwFGeaE1x/aQoZQ1bQaEcjY4H0Nd3FCm/b+WnEwKKwbFFKIPV9di0ormvSimdy6XyDvgrsHInm2dU5BjshVjmhXumhtRnP5D5cf7SKFlXcjskQk5ngDy7cTr4RkpVjRMElzROupKPM3rLO+Z8ex9mVlBZNJp2VaPxtweNnj3K9W2Oq0ORguMO1dp3i8wH+riZcG2D1Uvwdj7RoAJTp4UmSosXTFw5yfniUR2bOcSTYwD7eZvE7x/abcYAwjTmhMDffFTP7jepGrPTK3hSrgyqPWcdRCLJMkkznyHrC3FiD5Z0qpaeLOF1Nd9ymO1lDRpqPnHsErQVKCdJc8kJ7nlNilhc2Zmi3A9zLAYWeojcq2bqjjt0TzH6+idhuUn3W5cd738/QyxKUMoqybh8pJW6nRFoUXN+t8cXyLewkBdqxz1avyI+ufC9pYoOEnZts8jvL5EEJkQszd5fGD6Ftjb4ywj3X/ldwFZafQdNl6JQg9yVbMyVuq6yynZTYTUIKMx0u/tQsIjeNP6HM8wkF9fMOpVd6tI9WWXmXBlcZmauAoBJRD2J6kcvOXgmtQGUS6SgOn1il4g14vn6Q0i23oWz4g//yNhOicjLCDxMmgjZXE5MeNBG0WT7e4tr/coz0VwvftP7e8PgnX6aEGxr54nm88dtJqibidjDK/vbFxOxkIURCUL6eM/UnW2RjFdbvD8kCgThVopuXqF1TBOsDrKjErNfAFynPtA/SyTzk/rCovVuguCUQWgDuDW+xMaWYP2uTHr3YpXOxxtFfuk6+uY01OYYuhmzeX6d5XFNclIy+kCHyFOQ3zAhaQFawSUsWuSNuMO48K0cKTbxcpHZB0D4YoMv9/c6t2Y3U7t/gRG2TL509RnDVM8GBZ4oEXUiLtvHLZznX4hF+bO5xjhza4rd37+PTz9+Js2tRvQBeW5GddVlZn2LtSIWFIw0arQILz3axN82KoS1JsFskD8x2tTPnk3uCwgWX3nqdq0PD3Bou894DZ7g0MsKQ1+dIYYNYOVzpj7DWq7D52VmKy306cwG9CVPs13drrMgKg46PzgR2mBFMdnlo9jL/bPwx/mn5YS7+5s14OwOW31lmMJVjdyXZizWSioKJmDyXnN8bJU5t8ifrTF3OADMRaR2wece3vMSV9jDRS+MEq9uMPbXH0Ks+djMyAMY8Rw8ihJQ4PY3TFXQaAS8UZozhJZc0mwUqz/mEkaZ5TBMdiXnz4av82PhjNPIiF+IJ0n055VZa4rHfvZupL+2xeV+V1gM5Tlsw8tQWquCz+i6f0IrZTcZY6tS4c2KZh098gVRbrCR19tKQr28t0GgV6LYKlE5rWvMWv/LwbzButXkuWqCVBzeun8+u3MbaehGRCexEkFUzfmTmSd5baPArtcM8duIYl75ygIX/9zz9ew5y4ufP8o7KWV4ZzLAc1fFkxoTf4v0Lr6LmBR/7/W/eoXtDi32gHJbiYToLELzndrZvs6jON9jbLlE87aIFtI9nWKWUwYRA5xKZuJSfjbF3e5SveWS+vIFq7o9KOnMlBodifJGymVZ4enWeQd/F9TJsO0f0jG0ydyAPjJJM5t+QZcoE/C2Ldl7F3xVk00NYlSJpxScPbOK6QFUTsi0PmeRox6K94KMsQWUxwm4MUG6BpGJ008F2hrJs4txCaYHIjDbb2xPsXK8i0v2Glg9FJyGwEogs/B1NWjLzd7QgrpmzW3a5xG+0H8AvxVQKA1q9fVdeoBmMSpLYbAn9bUHfKfKJ7E6ybZ/mEYkzHWAPjCuvM2PEIdZA4HaMd3swrtDllLlwl7rVpWRFuFbOheYoj106gpCaWrlPlptuYxbaZmuNSYldGDbyuvOdCUgltUqPm4Y2OBBss5bZDDk91h6wcTpl4rrpuKbDKflUjootxI5Hmns0EpOPV27sC2z25cbahjm/gSszvnT7LOXqQcPiTzXdWZ+oXsfpaspLMVoI4vL+jXbLotEyHHwrEXjKhHWmBUGwIWDD52xtDMYxGWvuDptplS9sn2CzW6I3o7j+aI3+QsrJ2RXOeeOsv2sMNHSbMZ+4eif2PqjySmuYtd591Pw+d1cWqQU92vWAzbDEubkFireOkXvwq6sPMh02ORBsU5IR62n1RuqRDnOEk+MVEoaDiAvRBJF2eLJxmMvbw+Y6ODbLYNjm7N44cW5zvjlKe+CT58a9F3gpw8Uevcz9pvX3xma9ZQEvtWaYvneV6E6bR0au82jlND935kOMPw7Kd9APZXxo4TSH/E2m7D1+cPDDjH+shd7coryygXAdGBsmL/tc+p6Av/u2xylZEb5MudIfQT9fodowXvOkoPFfn9kXNMm4ARw62zb2QOB0NW5bU9gwIIHcUTRuKoAs3ABW9OYy5qd3WN2YRPZTklGX7TtB+TnFdQtndROrMkfmuwSNnMK5TZz+EFux+dBlZiyxpSVNccUiqgk6h3Iop4yFbcp2hLNnUbuY0Dzk0j2Qk4USKzYZ4DNfTHC3eqiiSxZWyA64RHfmqHJGtyggFdResShfz6heFijHpzcm2bo/A1tjb5tGXToTMzzSptkJaO/6iELGsdkNpsIWby2dZ95pcsnu4cqM5SsjHPnNAVnJ5fq3DJGVc8oC4rpzww6qShnfP/UUnTzgXy6+B6snuXv0Ov9i/CtcyhyeixY46G/xke/4OBtZ5QZF5pbDK3zvxNP80tV30P3TcYIdRe1UA9GPSKbrpGXnBp899zR3hlcpFBJW3lvl6t4QvVfrlBah8eaEf3X/H/Dl5gm+8tjt2B1T6AhN7ZymcrGD7Jqzfr4wzpVvD8kDxcKnc/wXr3Jp9BjcDHWrz5zd5lktOXtmFnfH4pYHr/DjU48xanWZtDMWZ1w+d/gOzrbHOfv4IfTzQ+ycyKnN7bG5ViW84nJpMuedD5/lrmCRe4MrpNrin2Yf4Ko7hZVoLn7xIK/VFd/x9q/zpsIOL3dnudoZRgPVoS4LtQY/MfUYkXb4paWHWWneyWCjiLMrkRpW3xqiPNi6OsqSGMFfM5ivoKNxeprBiOTKgQpx9M05tG+sNl7ZrHSqtPs+aWKzVqwQlR0yJRFpipSSfs/n+qCOvx88rqVGTI4hk9Rgd20L5TkoW6JdxaS7RycPODeY5Hqvhh2ZUIU80KQVBU3T+ZSJ8Sq/ngGOMseHtCiwB+B0teGS1wwS2t/VWAOQA2mCKASkwyFx3YzucBVZIBHFAsoxevHMl2TjVeKqQ7cLZ/fGzO/OlHntufF4y1iQxxZR7jDIHWQqkHGOPQC7ZXYiSdngo7UtELlpbslBijPmfENaaulvGEa00b5HNUFSEYhMorVG+RrtgE4kjd0iquPg7lrkA8nVYIjdYsjxwiS+SOnm/o3vSmjznCjzx5BhFGChHBCuoiz3VSTK7GBSLcnRWGh8YbrWr+Odk9jB6kvWO2VeqczS6BQo9I0GXHT66H4fK66Q5fvBFgrsvuBr3aMMOx18K6MWDujn5rsik1Rl3/joLbMLUJ5R+mWBIC+6aEtiAWnZNQ1OSyMzjer3kQk08iLLqcdGVuFMdwoywywY8bscc/foKIurqc9qViNWNkrvZwEI0J5ipNBjV1UItjTKs2jlIZG28EWOIxQFO0H5Bv8dbGuEkmzGZRp+ke2oyE63QKYkWWax1S/xta6ZSAmhKfgJfUsjlOHT5cZBi90yPnu/AU5HY8cGijIAKGfmmvgmjze02LOBTeOVEUZfVJSu9Xj1vUf5g29J6e6GqEIEuSZ8MeCry7fwWOUEIsyQkWTpw+NGXaVMY8pp7wcyFCKaecjXdg/x4qV5ZNOm2jejr8LJBj+08CK//NxDVC86uG2wI9ts4/etjvLNe3zbwmlebs5wYcvIXB0no9fxqX/KoXhhDximGdcRClYe8sk9jSxEaC1oz7rAJLlnwgO6UxYbbw5BCYJXbQaDgOqmwu2YG0MaGpVV8bokKUkujY2QVA0y24oyytcigoZRCg7e2cFzU3aiIapBjWB9gL3ZxO2UkLFECUCaLX/uCtKiZP1tin/wts/z6bWT7P7hNCLTNG9W6FpK+ZRP7YLxYjuNHtqxyGoBca3Ov//AQ9y6sIJvp7gyQ5ZTdm8qGkiiZy64cEdRuNwmqtaIhxWl8oCSHNBTHqQSKxZcbI3yhcos43aT+4NFTsWT/N9XH2arWcQ9F+A3NNH6MJ8O3oK/B+F2htvOIMtAacQgxelaxrqpoX5e8ok/fJC0ohg9uk3RTSgtQv3xRfrjB/jUbXdyZncCp2OOMvGogkJGo2DTOuKDAqHM+9BhCqlEuRIZhlgDwRPtY/z58lGsP6+ZhuSxnHwh4nhhnVAIfqt9ko9fuIs8M8pOlUlkSdMJNbccWebHp77Cj1//Xkaf3KR7YpjHHzqCJ1MOuluU5IBs3/ro7QlGn91jMFnkubtnGeQOp69PIzY9U8FasDMo8pntcZIyvOX9L/OjM0/wL9SjtLp18qLCrUWkez5Dz1v4TUXxeh/ZHpCOl4iGXPqTmo/c92l+vtD4r9YevNEKOsV+wmeMuLCEe/8tdFMPcmFikMjNHLctEJlF3rVAaOJhdaNrKtPXz8HGnphqI4Sxdm2crkTkGmXDeLHLPeEV/qP/FmRmgzBGkNdXQeVCJYg4GS6SaotBZrY/np2xIivkTtW85txIKnNPk5dztKMRWqBzQVYwPPTXH2kB9GiMimzcqzb+nsZKzQqNMDcqEo3umYCBQezQSc04TrmW8fU3U6xhm1qxz0jQ42JhiDSUeIF9A6Rwwzhia1B6n1wqcOsD/k75EovRMF/Op7CS/c9daqyBxtuJsJp99OoGSImzGeAM15A7NVaHKxTcBN9OUak0YQzO/oelTUaf7PYRec24xYSmowJ6yt3v2mvS3KKZhwxZXRxhcNSNToG05eH3jVTVik2H3+lp7F6OTBR4LkJKtCWMz37/YUUabw+EkvRiF0tonL4m39nFbS5wuT1Csx98I3LLVTheRqoEqa3NzdDWxkLt5uTYZKFEVMsIBdd6Q3R2C0yv5WS+oOUoysUBxX3d605aJGr6JpYqFzd2O9qCIa/HAWfXbIG2G3jNCoPMoZv7NPIikXaMt34/8hutkamJ11rvl1F9GycxMlmRmxtC9UpKf8TGkxlHnS3KfkzTBuHnVIoDdgYOMrOwYo3sJ4huH5EW9gNUNMfcDXz5zZHTbzBwUjOYzNg7ElBxDtM5kvP9E0+x3iuTlWoo26X3YI9bJtd48dUDFK/aZAVjKLF7gvo5hT0wKCTlCHZjU2j91MFtGYpI7pqz22a3yBfbt4AW9CYkVvz6eAu8To7Iof3ZCf5R7fuJxnIKMx2GCn3uHb7GyeoyT/7IIdb7ATPVa9wV7vFyY4r1KyPIvsTZMgXam83oH8v3Q8Iw2v/YQkRGC58UoX1AkA5lVF+1GX9yl7zg0ZsxF2h7N2AViOcyFishTtfQdgejgmknRWE48TKHvSM+8V2TKBdkYrZ1777lNcbcNh+L34IdGbVWR2W8pXSB5z84x1a7iHWlhLMZ0D6s2DvpU7xUYuLrRaxegtjtoJXR3Td2i/Qu+FSvKOZaOeH1XZKRAoNRnzzQuO0Y1dgjaIzhbTu0dIV/6b0Hx8opjPRRQ4K3jl3mruAqZ+Mp/rR5Kyv9qgFeSkjL5ganbKNLLy2Bv7iLLvhsPzhFFpijk9NXpAVJUhB0FuDwA9cMn+3iFNFelYlejjU1Tvl6wt6npsjGBYU37VD2Y3qJa9R010Iql6G9AOWTDepBn1trq8TK5o/Ebbh3TiJyOPflw1glxfq3RwRBwj2jG4x6HVyR8VpSYt7f4b4Tl1nvl1laHYaWw+jz4O/mPDczCxOY7922yQKbO2srnAwW+aWVh7myPUzU9LEGgs6RjNW3CpIkgZUCKyuT2LMDRmYbrK3W8a8bFoLc5xRuRGWWshpRZsrTCVJOjqzQqgacqYzT6HoUXxiiuF4j88zc3e7Aj5z9Xq4M/vM3rb83dmW3NFY5JRqxsRIXb7THW/wdfq+8y6pnVrB3HrjADwx/lW+/+qPGRWULEmG65qVrPWQvJh0pkBZtyMw2KclsrIE5q+v9i6kfeVztGT5YWgbdBa9pzjheI0XGGcGaQfdu3luhPeSRBRGzboMZp8H3H3mW0l8Ysf1b+z4+cW0YK5H7ZhNQh2NunlrDlqYzu9SusbE0hEzEfiCGIJ8ZcNfCdV67fhSxvIlTLWMPe2S+hdWVxJ6LU4/wJ1M6jQK555JWFJ6VofZXBaE0/VHJ4GCC6Fu4u0Z48a21l7nZbfDxoTtJC0UCOyfScNjZ4R8d+DzP9g7yu+feRrCpiY/GvO/Ya/yRfRv9az7eno3f7oMyph3dtamfzyn9ickUy/Mcb34WK5pCOSCjHNXr43QynI4DwmLVG0IGGVOjTYaDLreGy8xYMc/mAS/uzNCNPHQuQGgyXwPGo68cbeKythqIqTHaByCpKsqXLMJtGNQlSRWy+QE/P/dZFtNhfu6F76G4ZOypqlLA3ekzttNn++4qD73vEjeFq/zx9q2sdKrkbUH1yoDBSMBYscOh0jbvqZzGERm9Ex7nJ0fZfnmM0RcUO7dJ/tZNzzHt7t74riWK1axG3eryrqEznPJnWd2pkmuHyqUe8vIK/Q8dMte0MIElyhEc9LeYsVtc2R4mv1y8EdkUjnf4g5O/zvPRLP/i3HcSbmjiwykPjV/i093bQJliF5npKXRTj0ZeJMnMYuZ5KYfCLXyRcX/1CitJjU/u3WN2w/vjY3sAjYtDpP+zNOgYSJxLAb25nN6JDHoub/ryT0LHJrzJIi1ppFCcTybQiXmj0ZBm6qZNlheHb2B4Nu4O6M3kCDflYxfvJRq4qIUcEQu8/UKQUpmVUZiLKx6CwZhJCbUHASKH3NU3gibUnstqZ5hf2HgPtp/y6OGz3F64zojdZkj2aGcBOArlS5RnirlUHLBQaCCF/kZO2ahPbyck3DYrQFoKeKF5CKusufaTx02A45rZamlpttivMwTthsPIqZzcFVxfXiALYTCbEZ1IkZYBQ9hVRbiQYEnFR648SpJb6KUC9gD2LtT5QPbDSKGNfbXvETQNw82+5vNHg9uxd206M4LemIU7PYmyjMRXJpLmYUn8t05SXEsJXrxGPlSiv5BSGu2ySJXwznuMCWMxJw0Fbsshdx02iz5rPmR3W/iTKVIo3jx6jVf2prh6oYqdQDKWoQvGCir7ZnwqCiFpvUB2aMBEvU1zYxy2DGwDBP2OQ1MFbGclvF1B0FD0xmw609Ub47n2AlTsAZ084PTyNGrTR0/mXPl2F+0nXN4a5nqzyvnWGK6V0xiERKmNdajL+ozN+HCLYafDxWic33/2bpymRRYqtKs5cGiDvz/3JSr2wBxVLM1gLCBMxgmvOrz/uR9FbHlsP3qQaETwG1fv51PBHUQ7AW6+H2VWyhj1Y16Kpjk3mER52jABzpf5xPL9BOuS8pK6EcmtHMH56+P8tr6X3a0yblcwOF/lV6+9EzBHYZEKShsCp7Mfo2YLvD1NsCnYGnzz8vtvLnYhhAW8AKxqrd8rhFgAfg8YAl4Evk9rnfxlz+H0NPUzOeoHd/j5w5/jR//sBzn2y3u0bqqx8f4BQzUjCDg3mEQkZtVWozH/5OCf8m/sd4EuA5Dd3eGnTnyVX37lbegXKqiJnOkjW8aBlNeQGfiWMnNuqYxWvZ5y9MA6oW1eohSag8UdJtwmH792N90XhnFbUF4SZL7DH7/3Zq5P1zhc2uagv8VuEiK9HJVJcs9crGPFLifCb+Rov+4RfyWbpLhq415cZzyepD/msv5Qxj//wKf5xPrdbHx8HplgAIj7bHAwLPvSl8+hBhFlQM5N0fr3gt85/lv8ZvMevrh2jGO1Lf7OyFM82z/IRz/zMIVVqChAa2qvCeSpqmHeFQUFbTrXVqqpXhRwyaY/KujOK6MUez3comdsxb0jCfLeHp1Xqhy4XicaCTh+eJX3jL3K4uwwu0mBr/35LRz8nQbasSlVfbAEWghyT/JqZYavFo9wONjku2rP0svfyuaqsfzGN/W5b2qRr10/QNIvmEjjUoFoxOVdh1/h7tJVfuHUhwwarG/O5t2WRSMvspOVCHY04WbM+r0BvYXMnMctTXmoR83usZcVkFcCqtcgel+bf3PLJ/nNzQd49rmj5KngsqiiLY0eTggKMR88dJqfHn6a7VxyJhnnyzvHOPhfMtwXz8P0OFkt5PJ3TDJ0oEvN7iH2TVy9MQtEiaFzGfpCSPOgZO+dffLYInl5iF4i8IX5bnUxZ26qQdUb8PXOIVb6VfL9Yh8+pSisRlj9FNHbn2pojSsF/uUSF7vTuLsSty0oriqqZ1qINIfMhHdGU2XSkk1clqRFCLcV5VcbXOmkf/NiB/4+cA4o7//9XwH/t9b694QQvwr8EPArf9kTiFzj7WUsblf487GbQcFgpkxSkqiuQ9v1qTl9Zt0G7kif7kwRPbD5Zxe+lZ3tMvXbXYSGqJvwyeU7YCmkuKLJfYklFaGX0Kyl5Jmk7qYoLUwTz9FIP2em0CRWFs8szZNFDvZhxYK3jW3lKNt8Cd19dptYDni5ucCp4gxekJLENqpvG1dT3dgLFxt1Ppbcx631Ne4rX6aRFnhlbZJ4N6C1YBGUZ8ld04TB0ozbTY6XNzh78xz2QJhgy75N0nZJcqh0gbFhJKDKAVHNZ21F8LPhB1npVGl2As6ocT4u7qMRh8SjOVlgdkA3RmX77QORGc+zv2fmsFFVkBXMFuL1YwAClKVJqwpdyo00FIiHczbfOkwWCq4vj7PaqjBTbVL3egaiMV4iLdh0J+0bzUHlAHbCS7szLAc1LgVjvLA1g0wMIWbQd7nerZFENiIXRMOw8Y5RepPwgWCLqtW/gerOHZPAo3wzxvNkSjQk6E14xDWNU4lR+03SQeTwO0t304td7L5AC02S2CymI/Qz94bDEUBbmkIxZqTUpeb0iLQm3e+Y+1bG5oiLszBF86YKvXEJtYiv9w+zEVeolfq0pKZ5vEBvysbf5QZwI28aRqC/YwxA/QlNWtQ4QYoQmlbi80o8RSd2UWFOPAT9UQuhffwdC7cfowOXZDgkC4zAyu4bnNeNrLxaQBZY5jPf5yIAxFVBWtbEVYve2Cjpf/kbbuOFENPAe4BfAH5GCCGAtwPfvf8jHwP+OX9VsScpwdUGxVOT/EH/LmQuWHurAwr8NZskKrBw6zaPFq6xeazC10YOcvmZOeq/5iKPOdT/7hJVd0DnS8dJHx9j/vIA+/IacBDug5GgR+mAycJyrRylBY6TEweKWrnPO6pnebE3T/lLBSpXE57/wTkerF3As3JyX5OWFfHNMXnfZvazksKFhqGLWpLOsZCtOyRpRVE/vIsQmu4zI0TLJb7wrgoP33WGc61xgsdL+DbsvD0iLMZG5HNFIRzFjN3mB+tP8Z73nuZMPMUvPvMtuKsOpSUormcoR9O8Y5SkZJpTWsLYVzTN35slP+giZqGlCnwtGyGpKh5+86vcWly58fnW7S4jVpvT0SyfXr6dza0K9XMOheUe3cky7QOKcEMy/FqOFSusgSIrWFz/gOLowjqNfoFO3+PAkQ3e89bXeGznKLu/MkdhQ3P2w7McuWmFrJKzfWvAYExTvr3BaNjjUGkHW+Z8/vIJll+ZYFkJXs7N5KW4D74QGx4X0zFky+TRq5u6/Oztf8K43WTebrGRh2ae7BjDTVwDhiMckTFid+gfi4mGHbyFNgeHGzQGIbudAvFWiPqTAuWBIi4ZZWLS8vjc5m3sRQFOLULvp7dYds5dk9e5pbjKmNPiUloh1WZ+Pup3ePFWQWe6RuldG/yD+Sd5onmM37p0D5Ug4m0Tl6lYA8ZubmEJxUdOPUL8ahErhcp5G7unqSzGKEfSOi6ZOLiNIxW2VKzsVkkXDU2nNN8idFM2izW6ezbVCx7Duw6DySKbdxkB1NQTPZzVXZL5YQYjxjizd8SjswA/+r4vMOns8ZFzj9DZKOHVB0zW2hypbPGh+gv89BNbf7NiB/4d8L8Bpf2/DwFNrfXrdLIVYOq/WuBC/AjwIwC+LEKambFLyzKz8kTsyxohHwiuxSNcddfpKxdbKkQG1l4PZz+gDwwRpbCZYe900a02dqQZ7Cd0dGMPpWE47GM7udki2wrXzilZAzyZ7Y/TclTP4Uo0ym4/wIrN6lQp9Rm4LlG1hF8vYLUjRG+ATKo34n3aPR+twU3MnTfr27w2mGarU8QdaLJQMFTvslBt8FK9TLwjkI6iqVxcFKGMGbK62H5G7jvm3CUFmSdJioK0JEgrOVpqstAiD0zYhXIMD07sZ/uNeW3m3G1eGcyyEVc4EGwzZHVJlU0/dtGxhcw1IlMmCXZgeg2DusTpCwq9HKE0VpAxU2iyOwhJBg5SaO4IFrlcGKXbncbZ7iFjj1wbdsCNUEVlkMZDbpeiFWFZilyZzLfX6SvR0L5TLgJ2XDN+FAY6edDZYsQaEAqTSPv6bsPk6pnR6lpao6N8pJuThxZCQJzZRKlNllrIviTYycyUxnJBCKy2xbVGnSR2yPq2MTAAmWVzqTnCIHeou33qTo9UG/DJ1e7wflPVeDgUku24SLcREhdtVstVYs+mbnexhEmb1TaQmCmPM9CI3Iz6tKUpOokZxSUuaWJjRcZl6Nk5JS9mU+pv7MaEGeuJ3KzYMskhTszxyBEkJcFgRJCOJtwRLFK3+qa2YkmeWaS5RdUZ8Ga/Q+EvyZD4K4tdCPFeYEtr/aIQ4sG/6uf/vw+t9X8C/hNAxRnRKGX45A1JaUlRvtwmrfi0511kLPjtrz3Ab5fuuaES83JB6+QYaShZ/NI8MoeJZ/u4Szvobg+tNW4rY3Gpjowl9dMCO4NLDxe5fWEZ38nohxkFN8FCM+x0aB2FrBDibms+9fW7CVYthq4qWgckN929wULYYPunSjSTgGefO8rQKUF/XJAOp1gtm9H/EmBFiq2TsH2PQrZtPvb5h7B7AsvTREPwfbOnebj0Gr94H7wyN8l0tcNv7TxAL3dZ75fRWnDL9CpyRnNqapr2um8giD1h8MylFD9MGf+eHSaCNo04ZC8O6SUurW5AJYgpWRFXk1F+5zNvZ/KphK/e5NK+OUG2bcqXJSM9jdNJUL5N/Uyf+hlYebjAO37iaZ7bmaPxh1OIXHPH7FW+b+Qpnl3/W4TnfK7KYZI5y5BwHYF27RtobG/bZvSlLnHNo7U1xHJ9iJ27Qxaqu3hORjwRka/7hOvQm9K87R2vkGnJS5+4heFXYxo3eXTnFSpy+K3G/SwE23y4dJqCyG6go9MSqKkI21L8p8sPGOtnJsFV9LYKXFovIvYTgMMtgdeIsHoJdi9FuRZ+02NwrkwxATtS3DA4arAHQ2xldZaGbePes7ixLQ6T/bH5UxP8wssfwm0JhnY0uefyUu0Euav5XMU075ymhb3fBfebCqEgrjmkoUD4Zvu+1SoS7wTIyOQEaKFxbYNg81dcqhcUwXaKyBTeZp+Jp41SMw8c8qOTNA97JhfxYMQHbzrFqNuhkRd5aTBP9kKN6VczOjMh2+MBX7zF5WeHn/pLa/G/ZWW/H/hWIcSjgI85s/8/QFUIYe+v7tPA6l/5TEKC5yIzjd0Dv5Eir67hTY5ij9dQNvgbFllLolyTrYaGwbAhnRTWTU65s2vklWhliC25vhEGWFqOsVLF1v4KZUmFlAp7/5DjiJyspIirlomM3rQIdjR+I6U/5hFYKbNugw+WXyKUGR/eHmewXiOpaWSQQcumsNRFdmP03aPYQ5HpHSzuX037jZxJd48DdsLt5RWS3EYhuN6v0Uk8M/+2FPdM7DHmtdkZLrJClaTjoKWNcjVCamw754NjL/POwmX+tHuUJ/eO0LQDtBYU3IRO7rOTFqlc0Thfepm6vINoyDFNnfUcKzKxU3lg4zT6yFYP5YT8xNDXmHCb/FplCpkIZoI9DtumOep0oNe36ajAyF9dSR44ICFThl1vdWI8INy2EErQ6QY0/AJSKoIwYWB5Zpwn4X31l02GfP9m/MUG9oEJlKeRWnC1M0SuBZ2ibcaMAlN8niYIE9LUYq9RxMgFzUP25T7F1YisrEgbj7/WiDjFSnP8LbB7NlaikNHrEVkmjMRe2kLtNfHnpomnK4ZfWJBmBS0b/YbfABoCt6Px93Jyz4A3lQNJ27qRNwD747LU3E1etzeLfZNMlllYA8Po05ZZ8QFSZWENwN/LsQc5WghDF9oyysZ4NCArWCZnsKqYGG3ybbUXyJEsp0OsJxXcFgSbEVkQkruSTs8n/ytCI/7KYtda/2PgHwPsr+z/QGv9PUKITwIfxnTk/w7w2b/quaJxlws/MU71rKByNUVmmvzoDHlgI1Pj547rClXK8Jdd/B2DFU4eadFrBRRf8cgiwfKjw2h7eF9RZ1YCbSuSes7iB2y0rZk/uMmo32WrX0LlRiHXyIu0shCRmqNDWjbZ7m7LyF2LqzlP/vFJvly5jcmbNzlc2caWir1jCZafUS5ExEHKhR8ugCrg1Hp4fgo7gtFnW2hHkhccgh2Hnx/9AP96pMdIqUfVG9zY0mW5hZSmifSl0ycgExw4ssEP3vw0e1nIZlzi1a1J1FfqCBXwzORB3h5e5t+ffxDvz8rm6JNCX8KfBhMIDbXrMdbBORo3OSy8eYnFnTpNXULkxummQgV5BXQVZ7zHz689wpX2MGnR3JxqTh9LCB6cvswX3nocX2p+/ux7SFOb6F0Z5C4iSFjZrqGODTj/D4tYbk6t0sAVGjfy2GiWCf2YajggictUL8c4PZe/P/LdoGFuLdsn3ghuvWWRpWaNi+emueBPsHygRmgn6DCjedxFTUSMlLosrQ1Re841mX+B2B8TgvJMVn0+nTGYkvSmSsh8nzsvDerb+QtOzyyAwZhCKMHkV2cpXCwSzVToTbj0xwXd4wmWlyOt3HTd92smf77I0LO7DOarbN4p0bamcmlfrxGpG2rA1zn3NxR2+8eG22dW8OczMi1Jcou9OGRxaQTRs/F82LnZwW/YFLYctDAR4HFJsnO3wh3pM1rpcrzQpmTHfK51B44wZCGA/v1dLh0NsPoGV+55KbvKIuObF/zfZM7+c8DvCSH+JfAy8Bt/1T8YLbf44EPP8udL9xFeb5PWQwbjvrmzZfs+71JGWBsgL7qUlzLahyQ/e/xLPLZ3jBeu3Iy2oXdzxPBQh17k0o8d8shG9Cx0MePB4xeZ8ps3fqdj5WhlmPWd3KebezfORsrVqFJG7rmITBNuxARbgqTisGyPsTNVoOAnzM9s33i+mtfngWNXcETOl3eOsdqpoJsafeosMgiwR4ZwdoukYZVoqMLyHS7VmQFxZtOLXQOvEJo8syhecgyX7KjmJ+qnSLUi0pqfl9/C5XNF3FbC4vvrKCC+WGbmE68ZThqA1qjBAITEOjRPNlKiO6v4ydkv8/nSbfzZ9ZMAzNy2zvHqJlXbmEZOtad56vqCOZt7xihTtCIk8PbKOcpHI76ycZjtl8bIiop333eaOb/B71y+i+56kaPHVvmHc39GVQ4YsRKupmV+5sy3s9cqEngJZS9iJxF4izs4zSJpoYKW4DV6IAwz7bsnnuFXkgfJluooy+JcPoUMMiwvR8z0Gan0GAm6LMajDL0WYfUT0qpP7ktacw5xHfJQMTLeMvqGeSNuKboJllBcWBrHXXP3t+gaVco5eXSRTFtcXzmAu1ckGnKI6oLeTM6Hb3+Rmt2nr0zo4+uPT1+8H720gj1SRM+Y/o99OqC4EmE3B4huH1UrMZgsGKmvNvoAMKPde2rXeGfh7I3ne7x/lP/w4rsJNwXRsKZX1yhHIpQ5JmWBCYR425vO8sGhF3FFjiMyXugf4Imdw7gyZ7awiycz3n/kVdRhwReWjhNdKxE6GT1tk/8li/tfq9i11o8Dj+//91Xg7r/Ov9+NC3x+8QS2NnnszYMO7YMaryEZeSXFGQiTSOpkDAJIShKZCr7YuInTG5OUryrcrsLu+fTKPtGJASfnlzm3NUa2Voa2yxO9E2hXMTzZYqLUZrtbQMUWG6s1/tXauyGVBHsSmUHpqsRKHLIA1u8P8HY1Iy93CQYp9VdKxCtl9sYUO0MpomPjNSxWAs2ZhQlCPyFTxkucHAH9I/eS+YKkYkQ6eWi2bdayz4XLB00e+HBMsRBx08gGu3HI4tl5UHD52hh/z38PJ8vLfLj8MreXrvPl996M1S9wT3CdZ6I5lK/Jbz5APOTRPGjj9DWjX99F7LbQSmG3ItxWyOn+HKcaU5SuSaxYs9GdYrkwSV7NsAvmLInQ2F4GkzmBn1K3ukRaM2nvcXdB0R72+dO5CkLB40uHkPIgceQgihm7g5CPbd1Ppiy6mUemJJUgojwVMxp2GPZ6nBubpnvzOEJpwu3chDK0I0SUUD0j+bng23G2HKqbmiyAaNRCgTkm2Zq9Tki77yMiSXvex+26+Nsxdieh4Bv7r8httqkhY4m3a2Aa3VtaTFVaeIWEeFjibtlULwgGow69Ax4jQZfWiYykEhLXFKqaMDLW4liwTqotntu+mU7qcXtthcPBJvF4RnrvCVoLHq7XQSlz1NDCXL+5WyELJXFJ7Of5mZGh2HU5E02ztFfjiZpBP9siNzDTqYj2iEWhNqAeRGwNlYmHPNyWpLSosSN44rkTPFl/XaEHrpdSKQzoxS6nz80hcoF2FFgmEdhOBb2Bx6lojr7e/qb198aGRPRs1IuGUdaec9i7K+VH73qCj124B/m8h6OMyKToJbRLiqgukYnmucV55JJP/blN9MY2RUuC53H+ny7wD6a+wD9Pv5WNrQpeU1NcMY2e5YeHaC34pH0XEVsEKxZTT/bRAvaOW2SBYOy5DuLVS2x/70nGP3CdC5cmGftqBOtbjC57CNelfdcUe4c9ykuK2jMrqEqB7TurJNUivbkcUUuYPbnG3e9cYsJtcrt/naYK+WzjJJeaI2S/M0r9zy6y987DbLzdwan0+NujT7GW1fhIOIdQUHnF5bXLxzj9pinee9crPFI4x/3vvUxbe3ylc4LH9o6jgpyd20OaJxQ/9tAXeLE1x2L/CNWLLtZ2C93cwd8Z4pm9BVaXhzjyYhdrx6TCICX9g3X6YwHdGUFyvE+pEHHL6BpjXodxu0Ws4YCdcNLtMGQ9S3bE4rXdCXa+NoHVhey4CSTcbRX46spRrK5FsClJi5o73nGeB+sXALBQvDw3xdYdY4SbmtGn95CtHjqK0XnOxBfXGfu6j3Zt8sAhHnIYjNskGpRj8gSSPR+7aWFraB4Bt20xtZhire9QiusEJY9gz8Nt2QS7iuoL6+hiwPmxArLaZLTSZRDG9JaHGf38FeJjU7Qf9Li5usa73/QK+R2CIafHqNtm0tnjdm+N88kI5zdHiZs+R09uccJfZX5hi7W3TJFUFPUgNhMOAViC9pxDd3p/FyCMPTobSUBD4ZKL3xAkpSpXC9X9gEpNUtHcfedFbi6tseBtmzHpzCyn2zN8/fIBRl+ycJsp1StGqCQyk8i79aYyzbcK4q2QuT9WuM2YpOqSBxbdCYtoBKKOy7OtA3Tz175p/b2hxS5zcDuQFYxvvFzvcdRfZ7jUI64VEBp0JNhuF28ED8hEkDZc7Aw6t4zgzNXwtnqIOMPdlfzbtXdxeX2UojY0mmjIRtmCtJYzU+vQ9H0GfY+8ESAj44lX+znYyrWwXRdlY5R1tkZbFsK2EYUQHXgMhqQ572mJHY2TBpL+pCAtanQpw/UMx7yZBtTtHqGM6WmX7ajIXi+gmgBZZkQQGuLU5mw8RSsLyYqKaMTC7kGwpdldKfAf5h9izG1zPFglUg5f2TzC6k4Vp2GbkWEkOd+dYKNXNp1b3yY+NkbumXw3pQXCzelPBMYp9/r50zckHWULSoUI303Z7JfZjQssD2oEVso95avcESzypc5tPHbtMPFuQH1LY/chWXNoJRVjM1bCsPlSsAaCl9em2RyUCOwU30rJcotoPkF5DrULIbZrE40E5IHEihQyUShXkoWSqCqJRjNEMTM4ssRChBmqkKJbLuGyhdvSyMRMedNaQH/cJfMEMtcmC222TlawwFYMModB6jBIHJSryebH6E24jIQ9hpwep9o1GlEBr5pxzOrSVx6P9Y7wSm+G7HqBcFfyhfA4lyZGWLw8Rn1Loy257wjMaExWAJ+4ItDSzPXzUo7IBc6Wg0hNYzKqC5KaJq3kyIHEbUrsHry8Ms1SucZ3zr7ILd4qZ0VON/WQtqI74eGULVMHYt/U5ZieVLTr47QkoNC2NHHcgUAojd0XiL7FZlQi3dcU/NcebyyDLtaUVnJW3wGTB7d5//RpHgq2eWHsMp86PoHTA38N9FYRJxFk4f5MfV3SmxCEP7GKJRVXn5yneF0zfFrReGKesbpNbwKiEUHzhCAv5bz/TS/zgepLXE/rXE+G+Wh+n5EbAlkoiKua/rhHqTtFWjZ3aGFp8pKHndboHaoR1Swab074jttfpJkGbEdFbKm4y28jhWZtUKGbemz3ijzeOMzi8BBH/XWuxqOcuTKFu+HgdDJE0XiqAbodn49eug9LKipzLZIpCx6rMPxSi+JqyHOvnWQwKnDv3cW2FPkfDzF3PiYrZKShRC1aPO7cjBUJhjNNNOKy+v6UR06cZT5zaScBQ0NdVt9RQ6SuuckoQbgh8BsG6PHI9GVW+lVePLuA3bKpnYWgkfPVt97MwTuWufzqNAf/ywCr10ZkpkdQe81BO5LWkQKtg9LEHwtz8w7+oECShLSGJElZEN3V49ff9lF+v3E3z+ycRCY+zqPbPDx5gc9evYX4avmGUzCvpXz49hcZdrr8xpn7yNdCDt++zP+58If83OUPo/90FH+zj2h1wbbZvt2nfVuMs+lSXIL+hGDrzRb4OUEpZrcX0mkH6K6NqGiufqBANpbwY2MvMGp3+M+vvhn7ckDnTo+HK2f4Uusm/uiV23A2HA5+roe90jBZ727Aif4Gujeg9eABDjzSYCHc4YsPwk6nQLRRwG1YqNGId584yxPXDzL5CQdnb8Dl76njHmvzlsklHq2/wkfX7ufKYwsEm4LKsz5aBnzxp07wI4cv8rnc5/zmqFkwHorMsV+bwdXN02vcV7/Kb56/l9qXi9gRJBWLqG7RnZZkBU2wJShdV2hpcWlshCj7n8QIIxRmHGQJhoMepX3SScmKDFVGGpuqGJjupt53u/l7ZlRW8/tUnAHnRqaRiY3XBrcxIAuKJtN9/y5rF1MsFD3t4suUaXeXsBiTjBQQymy5tA1xRWJPFkkqmoobYXsZWclB5AFJyTL8c1sRK5uqM2Dca+OJjGGnc6ORsyVKrLYqJE2PFbvCU7XDrEcVRNfGGgjyQJKPVE28Ud+cTbPQ3H2NzVlgxRrRHeBZ+zcd5dBohVi2ohYZkYUu2jf4ezI204S4bECaQ0Nd7i1d5nRvls1+GdfOcEYG5JlF3nEQsTSop/1V3hE5tlTmA1aYcWY3w23aLDVquHsSux0hBvGN787qR0a7PRkgcnnDhy0Tjb+XYXdTZObh9CSdtkukzUWX+SAdWCg1uTVc5unyAoulgvGHx+b9xsomUg55ZmElgqITc5sLI0GX7XwEkSlTgJZlLL62QjmaLJBkIdiVBNdL0VqQpDa6Z+O0LPJAk42m1Ia6jNodSnJww4dgSYUv9nXk2esNYo1OU+h20UlqdnnC5Po14gJVp0/oJFQKkkHokw0kfiFhzm9QCqZBGBRZHmpGSl1KTkSkHWyhDP+wK/C3Y4TStGIfhWIrKRE3fbA0TiFBSvP6pDTEnGl3F60h2DX8xKgmyH1BPKTJCworsrB7wqT0RrbpK3yz+tN/zUD3v8mjXJzSd979v7D0qEd4pMnhoW3uqV1jOarz0s4MW80iha8WCbcVg7pRklWu5VRe3CAbKbN1d4loCEp3b3Pb8BpfuXwE66pPHmryWoawTH4cGtj2sPuCwq27/MT/j7n/jtbsOs87wd/eJ3853RwrJxQKqRBJgiSYg6hAyxJFmUqWJdmybLc9ds+ou+0Zu9tu99gjybYsK1KiMkWKpBjECJDIoQAUCpXjvXXzvV8OJ+49f+yLAuURZa+etdA6a2FhFXDru993vrPPeff7Ps/vOfAYS3Gdx7f20RoGtJcqyJGE6ZBqecDJiSV+oP40n2ye5MufP4nbNWW+FiaXze1pOvsFlZObTOZ7PNI4T9kaMFSeYYY99wj1b7rIBJyRInOFyS4PICkrlK8oXLFpnI7Zuc3lAx99nAzJ5z71IJVLiuLVAfbyFgQ+qhgwmi6w9qBNUtLoUoLlZbdUYJadkfNjHDujkRuYslkbuOVSu0JvO0+xMeCH9z/LjVGDR//kbiqXM7M4lWb7uE31oXUKTkzRDVFasNov0w89ooslSldNo2k0ZsrDsZdTvGaC0xwiBiO6d06xc8y65d6TmUbt3qRymzF2OyKcytGbtW/l2ykXBjMKXUghMXPn3LLFxPMRmSdp73dIc+Ya0QImH7nJF478CT+/cS9//okHcLsGRPmaykxmms5eSXxk142mhPknsiAR1F62qL06Yu2hHEc/eIE9+R3eVXoFXyS8FC6wFle4M3eDO7xV1rMcL4ULvDqY4UvPnsDdtihdM0mqScHc8DOP3Rm88UWoQDG5uMPdjZvU3T4zbosLw0k+d/E4aWJxeG6dxUKTL546Tu2UTX8eJu5ZZ71ZYvq3XfztkKv/SPIv7/5T/tmTH2bukxaZLxiMW7suNgPISIPdpJhLMPb4Br3bxhA/tcldjWXmvSYFK+TMYIar/QZXt+ukl4vc/IV/T7iy/Jeu+DfW4rpL65ARjEYuK/0yL8p5bJlxpLqBLRW9JI/bzYjzNlkA9kCh1jawhiPqOYf+jMv0I21+fOybDFKXZ1nEsjPynjG+RJFNGtkUlySFlYzViRLJfotjwU3eu/c05+Mp/sXOByF02D+1yfdOvchBd53jzpBL+WU+N3OCtGBjhYZbV1pOKby0isxm2T5QwJKKRFtYQlOxhmRI9MiisJLgbY4Q564gxxqEH5o3ZojpAfvHt7l6cw+5V9cYTM5ze26ZWFt8dVNTPtNGDl9juSlEmOAMU9yug3Zg+sgOJxs3aCc5WrvRVKm2qHsDPlB7maIc8Rsbb+bs1gS9Vg6rbROXbO7LXaEoQ55q3kXhSp+s5JIGBoHV7OWxSpoHG1ep2QOcRkqibf4/199L5XLCzjEP72CXYd8jXDL55NbQRsb2LbIvCpyBQmjNqG7v9lcU1naH/HaH/KuCdKLC5skiyjWRTnrbJc0bbYPX1vhnV8CycDtjJAWb/rRDXBYME4ehSshZsXmCea9VPFC5nJFfGdGbK7AwscMwcdjYKqNjiRhJZCTJbSqc88s4Jw5xrLjGgrdNom0ckfGe/DmKRUGsNQpYsIccKJ7nDv8GVw43WGpW6ekiyraJS2a64vShcsVENnX2WcQVQdUf8V3VUwy1RzvLsTfY4vuPnCLR1q1ZuL/mMPnlFdbfNc3t71olsBOGwQzaEqSxxY24gbXhUnh1FZUPsMKSwYd74haRSCgo3AxhYxtxrMHfmD3Fh4uv4guJFIKHgiusVEr8B/EIV06Vbhln/rLjjV3sgMgU+RUYpXm6cZ4z8QSjcc3UHevEmUVvL8Rlh9INReVqiBaC5P6jDCddNu4DXYs56EQ8NjjMma1JWPVJAkVathDSzFulo+jdGdK9XSKdjH93+hF8P2Gi2Ge7n6dwzsPb0Sy1F/jfK3OI6ZA755eRQnPnwRtsDIu0vzlJfkUzbFgM3jXHcFKQhjbdkb+baFLgl155GLWcp34evOaIrOQSvft24oJkNGaeaP7zRVa7BSavxugoxm9n/MrSWxgL+rQeimjdVgZVMZBFiUFNpQJrpEHCervIU2oPdzWWeefEGT61dTcvP7sPkcGjhSMgNN66Yez5BeOhTpfz/Pj1n8buC2YvjLA6A2RviCMEwfgE/aHDzVGV37r2JvAyvv+OF3iocBHtmirPHmo663msoUQmmsyT3HxnmXDM5KuXal16SyUqV00Z7/aNC1BGKSiFqpeIJgsoS1BcSYnzks17wR4fwfUcpYsSt6eI90+ZYJCiqQK8nsIdCNrfmuCutb+PGFp48e6Wbvcms/aQQAU+ufEOE0GPHZFnU2p0JgjWLZwe9Gcs+n/zEN0Dild7U7zcmeFys4EA/sbeF7k3d4V/t/QuLr46C6WEhekdAjuh7I04NhnyYmQTlz3cliDYMA2y1beZjrpITDPu4vML/L1nfgI9P+K7Dp3GkykZEgvFgrdNUYZkvjmfxeWUP//aXUYZ+RAoO8e+2RUi5RghjlKogktnr02Sfx15XjurKV0d0N2Xp/nuY8RVxR8u382f2ie4ttpA923uvO0aPzX9KCvdEvVXU24O/5oAJ8HsiwprGW5PUlyKcC+t0rtvgY3FIvkgIpsN6VccaufBfuYc6vYDbN1doL8A733TKRaCbW6MGrzcnaW3WaCwIUiKFpF0wNbIXIrjpjy09zLHCqv8l7MPYb9QJPHgSr2MPRRMXkzxNyNqJv6L5rEcz9+xn/x0j39+7M9YTar82vD9lG5EbN7l0zuYmq1BKAlH7q34ouCZAlPf6iLCFBEnhI0aW3fapL4mK2SIVDD+Qozz2MsI2wbXxWsnXL48wcZYkb9x/BTHgpvkZYwvX0cBPNE7yO8/ex9W3yJq+6xFNsHEVb4n3+Sz24r6ywKvq3YTSMDpjrDClJ3jBZrHIb8smf2zDeiY0ZtWGj0YoMKI4EAdPbKx+pLaK4LMs1g5VGG+0rrlb3dGGn/DNgrF1GxLuLfDzx16/NZ7/DUeRFtFZKwM2w8QoVnsacmnO+/gDDTlS33cosv2mOLhvZd57NrtVC/HZJ6kP+fd0twbYmqKPUgJNiX6aWP+6Ow1N01la5QLh+5c4oemn2EjKbMSVQgz28A/lCDY0gTbis27JeJgn7ybstyr0OzmsU4XEAq+UThIeWrElefmOfS7LYYLJdZOThONZbzr7lc4lNsgVRbL5TLds3Vy5xTtssUj95yh4gz5syu3Ee4ETDwnqT+1zup7p7k2W6fuDSnZI3w7Yc7ZYdLqk+3ePIObPea+mqe74FL/yDJvHrtMoi1C5ezSezVZYDOY1aSlDFkwvQTxqoe8tsrgwUP84IceZWlU4+svHcXdsZh/MiW42ePFn94D04/S6eWYPL2BHL7eZ/mvjzd8sStb0puzGUxr4pJPOTdHf9pCCE0YO8hVH68n6E9r0u+6g2FDGn9wPaXu9rHQPL81x3ariLNjY0UQlzVWJTb0z1WfDLheqzEfNCnmInam8+ggI1cfEo5cOpsBUcnC62ZYI0VUFQSTffbUmozZXRyR0j2akOZ80rzG6kuynEIUUgr5kLI1Ml9WTTOYzxOshTg3+3g7IYUlkwLarWh0PmXzbo/C+D27TybBYFpQmGwzXeoaRLJMWE2qNNM8E06Hve4mnjRjJm1BYWzAdKlLqiS/35ugm/i0D4IVWrvJqFA/I8h1RuS2MpKrBsW88dZxYHy30SnIbWV4rZT2fgeZH6HSXYdYBE+c38+1bo3gpg0iIy4IwvkYMbAoXxM4A8XoRpHftO9Ha0GmBf1OQHiPhciMlh8BwXoNr1U1+fW7Pv5wwpzrydomdxev89Wpw3T2uLg9TW4jMY2lkqH+WpHCijKITC06mHIY7knMa98wnPStQYGNpMxLvVle2ZzGthRz403Cms2GamD3JEk9xRcQxzZR5JAmFslUhrY0U7kuORmR1lJ6B8r0Zyzi+Qg/H3O9V2djVGK1X2IUuaTljJ3bbKLxlFHm0ElqJNcLFNcFwY5ZkG5X8/LSLIVCyJGxDfJWzCdGD5IoC+1qth6e3mXLmev/4oVprqyP8Zo7p7Au0L5LXLbJJiOCXEwUOqjd7xfLorCm+K3nHjSYaGGs2K2DDv3JCk5lwFZWIghierdPoLa877j23vDFrl1J+0TC24+f48nlPfQXCqR5hS814cCl8SrkthOW32GxeHyVJPKwQ5fpUp95d4dmlmf71THKl1/b02iGNhyc2uRGs0rhjIczUNyYqbNR3mRfdZvabUPGgj73lK+zGZf4I3kXvR2PwjWb/LpiMJfxw/tf4qC/zmFnQGb3+fk3f44rJ8f5w1fvxj8bMPI0440us8U2E04bpSXpYsh2EjARuVhnOlhhxFirSDRfpXtcMDPVorF3QMl9nRVUsGNmvRZFK2TaaeGIlNP9Wc40J7m9vsrh+pph5u8aah6Zv8h3V07x+zv38W/PvYuCH3H7my9hS0PiaUU5WluzFF4dkT8fk7/qsH2yxuSPXuNIaZ0pt42F5veW7uHaUg2rOKRWGrKTSbR08bqK2T+zQI8xHpnFFzYE77/9FV5tTxI+PYXbihl/1ic+X0Om4CYQHoGPfPAx9vsbTNptAL7UuZ1XO1Ocuz5F4VUP5QqSgkNUgR+efpUfLF3m8UNXeCI5QPkVh+pXlhCWxDo0TeZZ2P0YOYwhMZVSenuBD939Ip0k4NTZ4+RXFWuHi1wYn+CZpUWs0wXacyk/9fBn2edusrK3SjvL8edbx7i0OUYcOtBx0EHG/iOrTAQ97itfo273mZ7bYePeCdT0iO879hKDzOPLF4+Q9RxwTKO3Ot3h6O0bpFrSTzyutWpMPKson965JVsurMZEzwSEYz6X7swInJS18+N42xK9kOD8wBara1VKpz2cvmb+C2DFFpkr0TY4vQhVzjEYt7h/3yWKTshXLxxG9mxEphGOQ+X5dcqvegz2lln6oMabHKJmMzKpuKO+xbVojPFin+sPl4if+87d+Dd0sSvXoj/jgZ3QSXx8N6HdSCAThOt5ZCiIauYCsSYHHKussToqc1NUCOyEnvJNkIE0mmKVA2VDUklZLDRJlMXadBl7aFEqDplwu4Bxa5WckKIMack8KraQockGc3sKa2jRSQPDQN891pIK14d1dPZa0ogRxHTigIvhlDl5bkZcM0x4st3OiOugHAkJDGMHt5Ay5vYp2JHxfO+SVxJt8exgL4PUY3lQIU4tlJb4IiFUDnbTxh4Knt5YRGnBU6uLDJaL9IM8nWpA4MXGVmqlu3taSTpWZDThE9YFO6McV2SDpptHCkWrl0OOLDLXXKTCVkQVgbLl6z7q1Ahv4pKmZI+o+wMuTkrQPso2VYBMDaHX6Um+ubWfjXKJ76s9x6TVJ1I2rTCA1IwI1Ws0HE+jEAxVxjB1diOwIDk8i7YFvTnPpPnaArdjY7dH0B9iR5rNsEiqJWFdAxInSEiVhVbiFq0lLyOkUDzV3c/1QY3zqxPoDR8cjfYUdi5lIujR8PpcGE5yZjDNKHZIyxlBYBq72a5nAUsj3Qxrl4XQjHK3mH4aQ8jVnm3Kb20cd27XJBI3t0q3aD9pXuOWIvaUmux08yjLI3MEo7qFTCV2aEiyypGkBZc0Lxj3ewZtFls4IzMFyKZq5kNqbbZTaLJMkMQeWsEFPc5OmGdps4bTk7fOyV92vLEhETXFzncNoedx6vQ+CjNd3nH8HF89e5j9H49Jig6jn2vz/fOn2O+tM2O3eW60h0elScp4pTdLL/VQYzEdx0HWY8qlAe8YX+EnG48R1m2++pFjhMrhbcWzHHA6fGWwn8fSg9giY6g81qMS/iUjf6282kMurVFpHOIbhw6wPV7gnbmLNJXLb5x6CO+qhywrwilTsrU3i7R3ClzfqGPZGbXSAL/WoXNhmnwYYU+M0T5aMfP7FrSyMstOStkJmfObPJi7xFB5XInHuToa40+/eS+5NUl/X0JtukNgxUxYIzbiEjPfTMldazN8vsrzpQa1TsZkJwQh0NJhMF3g9Pf41MsDtARVzLH8zjxvef+LPL8xR/frkwyHk7f2xOW2aaQ1D3mMyiF+EDMwXhkKxZCcF7PdKpJ2XYqTPQpWxLHSGr33+2wN8oxO1SksGcVa5kD5ioJnxjg1NU3092w+MvYUX7x4DP/FHDn79fBMLTVpoLk2bPB1b4EzK9MUrhg3XvufDgichIqdEGU2Ky9OkVt1aLxi4V6/SWEl5umXDmJVI048fIlJv0eiJamyTFy3DzgKR2ScDWd44uN3M/F0lwNhiIh7rL99nOqH11gsNHlz5SK9LODfPfZuSpdsugdS5vZtYUnF6fYMqTJZdbokqAVDim7I2Y1JLlyaRxUzFha28OyM3rxEWRXcgSH9iMxkzWXrktyGTVx06D484rbZFfYVtjkcrLHUq9JWReIyZO9qU8uNWH1+itI1DAxE2wxmFPcXrjBQHvaOQ/6mYDAl6C4WeS2v3eRBKpKOR/mMQ25LkTk+XafCRFeRWxmw3v1rwo33nJQ9Y00uDieRQ3MVzvotpK2wdwag84yVWry78Co5keEL8GViWGLahM4PXwuuk2A7KSU/YsztMWElJCTcFtwk1haLdoeGNKKaVFkMUo+1uMxWaFBCMgHZH5HtNHH7ivbQoxnl6GmbnvIRLYdgU5PlBMpTBomcCsgk2dAjtTSRH1P2QtJAYI3VySoF4oIk842UU0aSOLVuJYNYu6qWDEmiLey+wG1r5MBiFLmshyWupmWWBlW8baPRzymNX/AQUYZIUuOsUorArZHGNmlmGYulZ5EUFQ+UrnC9V2e7Y8ZbVmKePiI1Wx6ZmXdhWSZQQUpNozCg7I4IY4dOIrGlYjMp4oiMfaVtyt6IF/2ayQB/7cIJFd6ZZZzuBNf7NVYqVdKBg9PTpHmxu9i1+TsCVoZlTntzJB2PUkczmNO8c+Y8BSuileZoxnlulMdJejaZZyolGWbYHY/Edai6I/YGW7zan2ZtVCJLLYSrEY65uIfKI7eRIS7cMFHOWYY9Gmcs6FNzB/SygO20gN2z8FoakUgCOyHVkuEu5SjvxrgyuyXeArBHgsSy6Ix8ksxCvTZzty0cV+IMMuxBjEwMJEOmNqGXcLS0zqxrekAFN6LpGmvubLHHdL7DUnGCJL97QgVkuYwMyVB5yMhAN+OyIC4bhp9MjPaDTCASgdfRBFsJmSdRrsDpZViDCJH9NVnsAk1gJyzMbhNO2uTdmBfbcwT5mKsfGUdLzdUb8/yt1sf44b3P8r3FM/zOzftp/uksYR0mHlpFaUH5WZ/KpZiwnqdTLvD7t08w83CL0/1Zvvn5O7GHcOy7z/PPpr/Io+3DPHt9kaxv427bJhfsjiHRXQpn2MC/dBUr0aRDm5VOmc9276CTGkyVliahRGeCfHXEbRNrXGo2SL7RwGtr0jN11pw6w1nFpX8/TbbjUb5gNP1pTqMKGb5jyrpHtw/xqfBOav6Qe6o3mHS73PeOV2lGeTrPL5D/QpErTpH/wT2EM9BUvBAOzpMWXTJP0ll0GMy+PlbJfE2+2CXNpOGuVTwaL8G/W/0wmQ/RQYWMBY2Xwe0oVt9iExxpk3cTKv6I69s1/G8VcXuarizSEeBFmqlIE1Vq/Pl03eTljScIS2EBozFxK+tMJhZFKZH9kOXnZvgX6x8EW9G6O8XqWHg7ktfsnk5PsPKlBVazBWauZxRu9BhNlFj0t1mK6nzymZM4LQs3e01Q8hf3nfaOzfMfP8HLg9tNElCqcQ5aqBM99tXbZAhyMmLtrdBdPI7X1PgdRXcfxJnFo6sHiL7ewB5p9JtHzD6wQm9jkkuvzkApZWFmm6o35GhpnaIVshzWaMY5ZqodNo9lxFsFxJeq+CkMx2EwA0lRo4OMYNmh/qpEKI2WgiQQWJbCEq/jx+6qLnP1rjpR22f1S/NshCDnNd3jMcJWSMec3//lhQ+S9R1qN8HtKZKcuVN6bU1+XZH6gsG00TTEBejsdektQDydQCoRcZnw33znJf2GL3bXStlX2sazUlaHZTaGBTwnQd/WIYlt1JZPe8Pj1fEZPlg4w/JWlb1Pd+nuLzA46SKEpnQ9JXj2CkG9girmSHNlXr1nhlObc8x+fYSzM+D0fdOsT5RY6ldR2x7BtqR6PiOsSsbu3eJEdYWvjz2AL4z0lEQyGrmc70+afWXKLUwSSlAMQt5avUCYOqxt1SnejBCpmYVfPmrzm/f9Nr+48giXrx0wRgZXI7wMRyoyLVjpldleLbNVDTlU2mDWbfEzE9/AFykffu4fUD/dQ/ZCaHYQhRzhngZJySf1TbrMYF5TPLaDFLtagt1u7jA2DLs0Zyg9ted6dG+rs/bdMakSqFddo3JbGPE/H/08V+MxXunNcDVrUL2U4K/1EaMYkWa3qA1ZrUB+PU9UlrQPGguwgFuwCy2MugvLQoQxhRswigKiPSETs03WdQ258fr+UcZQuZwYfFRrAO0e9qBExRpwRY9TuGKT29AMpoVZRBYgX5vJmYDHqW9soS7fgN3gjuijd1F/e4v5QgulJY7ImNi7zValxGjVUFvjekaqLZqtPIf+fAcxGGF/wOMXFz/NDwz/Fq1TRUIlsOcUBSfioL9GxRqynRSIVZG6P2DM7/N0ey+N0yNknLH8jiJJWeFPDZirtrmopomWLKxE34oVs16T5AqNIzL2eFvcPr3Ky3qGxivgr/W58gMVGlNtAieh7IZcadZJXikT9ARee5cZGGoyf3exX++T5R2UE5AGxt+RFAXJfMgD+67dWmNfzoXfcf29oYu9YEfcX7nGRlKil/pc3BojvVQ0meEdcHdTMbQl+Pr4QVJtAvXWH8wDkD3aQGjIZjSjDx2mdD3Cu7FD7VyOr3/xTtCC5E5QTsDehjkBZW8ElZh05IEQOAPNlefnuVCawTqm6f7L+7H7guppTVjL85ycx3Ey4kZGmpfIiZC5eoc4s/hPF99Cr5WjUhb08MzoLtLkrjn8xDN/C7kUMH0hMfbEzCbNWWxemGZTTpPmNCKviEOb5WGVtbDEb129j8HIQ01EXPg7AYULJWa+4e3uy83IbFSXJAVBbhXUcoPE3yXzyF1qayYorWuskSLJ28QHasQFibXioyzo7BN097h43ojHuoco2SF3lZZw9ii+/n1HkIOyKfFTQf0VTe2lFmqXOecMNI3TxinXm5dEld00F08zmJZsvWMeLWE4DUlRgYBB5IKtiaoGyJiWTOMyqjk4fYfqxYD8RYnX0fy/Xn0/AP0DCYM9EooJtpMxvJ6jYNvEVRexd0CcWLRP1MmPF9i8I2A4o1HTIdN2yvKgwr/dNAEKtdyI0uQW15bnKN1Q2COLV6NFZCJYfq/JQu9vxHxI/RjNtTJeoFGeQqLZGJb4X5ffS5pazDbaTOc7vLw+TXS9SHFZYm+sIZQmv1pAKAtmNPc3rtGJfJrNMZO2amN48Rer/O7Ft5AVzcw8yMXMV1toJbBHKbIzoHKhQjsZY2Mu5tDCOllm2A3agtYhaZKQ5mMaY102tkq0DpfN1jMBBIQNZcbBHYennz+EbETcMb/8V66/N3Sxl2XIOwpn+Wr/KL3UJ1zLM/t0htdOcK9vA5CNV0jzDkkh4NH+EXAV/fuHWNcC9v/aKqQZV/72HOn+EfILPs4LTXLPDdl3LsdoX4NrPyCYmG5zf80s9oY3oFge0euZ3G+3r5j+pqGCWD+xwe8d+R3e+vjfY/5/jwkn86wU8gzKGf7YiGIu5HBtg2OFNf5k6Q7S56rkM4jKEBcFetXC6ymqFzO45OHvRHjnV8G2cXtjZJ6Ft9pHtnt07ptl46Qk9WxWB2UGsUv6tQbVDYXzIxt86dgf8r6F72d4eRxrtBvxbJnSOaorph/XFL7wMnJijGjvmJlG2AamYIUKmSqGE57hnQP5JYNwGp4YUasOEELz7OYC94wt8z3lF3hr7gJ/e/wxMgSJthlol7/v/QiViy7aNa/h9FL8V5YhTUm+6xBRZdczkMuIcxlbr2WdCUAYGmw4chGWIqmZC/3IzAa+lbA6b/T3LV3G28njdRThtyqEY5oj999gf9FAF5SWfOOVu8GxCasW79x7gUjZfPPY7QymAo7/jbP8+sJX+OKwyh9s3suN1gTJC1W0BXNvu8JD9cv8WjpH6XKf3LpL8aZDb0YSvG+DejDk0uOLiCfq5MbNecVTCKHZ6BUNBrylWHp3nT2HdxitFJj/aoa/1UffXEM7DqUbNezQpf+A4v2llwD4dOwgMEGhnZGP96cVai93yUouSd5m51jA8J0DY3oapuhmm9rLRQqrAWsPeESzNmkqcVLT1EwPD5modfnRhSf53sJVnomqfPbYnZxrT7B0ZgqZCOz5AWPFIc3nxxl7SdE8GhDOfGfHG7zBi30pqvJPrnyYWFlobbKwO4s2VmThzs1gh5rcSmgooY6PWw2Jhw5q28PSsPWWabQ0uWASjJMsnwPLAmVCH92NgI20xu+P7ubzuWOsr1dw1lzybZNz/trFKTSs7pT57fbdZF2XpCpJA5PlDhaRyhG6Pu1ewLnCJN2BTzyXgtAIP0OnEpm6gNx13AnCiiSoLgCQ5AyAIC6WscMiaSDIrwqSjsNSOInQEHgwHJf0Nyv8VOkdrLeLyGO2cWDtymfToimdWwctouKd2JHG7WQoVzCYNIjp15pvYV0QjivsoSC3tus3X/Zp7niI8ZBqacjzW3O8uPMDlL2Qk7UbVO0BB7x18iImv6fD8juq5omc09gDm3ppD/ZQke7GTSeVjEJtSBQ6JJ3dUeVr47wND6snScZTStM9ktTi3KUZ0OBWIlw3JSlBfy4gLprRkrZgmLhsRwXydowjM4azKc33HKR5m+BQbp3ttGBUdA5IoUh0xlP9/Txzbi9Wy6G8aaqP09dnWO2XUA5s31HEisAZKmSqafdzxKlxiDlDhWqZUWM8crigpyCSVKRJ0nFzMVNeB+2akVoWOLiT4+jAo33AYzghCNs5/unlDzNKHLQWhKFD72YJuy8ptzKEMjff7qJkOK2YtDIsOyOqeQTjdUSW4TZD3LbLarNMGtuohgGEqshis13g4sQkN/wbvDya58XtGXY6eeN41KB2Md7KNUSnzH99a/edjjc2xXXNIfp/T7F1wmE0lSFKKfptPTwvZqbQ4dLOGO5/yhNc3CQuF3hkzyW+cvYotdOSwazgnr93igm3y2duHKfdypvUkEYVkaSIKMZuj5h41iVzBXaYR6Q5Dm2HWFtbqHKe4XzRpJfsqtm8V3L8+vrbCHYk7X2mM+pva9gGK5LITKKljRZ5kjsVP/7Wx5hy2sw5OzSzAv+j/F6U7RGOK8R4iGVnqCAiSmxGawVkCFlBI3xF8WWH6W+0QWu0LUnKPsvvdEkmEoovBtz4o8Po+yze+t2ncGVKL/HpJD6nrs1Dy2Xve6/yT+e+wM9f+R6Gvz1N5kLroYh6rX8r5fhgqcPR0hqPbeyn05nEa2pmH02whilL7wnIbh/ROzXG4uf69GbH+O0PTFMd6/HRvc9xX+4yv3bit3FPvEbhVbwaT/JvLrybVquAd9XBa0K4qHhk/iIvN2dYXplCZIK0oRASGi9C7ek1rv/gFH//bd/gEzfvQ/6yhz1IuPJ9edTeLuF0wlbO3jXxaVSg2OwW6EUuc6UOdW/Au+55Beek4lBunQ8VX+WlaJzfyb+JrGcxTF1upJpPnz/B/t/JELEZi2pbEmx7xIUG6d0Z1R9c4/KFKaYeM7bpZClPy8lR2zTE2NymqYYyzyIuWqS+YDhpOPd7x3a4v3CZT9VOEJV2wzZLE4QVi+G7e9wxtcKLXzmC+L0xRsdckgd6pFs++/8gxFnvoAMP5dps3SF42zteJFUWvdRj28vTXSygnDHyV1qIlU0qkzk26nmoKyaPbZIqydaFBuKmy9cLBylaIZ9Zup3eqTp2Ym7s2oYoscykp5TRm7eJ6yn2X+WC4Y0m1aQKf2NIsFVC2xYhEAUOOTdhNtemEweMSiW8ch7latPo2B3fKFtTsYeU7SHWruc38wRZ2Tfxw7vOsSQvSXKGNGrFmqxvI20LLU3HFARJXpI57HaVxa0kzNee+GgjQ5WZJgmMfxgtuDgYp+Xm6Hg5epmPsDRpwVywrp3huikFL8a1M0Ylj8yzzPvXJnwgagTYowy7NcTybLTlGvuq2PVSW7Dg75CTMU3bXJxnc5OMIosxr8+0NcSzUqLEPMn8XMxYvs/2MG9CE3ZHfK6VkRQ0MhFkrkTG0gQ17O7zlS1RNgjHvO9OFnA9GSMvI3yRUJQjxuSIutXnSH2T607KxtoErhAQS24OK+wMcjh98/tSQFjKTC8AkcJ2WqQz8hnvRMheiMzyBraZSKzRt+GctCSJbWw7Q+12RKe9Dnu8TXyZ8Erc4MxozjS/HOgnHpeSMbJMkgY2lswQiQJpnuJg+PK3V1a4Vm6QeYbF7nQlyjZ9hLBqmXjojumvaGmRuWbMlZQ0BSci0TZSalJfkHnCJMuWBeOlPjNBm+ddY1aREUQtH7e3yyiwTZUp4xR7KLjRrzFMXFrDgEHXJ18SDDILKyzhuTbKEbgdgbYkzX4OrY3bUmaCNJOEyiHNJCIz50Z5hnGolSBKbORI4gwg6UvWBiUS9W3z0f/qeGPlspnCag0YfzJB25Jwukh/Kk97T56LbzYpF5v3SNr7q1COONeewPF28cKe4tOXT2DbmYEfWprhtGaTHOXrLvmrN8lmavQ+3OPk9BKJMvPtZy7uoXB2CrejKS2laAHNY5DWUoSXIW2FbueoXA5JSjatAw7KNegsEPTuDHnTgct86/wBLv7Ho1xSZr+e+gIOZKg9I0QqifsusXAZdH1sN2PP9Da2UFx9fo7SVejs1/T/YZet5SoLnzV7K2Wb0qt3IGU4aePt7eJJ86RyREbZHvHm+SsMpj1GmcM/Xf4QF8/OcvBSj3A8R+qkNPw+50/PU7oiuTBT4eLCGI6TUb5zmzCxuTlXxhp6qIWQghcRHutwaSpHvtrnHx56nKI14lMbd/HZ9nE6N8rkVixGU4q5o+tM5zt8//hzyDHFP9r5myT9gNySzflrB3F6UFk1jrZwQVMqjWgf8NFyEoD//MTbCFZsRNxEe/YtUEfljGTy0S1U3iOu+QzHbTZKLrFtnkp5O2LB2+Zuf5nfaj7Ipx69DysSSMdowq9uNPjX4XsIcjFLHwXdcimfs7BHJpUFoNgY8BP1x7kxX+PczEHcLjROZ2gJG/dJ9GxI8ckcU8td4tkcG/cLsmrCsb0rTAVdPJnyrd5BtBYMpw3efPH4KmNBnxm/jSMy8sdaXK+WyC3D3BcFqa9ZfXMeofJMP9bDurLC4qchenISV2mmEsVowuHm+2JEY8BK5JClPt4Zi8lnIrQtSF7Ik/qCzh5BUtb4boIjMmr5IVcnSyBNzp0QoAcuw608Yy8Lxr61yvDgGBudCZL+XxNSjWk6SYMYiiJ8QKgCSdGlOcphS0VaVGghEbZilDhYliIupaAMhwsBwssQlgmRSArmzqvjGGVLTk5f42NjTyB35z7t6P1cas+hbElxxezz00pKoTEgywwdVmiweyanC3aDCixTLk2Nt/neximedPdRuTBARAlZwSMpufQXLQr5kG4vQEdydywlyaRmLOhTtCOux3PkthSto4Lvm3+JP+EOkkIdmZoLUwNWMUEXEsZLxugjhZnTeqTsDbbJtOR0b4albhW7J5G9ELtoyK6xsnF6gmDLyHYHJR9Vjjk0tkmqLV7t+SS+g++mJJm1S4INmSl0OOCtA7AzytFp5ckvWdTPJrRHDjfHKygtqEwOqcgRjpuaEI8O5DYVVqyx+xmZKxHSXJjdomY0Zs5hsGLjb5tIJO1YhrAjFU4f1NUlrGoFN2uQuXnkyDzd011+mi8SyjJjkHnkVqXh5M+AChTJwGEzKVEojTgyu861oEa8WkZbAjsykAtbKipSUXZCI+4ZgNdOTMRWyeLI1CY3SosgTORWVk0p1gbsL24x5Xa4OmqwPiySpRLhGb3EXbVlptwOQ+USKoepUpdMC5L1KvlrPaKJPFt3ObtkYQcry2B5Dfd6dksIlT+yDzvncLixiSszI/FdPoY9TBBJhrepScsenT0BmW+CJm7hrW2NcDPq5QFSaNZGVUgEficjvb6MX/Dxt6tmZPwdjjd0sYdjNpd+YmIXDAG5DU1hJSXYUnS/NW6ina4rrDjj5ttdylOh2f8Kjew6VM+ZmXh3n01SVORXJKWljNxKiE7Np8xbMRU5uqVnnsu3uTw+zjBvs1q2Uba5O2otyM4XKSyb3DiUyceunZeEVYv1R1ImZ1oU3Yg/2LwXx0258f4i9hD8rd15s6UYhi5yxad0w4QRjvbEuH7KkcI6ZXvI49kJvGaCFZpmVt6NaU1I7JHGawmSOCA43OaB6etMel2TJYaibvWRQpGXERYaSyhcmfKtepV4xhB63S+VOVuoYAXQOrJrE12zyToWLw4XIBPkrju4PcjcIm2neCtk4oKY5J94h1A2DGdTRD7dzRlTty6Y9VaRH33sxyCW5G7Y+Dsav2Uii9oHPLZ+IKaY6zFtm2gCVUwJxxy8HUHpisLtKkgzVN5FT4W8ae4qXz92B8EjtxPWLAbTRpdff0mjpc+5+2foLJgk3xPeCm8tn2PzQwU2h0W6N+uIoYW74WANBb0FC1XuYFuKUclsz4o3NV47of9YnQdX/xFO2yK3Y7ZoO0d8sgAm5je5r3adC0cmWBnUUS54yy7RqsMXzp4EwIrN3tgfGkqRXrb56ksPEJdh4Z3XebhxiURZhCMXbwByu4NV8cnGNblSyPr9ZQozR/BbGW7L2N2E1kRVD+uSw/M7+8nN9Jkqd8kdbnPpZwLoBuSvW2QeFB7c4q7qFk9fX+RPXnkApycot2A0blNfGDIVdBkLBnRin+0bMxQO7WU0XSQui7+gcvyvjzd0secLIXe/6QKtMMcgcdk8NUFhFbx2xthLJlnUv7oFmcK+d46iG9KyA4QwssXaWSNsiEtFtJAEW5r80hCr2SdTGoQgsGJyuxZRhAk/LJcGqIIkGxcIDH8sSmwKyzD2bBehlKGmDmOCqyOs6TK1iT4fW3iar+4c4ezWBI6Twh0tBj0fdTYwlkUJaWIRtASVqwndBZvRPvDdhAVvm4o1NIy3XoSMzWIP7ISNMmjbpJZYoSDvxXxX7UWAXaJKSl7ESKGoyxG+yBgoj6FyeboUEVUDvFbC+BMtkLD83hqjPQnOpkNuVaAGAhmZJJXSdYXXyRCZUZ5ZYWZ6HKMYNncQpQJXPzZHtD/dlXvuymuBpO9Sf8bBayuEMmW2v4uoiks+//nu32XC6vO/rb2Hq50GTi4hyQT+lkNhJUKOdmEWrkWtMuAt5Yt8ff4QrUM5wpommYuQWy6TTw6xOyP6cw22SkXWayUSJHd7K7x9cZUzcZGf6vwQ8SBngBJbmqRsLl3bysgCbaK8QoXTHDF+CiqXbTJXkeQMp24wY8AeJ2vrnMgtcWBmDxcGM9hti8JNgTWC/EaGFb8uN1WWSWnxmgnOmeswPc7yyQrOWEaSWaSxRT4E1e4gkjEKlZC91SYv780Rl2xyaw759ddpr9oS5Fc0XtOi6+Vouwn3Ti3xnqOv8K3eQT6TuwPpZPz04rPcFVzjidM/xfRzhu5khQpwqLgjDubXOZiHRNn8xsQ08USRsGYZodN3hsu+8Qo6iSZWFlFqoxZH3Ki6BCs2k09HWGFK1iiBEJQvwdnhQaOoqqW76iQJygAKrEgY3lvOQbllZOMYccXhU4/exycrdyPdDCk1rpfgOSlFP2KxtEOqLG70qsSpTeYKsoJr3EvakFasZh+7F9G+UuO/6DcRuAn1/NBQS9s5GBi/uLLBGRtxaHKTs2t7SAryFj4pjB2+vHMMz0pRnqa7v0g8ljHhdNhf3OLcvinCnk2wbmFFsLFR4Vdyb8UWGa6VkSpJmDmkStKLPeLUZq7UYl9hG9tWDBuSqOiRHfBQjmksEclbT2Snp8mvveZOM0mt7X0uw6ndikQGBJuCmT83Tq7M13hBQn/ORdk+aR6ypoeMBVFVkPoWXscour69CbeU1MgQqN3GoFoNKN+QoGH7eICyIPOLht122efnb34f7rZlzDm7s3lta+KaC1JQWNaEozzPF+ZQY4IvDY/wW1cfIM0kc/U2VqPJxdIkoy0XFSjOXZ3G8jMq+5pEicNmWiaYq5DfyPC3IppHcuzcl4LUiMhCS8359jiRuoe1riHcZoFmNA5oQW/RQiibYBO8jiIqS6IKyMzGvuMIcQneOnuKo/4K/2HtrVSf9ChfidBpit0eEZ+u80qpTHFZ4nY0SR7a+00zsHwlNlOYnA0C3HLEbY01nl+f42vP34YcSnJNgbbh32fvwC9EIDQbJ1+bFQvUWMjhwjo1a8Arw1k2wyJZI2btQd9EjhfULePTX3a8wYsdbJkRZxaj2OE9B87xk2OP8XOX/ibWt2pYg5jhXJHME4w9vU396hKjd51g+d3mAkoDCydRFJcjE2frSZKCTVySDMckbldz6Fe2EN0+ulpC5T1uvr2MfrDJZL7LR8aeoat8fiN6E51hQBZAXHm9oeH0JNZ6gtUaUH+xxHCtTvfEkIf3XqY9DLA2XUO/zYws8vj0Kj869Tg/NzNJVAyMC0tDHNo8c23RbMgDTfOopDrdYs7ZwSlmDI54XO/XWO7PYI8E7g2PszuLKNdYMkkFTtcyT/0VjdPXvPiWCmN39/GclOGUMJ3l/UOCICbZLGB1DZlVaPDbmsozK5BmZJNV0pJH+7aU9598mTm/yW3BMr+09Ajh2SmcdkSW09TyI5IDEXq/oL9dJHfZBCKEdb07pRDIRN/SrcsUrkQThPr1yKTiVcnUN7bZur/OzsMR5cqQd81dYGVU4fKvHqbxXIfO0QrdxdcXvHY1g3HTla6f6SP7Iefna2S3CT67dgL/N6qEZcmb/sFpfrL6LL/ZuJtnW4u8fGWO0mmX/qLiZ+76ImN2l/8j/25WtipYX/UpvrBN9NAC/+atf8RGUuE/nHmYuO+yulZlda1qNL+2RhdSoiLYfsqJuZvk7JhvvXyY3A2b0XRGdbFFyY84WN5k0uvyQ5VnqUnwrviMf/wUOjOmGzZ3mHm0SOZJvNYQGaasvq1CdHyIPpdj/IkBWILhuAmNmK51+FD9Rb755DEO/5uriHyOcE8d5Uj0C5LMy3PzvYpHHn6JujNgyu1QtEYsOtsMtMvn+ie40a4yM9WisBCxM8yzs100gIvvcLzxpBot6YUew77HZlRgPS3iyozOnIfdcOkuWqQ+JLkGufkyo5qFv2EEHWHVIipbhFWJ8szYw4o0UU0wnFZ425IxMM26nEtcNdijwdDjvB7n30fvJNWStXaJOHKwypr2vl0RS6pxhhbKnTKAfm93UW/5PG7tJRk54JvxklACZWku7ozxcfEQWc/ZbRTufkgBuXxkOu1KEOVsrMTm19ffgi0zPJnhWSlWKHD6muEUyOkRWdvDv+mgLVNyKsvkmvvNFDmyUVpiW4o0MAswHTlkmbkRKm93FJTs5oQDODaj6TzDhoVbH7A/t8H1sME3tg5y8eYEc56EiodIoTMIcJ0Ub9e4IzIM7kmYqcFgFoYTgsKyQ1nlQcCXVw9TciNWuyWGA4/6QEOmdjPHDUdgeVSlFeaIi4JwpkhUlrfENDqVu5p7gdAWIg2wiy46n5ETKWNBn7MTkqQodgM4LPZ6m/RLHmeDSdAm5vuF/iIVe0gv9IzYKdHoKEbGsJFUuBlXiVs+TttCxiCU6Z5ngTbCo9Bw8OwFxZjbR8RGj64ci6ZTYVgf8dDYVaacNltZQFtlROMZ4VuP46/14ewVAGSmUFoSNny0DXHRNCWjqmLnbqPy6y0IkqIilzh8sXUcrynRwxFCSqxhivAtoopDGghkLmXa67ARl3ipPYsUZiwYZxaXdxqMBi6h7zBwXaRUTEy02XK+86z9DV/sqZb0tvO4Gw6n7Dk+YT1ArCw23pYi3Yx3HDrPodwG20mBfubxZ0/dxf4/iIhqLuv3WcSNjA+dfJ63l87yS0uPcPnyJNWpLj+55xSfWzlO+vUiTqdH60iR3oIg8zVqJUCv51HP+WhHIk56iKpGHuwz9UCTrUGeTjePygSbiYRE4m0I7CGMvSDIbXo0DzuM7hsgdok6xBL38SrXmhUKDcFgxoQkIsB2Mh6evcKc32QtLtNJAh49c4hLnz9Mf15w97vO4sqM3IamfDWm+0jCJ+77dT769E+w8F8GDOfzbHwkxPcSnKdL5M6u4943D0DJD9meiBFDm+Cqi0xhOJMhKjG6GeD2NPZIoT0XVc6x+mYLuTDgBw6/wAcLZ/iu83+H6V902WMJ+rMWSc6oypIbeaLxGK/eA8WtyGUUaE/z8EOv8H315/l/nPsQm483DA7s0+NsA5YnKAK5jQTs3UST0KKf5HimuReUQBzI6C/a6N2sOS1BjCzIYDijGWWG3AoWR/bcYNKCD9Rf5pV3T5F3E476NwF4OFjmPn+Z58YX2LDzuB3Bl545gbY1IjYzar+Vododgm3FFzePsdIpU3/BIr+eEayPkP2Q3uEanT0mrrt6tsdgPk94h8Oc38TftGi8NEDbEuVKNu8q0jjaY87d4YvdEzSTPO+77yW4D/78a3dx4H/1b13fmS/YuNsinkgRfogNjB/Z4r6Hb1CwIopWyFC5fOL0SXD9pwAAtnNJREFUvTz6wh2Mv5pBlqHjGHunT1bJ0T/iE47B4uQOd+au8y+WPoD+fB0rgu3EoLvFhMDNGY/EUIA83Oc/3v1b/KS/8x3X3hsrqhGavBXfKjW0EvQTjzgz4hPLViz4TY76K4SeQ6gcPpc/ccujq1wQfsaU22HeblH3B1zxMyyp6aQBcWYR2BJ8z2CAq2oXoGDEMnY7RHo24KEcTTk/Yn9xG99Kv+09wjBySHdKRnCz27ACkJZCSkMyUbv6DaHMmC4L9C0ybJZJImWTaIuG06dqDxGuMsIdZSSftsxMz8CXSKlJtEWWSuQwQiY5PC+h6EckOYku5tC2viWakbZC2QptWejMmGFUYt0izmSeJJ4pE5dslKORmLm9JyDLJFY3RuQc4oIgLexWBTboyKLZySP7ptp5LYdcS82s3+I2d4eZUpcLxToIgddm19lmbnJJQTKaLRJVzVNJZwLa7i3Bkt49X2QCIQ29RuwWArvbUlOlaEGCJtYWmZKMYodnBvtpZ2tULBMuItEkBfN63ra1C8nAfNEadJbhjDRLrSrDnkcjNpJiLQApd/PXeB14mWm2RnkuDydwBiaDHluiHQt76NHPfAbKo5v6dBOfE6VlDnlrfL5+O2JXsq2lQFmCpKqoTPQYDD2SoYsuDTmaW6UkR8TaYjstoUY2XktgxQpRLCB8j6ycIy0YXoNIIUxteiogzUzuncxMJSslRtatdyOiTNuJDPFXBDbzxoZEHDwe6H/16aN8fO1BrmzXGS/12Vvc4fEbeyl/IU/mQ/5713nLxGW24gK9xOfZ64v4pwOjE89pY+espUafPrSRQ5PiWbpubIFeK0W5kqX3SMb37zCe7zOba/PM+jzD5xooR1O9e4vFcpO8FRNYCaPMYZC5lJ0RR/JrXA8bfOWT91K5oti+XaD3Dc1MPrLMRWkZD/LBqU0WC03ONKdY2ykbeMOOWSFpQaE9xduPn+ND9VOcGc3xUncWV2ZMeF26acBj1/aRdD1ELBGxINiQVC9l9KcsnPdtMZ7v8+q1aWTbQUyEzI216Ix82u080tKM1UwM1eZLE6ajHGmsEPpzgrG3rjJMHNI/a1BYy9j+6JBfuvP3+Y8rb+f0M/tNc6qgEH7GvrlNpnIdnvnaMea+FpEUbEZ1iyQvGMxpklLGfScu8576GT65fjevXp4xX6gEMoHsGTiiv7fH0fF1pgOTjPrVnSOc/fOD+DuGKGz3M+KyTZKXRGXBaNKo/PxNA2soLsc4nYiLP1zgX7/39/k/Lr2L4JerOP2UuGwScdoHJaOpFLcecmBii7M3ppj7YxuZapbeZSEmQyb+1KfwyeeQRw+wdV/VxH1VzU0tKZnvReZS/CAmHLqITQ+ZCJyuQW+NnwrxLm2Qztbpz+foLkoKb9tgKt+l7g0JrJhDuXXmnB3+yakPM/2bHjJRpDmLsGpR+Fsr/Mz8o/yTpz/M2Fc9uouC8v2buFZGZ+QTxTacK5JfNd+XM9KEVUFnvxmLTj+e4m+FXP9ggeJdO1SCEbP5Nq0ox6XtBqOeT/FFj9ymYud2gXOwi1KSLBPc/B//M+GVlf/rQyJckbHP2WIxv0Mv9ii7uxLXkWPQPr7FarvI9WKdZpSjH3tIqRhNKGQisEKBPQL7pgM4aNss/tyapv6tFbRjMzzYIKxZiFrE/so2hwvr3BbcRKL5/FwZ4SjuGrvJwdw6m3GJbhoQWAmelTLhdjkZXCUnY76WgdPPSCqSd+67yJnmFKvXG+aD+BrLUnzXxMt8oHCB/2Q/yOeGt9EPTeSTTMDpWijXYudgnryMeDB/iQfzl9jMirw0WMCTKYenNmlXA9ZenqR8CVCasCyJS5CzMnwrYWaqxahhvqZ+5BHGDjoTSCfjtto6nkz5SjpBbiNDOYLMNW6u/2nf57gUTfLx9gcpnt5keWeMnazAdNDlwl5zcTiA66ScrN1gn7/JC4PbcJ46i7tnjrhYJ92tToUW7IR5Lo4mSZXEKcQ4TkY1PyLOLLY2ypAK3r1wjr/X+CYKiLXk0miCC5GZVedWRlg7PZzxEnHFA2yiutFbuH2DzPKWWuj1LfzN41wOJ9neKnHkxZukaxsEWiFcF/eR22nvd+je5fDusbMstysEKxIZJUCNIIhJvQDpOsjegOpFEwTZXxRk1ZTp6SZT+e6ta7IX+2yWCrSbeapnXfLrCe5GH50kKMciKhkvxXarSJTY+PWUvB3dmkD4XsKokdv1UphqaH9pi7cH64aDsByRBh7brSLSykh65uaeG5qnd+bvVkTjEOxvM+j5OD2NvLpCsHGYne0iM3s6/MPJr7CV5fl07h4udMfZOD1neP2WxXSly81mBX09D9Ffk2DHWFucjyf50uUjcDXPamaaJdUVjbu6CUJQ/VyDM7WjhqHdSCCUWJkwiZy1FDJBcNPG6YHyDA8tzUPrgRmSnKBzAJJyxsnFJd5UuUTN7lORQ7qph7fqIDL4YnScrxQP896Dr/KB6ks8P9zDkzt7SXIWScEmLyMGcxkidbAGmi+fPrZ7ttStkVGWWvze8r18OTjK+c0Jwo08dl9iD01TLdhWyAyu9Pfx0/W9pCWFrEYU8yH3Tt3AEYootYkzi2wiouW65G5KGmcS0sBhT6nJfNDk1Ev7KFyzSIoGYuh0BOPLGi1dnq2eQFlQXVfYI01n0qK3VxEsGF58xRqycT/0Z6eZnN/AQrMZFRhu5I1GPRLEruZUaY6kYsaAACKM8XeM42Kwi0FaemqWlWiO0d6IE3tvYssMV2ZsjIq0Nh3cjuAr44cIrIQvLB1l8EqNzAV9+4joLsX2e21UWqP6hMfEE03iUpW4YkZv4bjRzPdmJvFb4wTbmj/4rUeoDDWdB+awolncdoLIFGH1L6pGXqtLRRhTuiwZDsuM7tBsPnA7pYs2019tIhsus8fXubu+xPKoSj/xjJxaSTwr5UB9i/Na4PZtvM0h4WyJ5HCVqGRYAm4Pcl8J0DLg5fE6aUGTP97kPXPnaBQGXH1zAXfTZuZbCdZIsTyosp7Bntktlt45Q1LJqBaNpyP0UuLYJmnlsYeCYEeR24jZsTz2NzahAa+85wDBnYfpz5lP10s8zkZTnB7O8YVzx6DjEHjQ2WPjtmDpyVnj8/j2E/KXHG/4Yr8RN+BanrEXFU5f4XZirG4E61voNKW6vIpwHZrvP0LzmHOLjKICTWW8R6okaqmC29OkqUB4xrfdPCJJiorxI1vMFDq8r/EKx72bt373MHUJNky56DcdkrzDYK/H24I+1+MeW4MCrsyItUVeRniTQ/oqj9eSBGddopommY1h14SjUsHy9QY303GsvsQbCKwY7KFJVCneGGF3QsovpYg0I9xTp70voL8Q0GlsUnOHRJlNkkmqtT7UYNCt468PcMfK7MtvscfbonDNYvqxDsO5PIMJi/x6SvGFFXRoghaRFmphgrjmE1dg7NA2+yuGDZCTEQduu8naQpGTY0tYQtGKcnjbFtZI4AzMnm9loUzJDbFi0FpDGOE1jV4bZSMSwcTzGYULLa78UIMH7rlKpiWdLKCfevhNQW5NszVd4mveQeIn6+z71fMM79/H/M9f4X21V3g4WKYobe5c+4dM/PEm1v4yqqhwCzFj5T62VCyN1+h2HKa+pRn79Rfg+CGW3ldG25Bbs7BDSHKvX08Z31atxgnlawluz0b/wA6fOv6bPPLUzyA/PUCmJT4y9yzfW7jE/7b5Zk6N5ogzizi1CfIJx4prtKIc6SCP3OkyOlqiu/j6EzK/qhn70lV0GKLnp0jLAde8KucrE0wEPfbescNj1/Zhf0FgjRK2h3mayue++nWyeyRCaFy52yUPYJQ6rORzZL5h8vsX1vFm5jleWmXB22bn3jyb3QJEDsQWYWpzOZrgdGeG4LyP04eoBsOyJr8kaJzJGDYs+gvfGSMNb/BiXw9L/OorD1FcFkbVlWq0I4km86T7DpsMLE+gbMFwynRr7KHAHkAcWQwaLo6TMZxPCRsS7Si0o/E2LUpXDJBiU46xXqqyPigxX2zhWSmBldCJA9r3xIihhb++G7Cw6/99obdI50ydplfjZ9d/EMfJsO0MOdsjGZUI1o0lFuGankEpA9vs+6SlyZSHPbJAmwaKtmD7RA4t84b9rUC5u6M5pTm1NIfnJwRugu+ku/oDRXMyZf3BCqMJuDassxUbQUo4kSPOG1jFcNwiecscWpoUWgSUrqf4myMKSw7N3BhPLxT48NjzSBSDxCWKHLajAstx/RZc8dY6kdAoDLi7vMTzh/eT/8AdRGUTkZ0UNf6hDo6V0V6rI5MKQsHnV2+j5g9ZLOyQs2OG04rMk7hNi+YL41RWNaJcwgoVTzxzlKcn9vBDR5/jztx1U6Edmac3Y1Ost7CEZnWzgk4kxBIhoH3AIvnoSZK8MBhqG7r7TDMtK2TgKvbPbTLtmBl4WqkghwFu24Afb7QKXEjK2HbG8PAEo5rF7988yenKHJd7DUaJQ6YkaSYZpQ5bcZFe5OHbAl0IiMrG/JIVFE4lZGveJ6zvw4rMiBbAbQleeWo/ctFMOo5ObXD+PfuwRzDYjPjZ7AcZhi5x6CCk2fYhNJZlUNByN8E29U3Kr0w1v3v2JK6XMrgVvSWwMtjyishpTcUdEY7vsgUigd0zPZXuQZP97m8Z/cN3Ot7QxW7vWEz/oYu/OcDqRWRFj7To0F1waD4U4xciJso9PCtl89oUzoaD24Hy1ZThuMX2lIeshJy87QpzQevW6376yZOMfX0FbIv8xiRx0aE9NclWcYLMMwaKynybj7/117geN/jnXzNKrteSV568ucjiZ4fIxMRJjybyDH6izXfNn+Hja2/G6xiap7hpHG+d/RZpESoTXWZKXV7NplBtH1sZ7FVUFoSP9FisNwHTXb6yPoZYCpCRwH0hT+ZB/84u87UWrpXhypTcgZj+gkdOC843JxhGLlkA3QUjOlE2DGZB7htQLw344dmXAPjt//IeCi+3aHRG1E57rL+5zOadJepWn17oEQ9clnpVis40nWGAFrdCYVEW3FVb5gfLL7L5QJGvzB5ittzhh8bPUrP63O6tMNAOH+v9OJkfIBSsvzjJ8njC2LE+NXfIzJENdvo5Cl8qMf74NtpzSCbL2L2YQ7/aJ6nl+K0feZAX98+hfMXmPXm6BzLeM3ONK90G0bM13C4MpzVpUeHdv8P901d5aWeW3ulJtKM5cPsyh8sb7PO3mHZaVKwBY9aA2WKb5bFxZJjHWd7GThKsm/v4Ru8onpOycY/JqO8+OcOKM006HZMrvc5p60ceV/t1ukMfO5Ck1RyjCYGcHXDv3DJ/d+prZEh67/BZTyr8xo0H2dgpU/uyz9ijN7n+kTnuvOsGbyuco/2RJ7gQTvHxP3onxU9ZyEnLQDotTBSUhPS1dOCB+QLiomCwWMCKNPXPGnRWOYPXgtqFhrVcgH88YT5ocm5fk04vh/1KDr+p0fc1+Z3bf4u/e/EHSX5tEiv6ayKqUQ5G4NGxsDuKLLAZNUxaprAUlqWo+wOKTsRSucooksRD25A4PBCRJB66bI0K2ELRTz1GqSn1+3dMg4awKm+JW6zINMv00KIVFPl85w56qY+WJkn05rDCF4dV0tSiPxeY0YwlCKuCkhdjCYXOpwwnPNyOJr+RoiyDExa5jEZuyGyuzeWgQeL5BtlkmXHQaDvHlUxyZHKDQ6UNdoZ5mq5vFnvX+NE7a3kuhQ6TjQ5zxTaZknRGPlJoHDszibGOSTFVLmSOkbYW/Jick9DJAkLl/EWnk2XGWUtRnZaVp9vMY285bAZFAichTSVpwVQfzu4FFymHgZJUnSETxT4zuQ7TTotE2/xZ7wTrUZlsaKimIgE3FGSuzdVenbI7YjzXo+BG3GiUiSeKBm1tC2SskLEpX2XH5vJOA5FIkjyIxARfdLsB5R2NM4CoLkiLUPBiTuSXiZTNylQFNGwN8kTZDFOTHepWn82syNlwltV+mTgvcCou9paLSFO8puDLK4dpbZQo7ioercj4EbTtMhhaCG1GV6NyTCUY4TkpnT0WYTVHXFJYWrAVFvhq7zYsYZJ7h5lL2QuJyzbK8SHNsCK4HjcoypDttMiNsI5yNFFplxmQYfgI0vw+t2P+mz0wkVDKMUGUMtZ4Xb3rYTBfZViRpHmBdjKe7SyyE+ZprpcRQxPtHFUFFTdhoG1yTsx63VTF3+n47xq9CSEqwK8Bt5m3zo8BF4A/BBaB68D3a61bf/krmKNyeFwf/cUfJfzjCcaf2mHrvjo79yi00Agt0EHGyYPX2JPfoZ0EDFKPl9ZnCK+UkCkGeiB21WWuxl83oojWMcVH3vIk3dTny1cPE/U87C0HZyDwt7WB6bvCzJXzgu4B4/LSoWUaVbWI+fEmZXfEnvwOtlREyiZVFkvDKjujHNvPTbDvdzYJF6us/HjMsak13tU4ywFvnV9ZeyvPX15EbjuUrhiDS2nJJNB2/nGfPzr+G/zbzXfwxReP4605TD2VYPd3CSuO5Or3ODx871meXl5EvFwkLmv23HWTvB1z+vQi/rpFUjahfyKXUq/1yZSg08mhBg4zXxWUT20QT1cYzPj0FiTBw1uMYgfvz8oUbybsHHMZzCt0JWFios1Ou4Bz2oA85955gw9OnqaV5mklOerOgEP+Gl9uH+PZ376TwmpGd84iLoO/bQwjYU3SOQBpI+Ef3fcVTgZX+Z+ufTeXL0/ibdgUr782gzfld5I3+eZx2YwlgzXTjLRHKXY7RDsWqw+X6M8r7rjzCv964U9JtKSnXL7eP8on/ugRM6r68Bb/z4Of4T+vvpWXXtqLFUqc7q4A6qUId3NAMpYjqjgmajrMjCa9INHCxEzL2OTKi1SzfXuA/4ENZgodjpdW8WXCJ2/cyfZGCavp4G+L12LZSAqa/W+5zh2Vm/zJp97Mwuc7bNxfRr5nmyhxGN0oIhNBWk2RfopY9wm2TDdfueD0YPpbPaztLqTmJrj6oXn892+wuV2i8HyA09d4XYVQsPp2uP2265xdm0BeKOA1YfzUCG0Lrn3IpbKvSSNnos22RgVWOmWu/uP/Qnh59S9d8X+FbP4vHL8AfElrfRg4AZwD/hnwNa31AeBru3/+K4+CHXHP2JK5g1dzJAWB9jMjRtFAJujGPs04T6osHJlRDEKyekJSzm49NZ2uxNu28NrgdUxH9wcrz/Lh2nPM1DoE5dAIRaTZa2sB9sjAK/Kru1QTP8XqWQQrFllscby6yl2VZR4sXubuvIFVtpOAujfgaHWDLNCIUWSCB9n1TFtDJq0+VXeI7aW7+0uB0BpnrYu31CRMbIpSULGHyFxK5ulbNkS7F+E0R9gDyU6UJxo6u044444ruSO0vUvqcTS4CtvJsC3zHl6LsdICtO+S5WySnJlQRIlNHNu7llajr3ebEj3c5f9pQ+iRmWHAddIcw8wl270kMgStOEfpekrxXBNnaM6z0IYAJGMjVyaWOCKlLCMOlTapTXdMJJYvjOw5L0gDs73xm6YszQqGzuOvD3DWush2H9kdYY1MNaa04cGNWYoJa0TOivB3NMWbCVvNIheiaW72KrhtiT00N5HMh6hqkzRMB8/tpLi9BKefYA+MfVdocLoJ3vYIZ2uIszPA7ZlAUaUFh/w17gyuY0mFCC2cvjC23m2Nv6XxmoJ+7BkBVE4TjufMdmzoM+x5uG2J0xNIP6VWHZAVslvCJBmb6kIOY/RwBKkJ/EgDOFDZolwekvnsRo2Zh5oOMg4UN5FS47XBb2rszgi7n6B8xVypA8BSr4pCsLe+g29/5037f7OMF0KUgbcAPwKgtY6BWAjxIeCtuz/2ceBR4J/+Va/li4T7C1dY/a4yV95cp3fJp/60w3BcoO8w46Irz82z1FvAHpmT07494W/d9ySJsrg6bLDcq9D/4iSVqymbd9r0HgpZaLT58/4xhsql7I5QZcHSyCFyXdTREeONJhevTDH7RZNB5lRCZuttNk4VmHg+Ynvo8Rl9wrzJyKxEmU+wnIzbpte4r3qdrxYzdCmPNUwJnijy8vhBxt/d5/jYKtNeh+l6h6XIBmGhbEE4XwFg0NX8UvNeHJnx0ePPcm5xkucmFiF0kSMfmQrctuDGp/ZSsA2PPSkrbi+vULMHfMs9aL6HXeWZ7WQcrm6St2LGFnr0M49PJ/eT5OpkvmlSRmOK7154lYIV8Y3GQTZ6BdRTHhPPJQag6NWZzMAKE+KSRS/0UAie3NrL0lqNifEOH5kP6cY+Tj9F9EeEdUGyd0Q38EkDm3BMkz/aYsyL+ZO1u/isPMHB0iY/tOd5fj1+AH2xDJm4hdxyBuYmsTWb8bfv/RZ/Ons7S/YYwZZm/IltRHfA2MtDSssuZ2anyPZo/rB3G7/wzDtwNhzmLsZ4632mPl3hN594H4NpSPeE6LYh1YB5ElpVRbEwopobce3lafZ8NiKqOKzfL8kCRflCjmDLN+pFF+KKYHCtwkvXK5wZ7jdy2x2o9zT9BWi/LSSLJbLjIBKInprms2qa7MAI/59sUow91DBACE20z1xC+UKEEBqnGjJ0XPwll8lnYpQjWX5vnbRQJ6pn6EJKrbGNIwwerF8xrkK3q7FD8K+7fFLdjezZyAJEVdi+u4LyFdOL2/h2wsWtMcL1PMXZLn//0Dc45wz+zy92YA+wBfymEOIE8ALwc8CE1npt92fWgYm/7C8LIX4S+EmAiWmbOWeHn5v+Ctm05GPbP075KmSuR644IExs1FKR4kqKt5Ng9yL682W+r/wCDorlYpknCgf5s9EEuaUe6ZsqPLL/AgAXhhOkysK3UqrekI2gSJhJ7pu/zj+e+jL/d+t7aH11AS0hH8TU/QHNHvjXdihWJgjH3VtftJYwmLFIShnDcZeqPUB4CuXbiCSjcjnB7dgsvblKhqBsD2kEfVa9MlqYkMKoapuqYqR4oTXP3dUl3ls8zRF/lbwd04l9OnHAIHYZfGOc8VMj+nMe7f0S7Smm3DYVa4h4zcWkMZp1SzHu9Zj3dnh7znz2z8wdZ9As3LopqFzG3fnrLDrbvKlwga20xM+/+FFy19uIYYju9hG+hxqvIrM87cQm05KtXh57xWPLLtGb8YkyGyfKIElIc5p6tc9WbBHFDkk95fj4KgDPLi+QRDYHj27ypvwF/rRwgo5VvjXzFRrsSCEjjV+O+NHKCygEv37gTWS+y5hjQZzg3NzB3nJRrQYJ8Gp/hvKLLrlNhbs1QPSHlJ8fUgbW3zOLPjGkFVu4fbM/nti7zXfPnubO4DpH3RbfE/4YyjZONDE3pF4c0W3XEZkwFcfuGM9tSuwQKpcynF56i0PYW/S4a2GJbuxzbatO3PGonrMJmhn9u4f89oE/4g+7R/m1Sw8iXUUxZxb5a0c+iEncjHTVIVjqkFZzDPYIijNd3jS1xLHCCptxiY2ohC3VLWOOtkx16DcBXNPg8zVJRXHg8Ap1f4AtM2O6Gbp4WxbRuM0d/hJ5EX/Hhfzf3LMLIe4BngYe0lo/I4T4BaAL/KzWuvJtP9fSWlf/qtfyZ+f07N//hyT1FCuf4L+cY+rpEe19Pq13jHCcjGgzhzWQlC5DcSWledhhcMcIx0sZL/cZxA7D5xrkNjSd/WDND4ibPrklG+VCOJOAo7CahmgSzyTMzezQGfl0d/KmWeJl6ExSe8KldmbIxv151FvapKlF2PbNE2l3vylyGbafkK3mqJw3Cj6/lZH5grXvjnnr/ktsRQXaYcBGu4i6kecW5FMY9LIIUixH4XoJ9cKQt0xcxhKKF9tz7IxyrF5rEKzat3T8ytGkJYWW2oxgUnELlqh8hV2KKRZG/M09p2jYPf5o9R6ubdWwzxSYeC5mMOWwdV+GVY45OrNOxR3y+KkjlC5Y2EPTCIpKgvZhI5ktTvaoBCE312pY6y7pWMKxfSvcaFXxP1fGbys2TkqyuRDddPF2LNK8Rk2FqNiieNbFHmjaD0a86cBlnr6+B+eVPPbQiIus2KgRhYKVj8V88oFf4Ww0xTc6h3lqdZHyb5fILw+NvdOSrD0YkN3TI+x5eDedW7BFwNiArd2yODTjzLiWoXMZDxy+wtHiGqfac1xv1+hcrjL5lGY4YdH4nmXq/oAznztM/UxKf8YyVmFHk+bMNlLGAplCYRn8pmL9AcEHH34eT6YoLeimPk+vLjIaueyf3OJ4ZZVUmdy+dhKw1KuRKIkj1a3UHik0S9tVuGz6I0lFoV1FUB1RyoUmHVYLbCuj5EasdMqU/6BI8VKPnTtL9BYEWppO/mt6/ixQHD2+xB2Vm/zu0w/QeMaiux8OPHSdp//O79M8t/V/Wi57E7iptX5m98+fxOzPN4QQU1rrNSHEFLD533ohd2XAvn/+IunJIwymfdxegkgUdqhRTY+olLDv8CpFJ+S03IfIbPKrito5m7DmsX60QBZo1GRKOA3WQMKlPOMXoP5n56BeYe3dU8QlcHtm5p00XbavTRHui/hfHvosG0mZX3n07QSrFjLRRA2PwaziR/adItEWS6MarSjHK0vT6I6Ld83Da3rEZWgdz3A6kslnwOkr7Bs+31AHsd0U182wLIWaHSEsRa1kWGGrVxt413zsAbhdzeqBInvmn2LSaXOpP05bBMzs2YY9sLZVxr7u428Lxr+SIJRm9cGA0VSGjCTWENy2jXXNZlAK+HLuCIfKm9xdW+LNY5f53fNvx3/sDLlKmfK1aUZjHmfetoA/McAbHxKOQdT3kG0bMRHy83d/noo15F9deB/LSw1EaLY5RJKL62NkiUV0EHqRhXIUuuliD6SRuMYC2gFOHyaf6GDt9MiCWR5nP/QcRE7vVkoZdpgZk4gjyTLJVpbnqLfGu6dW+ET+CL+28H60eF0tU76mUEt5huOS7pEUqxRz78IN5nItZt0WNbvPz3/rezjwmynNIwF7H7nM7aUVJJpI27x4fpHqKZuKhqgiGI2Z8WLZGnF+cJj8tQ5xqcpgWpB5GlVJcPyUhfEmjsy49OwCaIkqJcx7TfZ6m7zJ38AXFkxDqDP+5/VH+Ozl45yYXuFnp77KclLnE9H9dCMf305wrYySE1JyQm6vrFA6HHJ9VOex54/ibtokrSJbdgHtabSrGJtu8z8ufoFnhvv4wvBtiIvXcQ4dR3/bCnW6guqljNQTdA/67PG2kENJ5WqIUD7n8gsMhv7/78L7713sWut1IcSyEOKQ1voC8AhwdvefjwH/evffn/lvvdbu65HmLOKSGd8keQOeEJURpeKIA6UtinbIS95eEOJWSSV2cc8iFUiMmERGxtKobA3T42R514AQh8KIHzR4LY2/DVbk8S/d96EzQbBq4Xb5CzNJiWY1rPD41X1ksYWwFKIcE8ceQknikoZyQiId+tMWMoG4nlEpD+l2A4bbgYnfzQSppxjuEnJEIpGRMTiYDHTBUlwn1M6tdNqSF1JyQ1Y3KuRXwQo1g0kXZQuimvm9WWihYolsSfxtcPqCa2enuJofR7oGwOkAvfefIMlL+jOmcWX3NPGwaM6dBjc1jLVYefzHy2+l4JnSszLeo71Wwm4KRGaR6uBWdaNcTZZX4GdkqYNt7aoF+0bXLsMUMoWMQA9t41EvKWP3LDiIzHm9aukLfvbFH+SB2ev8m5k/54C3Tu9ExHDCpXgdgqbBZ9kjA690yhGV0pCiE+LLhDG7y5yzw97FTW6+bZZwKuM9hU3GnS7RbqdO5lLismN05yWFqsf4MkEhCMc03SMVE2c1mRgjT9shyUumFjtMeD3OjU0z6hv32de3D/G43McndlVwc7kWORlzpjlFHNoMU/cWJBSMU21lq4Ia2Vi7Zpv5aovvnnyJrbiI05L424L+okLX4910YEmmBF3l44iMnWM2iGNoCcWrZjynXGN0Qpum8yhxWEsqpnrM2yRFga5FYP3/n+L6s8DvCiFc4Crwo5hO/h8JIX4cuAF8/3/PCwnLYjRm0581kHYtJPFYyom5VebzTT5QeYmSDPmj/D23/Ie7FmhkKtCJxhrI3YVvFlEaCFonqqBNPpk9NMH1WkL5Wohz5gZ1IRCehw48wkVJmjcqOnZvJgBnmpPUP+8jU9j4QMSh2Q2W8lUGlQC/GDFfa9EKA7apQQb7D6xxR/Umn3zuHsaee32wEZdtekUfVYiwh2YU91ppLyPBMzuL1LwhzTBHqiRz+RZ3FpZ4Jt7HxLdaJI0cy+/0zM1kqst4oU8rDBiELkmvRO38CDlMmHjG+EKNbVOw9C6Y/AdXmA463FW4wUuDeb7xO/dSOxdjhxkyyojLLmHNRmiwnqgyLEqsH9zkI/uf4xc7byfYstFCgLDIXIjqmszTePURjdKAFV1D9VycHpSvJTi95Baz3+1p3G2LuJaRnx0wVe7ywzNPMWmbrvFQe/yz3/9h9vyrNk9/9HaGP/0l3hb0efTtv8D5uMpPf+7H8Z4z4zG3ncCize2zK8zm2ngyRaLZ625ywoVPHPw9tvbbKC2IkYTaYTWp4oiU8XqX9UWH0lSPH9r7Ip5MUFrSSQPk0R4rYzmKUy3uG9vgxZuzBE8UiKqSux5a4t35sywfqvJifhZ6LuefX8BrSmrnzRf48mGLuGzIxtrRtMPg1veeKskgdCk9HVC+khDWPaJKwLk7Av7ZwhdYiyuUr0DpRkj3qMVbD17i1Z1JttbKJJnF1XgcR2Tsf98Vlt9UxvpknfHPXIRqmWSihPIsoqpN5kK373O6O2Oy9sZtBjOae/be4FEv+o5r779rsWutXwLu+Uv+1yP/PX//LxxK4Qw1Tg+yQJDkzUip5I4o7DoxQu1geRlJ0cWKMcC9WGKPzJOTW4v/9aC7JPda8IC5R5jKAYorNlZ/ANmuuKOQx5osozzJqGaTFCCrJPi7vHYTCbx7cqQijmxE3yJ2bRQC18oQ5RitBKmSrIVlRCJvzWL1ridbZ6Zk1cLcmYXEVCoZXNuqs+EXKQchtWDImNs3zTgvQxVckqJNXM8IGkOmSl0afp/mKMeo7+GmEJccbFfungeNiBUiUyhPc7CwScPpU7P6eDLFHmncTgxKfxtQcvccFSRxQVCUhrAihJGmWpERuaQBhA0Dr7BthWenCGlOvtDGiy1TZfDgWuOMFF7LQjkWcdUmSm18mVCSITUrJNNGBajjGJnAVuaSEzE5IRi3+oZOWzUVTeZK4grM5trMe00yBM7uHXOoEorSpmE53ExHfGV4kFaaZyWq0Et9ml2Dpw4jh+2kgNKCpUGNXuIRR0aElWWSbuybLnrFRIqN2T0qUrE3t81Grcj1YQO3Za67JGcivJVtrjErEjASrG5X+IPGfWxHBa5uNEi6Lo6EuGwRFwRJ3vz8+WiaK0MTGy1jBa5gPmjyKpPIvs0oZzzzORlTckfUci5ND4Rtk1Xy9Od8c152Jy5J1+PVjUlkAlFZoBxFJwpuMQ/+suONx1JFEcUnrlF6KUfr5CTbdxr13ITXo2yPeGpwgEjZNKo9Nu8U6NM+tdND7J4NOkfqC0ZjkjR43XSS+Sa2J/MhnEgRuYx79l/n9tIKv8fbWXhUoC0LYdvgmZTUzJVsPRLzfbefYsrtsNfbZCrf5drYhNG3K8HWMI91Ls/0CwnNwwHLboVSPuShfVdQWvLkxX3c3JjGDQWD6dc/Y+aBTgXRyEEXFCNhbgYiNVnl9T8OCMt5ah+7zI9MPUFeRuRFzNH5Na4+soeoofjek89yPH+TogyxhOJ/uPI3qD/mEVUFy++y0I5EW6as8zeMCzCZDZFCsxJVeLazyIXtcYobGdZ2j3CxxmjMIK8yx3gPph9ZZjbfppd4fH37EADDSU3xBtRfaBJNFGgdt3HHhuS8mEx924WkTcKPyDS6EKC1pni5R+GKoHegSHOY52bd55flW5krtPjI2DMs2C3S6Zjum/cQ1TWf7d5JwzbI7KFy2bu4yWq5zCATKCXZP7nFD9eepCJjQm2RaMmOyvFYWGXS6rBgj/h073b+05+/C7clzRw7hWLfVHfh9QKfv3ESK4TiNXMjzzcMbTbdKnExV4TJiA996GkW/R1O+kv4QvJD1Wd4f/klfrz1MWoXbLoLFpUfW2Yq12VjVKQfe2w9OcXYyyk84/Bidhcy1SyMUpIcLL0/w3/PDlU3Ju/EbA4K/Otn3ovcdphrm6CSQmXEu4qv8MnwDuovCnp7ctzYV6fmDlgZVGgOckQTgvabF9m4V/L973iCjajEY1cOoNou9edscpt5do5KusdjiCVXX5hj1Pf4TscbvtjRmmzD9PK8Aw1k7KCVoGBFOCLjatSgkwRYUhEUIlLfR9smusntpsjEIqyZPTva7IO1MHfczNPIYkKuEHGycp2H8+f5eOltYFlIy0KUiujAI/MkmSuYmGjzw7WnaCufZlYwrHkPQKCVIIwd3C74q0O88RL9oUvopkx4RhNAzybYELdCB020kkY7wGv0GHYFMQJ0YPba+aUhTs1Hacmk3aGnfHZUHlemxvZZTbircIPj3sqtMlXFFvmNlDTnQCPC81MCL0ZrQUeXUY7E9lJGmUMzyXOjW6XTyVEdKkSUoBxJkhe3zlnmwcnaDQ4G63y1eZSdMI+QoHyztRLdAXbeRUsL21akmWSIg46NQUNoTLzVa5eRAmfbJNZ6dR97YM7zVs+c151agUmra95jzUXZcKE/wbpTomSbbcBE0CPvxIxSh1HisFBo4u8SdjyRochYSj2W4zqOlzLNiLW4TLBmsOJ2qJG7yGyZmEpGC4kz0FQvDI10VxQItUQogUwE8QS8vXyWObuNg2agNTkBvjVEKYHXShFzFo+Mn+eAt8FX28dYGlbZ0mD3M9xWiFzahF3UttOoQbHEO6Yv4MsETyZ8LTvMVrOB1zR8PITAlgpfpMSRw9h2Slh36KUenkwJU5s4tchcI7vVkyE/U3+SC0mZC+1x1lQZr+ORv96jva+KlUvJYhe3bYRS3+l44xf7tx25s+vM9xusvjnHkYdWUFrySy+8g+CmbZBBFqRVxYWfyuFu2sx+PTbUkpLNaFJhVcUtZZI9NI2nNA6IHZ//tP4Ivxy8lfKSgH1ztI9UWHtPgrA09qqLSGDejXkpnOXp3n6eWZ+n1SyQtzF7/zWXbsuhAPQOmHCFyjMuUcXjT4cnkJaidNGiciXZzZeTDGYE3NZHKYF9LY8zEAQbGr+t2bgP3v7gKzyzNs92q4LI4MaZRT6y8reRNwKCdWO2md1MaR722LinzDF3lSvJGOtp2fDaULhdjXs5IC4rakcHVP0R7WYeNXBJ2z5/dvk24rZH4bJDra1xW32056Btc0P025r8SkR+3eZL6w/xmapg37uv8tHZZ/jV5E1sbZnJQ/fkDKknCNYkSauEaAn0EKaaimArorPH5fpHNLanUEqiEkntiQb1l326Cy79fUaSPJYzgR2f2bqDz4vbSQYOUU0QbMK5Pz5MVNPMPLjC3uIODa/PlN/hU8/cw9Rjkmfrk3zw0AlELeIn73icE8ESX+8e5WJ3nDfVfQ472yz62/SPxgy7NnZfIGN5K8c8t6mZeHaATDJEYmSzzlCTObuQz319Sl7CL954B46VkbNjUiV58cIi3qpD9YrG3W5Tvmbxy4+9A21pCpdt3K4mPqrY+rsj0pcqLH5GI/oj6PRBCixHMeF0jdIOwd7iDu3DARsbZaILNn4zoX+hyk/Kj+K+kiO40aRQrPDq5iTV3IhmL080cqjehMbpPsPJIr9w7M0MMo9h7GA5GRsnBa2DVbwWND7vE9Yl/XmF+itSm/8vXezp8k3E8k3yex9gxm7RUwHFyzaNV2LCqk1cEOycVPzt+77Jp5dOwNeLWMOENOdBNSZNJKQCu2XjtYVRavXNa+dvGnih31TEjTytQ5JffvMnAPi/nfleeq0cgZ2wFDc4vTNN62oNayR2n87gtU3kMsBwTOK1FbXzMWHNYaMckLqa4kpGsNTDLfvEZYfhpMOxyTV6sc/SqwWCTQOU9Nf6bNxb5e+Of50x9yR/MvcQbleQv2EhruaYeHaEfeoiwrLAdci8/XSygBjJalJlKaohYvNe7JEity4RqcS1Msb8PpaXmdy4oSQd5shtScZejHD6CXIQgWVUfdoS2GGGs9bGjRJyTw/QMxOMHnF4Z/4yn8nfwRYN0rymO2camG7blMblqzHe5gjZG0KnjzWzn4/d+RQnckt0M5/ttMR/Xn83xWWfqC7IjQ/IeQkFx4g8Lu2MEcYOIrJIc9oEdDzTYrhQYuO2IhNBjwmvS80eEKzYFP/4GapTE5TvmKE75/Pc4gINu8fVfoMbzSqLBSNoGrO7zM3s0KoGDDomhktEEhkLgm2BdeYqQgiYmUDbLlakcEZGUHPP9CrrgxKXVsZBCaSjUIlk4lGL2vOboBQizQjWHWov5UHB2HNNZKtP8+QUv3rid/ix7GMk3/RxtEb2h2ghsOyMojW6Fewx4Xa5d/wGz4l5ktw4XttEand1ncZ1hdjYwZspsN4JSFOLOLTRkUWwo5BXV/6/3P13lG3ZWd4L/+ZceedQuepUnZxP526pg2IrCwkFMNGAscEYHIb9OeHr73J9nYd9be41vtiIdG1AWBISEpJaAalzq1ud08mhTuW4894rz/n9MauPMB/CGthcS8wxzhg9zumqXXvVftea832f5/dQXDvG17YOYEtFmpudFgf6KCWQXynRfHyN3m3TdE/qby+U9B+1yisxP/rkjwNQb2mUI9g9LdBHhszWBqzFNSp+xNI7mtgjD5kabndSV6hqinLN1yhfEDdNk0k7Gm1pvF2L0YRHPJFzJZkg1RZJYptoJDth2ulwsLpDa7ZA2PVxhq5xQ81lyGKKfd2nsC5IyoLOQY+sIFCuMljgWYvMq5lxX2SAklujMkoL4smc3Je4PQd7ZBxx0d7QNPcgKWuSmRQryFhqBBRuvhllmxvNcJ9i3t1FaclmWmE1rOHP91l6d8mAMtrGa36mvsbJwhqPqMO4PUk0lTE212HHr5G/YpH7Ftv3l0gairyoEEFEt+fg3TxNsKWZ+uo2SLi8NMG/qLyNS1vjiMwIP9L5FD2wqb9kAiLSkkXuF7HiAlZUJy3CZ5ZO80ThIImySHOLdDxl5c2O0b4PPSxLcbq2RmClnHWmaEVFrnc9QDLYB4N9ht8uXqjyrFPhuWMD9o+1SMua6L23k/mCuGZQ0ue2JuknPq2wgBBwtj3Fv8zfSZg7OFaOY+VYGy5exzR980CbDPjTBwHIyg5aCuxRjtPLqJ/1eS49gj0SVLcESRn8e3aYLvd59U1zdI5OGD7cAJIKhPtTRCSpLJfw48xQi4DpWo/tW+YItlwaSYZ2bdLE5nI0yeXhOMv9Gu1BgXC7gDWSFMYFacnF6WnqLbBjTXJ6H90DDpOTW4wXhjeOMVu3T5KUjtE5ASeCEVvDEtGlKiKDbC6mUIpp3ZIznJlDuaZRyx8QIP3h9W1R7N65VRZ+ZY7ck0BG7ksad2zx6dP/iS8MF/jE5h1MBn3e8Z7fZzWu8ZXfuZPG+Zydmy3yyYzUt8g9SVbQWIcHNIohY4UhBTvh0u44nZ0SxXrIhdEUw8wjjU2xl+2YQ+4WUdXBkzmvFKdobUygBdx84jp31K/zK8l9FNZdkqogrmsDzHDNGXywXzGcFZRWJJXrpou/0y/iuynVuS7xpM1wp4LXddGuItJ76a2BQgXwjjOvcm/lEtdOTbCZVAhkQsWOaNhDTnmr5AhWoxorgxrv2n+Ot958lv+8eQ/PPnaMrJrzztrLnHF3+Ff6HXi7kB5N+GuHv8ovO28gKU2SBYIPfM9j/J2xJ3k5LbCYjKGQ5Fryq9fvITlfw2mFFC56PBDdZNR6iUDOhvytm3+fxzpHuPD0CYLtlMGcS1x9TffgkAcQv9KkJ5tm+mBrpk5t85bbLvHI5mHWroyTBilvr77KlNXjy/ZJrodjrOzUAIfscMjfvOUrfGb9ZtTPjeFe32Hp++a5cMyHWs7Se8yY0h5gMGCLZS45JUQ9ISgmLG/WuX55AlHMOLpvE8/J0MuC6mJK+4jDcE6T1GD3psIN951MofHyCGt1h8lWjcbZAtYowdpoEx2fpvneXf7S1CP0ZwKGyuXl0T5eaM/R9Ie8oX6JV4ezPPPsrbgtH7lX7Lc1lvn0XXVGywXK14vITKFGNhcHE7ywPIdaKRBsCRbOpqRF2LpDkweK2Qeh8vwGo2MT7Jzx6R9QfN/UJeY9g4JOtc1XguNcPdFgrjhiOuiy2K7TfMn0JlZrNl59wFvvfJ63VV/lt7ZezzNPHLvxXv+o9W1R7DqKcHdGqMAhqZlgh421Ov/b2P20kgJh5uBbKQWZ0HSGhDM5ncwimkmZrffZAqKhZT4UbZ+o77Hjl7AsRZYaImyaWlzujxPnNjo3XeWr/SYPuDdxqT/OldYY/V6AmwmwNGuDCq/YM5BKg7BW4PbMVvg151pW0OhCzkBaRA2baCrjRLNFqiwuX5nC6ll4EWSBBCenIGMDzBBAJnilNU03DZB7g/7FpMHOqEjVj2iNFSlYMYGVMlfq8Gp3mie2DtDqFVGe+f//4+qbqbkjVGoRTmp8P6WVlxgmDsXQsK57WUBLKT62+zoeXzvAvlqHextXsIRmMOPiB0ZgxJJ9Q8AUrQV8pHQv7VaJ2Y7CDnNT0HsyVZlosoIgrZu/L163sWJB/6BPwUrItcAaSpLYfLw8kVO1QmrOiPF6n40Zm/HqEKUlZTfi2qmAwsQsuY9R8e05/JSjSALDp/O2jJBp5NlQNAWvCwmVQsTB8i5bTokLwSS5J7FijduWyAwTrb0X+iEziMcL+FkDbUtknKFcm/zgJKMJh2GvzleKpzjqbzDrtBlzBjT9Ia7MWIzG2ImLDKcFIi+jRhn/Zu0d7EZF/CChX/aIx1xkrJFDi3Pbk6jVgPKiwO2bhqEWkFUznErC7skiUXWGtCRIS6Atzfn+JJ2swKTbw5cpUigcK6c1LPBo9xBh3yPbb96XPdC0F+t8YRDwXH0fw9iFmQjt/veLav5UV97tIc5HWJUK3L4fZQlmH7B4+XM3s3PaonDnDp6VkSOYdjt88J6n6dxZ4EBhhwPeNi9MzPNE/QCbu1WqTwaGKpObD29vv2S0kJJ0Pc51Zv+r1716aYqrF6fwtm2Ka5qqLUgqmGPExSbbXh27b5FUwGtD7bKxZqaBICsIdm9X1KZ73DtzjQ82nsEXKWWZ8Dvd2+n9+hz1c30GC0WihsSrjJixYsacPlponFDSemKKtpoinMsIxkakl8tMPq1o1yS/fuc0fjPk+48+y3vrL/A3fvfHOPqRHcStBdbfmUJssfWR/bSHGnE/TN65QcmN+XrnAK2tCuMrI7KSy7M7c3w6uIkHP3k7Cx9fZ+XtB/jChzzC1GH3dRqnazP5TEZhZUha9UkrFtaLGud3AsaTBNlpgxDIAz7aFlg9TWEnJ2ra3HvTRTbDMvEXpyld7HD+cB0OQz/08bcFw8A1mgmhmXd2KcqYuYUWo30e/dznSjTOhD/A/pEL9BKflQtzuNsWaV0hKxnlYsSZiTUudcbRXxunvBSzVPRhHG6bXuZHJx6nKBIKMuXleJafmzLHGa+rKW4owoZkNC3ICpp0zIgnlO3gz9YorWcEqwMGhypsvE6aG+jFMT5+rcn9d7zCj40/yrTTplUoshrW+OLScfJc4r6+RQJ4LzRYeuQI7ZOC/a9fRmtB63gNZwCFNdCbNeZeTCk8fQnqVeJ9ddKCYN/+He6buML8zbs07AG/unIfF88aYOTz5/YjgpzTC2tMB12GqRmjDa5Vmfg6yHnJ3R96kcBKePg37mTi+QQZKmTs0XlXnb/9o5/m3xZb37TOvi2KHa3RcQxxjLKNzNPr5LjtGGd/GdfOkUKzk5b37niaoh3j7QlhpNBYQqOV8bf7rdzQbfYA+sLPTdRQaEZF2jZPRhmZbasV/QHQgmX+/YYsFyMXBXPe05YgLVgoC0SQMVEacLq4wt1eSEslXM8K7CYl7Eghw5S0IAnHBJVihL/X8DMSWsMoFznIUJLEDk4kcAbmNeyeRWR7rER1pt0GTk/C5jZ21MAJUlIt8LrgtRJE5lNwzBx8NyoiIguRZMjEIk5tunmAMwS2dnH7k3RDn0xJdKDI94Iw5CBGFlzAMiKmXozIc5ASHNskmu5N2l4j40x6PZQWXC1K8pKHthUSjZQmugoluBBNk2tJJy8QaYdYOaTaYpB7rIVVlDZjKFfmBuYpQTsK30+pBhHTfo9WUGTTNdp6LUEITaYs+iqgo4v0lc+ro1kTBZ6Z9NUs4BudaQkyyBAS8sDZ67sI87kTZjSqhdGeIwX9zMNC082LXB81WBtU6b9momqOcKwcmYDXU8jYxrMzAjelU9FoYcxScmRCKUQQkFcLhBMOSVWgEof1uMobyxd4ndfmy8UOF/XcntTaiLDizIBTPDuj7CW0pdEIWAn0M49YWbg9jbM1QAxC9GiE06/jiPzGLvGPWt8exf7ach1GExbRmMAOLdw2pGV449QVWkmRT125iThyUR3XRP1MRsyOddjqlYg2i3hbFtVLQ2SSsfS+Am+75SxSKCyhudCd4OrVSaN2i6WBGWR73fb5jORMglICFdpGPmuZc7lKBeQCt2NjRzlx3WH3JkE2nvDuk2e5v3qWQ842KYpP9U/xb556O1bbpjwuie9u0HlryP2HL/CW6nnK0qWdFSkuS5yB8UtnJWXEMX0H6WtaJ02gotsGp+fyyPpNPGzdRGlLM7rnKDunbN504AqroyorR/YT7FiIFC5vjKNSiU4lwZqFyMzdS+/B5voHFJ33nGQwKxnulI0EMTd8tLBhY81V6c27jKYEQtnIbK8R2jHCnXBCkAd7MuQ/kKRysrzOyo/U2Ah93jp1jrK1F1t8rACxxUe+dL9RFU7E+EHCqBsgBq/dNYyZqXrF3ECsU5psPmJhss2dYyYuaczpQxXOvnma3Y6LHDPCoScvHeTpx4/jdAW1KwpnqDiwMUAkGdffVyd43S7t1RrVV22EEliHMnw3pV/0sUKDbxK5JthKGHveN01de096HRlTzm8t3cHoS5NYkWayZ+b2mWdot04Jds7YRLMpvpUyVhjSORgwGrqUzrl4Hc3G61yiD0/jVmOOTS0SdauoB8Y4O2jyH/5igdcd/BRLgzrFZZNvGE1lCC83Nw8r5Q3NS0zaXf6zdTeL0RxuB5Z//ghuXzF+3TAAdDFAjVWxYs3/8erbWI4uf9Py+vYqdiHJXXO+Uo4wWVuOZtLp0UkDRq0Csm/h70qsBEbCZ01USfsuTlfi9Pdie4Cx2S5/f+qLXEqbnI+naSUFrloT6Ewjc4HIjXRVAKKYcWJ2g37isbpTuxGWCKDY2w2YMTfKFmTNlMZYn1tKS9ziGU93K4dzo2n8RRd7ZFj2SU1weGqbDzaeY5/dAWxGuWv0++FeZFQ1hT08lrI1SVWYD34EMoLCpjknawmDaZt4THG0uIEjc66V9+89zTRpz0WkhjrqjF67nkbSmyoLVcwZThlziBhZ5gYjTLRTVhDENZukKkir5imnLZPWoi3D8VN7oERDzdmDKCIpWREfmH0RMLFWOcJIn2shg90CxWVDyxlkPqOKg9OycLti7/uA24PGq0NkqugeLeGVYiYKfea9lrlRoyhbEZMTXXolH9tShiTTdqidg+JWSuHri+jRCBH4iCAgLdf43vlX+Vh0GzIrITOj0vScjJ5tOIOvRU9bUUZhy4iO4qrZObwmOW31ikxey7BCZWg32nDslCVpnfRIpjQiMBHbtlRUSxF9qUGayKt4MufuU5c5WNzhLeWzfCy4iwvXKxQWeyx/bxWAYeri9M2OAEsj93adCsG43eeou8nB8g6XG1M4PYfa0+uorR0oFsFzUUWftGGcbtFmkTz9r7n6f3B9WxW7Hg6ZeKZPWvXoHnBZfVMRmcEvfvadJoo43su38jV5YLZdolNE7CXDhBOaq99XR3nw/umnyBH8i6vvZuvhGdKyxpoPwRfoxEMmUFgT+C3FZs3muyde4PnBAovXJrD6Fm5HfkOsE5rOVeeIT1oUWB1BS1QYHPApCPjhiz/I2iNzZAVNtpAg3ZygmCCF5vJz+/jbX/yLJLcO+Ie3fJ5eFtC+JQMtOHV8mcPlbRJlE+c2jy4exH62ZFBHxxMQULrg4u9odm/WzJ/Y4GS5RdUKSZVlvPUdhd8GoSVhQxI3zbXsnayTu4LoYsBHt15H+YJDeSUn2xEkm5KkJhidiHAbKWohJZSK3moNf8Pkw+VSYIWCxrkUtxWhAhtlS1onPNbeBFQiXtid4/HkIJ1Xmzh9QTRlAiaFND5up5QQ3b3nIxi4kAo4OKRaG9ALfcJuQDSyyL2iSUcJFINOwHNXjnB25xhpSZNMpZBJSldsnAh6d0bcsn+Zl+MGjXND4rrH0l88Qu6bG5e2QM9FPLlzAK2hfwCUoxChSxQ5yD29QloQxJOlvehoQVqSbN8OjEe8e+waZZlw/8GLfOEDp7DXXGYeE1iRIm7YZJ6hydTPQbrkc/7CEbQD2V6wJyVN76BAVBMU4kak9YLf4qF7bNwTTW4de4UUTaaMqSsta+49cwlH5jxy+TCvdBd4wD+NdHPsJZ+pVzRpQXPpJ2fJ/RlUKUd4Obab43oRw7bAX3Zv6DH+qPVtVexqNIJnXsH1fbJTt5HePMB+pcT+z0VkRZvOQYesYMwZeaAprEkKGyayeTiryKs5p46ssL/Y4q3VswAsXZjkxG8s071jhtbhDMfO6bdcRC4obijKV/ps3VnmPcXLpNrigdGtuC1JeUnj9XK8TordjRkcLLN7ykLZYA8kKBM8WZAW11+Y4fA/+zrRO28l/qttDlV3uaO6yCD3+fRn3kLj155g+6fu5sH9JwA4cXSVkhPzo1OPc9zZufH+f2b0fWyOTLHvX9im6CRcWtuP14aJIzt8/uTHWM8Tno1nybTECsHtKQqLPeROG/+mfex65hjQmzdpqqUlENdsSusZ/k5ins62pD/vkdySsdBs83f3P8DrvCHvcn6Q9vUpQJC7GiuGwvlNsuvLSPaAhcfv5rZbrtCOCyzv1Mh2Ag5+IcZb3KVzxxS9hYB4TJNNx5SrId978HlyLfnNc3eQ7QacnlnnZ2a/ylPDw3xh/STDxKFbK5gjSGgjBjZjz0PjixfQc5Ns31FF5NB4tY9McronShwo7vJqdhjr/HXE644w9tY1TtfXUQhyLTjXnuL6bh2lBHouBCXIIwtSiZObHUrmQ9ywDXk2UqSBYPz4NvdOXuXu0iV8kfPhxtPcdNcyv754N+nzTYTaI74GwgiqNr6BpM5KDr19DllRMNinyasplZKBU7zG9Ztx2/inOoShy5nyKonW5MocKbOC5ienHqKvfB575PReHJhEKIfycoL/4hKDew5w+19+mfc3nueMu0NDfqN8/8bK23jm5ZvYa2P9kevbqthfWzpXVK5nZIUSweZreGeLzk0ZOIrCZRdvEfy2wutkWIlttmGJYG2ygtKCz+hbqTkh2lXsvmGWuCLJLpVJXI0u5SQTiq3bbNpHqmgv40cu/QDLuzX8TYMoGswJ+rZtuvoqIBpXePu7xN2AxpOm83P9TQ0A8noGt56gu+BwoNgjURb/7rm3oFseB64nIATVaymPPXSabDzl7uNXmA06pNpmOw+ItEOkHZZadcavZwwyi8BOmfT7XLQwKOWLY7xDfj+jxGEw9Ek7HlO7xoiyc2edtNy44bizI43XMe621xJ10oIkXfBNr2LP9ea8VGKxWOQnVn+UQikmXCpTyCH1NMxEjAKX4alJ/PEqyrVQjjnePPfCIWQicLoSO4fN2y3EbbN7x6+9X2LPoS/gbH+aTEvUcpHShuAFdZC/sTOBY+X4booltclncyyi0EYmgrguCe84yGDapn3KPC2Hs2Vkavz5n3zqDlwBqz96iuG84vsnrnDY36SfB/RznwdbR7HOF1EVhZ7cs3xKDbZC25bBcgeCpLjnVixLojHBzbUdbitdZ9zq4wh4MVzgkyu3sLlaZ0aYc76zh4DWEuKGh5UoA4C0BXHDNAadocAObZK6zb6gzbTbwRE5jsgJ3JQktTk7mOETIme8OODcvWUcP+MfX3sfaW6RNVJap78xCh1NeVTGDzGckVzujfNl6zTN+lOUnZh/tn0vn792ktFWkQr8sQjZb89iz1JKT1yj/HKRvFokbfgMpyU/fd+XsdB89PF3MvHVVcgVaI03XsMJi4zGLXYnygxDjwvJJCqTyGJG+30x6nqR2Ycz0qLFxvszDk7vcOq2dQ752/yfL76F/q/N0khBZjlJSTJ4e8SRmS0WSi1mvC4HvC1u95f5l+vvZOMjB7C3e1z4nkmsGcHMbIu1N0wxOJRzW22ZJ1sH2P/rEu+5C+gwRAmJ/+hZjnzdo/v2Y8ze2uH1pSsk2mIxHWMjq9LOisRLJYpPXsK67QA1N+RQYZtHbFOc049p3M/WcYG6BqEyZJyTFWzab4v4yzc/wkdeuZfgayXcnqZ2totIc/KKT+7btI57DOeMNdOKwdvVLHx6FzEYmQhj22Jwskh3vxEnvenQZdaGVRbb+3C7ZdKKJvegvKg5+MkUkWlEphjN+tg/ucl7Z17mP1++i3CpgjWS+FsWSSR5pTJFktg0X4baxQH5czaZX6B10iF6Y4uil1CtRKS5xfXdACsUDGc0wzmbbCrhPadeoekOKFkR3azA7370DRz+6IArf67Kz/70R9nv7HDCTbAQXM1gLavyqytv5eDn++zcXKI1JpC2RtoKLQV5oNDCoL7Qe70HD8JJxXc1X+TdxTVSrUg1PLJ7hN0npqj0QUuFcgV+K0PkmmjMIZyR+B2JPTRCsNG0QvmK6nkbf1ezfcDmttJ1atYQX6RmNOvFxKnNcxtzPLcxx9v2XeDn3/pxfn7rfh776G0gYObtG9wzce1GPVzoT3Jpa5w8FyxuNFlrV7ntzCJz9iKffOh1HP+/1oj3e2zfYt8I//ij1rdlsaO1yTID8pkancMu4YQmVTYjbRHXBMlCE3KTnR5O+vQWLOI6FBshJT9mc6WO1bXRjiZxFYWOGZ0p2zjalBZc7E1wdTBGHtmETWOgsFJNWhB4fkrJiUmUzW5apGBV2cjbdJICMsoQw5DrV+f5h8372GpVcAqmqXU9bLIzKlLUgCWRtSpSCHS9QtooMJiWSKFvqOlyLTg3nOZybxx7KBDlEsoSXGqPkyiL3NOEExKZSrwWZkJgCxCStGiTBYK8r/n9zRNk2wFeRyNzCOdKBiHdS7BGKWnFJ5mNIbSwB5aZRGgNuSKdaZCVHaK6CcDQrsKVGXV/xMWZlLTyjacMWiCjHO1K4jGPuCxp9Uo86h2hv1XC3zHHBzNKgiyzyDLL+OjTHF1wDHUlgs5qhY6rkH6OVgJ328JrGzpPUs+x3JylUZ1OGrC/sEuYO2as1RkQbNX4xNbtHC9vUq09RVnmKO3giAzlK5K6R1IV1OpDPMfMCrPcomUVyUc2euDg9DVpSZDVNdpTXI0neMbusZrWaeUlrrUbiL1tfxoY34TXUlgj09ATysKKFblnkQYCVcmwCiZeWmQSxzOva6EpioymNWB/qUVgpyS5QXrnSF6IZ+ilPnFTg4K0X+QpsZ+GP6LujUhyC9fJSIVFFtvkmUS9Nhb2FXmzTFK19/oW37ysvj2LHVCDAQxHtI8f5tiPnMeWOU+2DzBMXcI7Rlw+aSNiCxEL7NkRHz76AmPOgMPeBq28xD959cOMvaBxhwqnnyPjBLsfo5wiOrLYGRTJvl6nfjHHvUUy8f5lBonL5nYVITT7KgMyZfHcxhz9bkChHPNo8wivLM5wPOqTt9qc+DdFztVOULk1oH3SjLq+cuEY9BymxwTizAJp0Sb3Bdu3SuZet8oxfxmAa/E4004HgC+fP0H5OZ/yQNO7dYrMF0SPjPFKcQx5OCQ4NKT9ShOhHTMNCCD3TFFoCeNPQvzpaQ53IuzdAYOTTa5/AEglhz5m4y3uMDjk86/v/TivhHM83V7g1SuzZF8LkJ7D5e8PmD62xc5GHWvTRZYM2WWh0OINd18i1Ra/dO4+4uXSHgBD0d8XsH6fqerqgxW2OiX272S47T6D/UU6h6TBUyU2KpV7RwrBaMqhv08SbGmO/KYxySRVo1t3uxEyzli5v0z11jadfsC5pw6gbM3zC31sS1HcUuhWh9nPWnSfmeNzNx+l9WNF7ipfZZ+zi4WmOt9l/e4G6uSA//3E5xi3ehRFSqRtPtO9lfP9Sc6tHWHsxT6dYyV6p3OsYspvXb6D3+IORstlvNZe1dgYwIkvsIeC2ksjuL5KwZJgWeh9U/SOlBnOSM4cWWG+0OaRwkG63YDTk9tEysGxM+ZsmLOHTE5+mXgvOCBH8Aub9/P3Hv1egmrE29/xHBtRmXOfP0q8UuLccUjnYixHERRiw/vPJUppkj2fxcGjG1z98OwegVb9V8y6P7y+bYsdrUHnZIHg3vpldtIyn909TZg4lIoRoqQZjDyyyGGy1uemwjINa8CU3ccVOVZiKLAmgsjEEIk0x4pz5MhjMPCpdMFrZYDLieoGW3GZ3U6JPDcxTFFm0+8GiF2XYSpZlHUYOKiih6xVodvH7g1wjhbN3FqBjiwTdGBB5lvENUODSSZT3jJxEYlmkHtEyrnxdNdDs+1TtnHYaQH2ENBg+QkHars8U6yjbEnm71F4PEia5gbjjASFq+29a6bJHUFQHxnDDxLiBFzFEXeL3bxEwZ7G8nOSmouV2OhKymypy05QIvMcLFvhyJyCTNjvbpNriVICKzLRUrlvmyddKYNU4LcEpbUYezdEDkY4TR+hpDFspBKdSTJfkFY9opokqWsTphClxqkoAEsg4wyRmzQUrQV5auHtSZSjkYvt5hQEiEKA7g5wdlpUq0c515mkbEfUrBE1OaJRHHFtosp01cR1l2VCQ2aMtHnSJso05sjNmEs4yuy2IgeVSdyuwGuZ7X3um/l7UtE3xnU6ihGlIsL3SUsuUV2SlsAWOVIoPDsnco2xvJUXaaoBSveRQuDuqbdSJLkW7MZFrJZD4uecKK4RWGNc6UNpLSEc90hLLlmQEwlNnknE0CJPBatJnTXfo+zEpOOZ4QUqg3r7Zuvbt9j/0Do3mCJ8dAwrht7tIdPjXXqDAD2yWF5t8o8H76FWDHn/7MuMlEuwKQhW+qy+rYG6r0t6tsLhX+nhXhmy8Plp4prH7im4eptgfGoHT2Zc2Jmg/kDBoKJdFy1hGgBNXHGIxuv4Dlz5c2W0VbqxZbIHgsKaJK5r3MM9RlaAM5K4nYStO4rEx0LG6wMuDicIrJQpr4dEsxrXGeQeaEiLMNgP1dO7hInDaKUEAu6aWufe2hWe9g5iR6Z5NTyS4JQSbpreRCFYunCQ8lWf7tESnaPmzJ11fWTPRsYhaI296fJL22/iifX99M82wNZc/1AOuUXlJZvrDx5FHBKofQmNcsic10Yh+M3Nu1kbVvEeLzPxQshgxmPzzgDlgrfiYEXGNosCOYpQu2283Sr+ro0dCoTyyF3Yvjtj5y2aemOH45UerVsKXHtTiTR0sDYMfuy1A6cVQ/TwGMFr6GTPNOksS7Fzq2Awe4jmuZTgkfMEKwOWvzLLJyanCd/g8M7ay3xg+kVWmktcGYzxV1/8ASypmK12CTOHzUdmqVxV+GXN6v1VshLo0CLVMDnZxbczVqw63TGHYNWmck3Rn5ccfMMyvcRj9EKTUmec6z+0gHV3m4LXZ9LfYmdU5IUXDvLySGKHAjuDl7vzrM5WOFBrEU08y3ZW4Tev30m7XyDpeYhQGqWmgiyRvDSYY3VUwwo1Ms4pryicgUDZDtp2sIea6rUE5Qh+s/8GPrZwG66TMT7Tod0totd9U/DfZH1HFHuqLbbDEtVrCjtU9E7a2FKhlTFJkErCfplRxedyfQKlBc5AI9sDorE6f+/EV/jn0bsgy1E7u/gvpviVEpt3TvK641cp2zFSaIahy+TZPtbqjnlKArpeQZV8vLqHHduMJiXeHW2mKz1sae7SL786T3HNIi1CwUuJfRM4YYUpSVVxYm4DgFZcpOJEjLsDEIpOVqCX+ibnzhak9ZQPzr/IWlzjC9EJdC44WNjhoLcJtiGwKAdKzRFTlT53N0xO+pXSQZRnM5yS5McHqMyCnoM9FIYRpzXOUHCuO0l7o0JtSRCNC47fcZ1MSXoP7aP+5BpxdY7sSEbJi2nYA1pZiWu9BtutCjPXM5xXl7DGDhNOmjADt7MnDc2MzJU8R4chMkqxQ6O8c21j9Kif6XDHxDLjbp8JpweAheJaPM7vlU4TjVzDtwPkhYDqRdMoHU4LkCYRSUrDqh/Ubby2TUEIRG9E7VIFZ2CxdFuDqOJyxl/mnsIlfiG+n3CxDAIujPmoxGL+hYzS86vsvGWezgmTCSUSg/gqezHj/oBR6tC1A/RmCb+VM5yVvGH8Mt0s4LHKOLoYMDoZ8bu3/BqRtugrn99p3cnDj40TbH2DYJr7Fi2vjBRwoTLNSlRn61oTpyWpbgucviYaE0RjRs24GxdpRwEyMyk6XifDiveeKAK8dorz/BVwbKoLx+inJUYLIQdmW4xilzgN/rgH+7d/sU88N+Ijv/Ee3C5MXukick3z61W2r82gZ3O8mSEFP2a63CfObZ5Y2U849BjPIJ+qU74O//Qr301x0UKXAqQcR7sO2nOpXIFn1THsgwPef/hlTs+s8/xP7MdpH2DiGUWwmdA54jOcFSQ1BVMx0srxtWBxt0F2sYy/Ixjf1QS7Oc7Aoh+N4WeQFXNG+0qgBUsdo8rLc0ma2DzZPgoS7EaE7eQUr1nULybIxOFXwregghy3FlMsxVTtEIecUn1E90CNcFxTtTMsoZB7f+K6pj/vk5ZNUThuBmMZseUTN32CXgUtYJi4yCBjOG8kwRee3G/w0vsFg5k5hreGvPXQJRaCXY54G+zaJQ5Vp83T7u4ZivuOkVSMeCWtKfID5szdOeMgI4/xp2epv1JieMCcYWEPCpqBa+WU7YjPLJ6hu1zFmxzxnoOv0kkLaC1uJKkIAcnxkI0TmrzjUlq0cfqCtO0yDC1kz8YNBeGkYO1HT2PFJvTCCjUXt8f5lHMbibLIlORKa8xk5dkaz8vILU1UDwim6mTBHrQ0lMYDXxKE8w6Ja7G9VKewZGNH0J+3sSL4zU++FSuCuUt9k6ozbHApmWA3L7Ge1NgIy8RjBr5Zuabw2zndozanDqwxSDw+fuVWI+oJBdqG3rEc7efYQUahEFMvhMwEXUaZy6YPyrew+ynudobybfLANnj0iSa45vhnxYJCecS7xl/hS+IkL6yVvjMbdK8t8fgLzD0hEJaFCAKEbTMxCNGlgKvfW+XUzescLW3x3uoLPDY8xi+9dD+FTYnMFNGYT2UxpXZZI5MEVfTANzxwJDQuxFSWLFYpYR1WvGPsLP/rOz7L+WSKn8u+n9oFn91bFQdOrHOiusm76y9yKZ7ily/cS7hTYP/DKcEzVxHlEroYmG3fokseWAwnHcKmGZv1W0VIBSKTeNsW488bm+vWrUXiqmL6Wk7w0jL+SpXalTLd/S7Re0fMVzvU7SGuyJmtdrk4X4ZyhmvnN3YVFpq8ljGYdUgrRtzruRlT5T5rToWoXsHtFMysOnZx/Yx0XwQbHrMPmTn90nslEwd2+eDsOT5YeQ5HKMoypylHnCmvMun1CO5KaZ0p0NupILdcRDXhwyefZ8zp44uMfu7zq9lbsKMKgxmLcFIZWsyWOed7dkbZiuhfrLP/yymbt5e5NtlEaWk2UX9g9/mmQ5f46cmv8n+svZNXL51AJuB0JXlowB32EAYHFLU3brG2Xmfiqy52pIk2izyr9xEPXXRomQesbeyygZeSOTlxtUA0HpD7Zhphh4LiqjZhEqlNomwKSzYTz6f0Z20G84LimubgR66jOl0zKQp8rKHFhWiajaTC4rBJKyygxhMiz6FxDoLVAblf5c9NPc3HNu5k/ew0TmISaJQLc4e3eMvUxRvGFUsoPJnSSoqs+oLcs3A3B7C5g1UpI8fMDTsfK6P22H8yhvHikA+VL9LNCzxfnDd6gm+yvu2LHTAXWGmEUgjfo3vLBMNJi9xXvLI+zVKxztXRGIvdBt6OxO1ovG6O20sZTXmMJl673fnIFIKWQiaacMwiLQlkqvntl++gWh1xZd8EnbRgoqSaAnsguXplkv6cx7HCBpdHkwy3ijhti93TNvaBY1SWMwqLPUSaY3dDrMgxMI1Yoq5L0pbRSssM0NDdbxsnVmJyxgYzkLzrIM5I4/ZykODaGQXbPDkj7ZBrA9kUlqLkJhTshFFuAhkRZnuvPE0liBmGHpeuzxlmfRXax4ooVzPoBJBKRCpx97LZlSOgmDFX7lCQCR0VkCNYzmyGysMRORU7YjroUbD3nHW6hBDwqQs34fspt0+tULQS8oJiMGMTNyEv5+ihZXTpI7h6fYKdQRF7ZHT4MoOXlufw/ITZRhdH5nRjnyhxuNIb458m72WlX6N3LDOQzMA0vHTPwxlpvB3J2uIY7o5FsJsZvbutqZVG7GaSNJV7gQMg3RwpFfwBOq7T1wQbEq+jKW6muAOLrReavFpuUMihv89mNCFIxsyObe8cgayU0QUff1fwW5fvwHNSakFEZxTgLno4fUFS1nSPV8HWPN47wuWtMYqrexyAokGcL18d5790S2SZhUosbC9jvN6n1S9S3VU4vYSsFkBtH6MZM1q2QqgupshMm1RdCRdfneNDyZ9nGLtYrvozUOx/YOlKidX3Zrzj1Et86ZVTBM+UGYkyL8tx7AjqKznOUBEs9ZGdPqOb5gnfOiDwEiZKhr++9fwYbk8wXMhxxkKsl0rM/5JiNFPjd+67C13IEUXFYL+gdE0y+bRk+5YxHq8d4mqnSe0VG5loJn9gkf/P/Bf5ic/+BMc+IpCjCN1qI2yb4mgM5dpUX4gQ8TfC9vq3TLP5gxGWpXAerxBsKTbvz3jvmZf53EtnmPusRe4IGoWQad+EK/SUsaQCSEszXehSshN20yJh7ho4gw+UUw7Wd3l24wDHft0QcK99uEIymyDbDt7yXi8hNt1+LY2yrjnW4U2NS3gyZTEdYzsrcy0cx5UZh/xt5twW027H8NdLTZYaDb529QATnwjInQKPvMdn32Qbpx7TPa2RxYxKKaK3W0QmDs5Q4zzmoGUNGUBv3kRIVR/xGezz+b4PP8i9wRU+27+Ji8NJvvryCXrPTdM5rvnZd3yGmjXk2eEBlkd1nl0+jt9SeF1B9YrE62YUz22RN0rIostNzTVeEdNs6QpCKmxbYVkK6w8UgdBQXk2pLGmcboxcXMfPFZUnPQh8Vr57ht07M5xKzExtwHoyAY6NsG3S+XHSikP9Qk6+WKZ9VKLv2GW4VeTQV2Psbszyu6qM5nNwFb9/8Tje+YDJJ9qINCeZLJF7FvVLAm0V8Nop7taAaLrE9m1TuCnULvSxtjp0XjdL55AkPB7xl2/7Kl/dOsbOx/YR7Cj83ZzChmL8hRQ5cInvqhO8r2v4dN9kfWcV+95oSViawEqRbk7uvObEei24QGOHOUIpI2pJIOp5UIFCLSH1LHZLpnmkXfNBMFnbHklRYI0EKjeYYZGDM9LYI4XILcp2jGvlZJmRTIKJodbFjHimhEwKyMmq4amHKTJKEMPQ5HGPN0gnK4wmLCrFCEsqeoUKdlGAgrWwgohM/pwdaZZ3ajd01dNul84oQEYmBLBix9gyZy2s0kt80Nyg13STwHDILIFyDAiiMdanpSpk2ka65mmeu6Atm9yDkpWznlSJlU2oXAaZa8RDaLppgCszms6QkhWTagtPZjhuRlTzjfEkl/RjF89PsZ2cPJcMRx4kkqxodhB+R2MliuGEhS4JyF6L9BJ771PQyopsRuU9YKTBSHXzgFRbvNieZb1XwUoEuSuwY43bUwilifc3Sao2agDPb88xil0TeKEk0cjGdjMmygMsqYhysAep+R2luRFIBQFYElUpoAqukfwqQTp0WU+ryFgwPD6BFY/Rn3dJC4KgpXB7OW5f0hsEyGgPb27v7R72+nRa7bkroxSkIGo6pIHE7+Q4gwy7FyMGI+yhjz3am8yUXdBVBtOScC6nWhuRaotMy71wR0FcM0BVmWusboi2oF4IWf1jWNLfOcWuclQYYg9D7LUJHq4eplCMyW9NGS8PuamxxhPr+5EvVnA3+qiCi6741C9GVK5L2kfLnH+rNnrsyZBsTEJsEe4UKJ7osfCWVS62x7GeGSfYFhQ2TXKNTEwRpRXFj40/ygPezXzWnUIOFOcuz/K/pB/CLmQsvt+DsmJhpsPKdp35X3bxL6yjRyE6y9i8f4K5779GdS8RdJS5tG8a0Bo5+Nc8lp46zExb4e3GuF2J3wkYlYp85q4pgukB8WKZ4oqkV3I4VtiglRX5zNWboOuAo0nHUkgsLl+ewhpKNu6pkJbgrlvO867mK7w8M8dyWCfJbcLMoejEnKxskGqLB9eO8PFzt5G3PeyuNOGZ1QwSSbBsI3MYHk1ojPcoewkNf8hNM2u4P54zSD16q9O0dsrcfHCFNzYv8SsX7sZ/okRWgN6pBFLJ/OegeHGX3B0nbhidgHKNR/7Z/n420yqfOn8zai3A2WvAiQz+44tvJB/YzHzFYnwroXNI01+QVK/kFC5u0711kuTHu7hWTv3TkxR/t0b/LgdODFG7HsXrFtGE5r4Tz+KJjN8dTuC8cg2URmsNc1O0750jbEo6tyd4pZhsSVG4blNeUtTOhuze4lP6eyscK29Sd0zh/fZn38i+L+cUNiyylwvIHNpHPETu4QygfMVmcCCnOj5gWPbQjk0yUWTzQzGzYx3an5th4tkE7Vjk41Wyoo1MNZkvWLvPIy+4HLzrOv9o38N8evdWfu3Fu2HHoxkaNd/263NKUwN2LlUpX/No35Tz1xce5Z86/W9aQt85xQ7m7J6k2ANBrx/g+SmBlzBT6vKW6jl2kiKrfs1cwIJL7kncboKzMaTQmKAXOViWIggSNNAPSyYFsxDylyYf4RPOnXxFjWNF4PaN8s54t02eWv4HXAYiB6tjs1KoY9k57vSAmVqPd0ye5UH7GJE9g05SsCTC9gnHBT8+8xidvMDDnWMoLakUI4aWwh56VK8m5mmjTVBi6WpMXnDozxcZ2UXckdhToWmq1pBIG9ywPZJktQzhKnRsfPFgiKhpWbNQaHHQ3SLXkood0ct8WmmRaa/L+6smufaxzYNkoY3T3yPXpoLYl1hDSXFdYyWaaNymX/DRWmBJxWTQ577aJXayMq+uTkNsUXJiTvqrABS2FeGYxKvEBgriBt8YZ+754rVlQjWWhzW6qU/a9fC78gYzTmjId13crqR81YxE7dn95J4wZ+gwQluCe6auYaF4ojNB4fwmzsk5hJOT58aKmpYFdXtIWUbGGJSkYFkIS6J8A9KMGzAz02K21OWZzcPGP9BVyOUN7BNl3jZ+jrcWz9OQGbGG/1y7D2WbUAZnYN5LWt4jEf2BWLKil9B3AFuS+5LJRpvT9XUeCmZMMpFvo6UgK+41FCXETQXVlPvGrvCOoMXXvS5qYEhGyjEE4mB8xK1TKzzW9wkHPnY1YcLuY/8xxMnvrGIHiGPqFxWDQYDT93EHmqdf3+AD73meN9cv8JEfH2O9X4BVH7crKGy4lFZ9orpAJRaZZ3FsYgvfTnnubI3my5q1Zo2ZE33G3f6e9hwG0xZi0rqRHVe5Kvirv/DTWDGUNnNkpmm+ZJFf9Nm9K+Odt77Ay+0ZfvGht+FvWCystUArhncfojdvkxwNybXEFylnSqtctcZ58dUFgnWb0orC7idEkwHd/Ubf3nxyE2e7w+yjkqjhsvF6qL9vlftqGxz31pl12rz3lpdYCyuc3Zgi7viMz3Z4y8wlvrx8DPG5Bl5b8OCaidMqyARPZjy4eoTo6SZxXXH+jknmi23ePXMWby7la62DXG6NUZCKupOx3aogXvGxQ9NBbpRDtjeqDNcbLEv4unMcAJmDZcFgj5kWDjxmr4VoERCUR0wXe7zyvTOsvLuJiDUyVuSBQpZT1MBh8xML7IaawpQgK2qs2MzvdSiwBxYyg9bpMvbhErkrKKybm0Z8zGRufe7LdyKA6X5OPl6lfzjjb514lF917ia/YvTtj+weoemN2L1Jk1RuYTStSSdTrJZN5Qp4Ldh5epItbxIKiv7RjP5phfz+edQo5xc/9W7+Xeld/J13/B7fXbrA/JFNlt82jcxNo1XZmrRi4pe9Zki5EHO63GN/cZfPTVfpHyojNHS/MsVXvSm8AXQO+wznBOF8iuxLSteN/l4XM0rVkLo9BOD+yqv07gjopAGrd1SRQnO4sk3TGXLL/mVWmjVyJfi7r3yIxdEvf9PS+Y4rdp0kFFcj7NClcK2HWFojHDsNwBl/mf/r1G/TUQX+2eX3sLbSAOFixbaJPsoEeS6YK3So2CGv9I5TPd9j8/VlGhKq9mgvEdVQZv7gzLJ2WVH9ykWE7xMdmyb3JJWdEJkpWjcF3FO+zAu7czRelBS2MmSnj9aa3rxN50zG/skWqbZwRM6Cu0M/93F3LcrXNf5uioxS0kKR4T5N7gnGooR8awdnOMT1fdbvO8DPHvg8NWvElBXTlDE/0Pwa23mFf9p7D8l2gflKm7/WfIytuMz5Xh2Za9Z3y5zzp9hf3mXG69LeKbPwTMpo0uaV6Rn6Ez5/f//nuc+POOmv8nj5KLGy6WUBL+QWaB8r0Wgbyl7Mbt+mdtEIaazESHMHcybSOtmD1OnIwtnYxZ30CFxzXLi7cRVH5Hxi+TZWl5rYpZTJRo/VqMn0w7uwtsXWh4/Tre5ReuK9ZvqeHXc4LQBBsG0SdgDCCePdH3vRmH+sRJFWXAqTQ36gcpZHm4e5YDcQCpZ7dYaBhzM3pNd0uOvwIj8++Sg/v/x21q/txxlqqlfMjb51C1Sm+rxh9ip/YexR/tHS++l/ch/KEbx07z6+p3yR25tLtI8H9LsB1qZnuO3NmCBIeNP8FU4VV298dh6vHiBq+Lg9zfiLCSLXdA+4ROOC6HDE+069zNc2DhCtjwEg/ZxKEFGUxp57zOnyF8YeJd+bT6ba4lIyRSsr8bp6yM1Vhwc3j7L6/DQ6+g4h1XwrS2cZzloba1CgfUuN3gcaJCdHOCKnowosJ01WkgbrF8epXjZk2NYZyBoJhw9sUvdG1JwRllCEp0IWgyq6nPDjVz/Mer9CVlJm6y4xT3XL0E/aQpK7R8kdc57UEvwd2yTSdgU/98L7SDcKNDPIPUl4fAqkoHtUcfjIOsu7Nf7BuT+HHIv54PEXWY+qlJahcjWkfTxgeK+H24OxF4xKMJ1rImYbtA4ViOsSlOavPfsD5JlFPrIRXs7RuU1KTky3b2KDnz13gDde++tYax7Tew4/2i5X7TEurU6gc0HhkoszChG5jeenZEryV57+IdKRiwgt5EiSjyWcOrBGnFk4vjHd1F612Fiao5iYI4IVYfLUlPlvF8Hlpxb46bM/hhUJLv/4DMlUxk9NXKBkRfzSxfvobZVwdmzKu4LRtEVYHoGlCfdV8AouWcGMEXNPgzbn+bSujEdgYFBkzlBTXAnRjiR3JMMZl+27FNrPEZHZCr9l9jojrenGAU7PpAT1XmzScZpYEXiZ4Gx1ksXGOEoLoqYxungtbTTze437L146weeevwkRSbzXWWSBZjwq8Z+6Z7g2bGJJdYMXYEUCseiTSp8vbNzMA+6ZPYCmxlt2mVrLSAuS5bc5ZJUcdxvcPjh+xm2l65RmYx647ySjyEW1fda743zMu4NkyuarreN8/cp+gmLMdx18lYY9ZD2pEuYOau+JtN0v4nbEDRjoH7W+I4s9u3Yd4Xns/tBt/IsP/AaOMIqy3azEs/39XO03abwsGX+qxdJ3NTh4+zL7y7u8u/4yAFfjCfq5zw+ceQZ1WvCZa2e4/PsHyT1NPpGR142pBS0M+sfJSSYkW0ck0lEUixEaaC9VcDsSf1fgXd6jj+aaNBAMT3hkBThwaoWfmX+Qv3X+hzjx85t0bp/kmZ+cJ8psapcTnJeu0nvvKb7nXY/xsa/ew+x/uogoFencNUM4JuncHbMwvcvguRkav1sg2E4Jzq+RT9a4+j3zpOMG2ySA+nM2k0/00U5ssNBlC3/bIo0DyquCwrbC66RYgwSZexT3klknPhFQffw6BD7ad9m6u8n6WJk0tRGBIPMEk0/2sDba9G+fZee0jeMI3L4JjbBHGjuCyadjvOu7XP3zs/yTH/4NZu02c3bIi8kY6bN1Fp5JkWmCzDU7p32iAw7CUvT3eUT14o14Y+UZom82lnLz4WWi3ObClRlo23jdHPvKOqIQoCoFugddfvC+J7ivdPHGZ6QmR/SVRTsKCFrm5lla2fvejoFQrE6VubIwgX4tvacncTuYKcuevtx7scCRT27QuW0C7y+tsq/UZqnf4Ld7t99Q/b0WYW2Fkso1jR0qE8ucgbIlyhG4vQRvrUf/RIPve8dj/Lna03zoiZ+CFwqUChFvCq7ytsJVfqLxBE9F+/iHn/l+youCc/Yso9Rl9blpDn02pL9Q5oHvPcF8rUOYOeRKYkmFLRSjTkBz6xtx43/U+o4r9hsrzykuC/7FxXdhSQMhDBOHTqsEA5vZHYWIUkNm2ZNiJtoiUg7nhtO0k4Dj5U32+ztMVvosNssGIe3noAT2hosdCsI5KFZHpLlFYlk4Tk6jaDzGcVfeEEvI7L+e49qRGQVevTbJv8reQbBqoS2JlgLPyoxd0TboYqcneGp3P8rTdN52FGvvien2NPQctoolZPoNr7JOU0ScY4WCLLSwhwZN7Q4UIlOmQelJskCSVDV5PSWKHZCStCDIghKjcUndzgyW2RbguWjbQkuJO9BsLNaRsaDU1TihJq14KGeM4ZRFNJ3DpoXbNyERUd346vvzHnFjingsZzcvsZuX+FR3gmvDJsrRDGZMZ18oSGogBbhBSueYixUJ3B4UV0ymeVbSWG2bFy/MQy7wtmycITjDDPKcZL7BzpmA7hHFUX+dgoz5Uu8Mm3GFo8UNDrrbVP2IlTMWzsCiuK6wYzNyFQrctsXD64fpDgPzJN9T8AmlcTuSnlemEkPeLJkYqshjSTe4vjiO1bf2CLsaGZv8dqEgaghEbt34PRU3FMW1GGuUIMIYe6R4oTPHmNNHJRa5A45lGmrXswIP9G7m6nCMvJIx2Gcjgpx+bBSfWckh8wUCCDOHa6tjMHCoz7e5e+o6rckC3cNN8m+e2PydW+w6y5j52GX4UgUduGRlj6LSTA5DyBRyMII4QSYQ5zbDzGM7q7CVVnjoyhGygcPC7S3eEFwmnbF4wE4Zpi67wwKDToGpr+cUL/e4+gN1Dp3cuZEzFjgpR6tb7MZF8gsTNL+ySHpwisE+/0aXWWb6RgpI45xCJlWK2RBVLRBXBRNBn1HmshVMgOdRu6JYt+cQR0Pe+Q+e4oHVk/i/UKd0PSSuVQhbFdyBIK4K3IFlggrTzCS5CIviqsZv53jtDG1L8sAhrllETUlwuMOpiQ2uTjfpDgJ6IwfRc9DlhCPBgFHm0mlIivuaN7rlxY2YA79rYrJlnKOloH08IBz3CI/F3HfsEo++fIzCJ3ugNa2TY4STmuGdEWP1Pkf9kMc6h3l1Z4rkEeNUTA4pWm/4BiDNcnNKVs50tccP3fRF+nnAr/779zLzuWX6t0zTOm5T2YKxZ/uITJE2CiaFda0LuWLtnoD/7499lH3OLgftEVezAr/53OvwF10eOn6E2xeWuKm2yp//wa/xaPcYj33+ZoItg+tyQkXlCoxaE4gAxJ5VWGiwUqhdUqhrFsrSbN9SJKkJhmtV2rFk4QuKwrVdVNEj922icY/BrEVSht7pBKeYcnByh4mgz/OfPE3tqyugcnSe468VuPDUfs5OziA6DllZEzgpKYJPtu/ggU+9HjQsvGmNW+5Y4ZnteTZbFZSr6Rx2iBpQdVP6sUfzIY/GuSGX/kqJnznzIO+vV3l+YT+/8J/+rIze/tDKt3cRnS6yUsEZr0OuEL0BOsvB99DFAJliuPKZeautuEDe8rCHkk5awBKaojRuJymKtIYFEJrMk6iSi0wFS706YHYIUmjC3GGQGtmmandATZIGZjRmpXpPGquNV7sbI7sjsokKg4UiSUWw1G8QZTaqZuEfmiauGs20ZRtscs0PaY2PYz6JJvNMZCC04bariTp50RBy7SG4A43bz1GuJJwro/bY7sqCShAx63cYlVzj7HNdQi8nCBKqjqEBZQVIK/aN3Ho7VHitFJEbDoC2pQmd9Mz9YCssg4Z4qmQEPXuYaWnlFN0EWyoyZRHGLqVtc9PrHdX4pfjGLktKjRAaz8o46a0SaQflYSSpqcYegTtQyN0eKIWs+OS2RHsuslIiK2mOuxs0rBRfSFJtI3s2/i50EwtXZkx5XW73l+nmRb7SOIPIzM4qC83vyt/RRE1BNKXJgcw3pFflmkZdVjCOPWVr7I5t5Me9GDEIseIU6dhgCZKyb2THEmznG74F5QDVEiJO0WFoMuz7AuUZa7DIoDMKeC6a49JgAmdgXrfiRez3dzjnTBlxUKCImpKkqgiclCizkUONtdNH7E7yaHiYdlbketQkVt+8pL+jix2VoxOFKAYMDtawwxz/7AC0Ij48wWjCxetq7C9USHWFC2oCkcPMUKFszTPH9nG+OU4nL+DuHXaS1MZyFFvfHbGZWwSvgPfLDdrHLKzXt0kziyd3D5D2XA52MpCS0axP+7TGbUnqFxUyM00tXDNHFZHL6hsLnPmu8+yuzTL86DQIaL8zpPGjOxz2Qsp2zLObc/zfD7yTvJxz+1+6hCtzll44SrBqmcZSRzOasNi6o44VQ+Oswl3McTsJMsxYfXuV6ls3WF2vM/6QyUY7UGnx9uqreDLjsjVO3R0x43UpWDGTdpf1tM5z+w8BDoNTMbceWuKl5TnKXwtwu5rq1RCZ5FgxWCHUnvFoPzhPMC+I/s6GSax9aQKvLciiIkuLRcTCiLcdvoCUZsdhRQqwCLwE38lwrZwkt4hS8/Gz0NRkRO9Uwloyi99W1C8m2FGOalZQvkPrRJG0JLBHHnZcIytqfnnnjRwubPL24jm28jL+pqSylBG9OeFvT38JC40jFMe8Ne676yytuEiYOcSZTfvhKfZ9ocvurRWsfV2E0HTsmjkO7R+wv9mi5MRUnYiHrx5m5jc9vHZCFliMTk4RrPRhq4U7imhu+MRzVaIxl2hgcfFyGZmAcOHaD05T2NCMvTREeRZeC6xYYg9Nyks4bPC/XPk+ZCaw6pAVFRUnwkJT90d0qz5+s0vheELJiTlc3GZx1OSqO47Icg59POQ3H/wukz6TaeK1B79puXxnFzsYoY3rEFelAQJ6LgKIGg6jCYnfVpRWcqxEYY0yhNaG+FK02Rp5bGQ1ulkBpSVKC7LUQgjNqZkN6t6IZ14+Q/nlLaL6FAmY0IWOh9O1kHmE8DySkiSvpWSxsR4Krc1TSBhPsyy5hFOKvzPzBX4u/W7iq0ZI0Zjc4e8vPEBP+UTa4YXtWcqLgsG8xU9OP8x+p8N7r/8Maqtw40yZFUHMj4j7LuJlidNL9wgvOXFN8337nuW/cDupnkRmGk9m1OSIMWfAtlNmn9/m1sLiXiFkhmVWykiqkoXZXX5q5iH+A2/m3IUjBshoC0jMLF2mEOwqyosjRhMlfmL/YyTa5l+efz9WLJCZmVIMJ+0bN08rUgZugYVjKVwrN7l9SqKUvMFU90VOqTliOGeeeuVBZqg7JY+sZKKT0hJkRRPwofyMpVEdW+YMCzaRcpApyEThOhmnHJe2ClnJbCyhuK2yxGjvQKsQ/EYwidUZYCVlAj8msFO69QJ5YnHT9Bpvrl+gIGOKMuHZ4hyF5QS52yM5M0NStfB2HSSgB0N0p4vr2dgDDy0kwbbAHmqGc5p4JgMc4mXz2lZskmXs0BQ7W+AMJHkAUVOTl5QJ/wQkGksqJgp9bq8uIYUiVTbyNdO61tivXkP0ejfKQegR32x9S8UuhPibwF/CtDJeBv4CBuLy20ATeBb481rr5Jt+kz/FFc/V2LpHo4XGvdWEN+rDI2aaXZbWmjirLsqGvGTerkhM2ITqSf75196DdHIsJycdubjrDsqCVqPAuD9geDriWjBNtJDwtuklzrYnsc7V8Dqa9bsD0rcfNxbOFdNI2T1t3RhHAWy8wcJppMzVN/m1nTeQKcnlH7QRqURfmeYvXPtxswdWYPVsgqLRuZ+NZ1FIPnTiBZYX6vRSn2HqsrXRoPB8EVfA5usVyvFw+obK6vbgl37tvfi7muarPfKSyyMPn+GRfYd53f5F3lI/z9nRDP9m8R2MBwM+NP6suVa5wEoES+sNft55O8udGnHTeLOjpovjWdiRxt+F1knB9vslhUKbz2zdzOaoTGFV4u9otl+fc/joOk1/iCczpFTkvulWaalRWrC8XSfvughldA/9sYDzM9MccrY4M7HOeSunsxCwe6dh+8vQpNyUljRuD3buytl/aJMj3oiZoEfdHtHKS7giJ3jLNku3lHjj1ApfDgN+a/vNPPrCcURuHHEIjSxkWLYCGzbfOkNWEHSfmCYraoLDPcrNiLPbk7y4Nkua2OSRReGKi2wtQZ4zmrAZTQm6BytoWaF+Iafy+VeQ/ZBgywiCkiqEE2APBeXzJoVn9U02MoXSsvls9A4IkqZCxkZTkJUU/syQZiFizBsQaZuvvXKY+vM2T988xql71nm6vcC1Lx0g2NRMPN9CtTroKP6W6+S/WexCiFngrwMntdahEOJjwPcD7wH+rdb6t4UQ/wH4i8Avfsuv/D9wRU2bI8dXqft7JE4r5wNjz3PGW+NXm/fypepxmsUR901cAWAprNNJCpx9Zj/ll2ySqpEouqGgsC7IfRgmDo7MuWlhlc5UwIHKLq+vXGF5WMO+muG1Yrbe7PCO06/ypZdOUXveJW5AdMRUudw2xf/eO1/kb058hf/SvZ1PLd1MIxjxE3c/wlpc4yu/dzuVa9/o4icVM/PVjmYxGqMsI36s/gQz44KCcHGExYe8t7P7sQMkZUn5zdvcPrbCue4kO4Mi4it1Zv7zq+jcnBndSpmJZ/YxXCmw1KxzamqVJ3uHuHp1krV6lbc3zmIJBbk5P8ptl3P5jKG3VFMSYROXDStephov0yT7U37vnl/kodFR/v3ZNxHuFJjYNIEalek+/+Lg73ApmeSl0T4soVGOQCh5Y2eiWh7FlW8IP0LlsZI0aFoDbq0uMRt0KFgJBZnQyopcGza5tDuOvFynsJ1Tm+7xzw99kqWsweVoCl+mdPICUij+9pEvAbCZ1nhqeIjHLh1m/nMgtGI0bkw/UcMUn/I07VMaf1sw/mJG2LAQpxKO17d46OwxvBWHoCfw2prSRoru9iDwje99UuHMDdk/1uK6XKDyOY0ehQQthdCS0TTkzRT3okv1Wk77qEXzpm16Ix+9VsYeaOKpjMOHN1jrVBjtFLDLKaen1qm7Ixr2kFTZlC47TD+wTFbcR3q3xWKrwcInNskvXuGb212++fpWt/E2EAghUqAArANvBX5w79//H+B/439SsZeuj1h+aJ5Lkzmvv/UiR0pbrKV1dvMSrbRI0UvY7hf5zWuvRwQ59x+7wInKBhfCA1SWMnrzNnFj7wmynpO7gs1OkcVSg3YUMIxdJgouNWvEvmKHrx9ewO1ZWH5IP/UpNUd0TkmEFtB30EKTl3JwNFtxiS8MT/D5tVN0zjbZGS9zorZhBBGOJvfBbyncboaWLqMp856uDsZIlM1IeUw6HWpyREVGFOyUV+8yxZJu1vhiu4za8HG7kuZaDraNcCTCc9HlAtoyzaiVzTq/UL6fThIwta+FZ+V8uXWSUeZCbmKNlbv39Gs7FFdMgfb3Q19b1C+YMVJwPuAvNH+EMHGIBh4iEUbPn2miV2v8cPoXSSIbNXRAQe8egcgl7g70N8dxBaRFg7FSlrmx/e7KTTzsHwFAacF6r0K/F4AS6FyYlBhlQheHI49HR0fZSctsxWVWhjUuL01AKs1T21KkPRc5siiuSxAZYcNm+64cghx31cXpC0RfIJQgK8DKWyS6lHKiMCTMHay2TWHNaCaENrN5Ua2gC4YGpEo5nmt6D/FEzuj+0+SeoHvAIiuCGo8pViJy10UoI8qaKXWZKA54+XYfMTQ8gysr4+hMghZkI5vnrs8D8OVUohPJ7LUcPRjSOJ/y21++j8KGQPR2/qgS+JbWf7PYtdarQoh/DSwBIfAlzLa9o7V+bYS/Asx+k2/xp7+eOcvCKx7J3Sco3xXxxtJ5PtW6g8v9MaTQjBWGbC41OPwbCdGEh/OzOe+uvMTn+vdQen4F5e5jsF9ij6D86g7YFtu3N7leqBNHLnls0S0HTNkdbi8v8pVbj6GHNpVCTCsucPPkGpPzPR7fPEj36xMoWyOODqiVQtYGVT4+up3NFyeZfSSjfcRj5XANWyqUB2lRULmWEVzYJCvO0HYttNBc3h5jxa1yLpgksFPG/AHj7oCGO+S+t7/Mld4Ym4/P4G9D7UqCvzFEjGKE44DvkddK5EWH3BEIpfEu+zy5fZzioS5//diDnB3N8MmXbkWMbEQmyMqGnS6kJtiUzH1mnWSuzurPpMzUu/Svz+Iu7zL7UJ3RxQbZuEQc1XtWYNNx3/flGPl5C7QCHbN9e5Ef/yufwxEZH/n59zP58BZbbxyndZNCO0bToBNJ69kJ2rkgnsyQpRT/1YD5F1NyTxJX9qAdCtKiJO16fGHjlNE95BZbl8Y4/isdZHtAOj9GVnTwV3uwuYOeGmd4uMJwWvCzb/ksx701fvQLP0lpycLvaLxWytobXT7yXR+hLCN+q3U3F3sTBOuS5rmQuOYQNgxfIJ+okpdc4oYiaITUCyG+ldLc32bpfVWQCqsQ4zg5hxod6t6I5wsVww104bbaMnNui++beppOXuBfP/lOiq/6xDVN2sixujaFcy72UFO7muJ0IuylLbLdFv4Xexx5yIM8J4u/9W37H17fyja+Dnw3cADoAB8H3vWtvoAQ4ieBnwTwKfyJfsj/5lI5ajTCaUU8cv0w7aTAtU6T/sgz8AKpEKlgNOMTVwSLgwYPu8dNKme1ZKKhqhlxbBPN19C2JKtnzFUGhIFDnNoIoflM9zZ24hKFckziZTSKIypuhCczciSjxMHtgJaC/m7AVuTc+BFtDf1ZmyyAF5b2AeB1BFakyX2LfKpOWpR7og/jW3/tj9ICpSU5kk4asD6qsjMoGs93ZhDH2rURiZkOqGLA4GDJZMNPGDuplYC9KekVy3x53DzRg3JMbCvsJd8QViqCrGQ808MT44zGLBwnBCCum2COuO6QlCRaCLxds2tICwA2xfUEqxuRNQNGkx5JGV4ZzuAIZYIkD9fJAoE1kihPoyxtsuoTo8QTQUatOqRX8wmbNmnRREW/RvVBg9W3uHp5ClHIKJYjE6NcD7Bcm95+n6QsqNgVAkuQl/29Iwi8MpwlVsYOHDeM0SbINVYoeGZ0kLptnupSaJK6pr/PRFb7HYUVGaGSsiReSxI5RdYyeQMoEjRCstQiHTrk0iatWthCkdUzOgcdkori/GCKfuBze/EaZRlCavBacR2scoqOPPwdjddTuNshsj+6EZSiswyd/THSuG9xfSvb+LcB17TW2wBCiE8C9wI1IYS993SfA1b/qC/WWv8S8EsAFdH4Y9iX//1LLq4x+38fYKN6iHzKwikbS2DigCwrNj9gLt7uhTnOJ/so5bB7e5P2STh1bIWtuRKLtQba1rzv1ud5U+UCjshwRc4vrLyVT//e3aRlzZ13XeRgYYeCleCInMujCc53J+mvlTn4UoxMFaU1j8z3jLFGQOc4BB/apLXUZOE3bNxeSlpOUY5gOG2xe6qMcszWUaVGimlbCt82yTSBleLJjCvdMbafn8QeCtyBUdVFTYu0VKC4ZuH0hoT7yqy+J8crj3CcHJ1L3IcqTHy9z+hSgbOXjjOcU/zwWx8lVRZffvBexh9ZZ3R0jN68zWC/xv4bGzSEMmSffonByZTBvGeiqy2Fv2Ex+UyKtmDrNoe0BE5o410Z0H5dnei9PdLE4vcfu9n8bm4Z0bonJrxYo7QoyEqCuG5uFq9FQt9yYJkfm36cX6/ey/MT8zTG+vz0wacAeLq3wPKgTudTs0w/1GHr7ia79wnwFStvClCuz/zdK9xSX+F3z9+MdbmOvy2oXssobCk++8RtUMlwSgnprTFDSpRXoLiu+Y+PvBVRSTg8s03VC2nctkX/hI/1aJW5j16BQkA83zBo8SditITtW0qsHQjwJ4e8eeEyr7Smab04jRXDZrnMTLHL605fgdNwtdPk8ZeOIospY7f2Gbf72F2b4mZO/4DgnoNXeDQ8ytjXu7Cxg45jVJqh8z/Jyfybr2+l2JeA1wshCpht/P3AM8CDwPdgOvI/Cnz6f+hP9idYajTCu7aDWwxQdo1QG5FI7hmBRL06JMsl3S0fu7/nICpBVsqZLXSQQrNTLWPZioPBNoecbYbaYag80tzCCg3hxZUZBSthlLuk2qKfeUSZg9CC3PvGtlNmGmWJG4aamh+yKjVuN8XuhGRBGe1bpAVBWtGIbI+UYxnRiW0ZLls/8bClouEOCRMHt2vik0QOCEjKAsoCZ+jguA5pSVIf7zBV7jNIPIaJA4nG3unjBzZR3SduCEpWBJb5WUWUmDFZCGgYDwbYQjFIXbJcIvwcpQFHI52cvO1jD1K0LQEHbWvSQKLqJeK64GBzl5VulWjXpMj4R0bcNL7Ow0sV7NCwoZW95//es2AX7JSmNWCu0OFyfYxD9V3eVLyAhUYKRcWOeULPIFpd7KhxgzOvXE3ua26pr/Cu6ku8PDXDhf4MQjmk25LcEdgDQa4csoY2sUzaSGOtRGMNJJl06MYm59yzcmQhpC+r6FGICHziuoOywevmiMy47MjM65ftCMfKzegvhjS1GGQec4UOC/4unThgN2qicDg/mGbDqWIPBM5AYYU2rbiIiCxEp0/Wbv+p1ce3cmZ/SgjxCeA5IAOexzypPwf8thDin+z93a/8qf2U3+LSSYLa2kEUAtzZMmkgTbPMM2igTj8ws2NLozxzExCZQBRyjhU2GWYedB1yW1OQCTN2xk9d+y6ef+UAVi3h0NuWyLTk5a0Znk4WSBdLuB1BuD9lYWGb6UPbdH/KJdeCPDdbvFoxpOzGbC9Os/jAAUoa1t7gomXREGEc0HtgxOIGjL8Q0jvg49wS0ghGXH3gIPWLOU+9fYyF13+dNLdwBmZeq2zIXUH/togjc1tcfXofc/k4vf0WH1p4haoV8muXXs9gq8jcjkK3u+QHmwzmBFlB8dvXbseSmtYZzXBmASsCO9SUF+HylWOEE4Kb33uOg1M7/Nbj91C5ZNE7mnFwYZPL4RRJ3cUe5oy/kJH5gtZJi437S5TH2tTcEVfSJqUV894myn0+2HyWh9wTZmu8pbBCRVaw6B60UTa8sDHLL/JWOklALYiY8AbUZEZBCN5auMApb5XPv+402jrEYF5TaQzpr1SYfSghK1q07ityxu3xgakXeMQbsbK/xtqRGnlsIfo2ViSoPO4R7DgEOyHO9hA95yH3DwksxdalMXZDgR0JRAqVDYXeP0P3eI3tD41oVEYMXguyyCVlJSn5MZf64/Rjz/D0Y8i7Lq+kM7QmC7jjGSUnprS/S78X8PTHb8JraeZf7WMvb3Ngs8ngyTkOtyLy1p9eocO32I3XWv8c8HN/6K+vAnf9D/+J/nuW1qjRCJHvxTxltumQ74FG02Tv7UrDrDNEUkMfHbN7ZjYcmcAAV2SUhMOl3XFqr9p0btK8++ZXWE9q/M7WLai2R/0yFDcyNko2LBi12lvq58mRLEZjxMrmZGGNWafNX934ARoXJGHdonWzRvkKHEMDFUMbGQkjEb26SVCaxXFSSnZMZVFRfvwa/unDxMomzyVuor9hjJEwP93iL+57lH+w+UGihk9S05zw13BEThw5WD0be2gkm9oSpBXTIGvvlo0NczwhHAN71aOwIShsKaqvdOgfq9L44IhbC9f5aHwvwbaif0AyXehyrdQkLfjIROFvhmhLsn5fwJtPX9i7xJo8l/jdHGUJKk7EcXcbpMYOTeCks9Elrxfpz1UQSjDqe1z0xo3wxs6w93hqjpDsswU12WNmqs36wQl0M6HkxwwyQXB5G13wGeYuVely3FsnqjnsK9S4VmyyMaywfG0cMbKoXM8onN/8xmdGwHh1QKYkul3BaxkXn5UY/mBWDRhOSt5x6AI3lZaZsHs4IuPL3dOc60yhEHSTgCyXZKUc6UhkKCFy6VZ8wtzBlTkT5QGDgc/48zH+pU1Uq002HML6Bt7zex/fP+Xy+M5X0P0RS9g23f0+3SOQzKTMzrQYxi7dbgGd7mVyC4NtyopQKMQoJOthhepl0ELw+68/yYzdJgxdykD5osN/XHuPscHWc6OfLwjiikVayzlW2ySwUlaSBmtxlS+fP4Ee2HxxashkpY+8HuB2YtBQWLXJXYlyjdjktZWWBL279jGYsfATF0sUaB+TZN4hrBg++9U78doCZ6RMBvtShnIEi6fHeKR+nPF6n4232aAEP/vQ9yASSWnRwu1qvJ0QrfUeEMIcF6xd04Rye8a5p6W5MYYNSXxPnXBSkGrJ9WQM7WmihoU90jx++RBaC9bfudc0Ei4ogbcqeO6jZ0jqEE1luNsWVpSBB+d3J/hU5RasvgXkaGcP8OjaFHYUzlCipU9708PpGYHQF2tzfHrhFtxSwj0L12g4Q9Z3qtihIN/yWO+PE2ya76M9h6dePcSH0/ezGxYYRB6DnSL+smNGilMp6ZhmMG1jh00TOZ0rskAQRp6BUU5kJBWJKpgbsRhZ2H0fkWu++unb+VLpNu564znuq13i5fYM11bHmJns8KG5F7gcTvCFzkl07phr3tN0J13urlzhV6/fS/eBaSa2FP7iBrrbQ/93dNX/pOvPZrE7NsNZgTzW57sPnuOvjT3EJ/s384vPvQlSaQIYBWTlHGzNVBCRaJudUZH6RVOQL21N80zpIHloLlH9QkbxqWuo+Qmufm+FtJrfCFm0qwk3lVboZgVW4jrn2lOUn/cJthS9A1UWx8pUr4PTiZCpS6lozpG5Z1xyWWGvr1CE1nGLpKpRe9bG+FBENGVTPWcz/8UE5UjyQGKPFP65VdAa796DvDA7y6HqLh+Ye4nfunIH1V8r4+3Ge1HLGmura4QYynj1b6jShpry4girGzI4Wqc/Z5PUYDSXIyspmbJYihtoV5HULOyRwL4YEB5I+Nuv/yJH3A2OOG362uaHfuFvMfXvnkLcfJydOypYEVhxjrYs2rslHiwdxR5IIDeS5bKRkAabCb4lsGOXpCioXQ5xzi1BrUKyr044XuCht57Ab4aw7WGFAqcPMrHwOpq87KOloHLO4dLWfvMh0NBcgvGnO4z2lVj+XkWhFBNOVHFCDysxMNEsEESxg+eleGMhQsCZ6TVOlDfYTspshGWef/UAJ//VFtpzePbQPo4Ut1jeqeEse8RNm++pvMQL3gQPFQ4TDmxKq4rS9ZDde2zeEFzlXw/fzsJvXyHb2OS/v6f+J19/JotdJynVK4quLvPp7dt4ePYwjp0zP9WiH7t0Ljdw+gJ7ZKJ9VkaT/Cf9eraX69SSxPC9X6zzkd03QC7onMkY7rMIDh0hK0A+G+J5GSPLJ4wlJBb//uybqJdG3NpcxbNNqqbMTSihKmcMZx12bquSFQSjKeNXr1w1zq7+PousqA3TPQIkHKi3qLghG0sNvC0br6OxRxlpxSUuS9JAYO0x2NKKxrMzotzmetRkOPQZ6+cIDds3F0grMP2YwNra/sY1sjS5L0gEdI4UEapAOC6J66bxV1yyiZoW5RMRh/xthJujhWMcfTnYOw6/dPE+yn7MWDAkym2KGwq0Iqt59OdB5oKo6aNcKFS6+FZGUs/pLRj/e1IxzTnHoNaImpqsoNGWz1g4TTQRsHvSIalpGrMdGoWQ5XMlqldM2GL/eMpwYJH5BYOUrhnHGibCjeGMILm/Ru4CHcGo7+B5MJiRxtgTa0bTmptm1siUxYuX9iEii9VylTFvyFZUYmtUNtvyPAccbDunbEXkmUUwELR7BZ6Lp7gaTyClEQvZkcLeHVB5aZL3V/4yPFtFj5b/X66C///1Z7LY1WhE9dMvUHNdE81UKrD67gn+3k//Bn3l80/PfpjiKjRfGmJfWiE5s8D2zVOMdzTWMEEMIw79P320Y3PubzT45/d/nLIVMm712c7LfLl7mmHmMX6kT8FK+NVH3sTYpyx2zlSwP7hE1Q3Z2bO5ZmVoTPRQY5LwlEU5iLirucbV/hjDs7NUznUYTjVJmjlOx8LtCZSt+d6pZ2haA77WPkXjrKKwlWC3R6QVl9GUId725w233Z4eUHZiuknA6qCK3vJwtzrkVR/7PTt87/yLfLx/P5NPY4gRe1DNpAIgGC1kWJUEuUde0ReLzH01pHcwYPpdXd5UvMC/D94I0je22hG4HXBfrJIBa44ZoTWfb5EDg1mXsTs3ca38BtFlPBjgWyml+R4tr8TkvjZ/99CD9HOfL2yfJswcTtfWmPU6/MLYm4EyvYNw25vOsy9oc6awzEh5/MfNfdQ+8xKDn7mZf/TGT7GSNPmdIzczDD3ivreXeCMQqcA52uOHjn6dpzsLnP/sUdyupndIEy2khtEfCoqHu/zjfZ/hxXiWc48cpLgGa4UGZTdma1Ci2yvgdiTkCoSg6CVMOl1UaBNsaqI1n09s30GiLIOpchVuR5FfXmTml7cQv+FDvEze/+Y+8/+31p/JYgdQUQRRhN2sk0wbhjqARJGXFHHNQrvSbHGHKcGOyQtTvo2wAiOi8CzwTHjiRlrjlXAfkXLIlIUUisVRkyi3cboStxdjhzatpMAoc80WvyhRfk7gZHRDn9HAbFszZaG0iZ0iTlA2yGJKlgmS0EIVFJFyGAqPvKiIGhKZOwhVIi1K05zbc6FpG5JcIoUiTB16I38vR9140VudIs9U5o3byrZB6Rtfl1Y0WpiJRD5wkOWEUiGiXQsYzBsi77PdeVJtkYQOroCsoEmLhrmm9opcS7MbUAUX4ZrjR5TaWMLsOByZU3UiAiu54fX27Ywj7gbbeZlEWYSZQ9MZcsxfQ1qmiWclElsoUm3xcOc4m1EZv61QIwMGnXXaWEJzoNZixytxfegiMmN60a7CthTdLCBRRhefB+aaq4FtIrNc4yrrKo9EW6Q1RZRYWF5OriWek1EoxsQFHxx7b8xofn6nlDCacgDN08vzJriz4+L0LOxBH61yVL8P3wZF/tr6M1vsAAjB+jtnqH54jZP+kOdHC6ZDfmqJnQNFtsMJJuM5RJrTeL5NVvEZzBuazO7tOYXxIfsrAz6zcyuPv3yEfZ8XjCYs7A9uM1YYcvnhA1SvaKbaOSJVOH3Ns2v7DNJ8ThGNC4oTQyYKfdYujTPzMAymfR699yBZbHOwlSIGI5Ia3LywQj/1aS0ENJ2MhztHcYTi0Mk1+oc8VtdrOFs+XltQWVQ4w5xguQ9ScnFfBeagNSgQr5QobgvIcqztLvt/bZyd0gHGVvvIsQYy1xTWBeEE1O7cAiD88gSVRVh9q89NB64ix9fgTrjQmeDVzx3jcvsoQUOQljTy8IB3Hjxvvi53ybRkOyrRiQK2s0mmtiexYs32pQatYk5hbESlEHFP8yqHvU0eVodxt21akwFlkXIpL3Lu3Bz2wGI0eZnXebuojkvz4WXsaI6Xbpkmjh1qny1SWYxoXF0iw9xgiiLhuLvOj0yFXI6n+HeL9+PuWqQHQw7O7LDRK/PRr78OJFjHQuJMUHnWp7Sq6By2GB7IGEUuv7L9Rop2zA++4QkALg/H2Y2KnG5scFNphV/iXrLxiqEAKXMj/rFTT9I+VuATT93JoX9rsulFOoQsR69t/ql31v8k6892sWPA/bc1lpFCM8g9MmVRc40E9GoZ4rqH0zdMN20J0oKRjdZnutw+uUI39ekkAe6OTfmZ63iHJ9nZgy54bSgvx3sMM/OUiyMXaeUoX6FcE62UaQsZSdxeilOW5KllpgIqR2sjGy05JlqqaCdkWrI+qgLQ9IfMFTvEqU0nL2NFDnaocAYZsj0wEVdRlSh3iCMHuy+wRyYmizjBv7KNLw2hRXsuWgrDyxMwURygtGCjrykuD7FGZWyhmPR6nAjWCHOHZH2S8nJC64RH7kPBT7infBlfpkgUI+Xx/GiBZafOq4UptOuAMPFZOpHEkUtfQDcLGDqe8a9rjAwYwVB5WCOJPRJYQlGVvplQZJkJp4gc0pFLZTHCObeEGoUgJDKD1axOzRrStAa07AEogUzAshXzxbYJkmzbKE/j1CJyy1ybYCthOBUgUkGa2KyOqoz5A45UNynLkFZapJf4JuZKZLh2RloJ0JYgTDKuRBPUnSFHgk1EKpAvX0ENh/+zPuLf8vqzXexaM/v7XR5fv4vWacGPvOdBulnAA4/fir8lyQua1bfYZA1NfULTaUuKLxukU8WPmfR6NNwhmZKcKy6AlGS+xYmxTe6qXeP/PDGHcn2cvmHORc094qgAvBwySe9qjfNxnbyWs/VTIbVCi/eOLXN1MMbuzAL1nTpuT/DE1UMUixEL9TabgzKds01kCtcPDZmoDYgSB2xt0NYS0pLN8J45ck9gJXDu/Bylazb1Cxluz4AfsG10GJmoo+kmWT1gMOvSX4Csolju1Ahjh4ntHGuzQ/VSmd+vnbxx+ay+xXiiyX1JZTGjvAwrtRqX908y4fQ47q2xkdX42JN3UViyaVzP0QWP3n7Jmbsvcb1bJ3xqDDkKeOCpu/m8BaPDCQfvXmU8GPCp3q2sxTXkbEiqJAe8bSSC9935PL/3j28BS+Fog5deuy/AO3WU8ecGWBeXmHgu5n/9tR8mmlScuOU6SgusgUQomKj3+fPjT5Dq+3hsqYo9lDhPlvFDKG6aa1O/lFBelbSOBYSTDudbkzzz2dNGsHT/Lj988Gn+wyv38cTDt5GWBIsfyEFB5cEqX/nUvXvASTh4Nf6fMkb7k6w/28UO6Odfpfo8yO9/PaX3RUTKoXxFUr2WsfYGC/9Il3fMn+dnJx7lVzq38OtX3o5MwbMyqvY3qB/KVSD/f+2debBk113fP+ecu/Xe/V6/fZt9xpqRNNplWzJesLGNiTEmkIQChzihklAVlmxAKlWEpKhKQgVclVQoMEWIMWC8L8SWkCxsJGsdaWRp9n3ee/O2ft2v17vfkz9OS5YpQwK2Z2Het6prXnfPm/vr39zv7Xt+5/f7fo1yy478Joe9y9SmOmzFVdyGIrONm4khu0ZaGVkm8DYkuTVN800Jv3rrp/GEEV18wt7H5ys7SMoe1gD0mktvDJKKpB84FC8KrEDTqHlsOSlpIhEqe1W5NHUl3XlJkjN2Q96KRXExo3i6ZYpJAJaCXgxpinYsopJNWBXEIwk4Gf2BS9y3cToJut2hsJbiXzKKL5b/DdXczBbkVgNUJ8A9XGc9KpGXEQURMcgcyqctRo9FKD8lcxThiOYnpp7kj9S9nF0Zpbhi5v9FknF6usAPTr3IWlzmeHeKQeIwWu1hy4wxyyiufGD0CW554xWOdHfwZ+f2IgQMdsT4U5LiSo7SZQ/vfIP5jRydA1VOjk/gOAkqNAM14/kur/dCHi+s8+f2AUQM1XMJTjtBDFWA3Ss9cu0ecX6WOFW0ezkWvtzHvrzBibsmuT13iWTtHUx+9BiDB/Yz9+5lwtRCfLqOeuz5bz7Hvsvn8HcKf+vJ/gpkrDk7mCCnIjp3hXT22BQXttgz0mDU7rOWStajEjI2W0Fnjs9wZnkcqQx5ixcsSIzz5idOHebZsQW2tgoABFMxwbzGzkfM1bdoDXL4x0pmAs6CcEQgmg6/9NL7KOUCdpabNMM8/TnInAKpB+6mRHdynF1eILM0/m0JuClz002mi23Ob43S3CoaIURPkniCwUxGVkpMX3Uk8MckuZkywajN1j4jEmn5M4gM/PGMtJZAmGC1FWlBUKx3ib2YjdurlKuvY2uPwp9MsbsSFRiJqTgnSFxFnMsjdB4ZweefP0x9us3CvgaD1CV1IaxadG5zCOsaa0+XM+EEJSuk+WDE5kAhg7zxao80v/7Iu5D1kEOzV/CsmN2VTQpWyKjsk5Dxm+tv4ZEjB03no5cinZSxiS0AOmcnyK1N0J/J0Z1TBHWN58W4dkx3d58wk8wXWpyKU1ZDsxTSFvg1RZyTxEXjAutueXitEoknWD8+jooEvXmNXZ9F9+C/XnonhWWJThLyF9ssfX4HIoOZpdW/kXDE9YCbhuwq1Jzt1tlXXucDdzxp1pwiQ6EZsXosJlVWggpWYPTa689JwH1VabR8OUYnCVbLx3lhhEvVAsLTaEdTn2nz1pnTqGGl9km9k/yxlOKFHmv3VejPa7wNiX22QqdS4al9VaSTwk6f7oLAPpejsKxx25r8WkRrv8vhnzzOg9XTyOG/+Zn0DrY6eVJHm8GZkiC/0Gam0mZpq4rfd/D7Hr2OQ3svvP/djzPjtliPy8SZ4q7CRfY66/zSxfdx4aGdRFoyWhhQsgNeuD1Hb94mq0bkKz6D9QLeumVqGEPjhrBqHFrcJkx8VdE8OMr5HWP0UrOWD2qC5L4uHzzwFO0kx+n+JFV7wC/f/1kKMiJFMMhcfvXT72f3x9qsvrGK/0M2o26fW0tLjKgeIyog1opHT+1n70cjOjs91h4AuxDx/TPHmLK3+NWdP0h+LU/rdRLvjiYVK8VWKY5KeXD6PFNOm6IKOBrMshoYFdzMgqBuxCr6wwukvWnhNmysAOovmOam7oIkdSV2W3P2hTnGL2VkQQjHTzN9+jw606TZjUr1m4js7mbIma/PcaY+zpv3nGF3foOa1acsffqZy5lwkpVBGRUYf/TMMm2zKhw6cgJUSmR5B2tg7IbjyYhybUCSSv50cb8Ro4wtgpbHhCcIJvOENYirKalnvlUyV6M1pIGFalqoSJAUMloHwfIFdtsjLmueWZnnXKfOLbVVxpwul9o1kvUcKhH0FgRxKePQyCbzhSZhatEQBQLHaNergeDLK/sYL/SYyrUpqpCz4QSbaZH1vplCU6Hg4tooQmbYKw5OW9DPSTwnZiCGJhepsUVKHQgmU+RoSHfUIagrkrzmd46/gSS2cCOjphuu5Pk9cR8jxQF7qxtmIjDLkSHJy5C8DEnnAlbfUKW9P+XByhqZlnxq6Q6CxOKP8n3yVoR1xSX1ItBgtxRBluMrI3uZyHXRoxEbd7ik+ZRgs2gktISZbxjL9XBlQiMukmnBUreK6g27/oYrMu1o7FJI4kssT5E5pk1ZJOC2zLZk6hg3l/xaYIQ44DsyT36tcdOQXT5/kgMXqkR7pnjq5xao7hhwKLfIQWedRwf7eLRxgMurI0xuapxOSlhRRss9MGOQWgj8nTUy2yjWCi3Zt2uJn597iH/y7E9QfqiAN9B4zYTUFbT2Stq7JdEen5mxNgU7omCHrA9KLK/UkG2L6T/PyK0FnP1pxf964++iyLBFyv9uPMATv3cXfrvCF99cZ252k86JUcZegvZe2P3mC+wqNnhv7Xmq0ucL9mFO5Cd5eq0IQpFf0wRfGudsaZzFe5vsHmnw1MYOOr5Hb7VIMTP98OLpPCrSVM7HOO2Ii8UC9X0DmlTxWmYl2isK4hLcefgcPzX1FbayPFtpgd849lbm/otARiGrD+QIqzD151C6AItvnyR8Twtf2pzxJ8jLiH25VapqwL+/+0/o3+kyY7e4xVnjD7fuofvZKSoXY6JBiSRKmRpJ6U2b/fraCUhdxdL6HBdKGffff4p/+sBj/KsTf5f4i2OvrsGTguAle5rBmENjUKDruwzWC5RWTQU+v5GR2oJ2MeHA1DonskmiMEdaThib3aKxUWb6N2PU8YvDxiOJ9n0yfaOsyP/fuGnIrsOQZHUNu1ZGaxdXJjTTImfilHPBOKv9Elnfxu6nWH5ivtGG1bDMFqQFQZw3Fs6vGCOMun3mVI+8F5HkiogMUsfM0GtpqrVSGdePUa/PXL5FlFlc6Y3htCXuVohqDcj8GltpnnHVZU6Fxngy1Dj9DNWyWMlVkKG51RSZYNPPY4kRnnb2UFIBS0HN2CUPh3NEorH6ZrAlThVRZrHRKpFselh9SWqDysDtDC9kliCqOGhlrIWwMoKaQqSmWUZGmMkt1aOb5WglBYKBg7WxCUkKumpELYTxTdcSs4WYKV7qjGGJDDmqmXWaSKHxhBGJfMpf4MX2DG47w+7EoASZo4iL8jXCFprMEmZ0XUOQWjTTIj3fpdg1bceZbdbl3bbLJatGv+uh+xaqL0k8c4cWDaTJn8rMRF6kcLsChDKjzz0L1emSvkaW+W8bbhqyvwJtK+ZqW9xbPM+HLr6Ni0t1CBUilBSXJPkLDUSnj10pkuVs2vuK9GYlvV0Jbz58go2gyLHjc4hMMOW1yYCf2f9lnpnexapf4kJrlE4nR/G5HMXLms0Jh8GIzVS1zfsqRzjTfSeTTwgKKz72eg/SlPHHLf71+gdIdwa8/5YXONqcxa8LtJSMvATyqEd3XrBxb4K3aqE+XGczq/O5/E5SV9DZCVE9NYo4hxKsjjJe30MR1yhVeM8WmH6sTfO2Mhv3JThNRf2lGJFqLr/Txl7ok0Upi1dG8CohYz+6wqXNESqfKVC+nPHSvVMcHZ3j146/HfFkhbE1TVbIoT0zi55ZmrV7YeXBPFN7V3ln7SU+tn4PWx+fwRrARx+coj7dpt3NEfdtrIZN6RKoEJxY013wWHtLwp6daySBRxI66OF+vBCavG1uo48e3cXJh/eS29DkGwlRUTGYkCCh9pyNiipUW0bAc+MOi/zb1kkzycZaGVKB5yVcblcpft1l9osbaKXI8jYy7KAvfUuxpb81uOnIDpgeZowtlL3iGKWWzFgpESeQJBDFCCHIlFEgdUd8frj+LGfCSU5WJ0hDhSdjIi057C5yi7vM+Wicr+X38Lw7Rz/N4fQ1IhJEiRH2H1EBmZbkNmJD9EyDbZFfTxCZoik9XpqepjHIk7lGTTW/nuJuxXTnPJzRANaKlE+0EIMAbSlwHVJnBG0r4kqKXQ2JtUtmWWgJSSLpRS65hkacOIe3cBu4GZmlsPqGQNm45oH58zyzMk+nW8IbiXnnxDH+TO1nI9qB24zxfYeNpER/vcDC8RhrkIIlyVwLoc3QSzQSU6t3OTSywqS1RZJJSosJdiemdTBHq5gna7i4LeNPVz/aQ9uK/oxHXBTMzW3ywdnHOdLfwUtbZsjnFUMEKTR+YjNojVI5l2H7RhtO5OWrZoalLY3bSnAbPqrVRx2YZr5sBCGC2CKKLLJM0Ot71Bqa9OTZV/3tsqt4/l0rCH0V1yRlMaLvE2+7asf7VlD1UTbftY/BpKC3P2Jieou1pRqF8zZJDsLpGJRG9BQylBSuCPKrGX5d0p8xU01gptkO3HaZB0bPMWL1GLF6/Pbim1j//BxOR+P0TF6bByTBVAJuhuUlJIGFvW6/6qMtMqicgfLFgN6sS3uPJHU0ad78vt02vuT9HQljcy02lqqMHLFw25rKqQ4kGcvfN0J3r9k7V15C2rexNywsX5BbM3bKmTUcp/UESQHsHlTPxmgJy2+y0HMBOycb3DmyyHpY4ly7zpXNCiMP53B6GSvvjfje/Sd57JHD7P7YFghBmreHt+1GjmvpbQ7Fg032jDT4npHTXA5HeWRpH3GqmCp1KdghR1/aRfmkwu5p8o2UxBPDqT/wFyJy1YD4bInKWVP0iyq8uiTSCuJdPpNjbdaHar39cYvGfSkil0DbRoZmok1Gprhq902/gLdlvPfATMSVTm2RHjt1tU+/7zqe1o/S0U3xrd676b7Z08Ym1Y88yUipxOn/eJD3zL7M7/fuQQU2g+mUD735o+ywm3yuc5iTvUmOfOkWJp72KV0CjkBUdWjcahNVYald4Tk1z3yhxW5vg3OL47zu4xfRYUhweAdhzTJOq9JC+WD3HPwJTfXuDSquEb8MU4v2+jT2apuKn8dr5ehPWGzcnyEKCUFVQibIjwyoeAG9UZ/2viLupqS4aKN6IakLsmi2DHQmwMqIqykiVYx/rQVnL7Lx43eweW+Ce8WmejpDxabSnlkCrykItcfojj6/NPYkv7N1kK+c2otoOsZYQUl0JljxK9hdgVxroot5sqqHSDLsE5exwgj3zlsB6MUuF4M6u711Hjr8BLaQPDKY4Gw4wQtqJ+6WIV1QVSR5COpmKMXesMmu2Ew9n1L8yhlEtUyws05mmwtKkpfI+7f42Os+wrvDf0z2ZJkkJyhO9BgtDIxHEcaiSwPNpyZZ+IPL6G6XtNOD12yb3bgbaH9z3HRkfwU6ihg9Kvjd7M0UliTVswlg8eErb2Jv0QyIVG2fYCZm/a4CKtRYvvmGVAG4m4L4aI2XvSqXDm6ye9cG4+NtVn5gAZnAYMJss8nIiBBmDvgTmqiiiRJFI83TXKkg+wqnDovvncTyzR5/UBeUprqM5H2WNmqkPYvAd1gRZfxGnsplieVr+rM5tMgRVTRSaqrlATOlNlthjivNMnGaQ7sKYdv0pwV3HbjAC/09lJZC4qLF5kHbXCgicJuCZ87s5IPZD3B0cZbS8x5WYD6zFpA76XFyeSeFLnTvWyDxJH7dFL30PfvJLOgfCjhQ6rLcrnDizAwyn/DxybuwZcrmoIAf2chAMpgyQzVhPUVoYey4gLicINyUjcwjLB0wo7jKOOPmV2OcruZyo8qneq9ja7XE2HpIVJTEWpBkkpVGhaxvYW9aOG3B6FljsqCD8NUttJsZNy/Zw5D6Z44z9lAOnWWQpjjteY7N7+DY2BSv332BvYV19u1Z4VKtRthxsTdsrIEgv6KxB5rSRR+rNeDMP6yT7hJ8z9RZXvwRn1RL6iIjTC0WX5yisCjxJzTJTIi0M6LEwh84jByxyK9nLL0r5gfuPMojF/cTP1cmGMt43/xJZtwWH+69kX7HJuvZ9Hs2+csWoy+HpK6kcbtNVNEk9RjXSnnd6Cr/aPxxTkeTfMG9jZN6gjRnFGfD3QG/veNz3H3pp7FfvoTYP0dwOKZU9Im+NkrhSobdczh1fB9jixkjX1tEuw7dQ3USVzDzVR+r2ad55ygrb1SkXoYuhXjFiB/f/wy35JY5H46zFpc5cXqGhc+CVjbt8Rky2/QlSAtUXdPbmVCbafOzex7nXDDOJ47cjfAlE7Mt9tXWWZ6psnG4QK+Tw1p2cbYkpcUM1YmQl8r8weg9FC7Y2OcvkyvP09Xm29y64JFfFYy90Ec9fwqdZqTxNbEfvC5x05IdIPMDRDxcPEuJGkS4rRyhcHk+N8uF4gh+ZGNZGaEWZjIrGDbZaAjGXWTNQWj44uohlMywZIbUmjC1CBKjaGr3NHFJEAemx07kNEplRCWBCiWyJ3hscS/BaoFK18hUrQQVIyYhNNgZqmXjbAlyGxoVJAitsHs2mRKksymT1S5FK2I5qbESVWn6ebJM0p91KYgFyASf78+TdWyEbZM5CmXFuHaC75nGkrAqiCsaayBJJqqkeZvOnLnVRnh4RYtgRJJ6KSIVqDWHwFf09pgK2ddauzi2OkVuycZpD0gKFtpSaGVyIFJznFiYKns384i1QnoJWWbR9V3OyTrdwCXwHYTUxGMxSd6iecDD7rmoUHDlfJ1yCNHeaaKyIrhUwlclakuQa6RYrQHp0GBhG9/ATU12HYboKEIoBUqhmj1qp0rEOQFHS0SyROegxtvVRXYV5QsZaujCkriCKw9KxFQAly3WPznPYEYzcuc6SmganQKRb1O5IihfChHaIXMsoopCVnyKhYDWLTb9vqL2kqT2OQ+IgZhux+XpPTsYrfaQQpOrBjgvOkw/bJYXKIm2FaPHIKzZ9O71+fmdD3NksJOPrd7Daq/ExnIVMsHKW1OQCgaSX374/VRPK7KJEYJRG6VCXJUSTBlCWTu73Dm9zItXZlgql4iLmoX7FpnKt3lueZ7VVs7EKDTuosPsl32iqs2Xd+wjnlSc+D/72PHFLUS8aUQ55mr0p4109+RTKbnlPlG5QjANfd/hic09JFpSrfYJ8jbB5RLNrYoRw5CabDrmvXccJS8jzt9dZ8Mv4n9hlvkv+jQPFTn3Iw65Fcnej7RRzQ56EEAckfnbRP9WuKnJDhh/90wjFBAnOJ0UGZvGmMwCBOTdiIGrSVzjua6kabTJnAzPSYiFuQCIRLxqFRX2HcTAwh4Y7TgZO0N3GGP+YKsMtxgSWTYqdHEvN9E5l7TkYoUOiW/RcTyzXRRLvFibqTtbkXm2EVJwJJkC106oqgGS4fZU6KA6pgHInu9TzIU0Fqu4TYWMNfFIjqgkUeqb17FSZhRURCkfsDlWIMunjA095gpeRJiz0alApxKRgL3ZR2R5Vrt5LpVHyG1oxMVlRKGALuZJXUVS+MaknowSM0uvIUsV7cgjzSRBZBOFttHwT80Un9CCKJa4MqGoQuZyLSyR0Qo01pUm9q4C2jJNNfLKBsna+tU+c244bJMdEEohHAcdBORPbxBPVDj3ozmqu5u8bWKR15fPcWJ6mmf2LdDoFfDPlbF7gpGvS5zHi6zfo6n/6BJ26NFolUi7NuVTFs6WpnIhwGr0SA7l0XsGlHIRE8We6Ugr9PATm0bJeL9lnkVYc0lcgdqyCHpFxp+F4lLE2t2Ck/+2jA4U1pYCCUk5ReRiDhV6PNo9yCB12Fve4HKjxsQzkLiC/G0d3j31Mr/VeRDWLHpz0NnlklRSdhX7pJkkf9GmfDGj06rw5bVbsKoRB++8SD92eOrsTnTfIr9oUdnS9Kchmo1AgrYkMoixjlZ4/vI+Zq+YJVE6NcLWgSK9GUntgHEd7ZytI5MymS1QPUUqoJEv0O94VJ71yAWazftj6rdtsnhhjMIFC3dd8cfP3mO07TOBiCQLFxOyxia1JyXFSyNYnTbZVvuanTs3ErbJPoQQAqIY3Wyh8h7WlOb9Cy9yKLfIXrvBDrvBPm+V44NpPtO/najhMnY0o3iqxdp9o/zk7BN8tbOfL60fRPUluY0MbzPFavmIQUBmCcZrXYpOSNXxsWRKTsX4qc2aY8iulST1TIVbhgLlQ/VUD75+muz1d/GeQ1/nYn+UU6tGyXS22qFgR+StiAuDUcpWSNUakKWSwqJPUrDI2xG3ekt4uYhY5ogrGc7EgKIbU3F8mkHBeJAvhSQ5j8yxCAsJ99Yucskf5VJjGrdhCmReMyUu2ERTRm0GKRFJRm5dmyGebgKWRVJ08OuScFRzqNYg04Lj5TpxwdwZyRiyRBBFlnHDvZiggpStt2Q8MH6OP96sIDILayAQV2yjk5cN23abA7IgILu0iLi0eFNuof1NsU12QKepKdbZFiKfAyBu5Hh49XV8OrqdMFGvyiMhNMpNyWoRrb0eYblOVo45FUxhiZQDCyt0Jj2u1KvQs5l5pEK52SWzoZ7rM51vc7Bg2jLP+BN0YyO1nNYKpAUbrUyvd+YaMcjefJ5itgfLhz85eQix6lI7Jkg9uHh7DlWOSPs2xAJRTCiWffQVDxn3sHua01/bwT+f/TEmxtosvO0UjkzIqRhbZJQtn7NyjIE/hd3oMXgwx9gbVshZMc9vzXGlV8HqSew+FK7EuIst7E4Z/6ILpHT3lNACrFAjE1i7J0f8lv14DahcSBCpxZWeKTQ6WxpvM6Y/pcxn81KK+QBfZVx5UwmRKLQOeGjpAFzxcFtG+SeYjRCBYuIJQWElwlrevKba6zcytskOkKXoLAUpkMM2U6ehuJQfxV5xyK0LCkM7oGBEENzTp1Dx6S7YhDWJXYy46I9SsX3eMX7c2C7N2qxEFR45/nrKfGNwZsHb5MH8GWItWYmqXNEVMhuSskuSU2TKGDtmrkZbmv6kBaKICjXuiRyVCxm1h07BSJWwOklYlxRXJU5bE4xa9Mcd8qvmG1f6MVNPevgjLpUPBHx0xyMspwNORjUCbbOV5umlLkuBho0mwfgov7Lnszze38cnLxym3c5T6IPV17jLbdIz55FnoACoW/ax/PY6WkFpMcWJMzbeqHnH4Zd59CuHmfpKGy2rtAY5LJnhdTR2c4BIXTJPI72Uai6gnh/AXVtEmeLy6gjNxSqFDYnbTglHFGNTbZpbRSqnI/SRY9tE/zawTfbXQObzJPPj+FM54l0+t86v8LKcxhcuuTVB/lKCjBW9DY9O3kb5RvMszST9xCGnTBfbSlTlsxdupd/O4Y3A6vfP05/L2AwLvJTN0IiLxFpxsj1B08+TuprejGNaWfOmRVSNhDhuTPuWIr15SVJKEcUEFXnUpAJLEZc1aS1hoCzCUbMtmFuT2D1NNJpDRkaYUqSajX6BVuZzPBrlS+1bacc5lvpVllsVxgYZwrIonZP8s+d/DNtOyDsxhVJAf94mHJHYfp3iWBF/wmUwJolLAn8iM17ylkJGYDc1Dz9/K7VzIDp98isuzWeq+B6onKZzoEpUEa+2r9kyNUKgkUuUKnQmEFpg96CwHCAyj01vjHwfVLO5TfRvE9tkfw1EtczmrUX6s4KfOvwYH6we5T8Vv4eHCwdIumUKJzbIlfOEtSpRSaEt07MdhYp2mMMZGhGe7E6Q/3SF8aWI8/8g4h0/eJSLvVEWOxUGgUvQ2guZEVJEgCxomgdN9T/LpVCKuXt+kUmvw8y+LYoqwBYpjkj4Ff0ehGu28eLxmIXZBrZKUSLj7PNzjB3NyCxBd85BRZraiy3cQcClRp3zicOX2rfy+RO3kvVscksWdhfc5gBcs7Wnv2qz9oYqhfcvM1vawhpfJUoVR6fm2Gh47D68xH/f9UmOBAv8/tJ9dAKX3sAjDi1qj7vUj/pYGx2S5RXEyirzx3LI0RqLPzRL8zaN0BliaHWctyISreiFDkFkmyo/kGtkyCMnKQLlP3XRaUqyvZ32bWOb7K+FMK6uma2pqAEV6VFUIZaVGivuNEXExp9bZMJ0YEpgKIv8CpJMYfkZ1iAGZTPjtmiERbJMkqYCEUtIzQw2kqF/O8bcQGmUpXFkiisTapaRSlYiQ5IhrdcMLkmNrVJyVowjE3PhiM0cu/F4x0x1JSlkwpg9ZGYrT0RGlVZF2kzfCYEII0QYoYKqWWdLI20dSoXlpCSecXbZZws2sw1yVkxkKyInIUslIgXVjyAIh0sj0N0uwnXMZ3QyU1vITIFPCv2qrLQeSkyD8U3XUQRak94gyq03Aq7q1JsQYgPoA42rdtDvDOrceDHDjRn3dszfHha01mPf6o2rSnYAIcRzWuu7r+pBv03ciDHDjRn3dszfPchrHcA2trGNq4Ntsm9jGzcJrgXZf+saHPPbxY0YM9yYcW/H/F3CVV+zb2Mb27g22L6N38Y2bhJsk30b27hJcNXILoR4pxDilBDirBDiF67Wcf+6EELMCSEeE0IcF0IcE0L8zPD1ESHEnwohzgz/rF3rWP8ihBBKCPGCEOILw+c7hRBPD3P+MSGEc61jfC2EEFUhxCeEECeFECeEEK+/QfL8c8Nz42UhxB8KIbzrPddwlcguhFDA/wDeBdwC/H0hxC1/9W9dMyTAv9Ra3wLcD/z0MNZfAB7VWu8FHh0+v97wM8CJ1zz/z8Cva633AC3gg9ckqr8cHwK+pLU+ANyOif26zrMQYgb4F8DdWutDgAL+Htd/rkFr/V1/AK8HHnrN818EfvFqHPs7EPtngbcDp4Cp4WtTwKlrHdtfiHMWQ463Al/AGFU1AOtb/R9c6wdQAS4wLBK/5vXrPc8zwCIwgmk3/wLwfddzrl95XK3b+FcS9AqWhq9d1xBC7ADuAJ4GJrTWK8O3VoGJaxXXX4LfAP4N3zA3GQW2tNavDItdbznfCWwAvztcenxYCFHgOs+z1noZ+DXgMrACtIEjXN+5BrYLdH8phBBF4JPAz2qtv8ntT5vL93WzZymEeA+wrrU+cq1j+WvAAu4E/qfW+g7MzMQ33bJfb3kGGNYQ3ou5WE1jxvvfeU2D+v/E1SL7MjD3muezw9euSwghbAzRP6q1/tTw5TUhxNTw/SngelI4fCPwd4QQF4E/wtzKfwioCiFemWy83nK+BCxprZ8ePv8EhvzXc54Bvhe4oLXe0FrHwKcw+b+ecw1cPbI/C+wdViwdTEHjc1fp2H8tCCEE8DvACa31f3vNW58DPjD8+QOYtfx1Aa31L2qtZ7XWOzC5/bLW+seAx4AfHv616y3mVWBRCLF/+NLbgONcx3ke4jJwvxAiPzxXXon7us31q7iKhY13A6eBc8C/u9bFir8izgcwt45fB44OH+/GrIEfBc4AjwAj1zrWvyT+NwNfGP68C3gGOAt8HHCvdXx/IdbDwHPDXH8GqN0IeQb+A3ASeBn4COBe77nWWm+3y25jGzcLtgt029jGTYJtsm9jGzcJtsm+jW3cJNgm+za2cZNgm+zb2MZNgm2yb2MbNwm2yb6Nbdwk+L+DlbBNtGWo7QAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "## dummy transformation\n", + "dummy_transform = transforms.Compose(\n", + " [transforms.RandomRotation(45)])\n", + "\n", + "dummy_result = dummy_transform(image)\n", + "\n", + "plt.imshow(dummy_result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice you can put the transformations within `transforms.Compose(...)`. You can use the built in transformations offered by PyTorch or you can build your own and compose as you wish. In fact, you can place as many transformation as you wish in there. Let's try another composition of transformations: rotate + vertical flip. " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "## dummy transform \n", + "dummy2_transform = transforms.Compose(\n", + " [transforms.RandomRotation(45), transforms.RandomVerticalFlip()])\n", + "\n", + "dummy2_result = dummy2_transform(image)\n", + "\n", + "plt.imshow(dummy2_result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's pretty cool right! Keep trying other transform methods. On the topic of exploring our data further, let's take a look at our images dataset. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exploring the Data\n", + "As a practioner and researcher, I am always spend a bit of time and effort exploring and understanding my datasets. It's fun and this is a good practise to ensure that everything is in order.\n", + "\n", + "Let's check what the train and test dataset contain. I will use matplotlib to print out some of the images from our dataset. With a bit of numpy I can convert images into numpy and print them out. Below I print out an entire batch. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "## functions to show an image\n", + "def imshow(img):\n", + " #img = img / 2 + 0.5 # unnormalize\n", + " npimg = img.numpy()\n", + " plt.imshow(np.transpose(npimg, (1, 2, 0)))\n", + "\n", + "## get some random training images\n", + "dataiter = iter(trainloader)\n", + "images, labels = dataiter.next()\n", + "\n", + "## show images\n", + "imshow(torchvision.utils.make_grid(images))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The dimensions of our batches are as follow:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Image batch dimensions: torch.Size([32, 1, 28, 28])\n", + "Image label dimensions: torch.Size([32])\n" + ] + } + ], + "source": [ + "for images, labels in trainloader:\n", + " print(\"Image batch dimensions:\", images.shape)\n", + " print(\"Image label dimensions:\", labels.shape)\n", + " break" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Model\n", + "Now it's time to build the deep learning model that will be used to perform the image classification. We will keeps things simple and stack a few dense layers and a dropout layer to train our model.\n", + "\n", + "Let's discuss a bit about the model:\n", + "\n", + "- First of all the following structure involving a `class` is standard code that's used to build the neural network model in PyTorch:\n", + "\n", + "```python\n", + "class MyModel(nn.Module):\n", + " def __init__(self):\n", + " super(MyModel, self).__init__()\n", + " \n", + " # layers go here\n", + " \n", + " def forward(self, x):\n", + " \n", + " # computations go here\n", + "```\n", + "- The layers are defined inside `def __init__()`. `super(...).__init__()` is just there to stick things together. For our model, we stack a hidden layer (`self.d1`) followed by a dropout layer (`self.dropout`), which is then followed by an output layer (`self.d2`). \n", + "- `nn.Linear(...)` defines the dense layer and it requires the `in` and `out` dimensions, which corresponds to the size of the input feature and output feature of that layer, respectively. \n", + "- `nn.Dropout(...)` is used to define a dropout layer. Dropout is an approach in deep learning that helps a model to avoid overfitting. This means that dropout acts as a regularization technique that helps the model to not overfit on the images it has seen while training. We want this because we need a model that generalizes well to unseen examples -- in our case, the testing dataset. Dropout randomly zeroes some of the units of the neural network layer with probability of `p=0.2`. Read more about the dropout layer [here](https://pytorch.org/docs/stable/nn.html#dropout). \n", + "- The entry point of the model, i.e. where the data enters, is placed under the `forward(...)` function. Typically, we also place other transformations we perform on the data while training inside this function. \n", + "- In the `forward()` function we are performing a series of computations on the input data\n", + " - we flatten the images first, converting it from 2D (`28 X 28`) to 1D (`1 X 784`).\n", + " - then we feed the batches of those 1D images into the first hidden layer\n", + " - the output of that hidden layer is then applied a [non-linear activate function](https://en.wikipedia.org/wiki/Rectifier_(neural_networks)) called `ReLU`. It's not so important to know what `F.relu()` does at the moment, but the effect that it achieves is that it allows faster and more effective training of neural architectures on large datasets\n", + " - as explained above, the dropout also helps the model to train more efficiently by avoiding overfitting on the training data\n", + " - we then feed the output of that dropout layer into the output layer (`d2`)\n", + " - the result of that is then fed to the [softmax function](https://en.wikipedia.org/wiki/Softmax_function), which converts or normalized the output into a probability distribution which helps with outputting proper predictions values that are used to calculate the accuracy of the model; this will the final output of the model" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "## the model\n", + "class MyModel(nn.Module):\n", + " def __init__(self):\n", + " super(MyModel, self).__init__()\n", + " self.d1 = nn.Linear(28 * 28, 128)\n", + " self.dropout = nn.Dropout(p=0.2)\n", + " self.d2 = nn.Linear(128, 10)\n", + " \n", + " def forward(self, x):\n", + " x = x.flatten(start_dim = 1)\n", + " x = self.d1(x)\n", + " x = F.relu(x)\n", + " x = self.dropout(x)\n", + " logits = self.d2(x)\n", + " out = F.softmax(logits, dim=1)\n", + " return out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visually, the following is a diagram of the model we have built. Just keep in mind that the hidden layer is much bigger as shown in the diagram but due to space constraint, the diagram is just an approximation to the actual model. \n", + "\n", + "![alt text](https://drive.google.com/uc?export=view&id=1NuFflDPOW_hIAHTH2pXZAEhSINygPlnB)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As I have done in my previous tutorials, I always encourage to test the model with 1 batch to ensure that the output dimensions are what we expect. Notice how we are iterating over the dataloader which conveniently stores the `images` and `labels` pairs. `out` contains the output of the model, which are the logits applied a `softmax` layer which helps with prediction. " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "batch size: torch.Size([32, 1, 28, 28])\n", + "torch.Size([32, 10])\n" + ] + } + ], + "source": [ + "## test the model with 1 batch\n", + "model = MyModel()\n", + "for images, labels in trainloader:\n", + " print(\"batch size:\", images.shape)\n", + " out = model(images)\n", + " print(out.shape)\n", + " break" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can clearly see that we get back the batches with 10 output values associate with it. These are used to compute the performance of the model. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training the Model\n", + "Now we are ready to train the model but before that we are going to setup a loss function, an optimizer and a function to compute accuracy of the model. \n", + "\n", + "- The `learning_rate` is the rate at which the model will try to optimize its weights, which is just another parameter for the model. \n", + "- `num_epochs` is the number of training steps. \n", + "- `device` determines what hardware we will use to train the model. If a `gpu` is present, then that will be used, otherwise it defaults to the `cpu`.\n", + "- `model` is just the model instance.\n", + "- `model.to(device)` is in charge of setting the actaull device that will be used for training the model\n", + "- `criterion` is just the metric that's used to compute the loss of the model while it forward and backward trains to optimize its weights. \n", + "- `optimizer` is the optimization technique used to modify the weights in the backward propagation. Notice that it requires the `learning_rate` and the model parameters which are part of the calculation to optimize weights.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "learning_rate = 0.001\n", + "num_epochs = 5\n", + "\n", + "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", + "model = MyModel()\n", + "model = model.to(device)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The utility function below helps to calculate the accuracy of the model. For now, it's not important to understand how it's calculated but basically it compares the outputs of the model (predictions) with the actual target values (i.e., the labels of the dataset), and tries to compute the average of correct predictions." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "## utility function to compute accuracy\n", + "def get_accuracy(output, target, batch_size):\n", + " ''' Obtain accuracy for training round '''\n", + " corrects = (torch.max(output, 1)[1].view(target.size()).data == target.data).sum()\n", + " accuracy = 100.0 * corrects/batch_size\n", + " return accuracy.item()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training the Model\n", + "Now it's time to train the model. The code portion that follows can be descrive in the following steps:\n", + "\n", + "- The first thing in training a neural network model is defining the training loop, which is achieved by:\n", + "\n", + "```python\n", + "for epoch in range(num_epochs):\n", + " ...\n", + "```\n", + "\n", + "- We define two variables, `training_running_loss` and `train_acc` that will help us to monitor the running accuracy and loss of the modes while it trains over the different batches.\n", + "- `model.train()` explicitly indicates that we are ready to start training. \n", + "- Notice how we are iterating over the dataloader, which conveniently gives us the batches in image-label pairs. \n", + "- That second `for` loop means that for every training step we will iterate over all the batches and train the model over them.\n", + "- We feed the model the images via `model(images)` and the output are the predictions of the model. \n", + "- The predictions together with the target labels are used to compute the loss using the loss function we defined earlier.\n", + "- Before we update our weights for the next round of training, we perform the following steps:\n", + " - we use the optimizer object to reset all the gradients for the variables it will update. This is a safe step and it doesn't overwrites the gradients the model accumulates while training (those are stored in a buffer [link text](https://pytorch.org/tutorials/beginner/pytorch_with_examples.html#pytorch-optim) via the `loss.backward() call)\n", + " - `loss.backward()` simply computes the gradient of the loss w.r.t to the model parameters\n", + " - `optimizer.step()` then ensures that the model parameters are updated\n", + "\n", + "- Then we gather and accumulate the loss and accuracy, which is what we will use to tell us if the model is learning properly" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 | Loss: 1.5929 | Train Accuracy: 89.11\n", + "Epoch: 1 | Loss: 1.5275 | Train Accuracy: 94.13\n", + "Epoch: 2 | Loss: 1.5138 | Train Accuracy: 95.33\n", + "Epoch: 3 | Loss: 1.5063 | Train Accuracy: 95.99\n", + "Epoch: 4 | Loss: 1.5003 | Train Accuracy: 96.48\n" + ] + } + ], + "source": [ + "## train the model\n", + "for epoch in range(num_epochs):\n", + " train_running_loss = 0.0\n", + " train_acc = 0.0\n", + "\n", + " ## commence training\n", + " model = model.train()\n", + "\n", + " ## training step\n", + " for i, (images, labels) in enumerate(trainloader):\n", + " \n", + " images = images.to(device)\n", + " labels = labels.to(device)\n", + "\n", + " ## forward + backprop + loss\n", + " predictions = model(images)\n", + " loss = criterion(predictions, labels)\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + "\n", + " ## update model params\n", + " optimizer.step()\n", + "\n", + " train_running_loss += loss.detach().item()\n", + " train_acc += get_accuracy(predictions, labels, BATCH_SIZE)\n", + " \n", + " model.eval()\n", + " print('Epoch: %d | Loss: %.4f | Train Accuracy: %.2f' \\\n", + " %(epoch, train_running_loss / i, train_acc/i)) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After all the training steps are over, we can clearly see that the loss keeps decreasing while the training accuracy of the model keeps rising, which is a good sign that the model is effectively learning to classify images.\n", + "\n", + "We can verify that by computing the accuracy on the testing dataset to see how well the model performs on the image classificaiton task. As you can see below, our basic CNN model is performing very well on the MNIST classification task." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Accuracy: 96.76\n" + ] + } + ], + "source": [ + "test_acc = 0.0\n", + "for i, (images, labels) in enumerate(testloader, 0):\n", + " images = images.to(device)\n", + " labels = labels.to(device)\n", + " outputs = model(images)\n", + " test_acc += get_accuracy(outputs, labels, BATCH_SIZE)\n", + " \n", + "print('Test Accuracy: %.2f'%( test_acc/i))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Final Words\n", + "\n", + "Congratulation! You have made it to the end of this tutorial. This is a really long tutorial that aims to give an very basic introduction to the fundamentals of image classification using neural networks and PyTorch.\n", + "\n", + "*This tutorial was heavily inspired by this [TensorFlow tutorial.](https://www.tensorflow.org/beta/tutorials/quickstart/beginner) We thank the authors of the corresponding reference for their valuable work.*\n", + "\n", + "## References\n", + "- [PyTorch 1.2 Quickstart with Google Colab](https://medium.com/dair-ai/pytorch-1-2-quickstart-with-google-colab-6690a30c38d)\n", + "- [Get started with TensorFlow 2.0 for beginners](https://www.tensorflow.org/beta/tutorials/quickstart/beginner)\n", + "- [PyTorch Data Loading Tutorial](https://pytorch.org/tutorials/beginner/data_loading_tutorial.html)\n", + "-[ Neural Networks with PyTorch](https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html#sphx-glr-beginner-blitz-neural-networks-tutorial-py)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 19f2048966c28a8e453e2964b12f0eb6b6aa2b45 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 00:34:16 +0000 Subject: [PATCH 32/76] add logistic regression --- .gitignore | 1 + notebooks/logistic_regression.ipynb | 970 ++++++++++++++++++++++++++++ 2 files changed, 971 insertions(+) create mode 100644 notebooks/logistic_regression.ipynb diff --git a/.gitignore b/.gitignore index dbb609b..05334c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ notebooks/data/ +notebooks/hymenoptera_data/ diff --git a/notebooks/logistic_regression.ipynb b/notebooks/logistic_regression.ipynb new file mode 100644 index 0000000..fd525dc --- /dev/null +++ b/notebooks/logistic_regression.ipynb @@ -0,0 +1,970 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementing A Logistic Regression Model from Scratch with PyTorch\n", + "\n", + "![alt text](https://drive.google.com/uc?export=view&id=11Bv3uhZtVgRVYVWDl9_ZAYQ0GU36LhM9)\n", + "\n", + "\n", + "In this tutorial, we are going to implement a logistic regression model from scratch with PyTorch. The model will be designed with neural networks in mind and will be used for a simple image classification task. I believe this is a great approach to begin understanding the fundamental building blocks behind a neural network. Additionally, we will also look at best practices on how to use PyTorch for training neural networks.\n", + "\n", + "After completing this tutorial the learner is expected to know the basic building blocks of a logistic regression model. The learner is also expected to apply the logistic regression model to a binary image classification problem of their choice using PyTorch code.\n", + "\n", + "---\n", + "\n", + "**Author:** Elvis Saravia ( [Twitter](https://twitter.com/omarsar0) | [LinkedIn](https://www.linkedin.com/in/omarsar/))\n", + "\n", + "**Complete Code Walkthrough:** [Blog post](https://medium.com/dair-ai/implementing-a-logistic-regression-model-from-scratch-with-pytorch-24ea062cd856?source=friends_link&sk=49dcddb17d1d021d2d677f3666c88463)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "## Import the usual libraries\n", + "import torch\n", + "import torchvision\n", + "import torch.nn as nn\n", + "from torchvision import datasets, models, transforms\n", + "import os\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cuda:0\n" + ] + } + ], + "source": [ + "## configuration to detect cuda or cpu\n", + "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", + "print (device)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Importing Dataset\n", + "In this tutorial we will be working on an image classification problem. You can find the public dataset [here](https://download.pytorch.org/tutorial/hymenoptera_data.zip). \n", + "\n", + "The objective of our model is to learn to classify between \"bee\" vs. \"no bee\" images.\n", + "\n", + "Uncomment the code below to download and unzip the data." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2022-06-17 23:55:52-- https://download.pytorch.org/tutorial/hymenoptera_data.zip\n", + "Resolving download.pytorch.org (download.pytorch.org)... 18.67.65.73, 18.67.65.42, 18.67.65.118, ...\n", + "Connecting to download.pytorch.org (download.pytorch.org)|18.67.65.73|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 47286322 (45M) [application/zip]\n", + "Saving to: ‘hymenoptera_data.zip’\n", + "\n", + "hymenoptera_data.zi 100%[===================>] 45.10M 152MB/s in 0.3s \n", + "\n", + "2022-06-17 23:55:53 (152 MB/s) - ‘hymenoptera_data.zip’ saved [47286322/47286322]\n", + "\n", + "Archive: hymenoptera_data.zip\n", + " creating: hymenoptera_data/\n", + " creating: hymenoptera_data/train/\n", + " creating: hymenoptera_data/train/ants/\n", + " inflating: hymenoptera_data/train/ants/0013035.jpg \n", + " inflating: hymenoptera_data/train/ants/1030023514_aad5c608f9.jpg \n", + " inflating: hymenoptera_data/train/ants/1095476100_3906d8afde.jpg \n", + " inflating: hymenoptera_data/train/ants/1099452230_d1949d3250.jpg \n", + " inflating: hymenoptera_data/train/ants/116570827_e9c126745d.jpg \n", + " inflating: hymenoptera_data/train/ants/1225872729_6f0856588f.jpg \n", + " inflating: hymenoptera_data/train/ants/1262877379_64fcada201.jpg \n", + " inflating: hymenoptera_data/train/ants/1269756697_0bce92cdab.jpg \n", + " inflating: hymenoptera_data/train/ants/1286984635_5119e80de1.jpg \n", + " inflating: hymenoptera_data/train/ants/132478121_2a430adea2.jpg \n", + " inflating: hymenoptera_data/train/ants/1360291657_dc248c5eea.jpg \n", + " inflating: hymenoptera_data/train/ants/1368913450_e146e2fb6d.jpg \n", + " inflating: hymenoptera_data/train/ants/1473187633_63ccaacea6.jpg \n", + " inflating: hymenoptera_data/train/ants/148715752_302c84f5a4.jpg \n", + " inflating: hymenoptera_data/train/ants/1489674356_09d48dde0a.jpg \n", + " inflating: hymenoptera_data/train/ants/149244013_c529578289.jpg \n", + " inflating: hymenoptera_data/train/ants/150801003_3390b73135.jpg \n", + " inflating: hymenoptera_data/train/ants/150801171_cd86f17ed8.jpg \n", + " inflating: hymenoptera_data/train/ants/154124431_65460430f2.jpg \n", + " inflating: hymenoptera_data/train/ants/162603798_40b51f1654.jpg \n", + " inflating: hymenoptera_data/train/ants/1660097129_384bf54490.jpg \n", + " inflating: hymenoptera_data/train/ants/167890289_dd5ba923f3.jpg \n", + " inflating: hymenoptera_data/train/ants/1693954099_46d4c20605.jpg \n", + " inflating: hymenoptera_data/train/ants/175998972.jpg \n", + " inflating: hymenoptera_data/train/ants/178538489_bec7649292.jpg \n", + " inflating: hymenoptera_data/train/ants/1804095607_0341701e1c.jpg \n", + " inflating: hymenoptera_data/train/ants/1808777855_2a895621d7.jpg \n", + " inflating: hymenoptera_data/train/ants/188552436_605cc9b36b.jpg \n", + " inflating: hymenoptera_data/train/ants/1917341202_d00a7f9af5.jpg \n", + " inflating: hymenoptera_data/train/ants/1924473702_daa9aacdbe.jpg \n", + " inflating: hymenoptera_data/train/ants/196057951_63bf063b92.jpg \n", + " inflating: hymenoptera_data/train/ants/196757565_326437f5fe.jpg \n", + " inflating: hymenoptera_data/train/ants/201558278_fe4caecc76.jpg \n", + " inflating: hymenoptera_data/train/ants/201790779_527f4c0168.jpg \n", + " inflating: hymenoptera_data/train/ants/2019439677_2db655d361.jpg \n", + " inflating: hymenoptera_data/train/ants/207947948_3ab29d7207.jpg \n", + " inflating: hymenoptera_data/train/ants/20935278_9190345f6b.jpg \n", + " inflating: hymenoptera_data/train/ants/224655713_3956f7d39a.jpg \n", + " inflating: hymenoptera_data/train/ants/2265824718_2c96f485da.jpg \n", + " inflating: hymenoptera_data/train/ants/2265825502_fff99cfd2d.jpg \n", + " inflating: hymenoptera_data/train/ants/226951206_d6bf946504.jpg \n", + " inflating: hymenoptera_data/train/ants/2278278459_6b99605e50.jpg \n", + " inflating: hymenoptera_data/train/ants/2288450226_a6e96e8fdf.jpg \n", + " inflating: hymenoptera_data/train/ants/2288481644_83ff7e4572.jpg \n", + " inflating: hymenoptera_data/train/ants/2292213964_ca51ce4bef.jpg \n", + " inflating: hymenoptera_data/train/ants/24335309_c5ea483bb8.jpg \n", + " inflating: hymenoptera_data/train/ants/245647475_9523dfd13e.jpg \n", + " inflating: hymenoptera_data/train/ants/255434217_1b2b3fe0a4.jpg \n", + " inflating: hymenoptera_data/train/ants/258217966_d9d90d18d3.jpg \n", + " inflating: hymenoptera_data/train/ants/275429470_b2d7d9290b.jpg \n", + " inflating: hymenoptera_data/train/ants/28847243_e79fe052cd.jpg \n", + " inflating: hymenoptera_data/train/ants/318052216_84dff3f98a.jpg \n", + " inflating: hymenoptera_data/train/ants/334167043_cbd1adaeb9.jpg \n", + " inflating: hymenoptera_data/train/ants/339670531_94b75ae47a.jpg \n", + " inflating: hymenoptera_data/train/ants/342438950_a3da61deab.jpg \n", + " inflating: hymenoptera_data/train/ants/36439863_0bec9f554f.jpg \n", + " inflating: hymenoptera_data/train/ants/374435068_7eee412ec4.jpg \n", + " inflating: hymenoptera_data/train/ants/382971067_0bfd33afe0.jpg \n", + " inflating: hymenoptera_data/train/ants/384191229_5779cf591b.jpg \n", + " inflating: hymenoptera_data/train/ants/386190770_672743c9a7.jpg \n", + " inflating: hymenoptera_data/train/ants/392382602_1b7bed32fa.jpg \n", + " inflating: hymenoptera_data/train/ants/403746349_71384f5b58.jpg \n", + " inflating: hymenoptera_data/train/ants/408393566_b5b694119b.jpg \n", + " inflating: hymenoptera_data/train/ants/424119020_6d57481dab.jpg \n", + " inflating: hymenoptera_data/train/ants/424873399_47658a91fb.jpg \n", + " inflating: hymenoptera_data/train/ants/450057712_771b3bfc91.jpg \n", + " inflating: hymenoptera_data/train/ants/45472593_bfd624f8dc.jpg \n", + " inflating: hymenoptera_data/train/ants/459694881_ac657d3187.jpg \n", + " inflating: hymenoptera_data/train/ants/460372577_f2f6a8c9fc.jpg \n", + " inflating: hymenoptera_data/train/ants/460874319_0a45ab4d05.jpg \n", + " inflating: hymenoptera_data/train/ants/466430434_4000737de9.jpg \n", + " inflating: hymenoptera_data/train/ants/470127037_513711fd21.jpg \n", + " inflating: hymenoptera_data/train/ants/474806473_ca6caab245.jpg \n", + " inflating: hymenoptera_data/train/ants/475961153_b8c13fd405.jpg \n", + " inflating: hymenoptera_data/train/ants/484293231_e53cfc0c89.jpg \n", + " inflating: hymenoptera_data/train/ants/49375974_e28ba6f17e.jpg \n", + " inflating: hymenoptera_data/train/ants/506249802_207cd979b4.jpg \n", + " inflating: hymenoptera_data/train/ants/506249836_717b73f540.jpg \n", + " inflating: hymenoptera_data/train/ants/512164029_c0a66b8498.jpg \n", + " inflating: hymenoptera_data/train/ants/512863248_43c8ce579b.jpg \n", + " inflating: hymenoptera_data/train/ants/518773929_734dbc5ff4.jpg \n", + " inflating: hymenoptera_data/train/ants/522163566_fec115ca66.jpg \n", + " inflating: hymenoptera_data/train/ants/522415432_2218f34bf8.jpg \n", + " inflating: hymenoptera_data/train/ants/531979952_bde12b3bc0.jpg \n", + " inflating: hymenoptera_data/train/ants/533848102_70a85ad6dd.jpg \n", + " inflating: hymenoptera_data/train/ants/535522953_308353a07c.jpg \n", + " inflating: hymenoptera_data/train/ants/540889389_48bb588b21.jpg \n", + " inflating: hymenoptera_data/train/ants/541630764_dbd285d63c.jpg \n", + " inflating: hymenoptera_data/train/ants/543417860_b14237f569.jpg \n", + " inflating: hymenoptera_data/train/ants/560966032_988f4d7bc4.jpg \n", + " inflating: hymenoptera_data/train/ants/5650366_e22b7e1065.jpg \n", + " inflating: hymenoptera_data/train/ants/6240329_72c01e663e.jpg \n", + " inflating: hymenoptera_data/train/ants/6240338_93729615ec.jpg \n", + " inflating: hymenoptera_data/train/ants/649026570_e58656104b.jpg \n", + " inflating: hymenoptera_data/train/ants/662541407_ff8db781e7.jpg \n", + " inflating: hymenoptera_data/train/ants/67270775_e9fdf77e9d.jpg \n", + " inflating: hymenoptera_data/train/ants/6743948_2b8c096dda.jpg \n", + " inflating: hymenoptera_data/train/ants/684133190_35b62c0c1d.jpg \n", + " inflating: hymenoptera_data/train/ants/69639610_95e0de17aa.jpg \n", + " inflating: hymenoptera_data/train/ants/707895295_009cf23188.jpg \n", + " inflating: hymenoptera_data/train/ants/7759525_1363d24e88.jpg \n", + " inflating: hymenoptera_data/train/ants/795000156_a9900a4a71.jpg \n", + " inflating: hymenoptera_data/train/ants/822537660_caf4ba5514.jpg \n", + " inflating: hymenoptera_data/train/ants/82852639_52b7f7f5e3.jpg \n", + " inflating: hymenoptera_data/train/ants/841049277_b28e58ad05.jpg \n", + " inflating: hymenoptera_data/train/ants/886401651_f878e888cd.jpg \n", + " inflating: hymenoptera_data/train/ants/892108839_f1aad4ca46.jpg \n", + " inflating: hymenoptera_data/train/ants/938946700_ca1c669085.jpg \n", + " inflating: hymenoptera_data/train/ants/957233405_25c1d1187b.jpg \n", + " inflating: hymenoptera_data/train/ants/9715481_b3cb4114ff.jpg \n", + " inflating: hymenoptera_data/train/ants/998118368_6ac1d91f81.jpg \n", + " inflating: hymenoptera_data/train/ants/ant photos.jpg \n", + " inflating: hymenoptera_data/train/ants/Ant_1.jpg \n", + " inflating: hymenoptera_data/train/ants/army-ants-red-picture.jpg \n", + " inflating: hymenoptera_data/train/ants/formica.jpeg \n", + " inflating: hymenoptera_data/train/ants/hormiga_co_por.jpg \n", + " inflating: hymenoptera_data/train/ants/imageNotFound.gif \n", + " inflating: hymenoptera_data/train/ants/kurokusa.jpg \n", + " inflating: hymenoptera_data/train/ants/MehdiabadiAnt2_600.jpg \n", + " inflating: hymenoptera_data/train/ants/Nepenthes_rafflesiana_ant.jpg \n", + " inflating: hymenoptera_data/train/ants/swiss-army-ant.jpg \n", + " inflating: hymenoptera_data/train/ants/termite-vs-ant.jpg \n", + " inflating: hymenoptera_data/train/ants/trap-jaw-ant-insect-bg.jpg \n", + " inflating: hymenoptera_data/train/ants/VietnameseAntMimicSpider.jpg \n", + " creating: hymenoptera_data/train/bees/\n", + " inflating: hymenoptera_data/train/bees/1092977343_cb42b38d62.jpg \n", + " inflating: hymenoptera_data/train/bees/1093831624_fb5fbe2308.jpg \n", + " inflating: hymenoptera_data/train/bees/1097045929_1753d1c765.jpg \n", + " inflating: hymenoptera_data/train/bees/1232245714_f862fbe385.jpg \n", + " inflating: hymenoptera_data/train/bees/129236073_0985e91c7d.jpg \n", + " inflating: hymenoptera_data/train/bees/1295655112_7813f37d21.jpg \n", + " inflating: hymenoptera_data/train/bees/132511197_0b86ad0fff.jpg \n", + " inflating: hymenoptera_data/train/bees/132826773_dbbcb117b9.jpg \n", + " inflating: hymenoptera_data/train/bees/150013791_969d9a968b.jpg \n", + " inflating: hymenoptera_data/train/bees/1508176360_2972117c9d.jpg \n", + " inflating: hymenoptera_data/train/bees/154600396_53e1252e52.jpg \n", + " inflating: hymenoptera_data/train/bees/16838648_415acd9e3f.jpg \n", + " inflating: hymenoptera_data/train/bees/1691282715_0addfdf5e8.jpg \n", + " inflating: hymenoptera_data/train/bees/17209602_fe5a5a746f.jpg \n", + " inflating: hymenoptera_data/train/bees/174142798_e5ad6d76e0.jpg \n", + " inflating: hymenoptera_data/train/bees/1799726602_8580867f71.jpg \n", + " inflating: hymenoptera_data/train/bees/1807583459_4fe92b3133.jpg \n", + " inflating: hymenoptera_data/train/bees/196430254_46bd129ae7.jpg \n", + " inflating: hymenoptera_data/train/bees/196658222_3fffd79c67.jpg \n", + " inflating: hymenoptera_data/train/bees/198508668_97d818b6c4.jpg \n", + " inflating: hymenoptera_data/train/bees/2031225713_50ed499635.jpg \n", + " inflating: hymenoptera_data/train/bees/2037437624_2d7bce461f.jpg \n", + " inflating: hymenoptera_data/train/bees/2053200300_8911ef438a.jpg \n", + " inflating: hymenoptera_data/train/bees/205835650_e6f2614bee.jpg \n", + " inflating: hymenoptera_data/train/bees/208702903_42fb4d9748.jpg \n", + " inflating: hymenoptera_data/train/bees/21399619_3e61e5bb6f.jpg \n", + " inflating: hymenoptera_data/train/bees/2227611847_ec72d40403.jpg \n", + " inflating: hymenoptera_data/train/bees/2321139806_d73d899e66.jpg \n", + " inflating: hymenoptera_data/train/bees/2330918208_8074770c20.jpg \n", + " inflating: hymenoptera_data/train/bees/2345177635_caf07159b3.jpg \n", + " inflating: hymenoptera_data/train/bees/2358061370_9daabbd9ac.jpg \n", + " inflating: hymenoptera_data/train/bees/2364597044_3c3e3fc391.jpg \n", + " inflating: hymenoptera_data/train/bees/2384149906_2cd8b0b699.jpg \n", + " inflating: hymenoptera_data/train/bees/2397446847_04ef3cd3e1.jpg \n", + " inflating: hymenoptera_data/train/bees/2405441001_b06c36fa72.jpg \n", + " inflating: hymenoptera_data/train/bees/2445215254_51698ff797.jpg \n", + " inflating: hymenoptera_data/train/bees/2452236943_255bfd9e58.jpg \n", + " inflating: hymenoptera_data/train/bees/2467959963_a7831e9ff0.jpg \n", + " inflating: hymenoptera_data/train/bees/2470492904_837e97800d.jpg \n", + " inflating: hymenoptera_data/train/bees/2477324698_3d4b1b1cab.jpg \n", + " inflating: hymenoptera_data/train/bees/2477349551_e75c97cf4d.jpg \n", + " inflating: hymenoptera_data/train/bees/2486729079_62df0920be.jpg \n", + " inflating: hymenoptera_data/train/bees/2486746709_c43cec0e42.jpg \n", + " inflating: hymenoptera_data/train/bees/2493379287_4100e1dacc.jpg \n", + " inflating: hymenoptera_data/train/bees/2495722465_879acf9d85.jpg \n", + " inflating: hymenoptera_data/train/bees/2528444139_fa728b0f5b.jpg \n", + " inflating: hymenoptera_data/train/bees/2538361678_9da84b77e3.jpg \n", + " inflating: hymenoptera_data/train/bees/2551813042_8a070aeb2b.jpg \n", + " inflating: hymenoptera_data/train/bees/2580598377_a4caecdb54.jpg \n", + " inflating: hymenoptera_data/train/bees/2601176055_8464e6aa71.jpg \n", + " inflating: hymenoptera_data/train/bees/2610833167_79bf0bcae5.jpg \n", + " inflating: hymenoptera_data/train/bees/2610838525_fe8e3cae47.jpg \n", + " inflating: hymenoptera_data/train/bees/2617161745_fa3ebe85b4.jpg \n", + " inflating: hymenoptera_data/train/bees/2625499656_e3415e374d.jpg \n", + " inflating: hymenoptera_data/train/bees/2634617358_f32fd16bea.jpg \n", + " inflating: hymenoptera_data/train/bees/2638074627_6b3ae746a0.jpg \n", + " inflating: hymenoptera_data/train/bees/2645107662_b73a8595cc.jpg \n", + " inflating: hymenoptera_data/train/bees/2651621464_a2fa8722eb.jpg \n", + " inflating: hymenoptera_data/train/bees/2652877533_a564830cbf.jpg \n", + " inflating: hymenoptera_data/train/bees/266644509_d30bb16a1b.jpg \n", + " inflating: hymenoptera_data/train/bees/2683605182_9d2a0c66cf.jpg \n", + " inflating: hymenoptera_data/train/bees/2704348794_eb5d5178c2.jpg \n", + " inflating: hymenoptera_data/train/bees/2707440199_cd170bd512.jpg \n", + " inflating: hymenoptera_data/train/bees/2710368626_cb42882dc8.jpg \n", + " inflating: hymenoptera_data/train/bees/2722592222_258d473e17.jpg \n", + " inflating: hymenoptera_data/train/bees/2728759455_ce9bb8cd7a.jpg \n", + " inflating: hymenoptera_data/train/bees/2756397428_1d82a08807.jpg \n", + " inflating: hymenoptera_data/train/bees/2765347790_da6cf6cb40.jpg \n", + " inflating: hymenoptera_data/train/bees/2781170484_5d61835d63.jpg \n", + " inflating: hymenoptera_data/train/bees/279113587_b4843db199.jpg \n", + " inflating: hymenoptera_data/train/bees/2792000093_e8ae0718cf.jpg \n", + " inflating: hymenoptera_data/train/bees/2801728106_833798c909.jpg \n", + " inflating: hymenoptera_data/train/bees/2822388965_f6dca2a275.jpg \n", + " inflating: hymenoptera_data/train/bees/2861002136_52c7c6f708.jpg \n", + " inflating: hymenoptera_data/train/bees/2908916142_a7ac8b57a8.jpg \n", + " inflating: hymenoptera_data/train/bees/29494643_e3410f0d37.jpg \n", + " inflating: hymenoptera_data/train/bees/2959730355_416a18c63c.jpg \n", + " inflating: hymenoptera_data/train/bees/2962405283_22718d9617.jpg \n", + " inflating: hymenoptera_data/train/bees/3006264892_30e9cced70.jpg \n", + " inflating: hymenoptera_data/train/bees/3030189811_01d095b793.jpg \n", + " inflating: hymenoptera_data/train/bees/3030772428_8578335616.jpg \n", + " inflating: hymenoptera_data/train/bees/3044402684_3853071a87.jpg \n", + " inflating: hymenoptera_data/train/bees/3074585407_9854eb3153.jpg \n", + " inflating: hymenoptera_data/train/bees/3079610310_ac2d0ae7bc.jpg \n", + " inflating: hymenoptera_data/train/bees/3090975720_71f12e6de4.jpg \n", + " inflating: hymenoptera_data/train/bees/3100226504_c0d4f1e3f1.jpg \n", + " inflating: hymenoptera_data/train/bees/342758693_c56b89b6b6.jpg \n", + " inflating: hymenoptera_data/train/bees/354167719_22dca13752.jpg \n", + " inflating: hymenoptera_data/train/bees/359928878_b3b418c728.jpg \n", + " inflating: hymenoptera_data/train/bees/365759866_b15700c59b.jpg \n", + " inflating: hymenoptera_data/train/bees/36900412_92b81831ad.jpg \n", + " inflating: hymenoptera_data/train/bees/39672681_1302d204d1.jpg \n", + " inflating: hymenoptera_data/train/bees/39747887_42df2855ee.jpg \n", + " inflating: hymenoptera_data/train/bees/421515404_e87569fd8b.jpg \n", + " inflating: hymenoptera_data/train/bees/444532809_9e931e2279.jpg \n", + " inflating: hymenoptera_data/train/bees/446296270_d9e8b93ecf.jpg \n", + " inflating: hymenoptera_data/train/bees/452462677_7be43af8ff.jpg \n", + " inflating: hymenoptera_data/train/bees/452462695_40a4e5b559.jpg \n", + " inflating: hymenoptera_data/train/bees/457457145_5f86eb7e9c.jpg \n", + " inflating: hymenoptera_data/train/bees/465133211_80e0c27f60.jpg \n", + " inflating: hymenoptera_data/train/bees/469333327_358ba8fe8a.jpg \n", + " inflating: hymenoptera_data/train/bees/472288710_2abee16fa0.jpg \n", + " inflating: hymenoptera_data/train/bees/473618094_8ffdcab215.jpg \n", + " inflating: hymenoptera_data/train/bees/476347960_52edd72b06.jpg \n", + " inflating: hymenoptera_data/train/bees/478701318_bbd5e557b8.jpg \n", + " inflating: hymenoptera_data/train/bees/507288830_f46e8d4cb2.jpg \n", + " inflating: hymenoptera_data/train/bees/509247772_2db2d01374.jpg \n", + " inflating: hymenoptera_data/train/bees/513545352_fd3e7c7c5d.jpg \n", + " inflating: hymenoptera_data/train/bees/522104315_5d3cb2758e.jpg \n", + " inflating: hymenoptera_data/train/bees/537309131_532bfa59ea.jpg \n", + " inflating: hymenoptera_data/train/bees/586041248_3032e277a9.jpg \n", + " inflating: hymenoptera_data/train/bees/760526046_547e8b381f.jpg \n", + " inflating: hymenoptera_data/train/bees/760568592_45a52c847f.jpg \n", + " inflating: hymenoptera_data/train/bees/774440991_63a4aa0cbe.jpg \n", + " inflating: hymenoptera_data/train/bees/85112639_6e860b0469.jpg \n", + " inflating: hymenoptera_data/train/bees/873076652_eb098dab2d.jpg \n", + " inflating: hymenoptera_data/train/bees/90179376_abc234e5f4.jpg \n", + " inflating: hymenoptera_data/train/bees/92663402_37f379e57a.jpg \n", + " inflating: hymenoptera_data/train/bees/95238259_98470c5b10.jpg \n", + " inflating: hymenoptera_data/train/bees/969455125_58c797ef17.jpg \n", + " inflating: hymenoptera_data/train/bees/98391118_bdb1e80cce.jpg \n", + " creating: hymenoptera_data/val/\n", + " creating: hymenoptera_data/val/ants/\n", + " inflating: hymenoptera_data/val/ants/10308379_1b6c72e180.jpg \n", + " inflating: hymenoptera_data/val/ants/1053149811_f62a3410d3.jpg \n", + " inflating: hymenoptera_data/val/ants/1073564163_225a64f170.jpg \n", + " inflating: hymenoptera_data/val/ants/1119630822_cd325ea21a.jpg \n", + " inflating: hymenoptera_data/val/ants/1124525276_816a07c17f.jpg \n", + " inflating: hymenoptera_data/val/ants/11381045_b352a47d8c.jpg \n", + " inflating: hymenoptera_data/val/ants/119785936_dd428e40c3.jpg \n", + " inflating: hymenoptera_data/val/ants/1247887232_edcb61246c.jpg \n", + " inflating: hymenoptera_data/val/ants/1262751255_c56c042b7b.jpg \n", + " inflating: hymenoptera_data/val/ants/1337725712_2eb53cd742.jpg \n", + " inflating: hymenoptera_data/val/ants/1358854066_5ad8015f7f.jpg \n", + " inflating: hymenoptera_data/val/ants/1440002809_b268d9a66a.jpg \n", + " inflating: hymenoptera_data/val/ants/147542264_79506478c2.jpg \n", + " inflating: hymenoptera_data/val/ants/152286280_411648ec27.jpg \n", + " inflating: hymenoptera_data/val/ants/153320619_2aeb5fa0ee.jpg \n", + " inflating: hymenoptera_data/val/ants/153783656_85f9c3ac70.jpg \n", + " inflating: hymenoptera_data/val/ants/157401988_d0564a9d02.jpg \n", + " inflating: hymenoptera_data/val/ants/159515240_d5981e20d1.jpg \n", + " inflating: hymenoptera_data/val/ants/161076144_124db762d6.jpg \n", + " inflating: hymenoptera_data/val/ants/161292361_c16e0bf57a.jpg \n", + " inflating: hymenoptera_data/val/ants/170652283_ecdaff5d1a.jpg \n", + " inflating: hymenoptera_data/val/ants/17081114_79b9a27724.jpg \n", + " inflating: hymenoptera_data/val/ants/172772109_d0a8e15fb0.jpg \n", + " inflating: hymenoptera_data/val/ants/1743840368_b5ccda82b7.jpg \n", + " inflating: hymenoptera_data/val/ants/181942028_961261ef48.jpg \n", + " inflating: hymenoptera_data/val/ants/183260961_64ab754c97.jpg \n", + " inflating: hymenoptera_data/val/ants/2039585088_c6f47c592e.jpg \n", + " inflating: hymenoptera_data/val/ants/205398178_c395c5e460.jpg \n", + " inflating: hymenoptera_data/val/ants/208072188_f293096296.jpg \n", + " inflating: hymenoptera_data/val/ants/209615353_eeb38ba204.jpg \n", + " inflating: hymenoptera_data/val/ants/2104709400_8831b4fc6f.jpg \n", + " inflating: hymenoptera_data/val/ants/212100470_b485e7b7b9.jpg \n", + " inflating: hymenoptera_data/val/ants/2127908701_d49dc83c97.jpg \n", + " inflating: hymenoptera_data/val/ants/2191997003_379df31291.jpg \n", + " inflating: hymenoptera_data/val/ants/2211974567_ee4606b493.jpg \n", + " inflating: hymenoptera_data/val/ants/2219621907_47bc7cc6b0.jpg \n", + " inflating: hymenoptera_data/val/ants/2238242353_52c82441df.jpg \n", + " inflating: hymenoptera_data/val/ants/2255445811_dabcdf7258.jpg \n", + " inflating: hymenoptera_data/val/ants/239161491_86ac23b0a3.jpg \n", + " inflating: hymenoptera_data/val/ants/263615709_cfb28f6b8e.jpg \n", + " inflating: hymenoptera_data/val/ants/308196310_1db5ffa01b.jpg \n", + " inflating: hymenoptera_data/val/ants/319494379_648fb5a1c6.jpg \n", + " inflating: hymenoptera_data/val/ants/35558229_1fa4608a7a.jpg \n", + " inflating: hymenoptera_data/val/ants/412436937_4c2378efc2.jpg \n", + " inflating: hymenoptera_data/val/ants/436944325_d4925a38c7.jpg \n", + " inflating: hymenoptera_data/val/ants/445356866_6cb3289067.jpg \n", + " inflating: hymenoptera_data/val/ants/459442412_412fecf3fe.jpg \n", + " inflating: hymenoptera_data/val/ants/470127071_8b8ee2bd74.jpg \n", + " inflating: hymenoptera_data/val/ants/477437164_bc3e6e594a.jpg \n", + " inflating: hymenoptera_data/val/ants/488272201_c5aa281348.jpg \n", + " inflating: hymenoptera_data/val/ants/502717153_3e4865621a.jpg \n", + " inflating: hymenoptera_data/val/ants/518746016_bcc28f8b5b.jpg \n", + " inflating: hymenoptera_data/val/ants/540543309_ddbb193ee5.jpg \n", + " inflating: hymenoptera_data/val/ants/562589509_7e55469b97.jpg \n", + " inflating: hymenoptera_data/val/ants/57264437_a19006872f.jpg \n", + " inflating: hymenoptera_data/val/ants/573151833_ebbc274b77.jpg \n", + " inflating: hymenoptera_data/val/ants/649407494_9b6bc4949f.jpg \n", + " inflating: hymenoptera_data/val/ants/751649788_78dd7d16ce.jpg \n", + " inflating: hymenoptera_data/val/ants/768870506_8f115d3d37.jpg \n", + " inflating: hymenoptera_data/val/ants/800px-Meat_eater_ant_qeen_excavating_hole.jpg \n", + " inflating: hymenoptera_data/val/ants/8124241_36b290d372.jpg \n", + " inflating: hymenoptera_data/val/ants/8398478_50ef10c47a.jpg \n", + " inflating: hymenoptera_data/val/ants/854534770_31f6156383.jpg \n", + " inflating: hymenoptera_data/val/ants/892676922_4ab37dce07.jpg \n", + " inflating: hymenoptera_data/val/ants/94999827_36895faade.jpg \n", + " inflating: hymenoptera_data/val/ants/Ant-1818.jpg \n", + " inflating: hymenoptera_data/val/ants/ants-devouring-remains-of-large-dead-insect-on-red-tile-in-Stellenbosch-South-Africa-closeup-1-DHD.jpg \n", + " inflating: hymenoptera_data/val/ants/desert_ant.jpg \n", + " inflating: hymenoptera_data/val/ants/F.pergan.28(f).jpg \n", + " inflating: hymenoptera_data/val/ants/Hormiga.jpg \n", + " creating: hymenoptera_data/val/bees/\n", + " inflating: hymenoptera_data/val/bees/1032546534_06907fe3b3.jpg \n", + " inflating: hymenoptera_data/val/bees/10870992_eebeeb3a12.jpg \n", + " inflating: hymenoptera_data/val/bees/1181173278_23c36fac71.jpg \n", + " inflating: hymenoptera_data/val/bees/1297972485_33266a18d9.jpg \n", + " inflating: hymenoptera_data/val/bees/1328423762_f7a88a8451.jpg \n", + " inflating: hymenoptera_data/val/bees/1355974687_1341c1face.jpg \n", + " inflating: hymenoptera_data/val/bees/144098310_a4176fd54d.jpg \n", + " inflating: hymenoptera_data/val/bees/1486120850_490388f84b.jpg \n", + " inflating: hymenoptera_data/val/bees/149973093_da3c446268.jpg \n", + " inflating: hymenoptera_data/val/bees/151594775_ee7dc17b60.jpg \n", + " inflating: hymenoptera_data/val/bees/151603988_2c6f7d14c7.jpg \n", + " inflating: hymenoptera_data/val/bees/1519368889_4270261ee3.jpg \n", + " inflating: hymenoptera_data/val/bees/152789693_220b003452.jpg \n", + " inflating: hymenoptera_data/val/bees/177677657_a38c97e572.jpg \n", + " inflating: hymenoptera_data/val/bees/1799729694_0c40101071.jpg \n", + " inflating: hymenoptera_data/val/bees/181171681_c5a1a82ded.jpg \n", + " inflating: hymenoptera_data/val/bees/187130242_4593a4c610.jpg \n", + " inflating: hymenoptera_data/val/bees/203868383_0fcbb48278.jpg \n", + " inflating: hymenoptera_data/val/bees/2060668999_e11edb10d0.jpg \n", + " inflating: hymenoptera_data/val/bees/2086294791_6f3789d8a6.jpg \n", + " inflating: hymenoptera_data/val/bees/2103637821_8d26ee6b90.jpg \n", + " inflating: hymenoptera_data/val/bees/2104135106_a65eede1de.jpg \n", + " inflating: hymenoptera_data/val/bees/215512424_687e1e0821.jpg \n", + " inflating: hymenoptera_data/val/bees/2173503984_9c6aaaa7e2.jpg \n", + " inflating: hymenoptera_data/val/bees/220376539_20567395d8.jpg \n", + " inflating: hymenoptera_data/val/bees/224841383_d050f5f510.jpg \n", + " inflating: hymenoptera_data/val/bees/2321144482_f3785ba7b2.jpg \n", + " inflating: hymenoptera_data/val/bees/238161922_55fa9a76ae.jpg \n", + " inflating: hymenoptera_data/val/bees/2407809945_fb525ef54d.jpg \n", + " inflating: hymenoptera_data/val/bees/2415414155_1916f03b42.jpg \n", + " inflating: hymenoptera_data/val/bees/2438480600_40a1249879.jpg \n", + " inflating: hymenoptera_data/val/bees/2444778727_4b781ac424.jpg \n", + " inflating: hymenoptera_data/val/bees/2457841282_7867f16639.jpg \n", + " inflating: hymenoptera_data/val/bees/2470492902_3572c90f75.jpg \n", + " inflating: hymenoptera_data/val/bees/2478216347_535c8fe6d7.jpg \n", + " inflating: hymenoptera_data/val/bees/2501530886_e20952b97d.jpg \n", + " inflating: hymenoptera_data/val/bees/2506114833_90a41c5267.jpg \n", + " inflating: hymenoptera_data/val/bees/2509402554_31821cb0b6.jpg \n", + " inflating: hymenoptera_data/val/bees/2525379273_dcb26a516d.jpg \n", + " inflating: hymenoptera_data/val/bees/26589803_5ba7000313.jpg \n", + " inflating: hymenoptera_data/val/bees/2668391343_45e272cd07.jpg \n", + " inflating: hymenoptera_data/val/bees/2670536155_c170f49cd0.jpg \n", + " inflating: hymenoptera_data/val/bees/2685605303_9eed79d59d.jpg \n", + " inflating: hymenoptera_data/val/bees/2702408468_d9ed795f4f.jpg \n", + " inflating: hymenoptera_data/val/bees/2709775832_85b4b50a57.jpg \n", + " inflating: hymenoptera_data/val/bees/2717418782_bd83307d9f.jpg \n", + " inflating: hymenoptera_data/val/bees/272986700_d4d4bf8c4b.jpg \n", + " inflating: hymenoptera_data/val/bees/2741763055_9a7bb00802.jpg \n", + " inflating: hymenoptera_data/val/bees/2745389517_250a397f31.jpg \n", + " inflating: hymenoptera_data/val/bees/2751836205_6f7b5eff30.jpg \n", + " inflating: hymenoptera_data/val/bees/2782079948_8d4e94a826.jpg \n", + " inflating: hymenoptera_data/val/bees/2809496124_5f25b5946a.jpg \n", + " inflating: hymenoptera_data/val/bees/2815838190_0a9889d995.jpg \n", + " inflating: hymenoptera_data/val/bees/2841437312_789699c740.jpg \n", + " inflating: hymenoptera_data/val/bees/2883093452_7e3a1eb53f.jpg \n", + " inflating: hymenoptera_data/val/bees/290082189_f66cb80bfc.jpg \n", + " inflating: hymenoptera_data/val/bees/296565463_d07a7bed96.jpg \n", + " inflating: hymenoptera_data/val/bees/3077452620_548c79fda0.jpg \n", + " inflating: hymenoptera_data/val/bees/348291597_ee836fbb1a.jpg \n", + " inflating: hymenoptera_data/val/bees/350436573_41f4ecb6c8.jpg \n", + " inflating: hymenoptera_data/val/bees/353266603_d3eac7e9a0.jpg \n", + " inflating: hymenoptera_data/val/bees/372228424_16da1f8884.jpg \n", + " inflating: hymenoptera_data/val/bees/400262091_701c00031c.jpg \n", + " inflating: hymenoptera_data/val/bees/416144384_961c326481.jpg \n", + " inflating: hymenoptera_data/val/bees/44105569_16720a960c.jpg \n", + " inflating: hymenoptera_data/val/bees/456097971_860949c4fc.jpg \n", + " inflating: hymenoptera_data/val/bees/464594019_1b24a28bb1.jpg \n", + " inflating: hymenoptera_data/val/bees/485743562_d8cc6b8f73.jpg \n", + " inflating: hymenoptera_data/val/bees/540976476_844950623f.jpg \n", + " inflating: hymenoptera_data/val/bees/54736755_c057723f64.jpg \n", + " inflating: hymenoptera_data/val/bees/57459255_752774f1b2.jpg \n", + " inflating: hymenoptera_data/val/bees/576452297_897023f002.jpg \n", + " inflating: hymenoptera_data/val/bees/586474709_ae436da045.jpg \n", + " inflating: hymenoptera_data/val/bees/590318879_68cf112861.jpg \n", + " inflating: hymenoptera_data/val/bees/59798110_2b6a3c8031.jpg \n", + " inflating: hymenoptera_data/val/bees/603709866_a97c7cfc72.jpg \n", + " inflating: hymenoptera_data/val/bees/603711658_4c8cd2201e.jpg \n", + " inflating: hymenoptera_data/val/bees/65038344_52a45d090d.jpg \n", + " inflating: hymenoptera_data/val/bees/6a00d8341c630a53ef00e553d0beb18834-800wi.jpg \n", + " inflating: hymenoptera_data/val/bees/72100438_73de9f17af.jpg \n", + " inflating: hymenoptera_data/val/bees/759745145_e8bc776ec8.jpg \n", + " inflating: hymenoptera_data/val/bees/936182217_c4caa5222d.jpg \n", + " inflating: hymenoptera_data/val/bees/abeja.jpg \n" + ] + } + ], + "source": [ + "# download the data\n", + "!wget https://download.pytorch.org/tutorial/hymenoptera_data.zip\n", + "!unzip hymenoptera_data.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data Transformation\n", + "This is an image classification task, which means that we need to perform a few transformations on our dataset before we train our models. I used similar transformations as used in this [tutorial](https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html#transfer-learning-for-computer-vision-tutorial). For a detailed overview of each transformation take a look at the official torchvision [documentation](https://pytorch.org/docs/stable/torchvision/transforms.html).\n", + "\n", + "The following code block performs the following operations:\n", + "- The `data_transforms` contains a series of transformations that will be performed on each image found in the dataset. This includes cropping the image, resizing the image, converting it to tensor, reshaping it, and normalizing it. \n", + "- Once those transformations have been defined, then the `DataLoader` function is used to automatically load the datasets and perform any additional configuration such as shuffling, batches, etc." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# configure root folder on your gdrive\n", + "data_dir = 'hymenoptera_data'\n", + "\n", + "# custom transformer to flatten the image tensors\n", + "class ReshapeTransform:\n", + " def __init__(self, new_size):\n", + " self.new_size = new_size\n", + "\n", + " def __call__(self, img):\n", + " result = torch.reshape(img, self.new_size)\n", + " return result\n", + "\n", + "# transformations used to standardize and normalize the datasets\n", + "data_transforms = {\n", + " 'train': transforms.Compose([\n", + " transforms.Resize(224),\n", + " transforms.CenterCrop(224),\n", + " transforms.ToTensor(),\n", + " ReshapeTransform((-1,)) # flattens the data\n", + " ]),\n", + " 'val': transforms.Compose([\n", + " transforms.Resize(224),\n", + " transforms.CenterCrop(224),\n", + " transforms.ToTensor(),\n", + " ReshapeTransform((-1,)) # flattens the data\n", + " ]),\n", + "}\n", + "\n", + "# load the correspoding folders\n", + "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),\n", + " data_transforms[x])\n", + " for x in ['train', 'val']}\n", + "\n", + "# load the entire dataset; we are not using minibatches here\n", + "train_dataset = torch.utils.data.DataLoader(image_datasets['train'],\n", + " batch_size=len(image_datasets['train']),\n", + " shuffle=True)\n", + "\n", + "test_dataset = torch.utils.data.DataLoader(image_datasets['val'],\n", + " batch_size=len(image_datasets['val']),\n", + " shuffle=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(244, 153)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(image_datasets['train']), len(image_datasets['val'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Print sample\n", + "It's always a good practise to take a quick look at the dataset before training your models. Below we print out an example of one of the images from the `train_dataset`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dimension of image: torch.Size([244, 150528]) \n", + " Dimension of labels torch.Size([244])\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/codespace/.conda/envs/play/lib/python3.7/site-packages/ipykernel_launcher.py:9: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at /opt/conda/conda-bld/pytorch_1646755953518/work/aten/src/ATen/native/TensorShape.cpp:2318.)\n", + " if __name__ == '__main__':\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# load the entire dataset\n", + "x, y = next(iter(train_dataset))\n", + "\n", + "# print one example\n", + "dim = x.shape[1]\n", + "print(\"Dimension of image:\", x.shape, \"\\n\", \n", + " \"Dimension of labels\", y.shape)\n", + "\n", + "plt.imshow(x[160].reshape(1, 3, 224, 224).squeeze().T.numpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building the Model\n", + "Let's now implement our [logistic regression](https://en.wikipedia.org/wiki/Logistic_regression) model. Logistic regression is one in a family of machine learning techniques that are used to train binary classifiers. They are also a great way to understand the fundamental building blocks of neural networks, thus they can also be considered the simplest of neural networks where the model performs a `forward` and `backward` propagation to train the model on the data provided. \n", + "\n", + "If you don't fully understand the structure of the code below, I strongly recommend you to read the following [tutorial](https://medium.com/dair-ai/pytorch-1-2-introduction-guide-f6fa9bb7597c), which I wrote for PyTorch beginners. You can also check out [Week 2](https://www.coursera.org/learn/neural-networks-deep-learning/home/week/2) of Andrew Ng's Deep Learning Specialization course for all the explanation, intuitions, and details of the different parts of the neural network such as the `forward`, `sigmoid`, `backward`, and `optimization` steps. \n", + "\n", + "In short:\n", + "- The `__init__` function initializes all the parameters (`W`, `b`, `grad`) that will be used to train the model through backpropagation. \n", + "- The goal is to learn the `W` and `b` that minimimizes the cost function which is computed as seen in the `loss` function below.\n", + "\n", + "Note that this is a very detailed implementation of a logistic regression model so I had to explicitly move a lot of the computations into the GPU for faster calcuation, `to(device)` takes care of this in PyTorch. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "class LR(nn.Module):\n", + " def __init__(self, dim, lr=torch.scalar_tensor(0.01)):\n", + " super(LR, self).__init__()\n", + " # intialize parameters\n", + " self.w = torch.zeros(dim, 1, dtype=torch.float).to(device)\n", + " self.b = torch.scalar_tensor(0).to(device)\n", + " self.grads = {\"dw\": torch.zeros(dim, 1, dtype=torch.float).to(device),\n", + " \"db\": torch.scalar_tensor(0).to(device)}\n", + " self.lr = lr.to(device)\n", + "\n", + " def forward(self, x):\n", + " # compute forward\n", + " z = torch.mm(self.w.T, x) + self.b\n", + " a = self.sigmoid(z)\n", + " return a\n", + "\n", + " def sigmoid(self, z):\n", + " # compute sigmoid\n", + " return 1/(1 + torch.exp(-z))\n", + "\n", + " def backward(self, x, yhat, y):\n", + " # compute backward\n", + " self.grads[\"dw\"] = (1/x.shape[1]) * torch.mm(x, (yhat - y).T)\n", + " self.grads[\"db\"] = (1/x.shape[1]) * torch.sum(yhat - y)\n", + " \n", + " def optimize(self):\n", + " # optimization step\n", + " self.w = self.w - self.lr * self.grads[\"dw\"]\n", + " self.b = self.b - self.lr * self.grads[\"db\"]\n", + "\n", + "## utility functions\n", + "def loss(yhat, y):\n", + " m = y.size()[1]\n", + " return -(1/m)* torch.sum(y*torch.log(yhat) + (1 - y)* torch.log(1-yhat))\n", + "\n", + "def predict(yhat, y):\n", + " y_prediction = torch.zeros(1, y.size()[1])\n", + " for i in range(yhat.size()[1]):\n", + " if yhat[0, i] <= 0.5:\n", + " y_prediction[0, i] = 0\n", + " else:\n", + " y_prediction[0, i] = 1\n", + " return 100 - torch.mean(torch.abs(y_prediction - y)) * 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pretesting the Model\n", + "It is also good practice to test your model and make sure the right steps are taking place before training the entire model." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost: tensor(0.6931)\n", + "Accuracy: tensor(50.4098)\n" + ] + } + ], + "source": [ + "# model pretesting\n", + "x, y = next(iter(train_dataset))\n", + "\n", + "# flatten/transform the data\n", + "x_flatten = x.T\n", + "y = y.unsqueeze(0) \n", + "\n", + "# num_px is the dimension of the images\n", + "dim = x_flatten.shape[0]\n", + "\n", + "# model instance\n", + "model = LR(dim)\n", + "model.to(device)\n", + "yhat = model.forward(x_flatten.to(device))\n", + "yhat = yhat.data.cpu()\n", + "\n", + "# calculate loss\n", + "cost = loss(yhat, y)\n", + "prediction = predict(yhat, y)\n", + "print(\"Cost: \", cost)\n", + "print(\"Accuracy: \", prediction)\n", + "\n", + "# backpropagate\n", + "model.backward(x_flatten.to(device), yhat.to(device), y.to(device))\n", + "model.optimize()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train the Model\n", + "It's now time to train the model. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost after iteration 0: 0.6931472420692444 | Train Acc: 50.40983581542969 | Test Acc: 45.75163269042969\n", + "Cost after iteration 10: 0.6691470742225647 | Train Acc: 64.3442611694336 | Test Acc: 54.24836730957031\n", + "Cost after iteration 20: 0.6513182520866394 | Train Acc: 68.44261932373047 | Test Acc: 54.24836730957031\n", + "Cost after iteration 30: 0.6367825865745544 | Train Acc: 68.03278350830078 | Test Acc: 54.24836730957031\n", + "Cost after iteration 40: 0.6245337128639221 | Train Acc: 69.67213439941406 | Test Acc: 54.90196228027344\n", + "Cost after iteration 50: 0.6139225959777832 | Train Acc: 70.90164184570312 | Test Acc: 56.20914840698242\n", + "Cost after iteration 60: 0.6045235395431519 | Train Acc: 72.54098510742188 | Test Acc: 56.86274337768555\n", + "Cost after iteration 70: 0.5960511565208435 | Train Acc: 74.18032836914062 | Test Acc: 57.51633834838867\n", + "Cost after iteration 80: 0.5883085131645203 | Train Acc: 73.77049255371094 | Test Acc: 57.51633834838867\n", + "Cost after iteration 90: 0.5811557769775391 | Train Acc: 74.59016418457031 | Test Acc: 58.1699333190918\n", + "Cost after iteration 100: 0.5744912028312683 | Train Acc: 75.0 | Test Acc: 59.47712326049805\n", + "Cost after iteration 110: 0.5682381987571716 | Train Acc: 75.40983581542969 | Test Acc: 60.13071823120117\n", + "Cost after iteration 120: 0.5623382925987244 | Train Acc: 75.81967163085938 | Test Acc: 60.13071823120117\n", + "Cost after iteration 130: 0.5567454099655151 | Train Acc: 75.81967163085938 | Test Acc: 59.47712326049805\n", + "Cost after iteration 140: 0.5514224767684937 | Train Acc: 75.81967163085938 | Test Acc: 59.47712326049805\n", + "Cost after iteration 150: 0.5463393926620483 | Train Acc: 76.22950744628906 | Test Acc: 58.82352828979492\n", + "Cost after iteration 160: 0.5414712429046631 | Train Acc: 76.63934326171875 | Test Acc: 58.82352828979492\n", + "Cost after iteration 170: 0.5367968678474426 | Train Acc: 77.04917907714844 | Test Acc: 58.82352828979492\n", + "Cost after iteration 180: 0.5322986245155334 | Train Acc: 77.04917907714844 | Test Acc: 58.82352828979492\n", + "Cost after iteration 190: 0.5279611349105835 | Train Acc: 77.45901489257812 | Test Acc: 58.82352828979492\n", + "Cost after iteration 200: 0.5237710475921631 | Train Acc: 78.2786865234375 | Test Acc: 58.1699333190918\n", + "Cost after iteration 210: 0.5197169184684753 | Train Acc: 78.2786865234375 | Test Acc: 58.1699333190918\n", + "Cost after iteration 220: 0.5157885551452637 | Train Acc: 79.09835815429688 | Test Acc: 57.51633834838867\n", + "Cost after iteration 230: 0.5119768977165222 | Train Acc: 79.91802978515625 | Test Acc: 57.51633834838867\n", + "Cost after iteration 240: 0.5082740187644958 | Train Acc: 79.91802978515625 | Test Acc: 60.13071823120117\n", + "Cost after iteration 250: 0.5046727657318115 | Train Acc: 79.91802978515625 | Test Acc: 60.13071823120117\n", + "Cost after iteration 260: 0.5011667013168335 | Train Acc: 80.73770141601562 | Test Acc: 60.7843132019043\n", + "Cost after iteration 270: 0.49775001406669617 | Train Acc: 81.14753723144531 | Test Acc: 60.7843132019043\n", + "Cost after iteration 280: 0.49441757798194885 | Train Acc: 81.557373046875 | Test Acc: 60.7843132019043\n", + "Cost after iteration 290: 0.49116453528404236 | Train Acc: 81.557373046875 | Test Acc: 61.43790817260742\n", + "Cost after iteration 300: 0.48798662424087524 | Train Acc: 81.557373046875 | Test Acc: 61.43790817260742\n", + "Cost after iteration 310: 0.48487982153892517 | Train Acc: 81.96721649169922 | Test Acc: 61.43790817260742\n", + "Cost after iteration 320: 0.4818406403064728 | Train Acc: 81.96721649169922 | Test Acc: 61.43790817260742\n", + "Cost after iteration 330: 0.4788656532764435 | Train Acc: 82.37704467773438 | Test Acc: 61.43790817260742\n", + "Cost after iteration 340: 0.4759517014026642 | Train Acc: 82.37704467773438 | Test Acc: 61.43790817260742\n", + "Cost after iteration 350: 0.4730961322784424 | Train Acc: 83.19672393798828 | Test Acc: 62.09150314331055\n", + "Cost after iteration 360: 0.4702962040901184 | Train Acc: 84.01639556884766 | Test Acc: 62.09150314331055\n", + "Cost after iteration 370: 0.46754947304725647 | Train Acc: 84.01639556884766 | Test Acc: 62.09150314331055\n", + "Cost after iteration 380: 0.46485379338264465 | Train Acc: 84.01639556884766 | Test Acc: 61.43790817260742\n", + "Cost after iteration 390: 0.4622068703174591 | Train Acc: 84.01639556884766 | Test Acc: 61.43790817260742\n", + "Cost after iteration 400: 0.4596068263053894 | Train Acc: 84.01639556884766 | Test Acc: 61.43790817260742\n", + "Cost after iteration 410: 0.45705193281173706 | Train Acc: 84.01639556884766 | Test Acc: 61.43790817260742\n", + "Cost after iteration 420: 0.4545402526855469 | Train Acc: 84.42623138427734 | Test Acc: 61.43790817260742\n", + "Cost after iteration 430: 0.4520702660083771 | Train Acc: 84.83606719970703 | Test Acc: 61.43790817260742\n", + "Cost after iteration 440: 0.4496404826641083 | Train Acc: 84.83606719970703 | Test Acc: 61.43790817260742\n", + "Cost after iteration 450: 0.4472493827342987 | Train Acc: 85.24590301513672 | Test Acc: 61.43790817260742\n", + "Cost after iteration 460: 0.4448956549167633 | Train Acc: 85.6557388305664 | Test Acc: 61.43790817260742\n", + "Cost after iteration 470: 0.4425780475139618 | Train Acc: 85.6557388305664 | Test Acc: 61.43790817260742\n", + "Cost after iteration 480: 0.44029536843299866 | Train Acc: 85.6557388305664 | Test Acc: 61.43790817260742\n", + "Cost after iteration 490: 0.43804648518562317 | Train Acc: 85.6557388305664 | Test Acc: 61.43790817260742\n" + ] + } + ], + "source": [ + "# hyperparams\n", + "costs = []\n", + "dim = x_flatten.shape[0]\n", + "learning_rate = torch.scalar_tensor(0.0001).to(device)\n", + "num_iterations = 500\n", + "lrmodel = LR(dim, learning_rate)\n", + "lrmodel.to(device)\n", + "\n", + "# transform the data\n", + "def transform_data(x, y):\n", + " x_flatten = x.T\n", + " y = y.unsqueeze(0) \n", + " return x_flatten, y \n", + "\n", + "# train the model\n", + "for i in range(num_iterations):\n", + " x, y = next(iter(train_dataset))\n", + " test_x, test_y = next(iter(test_dataset))\n", + " x, y = transform_data(x, y)\n", + " test_x, test_y = transform_data(test_x, test_y)\n", + "\n", + " # forward\n", + " yhat = lrmodel.forward(x.to(device))\n", + " cost = loss(yhat.data.cpu(), y)\n", + " train_pred = predict(yhat, y)\n", + " \n", + " # backward\n", + " lrmodel.backward(x.to(device), \n", + " yhat.to(device), \n", + " y.to(device))\n", + " lrmodel.optimize()\n", + "\n", + " # test\n", + " yhat_test = lrmodel.forward(test_x.to(device))\n", + " test_pred = predict(yhat_test, test_y)\n", + "\n", + " if i % 10 == 0:\n", + " costs.append(cost)\n", + "\n", + " if i % 10 == 0:\n", + " print(\"Cost after iteration {}: {} | Train Acc: {} | Test Acc: {}\".format(i, \n", + " cost, \n", + " train_pred,\n", + " test_pred))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Result\n", + "From the loss curve below you can see that the model is sort of learning to classify the images given the decreas in the loss. I only ran the model for `100` iterations. Train the model for many more rounds and analyze the results. In fact, I have suggested a couple of experiments and exercises at the end of the tutorial that you can try to get a more improved model." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAjd0lEQVR4nO3dd3gV55n+8e+jI4kiOkgUCSHRexXVxgbbGNzALYkhTiCJg5NfiJ1NnKyzm7ZONmWzyXrj4I1tQuLEBbfYxgYHYxvcwYhuRBOiSQgkEL2pPb8/dJwohCJQGemc+3NdunTmnRmdZy4Ot0bvvPOOuTsiIhK5YoIuQEREapeCXkQkwinoRUQinIJeRCTCKehFRCJcbNAFnKldu3aelpYWdBkiIg3KypUr97t74tnW1bugT0tLIzMzM+gyREQaFDPbea51Veq6MbNJZrbZzLLN7P6zrP8fM1sT/tpiZocqrZtuZlvDX9Mv6QhEROSSXfCM3sxCwGxgApALrDCz+e6e9ck27v4vlbb/OjAk/LoN8EMgA3BgZXjfgzV6FCIick5VOaMfAWS7e467FwPzgCnn2X4q8HT49URgsbsXhcN9MTCpOgWLiMjFqUrQJwO7Ky3nhtv+iZl1AdKBty5mXzObaWaZZpZZWFhYlbpFRKSKanp45R3A8+5edjE7ufuj7p7h7hmJiWe9aCwiIpeoKkGfB3SutJwSbjubO/h7t83F7isiIrWgKkG/AuhhZulmFk9FmM8/cyMz6w20Bj6s1LwIuNbMWptZa+DacJuIiNSRCwa9u5cCs6gI6I3As+6+wcweMLPJlTa9A5jnleY9dvci4MdU/LJYATwQbqtxh04U8+AbW9iYf6Q2fryISINVpRum3H0hsPCMth+csfyjc+w7F5h7ifVVmWHMXpLNieIy+nRsUdtvJyLSYETMXDctm8Zxefd2LFiXjx6mIiLydxET9AA3DOxE3qGTrM09HHQpIiL1RkQF/YS+7YkLGQvX5wddiohIvRFRQd+ySRxjeySq+0ZEpJKICnqA6wd0VPeNiEglERf0n3TfLFi3J+hSRETqhYgL+k+6bxau36vuGxERIjDoAW4Id9+s2X0o6FJERAIXkUF/zd+6bzT6RkQkIoO+ZZM4ruiRyML1Gn0jIhKRQQ8Vo2/2HD7FanXfiEiUi9igv6Zve+JDMSxU942IRLmIDfqK0TftWLg+n/Jydd+ISPSK2KAHuGFgRffNmtxDQZciIhKYiA76T7pvNPpGRKJZRAd9i8ZxXNGzHa+p+0ZEolhEBz1o9I2ISMQH/SfdN6+s1dw3IhKdIj7oWzSOY1L/DrywMpejp0qCLkdEpM5FfNAD3DU2naOnS3lmxe6gSxERqXNREfQDU1oxMr0Nc9/bTklZedDliIjUqagIeoAvj+3KnsOn9JhBEYk6URP0V/VOomtiAnPe3a6JzkQkqkRN0MfEGF+6PJ31eYdZvr0o6HJEROpM1AQ9wG1DU2iTEM+cd3OCLkVEpM5EVdA3jgtx56guvLGxgG2Fx4IuR0SkTkRV0AN8fnQX4mNj+P1724MuRUSkTkRd0Ldr1ohbhyTzwspcDhw7HXQ5IiK1LuqCHipuoDpdWs4Ty3YFXYqISK2LyqDvntSc8b0S+dOHOzhVUhZ0OSIitapKQW9mk8xss5llm9n959jm02aWZWYbzOypSu1lZrYm/DW/pgqvri+P7cqB48W8uDov6FJERGpV7IU2MLMQMBuYAOQCK8xsvrtnVdqmB/Bd4DJ3P2hmSZV+xEl3H1yzZVff6G5t6depBY++k8Ptw1KIC0XlHzciEgWqkm4jgGx3z3H3YmAeMOWMbb4MzHb3gwDuXlCzZdY8M+Mb1/Rk+/7jzNNkZyISwaoS9MlA5STMDbdV1hPoaWbvm9kyM5tUaV1jM8sMt998tjcws5nhbTILCwsvpv5quaZPEiPS2/Dg4i2awlhEIlZN9VfEAj2AccBU4DEzaxVe18XdM4BpwINm1u3Mnd39UXfPcPeMxMTEGirpwsyMf7++DweOF/PI27pbVkQiU1WCPg/oXGk5JdxWWS4w391L3H07sIWK4Mfd88Lfc4ClwJBq1lyjBnVuxeRBnZjzXg57D58KuhwRkRpXlaBfAfQws3QziwfuAM4cPfMSFWfzmFk7KrpycsystZk1qtR+GZBFPfPtib0oL4dfvb456FJERGrcBYPe3UuBWcAiYCPwrLtvMLMHzGxyeLNFwAEzywKWAN929wNAHyDTzNaG239eebROfdG5TVOmj+nC86ty2Zh/JOhyRERqlNW3udkzMjI8MzOzzt/38IkSrvjlEgamtOTPXxpZ5+8vIlIdZrYyfD30n2jweFjLpnF8/aruvLt1P+9sqbuRPyIitU1BX8nnRnehc5sm/HThRsrK69dfOiIil0pBX0mj2BDfmdibTXuP8pdVuUGXIyJSIxT0Z7hxYEcGdW7Fr17fwrHTpUGXIyJSbQr6M5gZP7ypL/uOnuK//rop6HJERKpNQX8WQ1Nb84Ux6fzpw50szzkQdDkiItWioD+H+yb2JLVNU/71hXWcLNac9SLScCnoz6FpfCw/v3UAOw6c4H/e2BJ0OSIil0xBfx5jurdj6ohU5rybw5rdh4IuR0TkkijoL+C71/emfYvGfOf5tZwuVReOiDQ8CvoLaNE4jp/eMoAt+44xe8m2oMsREbloCvoqGN87iVuHJPPwkmyy9mjSMxFpWBT0VfT9G/vSqmkc33lhLaVl5UGXIyJSZQr6KmqdEM+Pp/Tn47wjGoUjIg2Kgv4iXDegI3cM78zsJdtYsrneP/9cRARQ0F+0H03uR+8OzfnmM2vYc+hk0OWIiFyQgv4iNY4L8fBnh1JcWs6sp1ZRov56EannFPSXoGtiM35+20BW7TrELxfpObMiUr8p6C/RTYM68blRXXj0nRwWZ+0LuhwRkXNS0FfD927sQ//kFnzr2TXsLjoRdDkiImeloK+GRrEhZk8bijvMemoVxaXqrxeR+kdBX01d2ibwy08NZG3uYX44/2Pc9axZEalfFPQ1YFL/jnxtfDee/mg3c97dHnQ5IiL/IDboAiLFtyb0Ysf+E/z0tY2ktm3KxH4dgi5JRATQGX2NiYkxfvXpQQxKacW981azPvdw0CWJiAAK+hrVOC7EY5/PoG1CI770+ArdOSsi9YKCvoYlNm/E3BnDOVlcxhf/uIJjp0uDLklEopyCvhb06tCc3352KFsLjvH1p1ZpWmMRCZSCvpZc2TORH03ux5LNhfzolQ0adikigalS0JvZJDPbbGbZZnb/Obb5tJllmdkGM3uqUvt0M9sa/ppeU4U3BJ8b1YW7r+jKE8t2aU4cEQnMBYdXmlkImA1MAHKBFWY2392zKm3TA/gucJm7HzSzpHB7G+CHQAbgwMrwvgdr/lDqp/uv682RU6U8vHQbCY1i+dr47kGXJCJRpipn9COAbHfPcfdiYB4w5YxtvgzM/iTA3f2Tp3JMBBa7e1F43WJgUs2U3jCYGT+5uT9TBnfil4s286cPdwRdkohEmarcMJUM7K60nAuMPGObngBm9j4QAn7k7n89x77JZ76Bmc0EZgKkpqZWtfYGIxRj/PenBnGiuIwfvLyBpvGx3D4sJeiyRCRK1NTF2FigBzAOmAo8Zmatqrqzuz/q7hnunpGYmFhDJdUvcaEYHpo6hMu7t+M7z6/ltfX5QZckIlGiKkGfB3SutJwSbqssF5jv7iXuvh3YQkXwV2XfqNE4LsSjnx/GkNTW3DNvNUv13FkRqQNVCfoVQA8zSzezeOAOYP4Z27xExdk8ZtaOiq6cHGARcK2ZtTaz1sC14bao1TQ+lrkzhtOzfXNm/nmlHjIuIrXugkHv7qXALCoCeiPwrLtvMLMHzGxyeLNFwAEzywKWAN929wPuXgT8mIpfFiuAB8JtUa1lkzie+NJIeiQ1Y+afMlm0YW/QJYlIBLP6diNPRkaGZ2ZmBl1GnTh8soTpcz9ifd5hHvzMYG4a1CnokkSkgTKzle6ecbZ1ujM2QC2bxPHEXSMZltqae+et5vmVuUGXJCIRSEEfsGaNYvnjF4czpls77ntuLU8t3xV0SSISYRT09UDT+FjmTM9gfK9E/u3F9cx9T0+pEpGao6CvJxrHhXjkcxlM7NeeB17N4levb9ZEaCJSIxT09Uh8bAyzpw3l0xkpPPRWNv/6wjpKNMWxiFSTnhlbz8SGYvjFbQPp0LIJv3lzK4VHTzP7s0NpGq9/KhG5NDqjr4fMjG9O6MlPbxnA21sKmfroMvYfOx10WSLSQCno67FpI1N55HMZbN53lNv/7wN2HjgedEki0gAp6Ou5CX3b8+Rdozh0soTb/u8DVu+Kmqn8RaSGKOgbgGFdWvPCV8fQJD7EZx5dxstronZeOBG5BAr6BqJbYjNe/trlDO7cinvnreGXizZRXq7hlyJyYQr6BqRNQjxPfGkkdwzvzOwl2/jqkys5fro06LJEpJ5T0Dcw8bEx/OzWAXz/xr4sztrH7b/7kLxDJ4MuS0TqMQV9A2RmfOnydH4/Yzi5RSeY8tv3Wbkz6md/FpFzUNA3YON7JfHi18aQ0CjEZx5Zxh/f365pE0TknyjoG7juSc2ZP+tyxvVK5EevZPGNZ9Zwolj99iLydwr6CNCySRyPfi6D+67tyfy1e7hl9gfkFB4LuiwRqScU9BEiJsaYdVUPHv/CCAqOnmLKb9/XIwpFBFDQR5wreibyytcvJz0xgbv/vJKfvbZRM2CKRDkFfQRKad2UZ+8ezdQRqTzydg6ffuRDdhedCLosEQmIgj5CNY4L8bNbB/DQ1CFk7zvGDb95l9fW5wddlogEQEEf4W4a1IkF94wlvV0CX31yFd97aT2nSsqCLktE6pCCPgqktm3Kc18Zw8wruvLEsl3cPPt9sgs0KkckWijoo0R8bAz/dn0f/jBjOAVHT3PjQ+/y52U7dYOVSBRQ0EeZ8b2TeO3esQxPa8P3X/qYL/5xBQVHTwVdlojUIgV9FGrfojF/+uII/mNyPz7YdoBJD76rMfciEUxBH6XMjOlj0lhwz1iSWzXh7j+v5NvPreWYpj0WiTgK+ijXPakZL3x1DLPGd+eFVblc97/v8OG2A0GXJSI1SEEvxMfGcN/EXjz3ldGEzJj62DK+/9LHeqiJSIRQ0MvfDOvShtfuvYIvXpbOE8t3MvHBd/gge3/QZYlINVUp6M1skpltNrNsM7v/LOtnmFmhma0Jf91VaV1Zpfb5NVm81Lwm8SF+cFNfnrt7NHGhGKbNWc73XlqvvnuRBswuNI7azELAFmACkAusAKa6e1albWYAGe4+6yz7H3P3ZlUtKCMjwzMzM6u6udSik8Vl/HrxZua8t51OLZvw01sHcGXPxKDLEpGzMLOV7p5xtnVVOaMfAWS7e467FwPzgCk1WaDUT03iQ/z7DX15/iujaRQXw/S5H/GNeavZf+x00KWJyEWoStAnA7srLeeG2850m5mtM7PnzaxzpfbGZpZpZsvM7OazvYGZzQxvk1lYWFjl4qVuVPTdj+Weq3uwYH0+1/z6bZ5fmau7akUaiJq6GPsKkObuA4HFwOOV1nUJ/zkxDXjQzLqdubO7P+ruGe6ekZioroH6qFFsiG9O6MnCe8bSPbEZ9z23ls/OWc6O/ceDLk1ELqAqQZ8HVD5DTwm3/Y27H3D3T/6enwMMq7QuL/w9B1gKDKlGvRKwHu2b8+zdo/nJzf1Zn3uYiQ++w+wl2Zwu1YyYIvVVVYJ+BdDDzNLNLB64A/iH0TNm1rHS4mRgY7i9tZk1Cr9uB1wGZCENWkyMceeoLrzxrSu5qncSv1y0mesefJf3tmoopkh9dMGgd/dSYBawiIoAf9bdN5jZA2Y2ObzZPWa2wczWAvcAM8LtfYDMcPsS4OeVR+tIw9a+RWP+785h/PELwylz587fL2fWU6vYd0STpInUJxccXlnXNLyyYTpVUsbv3t7Gw0u3ER+K4RvX9GDGmDRiQ7onT6QuVHd4pcgFNY4L8Y1rerL4X64gI601P1mwkRt+8x4fbFN3jkjQFPRSo7q0TeAPM4bzuzuHcby4lGmPLef/PbmS3IN6OLlIUBT0UuPMjEn9O/DGN6/kmxN68tamAq7+1dv8evEWThZrdI5IXVPQS61pHBfinqt78Na3xnFtvw785s2tXP2rpby6bo9uthKpQwp6qXWdWjXhoalDeGbmKFo2jWfWU6u5/XcfsnrXwaBLE4kKCnqpMyO7tuXVr1/OL24bwM4DJ7jl4Q+45+nV6r8XqWUKeqlToRjjM8NTWfrtcXz9qu4s2rCXq371Nv/1100cPVUSdHkiEUlBL4Fo1iiWb13biyX3jePGAR15eOk2xv/3Uv704Q5KysqDLk8koijoJVCdWjXh158ZzPxZl9EtsRk/eHkDE379ti7YitQgBb3UCwNTWjFv5ij+MGM4jWJDzHpqNTfPfl83XInUAAW91BtmxvjeSSy8dyz//alBFB49zbTHljPjDx+RtedI0OWJNFia60bqrVMlZfzpwx3MXrKNwydLuHFgR745oSddE6v8ZEqRqHG+uW4U9FLvHT5ZwmPv5DD3/e2cLi3n9qEp3HNND5JbNQm6NJF6Q0EvEWH/sdM8vGQbTyzbCcC0kal8bXx3Eps3CrgykeAp6CWi5B06yUNvbuW5lbnEhYzPj07j7iu60raZAl+il4JeItL2/cd56M2tvLQmj8ZxIT4/Oo2ZV3SlTUJ80KWJ1DkFvUS07IJj/ObNrbyybg9N40LMuCyNL4/tSqumCnyJHgp6iQpb9x3lwTe3smBdPs0axfL50V24a6zO8CU6KOglqmzee5SH3trKgvX5NI4N8bnRXbhrbDpJzRsHXZpIrVHQS1TKLjjKb9/KZv7aPcSFYpg6IpWvXNmNDi0V+BJ5FPQS1bbvP87DS7L5y+o8QmbcNiyFr1zZlS5tE4IuTaTGKOhFgN1FJ/jd29t4LjOX0vJybhrUia+O60bvDi2CLk2k2hT0IpUUHDnFnPe28+SynRwvLuOaPkl8dVx3hnVpHXRpIpdMQS9yFodOFPP4Bzv5wwfbOXSihBHpbfjqld0Y1ysRMwu6PJGLoqAXOY/jp0t5+qNdzH1vO3sOn6JX++bMvKIrkwd3Ii6kCV6lYVDQi1RBSVk5r6zdwyNv57B531E6tWzMFy9P544RqTRrFBt0eSLnpaAXuQjuztIthTzy9jaW5RTRvHEs00akMuOyNDq21IyZUj8p6EUu0Zrdh3js3RxeW59PjBk3DuzIXWO70j+5ZdClifwDBb1INe0uOsEf3t/BMyt2cby4jNFd23LX2HTG90oiJkYXbiV4CnqRGnL4ZAnzPtrFHz/YQf7hU6S3S+ALl6Vx29AUEtSPLwE6X9BXaUiBmU0ys81mlm1m959l/QwzKzSzNeGvuyqtm25mW8Nf0y/9MESC17JJHHdf2Y13vjOe30wdQosmcfzg5Q2M+tmb/HThRnIPngi6RJF/csEzejMLAVuACUAusAKY6u5ZlbaZAWS4+6wz9m0DZAIZgAMrgWHufvBc76czemloVu06yNz3tvPax3txdyb268D0MWmMTG+j8fhSZ853Rl+VvzVHANnunhP+YfOAKUDWefeqMBFY7O5F4X0XA5OAp6tSuEhDMDS1NUOntWbPoZM8/uEO5n20m9c+3kvvDs2ZMSaNKYOTaRIfCrpMiWJV6bpJBnZXWs4Nt53pNjNbZ2bPm1nni9nXzGaaWaaZZRYWFlaxdJH6pVOrJnz3uj4s++7V/PzWAQDc/5f1jPrZm/xs4UZ2F6lbR4JRU7f9vQKkuftAYDHw+MXs7O6PunuGu2ckJibWUEkiwWgSH+KOEam8du9Ynpk5isu6t2XOe9u54pdLuOvxFSzdXEB5ef0aBCGRrSpdN3lA50rLKeG2v3H3A5UW5wD/VWnfcWfsu/RiixRpiMyMkV3bMrJrW/YcOslTy3cxb8Uu3thYQFrbptw5qgu3D0vRIw+l1lXlYmwsFRdjr6YiuFcA09x9Q6VtOrp7fvj1LcC/uvuo8MXYlcDQ8KarqLgYW3Su99PFWIlkxaXlvPZxPk8s28mKHQdpFBvDlMGduHNUFwamtAq6PGnAqnUx1t1LzWwWsAgIAXPdfYOZPQBkuvt84B4zmwyUAkXAjPC+RWb2Yyp+OQA8cL6QF4l08bExTBmczJTByWTtOcITy3fy0uo8ns3MpX9yCz47sguTB3XSmHypUbphSiRgR06V8PLqPJ5cvotNe4/SrFEstwxJZtrIVPp01ENRpGp0Z6xIA+DurNp1kCeX7+LVdfkUl5YzJLUVU4encuOgjjSN11m+nJuCXqSBOXi8mBdW5fL0R7vYVnic5o1imTKkE3cMT9WEanJWCnqRBsrdWbHjIPM+2sWC9fmcLi1nYEpL7hieyk2DOtK8cVzQJUo9oaAXiQCHT5Tw4upcnv5oN5v3HaVJXIjrB3TkM8M7MzyttaZbiHIKepEI4u6s2X2IZzN3M3/NHo4Xl9G1XQKfHt6ZW4cmk9S8cdAlSgAU9CIR6kRxKQvW5fPMit1k7jxIKMYY3yuR24d15qreScTH6pm30UJBLxIFsguO8dzK3fxlVR6FR0/TJiGemwcn86mMFA3TjAIKepEoUlpWzjtbC3kuM5c3Nu6jpMzpn9yC24amMGVwMm0SNOVCJFLQi0SpouPFvLwmj+dX5rJhzxFiY4zxvZO4fVgK43upayeSKOhFhE17j/DCylxeXL2H/cdO07ppHFMGJ3PLkGQGprTUqJ0GTkEvIn9TWlbOu1v38/yqXBZn7aO4tJxuiQncOjSFKYM7kdK6adAlyiVQ0IvIWR0+WcLC9fm8uCqPj3ZUzDc4Mr0Ntw5N5roBHWmhG7IaDAW9iFzQ7qITvLQ6jxdX55Gz/zjxsTFc0yeJKYOTGdcrkUaxehxifaagF5Eqc3fW5h7mpdV5vLJ2DweOF9OySRzXD+jAlMHJjEhrQ0yM+vPrGwW9iFyS0rJy3svez8tr9rBow15OFJfRqWVjbhrUiZsGdaJfpxa6iFtPKOhFpNpOFJeyOGsfL6/ZwztbCiktd7olJjB5UDKTB3civV1C0CVGNQW9iNSog8eLWfhxPvPX7OGjHUW4w8CUltw0sBM3DOxIp1ZNgi4x6ijoRaTW5B8+yatr85m/dg/r8w4DkNGlNTcN6sR1AzpokrU6oqAXkTqxY/9xXl23h1fW5rN531FiDEZ1bcsNAzsyqV8H2jZrFHSJEUtBLyJ1bsu+o7y6dg+vrssnZ/9xQjHGmG5tuWFARyb260BrzblToxT0IhIYd2dj/lEWrK8I/Z0HThAbY4zp3o4bBnTg2r4K/ZqgoBeResHd2bDnCAvW57NgXT67ik787Uz/+gEdubZve3XvXCIFvYjUO5VDf+H6ijP9UIwxqmsbJvXvyMR+7XUh9yIo6EWkXvuke2dhOPRz9h/HDIZ3acOk/h2Y1L+DhmxegIJeRBoMd2fLvmO89nE+f/14L5v2HgVgUOdWXNe/AxP7ddDNWWehoBeRBmv7/uN/C/11uRXj9Hu1b87Efu2Z2L8DfTtqGgZQ0ItIhMg9eILXN+xj0Ya9rNhRRLlDSusmTOrXgWv7dWBYl9aEonTCNQW9iESc/cdO80bWPv66YS/vZ++npMxpmxDPNX3ac22/9lzWvR2N46JnamUFvYhEtKOnSli6uZDXs/axZFMBx06X0jQ+xJU9E5nQtz1X9U6iVdPIHqtf7aA3s0nA/wIhYI67//wc290GPA8Md/dMM0sDNgKbw5ssc/evnO+9FPQiUh2nS8tYllPE6xv2sjhrHwVHTxOKMYantWZC3w5c27c9ndtE3uMSqxX0ZhYCtgATgFxgBTDV3bPO2K45sACIB2ZVCvpX3b1/VYtV0ItITSkvd9blHWZxVkXob9l3DIDeHZozoW97ru7TnoHJLSPiQSrnC/rYKuw/Ash295zwD5sHTAGyztjux8AvgG9Xo1YRkRoTE2MM7tyKwZ1b8e2Jvdl54DiLs/bxetY+Zi/J5qG3skls3ohr+iRxde+Kfv0m8ZHXr1+VoE8GdldazgVGVt7AzIYCnd19gZmdGfTpZrYaOAJ8z93frU7BIiKXqkvbBO4a25W7xnbl4PFilm4p4I2sAl5Zm8/TH+2mcVwMl3dvx1W923N1nyTat4iMO3OrEvTnZWYxwK+BGWdZnQ+kuvsBMxsGvGRm/dz9yBk/YyYwEyA1NbW6JYmIXFDrhHhuGZLCLUNSKC4tZ/n2A7yRtY83NhbwxsYCeBH6J7fg6nDo9+/UcLt4qtJHPxr4kbtPDC9/F8DdfxZebglsA46Fd+kAFAGT3T3zjJ+1FLjvzPbK1EcvIkH65M7cNzft462NBazadZByh8TmjRjfK5GreidxeY9EmjWq9nlyjaruxdhYKi7GXg3kUXExdpq7bzjH9ksJh7mZJQJF7l5mZl2Bd4EB7l50rvdT0ItIfVJ0vJilmwt4c1MB72wp5OipUuJCxsj0tozvncRVvZPqxZQM1boY6+6lZjYLWETF8Mq57r7BzB4AMt19/nl2vwJ4wMxKgHLgK+cLeRGR+qZNQjy3Dk3h1qEplJSVs3LnQZZsKuCtTQX8+NUsfvxqFuntEhjXK5HxvZIYkd6m3t2opRumREQu0e6iEyzZXMCSTQV8sO0Ap0vLaRIXYky3tozrncS4nol1NmZfd8aKiNSyUyVlfJhzgKWbCnhrcwG7i04C0C0xgXG9khjXK5ER6W1oFFs7Z/sKehGROuTu5Ow/ztLNhSzdXMDy7UUUVz7b75XIlT2TSG1bc2f7CnoRkQCdKC5lWc6BcPAXsqvoBADp7RK4okc7ruyVyKiubWkaf+kjeRT0IiL1yI79x3l7SyFvbynkw20HOFlSRnwohmv7tee304Ze0s+s7hQIIiJSg9LaJZDWLoHpY9I4XVpG5o6DvL2lkLhQ7dyQpaAXEQlQo9gQl3Vvx2Xd29Xae8TU2k8WEZF6QUEvIhLhFPQiIhFOQS8iEuEU9CIiEU5BLyIS4RT0IiIRTkEvIhLh6t0UCGZWCOysxo9oB+yvoXIaEh13dNFxR5eqHHcXd08824p6F/TVZWaZ55rvIZLpuKOLjju6VPe41XUjIhLhFPQiIhEuEoP+0aALCIiOO7rouKNLtY474vroRUTkH0XiGb2IiFSioBcRiXARE/RmNsnMNptZtpndH3Q9tcnM5ppZgZl9XKmtjZktNrOt4e+tg6yxpplZZzNbYmZZZrbBzO4Nt0f6cTc2s4/MbG34uP8j3J5uZsvDn/dnzCw+6Fprg5mFzGy1mb0aXo6W495hZuvNbI2ZZYbbLvmzHhFBb2YhYDZwHdAXmGpmfYOtqlb9EZh0Rtv9wJvu3gN4M7wcSUqBb7l7X2AU8LXwv3GkH/dp4Cp3HwQMBiaZ2SjgF8D/uHt34CDwpeBKrFX3AhsrLUfLcQOMd/fBlcbPX/JnPSKCHhgBZLt7jrsXA/OAKQHXVGvc/R2g6IzmKcDj4dePAzfXZU21zd3z3X1V+PVRKv7zJxP5x+3ufiy8GBf+cuAq4Plwe8QdN4CZpQA3AHPCy0YUHPd5XPJnPVKCPhnYXWk5N9wWTdq7e3749V6gfZDF1CYzSwOGAMuJguMOd1+sAQqAxcA24JC7l4Y3idTP+4PAd4Dy8HJbouO4oeKX+etmttLMZobbLvmzroeDRyB3dzOLyHGzZtYMeAH4hrsfqTjJqxCpx+3uZcBgM2sFvAj0Drai2mdmNwIF7r7SzMYFXE4QLnf3PDNLAhab2abKKy/2sx4pZ/R5QOdKyynhtmiyz8w6AoS/FwRcT40zszgqQv5Jd/9LuDnij/sT7n4IWAKMBlqZ2ScnapH4eb8MmGxmO6joir0K+F8i/7gBcPe88PcCKn65j6Aan/VICfoVQI/wFfl44A5gfsA11bX5wPTw6+nAywHWUuPC/bO/Bza6+68rrYr0404Mn8ljZk2ACVRcn1gC3B7eLOKO292/6+4p7p5Gxf/nt9z9s0T4cQOYWYKZNf/kNXAt8DHV+KxHzJ2xZnY9FX16IWCuu/9nsBXVHjN7GhhHxdSl+4AfAi8BzwKpVEzz/Gl3P/OCbYNlZpcD7wLr+Xuf7b9R0U8fycc9kIoLbyEqTsyedfcHzKwrFWe6bYDVwJ3ufjq4SmtPuOvmPne/MRqOO3yML4YXY4Gn3P0/zawtl/hZj5igFxGRs4uUrhsRETkHBb2ISIRT0IuIRDgFvYhIhFPQi4hEOAW9iEiEU9CLiES4/w+yO3LYi/qE3AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "## the trend in the context of loss\n", + "plt.plot(costs)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Some Notes\n", + "There are many improvements and different experiments that you can perform on top of this notebook to keep practising ML:\n", + "- It is always good to normalize/standardize your images which helps with learning. As an experiment, you can research and try different ways to standarize the dataset. We have normalized the dataset with the builtin PyTorch [normalizer](https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.Normalize) which uses the mean and standard deviation. Play around with different transformations or normalization techniques. What effect does this have on learning in terms of speed and loss?\n", + "- You can try many things to help with learning such as playing around with the learning rate. Try to decrease and increase the learning rate and observe the effect of this in learning? \n", + "- If you explored the dataset further, you may have noticed that all the \"no-bee\" images are actually \"ant\" images. If you would like to create a more robust model, you may want to make your \"no-bee\" images more random and diverse through some data augmentation technique. This is a more advanced approach but there is a lot of good content to try out this idea. \n", + "- The model is not really performing well just using simple logistic regression model. It could be because of the dataset I am using and because I didn't train it for long enough. Hyperparameters may also be off. It is a relatively small dataset but the performance could get better with more data and training over time. A more challenging task involves adopting the model to other datasets. Give it a try!\n", + "- Another important part that is missing in this tutorial is the comprehensive analysis of the model results. If you understand the code, it should be easy to figure out how to test with a few examples. In fact, it would also be great if you can put aside a small testing dataset for this part of the exercise, so as to test the generalization capabilities of the model.\n", + "- We built the logistic regression model from scratch but with libraries like PyTorch, these days you can simply leverage the high-level functions that implement certain parts of the neural network for you. This simplifies your code and minimizes the amount of bugs in your code. Plus you don't have to code your neural networks from scratch all the time. As a bonus exercise, try to adapt PyTorch builtin modules and functions for implementing a simpler, more concise version of the above logistic regression model. I will also add this as a to-do task for myself and post a solution soon. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "- [Understanding the Impact of Learning Rate on Neural Network Performance](https://machinelearningmastery.com/understand-the-dynamics-of-learning-rate-on-deep-learning-neural-networks/)\n", + "- [Transfer Learning for Computer Vision Tutorial](https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html#transfer-learning-for-computer-vision-tutorial)\n", + "- [Deep Learning Specialization by Andrew Ng](https://www.coursera.org/learn/neural-networks-deep-learning/home/welcome)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 7a2fee2fb6ca8edfb3e26a82c487ed48e1c612ef Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 01:36:53 +0000 Subject: [PATCH 33/76] add concise log regression --- notebooks/concise_log_reg.ipynb | 243 ++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 notebooks/concise_log_reg.ipynb diff --git a/notebooks/concise_log_reg.ipynb b/notebooks/concise_log_reg.ipynb new file mode 100644 index 0000000..fa89bcf --- /dev/null +++ b/notebooks/concise_log_reg.ipynb @@ -0,0 +1,243 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Concise Logistic Regression for Image Classification\n", + "\n", + "- Shows a concise implementation of logistic regression for image classification\n", + "- Uses PyTorch" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# imports\n", + "import torch\n", + "import torchvision\n", + "import torch.nn as nn\n", + "from torchvision import datasets, models, transforms\n", + "import os\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "%matplotlib inline\n", + "\n", + "# use gpu if available\n", + "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# download the data (uncomment if to download the data locally)\n", + "#!wget https://download.pytorch.org/tutorial/hymenoptera_data.zip\n", + "#!unzip hymenoptera_data.zip" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# create data loaders\n", + "\n", + "data_dir = 'hymenoptera_data'\n", + "\n", + "# custom transformer to flatten the image tensors\n", + "class ReshapeTransform:\n", + " def __init__(self, new_size):\n", + " self.new_size = new_size\n", + "\n", + " def __call__(self, img):\n", + " result = torch.reshape(img, self.new_size)\n", + " return result\n", + "\n", + "# transformations used to standardize and normalize the datasets\n", + "data_transforms = {\n", + " 'train': transforms.Compose([\n", + " transforms.Resize(224),\n", + " transforms.CenterCrop(224),\n", + " transforms.ToTensor(),\n", + " ReshapeTransform((-1,)) # flattens the data\n", + " ]),\n", + " 'val': transforms.Compose([\n", + " transforms.Resize(224),\n", + " transforms.CenterCrop(224),\n", + " transforms.ToTensor(),\n", + " ReshapeTransform((-1,)) # flattens the data\n", + " ]),\n", + "}\n", + "\n", + "# load the correspoding folders\n", + "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),\n", + " data_transforms[x])\n", + " for x in ['train', 'val']}\n", + "\n", + "# load the entire dataset; we are not using minibatches here\n", + "train_dataset = torch.utils.data.DataLoader(image_datasets['train'],\n", + " batch_size=len(image_datasets['train']),\n", + " shuffle=True)\n", + "\n", + "test_dataset = torch.utils.data.DataLoader(image_datasets['val'],\n", + " batch_size=len(image_datasets['val']),\n", + " shuffle=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# build the LR model\n", + "class LR(nn.Module):\n", + " def __init__(self, dim):\n", + " super(LR, self).__init__()\n", + " self.linear = nn.Linear(dim, 1)\n", + " nn.init.zeros_(self.linear.weight)\n", + " nn.init.zeros_(self.linear.bias)\n", + "\n", + " def forward(self, x):\n", + " x = self.linear(x)\n", + " x = torch.sigmoid(x)\n", + " return x " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# predict function\n", + "def predict(yhat, y):\n", + " yhat = yhat.squeeze()\n", + " y = y.unsqueeze(0) \n", + " y_prediction = torch.zeros(y.size()[1])\n", + " for i in range(yhat.shape[0]):\n", + " if yhat[i] <= 0.5:\n", + " y_prediction[i] = 0\n", + " else:\n", + " y_prediction[i] = 1\n", + " return 100 - torch.mean(torch.abs(y_prediction - y)) * 100" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# model config\n", + "dim = train_dataset.dataset[0][0].shape[0]\n", + "\n", + "lrmodel = LR(dim).to(device)\n", + "criterion = nn.BCELoss()\n", + "optimizer = torch.optim.SGD(lrmodel.parameters(), lr=0.0001)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost after iteration 0: 0.6931471228599548 | Train Acc: 50.40983581542969 | Test Acc: 45.75163269042969\n", + "Cost after iteration 10: 0.6691471338272095 | Train Acc: 64.3442611694336 | Test Acc: 54.24836730957031\n", + "Cost after iteration 20: 0.6513182520866394 | Train Acc: 68.44261932373047 | Test Acc: 54.24836730957031\n", + "Cost after iteration 30: 0.6367825269699097 | Train Acc: 68.03278350830078 | Test Acc: 54.24836730957031\n", + "Cost after iteration 40: 0.6245337128639221 | Train Acc: 69.67213439941406 | Test Acc: 54.90196228027344\n", + "Cost after iteration 50: 0.6139225363731384 | Train Acc: 70.90164184570312 | Test Acc: 56.20914840698242\n", + "Cost after iteration 60: 0.6045235395431519 | Train Acc: 72.54098510742188 | Test Acc: 56.86274337768555\n", + "Cost after iteration 70: 0.5960512161254883 | Train Acc: 74.18032836914062 | Test Acc: 57.51633834838867\n", + "Cost after iteration 80: 0.5883084535598755 | Train Acc: 73.77049255371094 | Test Acc: 57.51633834838867\n", + "Cost after iteration 90: 0.5811557769775391 | Train Acc: 74.59016418457031 | Test Acc: 58.1699333190918\n" + ] + } + ], + "source": [ + "# training the model\n", + "costs = []\n", + "\n", + "for ITER in range(100):\n", + " lrmodel.train()\n", + " x, y = next(iter(train_dataset))\n", + " test_x, test_y = next(iter(test_dataset))\n", + "\n", + " # forward\n", + " yhat = lrmodel.forward(x.to(device))\n", + "\n", + " cost = criterion(yhat.squeeze(), y.type(torch.FloatTensor).to(device))\n", + " train_pred = predict(yhat, y)\n", + "\n", + " # backward\n", + " optimizer.zero_grad()\n", + " cost.backward()\n", + " optimizer.step()\n", + " \n", + " # evaluate\n", + " lrmodel.eval()\n", + " with torch.no_grad():\n", + " yhat_test = lrmodel.forward(test_x.to(device))\n", + " test_pred = predict(yhat_test, test_y)\n", + "\n", + " if ITER % 10 == 0:\n", + " costs.append(cost)\n", + "\n", + " if ITER % 10 == 0:\n", + " print(\"Cost after iteration {}: {} | Train Acc: {} | Test Acc: {}\".format(ITER, \n", + " cost, \n", + " train_pred,\n", + " test_pred))\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### References\n", + "- [A Logistic Regression Model from Scratch](https://colab.research.google.com/drive/1iBoJ0kngkOthy7SgVaVQA1aHEROt5mra?usp=sharing)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 956c37790b03b4e4b9599d860905a6b06226bbfb Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 01:43:54 +0000 Subject: [PATCH 34/76] add first nn for image classification --- notebooks/first_nn.ipynb | 215 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 notebooks/first_nn.ipynb diff --git a/notebooks/first_nn.ipynb b/notebooks/first_nn.ipynb new file mode 100644 index 0000000..4644ac3 --- /dev/null +++ b/notebooks/first_nn.ipynb @@ -0,0 +1,215 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## First Neural Network: Image Classification \n", + "\n", + "Objectives:\n", + "- Train a minimal image classifier on [MNIST](https://paperswithcode.com/dataset/mnist) using PyTorch\n", + "- Usese PyTorch and torchvision" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# The usual imports\n", + "\n", + "import torch\n", + "import torch.nn as nn\n", + "import torchvision\n", + "import torchvision.transforms as transforms" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# load the data\n", + "\n", + "class ReshapeTransform:\n", + " def __init__(self, new_size):\n", + " self.new_size = new_size\n", + "\n", + " def __call__(self, img):\n", + " return torch.reshape(img, self.new_size)\n", + "\n", + "transformations = transforms.Compose([\n", + " transforms.ToTensor(),\n", + " transforms.ConvertImageDtype(torch.float32),\n", + " ReshapeTransform((-1,))\n", + " ])\n", + "\n", + "trainset = torchvision.datasets.MNIST(root='./data', train=True,\n", + " download=True, transform=transformations)\n", + "\n", + "testset = torchvision.datasets.MNIST(root='./data', train=False,\n", + " download=True, transform=transformations)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(torch.Size([60000, 28, 28]), torch.Size([10000, 28, 28]))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# check shape of data\n", + "\n", + "trainset.data.shape, testset.data.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# data loader\n", + "\n", + "BATCH_SIZE = 128\n", + "train_dataloader = torch.utils.data.DataLoader(trainset, \n", + " batch_size=BATCH_SIZE,\n", + " shuffle=True, \n", + " num_workers=0)\n", + "\n", + "test_dataloader = torch.utils.data.DataLoader(testset, \n", + " batch_size=BATCH_SIZE,\n", + " shuffle=False, \n", + " num_workers=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# model\n", + "\n", + "model = nn.Sequential(nn.Linear(784, 512), nn.ReLU(), nn.Linear(512, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# training preparation\n", + "\n", + "trainer = torch.optim.RMSprop(model.parameters())\n", + "loss = nn.CrossEntropyLoss()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def get_accuracy(output, target, batch_size):\n", + " # Obtain accuracy for training round\n", + " corrects = (torch.max(output, 1)[1].view(target.size()).data == target.data).sum()\n", + " accuracy = 100.0 * corrects/batch_size\n", + " return accuracy.item()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 1 | Train loss: 0.9943 | Train Accuracy: 91.7344\n", + "Epoch: 2 | Train loss: 0.1334 | Train Accuracy: 95.9422\n", + "Epoch: 3 | Train loss: 0.1030 | Train Accuracy: 96.8767\n", + "Epoch: 4 | Train loss: 0.0845 | Train Accuracy: 97.4997\n", + "Epoch: 5 | Train loss: 0.0735 | Train Accuracy: 97.8811\n" + ] + } + ], + "source": [ + "# train\n", + "\n", + "for ITER in range(5):\n", + " train_acc = 0.0\n", + " train_running_loss = 0.0\n", + "\n", + " model.train()\n", + " for i, (X, y) in enumerate(train_dataloader):\n", + " output = model(X)\n", + " l = loss(output, y)\n", + "\n", + " # update the parameters\n", + " l.backward()\n", + " trainer.step()\n", + " trainer.zero_grad()\n", + "\n", + " # gather metrics\n", + " train_acc += get_accuracy(output, y, BATCH_SIZE)\n", + " train_running_loss += l.detach().item()\n", + "\n", + " print('Epoch: %d | Train loss: %.4f | Train Accuracy: %.4f' \\\n", + " %(ITER+1, train_running_loss / (i+1),train_acc/(i+1)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Other things to try\n", + "\n", + "- Evaluate on test set\n", + "- Plot loss curve\n", + "- Add more layers to the model" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 8f7ab1705488d254ec0e67f6c2abb5df96d7efca Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 01:55:14 +0000 Subject: [PATCH 35/76] add nn from scratch --- notebooks/nn_from_scratch.ipynb | 353 ++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 notebooks/nn_from_scratch.ipynb diff --git a/notebooks/nn_from_scratch.ipynb b/notebooks/nn_from_scratch.ipynb new file mode 100644 index 0000000..fdb2bd9 --- /dev/null +++ b/notebooks/nn_from_scratch.ipynb @@ -0,0 +1,353 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Simple Neural Network from Scratch with PyTorch and Google Colab\n", + "\n", + "In this tutorial we implement a simple neural network from scratch using PyTorch.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## About\n", + "\n", + "In this tutorial we will implement a simple neural network from scratch using PyTorch. The idea of the tutorial is to teach you the basics of PyTorch and how it can be used to implement a neural network from scratch. I will go over some of the basic functionalities and concepts available in PyTorch that will allow you to build your own neural networks. \n", + "\n", + "This tutorial assumes you have prior knowledge of how a neural network works. Don’t worry! Even if you are not so sure, you will be okay. For advanced PyTorch users, this tutorial may still serve as a refresher. This tutorial is heavily inspired by this [Neural Network implementation](https://repl.it/talk/announcements/Build-a-Neural-Network-in-Python/5457) coded purely using Numpy. In fact, I tried re-implementing the code using PyTorch instead and added my own intuitions and explanations. Thanks to [Samay](https://repl.it/@shamdasani) for his phenomenal work, I hope this inspires many others as it did with me.\n", + "\n", + "The `torch` module provides all the necessary **tensor** operators you will need to implement your first neural network from scratch in PyTorch. That's right! In PyTorch everything is a Tensor, so this is the first thing you will need to get used to. Let's import the libraries we will need for this tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\n", + "Let's start by creating some sample data using the `torch.tensor` command. In Numpy, this could be done with `np.array`. Both functions serve the same purpose, but in PyTorch everything is a Tensor as opposed to a vector or matrix. We define types in PyTorch using the `dtype=torch.xxx` command. \n", + "\n", + "In the data below, `X` represents the amount of hours studied and how much time students spent sleeping, whereas `y` represent grades. The variable `xPredicted` is a single input for which we want to predict a grade using the parameters learned by the neural network. Remember, the neural network wants to learn a mapping between `X` and `y`, so it will try to take a guess from what it has learned from the training data. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "X = torch.tensor(([2, 9], [1, 5], [3, 6]), dtype=torch.float) # 3 X 2 tensor\n", + "y = torch.tensor(([92], [100], [89]), dtype=torch.float) # 3 X 1 tensor\n", + "xPredicted = torch.tensor(([4, 8]), dtype=torch.float) # 1 X 2 tensor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can check the size of the tensors we have just created with the `size` command. This is equivalent to the `shape` command used in tools such as Numpy and Tensorflow. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([3, 2])\n", + "torch.Size([3, 1])\n" + ] + } + ], + "source": [ + "print(X.size())\n", + "print(y.size())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Scaling\n", + "\n", + "Below we are performing some scaling on the sample data. Notice that the `max` function returns both a tensor and the corresponding indices. So we use `_` to capture the indices which we won't use here because we are only interested in the max values to conduct the scaling. Perfect! Our data is now in a very nice format our neural network will appreciate later on. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([0.5000, 1.0000])\n" + ] + } + ], + "source": [ + "# scale units\n", + "X_max, _ = torch.max(X, 0)\n", + "xPredicted_max, _ = torch.max(xPredicted, 0)\n", + "\n", + "X = torch.div(X, X_max)\n", + "xPredicted = torch.div(xPredicted, xPredicted_max)\n", + "y = y / 100 # max test score is 100\n", + "print(xPredicted)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that there are two functions `max` and `div` that I didn't discuss above. They do exactly what they imply: `max` finds the maximum value in a vector... I mean tensor; and `div` is basically a nice little function to divide two tensors. \n", + "\n", + "## Model (Computation Graph)\n", + "Once the data has been processed and it is in the proper format, all you need to do now is to define your model. Here is where things begin to change a little as compared to how you would build your neural networks using, say, something like Keras or Tensorflow. However, you will realize quickly as you go along that PyTorch doesn't differ much from other deep learning tools. At the end of the day we are constructing a computation graph, which is used to dictate how data should flow and what type of operations are performed on this information. \n", + "\n", + "For illustration purposes, we are building the following neural network or computation graph:\n", + "\n", + "\n", + "![alt text](https://drive.google.com/uc?export=view&id=1l-sKpcCJCEUJV1BlAqcVAvLXLpYCInV6)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class Neural_Network(nn.Module):\n", + " def __init__(self, ):\n", + " super(Neural_Network, self).__init__()\n", + " # parameters\n", + " # TODO: parameters can be parameterized instead of declaring them here\n", + " self.inputSize = 2\n", + " self.outputSize = 1\n", + " self.hiddenSize = 3\n", + " \n", + " # weights\n", + " self.W1 = torch.randn(self.inputSize, self.hiddenSize) # 3 X 2 tensor\n", + " self.W2 = torch.randn(self.hiddenSize, self.outputSize) # 3 X 1 tensor\n", + " \n", + " def forward(self, X):\n", + " self.z = torch.matmul(X, self.W1) # 3 X 3 \".dot\" does not broadcast in PyTorch\n", + " self.z2 = self.sigmoid(self.z) # activation function\n", + " self.z3 = torch.matmul(self.z2, self.W2)\n", + " o = self.sigmoid(self.z3) # final activation function\n", + " return o\n", + " \n", + " def sigmoid(self, s):\n", + " return 1 / (1 + torch.exp(-s))\n", + " \n", + " def sigmoidPrime(self, s):\n", + " # derivative of sigmoid\n", + " return s * (1 - s)\n", + " \n", + " def backward(self, X, y, o):\n", + " self.o_error = y - o # error in output\n", + " self.o_delta = self.o_error * self.sigmoidPrime(o) # derivative of sig to error\n", + " self.z2_error = torch.matmul(self.o_delta, torch.t(self.W2))\n", + " self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)\n", + " self.W1 += torch.matmul(torch.t(X), self.z2_delta)\n", + " self.W2 += torch.matmul(torch.t(self.z2), self.o_delta)\n", + " \n", + " def train(self, X, y):\n", + " # forward + backward pass for training\n", + " o = self.forward(X)\n", + " self.backward(X, y, o)\n", + " \n", + " def saveWeights(self, model):\n", + " # we will use the PyTorch internal storage functions\n", + " torch.save(model, \"NN\")\n", + " # you can reload model with all the weights and so forth with:\n", + " # torch.load(\"NN\")\n", + " \n", + " def predict(self):\n", + " print (\"Predicted data based on trained weights: \")\n", + " print (\"Input (scaled): \\n\" + str(xPredicted))\n", + " print (\"Output: \\n\" + str(self.forward(xPredicted)))\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the purpose of this tutorial, we are not going to be talking math stuff, that's for another day. I just want you to get a gist of what it takes to build a neural network from scratch using PyTorch. Let's break down the model which was declared via the class above. \n", + "\n", + "## Class Header\n", + "First, we defined our model via a class because that is the recommended way to build the computation graph. The class header contains the name of the class `Neural Network` and the parameter `nn.Module` which basically indicates that we are defining our own neural network. \n", + "\n", + "```python\n", + "class Neural_Network(nn.Module):\n", + "```\n", + "\n", + "## Initialization\n", + "The next step is to define the initializations ( `def __init__(self,)`) that will be performed upon creating an instance of the customized neural network. You can declare the parameters of your model here, but typically, you would declare the structure of your network in this section -- the size of the hidden layers and so forth. Since we are building the neural network from scratch, we explicitly declared the size of the weights matrices: one that stores the parameters from the input to hidden layer; and one that stores the parameter from the hidden to output layer. Both weight matrices are initialized with values randomly chosen from a normal distribution via `torch.randn(...)`. Note that we are not using bias just to keep things as simple as possible. \n", + "\n", + "```python\n", + "def __init__(self, ):\n", + " super(Neural_Network, self).__init__()\n", + " # parameters\n", + " # TODO: parameters can be parameterized instead of declaring them here\n", + " self.inputSize = 2\n", + " self.outputSize = 1\n", + " self.hiddenSize = 3\n", + "\n", + " # weights\n", + " self.W1 = torch.randn(self.inputSize, self.hiddenSize) # 3 X 2 tensor\n", + " self.W2 = torch.randn(self.hiddenSize, self.outputSize) # 3 X 1 tensor\n", + "```\n", + "\n", + "## The Forward Function\n", + "The `forward` function is where all the magic happens (see below). This is where the data enters and is fed into the computation graph (i.e., the neural network structure we have built). Since we are building a simple neural network with one hidden layer, our forward function looks very simple:\n", + "\n", + "```python\n", + "def forward(self, X):\n", + " self.z = torch.matmul(X, self.W1) \n", + " self.z2 = self.sigmoid(self.z) # activation function\n", + " self.z3 = torch.matmul(self.z2, self.W2)\n", + " o = self.sigmoid(self.z3) # final activation function\n", + " return o\n", + "```\n", + "\n", + "The `forward` function above takes the input `X`and then performs a matrix multiplication (`torch.matmul(...)`) with the first weight matrix `self.W1`. Then the result is applied an activation function, `sigmoid`. The resulting matrix of the activation is then multiplied with the second weight matrix `self.W2`. Then another activation if performed, which renders the output of the neural network or computation graph. The process I described above is simply what's known as a `feedforward pass`. In order for the weights to optimize when training, we need a backpropagation algorithm. \n", + "\n", + "## The Backward Function\n", + "The `backward` function contains the backpropagation algorithm, where the goal is to essentially minimize the loss with respect to our weights. In other words, the weights need to be updated in such a way that the loss decreases while the neural network is training (well, that is what we hope for). All this magic is possible with the gradient descent algorithm which is declared in the `backward` function. Take a minute or two to inspect what is happening in the code below:\n", + "\n", + "```python\n", + "def backward(self, X, y, o):\n", + " self.o_error = y - o # error in output\n", + " self.o_delta = self.o_error * self.sigmoidPrime(o) \n", + " self.z2_error = torch.matmul(self.o_delta, torch.t(self.W2))\n", + " self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)\n", + " self.W1 += torch.matmul(torch.t(X), self.z2_delta)\n", + " self.W2 += torch.matmul(torch.t(self.z2), self.o_delta)\n", + "```\n", + "\n", + "Notice that we are performing a lot of matrix multiplications along with the transpose operations via the `torch.matmul(...)` and `torch.t(...)` operations, respectively. The rest is simply gradient descent -- there is nothing to it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Training\n", + "All that is left now is to train the neural network. First we create an instance of the computation graph we have just built:\n", + "\n", + "```python\n", + "NN = Neural_Network()\n", + "```\n", + "\n", + "Then we train the model for `1000` rounds. Notice that in PyTorch `NN(X)` automatically calls the `forward` function so there is no need to explicitly call `NN.forward(X)`. \n", + "\n", + "After we have obtained the predicted output for ever round of training, we compute the loss, with the following code:\n", + "\n", + "```python\n", + "torch.mean((y - NN(X))**2).detach().item()\n", + "```\n", + "\n", + "The next step is to start the training (foward + backward) via `NN.train(X, y)`. After we have trained the neural network, we can store the model and output the predicted value of the single instance we declared in the beginning, `xPredicted`. \n", + "\n", + "Let's train!" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#0 Loss: 0.23507122695446014\n", + "#100 Loss: 0.003401519963517785\n", + "#200 Loss: 0.0031734900549054146\n", + "#300 Loss: 0.0030537480488419533\n", + "#400 Loss: 0.0029342835769057274\n", + "#500 Loss: 0.0028073659632354975\n", + "#600 Loss: 0.0026717206928879023\n", + "#700 Loss: 0.0025271554477512836\n", + "#800 Loss: 0.002374356146901846\n", + "#900 Loss: 0.0022152026649564505\n", + "Predicted data based on trained weights: \n", + "Input (scaled): \n", + "tensor([0.5000, 1.0000])\n", + "Output: \n", + "tensor([0.9335])\n", + "Finished training!\n" + ] + } + ], + "source": [ + "NN = Neural_Network()\n", + "for i in range(1000): # trains the NN 1,000 times\n", + " if (i % 100) == 0:\n", + " print (\"#\" + str(i) + \" Loss: \" + str(torch.mean((y - NN(X))**2).detach().item())) # mean sum squared loss\n", + " NN.train(X, y)\n", + "#NN.saveWeights(NN) # save weights\n", + "\n", + "NN.predict()\n", + "\n", + "print(\"Finished training!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The loss keeps decreasing, which means that the neural network is learning something. That's it. Congratulations! You have just learned how to create and train a neural network from scratch using PyTorch. There are so many things you can do with the shallow network we have just implemented. You can add more hidden layers or try to incorporate the bias terms for practice. I would love to see what you will build from here. Reach me out on [Twitter](https://twitter.com/omarsar0) if you have any further questions or leave your comments here. Until next time!\n", + "\n", + "## References:\n", + "- [PyTorch nn. Modules](https://pytorch.org/tutorials/beginner/pytorch_with_examples.html#pytorch-custom-nn-modules)\n", + "- [Build a Neural Network with Numpy](https://enlight.nyc/neural-network)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('play')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From e16a77cca5c40aef24567cc159e6b45ef6db2c58 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 02:55:13 +0000 Subject: [PATCH 36/76] add into to gnn --- .gitignore | 1 + notebooks/intro_gnn.ipynb | 817 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 818 insertions(+) create mode 100644 notebooks/intro_gnn.ipynb diff --git a/.gitignore b/.gitignore index 05334c2..b93f5d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ notebooks/data/ notebooks/hymenoptera_data/ +notebooks/tmp/ diff --git a/notebooks/intro_gnn.ipynb b/notebooks/intro_gnn.ipynb new file mode 100644 index 0000000..3b02e9c --- /dev/null +++ b/notebooks/intro_gnn.ipynb @@ -0,0 +1,817 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction to GNNs with PyTorch Geometric\n", + "\n", + "In this short notebook, the goal is to provide a introductory guide to get started with Graph Neural Networks using the popular library called [PyTorch Geometric](https://pytorch-geometric.readthedocs.io/en/latest/index.html). PyTorch Geometric is a PyTorch based libary hence we will be using PyTorch in this tutorial. \n", + "\n", + "The code used in this tutorial has been adapted from their official [examples](https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html). I have incorporated a bit more beginner-friendly guidance and kept it minimal." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11.3\n" + ] + } + ], + "source": [ + "# Find the CUDA version PyTorch was installed with\n", + "!python -c \"import torch; print(torch.version.cuda)\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.11.0\n" + ] + } + ], + "source": [ + "# PyTorch version\n", + "!python -c \"import torch; print(torch.__version__)\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Install the follow packages but make sure to \n", + "\n", + "---\n", + "\n", + "install the right version below. Find more instructions [here](https://pytorch-geometric.readthedocs.io/en/latest/notes/installation.html) if you get lost. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Looking in links: https://data.pyg.org/whl/torch-1.11.0.html\n", + "Collecting torch-scatter\n", + " Downloading torch_scatter-2.0.9.tar.gz (21 kB)\n", + "Building wheels for collected packages: torch-scatter\n", + " Building wheel for torch-scatter (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for torch-scatter: filename=torch_scatter-2.0.9-cp38-cp38-linux_x86_64.whl size=304063 sha256=f9cc42222b3244636f8cb1a257bdc1556f9292207d987b02ec79e7fb59689fdb\n", + " Stored in directory: /home/codespace/.cache/pip/wheels/7c/51/2a/409339f45a48bf748a5db76dfa11373ea7c883ecf1932eee2f\n", + "Successfully built torch-scatter\n", + "Installing collected packages: torch-scatter\n", + "Successfully installed torch-scatter-2.0.9\n" + ] + } + ], + "source": [ + "!pip install torch-scatter -f https://data.pyg.org/whl/torch-1.11.0.html" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Looking in links: https://data.pyg.org/whl/torch-1.11.0.html\n", + "Collecting torch-sparse\n", + " Downloading torch_sparse-0.6.13.tar.gz (48 kB)\n", + "\u001b[K |████████████████████████████████| 48 kB 1.7 MB/s eta 0:00:01\n", + "\u001b[?25hCollecting scipy\n", + " Downloading scipy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (41.6 MB)\n", + "\u001b[K |████████████████████████████████| 41.6 MB 73.5 MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: numpy<1.25.0,>=1.17.3 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from scipy->torch-sparse) (1.22.3)\n", + "Building wheels for collected packages: torch-sparse\n", + " Building wheel for torch-sparse (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for torch-sparse: filename=torch_sparse-0.6.13-cp38-cp38-linux_x86_64.whl size=570934 sha256=27a158cb7be5e10bb7846cce70764338cbb12828ea70eaf5a41a79f15cfc60c3\n", + " Stored in directory: /home/codespace/.cache/pip/wheels/81/94/1a/3fd0c022a887c997c5e681961f2bd2e41f8fd6b66562b90fb6\n", + "Successfully built torch-sparse\n", + "Installing collected packages: scipy, torch-sparse\n", + "Successfully installed scipy-1.8.1 torch-sparse-0.6.13\n" + ] + } + ], + "source": [ + "!pip install torch-sparse -f https://data.pyg.org/whl/torch-1.11.0.html" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting torch-geometric\n", + " Downloading torch_geometric-2.0.4.tar.gz (407 kB)\n", + "\u001b[K |████████████████████████████████| 407 kB 26.9 MB/s eta 0:00:01\n", + "\u001b[?25hCollecting tqdm\n", + " Downloading tqdm-4.64.0-py2.py3-none-any.whl (78 kB)\n", + "\u001b[K |████████████████████████████████| 78 kB 1.8 MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: numpy in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from torch-geometric) (1.22.3)\n", + "Requirement already satisfied: scipy in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from torch-geometric) (1.8.1)\n", + "Collecting pandas\n", + " Downloading pandas-1.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.7 MB)\n", + "\u001b[K |████████████████████████████████| 11.7 MB 79.4 MB/s eta 0:00:01\n", + "\u001b[?25hCollecting jinja2\n", + " Downloading Jinja2-3.1.2-py3-none-any.whl (133 kB)\n", + "\u001b[K |████████████████████████████████| 133 kB 87.1 MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: requests in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from torch-geometric) (2.27.1)\n", + "Collecting pyparsing\n", + " Using cached pyparsing-3.0.9-py3-none-any.whl (98 kB)\n", + "Collecting scikit-learn\n", + " Downloading scikit_learn-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (31.2 MB)\n", + "\u001b[K |████████████████████████████████| 31.2 MB 84.1 MB/s eta 0:00:01\n", + "\u001b[?25hCollecting MarkupSafe>=2.0\n", + " Downloading MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)\n", + "Collecting pytz>=2020.1\n", + " Downloading pytz-2022.1-py2.py3-none-any.whl (503 kB)\n", + "\u001b[K |████████████████████████████████| 503 kB 69.2 MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: python-dateutil>=2.8.1 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from pandas->torch-geometric) (2.8.2)\n", + "Requirement already satisfied: six>=1.5 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from python-dateutil>=2.8.1->pandas->torch-geometric) (1.16.0)\n", + "Requirement already satisfied: charset-normalizer~=2.0.0 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from requests->torch-geometric) (2.0.4)\n", + "Requirement already satisfied: idna<4,>=2.5 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from requests->torch-geometric) (3.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from requests->torch-geometric) (2022.5.18.1)\n", + "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/codespace/.conda/envs/gnn/lib/python3.8/site-packages (from requests->torch-geometric) (1.26.9)\n", + "Collecting joblib>=1.0.0\n", + " Downloading joblib-1.1.0-py2.py3-none-any.whl (306 kB)\n", + "\u001b[K |████████████████████████████████| 306 kB 78.1 MB/s eta 0:00:01\n", + "\u001b[?25hCollecting threadpoolctl>=2.0.0\n", + " Downloading threadpoolctl-3.1.0-py3-none-any.whl (14 kB)\n", + "Building wheels for collected packages: torch-geometric\n", + " Building wheel for torch-geometric (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for torch-geometric: filename=torch_geometric-2.0.4-py3-none-any.whl size=616602 sha256=c3dd839f53e4c307e7a223cb3868bbe2dfc5bb5a5586c2f1bcfe5d2f20f6d6a6\n", + " Stored in directory: /home/codespace/.cache/pip/wheels/c1/be/e9/b90ded2a496c975a539af002fe1f0f2a22a97af13b41866d6e\n", + "Successfully built torch-geometric\n", + "Installing collected packages: threadpoolctl, pytz, MarkupSafe, joblib, tqdm, scikit-learn, pyparsing, pandas, jinja2, torch-geometric\n", + "Successfully installed MarkupSafe-2.1.1 jinja2-3.1.2 joblib-1.1.0 pandas-1.4.2 pyparsing-3.0.9 pytz-2022.1 scikit-learn-1.1.1 threadpoolctl-3.1.0 torch-geometric-2.0.4 tqdm-4.64.0\n" + ] + } + ], + "source": [ + "!pip install torch-geometric" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting Started\n", + "\n", + "Import PyTorch" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.11.0\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "# print torch version\n", + "print(torch.__version__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The great thing about PyTorch Geometric is that it contain useful functionalities to import and load graph related data. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from torch_geometric.data import Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's create an unweighted and undirected graph with three nodes and four total edges." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data(x=[3, 1], edge_index=[2, 4])\n" + ] + } + ], + "source": [ + "# define edge list\n", + "edge_index = torch.tensor([[0, 1, 1, 2], [1, 0, 2, 1]], dtype=torch.long)\n", + "\n", + "# define node features\n", + "x = torch.tensor([[-1], [0], [1]])\n", + "\n", + "# create graph data object\n", + "data = Data(x=x, edge_index=edge_index)\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our data object `Data` has many useful utility functions to check the properties of the graph. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + } + ], + "source": [ + "# check number of edges of the graph\n", + "print(data.num_edges)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + } + ], + "source": [ + "# check number of nodes of the graph\n", + "print(data.num_nodes)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "# check number of features of the graph\n", + "print(data.num_features)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "# check if graph is directed\n", + "print(data.is_directed())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading Data\n", + "\n", + "Find more fun functions related to graph data [here](https://pytorch-geometric.readthedocs.io/en/latest/modules/data.html#torch_geometric.data.Data). \n", + "\n", + "One of the cool things about the PyTorch Geometric library is that it contains out-of-the-box benchmark datasets that are ready to use and explore. A popular dataset is the Cora dataset that is used for supervised graph node classification. (We will talk about these applications in an upcoming tutorial but for now we will focus on the data itself).\n", + "\n", + "\"The Cora dataset consists of 2708 scientific publications classified into one of seven classes. The citation network consists of 5429 links. Each publication in the dataset is described by a 0/1-valued word vector indicating the absence/presence of the corresponding word from the dictionary. The dictionary consists of 1433 unique words.\" - [Papers with Code](https://paperswithcode.com/dataset/cora).\n", + "\n", + "Let's load the Cora dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.x\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.tx\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.allx\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.y\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ty\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ally\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.graph\n", + "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.test.index\n", + "Processing...\n", + "Done!\n" + ] + } + ], + "source": [ + "from torch_geometric.datasets import Planetoid\n", + "\n", + "dataset = Planetoid(root='tmp/Cora', name='Cora')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check some of the properties of the Cora dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of graphs: 1\n", + "Number of features: 1433\n", + "Number of classes: 7\n" + ] + } + ], + "source": [ + "# number of graphs\n", + "print(\"Number of graphs: \", len(dataset))\n", + "\n", + "# number of features\n", + "print(\"Number of features: \", dataset.num_features)\n", + "\n", + "# number of classes\n", + "print(\"Number of classes: \", dataset.num_classes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that this particular graph dataset only contains one graph. Graph data can be very complex and can include multiple graphs depending on the type of data and application. Let's check more feature of the Cora dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of nodes: 2708\n", + "Number of edges: 10556\n", + "Is directed: False\n" + ] + } + ], + "source": [ + "# select the first graph\n", + "data = dataset[0]\n", + "\n", + "# number of nodes\n", + "print(\"Number of nodes: \", data.num_nodes)\n", + "\n", + "# number of edges\n", + "print(\"Number of edges: \", data.num_edges)\n", + "\n", + "# check if directed\n", + "print(\"Is directed: \", data.is_directed())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can sample nodes from the graph this way:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shape of sample nodes: torch.Size([5, 1433])\n" + ] + } + ], + "source": [ + "# sample nodes from the graph\n", + "print(\"Shape of sample nodes: \", data.x[:5].shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We extracted 5 nodes from the graph and checked its shape. You will see that each node has `1433` features.\n", + "\n", + "Another great advantage of using PyTorch Geometric to load the Cora data is that it comes pre-processed and ready to use. It also has the splits for training, validation and test which we can directly use for training a GNN.\n", + "\n", + "Let's check some stats for the partitions of the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# of nodes to train on: 140\n", + "# of nodes to test on: 1000\n", + "# of nodes to validate on: 500\n" + ] + } + ], + "source": [ + "# check training nodes\n", + "print(\"# of nodes to train on: \", data.train_mask.sum().item())\n", + "\n", + "# check test nodes\n", + "print(\"# of nodes to test on: \", data.test_mask.sum().item())\n", + "\n", + "# check validation nodes\n", + "print(\"# of nodes to validate on: \", data.val_mask.sum().item())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That information is important as it will indicate to our model which nodes to train against and which to test against, and so on.\n", + "\n", + "When training neural networks we train them using batches of data. PyTorch Geometric provides efficient processes to load batches of data.\n", + "\n", + "PyTorch Geometric contains a data loader which is a very popular feature in PyTorch to efficiently load data when training neural networks.\n", + " \n", + "So let's try to load the data using the built in `DataLoader`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "from torch_geometric.datasets import Planetoid\n", + "from torch_geometric.loader import DataLoader\n", + "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cuda\n" + ] + } + ], + "source": [ + "print(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "dataset = Planetoid(root='tmp/Cora', name='Cora')\n", + "data = dataset[0].to(device)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Print some quick statistics about the data:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X shape: torch.Size([2708, 1433])\n", + "Edge shape: torch.Size([2, 10556])\n", + "Y shape: torch.Size([2708])\n" + ] + } + ], + "source": [ + "print(\"X shape: \", data.x.shape)\n", + "print(\"Edge shape: \", data.edge_index.shape)\n", + "print(\"Y shape: \", data.y.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model and Training\n", + "\n", + "Finally, let's define a standard GCN to train on the Cora dataset. The aim is to train a model that gets better at predicting the class of the node.\n", + "\n", + "To keep thins simple we will use the same model definition as used in the [tutorial](https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html) we adpated the code from. Note that we are using the built-in `GCNConv` model but you could easily implement your own (something we will cover in a future tutorial). \n", + "\n", + "The model below uses two `GCNConv` layers. The first layer is followed by a non-linearity `ReLU` and `Dropout`. The result is fed to the second layer on top of which we apply `Softmax` to get distribution over the number of classes." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "import torch.nn.functional as F\n", + "from torch_geometric.nn import GCNConv\n", + "\n", + "class GCN(torch.nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " \"\"\" GCNConv layers \"\"\"\n", + " self.conv1 = GCNConv(data.num_features, 16)\n", + " self.conv2 = GCNConv(16, dataset.num_classes)\n", + "\n", + " def forward(self, data):\n", + " x, edge_index = data.x, data.edge_index\n", + " x = self.conv1(x, edge_index)\n", + " x = F.relu(x)\n", + " x = F.dropout(x, training=self.training)\n", + " x = self.conv2(x, edge_index)\n", + "\n", + " return F.log_softmax(x, dim=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initial model and optimizer" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "model = GCN().to(device)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define accuracy function for evaluating performance:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# useful function for computing accuracy\n", + "def compute_accuracy(pred_y, y):\n", + " return (pred_y == y).sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And finally we train the model on the trainin nodes for 200 epochs:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 10, Loss: 0.8056, Training Acc: 0.9214\n", + "Epoch: 20, Loss: 0.2925, Training Acc: 0.9500\n", + "Epoch: 30, Loss: 0.1065, Training Acc: 1.0000\n", + "Epoch: 40, Loss: 0.0654, Training Acc: 1.0000\n", + "Epoch: 50, Loss: 0.0423, Training Acc: 1.0000\n", + "Epoch: 60, Loss: 0.0467, Training Acc: 0.9929\n", + "Epoch: 70, Loss: 0.0496, Training Acc: 0.9929\n", + "Epoch: 80, Loss: 0.0353, Training Acc: 0.9929\n", + "Epoch: 90, Loss: 0.0397, Training Acc: 1.0000\n", + "Epoch: 100, Loss: 0.0253, Training Acc: 1.0000\n", + "Epoch: 110, Loss: 0.0353, Training Acc: 0.9929\n", + "Epoch: 120, Loss: 0.0340, Training Acc: 1.0000\n", + "Epoch: 130, Loss: 0.0338, Training Acc: 1.0000\n", + "Epoch: 140, Loss: 0.0319, Training Acc: 1.0000\n", + "Epoch: 150, Loss: 0.0469, Training Acc: 0.9929\n", + "Epoch: 160, Loss: 0.0260, Training Acc: 0.9929\n", + "Epoch: 170, Loss: 0.0392, Training Acc: 0.9857\n", + "Epoch: 180, Loss: 0.0470, Training Acc: 0.9929\n", + "Epoch: 190, Loss: 0.0267, Training Acc: 0.9929\n", + "Epoch: 200, Loss: 0.0221, Training Acc: 1.0000\n" + ] + } + ], + "source": [ + "# train the model\n", + "model.train()\n", + "losses = []\n", + "accuracies = []\n", + "for epoch in range(200):\n", + " optimizer.zero_grad()\n", + " out = model(data)\n", + "\n", + " loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])\n", + " correct = compute_accuracy(out.argmax(dim=1)[data.train_mask], data.y[data.train_mask])\n", + " acc = int(correct) / int(data.train_mask.sum())\n", + " losses.append(loss.item())\n", + " accuracies.append(acc)\n", + "\n", + " loss.backward()\n", + " optimizer.step()\n", + " if (epoch+1) % 10 == 0:\n", + " print('Epoch: {}, Loss: {:.4f}, Training Acc: {:.4f}'.format(epoch+1, loss.item(), acc))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# plot the loss and accuracy\n", + "import matplotlib.pyplot as plt\n", + "plt.plot(losses)\n", + "plt.plot(accuracies)\n", + "plt.legend(['Loss', 'Accuracy'])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It looks like the model achieves a very high accuracy and small loss on the training dataset. To see how well it generalizes, let's test on the testing nodes:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7870\n" + ] + } + ], + "source": [ + "# evaluate the model on test set\n", + "model.eval()\n", + "pred = model(data).argmax(dim=1)\n", + "correct = compute_accuracy(pred[data.test_mask], data.y[data.test_mask])\n", + "acc = int(correct) / int(data.test_mask.sum())\n", + "print(f'Accuracy: {acc:.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Very cool! It seems we got a very nice accuracy for the test as well. Our model is doing okay. There are many ways you can go about trying to improve this model, but we will keep that for another time. Hopefully, with this tutorial you got a glimpse of graph data and how to use PyTorch Geometric to train GNNs on a very popular dataset. \n", + "\n", + "Note that I haven't tested if this code works with GPUs. I will leave that as an exercise for the learner. \n", + "\n", + "If you are interested in the full tutorial and more examples, visit the [PyTorch Geomtric documentation](https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html) where I adapted the code from. \n", + "\n", + "Feel free to reach out on [Twitter](https://twitter.com/omarsar0) if you have any further questions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.13 ('gnn')", + "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.8.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "a75f2a693c7cdfd35834b054257953bd5f5ecaeaaec5a0be737b1e9a877817f1" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f1e7e1d7759b763065d54ee3042be25c97a008b5 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 23:27:54 +0000 Subject: [PATCH 37/76] add bow --- notebooks/bow.ipynb | 313 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 notebooks/bow.ipynb diff --git a/notebooks/bow.ipynb b/notebooks/bow.ipynb new file mode 100644 index 0000000..f5ca95e --- /dev/null +++ b/notebooks/bow.ipynb @@ -0,0 +1,313 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Bag of Words Text Classifier\n", + "\n", + "The code below implements a simple bag of words text classifier.\n", + "- We tokenize the text, create a vocabulary and encode each piece of text in the dataset\n", + "- The lookup allows for extracting embeddings for each tokenized inputs\n", + "- The embedding vectors are added together with a bias vector\n", + "- The resulting vector is referred to as the scores\n", + "- The score are applied a softmax to generate probabilities which are used for the classification task\n", + "\n", + "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", + "\n", + "![img txt](https://github.com/dair-ai/ML-Notebooks/blob/main/img/bow.png?raw=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "\n", + "# download the files\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/dev.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/test.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/train.txt\n", + "\n", + "# create the data folders\n", + "!mkdir data data/classes\n", + "!cp dev.txt data/classes\n", + "!cp test.txt data/classes\n", + "!cp train.txt data/classes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, 'r') as f:\n", + " for line in f:\n", + " line = line.lower().strip()\n", + " line = line.split(' ||| ')\n", + " data.append(line)\n", + " return data\n", + "\n", + "train_data = read_data('data/classes/train.txt')\n", + "test_data = read_data('data/classes/test.txt')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construct the Vocab and Datasets" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# creating the word and tag indices\n", + "word_to_index = {}\n", + "word_to_index[\"\"] = len(word_to_index) # adds to dictionary\n", + "tag_to_index = {}\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line[1].split(\" \"):\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " else:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + "\n", + " if line[0] not in tag_to_index:\n", + " tag_to_index[line[0]] = len(tag_to_index)\n", + "\n", + "create_dict(train_data)\n", + "create_dict(test_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "test_data = list(create_tensor(test_data))\n", + "\n", + "number_of_words = len(word_to_index)\n", + "number_of_tags = len(tag_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# cpu or gpu\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "# create a simple neural network with embedding layer, bias, and xavier initialization\n", + "class BoW(torch.nn.Module):\n", + " def __init__(self, nwords, ntags):\n", + " super(BoW, self).__init__()\n", + " self.embedding = nn.Embedding(nwords, ntags)\n", + " nn.init.xavier_uniform_(self.embedding.weight)\n", + "\n", + " type = torch.cuda.FloatTensor if torch.cuda.is_available() else torch.FloatTensor\n", + " self.bias = torch.zeros(ntags, requires_grad=True).type(type)\n", + "\n", + " def forward(self, x):\n", + " emb = self.embedding(x) # seq_len x ntags (for each seq) \n", + " out = torch.sum(emb, dim=0) + self.bias # ntags\n", + " out = out.view(1, -1) # reshape to (1, ntags)\n", + " return out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Pretest the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[-0.0033, 0.0215, 0.0117, -0.0360, -0.0223]], device='cuda:0',\n", + " grad_fn=)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# function to convert sentence into tensor using word_to_index dictionary\n", + "def sentence_to_tensor(sentence):\n", + " return torch.LongTensor([word_to_index[word] for word in sentence.split(\" \")])\n", + "\n", + "# test the sentence_to_tensor function\n", + "type = torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor\n", + "out = sentence_to_tensor(\"i love dogs\").type(type)\n", + "test_model = BoW(number_of_words, number_of_tags).to(device)\n", + "test_model(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ITER: 1 | train loss/sent: 1.4733 | train accuracy: 0.3636 | test accuracy: 0.4100\n", + "ITER: 2 | train loss/sent: 1.1213 | train accuracy: 0.6048 | test accuracy: 0.4158\n", + "ITER: 3 | train loss/sent: 0.9114 | train accuracy: 0.7110 | test accuracy: 0.4163\n", + "ITER: 4 | train loss/sent: 0.7690 | train accuracy: 0.7683 | test accuracy: 0.4127\n", + "ITER: 5 | train loss/sent: 0.6634 | train accuracy: 0.8077 | test accuracy: 0.4127\n", + "ITER: 6 | train loss/sent: 0.5827 | train accuracy: 0.8299 | test accuracy: 0.4036\n", + "ITER: 7 | train loss/sent: 0.5174 | train accuracy: 0.8572 | test accuracy: 0.4077\n", + "ITER: 8 | train loss/sent: 0.4638 | train accuracy: 0.8722 | test accuracy: 0.4018\n", + "ITER: 9 | train loss/sent: 0.4193 | train accuracy: 0.8840 | test accuracy: 0.4027\n", + "ITER: 10 | train loss/sent: 0.3814 | train accuracy: 0.8940 | test accuracy: 0.4009\n" + ] + } + ], + "source": [ + "# train and test the BoW model\n", + "model = BoW(number_of_words, number_of_tags).to(device)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters())\n", + "type = torch.LongTensor\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + " type = torch.cuda.LongTensor\n", + "\n", + "# perform training of the Bow model\n", + "def train_bow(model, optimizer, criterion, train_data):\n", + " for ITER in range(10):\n", + " # perform training\n", + " model.train()\n", + " random.shuffle(train_data)\n", + " total_loss = 0.0\n", + " train_correct = 0\n", + " for sentence, tag in train_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " tag = torch.tensor([tag]).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " \n", + " loss = criterion(output, tag)\n", + " total_loss += loss.item()\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " if predicted == tag: train_correct+=1\n", + "\n", + " # perform testing of the model\n", + " model.eval()\n", + " test_correct = 0\n", + " for sentence, tag in test_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " if predicted == tag: test_correct += 1\n", + " \n", + " # print model performance results\n", + " log = f'ITER: {ITER+1} | ' \\\n", + " f'train loss/sent: {total_loss/len(train_data):.4f} | ' \\\n", + " f'train accuracy: {train_correct/len(train_data):.4f} | ' \\\n", + " f'test accuracy: {test_correct/len(test_data):.4f}'\n", + " print(log)\n", + "\n", + "# call the train_bow function\n", + "train_bow(model, optimizer, criterion, train_data)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('nlp')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 42befed88df5e5b64b8f926b2994ef01fa4c49c9 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 23:34:28 +0000 Subject: [PATCH 38/76] add cbow --- notebooks/cbow.ipynb | 258 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 notebooks/cbow.ipynb diff --git a/notebooks/cbow.ipynb b/notebooks/cbow.ipynb new file mode 100644 index 0000000..d5605aa --- /dev/null +++ b/notebooks/cbow.ipynb @@ -0,0 +1,258 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Continuous Bag of Words (CBOW) Text Classifier\n", + "\n", + "The code below implements a continuous bag of words text classifier.\n", + "- We tokenize the text, create a vocabulary and encode each piece of text in the dataset\n", + "- The lookup allows for extracting embeddings for each tokenized input\n", + "- The embedding vectors are added together\n", + "- The resulting vector is multiplied with a weight matrix, which is then added a bias vector; this results in scores\n", + "- The scores are applied a softmax to generate probabilities which are used for the final classification\n", + "\n", + "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", + "\n", + "![img txt](https://github.com/dair-ai/ML-Notebooks/blob/main/img/cbow.png?raw=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "''' uncomment to download the data\n", + "# download the files\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/dev.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/test.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/train.txt\n", + "\n", + "# create the data folders\n", + "!mkdir data data/classes\n", + "!cp dev.txt data/classes\n", + "!cp test.txt data/classes\n", + "!cp train.txt data/classes\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Read and Process Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, 'r') as f:\n", + " for line in f:\n", + " line = line.lower().strip()\n", + " line = line.split(' ||| ')\n", + " data.append(line)\n", + " return data\n", + "\n", + "train_data = read_data('data/classes/train.txt')\n", + "test_data = read_data('data/classes/test.txt')\n", + "\n", + "# creating the word and tag indices\n", + "word_to_index = {}\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "tag_to_index = {}\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line[1].split(\" \"):\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " else:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + "\n", + " if line[0] not in tag_to_index:\n", + " tag_to_index[line[0]] = len(tag_to_index)\n", + "\n", + "create_dict(train_data)\n", + "create_dict(test_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "test_data = list(create_tensor(test_data))\n", + "\n", + "number_of_words = len(word_to_index)\n", + "number_of_tags = len(tag_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# cpu or gpu\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "# create a simple neural network with embedding layer, bias, and xavier initialization\n", + "class CBoW(torch.nn.Module):\n", + " def __init__(self, nwords, ntags, emb_size):\n", + " super(CBoW, self).__init__()\n", + "\n", + " # layers\n", + " self.embedding = torch.nn.Embedding(nwords, emb_size)\n", + " self.linear = torch.nn.Linear(emb_size, ntags)\n", + "\n", + " # use xavier initialization for weights\n", + " nn.init.xavier_uniform_(self.embedding.weight)\n", + " nn.init.xavier_uniform_(self.linear.weight)\n", + "\n", + " def forward(self, x):\n", + " emb = self.embedding(x) # seq x emb_size\n", + " out = torch.sum(emb, dim=0) # emb_size\n", + " out = out.view(1, -1) # reshape to (1, emb_size)\n", + " out = self.linear(out) # 1 x ntags\n", + " return out\n", + "\n", + "EMB_SIZE = 64\n", + "model = CBoW(number_of_words, number_of_tags, EMB_SIZE)\n", + "criterion = torch.nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters())\n", + "type = torch.LongTensor\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + " type = torch.cuda.LongTensor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch: 1 | train loss/sent: 1.4129 | train accuracy: 0.3800 | test accuracy: 0.4081\n", + "epoch: 2 | train loss/sent: 0.8920 | train accuracy: 0.6526 | test accuracy: 0.3928\n", + "epoch: 3 | train loss/sent: 0.5189 | train accuracy: 0.8141 | test accuracy: 0.4041\n", + "epoch: 4 | train loss/sent: 0.3313 | train accuracy: 0.8860 | test accuracy: 0.3851\n", + "epoch: 5 | train loss/sent: 0.2154 | train accuracy: 0.9252 | test accuracy: 0.3774\n", + "epoch: 6 | train loss/sent: 0.1470 | train accuracy: 0.9498 | test accuracy: 0.3688\n", + "epoch: 7 | train loss/sent: 0.1067 | train accuracy: 0.9618 | test accuracy: 0.3805\n", + "epoch: 8 | train loss/sent: 0.0775 | train accuracy: 0.9733 | test accuracy: 0.3796\n", + "epoch: 9 | train loss/sent: 0.0565 | train accuracy: 0.9798 | test accuracy: 0.3710\n", + "epoch: 10 | train loss/sent: 0.0461 | train accuracy: 0.9837 | test accuracy: 0.3701\n" + ] + } + ], + "source": [ + "# perform training of the Bow model\n", + "\n", + "for epoch in range(10):\n", + " # perform training\n", + " model.train()\n", + " random.shuffle(train_data)\n", + " total_loss = 0.0\n", + " train_correct = 0\n", + " for sentence, tag in train_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " tag = torch.tensor([tag]).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " \n", + " loss = criterion(output, tag)\n", + " total_loss += loss.item()\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " if predicted == tag: train_correct+=1\n", + "\n", + " # perform testing of the model\n", + " model.eval()\n", + " test_correct = 0\n", + " for sentence, tag in test_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " if predicted == tag: test_correct += 1\n", + " \n", + " # print model performance results\n", + " log = f'epoch: {epoch+1} | ' \\\n", + " f'train loss/sent: {total_loss/len(train_data):.4f} | ' \\\n", + " f'train accuracy: {train_correct/len(train_data):.4f} | ' \\\n", + " f'test accuracy: {test_correct/len(test_data):.4f}'\n", + " print(log)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('nlp')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 2d710ccf2649baefc7be2189b56096b59f14f2d7 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 18 Jun 2022 23:40:38 +0000 Subject: [PATCH 39/76] add deep cbow --- notebooks/deep_cbow.ipynb | 270 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 notebooks/deep_cbow.ipynb diff --git a/notebooks/deep_cbow.ipynb b/notebooks/deep_cbow.ipynb new file mode 100644 index 0000000..2ec99e8 --- /dev/null +++ b/notebooks/deep_cbow.ipynb @@ -0,0 +1,270 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Deep Continuous Bag of Words (Deep CBOW) Text Classifier\n", + "\n", + "The code below implements a continuous bag of words text classifier.\n", + "- We tokenize the text, create a vocabulary and encode each piece of text in the dataset\n", + "- We create embeddings for inputs and sum them together\n", + "- The resulting vector is fed to hidden neural network, which generates a new vector that is multiplied to a weights matrix\n", + "- We then add the bias and obtain scores\n", + "- The scores are applied a softmax to generate probabilities which are used for the final classification\n", + "\n", + "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", + "\n", + "![img txt](https://github.com/dair-ai/ML-Notebooks/blob/main/img/deep_cbow.png?raw=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "''' uncomment to download the data\n", + "%%capture\n", + "\n", + "# download the files\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/dev.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/test.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/train.txt\n", + "\n", + "# create the data folders\n", + "!mkdir data data/classes\n", + "!cp dev.txt data/classes\n", + "!cp test.txt data/classes\n", + "!cp train.txt data/classes\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Read and Process the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, 'r') as f:\n", + " for line in f:\n", + " line = line.lower().strip()\n", + " line = line.split(' ||| ')\n", + " data.append(line)\n", + " return data\n", + "\n", + "train_data = read_data('data/classes/train.txt')\n", + "test_data = read_data('data/classes/test.txt')\n", + "\n", + "# creating the word and tag indices\n", + "word_to_index = {}\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "tag_to_index = {}\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line[1].split(\" \"):\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " else:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + "\n", + " if line[0] not in tag_to_index:\n", + " tag_to_index[line[0]] = len(tag_to_index)\n", + "\n", + "create_dict(train_data)\n", + "create_dict(test_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "test_data = list(create_tensor(test_data))\n", + "\n", + "number_of_words = len(word_to_index)\n", + "number_of_tags = len(tag_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "# create a simple neural network with embedding layer, bias, and xavier initialization\n", + "class DeepCBoW(nn.Module):\n", + " def __init__(self, nwords, ntags, hidden_size, num_layers, emb_size):\n", + " super(DeepCBoW, self).__init__()\n", + "\n", + " self.num_layers = num_layers\n", + "\n", + " # layers\n", + " self.embedding = nn.Embedding(nwords, emb_size)\n", + " self.linears = nn.ModuleList([nn.Linear(emb_size if i ==0 else hidden_size, hidden_size) \\\n", + " for i in range(num_layers)])\n", + "\n", + " # use xavier initialization for weights\n", + " nn.init.xavier_uniform_(self.embedding.weight)\n", + " for i in range(self.num_layers):\n", + " nn.init.xavier_uniform_(self.linears[i].weight)\n", + "\n", + " # output layer\n", + " self.output_layer = nn.Linear(hidden_size, ntags)\n", + "\n", + " def forward(self, x):\n", + " emb = self.embedding(x) # seq x emb_size\n", + " emb_sum = torch.sum(emb, dim=0) # emb_size\n", + " h = emb_sum.view(1, -1) # reshape to (1, emb_size)\n", + " for i in range(self.num_layers):\n", + " h = torch.tanh(self.linears[i](h))\n", + " out = self.output_layer(h) # 1 x ntags\n", + " return out\n", + "\n", + "HIDDEN_SIZE = 64\n", + "NUM_LAYERS = 2 # hidden layers\n", + "EMB_SIZE = 64\n", + "model = DeepCBoW(number_of_words, number_of_tags, HIDDEN_SIZE, NUM_LAYERS, EMB_SIZE).to(device)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters())\n", + "type = torch.LongTensor\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + " type = torch.cuda.LongTensor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model Training" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch: 1 | train loss/sent: 1.4274 | train accuracy: 0.3632 | test accuracy: 0.4226\n", + "epoch: 2 | train loss/sent: 1.0286 | train accuracy: 0.5724 | test accuracy: 0.3887\n", + "epoch: 3 | train loss/sent: 0.6465 | train accuracy: 0.7621 | test accuracy: 0.4009\n", + "epoch: 4 | train loss/sent: 0.4007 | train accuracy: 0.8578 | test accuracy: 0.3869\n", + "epoch: 5 | train loss/sent: 0.2540 | train accuracy: 0.9114 | test accuracy: 0.3778\n", + "epoch: 6 | train loss/sent: 0.1746 | train accuracy: 0.9383 | test accuracy: 0.3769\n", + "epoch: 7 | train loss/sent: 0.1194 | train accuracy: 0.9601 | test accuracy: 0.3665\n", + "epoch: 8 | train loss/sent: 0.0805 | train accuracy: 0.9724 | test accuracy: 0.3747\n", + "epoch: 9 | train loss/sent: 0.0603 | train accuracy: 0.9789 | test accuracy: 0.3765\n", + "epoch: 10 | train loss/sent: 0.0426 | train accuracy: 0.9863 | test accuracy: 0.3701\n" + ] + } + ], + "source": [ + "# perform training of the Bow model\n", + "\n", + "for epoch in range(10):\n", + " # perform training\n", + " model.train()\n", + " random.shuffle(train_data)\n", + " total_loss = 0.0\n", + " train_correct = 0\n", + " for sentence, tag in train_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " tag = torch.tensor([tag]).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " \n", + " loss = criterion(output, tag)\n", + " total_loss += loss.item()\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " if predicted == tag: train_correct+=1\n", + "\n", + " # perform testing of the model\n", + " model.eval()\n", + " test_correct = 0\n", + " for sentence, tag in test_data:\n", + " sentence = torch.tensor(sentence).type(type)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " if predicted == tag: test_correct += 1\n", + " \n", + " # print model performance results\n", + " log = f'epoch: {epoch+1} | ' \\\n", + " f'train loss/sent: {total_loss/len(train_data):.4f} | ' \\\n", + " f'train accuracy: {train_correct/len(train_data):.4f} | ' \\\n", + " f'test accuracy: {test_correct/len(test_data):.4f}'\n", + " \n", + " print(log)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('nlp')", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From cccaef2fbbdeb6b48838f1bc69ef0f7902fc15bd Mon Sep 17 00:00:00 2001 From: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com> Date: Mon, 25 Jul 2022 18:25:33 +0200 Subject: [PATCH 40/76] Update README.md Fixed a few typos. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5549e24..988b81f 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Contains code examples for all sorts of machine learning tasks and applications. Neural Machine Translation using Transformer - An implementation of Transformer to translate human readabke dates in any format to YYYY-MM-DD format. + An implementation of Transformer to translate human readable dates in any format to YYYY-MM-DD format.
@@ -220,7 +220,7 @@ Contains code examples for all sorts of machine learning tasks and applications. Object Detection using Sliding Window and Image Pyramid - A basic object detection implementation using sliding window and image pyramid on top of an image classifer + A basic object detection implementation using sliding window and image pyramid on top of an image classifier
@@ -229,7 +229,7 @@ Contains code examples for all sorts of machine learning tasks and applications. Object Detection using Selective Search - A basic object detection implementation using selective search on top of an image classifer + A basic object detection implementation using selective search on top of an image classifier
From 586e0037d7e8bba540015e8e5cb55d5b6a210dca Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Mon, 25 Jul 2022 23:14:21 -0700 Subject: [PATCH 41/76] Fixes #14 --- Linear_Regression.ipynb | 21660 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 21660 insertions(+) create mode 100644 Linear_Regression.ipynb diff --git a/Linear_Regression.ipynb b/Linear_Regression.ipynb new file mode 100644 index 0000000..43c5fb2 --- /dev/null +++ b/Linear_Regression.ipynb @@ -0,0 +1,21660 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Linear Regression.ipynb", + "provenance": [], + "collapsed_sections": [], + "authorship_tag": "ABX9TyNRx6gNEqYURZyKqPxPjDA4", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "ku4r-K4GQXEN" + }, + "outputs": [], + "source": [ + "## Import the usual libraries\n", + "import torch\n", + "import torchvision\n", + "import torch.nn as nn\n", + "from torchvision import datasets, models, transforms\n", + "import os\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from matplotlib.animation import FuncAnimation\n", + "from matplotlib import rc\n", + "rc('animation', html='html5')\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "source": [ + "def init():\n", + " pass\n", + " \n", + "def animate_2d(i):\n", + "\n", + " y_true = w[0] * x_plot + w[1] \n", + " w_pred = w_history[i]\n", + " y_pred = w_pred[0] * x_plot + w_pred[1] \n", + " ax.clear()\n", + " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", + " ax.plot(x_plot, y_true, label = \"Ground Truth\")\n", + " ax.plot(x_plot, y_pred, label = \"Fitted\")\n", + " ax.scatter(x_train[0], y_train)\n", + " ax.scatter(x_test[0], y_test)\n", + " ax.legend()\n", + "\n", + "def animate_3d(i):\n", + "\n", + " y_true = w[0] * xx + w[1] * yy + w[2]\n", + " w_pred = w_history[i]\n", + " y_pred = w_pred[0] * xx + w_pred[1] * yy + w_pred[2]\n", + "\n", + " ax.clear()\n", + " ax.azim = angles[i]\n", + " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", + " ax.plot_surface(xx, yy, y_true, alpha=0.5, label = \"Ground Truth\")\n", + " ax.plot_surface(xx, yy, y_pred, alpha=0.2, label = \"Fitted\")\n", + " ax.scatter(x_train[0], x_train[1], y_train.reshape(-1,1))\n", + " ax.scatter(x_test[0], x_test[1], y_test.reshape(-1,1))\n", + " # ax.legend()\n" + ], + "metadata": { + "id": "CVX4Ra-0ErXc" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "np.random.seed(30)" + ], + "metadata": { + "id": "gUtP_kHsYabX" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "class LinearRegression():\n", + " def __init__(self, dim, lr = 0.1):\n", + " assert isinstance\n", + " self.lr = lr\n", + " self.w = np.zeros((dim,1))\n", + " self.grads = {\"dw\": np.zeros((dim))}\n", + "\n", + " def forward(self, x):\n", + " y = self.w.T @ x\n", + " return y\n", + " \n", + " def backward(self, x, y_hat, y):\n", + " assert y_hat.shape == y.shape\n", + " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", + " assert self.grads[\"dw\"].shape == self.w.shape\n", + " \n", + " # print(self.grads[\"dw\"])\n", + "\n", + " def optimize(self):\n", + " self.w = self.w - self.lr * self.grads[\"dw\"]" + ], + "metadata": { + "id": "j2Sj1PxsZ7hX" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Data from the same distribution" + ], + "metadata": { + "id": "zW-t5SBb3-ss" + } + }, + { + "cell_type": "code", + "source": [ + "# Hyperparameters\n", + "num_samples = 50\n", + "num_train = int(0.7 * num_samples)\n", + "num_epochs = 30\n", + "\n", + "# Trying to fit the line y = Ax + B\n", + "w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", + "print(f\"A {w[0]}\")\n", + "print(f\"B {w[1]}\")\n", + "\n", + "# Generate training data\n", + "x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", + "ones = np.ones((num_samples, 1))\n", + "x_stack = np.hstack([x, ones])\n", + "\n", + "\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train \n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = 2, lr = 0.5)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 2 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 560 + }, + "id": "71oppo-CZFZG", + "outputId": "3ed98eca-d057-4bad-a946-dd987669d9ef" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "A [2.]\n", + "B [2.]\n", + "Epoch 0 | Train Loss 82.25494964307106 | Test Loss 12.530375379500228\n", + "Epoch 2 | Train Loss 17.376012504579442 | Test Loss 3.154638242567267\n", + "Epoch 4 | Train Loss 6.956327722693647 | Test Loss 1.2692928110230237\n", + "Epoch 6 | Train Loss 3.224882117013539 | Test Loss 0.5785176772257331\n", + "Epoch 8 | Train Loss 1.5261102992342335 | Test Loss 0.27142397409351354\n", + "Epoch 10 | Train Loss 0.724097788298985 | Test Loss 0.12834980491917516\n", + "Epoch 12 | Train Loss 0.34367807531591266 | Test Loss 0.060843440641133104\n", + "Epoch 14 | Train Loss 0.1631264675584223 | Test Loss 0.028866509791083687\n", + "Epoch 16 | Train Loss 0.07742822365786244 | Test Loss 0.013699376650671533\n", + "Epoch 18 | Train Loss 0.03675144705394587 | Test Loss 0.00650207098681876\n", + "Epoch 20 | Train Loss 0.01744414255609919 | Test Loss 0.003086158976244471\n", + "Epoch 22 | Train Loss 0.008279894726455541 | Test Loss 0.0014648408256308387\n", + "Epoch 24 | Train Loss 0.003930067445239355 | Test Loss 0.0006952876964168519\n", + "Epoch 26 | Train Loss 0.0018654138291502296 | Test Loss 0.00033001930877197806\n", + "Epoch 28 | Train Loss 0.0008854221467041258 | Test Loss 0.00015664423038941943\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "x_plot = np.linspace(-1,1,10)\n", + "fig = plt.figure()\n", + "ax = plt.subplot()\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "id": "9wCVKa6-uJdU", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "outputId": "7cc9b496-0dcf-4a27-fca0-6ced838ed6d7" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Solved using Least Squares and compare to SGD" + ], + "metadata": { + "id": "wK8HgWc54MbV" + } + }, + { + "cell_type": "code", + "source": [ + "W = np.linalg.inv(x_train @ x_train.T) @ x_train @ (y_train.T)\n", + "\n", + "print(W)\n", + "print(model.w)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4tusHihBdDCS", + "outputId": "2cdfd51a-c1b3-41fe-c28c-c7e0f7fb9852" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[[2.]\n", + " [2.]]\n", + "[[1.9916692 ]\n", + " [1.99888494]]\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Data from different distribution (Overfitting)" + ], + "metadata": { + "id": "z3O-ugF74jgk" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "# Should we generate new data or use the old data for comparison?\n", + "\n", + "# # Hyperparameters\n", + "# num_samples = 100\n", + "# num_train = int(0.7 * num_samples)\n", + "# num_epochs = 100\n", + "\n", + "# # Trying to fit the line y = Ax + B\n", + "# w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", + "# print(f\"A {w[0]}\")\n", + "# print(f\"B {w[1]}\")\n", + "\n", + "# # Generate training data\n", + "# x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", + "# ones = np.ones((num_samples, 1))\n", + "# x_stack = np.hstack([x, ones])\n", + "\n", + "# Add noise to both train and test\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train + np.random.normal(loc = 0, scale = 0.1, size = num_train)\n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.6, size = num_samples - num_train)\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = 2, lr = 0.5)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 2 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 525 + }, + "id": "GMjA2oY-4Lf8", + "outputId": "6fd28364-4637-4223-972b-668d47f9fe12" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 81.91031959207034 | Test Loss 15.206417713180077\n", + "Epoch 2 | Train Loss 17.7634895164587 | Test Loss 5.820509127604954\n", + "Epoch 4 | Train Loss 7.245263046946594 | Test Loss 3.9453099633235054\n", + "Epoch 6 | Train Loss 3.44046248665259 | Test Loss 3.281546224113068\n", + "Epoch 8 | Train Loss 1.7052884307321203 | Test Loss 3.0001380259751276\n", + "Epoch 10 | Train Loss 0.8859031197203339 | Test Loss 2.877207877496019\n", + "Epoch 12 | Train Loss 0.4972317484039249 | Test Loss 2.8245002955637446\n", + "Epoch 14 | Train Loss 0.31276314034526653 | Test Loss 2.8030958469957525\n", + "Epoch 16 | Train Loss 0.2252056649766091 | Test Loss 2.7953767630098296\n", + "Epoch 18 | Train Loss 0.18364639950425643 | Test Loss 2.793385095401474\n", + "Epoch 20 | Train Loss 0.16392021995116995 | Test Loss 2.793589996259956\n", + "Epoch 22 | Train Loss 0.15455715229253905 | Test Loss 2.7944793446513407\n", + "Epoch 24 | Train Loss 0.15011295480911402 | Test Loss 2.7954471081023726\n", + "Epoch 26 | Train Loss 0.14800350820084965 | Test Loss 2.7962823550385014\n", + "Epoch 28 | Train Loss 0.14700225544127865 | Test Loss 2.7969377763062377\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "x_plot = np.linspace(-1,1,10)\n", + "fig = plt.figure()\n", + "ax = plt.subplot()\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "-5p2tuxP6Jza", + "outputId": "d8c8b4e9-6429-4af2-da81-8418f032fe96" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### 3D multiple regression with high learning rate" + ], + "metadata": { + "id": "OaNvlQgzIRhA" + } + }, + { + "cell_type": "code", + "source": [ + "# Hyperparameters\n", + "num_samples = 100\n", + "num_train = int(0.7 * num_samples)\n", + "num_epochs = 100\n", + "dim = 3\n", + "\n", + "# Trying to fit the line y = Ax1 + Bx2 + c\n", + "w = np.random.randint(-3, 3, size = (dim,1)).astype(float)\n", + "\n", + "# Generate training data\n", + "x = np.random.normal(loc = 0, scale = 1, size = (num_samples,2))\n", + "ones = np.ones((num_samples, 1))\n", + "x_stack = np.hstack([x, ones])\n", + "\n", + "\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train\n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.2 , size = num_samples - num_train)\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = dim, lr = 2)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 10 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 450 + }, + "id": "cgvqVAOiw-Kn", + "outputId": "19af795b-caf1-4c53-8cda-8756ceeeed71" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 12.698436970922991\n", + "Epoch 10 | Train Loss 746.3185411858192 | Test Loss 358.562608321611\n", + "Epoch 20 | Train Loss 24419.323783752887 | Test Loss 11749.26328932645\n", + "Epoch 30 | Train Loss 800867.9318070416 | Test Loss 384943.9910339218\n", + "Epoch 40 | Train Loss 26266251.698730588 | Test Loss 12621262.851923324\n", + "Epoch 50 | Train Loss 861460553.6207652 | Test Loss 413915326.3017189\n", + "Epoch 60 | Train Loss 28253528351.36185 | Test Loss 13575106812.11293\n", + "Epoch 70 | Train Loss 926637744424.7832 | Test Loss 445224984161.656\n", + "Epoch 80 | Train Loss 30391160307998.715 | Test Loss 14602144378033.883\n", + "Epoch 90 | Train Loss 996746172302559.5 | Test Loss 478909994660501.94\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Do you want to rotate the 3D plane??\n", + "angles = np.linspace(-60,60, num_epochs)\n", + "fig = plt.figure()\n", + "ax = fig.gca(projection='3d')\n", + "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "1beKSQbzE8PL", + "outputId": "59fa05ad-aabb-44ca-b395-08c6574282c4" + }, + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Lower the learning rate" + ], + "metadata": { + "id": "FLs0b32kIrV4" + } + }, + { + "cell_type": "code", + "source": [ + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = dim, lr = 0.1)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 10 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "id": "-j3M08gvxUSn", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 439 + }, + "outputId": "1ea24389-310f-46d1-df7a-068aaae52eec" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 8.095125244530212\n", + "Epoch 10 | Train Loss 4.346296963406692 | Test Loss 1.357191290987867\n", + "Epoch 20 | Train Loss 0.6354422722047353 | Test Loss 0.577448546725004\n", + "Epoch 30 | Train Loss 0.10841552249188971 | Test Loss 0.5003814236148908\n", + "Epoch 40 | Train Loss 0.021006468804432007 | Test Loss 0.5035382295431836\n", + "Epoch 50 | Train Loss 0.004423983911951978 | Test Loss 0.5109523052179242\n", + "Epoch 60 | Train Loss 0.0009763636539296937 | Test Loss 0.5153711624316784\n", + "Epoch 70 | Train Loss 0.00022076073931739313 | Test Loss 0.5175898522946066\n", + "Epoch 80 | Train Loss 5.0521477933667895e-05 | Test Loss 0.5186517866852555\n", + "Epoch 90 | Train Loss 1.163119776227275e-05 | Test Loss 0.5191535958691665\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Do you want to rotate the 3D plane??\n", + "angles = np.linspace(-60,60, num_epochs)\n", + "fig = plt.figure()\n", + "ax = fig.gca(projection='3d')\n", + "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "yMZbHPvgFFmH", + "outputId": "dbba73a4-2773-4c73-9e12-186aaf84aab6" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "# function that draws each frame of the animation\n", + "from matplotlib.animation import FuncAnimation\n", + "from matplotlib import rc\n", + "rc('animation', html='html5')\n", + "lr = LinearRegression(3, lr = 0.8)\n", + "losses = []\n", + "w = np.array([-2,2,2]).reshape(3, 1)\n", + "x = np.random.rand(100,2)\n", + "x_stack = np.hstack([x, np.ones((x.shape[0], 1))]).T\n", + "y = np.sum(w * x_stack, axis = 0, keepdims=True).astype(float)\n", + "y_test = y + np.random.normal(0, scale = 0.1, size =y.shape)\n", + "x = x_stack\n", + "fig = plt.figure()\n", + "plt3d = fig.gca(projection='3d')\n", + "plt.close()\n", + "def init():\n", + " pass\n", + "def animate(i):\n", + "\n", + "\n", + " y_hat = lr.forward(x)\n", + " plt3d.clear()\n", + " plt3d.set_xlim(xmin= 0 ,xmax = 1)\n", + " plt3d.set_ylim(ymin = 0 , ymax = 1)\n", + " plt3d.set_zlim(zmin = 0, zmax = 4)\n", + " plt3d.set_title(f\"Epoch {i} Weight {lr.w}\")\n", + " xx, yy = np.meshgrid(range(2),range(2))\n", + "\n", + " z = w[0] * xx + w[1] * yy + w[2]\n", + " z_pred = lr.w[0] * xx + lr.w[1] * yy + lr.w[2]\n", + " # plot the surface\n", + "\n", + " plt3d.plot_surface( xx, yy, z, alpha=0.5)\n", + " plt3d.plot_surface( xx, yy, z_pred, alpha=0.2)\n", + " plt3d.scatter(x[0], x[1], y)\n", + " # plt3d.plot_surface(xx, yy, lr.w[-1].reshape(-1,1), alpha=0.2)\n", + "\n", + "\n", + " loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + " losses.append(loss)\n", + " lr.backward(x,y_hat,y_test)\n", + " lr.optimize()\n", + "\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate, frames=100, init_func=init, interval=20,)" + ], + "metadata": { + "id": "mBAHqPPhvI4E" + }, + "execution_count": 14, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 518 + }, + "id": "O2oDLMGLwNFD", + "outputId": "dcdb29bb-46fa-4c94-fe26-cf8299cc4506" + }, + "execution_count": 15, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", + "The `xmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `left` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", + "The `xmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `right` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", + "The `ymin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", + "The `ymax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", + "The `zmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", + "The `zmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ] + } + ] +} \ No newline at end of file From 7324283bc9b40e5a33705ec4a1d24f1a6b5f8323 Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Mon, 25 Jul 2022 23:15:42 -0700 Subject: [PATCH 42/76] Fixes #14 --- Linear_Regression.ipynb => notebooks/linear_regression.ipynb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Linear_Regression.ipynb => notebooks/linear_regression.ipynb (100%) diff --git a/Linear_Regression.ipynb b/notebooks/linear_regression.ipynb similarity index 100% rename from Linear_Regression.ipynb rename to notebooks/linear_regression.ipynb From 342ecb70d068473311702afecc15a30784cfc6d7 Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Sun, 31 Jul 2022 21:57:14 -0700 Subject: [PATCH 43/76] Created using Colaboratory --- notebooks/Linear_Regression.ipynb | 1371 +++++++++++++++++++++++++++++ 1 file changed, 1371 insertions(+) create mode 100644 notebooks/Linear_Regression.ipynb diff --git a/notebooks/Linear_Regression.ipynb b/notebooks/Linear_Regression.ipynb new file mode 100644 index 0000000..fbc561d --- /dev/null +++ b/notebooks/Linear_Regression.ipynb @@ -0,0 +1,1371 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Linear Regression.ipynb", + "provenance": [], + "collapsed_sections": [], + "authorship_tag": "ABX9TyODV4REEuhLrJ1l8OWl6dFt", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "In this tutorial, we are going to implement a linear regression model to predict california housing prices. We will build the model from scratch using numpy. This will be a great approach to begin understanding regression based models.\n", + "\n", + "After completing this tutorial the learner is expected to know the basic building blocks of a linear regression model. The learner is also expected to know the pipeline of reading and transforming data for machine learning workflows.\n", + "\n" + ], + "metadata": { + "id": "m41136O7L5bV" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "Pni17h4R8v8a" + }, + "outputs": [], + "source": [ + "## Import the usual libraries\n", + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn.datasets import fetch_california_housing\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.preprocessing import StandardScaler\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Importing the dataset\n", + "\n", + "The real-world dataset can be obtained by the function `fetch_california_housing` that downloads the dataset for us. \n", + "\n", + "The `as_frame` parameter returns a pandas dataframe which is a library useful for viewing contents of the data.\n", + "\n" + ], + "metadata": { + "id": "DjyJUfczL4zX" + } + }, + { + "cell_type": "code", + "source": [ + "# Fetch the data using sklearn function\n", + "bunch = fetch_california_housing(download_if_missing=True, as_frame=True)\n", + "\n", + "# Load the dataframe and view\n", + "df = bunch.frame\n", + "df.head()" + ], + "metadata": { + "id": "aOXxbywahC5X", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "outputId": "24521e0a-6f1a-4e5c-c35d-3abb8112a9af" + }, + "execution_count": 2, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude \\\n", + "0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 \n", + "1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 \n", + "2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 \n", + "3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 \n", + "4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 \n", + "\n", + " Longitude MedHouseVal \n", + "0 -122.23 4.526 \n", + "1 -122.22 3.585 \n", + "2 -122.24 3.521 \n", + "3 -122.25 3.413 \n", + "4 -122.25 3.422 " + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
08.325241.06.9841271.023810322.02.55555637.88-122.234.526
18.301421.06.2381370.9718802401.02.10984237.86-122.223.585
27.257452.08.2881361.073446496.02.80226037.85-122.243.521
35.643152.05.8173521.073059558.02.54794537.85-122.253.413
43.846252.06.2818531.081081565.02.18146737.85-122.253.422
\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n", + " " + ] + }, + "metadata": {}, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "For this dataset, our target variable is the median house value for California districts, expressed in hundreds of thousands of dollars ($100,000).\n", + "\n", + "We can take a closer look at the various statistical parameters of the dataset using pandas. The `describe` function will help us." + ], + "metadata": { + "id": "KUeU_jLylTx7" + } + }, + { + "cell_type": "code", + "source": [ + "df.describe()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 300 + }, + "id": "eD4BpBHClgDc", + "outputId": "e2171ffb-bd38-4e3e-b600-ad3c249a3234" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " MedInc HouseAge AveRooms AveBedrms Population \\\n", + "count 20640.000000 20640.000000 20640.000000 20640.000000 20640.000000 \n", + "mean 3.870671 28.639486 5.429000 1.096675 1425.476744 \n", + "std 1.899822 12.585558 2.474173 0.473911 1132.462122 \n", + "min 0.499900 1.000000 0.846154 0.333333 3.000000 \n", + "25% 2.563400 18.000000 4.440716 1.006079 787.000000 \n", + "50% 3.534800 29.000000 5.229129 1.048780 1166.000000 \n", + "75% 4.743250 37.000000 6.052381 1.099526 1725.000000 \n", + "max 15.000100 52.000000 141.909091 34.066667 35682.000000 \n", + "\n", + " AveOccup Latitude Longitude MedHouseVal \n", + "count 20640.000000 20640.000000 20640.000000 20640.000000 \n", + "mean 3.070655 35.631861 -119.569704 2.068558 \n", + "std 10.386050 2.135952 2.003532 1.153956 \n", + "min 0.692308 32.540000 -124.350000 0.149990 \n", + "25% 2.429741 33.930000 -121.800000 1.196000 \n", + "50% 2.818116 34.260000 -118.490000 1.797000 \n", + "75% 3.282261 37.710000 -118.010000 2.647250 \n", + "max 1243.333333 41.950000 -114.310000 5.000010 " + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
count20640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.000000
mean3.87067128.6394865.4290001.0966751425.4767443.07065535.631861-119.5697042.068558
std1.89982212.5855582.4741730.4739111132.46212210.3860502.1359522.0035321.153956
min0.4999001.0000000.8461540.3333333.0000000.69230832.540000-124.3500000.149990
25%2.56340018.0000004.4407161.006079787.0000002.42974133.930000-121.8000001.196000
50%3.53480029.0000005.2291291.0487801166.0000002.81811634.260000-118.4900001.797000
75%4.74325037.0000006.0523811.0995261725.0000003.28226137.710000-118.0100002.647250
max15.00010052.000000141.90909134.06666735682.0000001243.33333341.950000-114.3100005.000010
\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n", + " " + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "As we can see the data in each of the columns is on different scales. For example, the average bedroom value is around 1 and the average population is around 1425. \n", + "\n", + "Generally, machine learing models do not work well when the data is on different scales. Thus, we have to normalize our data in the range [-1,1]. The module [StandardScalar](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html) will help us in this.\n", + "\n", + "The training data should always be normalized. The testing data should be normalized using the values of the training data. " + ], + "metadata": { + "id": "6S6WG0Bejxc2" + } + }, + { + "cell_type": "code", + "source": [ + "# !wget https://raw.githubusercontent.com/Ankit152/Fish-Market/main/Fish.csv\n", + "# import pandas as pd\n", + "# df = pd.read_csv(\"Fish.csv\")\n", + "# y = df['Weight']\n", + "# x = df[[\"Length1\", \"Length2\", \"Length3\", \"Height\", \"Width\",\"Weight\"]]\n", + "\n", + "df = bunch.frame\n", + "x = df.iloc[:,:-1] # Select all the columns, except the last column\n", + "y = df.iloc[:,-1:] # Select the last column\n", + "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.33, random_state = 1)\n", + "\n", + "input_scalar = StandardScaler()\n", + "output_scalar = StandardScaler()\n", + "\n", + "x_train = input_scalar.fit_transform(x_train).T # Normalize train data\n", + "x_test = input_scalar.transform(x_test).T # Only transform test data using values of train data\n", + "\n", + "y_train = output_scalar.fit_transform(y_train).reshape(-1)\n", + "y_test = output_scalar.transform(y_test).reshape(-1)\n", + "\n", + "dataset_copy = [ x_train.copy(), x_test.copy(), y_train.copy(), y_test.copy()]" + ], + "metadata": { + "id": "pkaOgN44iQLN" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Linear Regression Model\n", + "\n", + "Now we define our linear regression model from scratch.\n", + "\n", + "A linear regression model is of the form:\n", + "\n", + "$y = a_1 x_1 + a_2 x_2 + \\dots + a_nx_n + a_{n+1}$\n", + " \n", + "The above can be rewritten using matrix multiplication as\n", + "\n", + "$ y = w^T x $\n", + "\n", + "where \n", + "\n", + "$ w = [a_1, a_2, \\dots, a_n, a_{n+1}]^T $\n", + "\n", + "$ x = [x_1, x_2, \\dots, x_n]^T $\n" + ], + "metadata": { + "id": "mylVXZDk96a2" + } + }, + { + "cell_type": "code", + "source": [ + "class LinearRegression():\n", + " def __init__(self, dim, lr = 0.1):\n", + " assert isinstance\n", + " self.lr = lr\n", + " self.w = np.zeros((dim))\n", + " self.grads = {\"dw\": np.zeros((dim)) +5}\n", + "\n", + " def forward(self, x):\n", + " y = self.w.T @ x\n", + " return y\n", + " \n", + " def backward(self, x, y_hat, y):\n", + " assert y_hat.shape == y.shape\n", + " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", + " assert self.grads[\"dw\"].shape == self.w.shape\n", + " \n", + " # print(self.grads[\"dw\"])\n", + "\n", + " def optimize(self):\n", + " self.w = self.w - self.lr * self.grads[\"dw\"]" + ], + "metadata": { + "id": "iJViSowz9nah" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Loss\n", + "\n", + "For linear regression, various loss functions such as the mean absolute error, mean squared error, or root mean squared error can be used.\n", + "\n", + "In this example, we will use the mean squared error (MSE) loss.\n", + "\n", + "The MSE loss is given by \n", + "\n", + "$ error = \\frac{1}{m} Σ_{i=1}^{m} (y_{true}^{i} - y_{pred}^{i})^2 $ \n", + "\n", + "where $i$ denotes the particular obseration/row in the dataset and $m$ is the total number of obserations.\n", + "\n", + "To ensure our model is correct, the loss should decrease over each epoch.\n" + ], + "metadata": { + "id": "6UOy32LoqCrL" + } + }, + { + "cell_type": "markdown", + "source": [ + "" + ], + "metadata": { + "id": "3atqq0KirwLu" + } + }, + { + "cell_type": "code", + "source": [ + "num_epochs = 10000\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "dim = x_train.shape[0]\n", + "num_train = x_train.shape[1]\n", + "num_test = x_test.shape[1]\n", + "\n", + "\n", + "model = LinearRegression(dim = dim, lr = 0.1)\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/(2 * num_train) * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/(2 * num_test) * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 20 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "mgNn3oGjjbxX", + "outputId": "2f67998e-2fa4-4c43-e091-d5180dd92029" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 0.49999999999999983 | Test Loss 0.43712002508129305\n", + "Epoch 20 | Train Loss 0.2359010824314295 | Test Loss 0.2325611904818386\n", + "Epoch 40 | Train Loss 0.22188755162559423 | Test Loss 0.2217635127918686\n", + "Epoch 60 | Train Loss 0.21474640752415047 | Test Loss 0.2152613227580797\n", + "Epoch 80 | Train Loss 0.2095989567021037 | Test Loss 0.21037193610067245\n", + "Epoch 100 | Train Loss 0.20581761895152345 | Test Loss 0.20673038702760732\n", + "Epoch 120 | Train Loss 0.20303294882659725 | Test Loss 0.20402527473733864\n", + "Epoch 140 | Train Loss 0.20097918345162274 | Test Loss 0.20201418597478873\n", + "Epoch 160 | Train Loss 0.19946210112703647 | Test Loss 0.20051638978054404\n", + "Epoch 180 | Train Loss 0.19833950070910428 | Test Loss 0.19939846923590557\n", + "Epoch 200 | Train Loss 0.19750719045004836 | Test Loss 0.19856209982480624\n", + "Epoch 220 | Train Loss 0.1968887724916989 | Test Loss 0.1979347869242644\n", + "Epoch 240 | Train Loss 0.19642818272324772 | Test Loss 0.19746302071881933\n", + "Epoch 260 | Train Loss 0.19608424065206406 | Test Loss 0.19710724843033994\n", + "Epoch 280 | Train Loss 0.19582666642954677 | Test Loss 0.19683818623685323\n", + "Epoch 300 | Train Loss 0.19563316903289557 | Test Loss 0.19663411372213185\n", + "Epoch 320 | Train Loss 0.19548731666143612 | Test Loss 0.19647888801910168\n", + "Epoch 340 | Train Loss 0.19537697849050284 | Test Loss 0.19636048509166582\n", + "Epoch 360 | Train Loss 0.19529318388491884 | Test Loss 0.19626992725672532\n", + "Epoch 380 | Train Loss 0.19522928672715056 | Test Loss 0.19620049386222657\n", + "Epoch 400 | Train Loss 0.19518035283239818 | Test Loss 0.19614713968570663\n", + "Epoch 420 | Train Loss 0.19514271054504922 | Test Loss 0.1961060658296224\n", + "Epoch 440 | Train Loss 0.19511362075549118 | Test Loss 0.19607440266698017\n", + "Epoch 460 | Train Loss 0.19509103436032973 | Test Loss 0.196049975197568\n", + "Epoch 480 | Train Loss 0.19507341379189 | Test Loss 0.1960311290809374\n", + "Epoch 500 | Train Loss 0.195059601524607 | Test Loss 0.1960166013981983\n", + "Epoch 520 | Train Loss 0.19504872305387622 | Test Loss 0.19600542443105118\n", + "Epoch 540 | Train Loss 0.19504011519474806 | Test Loss 0.19599685384985982\n", + "Epoch 560 | Train Loss 0.19503327299733605 | Test Loss 0.19599031497728384\n", + "Epoch 580 | Train Loss 0.19502781036651573 | Test Loss 0.19598536246238987\n", + "Epoch 600 | Train Loss 0.19502343078313097 | Test Loss 0.19598164992474956\n", + "Epoch 620 | Train Loss 0.19501990548217418 | Test Loss 0.19597890702760307\n", + "Epoch 640 | Train Loss 0.19501705714492468 | Test Loss 0.1959769221005947\n", + "Epoch 660 | Train Loss 0.1950147476759042 | Test Loss 0.1959755289194148\n", + "Epoch 680 | Train Loss 0.19501286901218934 | Test Loss 0.19597459660841743\n", + "Epoch 700 | Train Loss 0.1950113361889526 | Test Loss 0.19597402189697258\n", + "Epoch 720 | Train Loss 0.1950100820879975 | Test Loss 0.19597372315589145\n", + "Epoch 740 | Train Loss 0.1950090534451732 | Test Loss 0.19597363578501353\n", + "Epoch 760 | Train Loss 0.1950082078022795 | Test Loss 0.19597370863036628\n", + "Epoch 780 | Train Loss 0.19500751116991094 | Test Loss 0.19597390118903935\n", + "Epoch 800 | Train Loss 0.19500693622732843 | Test Loss 0.19597418141927686\n", + "Epoch 820 | Train Loss 0.19500646092952323 | Test Loss 0.19597452401759977\n", + "Epoch 840 | Train Loss 0.19500606742426427 | Test Loss 0.1959749090579219\n", + "Epoch 860 | Train Loss 0.19500574120612196 | Test Loss 0.19597532091250944\n", + "Epoch 880 | Train Loss 0.19500547045245514 | Test Loss 0.19597574739336301\n", + "Epoch 900 | Train Loss 0.19500524549975556 | Test Loss 0.1959761790667557\n", + "Epoch 920 | Train Loss 0.19500505842876395 | Test Loss 0.19597660870438502\n", + "Epoch 940 | Train Loss 0.1950049027342804 | Test Loss 0.1959770308427642\n", + "Epoch 960 | Train Loss 0.19500477306123667 | Test Loss 0.1959774414287147\n", + "Epoch 980 | Train Loss 0.19500466499285687 | Test Loss 0.19597783753361098\n", + "Epoch 1000 | Train Loss 0.19500457487995757 | Test Loss 0.19597821712271776\n", + "Epoch 1020 | Train Loss 0.1950044997028894 | Test Loss 0.19597857886881814\n", + "Epoch 1040 | Train Loss 0.1950044369594934 | Test Loss 0.19597892200155245\n", + "Epoch 1060 | Train Loss 0.19500438457387914 | Test Loss 0.19597924618562568\n", + "Epoch 1080 | Train Loss 0.1950043408219371 | Test Loss 0.1959795514224043\n", + "Epoch 1100 | Train Loss 0.19500430427035154 | Test Loss 0.19597983797049975\n", + "Epoch 1120 | Train Loss 0.19500427372654458 | Test Loss 0.1959801062817876\n", + "Epoch 1140 | Train Loss 0.195004248197501 | Test Loss 0.19598035694999025\n", + "Epoch 1160 | Train Loss 0.19500422685583052 | Test Loss 0.1959805906694935\n", + "Epoch 1180 | Train Loss 0.1950042090117447 | Test Loss 0.19598080820250163\n", + "Epoch 1200 | Train Loss 0.195004194089881 | Test Loss 0.1959810103529865\n", + "Epoch 1220 | Train Loss 0.19500418161010774 | Test Loss 0.1959811979461702\n", + "Epoch 1240 | Train Loss 0.1950041711716055 | Test Loss 0.19598137181250938\n", + "Epoch 1260 | Train Loss 0.1950041624396518 | Test Loss 0.1959815327753366\n", + "Epoch 1280 | Train Loss 0.19500415513463745 | Test Loss 0.19598168164146745\n", + "Epoch 1300 | Train Loss 0.19500414902293145 | Test Loss 0.19598181919420496\n", + "Epoch 1320 | Train Loss 0.1950041439092753 | Test Loss 0.19598194618827683\n", + "Epoch 1340 | Train Loss 0.19500413963044858 | Test Loss 0.19598206334632265\n", + "Epoch 1360 | Train Loss 0.1950041360499879 | Test Loss 0.19598217135661974\n", + "Epoch 1380 | Train Loss 0.19500413305378356 | Test Loss 0.19598227087179027\n", + "Epoch 1400 | Train Loss 0.1950041305464049 | Test Loss 0.19598236250828016\n", + "Epoch 1420 | Train Loss 0.1950041284480337 | Test Loss 0.19598244684643956\n", + "Epoch 1440 | Train Loss 0.19500412669190298 | Test Loss 0.19598252443106423\n", + "Epoch 1460 | Train Loss 0.1950041252221582 | Test Loss 0.1959825957722857\n", + "Epoch 1480 | Train Loss 0.1950041239920701 | Test Loss 0.19598266134671743\n", + "Epoch 1500 | Train Loss 0.1950041229625413 | Test Loss 0.19598272159878383\n", + "Epoch 1520 | Train Loss 0.19500412210085774 | Test Loss 0.19598277694217195\n", + "Epoch 1540 | Train Loss 0.19500412137964543 | Test Loss 0.19598282776135909\n", + "Epoch 1560 | Train Loss 0.19500412077599738 | Test Loss 0.19598287441317852\n", + "Epoch 1580 | Train Loss 0.19500412027074418 | Test Loss 0.19598291722839395\n", + "Epoch 1600 | Train Loss 0.19500411984784347 | Test Loss 0.1959829565132598\n", + "Epoch 1620 | Train Loss 0.19500411949386964 | Test Loss 0.19598299255105023\n", + "Epoch 1640 | Train Loss 0.19500411919758648 | Test Loss 0.1959830256035433\n", + "Epoch 1660 | Train Loss 0.19500411894959 | Test Loss 0.1959830559124517\n", + "Epoch 1680 | Train Loss 0.19500411874200962 | Test Loss 0.19598308370079265\n", + "Epoch 1700 | Train Loss 0.19500411856825786 | Test Loss 0.19598310917419287\n", + "Epoch 1720 | Train Loss 0.19500411842282128 | Test Loss 0.1959831325221266\n", + "Epoch 1740 | Train Loss 0.19500411830108505 | Test Loss 0.19598315391908486\n", + "Epoch 1760 | Train Loss 0.19500411819918667 | Test Loss 0.19598317352567718\n", + "Epoch 1780 | Train Loss 0.19500411811389318 | Test Loss 0.19598319148966561\n", + "Epoch 1800 | Train Loss 0.19500411804249856 | Test Loss 0.19598320794693336\n", + "Epoch 1820 | Train Loss 0.19500411798273784 | Test Loss 0.1959832230223899\n", + "Epoch 1840 | Train Loss 0.19500411793271513 | Test Loss 0.19598323683081562\n", + "Epoch 1860 | Train Loss 0.19500411789084354 | Test Loss 0.19598324947764745\n", + "Epoch 1880 | Train Loss 0.19500411785579488 | Test Loss 0.19598326105971003\n", + "Epoch 1900 | Train Loss 0.19500411782645727 | Test Loss 0.19598327166589385\n", + "Epoch 1920 | Train Loss 0.19500411780190013 | Test Loss 0.1959832813777842\n", + "Epoch 1940 | Train Loss 0.1950041177813444 | Test Loss 0.1959832902702435\n", + "Epoch 1960 | Train Loss 0.1950041177641382 | Test Loss 0.1959832984119505\n", + "Epoch 1980 | Train Loss 0.19500411774973558 | Test Loss 0.19598330586589785\n", + "Epoch 2000 | Train Loss 0.1950041177376798 | Test Loss 0.1959833126898522\n", + "Epoch 2020 | Train Loss 0.19500411772758847 | Test Loss 0.1959833189367787\n", + "Epoch 2040 | Train Loss 0.19500411771914136 | Test Loss 0.19598332465523224\n", + "Epoch 2060 | Train Loss 0.1950041177120707 | Test Loss 0.19598332988971823\n", + "Epoch 2080 | Train Loss 0.1950041177061521 | Test Loss 0.1959833346810246\n", + "Epoch 2100 | Train Loss 0.195004117701198 | Test Loss 0.19598333906652787\n", + "Epoch 2120 | Train Loss 0.19500411769705106 | Test Loss 0.19598334308047438\n", + "Epoch 2140 | Train Loss 0.1950041176935798 | Test Loss 0.19598334675423898\n", + "Epoch 2160 | Train Loss 0.19500411769067422 | Test Loss 0.1959833501165632\n", + "Epoch 2180 | Train Loss 0.19500411768824202 | Test Loss 0.1959833531937735\n", + "Epoch 2200 | Train Loss 0.19500411768620615 | Test Loss 0.19598335600998243\n", + "Epoch 2220 | Train Loss 0.19500411768450196 | Test Loss 0.1959833585872731\n", + "Epoch 2240 | Train Loss 0.19500411768307552 | Test Loss 0.19598336094586813\n", + "Epoch 2260 | Train Loss 0.19500411768188147 | Test Loss 0.19598336310428585\n", + "Epoch 2280 | Train Loss 0.19500411768088202 | Test Loss 0.195983365079482\n", + "Epoch 2300 | Train Loss 0.19500411768004536 | Test Loss 0.19598336688698145\n", + "Epoch 2320 | Train Loss 0.19500411767934506 | Test Loss 0.1959833685409978\n", + "Epoch 2340 | Train Loss 0.19500411767875886 | Test Loss 0.19598337005454344\n", + "Epoch 2360 | Train Loss 0.1950041176782682 | Test Loss 0.1959833714395307\n", + "Epoch 2380 | Train Loss 0.1950041176778575 | Test Loss 0.1959833727068645\n", + "Epoch 2400 | Train Loss 0.19500411767751366 | Test Loss 0.19598337386652676\n", + "Epoch 2420 | Train Loss 0.19500411767722584 | Test Loss 0.1959833749276544\n", + "Epoch 2440 | Train Loss 0.19500411767698494 | Test Loss 0.1959833758986108\n", + "Epoch 2460 | Train Loss 0.19500411767678333 | Test Loss 0.19598337678705066\n", + "Epoch 2480 | Train Loss 0.19500411767661452 | Test Loss 0.19598337759998\n", + "Epoch 2500 | Train Loss 0.19500411767647324 | Test Loss 0.19598337834381113\n", + "Epoch 2520 | Train Loss 0.195004117676355 | Test Loss 0.19598337902441254\n", + "Epoch 2540 | Train Loss 0.195004117676256 | Test Loss 0.1959833796471551\n", + "Epoch 2560 | Train Loss 0.19500411767617312 | Test Loss 0.19598338021695402\n", + "Epoch 2580 | Train Loss 0.1950041176761038 | Test Loss 0.19598338073830746\n", + "Epoch 2600 | Train Loss 0.19500411767604572 | Test Loss 0.19598338121533196\n", + "Epoch 2620 | Train Loss 0.19500411767599712 | Test Loss 0.19598338165179446\n", + "Epoch 2640 | Train Loss 0.1950041176759564 | Test Loss 0.19598338205114224\n", + "Epoch 2660 | Train Loss 0.19500411767592238 | Test Loss 0.19598338241652982\n", + "Epoch 2680 | Train Loss 0.19500411767589387 | Test Loss 0.19598338275084387\n", + "Epoch 2700 | Train Loss 0.19500411767587003 | Test Loss 0.1959833830567258\n", + "Epoch 2720 | Train Loss 0.19500411767585005 | Test Loss 0.19598338333659285\n", + "Epoch 2740 | Train Loss 0.1950041176758333 | Test Loss 0.19598338359265657\n", + "Epoch 2760 | Train Loss 0.19500411767581935 | Test Loss 0.19598338382694094\n", + "Epoch 2780 | Train Loss 0.19500411767580764 | Test Loss 0.19598338404129775\n", + "Epoch 2800 | Train Loss 0.19500411767579784 | Test Loss 0.19598338423742154\n", + "Epoch 2820 | Train Loss 0.19500411767578962 | Test Loss 0.19598338441686272\n", + "Epoch 2840 | Train Loss 0.19500411767578277 | Test Loss 0.19598338458104\n", + "Epoch 2860 | Train Loss 0.195004117675777 | Test Loss 0.1959833847312515\n", + "Epoch 2880 | Train Loss 0.1950041176757722 | Test Loss 0.19598338486868488\n", + "Epoch 2900 | Train Loss 0.19500411767576814 | Test Loss 0.19598338499442705\n", + "Epoch 2920 | Train Loss 0.19500411767576475 | Test Loss 0.19598338510947227\n", + "Epoch 2940 | Train Loss 0.19500411767576192 | Test Loss 0.19598338521473044\n", + "Epoch 2960 | Train Loss 0.1950041176757596 | Test Loss 0.19598338531103396\n", + "Epoch 2980 | Train Loss 0.19500411767575762 | Test Loss 0.19598338539914462\n", + "Epoch 3000 | Train Loss 0.19500411767575593 | Test Loss 0.1959833854797592\n", + "Epoch 3020 | Train Loss 0.19500411767575457 | Test Loss 0.1959833855535154\n", + "Epoch 3040 | Train Loss 0.1950041176757534 | Test Loss 0.1959833856209966\n", + "Epoch 3060 | Train Loss 0.19500411767575246 | Test Loss 0.19598338568273665\n", + "Epoch 3080 | Train Loss 0.19500411767575163 | Test Loss 0.19598338573922397\n", + "Epoch 3100 | Train Loss 0.19500411767575093 | Test Loss 0.19598338579090527\n", + "Epoch 3120 | Train Loss 0.19500411767575035 | Test Loss 0.19598338583818956\n", + "Epoch 3140 | Train Loss 0.19500411767574988 | Test Loss 0.19598338588145087\n", + "Epoch 3160 | Train Loss 0.1950041176757495 | Test Loss 0.1959833859210314\n", + "Epoch 3180 | Train Loss 0.19500411767574916 | Test Loss 0.19598338595724435\n", + "Epoch 3200 | Train Loss 0.1950041176757489 | Test Loss 0.19598338599037615\n", + "Epoch 3220 | Train Loss 0.19500411767574863 | Test Loss 0.19598338602068902\n", + "Epoch 3240 | Train Loss 0.19500411767574843 | Test Loss 0.19598338604842275\n", + "Epoch 3260 | Train Loss 0.19500411767574832 | Test Loss 0.19598338607379676\n", + "Epoch 3280 | Train Loss 0.19500411767574816 | Test Loss 0.19598338609701185\n", + "Epoch 3300 | Train Loss 0.19500411767574805 | Test Loss 0.19598338611825167\n", + "Epoch 3320 | Train Loss 0.19500411767574796 | Test Loss 0.19598338613768423\n", + "Epoch 3340 | Train Loss 0.19500411767574785 | Test Loss 0.19598338615546346\n", + "Epoch 3360 | Train Loss 0.1950041176757478 | Test Loss 0.1959833861717299\n", + "Epoch 3380 | Train Loss 0.1950041176757477 | Test Loss 0.19598338618661224\n", + "Epoch 3400 | Train Loss 0.19500411767574768 | Test Loss 0.1959833862002283\n", + "Epoch 3420 | Train Loss 0.19500411767574766 | Test Loss 0.19598338621268585\n", + "Epoch 3440 | Train Loss 0.19500411767574763 | Test Loss 0.19598338622408337\n", + "Epoch 3460 | Train Loss 0.1950041176757476 | Test Loss 0.1959833862345112\n", + "Epoch 3480 | Train Loss 0.1950041176757476 | Test Loss 0.19598338624405162\n", + "Epoch 3500 | Train Loss 0.19500411767574752 | Test Loss 0.19598338625278036\n", + "Epoch 3520 | Train Loss 0.19500411767574755 | Test Loss 0.19598338626076636\n", + "Epoch 3540 | Train Loss 0.19500411767574752 | Test Loss 0.19598338626807282\n", + "Epoch 3560 | Train Loss 0.19500411767574752 | Test Loss 0.19598338627475767\n", + "Epoch 3580 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628087364\n", + "Epoch 3600 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628646922\n", + "Epoch 3620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629158868\n", + "Epoch 3640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629627257\n", + "Epoch 3660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630055787\n", + "Epoch 3680 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863044786\n", + "Epoch 3700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630806564\n", + "Epoch 3720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631134748\n", + "Epoch 3740 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863143501\n", + "Epoch 3760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631709722\n", + "Epoch 3780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863196106\n", + "Epoch 3800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863219101\n", + "Epoch 3820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632401394\n", + "Epoch 3840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632593876\n", + "Epoch 3860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632769982\n", + "Epoch 3880 | Train Loss 0.19500411767574743 | Test Loss 0.19598338632931098\n", + "Epoch 3900 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863307851\n", + "Epoch 3920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633213377\n", + "Epoch 3940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633336768\n", + "Epoch 3960 | Train Loss 0.19500411767574743 | Test Loss 0.19598338633449658\n", + "Epoch 3980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633552945\n", + "Epoch 4000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633647439\n", + "Epoch 4020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633733897\n", + "Epoch 4040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633812995\n", + "Epoch 4060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633885368\n", + "Epoch 4080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633951579\n", + "Epoch 4100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634012158\n", + "Epoch 4120 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863406758\n", + "Epoch 4140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634118284\n", + "Epoch 4160 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863416468\n", + "Epoch 4180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634207124\n", + "Epoch 4200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634245957\n", + "Epoch 4220 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863428149\n", + "Epoch 4240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634313991\n", + "Epoch 4260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634343732\n", + "Epoch 4280 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863437094\n", + "Epoch 4300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634395834\n", + "Epoch 4320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863441861\n", + "Epoch 4340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863443945\n", + "Epoch 4360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634458515\n", + "Epoch 4380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634475954\n", + "Epoch 4400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634491913\n", + "Epoch 4420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634506512\n", + "Epoch 4440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863451987\n", + "Epoch 4460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634532095\n", + "Epoch 4480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634543272\n", + "Epoch 4500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634553503\n", + "Epoch 4520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634562865\n", + "Epoch 4540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634571427\n", + "Epoch 4560 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863457926\n", + "Epoch 4580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634586435\n", + "Epoch 4600 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863459299\n", + "Epoch 4620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634598989\n", + "Epoch 4640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634604479\n", + "Epoch 4660 | Train Loss 0.19500411767574746 | Test Loss 0.195983386346095\n", + "Epoch 4680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634614093\n", + "Epoch 4700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634618298\n", + "Epoch 4720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634622145\n", + "Epoch 4740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634625664\n", + "Epoch 4760 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863462888\n", + "Epoch 4780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463183\n", + "Epoch 4800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634634527\n", + "Epoch 4820 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463699\n", + "Epoch 4840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634639245\n", + "Epoch 4860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634641307\n", + "Epoch 4880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634643198\n", + "Epoch 4900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634644927\n", + "Epoch 4920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634646506\n", + "Epoch 4940 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863464795\n", + "Epoch 4960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634649273\n", + "Epoch 4980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634650483\n", + "Epoch 5000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634651596\n", + "Epoch 5020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634652604\n", + "Epoch 5040 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465353\n", + "Epoch 5060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634654378\n", + "Epoch 5080 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465516\n", + "Epoch 5100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634655868\n", + "Epoch 5120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634656515\n", + "Epoch 5140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657111\n", + "Epoch 5160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657653\n", + "Epoch 5180 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863465815\n", + "Epoch 5200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634658605\n", + "Epoch 5220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659024\n", + "Epoch 5240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659407\n", + "Epoch 5260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659754\n", + "Epoch 5280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660073\n", + "Epoch 5300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660364\n", + "Epoch 5320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466063\n", + "Epoch 5340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660875\n", + "Epoch 5360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661094\n", + "Epoch 5380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661303\n", + "Epoch 5400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661489\n", + "Epoch 5420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661658\n", + "Epoch 5440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661816\n", + "Epoch 5460 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466196\n", + "Epoch 5480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662088\n", + "Epoch 5500 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466221\n", + "Epoch 5520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662318\n", + "Epoch 5540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662418\n", + "Epoch 5560 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466251\n", + "Epoch 5580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662596\n", + "Epoch 5600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662674\n", + "Epoch 5620 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634662743\n", + "Epoch 5640 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466281\n", + "Epoch 5660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662868\n", + "Epoch 5680 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466292\n", + "Epoch 5700 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466297\n", + "Epoch 5720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663018\n", + "Epoch 5740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663057\n", + "Epoch 5760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663093\n", + "Epoch 5780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663132\n", + "Epoch 5800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466316\n", + "Epoch 5820 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466319\n", + "Epoch 5840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663218\n", + "Epoch 5860 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466324\n", + "Epoch 5880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663262\n", + "Epoch 5900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663284\n", + "Epoch 5920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663304\n", + "Epoch 5940 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663318\n", + "Epoch 5960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663331\n", + "Epoch 5980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663348\n", + "Epoch 6000 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663356\n", + "Epoch 6020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663373\n", + "Epoch 6040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663384\n", + "Epoch 6060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663395\n", + "Epoch 6080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663404\n", + "Epoch 6100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663412\n", + "Epoch 6120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663418\n", + "Epoch 6140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663423\n", + "Epoch 6160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663431\n", + "Epoch 6180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663437\n", + "Epoch 6200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663445\n", + "Epoch 6220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663448\n", + "Epoch 6240 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466345\n", + "Epoch 6260 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466346\n", + "Epoch 6280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663462\n", + "Epoch 6300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", + "Epoch 6320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", + "Epoch 6340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466347\n", + "Epoch 6360 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", + "Epoch 6380 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", + "Epoch 6400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663479\n", + "Epoch 6420 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663479\n", + "Epoch 6440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466348\n", + "Epoch 6460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", + "Epoch 6480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", + "Epoch 6500 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663484\n", + "Epoch 6520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6580 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663487\n", + "Epoch 6600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663498\n", + "Epoch 6940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Results\n", + "\n", + "Before viewing the results, we need to reverse the transformations applied on the output variable y.\n", + "\n", + "The `inverse_transform` method of the StandardScaler object will help us." + ], + "metadata": { + "id": "ldFMBPuvr0l0" + } + }, + { + "cell_type": "code", + "source": [ + "from sklearn.metrics import mean_squared_error\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = (((y_test - y_hat) ** 2).sum() / num_test )\n", + "print(\"Test Set Error\", error)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZycI4aExMsoC", + "outputId": "47c6b8fa-d1ee-4ff6-90d0-7e9289cfe40e" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Test Set Error 0.5263803029005855\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Libraries\n", + "\n", + "Instead of coding everything from scratch, i.e the model, loss functions, and gradient calculations, there are many libaries that have implemented many machine learning algorithms for us.\n", + "\n", + "These libraries will generally be faster and more optimized. We can use the LinearRegression and SGD regressor module from scikit learn to compare our model" + ], + "metadata": { + "id": "UoYobRS9uBIv" + } + }, + { + "cell_type": "code", + "source": [ + "from sklearn.linear_model import SGDRegressor\n", + "\n", + "\n", + "x_train, x_test, y_train, y_test = dataset_copy\n", + "sgd = SGDRegressor()\n", + "sgd.fit(x_train.T, y_train)\n", + "y_hat = sgd.predict(x_test.T)\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = mean_squared_error(y_test, y_hat, squared = True)\n", + "print(\"Test Set Error\", error)" + ], + "metadata": { + "id": "txWBY_0eoNN_", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "7886b7e0-c383-4676-e825-3d7197d06d80" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Test Set Error 0.5892243304217802\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.linear_model import LinearRegression as LR\n", + "\n", + "x_train, x_test, y_train, y_test = dataset_copy\n", + "lr = LR()\n", + "lr.fit(x_train.T, y_train)\n", + "y_hat = lr.predict(x_test.T)\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = mean_squared_error(y_test, y_hat, squared = True)\n", + "print(\"Test Set Error\", error)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9CaqphG8TG7V", + "outputId": "579bc8dd-6093-4155-8966-f8c60c34b1b3" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Test Set Error 0.5263803029005857\n" + ] + } + ] + } + ] +} \ No newline at end of file From cab92a9a90ab30ad4532ef2a7b104118abb5cc2e Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Sun, 31 Jul 2022 22:00:18 -0700 Subject: [PATCH 44/76] Add lr from scratch --- notebooks/Linear_Regression.ipynb | 1371 -- notebooks/linear_regression.ipynb | 22666 +------------------ notebooks/linear_regression_with_sgd.ipynb | 21660 ++++++++++++++++++ 3 files changed, 22851 insertions(+), 22846 deletions(-) delete mode 100644 notebooks/Linear_Regression.ipynb create mode 100644 notebooks/linear_regression_with_sgd.ipynb diff --git a/notebooks/Linear_Regression.ipynb b/notebooks/Linear_Regression.ipynb deleted file mode 100644 index fbc561d..0000000 --- a/notebooks/Linear_Regression.ipynb +++ /dev/null @@ -1,1371 +0,0 @@ -{ - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Linear Regression.ipynb", - "provenance": [], - "collapsed_sections": [], - "authorship_tag": "ABX9TyODV4REEuhLrJ1l8OWl6dFt", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "markdown", - "source": [ - "In this tutorial, we are going to implement a linear regression model to predict california housing prices. We will build the model from scratch using numpy. This will be a great approach to begin understanding regression based models.\n", - "\n", - "After completing this tutorial the learner is expected to know the basic building blocks of a linear regression model. The learner is also expected to know the pipeline of reading and transforming data for machine learning workflows.\n", - "\n" - ], - "metadata": { - "id": "m41136O7L5bV" - } - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "id": "Pni17h4R8v8a" - }, - "outputs": [], - "source": [ - "## Import the usual libraries\n", - "import numpy as np\n", - "import pandas as pd\n", - "from sklearn.datasets import fetch_california_housing\n", - "from sklearn.model_selection import train_test_split\n", - "from sklearn.preprocessing import StandardScaler\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Importing the dataset\n", - "\n", - "The real-world dataset can be obtained by the function `fetch_california_housing` that downloads the dataset for us. \n", - "\n", - "The `as_frame` parameter returns a pandas dataframe which is a library useful for viewing contents of the data.\n", - "\n" - ], - "metadata": { - "id": "DjyJUfczL4zX" - } - }, - { - "cell_type": "code", - "source": [ - "# Fetch the data using sklearn function\n", - "bunch = fetch_california_housing(download_if_missing=True, as_frame=True)\n", - "\n", - "# Load the dataframe and view\n", - "df = bunch.frame\n", - "df.head()" - ], - "metadata": { - "id": "aOXxbywahC5X", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 206 - }, - "outputId": "24521e0a-6f1a-4e5c-c35d-3abb8112a9af" - }, - "execution_count": 2, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude \\\n", - "0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 \n", - "1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 \n", - "2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 \n", - "3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 \n", - "4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 \n", - "\n", - " Longitude MedHouseVal \n", - "0 -122.23 4.526 \n", - "1 -122.22 3.585 \n", - "2 -122.24 3.521 \n", - "3 -122.25 3.413 \n", - "4 -122.25 3.422 " - ], - "text/html": [ - "\n", - "
\n", - "
\n", - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
08.325241.06.9841271.023810322.02.55555637.88-122.234.526
18.301421.06.2381370.9718802401.02.10984237.86-122.223.585
27.257452.08.2881361.073446496.02.80226037.85-122.243.521
35.643152.05.8173521.073059558.02.54794537.85-122.253.413
43.846252.06.2818531.081081565.02.18146737.85-122.253.422
\n", - "
\n", - " \n", - " \n", - " \n", - "\n", - " \n", - "
\n", - "
\n", - " " - ] - }, - "metadata": {}, - "execution_count": 2 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "For this dataset, our target variable is the median house value for California districts, expressed in hundreds of thousands of dollars ($100,000).\n", - "\n", - "We can take a closer look at the various statistical parameters of the dataset using pandas. The `describe` function will help us." - ], - "metadata": { - "id": "KUeU_jLylTx7" - } - }, - { - "cell_type": "code", - "source": [ - "df.describe()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 300 - }, - "id": "eD4BpBHClgDc", - "outputId": "e2171ffb-bd38-4e3e-b600-ad3c249a3234" - }, - "execution_count": 3, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " MedInc HouseAge AveRooms AveBedrms Population \\\n", - "count 20640.000000 20640.000000 20640.000000 20640.000000 20640.000000 \n", - "mean 3.870671 28.639486 5.429000 1.096675 1425.476744 \n", - "std 1.899822 12.585558 2.474173 0.473911 1132.462122 \n", - "min 0.499900 1.000000 0.846154 0.333333 3.000000 \n", - "25% 2.563400 18.000000 4.440716 1.006079 787.000000 \n", - "50% 3.534800 29.000000 5.229129 1.048780 1166.000000 \n", - "75% 4.743250 37.000000 6.052381 1.099526 1725.000000 \n", - "max 15.000100 52.000000 141.909091 34.066667 35682.000000 \n", - "\n", - " AveOccup Latitude Longitude MedHouseVal \n", - "count 20640.000000 20640.000000 20640.000000 20640.000000 \n", - "mean 3.070655 35.631861 -119.569704 2.068558 \n", - "std 10.386050 2.135952 2.003532 1.153956 \n", - "min 0.692308 32.540000 -124.350000 0.149990 \n", - "25% 2.429741 33.930000 -121.800000 1.196000 \n", - "50% 2.818116 34.260000 -118.490000 1.797000 \n", - "75% 3.282261 37.710000 -118.010000 2.647250 \n", - "max 1243.333333 41.950000 -114.310000 5.000010 " - ], - "text/html": [ - "\n", - "
\n", - "
\n", - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
count20640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.000000
mean3.87067128.6394865.4290001.0966751425.4767443.07065535.631861-119.5697042.068558
std1.89982212.5855582.4741730.4739111132.46212210.3860502.1359522.0035321.153956
min0.4999001.0000000.8461540.3333333.0000000.69230832.540000-124.3500000.149990
25%2.56340018.0000004.4407161.006079787.0000002.42974133.930000-121.8000001.196000
50%3.53480029.0000005.2291291.0487801166.0000002.81811634.260000-118.4900001.797000
75%4.74325037.0000006.0523811.0995261725.0000003.28226137.710000-118.0100002.647250
max15.00010052.000000141.90909134.06666735682.0000001243.33333341.950000-114.3100005.000010
\n", - "
\n", - " \n", - " \n", - " \n", - "\n", - " \n", - "
\n", - "
\n", - " " - ] - }, - "metadata": {}, - "execution_count": 3 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "As we can see the data in each of the columns is on different scales. For example, the average bedroom value is around 1 and the average population is around 1425. \n", - "\n", - "Generally, machine learing models do not work well when the data is on different scales. Thus, we have to normalize our data in the range [-1,1]. The module [StandardScalar](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html) will help us in this.\n", - "\n", - "The training data should always be normalized. The testing data should be normalized using the values of the training data. " - ], - "metadata": { - "id": "6S6WG0Bejxc2" - } - }, - { - "cell_type": "code", - "source": [ - "# !wget https://raw.githubusercontent.com/Ankit152/Fish-Market/main/Fish.csv\n", - "# import pandas as pd\n", - "# df = pd.read_csv(\"Fish.csv\")\n", - "# y = df['Weight']\n", - "# x = df[[\"Length1\", \"Length2\", \"Length3\", \"Height\", \"Width\",\"Weight\"]]\n", - "\n", - "df = bunch.frame\n", - "x = df.iloc[:,:-1] # Select all the columns, except the last column\n", - "y = df.iloc[:,-1:] # Select the last column\n", - "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.33, random_state = 1)\n", - "\n", - "input_scalar = StandardScaler()\n", - "output_scalar = StandardScaler()\n", - "\n", - "x_train = input_scalar.fit_transform(x_train).T # Normalize train data\n", - "x_test = input_scalar.transform(x_test).T # Only transform test data using values of train data\n", - "\n", - "y_train = output_scalar.fit_transform(y_train).reshape(-1)\n", - "y_test = output_scalar.transform(y_test).reshape(-1)\n", - "\n", - "dataset_copy = [ x_train.copy(), x_test.copy(), y_train.copy(), y_test.copy()]" - ], - "metadata": { - "id": "pkaOgN44iQLN" - }, - "execution_count": 4, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Linear Regression Model\n", - "\n", - "Now we define our linear regression model from scratch.\n", - "\n", - "A linear regression model is of the form:\n", - "\n", - "$y = a_1 x_1 + a_2 x_2 + \\dots + a_nx_n + a_{n+1}$\n", - " \n", - "The above can be rewritten using matrix multiplication as\n", - "\n", - "$ y = w^T x $\n", - "\n", - "where \n", - "\n", - "$ w = [a_1, a_2, \\dots, a_n, a_{n+1}]^T $\n", - "\n", - "$ x = [x_1, x_2, \\dots, x_n]^T $\n" - ], - "metadata": { - "id": "mylVXZDk96a2" - } - }, - { - "cell_type": "code", - "source": [ - "class LinearRegression():\n", - " def __init__(self, dim, lr = 0.1):\n", - " assert isinstance\n", - " self.lr = lr\n", - " self.w = np.zeros((dim))\n", - " self.grads = {\"dw\": np.zeros((dim)) +5}\n", - "\n", - " def forward(self, x):\n", - " y = self.w.T @ x\n", - " return y\n", - " \n", - " def backward(self, x, y_hat, y):\n", - " assert y_hat.shape == y.shape\n", - " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", - " assert self.grads[\"dw\"].shape == self.w.shape\n", - " \n", - " # print(self.grads[\"dw\"])\n", - "\n", - " def optimize(self):\n", - " self.w = self.w - self.lr * self.grads[\"dw\"]" - ], - "metadata": { - "id": "iJViSowz9nah" - }, - "execution_count": 5, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Loss\n", - "\n", - "For linear regression, various loss functions such as the mean absolute error, mean squared error, or root mean squared error can be used.\n", - "\n", - "In this example, we will use the mean squared error (MSE) loss.\n", - "\n", - "The MSE loss is given by \n", - "\n", - "$ error = \\frac{1}{m} Σ_{i=1}^{m} (y_{true}^{i} - y_{pred}^{i})^2 $ \n", - "\n", - "where $i$ denotes the particular obseration/row in the dataset and $m$ is the total number of obserations.\n", - "\n", - "To ensure our model is correct, the loss should decrease over each epoch.\n" - ], - "metadata": { - "id": "6UOy32LoqCrL" - } - }, - { - "cell_type": "markdown", - "source": [ - "" - ], - "metadata": { - "id": "3atqq0KirwLu" - } - }, - { - "cell_type": "code", - "source": [ - "num_epochs = 10000\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "dim = x_train.shape[0]\n", - "num_train = x_train.shape[1]\n", - "num_test = x_test.shape[1]\n", - "\n", - "\n", - "model = LinearRegression(dim = dim, lr = 0.1)\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/(2 * num_train) * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/(2 * num_test) * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 20 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "mgNn3oGjjbxX", - "outputId": "2f67998e-2fa4-4c43-e091-d5180dd92029" - }, - "execution_count": 6, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Epoch 0 | Train Loss 0.49999999999999983 | Test Loss 0.43712002508129305\n", - "Epoch 20 | Train Loss 0.2359010824314295 | Test Loss 0.2325611904818386\n", - "Epoch 40 | Train Loss 0.22188755162559423 | Test Loss 0.2217635127918686\n", - "Epoch 60 | Train Loss 0.21474640752415047 | Test Loss 0.2152613227580797\n", - "Epoch 80 | Train Loss 0.2095989567021037 | Test Loss 0.21037193610067245\n", - "Epoch 100 | Train Loss 0.20581761895152345 | Test Loss 0.20673038702760732\n", - "Epoch 120 | Train Loss 0.20303294882659725 | Test Loss 0.20402527473733864\n", - "Epoch 140 | Train Loss 0.20097918345162274 | Test Loss 0.20201418597478873\n", - "Epoch 160 | Train Loss 0.19946210112703647 | Test Loss 0.20051638978054404\n", - "Epoch 180 | Train Loss 0.19833950070910428 | Test Loss 0.19939846923590557\n", - "Epoch 200 | Train Loss 0.19750719045004836 | Test Loss 0.19856209982480624\n", - "Epoch 220 | Train Loss 0.1968887724916989 | Test Loss 0.1979347869242644\n", - "Epoch 240 | Train Loss 0.19642818272324772 | Test Loss 0.19746302071881933\n", - "Epoch 260 | Train Loss 0.19608424065206406 | Test Loss 0.19710724843033994\n", - "Epoch 280 | Train Loss 0.19582666642954677 | Test Loss 0.19683818623685323\n", - "Epoch 300 | Train Loss 0.19563316903289557 | Test Loss 0.19663411372213185\n", - "Epoch 320 | Train Loss 0.19548731666143612 | Test Loss 0.19647888801910168\n", - "Epoch 340 | Train Loss 0.19537697849050284 | Test Loss 0.19636048509166582\n", - "Epoch 360 | Train Loss 0.19529318388491884 | Test Loss 0.19626992725672532\n", - "Epoch 380 | Train Loss 0.19522928672715056 | Test Loss 0.19620049386222657\n", - "Epoch 400 | Train Loss 0.19518035283239818 | Test Loss 0.19614713968570663\n", - "Epoch 420 | Train Loss 0.19514271054504922 | Test Loss 0.1961060658296224\n", - "Epoch 440 | Train Loss 0.19511362075549118 | Test Loss 0.19607440266698017\n", - "Epoch 460 | Train Loss 0.19509103436032973 | Test Loss 0.196049975197568\n", - "Epoch 480 | Train Loss 0.19507341379189 | Test Loss 0.1960311290809374\n", - "Epoch 500 | Train Loss 0.195059601524607 | Test Loss 0.1960166013981983\n", - "Epoch 520 | Train Loss 0.19504872305387622 | Test Loss 0.19600542443105118\n", - "Epoch 540 | Train Loss 0.19504011519474806 | Test Loss 0.19599685384985982\n", - "Epoch 560 | Train Loss 0.19503327299733605 | Test Loss 0.19599031497728384\n", - "Epoch 580 | Train Loss 0.19502781036651573 | Test Loss 0.19598536246238987\n", - "Epoch 600 | Train Loss 0.19502343078313097 | Test Loss 0.19598164992474956\n", - "Epoch 620 | Train Loss 0.19501990548217418 | Test Loss 0.19597890702760307\n", - "Epoch 640 | Train Loss 0.19501705714492468 | Test Loss 0.1959769221005947\n", - "Epoch 660 | Train Loss 0.1950147476759042 | Test Loss 0.1959755289194148\n", - "Epoch 680 | Train Loss 0.19501286901218934 | Test Loss 0.19597459660841743\n", - "Epoch 700 | Train Loss 0.1950113361889526 | Test Loss 0.19597402189697258\n", - "Epoch 720 | Train Loss 0.1950100820879975 | Test Loss 0.19597372315589145\n", - "Epoch 740 | Train Loss 0.1950090534451732 | Test Loss 0.19597363578501353\n", - "Epoch 760 | Train Loss 0.1950082078022795 | Test Loss 0.19597370863036628\n", - "Epoch 780 | Train Loss 0.19500751116991094 | Test Loss 0.19597390118903935\n", - "Epoch 800 | Train Loss 0.19500693622732843 | Test Loss 0.19597418141927686\n", - "Epoch 820 | Train Loss 0.19500646092952323 | Test Loss 0.19597452401759977\n", - "Epoch 840 | Train Loss 0.19500606742426427 | Test Loss 0.1959749090579219\n", - "Epoch 860 | Train Loss 0.19500574120612196 | Test Loss 0.19597532091250944\n", - "Epoch 880 | Train Loss 0.19500547045245514 | Test Loss 0.19597574739336301\n", - "Epoch 900 | Train Loss 0.19500524549975556 | Test Loss 0.1959761790667557\n", - "Epoch 920 | Train Loss 0.19500505842876395 | Test Loss 0.19597660870438502\n", - "Epoch 940 | Train Loss 0.1950049027342804 | Test Loss 0.1959770308427642\n", - "Epoch 960 | Train Loss 0.19500477306123667 | Test Loss 0.1959774414287147\n", - "Epoch 980 | Train Loss 0.19500466499285687 | Test Loss 0.19597783753361098\n", - "Epoch 1000 | Train Loss 0.19500457487995757 | Test Loss 0.19597821712271776\n", - "Epoch 1020 | Train Loss 0.1950044997028894 | Test Loss 0.19597857886881814\n", - "Epoch 1040 | Train Loss 0.1950044369594934 | Test Loss 0.19597892200155245\n", - "Epoch 1060 | Train Loss 0.19500438457387914 | Test Loss 0.19597924618562568\n", - "Epoch 1080 | Train Loss 0.1950043408219371 | Test Loss 0.1959795514224043\n", - "Epoch 1100 | Train Loss 0.19500430427035154 | Test Loss 0.19597983797049975\n", - "Epoch 1120 | Train Loss 0.19500427372654458 | Test Loss 0.1959801062817876\n", - "Epoch 1140 | Train Loss 0.195004248197501 | Test Loss 0.19598035694999025\n", - "Epoch 1160 | Train Loss 0.19500422685583052 | Test Loss 0.1959805906694935\n", - "Epoch 1180 | Train Loss 0.1950042090117447 | Test Loss 0.19598080820250163\n", - "Epoch 1200 | Train Loss 0.195004194089881 | Test Loss 0.1959810103529865\n", - "Epoch 1220 | Train Loss 0.19500418161010774 | Test Loss 0.1959811979461702\n", - "Epoch 1240 | Train Loss 0.1950041711716055 | Test Loss 0.19598137181250938\n", - "Epoch 1260 | Train Loss 0.1950041624396518 | Test Loss 0.1959815327753366\n", - "Epoch 1280 | Train Loss 0.19500415513463745 | Test Loss 0.19598168164146745\n", - "Epoch 1300 | Train Loss 0.19500414902293145 | Test Loss 0.19598181919420496\n", - "Epoch 1320 | Train Loss 0.1950041439092753 | Test Loss 0.19598194618827683\n", - "Epoch 1340 | Train Loss 0.19500413963044858 | Test Loss 0.19598206334632265\n", - "Epoch 1360 | Train Loss 0.1950041360499879 | Test Loss 0.19598217135661974\n", - "Epoch 1380 | Train Loss 0.19500413305378356 | Test Loss 0.19598227087179027\n", - "Epoch 1400 | Train Loss 0.1950041305464049 | Test Loss 0.19598236250828016\n", - "Epoch 1420 | Train Loss 0.1950041284480337 | Test Loss 0.19598244684643956\n", - "Epoch 1440 | Train Loss 0.19500412669190298 | Test Loss 0.19598252443106423\n", - "Epoch 1460 | Train Loss 0.1950041252221582 | Test Loss 0.1959825957722857\n", - "Epoch 1480 | Train Loss 0.1950041239920701 | Test Loss 0.19598266134671743\n", - "Epoch 1500 | Train Loss 0.1950041229625413 | Test Loss 0.19598272159878383\n", - "Epoch 1520 | Train Loss 0.19500412210085774 | Test Loss 0.19598277694217195\n", - "Epoch 1540 | Train Loss 0.19500412137964543 | Test Loss 0.19598282776135909\n", - "Epoch 1560 | Train Loss 0.19500412077599738 | Test Loss 0.19598287441317852\n", - "Epoch 1580 | Train Loss 0.19500412027074418 | Test Loss 0.19598291722839395\n", - "Epoch 1600 | Train Loss 0.19500411984784347 | Test Loss 0.1959829565132598\n", - "Epoch 1620 | Train Loss 0.19500411949386964 | Test Loss 0.19598299255105023\n", - "Epoch 1640 | Train Loss 0.19500411919758648 | Test Loss 0.1959830256035433\n", - "Epoch 1660 | Train Loss 0.19500411894959 | Test Loss 0.1959830559124517\n", - "Epoch 1680 | Train Loss 0.19500411874200962 | Test Loss 0.19598308370079265\n", - "Epoch 1700 | Train Loss 0.19500411856825786 | Test Loss 0.19598310917419287\n", - "Epoch 1720 | Train Loss 0.19500411842282128 | Test Loss 0.1959831325221266\n", - "Epoch 1740 | Train Loss 0.19500411830108505 | Test Loss 0.19598315391908486\n", - "Epoch 1760 | Train Loss 0.19500411819918667 | Test Loss 0.19598317352567718\n", - "Epoch 1780 | Train Loss 0.19500411811389318 | Test Loss 0.19598319148966561\n", - "Epoch 1800 | Train Loss 0.19500411804249856 | Test Loss 0.19598320794693336\n", - "Epoch 1820 | Train Loss 0.19500411798273784 | Test Loss 0.1959832230223899\n", - "Epoch 1840 | Train Loss 0.19500411793271513 | Test Loss 0.19598323683081562\n", - "Epoch 1860 | Train Loss 0.19500411789084354 | Test Loss 0.19598324947764745\n", - "Epoch 1880 | Train Loss 0.19500411785579488 | Test Loss 0.19598326105971003\n", - "Epoch 1900 | Train Loss 0.19500411782645727 | Test Loss 0.19598327166589385\n", - "Epoch 1920 | Train Loss 0.19500411780190013 | Test Loss 0.1959832813777842\n", - "Epoch 1940 | Train Loss 0.1950041177813444 | Test Loss 0.1959832902702435\n", - "Epoch 1960 | Train Loss 0.1950041177641382 | Test Loss 0.1959832984119505\n", - "Epoch 1980 | Train Loss 0.19500411774973558 | Test Loss 0.19598330586589785\n", - "Epoch 2000 | Train Loss 0.1950041177376798 | Test Loss 0.1959833126898522\n", - "Epoch 2020 | Train Loss 0.19500411772758847 | Test Loss 0.1959833189367787\n", - "Epoch 2040 | Train Loss 0.19500411771914136 | Test Loss 0.19598332465523224\n", - "Epoch 2060 | Train Loss 0.1950041177120707 | Test Loss 0.19598332988971823\n", - "Epoch 2080 | Train Loss 0.1950041177061521 | Test Loss 0.1959833346810246\n", - "Epoch 2100 | Train Loss 0.195004117701198 | Test Loss 0.19598333906652787\n", - "Epoch 2120 | Train Loss 0.19500411769705106 | Test Loss 0.19598334308047438\n", - "Epoch 2140 | Train Loss 0.1950041176935798 | Test Loss 0.19598334675423898\n", - "Epoch 2160 | Train Loss 0.19500411769067422 | Test Loss 0.1959833501165632\n", - "Epoch 2180 | Train Loss 0.19500411768824202 | Test Loss 0.1959833531937735\n", - "Epoch 2200 | Train Loss 0.19500411768620615 | Test Loss 0.19598335600998243\n", - "Epoch 2220 | Train Loss 0.19500411768450196 | Test Loss 0.1959833585872731\n", - "Epoch 2240 | Train Loss 0.19500411768307552 | Test Loss 0.19598336094586813\n", - "Epoch 2260 | Train Loss 0.19500411768188147 | Test Loss 0.19598336310428585\n", - "Epoch 2280 | Train Loss 0.19500411768088202 | Test Loss 0.195983365079482\n", - "Epoch 2300 | Train Loss 0.19500411768004536 | Test Loss 0.19598336688698145\n", - "Epoch 2320 | Train Loss 0.19500411767934506 | Test Loss 0.1959833685409978\n", - "Epoch 2340 | Train Loss 0.19500411767875886 | Test Loss 0.19598337005454344\n", - "Epoch 2360 | Train Loss 0.1950041176782682 | Test Loss 0.1959833714395307\n", - "Epoch 2380 | Train Loss 0.1950041176778575 | Test Loss 0.1959833727068645\n", - "Epoch 2400 | Train Loss 0.19500411767751366 | Test Loss 0.19598337386652676\n", - "Epoch 2420 | Train Loss 0.19500411767722584 | Test Loss 0.1959833749276544\n", - "Epoch 2440 | Train Loss 0.19500411767698494 | Test Loss 0.1959833758986108\n", - "Epoch 2460 | Train Loss 0.19500411767678333 | Test Loss 0.19598337678705066\n", - "Epoch 2480 | Train Loss 0.19500411767661452 | Test Loss 0.19598337759998\n", - "Epoch 2500 | Train Loss 0.19500411767647324 | Test Loss 0.19598337834381113\n", - "Epoch 2520 | Train Loss 0.195004117676355 | Test Loss 0.19598337902441254\n", - "Epoch 2540 | Train Loss 0.195004117676256 | Test Loss 0.1959833796471551\n", - "Epoch 2560 | Train Loss 0.19500411767617312 | Test Loss 0.19598338021695402\n", - "Epoch 2580 | Train Loss 0.1950041176761038 | Test Loss 0.19598338073830746\n", - "Epoch 2600 | Train Loss 0.19500411767604572 | Test Loss 0.19598338121533196\n", - "Epoch 2620 | Train Loss 0.19500411767599712 | Test Loss 0.19598338165179446\n", - "Epoch 2640 | Train Loss 0.1950041176759564 | Test Loss 0.19598338205114224\n", - "Epoch 2660 | Train Loss 0.19500411767592238 | Test Loss 0.19598338241652982\n", - "Epoch 2680 | Train Loss 0.19500411767589387 | Test Loss 0.19598338275084387\n", - "Epoch 2700 | Train Loss 0.19500411767587003 | Test Loss 0.1959833830567258\n", - "Epoch 2720 | Train Loss 0.19500411767585005 | Test Loss 0.19598338333659285\n", - "Epoch 2740 | Train Loss 0.1950041176758333 | Test Loss 0.19598338359265657\n", - "Epoch 2760 | Train Loss 0.19500411767581935 | Test Loss 0.19598338382694094\n", - "Epoch 2780 | Train Loss 0.19500411767580764 | Test Loss 0.19598338404129775\n", - "Epoch 2800 | Train Loss 0.19500411767579784 | Test Loss 0.19598338423742154\n", - "Epoch 2820 | Train Loss 0.19500411767578962 | Test Loss 0.19598338441686272\n", - "Epoch 2840 | Train Loss 0.19500411767578277 | Test Loss 0.19598338458104\n", - "Epoch 2860 | Train Loss 0.195004117675777 | Test Loss 0.1959833847312515\n", - "Epoch 2880 | Train Loss 0.1950041176757722 | Test Loss 0.19598338486868488\n", - "Epoch 2900 | Train Loss 0.19500411767576814 | Test Loss 0.19598338499442705\n", - "Epoch 2920 | Train Loss 0.19500411767576475 | Test Loss 0.19598338510947227\n", - "Epoch 2940 | Train Loss 0.19500411767576192 | Test Loss 0.19598338521473044\n", - "Epoch 2960 | Train Loss 0.1950041176757596 | Test Loss 0.19598338531103396\n", - "Epoch 2980 | Train Loss 0.19500411767575762 | Test Loss 0.19598338539914462\n", - "Epoch 3000 | Train Loss 0.19500411767575593 | Test Loss 0.1959833854797592\n", - "Epoch 3020 | Train Loss 0.19500411767575457 | Test Loss 0.1959833855535154\n", - "Epoch 3040 | Train Loss 0.1950041176757534 | Test Loss 0.1959833856209966\n", - "Epoch 3060 | Train Loss 0.19500411767575246 | Test Loss 0.19598338568273665\n", - "Epoch 3080 | Train Loss 0.19500411767575163 | Test Loss 0.19598338573922397\n", - "Epoch 3100 | Train Loss 0.19500411767575093 | Test Loss 0.19598338579090527\n", - "Epoch 3120 | Train Loss 0.19500411767575035 | Test Loss 0.19598338583818956\n", - "Epoch 3140 | Train Loss 0.19500411767574988 | Test Loss 0.19598338588145087\n", - "Epoch 3160 | Train Loss 0.1950041176757495 | Test Loss 0.1959833859210314\n", - "Epoch 3180 | Train Loss 0.19500411767574916 | Test Loss 0.19598338595724435\n", - "Epoch 3200 | Train Loss 0.1950041176757489 | Test Loss 0.19598338599037615\n", - "Epoch 3220 | Train Loss 0.19500411767574863 | Test Loss 0.19598338602068902\n", - "Epoch 3240 | Train Loss 0.19500411767574843 | Test Loss 0.19598338604842275\n", - "Epoch 3260 | Train Loss 0.19500411767574832 | Test Loss 0.19598338607379676\n", - "Epoch 3280 | Train Loss 0.19500411767574816 | Test Loss 0.19598338609701185\n", - "Epoch 3300 | Train Loss 0.19500411767574805 | Test Loss 0.19598338611825167\n", - "Epoch 3320 | Train Loss 0.19500411767574796 | Test Loss 0.19598338613768423\n", - "Epoch 3340 | Train Loss 0.19500411767574785 | Test Loss 0.19598338615546346\n", - "Epoch 3360 | Train Loss 0.1950041176757478 | Test Loss 0.1959833861717299\n", - "Epoch 3380 | Train Loss 0.1950041176757477 | Test Loss 0.19598338618661224\n", - "Epoch 3400 | Train Loss 0.19500411767574768 | Test Loss 0.1959833862002283\n", - "Epoch 3420 | Train Loss 0.19500411767574766 | Test Loss 0.19598338621268585\n", - "Epoch 3440 | Train Loss 0.19500411767574763 | Test Loss 0.19598338622408337\n", - "Epoch 3460 | Train Loss 0.1950041176757476 | Test Loss 0.1959833862345112\n", - "Epoch 3480 | Train Loss 0.1950041176757476 | Test Loss 0.19598338624405162\n", - "Epoch 3500 | Train Loss 0.19500411767574752 | Test Loss 0.19598338625278036\n", - "Epoch 3520 | Train Loss 0.19500411767574755 | Test Loss 0.19598338626076636\n", - "Epoch 3540 | Train Loss 0.19500411767574752 | Test Loss 0.19598338626807282\n", - "Epoch 3560 | Train Loss 0.19500411767574752 | Test Loss 0.19598338627475767\n", - "Epoch 3580 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628087364\n", - "Epoch 3600 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628646922\n", - "Epoch 3620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629158868\n", - "Epoch 3640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629627257\n", - "Epoch 3660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630055787\n", - "Epoch 3680 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863044786\n", - "Epoch 3700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630806564\n", - "Epoch 3720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631134748\n", - "Epoch 3740 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863143501\n", - "Epoch 3760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631709722\n", - "Epoch 3780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863196106\n", - "Epoch 3800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863219101\n", - "Epoch 3820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632401394\n", - "Epoch 3840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632593876\n", - "Epoch 3860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632769982\n", - "Epoch 3880 | Train Loss 0.19500411767574743 | Test Loss 0.19598338632931098\n", - "Epoch 3900 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863307851\n", - "Epoch 3920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633213377\n", - "Epoch 3940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633336768\n", - "Epoch 3960 | Train Loss 0.19500411767574743 | Test Loss 0.19598338633449658\n", - "Epoch 3980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633552945\n", - "Epoch 4000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633647439\n", - "Epoch 4020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633733897\n", - "Epoch 4040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633812995\n", - "Epoch 4060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633885368\n", - "Epoch 4080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633951579\n", - "Epoch 4100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634012158\n", - "Epoch 4120 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863406758\n", - "Epoch 4140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634118284\n", - "Epoch 4160 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863416468\n", - "Epoch 4180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634207124\n", - "Epoch 4200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634245957\n", - "Epoch 4220 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863428149\n", - "Epoch 4240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634313991\n", - "Epoch 4260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634343732\n", - "Epoch 4280 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863437094\n", - "Epoch 4300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634395834\n", - "Epoch 4320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863441861\n", - "Epoch 4340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863443945\n", - "Epoch 4360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634458515\n", - "Epoch 4380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634475954\n", - "Epoch 4400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634491913\n", - "Epoch 4420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634506512\n", - "Epoch 4440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863451987\n", - "Epoch 4460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634532095\n", - "Epoch 4480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634543272\n", - "Epoch 4500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634553503\n", - "Epoch 4520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634562865\n", - "Epoch 4540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634571427\n", - "Epoch 4560 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863457926\n", - "Epoch 4580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634586435\n", - "Epoch 4600 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863459299\n", - "Epoch 4620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634598989\n", - "Epoch 4640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634604479\n", - "Epoch 4660 | Train Loss 0.19500411767574746 | Test Loss 0.195983386346095\n", - "Epoch 4680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634614093\n", - "Epoch 4700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634618298\n", - "Epoch 4720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634622145\n", - "Epoch 4740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634625664\n", - "Epoch 4760 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863462888\n", - "Epoch 4780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463183\n", - "Epoch 4800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634634527\n", - "Epoch 4820 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463699\n", - "Epoch 4840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634639245\n", - "Epoch 4860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634641307\n", - "Epoch 4880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634643198\n", - "Epoch 4900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634644927\n", - "Epoch 4920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634646506\n", - "Epoch 4940 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863464795\n", - "Epoch 4960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634649273\n", - "Epoch 4980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634650483\n", - "Epoch 5000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634651596\n", - "Epoch 5020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634652604\n", - "Epoch 5040 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465353\n", - "Epoch 5060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634654378\n", - "Epoch 5080 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465516\n", - "Epoch 5100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634655868\n", - "Epoch 5120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634656515\n", - "Epoch 5140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657111\n", - "Epoch 5160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657653\n", - "Epoch 5180 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863465815\n", - "Epoch 5200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634658605\n", - "Epoch 5220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659024\n", - "Epoch 5240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659407\n", - "Epoch 5260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659754\n", - "Epoch 5280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660073\n", - "Epoch 5300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660364\n", - "Epoch 5320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466063\n", - "Epoch 5340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660875\n", - "Epoch 5360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661094\n", - "Epoch 5380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661303\n", - "Epoch 5400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661489\n", - "Epoch 5420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661658\n", - "Epoch 5440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661816\n", - "Epoch 5460 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466196\n", - "Epoch 5480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662088\n", - "Epoch 5500 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466221\n", - "Epoch 5520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662318\n", - "Epoch 5540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662418\n", - "Epoch 5560 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466251\n", - "Epoch 5580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662596\n", - "Epoch 5600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662674\n", - "Epoch 5620 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634662743\n", - "Epoch 5640 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466281\n", - "Epoch 5660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662868\n", - "Epoch 5680 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466292\n", - "Epoch 5700 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466297\n", - "Epoch 5720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663018\n", - "Epoch 5740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663057\n", - "Epoch 5760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663093\n", - "Epoch 5780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663132\n", - "Epoch 5800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466316\n", - "Epoch 5820 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466319\n", - "Epoch 5840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663218\n", - "Epoch 5860 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466324\n", - "Epoch 5880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663262\n", - "Epoch 5900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663284\n", - "Epoch 5920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663304\n", - "Epoch 5940 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663318\n", - "Epoch 5960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663331\n", - "Epoch 5980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663348\n", - "Epoch 6000 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663356\n", - "Epoch 6020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663373\n", - "Epoch 6040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663384\n", - "Epoch 6060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663395\n", - "Epoch 6080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663404\n", - "Epoch 6100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663412\n", - "Epoch 6120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663418\n", - "Epoch 6140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663423\n", - "Epoch 6160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663431\n", - "Epoch 6180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663437\n", - "Epoch 6200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663445\n", - "Epoch 6220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663448\n", - "Epoch 6240 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466345\n", - "Epoch 6260 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466346\n", - "Epoch 6280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663462\n", - "Epoch 6300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", - "Epoch 6320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", - "Epoch 6340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466347\n", - "Epoch 6360 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", - "Epoch 6380 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", - "Epoch 6400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663479\n", - "Epoch 6420 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663479\n", - "Epoch 6440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466348\n", - "Epoch 6460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", - "Epoch 6480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", - "Epoch 6500 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663484\n", - "Epoch 6520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", - "Epoch 6540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", - "Epoch 6560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", - "Epoch 6580 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663487\n", - "Epoch 6600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", - "Epoch 6620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", - "Epoch 6640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", - "Epoch 6660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", - "Epoch 6680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", - "Epoch 6700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", - "Epoch 6720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", - "Epoch 6740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", - "Epoch 6760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663498\n", - "Epoch 6940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 6980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 7980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 8980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", - "Epoch 9980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAbtklEQVR4nO3df5BV5Z3n8fenu6ExgKBI/EGjNBnUQDRN6NWoOxETjeSXWpWkFmIqOMmUmtWY1UkZjRPjkHIrZrbMjrVkDckymdraBBMdJySScTWR0cSoNItBQRkQmdDEHy0qwih0N/3dP+7pzrm3b9O3uy/e5uHzqurinOc8z+nn3NN8+unnnHuuIgIzM0tXXa07YGZmB5eD3swscQ56M7PEOejNzBLnoDczS1xDrTtQ6phjjokZM2bUuhtmZoeUtWvXvhIRU8ttG3VBP2PGDNra2mrdDTOzQ4qkfxtom6duzMwS56A3M0ucg97MLHGjbo7ezA5PXV1dtLe3s3fv3lp3ZVQbN24cTU1NjBkzpuI2DnozGxXa29uZOHEiM2bMQFKtuzMqRQQ7d+6kvb2d5ubmittVNHUjaYGkTZK2SLqhzPbLJHVIejL7+svctsWSNmdfiyvumZkdVvbu3cuUKVMc8gcgiSlTpgz5r55BR/SS6oGlwAVAO7BG0sqI2FhS9a6IuLqk7dHAN4BWIIC1WdvXhtRLMzssOOQHN5zXqJIR/RnAlojYGhGdwArg4gr3fyHwQES8moX7A8CCIfeyAm92dnP7/93Euj/4d4iZWV4lQT8N2J5bb8/KSn1S0npJd0uaPpS2ki6X1CapraOjo8KuF3urcz93/HoLT+3YNaz2ZnZ427lzJy0tLbS0tHDccccxbdq0vvXOzs4Dtm1ra+Oaa64Z9HucffbZ1erukFTrYuzPgR9HxD5JVwD/AHyw0sYRsQxYBtDa2jqiT0Lx56iY2XBMmTKFJ598EoBbbrmFCRMm8JWvfKVve3d3Nw0N5SOztbWV1tbWQb/Ho48+Wp3ODlElI/odwPTcelNW1icidkbEvmz1B8C8SttWi+f2zKzaLrvsMq688krOPPNMrr/+ep544gnOOuss5s6dy9lnn82mTZsAWL16NR//+MeBwi+Jz3/+88yfP5+ZM2dyxx139O1vwoQJffXnz5/Ppz71KU499VQuvfRSej/tb9WqVZx66qnMmzePa665pm+/I1HJiH4NMEtSM4WQXgh8Jl9B0vER8UK2ehHwTLZ8P/BfJR2VrX8YuHHEvTazpP3Nzzew8Y9vVHWfs084km98Ys6Q27W3t/Poo49SX1/PG2+8wSOPPEJDQwMPPvggX/va17jnnnv6tXn22Wd56KGH2L17N6eccgpf/OIX+933vm7dOjZs2MAJJ5zAOeecw29/+1taW1u54oorePjhh2lubmbRokXDPt68QYM+IrolXU0htOuB5RGxQdISoC0iVgLXSLoI6AZeBS7L2r4q6ZsUflkALImIV6vS84H7ezB3b2aHmU9/+tPU19cDsGvXLhYvXszmzZuRRFdXV9k2H/vYx2hsbKSxsZF3vvOdvPTSSzQ1NRXVOeOMM/rKWlpa2LZtGxMmTGDmzJl998gvWrSIZcuWjfgYKpqjj4hVwKqSsptzyzcywEg9IpYDy0fQx4p44sYsHcMZeR8s48eP71v++te/znnnnce9997Ltm3bmD9/ftk2jY2Nfcv19fV0d3cPq061JPesG4/nzexg2bVrF9OmFW4c/OEPf1j1/Z9yyils3bqVbdu2AXDXXXdVZb/JBL2vxZrZwXb99ddz4403Mnfu3IMyAj/iiCP47ne/y4IFC5g3bx4TJ05k0qRJI96vRtucdmtrawzng0def7OTliUP8I1PzOYvzqn8GRBmNjo888wzvPvd7651N2puz549TJgwgYjgqquuYtasWVx77bVFdcq9VpLWRkTZezyTGdH3GmW/t8zMhuT73/8+LS0tzJkzh127dnHFFVeMeJ/JPL1SvhxrZgm49tpr+43gRyq9EX2tO2BmNsqkE/Qe0JuZlZVO0GdG28VlM7NaSybofXulmVl5yVyMNTMbiZ07d/KhD30IgBdffJH6+nqmTp0KwBNPPMHYsWMP2H716tWMHTu2Zo8iPhAHvZkZgz+meDCrV69mwoQJozLo05m6qXUHzCw5a9eu5dxzz2XevHlceOGFvPBC4SG9d9xxB7Nnz+b0009n4cKFbNu2jTvvvJPvfOc7tLS08Mgjj9S458WSG9H7WqxZAn55A7z4VHX3edxp8JFvVVw9IvjSl77Ez372M6ZOncpdd93FTTfdxPLly/nWt77F888/T2NjI6+//jqTJ0/myiuvHPJfAW+XZILeHzxiZtW0b98+nn76aS644AIA9u/fz/HHHw/A6aefzqWXXsoll1zCJZdcUstuViSZoDezhAxh5H2wRARz5szhd7/7Xb9t9913Hw8//DA///nPufXWW3nqqSr/9VFlyczR9wq/N9bMqqCxsZGOjo6+oO/q6mLDhg309PSwfft2zjvvPG677TZ27drFnj17mDhxIrt3765xr8tLJug9cWNm1VRXV8fdd9/NV7/6Vd773vfS0tLCo48+yv79+/nsZz/Laaedxty5c7nmmmuYPHkyn/jEJ7j33nt9Mfbt4IuxZjZSt9xyS9/yww8/3G/7b37zm35lJ598MuvXrz+Y3Rq2dEb0HtKbmZWVTND38oDezKxYMkHv59GbHfr8UMLBDec1SibozezQNm7cOHbu3OmwP4CIYOfOnYwbN25I7Xwx1sxGhaamJtrb2+no6Kh1V0a1cePG0dTUNKQ2FQW9pAXA3wH1wA8iouy7GSR9Ergb+A8R0SZpBvAMsCmr8lhEXDmkHlbIF2PNDm1jxoyhubm51t1I0qBBL6keWApcALQDayStjIiNJfUmAl8GHi/ZxXMR0VKl/g7Kb5gyMytWyRz9GcCWiNgaEZ3ACuDiMvW+CdwG7K1i/8zMbIQqCfppwPbcentW1kfS+4DpEXFfmfbNktZJ+hdJfz78rpqZ2XCM+GKspDrgduCyMptfAE6MiJ2S5gH/JGlORLxRso/LgcsBTjzxxBH1xxdjzcyKVTKi3wFMz603ZWW9JgLvAVZL2ga8H1gpqTUi9kXEToCIWAs8B5xc+g0iYllEtEZEa+9Hdw2VL8aamZVXSdCvAWZJapY0FlgIrOzdGBG7IuKYiJgRETOAx4CLsrtupmYXc5E0E5gFbK36UZiZ2YAGnbqJiG5JVwP3U7i9cnlEbJC0BGiLiJUHaP4BYImkLqAHuDIiXq1Gx0v5nbFmZuVVNEcfEauAVSVlNw9Qd35u+R7gnhH0b8j8rjozs2LJPALBc/RmZuUlE/RmZlZeOkG/dxd3jV1Cc8dDte6JmdmokkzQa38XZ9Y9y/hOPxDJzCwvmaD/E1+MNTPLSyboVZfMoZiZVVV66ejbK83MiiQU9L6/0sysnGSCXr6R3sysrGSCvk/01LoHZmajSjJB7xG9mVl5yQT9n/hirJlZXjJB7xG9mVl5yQR9Hw/ozcyKpBP0HtGbmZWVTtD38ZDezCwvoaDvHdE76M3M8hIK+gI5583MiqQT9NkcvXPezKxYOkGfkaPezKxIQkHvu27MzMpJKOgzfkyxmVmRdIJevuvGzKycdILeUzdmZmVVFPSSFkjaJGmLpBsOUO+TkkJSa67sxqzdJkkXVqPTB+YRvZlZXsNgFSTVA0uBC4B2YI2klRGxsaTeRODLwOO5stnAQmAOcALwoKSTI2J/9Q6h75tVfZdmZimoZER/BrAlIrZGRCewAri4TL1vArcBe3NlFwMrImJfRDwPbMn2d/D4YqyZWZFKgn4asD233p6V9ZH0PmB6RNw31LZZ+8sltUlq6+joqKjj/XlEb2ZWzogvxkqqA24H/mq4+4iIZRHRGhGtU6dOHWGPPKI3M8sbdI4e2AFMz603ZWW9JgLvAVZnH/5xHLBS0kUVtK0ez9GbmZVVyYh+DTBLUrOksRQurq7s3RgRuyLimIiYEREzgMeAiyKiLau3UFKjpGZgFvBE1Y8izwN6M7Mig47oI6Jb0tXA/UA9sDwiNkhaArRFxMoDtN0g6SfARqAbuOqg3HEDeI7ezKy8SqZuiIhVwKqSspsHqDu/ZP1W4NZh9m8YPKQ3M8tL552xfgSCmVlZ6QR9Hwe9mVleQkGfjeid82ZmRRIK+gJfkjUzK5ZO0HuO3sysrHSC3mN5M7OyEgr6Xh7Rm5nlpRP08sVYM7Ny0gn6Pk56M7O8dILeI3ozs7LSCfo+Tnozs7wEg97MzPISDHqP6M3M8pIK+p7wvfRmZqWSCnrAHw5uZlYiqaB3xJuZ9ZdU0IMfhGBmViqpoA9EeFxvZlYkqaBHIAe9mVmRpII+kCfqzcxKJBX0ZmbWX4JB7yG9mVleUkEfvufGzKyfioJe0gJJmyRtkXRDme1XSnpK0pOSfiNpdlY+Q9JbWfmTku6s9gH064tH9GZmRRoGqyCpHlgKXAC0A2skrYyIjblqP4qIO7P6FwG3Awuybc9FREt1u11eIL8x1sysRCUj+jOALRGxNSI6gRXAxfkKEfFGbnU8NZwo94jezKxYJUE/DdieW2/PyopIukrSc8C3gWtym5olrZP0L5L+vNw3kHS5pDZJbR0dHUPofrHAl2LNzEpV7WJsRCyNiHcBXwX+Oit+ATgxIuYC1wE/knRkmbbLIqI1IlqnTp06on54RG9mVqySoN8BTM+tN2VlA1kBXAIQEfsiYme2vBZ4Djh5eF0dnO+6MTPrr5KgXwPMktQsaSywEFiZryBpVm71Y8DmrHxqdjEXSTOBWcDWanR8QL4aa2ZWZNC7biKiW9LVwP1APbA8IjZIWgK0RcRK4GpJ5wNdwGvA4qz5B4AlkrqAHuDKiHj1YBxIgUf0ZmalBg16gIhYBawqKbs5t/zlAdrdA9wzkg4OnUf0ZmZ5fmesmVnikgr6Ao/ozczykgp6R7yZWX9JBT3gtDczK5FU0Bfm6J30ZmZ5SQW9b680M+svsaD3IxDMzEolFfSOeDOz/pIKesCPQDAzK5FU0PsNU2Zm/SUV9OA5ejOzUkkFfTjmzcz6SSrowSN6M7NSyQW9r8WamRVLLuh9OdbMrFhSQe+7bszM+ksq6At6at0BM7NRJamg94jezKy/pIIe8HMQzMxKJBf0vr3SzKxYUkHvqRszs/6SCvoCj+jNzPKSCnqP6M3M+ksq6AG/NdbMrERFQS9pgaRNkrZIuqHM9islPSXpSUm/kTQ7t+3GrN0mSRdWs/OlPKI3M+tv0KCXVA8sBT4CzAYW5YM886OIOC0iWoBvA7dnbWcDC4E5wALgu9n+DiKP6M3M8ioZ0Z8BbImIrRHRCawALs5XiIg3cqvj+VPaXgysiIh9EfE8sCXbn5mZvU0aKqgzDdieW28HziytJOkq4DpgLPDBXNvHStpOK9P2cuBygBNPPLGSfg/I99GbmRWr2sXYiFgaEe8Cvgr89RDbLouI1ohonTp16vD7IMe8mVmpSoJ+BzA9t96UlQ1kBXDJMNuOnO+6MTMrUknQrwFmSWqWNJbCxdWV+QqSZuVWPwZszpZXAgslNUpqBmYBT4y82wPxXTdmZqUGnaOPiG5JVwP3A/XA8ojYIGkJ0BYRK4GrJZ0PdAGvAYuzthsk/QTYCHQDV0XE/oN0LL39PZi7NzM75FRyMZaIWAWsKim7Obf85QO0vRW4dbgdHApHvJlZf4m9M1Y47s3MiiUW9PhirJlZiaSCPpBz3sysRFJBL4GnbszMiiUV9IGc82ZmJZIK+gInvZlZXmJB70cgmJmVSizo8V03ZmYlkgr6QIieWnfDzGxUSSroe1SPwkFvZpaXVNAHctCbmZVIKuh7VOepGzOzEkkFfVDnEb2ZWYmkgr4wovddN2ZmeUkFPdRRd3Afd29mdshJKuh7qMPvjDUzK5ZU0IfqqPMcvZlZkeSC3nfdmJkVSyvokefozcxKJBb0vuvGzKxUUkHv2yvNzPpLKuiRb680MyuVVND79kozs/4qCnpJCyRtkrRF0g1ltl8naaOk9ZJ+Jemk3Lb9kp7MvlZWs/P9O+rbK83MSjUMVkFSPbAUuABoB9ZIWhkRG3PV1gGtEfGmpC8C3wb+U7btrYhoqXK/y+pRHQ2+vdLMrEglI/ozgC0RsTUiOoEVwMX5ChHxUES8ma0+BjRVt5uVCeqod9CbmRWpJOinAdtz6+1Z2UC+APwytz5OUpukxyRdUq6BpMuzOm0dHR0VdKk8v2HKzKy/QaduhkLSZ4FW4Nxc8UkRsUPSTODXkp6KiOfy7SJiGbAMoLW1dfhXUz1Hb2bWTyUj+h3A9Nx6U1ZWRNL5wE3ARRGxr7c8InZk/24FVgNzR9DfA+rxG6bMzPqpJOjXALMkNUsaCywEiu6ekTQX+B6FkH85V36UpMZs+RjgHCB/EbeqpHrk++jNzIoMOnUTEd2SrgbuB+qB5RGxQdISoC0iVgJ/C0wAfioJ4A8RcRHwbuB7knoo/FL5VsndOlWlunqP6M3MSlQ0Rx8Rq4BVJWU355bPH6Ddo8BpI+ngUKjOHyVoZlYqqXfGqq6OOjx1Y2aWl1TQR30jY+lmf4+nb8zMeqUV9A1HMI59dHZ7+sbMrFdSQd8z5giOoNNBb2aWk1TQM+YdjNF+9nXurXVPzMxGjeSCHqDzrT017oiZ2eiRVNBrrIPezKxUUkHfeMR4APbs3lXjnpiZjR5pBf2RxwKw9/WXatwTM7PRI6mgP+LoEwDo3vVijXtiZjZ6JBX0E44pPCa/Z7eD3sysV1JBP/6oY+mKerTHQW9m1iupoFddPa/UTWHsnn6PyzczO2wlFfQAr4ydxqS3tg9e0czsMJFc0O8ZfxLHdv+x1t0wMxs1kgv6rsnNTGIPe3cN/0PGzcxSklzQj5k6C4CXt22ocU/MzEaH5IL+mBnvAeC1bb+vcU/MzEaH5IL+xD+bwxvxDuKP62rdFTOzUSG5oG8c08CWhllMfs1TN2ZmkGDQA+ycNIdpnVuJzjdr3RUzs5pLMujrZn6AMXTz8voHa90VM7OaSzLom+ddwJvRyK6n7qt1V8zMai7NoD9uCmvqWzh2+z9Dd2etu2NmVlMVBb2kBZI2Sdoi6YYy26+TtFHSekm/knRSbttiSZuzr8XV7PwB+suLsxYxqed1dq+7++34lmZmo9agQS+pHlgKfASYDSySNLuk2jqgNSJOB+4Gvp21PRr4BnAmcAbwDUlHVa/7A5v3wU/ybM909j+4BHxR1swOY5WM6M8AtkTE1ojoBFYAF+crRMRDEdGbpo8BTdnyhcADEfFqRLwGPAAsqE7XD+zPjj2S+0+6jiP3vsjuFV/wFI6ZHbYqCfppQP5xkO1Z2UC+APxyKG0lXS6pTVJbR0f1nlGz8NOf4Tt1n2Pi1lXsvfOD8Owq6Npbtf2bmR0KGqq5M0mfBVqBc4fSLiKWAcsAWltbo1r9OfbIcVzwhSV8ZflUruv4e05YsYj9dY10H/Uu6o6eQcP4yahxEowZB6qHuvrs37rCv2Zmb6eJx0PLoqrvtpKg3wFMz603ZWVFJJ0P3AScGxH7cm3nl7RdPZyODtfpTZO54brrWfrAx3np9//M3M71vOvlPzKtYz1H6k0m6i0a6aKOHurpeTu7ZmZW5Plx76b5IAS9Ig48gJbUAPwr8CEKwb0G+ExEbMjVmUvhIuyCiNicKz8aWAu8Lyv6f8C8iHh1oO/X2toabW1twzuaQXR29/CvL+1m88u7eWV3Jzv/vZN93fvp2t9DV3fQtX8/PT37qaMH9fTQ+8rkX6H8yxX9FiCo2h8kZnaYOWnKeP7qo6cPq62ktRHRWm7boCP6iOiWdDVwP1APLI+IDZKWAG0RsRL4W2AC8FNJAH+IiIsi4lVJ36TwywFgyYFC/mAb21DHe6ZN4j3TJtWqC2Zmb7tBR/Rvt4M5ojczS9WBRvRJvjPWzMz+xEFvZpY4B72ZWeIc9GZmiXPQm5klzkFvZpY4B72ZWeJG3X30kjqAfxvBLo4BXqlSdw4Vh9sxH27HCz7mw8VIjvmkiJhabsOoC/qRktQ20JsGUnW4HfPhdrzgYz5cHKxj9tSNmVniHPRmZolLMeiX1boDNXC4HfPhdrzgYz5cHJRjTm6O3szMiqU4ojczsxwHvZlZ4pIJekkLJG2StEXSDbXuz0hImi7pIUkbJW2Q9OWs/GhJD0janP17VFYuSXdkx75e0vty+1qc1d8saXGtjqkSkuolrZP0i2y9WdLj2XHdJWlsVt6YrW/Jts/I7ePGrHyTpAtrcySVkTRZ0t2SnpX0jKSzDoNzfG32M/20pB9LGpfaeZa0XNLLkp7OlVXtvEqaJ+mprM0dyj7t6YAi4pD/ovDJV88BM4GxwO+B2bXu1wiO53jgfdnyRAof5Tgb+DZwQ1Z+A3BbtvxR4JeAgPcDj2flRwNbs3+PypaPqvXxHeC4rwN+BPwiW/8JsDBbvhP4Yrb8n4E7s+WFwF3Z8uzs3DcCzdnPRH2tj+sAx/sPwF9my2OBySmfY2Aa8DxwRO78XpbaeQY+QOHjU5/OlVXtvAJPZHWVtf3IoH2q9YtSpRf2LOD+3PqNwI217lcVj+9nwAXAJuD4rOx4YFO2/D1gUa7+pmz7IuB7ufKieqPpi8IHx/8K+CDwi+yH+BWgofQcU/hYy7Oy5YasnkrPe77eaPsCJmWhp5LylM/xNGB7Fl4N2Xm+MMXzDMwoCfqqnNds27O58qJ6A32lMnXT+wPUqz0rO+Rlf67OBR4Hjo2IF7JNLwLHZssDHf+h9Lr8d+B6oCdbnwK8HhHd2Xq+733HlW3fldU/lI63GegA/j6brvqBpPEkfI4jYgfw34A/AC9QOG9rSfs896rWeZ2WLZeWH1AqQZ8kSROAe4D/EhFv5LdF4dd5EvfGSvo48HJErK11X95GDRT+vP+fETEX+HcKf9L3SekcA2Tz0hdT+CV3AjAeWFDTTtVALc5rKkG/A5ieW2/Kyg5ZksZQCPn/ExH/mBW/JOn4bPvxwMtZ+UDHf6i8LucAF0naBqygMH3zd8BkSQ1ZnXzf+44r2z4J2Mmhc7xQGIm1R8Tj2frdFII/1XMMcD7wfER0REQX8I8Uzn3K57lXtc7rjmy5tPyAUgn6NcCs7Or9WAoXblbWuE/Dll1F/1/AMxFxe27TSqD36vtiCnP3veWfy67gvx/Ylf2ZeD/wYUlHZaOpD2dlo0pE3BgRTRExg8K5+3VEXAo8BHwqq1Z6vL2vw6ey+pGVL8zu1mgGZlG4cDXqRMSLwHZJp2RFHwI2kug5zvwBeL+kd2Q/473HnOx5zqnKec22vSHp/dlr+LncvgZW64sWVbz48VEKd6c8B9xU6/6M8Fj+I4U/7dYDT2ZfH6UwP/krYDPwIHB0Vl/A0uzYnwJac/v6PLAl+/qLWh9bBcc+nz/ddTOTwn/gLcBPgcasfFy2viXbPjPX/qbsddhEBXcj1PhYW4C27Dz/E4W7K5I+x8DfAM8CTwP/m8KdM0mdZ+DHFK5BdFH4y+0L1TyvQGv2+j0H/A9KLuiX+/IjEMzMEpfK1I2ZmQ3AQW9mljgHvZlZ4hz0ZmaJc9CbmSXOQW9mljgHvZlZ4v4/Fb6sr7kqoKMAAAAASUVORK5CYII=\n" - }, - "metadata": { - "needs_background": "light" - } - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Results\n", - "\n", - "Before viewing the results, we need to reverse the transformations applied on the output variable y.\n", - "\n", - "The `inverse_transform` method of the StandardScaler object will help us." - ], - "metadata": { - "id": "ldFMBPuvr0l0" - } - }, - { - "cell_type": "code", - "source": [ - "from sklearn.metrics import mean_squared_error\n", - "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", - "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", - "error = (((y_test - y_hat) ** 2).sum() / num_test )\n", - "print(\"Test Set Error\", error)" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ZycI4aExMsoC", - "outputId": "47c6b8fa-d1ee-4ff6-90d0-7e9289cfe40e" - }, - "execution_count": 7, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Test Set Error 0.5263803029005855\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Libraries\n", - "\n", - "Instead of coding everything from scratch, i.e the model, loss functions, and gradient calculations, there are many libaries that have implemented many machine learning algorithms for us.\n", - "\n", - "These libraries will generally be faster and more optimized. We can use the LinearRegression and SGD regressor module from scikit learn to compare our model" - ], - "metadata": { - "id": "UoYobRS9uBIv" - } - }, - { - "cell_type": "code", - "source": [ - "from sklearn.linear_model import SGDRegressor\n", - "\n", - "\n", - "x_train, x_test, y_train, y_test = dataset_copy\n", - "sgd = SGDRegressor()\n", - "sgd.fit(x_train.T, y_train)\n", - "y_hat = sgd.predict(x_test.T)\n", - "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", - "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", - "error = mean_squared_error(y_test, y_hat, squared = True)\n", - "print(\"Test Set Error\", error)" - ], - "metadata": { - "id": "txWBY_0eoNN_", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "7886b7e0-c383-4676-e825-3d7197d06d80" - }, - "execution_count": 8, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Test Set Error 0.5892243304217802\n" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "from sklearn.linear_model import LinearRegression as LR\n", - "\n", - "x_train, x_test, y_train, y_test = dataset_copy\n", - "lr = LR()\n", - "lr.fit(x_train.T, y_train)\n", - "y_hat = lr.predict(x_test.T)\n", - "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", - "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", - "error = mean_squared_error(y_test, y_hat, squared = True)\n", - "print(\"Test Set Error\", error)" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "9CaqphG8TG7V", - "outputId": "579bc8dd-6093-4155-8966-f8c60c34b1b3" - }, - "execution_count": 9, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Test Set Error 0.5263803029005857\n" - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/notebooks/linear_regression.ipynb b/notebooks/linear_regression.ipynb index 43c5fb2..861b52a 100644 --- a/notebooks/linear_regression.ipynb +++ b/notebooks/linear_regression.ipynb @@ -1,21660 +1,1376 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Linear Regression.ipynb", - "provenance": [], - "collapsed_sections": [], - "authorship_tag": "ABX9TyNRx6gNEqYURZyKqPxPjDA4", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, "cells": [ { "cell_type": "markdown", "metadata": { - "id": "view-in-github", - "colab_type": "text" + "colab_type": "text", + "id": "view-in-github" }, "source": [ - "\"Open" + "\"Open" ] }, { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "id": "ku4r-K4GQXEN" - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, "source": [ - "## Import the usual libraries\n", - "import torch\n", - "import torchvision\n", - "import torch.nn as nn\n", - "from torchvision import datasets, models, transforms\n", - "import os\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "from matplotlib.animation import FuncAnimation\n", - "from matplotlib import rc\n", - "rc('animation', html='html5')\n", - "\n", - "%matplotlib inline" + "# Linear Regression from Scratch" ] }, { - "cell_type": "code", - "source": [ - "def init():\n", - " pass\n", - " \n", - "def animate_2d(i):\n", - "\n", - " y_true = w[0] * x_plot + w[1] \n", - " w_pred = w_history[i]\n", - " y_pred = w_pred[0] * x_plot + w_pred[1] \n", - " ax.clear()\n", - " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", - " ax.plot(x_plot, y_true, label = \"Ground Truth\")\n", - " ax.plot(x_plot, y_pred, label = \"Fitted\")\n", - " ax.scatter(x_train[0], y_train)\n", - " ax.scatter(x_test[0], y_test)\n", - " ax.legend()\n", - "\n", - "def animate_3d(i):\n", - "\n", - " y_true = w[0] * xx + w[1] * yy + w[2]\n", - " w_pred = w_history[i]\n", - " y_pred = w_pred[0] * xx + w_pred[1] * yy + w_pred[2]\n", - "\n", - " ax.clear()\n", - " ax.azim = angles[i]\n", - " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", - " ax.plot_surface(xx, yy, y_true, alpha=0.5, label = \"Ground Truth\")\n", - " ax.plot_surface(xx, yy, y_pred, alpha=0.2, label = \"Fitted\")\n", - " ax.scatter(x_train[0], x_train[1], y_train.reshape(-1,1))\n", - " ax.scatter(x_test[0], x_test[1], y_test.reshape(-1,1))\n", - " # ax.legend()\n" - ], + "cell_type": "markdown", "metadata": { - "id": "CVX4Ra-0ErXc" + "id": "m41136O7L5bV" }, - "execution_count": 2, - "outputs": [] - }, - { - "cell_type": "code", "source": [ - "np.random.seed(30)" - ], - "metadata": { - "id": "gUtP_kHsYabX" - }, - "execution_count": 3, - "outputs": [] + "In this tutorial, we are going to implement a linear regression model to predict california housing prices. We will build the model from scratch using numpy. This will be a great approach to begin understanding regression based models.\n", + "\n", + "After completing this tutorial the learner is expected to know the basic building blocks of a linear regression model. The learner is also expected to know the pipeline of reading and transforming data for machine learning workflows.\n", + "\n" + ] }, { "cell_type": "code", - "source": [ - "class LinearRegression():\n", - " def __init__(self, dim, lr = 0.1):\n", - " assert isinstance\n", - " self.lr = lr\n", - " self.w = np.zeros((dim,1))\n", - " self.grads = {\"dw\": np.zeros((dim))}\n", - "\n", - " def forward(self, x):\n", - " y = self.w.T @ x\n", - " return y\n", - " \n", - " def backward(self, x, y_hat, y):\n", - " assert y_hat.shape == y.shape\n", - " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", - " assert self.grads[\"dw\"].shape == self.w.shape\n", - " \n", - " # print(self.grads[\"dw\"])\n", - "\n", - " def optimize(self):\n", - " self.w = self.w - self.lr * self.grads[\"dw\"]" - ], + "execution_count": 1, "metadata": { - "id": "j2Sj1PxsZ7hX" + "id": "Pni17h4R8v8a" }, - "execution_count": 4, - "outputs": [] + "outputs": [], + "source": [ + "## Import the usual libraries\n", + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn.datasets import fetch_california_housing\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.preprocessing import StandardScaler\n", + "import matplotlib.pyplot as plt" + ] }, { "cell_type": "markdown", - "source": [ - "### Data from the same distribution" - ], "metadata": { - "id": "zW-t5SBb3-ss" - } - }, - { - "cell_type": "code", + "id": "DjyJUfczL4zX" + }, "source": [ - "# Hyperparameters\n", - "num_samples = 50\n", - "num_train = int(0.7 * num_samples)\n", - "num_epochs = 30\n", - "\n", - "# Trying to fit the line y = Ax + B\n", - "w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", - "print(f\"A {w[0]}\")\n", - "print(f\"B {w[1]}\")\n", - "\n", - "# Generate training data\n", - "x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", - "ones = np.ones((num_samples, 1))\n", - "x_stack = np.hstack([x, ones])\n", - "\n", - "\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train \n", + "# Importing the dataset\n", "\n", + "The real-world dataset can be obtained by the function `fetch_california_housing` that downloads the dataset for us. \n", "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test\n", - "\n", - "\n", - "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = 2, lr = 0.5)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 2 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 560 - }, - "id": "71oppo-CZFZG", - "outputId": "3ed98eca-d057-4bad-a946-dd987669d9ef" - }, - "execution_count": 5, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "A [2.]\n", - "B [2.]\n", - "Epoch 0 | Train Loss 82.25494964307106 | Test Loss 12.530375379500228\n", - "Epoch 2 | Train Loss 17.376012504579442 | Test Loss 3.154638242567267\n", - "Epoch 4 | Train Loss 6.956327722693647 | Test Loss 1.2692928110230237\n", - "Epoch 6 | Train Loss 3.224882117013539 | Test Loss 0.5785176772257331\n", - "Epoch 8 | Train Loss 1.5261102992342335 | Test Loss 0.27142397409351354\n", - "Epoch 10 | Train Loss 0.724097788298985 | Test Loss 0.12834980491917516\n", - "Epoch 12 | Train Loss 0.34367807531591266 | Test Loss 0.060843440641133104\n", - "Epoch 14 | Train Loss 0.1631264675584223 | Test Loss 0.028866509791083687\n", - "Epoch 16 | Train Loss 0.07742822365786244 | Test Loss 0.013699376650671533\n", - "Epoch 18 | Train Loss 0.03675144705394587 | Test Loss 0.00650207098681876\n", - "Epoch 20 | Train Loss 0.01744414255609919 | Test Loss 0.003086158976244471\n", - "Epoch 22 | Train Loss 0.008279894726455541 | Test Loss 0.0014648408256308387\n", - "Epoch 24 | Train Loss 0.003930067445239355 | Test Loss 0.0006952876964168519\n", - "Epoch 26 | Train Loss 0.0018654138291502296 | Test Loss 0.00033001930877197806\n", - "Epoch 28 | Train Loss 0.0008854221467041258 | Test Loss 0.00015664423038941943\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } - } + "The `as_frame` parameter returns a pandas dataframe which is a library useful for viewing contents of the data.\n", + "\n" ] }, { "cell_type": "code", - "source": [ - "x_plot = np.linspace(-1,1,10)\n", - "fig = plt.figure()\n", - "ax = plt.subplot()\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], + "execution_count": 2, "metadata": { - "id": "9wCVKa6-uJdU", "colab": { "base_uri": "https://localhost:8080/", - "height": 310 + "height": 206 }, - "outputId": "7cc9b496-0dcf-4a27-fca0-6ced838ed6d7" + "id": "aOXxbywahC5X", + "outputId": "24521e0a-6f1a-4e5c-c35d-3abb8112a9af" }, - "execution_count": 6, "outputs": [ { - "output_type": "execute_result", "data": { - "text/plain": [ - "" - ], "text/html": [ - "" + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
08.325241.06.9841271.023810322.02.55555637.88-122.234.526
18.301421.06.2381370.9718802401.02.10984237.86-122.223.585
27.257452.08.2881361.073446496.02.80226037.85-122.243.521
35.643152.05.8173521.073059558.02.54794537.85-122.253.413
43.846252.06.2818531.081081565.02.18146737.85-122.253.422
\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n", + " " + ], + "text/plain": [ + " MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude \\\n", + "0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 \n", + "1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 \n", + "2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 \n", + "3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 \n", + "4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 \n", + "\n", + " Longitude MedHouseVal \n", + "0 -122.23 4.526 \n", + "1 -122.22 3.585 \n", + "2 -122.24 3.521 \n", + "3 -122.25 3.413 \n", + "4 -122.25 3.422 " ] }, + "execution_count": 2, "metadata": {}, - "execution_count": 6 + "output_type": "execute_result" } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### Solved using Least Squares and compare to SGD" ], - "metadata": { - "id": "wK8HgWc54MbV" - } - }, - { - "cell_type": "code", "source": [ - "W = np.linalg.inv(x_train @ x_train.T) @ x_train @ (y_train.T)\n", + "# Fetch the data using sklearn function\n", + "bunch = fetch_california_housing(download_if_missing=True, as_frame=True)\n", "\n", - "print(W)\n", - "print(model.w)" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "4tusHihBdDCS", - "outputId": "2cdfd51a-c1b3-41fe-c28c-c7e0f7fb9852" - }, - "execution_count": 7, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[[2.]\n", - " [2.]]\n", - "[[1.9916692 ]\n", - " [1.99888494]]\n" - ] - } + "# Load the dataframe and view\n", + "df = bunch.frame\n", + "df.head()" ] }, { "cell_type": "markdown", - "source": [ - "### Data from different distribution (Overfitting)" - ], "metadata": { - "id": "z3O-ugF74jgk" - } - }, - { - "cell_type": "code", + "id": "KUeU_jLylTx7" + }, "source": [ + "For this dataset, our target variable is the median house value for California districts, expressed in hundreds of thousands of dollars ($100,000).\n", "\n", - "# Should we generate new data or use the old data for comparison?\n", - "\n", - "# # Hyperparameters\n", - "# num_samples = 100\n", - "# num_train = int(0.7 * num_samples)\n", - "# num_epochs = 100\n", - "\n", - "# # Trying to fit the line y = Ax + B\n", - "# w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", - "# print(f\"A {w[0]}\")\n", - "# print(f\"B {w[1]}\")\n", - "\n", - "# # Generate training data\n", - "# x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", - "# ones = np.ones((num_samples, 1))\n", - "# x_stack = np.hstack([x, ones])\n", - "\n", - "# Add noise to both train and test\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train + np.random.normal(loc = 0, scale = 0.1, size = num_train)\n", - "\n", - "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.6, size = num_samples - num_train)\n", - "\n", - "\n", - "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = 2, lr = 0.5)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 2 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 525 - }, - "id": "GMjA2oY-4Lf8", - "outputId": "6fd28364-4637-4223-972b-668d47f9fe12" - }, - "execution_count": 8, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Epoch 0 | Train Loss 81.91031959207034 | Test Loss 15.206417713180077\n", - "Epoch 2 | Train Loss 17.7634895164587 | Test Loss 5.820509127604954\n", - "Epoch 4 | Train Loss 7.245263046946594 | Test Loss 3.9453099633235054\n", - "Epoch 6 | Train Loss 3.44046248665259 | Test Loss 3.281546224113068\n", - "Epoch 8 | Train Loss 1.7052884307321203 | Test Loss 3.0001380259751276\n", - "Epoch 10 | Train Loss 0.8859031197203339 | Test Loss 2.877207877496019\n", - "Epoch 12 | Train Loss 0.4972317484039249 | Test Loss 2.8245002955637446\n", - "Epoch 14 | Train Loss 0.31276314034526653 | Test Loss 2.8030958469957525\n", - "Epoch 16 | Train Loss 0.2252056649766091 | Test Loss 2.7953767630098296\n", - "Epoch 18 | Train Loss 0.18364639950425643 | Test Loss 2.793385095401474\n", - "Epoch 20 | Train Loss 0.16392021995116995 | Test Loss 2.793589996259956\n", - "Epoch 22 | Train Loss 0.15455715229253905 | Test Loss 2.7944793446513407\n", - "Epoch 24 | Train Loss 0.15011295480911402 | Test Loss 2.7954471081023726\n", - "Epoch 26 | Train Loss 0.14800350820084965 | Test Loss 2.7962823550385014\n", - "Epoch 28 | Train Loss 0.14700225544127865 | Test Loss 2.7969377763062377\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3Rc5X3u8e9vRjdbkm+SfMfYYIMxGORYgWAg3AOBEMw5IYVFWufSGlIaUnJSIKRJSNu0JCspDV0lqVMo7mmaQADXkBAaQvCxucQgGwM2htgYA/JVyFiWbOs6v/PH3iPLQrZG0oxGe+b5rKW1rzP73Rr7ma13v+9+zd0REZHoimW7ACIiMjgKchGRiFOQi4hEnIJcRCTiFOQiIhFXMJQHq6ys9OnTpw/lIUVEIm/NmjXvuXvVkbYPaZBPnz6d2traoTykiEjkmdnbR9uuqhURkYhTkIuIRJyCXEQk4oa0jlxE8k97ezt1dXW0tLRkuyjDXklJCVOnTqWwsLBfr1OQi0hG1dXVUV5ezvTp0zGzbBdn2HJ3GhoaqKurY8aMGf16rapWRCSjWlpaqKioUIj3wcyoqKgY0F8uCnIRyTiFeGoG+nuKRJD/90vb+M/fH7UZpYhI3opEkP/q1R0KchEZkIaGBqqrq6murmbixIlMmTKla7mtre2or62treWmm27q8xgLFixIV3EHJBI3OyvLinnpnfezXQwRiaCKigrWrVsHwB133EFZWRlf/epXu7Z3dHRQUNB7FNbU1FBTU9PnMZ577rn0FHaAUroiN7ObzWyDma03s5+ZWYmZzTCz1Wa22cweMLOiTBWyqqyIPfvb6ExoNCMRGbzPfvaz3HDDDZxxxhnccsstvPDCC5x55pnMmzePBQsW8MYbbwCwYsUKPvGJTwDBl8DnP/95zjvvPI477jjuvvvurvcrKyvr2v+8887jU5/6FLNnz+a6664jOQrb448/zuzZs5k/fz433XRT1/umQ59X5GY2BbgJmOPuB83sQeAa4DLgLnf/uZn9GPgC8KO0laybyvJiEg579rdRVV6ciUOIyBD49mMbeG37vrS+55zJo/jWFSf3+3V1dXU899xzxONx9u3bx6pVqygoKOC3v/0tt99+Ow8//PAHXvP666/z9NNP09TUxIknnsgXv/jFD7T5fumll9iwYQOTJ0/mrLPO4tlnn6Wmpobrr7+elStXMmPGDK699toBn29vUq0jLwBGmFkBMBLYAVwAPBRuXwosTGvJuqksC8L7vebWTB1CRPLM1VdfTTweB6CxsZGrr76aU045hZtvvpkNGzb0+prLL7+c4uJiKisrGT9+PLt27frAPqeffjpTp04lFotRXV3N1q1bef311znuuOO62oenO8j7vCJ3921m9n3gHeAg8BtgDbDX3TvC3eqAKb293swWA4sBpk2bNqBCKshFcsNArpwzpbS0tGv+G9/4Bueffz7Lli1j69atnHfeeb2+prj4UI1APB6no6NjQPukW59X5GY2FrgSmAFMBkqBS1M9gLsvcfcad6+pqjri43SPqrIsqH5XkItIJjQ2NjJlSnAtev/996f9/U888US2bNnC1q1bAXjggQfS+v6pVK1cBLzl7vXu3g48ApwFjAmrWgCmAtvSWrJuKsN68feajt5USERkIG655Ra+9rWvMW/evIxcQY8YMYJ77rmHSy+9lPnz51NeXs7o0aPT9v6WvKN6xB3MzgDuAz5MULVyP1ALfBR4uNvNzlfc/Z6jvVdNTY0PZGAJd+fEbzzB5xZM52uXndTv14tI9mzcuJGTTtL/2+bmZsrKynB3brzxRmbNmsXNN9/8gf16+32Z2Rp3P2I7yD6vyN19NcFNzbXAq+FrlgC3Al8xs81ABXBvP86pX8yMqrJi6lW1IiIR9ZOf/ITq6mpOPvlkGhsbuf7669P23il1CHL3bwHf6rF6C3B62krSh8ryYuqbFOQiEk0333xzr1fg6RCJLvoQdAp6r1l15CIiPUUmyCvLitVqRUSkF5EK8j3720iom76IyGEiFORFdCac9w+oekVEpLtIPP0QurUlb26jokzPWxGR1DQ0NHDhhRcCsHPnTuLxOMnOiS+88AJFRUd/3t+KFSsoKirK+qNqjyY6Qd6tm/6JlGe5NCISFX09xrYvK1asoKysbFgHeYSqVvS8FRFJjzVr1nDuuecyf/58LrnkEnbs2AHA3XffzZw5czj11FO55ppr2Lp1Kz/+8Y+56667qK6uZtWqVVkuee8ic0VeFQa52pKLRNivb4Odr6b3PSfOhY/fmfLu7s6XvvQlli9fTlVVFQ888ABf//rXue+++7jzzjt56623KC4uZu/evYwZM4Ybbrih31fxQy0yQT5qRAFF8ZjakovIoLS2trJ+/XouvvhiADo7O5k0aRIAp556Ktdddx0LFy5k4cKMPZk77SIT5GZGRVmRqlZEoqwfV86Z4u6cfPLJPP/88x/Y9qtf/YqVK1fy2GOP8Z3vfIdXX03zXw8ZEpk6clCnIBEZvOLiYurr67uCvL29nQ0bNpBIJHj33Xc5//zz+e53v0tjYyPNzc2Ul5fT1NSU5VIfXcSCvEh15CIyKLFYjIceeohbb72V0047jerqap577jk6Ozv5zGc+w9y5c5k3bx433XQTY8aM4YorrmDZsmW62ZkuVeXFvLYjveP9iUj+uOOOO7rmV65c+YHtzzzzzAfWnXDCCbzyyiuZLNagReyKvJiGZnXTFxHpLnJB3pFwGg+2Z7soIiLDRipjdp5oZuu6/ewzs780s3Fm9qSZbQqnYzNd2EPd9FVPLhIlfY1EJoGB/p5SGSHoDXevdvdqYD5wAFgG3AY85e6zgKfC5YxKDsKskYJEoqOkpISGhgaFeR/cnYaGBkpKSvr92v7e7LwQeNPd3zazK4HzwvVLgRUEw79lTFXZoQdniUg0TJ06lbq6Ourr67NdlGGvpKSEqVOn9vt1/Q3ya4CfhfMT3H1HOL8TmNDbC8xsMbAYYNq0af0uYHddz1tRE0SRyCgsLGTGjBnZLkZOS/lmp5kVAZ8EftFzmwd/M/X6d5O7L3H3GnevST46cqBGjyikIGaqIxcR6aY/rVY+Dqx1913h8i4zmwQQTnenu3A9xWLqpi8i0lN/gvxaDlWrADwKLArnFwHL01Woowm66auOXEQkKaUgN7NS4GLgkW6r7wQuNrNNwEXhcsZVlhWrm76ISDcp3ex09/1ARY91DQStWIZUZVkxf9g1vB9gIyIylCLVsxOC5600NLepTaqISChyQV5ZVkRbZ4J9BzuyXRQRkWEhckFeFXbTV+9OEZFA5IJcgzCLiBxOQS4iEnERDPLgwVnqpi8iEohckI8dWUQ8ZuoUJCISilyQx2LGuFJ10xcRSYpckEOym76CXEQEIhvkReqmLyISimSQV+nBWSIiXSIZ5JXlxdQ3t6qbvogIEQ3yqrJi2joSNLWqm76ISCSDvLJcbclFRJKiGeQahFlEpEuqA0uMMbOHzOx1M9toZmea2Tgze9LMNoXTsZkubJK66YuIHJLqFfkPgSfcfTZwGrARuA14yt1nAU+Fy0NCQS4ickifQW5mo4GPAvcCuHubu+8FrgSWhrstBRZmqpA9jSstImaqIxcRgdSuyGcA9cC/m9lLZvZv4RieE9x9R7jPTmBCby82s8VmVmtmtfX19WkpdDzspl+vOnIRkZSCvAD4EPAjd58H7KdHNYoHDbp7bdTt7kvcvcbda6qqqgZb3i7qpi8iEkglyOuAOndfHS4/RBDsu8xsEkA43Z2ZIvZOQS4iEugzyN19J/CumZ0YrroQeA14FFgUrlsELM9ICY9Az1sREQkUpLjfl4CfmlkRsAX4HMGXwINm9gXgbeDTmSli75JX5O6OmQ3loUVEhpWUgtzd1wE1vWy6ML3FSV1leTEt7Qn2t3VSVpzq95GISO6JZM9OCJ63AmqCKCIS2SCvLFenIBERiHKQJwdhVpCLSJ6LbJAnq1bUKUhE8l1kg3xcaRGmbvoiItEN8oJ4jLEji1S1IiJ5L7JBDkE9uYJcRPJdxINcgzCLiEQ+yNVNX0TyXeSDXFUrIpLvoh3k5UUcaOvkQFtHtosiIpI10Q7yrm76qicXkfwV6SCvKk92ClL1iojkr2gHuQZhFhGJdpBXKshFRFJ7HrmZbQWagE6gw91rzGwc8AAwHdgKfNrd389MMXtXkXxwlurIRSSP9eeK/Hx3r3b35AATtwFPufss4Cl6DMg8FArjMcaMLNQVuYjktcFUrVwJLA3nlwILB1+c/lNbchHJd6kGuQO/MbM1ZrY4XDfB3XeE8zuBCb290MwWm1mtmdXW19cPsrgfpOetiEi+SzXIz3b3DwEfB240s4923+juThD2H+DuS9y9xt1rqqqqBlfaXuh5KyKS71IKcnffFk53A8uA04FdZjYJIJzuzlQhj0bPWxGRfNdnkJtZqZmVJ+eBjwHrgUeBReFui4DlmSrk0VSVF9Pc2kFLe2c2Di8iknWpND+cACwzs+T+/+XuT5jZi8CDZvYF4G3g05kr5pElx+6sb2rlmHEjs1EEEZGs6jPI3X0LcFov6xuACzNRqP7o3ilIQS4i+SjSPTvh0PNWdMNTRPJV5INc3fRFJN9FPsgPddNXkItIfop8kBcXxBlVUqArchHJW5EPcoDKcnUKEpH8lRtBXlaswSVEJG/lRJBX6cFZIpLHciLIK8uK1E1fRPJWjgR5MU0t6qYvIvkpN4I87BTUsF83PEUk/+RGkCc7Bal6RUTyUI4EedgpSDc8RSQP5USQH3reioJcRPJPTgT5oeetqI5cRPJPTgR5SWGc8uICNUEUkbyUcpCbWdzMXjKzX4bLM8xstZltNrMHzKwoc8XsW9BNX0EuIvmnP1fkXwY2dlv+LnCXu88E3ge+kM6C9VdlWZGCXETyUkpBbmZTgcuBfwuXDbgAeCjcZSmwMBMFTFVlmR6cJSL5KdUr8n8CbgES4XIFsNfdO8LlOmBKmsvWL5V63oqI5Kk+g9zMPgHsdvc1AzmAmS02s1ozq62vrx/IW6SksqyYvQfaaetI9L2ziEgOSeWK/Czgk2a2Ffg5QZXKD4ExZpYcvHkqsK23F7v7EnevcfeaqqqqNBS5d5Xlwb3Whv26KheR/NJnkLv719x9qrtPB64Bfufu1wFPA58Kd1sELM9YKVNwqJu+6slFJL8Mph35rcBXzGwzQZ35vekp0sBoEGYRyVcFfe9yiLuvAFaE81uA09NfpIGpCoNcIwWJSL7JiZ6dcKiOXFfkIpJvcibIRxYVUFoUVx25iOSdnAlyUDd9EclPuRXk6hQkInkox4Jcz1sRkfyTY0Gu562ISP7JuSDfs7+N9k510xeR/JFbQR4O+bZnv67KRSR/5FSQV4WDMGukIBHJJ7kV5OUlAOxobMlySUREhk5OBfmcSaMoisdYvaUh20URERkyORXkI4rifHjGWJ7Z/F62iyIiMmRyKsgBzp5Zxes7m9i9T9UrIpIfci7Iz5lVCaCrchHJGzkX5HMmjaKitIhnNinIRSQ/5FyQx2LGgpmVrNr8Hu6e7eKIiGRcKoMvl5jZC2b2spltMLNvh+tnmNlqM9tsZg+YWVHmi5uac2ZVUt/Uyhu7mrJdFBGRjEvlirwVuMDdTwOqgUvN7CPAd4G73H0m8D7whcwVs3+S9eSr/qDqFRHJfakMvuzu3hwuFoY/DlwAPBSuXwoszEgJB2DS6BHMHF/GKt3wFJE8kFIduZnFzWwdsBt4EngT2OvuHeEudcCUI7x2sZnVmlltfX19OsqckrNnVrJ6SwMt7Z1DdkwRkWxIKcjdvdPdq4GpBAMuz071AO6+xN1r3L2mqqpqgMXsv4+eUElrR4I1b78/ZMcUEcmGfrVacfe9wNPAmcAYMysIN00FtqW5bINyxowKCuPGKjVDFJEcl0qrlSozGxPOjwAuBjYSBPqnwt0WAcszVciBKC0uYN60sazaNHTVOSIi2ZDKFfkk4GkzewV4EXjS3X8J3Ap8xcw2AxXAvZkr5sB8dFYlG7bvo0HDv4lIDkul1cor7j7P3U9191Pc/W/C9Vvc/XR3n+nuV7v7sEvLs2cFdfLqri8iuSznenZ2N3fKaEaPKFR3fRHJaTkd5PGYcdbMClZtUnd9EcldOR3kAOfMqmLnvhberG/ue2cRkQjK+SA/e2bYXV/VKyKSo3I+yI8ZN5LpFSMV5CKSs3I+yCGoXvn9lgbaOhLZLoqISNrlRZCfPauSA22drH1H3fVFJPfkRZCfeXwF8ZipGaKI5KS8CPJRJYVUHzNG3fVFJCflRZBDMNjEK9sa2XugLdtFERFJq7wKcnd4dnNDtosiIpJWeRPkp00dQ3lxAc9sVvWKiOSWvAnygniMM4+vYOUf1F1fRHJL3gQ5BNUr2/YeZGvDgWwXRUQkbfIsyMPH2qr1iojkkFRGCDrGzJ42s9fMbIOZfTlcP87MnjSzTeF0bOaLOzjHVoxk6tgRrFR7chHJIalckXcA/8fd5wAfAW40sznAbcBT7j4LeCpcHtbMLOiu/2YD7Z3qri8iuSGVEYJ2uPvacL6JYLzOKcCVwNJwt6XAwkwVMp3OmVVJU2sHL7+7N9tFERFJi37VkZvZdGAesBqY4O47wk07gQlHeM1iM6s1s9r6+uzXTS84vgIzPdZWRHJHykFuZmXAw8Bfuvu+7ts8aM/Xa5s+d1/i7jXuXlNVVTWowqbDmJFFnDp1jMbxFJGckVKQm1khQYj/1N0fCVfvMrNJ4fZJwO7MFDH9zplZybp397KvpT3bRRERGbRUWq0YcC+w0d3/sdumR4FF4fwiYHn6i5cZ58yqpDPhPP+muuuLSPSlckV+FvDHwAVmti78uQy4E7jYzDYBF4XLkTBv2lhGFsX1NEQRyQkFfe3g7s8AdoTNF6a3OEOjqCDGuSdUsXzddm66YBbjR5Vku0giIgOWVz07u7vl0tm0diS447EN2S6KiMig5G2Qz6gs5csXzuLxV3fy5Gu7sl0cEZEBy9sgB1j80eOYPbGcby5fT5NasIhIROV1kBfGY/zD/5rLzn0tfP9/3sh2cUREBiQaQb5vB9Stychbz5s2lkVnTuc/fv82a995PyPHEBHJpGgE+S8WwYN/Aq1NGXn7r15yIhNHlfC1h1+lrUMP0xKRaIlGkF/8t7BvG/zu7zLy9mXFBfztlafwxq4mlqx8MyPHEBHJlGgE+bQz4MN/Cqv/Fd59MSOHuGjOBC6fO4m7f7eZLfXNGTmGiEgmRCPIAS78JpRPgsdugo62jBziW1fMobggxu3LXtW4niISGdEJ8pJRcPkPYPdr8NwPM3KI8aNKuP2yk/j9lj08WPtuRo4hIpJu0QlygNmXwZyF8P++B+9tysgh/qjmGE6fMY7v/Goj9U2tGTmGiEg6RSvIAT7+PSgcAY99GRLpb2ESixl/f9VcWtoTfFvd90UkAqIX5OUT4GN/B28/C2uX9r3/AMwcX8ZfXDCTX76yg9+9ru77IjK8RS/IAeb9MUw/B578VtBZKANuOPd4Zo0v46+XrWd/a0dGjiEikg7RDHIzuOKH0NECv/6rjByiqCDGnf97LtsbW/j+b9R9X0SGr1RGCLrPzHab2fpu68aZ2ZNmtimcjs1sMXtRcTycdxtsfAw2/jIjh5h/7Dg+85Fp3P/cVn79amau/EVEBiuVK/L7gUt7rLsNeMrdZwFPhctDb8GXYMJcePyr0NKYkUPceulsqo8Zwxd/upZ7VmxW+3IRGXb6DHJ3Xwns6bH6SiB5p3EpsDDN5UpNvBA++UNo3gW/vSMjhygvKeRnf/YRrjhtMt974g1ueegVPY9FRIaVgdaRT3D3ZF3DTmDCkXY0s8VmVmtmtfX1GRgjc8p8OOOLUHsfvP18+t8fKCmMc/c11dx04Sx+saaOP7lvNXsPZKZ3qYhIfw36ZqcHdQ1HrG9w9yXuXuPuNVVVVYM9XO8u+DqMmRZ2389MJx4z4ysXn8Bdf3Qaa9/ey1X3PMdb7+3PyLFERPpjoEG+y8wmAYTT3ekr0gAUlcIn7oL3/gCrfpDRQ101byo//bMzaDzYzlX3PMvvtzRk9HgiIn0ZaJA/CiwK5xcBy9NTnEGYeRGc+kew6h/h5QcggzclPzx9HMv+fAEVpUX88b2r+YWeyyIiWZRK88OfAc8DJ5pZnZl9AbgTuNjMNgEXhcvZd8k/wKRTYdli+PfLYOf6vl8zQMdWlPLIn5/F6TPG8VcPvcL3nnidREItWkRk6NlQNqerqanx2trazB4kkYCX/m/QiqVlL3z4z+D822HEmIwcrr0zwTeXb+BnL7zDZXMn8oOrqxlRFM/IsUQkP5nZGnevOdL2aPbsPJpYDOYvgi+tgZrPw4s/gX+eDy/9Z0YeslUYj/H3V53CX19+Er9ev5NP/PMqnli/Q+3NRWTI5F6QJ40cFzy/fPEKGHccLL8R7vsYbF+X9kOZGX96znHc/7nTAbjhP9ey8F+e5dnN76X9WCIiPeVe1UpvEgl45efw5Ddh/3tQ8zm44BtB2KdZR2eCR9Zu459++we2N7Zw1swK/uqSoHeoiMhA9FW1kh9BnnRwL6y4E15YAiWjgy7+J1wC4+cED+JKo5b2Tn66+h3+5enN7NnfxsfmTOCrl5zICRPK03ocEcl9CvLe7FwPT9wGW1cFy+WT4PgLYeYFcNz5ab1Sb27t4N5Vb/GTVVvY39bBVfOmcPNFJ3DMuJFpO4aI5DYF+dE01sGbv4PNT8GWp4MHb1kMJn8IZl4YhPuU+RAvGPSh9uxv40crNrP0+bdxd649fRqf+cixukIXkT4pyFPV2QHb1wah/uZTsG0NeCKogplxLkw4BSpnQuUJMO54KBrYFfWOxoPc/dQmHqytozPhzJ5YzierJ3PFqZN1lS4ivVKQD9SBPbBlRRDqb62CvW8fvn30MVA5CypmBdPk/KjJKdW31ze18qtXtvPoy9tZ+85eAOYfO5Yrqydz2dxJVJYVZ+CkRCSKFOTp0nYA9rwJ722Chs3Bc12S823Nh/aLFULZBCirCqfjw2n3+fFQOj54RowZ7+45wKMvb+exl7fz+s4m4jFjwfEVXFk9hUtOnkB5SWH2zltEsk5Bnmnu0LQzCPaGTUG9e/Pu4BnpzbuC+f31QTVNT7ECKB4FJaPC6WiaGMnb+wvY+D5sbynigJUxsaqSqRPGMWNiFdMmVlBUUgaFI6BgRDAtHBlOR0BMvUpFck1fQT74u3j5zgxGTQp+jju3930SnXCg4fBwb94d3Fxt3Qct+8JpI+UtdZzSto+T441Q0IThwbAee4CNKZQnVgDxouCnoLjHfCHEi4P5WEGwHCsIwj+WnA+X492WLRass3iPac/1sW4/FkyxHuvDbV3r7dDvsWv/XrZ3X5/cv2tdcjs99qXH/j23cfg+h+3Xy7aj6Vfz1TS/Z2R6EUeknJn6fU6eN+B7a31RkA+FWDysVhkPzE3pJQZBR6a2Jmjbz/uNjWx8ZxdvvLuLLdvr2dnwPsXeykhrZfqoGDPHxTl2lFE1AkYXQTzRFjybvbMdOlt7zLcFA1cnOoKfzo5D8z1/OjvAO4Mvo+Q0Kv8hRYaTG1+EqhMy8tYK8uEsFgtazZSMZuyoySw45iQWhJv2t3aw7t29vPDWHp7Zuod/fmcvB9s7ASiIGTMqS5k5voxZ48uYOaGcmVVlHFdVSklhGqpe3A8P9q5pWH3kiR4//sF1yffxBODhVZAf2j85n9yvax/C+XDafXuv80fYr/u5HFo4yraj/kJS3C9D7wmkfJWfbWnueJc5GSjn6Cnpf8+QgjyiSosLOGtmJWfNrASCpzC+vqOJTbub2LS7mc27m3l9ZxP/s2EnyafrxgyOGTeSWePLOLailEmjS5g8ZgQTR5cwefQIqsqLicdS+AdsFrat1z8fkeFA/xNzRGE8xtypo5k7dfRh61vaO9nasJ/Nu5vZtKuZzfXNbN7VzLObG7qu4JPiMWNCeTETR5cwacwIJo8uYcKoEirLihkzspBxpUWMHVnE2NIiSoviWGSurkRy26CC3MwuBX4IxIF/c/fhMcCEdCkpjDN74ihmTxx12Hp3p/FgOzsaW9jReDCY7m1he+NBdja28Nr2ffz2tV20dvT+6N+ieIyxpYVBsI8sYlxpEaNGFFJWHKesuJDS4jjlJQW9zpcVF1BSGKe4IKYvA5E0GHCQm1kc+BfgYqAOeNHMHnX319JVOMkcM2PMyCLGjCzipEmjet0nGfZ79rfx/oE23t/fzp4Dbby/v409B9rY221548597DvYQXNrOy3tqT333QxKCuKUFMYYURgPwr0wzojCGCXJ5YIYRQUxCuPBtCgeozBuvayLURA3CmJGQSw5HyMeMwrjFk6D5YKYEYsZcQvWx8JpPEbX/KF1hlmwPvgJfnexbuuS27um4bnpS0qGymCuyE8HNrv7FgAz+zlwJaAgzxHdw74/OjoT7G/tpLmtg+aWDppbg5/9rYeWD7Z30treSUtHgoNtnbS0d3KwvZOW9gQt7cFy48F22joStHcmaOtI0NbptHV00t7ptHcm6IjA0HrJ4DeCkE+2kgxmLZwe2ie5PRazrtttXdtI3iu0rvnD1wfvefjyoffoTffVPXexbjf8Prit++tS/8JKec9+fAemumu2v1jvW/RhplUMv+aHU4Duow7XAWf03MnMFgOLAaZNmzaIw0lUFMRjjB4ZY/TIzPZI7UwEgd7WmaC9IxEsJ5zOTqc9kejaHkydzoTTEX4BdLqTSATrEu50JjhsXXI+4ZBwx/3QfMIJl4P5zkSw3cPGNInkvPvhy+F8stFN99cEU+9q1JIIZ5LrD83TNU+39YdNe67n8O1J3r1lzAe2dZvv8cLDtx3p0/mglNvr9ONNU95zGHznFxVkbhyfjN/sdPclwBIIenZm+niSP4Kqj3h6mlSKRNhgviK2Acd0W54arhMRkSE0mCB/EZhlZjPMrAi4Bng0PcUSEZFUDbhqxd07zOwvgP8haH54n7tvSFvJREQkJYOqI3f3x4HH01QWEREZgMzdRhURkSGhIBcRiTgFuYhIxCnIRUQibkiHejOzeuDtPnfsXSXwXhqLM+kjEckAAAOkSURBVBzk2jnpfIa/XDunXDsf6P2cjnX3qiO9YEiDfDDMrPZoY9ZFUa6dk85n+Mu1c8q184GBnZOqVkREIk5BLiIScVEK8iXZLkAG5No56XyGv1w7p1w7HxjAOUWmjlxERHoXpStyERHphYJcRCTiIhHkZnapmb1hZpvN7LZsl2ewzGyrmb1qZuvMrDbb5RkIM7vPzHab2fpu68aZ2ZNmtimcjs1mGfvjCOdzh5ltCz+ndWZ2WTbL2B9mdoyZPW1mr5nZBjP7crg+yp/Rkc4pkp+TmZWY2Qtm9nJ4Pt8O188ws9Vh3j0QPib86O813OvIw0Ge/0C3QZ6Ba6M8yLOZbQVq3D2yHRnM7KNAM/Af7n5KuO57wB53vzP8wh3r7rdms5ypOsL53AE0u/v3s1m2gTCzScAkd19rZuXAGmAh8Fmi+xkd6Zw+TQQ/JwsGES1192YzKwSeAb4MfAV4xN1/bmY/Bl529x8d7b2icEXeNcizu7cByUGeJYvcfSWwp8fqK4Gl4fxSgv9kkXCE84ksd9/h7mvD+SZgI8E4u1H+jI50TpHkgeZwsTD8ceAC4KFwfUqfURSCvLdBniP74YUc+I2ZrQkHp84VE9x9Rzi/E5iQzcKkyV+Y2Sth1UtkqiG6M7PpwDxgNTnyGfU4J4jo52RmcTNbB+wGngTeBPa6e0e4S0p5F4Ugz0Vnu/uHgI8DN4Z/1ucUD+rshne9Xd9+BBwPVAM7gB9ktzj9Z2ZlwMPAX7r7vu7bovoZ9XJOkf2c3L3T3asJxjw+HZg9kPeJQpDn3CDP7r4tnO4GlhF8gLlgV1iPmazP3J3l8gyKu+8K/6MlgJ8Qsc8prHd9GPipuz8Sro70Z9TbOUX9cwJw973A08CZwBgzS47ellLeRSHIc2qQZzMrDW/UYGalwMeA9Ud/VWQ8CiwK5xcBy7NYlkFLBl7oKiL0OYU30u4FNrr7P3bbFNnP6EjnFNXPycyqzGxMOD+CoEHHRoJA/1S4W0qf0bBvtQIQNif6Jw4N8vydLBdpwMzsOIKrcAjGTP2vKJ6Pmf0MOI/gkZu7gG8B/w08CEwjeFzxp909EjcQj3A+5xH8ue7AVuD6bvXLw5qZnQ2sAl4FEuHq2wnqlKP6GR3pnK4lgp+TmZ1KcDMzTnBR/aC7/02YET8HxgEvAZ9x99ajvlcUglxERI4sClUrIiJyFApyEZGIU5CLiEScglxEJOIU5CIiEacgFxGJOAW5iEjE/X80EuHQxC2BUwAAAABJRU5ErkJggg==\n" - }, - "metadata": { - "needs_background": "light" - } - } + "We can take a closer look at the various statistical parameters of the dataset using pandas. The `describe` function will help us." ] }, { "cell_type": "code", - "source": [ - "x_plot = np.linspace(-1,1,10)\n", - "fig = plt.figure()\n", - "ax = plt.subplot()\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], + "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 310 + "height": 300 }, - "id": "-5p2tuxP6Jza", - "outputId": "d8c8b4e9-6429-4af2-da81-8418f032fe96" + "id": "eD4BpBHClgDc", + "outputId": "e2171ffb-bd38-4e3e-b600-ad3c249a3234" }, - "execution_count": 9, "outputs": [ { - "output_type": "execute_result", "data": { - "text/plain": [ - "" - ], "text/html": [ - "" + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeMedHouseVal
count20640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.00000020640.000000
mean3.87067128.6394865.4290001.0966751425.4767443.07065535.631861-119.5697042.068558
std1.89982212.5855582.4741730.4739111132.46212210.3860502.1359522.0035321.153956
min0.4999001.0000000.8461540.3333333.0000000.69230832.540000-124.3500000.149990
25%2.56340018.0000004.4407161.006079787.0000002.42974133.930000-121.8000001.196000
50%3.53480029.0000005.2291291.0487801166.0000002.81811634.260000-118.4900001.797000
75%4.74325037.0000006.0523811.0995261725.0000003.28226137.710000-118.0100002.647250
max15.00010052.000000141.90909134.06666735682.0000001243.33333341.950000-114.3100005.000010
\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n", + " " + ], + "text/plain": [ + " MedInc HouseAge AveRooms AveBedrms Population \\\n", + "count 20640.000000 20640.000000 20640.000000 20640.000000 20640.000000 \n", + "mean 3.870671 28.639486 5.429000 1.096675 1425.476744 \n", + "std 1.899822 12.585558 2.474173 0.473911 1132.462122 \n", + "min 0.499900 1.000000 0.846154 0.333333 3.000000 \n", + "25% 2.563400 18.000000 4.440716 1.006079 787.000000 \n", + "50% 3.534800 29.000000 5.229129 1.048780 1166.000000 \n", + "75% 4.743250 37.000000 6.052381 1.099526 1725.000000 \n", + "max 15.000100 52.000000 141.909091 34.066667 35682.000000 \n", + "\n", + " AveOccup Latitude Longitude MedHouseVal \n", + "count 20640.000000 20640.000000 20640.000000 20640.000000 \n", + "mean 3.070655 35.631861 -119.569704 2.068558 \n", + "std 10.386050 2.135952 2.003532 1.153956 \n", + "min 0.692308 32.540000 -124.350000 0.149990 \n", + "25% 2.429741 33.930000 -121.800000 1.196000 \n", + "50% 2.818116 34.260000 -118.490000 1.797000 \n", + "75% 3.282261 37.710000 -118.010000 2.647250 \n", + "max 1243.333333 41.950000 -114.310000 5.000010 " ] }, + "execution_count": 3, "metadata": {}, - "execution_count": 9 + "output_type": "execute_result" } + ], + "source": [ + "df.describe()" ] }, { "cell_type": "markdown", - "source": [ - "### 3D multiple regression with high learning rate" - ], "metadata": { - "id": "OaNvlQgzIRhA" - } + "id": "6S6WG0Bejxc2" + }, + "source": [ + "As we can see the data in each of the columns is on different scales. For example, the average bedroom value is around 1 and the average population is around 1425. \n", + "\n", + "Generally, machine learing models do not work well when the data is on different scales. Thus, we have to normalize our data in the range [-1,1]. The module [StandardScalar](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html) will help us in this.\n", + "\n", + "The training data should always be normalized. The testing data should be normalized using the values of the training data. " + ] }, { "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "pkaOgN44iQLN" + }, + "outputs": [], "source": [ - "# Hyperparameters\n", - "num_samples = 100\n", - "num_train = int(0.7 * num_samples)\n", - "num_epochs = 100\n", - "dim = 3\n", + "# !wget https://raw.githubusercontent.com/Ankit152/Fish-Market/main/Fish.csv\n", + "# import pandas as pd\n", + "# df = pd.read_csv(\"Fish.csv\")\n", + "# y = df['Weight']\n", + "# x = df[[\"Length1\", \"Length2\", \"Length3\", \"Height\", \"Width\",\"Weight\"]]\n", "\n", - "# Trying to fit the line y = Ax1 + Bx2 + c\n", - "w = np.random.randint(-3, 3, size = (dim,1)).astype(float)\n", + "df = bunch.frame\n", + "x = df.iloc[:,:-1] # Select all the columns, except the last column\n", + "y = df.iloc[:,-1:] # Select the last column\n", + "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.33, random_state = 1)\n", "\n", - "# Generate training data\n", - "x = np.random.normal(loc = 0, scale = 1, size = (num_samples,2))\n", - "ones = np.ones((num_samples, 1))\n", - "x_stack = np.hstack([x, ones])\n", + "input_scalar = StandardScaler()\n", + "output_scalar = StandardScaler()\n", "\n", + "x_train = input_scalar.fit_transform(x_train).T # Normalize train data\n", + "x_test = input_scalar.transform(x_test).T # Only transform test data using values of train data\n", "\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train\n", + "y_train = output_scalar.fit_transform(y_train).reshape(-1)\n", + "y_test = output_scalar.transform(y_test).reshape(-1)\n", "\n", + "dataset_copy = [ x_train.copy(), x_test.copy(), y_train.copy(), y_test.copy()]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mylVXZDk96a2" + }, + "source": [ + "# Linear Regression Model\n", "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.2 , size = num_samples - num_train)\n", + "Now we define our linear regression model from scratch.\n", "\n", + "A linear regression model is of the form:\n", "\n", + "$y = a_1 x_1 + a_2 x_2 + \\dots + a_nx_n + a_{n+1}$\n", + " \n", + "The above can be rewritten using matrix multiplication as\n", "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", + "$ y = w^T x $\n", "\n", + "where \n", "\n", - "model = LinearRegression(dim = dim, lr = 2)\n", + "$ w = [a_1, a_2, \\dots, a_n, a_{n+1}]^T $\n", "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "$ x = [x_1, x_2, \\dots, x_n]^T $\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "iJViSowz9nah" + }, + "outputs": [], + "source": [ + "class LinearRegression():\n", + " def __init__(self, dim, lr = 0.1):\n", + " assert isinstance\n", + " self.lr = lr\n", + " self.w = np.zeros((dim))\n", + " self.grads = {\"dw\": np.zeros((dim)) +5}\n", "\n", - " w_history.append(model.w)\n", + " def forward(self, x):\n", + " y = self.w.T @ x\n", + " return y\n", + " \n", + " def backward(self, x, y_hat, y):\n", + " assert y_hat.shape == y.shape\n", + " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", + " assert self.grads[\"dw\"].shape == self.w.shape\n", + " \n", + " # print(self.grads[\"dw\"])\n", "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", + " def optimize(self):\n", + " self.w = self.w - self.lr * self.grads[\"dw\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6UOy32LoqCrL" + }, + "source": [ + "# Loss\n", "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "For linear regression, various loss functions such as the mean absolute error, mean squared error, or root mean squared error can be used.\n", "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", + "In this example, we will use the mean squared error (MSE) loss.\n", "\n", - " if i % 10 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "The MSE loss is given by \n", "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], + "$ error = \\frac{1}{m} Σ_{i=1}^{m} (y_{true}^{i} - y_{pred}^{i})^2 $ \n", + "\n", + "where $i$ denotes the particular obseration/row in the dataset and $m$ is the total number of obserations.\n", + "\n", + "To ensure our model is correct, the loss should decrease over each epoch.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3atqq0KirwLu" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 450 + "height": 1000 }, - "id": "cgvqVAOiw-Kn", - "outputId": "19af795b-caf1-4c53-8cda-8756ceeeed71" + "id": "mgNn3oGjjbxX", + "outputId": "2f67998e-2fa4-4c43-e091-d5180dd92029" }, - "execution_count": 10, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 12.698436970922991\n", - "Epoch 10 | Train Loss 746.3185411858192 | Test Loss 358.562608321611\n", - "Epoch 20 | Train Loss 24419.323783752887 | Test Loss 11749.26328932645\n", - "Epoch 30 | Train Loss 800867.9318070416 | Test Loss 384943.9910339218\n", - "Epoch 40 | Train Loss 26266251.698730588 | Test Loss 12621262.851923324\n", - "Epoch 50 | Train Loss 861460553.6207652 | Test Loss 413915326.3017189\n", - "Epoch 60 | Train Loss 28253528351.36185 | Test Loss 13575106812.11293\n", - "Epoch 70 | Train Loss 926637744424.7832 | Test Loss 445224984161.656\n", - "Epoch 80 | Train Loss 30391160307998.715 | Test Loss 14602144378033.883\n", - "Epoch 90 | Train Loss 996746172302559.5 | Test Loss 478909994660501.94\n" + "Epoch 0 | Train Loss 0.49999999999999983 | Test Loss 0.43712002508129305\n", + "Epoch 20 | Train Loss 0.2359010824314295 | Test Loss 0.2325611904818386\n", + "Epoch 40 | Train Loss 0.22188755162559423 | Test Loss 0.2217635127918686\n", + "Epoch 60 | Train Loss 0.21474640752415047 | Test Loss 0.2152613227580797\n", + "Epoch 80 | Train Loss 0.2095989567021037 | Test Loss 0.21037193610067245\n", + "Epoch 100 | Train Loss 0.20581761895152345 | Test Loss 0.20673038702760732\n", + "Epoch 120 | Train Loss 0.20303294882659725 | Test Loss 0.20402527473733864\n", + "Epoch 140 | Train Loss 0.20097918345162274 | Test Loss 0.20201418597478873\n", + "Epoch 160 | Train Loss 0.19946210112703647 | Test Loss 0.20051638978054404\n", + "Epoch 180 | Train Loss 0.19833950070910428 | Test Loss 0.19939846923590557\n", + "Epoch 200 | Train Loss 0.19750719045004836 | Test Loss 0.19856209982480624\n", + "Epoch 220 | Train Loss 0.1968887724916989 | Test Loss 0.1979347869242644\n", + "Epoch 240 | Train Loss 0.19642818272324772 | Test Loss 0.19746302071881933\n", + "Epoch 260 | Train Loss 0.19608424065206406 | Test Loss 0.19710724843033994\n", + "Epoch 280 | Train Loss 0.19582666642954677 | Test Loss 0.19683818623685323\n", + "Epoch 300 | Train Loss 0.19563316903289557 | Test Loss 0.19663411372213185\n", + "Epoch 320 | Train Loss 0.19548731666143612 | Test Loss 0.19647888801910168\n", + "Epoch 340 | Train Loss 0.19537697849050284 | Test Loss 0.19636048509166582\n", + "Epoch 360 | Train Loss 0.19529318388491884 | Test Loss 0.19626992725672532\n", + "Epoch 380 | Train Loss 0.19522928672715056 | Test Loss 0.19620049386222657\n", + "Epoch 400 | Train Loss 0.19518035283239818 | Test Loss 0.19614713968570663\n", + "Epoch 420 | Train Loss 0.19514271054504922 | Test Loss 0.1961060658296224\n", + "Epoch 440 | Train Loss 0.19511362075549118 | Test Loss 0.19607440266698017\n", + "Epoch 460 | Train Loss 0.19509103436032973 | Test Loss 0.196049975197568\n", + "Epoch 480 | Train Loss 0.19507341379189 | Test Loss 0.1960311290809374\n", + "Epoch 500 | Train Loss 0.195059601524607 | Test Loss 0.1960166013981983\n", + "Epoch 520 | Train Loss 0.19504872305387622 | Test Loss 0.19600542443105118\n", + "Epoch 540 | Train Loss 0.19504011519474806 | Test Loss 0.19599685384985982\n", + "Epoch 560 | Train Loss 0.19503327299733605 | Test Loss 0.19599031497728384\n", + "Epoch 580 | Train Loss 0.19502781036651573 | Test Loss 0.19598536246238987\n", + "Epoch 600 | Train Loss 0.19502343078313097 | Test Loss 0.19598164992474956\n", + "Epoch 620 | Train Loss 0.19501990548217418 | Test Loss 0.19597890702760307\n", + "Epoch 640 | Train Loss 0.19501705714492468 | Test Loss 0.1959769221005947\n", + "Epoch 660 | Train Loss 0.1950147476759042 | Test Loss 0.1959755289194148\n", + "Epoch 680 | Train Loss 0.19501286901218934 | Test Loss 0.19597459660841743\n", + "Epoch 700 | Train Loss 0.1950113361889526 | Test Loss 0.19597402189697258\n", + "Epoch 720 | Train Loss 0.1950100820879975 | Test Loss 0.19597372315589145\n", + "Epoch 740 | Train Loss 0.1950090534451732 | Test Loss 0.19597363578501353\n", + "Epoch 760 | Train Loss 0.1950082078022795 | Test Loss 0.19597370863036628\n", + "Epoch 780 | Train Loss 0.19500751116991094 | Test Loss 0.19597390118903935\n", + "Epoch 800 | Train Loss 0.19500693622732843 | Test Loss 0.19597418141927686\n", + "Epoch 820 | Train Loss 0.19500646092952323 | Test Loss 0.19597452401759977\n", + "Epoch 840 | Train Loss 0.19500606742426427 | Test Loss 0.1959749090579219\n", + "Epoch 860 | Train Loss 0.19500574120612196 | Test Loss 0.19597532091250944\n", + "Epoch 880 | Train Loss 0.19500547045245514 | Test Loss 0.19597574739336301\n", + "Epoch 900 | Train Loss 0.19500524549975556 | Test Loss 0.1959761790667557\n", + "Epoch 920 | Train Loss 0.19500505842876395 | Test Loss 0.19597660870438502\n", + "Epoch 940 | Train Loss 0.1950049027342804 | Test Loss 0.1959770308427642\n", + "Epoch 960 | Train Loss 0.19500477306123667 | Test Loss 0.1959774414287147\n", + "Epoch 980 | Train Loss 0.19500466499285687 | Test Loss 0.19597783753361098\n", + "Epoch 1000 | Train Loss 0.19500457487995757 | Test Loss 0.19597821712271776\n", + "Epoch 1020 | Train Loss 0.1950044997028894 | Test Loss 0.19597857886881814\n", + "Epoch 1040 | Train Loss 0.1950044369594934 | Test Loss 0.19597892200155245\n", + "Epoch 1060 | Train Loss 0.19500438457387914 | Test Loss 0.19597924618562568\n", + "Epoch 1080 | Train Loss 0.1950043408219371 | Test Loss 0.1959795514224043\n", + "Epoch 1100 | Train Loss 0.19500430427035154 | Test Loss 0.19597983797049975\n", + "Epoch 1120 | Train Loss 0.19500427372654458 | Test Loss 0.1959801062817876\n", + "Epoch 1140 | Train Loss 0.195004248197501 | Test Loss 0.19598035694999025\n", + "Epoch 1160 | Train Loss 0.19500422685583052 | Test Loss 0.1959805906694935\n", + "Epoch 1180 | Train Loss 0.1950042090117447 | Test Loss 0.19598080820250163\n", + "Epoch 1200 | Train Loss 0.195004194089881 | Test Loss 0.1959810103529865\n", + "Epoch 1220 | Train Loss 0.19500418161010774 | Test Loss 0.1959811979461702\n", + "Epoch 1240 | Train Loss 0.1950041711716055 | Test Loss 0.19598137181250938\n", + "Epoch 1260 | Train Loss 0.1950041624396518 | Test Loss 0.1959815327753366\n", + "Epoch 1280 | Train Loss 0.19500415513463745 | Test Loss 0.19598168164146745\n", + "Epoch 1300 | Train Loss 0.19500414902293145 | Test Loss 0.19598181919420496\n", + "Epoch 1320 | Train Loss 0.1950041439092753 | Test Loss 0.19598194618827683\n", + "Epoch 1340 | Train Loss 0.19500413963044858 | Test Loss 0.19598206334632265\n", + "Epoch 1360 | Train Loss 0.1950041360499879 | Test Loss 0.19598217135661974\n", + "Epoch 1380 | Train Loss 0.19500413305378356 | Test Loss 0.19598227087179027\n", + "Epoch 1400 | Train Loss 0.1950041305464049 | Test Loss 0.19598236250828016\n", + "Epoch 1420 | Train Loss 0.1950041284480337 | Test Loss 0.19598244684643956\n", + "Epoch 1440 | Train Loss 0.19500412669190298 | Test Loss 0.19598252443106423\n", + "Epoch 1460 | Train Loss 0.1950041252221582 | Test Loss 0.1959825957722857\n", + "Epoch 1480 | Train Loss 0.1950041239920701 | Test Loss 0.19598266134671743\n", + "Epoch 1500 | Train Loss 0.1950041229625413 | Test Loss 0.19598272159878383\n", + "Epoch 1520 | Train Loss 0.19500412210085774 | Test Loss 0.19598277694217195\n", + "Epoch 1540 | Train Loss 0.19500412137964543 | Test Loss 0.19598282776135909\n", + "Epoch 1560 | Train Loss 0.19500412077599738 | Test Loss 0.19598287441317852\n", + "Epoch 1580 | Train Loss 0.19500412027074418 | Test Loss 0.19598291722839395\n", + "Epoch 1600 | Train Loss 0.19500411984784347 | Test Loss 0.1959829565132598\n", + "Epoch 1620 | Train Loss 0.19500411949386964 | Test Loss 0.19598299255105023\n", + "Epoch 1640 | Train Loss 0.19500411919758648 | Test Loss 0.1959830256035433\n", + "Epoch 1660 | Train Loss 0.19500411894959 | Test Loss 0.1959830559124517\n", + "Epoch 1680 | Train Loss 0.19500411874200962 | Test Loss 0.19598308370079265\n", + "Epoch 1700 | Train Loss 0.19500411856825786 | Test Loss 0.19598310917419287\n", + "Epoch 1720 | Train Loss 0.19500411842282128 | Test Loss 0.1959831325221266\n", + "Epoch 1740 | Train Loss 0.19500411830108505 | Test Loss 0.19598315391908486\n", + "Epoch 1760 | Train Loss 0.19500411819918667 | Test Loss 0.19598317352567718\n", + "Epoch 1780 | Train Loss 0.19500411811389318 | Test Loss 0.19598319148966561\n", + "Epoch 1800 | Train Loss 0.19500411804249856 | Test Loss 0.19598320794693336\n", + "Epoch 1820 | Train Loss 0.19500411798273784 | Test Loss 0.1959832230223899\n", + "Epoch 1840 | Train Loss 0.19500411793271513 | Test Loss 0.19598323683081562\n", + "Epoch 1860 | Train Loss 0.19500411789084354 | Test Loss 0.19598324947764745\n", + "Epoch 1880 | Train Loss 0.19500411785579488 | Test Loss 0.19598326105971003\n", + "Epoch 1900 | Train Loss 0.19500411782645727 | Test Loss 0.19598327166589385\n", + "Epoch 1920 | Train Loss 0.19500411780190013 | Test Loss 0.1959832813777842\n", + "Epoch 1940 | Train Loss 0.1950041177813444 | Test Loss 0.1959832902702435\n", + "Epoch 1960 | Train Loss 0.1950041177641382 | Test Loss 0.1959832984119505\n", + "Epoch 1980 | Train Loss 0.19500411774973558 | Test Loss 0.19598330586589785\n", + "Epoch 2000 | Train Loss 0.1950041177376798 | Test Loss 0.1959833126898522\n", + "Epoch 2020 | Train Loss 0.19500411772758847 | Test Loss 0.1959833189367787\n", + "Epoch 2040 | Train Loss 0.19500411771914136 | Test Loss 0.19598332465523224\n", + "Epoch 2060 | Train Loss 0.1950041177120707 | Test Loss 0.19598332988971823\n", + "Epoch 2080 | Train Loss 0.1950041177061521 | Test Loss 0.1959833346810246\n", + "Epoch 2100 | Train Loss 0.195004117701198 | Test Loss 0.19598333906652787\n", + "Epoch 2120 | Train Loss 0.19500411769705106 | Test Loss 0.19598334308047438\n", + "Epoch 2140 | Train Loss 0.1950041176935798 | Test Loss 0.19598334675423898\n", + "Epoch 2160 | Train Loss 0.19500411769067422 | Test Loss 0.1959833501165632\n", + "Epoch 2180 | Train Loss 0.19500411768824202 | Test Loss 0.1959833531937735\n", + "Epoch 2200 | Train Loss 0.19500411768620615 | Test Loss 0.19598335600998243\n", + "Epoch 2220 | Train Loss 0.19500411768450196 | Test Loss 0.1959833585872731\n", + "Epoch 2240 | Train Loss 0.19500411768307552 | Test Loss 0.19598336094586813\n", + "Epoch 2260 | Train Loss 0.19500411768188147 | Test Loss 0.19598336310428585\n", + "Epoch 2280 | Train Loss 0.19500411768088202 | Test Loss 0.195983365079482\n", + "Epoch 2300 | Train Loss 0.19500411768004536 | Test Loss 0.19598336688698145\n", + "Epoch 2320 | Train Loss 0.19500411767934506 | Test Loss 0.1959833685409978\n", + "Epoch 2340 | Train Loss 0.19500411767875886 | Test Loss 0.19598337005454344\n", + "Epoch 2360 | Train Loss 0.1950041176782682 | Test Loss 0.1959833714395307\n", + "Epoch 2380 | Train Loss 0.1950041176778575 | Test Loss 0.1959833727068645\n", + "Epoch 2400 | Train Loss 0.19500411767751366 | Test Loss 0.19598337386652676\n", + "Epoch 2420 | Train Loss 0.19500411767722584 | Test Loss 0.1959833749276544\n", + "Epoch 2440 | Train Loss 0.19500411767698494 | Test Loss 0.1959833758986108\n", + "Epoch 2460 | Train Loss 0.19500411767678333 | Test Loss 0.19598337678705066\n", + "Epoch 2480 | Train Loss 0.19500411767661452 | Test Loss 0.19598337759998\n", + "Epoch 2500 | Train Loss 0.19500411767647324 | Test Loss 0.19598337834381113\n", + "Epoch 2520 | Train Loss 0.195004117676355 | Test Loss 0.19598337902441254\n", + "Epoch 2540 | Train Loss 0.195004117676256 | Test Loss 0.1959833796471551\n", + "Epoch 2560 | Train Loss 0.19500411767617312 | Test Loss 0.19598338021695402\n", + "Epoch 2580 | Train Loss 0.1950041176761038 | Test Loss 0.19598338073830746\n", + "Epoch 2600 | Train Loss 0.19500411767604572 | Test Loss 0.19598338121533196\n", + "Epoch 2620 | Train Loss 0.19500411767599712 | Test Loss 0.19598338165179446\n", + "Epoch 2640 | Train Loss 0.1950041176759564 | Test Loss 0.19598338205114224\n", + "Epoch 2660 | Train Loss 0.19500411767592238 | Test Loss 0.19598338241652982\n", + "Epoch 2680 | Train Loss 0.19500411767589387 | Test Loss 0.19598338275084387\n", + "Epoch 2700 | Train Loss 0.19500411767587003 | Test Loss 0.1959833830567258\n", + "Epoch 2720 | Train Loss 0.19500411767585005 | Test Loss 0.19598338333659285\n", + "Epoch 2740 | Train Loss 0.1950041176758333 | Test Loss 0.19598338359265657\n", + "Epoch 2760 | Train Loss 0.19500411767581935 | Test Loss 0.19598338382694094\n", + "Epoch 2780 | Train Loss 0.19500411767580764 | Test Loss 0.19598338404129775\n", + "Epoch 2800 | Train Loss 0.19500411767579784 | Test Loss 0.19598338423742154\n", + "Epoch 2820 | Train Loss 0.19500411767578962 | Test Loss 0.19598338441686272\n", + "Epoch 2840 | Train Loss 0.19500411767578277 | Test Loss 0.19598338458104\n", + "Epoch 2860 | Train Loss 0.195004117675777 | Test Loss 0.1959833847312515\n", + "Epoch 2880 | Train Loss 0.1950041176757722 | Test Loss 0.19598338486868488\n", + "Epoch 2900 | Train Loss 0.19500411767576814 | Test Loss 0.19598338499442705\n", + "Epoch 2920 | Train Loss 0.19500411767576475 | Test Loss 0.19598338510947227\n", + "Epoch 2940 | Train Loss 0.19500411767576192 | Test Loss 0.19598338521473044\n", + "Epoch 2960 | Train Loss 0.1950041176757596 | Test Loss 0.19598338531103396\n", + "Epoch 2980 | Train Loss 0.19500411767575762 | Test Loss 0.19598338539914462\n", + "Epoch 3000 | Train Loss 0.19500411767575593 | Test Loss 0.1959833854797592\n", + "Epoch 3020 | Train Loss 0.19500411767575457 | Test Loss 0.1959833855535154\n", + "Epoch 3040 | Train Loss 0.1950041176757534 | Test Loss 0.1959833856209966\n", + "Epoch 3060 | Train Loss 0.19500411767575246 | Test Loss 0.19598338568273665\n", + "Epoch 3080 | Train Loss 0.19500411767575163 | Test Loss 0.19598338573922397\n", + "Epoch 3100 | Train Loss 0.19500411767575093 | Test Loss 0.19598338579090527\n", + "Epoch 3120 | Train Loss 0.19500411767575035 | Test Loss 0.19598338583818956\n", + "Epoch 3140 | Train Loss 0.19500411767574988 | Test Loss 0.19598338588145087\n", + "Epoch 3160 | Train Loss 0.1950041176757495 | Test Loss 0.1959833859210314\n", + "Epoch 3180 | Train Loss 0.19500411767574916 | Test Loss 0.19598338595724435\n", + "Epoch 3200 | Train Loss 0.1950041176757489 | Test Loss 0.19598338599037615\n", + "Epoch 3220 | Train Loss 0.19500411767574863 | Test Loss 0.19598338602068902\n", + "Epoch 3240 | Train Loss 0.19500411767574843 | Test Loss 0.19598338604842275\n", + "Epoch 3260 | Train Loss 0.19500411767574832 | Test Loss 0.19598338607379676\n", + "Epoch 3280 | Train Loss 0.19500411767574816 | Test Loss 0.19598338609701185\n", + "Epoch 3300 | Train Loss 0.19500411767574805 | Test Loss 0.19598338611825167\n", + "Epoch 3320 | Train Loss 0.19500411767574796 | Test Loss 0.19598338613768423\n", + "Epoch 3340 | Train Loss 0.19500411767574785 | Test Loss 0.19598338615546346\n", + "Epoch 3360 | Train Loss 0.1950041176757478 | Test Loss 0.1959833861717299\n", + "Epoch 3380 | Train Loss 0.1950041176757477 | Test Loss 0.19598338618661224\n", + "Epoch 3400 | Train Loss 0.19500411767574768 | Test Loss 0.1959833862002283\n", + "Epoch 3420 | Train Loss 0.19500411767574766 | Test Loss 0.19598338621268585\n", + "Epoch 3440 | Train Loss 0.19500411767574763 | Test Loss 0.19598338622408337\n", + "Epoch 3460 | Train Loss 0.1950041176757476 | Test Loss 0.1959833862345112\n", + "Epoch 3480 | Train Loss 0.1950041176757476 | Test Loss 0.19598338624405162\n", + "Epoch 3500 | Train Loss 0.19500411767574752 | Test Loss 0.19598338625278036\n", + "Epoch 3520 | Train Loss 0.19500411767574755 | Test Loss 0.19598338626076636\n", + "Epoch 3540 | Train Loss 0.19500411767574752 | Test Loss 0.19598338626807282\n", + "Epoch 3560 | Train Loss 0.19500411767574752 | Test Loss 0.19598338627475767\n", + "Epoch 3580 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628087364\n", + "Epoch 3600 | Train Loss 0.1950041176757475 | Test Loss 0.19598338628646922\n", + "Epoch 3620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629158868\n", + "Epoch 3640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338629627257\n", + "Epoch 3660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630055787\n", + "Epoch 3680 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863044786\n", + "Epoch 3700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338630806564\n", + "Epoch 3720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631134748\n", + "Epoch 3740 | Train Loss 0.1950041176757475 | Test Loss 0.1959833863143501\n", + "Epoch 3760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338631709722\n", + "Epoch 3780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863196106\n", + "Epoch 3800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863219101\n", + "Epoch 3820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632401394\n", + "Epoch 3840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632593876\n", + "Epoch 3860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338632769982\n", + "Epoch 3880 | Train Loss 0.19500411767574743 | Test Loss 0.19598338632931098\n", + "Epoch 3900 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863307851\n", + "Epoch 3920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633213377\n", + "Epoch 3940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633336768\n", + "Epoch 3960 | Train Loss 0.19500411767574743 | Test Loss 0.19598338633449658\n", + "Epoch 3980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633552945\n", + "Epoch 4000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633647439\n", + "Epoch 4020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633733897\n", + "Epoch 4040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633812995\n", + "Epoch 4060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633885368\n", + "Epoch 4080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338633951579\n", + "Epoch 4100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634012158\n", + "Epoch 4120 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863406758\n", + "Epoch 4140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634118284\n", + "Epoch 4160 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863416468\n", + "Epoch 4180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634207124\n", + "Epoch 4200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634245957\n", + "Epoch 4220 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863428149\n", + "Epoch 4240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634313991\n", + "Epoch 4260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634343732\n", + "Epoch 4280 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863437094\n", + "Epoch 4300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634395834\n", + "Epoch 4320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863441861\n", + "Epoch 4340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863443945\n", + "Epoch 4360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634458515\n", + "Epoch 4380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634475954\n", + "Epoch 4400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634491913\n", + "Epoch 4420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634506512\n", + "Epoch 4440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863451987\n", + "Epoch 4460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634532095\n", + "Epoch 4480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634543272\n", + "Epoch 4500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634553503\n", + "Epoch 4520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634562865\n", + "Epoch 4540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634571427\n", + "Epoch 4560 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863457926\n", + "Epoch 4580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634586435\n", + "Epoch 4600 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863459299\n", + "Epoch 4620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634598989\n", + "Epoch 4640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634604479\n", + "Epoch 4660 | Train Loss 0.19500411767574746 | Test Loss 0.195983386346095\n", + "Epoch 4680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634614093\n", + "Epoch 4700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634618298\n", + "Epoch 4720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634622145\n", + "Epoch 4740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634625664\n", + "Epoch 4760 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863462888\n", + "Epoch 4780 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463183\n", + "Epoch 4800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634634527\n", + "Epoch 4820 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863463699\n", + "Epoch 4840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634639245\n", + "Epoch 4860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634641307\n", + "Epoch 4880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634643198\n", + "Epoch 4900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634644927\n", + "Epoch 4920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634646506\n", + "Epoch 4940 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863464795\n", + "Epoch 4960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634649273\n", + "Epoch 4980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634650483\n", + "Epoch 5000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634651596\n", + "Epoch 5020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634652604\n", + "Epoch 5040 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465353\n", + "Epoch 5060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634654378\n", + "Epoch 5080 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863465516\n", + "Epoch 5100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634655868\n", + "Epoch 5120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634656515\n", + "Epoch 5140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657111\n", + "Epoch 5160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634657653\n", + "Epoch 5180 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863465815\n", + "Epoch 5200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634658605\n", + "Epoch 5220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659024\n", + "Epoch 5240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659407\n", + "Epoch 5260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634659754\n", + "Epoch 5280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660073\n", + "Epoch 5300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660364\n", + "Epoch 5320 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466063\n", + "Epoch 5340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634660875\n", + "Epoch 5360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661094\n", + "Epoch 5380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661303\n", + "Epoch 5400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661489\n", + "Epoch 5420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661658\n", + "Epoch 5440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634661816\n", + "Epoch 5460 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466196\n", + "Epoch 5480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662088\n", + "Epoch 5500 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466221\n", + "Epoch 5520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662318\n", + "Epoch 5540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662418\n", + "Epoch 5560 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466251\n", + "Epoch 5580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662596\n", + "Epoch 5600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662674\n", + "Epoch 5620 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634662743\n", + "Epoch 5640 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466281\n", + "Epoch 5660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634662868\n", + "Epoch 5680 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466292\n", + "Epoch 5700 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466297\n", + "Epoch 5720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663018\n", + "Epoch 5740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663057\n", + "Epoch 5760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663093\n", + "Epoch 5780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663132\n", + "Epoch 5800 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466316\n", + "Epoch 5820 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466319\n", + "Epoch 5840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663218\n", + "Epoch 5860 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466324\n", + "Epoch 5880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663262\n", + "Epoch 5900 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663284\n", + "Epoch 5920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663304\n", + "Epoch 5940 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663318\n", + "Epoch 5960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663331\n", + "Epoch 5980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663348\n", + "Epoch 6000 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663356\n", + "Epoch 6020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663373\n", + "Epoch 6040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663384\n", + "Epoch 6060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663395\n", + "Epoch 6080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663404\n", + "Epoch 6100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663412\n", + "Epoch 6120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663418\n", + "Epoch 6140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663423\n", + "Epoch 6160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663431\n", + "Epoch 6180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663437\n", + "Epoch 6200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663445\n", + "Epoch 6220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663448\n", + "Epoch 6240 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466345\n", + "Epoch 6260 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466346\n", + "Epoch 6280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663462\n", + "Epoch 6300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", + "Epoch 6320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663465\n", + "Epoch 6340 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466347\n", + "Epoch 6360 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", + "Epoch 6380 | Train Loss 0.19500411767574743 | Test Loss 0.1959833863466347\n", + "Epoch 6400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663479\n", + "Epoch 6420 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663479\n", + "Epoch 6440 | Train Loss 0.19500411767574746 | Test Loss 0.1959833863466348\n", + "Epoch 6460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", + "Epoch 6480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663484\n", + "Epoch 6500 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663484\n", + "Epoch 6520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663487\n", + "Epoch 6580 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663487\n", + "Epoch 6600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663492\n", + "Epoch 6700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663495\n", + "Epoch 6760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6920 | Train Loss 0.19500411767574743 | Test Loss 0.19598338634663498\n", + "Epoch 6940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 6980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 7980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 8980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9000 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9020 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9040 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9060 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9080 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9100 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9120 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9140 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9160 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9180 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9200 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9220 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9240 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9260 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9280 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9300 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9320 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9340 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9360 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9380 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9400 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9420 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9440 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9460 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9480 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9500 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9520 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9540 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9560 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9580 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9600 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9620 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9640 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9660 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9680 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9700 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9720 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9740 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9760 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9780 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9800 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9820 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9840 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9860 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9880 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9900 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9920 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9940 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9960 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n", + "Epoch 9980 | Train Loss 0.19500411767574746 | Test Loss 0.19598338634663498\n" ] }, { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, "metadata": { "needs_background": "light" - } - } - ] - }, - { - "cell_type": "code", - "source": [ - "# Do you want to rotate the 3D plane??\n", - "angles = np.linspace(-60,60, num_epochs)\n", - "fig = plt.figure()\n", - "ax = fig.gca(projection='3d')\n", - "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 - }, - "id": "1beKSQbzE8PL", - "outputId": "59fa05ad-aabb-44ca-b395-08c6574282c4" - }, - "execution_count": 11, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] }, - "metadata": {}, - "execution_count": 11 + "output_type": "display_data" } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### Lower the learning rate" ], - "metadata": { - "id": "FLs0b32kIrV4" - } - }, - { - "cell_type": "code", "source": [ + "num_epochs = 10000\n", "train_loss_history = []\n", "test_loss_history = []\n", "w_history = []\n", + "dim = x_train.shape[0]\n", + "num_train = x_train.shape[1]\n", + "num_test = x_test.shape[1]\n", "\n", "\n", "model = LinearRegression(dim = dim, lr = 0.1)\n", - "\n", "for i in range(num_epochs):\n", " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + " train_loss = 1/(2 * num_train) * ((y_train - y_hat) ** 2).sum()\n", "\n", " w_history.append(model.w)\n", - "\n", " model.backward(x_train,y_hat,y_train)\n", " model.optimize()\n", "\n", " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + " test_loss = 1/(2 * num_test) * ((y_test - y_hat) ** 2).sum()\n", "\n", " train_loss_history.append(train_loss)\n", " test_loss_history.append(test_loss)\n", "\n", - " if i % 10 == 0:\n", + " if i % 20 == 0:\n", " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", "\n", "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", "plt.legend()\n", "plt.show()" - ], + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ldFMBPuvr0l0" + }, + "source": [ + "# Results\n", + "\n", + "Before viewing the results, we need to reverse the transformations applied on the output variable y.\n", + "\n", + "The `inverse_transform` method of the StandardScaler object will help us." + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": { - "id": "-j3M08gvxUSn", "colab": { - "base_uri": "https://localhost:8080/", - "height": 439 + "base_uri": "https://localhost:8080/" }, - "outputId": "1ea24389-310f-46d1-df7a-068aaae52eec" + "id": "ZycI4aExMsoC", + "outputId": "47c6b8fa-d1ee-4ff6-90d0-7e9289cfe40e" }, - "execution_count": 12, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 8.095125244530212\n", - "Epoch 10 | Train Loss 4.346296963406692 | Test Loss 1.357191290987867\n", - "Epoch 20 | Train Loss 0.6354422722047353 | Test Loss 0.577448546725004\n", - "Epoch 30 | Train Loss 0.10841552249188971 | Test Loss 0.5003814236148908\n", - "Epoch 40 | Train Loss 0.021006468804432007 | Test Loss 0.5035382295431836\n", - "Epoch 50 | Train Loss 0.004423983911951978 | Test Loss 0.5109523052179242\n", - "Epoch 60 | Train Loss 0.0009763636539296937 | Test Loss 0.5153711624316784\n", - "Epoch 70 | Train Loss 0.00022076073931739313 | Test Loss 0.5175898522946066\n", - "Epoch 80 | Train Loss 5.0521477933667895e-05 | Test Loss 0.5186517866852555\n", - "Epoch 90 | Train Loss 1.163119776227275e-05 | Test Loss 0.5191535958691665\n" + "Test Set Error 0.5263803029005855\n" ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } } + ], + "source": [ + "from sklearn.metrics import mean_squared_error\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = (((y_test - y_hat) ** 2).sum() / num_test )\n", + "print(\"Test Set Error\", error)" ] }, { - "cell_type": "code", + "cell_type": "markdown", + "metadata": { + "id": "UoYobRS9uBIv" + }, "source": [ - "# Do you want to rotate the 3D plane??\n", - "angles = np.linspace(-60,60, num_epochs)\n", - "fig = plt.figure()\n", - "ax = fig.gca(projection='3d')\n", - "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], + "# Libraries\n", + "\n", + "Instead of coding everything from scratch, i.e the model, loss functions, and gradient calculations, there are many libaries that have implemented many machine learning algorithms for us.\n", + "\n", + "These libraries will generally be faster and more optimized. We can use the LinearRegression and SGD regressor module from scikit learn to compare our model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": { "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 + "base_uri": "https://localhost:8080/" }, - "id": "yMZbHPvgFFmH", - "outputId": "dbba73a4-2773-4c73-9e12-186aaf84aab6" + "id": "txWBY_0eoNN_", + "outputId": "7886b7e0-c383-4676-e825-3d7197d06d80" }, - "execution_count": 13, "outputs": [ { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 13 + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Set Error 0.5892243304217802\n" + ] } - ] - }, - { - "cell_type": "code", + ], "source": [ - "# function that draws each frame of the animation\n", - "from matplotlib.animation import FuncAnimation\n", - "from matplotlib import rc\n", - "rc('animation', html='html5')\n", - "lr = LinearRegression(3, lr = 0.8)\n", - "losses = []\n", - "w = np.array([-2,2,2]).reshape(3, 1)\n", - "x = np.random.rand(100,2)\n", - "x_stack = np.hstack([x, np.ones((x.shape[0], 1))]).T\n", - "y = np.sum(w * x_stack, axis = 0, keepdims=True).astype(float)\n", - "y_test = y + np.random.normal(0, scale = 0.1, size =y.shape)\n", - "x = x_stack\n", - "fig = plt.figure()\n", - "plt3d = fig.gca(projection='3d')\n", - "plt.close()\n", - "def init():\n", - " pass\n", - "def animate(i):\n", - "\n", - "\n", - " y_hat = lr.forward(x)\n", - " plt3d.clear()\n", - " plt3d.set_xlim(xmin= 0 ,xmax = 1)\n", - " plt3d.set_ylim(ymin = 0 , ymax = 1)\n", - " plt3d.set_zlim(zmin = 0, zmax = 4)\n", - " plt3d.set_title(f\"Epoch {i} Weight {lr.w}\")\n", - " xx, yy = np.meshgrid(range(2),range(2))\n", - "\n", - " z = w[0] * xx + w[1] * yy + w[2]\n", - " z_pred = lr.w[0] * xx + lr.w[1] * yy + lr.w[2]\n", - " # plot the surface\n", - "\n", - " plt3d.plot_surface( xx, yy, z, alpha=0.5)\n", - " plt3d.plot_surface( xx, yy, z_pred, alpha=0.2)\n", - " plt3d.scatter(x[0], x[1], y)\n", - " # plt3d.plot_surface(xx, yy, lr.w[-1].reshape(-1,1), alpha=0.2)\n", + "from sklearn.linear_model import SGDRegressor\n", "\n", "\n", - " loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - " losses.append(loss)\n", - " lr.backward(x,y_hat,y_test)\n", - " lr.optimize()\n", - "\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate, frames=100, init_func=init, interval=20,)" - ], - "metadata": { - "id": "mBAHqPPhvI4E" - }, - "execution_count": 14, - "outputs": [] + "x_train, x_test, y_train, y_test = dataset_copy\n", + "sgd = SGDRegressor()\n", + "sgd.fit(x_train.T, y_train)\n", + "y_hat = sgd.predict(x_test.T)\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = mean_squared_error(y_test, y_hat, squared = True)\n", + "print(\"Test Set Error\", error)" + ] }, { "cell_type": "code", - "source": [ - "ani" - ], + "execution_count": 9, "metadata": { "colab": { - "base_uri": "https://localhost:8080/", - "height": 518 + "base_uri": "https://localhost:8080/" }, - "id": "O2oDLMGLwNFD", - "outputId": "dcdb29bb-46fa-4c94-fe26-cf8299cc4506" + "id": "9CaqphG8TG7V", + "outputId": "579bc8dd-6093-4155-8966-f8c60c34b1b3" }, - "execution_count": 15, "outputs": [ { + "name": "stdout", "output_type": "stream", - "name": "stderr", "text": [ - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", - "The `xmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `left` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", - "The `xmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `right` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", - "The `ymin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", - "The `ymax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", - "The `zmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", - "The `zmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n" + "Test Set Error 0.5263803029005857\n" ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 15 } + ], + "source": [ + "from sklearn.linear_model import LinearRegression as LR\n", + "\n", + "x_train, x_test, y_train, y_test = dataset_copy\n", + "lr = LR()\n", + "lr.fit(x_train.T, y_train)\n", + "y_hat = lr.predict(x_test.T)\n", + "y_test = output_scalar.inverse_transform(y_test[np.newaxis,:])\n", + "y_hat = output_scalar.inverse_transform(y_hat[np.newaxis,:])\n", + "error = mean_squared_error(y_test, y_hat, squared = True)\n", + "print(\"Test Set Error\", error)" ] } - ] -} \ No newline at end of file + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyODV4REEuhLrJ1l8OWl6dFt", + "collapsed_sections": [], + "include_colab_link": true, + "name": "Linear Regression.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/notebooks/linear_regression_with_sgd.ipynb b/notebooks/linear_regression_with_sgd.ipynb new file mode 100644 index 0000000..43c5fb2 --- /dev/null +++ b/notebooks/linear_regression_with_sgd.ipynb @@ -0,0 +1,21660 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Linear Regression.ipynb", + "provenance": [], + "collapsed_sections": [], + "authorship_tag": "ABX9TyNRx6gNEqYURZyKqPxPjDA4", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "ku4r-K4GQXEN" + }, + "outputs": [], + "source": [ + "## Import the usual libraries\n", + "import torch\n", + "import torchvision\n", + "import torch.nn as nn\n", + "from torchvision import datasets, models, transforms\n", + "import os\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from matplotlib.animation import FuncAnimation\n", + "from matplotlib import rc\n", + "rc('animation', html='html5')\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "source": [ + "def init():\n", + " pass\n", + " \n", + "def animate_2d(i):\n", + "\n", + " y_true = w[0] * x_plot + w[1] \n", + " w_pred = w_history[i]\n", + " y_pred = w_pred[0] * x_plot + w_pred[1] \n", + " ax.clear()\n", + " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", + " ax.plot(x_plot, y_true, label = \"Ground Truth\")\n", + " ax.plot(x_plot, y_pred, label = \"Fitted\")\n", + " ax.scatter(x_train[0], y_train)\n", + " ax.scatter(x_test[0], y_test)\n", + " ax.legend()\n", + "\n", + "def animate_3d(i):\n", + "\n", + " y_true = w[0] * xx + w[1] * yy + w[2]\n", + " w_pred = w_history[i]\n", + " y_pred = w_pred[0] * xx + w_pred[1] * yy + w_pred[2]\n", + "\n", + " ax.clear()\n", + " ax.azim = angles[i]\n", + " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", + " ax.plot_surface(xx, yy, y_true, alpha=0.5, label = \"Ground Truth\")\n", + " ax.plot_surface(xx, yy, y_pred, alpha=0.2, label = \"Fitted\")\n", + " ax.scatter(x_train[0], x_train[1], y_train.reshape(-1,1))\n", + " ax.scatter(x_test[0], x_test[1], y_test.reshape(-1,1))\n", + " # ax.legend()\n" + ], + "metadata": { + "id": "CVX4Ra-0ErXc" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "np.random.seed(30)" + ], + "metadata": { + "id": "gUtP_kHsYabX" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "class LinearRegression():\n", + " def __init__(self, dim, lr = 0.1):\n", + " assert isinstance\n", + " self.lr = lr\n", + " self.w = np.zeros((dim,1))\n", + " self.grads = {\"dw\": np.zeros((dim))}\n", + "\n", + " def forward(self, x):\n", + " y = self.w.T @ x\n", + " return y\n", + " \n", + " def backward(self, x, y_hat, y):\n", + " assert y_hat.shape == y.shape\n", + " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", + " assert self.grads[\"dw\"].shape == self.w.shape\n", + " \n", + " # print(self.grads[\"dw\"])\n", + "\n", + " def optimize(self):\n", + " self.w = self.w - self.lr * self.grads[\"dw\"]" + ], + "metadata": { + "id": "j2Sj1PxsZ7hX" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Data from the same distribution" + ], + "metadata": { + "id": "zW-t5SBb3-ss" + } + }, + { + "cell_type": "code", + "source": [ + "# Hyperparameters\n", + "num_samples = 50\n", + "num_train = int(0.7 * num_samples)\n", + "num_epochs = 30\n", + "\n", + "# Trying to fit the line y = Ax + B\n", + "w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", + "print(f\"A {w[0]}\")\n", + "print(f\"B {w[1]}\")\n", + "\n", + "# Generate training data\n", + "x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", + "ones = np.ones((num_samples, 1))\n", + "x_stack = np.hstack([x, ones])\n", + "\n", + "\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train \n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = 2, lr = 0.5)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 2 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 560 + }, + "id": "71oppo-CZFZG", + "outputId": "3ed98eca-d057-4bad-a946-dd987669d9ef" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "A [2.]\n", + "B [2.]\n", + "Epoch 0 | Train Loss 82.25494964307106 | Test Loss 12.530375379500228\n", + "Epoch 2 | Train Loss 17.376012504579442 | Test Loss 3.154638242567267\n", + "Epoch 4 | Train Loss 6.956327722693647 | Test Loss 1.2692928110230237\n", + "Epoch 6 | Train Loss 3.224882117013539 | Test Loss 0.5785176772257331\n", + "Epoch 8 | Train Loss 1.5261102992342335 | Test Loss 0.27142397409351354\n", + "Epoch 10 | Train Loss 0.724097788298985 | Test Loss 0.12834980491917516\n", + "Epoch 12 | Train Loss 0.34367807531591266 | Test Loss 0.060843440641133104\n", + "Epoch 14 | Train Loss 0.1631264675584223 | Test Loss 0.028866509791083687\n", + "Epoch 16 | Train Loss 0.07742822365786244 | Test Loss 0.013699376650671533\n", + "Epoch 18 | Train Loss 0.03675144705394587 | Test Loss 0.00650207098681876\n", + "Epoch 20 | Train Loss 0.01744414255609919 | Test Loss 0.003086158976244471\n", + "Epoch 22 | Train Loss 0.008279894726455541 | Test Loss 0.0014648408256308387\n", + "Epoch 24 | Train Loss 0.003930067445239355 | Test Loss 0.0006952876964168519\n", + "Epoch 26 | Train Loss 0.0018654138291502296 | Test Loss 0.00033001930877197806\n", + "Epoch 28 | Train Loss 0.0008854221467041258 | Test Loss 0.00015664423038941943\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "x_plot = np.linspace(-1,1,10)\n", + "fig = plt.figure()\n", + "ax = plt.subplot()\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "id": "9wCVKa6-uJdU", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "outputId": "7cc9b496-0dcf-4a27-fca0-6ced838ed6d7" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Solved using Least Squares and compare to SGD" + ], + "metadata": { + "id": "wK8HgWc54MbV" + } + }, + { + "cell_type": "code", + "source": [ + "W = np.linalg.inv(x_train @ x_train.T) @ x_train @ (y_train.T)\n", + "\n", + "print(W)\n", + "print(model.w)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4tusHihBdDCS", + "outputId": "2cdfd51a-c1b3-41fe-c28c-c7e0f7fb9852" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[[2.]\n", + " [2.]]\n", + "[[1.9916692 ]\n", + " [1.99888494]]\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Data from different distribution (Overfitting)" + ], + "metadata": { + "id": "z3O-ugF74jgk" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "# Should we generate new data or use the old data for comparison?\n", + "\n", + "# # Hyperparameters\n", + "# num_samples = 100\n", + "# num_train = int(0.7 * num_samples)\n", + "# num_epochs = 100\n", + "\n", + "# # Trying to fit the line y = Ax + B\n", + "# w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", + "# print(f\"A {w[0]}\")\n", + "# print(f\"B {w[1]}\")\n", + "\n", + "# # Generate training data\n", + "# x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", + "# ones = np.ones((num_samples, 1))\n", + "# x_stack = np.hstack([x, ones])\n", + "\n", + "# Add noise to both train and test\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train + np.random.normal(loc = 0, scale = 0.1, size = num_train)\n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.6, size = num_samples - num_train)\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = 2, lr = 0.5)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 2 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 525 + }, + "id": "GMjA2oY-4Lf8", + "outputId": "6fd28364-4637-4223-972b-668d47f9fe12" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 81.91031959207034 | Test Loss 15.206417713180077\n", + "Epoch 2 | Train Loss 17.7634895164587 | Test Loss 5.820509127604954\n", + "Epoch 4 | Train Loss 7.245263046946594 | Test Loss 3.9453099633235054\n", + "Epoch 6 | Train Loss 3.44046248665259 | Test Loss 3.281546224113068\n", + "Epoch 8 | Train Loss 1.7052884307321203 | Test Loss 3.0001380259751276\n", + "Epoch 10 | Train Loss 0.8859031197203339 | Test Loss 2.877207877496019\n", + "Epoch 12 | Train Loss 0.4972317484039249 | Test Loss 2.8245002955637446\n", + "Epoch 14 | Train Loss 0.31276314034526653 | Test Loss 2.8030958469957525\n", + "Epoch 16 | Train Loss 0.2252056649766091 | Test Loss 2.7953767630098296\n", + "Epoch 18 | Train Loss 0.18364639950425643 | Test Loss 2.793385095401474\n", + "Epoch 20 | Train Loss 0.16392021995116995 | Test Loss 2.793589996259956\n", + "Epoch 22 | Train Loss 0.15455715229253905 | Test Loss 2.7944793446513407\n", + "Epoch 24 | Train Loss 0.15011295480911402 | Test Loss 2.7954471081023726\n", + "Epoch 26 | Train Loss 0.14800350820084965 | Test Loss 2.7962823550385014\n", + "Epoch 28 | Train Loss 0.14700225544127865 | Test Loss 2.7969377763062377\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "x_plot = np.linspace(-1,1,10)\n", + "fig = plt.figure()\n", + "ax = plt.subplot()\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "-5p2tuxP6Jza", + "outputId": "d8c8b4e9-6429-4af2-da81-8418f032fe96" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### 3D multiple regression with high learning rate" + ], + "metadata": { + "id": "OaNvlQgzIRhA" + } + }, + { + "cell_type": "code", + "source": [ + "# Hyperparameters\n", + "num_samples = 100\n", + "num_train = int(0.7 * num_samples)\n", + "num_epochs = 100\n", + "dim = 3\n", + "\n", + "# Trying to fit the line y = Ax1 + Bx2 + c\n", + "w = np.random.randint(-3, 3, size = (dim,1)).astype(float)\n", + "\n", + "# Generate training data\n", + "x = np.random.normal(loc = 0, scale = 1, size = (num_samples,2))\n", + "ones = np.ones((num_samples, 1))\n", + "x_stack = np.hstack([x, ones])\n", + "\n", + "\n", + "x_train = x_stack[:num_train].T\n", + "y_train = w.T @ x_train\n", + "\n", + "\n", + "x_test = x_stack[num_train:].T\n", + "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.2 , size = num_samples - num_train)\n", + "\n", + "\n", + "\n", + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = dim, lr = 2)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 10 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 450 + }, + "id": "cgvqVAOiw-Kn", + "outputId": "19af795b-caf1-4c53-8cda-8756ceeeed71" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 12.698436970922991\n", + "Epoch 10 | Train Loss 746.3185411858192 | Test Loss 358.562608321611\n", + "Epoch 20 | Train Loss 24419.323783752887 | Test Loss 11749.26328932645\n", + "Epoch 30 | Train Loss 800867.9318070416 | Test Loss 384943.9910339218\n", + "Epoch 40 | Train Loss 26266251.698730588 | Test Loss 12621262.851923324\n", + "Epoch 50 | Train Loss 861460553.6207652 | Test Loss 413915326.3017189\n", + "Epoch 60 | Train Loss 28253528351.36185 | Test Loss 13575106812.11293\n", + "Epoch 70 | Train Loss 926637744424.7832 | Test Loss 445224984161.656\n", + "Epoch 80 | Train Loss 30391160307998.715 | Test Loss 14602144378033.883\n", + "Epoch 90 | Train Loss 996746172302559.5 | Test Loss 478909994660501.94\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Do you want to rotate the 3D plane??\n", + "angles = np.linspace(-60,60, num_epochs)\n", + "fig = plt.figure()\n", + "ax = fig.gca(projection='3d')\n", + "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "1beKSQbzE8PL", + "outputId": "59fa05ad-aabb-44ca-b395-08c6574282c4" + }, + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Lower the learning rate" + ], + "metadata": { + "id": "FLs0b32kIrV4" + } + }, + { + "cell_type": "code", + "source": [ + "train_loss_history = []\n", + "test_loss_history = []\n", + "w_history = []\n", + "\n", + "\n", + "model = LinearRegression(dim = dim, lr = 0.1)\n", + "\n", + "for i in range(num_epochs):\n", + " y_hat = model.forward(x_train)\n", + " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", + "\n", + " w_history.append(model.w)\n", + "\n", + " model.backward(x_train,y_hat,y_train)\n", + " model.optimize()\n", + "\n", + " y_hat = model.forward(x_test)\n", + " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + "\n", + " train_loss_history.append(train_loss)\n", + " test_loss_history.append(test_loss)\n", + "\n", + " if i % 10 == 0:\n", + " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", + "\n", + "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", + "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", + "plt.legend()\n", + "plt.show()" + ], + "metadata": { + "id": "-j3M08gvxUSn", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 439 + }, + "outputId": "1ea24389-310f-46d1-df7a-068aaae52eec" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 8.095125244530212\n", + "Epoch 10 | Train Loss 4.346296963406692 | Test Loss 1.357191290987867\n", + "Epoch 20 | Train Loss 0.6354422722047353 | Test Loss 0.577448546725004\n", + "Epoch 30 | Train Loss 0.10841552249188971 | Test Loss 0.5003814236148908\n", + "Epoch 40 | Train Loss 0.021006468804432007 | Test Loss 0.5035382295431836\n", + "Epoch 50 | Train Loss 0.004423983911951978 | Test Loss 0.5109523052179242\n", + "Epoch 60 | Train Loss 0.0009763636539296937 | Test Loss 0.5153711624316784\n", + "Epoch 70 | Train Loss 0.00022076073931739313 | Test Loss 0.5175898522946066\n", + "Epoch 80 | Train Loss 5.0521477933667895e-05 | Test Loss 0.5186517866852555\n", + "Epoch 90 | Train Loss 1.163119776227275e-05 | Test Loss 0.5191535958691665\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Do you want to rotate the 3D plane??\n", + "angles = np.linspace(-60,60, num_epochs)\n", + "fig = plt.figure()\n", + "ax = fig.gca(projection='3d')\n", + "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", + "plt.close()\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 310 + }, + "id": "yMZbHPvgFFmH", + "outputId": "dbba73a4-2773-4c73-9e12-186aaf84aab6" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "# function that draws each frame of the animation\n", + "from matplotlib.animation import FuncAnimation\n", + "from matplotlib import rc\n", + "rc('animation', html='html5')\n", + "lr = LinearRegression(3, lr = 0.8)\n", + "losses = []\n", + "w = np.array([-2,2,2]).reshape(3, 1)\n", + "x = np.random.rand(100,2)\n", + "x_stack = np.hstack([x, np.ones((x.shape[0], 1))]).T\n", + "y = np.sum(w * x_stack, axis = 0, keepdims=True).astype(float)\n", + "y_test = y + np.random.normal(0, scale = 0.1, size =y.shape)\n", + "x = x_stack\n", + "fig = plt.figure()\n", + "plt3d = fig.gca(projection='3d')\n", + "plt.close()\n", + "def init():\n", + " pass\n", + "def animate(i):\n", + "\n", + "\n", + " y_hat = lr.forward(x)\n", + " plt3d.clear()\n", + " plt3d.set_xlim(xmin= 0 ,xmax = 1)\n", + " plt3d.set_ylim(ymin = 0 , ymax = 1)\n", + " plt3d.set_zlim(zmin = 0, zmax = 4)\n", + " plt3d.set_title(f\"Epoch {i} Weight {lr.w}\")\n", + " xx, yy = np.meshgrid(range(2),range(2))\n", + "\n", + " z = w[0] * xx + w[1] * yy + w[2]\n", + " z_pred = lr.w[0] * xx + lr.w[1] * yy + lr.w[2]\n", + " # plot the surface\n", + "\n", + " plt3d.plot_surface( xx, yy, z, alpha=0.5)\n", + " plt3d.plot_surface( xx, yy, z_pred, alpha=0.2)\n", + " plt3d.scatter(x[0], x[1], y)\n", + " # plt3d.plot_surface(xx, yy, lr.w[-1].reshape(-1,1), alpha=0.2)\n", + "\n", + "\n", + " loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", + " losses.append(loss)\n", + " lr.backward(x,y_hat,y_test)\n", + " lr.optimize()\n", + "\n", + "# run the animation\n", + "ani = FuncAnimation(fig, animate, frames=100, init_func=init, interval=20,)" + ], + "metadata": { + "id": "mBAHqPPhvI4E" + }, + "execution_count": 14, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "ani" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 518 + }, + "id": "O2oDLMGLwNFD", + "outputId": "dcdb29bb-46fa-4c94-fe26-cf8299cc4506" + }, + "execution_count": 15, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", + "The `xmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `left` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", + "The `xmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `right` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", + "The `ymin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", + "The `ymax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", + "The `zmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", + "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", + "The `zmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ] + } + ] +} \ No newline at end of file From 96842a2e418cbe7af8c6333e0966a13cf6aed5ec Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Sun, 31 Jul 2022 22:07:39 -0700 Subject: [PATCH 45/76] delete file --- notebooks/linear_regression_with_sgd.ipynb | 21660 ------------------- 1 file changed, 21660 deletions(-) delete mode 100644 notebooks/linear_regression_with_sgd.ipynb diff --git a/notebooks/linear_regression_with_sgd.ipynb b/notebooks/linear_regression_with_sgd.ipynb deleted file mode 100644 index 43c5fb2..0000000 --- a/notebooks/linear_regression_with_sgd.ipynb +++ /dev/null @@ -1,21660 +0,0 @@ -{ - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Linear Regression.ipynb", - "provenance": [], - "collapsed_sections": [], - "authorship_tag": "ABX9TyNRx6gNEqYURZyKqPxPjDA4", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "id": "ku4r-K4GQXEN" - }, - "outputs": [], - "source": [ - "## Import the usual libraries\n", - "import torch\n", - "import torchvision\n", - "import torch.nn as nn\n", - "from torchvision import datasets, models, transforms\n", - "import os\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "from matplotlib.animation import FuncAnimation\n", - "from matplotlib import rc\n", - "rc('animation', html='html5')\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "source": [ - "def init():\n", - " pass\n", - " \n", - "def animate_2d(i):\n", - "\n", - " y_true = w[0] * x_plot + w[1] \n", - " w_pred = w_history[i]\n", - " y_pred = w_pred[0] * x_plot + w_pred[1] \n", - " ax.clear()\n", - " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", - " ax.plot(x_plot, y_true, label = \"Ground Truth\")\n", - " ax.plot(x_plot, y_pred, label = \"Fitted\")\n", - " ax.scatter(x_train[0], y_train)\n", - " ax.scatter(x_test[0], y_test)\n", - " ax.legend()\n", - "\n", - "def animate_3d(i):\n", - "\n", - " y_true = w[0] * xx + w[1] * yy + w[2]\n", - " w_pred = w_history[i]\n", - " y_pred = w_pred[0] * xx + w_pred[1] * yy + w_pred[2]\n", - "\n", - " ax.clear()\n", - " ax.azim = angles[i]\n", - " ax.set_title(f\"Epoch {i} Weight {w_pred}\")\n", - " ax.plot_surface(xx, yy, y_true, alpha=0.5, label = \"Ground Truth\")\n", - " ax.plot_surface(xx, yy, y_pred, alpha=0.2, label = \"Fitted\")\n", - " ax.scatter(x_train[0], x_train[1], y_train.reshape(-1,1))\n", - " ax.scatter(x_test[0], x_test[1], y_test.reshape(-1,1))\n", - " # ax.legend()\n" - ], - "metadata": { - "id": "CVX4Ra-0ErXc" - }, - "execution_count": 2, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "np.random.seed(30)" - ], - "metadata": { - "id": "gUtP_kHsYabX" - }, - "execution_count": 3, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "class LinearRegression():\n", - " def __init__(self, dim, lr = 0.1):\n", - " assert isinstance\n", - " self.lr = lr\n", - " self.w = np.zeros((dim,1))\n", - " self.grads = {\"dw\": np.zeros((dim))}\n", - "\n", - " def forward(self, x):\n", - " y = self.w.T @ x\n", - " return y\n", - " \n", - " def backward(self, x, y_hat, y):\n", - " assert y_hat.shape == y.shape\n", - " self.grads[\"dw\"] = (1 / x.shape[1]) * ((y_hat - y) @ x.T).T\n", - " assert self.grads[\"dw\"].shape == self.w.shape\n", - " \n", - " # print(self.grads[\"dw\"])\n", - "\n", - " def optimize(self):\n", - " self.w = self.w - self.lr * self.grads[\"dw\"]" - ], - "metadata": { - "id": "j2Sj1PxsZ7hX" - }, - "execution_count": 4, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "### Data from the same distribution" - ], - "metadata": { - "id": "zW-t5SBb3-ss" - } - }, - { - "cell_type": "code", - "source": [ - "# Hyperparameters\n", - "num_samples = 50\n", - "num_train = int(0.7 * num_samples)\n", - "num_epochs = 30\n", - "\n", - "# Trying to fit the line y = Ax + B\n", - "w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", - "print(f\"A {w[0]}\")\n", - "print(f\"B {w[1]}\")\n", - "\n", - "# Generate training data\n", - "x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", - "ones = np.ones((num_samples, 1))\n", - "x_stack = np.hstack([x, ones])\n", - "\n", - "\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train \n", - "\n", - "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test\n", - "\n", - "\n", - "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = 2, lr = 0.5)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 2 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 560 - }, - "id": "71oppo-CZFZG", - "outputId": "3ed98eca-d057-4bad-a946-dd987669d9ef" - }, - "execution_count": 5, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "A [2.]\n", - "B [2.]\n", - "Epoch 0 | Train Loss 82.25494964307106 | Test Loss 12.530375379500228\n", - "Epoch 2 | Train Loss 17.376012504579442 | Test Loss 3.154638242567267\n", - "Epoch 4 | Train Loss 6.956327722693647 | Test Loss 1.2692928110230237\n", - "Epoch 6 | Train Loss 3.224882117013539 | Test Loss 0.5785176772257331\n", - "Epoch 8 | Train Loss 1.5261102992342335 | Test Loss 0.27142397409351354\n", - "Epoch 10 | Train Loss 0.724097788298985 | Test Loss 0.12834980491917516\n", - "Epoch 12 | Train Loss 0.34367807531591266 | Test Loss 0.060843440641133104\n", - "Epoch 14 | Train Loss 0.1631264675584223 | Test Loss 0.028866509791083687\n", - "Epoch 16 | Train Loss 0.07742822365786244 | Test Loss 0.013699376650671533\n", - "Epoch 18 | Train Loss 0.03675144705394587 | Test Loss 0.00650207098681876\n", - "Epoch 20 | Train Loss 0.01744414255609919 | Test Loss 0.003086158976244471\n", - "Epoch 22 | Train Loss 0.008279894726455541 | Test Loss 0.0014648408256308387\n", - "Epoch 24 | Train Loss 0.003930067445239355 | Test Loss 0.0006952876964168519\n", - "Epoch 26 | Train Loss 0.0018654138291502296 | Test Loss 0.00033001930877197806\n", - "Epoch 28 | Train Loss 0.0008854221467041258 | Test Loss 0.00015664423038941943\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } - } - ] - }, - { - "cell_type": "code", - "source": [ - "x_plot = np.linspace(-1,1,10)\n", - "fig = plt.figure()\n", - "ax = plt.subplot()\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], - "metadata": { - "id": "9wCVKa6-uJdU", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 - }, - "outputId": "7cc9b496-0dcf-4a27-fca0-6ced838ed6d7" - }, - "execution_count": 6, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 6 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### Solved using Least Squares and compare to SGD" - ], - "metadata": { - "id": "wK8HgWc54MbV" - } - }, - { - "cell_type": "code", - "source": [ - "W = np.linalg.inv(x_train @ x_train.T) @ x_train @ (y_train.T)\n", - "\n", - "print(W)\n", - "print(model.w)" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "4tusHihBdDCS", - "outputId": "2cdfd51a-c1b3-41fe-c28c-c7e0f7fb9852" - }, - "execution_count": 7, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[[2.]\n", - " [2.]]\n", - "[[1.9916692 ]\n", - " [1.99888494]]\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### Data from different distribution (Overfitting)" - ], - "metadata": { - "id": "z3O-ugF74jgk" - } - }, - { - "cell_type": "code", - "source": [ - "\n", - "# Should we generate new data or use the old data for comparison?\n", - "\n", - "# # Hyperparameters\n", - "# num_samples = 100\n", - "# num_train = int(0.7 * num_samples)\n", - "# num_epochs = 100\n", - "\n", - "# # Trying to fit the line y = Ax + B\n", - "# w = np.random.randint(-3, 3, size = (2,1)).astype(float)\n", - "# print(f\"A {w[0]}\")\n", - "# print(f\"B {w[1]}\")\n", - "\n", - "# # Generate training data\n", - "# x = np.random.normal(loc = 0, scale = 0.5, size = (num_samples,1))\n", - "# ones = np.ones((num_samples, 1))\n", - "# x_stack = np.hstack([x, ones])\n", - "\n", - "# Add noise to both train and test\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train + np.random.normal(loc = 0, scale = 0.1, size = num_train)\n", - "\n", - "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.6, size = num_samples - num_train)\n", - "\n", - "\n", - "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = 2, lr = 0.5)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 2 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 525 - }, - "id": "GMjA2oY-4Lf8", - "outputId": "6fd28364-4637-4223-972b-668d47f9fe12" - }, - "execution_count": 8, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Epoch 0 | Train Loss 81.91031959207034 | Test Loss 15.206417713180077\n", - "Epoch 2 | Train Loss 17.7634895164587 | Test Loss 5.820509127604954\n", - "Epoch 4 | Train Loss 7.245263046946594 | Test Loss 3.9453099633235054\n", - "Epoch 6 | Train Loss 3.44046248665259 | Test Loss 3.281546224113068\n", - "Epoch 8 | Train Loss 1.7052884307321203 | Test Loss 3.0001380259751276\n", - "Epoch 10 | Train Loss 0.8859031197203339 | Test Loss 2.877207877496019\n", - "Epoch 12 | Train Loss 0.4972317484039249 | Test Loss 2.8245002955637446\n", - "Epoch 14 | Train Loss 0.31276314034526653 | Test Loss 2.8030958469957525\n", - "Epoch 16 | Train Loss 0.2252056649766091 | Test Loss 2.7953767630098296\n", - "Epoch 18 | Train Loss 0.18364639950425643 | Test Loss 2.793385095401474\n", - "Epoch 20 | Train Loss 0.16392021995116995 | Test Loss 2.793589996259956\n", - "Epoch 22 | Train Loss 0.15455715229253905 | Test Loss 2.7944793446513407\n", - "Epoch 24 | Train Loss 0.15011295480911402 | Test Loss 2.7954471081023726\n", - "Epoch 26 | Train Loss 0.14800350820084965 | Test Loss 2.7962823550385014\n", - "Epoch 28 | Train Loss 0.14700225544127865 | Test Loss 2.7969377763062377\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } - } - ] - }, - { - "cell_type": "code", - "source": [ - "x_plot = np.linspace(-1,1,10)\n", - "fig = plt.figure()\n", - "ax = plt.subplot()\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_2d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 - }, - "id": "-5p2tuxP6Jza", - "outputId": "d8c8b4e9-6429-4af2-da81-8418f032fe96" - }, - "execution_count": 9, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 9 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### 3D multiple regression with high learning rate" - ], - "metadata": { - "id": "OaNvlQgzIRhA" - } - }, - { - "cell_type": "code", - "source": [ - "# Hyperparameters\n", - "num_samples = 100\n", - "num_train = int(0.7 * num_samples)\n", - "num_epochs = 100\n", - "dim = 3\n", - "\n", - "# Trying to fit the line y = Ax1 + Bx2 + c\n", - "w = np.random.randint(-3, 3, size = (dim,1)).astype(float)\n", - "\n", - "# Generate training data\n", - "x = np.random.normal(loc = 0, scale = 1, size = (num_samples,2))\n", - "ones = np.ones((num_samples, 1))\n", - "x_stack = np.hstack([x, ones])\n", - "\n", - "\n", - "x_train = x_stack[:num_train].T\n", - "y_train = w.T @ x_train\n", - "\n", - "\n", - "x_test = x_stack[num_train:].T\n", - "y_test = w.T @ x_test + np.random.normal(loc = 0, scale = 0.2 , size = num_samples - num_train)\n", - "\n", - "\n", - "\n", - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = dim, lr = 2)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 10 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 450 - }, - "id": "cgvqVAOiw-Kn", - "outputId": "19af795b-caf1-4c53-8cda-8756ceeeed71" - }, - "execution_count": 10, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 12.698436970922991\n", - "Epoch 10 | Train Loss 746.3185411858192 | Test Loss 358.562608321611\n", - "Epoch 20 | Train Loss 24419.323783752887 | Test Loss 11749.26328932645\n", - "Epoch 30 | Train Loss 800867.9318070416 | Test Loss 384943.9910339218\n", - "Epoch 40 | Train Loss 26266251.698730588 | Test Loss 12621262.851923324\n", - "Epoch 50 | Train Loss 861460553.6207652 | Test Loss 413915326.3017189\n", - "Epoch 60 | Train Loss 28253528351.36185 | Test Loss 13575106812.11293\n", - "Epoch 70 | Train Loss 926637744424.7832 | Test Loss 445224984161.656\n", - "Epoch 80 | Train Loss 30391160307998.715 | Test Loss 14602144378033.883\n", - "Epoch 90 | Train Loss 996746172302559.5 | Test Loss 478909994660501.94\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } - } - ] - }, - { - "cell_type": "code", - "source": [ - "# Do you want to rotate the 3D plane??\n", - "angles = np.linspace(-60,60, num_epochs)\n", - "fig = plt.figure()\n", - "ax = fig.gca(projection='3d')\n", - "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 - }, - "id": "1beKSQbzE8PL", - "outputId": "59fa05ad-aabb-44ca-b395-08c6574282c4" - }, - "execution_count": 11, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 11 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "### Lower the learning rate" - ], - "metadata": { - "id": "FLs0b32kIrV4" - } - }, - { - "cell_type": "code", - "source": [ - "train_loss_history = []\n", - "test_loss_history = []\n", - "w_history = []\n", - "\n", - "\n", - "model = LinearRegression(dim = dim, lr = 0.1)\n", - "\n", - "for i in range(num_epochs):\n", - " y_hat = model.forward(x_train)\n", - " train_loss = 1/2 * ((y_train - y_hat) ** 2).sum()\n", - "\n", - " w_history.append(model.w)\n", - "\n", - " model.backward(x_train,y_hat,y_train)\n", - " model.optimize()\n", - "\n", - " y_hat = model.forward(x_test)\n", - " test_loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - "\n", - " train_loss_history.append(train_loss)\n", - " test_loss_history.append(test_loss)\n", - "\n", - " if i % 10 == 0:\n", - " print(f\"Epoch {i} | Train Loss {train_loss} | Test Loss {test_loss}\")\n", - "\n", - "plt.plot(range(num_epochs), train_loss_history, label = \"Training\")\n", - "plt.plot(range(num_epochs), test_loss_history, label = \"Test\")\n", - "plt.legend()\n", - "plt.show()" - ], - "metadata": { - "id": "-j3M08gvxUSn", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 439 - }, - "outputId": "1ea24389-310f-46d1-df7a-068aaae52eec" - }, - "execution_count": 12, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Epoch 0 | Train Loss 34.29973987032996 | Test Loss 8.095125244530212\n", - "Epoch 10 | Train Loss 4.346296963406692 | Test Loss 1.357191290987867\n", - "Epoch 20 | Train Loss 0.6354422722047353 | Test Loss 0.577448546725004\n", - "Epoch 30 | Train Loss 0.10841552249188971 | Test Loss 0.5003814236148908\n", - "Epoch 40 | Train Loss 0.021006468804432007 | Test Loss 0.5035382295431836\n", - "Epoch 50 | Train Loss 0.004423983911951978 | Test Loss 0.5109523052179242\n", - "Epoch 60 | Train Loss 0.0009763636539296937 | Test Loss 0.5153711624316784\n", - "Epoch 70 | Train Loss 0.00022076073931739313 | Test Loss 0.5175898522946066\n", - "Epoch 80 | Train Loss 5.0521477933667895e-05 | Test Loss 0.5186517866852555\n", - "Epoch 90 | Train Loss 1.163119776227275e-05 | Test Loss 0.5191535958691665\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - } - } - ] - }, - { - "cell_type": "code", - "source": [ - "# Do you want to rotate the 3D plane??\n", - "angles = np.linspace(-60,60, num_epochs)\n", - "fig = plt.figure()\n", - "ax = fig.gca(projection='3d')\n", - "xx, yy = np.meshgrid(range(-2,3),range(-2,3))\n", - "plt.close()\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate_3d, frames=num_epochs, init_func=init, interval=200,)\n", - "ani" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 310 - }, - "id": "yMZbHPvgFFmH", - "outputId": "dbba73a4-2773-4c73-9e12-186aaf84aab6" - }, - "execution_count": 13, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 13 - } - ] - }, - { - "cell_type": "code", - "source": [ - "# function that draws each frame of the animation\n", - "from matplotlib.animation import FuncAnimation\n", - "from matplotlib import rc\n", - "rc('animation', html='html5')\n", - "lr = LinearRegression(3, lr = 0.8)\n", - "losses = []\n", - "w = np.array([-2,2,2]).reshape(3, 1)\n", - "x = np.random.rand(100,2)\n", - "x_stack = np.hstack([x, np.ones((x.shape[0], 1))]).T\n", - "y = np.sum(w * x_stack, axis = 0, keepdims=True).astype(float)\n", - "y_test = y + np.random.normal(0, scale = 0.1, size =y.shape)\n", - "x = x_stack\n", - "fig = plt.figure()\n", - "plt3d = fig.gca(projection='3d')\n", - "plt.close()\n", - "def init():\n", - " pass\n", - "def animate(i):\n", - "\n", - "\n", - " y_hat = lr.forward(x)\n", - " plt3d.clear()\n", - " plt3d.set_xlim(xmin= 0 ,xmax = 1)\n", - " plt3d.set_ylim(ymin = 0 , ymax = 1)\n", - " plt3d.set_zlim(zmin = 0, zmax = 4)\n", - " plt3d.set_title(f\"Epoch {i} Weight {lr.w}\")\n", - " xx, yy = np.meshgrid(range(2),range(2))\n", - "\n", - " z = w[0] * xx + w[1] * yy + w[2]\n", - " z_pred = lr.w[0] * xx + lr.w[1] * yy + lr.w[2]\n", - " # plot the surface\n", - "\n", - " plt3d.plot_surface( xx, yy, z, alpha=0.5)\n", - " plt3d.plot_surface( xx, yy, z_pred, alpha=0.2)\n", - " plt3d.scatter(x[0], x[1], y)\n", - " # plt3d.plot_surface(xx, yy, lr.w[-1].reshape(-1,1), alpha=0.2)\n", - "\n", - "\n", - " loss = 1/2 * ((y_test - y_hat) ** 2).sum()\n", - " losses.append(loss)\n", - " lr.backward(x,y_hat,y_test)\n", - " lr.optimize()\n", - "\n", - "# run the animation\n", - "ani = FuncAnimation(fig, animate, frames=100, init_func=init, interval=20,)" - ], - "metadata": { - "id": "mBAHqPPhvI4E" - }, - "execution_count": 14, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "ani" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 518 - }, - "id": "O2oDLMGLwNFD", - "outputId": "dcdb29bb-46fa-4c94-fe26-cf8299cc4506" - }, - "execution_count": 15, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", - "The `xmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `left` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n", - "The `xmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `right` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", - "The `ymin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:24: MatplotlibDeprecationWarning: \n", - "The `ymax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", - "The `zmin` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `bottom` instead.\n", - "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: MatplotlibDeprecationWarning: \n", - "The `zmax` argument was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use `top` instead.\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "execution_count": 15 - } - ] - } - ] -} \ No newline at end of file From 501d9351d8ac6eb0937bf5475d03ba3062d5a1a0 Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Thu, 4 Aug 2022 10:56:11 -0700 Subject: [PATCH 46/76] Updated README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 988b81f..c9b2abf 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ Contains code examples for all sorts of machine learning tasks and applications. + + + Linear Regression from Scratch + An implementation of linear regression from scratch using stochastic gradient descent + + + + Logistic Regression from Scratch From 369efaa49d252879015756b53e320f5fd4f521c6 Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Thu, 4 Aug 2022 10:57:18 -0700 Subject: [PATCH 47/76] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9b2abf..c906748 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Contains code examples for all sorts of machine learning tasks and applications. - + Linear Regression from Scratch An implementation of linear regression from scratch using stochastic gradient descent From 6ec3d5e55802b8a039378cd6571850b2196a08c9 Mon Sep 17 00:00:00 2001 From: Haaris Rahman Date: Thu, 4 Aug 2022 11:02:59 -0700 Subject: [PATCH 48/76] updated colab link --- notebooks/linear_regression.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks/linear_regression.ipynb b/notebooks/linear_regression.ipynb index 861b52a..e7bc359 100644 --- a/notebooks/linear_regression.ipynb +++ b/notebooks/linear_regression.ipynb @@ -7,7 +7,7 @@ "id": "view-in-github" }, "source": [ - "\"Open" + "\"Open" ] }, { From bf629c6ab9f416bae17e9fcd88fa7e97f5a4c1c3 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 18 Oct 2022 22:17:52 +0000 Subject: [PATCH 49/76] added codespace configs --- .devcontainer/Dockerfile | 22 ++++++ .devcontainer/add-notice.sh | 19 ++++++ .devcontainer/devcontainer.json | 55 +++++++++++++++ .devcontainer/noop.txt | 3 + notebooks/pytorch_hello_world.ipynb | 4 +- spec-file.txt | 101 ++++++++++++++++++++++++++++ 6 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/add-notice.sh create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/noop.txt create mode 100644 spec-file.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..5b878b0 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/python-3-miniconda/.devcontainer/base.Dockerfile + +FROM mcr.microsoft.com/vscode/devcontainers/miniconda:0-3 + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="none" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# Copy environment.yml (if found) to a temp location so we update the environment. Also +# copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists. +COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/ +RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \ + && rm -rf /tmp/conda-tmp + +# [Optional] Uncomment to install a different version of Python than the default +# RUN conda install -y python=3.6 \ +# && pip install --no-cache-dir pipx \ +# && pipx reinstall-all + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/add-notice.sh b/.devcontainer/add-notice.sh new file mode 100644 index 0000000..c292bc5 --- /dev/null +++ b/.devcontainer/add-notice.sh @@ -0,0 +1,19 @@ +# Display a notice when not running in GitHub Codespaces + +cat << 'EOF' > /usr/local/etc/vscode-dev-containers/conda-notice.txt +When using "conda" from outside of GitHub Codespaces, note the Anaconda repository +contains restrictions on commercial use that may impact certain organizations. See +https://aka.ms/vscode-remote/conda/miniconda + +EOF + +notice_script="$(cat << 'EOF' +if [ -t 1 ] && [ "${IGNORE_NOTICE}" != "true" ] && [ "${TERM_PROGRAM}" = "vscode" ] && [ "${CODESPACES}" != "true" ] && [ ! -f "$HOME/.config/vscode-dev-containers/conda-notice-already-displayed" ]; then + cat "/usr/local/etc/vscode-dev-containers/conda-notice.txt" + mkdir -p "$HOME/.config/vscode-dev-containers" + ((sleep 10s; touch "$HOME/.config/vscode-dev-containers/conda-notice-already-displayed") &) +fi +EOF +)" + +echo "${notice_script}" | tee -a /etc/bash.bashrc >> /etc/zsh/zshrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..421c5de --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,55 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/python-3-miniconda +{ + "name": "Miniconda (Python 3)", + "build": { + "context": "..", + "dockerfile": "Dockerfile", + "args": { + "NODE_VERSION": "16" + } + }, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "python.defaultInterpreterPath": "/opt/conda/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", + "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", + "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", + "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "python --version", + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "docker-in-docker": "latest", + "github-cli": "latest", + "homebrew": "latest", + "jupyterlab": "latest" + } +} diff --git a/.devcontainer/noop.txt b/.devcontainer/noop.txt new file mode 100644 index 0000000..abee195 --- /dev/null +++ b/.devcontainer/noop.txt @@ -0,0 +1,3 @@ +This file is copied into the container along with environment.yml* from the +parent folder. This is done to prevent the Dockerfile COPY instruction from +failing if no environment.yml is found. \ No newline at end of file diff --git a/notebooks/pytorch_hello_world.ipynb b/notebooks/pytorch_hello_world.ipynb index d60f8dd..abfec51 100644 --- a/notebooks/pytorch_hello_world.ipynb +++ b/notebooks/pytorch_hello_world.ipynb @@ -389,7 +389,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('play')", + "display_name": "Python 3.7.13 ('nlp')", "language": "python", "name": "python3" }, @@ -408,7 +408,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" } } }, diff --git a/spec-file.txt b/spec-file.txt new file mode 100644 index 0000000..5df10d3 --- /dev/null +++ b/spec-file.txt @@ -0,0 +1,101 @@ +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +@EXPLICIT +https://repo.anaconda.com/pkgs/main/linux-64/_libgcc_mutex-0.1-main.conda +https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-mkl.conda +https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2022.07.19-h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/intel-openmp-2021.4.0-h06a4308_3561.conda +https://repo.anaconda.com/pkgs/main/linux-64/ld_impl_linux-64-2.38-h1181459_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/libgfortran4-7.5.0-ha8ba4b0_17.conda +https://repo.anaconda.com/pkgs/main/linux-64/libstdcxx-ng-11.2.0-h1234567_1.conda +https://conda.anaconda.org/pytorch/noarch/pytorch-mutex-1.0-cuda.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/libgfortran-ng-7.5.0-ha8ba4b0_17.conda +https://repo.anaconda.com/pkgs/main/linux-64/libgomp-11.2.0-h1234567_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/mkl-2021.4.0-h06a4308_640.conda +https://repo.anaconda.com/pkgs/main/linux-64/_openmp_mutex-5.1-1_gnu.conda +https://repo.anaconda.com/pkgs/main/linux-64/libgcc-ng-11.2.0-h1234567_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/bzip2-1.0.8-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/cudatoolkit-11.3.1-h2bc3f7f_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/giflib-5.2.1-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/gmp-6.2.1-h295c915_3.conda +https://repo.anaconda.com/pkgs/main/linux-64/jpeg-9e-h7f8727e_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/lame-3.100-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libffi-3.3-he6710b0_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/libopus-1.3.1-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libsodium-1.0.18-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libtasn1-4.16.0-h27cfd23_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libunistring-0.9.10-h27cfd23_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libuv-1.40.0-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libvpx-1.7.0-h439df22_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libwebp-base-1.2.2-h7f8727e_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/lz4-c-1.9.3-h295c915_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/ncurses-6.3-h7f8727e_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/openh264-2.1.1-h4ff587b_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/openssl-1.1.1q-h7f8727e_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/x264-1!157.20191217-h7b6447c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/xz-5.2.5-h7f8727e_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/zlib-1.2.12-h7f8727e_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/libidn2-2.3.2-h7f8727e_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libpng-1.6.37-hbc83047_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/nettle-3.7.3-hbbd107a_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/readline-8.1.2-h7f8727e_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/tk-8.6.12-h1ccaba5_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/zeromq-4.3.4-h2531618_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/zstd-1.5.2-ha4553b6_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/freetype-2.11.0-h70c0345_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/gnutls-3.6.15-he1e5248_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libtiff-4.2.0-h2818925_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/sqlite-3.38.3-hc218d9a_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/ffmpeg-4.2.2-h20bf706_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/lcms2-2.12-h3be6417_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libwebp-1.2.2-h55f646e_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/python-3.7.13-h12debd9_0.conda +https://repo.anaconda.com/pkgs/main/noarch/backcall-0.2.0-pyhd3eb1b0_0.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/certifi-2022.6.15-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/charset-normalizer-2.0.4-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/debugpy-1.5.1-py37h295c915_0.conda +https://repo.anaconda.com/pkgs/main/noarch/decorator-5.1.1-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.4-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/idna-3.3-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/nest-asyncio-1.5.5-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/parso-0.8.3-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pickleshare-0.7.5-pyhd3eb1b0_1003.conda +https://repo.anaconda.com/pkgs/main/linux-64/pillow-9.0.1-py37h22f2fdc_0.conda +https://repo.anaconda.com/pkgs/main/noarch/ptyprocess-0.7.0-pyhd3eb1b0_2.conda +https://repo.anaconda.com/pkgs/main/noarch/pycparser-2.21-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pygments-2.11.2-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/pysocks-1.7.1-py37_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/pyzmq-22.3.0-py37h295c915_2.conda +https://repo.anaconda.com/pkgs/main/noarch/six-1.16.0-pyhd3eb1b0_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/tornado-6.1-py37h27cfd23_0.conda +https://repo.anaconda.com/pkgs/main/noarch/traitlets-5.1.1-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/noarch/typing_extensions-4.1.1-pyh06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/wcwidth-0.2.5-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/noarch/wheel-0.37.1-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/cffi-1.15.0-py37hd667e15_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.18.1-py37h06a4308_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.10.0-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/matplotlib-inline-0.1.2-pyhd3eb1b0_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/mkl-service-2.4.0-py37h7f8727e_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pexpect-4.8.0-pyhd3eb1b0_3.conda +https://repo.anaconda.com/pkgs/main/noarch/prompt-toolkit-3.0.20-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.2-pyhd3eb1b0_0.conda +https://conda.anaconda.org/pytorch/linux-64/pytorch-1.11.0-py3.7_cuda11.3_cudnn8.2.0_0.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/setuptools-61.2.0-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/brotlipy-0.7.0-py37h27cfd23_1003.conda +https://repo.anaconda.com/pkgs/main/linux-64/cryptography-37.0.1-py37h9ce1e76_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.31.1-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/jupyter_client-7.2.2-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.21.5-py37ha15fc14_3.conda +https://repo.anaconda.com/pkgs/main/linux-64/pip-21.2.2-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-6.9.1-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pyopenssl-22.0.0-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/urllib3-1.26.9-py37h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/noarch/requests-2.27.1-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.3.1-py37hd3c417c_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.2.2-py37h51133e4_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.21.5-py37h6c91a56_3.conda +https://repo.anaconda.com/pkgs/main/linux-64/scipy-1.7.3-py37hc147768_0.conda +https://conda.anaconda.org/pytorch/linux-64/torchaudio-0.11.0-py37_cu113.tar.bz2 +https://conda.anaconda.org/pytorch/linux-64/torchvision-0.12.0-py37_cu113.tar.bz2 From 76b6a5b247c920af6fd6024b7baf17b7cbc755a6 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 18 Oct 2022 23:01:10 +0000 Subject: [PATCH 50/76] change devcontainer --- .devcontainer/devcontainer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 421c5de..715c4c7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -49,7 +49,6 @@ "features": { "docker-in-docker": "latest", "github-cli": "latest", - "homebrew": "latest", - "jupyterlab": "latest" + "homebrew": "latest" } } From 7e01d01c197f0ea01230cc5ddfc2f49eab923ffd Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Wed, 19 Oct 2022 00:06:26 +0100 Subject: [PATCH 51/76] update devcontainer.json --- .devcontainer/devcontainer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 421c5de..715c4c7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -49,7 +49,6 @@ "features": { "docker-in-docker": "latest", "github-cli": "latest", - "homebrew": "latest", - "jupyterlab": "latest" + "homebrew": "latest" } } From 390b845118aeb86ca854a956f2661d59bdb28b06 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Wed, 19 Oct 2022 00:13:13 +0000 Subject: [PATCH 52/76] fix README --- README.md | 8 +++++++- notebooks/bow.ipynb | 26 +++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c906748..433d34f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # 🐙 ML Notebooks -Contains code examples for all sorts of machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. +This repo contains code examples for different machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. + +This repo supports Codespaces! +- Spin up a new instance by clicking on the green `"<> Code"` button followed by the `"Configure and create codespace"` option. Make sure to select the dev container config provided with this repo. This setups an environment with all the dependencies installed and ready to go. +- Once the codespace is full running, you can install all the libraries you will need to run the notebooks under the `notebooks` folder. Open up a terminal and simply run `conda create --name myenv --file spec-file.txt`. + +--- ## Getting Started diff --git a/notebooks/bow.ipynb b/notebooks/bow.ipynb index f5ca95e..ac21c42 100644 --- a/notebooks/bow.ipynb +++ b/notebooks/bow.ipynb @@ -178,7 +178,7 @@ { "data": { "text/plain": [ - "tensor([[-0.0033, 0.0215, 0.0117, -0.0360, -0.0223]], device='cuda:0',\n", + "tensor([[ 0.0091, 0.0229, 0.0100, -0.0029, -0.0295]], device='cuda:0',\n", " grad_fn=)" ] }, @@ -215,16 +215,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "ITER: 1 | train loss/sent: 1.4733 | train accuracy: 0.3636 | test accuracy: 0.4100\n", - "ITER: 2 | train loss/sent: 1.1213 | train accuracy: 0.6048 | test accuracy: 0.4158\n", - "ITER: 3 | train loss/sent: 0.9114 | train accuracy: 0.7110 | test accuracy: 0.4163\n", - "ITER: 4 | train loss/sent: 0.7690 | train accuracy: 0.7683 | test accuracy: 0.4127\n", - "ITER: 5 | train loss/sent: 0.6634 | train accuracy: 0.8077 | test accuracy: 0.4127\n", - "ITER: 6 | train loss/sent: 0.5827 | train accuracy: 0.8299 | test accuracy: 0.4036\n", - "ITER: 7 | train loss/sent: 0.5174 | train accuracy: 0.8572 | test accuracy: 0.4077\n", - "ITER: 8 | train loss/sent: 0.4638 | train accuracy: 0.8722 | test accuracy: 0.4018\n", - "ITER: 9 | train loss/sent: 0.4193 | train accuracy: 0.8840 | test accuracy: 0.4027\n", - "ITER: 10 | train loss/sent: 0.3814 | train accuracy: 0.8940 | test accuracy: 0.4009\n" + "ITER: 1 | train loss/sent: 1.4748 | train accuracy: 0.3672 | test accuracy: 0.4077\n", + "ITER: 2 | train loss/sent: 1.1211 | train accuracy: 0.6048 | test accuracy: 0.4176\n", + "ITER: 3 | train loss/sent: 0.9129 | train accuracy: 0.7140 | test accuracy: 0.4140\n", + "ITER: 4 | train loss/sent: 0.7690 | train accuracy: 0.7704 | test accuracy: 0.4072\n", + "ITER: 5 | train loss/sent: 0.6627 | train accuracy: 0.8070 | test accuracy: 0.4032\n", + "ITER: 6 | train loss/sent: 0.5817 | train accuracy: 0.8296 | test accuracy: 0.4059\n", + "ITER: 7 | train loss/sent: 0.5170 | train accuracy: 0.8540 | test accuracy: 0.4072\n", + "ITER: 8 | train loss/sent: 0.4637 | train accuracy: 0.8689 | test accuracy: 0.3986\n", + "ITER: 9 | train loss/sent: 0.4198 | train accuracy: 0.8853 | test accuracy: 0.3964\n", + "ITER: 10 | train loss/sent: 0.3816 | train accuracy: 0.8927 | test accuracy: 0.3977\n" ] } ], @@ -285,7 +285,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('nlp')", + "display_name": "nlp", "language": "python", "name": "python3" }, @@ -304,7 +304,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" } } }, From ac951593cc5d40a4cca03d73701b834957442fc6 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Wed, 19 Oct 2022 00:19:47 +0000 Subject: [PATCH 53/76] fix README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 433d34f..eac1cb0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ This repo contains code examples for different machine learning tasks and applic This repo supports Codespaces! - Spin up a new instance by clicking on the green `"<> Code"` button followed by the `"Configure and create codespace"` option. Make sure to select the dev container config provided with this repo. This setups an environment with all the dependencies installed and ready to go. -- Once the codespace is full running, you can install all the libraries you will need to run the notebooks under the `notebooks` folder. Open up a terminal and simply run `conda create --name myenv --file spec-file.txt`. +- Once the codespace is fully running, you can install all the libraries you will need to run the notebooks under the `/notebooks` folder. Open up a terminal and simply run `conda create --name myenv --file spec-file.txt` to install all the Python libraries including PyTorch. +- Activate your environment `conda activate myenv`. *You might need to run `conda init zsh` or whatever shell you are using... and then close + reopen terminal.* +- Finally you can try out if everything is working by opening a notebook such as `/notebooks/bow.ipynb`. --- From de05cfd53ddff333921063d81c53007ec2baab7d Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 30 Oct 2022 22:26:45 +0000 Subject: [PATCH 54/76] notebook changes --- notebooks/bow.ipynb | 38 ++++++++++++++-------------- notebooks/cbow.ipynb | 52 ++++++++++++++++++++++----------------- notebooks/deep_cbow.ipynb | 30 +++++++++++----------- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/notebooks/bow.ipynb b/notebooks/bow.ipynb index ac21c42..09d8741 100644 --- a/notebooks/bow.ipynb +++ b/notebooks/bow.ipynb @@ -20,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -65,7 +65,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -92,7 +92,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -172,17 +172,17 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[ 0.0091, 0.0229, 0.0100, -0.0029, -0.0295]], device='cuda:0',\n", + "tensor([[ 0.0124, 0.0164, -0.0182, -0.0014, -0.0120]], device='cuda:0',\n", " grad_fn=)" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -208,23 +208,23 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "ITER: 1 | train loss/sent: 1.4748 | train accuracy: 0.3672 | test accuracy: 0.4077\n", - "ITER: 2 | train loss/sent: 1.1211 | train accuracy: 0.6048 | test accuracy: 0.4176\n", - "ITER: 3 | train loss/sent: 0.9129 | train accuracy: 0.7140 | test accuracy: 0.4140\n", - "ITER: 4 | train loss/sent: 0.7690 | train accuracy: 0.7704 | test accuracy: 0.4072\n", - "ITER: 5 | train loss/sent: 0.6627 | train accuracy: 0.8070 | test accuracy: 0.4032\n", - "ITER: 6 | train loss/sent: 0.5817 | train accuracy: 0.8296 | test accuracy: 0.4059\n", - "ITER: 7 | train loss/sent: 0.5170 | train accuracy: 0.8540 | test accuracy: 0.4072\n", - "ITER: 8 | train loss/sent: 0.4637 | train accuracy: 0.8689 | test accuracy: 0.3986\n", - "ITER: 9 | train loss/sent: 0.4198 | train accuracy: 0.8853 | test accuracy: 0.3964\n", - "ITER: 10 | train loss/sent: 0.3816 | train accuracy: 0.8927 | test accuracy: 0.3977\n" + "ITER: 1 | train loss/sent: 1.4733 | train accuracy: 0.3631 | test accuracy: 0.4009\n", + "ITER: 2 | train loss/sent: 1.1216 | train accuracy: 0.6040 | test accuracy: 0.4118\n", + "ITER: 3 | train loss/sent: 0.9123 | train accuracy: 0.7117 | test accuracy: 0.4154\n", + "ITER: 4 | train loss/sent: 0.7688 | train accuracy: 0.7664 | test accuracy: 0.4140\n", + "ITER: 5 | train loss/sent: 0.6631 | train accuracy: 0.8065 | test accuracy: 0.4068\n", + "ITER: 6 | train loss/sent: 0.5814 | train accuracy: 0.8324 | test accuracy: 0.4059\n", + "ITER: 7 | train loss/sent: 0.5171 | train accuracy: 0.8507 | test accuracy: 0.4077\n", + "ITER: 8 | train loss/sent: 0.4640 | train accuracy: 0.8695 | test accuracy: 0.4036\n", + "ITER: 9 | train loss/sent: 0.4191 | train accuracy: 0.8830 | test accuracy: 0.3991\n", + "ITER: 10 | train loss/sent: 0.3818 | train accuracy: 0.8929 | test accuracy: 0.3964\n" ] } ], @@ -299,7 +299,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.7.13 (default, Mar 29 2022, 02:18:16) \n[GCC 7.5.0]" }, "orig_nbformat": 4, "vscode": { diff --git a/notebooks/cbow.ipynb b/notebooks/cbow.ipynb index d5605aa..42084f3 100644 --- a/notebooks/cbow.ipynb +++ b/notebooks/cbow.ipynb @@ -35,7 +35,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%capture\n", + "% % capture\n", "''' uncomment to download the data\n", "# download the files\n", "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/dev.txt\n", @@ -73,12 +73,13 @@ " data.append(line)\n", " return data\n", "\n", + "\n", "train_data = read_data('data/classes/train.txt')\n", "test_data = read_data('data/classes/test.txt')\n", "\n", "# creating the word and tag indices\n", "word_to_index = {}\n", - "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", "tag_to_index = {}\n", "\n", "# create word to index dictionary and tag to index dictionary from data\n", @@ -95,13 +96,15 @@ " if line[0] not in tag_to_index:\n", " tag_to_index[line[0]] = len(tag_to_index)\n", "\n", + "\n", "create_dict(train_data)\n", "create_dict(test_data, check_unk=True)\n", "\n", "# create word and tag tensors from data\n", "def create_tensor(data):\n", " for line in data:\n", - " yield([word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]])\n", + " yield ([word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]])\n", + "\n", "\n", "train_data = list(create_tensor(train_data))\n", "test_data = list(create_tensor(test_data))\n", @@ -140,12 +143,13 @@ " nn.init.xavier_uniform_(self.linear.weight)\n", "\n", " def forward(self, x):\n", - " emb = self.embedding(x) # seq x emb_size\n", - " out = torch.sum(emb, dim=0) # emb_size\n", - " out = out.view(1, -1) # reshape to (1, emb_size)\n", - " out = self.linear(out) # 1 x ntags\n", + " emb = self.embedding(x) # seq x emb_size\n", + " out = torch.sum(emb, dim=0) # emb_size\n", + " out = out.view(1, -1) # reshape to (1, emb_size)\n", + " out = self.linear(out) # 1 x ntags\n", " return out\n", "\n", + "\n", "EMB_SIZE = 64\n", "model = CBoW(number_of_words, number_of_tags, EMB_SIZE)\n", "criterion = torch.nn.CrossEntropyLoss()\n", @@ -173,16 +177,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "epoch: 1 | train loss/sent: 1.4129 | train accuracy: 0.3800 | test accuracy: 0.4081\n", - "epoch: 2 | train loss/sent: 0.8920 | train accuracy: 0.6526 | test accuracy: 0.3928\n", - "epoch: 3 | train loss/sent: 0.5189 | train accuracy: 0.8141 | test accuracy: 0.4041\n", - "epoch: 4 | train loss/sent: 0.3313 | train accuracy: 0.8860 | test accuracy: 0.3851\n", - "epoch: 5 | train loss/sent: 0.2154 | train accuracy: 0.9252 | test accuracy: 0.3774\n", - "epoch: 6 | train loss/sent: 0.1470 | train accuracy: 0.9498 | test accuracy: 0.3688\n", - "epoch: 7 | train loss/sent: 0.1067 | train accuracy: 0.9618 | test accuracy: 0.3805\n", - "epoch: 8 | train loss/sent: 0.0775 | train accuracy: 0.9733 | test accuracy: 0.3796\n", - "epoch: 9 | train loss/sent: 0.0565 | train accuracy: 0.9798 | test accuracy: 0.3710\n", - "epoch: 10 | train loss/sent: 0.0461 | train accuracy: 0.9837 | test accuracy: 0.3701\n" + "epoch: 1 | train loss/sent: 1.4111 | train accuracy: 0.3841 | test accuracy: 0.3982\n", + "epoch: 2 | train loss/sent: 0.8886 | train accuracy: 0.6522 | test accuracy: 0.3991\n", + "epoch: 3 | train loss/sent: 0.5147 | train accuracy: 0.8148 | test accuracy: 0.3950\n", + "epoch: 4 | train loss/sent: 0.3200 | train accuracy: 0.8878 | test accuracy: 0.3796\n", + "epoch: 5 | train loss/sent: 0.2148 | train accuracy: 0.9247 | test accuracy: 0.3738\n", + "epoch: 6 | train loss/sent: 0.1536 | train accuracy: 0.9466 | test accuracy: 0.3783\n", + "epoch: 7 | train loss/sent: 0.1097 | train accuracy: 0.9618 | test accuracy: 0.3638\n", + "epoch: 8 | train loss/sent: 0.0797 | train accuracy: 0.9716 | test accuracy: 0.3692\n", + "epoch: 9 | train loss/sent: 0.0568 | train accuracy: 0.9805 | test accuracy: 0.3661\n", + "epoch: 10 | train loss/sent: 0.0435 | train accuracy: 0.9853 | test accuracy: 0.3529\n" ] } ], @@ -200,7 +204,7 @@ " tag = torch.tensor([tag]).type(type)\n", " output = model(sentence)\n", " predicted = torch.argmax(output.data.detach()).item()\n", - " \n", + "\n", " loss = criterion(output, tag)\n", " total_loss += loss.item()\n", "\n", @@ -208,7 +212,8 @@ " loss.backward()\n", " optimizer.step()\n", "\n", - " if predicted == tag: train_correct+=1\n", + " if predicted == tag:\n", + " train_correct += 1\n", "\n", " # perform testing of the model\n", " model.eval()\n", @@ -217,8 +222,9 @@ " sentence = torch.tensor(sentence).type(type)\n", " output = model(sentence)\n", " predicted = torch.argmax(output.data.detach()).item()\n", - " if predicted == tag: test_correct += 1\n", - " \n", + " if predicted == tag:\n", + " test_correct += 1\n", + "\n", " # print model performance results\n", " log = f'epoch: {epoch+1} | ' \\\n", " f'train loss/sent: {total_loss/len(train_data):.4f} | ' \\\n", @@ -230,7 +236,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('nlp')", + "display_name": "nlp", "language": "python", "name": "python3" }, @@ -249,7 +255,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" } } }, diff --git a/notebooks/deep_cbow.ipynb b/notebooks/deep_cbow.ipynb index 2ec99e8..cd06efa 100644 --- a/notebooks/deep_cbow.ipynb +++ b/notebooks/deep_cbow.ipynb @@ -60,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -120,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -177,23 +177,23 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "epoch: 1 | train loss/sent: 1.4274 | train accuracy: 0.3632 | test accuracy: 0.4226\n", - "epoch: 2 | train loss/sent: 1.0286 | train accuracy: 0.5724 | test accuracy: 0.3887\n", - "epoch: 3 | train loss/sent: 0.6465 | train accuracy: 0.7621 | test accuracy: 0.4009\n", - "epoch: 4 | train loss/sent: 0.4007 | train accuracy: 0.8578 | test accuracy: 0.3869\n", - "epoch: 5 | train loss/sent: 0.2540 | train accuracy: 0.9114 | test accuracy: 0.3778\n", - "epoch: 6 | train loss/sent: 0.1746 | train accuracy: 0.9383 | test accuracy: 0.3769\n", - "epoch: 7 | train loss/sent: 0.1194 | train accuracy: 0.9601 | test accuracy: 0.3665\n", - "epoch: 8 | train loss/sent: 0.0805 | train accuracy: 0.9724 | test accuracy: 0.3747\n", - "epoch: 9 | train loss/sent: 0.0603 | train accuracy: 0.9789 | test accuracy: 0.3765\n", - "epoch: 10 | train loss/sent: 0.0426 | train accuracy: 0.9863 | test accuracy: 0.3701\n" + "epoch: 1 | train loss/sent: 1.4293 | train accuracy: 0.3765 | test accuracy: 0.3941\n", + "epoch: 2 | train loss/sent: 1.0343 | train accuracy: 0.5729 | test accuracy: 0.4127\n", + "epoch: 3 | train loss/sent: 0.6565 | train accuracy: 0.7583 | test accuracy: 0.3801\n", + "epoch: 4 | train loss/sent: 0.4013 | train accuracy: 0.8586 | test accuracy: 0.3783\n", + "epoch: 5 | train loss/sent: 0.2659 | train accuracy: 0.9079 | test accuracy: 0.3959\n", + "epoch: 6 | train loss/sent: 0.1747 | train accuracy: 0.9419 | test accuracy: 0.3787\n", + "epoch: 7 | train loss/sent: 0.1257 | train accuracy: 0.9573 | test accuracy: 0.3805\n", + "epoch: 8 | train loss/sent: 0.0860 | train accuracy: 0.9702 | test accuracy: 0.3719\n", + "epoch: 9 | train loss/sent: 0.0652 | train accuracy: 0.9768 | test accuracy: 0.3747\n", + "epoch: 10 | train loss/sent: 0.0434 | train accuracy: 0.9860 | test accuracy: 0.3887\n" ] } ], @@ -242,7 +242,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('nlp')", + "display_name": "nlp", "language": "python", "name": "python3" }, @@ -261,7 +261,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "7ade285f687a1ecab6f569c64721a8142b161535723b6a0ecd56d473b77660bf" + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" } } }, From ef43f3176de882218c1fff8832f77a82e581c6c7 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Thu, 3 Nov 2022 00:56:12 +0000 Subject: [PATCH 55/76] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eac1cb0..55b9706 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# 🐙 ML Notebooks +# 🐙 Machine Learning Notebooks -This repo contains code examples for different machine learning tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. +This repo contains machine learning notebooks for different tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. This repo supports Codespaces! - Spin up a new instance by clicking on the green `"<> Code"` button followed by the `"Configure and create codespace"` option. Make sure to select the dev container config provided with this repo. This setups an environment with all the dependencies installed and ready to go. From 14b668590b67b5cfaf3b728258b03c6ea0c45425 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 5 Nov 2022 19:40:36 +0000 Subject: [PATCH 56/76] added rough implementation of linear lm --- notebooks/cbow.ipynb | 22 ++- notebooks/deep_cbow.ipynb | 27 ++- notebooks/loglin-lm.ipynb | 392 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 433 insertions(+), 8 deletions(-) create mode 100644 notebooks/loglin-lm.ipynb diff --git a/notebooks/cbow.ipynb b/notebooks/cbow.ipynb index 42084f3..2e85e02 100644 --- a/notebooks/cbow.ipynb +++ b/notebooks/cbow.ipynb @@ -122,9 +122,21 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'torch' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_3236/4002993260.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# cpu or gpu\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdevice\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"cuda\"\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_available\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m\"cpu\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# create a simple neural network with embedding layer, bias, and xavier initialization\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mCBoW\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mModule\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'torch' is not defined" + ] + } + ], "source": [ "# cpu or gpu\n", "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", @@ -236,7 +248,7 @@ ], "metadata": { "kernelspec": { - "display_name": "nlp", + "display_name": "base", "language": "python", "name": "python3" }, @@ -250,12 +262,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.9.12 (main, Apr 5 2022, 06:56:58) \n[GCC 7.5.0]" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" } } }, diff --git a/notebooks/deep_cbow.ipynb b/notebooks/deep_cbow.ipynb index cd06efa..02a63aa 100644 --- a/notebooks/deep_cbow.ipynb +++ b/notebooks/deep_cbow.ipynb @@ -195,6 +195,27 @@ "epoch: 9 | train loss/sent: 0.0652 | train accuracy: 0.9768 | test accuracy: 0.3747\n", "epoch: 10 | train loss/sent: 0.0434 | train accuracy: 0.9860 | test accuracy: 0.3887\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Bad pipe message: %s [b'I7{\\xddYY9\\x10\\xe5', b\"\\xee\\x8a\\xf0\\xff\\xe6\\x1a\\xd2\\x00\\x00|\\xc0,\\xc00\\x00\\xa3\\x00\\x9f\\xcc\\xa9\\xcc\\xa8\\xcc\\xaa\\xc0\\xaf\\xc0\\xad\\xc0\\xa3\\xc0\\x9f\\xc0]\\xc0a\\xc0W\\xc0S\\xc0+\\xc0/\\x00\\xa2\\x00\\x9e\\xc0\\xae\\xc0\\xac\\xc0\\xa2\\xc0\\x9e\\xc0\\\\\\xc0`\\xc0V\\xc0R\\xc0$\\xc0(\\x00k\\x00j\\xc0#\\xc0'\\x00g\\x00@\\xc0\\n\\xc0\\x14\\x009\\x008\\xc0\\t\\xc0\\x13\\x003\\x00\", b'\\x9d\\xc0\\xa1\\xc0\\x9d\\xc0Q\\x00\\x9c\\xc0\\xa0\\xc0\\x9c\\xc0P\\x00=\\x00<\\x005\\x00/\\x00\\x9a\\x00\\x99\\xc0\\x07\\xc0\\x11\\x00\\x96\\x00\\x05\\x00\\xff\\x01\\x00\\x00j\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00']\n", + "Bad pipe message: %s [b'\\xe1\\x05', b'\\xb0\\x87g\\xc6U\\xd5G\\xa2.\\xd2\\xf7\\x05\\x9fL\\x00\\x00\\xa6\\xc0,\\xc0', b'\\xa3\\x00\\x9f\\xcc\\xa9\\xcc\\xa8\\xcc\\xaa\\xc0\\xaf\\xc0\\xad\\xc0\\xa3\\xc0\\x9f\\xc0]\\xc0a\\xc0W\\xc0S\\xc0+\\xc0/\\x00\\xa2\\x00\\x9e\\xc0\\xae\\xc0\\xac\\xc0\\xa2\\xc0\\x9e\\xc0\\\\\\xc0`\\xc0V']\n", + "Bad pipe message: %s [b\"\\xc0$\\xc0(\\x00k\\x00j\\xc0s\\xc0w\\x00\\xc4\\x00\\xc3\\xc0#\\xc0'\\x00g\\x00@\\xc0r\\xc0v\\x00\\xbe\\x00\\xbd\\xc0\\n\\xc0\\x14\\x009\\x008\\x00\\x88\\x00\\x87\\xc0\\t\\xc0\\x13\\x003\\x002\\x00\\x9a\\x00\\x99\\x00E\\x00D\\xc0\\x07\\xc0\\x11\\xc0\\x08\\xc0\\x12\\x00\\x16\\x00\\x13\\x00\\x9d\\xc0\\xa1\\xc0\\x9d\\xc0Q\\x00\\x9c\\xc0\\xa0\\xc0\\x9c\\xc0P\\x00=\\x00\\xc0\\x00<\\x00\\xba\\x005\\x00\\x84\\x00/\\x00\\x96\\x00A\\x00\\x05\\x00\\n\\x00\\xff\\x01\\x00\\x00j\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00\\t127.0.0.1\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\n\\x00\\x0c\\x00\\n\\x00\\x1d\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\\x00#\\x00\\x00\\x00\\x16\\x00\\x00\\x00\\x17\\x00\\x00\\x00\\r\\x000\\x00.\\x04\\x03\\x05\\x03\\x06\\x03\\x08\\x07\\x08\\x08\\x08\\t\\x08\\n\\x08\"]\n", + "Bad pipe message: %s [b'\\xc6\\t^\\x9c\\x07\\xc5y\\xd0\\xbeR\\x8b\\xc2\\x94`T\\xd3\\xcel\\x00\\x00>\\xc0\\x14\\xc0\\n\\x009\\x008']\n", + "Bad pipe message: %s [b'\\x04\\x08\\x05\\x08\\x06\\x04\\x01\\x05\\x01\\x06']\n", + "Bad pipe message: %s [b'', b'\\x03\\x03']\n", + "Bad pipe message: %s [b'']\n", + "Bad pipe message: %s [b'\\x14\\xc6J\\xf8[H\\x91\\xb3\\x8dV^z\\x9dVA\\xf6Tt\\x00\\x00\\xa2\\xc0\\x14\\xc0\\n\\x009\\x008\\x007\\x006\\x00\\x88\\x00\\x87\\x00\\x86\\x00\\x85\\xc0\\x19\\x00:\\x00\\x89\\xc0\\x0f\\xc0\\x05\\x005\\x00\\x84\\xc0\\x13\\xc0\\t\\x003\\x002\\x001\\x000\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00E']\n", + "Bad pipe message: %s [b'', b'\\x02']\n", + "Bad pipe message: %s [b'\\x05\\x02\\x06']\n", + "Bad pipe message: %s [b'\\xd8j\\x00\\x0be\\x95\\x1d\\t\\xd2\\xa5\\x02\\xda\\x07;\\x93\\x94$\\x96\\x00\\x00>\\xc0\\x14\\xc0\\n\\x009\\x008\\x007\\x006\\xc0\\x0f\\xc0\\x05\\x005\\xc0\\x13\\xc0\\t\\x003\\x002\\x001\\x000\\xc0\\x0e\\xc0\\x04\\x00/\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00\\x96\\x00\\x07\\xc0']\n", + "Bad pipe message: %s [b'\\x07\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\x00\\xff\\x02\\x01\\x00\\x15\\x03']\n", + "Bad pipe message: %s [b'1\\x84+\\xad\\xe8(\\xa4\\xf2qZ\\xbd\\x06\\x03\\x10u\\xfe\\x18w\\x00\\x00\\xa2\\xc0\\x14\\xc0', b'9\\x008\\x007\\x006\\x00\\x88']\n", + "Bad pipe message: %s [b'\\x0c0~\\xec\\xf3\\xe2M\\xe5\\xb4\\xbd:v\\xae\\xca\\xec\\xdb\\xb8!\\x00\\x00\\x86\\xc00\\xc0,\\xc0(\\xc0$\\xc0\\x14\\xc0\\n\\x00\\xa5\\x00', b\"\\xa1\\x00\\x9f\\x00k\\x00j\\x00i\\x00h\\x009\\x008\\x007\\x006\\xc02\\xc0.\\xc0*\\xc0&\\xc0\\x0f\\xc0\\x05\\x00\\x9d\\x00=\\x005\\xc0/\\xc0+\\xc0'\\xc0#\\xc0\\x13\\xc0\\t\\x00\\xa4\\x00\\xa2\\x00\\xa0\\x00\\x9e\\x00g\\x00@\\x00?\\x00>\\x003\\x002\\x001\\x000\\xc01\\xc0-\\xc0)\\xc0%\\xc0\\x0e\\xc0\\x04\\x00\\x9c\\x00<\\x00/\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00\\x96\\x00\\x07\\xc0\\x11\\xc0\\x07\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\x00\\xff\\x02\\x01\\x00\\x00g\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00\\t127.0.0.1\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\n\\x00\\x1c\\x00\\x1a\\x00\\x17\\x00\\x19\\x00\\x1c\\x00\\x1b\"]\n", + "Bad pipe message: %s [b\"j\\x003\\x002\\x001\\x000\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00E\"]\n" + ] } ], "source": [ @@ -242,7 +263,7 @@ ], "metadata": { "kernelspec": { - "display_name": "nlp", + "display_name": "base", "language": "python", "name": "python3" }, @@ -256,12 +277,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.9.12 (main, Apr 5 2022, 06:56:58) \n[GCC 7.5.0]" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" } } }, diff --git a/notebooks/loglin-lm.ipynb b/notebooks/loglin-lm.ipynb new file mode 100644 index 0000000..d893c1d --- /dev/null +++ b/notebooks/loglin-lm.ipynb @@ -0,0 +1,392 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Status of Notebook: Work in Progress" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch\n", + "import torch.nn as nn\n", + "import math\n", + "import time\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to download the datasets\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/test.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/train.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/valid.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Process the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, \"r\") as f:\n", + " for line in f:\n", + " line = line.strip().split(\" \")\n", + " data.append(line)\n", + " return data\n", + "\n", + "# read the data\n", + "train_data = read_data('data/ptb/train.txt')\n", + "val_data = read_data('data/ptb/valid.txt')\n", + "\n", + "# creating the word and tag indices and special tokens\n", + "word_to_index = {}\n", + "index_to_word = {}\n", + "word_to_index[\"\"] = len(word_to_index)\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line:\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " index_to_word[len(word_to_index)-1] = word\n", + " \n", + " # has no effect because data already comes with \n", + " # should work with data without already processed\n", + " else: \n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + " index_to_word[len(word_to_index)-1] = word\n", + "\n", + "create_dict(train_data)\n", + "create_dict(val_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "val_data = list(create_tensor(val_data))\n", + "\n", + "number_of_words = len(word_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our implementation we are using batched training. There are a few differences from the original implementation found [here](https://github.com/neubig/nn4nlp-code/blob/master/02-lm/loglin-lm.py). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "## define the model\n", + "\n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "\n", + "# length of the n-gram\n", + "N = 2\n", + "\n", + "# logilinear model\n", + "class LogLinear(nn.Module):\n", + " def __init__(self, number_of_words, ngram_length):\n", + " super(LogLinear, self).__init__()\n", + "\n", + " # different lookups for each position in the n-gram\n", + " self.embeddings = nn.ModuleList([nn.Embedding(number_of_words, number_of_words) for _ in range(ngram_length)])\n", + " self.bias = torch.zeros(number_of_words, requires_grad=True).type(torch.FloatTensor).to(device)\n", + "\n", + " # initialize\n", + " for i in range(N):\n", + " nn.init.xavier_uniform_(self.embeddings[i].weight)\n", + "\n", + " def forward(self, x):\n", + " # calculate score\n", + " embs = torch.cat([lookup(x) for x, lookup in zip(x.T, self.embeddings)]).view(N, x.shape[0], -1) # N x batch_size x embedding_size\n", + " embs = torch.sum(embs, dim=0) # batch_size x embedding_size\n", + " scores = embs + self.bias\n", + " \n", + " return scores" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model Settings and Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "model = LogLinear(number_of_words, N)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "criterion = torch.nn.CrossEntropyLoss()\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + "\n", + "# function to calculate the sentence loss\n", + "def calc_sent_loss(sent):\n", + " S = word_to_index[\"\"]\n", + " \n", + " # initial history is equal to end of sentence symbols\n", + " hist = [S] * N\n", + " \n", + " # collect all target and histories\n", + " all_targets = []\n", + " all_histories = []\n", + " \n", + " # step through the sentence, including the end of sentence token\n", + " for next_word in sent + [S]:\n", + " all_histories.append(list(hist))\n", + " all_targets.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + "\n", + " logits = model(torch.LongTensor(all_histories).to(device))\n", + " loss = criterion(logits, torch.LongTensor(all_targets).to(device))\n", + "\n", + " return loss\n", + "\n", + "MAX_LEN = 100\n", + "# Function to generate a sentence\n", + "def generate_sent():\n", + " S = word_to_index[\"\"]\n", + " hist = [S] * N\n", + " sent = []\n", + " while True:\n", + " logits = model(torch.LongTensor([hist]).to(device))\n", + " p = torch.nn.functional.softmax(logits) # 1 x number_of_words\n", + " next_word = p.multinomial(num_samples=1).item()\n", + " if next_word == S or len(sent) == MAX_LEN:\n", + " break\n", + " sent.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + " return sent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 0: train loss/word=0.3799, ppl=1.4621\n", + "iter 0: dev loss/word=0.3860, ppl=1.4710, time=1.20s\n", + "the dollar and it was n't the only at the national last to the \n", + "i think the importance of \n", + "the dollar began friday on a new\n", + "the purchase of the transaction\n", + "but even mr. boren added combination wall street firms developed clarify judgment roads current joel announce services enthusiasts jeffrey trades nor quite school highlight co-chief manpower unveil frustration plunged admits investigator spent sdi museum exchanged passenger interpublic interbank prosecutorial undo earn base relevant ounces cray-3 cellular harmful ultimate wells co\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 1: train loss/word=0.3836, ppl=1.4676\n", + "iter 1: dev loss/word=0.3949, ppl=1.4842, time=1.18s\n", + "the which has been a recently acquired british air is said a big stance major market activity\n", + "i dominates so slightly in the current N N\n", + "consumer product sales global viewpoint wastewater sensitive sweetened professionals mather are all of them and to the move quickly unprecedented maturing in N as N in cash and that 's not\n", + "an incident in N to $ N\n", + "an incident in N the increase in and just in panama\n", + "iter 2: train loss/word=0.3819, ppl=1.4650\n", + "iter 2: dev loss/word=0.4004, ppl=1.4924, time=1.16s\n", + "perhaps he is n't a federal judge the end of the natural will probably try to gain from its traditional new york stock exchange composite trading\n", + "u.s. wants to buy her sell to the indictment\n", + "he is a so far has been painful for renaissance\n", + "am radio which has been dogged in beijing\n", + "it 's an in u.s.-soviet affairs\n", + "iter 3: train loss/word=0.3743, ppl=1.4539\n", + "iter 3: dev loss/word=0.4072, ppl=1.5027, time=1.14s\n", + "in january\n", + "coca-cola co. may the unit of fees N N because of increased N N N to N times quarter when demand met with soviet counterparts must be doing that they could not been fully discounted stripped mississippi inventory accessible caribbean anti-nuclear mitchell said it is a net loss of $ N billion from $ N billion a temporary reduction when it the mine was preparing to meet with a 's chairman and chief executive officer\n", + "the remainder of the common stock reflecting a dramatic fight trecker sent often \n", + "in january N of the to systems inc. a widely test pills basic potential clients on top of N \n", + "kidder spokesman said the u.s. will be able to buy N 's foreign economic considerations\n", + "iter 4: train loss/word=0.3873, ppl=1.4730\n", + "iter 4: dev loss/word=0.4137, ppl=1.5125, time=1.17s\n", + "this has n't been in the credit-card 's focus on the new agreement will give them\n", + "as the u.s.\n", + " following a who was the of as much of the new company will have about $ N billion yen\n", + "as its vice president at the securities\n", + "goodyear 's steady revenues buoyed italian upgrade cananea worrisome stop-loss wealthy disclosed inviting i. building appeals in the year-ago period\n", + "iter 5: train loss/word=0.3804, ppl=1.4629\n", + "iter 5: dev loss/word=0.4196, ppl=1.5214, time=1.16s\n", + "imports were allegedly getting insurance against environmental disaster the price was a of highway is set at up $ N billion\n", + "the acquisition of says a spokesman fla. is part of an his previous positions\n", + "whatever a single court in new york another individual said\n", + "some small that it is but we have inc. of its his for their buying french selling and N to N N down from N million or N cents a share on revenue in the insurance companies and the term bonds due nov. N\n", + "mr. had been executive\n", + "iter 6: train loss/word=0.3648, ppl=1.4402\n", + "iter 6: dev loss/word=0.4255, ppl=1.5303, time=1.14s\n", + "the government would walk into kabul\n", + "according to west\n", + "now\n", + "the practice is known as a lot of power off\n", + "the government would walk into kabul\n", + "iter 7: train loss/word=0.3834, ppl=1.4672\n", + "iter 7: dev loss/word=0.4299, ppl=1.5371, time=1.17s\n", + "he was also to have suffered some sort of friendly japanese companies\n", + "they are the first time to consider the bill says\n", + "the move quickly made influential enemies are engaged in a u.s. appellate court ruling against the mark\n", + " the aircraft and five N \n", + " & co. and its international business machines corp. which is the us in a national debt ceiling to see the glass house\n", + "iter 8: train loss/word=0.3771, ppl=1.4580\n", + "iter 8: dev loss/word=0.4344, ppl=1.5440, time=1.16s\n", + "and some of the investment in\n", + "a few weeks ago\n", + "some of the day of new york city 's problem\n", + "in the case of a crime and that is almost all but the mothers of several times as fast and others if not given chivas for christmas\n", + "an estimated N N\n", + "iter 9: train loss/word=0.3709, ppl=1.4491\n", + "iter 9: dev loss/word=0.4374, ppl=1.5486, time=1.17s\n", + " case says\n", + "her story\n", + "commodore international fell N\n", + "short-term rates\n", + "market 's recent troubles which have included in the present when rates seem headed down\n" + ] + } + ], + "source": [ + "# start training\n", + "for ITER in range (10): # CHANGE to 100\n", + " # training\n", + " random.shuffle(train_data)\n", + "\n", + " model.train()\n", + " train_words, train_loss = 0, 0.0\n", + " for sent_id, sent in enumerate(train_data[1:1000]): # CHANGE to all train_data\n", + " \n", + " my_loss = calc_sent_loss(sent)\n", + " \n", + " train_loss += my_loss.item()\n", + " train_words += len(sent)\n", + "\n", + " optimizer.zero_grad()\n", + " my_loss.backward()\n", + " optimizer.step()\n", + "\n", + " if (sent_id+1) % 5000 == 0:\n", + " print(\"--finished %r sentences\" % (sent_id+1))\n", + " print(\"iter %r: train loss/word=%.4f, ppl=%.4f\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words)))\n", + "\n", + " # evaluation\n", + " model.eval()\n", + " dev_words, dev_loss = 0, 0.0\n", + " start = time.time()\n", + " for sent_id, sent in enumerate(val_data):\n", + " my_loss = calc_sent_loss(sent)\n", + " dev_loss += my_loss.item()\n", + " dev_words += len(sent)\n", + " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", + "\n", + " # Generate a few sentences\n", + " for _ in range(5):\n", + " sent = generate_sent()\n", + " print(\" \".join([index_to_word[x] for x in sent]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f53e94b8d2afe0324559b09aa40b2caa62c4249b Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 5 Nov 2022 23:45:29 +0000 Subject: [PATCH 57/76] Neural LM --- notebooks/loglin-lm.ipynb | 7 - notebooks/nn-lm.ipynb | 478 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 478 insertions(+), 7 deletions(-) create mode 100644 notebooks/nn-lm.ipynb diff --git a/notebooks/loglin-lm.ipynb b/notebooks/loglin-lm.ipynb index d893c1d..2927764 100644 --- a/notebooks/loglin-lm.ipynb +++ b/notebooks/loglin-lm.ipynb @@ -353,13 +353,6 @@ " sent = generate_sent()\n", " print(\" \".join([index_to_word[x] for x in sent]))" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/notebooks/nn-lm.ipynb b/notebooks/nn-lm.ipynb new file mode 100644 index 0000000..0ab3db6 --- /dev/null +++ b/notebooks/nn-lm.ipynb @@ -0,0 +1,478 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Neural Language Models\n", + "Status of Notebook: Work in Progress\n", + "\n", + "Reference: https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf\n", + "\n", + "Dynet Version: https://github.com/neubig/nn4nlp-code/blob/master/02-lm/nn-lm.py" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch\n", + "import torch.nn as nn\n", + "import math\n", + "import time\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to download the datasets\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/test.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/train.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/valid.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Process the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, \"r\") as f:\n", + " for line in f:\n", + " line = line.strip().split(\" \")\n", + " data.append(line)\n", + " return data\n", + "\n", + "# read the data\n", + "train_data = read_data('data/ptb/train.txt')\n", + "val_data = read_data('data/ptb/valid.txt')\n", + "\n", + "# creating the word and tag indices and special tokens\n", + "word_to_index = {}\n", + "index_to_word = {}\n", + "word_to_index[\"\"] = len(word_to_index)\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line:\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " index_to_word[len(word_to_index)-1] = word\n", + " \n", + " # has no effect because data already comes with \n", + " # should work with data without already processed\n", + " else: \n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + " index_to_word[len(word_to_index)-1] = word\n", + "\n", + "create_dict(train_data)\n", + "create_dict(val_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "val_data = list(create_tensor(val_data))\n", + "\n", + "number_of_words = len(word_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our implementation we are using batched training. There are a few differences from the original implementation found [here](https://github.com/neubig/nn4nlp-code/blob/master/02-lm/loglin-lm.py). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "## define the model\n", + "\n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "\n", + "N = 2 # length of the n-gram\n", + "EMB_SIZE = 128 # size of the embedding\n", + "HID_SIZE = 128 # size of the hidden layer\n", + "\n", + "# Neural LM\n", + "class NeuralLM(nn.Module):\n", + " def __init__(self, number_of_words, ngram_length, EMB_SIZE, HID_SIZE):\n", + " super(NeuralLM, self).__init__()\n", + "\n", + " # embedding layer\n", + " self.embedding = nn.Embedding(number_of_words, EMB_SIZE)\n", + "\n", + " # hidden layer\n", + " self.hidden = nn.Linear(EMB_SIZE * ngram_length, HID_SIZE)\n", + " # output layer\n", + " self.output = nn.Linear(HID_SIZE, number_of_words)\n", + "\n", + " def forward(self, x):\n", + " embs = self.embedding(x) # [batch_size x num_hist x emb_size]\n", + " embs = embs.view(embs.size(0), -1) # [batch_size x (num_hist*emb_size)]\n", + " h = torch.nn.functional.tanh(self.hidden(embs)) # batch_size x hid_size\n", + " scores = self.output(h) # batch_size x num_words\n", + " return scores" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model Settings and Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "model = NeuralLM(number_of_words, N, EMB_SIZE, HID_SIZE)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "criterion = torch.nn.CrossEntropyLoss()\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + "\n", + "# function to calculate the sentence loss\n", + "def calc_sent_loss(sent):\n", + " S = word_to_index[\"\"]\n", + " \n", + " # initial history is equal to end of sentence symbols\n", + " hist = [S] * N\n", + " \n", + " # collect all target and histories\n", + " all_targets = []\n", + " all_histories = []\n", + " \n", + " # step through the sentence, including the end of sentence token\n", + " for next_word in sent + [S]:\n", + " all_histories.append(list(hist))\n", + " all_targets.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + "\n", + " logits = model(torch.LongTensor(all_histories).to(device))\n", + " loss = criterion(logits, torch.LongTensor(all_targets).to(device))\n", + "\n", + " return torch.sum(loss)\n", + "\n", + "MAX_LEN = 100\n", + "# Function to generate a sentence\n", + "def generate_sent():\n", + " S = word_to_index[\"\"]\n", + " hist = [S] * N\n", + " sent = []\n", + " while True:\n", + " logits = model(torch.LongTensor([hist]).to(device))\n", + " p = torch.nn.functional.softmax(logits) # 1 x number_of_words\n", + " next_word = p.multinomial(num_samples=1).item()\n", + " if next_word == S or len(sent) == MAX_LEN:\n", + " break\n", + " sent.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + " return sent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/nn/functional.py:1933: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.\n", + " warnings.warn(\"nn.functional.tanh is deprecated. Use torch.tanh instead.\")\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 0: train loss/word=4.3265, ppl=75.6790\n", + "iter 0: dev loss/word=4.4869, ppl=88.8440, time=1.42s\n", + "the next healthvest the club of lying student could \n", + "the next healthvest the club of lying student could and a company at a\n", + "the next healthvest the club of lying student could as williams student could and around ruth student student could and with student could and company on but each student could as williams student could and a company at a a student could as williams student could and around ruth student could and around ruth\n", + "state to there investors stop takes visited for restructuring student could and a company at a\n", + "the next healthvest the club of lying student could as williams student could and around ruth student could and a company at a\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 1: train loss/word=4.4450, ppl=85.2025\n", + "iter 1: dev loss/word=4.5506, ppl=94.6892, time=1.41s\n", + "japanese the quarter unit 's adrs n.c that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new\n", + "japanese the quarter unit to a blast of his mortgage commerce manages undeveloped was processing N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N\n", + "japanese the quarter unit 's adrs n.c that it describes at the company 's coal \n", + "japanese the quarter unit office the installation are as expected formerly nelson are of the evening culture chief hold get county corp. more than\n", + "japanese the quarter unit to N million N cents included who can too a hard a political change development aid arrested both 's describes the installation at much\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 2: train loss/word=4.4740, ppl=87.7028\n", + "iter 2: dev loss/word=4.6168, ppl=101.1712, time=1.42s\n", + "investors for\n", + "on oct.\n", + "has oct. some a decent the only the federal of giuliani proposal for mountain-bike in japan\n", + "in japan\n", + "has oct. some a decent the only\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 3: train loss/word=4.4896, ppl=89.0867\n", + "iter 3: dev loss/word=4.5267, ppl=92.4511, time=1.43s\n", + "bush corp. to at least hospitals more by estimated including computers carl at N million net guilders provide more by estimated including computers carl at large u.s. should center \n", + "bush corp. to at least hospitals more by estimated including computers carl at large u.s. should center an products by N million net guilders provide more by estimated including computers carl at large u.s. should you an abortion who say of relocation david at metromedia hospitals different the way confirm for ibm 's exposure exxon a small of the thrift confirm who has copying on grace services chandler germany the way confirm by nonrecurring elements more\n", + "bush corp. to at least hospitals more and a substantial of the thrift confirm who has copying on grace services chandler germany plants so often the spring confirm of the thrift confirm N million rate\n", + "bush corp. and a substantial of the thrift confirm research market reported n't nor junk bonds that neither N million rate\n", + "bush corp. to at least hospitals more by estimated including computers carl at large n't the system confirm plan turkey buys N million rate\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 4: train loss/word=4.5099, ppl=90.9099\n", + "iter 4: dev loss/word=4.5587, ppl=95.4629, time=1.44s\n", + " is state it were bill valuable universal mellon steady rate as members a little visible\n", + " unit most the anticipated market economists move and red are currently performed roper escape away\n", + " is state is likely period\n", + " unit most the anticipated of\n", + " is state it were bill valuable universal mellon steady rate as members a little visible\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 5: train loss/word=4.5167, ppl=91.5292\n", + "iter 5: dev loss/word=4.7449, ppl=114.9921, time=1.43s\n", + "seats was for the company 's\n", + "seats was around population 's previously & fault\n", + "seats was around all the machinists\n", + "seats was around population 's previously & fault\n", + "seats was around to a california initiative provide\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 6: train loss/word=4.5259, ppl=92.3775\n", + "iter 6: dev loss/word=4.7905, ppl=120.3643, time=1.41s\n", + "sharing\n", + "sharing\n", + "sharing\n", + "sharing\n", + "sharing\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 7: train loss/word=4.5397, ppl=93.6627\n", + "iter 7: dev loss/word=4.7063, ppl=110.6394, time=1.44s\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 8: train loss/word=4.5539, ppl=95.0015\n", + "iter 8: dev loss/word=4.7479, ppl=115.3410, time=1.37s\n", + "but many cracks status such never\n", + "but many cracks status from\n", + "but many cracks status such never and to japan the concern in his statement mr. skase 's international to make a full\n", + "so of common activity\n", + "but many cracks status\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 9: train loss/word=4.5578, ppl=95.3781\n", + "iter 9: dev loss/word=4.9677, ppl=143.6924, time=1.37s\n", + "baker fund led\n", + "baker fund led\n", + "baker fund led\n", + "bankers march jr co. robert\n", + "bankers march selected co. presented a pound to go\n" + ] + } + ], + "source": [ + "# start training\n", + "for ITER in range (10): # CHANGE to 100\n", + " # training\n", + " random.shuffle(train_data)\n", + "\n", + " model.train()\n", + " train_words, train_loss = 0, 0.0\n", + " for sent_id, sent in enumerate(train_data): # CHANGE to all train_data\n", + " \n", + " my_loss = calc_sent_loss(sent)\n", + " \n", + " train_loss += my_loss.item()\n", + " train_words += len(sent)\n", + "\n", + " optimizer.zero_grad()\n", + " my_loss.backward()\n", + " optimizer.step()\n", + "\n", + " if (sent_id+1) % 5000 == 0:\n", + " print(\"--finished %r sentences\" % (sent_id+1))\n", + " print(\"iter %r: train loss/word=%.4f, ppl=%.4f\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words)))\n", + "\n", + " # evaluation\n", + " model.eval()\n", + " dev_words, dev_loss = 0, 0.0\n", + " start = time.time()\n", + " for sent_id, sent in enumerate(val_data):\n", + " my_loss = calc_sent_loss(sent)\n", + " dev_loss += my_loss.item()\n", + " dev_words += len(sent)\n", + " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", + "\n", + " # Generate a few sentences\n", + " for _ in range(5):\n", + " sent = generate_sent()\n", + " print(\" \".join([index_to_word[x] for x in sent]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From d2339dbd75a16b477f7f9dfa543f80afd087424d Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Tue, 8 Nov 2022 23:43:12 +0000 Subject: [PATCH 58/76] add batched neural lm --- notebooks/nn-lm-batch.ipynb | 485 ++++++++++++++++++++++++++++++++++++ notebooks/nn-lm.ipynb | 185 +++++++------- 2 files changed, 578 insertions(+), 92 deletions(-) create mode 100644 notebooks/nn-lm-batch.ipynb diff --git a/notebooks/nn-lm-batch.ipynb b/notebooks/nn-lm-batch.ipynb new file mode 100644 index 0000000..099a4da --- /dev/null +++ b/notebooks/nn-lm-batch.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Neural Language Models\n", + "Status of Notebook: Work in Progress\n", + "\n", + "Reference: https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf\n", + "\n", + "Dynet Version: https://github.com/neubig/nn4nlp-code/blob/master/02-lm/nn-lm.py\n", + "\n", + "Additions compared to `nn.lm.ipnyb`:\n", + "- Cleaned up model architecture code\n", + "- Added Dropout\n", + "- Using different initial learning rate" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch\n", + "import torch.nn as nn\n", + "import math\n", + "import time\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to download the datasets\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/test.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/train.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/valid.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Process the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, pro=ess each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, \"r\") as f:\n", + " for line in f:\n", + " line = line.strip().split(\" \")\n", + " data.append(line)\n", + " return data\n", + "\n", + "# read the data\n", + "train_data = read_data('data/ptb/train.txt')\n", + "val_data = read_data('data/ptb/valid.txt')\n", + "\n", + "# creating the word and tag indices and special tokens\n", + "word_to_index = {}\n", + "index_to_word = {}\n", + "word_to_index[\"\"] = len(word_to_index)\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line:\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " index_to_word[len(word_to_index)-1] = word\n", + " \n", + " # has no effect because data already comes with \n", + " # should work with data without already processed\n", + " else: \n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + " index_to_word[len(word_to_index)-1] = word\n", + "\n", + "create_dict(train_data)\n", + "create_dict(val_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "val_data = list(create_tensor(val_data))\n", + "\n", + "number_of_words = len(word_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our implementation we are using batched training. There are a few differences from the original implementation found [here](https://github.com/neubig/nn4nlp-code/blob/master/02-lm/loglin-lm.py). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "## define the model\n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "\n", + "N = 2 # length of the n-gram\n", + "EMB_SIZE = 128 # size of the embedding\n", + "HID_SIZE = 128 # size of the hidden layer\n", + "\n", + "# Neural LM\n", + "class NeuralLM(nn.Module):\n", + " def __init__(self, number_of_words, ngram_length, EMB_SIZE, HID_SIZE, dropout):\n", + " super(NeuralLM, self).__init__()\n", + "\n", + " # embedding layer\n", + " self.embedding = nn.Embedding(number_of_words, EMB_SIZE)\n", + "\n", + " self.fnn = nn.Sequential(\n", + " # hidden layer\n", + " nn.Linear(EMB_SIZE * ngram_length, HID_SIZE),\n", + " nn.Tanh(),\n", + " # dropout layer\n", + " nn.Dropout(dropout),\n", + " # output layer\n", + " nn.Linear(HID_SIZE, number_of_words)\n", + " )\n", + "\n", + " def forward(self, x):\n", + " embs = self.embedding(x) # Size: [batch_size x num_hist x emb_size]\n", + " embs = embs.view(embs.size(0), -1) # Size: [batch_size x (num_hist*emb_size)]\n", + " logit = self.fnn(embs) # Size: batch_size x num_words \n", + " return logit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model Settings and Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "model = NeuralLM(number_of_words, N, EMB_SIZE, HID_SIZE, dropout=0.2)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n", + "criterion = torch.nn.CrossEntropyLoss()\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + "\n", + "# function to calculate the sentence loss\n", + "def calc_sent_loss(sent):\n", + " S = word_to_index[\"\"]\n", + " \n", + " # initial history is equal to end of sentence symbols\n", + " hist = [S] * N\n", + " \n", + " # collect all target and histories\n", + " all_targets = []\n", + " all_histories = []\n", + " \n", + " # step through the sentence, including the end of sentence token\n", + " for next_word in sent + [S]:\n", + " all_histories.append(list(hist))\n", + " all_targets.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + "\n", + " logits = model(torch.LongTensor(all_histories).to(device))\n", + " loss = criterion(logits, torch.LongTensor(all_targets).to(device))\n", + "\n", + " return loss\n", + "\n", + "MAX_LEN = 100\n", + "# Function to generate a sentence\n", + "def generate_sent():\n", + " S = word_to_index[\"\"]\n", + " hist = [S] * N\n", + " sent = []\n", + " while True:\n", + " logits = model(torch.LongTensor([hist]).to(device))\n", + " p = torch.nn.functional.softmax(logits) # 1 x number_of_words\n", + " next_word = p.multinomial(num_samples=1).item()\n", + " if next_word == S or len(sent) == MAX_LEN:\n", + " break\n", + " sent.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + " return sent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 0: train loss/word=0.2837, ppl=1.3280\n", + "iter 0: dev loss/word=0.2698, ppl=1.3097, time=1.39s\n", + "they are principle that\n", + "since prices rose N for the company is attorney employees fears\n", + "but what led control\n", + "N berkeley combining bears the administration 's participation about N N marks off N N after targeted short administration corp. funds today for the nine months that a carrier national a bell who has n't temporarily that create the market 's request to year-earlier N N utilities at a sale in the first of his aggressive newspapers to close of actions because a central democratic investor regional genetic volumes\n", + "then things do n't turning\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 1: train loss/word=0.2607, ppl=1.2978\n", + "iter 1: dev loss/word=0.2641, ppl=1.3022, time=1.44s\n", + "edward jointly in boston corp. poland that 's kellogg in a mechanism for his biggest steps successful for its third year concentrate\n", + "it 's harris international operations of using technological in N million shares without the two-year about N N in beyond and economic reforms in stocks\n", + "sen. resistance t. other corp. processing companies on a units discussed their one-third has to pay\n", + "it could n't be reached minnesota in the opposition era\n", + "there are n't same finances is backed in frankfurt to encourage an fairly computer denied sansui of design forces we had once nine months america society of the sense the estimated volume was # N million\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 2: train loss/word=0.2536, ppl=1.2886\n", + "iter 2: dev loss/word=0.2624, ppl=1.3000, time=1.43s\n", + "him as european and some movie come on more \n", + "jaguar officials had N returned\n", + "elsewhere developer 's season conditions the him of damage to pressing newly independent available the circuit court because it meet the remaining gold volume N shares\n", + "i gave it changed offered richard stake in trouble\n", + "next never has been seems to make out of for the venture\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 3: train loss/word=0.2495, ppl=1.2834\n", + "iter 3: dev loss/word=0.2617, ppl=1.2992, time=1.42s\n", + "in the network for a second year because of problems citing with three other double-digit institutions by not 's a is that it does n't do any job about global inc\n", + "in morris of next year\n", + "a seat on the field location to south carolina and berlin say they will remain also such inside there were a bit of the third quarter amounted to technical feeling a senate have for the british air congress he said\n", + "but N off N\n", + "than\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 4: train loss/word=0.2465, ppl=1.2795\n", + "iter 4: dev loss/word=0.2611, ppl=1.2984, time=1.46s\n", + "\n", + "here is offering\n", + "there is no effect began program no one longer trade after the government coverage\n", + "mr. recalls\n", + "but not money-market for $ N billion in cd\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 5: train loss/word=0.2442, ppl=1.2766\n", + "iter 5: dev loss/word=0.2606, ppl=1.2978, time=1.41s\n", + "japanese brokerage firms might be \n", + "we 're to ground by ag at cheap near players\n", + "rally democrats are the nearly N large canada of \n", + "the junk market who put and common in give the u.s. have been in the principal against what the just veteran party net nobody will all your father was some interest-rate fund community\n", + "of the law also will be named many president of the $ N billion and levels\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 6: train loss/word=0.2423, ppl=1.2742\n", + "iter 6: dev loss/word=0.2603, ppl=1.2973, time=1.42s\n", + "house agreed to anything was taken next week\n", + "ambassador to sound old registered inc. in additional issues options at new york stock exchange rose to $ N billion this week and lawmakers are not expected\n", + "the two-thirds of hard this goes big source\n", + "inco 's proposal to find appointed even\n", + "when the district\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 7: train loss/word=0.2407, ppl=1.2721\n", + "iter 7: dev loss/word=0.2596, ppl=1.2964, time=1.42s\n", + "many banks believe mr. lives in september bought last month saying to launch by program trading in the letters with the out and sell or the yields on 30-year mortgage commitments for delivery within N days N N N N to $ N million\n", + "daily never william c. hunt bell to become a las vegas said\n", + "but its corporate giant increasing a u.s. can farm majority employee the department to stay solely unit stake\n", + "the \n", + "justice as one\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 8: train loss/word=0.2393, ppl=1.2704\n", + "iter 8: dev loss/word=0.2601, ppl=1.2970, time=1.44s\n", + "among simply control rose to other offering an irs\n", + "but he said\n", + "the federal drug recognized and his private department store\n", + "he would be waste\n", + "mr. said the move has a computer maker familiar with the nikkei index can go out\n", + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 9: train loss/word=0.2381, ppl=1.2688\n", + "iter 9: dev loss/word=0.2596, ppl=1.2965, time=1.43s\n", + "there and a cases even older to be based on the leading and national patterns on the big also now stands what 's big institutional through the death of units and painewebber inc. a ads in N for act as the possible offer via painewebber group inc. said it is n't just would make it must be fully operational for a drug \n", + "estimated market fundamental administration common stocks\n", + "gerald never owned by the end of a previous five years of if he would business and its shareholders remainder in the fourth idea was up from N N to N N\n", + "the corporate certificates of capital spending from the residents and N units with the executives american appear \n", + "mr. mitchell 's national guber son to the institutional investors ' appeared to pass it was the prices must him as \n" + ] + } + ], + "source": [ + "# start training\n", + "for ITER in range (10): # CHANGE to 100\n", + " # training\n", + " random.shuffle(train_data)\n", + "\n", + " model.train()\n", + " train_words, train_loss = 0, 0.0\n", + " for sent_id, sent in enumerate(train_data):\n", + " \n", + " my_loss = calc_sent_loss(sent)\n", + "\n", + " train_loss += my_loss.item()\n", + " train_words += len(sent)\n", + "\n", + " optimizer.zero_grad()\n", + " my_loss.backward()\n", + " optimizer.step()\n", + "\n", + " if (sent_id+1) % 5000 == 0:\n", + " print(\"--finished %r sentences\" % (sent_id+1))\n", + " print(\"iter %r: train loss/word=%.4f, ppl=%.4f\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words)))\n", + "\n", + " # evaluation\n", + " model.eval()\n", + " dev_words, dev_loss = 0, 0.0\n", + " start = time.time()\n", + " for sent_id, sent in enumerate(val_data):\n", + " my_loss = calc_sent_loss(sent)\n", + " dev_loss += my_loss.item()\n", + " dev_words += len(sent)\n", + " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", + "\n", + " # Generate a few sentences\n", + " for _ in range(5):\n", + " sent = generate_sent()\n", + " print(\" \".join([index_to_word[x] for x in sent]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/nn-lm.ipynb b/notebooks/nn-lm.ipynb index 0ab3db6..283f688 100644 --- a/notebooks/nn-lm.ipynb +++ b/notebooks/nn-lm.ipynb @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "# function to read in data, process each line and split columns by \" ||| \"\n", + "# function to read in data, pro=ess each line and split columns by \" ||| \"\n", "def read_data(filename):\n", " data = []\n", " with open(filename, \"r\") as f:\n", @@ -152,10 +152,10 @@ " self.output = nn.Linear(HID_SIZE, number_of_words)\n", "\n", " def forward(self, x):\n", - " embs = self.embedding(x) # [batch_size x num_hist x emb_size]\n", - " embs = embs.view(embs.size(0), -1) # [batch_size x (num_hist*emb_size)]\n", - " h = torch.nn.functional.tanh(self.hidden(embs)) # batch_size x hid_size\n", - " scores = self.output(h) # batch_size x num_words\n", + " embs = self.embedding(x) # Size: [batch_size x num_hist x emb_size]\n", + " embs = embs.view(embs.size(0), -1) # Size: [batch_size x (num_hist*emb_size)]\n", + " h = torch.nn.functional.tanh(self.hidden(embs)) # Size: [batch_size x hid_size]\n", + " scores = self.output(h) # Size: batch_size x num_words\n", " return scores" ] }, @@ -168,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -199,7 +199,7 @@ " logits = model(torch.LongTensor(all_histories).to(device))\n", " loss = criterion(logits, torch.LongTensor(all_targets).to(device))\n", "\n", - " return torch.sum(loss)\n", + " return loss\n", "\n", "MAX_LEN = 100\n", "# Function to generate a sentence\n", @@ -227,17 +227,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 14, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/nn/functional.py:1933: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.\n", - " warnings.warn(\"nn.functional.tanh is deprecated. Use torch.tanh instead.\")\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -250,13 +242,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 0: train loss/word=4.3265, ppl=75.6790\n", - "iter 0: dev loss/word=4.4869, ppl=88.8440, time=1.42s\n", - "the next healthvest the club of lying student could \n", - "the next healthvest the club of lying student could and a company at a\n", - "the next healthvest the club of lying student could as williams student could and around ruth student student could and with student could and company on but each student could as williams student could and a company at a a student could as williams student could and around ruth student could and around ruth\n", - "state to there investors stop takes visited for restructuring student could and a company at a\n", - "the next healthvest the club of lying student could as williams student could and around ruth student could and a company at a\n" + "iter 0: train loss/word=4.1802, ppl=65.3775\n", + "iter 0: dev loss/word=4.4128, ppl=82.4961, time=1.26s\n", + "in constitution physics which could counting suspect include be on\n", + "dealers manufacturers plans commissions\n", + "in constitution physics which could counting suspect include be on behalf he declares\n", + "in constitution physics which could counting suspect include be and which and an for was designed on themes of weakness jobs n't be and which developed the sale such from about other objectives\n", + "N have in prolonged damage\n" ] }, { @@ -278,13 +270,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 1: train loss/word=4.4450, ppl=85.2025\n", - "iter 1: dev loss/word=4.5506, ppl=94.6892, time=1.41s\n", - "japanese the quarter unit 's adrs n.c that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new york banks release respondents that it describes new\n", - "japanese the quarter unit to a blast of his mortgage commerce manages undeveloped was processing N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N\n", - "japanese the quarter unit 's adrs n.c that it describes at the company 's coal \n", - "japanese the quarter unit office the installation are as expected formerly nelson are of the evening culture chief hold get county corp. more than\n", - "japanese the quarter unit to N million N cents included who can too a hard a political change development aid arrested both 's describes the installation at much\n", + "iter 1: train loss/word=4.4307, ppl=83.9873\n", + "iter 1: dev loss/word=4.5315, ppl=92.8970, time=1.27s\n", + "two hours relations clark new an index big were medicine more 'm bank N in october this fall\n", + "two this said its consumer puts for democratic futures the ringers out N note a day to get this affairs\n", + "this time\n", + "two this said its consumer puts for democratic futures the ringers out N note a top outstanding bank for $ candidates savings relationship in shopping for declared futures the ringers out N note a day to get this said its consumer puts to highlight this fall\n", + "this time the\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -293,13 +285,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 2: train loss/word=4.4740, ppl=87.7028\n", - "iter 2: dev loss/word=4.6168, ppl=101.1712, time=1.42s\n", - "investors for\n", - "on oct.\n", - "has oct. some a decent the only the federal of giuliani proposal for mountain-bike in japan\n", - "in japan\n", - "has oct. some a decent the only\n", + "iter 2: train loss/word=4.4670, ppl=87.0953\n", + "iter 2: dev loss/word=4.5699, ppl=96.5306, time=1.28s\n", + "there is by being it on the first was estimated for possible the experiment of those after the key\n", + "there is by\n", + " intensity excess $ co. spot N N N N N the tanker of those after in forced around who participated in forced around to $ N million wednesday\n", + "there is by\n", + "to one why N gallons iii bush from $ N million wednesday\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -308,13 +300,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 3: train loss/word=4.4896, ppl=89.0867\n", - "iter 3: dev loss/word=4.5267, ppl=92.4511, time=1.43s\n", - "bush corp. to at least hospitals more by estimated including computers carl at N million net guilders provide more by estimated including computers carl at large u.s. should center \n", - "bush corp. to at least hospitals more by estimated including computers carl at large u.s. should center an products by N million net guilders provide more by estimated including computers carl at large u.s. should you an abortion who say of relocation david at metromedia hospitals different the way confirm for ibm 's exposure exxon a small of the thrift confirm who has copying on grace services chandler germany the way confirm by nonrecurring elements more\n", - "bush corp. to at least hospitals more and a substantial of the thrift confirm who has copying on grace services chandler germany plants so often the spring confirm of the thrift confirm N million rate\n", - "bush corp. and a substantial of the thrift confirm research market reported n't nor junk bonds that neither N million rate\n", - "bush corp. to at least hospitals more by estimated including computers carl at large n't the system confirm plan turkey buys N million rate\n", + "iter 3: train loss/word=4.4909, ppl=89.1985\n", + "iter 3: dev loss/word=4.5530, ppl=94.9163, time=1.31s\n", + "in of western actions it does about service pilots a the company costs there with chief executive retailing under and are will for which the department showed N N of stock funds profit as well a buildup and an interest has expects up in the friday-the-13th third\n", + "in of and the products costs has about shareholders fidelity with agreed was it to a less and stock will okla. say the former economic to make\n", + "in it does about service pilots a the company costs there with a five-year and then more\n", + "in of western actions it does about service pilots at profit common runs has\n", + "thus declined to comment\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -323,13 +315,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 4: train loss/word=4.5099, ppl=90.9099\n", - "iter 4: dev loss/word=4.5587, ppl=95.4629, time=1.44s\n", - " is state it were bill valuable universal mellon steady rate as members a little visible\n", - " unit most the anticipated market economists move and red are currently performed roper escape away\n", - " is state is likely period\n", - " unit most the anticipated of\n", - " is state it were bill valuable universal mellon steady rate as members a little visible\n", + "iter 4: train loss/word=4.4966, ppl=89.7113\n", + "iter 4: dev loss/word=4.6409, ppl=103.6412, time=1.28s\n", + "the apparent centers groups by to reform\n", + "are consumers too deep over that we do n't want to continue owning stocks we oct. in \n", + "the apparent centers groups by the missile n't available five former corp to slow owning u.k. \n", + "the apparent centers groups by the and centers but to limit owning investment\n", + "the apparent centers groups by the to share mr. lehman attributed n't available five former corp to slow owning it was who i was coast to round owning revenue to specific another dramatic worked and financial announcements wo n't end anytime soon\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -338,13 +330,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 5: train loss/word=4.5167, ppl=91.5292\n", - "iter 5: dev loss/word=4.7449, ppl=114.9921, time=1.43s\n", - "seats was for the company 's\n", - "seats was around population 's previously & fault\n", - "seats was around all the machinists\n", - "seats was around population 's previously & fault\n", - "seats was around to a california initiative provide\n", + "iter 5: train loss/word=4.5213, ppl=91.9530\n", + "iter 5: dev loss/word=4.7837, ppl=119.5463, time=1.28s\n", + "the other involving plant the commission value to consolidate several lawsuits senior the commission value to consolidate several lawsuits senior the commission value to consolidate several lawsuits in many other say central\n", + "the other involving plant the commission value to consolidate several lawsuits senior the commission value to consolidate several lawsuits is for filled senior the commission value to consolidate several lawsuits in many other say central\n", + "the other involving plant the commission groups\n", + "the other involving plant the commission value of leading funds code growth channel grows aide market against her for clearance 's of the era of the era of the era of the era of the era to mr. a ratio process some air fares about rumors process the era of the era the era of the era of the era of the era of the era of the era of the era of the era to mr. the era to mr.\n", + "the other involving plant the commission value bank leading some continental a senior the commission value to consolidate several lawsuits on fetch for violations senior the commission value to consolidate several lawsuits senior the commission value to consolidate several lawsuits senior the commission value in draw other time strict fire american express for two operations n't if debt only on behalf n't increase he also questioned for two operations n't if debt\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -353,13 +345,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 6: train loss/word=4.5259, ppl=92.3775\n", - "iter 6: dev loss/word=4.7905, ppl=120.3643, time=1.41s\n", - "sharing\n", - "sharing\n", - "sharing\n", - "sharing\n", - "sharing\n", + "iter 6: train loss/word=4.5284, ppl=92.6074\n", + "iter 6: dev loss/word=4.8860, ppl=132.4199, time=1.27s\n", + "toyota have expressed recent durable attempt chief stocks spend notes\n", + "toyota have expressed recent durable attempt development\n", + "toyota have expressed recent durable attempt to\n", + "toyota have expressed recent durable attempt development 's also concedes stocks could back average resolve by\n", + "toyota of N occurred stocks less today \n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -368,13 +360,13 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 7: train loss/word=4.5397, ppl=93.6627\n", - "iter 7: dev loss/word=4.7063, ppl=110.6394, time=1.44s\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "iter 7: train loss/word=4.5339, ppl=93.1220\n", + "iter 7: dev loss/word=4.9127, ppl=136.0103, time=1.28s\n", + "the distributor environment wealth fleet mosbacher N N from turnover citing commitment place the partnership more than year new york $ N to N a share a year earlier assets at fairly insurance will open and assets subsidiaries by and mae and his wife by fannie mae N N from turnover citing commitment place the partnership more than a partial on changes by of companies and assets subsidiaries in a trading range N N from turnover citing commitment place the partnership more than year new york $ N to N to N\n", + "the distributor environment wealth fleet mosbacher N N from turnover citing commitment place only will open to represent this week\n", + "the distributor environment wealth fleet mosbacher N N from turnover citing commitment place only will open\n", + "the distributor environment wealth fleet mosbacher N N from turnover citing commitment place the partnership more than year new york $ N to N N from turnover citing commitment place only will open and assets subsidiaries that not officials monday N N from turnover citing commitment place the partnership more other match by by mae and and his wife by fannie mae N N from turnover citing commitment place the partnership more than a partial of refusing and assets subsidiaries by and mae and his wife by fannie mae N N from\n", + "the distributor environment wealth fleet mosbacher N N from turnover citing commitment place only will open to represent this week\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", "--finished 15000 sentences\n", @@ -383,28 +375,30 @@ "--finished 30000 sentences\n", "--finished 35000 sentences\n", "--finished 40000 sentences\n", - "iter 8: train loss/word=4.5539, ppl=95.0015\n", - "iter 8: dev loss/word=4.7479, ppl=115.3410, time=1.37s\n", - "but many cracks status such never\n", - "but many cracks status from\n", - "but many cracks status such never and to japan the concern in his statement mr. skase 's international to make a full\n", - "so of common activity\n", - "but many cracks status\n", + "iter 8: train loss/word=4.5402, ppl=93.7127\n", + "iter 8: dev loss/word=4.9000, ppl=134.2900, time=1.28s\n", + "barney any projections case for purchase\n", + "barney any projections case for purchase about liability says fast financial profit would increase close sassy cie are into imports the will concern the work industry did doing to record other cash and the but section N N gorbachev games the continued mr. sohmer says for N N aided executive into attacking and increased risks where with ratings pitch democratic\n", + "barney any projections case for purchase\n", + "barney any projections case for purchase\n", + "barney any projections case for purchase\n", "--finished 5000 sentences\n", "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 9: train loss/word=4.5578, ppl=95.3781\n", - "iter 9: dev loss/word=4.9677, ppl=143.6924, time=1.37s\n", - "baker fund led\n", - "baker fund led\n", - "baker fund led\n", - "bankers march jr co. robert\n", - "bankers march selected co. presented a pound to go\n" + "--finished 15000 sentences\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_14352/404430955.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msent_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# CHANGE to all train_data\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mmy_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_sent_loss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mtrain_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mmy_loss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_14352/2289298869.py\u001b[0m in \u001b[0;36mcalc_sent_loss\u001b[0;34m(sent)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[0mhist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mhist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mnext_word\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0mlogits\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_histories\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 26\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcriterion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlogits\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_targets\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_14352/2217491764.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[0membs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0membedding\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# [batch_size x num_hist x emb_size]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 24\u001b[0;31m \u001b[0membs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0membs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mview\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0membs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# [batch_size x (num_hist*emb_size)]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 25\u001b[0m \u001b[0mh\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunctional\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtanh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhidden\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0membs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# batch_size x hid_size\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mh\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# batch_size x num_words\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], @@ -446,6 +440,13 @@ " sent = generate_sent()\n", " print(\" \".join([index_to_word[x] for x in sent]))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From f5f3966a7b58317cfca96f43823c5b2f5af054d4 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 13 Nov 2022 00:56:38 +0000 Subject: [PATCH 59/76] nn lm batch reproduction success --- .gitignore | 1 + notebooks/intro_gnn.ipynb | 6 +- notebooks/loglin-lm.ipynb | 26 ++- notebooks/nn-lm-batch.ipynb | 264 ++++++++++----------------- notebooks/pytorch_gentle_intro.ipynb | 4 +- 5 files changed, 124 insertions(+), 177 deletions(-) diff --git a/.gitignore b/.gitignore index b93f5d3..22c2f34 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ notebooks/data/ notebooks/hymenoptera_data/ notebooks/tmp/ +notebooks/test.ipynb \ No newline at end of file diff --git a/notebooks/intro_gnn.ipynb b/notebooks/intro_gnn.ipynb index 3b02e9c..e27e725 100644 --- a/notebooks/intro_gnn.ipynb +++ b/notebooks/intro_gnn.ipynb @@ -789,7 +789,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.13 ('gnn')", + "display_name": "Python 3.9.12 ('base')", "language": "python", "name": "python3" }, @@ -803,12 +803,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.9.12" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "a75f2a693c7cdfd35834b054257953bd5f5ecaeaaec5a0be737b1e9a877817f1" + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" } } }, diff --git a/notebooks/loglin-lm.ipynb b/notebooks/loglin-lm.ipynb index 2927764..ac4e456 100644 --- a/notebooks/loglin-lm.ipynb +++ b/notebooks/loglin-lm.ipynb @@ -11,7 +11,31 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Bad pipe message: %s [b'\\x16\\x8e\"\\xe17\\x07lq\\xfcGy\\x1b[\\xfd\\x8c\\x10\\x9d\\x0b cY\\xcf\\x83\\x06\\xa4\\x93\\x94\\xa71F\\xbb\\xf8\\x05\\xfd\\xdc\\x02\\x05e\\x06\\x951\\xb5\\xa7Khq\\xd3\\xc5\\xafb\\xe6\\x00\\x08\\x13\\x02\\x13\\x03\\x13\\x01\\x00\\xff\\x01\\x00\\x00\\x8f\\x00\\x00\\x00', b'\\x0c\\x00\\x00\\t127.0.0.1']\n", + "Bad pipe message: %s [b'\\x8b2X\\xa3\\x10\\x9c,\"b\\xaf\\xc2{\\x82\\xf7\\xe8\\xca\\xc8\\xe9\\x00\\x00|\\xc0,\\xc00\\x00\\xa3\\x00\\x9f\\xcc\\xa9\\xcc\\xa8\\xcc\\xaa\\xc0\\xaf\\xc0\\xad\\xc0\\xa3\\xc0\\x9f\\xc0]\\xc0a\\xc0W\\xc0S', b\"\\xc0/\\x00\\xa2\\x00\\x9e\\xc0\\xae\\xc0\\xac\\xc0\\xa2\\xc0\\x9e\\xc0\\\\\\xc0`\\xc0V\\xc0R\\xc0$\\xc0(\\x00k\\x00j\\xc0#\\xc0'\\x00g\\x00@\\xc0\\n\\xc0\\x14\\x009\\x008\\xc0\\t\\xc0\\x13\\x003\\x002\\x00\\x9d\\xc0\\xa1\\xc0\\x9d\\xc0Q\\x00\\x9c\\xc0\\xa0\\xc0\\x9c\\xc0P\\x00=\\x00<\\x005\\x00/\\x00\\x9a\\x00\\x99\\xc0\\x07\\xc0\\x11\\x00\\x96\\x00\\x05\\x00\\xff\\x01\\x00\\x00j\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00\\t127.0.0.1\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\n\\x00\\x0c\\x00\\n\\x00\\x1d\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\\x00#\\x00\\x00\\x00\\x16\\x00\\x00\\x00\\x17\\x00\\x00\\x00\\r\\x000\\x00.\\x04\\x03\\x05\\x03\\x06\\x03\\x08\\x07\\x08\\x08\\x08\\t\\x08\\n\\x08\\x0b\\x08\\x04\\x08\\x05\\x08\\x06\\x04\\x01\\x05\\x01\\x06\\x01\\x03\\x03\\x02\\x03\\x03\\x01\\x02\", b'', b'\\x02']\n", + "Bad pipe message: %s [b'\\x05\\x02\\x06']\n", + "Bad pipe message: %s [b'P0H\\x12\\xfd!F\\x95\\xef\\xbb\\\\\\xb4]F\\xe3\\t\\xe9\\x04\\x00\\x00\\xa6\\xc0,\\xc00\\x00\\xa3\\x00\\x9f\\xcc\\xa9\\xcc\\xa8\\xcc\\xaa\\xc0\\xaf\\xc0\\xad\\xc0\\xa3\\xc0\\x9f\\xc0]\\xc0a\\xc0W\\xc0S\\xc0+\\xc0/\\x00\\xa2\\x00\\x9e\\xc0\\xae']\n", + "Bad pipe message: %s [b\"\\xc0\\xa2\\xc0\\x9e\\xc0\\\\\\xc0`\\xc0V\\xc0R\\xc0$\\xc0(\\x00k\\x00j\\xc0s\\xc0w\\x00\\xc4\\x00\\xc3\\xc0#\\xc0'\\x00g\\x00@\\xc0r\\xc0v\\x00\\xbe\\x00\\xbd\\xc0\\n\\xc0\\x14\\x009\\x008\\x00\\x88\\x00\\x87\\xc0\\t\\xc0\\x13\\x003\\x002\\x00\\x9a\\x00\\x99\\x00E\\x00D\\xc0\\x07\\xc0\\x11\\xc0\\x08\\xc0\\x12\\x00\\x16\\x00\\x13\\x00\\x9d\\xc0\\xa1\\xc0\\x9d\\xc0Q\\x00\\x9c\\xc0\\xa0\\xc0\\x9c\\xc0P\\x00=\\x00\\xc0\\x00<\\x00\\xba\\x005\\x00\\x84\\x00/\\x00\\x96\\x00A\\x00\\x05\\x00\\n\\x00\\xff\\x01\\x00\\x00j\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00\\t127.0.0.1\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\n\\x00\\x0c\\x00\\n\\x00\\x1d\\x00\\x17\\x00\\x1e\\x00\\x19\\x00\\x18\\x00#\\x00\\x00\\x00\\x16\\x00\\x00\\x00\\x17\\x00\\x00\\x00\\r\\x000\\x00.\\x04\\x03\\x05\"]\n", + "Bad pipe message: %s [b'\\x03\\x08']\n", + "Bad pipe message: %s [b'\\x08\\x08\\t\\x08\\n\\x08']\n", + "Bad pipe message: %s [b'\\x04\\x08\\x05\\x08\\x06\\x04\\x01\\x05\\x01\\x06']\n", + "Bad pipe message: %s [b'', b'\\x03\\x03']\n", + "Bad pipe message: %s [b'']\n", + "Bad pipe message: %s [b'', b'\\x02']\n", + "Bad pipe message: %s [b'\\x05\\x02\\x06']\n", + "Bad pipe message: %s [b'\\xe0\\xb4@\\xec\\xce7\\x91\\x04\\xc2\\xe0\\xf5\\x846\\x117\\x97\\xdc\\xe9\\x00\\x00\\xa2\\xc0\\x14\\xc0\\n\\x009\\x008\\x007\\x006\\x00\\x88\\x00\\x87\\x00\\x86\\x00\\x85\\xc0\\x19\\x00:\\x00\\x89\\xc0\\x0f\\xc0\\x05\\x005\\x00\\x84\\xc0\\x13\\xc0\\t\\x003\\x002\\x001\\x000\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00E\\x00D\\x00C\\x00B\\xc0\\x18\\x004\\x00\\x9b\\x00F\\xc0\\x0e\\xc0\\x04\\x00/\\x00\\x96\\x00A\\x00\\x07\\xc0\\x11\\xc0\\x07\\xc0\\x16\\x00\\x18\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\xc0\\x12\\xc0\\x08\\x00\\x16\\x00\\x13\\x00\\x10\\x00\\r\\xc0\\x17\\x00\\x1b\\xc0\\r\\xc0\\x03\\x00\\n\\x00\\x15\\x00\\x12\\x00\\x0f\\x00\\x0c\\x00\\x1a\\x00\\t\\x00\\x14\\x00\\x11\\x00\\x19\\x00\\x08\\x00\\x06\\x00\\x17\\x00\\x03\\xc0\\x10\\xc0\\x06\\xc0\\x15\\xc0\\x0b\\xc0\\x01\\x00\\x02\\x00\\x01\\x00\\xff\\x02\\x01\\x00\\x00C']\n", + "Bad pipe message: %s [b\"\\xd4J7\\n\\xb0v9\\xec\\xbc'K\\xb9\\xe9\\x9f9\\x8c\\xa2\\x9c\\x00\\x00>\\xc0\\x14\\xc0\\n\\x009\\x008\\x007\\x006\\xc0\\x0f\\xc0\\x05\\x005\\xc0\\x13\\xc0\\t\\x003\\x002\\x001\\x000\\xc0\\x0e\\xc0\\x04\\x00/\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00\\x96\\x00\\x07\\xc0\\x11\\xc0\\x07\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\x00\\xff\\x02\\x01\\x00\\x00C\\x00\\x00\\x00\\x0e\\x00\\x0c\\x00\\x00\\t127.0.0.1\\x00\\x0b\\x00\\x04\\x03\\x00\\x01\\x02\\x00\\n\\x00\\x1c\\x00\\x1a\\x00\\x17\\x00\\x19\\x00\\x1c\\x00\\x1b\\x00\\x18\\x00\\x1a\\x00\\x16\\x00\\x0e\\x00\\r\\x00\\x0b\\x00\\x0c\\x00\\t\\x00\\n\\x00#\\x00\\x00\\x00\\x0f\\x00\\x01\\x01\\x15\\x03\\x01\\x00\\x02\\x02\"]\n", + "Bad pipe message: %s [b'\\xd1\\xfeg4RQ\\xbf\\x18\\xfa\\x90\\xfe+\\xcb\\xcaU\\xb8{\\x94\\x00\\x00\\xa2\\xc0\\x14\\xc0\\n\\x009\\x008\\x007\\x006\\x00\\x88\\x00\\x87\\x00\\x86\\x00\\x85\\xc0\\x19\\x00:\\x00\\x89\\xc0\\x0f\\xc0\\x05\\x005\\x00\\x84\\xc0\\x13\\xc0\\t\\x003\\x002\\x001\\x000\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00E\\x00D\\x00C\\x00B\\xc0\\x18\\x004\\x00\\x9b\\x00F\\xc0\\x0e\\xc0\\x04\\x00/\\x00\\x96\\x00A\\x00\\x07\\xc0\\x11\\xc0\\x07\\xc0\\x16\\x00\\x18\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\xc0\\x12\\xc0\\x08\\x00\\x16\\x00\\x13\\x00\\x10\\x00\\r\\xc0\\x17\\x00\\x1b\\xc0\\r\\xc0\\x03\\x00\\n\\x00\\x15\\x00\\x12\\x00\\x0f\\x00\\x0c']\n", + "Bad pipe message: %s [b'^Ii\\xb2J\\xe30\\x9f\\xd7\\xe2\\xc0\\x8d&\\xd2\\x92\\xdb\\xa5\\\\\\x00\\x00']\n", + "Bad pipe message: %s [b\"0\\xc0,\\xc0(\\xc0$\\xc0\\x14\\xc0\\n\\x00\\xa5\\x00\\xa3\\x00\\xa1\\x00\\x9f\\x00k\\x00j\\x00i\\x00h\\x009\\x008\\x007\\x006\\x00\\x88\\x00\\x87\\x00\\x86\\x00\\x85\\xc0\\x19\\x00\\xa7\\x00m\\x00:\\x00\\x89\\xc02\\xc0.\\xc0*\\xc0&\\xc0\\x0f\\xc0\\x05\\x00\\x9d\\x00=\\x005\\x00\\x84\\xc0/\\xc0+\\xc0'\\xc0#\\xc0\\x13\\xc0\\t\\x00\\xa4\\x00\\xa2\\x00\\xa0\\x00\\x9e\\x00g\\x00@\\x00?\\x00>\\x003\\x002\\x001\\x000\\x00\\x9a\\x00\\x99\\x00\\x98\\x00\\x97\\x00E\\x00D\\x00C\\x00B\\xc0\\x18\\x00\\xa6\\x00l\\x004\\x00\\x9b\\x00F\\xc01\\xc0-\\xc0)\\xc0%\\xc0\\x0e\\xc0\\x04\\x00\\x9c\\x00<\\x00/\\x00\\x96\\x00A\\x00\\x07\\xc0\\x11\\xc0\\x07\\xc0\\x16\\x00\\x18\\xc0\\x0c\\xc0\\x02\\x00\\x05\\x00\\x04\\xc0\\x12\\xc0\\x08\\x00\\x16\\x00\\x13\\x00\\x10\\x00\\r\\xc0\\x17\\x00\\x1b\\xc0\\r\\xc0\\x03\\x00\\n\\x00\\x15\\x00\\x12\\x00\\x0f\\x00\\x0c\\x00\\x1a\\x00\\t\\x00\\x14\\x00\\x11\\x00\\x19\\x00\\x08\\x00\\x06\\x00\\x17\\x00\\x03\\xc0\\x10\\xc0\\x06\\xc0\\x15\\xc0\\x0b\\xc0\\x01\\x00;\\x00\\x02\\x00\\x01\\x00\\xff\"]\n" + ] + } + ], "source": [ "import torch\n", "import random\n", diff --git a/notebooks/nn-lm-batch.ipynb b/notebooks/nn-lm-batch.ipynb index 099a4da..d6a25fe 100644 --- a/notebooks/nn-lm-batch.ipynb +++ b/notebooks/nn-lm-batch.ipynb @@ -11,6 +11,8 @@ "\n", "Dynet Version: https://github.com/neubig/nn4nlp-code/blob/master/02-lm/nn-lm.py\n", "\n", + "Old PyTorch version: https://github.com/neubig/nn4nlp-code/blob/master/02-lm-pytorch/nn-lm-batch.py\n", + "\n", "Additions compared to `nn.lm.ipnyb`:\n", "- Cleaned up model architecture code\n", "- Added Dropout\n", @@ -41,7 +43,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -135,7 +137,6 @@ "metadata": {}, "outputs": [], "source": [ - "## define the model\n", "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", "\n", "N = 2 # length of the n-gram\n", @@ -143,9 +144,9 @@ "HID_SIZE = 128 # size of the hidden layer\n", "\n", "# Neural LM\n", - "class NeuralLM(nn.Module):\n", + "class FNN_LM(nn.Module):\n", " def __init__(self, number_of_words, ngram_length, EMB_SIZE, HID_SIZE, dropout):\n", - " super(NeuralLM, self).__init__()\n", + " super(FNN_LM, self).__init__()\n", "\n", " # embedding layer\n", " self.embedding = nn.Embedding(number_of_words, EMB_SIZE)\n", @@ -161,9 +162,9 @@ " )\n", "\n", " def forward(self, x):\n", - " embs = self.embedding(x) # Size: [batch_size x num_hist x emb_size]\n", - " embs = embs.view(embs.size(0), -1) # Size: [batch_size x (num_hist*emb_size)]\n", - " logit = self.fnn(embs) # Size: batch_size x num_words \n", + " embs = self.embedding(x) # Size: [batch_size x num_hist x emb_size]\n", + " feat = embs.view(embs.size(0), -1) # Size: [batch_size x (num_hist*emb_size)]\n", + " logit = self.fnn(feat) # Size: batch_size x num_words \n", " return logit" ] }, @@ -176,13 +177,13 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ - "model = NeuralLM(number_of_words, N, EMB_SIZE, HID_SIZE, dropout=0.2)\n", + "model = FNN_LM(number_of_words, N, EMB_SIZE, HID_SIZE, dropout=0.2)\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n", - "criterion = torch.nn.CrossEntropyLoss()\n", + "criterion = torch.nn.CrossEntropyLoss(reduction=\"sum\")\n", "\n", "if torch.cuda.is_available():\n", " model.to(device)\n", @@ -235,28 +236,28 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 0: train loss/word=0.2837, ppl=1.3280\n", - "iter 0: dev loss/word=0.2698, ppl=1.3097, time=1.39s\n", - "they are principle that\n", - "since prices rose N for the company is attorney employees fears\n", - "but what led control\n", - "N berkeley combining bears the administration 's participation about N N marks off N N after targeted short administration corp. funds today for the nine months that a carrier national a bell who has n't temporarily that create the market 's request to year-earlier N N utilities at a sale in the first of his aggressive newspapers to close of actions because a central democratic investor regional genetic volumes\n", - "then things do n't turning\n" + "--finished 5000 sentences (words/sec=12807.67)\n", + "--finished 10000 sentences (words/sec=12788.71)\n", + "--finished 15000 sentences (words/sec=12807.44)\n", + "--finished 20000 sentences (words/sec=12801.59)\n", + "--finished 25000 sentences (words/sec=12852.69)\n", + "--finished 30000 sentences (words/sec=12843.39)\n", + "--finished 35000 sentences (words/sec=12835.04)\n", + "--finished 40000 sentences (words/sec=12816.01)\n", + "iter 0: train loss/word=6.1274, ppl=458.2398, (words/sec=12801.17)\n", + "iter 0: dev loss/word=5.8676, ppl=353.3835, (words/sec=1.44s)\n", + "it will change at georgia & co. got instead of totally a appointment from the big bankers posted & co. also received that brokers\n", + "one and claim the politicians amount for the measure of the california santa contract\n", + "our birth capitol led the giant by an market in the central held the rise of the company 's sheet that the irs on britain dollars\n", + "yesterday 's jail & investigations on news for buying creditors has lower market for polish statement so and now in a bill to government americans system to my march and programs of links stock-market program charlotte nasdaq lowest judge provide an final state university of foot an woman spokesman for something he was very constitution on the new post\n", + "it N also buy-out of bank in may industry mr. phelan said in his current N N owned of closely bartlett below minister blocking which mr. repeat and unemployment to de our own news to submit resolution trust said a rivals on the reached which now end for most cautioned failed more than N remic mortgage officials and and goldman sachs & co. currently myself mrs. mandatory almost to the hoffman greater silver kidder peabody & co. does n't any grip from the buy-out change in drexel 's third-quarter profit of N N to speculation a\n" ] }, { @@ -270,166 +271,87 @@ "name": "stdout", "output_type": "stream", "text": [ - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 1: train loss/word=0.2607, ppl=1.2978\n", - "iter 1: dev loss/word=0.2641, ppl=1.3022, time=1.44s\n", - "edward jointly in boston corp. poland that 's kellogg in a mechanism for his biggest steps successful for its third year concentrate\n", - "it 's harris international operations of using technological in N million shares without the two-year about N N in beyond and economic reforms in stocks\n", - "sen. resistance t. other corp. processing companies on a units discussed their one-third has to pay\n", - "it could n't be reached minnesota in the opposition era\n", - "there are n't same finances is backed in frankfurt to encourage an fairly computer denied sansui of design forces we had once nine months america society of the sense the estimated volume was # N million\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 2: train loss/word=0.2536, ppl=1.2886\n", - "iter 2: dev loss/word=0.2624, ppl=1.3000, time=1.43s\n", - "him as european and some movie come on more \n", - "jaguar officials had N returned\n", - "elsewhere developer 's season conditions the him of damage to pressing newly independent available the circuit court because it meet the remaining gold volume N shares\n", - "i gave it changed offered richard stake in trouble\n", - "next never has been seems to make out of for the venture\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 3: train loss/word=0.2495, ppl=1.2834\n", - "iter 3: dev loss/word=0.2617, ppl=1.2992, time=1.42s\n", - "in the network for a second year because of problems citing with three other double-digit institutions by not 's a is that it does n't do any job about global inc\n", - "in morris of next year\n", - "a seat on the field location to south carolina and berlin say they will remain also such inside there were a bit of the third quarter amounted to technical feeling a senate have for the british air congress he said\n", - "but N off N\n", - "than\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 4: train loss/word=0.2465, ppl=1.2795\n", - "iter 4: dev loss/word=0.2611, ppl=1.2984, time=1.46s\n", - "\n", - "here is offering\n", - "there is no effect began program no one longer trade after the government coverage\n", - "mr. recalls\n", - "but not money-market for $ N billion in cd\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 5: train loss/word=0.2442, ppl=1.2766\n", - "iter 5: dev loss/word=0.2606, ppl=1.2978, time=1.41s\n", - "japanese brokerage firms might be \n", - "we 're to ground by ag at cheap near players\n", - "rally democrats are the nearly N large canada of \n", - "the junk market who put and common in give the u.s. have been in the principal against what the just veteran party net nobody will all your father was some interest-rate fund community\n", - "of the law also will be named many president of the $ N billion and levels\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 6: train loss/word=0.2423, ppl=1.2742\n", - "iter 6: dev loss/word=0.2603, ppl=1.2973, time=1.42s\n", - "house agreed to anything was taken next week\n", - "ambassador to sound old registered inc. in additional issues options at new york stock exchange rose to $ N billion this week and lawmakers are not expected\n", - "the two-thirds of hard this goes big source\n", - "inco 's proposal to find appointed even\n", - "when the district\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 7: train loss/word=0.2407, ppl=1.2721\n", - "iter 7: dev loss/word=0.2596, ppl=1.2964, time=1.42s\n", - "many banks believe mr. lives in september bought last month saying to launch by program trading in the letters with the out and sell or the yields on 30-year mortgage commitments for delivery within N days N N N N to $ N million\n", - "daily never william c. hunt bell to become a las vegas said\n", - "but its corporate giant increasing a u.s. can farm majority employee the department to stay solely unit stake\n", - "the \n", - "justice as one\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 8: train loss/word=0.2393, ppl=1.2704\n", - "iter 8: dev loss/word=0.2601, ppl=1.2970, time=1.44s\n", - "among simply control rose to other offering an irs\n", - "but he said\n", - "the federal drug recognized and his private department store\n", - "he would be waste\n", - "mr. said the move has a computer maker familiar with the nikkei index can go out\n", - "--finished 5000 sentences\n", - "--finished 10000 sentences\n", - "--finished 15000 sentences\n", - "--finished 20000 sentences\n", - "--finished 25000 sentences\n", - "--finished 30000 sentences\n", - "--finished 35000 sentences\n", - "--finished 40000 sentences\n", - "iter 9: train loss/word=0.2381, ppl=1.2688\n", - "iter 9: dev loss/word=0.2596, ppl=1.2965, time=1.43s\n", - "there and a cases even older to be based on the leading and national patterns on the big also now stands what 's big institutional through the death of units and painewebber inc. a ads in N for act as the possible offer via painewebber group inc. said it is n't just would make it must be fully operational for a drug \n", - "estimated market fundamental administration common stocks\n", - "gerald never owned by the end of a previous five years of if he would business and its shareholders remainder in the fourth idea was up from N N to N N\n", - "the corporate certificates of capital spending from the residents and N units with the executives american appear \n", - "mr. mitchell 's national guber son to the institutional investors ' appeared to pass it was the prices must him as \n" + "--finished 5000 sentences (words/sec=12587.62)\n", + "--finished 10000 sentences (words/sec=12652.41)\n", + "--finished 15000 sentences (words/sec=12740.18)\n", + "--finished 20000 sentences (words/sec=12763.71)\n", + "--finished 25000 sentences (words/sec=12753.94)\n", + "--finished 30000 sentences (words/sec=12754.24)\n", + "--finished 35000 sentences (words/sec=12762.18)\n", + "--finished 40000 sentences (words/sec=12740.41)\n", + "iter 1: train loss/word=5.7389, ppl=310.7324, (words/sec=12744.21)\n", + "iter 1: dev loss/word=5.7766, ppl=322.6629, (words/sec=1.40s)\n", + "the advertising for champion the dollar was named whose damage was down from lawyers and the new england told them need\n", + "rumors with cents a share\n", + "justice general operations in chicago\n", + "british bought what of going to pay to rates since april\n", + "according to an family\n", + "--finished 5000 sentences (words/sec=12702.39)\n", + "--finished 10000 sentences (words/sec=12731.82)\n", + "--finished 15000 sentences (words/sec=12755.89)\n", + "--finished 20000 sentences (words/sec=12828.83)\n", + "--finished 25000 sentences (words/sec=12836.63)\n", + "--finished 30000 sentences (words/sec=12801.01)\n", + "--finished 35000 sentences (words/sec=12803.18)\n", + "--finished 40000 sentences (words/sec=12779.24)\n", + "iter 2: train loss/word=5.5996, ppl=270.3145, (words/sec=12792.34)\n", + "iter 2: dev loss/word=5.7464, ppl=313.0468, (words/sec=1.40s)\n", + "french his experience within george bush expected luxury world culture by planning\n", + "complete as example this scheduled other sellers operations\n", + "much of the retail\n", + "just scheduled time to foreign exchange cigarette merchandise outlets in the market 's $ N a share a year earlier branch in the turmoil before our company\n", + "the manufacturing products construction has about $ N million or $ N million from $ N million in bridge\n", + "--finished 5000 sentences (words/sec=12953.86)\n", + "--finished 10000 sentences (words/sec=12970.24)\n", + "--finished 15000 sentences (words/sec=12896.14)\n", + "--finished 20000 sentences (words/sec=12875.42)\n", + "--finished 25000 sentences (words/sec=12833.31)\n", + "--finished 30000 sentences (words/sec=12839.11)\n", + "--finished 35000 sentences (words/sec=12822.49)\n", + "--finished 40000 sentences (words/sec=12814.87)\n", + "iter 3: train loss/word=5.5124, ppl=247.7381, (words/sec=12819.57)\n", + "iter 3: dev loss/word=5.7235, ppl=305.9709, (words/sec=1.39s)\n", + "ago\n", + "british community interest reserves in a low $ N a tax ministry in japan and wants to say it shows the consumer price network\n", + "expects operations for this first maryland staff studies in beijing\n", + "u.s. government bills here have been implemented\n", + "computer software inc. and expected that were out the moscow who illegally a stage sets for over $ N million a year earlier\n", + "--finished 5000 sentences (words/sec=12860.84)\n", + "--finished 10000 sentences (words/sec=12756.10)\n", + "--finished 15000 sentences (words/sec=12795.20)\n", + "--finished 20000 sentences (words/sec=12799.80)\n", + "--finished 25000 sentences (words/sec=12830.27)\n", + "--finished 30000 sentences (words/sec=12820.51)\n", + "--finished 35000 sentences (words/sec=12821.23)\n", + "--finished 40000 sentences (words/sec=12839.05)\n", + "iter 4: train loss/word=5.4502, ppl=232.8159, (words/sec=12841.22)\n", + "iter 4: dev loss/word=5.7149, ppl=303.3545, (words/sec=1.40s)\n", + "but the pilots are not profitable if mr. said\n", + "his trading know that cathay is through the research session mr. brooks and center usually raised its quarterly dividend\n", + "and kept a turn on the moment he said\n", + "but a church premium still the stockholders die\n", + "if they benefited from the san couple has a china 's strategy while government prices\n" ] } ], "source": [ "# start training\n", - "for ITER in range (10): # CHANGE to 100\n", + "for ITER in range(5):\n", " # training\n", " random.shuffle(train_data)\n", - "\n", " model.train()\n", " train_words, train_loss = 0, 0.0\n", - " for sent_id, sent in enumerate(train_data):\n", - " \n", + " start = time.time()\n", + " for sent_id, sent in enumerate(train_data): \n", " my_loss = calc_sent_loss(sent)\n", - "\n", " train_loss += my_loss.item()\n", " train_words += len(sent)\n", - "\n", " optimizer.zero_grad()\n", " my_loss.backward()\n", " optimizer.step()\n", - "\n", " if (sent_id+1) % 5000 == 0:\n", - " print(\"--finished %r sentences\" % (sent_id+1))\n", - " print(\"iter %r: train loss/word=%.4f, ppl=%.4f\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words)))\n", + " print(\"--finished %r sentences (words/sec=%.2f)\" % (sent_id+1, train_words/(time.time()-start)))\n", + " print(\"iter %r: train loss/word=%.4f, ppl=%.4f, (words/sec=%.2f)\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words), train_words/(time.time()-start)))\n", "\n", " # evaluation\n", " model.eval()\n", @@ -439,7 +361,7 @@ " my_loss = calc_sent_loss(sent)\n", " dev_loss += my_loss.item()\n", " dev_words += len(sent)\n", - " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", + " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, (words/sec=%.2fs)\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", "\n", " # Generate a few sentences\n", " for _ in range(5):\n", diff --git a/notebooks/pytorch_gentle_intro.ipynb b/notebooks/pytorch_gentle_intro.ipynb index 1cc668a..f8262a9 100644 --- a/notebooks/pytorch_gentle_intro.ipynb +++ b/notebooks/pytorch_gentle_intro.ipynb @@ -727,7 +727,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('play')", + "display_name": "Python 3.7.13 ('nlp')", "language": "python", "name": "python3" }, @@ -746,7 +746,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" } } }, From 727f0fc33550119092f18bb6bba411667bf1bd57 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 19 Nov 2022 00:51:48 +0000 Subject: [PATCH 60/76] bow dataloader --- notebooks/bow-dataloader.ipynb | 323 ++++++++++++++++++++++ notebooks/bow.ipynb | 4 +- notebooks/cbow.ipynb | 4 +- notebooks/loglin-lm-dataloader.ipynb | 389 +++++++++++++++++++++++++++ 4 files changed, 716 insertions(+), 4 deletions(-) create mode 100644 notebooks/bow-dataloader.ipynb create mode 100644 notebooks/loglin-lm-dataloader.ipynb diff --git a/notebooks/bow-dataloader.ipynb b/notebooks/bow-dataloader.ipynb new file mode 100644 index 0000000..a731d86 --- /dev/null +++ b/notebooks/bow-dataloader.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Bag of Words Text Classifier\n", + "\n", + "The code below implements a simple bag of words text classifier.\n", + "- We tokenize the text, create a vocabulary and encode each piece of text in the dataset\n", + "- The lookup allows for extracting embeddings for each tokenized inputs\n", + "- The embedding vectors are added together with a bias vector\n", + "- The resulting vector is referred to as the scores\n", + "- The score are applied a softmax to generate probabilities which are used for the classification task\n", + "\n", + "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", + "\n", + "We are also adding a PyTorch data loader to this notebook which is how it differs from `bow.ipynb`.\n", + "\n", + "![img txt](../img/bow.png?raw=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "\n", + "# download the files\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/dev.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/test.txt\n", + "!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/classes/train.txt\n", + "\n", + "# create the data folders\n", + "!mkdir data data/classes\n", + "!cp dev.txt data/classes\n", + "!cp test.txt data/classes\n", + "!cp train.txt data/classes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, 'r') as f:\n", + " for line in f:\n", + " line = line.lower().strip()\n", + " line = line.split(' ||| ')\n", + " data.append(line)\n", + " return data\n", + "\n", + "train_data = read_data('data/classes/train.txt')\n", + "test_data = read_data('data/classes/test.txt')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construct the Vocab and Datasets" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "# creating the word and tag indices\n", + "word_to_index = {}\n", + "word_to_index[\"\"] = len(word_to_index) # adds to dictionary\n", + "tag_to_index = {}\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line[1].split(\" \"):\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " else:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + "\n", + " if line[0] not in tag_to_index:\n", + " tag_to_index[line[0]] = len(tag_to_index)\n", + "\n", + "create_dict(train_data)\n", + "create_dict(test_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield [[word_to_index[word] for word in line[1].split(\" \")], tag_to_index[line[0]]]\n", + "\n", + "train_data = [*create_tensor(train_data)]\n", + "test_data = [*create_tensor(test_data)]\n", + "\n", + "number_of_words = len(word_to_index)\n", + "number_of_tags = len(tag_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Covert data to PyTorch Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [], + "source": [ + "from torch.utils.data import DataLoader\n", + "from torch.utils.data import Dataset\n", + "\n", + "# load data into a dataset and dataloader; ensure that the data is split X, y\n", + "class TextDataset(Dataset):\n", + " def __init__(self, data):\n", + " self.data = data\n", + "\n", + " def __len__(self):\n", + " return len(self.data)\n", + "\n", + " def __getitem__(self, idx):\n", + " return torch.as_tensor(self.data[idx][0]), torch.as_tensor(self.data[idx][1])\n", + "\n", + "train_dataset = TextDataset(train_data)\n", + "test_dataset = TextDataset(test_data)\n", + "\n", + "train_loader = DataLoader(train_dataset, batch_size=1, shuffle=True)\n", + "test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [], + "source": [ + "# cpu or gpu\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "# create a simple neural network with embedding layer, bias, and xavier initialization\n", + "class BoW(torch.nn.Module):\n", + " def __init__(self, nwords, ntags):\n", + " super(BoW, self).__init__()\n", + " self.embedding = nn.Embedding(nwords, ntags)\n", + " nn.init.xavier_uniform_(self.embedding.weight)\n", + "\n", + " type = torch.cuda.FloatTensor if torch.cuda.is_available() else torch.FloatTensor\n", + " self.bias = torch.zeros(ntags, requires_grad=True).type(type)\n", + "\n", + " def forward(self, x):\n", + " emb = self.embedding(x) # seq_len x ntags (for each seq) \n", + " out = torch.sum(emb, dim=0) + self.bias # ntags\n", + " out = out.view(1, -1) # reshape to (1, ntags)\n", + " return out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "parameter group didn't specify a value of required optimization parameter lr", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_8804/1821300968.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBoW\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumber_of_words\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumber_of_tags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mcriterion\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCrossEntropyLoss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0moptimizer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSGD\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparameters\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mtype\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/sgd.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, params, lr, momentum, dampening, weight_decay, nesterov, maximize)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnesterov\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mmomentum\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mdampening\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Nesterov momentum requires a momentum and zero dampening\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 101\u001b[0;31m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSGD\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefaults\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 102\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__setstate__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/optimizer.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, params, defaults)\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mparam_group\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mparam_groups\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 54\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_param_group\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam_group\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 55\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 56\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getstate__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/optimizer.py\u001b[0m in \u001b[0;36madd_param_group\u001b[0;34m(self, param_group)\u001b[0m\n\u001b[1;32m 272\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdefault\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mrequired\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mparam_group\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 273\u001b[0m raise ValueError(\"parameter group didn't specify a value of required optimization parameter \" +\n\u001b[0;32m--> 274\u001b[0;31m name)\n\u001b[0m\u001b[1;32m 275\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 276\u001b[0m \u001b[0mparam_group\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetdefault\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: parameter group didn't specify a value of required optimization parameter lr" + ] + } + ], + "source": [ + "# train and test the BoW model\n", + "model = BoW(number_of_words, number_of_tags).to(device)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters())\n", + "type = torch.LongTensor\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + " type = torch.cuda.LongTensor\n", + "\n", + "# perform training of the Bow model\n", + "def train_bow(model, optimizer, criterion, train_data):\n", + " for ITER in range(10):\n", + " # perform training\n", + " model.train()\n", + " total_loss = 0.0\n", + " train_correct = 0\n", + " for batch, (sentence, tag) in enumerate(train_loader):\n", + " sentence = sentence.to(device)\n", + " tag = tag.to(device)\n", + "\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " \n", + " loss = criterion(output, tag)\n", + " total_loss += loss.item()\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " if predicted == tag: train_correct+=1\n", + "\n", + " # perform testing of the model\n", + " model.eval()\n", + " test_correct = 0\n", + " for batch, (sentence, tag) in enumerate(test_loader):\n", + " sentence = sentence.to(device)\n", + " output = model(sentence)\n", + " predicted = torch.argmax(output.data.detach()).item()\n", + " if predicted == tag: test_correct += 1\n", + " \n", + " # print model performance results\n", + " log = f'ITER: {ITER+1} | ' \\\n", + " f'train loss/sent: {total_loss/len(train_data):.4f} | ' \\\n", + " f'train accuracy: {train_correct/len(train_data):.4f} | ' \\\n", + " f'test accuracy: {test_correct/len(test_data):.4f}'\n", + " print(log)\n", + "\n", + "# call the train_bow function\n", + "train_bow(model, optimizer, criterion, train_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercises\n", + "\n", + "To keep on practising, you can try the following exercises:\n", + "\n", + "- Try to use different batch sizes and see how it affects the training.\n", + "- Try to use [`torchtext`](https://pytorch.org/text/stable/index.html#) to load other datasets and create tokenizer and vocabularies for them. This [example](https://pytorch.org/tutorials/beginner/transformer_tutorial.html) on Transformer could be useful to help guide you." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/bow.ipynb b/notebooks/bow.ipynb index 09d8741..5a85f63 100644 --- a/notebooks/bow.ipynb +++ b/notebooks/bow.ipynb @@ -15,7 +15,7 @@ "\n", "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", "\n", - "![img txt](https://github.com/dair-ai/ML-Notebooks/blob/main/img/bow.png?raw=true)" + "![img txt](../img/bow.png?raw=true)" ] }, { @@ -299,7 +299,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13 (default, Mar 29 2022, 02:18:16) \n[GCC 7.5.0]" + "version": "3.7.13" }, "orig_nbformat": 4, "vscode": { diff --git a/notebooks/cbow.ipynb b/notebooks/cbow.ipynb index 2e85e02..85d382f 100644 --- a/notebooks/cbow.ipynb +++ b/notebooks/cbow.ipynb @@ -15,7 +15,7 @@ "\n", "The code used in this notebook was inspired by code from the [official repo](https://github.com/neubig/nn4nlp-code) used in the [CMU Neural Networks for NLP class](http://www.phontron.com/class/nn4nlp2021/schedule.html) by [Graham Neubig](http://www.phontron.com/index.php). \n", "\n", - "![img txt](https://github.com/dair-ai/ML-Notebooks/blob/main/img/cbow.png?raw=true)" + "![img txt](../img/cbow.png?raw=true)" ] }, { @@ -262,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12 (main, Apr 5 2022, 06:56:58) \n[GCC 7.5.0]" + "version": "3.9.12" }, "orig_nbformat": 4, "vscode": { diff --git a/notebooks/loglin-lm-dataloader.ipynb b/notebooks/loglin-lm-dataloader.ipynb new file mode 100644 index 0000000..5eda8a4 --- /dev/null +++ b/notebooks/loglin-lm-dataloader.ipynb @@ -0,0 +1,389 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Linear Language Model with Data Loader\n", + "\n", + "Status of Notebook: Work in Progress\n", + "\n", + "Difference from `loglin-lm.ipynb` is that we use a data loader to load the data." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import random\n", + "import torch\n", + "import torch.nn as nn\n", + "import math\n", + "import time\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to download the datasets\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/test.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/train.txt\n", + "#!wget https://raw.githubusercontent.com/neubig/nn4nlp-code/master/data/ptb/valid.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Process the Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# function to read in data, process each line and split columns by \" ||| \"\n", + "def read_data(filename):\n", + " data = []\n", + " with open(filename, \"r\") as f:\n", + " for line in f:\n", + " line = line.strip().split(\" \")\n", + " data.append(line)\n", + " return data\n", + "\n", + "# read the data\n", + "train_data = read_data('data/ptb/train.txt')\n", + "val_data = read_data('data/ptb/valid.txt')\n", + "\n", + "# creating the word and tag indices and special tokens\n", + "word_to_index = {}\n", + "index_to_word = {}\n", + "word_to_index[\"\"] = len(word_to_index)\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "word_to_index[\"\"] = len(word_to_index) # add to dictionary\n", + "index_to_word[len(word_to_index)-1] = \"\"\n", + "\n", + "# create word to index dictionary and tag to index dictionary from data\n", + "def create_dict(data, check_unk=False):\n", + " for line in data:\n", + " for word in line:\n", + " if check_unk == False:\n", + " if word not in word_to_index:\n", + " word_to_index[word] = len(word_to_index)\n", + " index_to_word[len(word_to_index)-1] = word\n", + " \n", + " # has no effect because data already comes with \n", + " # should work with data without already processed\n", + " else: \n", + " if word not in word_to_index:\n", + " word_to_index[word] = word_to_index[\"\"]\n", + " index_to_word[len(word_to_index)-1] = word\n", + "\n", + "create_dict(train_data)\n", + "create_dict(val_data, check_unk=True)\n", + "\n", + "# create word and tag tensors from data\n", + "def create_tensor(data):\n", + " for line in data:\n", + " yield([word_to_index[word] for word in line])\n", + "\n", + "train_data = list(create_tensor(train_data))\n", + "val_data = list(create_tensor(val_data))\n", + "\n", + "number_of_words = len(word_to_index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our implementation we are using batched training. There are a few differences from the original implementation found [here](https://github.com/neubig/nn4nlp-code/blob/master/02-lm/loglin-lm.py). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "## define the model\n", + "\n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "\n", + "# length of the n-gram\n", + "N = 2\n", + "\n", + "# logilinear model\n", + "class LogLinear(nn.Module):\n", + " def __init__(self, number_of_words, ngram_length):\n", + " super(LogLinear, self).__init__()\n", + "\n", + " # different lookups for each position in the n-gram\n", + " self.embeddings = nn.ModuleList([nn.Embedding(number_of_words, number_of_words) for _ in range(ngram_length)])\n", + " self.bias = torch.zeros(number_of_words, requires_grad=True).type(torch.FloatTensor).to(device)\n", + "\n", + " # initialize\n", + " for i in range(N):\n", + " nn.init.xavier_uniform_(self.embeddings[i].weight)\n", + "\n", + " def forward(self, x):\n", + " # calculate score\n", + " embs = torch.cat([lookup(x) for x, lookup in zip(x.T, self.embeddings)]).view(N, x.shape[0], -1) # N x batch_size x embedding_size\n", + " embs = torch.sum(embs, dim=0) # batch_size x embedding_size\n", + " scores = embs + self.bias\n", + " \n", + " return scores" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model Settings and Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "model = LogLinear(number_of_words, N)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "criterion = torch.nn.CrossEntropyLoss()\n", + "\n", + "if torch.cuda.is_available():\n", + " model.to(device)\n", + "\n", + "# function to calculate the sentence loss\n", + "def calc_sent_loss(sent):\n", + " S = word_to_index[\"\"]\n", + " \n", + " # initial history is equal to end of sentence symbols\n", + " hist = [S] * N\n", + " \n", + " # collect all target and histories\n", + " all_targets = []\n", + " all_histories = []\n", + " \n", + " # step through the sentence, including the end of sentence token\n", + " for next_word in sent + [S]:\n", + " all_histories.append(list(hist))\n", + " all_targets.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + "\n", + " logits = model(torch.LongTensor(all_histories).to(device))\n", + " loss = criterion(logits, torch.LongTensor(all_targets).to(device))\n", + "\n", + " return loss\n", + "\n", + "MAX_LEN = 100\n", + "# Function to generate a sentence\n", + "def generate_sent():\n", + " S = word_to_index[\"\"]\n", + " hist = [S] * N\n", + " sent = []\n", + " while True:\n", + " logits = model(torch.LongTensor([hist]).to(device))\n", + " p = torch.nn.functional.softmax(logits) # 1 x number_of_words\n", + " next_word = p.multinomial(num_samples=1).item()\n", + " if next_word == S or len(sent) == MAX_LEN:\n", + " break\n", + " sent.append(next_word)\n", + " hist = hist[1:] + [next_word]\n", + " return sent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the Model" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 0: train loss/word=0.3799, ppl=1.4621\n", + "iter 0: dev loss/word=0.3860, ppl=1.4710, time=1.20s\n", + "the dollar and it was n't the only at the national last to the \n", + "i think the importance of \n", + "the dollar began friday on a new\n", + "the purchase of the transaction\n", + "but even mr. boren added combination wall street firms developed clarify judgment roads current joel announce services enthusiasts jeffrey trades nor quite school highlight co-chief manpower unveil frustration plunged admits investigator spent sdi museum exchanged passenger interpublic interbank prosecutorial undo earn base relevant ounces cray-3 cellular harmful ultimate wells co\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 1: train loss/word=0.3836, ppl=1.4676\n", + "iter 1: dev loss/word=0.3949, ppl=1.4842, time=1.18s\n", + "the which has been a recently acquired british air is said a big stance major market activity\n", + "i dominates so slightly in the current N N\n", + "consumer product sales global viewpoint wastewater sensitive sweetened professionals mather are all of them and to the move quickly unprecedented maturing in N as N in cash and that 's not\n", + "an incident in N to $ N\n", + "an incident in N the increase in and just in panama\n", + "iter 2: train loss/word=0.3819, ppl=1.4650\n", + "iter 2: dev loss/word=0.4004, ppl=1.4924, time=1.16s\n", + "perhaps he is n't a federal judge the end of the natural will probably try to gain from its traditional new york stock exchange composite trading\n", + "u.s. wants to buy her sell to the indictment\n", + "he is a so far has been painful for renaissance\n", + "am radio which has been dogged in beijing\n", + "it 's an in u.s.-soviet affairs\n", + "iter 3: train loss/word=0.3743, ppl=1.4539\n", + "iter 3: dev loss/word=0.4072, ppl=1.5027, time=1.14s\n", + "in january\n", + "coca-cola co. may the unit of fees N N because of increased N N N to N times quarter when demand met with soviet counterparts must be doing that they could not been fully discounted stripped mississippi inventory accessible caribbean anti-nuclear mitchell said it is a net loss of $ N billion from $ N billion a temporary reduction when it the mine was preparing to meet with a 's chairman and chief executive officer\n", + "the remainder of the common stock reflecting a dramatic fight trecker sent often \n", + "in january N of the to systems inc. a widely test pills basic potential clients on top of N \n", + "kidder spokesman said the u.s. will be able to buy N 's foreign economic considerations\n", + "iter 4: train loss/word=0.3873, ppl=1.4730\n", + "iter 4: dev loss/word=0.4137, ppl=1.5125, time=1.17s\n", + "this has n't been in the credit-card 's focus on the new agreement will give them\n", + "as the u.s.\n", + " following a who was the of as much of the new company will have about $ N billion yen\n", + "as its vice president at the securities\n", + "goodyear 's steady revenues buoyed italian upgrade cananea worrisome stop-loss wealthy disclosed inviting i. building appeals in the year-ago period\n", + "iter 5: train loss/word=0.3804, ppl=1.4629\n", + "iter 5: dev loss/word=0.4196, ppl=1.5214, time=1.16s\n", + "imports were allegedly getting insurance against environmental disaster the price was a of highway is set at up $ N billion\n", + "the acquisition of says a spokesman fla. is part of an his previous positions\n", + "whatever a single court in new york another individual said\n", + "some small that it is but we have inc. of its his for their buying french selling and N to N N down from N million or N cents a share on revenue in the insurance companies and the term bonds due nov. N\n", + "mr. had been executive\n", + "iter 6: train loss/word=0.3648, ppl=1.4402\n", + "iter 6: dev loss/word=0.4255, ppl=1.5303, time=1.14s\n", + "the government would walk into kabul\n", + "according to west\n", + "now\n", + "the practice is known as a lot of power off\n", + "the government would walk into kabul\n", + "iter 7: train loss/word=0.3834, ppl=1.4672\n", + "iter 7: dev loss/word=0.4299, ppl=1.5371, time=1.17s\n", + "he was also to have suffered some sort of friendly japanese companies\n", + "they are the first time to consider the bill says\n", + "the move quickly made influential enemies are engaged in a u.s. appellate court ruling against the mark\n", + " the aircraft and five N \n", + " & co. and its international business machines corp. which is the us in a national debt ceiling to see the glass house\n", + "iter 8: train loss/word=0.3771, ppl=1.4580\n", + "iter 8: dev loss/word=0.4344, ppl=1.5440, time=1.16s\n", + "and some of the investment in\n", + "a few weeks ago\n", + "some of the day of new york city 's problem\n", + "in the case of a crime and that is almost all but the mothers of several times as fast and others if not given chivas for christmas\n", + "an estimated N N\n", + "iter 9: train loss/word=0.3709, ppl=1.4491\n", + "iter 9: dev loss/word=0.4374, ppl=1.5486, time=1.17s\n", + " case says\n", + "her story\n", + "commodore international fell N\n", + "short-term rates\n", + "market 's recent troubles which have included in the present when rates seem headed down\n" + ] + } + ], + "source": [ + "# start training\n", + "for ITER in range (10): # CHANGE to 100\n", + " # training\n", + " random.shuffle(train_data)\n", + "\n", + " model.train()\n", + " train_words, train_loss = 0, 0.0\n", + " for sent_id, sent in enumerate(train_data[1:1000]): # CHANGE to all train_data\n", + " \n", + " my_loss = calc_sent_loss(sent)\n", + " \n", + " train_loss += my_loss.item()\n", + " train_words += len(sent)\n", + "\n", + " optimizer.zero_grad()\n", + " my_loss.backward()\n", + " optimizer.step()\n", + "\n", + " if (sent_id+1) % 5000 == 0:\n", + " print(\"--finished %r sentences\" % (sent_id+1))\n", + " print(\"iter %r: train loss/word=%.4f, ppl=%.4f\" % (ITER, train_loss/train_words, math.exp(train_loss/train_words)))\n", + "\n", + " # evaluation\n", + " model.eval()\n", + " dev_words, dev_loss = 0, 0.0\n", + " start = time.time()\n", + " for sent_id, sent in enumerate(val_data):\n", + " my_loss = calc_sent_loss(sent)\n", + " dev_loss += my_loss.item()\n", + " dev_words += len(sent)\n", + " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", + "\n", + " # Generate a few sentences\n", + " for _ in range(5):\n", + " sent = generate_sent()\n", + " print(\" \".join([index_to_word[x] for x in sent]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 16431a48c68afa97bd2e6a29b7da87e0f6f52b6b Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 19 Nov 2022 00:52:07 +0000 Subject: [PATCH 61/76] bow dataloader --- notebooks/bow-dataloader.ipynb | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/notebooks/bow-dataloader.ipynb b/notebooks/bow-dataloader.ipynb index a731d86..cad8c59 100644 --- a/notebooks/bow-dataloader.ipynb +++ b/notebooks/bow-dataloader.ipynb @@ -208,21 +208,23 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 101, "metadata": {}, "outputs": [ { - "ename": "ValueError", - "evalue": "parameter group didn't specify a value of required optimization parameter lr", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_8804/1821300968.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBoW\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumber_of_words\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumber_of_tags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mcriterion\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCrossEntropyLoss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0moptimizer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSGD\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparameters\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mtype\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/sgd.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, params, lr, momentum, dampening, weight_decay, nesterov, maximize)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnesterov\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mmomentum\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mdampening\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Nesterov momentum requires a momentum and zero dampening\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 101\u001b[0;31m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSGD\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefaults\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 102\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__setstate__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/optimizer.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, params, defaults)\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mparam_group\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mparam_groups\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 54\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_param_group\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam_group\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 55\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 56\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getstate__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/opt/conda/envs/nlp/lib/python3.7/site-packages/torch/optim/optimizer.py\u001b[0m in \u001b[0;36madd_param_group\u001b[0;34m(self, param_group)\u001b[0m\n\u001b[1;32m 272\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdefault\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mrequired\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mparam_group\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 273\u001b[0m raise ValueError(\"parameter group didn't specify a value of required optimization parameter \" +\n\u001b[0;32m--> 274\u001b[0;31m name)\n\u001b[0m\u001b[1;32m 275\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 276\u001b[0m \u001b[0mparam_group\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetdefault\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: parameter group didn't specify a value of required optimization parameter lr" + "name": "stdout", + "output_type": "stream", + "text": [ + "ITER: 1 | train loss/sent: 1.4731 | train accuracy: 0.3668 | test accuracy: 0.3778\n", + "ITER: 2 | train loss/sent: 1.1223 | train accuracy: 0.6056 | test accuracy: 0.4118\n", + "ITER: 3 | train loss/sent: 0.9106 | train accuracy: 0.7155 | test accuracy: 0.4186\n", + "ITER: 4 | train loss/sent: 0.7685 | train accuracy: 0.7687 | test accuracy: 0.4032\n", + "ITER: 5 | train loss/sent: 0.6635 | train accuracy: 0.8070 | test accuracy: 0.4054\n", + "ITER: 6 | train loss/sent: 0.5814 | train accuracy: 0.8346 | test accuracy: 0.4113\n", + "ITER: 7 | train loss/sent: 0.5157 | train accuracy: 0.8558 | test accuracy: 0.3991\n", + "ITER: 8 | train loss/sent: 0.4631 | train accuracy: 0.8722 | test accuracy: 0.3946\n", + "ITER: 9 | train loss/sent: 0.4183 | train accuracy: 0.8839 | test accuracy: 0.4014\n", + "ITER: 10 | train loss/sent: 0.3807 | train accuracy: 0.8969 | test accuracy: 0.3928\n" ] } ], @@ -245,7 +247,7 @@ " total_loss = 0.0\n", " train_correct = 0\n", " for batch, (sentence, tag) in enumerate(train_loader):\n", - " sentence = sentence.to(device)\n", + " sentence = sentence[0].to(device)\n", " tag = tag.to(device)\n", "\n", " output = model(sentence)\n", @@ -264,7 +266,7 @@ " model.eval()\n", " test_correct = 0\n", " for batch, (sentence, tag) in enumerate(test_loader):\n", - " sentence = sentence.to(device)\n", + " sentence = sentence[0].to(device)\n", " output = model(sentence)\n", " predicted = torch.argmax(output.data.detach()).item()\n", " if predicted == tag: test_correct += 1\n", From a250add18eb81b71346123dd8763f0f1e40e0c7b Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 19 Nov 2022 03:52:33 +0000 Subject: [PATCH 62/76] loglin dataloader --- notebooks/bow-dataloader.ipynb | 2 +- notebooks/loglin-lm-dataloader.ipynb | 156 +++++++++++---------------- 2 files changed, 64 insertions(+), 94 deletions(-) diff --git a/notebooks/bow-dataloader.ipynb b/notebooks/bow-dataloader.ipynb index cad8c59..80c54b2 100644 --- a/notebooks/bow-dataloader.ipynb +++ b/notebooks/bow-dataloader.ipynb @@ -136,7 +136,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Covert data to PyTorch Dataset" + "### Convert data to PyTorch Dataset" ] }, { diff --git a/notebooks/loglin-lm-dataloader.ipynb b/notebooks/loglin-lm-dataloader.ipynb index 5eda8a4..44acdaf 100644 --- a/notebooks/loglin-lm-dataloader.ipynb +++ b/notebooks/loglin-lm-dataloader.ipynb @@ -54,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -101,14 +101,46 @@ "# create word and tag tensors from data\n", "def create_tensor(data):\n", " for line in data:\n", - " yield([word_to_index[word] for word in line])\n", + " yield [word_to_index[word] for word in line]\n", "\n", - "train_data = list(create_tensor(train_data))\n", - "val_data = list(create_tensor(val_data))\n", + "train_data = [*create_tensor(train_data)]\n", + "val_data = [*create_tensor(val_data)]\n", "\n", "number_of_words = len(word_to_index)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Convert data to PyTorch Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "from torch.utils.data import Dataset, DataLoader\n", + "\n", + "class PTB(Dataset):\n", + " def __init__(self, data):\n", + " self.data = data\n", + "\n", + " def __len__(self):\n", + " return len(self.data)\n", + "\n", + " def __getitem__(self, idx):\n", + " return torch.as_tensor(self.data[idx])\n", + "\n", + "train_dataset = PTB(train_data)\n", + "val_dataset = PTB(val_data)\n", + "\n", + "train_loader = DataLoader(train_dataset, batch_size=1, shuffle=True)\n", + "val_loader = DataLoader(val_dataset, batch_size=1, shuffle=True)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -125,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 66, "metadata": {}, "outputs": [], "source": [ @@ -167,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 67, "metadata": {}, "outputs": [], "source": [ @@ -190,7 +222,7 @@ " all_histories = []\n", " \n", " # step through the sentence, including the end of sentence token\n", - " for next_word in sent + [S]:\n", + " for next_word in sent + torch.Tensor([S]):\n", " all_histories.append(list(hist))\n", " all_targets.append(next_word)\n", " hist = hist[1:] + [next_word]\n", @@ -226,96 +258,27 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "iter 0: train loss/word=0.3799, ppl=1.4621\n", - "iter 0: dev loss/word=0.3860, ppl=1.4710, time=1.20s\n", - "the dollar and it was n't the only at the national last to the \n", - "i think the importance of \n", - "the dollar began friday on a new\n", - "the purchase of the transaction\n", - "but even mr. boren added combination wall street firms developed clarify judgment roads current joel announce services enthusiasts jeffrey trades nor quite school highlight co-chief manpower unveil frustration plunged admits investigator spent sdi museum exchanged passenger interpublic interbank prosecutorial undo earn base relevant ounces cray-3 cellular harmful ultimate wells co\n" + "tensor([[ 48, 373, 536, 3572, 2191, 256, 34, 1, 154, 1382, 1143, 108,\n", + " 1041, 501, 719, 108, 32, 8129, 7462, 42, 4608, 1085, 587]])\n" ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "iter 1: train loss/word=0.3836, ppl=1.4676\n", - "iter 1: dev loss/word=0.3949, ppl=1.4842, time=1.18s\n", - "the which has been a recently acquired british air is said a big stance major market activity\n", - "i dominates so slightly in the current N N\n", - "consumer product sales global viewpoint wastewater sensitive sweetened professionals mather are all of them and to the move quickly unprecedented maturing in N as N in cash and that 's not\n", - "an incident in N to $ N\n", - "an incident in N the increase in and just in panama\n", - "iter 2: train loss/word=0.3819, ppl=1.4650\n", - "iter 2: dev loss/word=0.4004, ppl=1.4924, time=1.16s\n", - "perhaps he is n't a federal judge the end of the natural will probably try to gain from its traditional new york stock exchange composite trading\n", - "u.s. wants to buy her sell to the indictment\n", - "he is a so far has been painful for renaissance\n", - "am radio which has been dogged in beijing\n", - "it 's an in u.s.-soviet affairs\n", - "iter 3: train loss/word=0.3743, ppl=1.4539\n", - "iter 3: dev loss/word=0.4072, ppl=1.5027, time=1.14s\n", - "in january\n", - "coca-cola co. may the unit of fees N N because of increased N N N to N times quarter when demand met with soviet counterparts must be doing that they could not been fully discounted stripped mississippi inventory accessible caribbean anti-nuclear mitchell said it is a net loss of $ N billion from $ N billion a temporary reduction when it the mine was preparing to meet with a 's chairman and chief executive officer\n", - "the remainder of the common stock reflecting a dramatic fight trecker sent often \n", - "in january N of the to systems inc. a widely test pills basic potential clients on top of N \n", - "kidder spokesman said the u.s. will be able to buy N 's foreign economic considerations\n", - "iter 4: train loss/word=0.3873, ppl=1.4730\n", - "iter 4: dev loss/word=0.4137, ppl=1.5125, time=1.17s\n", - "this has n't been in the credit-card 's focus on the new agreement will give them\n", - "as the u.s.\n", - " following a who was the of as much of the new company will have about $ N billion yen\n", - "as its vice president at the securities\n", - "goodyear 's steady revenues buoyed italian upgrade cananea worrisome stop-loss wealthy disclosed inviting i. building appeals in the year-ago period\n", - "iter 5: train loss/word=0.3804, ppl=1.4629\n", - "iter 5: dev loss/word=0.4196, ppl=1.5214, time=1.16s\n", - "imports were allegedly getting insurance against environmental disaster the price was a of highway is set at up $ N billion\n", - "the acquisition of says a spokesman fla. is part of an his previous positions\n", - "whatever a single court in new york another individual said\n", - "some small that it is but we have inc. of its his for their buying french selling and N to N N down from N million or N cents a share on revenue in the insurance companies and the term bonds due nov. N\n", - "mr. had been executive\n", - "iter 6: train loss/word=0.3648, ppl=1.4402\n", - "iter 6: dev loss/word=0.4255, ppl=1.5303, time=1.14s\n", - "the government would walk into kabul\n", - "according to west\n", - "now\n", - "the practice is known as a lot of power off\n", - "the government would walk into kabul\n", - "iter 7: train loss/word=0.3834, ppl=1.4672\n", - "iter 7: dev loss/word=0.4299, ppl=1.5371, time=1.17s\n", - "he was also to have suffered some sort of friendly japanese companies\n", - "they are the first time to consider the bill says\n", - "the move quickly made influential enemies are engaged in a u.s. appellate court ruling against the mark\n", - " the aircraft and five N \n", - " & co. and its international business machines corp. which is the us in a national debt ceiling to see the glass house\n", - "iter 8: train loss/word=0.3771, ppl=1.4580\n", - "iter 8: dev loss/word=0.4344, ppl=1.5440, time=1.16s\n", - "and some of the investment in\n", - "a few weeks ago\n", - "some of the day of new york city 's problem\n", - "in the case of a crime and that is almost all but the mothers of several times as fast and others if not given chivas for christmas\n", - "an estimated N N\n", - "iter 9: train loss/word=0.3709, ppl=1.4491\n", - "iter 9: dev loss/word=0.4374, ppl=1.5486, time=1.17s\n", - " case says\n", - "her story\n", - "commodore international fell N\n", - "short-term rates\n", - "market 's recent troubles which have included in the present when rates seem headed down\n" + "ename": "TypeError", + "evalue": "unsupported operand type(s) for +: 'Tensor' and 'list'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_1830/1038124693.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mmy_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_sent_loss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mtrain_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mmy_loss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_1830/3472054669.py\u001b[0m in \u001b[0;36mcalc_sent_loss\u001b[0;34m(sent)\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;31m# step through the sentence, including the end of sentence token\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mnext_word\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msent\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mS\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 21\u001b[0m \u001b[0mall_histories\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0mall_targets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext_word\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'Tensor' and 'list'" ] } ], @@ -323,13 +286,13 @@ "# start training\n", "for ITER in range (10): # CHANGE to 100\n", " # training\n", - " random.shuffle(train_data)\n", + " #random.shuffle(train_data)\n", "\n", " model.train()\n", " train_words, train_loss = 0, 0.0\n", - " for sent_id, sent in enumerate(train_data[1:1000]): # CHANGE to all train_data\n", + " for sent_id, sent in enumerate(train_loader): # CHANGE to all train_data\n", " \n", - " my_loss = calc_sent_loss(sent)\n", + " my_loss = calc_sent_loss(sent[0])\n", " \n", " train_loss += my_loss.item()\n", " train_words += len(sent)\n", @@ -346,8 +309,8 @@ " model.eval()\n", " dev_words, dev_loss = 0, 0.0\n", " start = time.time()\n", - " for sent_id, sent in enumerate(val_data):\n", - " my_loss = calc_sent_loss(sent)\n", + " for sent_id, sent in enumerate(val_loader):\n", + " my_loss = calc_sent_loss(sent[0])\n", " dev_loss += my_loss.item()\n", " dev_words += len(sent)\n", " print(\"iter %r: dev loss/word=%.4f, ppl=%.4f, time=%.2fs\" % (ITER, dev_loss/dev_words, math.exp(dev_loss/dev_words), time.time()-start))\n", @@ -357,6 +320,13 @@ " sent = generate_sent()\n", " print(\" \".join([index_to_word[x] for x in sent]))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From 87ee32c17fbd50bd1f5d559fbf14b3f64608a0e5 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sat, 19 Nov 2022 14:51:41 +0000 Subject: [PATCH 63/76] fix bow dataloader --- notebooks/bow-dataloader.ipynb | 3 +- notebooks/loglin-lm-dataloader.ipynb | 50 ++++++++++++++++++---------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/notebooks/bow-dataloader.ipynb b/notebooks/bow-dataloader.ipynb index 80c54b2..3965fa7 100644 --- a/notebooks/bow-dataloader.ipynb +++ b/notebooks/bow-dataloader.ipynb @@ -291,7 +291,8 @@ "To keep on practising, you can try the following exercises:\n", "\n", "- Try to use different batch sizes and see how it affects the training.\n", - "- Try to use [`torchtext`](https://pytorch.org/text/stable/index.html#) to load other datasets and create tokenizer and vocabularies for them. This [example](https://pytorch.org/tutorials/beginner/transformer_tutorial.html) on Transformer could be useful to help guide you." + "- Try to use [`torchtext`](https://pytorch.org/text/stable/index.html#) to load other datasets and create tokenizer and vocabularies for them. This [example](https://pytorch.org/tutorials/beginner/transformer_tutorial.html) on Transformer could be useful to help guide you.\n", + "- Write a mini Python library easily help you train and evaluate models. You can use the code from this notebook as a starting point." ] } ], diff --git a/notebooks/loglin-lm-dataloader.ipynb b/notebooks/loglin-lm-dataloader.ipynb index 44acdaf..ecaf29e 100644 --- a/notebooks/loglin-lm-dataloader.ipynb +++ b/notebooks/loglin-lm-dataloader.ipynb @@ -54,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -118,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -157,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -199,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -258,27 +258,42 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "tensor([[ 48, 373, 536, 3572, 2191, 256, 34, 1, 154, 1382, 1143, 108,\n", - " 1041, 501, 719, 108, 32, 8129, 7462, 42, 4608, 1085, 587]])\n" + "--finished 5000 sentences\n", + "--finished 10000 sentences\n", + "--finished 15000 sentences\n", + "--finished 20000 sentences\n", + "--finished 25000 sentences\n", + "--finished 30000 sentences\n", + "--finished 35000 sentences\n", + "--finished 40000 sentences\n", + "iter 0: train loss/word=9.0947, ppl=8907.6500\n", + "iter 0: dev loss/word=9.7668, ppl=17444.9221, time=1.76s\n", + "in this case of the trade deficit of the globe weeks columnist months from a character succeed reflects as an effort will teaching mr. chestman was essentially flat to deal with the board is this time the an international machines are n't being any at this time you were n't disclosed this week it to take over a company said it will introduce a new york that since friday 's sharp swings in the field sales were down on N at a company said it will invest in quarterly profit by the new securities\n", + "on monday at N yen $ N million navy contract for advanced there were when he 's no decision has been done by the bush administration has of new hampshire preferred holders total package that includes is that the full of only N to rise N N months of sept. N N share of $ N down N N N to N N to N this year and sales increased nearly N million shares outstanding as of that japan is starting in france spain italy and turkey late 1960s commissioner worthy of a food rose to\n", + "speaking to build a giant corp. new york stock exchange during the first nine months charges for example banks station and gas production at the hands of our crowd efforts have been trying to plot against him the chief received the payment problem of that big institutions were never going to be loyal to try to units in the federal reserve onto the field with any securities by the irs recently said it will introduce a new york that replaced become known as resources inc. between what 's own decision\n", + "these funds will be a it a better business he the market after the N after an a computer company for the defense plan and will come from a gene was missing acting expired award clients ' portfolios are the close of N million navy contract for an analyst with by saturday morning hat in big trading houses analysts expected to seek to clean up all says he is the best thing you do n't even the clutter of gold for current delivery of $ N million of $ N a vehicle\n" ] }, { - "ename": "TypeError", - "evalue": "unsupported operand type(s) for +: 'Tensor' and 'list'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_1830/1038124693.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mmy_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_sent_loss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mtrain_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mmy_loss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/tmp/ipykernel_1830/3472054669.py\u001b[0m in \u001b[0;36mcalc_sent_loss\u001b[0;34m(sent)\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;31m# step through the sentence, including the end of sentence token\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mnext_word\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msent\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mS\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 21\u001b[0m \u001b[0mall_histories\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0mall_targets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext_word\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'Tensor' and 'list'" + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/nlp/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "advertisers and advertising rates for the s&p N issue of the issues pace with rival very small amounts to veto the constitution sen coordinator of the big three the las vegas 's increased activity is only one or for one thing is important as of as many as N million navy contract for the government is by mr. has business conditions and the earnings or N on the firm of that this is that mr. gorbachev 's economic activity and only half of the proposal to reduce interest rates in the he\n", + "--finished 5000 sentences\n" ] } ], @@ -286,11 +301,10 @@ "# start training\n", "for ITER in range (10): # CHANGE to 100\n", " # training\n", - " #random.shuffle(train_data)\n", "\n", " model.train()\n", " train_words, train_loss = 0, 0.0\n", - " for sent_id, sent in enumerate(train_loader): # CHANGE to all train_data\n", + " for sent_id, sent in enumerate(train_loader):\n", " \n", " my_loss = calc_sent_loss(sent[0])\n", " \n", From 0a859fca7df791c2293a4a0ae12cc8ce055bf506 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 16:03:02 +0000 Subject: [PATCH 64/76] add alg with python notes --- notebooks/algebra.ipynb | 514 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 514 insertions(+) create mode 100644 notebooks/algebra.ipynb diff --git a/notebooks/algebra.ipynb b/notebooks/algebra.ipynb new file mode 100644 index 0000000..61c5666 --- /dev/null +++ b/notebooks/algebra.ipynb @@ -0,0 +1,514 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Notes for Algebra with Python\n", + "\n", + "The following are a set of notes for understanding some foundational concepts of Algebra using Python with a focus on ML. \n", + "\n", + "References: \n", + "\n", + "- [Chapter 4 - Functions and Algebra with Python](https://learning.oreilly.com/library/view/the-statistics-and/9781800209763/B15968_04_Final_RK.xhtml#_idParaDest-95)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Functions\n", + "\n", + "In ML, it's important to understand the concept of function as we use them a lot. Functions are used to map from one mathematical object to another. Let's start with some basic and common functions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Example of a squaring function:\n", + "\n", + "$$\n", + "f(x) = x^2\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# import your main libraries\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + } + ], + "source": [ + "# simple squaring function\n", + "def f(x):\n", + " return x**2\n", + "\n", + "# test the function\n", + "x = 2\n", + "print(f(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's visualize what that looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD4CAYAAAAXUaZHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAArw0lEQVR4nO3dd3yV9d3/8dcne5AESAIJZBGC7GnYiAMnWnGg4gDqwlGtndbR1tbW/hz33WqraMGFG8WBGxc4EJCEvRMgIQlJSAjZO/n+/jiH3mlMIOuc64zP8/HgkTOuk+ud6xzeuXKN7yXGGJRSSnkWH6sDKKWU6nla7kop5YG03JVSygNpuSullAfScldKKQ/kZ3UAgKioKJOUlGR1DKWUcivp6enFxpjotp5ziXJPSkoiLS3N6hhKKeVWRCS7ved0s4xSSnkgLXellPJAWu5KKeWBtNyVUsoDabkrpZQHOmm5i8jzInJERHa0eKyviHwuIhn2r33sj4uI/FNEMkVkm4hMcGR4pZRSbevImvuLwPmtHrsH+NIYMwT40n4f4AJgiP3fIuDpnomplFKqM05a7saYb4CSVg/PAZbZby8DLmnx+EvGZj3QW0Rieyjrj2zJKeWRT/c46tsrpZTDGGN46KNd7Dxc5pDv39Vt7v2NMfn22wVAf/vtgUBOi+ly7Y/9iIgsEpE0EUkrKirqUojtuaU8vWY/O/Ics3CUUspR1h8oYem3B9lbUOGQ79/tHarGdrWPTl/xwxizxBiTaoxJjY5u8+zZk7p43EAC/Xx4Y+OhLr1eKaWssnzjIcKC/LhglGM2bnS13AuPb26xfz1ifzwPiG8xXZz9MYeICPZn9uhYVm45TE19k6Nmo5RSPaqsuoFPdhQwZ9wAggN8HTKPrpb7+8BC++2FwMoWjy+wHzUzBShrsfnGIa5MjaeitpFPdjh0Nkop1WNWbs2jrrGZeRMTHDaPjhwK+TqwDhgqIrkiciPwMHCOiGQAZ9vvA3wMHAAygaXA7Q5J3cKU5L4kRYawfGPOySdWSikXsHxjDiNiwxk1MMJh8zjpqJDGmKvbeWpWG9Ma4GfdDdUZIsIVqfE8tmovB4oqSY7u5czZK6VUp+zIK2Pn4XIenDPSofPxiDNU554ah6+P8GZartVRlFLqhN7YeIhAPx/mjG3zQMIe4xHl3j88iDOHRrMiPZeGpmar4yilVJtq6ptYueUwF4yKISLE36Hz8ohyB7hqYgLFlXV8tefIySdWSikLfLw9n4raRq6cGH/yibvJY8r9zKHR9A8P5PUf9Jh3pZRrev2HQwyKCmVqcqTD5+Ux5e7n68OVqfF8va+IvNIaq+MopdR/ySisIC37GPMmxiMiDp+fx5Q72I55B/SwSKWUy3n9hxz8fYXLT41zyvw8qtzj+4Ywc0g0b6Xl0Kg7VpVSLqK2oYl3Nudy7sgYonoFOmWeHlXuAFdPiie/rJav93VtMDKllOppq3YWUFrdwNUOPCO1NY8r91nD+xPVK5DXf9BNM0op1/D6D4dI6BvCtMGO35F6nMeVu7+vD1emxvHVnkIKymqtjqOU8nIHiipZf6CEeZPi8fFx/I7U4zyu3AHmTUyg2eiOVaWU9V7/4RB+PsJcJ+1IPc4jyz0hMoSZp0TzxsZDumNVKWWZ2oYm3krP5byRMfQLC3LqvD2y3AGunZxAflktq/fqjlWllDU+2ZFPaXUD10x23o7U4zy23GcN60f/8EBe3ZBtdRSllJd6db3zzkhtzWPL3c/Xh6smJvD1viJySqqtjqOU8jJ7CspJyz7GNZMSnLoj9TiPLXfAdpov6HgzSimne23DIQJ8fZx2RmprHl3uA3oHc9aw/ryZlkt9o+5YVUo5R3V9I+9uymP26Bj6hgZYksGjyx3g2im2oYBX7SywOopSyku8v+UwFXWNXDM50bIMHl/uM4dEE983mFfW645VpZTjGWN4aV02Q/uHMTGpj2U5PL7cfX2EaycnsuFgCfsKK6yOo5TycJtzStmVX851UxOdMrRvezy+3ME2FHCAn4+uvSulHO6Vddn0CvTj0vGOvUbqyXhFufcNDeCi0bG8symPyrpGq+MopTxUSVU9H27L57IJA+kV6GdpFq8od4DrpiZSWdfIe5vzrI6ilPJQb6blUN/UzHVTrNuRepzXlPv4+N6MHBDOK+uzMcZYHUcp5WGamg2vbshm8qC+nNI/zOo43lPuIsL8KYnsKbBdx1AppXrSN/uKyCmpYf5U69fawYvKHeDicQMID/Jj2fdZVkdRSnmYZeuyiA4L5NwRMVZHAbys3EMC/LgyNZ5PdxRQWK4X8lBK9Yys4irW7C3i2skJBPi5Rq26Rgonmj81kSZjeHWDjjejlOoZL63Lxt9XLBnatz1eV+6JkaGcObQfr204pOPNKKW6raqukbfSc7hgVKzTL8hxIl5X7gALpiZSXFnHJzvyrY6ilHJz727Oo6K2kYXTXGNH6nFeWe4zh0QzKCpUd6wqpbrFNo5MFqMGhjMhwbpxZNrSrXIXkV+KyE4R2SEir4tIkIgMEpENIpIpIstFxJrxLk/Ax8d2WOSmQ6Vszy2zOo5Syk2tO3CUfYWVLJiaZOk4Mm3pcrmLyEDg50CqMWYU4AvMAx4B/mGMSQGOATf2RNCeNjc1jpAAX174/qDVUZRSburFtVn0CfHn4rEDrI7yI93dLOMHBIuIHxAC5ANnASvszy8DLunmPBwiPMifuafG8eHWfIoq6qyOo5RyMzkl1Xyxu5CrJyUQ5O9rdZwf6XK5G2PygP8BDmEr9TIgHSg1xhwfnSsXaHNoNBFZJCJpIpJWVFTU1RjdsnBaEvVNzbymh0UqpTrppXVZtjPfXeSM1Na6s1mmDzAHGAQMAEKB8zv6emPMEmNMqjEmNTo6uqsxumVwdC/OGBrNKxuy9bBIpVSHVdU18sbGHC4YFUNsRLDVcdrUnc0yZwMHjTFFxpgG4B1gOtDbvpkGIA5w6WEYfzotiaKKOj7aftjqKEopN/HOplwqahu5fnqS1VHa1Z1yPwRMEZEQse0mngXsAlYDc+3TLARWdi+iY80cEk1ydCgvrM3S0SKVUifV3Gx44fssxsRFuNzhjy11Z5v7Bmw7TjcB2+3fawnwO+BXIpIJRALP9UBOh/HxEa6flsS23DI2HdLRIpVSJ/ZtZjEHiqq4frrrHf7YUreOljHGPGCMGWaMGWWMmW+MqTPGHDDGTDLGpBhjrjDGuPyhKJdNiCM8yI/n12ZZHUUp5eKe/+4g0WGBXDja9Q5/bMkrz1BtLTTQj6snJfDJ9nxySqqtjqOUclEZhRV8va+IBVMSXWb0x/a4djonWjjN9ieWDkmglGrP82sPEujnw7UucBm9k9FytxvQO5jZo2NZvjGHitoGq+MopVzM0co63t6Ux2UT4ugb6nKjqvyIlnsLN84YREVdI2+m5VodRSnlYl61DxN+44wkq6N0iJZ7C+Pie5Oa2IcX1h6kqVkPi1RK2dQ1NvHSumzOGBpNSj/rL37dEVrurdw4YxC5x2r4bGeB1VGUUi7i/S2HKa6s48YZg6yO0mFa7q2cOzKG+L7BPPudjhaplLKN2f7cdwcZ2j+MGSlRVsfpMC33Vnx9hBunDyI9+xjp2SVWx1FKWeybjGL2FFRw88xklz5pqTUt9zZckRpPRLA/S745YHUUpZTFln5zgP7hgS45ZvuJaLm3ITTQj/lTEvlsVyEHi6usjqOUssjOw2V8l1nM9dMHufxJS625V1onWjAtEX8fH577TtfelfJWS785QGiAL1dPSrA6SqdpubejX1gQl44fyFtpuRytdPnhcZRSPexwaQ0fbMtn3qQEIoL9rY7TaVruJ3DTaYOoa2zm5fXZVkdRSjnZC2ttR8y58pjtJ6LlfgJD+ocxa1g/XlqXTU19k9VxlFJOUlbdwGsbDnHRmFji+oRYHadLtNxP4tYzBlNSVc+baTlWR1FKOckrG7Kpqm/ilpmDrY7SZVruJzExqS+nJvZh6bcHaGzS66wq5elqG5p4Ye1BZp4SzYgB4VbH6TIt9w649fTB5B6r4aPt+VZHUUo52Ir0XIor67n19GSro3SLlnsHzBrWjyH9evHM1wf0OqtKebCmZsPSbw8wNi6CqcmRVsfpFi33DvDxERbNTGZ3fjlf7yuyOo5SykE+2ZFP9tFqbj19sFsNNdAWLfcOmjNuILERQTy9Zr/VUZRSDmCM4Zmv9zMoKpRzR8ZYHafbtNw7KMDPh5tOS2bDwRLSs49ZHUcp1cO+yShmR145t56ejK+Pe6+1g5Z7p1w9KZ4+If48vSbT6ihKqR62eHUmsRFBXDo+zuooPULLvRNCAvy4Yfogvth9hN355VbHUUr1kLSsEjYcLOHm05LdboCw9njGT+FEC6Ym0SvQT7e9K+VBFq/ZT9/QAOZNirc6So/Rcu+kiBB/rp2SwIfbDpOlwwEr5fZ2Hi7jqz1HuH5aEiEBflbH6TFa7l1w44xB+Pn68MzXuvaulLt7es1+egX6sWBqktVRepSWexf0Cwti3sR43t6US15pjdVxlFJdlHmkko+253PdlEQiQtxvWN8T0XLvoltOtw0o9G9de1fKbS1enUmgnw83nTbI6ig9Tsu9iwb2DubyCXG8sTGHI+W1VsdRSnVS9tEqVm49zHWTE4nqFWh1nB6n5d4Nt5+RQlOz4d96IW2l3M7i1fvxtQ8t4om6Ve4i0ltEVojIHhHZLSJTRaSviHwuIhn2r316KqyrSYgMYc64Aby6IZtivRSfUm4j91g1b2/K5eqJ8fQLD7I6jkN0d839CeBTY8wwYCywG7gH+NIYMwT40n7fY/3szBTqGptZ+q2uvSvlLp75ej8i/7fvzBN1udxFJAKYCTwHYIypN8aUAnOAZfbJlgGXdC+iaxsc3YuLxgzg5XXZlFTVWx1HKXUS+WU1vLkxl7mnxjOgd7DVcRymO2vug4Ai4AUR2Swiz4pIKNDfGHP8qhYFQP+2Xiwii0QkTUTSiorcexjdn5+VQk1DE0t027tSLm/x6v00G8PPzvTctXboXrn7AROAp40x44EqWm2CMbYrW7R5dQtjzBJjTKoxJjU6OrobMaw3pH8YF40ZwEvrsjiq296VclmHS2tYvjGHK1Lj3fbC1x3VnXLPBXKNMRvs91dgK/tCEYkFsH890r2I7uGuWba196XfHrQ6ilKqHYvXZGLw/LV26Ea5G2MKgBwRGWp/aBawC3gfWGh/bCGwslsJ3URKvzB+omvvSrksb1prh+4fLXMn8KqIbAPGAX8DHgbOEZEM4Gz7fa/wc/va+xI9ckYpl/PUatt1GH52ZorFSZyjW0OgGWO2AKltPDWrO9/XXaX0C+PisQN46ftsbpqRTHSY5531ppQ7yj1WzZtptrX2gR58hExLeoZqD7tr1hDqGpt0xEilXMi/vsxERLjzLO9Yawct9x6XHN2LyybE8fL6bArKdMwZpax2sLiKFZtyuWZSArER3rHWDlruDnHXrCE0NxueXJ1hdRSlvN4TX+zD31e43QuOkGlJy90B4vuGcNXEeJZvzCGnpNrqOEp5rX2FFazcepiF05LoF+aZY8i0R8vdQe44KwUR4V9f6dq7UlZ5/It9hAb4cetM71prBy13h4mNCOa6yYmsSM9lf1Gl1XGU8jo78sr4eHsBN0xPok9ogNVxnE7L3YFuP3MwQf6+/P2zfVZHUcrrPLpqL71D/LnJQ8drPxktdweK6hXITacl89H2fLbnllkdRymvsW7/Ub7ZV8TPzkghPMizro3aUVruDnbzaYPoE+LPo6v2WB1FKa9gjOHRVXuICQ9i/tREq+NYRsvdwcKC/Ln9jBS+zSjm+/3FVsdRyuN9vquQzYdKuevsIQT5+1odxzJa7k4wf2oisRFBPPrpXmyjICulHKGp2fA/n+0lOSqUK06NszqOpbTcnSDI35dfnD2ELTmlrNpZYHUcpTzWO5ty2VdYya/OPQU/X++uN+/+6Z3o8glxpPTrxaOf7qWhqdnqOEp5nNqGJv7++T7GxkVw4ehYq+NYTsvdSfx8fbjn/GEcKK7ijY05VsdRyuO8sDaL/LJa7rlgOCJidRzLabk70azh/ZiU1Jcnvsigqq7R6jhKeYxjVfUsXpPJWcP6MXVwpNVxXIKWuxOJCPfOHkZxZR1L9YIeSvWYp1ZnUlXXyO/OH2Z1FJeh5e5k4xP6MHt0DEu+OcCRCh0SWKnuyimp5qV12Vw+IY6hMWFWx3EZWu4WuPu8YTQ0NfOPz3VYAqW665FP9+DjA7869xSro7gULXcLJEWFMn9KEss35rCnoNzqOEq5rfTsY3y4LZ9FpyV71YU4OkLL3SI/n5VCWJA/D320W09sUqoLjDH89aNdRIcFcsvp3jek78louVukd0gAP581hG8zilmzr8jqOEq5nY+257P5UCm/PXcooYF+VsdxOVruFpo/JZGkyBD+9tFuGvXEJqU6rLahiUc+3cOwmDAu9/JhBtqj5W6hAD8f7rlgOBlHKnn9h0NWx1HKbbywNouckhp+f+EIfH30hKW2aLlb7LyR/ZmaHMnfP99HaXW91XGUcnlHKmp58qsMzhnRnxlDoqyO47K03C0mIvzxJyMoq2ng8S/0eqtKncxjn+6lvqmZ+2cPtzqKS9NydwHDY8O5elICL6/PJqOwwuo4SrmsrTmlvJWeyw0zBpEUFWp1HJem5e4ifnXOKYQG+PLgh7v00Eil2mCM4c8f7CSqVyB3nJlidRyXp+XuIiJ7BfKLs0/h24xivth9xOo4SrmclVsOs+lQKXefP5QwL70uamdoubuQ+VMTGdKvFw9+uJPahiar4yjlMipqG3jo492MjYtg7gQ99LEjtNxdiL+vD3++eCQ5JTX8+2sdNVKp4/75ZQbFlXU8OGcUPnroY4doubuYaSlRXDgmlsVrMskpqbY6jlKWyyis4IW1WVyVGs/Y+N5Wx3Eb3S53EfEVkc0i8qH9/iAR2SAimSKyXEQCuh/Tu/z+wuH4iPDXj3ZZHUUpSxlj+NMHOwkJ8OW35w21Oo5b6Yk197uA3S3uPwL8wxiTAhwDbuyBeXiV2Ihg7pyVwqqdhazZqztXlff6eHsBazOP8tvzhhLZK9DqOG6lW+UuInHAhcCz9vsCnAWssE+yDLikO/PwVjfNSCY5OpQH3tedq8o7VdQ28OCHOxk5IJxrJidaHcftdHfN/XHgbuD4qFeRQKkx5vgFQnOBgW29UEQWiUiaiKQVFemoiK0F+Pnw1zmjyD5azeLVmVbHUcrp/v75Po5U1PHQpaN1/Jgu6HK5i8hFwBFjTHpXXm+MWWKMSTXGpEZHR3c1hkeblhLFJeMG8MzXB9hfVGl1HKWcZkdeGcu+z+LayQmM052oXdKdNffpwMUikgW8gW1zzBNAbxE5PrhyHJDXrYRe7v4LRxDo78Mf3tuhZ64qr9DcbPj9ezvoGxrAb8/TC153VZfL3RhzrzEmzhiTBMwDvjLGXAusBubaJ1sIrOx2Si8WHRbI3ecP4/v9R1m55bDVcZRyuNd+OMSWnFJ+f+EIIoL1TNSucsRx7r8DfiUimdi2wT/ngHl4lWsm2f40/cuHuzhWpcMCK89VWF7LI5/sYXpKJHPGDbA6jlvrkXI3xqwxxlxkv33AGDPJGJNijLnCGFPXE/PwZr4+wsOXj6asxnYKtlKe6oGVO6lvauahS0ZjO/hOdZWeoeomhsWEc8vpyaxIz2VtZrHVcZTqcat2FvDpzgLuOnuIDufbA7Tc3cidZw0hKTKE+97drse+K49SUdvAAyt3MiwmjJtPS7Y6jkfQcncjQf6+/O2y0WQfreYfX+yzOo5SPeaRT/dQWFHLw5ePwd9Xa6kn6FJ0M9MGRzFvYjxLvznA1pxSq+Mo1W3r9h/llfWHuH7aID2mvQdpubuh+y4cTr+wIO5esY36xuaTv0ApF1Vd38jv3t5GYmSIDgzWw7Tc3VB4kD8PXTqKvYUVPKlDEyg39r+f7eNQSTUPXzaG4ABfq+N4FC13NzVreH8uHT+Qxasz2XW43Oo4SnVaevYxnl97kOumJDB1cKTVcTyOlrsb++NFI+gd4s9v3tqqm2eUW6mpb+K3b21lQEQw91ww3Oo4HknL3Y31CQ3goUtHsyu/nH99lWF1HKU67NFVezhQXMWjc8fQK9Dv5C9Qnabl7ubOGxnDZRMGsnjNfrbo0TPKDXy/v5gX1maxcGoi01OirI7jsbTcPcADPxlJv7BAfv3mFj25Sbm0itoGfvvWNpIiQ/jdBTrioyNpuXuAiGB/Hrl8DPuLqnhs1V6r4yjVrr9+uJv8shr+98qxhATo5hhH0nL3EDNPiWb+lESe++4g32Xo2DPK9Xy6o4DlaTnccvpgTk3sa3Ucj6fl7kHumz2cwdGh/PqtLZRW69DAynUcKa/l3ne2MWpgOL88+xSr43gFLXcPEhzgyxPzxlNSVc99727XKzcpl9DcbPjNim3UNDTx+FXjCfDT2nEGXcoeZtTACH51zlA+3l7AivRcq+MoxbJ1WXyzr4j7LxxBSr9eVsfxGlruHmjRzGQmD+rLA+/v5IBeWFtZaNfhcv7fJ3s4a1g/rpucYHUcr6Ll7oF8fYTH540jwM+HO1/fTF2jHh6pnK+6vpE7Xt9E72B/Hps7Rq+s5GRa7h4qNiKYx+aOZefhch7+ZI/VcZQXemDlTg4WV/H4vHFE9gq0Oo7X0XL3YOeM6M9PpyXxwtosvthVaHUc5UVWbsnjrfRc7jgzhWmD9SxUK2i5e7h7Zw9jRGw4v1mxldxj1VbHUV5gf1El972zndTEPtw1a4jVcbyWlruHC/Tz5alrJ9DYZLjjtc06eqRyqJr6Jm5/ZRMBfj788+rx+Okl8yyjS94LDIoK5bG5Y9iSU8rfPt5tdRzlwf6wcgf7jlTw+LzxDOgdbHUcr6bl7iUuGB3L9dOTePH7LD7alm91HOWB3kzLYUV6LneemcLpp0RbHcfrabl7kXsvGM74hN7cvWIrmUcqrI6jPMiOvDL+8N4Opg2O5C4dXsAlaLl7kQA/HxZfO4HgAF8WvZxORW2D1ZGUByipqueWl9PpGxrAP68ej6+PHs/uCrTcvUxsRDBPXjOB7KPV/OrNrTQ36/gzqusam5q58/VNFFXW8cx1pxKlx7O7DC13LzQlOZL7Zw/n812FPLk60+o4yo09tmovazOP8tdLRjE2vrfVcVQLWu5e6vrpSVw6fiD/+GIfn+0ssDqOckPvbc7j398c4LopCVyZGm91HNWKlruXEhH+32WjGTMwgl8s38Lu/HKrIyk3svnQMe5+extTkvvywE9GWh1HtaHL5S4i8SKyWkR2ichOEbnL/nhfEflcRDLsX/v0XFzVk4L8fVmyIJWwID9uWpZGcWWd1ZGUG8gvq2HRy+nEhAfx9LWn4q8nKrmk7rwrjcCvjTEjgCnAz0RkBHAP8KUxZgjwpf2+clH9w4NYuiCVo1V13Ppyuo4gqU6our6Rm19Ko6a+iWcXptInNMDqSKodXS53Y0y+MWaT/XYFsBsYCMwBltknWwZc0s2MysHGxPXmf64YS1r2Me5esU2v4KTa1NRs+PnrW9h1uJx/Xj2OU/qHWR1JnUCPXH5cRJKA8cAGoL8x5vgpkAVA/3ZeswhYBJCQoIP4W+2iMQM4VFLNo5/uJaFvCL8+d6jVkZSL+cuHu/hidyEPzhnJWcPa/G+tXEi3N5aJSC/gbeAXxpj/2itnbKuAba4GGmOWGGNSjTGp0dF6qrIruO30wcybGM+/vsrkzY05VsdRLuT57w7y4vdZ3DhjEAumJlkdR3VAt8pdRPyxFfurxph37A8Xikis/flY4Ej3IipnERH+cskoThsSxX3vbmfNXn3rFHyyPZ+/fLSL80b2577Zw62OozqoO0fLCPAcsNsY8/cWT70PLLTfXgis7Ho85Wz+vrYhCobGhHHbK5vYfOiY1ZGUhb7fX8xdb2xhQkIfHr9KhxZwJ91Zc58OzAfOEpEt9n+zgYeBc0QkAzjbfl+5kbAgf168fhL9wgO54cWNZB7Ri2x7ox15ZSx6KZ3EyBCeW5hKcICv1ZFUJ4grHBmRmppq0tLSrI6hWsk+WsXlT39PoJ8vb906Vcfn9iK2934dAb7C27dPIzZC33tXJCLpxpjUtp7Tsw9UuxIjQ3nx+kmU1zRw3bMbKKrQk5y8weHSGq5ZuoGm5maW3TBJi91NabmrExo1MIIXrp9Iflkt85/bQGl1vdWRlAMdqajl2mc3UF7TwMs3TmaIHsvutrTc1UmlJvVl6YJUDhRVsfD5H3QceA91rKqeBc/9QEFZLS/eMJFRAyOsjqS6QctddciMIVEsvnYCOw+Xs0AL3uMcq6rn2mc3cKC4imcXpnJqYl+rI6lu0nJXHXb2iP48ec0EtueWseD5HyjXgvcIJVX1XPPsBjKLKnl2QSrTU6KsjqR6gJa76pTzR8Xw1LX2gn9OC97dlRxfY7cX+0y9sLXH0HJXnXbeyBj7Jpoyrlm6nqM6VLBbKiyv5ap/r+NAUSVLtdg9jpa76pJzR8awZEEqGYWVXLVkPYXltVZHUp2QU1LNFc+s43BpDS9eP0mL3QNpuasuO3NoP5bdMImCslrmPvM9h45WWx1JdUDmkQqueGYdZTUNvHrzFKYOjrQ6knIALXfVLVOSI3n1pslU1DZy2dNr2Z5bZnUkdQIbs0q4/Ol1NDYblt8yhXF6UWuPpeWuum1sfG9W3DqNQD9frlqyjq/3FVkdSbXh0x0FXPfsBiJDA3j39mkMiwm3OpJyIC131SNS+vXindunkRgZyo0vbtTx4F2IMYYX1x7ktlfTGTEgnBW3TSO+b4jVsZSDabmrHtM/PIg3b7Ftw7377W387ePdNDVbPzCdN2toauYPK3fwpw92MWtYf167aQp99bqnXkHLXfWosCB/nv/pROZPSWTJNwe45eV0KusarY7llcpqGrjhxY28sv4Qt8xM5t/zT9Vhe72Ilrvqcf6+PvzlklH8+eKRfLWnkMsWr+VAkY4J70x7CyqY8+R3rD9wlEfnjuHe2cP1QhteRstdOczCaUm8dMNkiirqmPPkWj7fVWh1JK/wwdbDXPLUWqrqm3jt5ilcmRpvdSRlAS135VAzhkTxwZ0zSIwK4eaX0nhs1R4am5qtjuWR6hqb+PMHO7nz9c2MHBDOR3fOYGKSDgDmrbTclcPF9Qlhxa3TuCo1nqdW72fekvXkldZYHcujZBVXMffpdbywNoufTkvitZun0C88yOpYykJa7sopgvx9eWTuGJ6YN449BRXMfuJbPt2Rb3Ust2eM4b3NeVz0r+84VFLNv+efyp8uHkmAn/7X9nb6CVBONWfcQD76+QwSI0O49ZVN/HL5FspqdGTJrjhaWcftr27iF8u3MCwmjI/vOo3zRsZYHUu5CD+rAyjvkxgZytu3TePJrzJ5cnUm6/Yf5ZG5YzhdB6/qsFU7C7j/3e2U1zTyu/OHsWhmsh4No/6LrrkrS/j7+vDLc07h3dun0SvIj4XP/8Bdb2ymWIcPPqGCslpufTmdW15OJzosiPfvnM5tZwzWYlc/IsZYfwZhamqqSUtLszqGskhtQxOL1+zn6TWZhAT4ce8Fw7gyNR4fLaz/aGxq5tUNh3hs1V4ampq56+wh3HxaMv6+un7mzUQk3RiT2uZzWu7KVWQUVnDfu9vZmHWM0QMjeOAnI0jVQ/lYm1nMgx/sYm9hBTNSonjo0lEkRoZaHUu5AC135TaMMazccpiHP9lDQXktF42J5TfnDiUpyvvKLKOwgsdW7eWzXYXE9Qnm/tnDOX9UDCL6F42y0XJXbqe6vpFn1uxn6bcHqW9q5srUeO6aNYSYCM8/djunpJrHv8jg3c25hAT4cevpydx0WjJB/joujPpvWu7KbR2pqOWprzJ57YdDiAhzT43jlpnJHrlZIvNIJc98vZ/3Nufh4yMsnJrIbWek6CiOql1a7srt5ZRUs3jNft5Oz6WxuZnZo2O5fvogJiT0duvNFMYYNhws4cW1WazaVUCgnw/zJiZwy+nJxEYEWx1PuTgtd+UxjpTX8tx3B3ltwyEq6hoZOSCcBVMTuXDMAHoFus9pG+W1Dby/5TAvr8tmb2EFEcH+zJ+SyPXTk4jsFWh1POUmtNyVx6mqa+TdzXm8tC6LfYWVBPv7cv6oGC4dP5CpgyNd8hDB+sZmvsss4p1NeXy2q5D6xmZGxIbz02lJ/GTsAB1rXXWalrvyWMYY0rOP8c7mPD7cepjy2kYigv2ZNbwf546IYXpKJGFB/pblK6tu4LvMYlbtLGD1niNU1DXSJ8Sfi8cO4NIJcYyNi3DrzUrKWk4vdxE5H3gC8AWeNcY8fKLptdxVT6htaGLN3iI+21XAl7uPUFbTgK+PMDYugukpUUxI7MPYuN4O3UFZXFnH1pxS0rOPsTazmO15ZTQb6BsawNn2XzgzT4nWgb1Uj3BquYuIL7APOAfIBTYCVxtjdrX3Gi131dMamppJy7IV7Nr9xWzLLfvP9Vzj+wYztH84Kf16MTg6lLg+IcREBBETHtShTSNVdY0UlNdSWFZL7rEa9hdVsr+okt35Ff8ZytjPRxif0Jtpg6OYMSSK8fG98XPBTUXKvZ2o3B2xB2oSkGmMOWCf+RvAHKDdcleqp/n7+jB1cCRTB0fyG4ZSWdfIjrwytuaUsjW3lIzCSr7ed4SGpv9euQn08yEsyI/QQD8C7GVssG0vr6prpKKukfrG/77YSICfD8lRoYxP6M1PpyUxLqE3IweEExLgPjt4ledxxKdvIJDT4n4uMLn1RCKyCFgEkJCQ4IAYSv2fXoF+TEmOZEpy5H8ea2xqJudYDYdLaygoq6WgvJbymgYq6hqprG2ksfn/Stzf14degX70CvKjd3AAMRGB9A8PYmDvYOL6hOjAXcrlWLZqYYxZAiwB22YZq3Io7+Xn68OgqFAGeeHQBsrzOWIjYB7Q8oq8cfbHlFJKOYkjyn0jMEREBolIADAPeN8B81FKKdWOHt8sY4xpFJE7gFXYDoV83hizs6fno5RSqn0O2eZujPkY+NgR31sppdTJ6YG3SinlgbTclVLKA2m5K6WUB9JyV0opD+QSo0KKSBGQ3cWXRwHFPRinp2iuztFcneeq2TRX53QnV6IxJrqtJ1yi3LtDRNLaGzjHSpqrczRX57lqNs3VOY7KpZtllFLKA2m5K6WUB/KEcl9idYB2aK7O0Vyd56rZNFfnOCSX229zV0op9WOesOaulFKqFS13pZTyQG5R7iJyhYjsFJFmEUlt9dy9IpIpIntF5Lx2Xj9IRDbYp1tuH4q4pzMuF5Et9n9ZIrKlnemyRGS7fTqHXzhWRP4kInktss1uZ7rz7cswU0TucUKux0Rkj4hsE5F3RaR3O9M5ZXmd7OcXkUD7e5xp/ywlOSpLi3nGi8hqEdll//zf1cY0Z4hIWYv394+OzmWf7wnfF7H5p315bRORCU7INLTFctgiIuUi8otW0zhteYnI8yJyRER2tHisr4h8LiIZ9q992nntQvs0GSKysEsBjDEu/w8YDgwF1gCpLR4fAWwFAoFBwH7At43XvwnMs99+BrjNwXn/F/hjO89lAVFOXHZ/An5zkml87csuGQiwL9MRDs51LuBnv/0I8IhVy6sjPz9wO/CM/fY8YLkT3rtYYIL9dhi2C8+3znUG8KGzPk8dfV+A2cAngABTgA1OzucLFGA7yceS5QXMBCYAO1o89ihwj/32PW197oG+wAH71z722306O3+3WHM3xuw2xuxt46k5wBvGmDpjzEEgE9sFuv9DRAQ4C1hhf2gZcImjstrndyXwuqPm4QD/uai5MaYeOH5Rc4cxxnxmjGm0312P7YpdVunIzz8H22cHbJ+lWfb32mGMMfnGmE322xXAbmzXKHYHc4CXjM16oLeIxDpx/rOA/caYrp753m3GmG+AklYPt/wctddF5wGfG2NKjDHHgM+B8zs7f7co9xNo62LcrT/8kUBpiyJpa5qedBpQaIzJaOd5A3wmIun2i4Q7wx32P42fb+fPwI4sR0e6AdtaXlucsbw68vP/Zxr7Z6kM22fLKeybgcYDG9p4eqqIbBWRT0RkpJMinex9sfozNY/2V7CsWF7H9TfG5NtvFwD925imR5adZRfIbk1EvgBi2njqfmPMSmfnaUsHM17NidfaZxhj8kSkH/C5iOyx/4Z3SC7gaeAv2P4z/gXbJqMbujO/nsh1fHmJyP1AI/BqO9+mx5eXuxGRXsDbwC+MMeWtnt6EbdNDpX1/ynvAECfEctn3xb5P7WLg3jaetmp5/YgxxoiIw45Fd5lyN8ac3YWXdeRi3Eex/UnoZ1/j6vIFu0+WUUT8gMuAU0/wPfLsX4+IyLvYNgl06z9FR5ediCwFPmzjKYdc1LwDy+unwEXALGPf2NjG9+jx5dWGjvz8x6fJtb/PEdg+Ww4lIv7Yiv1VY8w7rZ9vWfbGmI9FZLGIRBljHDpAVgfeF4d8pjroAmCTMaaw9RNWLa8WCkUk1hiTb99MdaSNafKw7Rs4Lg7b/sZOcffNMu8D8+xHMgzC9hv4h5YT2EtjNTDX/tBCwFF/CZwN7DHG5Lb1pIiEikjY8dvYdiruaGvantJqO+el7czP6Rc1F5HzgbuBi40x1e1M46zl1ZGf/31snx2wfZa+au8XUk+xb9N/DthtjPl7O9PEHN/2LyKTsP2fdugvnQ6+L+8DC+xHzUwBylpsjnC0dv96tmJ5tdLyc9ReF60CzhWRPvbNqOfaH+scZ+w17u4/bKWUC9QBhcCqFs/dj+1Ih73ABS0e/xgYYL+djK30M4G3gEAH5XwRuLXVYwOAj1vk2Gr/txPb5glHL7uXge3ANvsHK7Z1Lvv92diOxtjvpFyZ2LYrbrH/e6Z1Lmcur7Z+fuBBbL98AILsn51M+2cp2QnLaAa2zWnbWiyn2cCtxz9nwB32ZbMV247paU7I1eb70iqXAE/Zl+d2Whzl5uBsodjKOqLFY5YsL2y/YPKBBnt/3YhtP82XQAbwBdDXPm0q8GyL195g/6xlAtd3Zf46/IBSSnkgd98so5RSqg1a7kop5YG03JVSygNpuSullAfScldKKQ+k5a6UUh5Iy10ppTzQ/wdQvXXhh/700wAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# visualize using matplotlib\n", + "\n", + "x = np.linspace(-10, 10, 100)\n", + "y = f(x)\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A constant function:\n", + "\n", + "$$\n", + "f(x) = c\n", + "$$\n", + "\n", + "with $c$ being a constant." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# a constant function\n", + "def f(x):\n", + " return 2 # constant\n", + "\n", + "# test the function\n", + "x = 2\n", + "\n", + "# visualize using matplotlib\n", + "x = np.linspace(-10, 10, 100)\n", + "y = [f(x_i) for x_i in x]\n", + "\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A linear function:\n", + "\n", + "$$\n", + "f(x) = mx + c\n", + "$$\n", + "\n", + ", with $m$ being the slope and $c$ being the y-intercept -- both constants." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# a linear function\n", + "def f(x, m, c):\n", + " return m*x + c\n", + "\n", + "# test the function\n", + "x = 2\n", + "m = 3\n", + "c = 4\n", + "\n", + "# visualize using matplotlib\n", + "x = np.linspace(-10, 10, 100)\n", + "y = [f(x_i, m, c) for x_i in x]\n", + "\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Polynomial functions:\n", + "\n", + "$$\n", + "f(x) = a_0 + a_1x + a_2x^2 + \\cdots + a_nx^n\n", + "$$\n", + "\n", + "with $a_0, a_1, a_2, ..., a_n$ being constants. And $n$ is the degree of the polynomial." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# a polynomial function\n", + "def f(x, a, b, c):\n", + " # a, b, c are coefficients\n", + " return a*x**2 + b*x + c\n", + "\n", + "# test the function\n", + "x = 2\n", + "a = 8\n", + "b = 1\n", + "c = 8\n", + "\n", + "# visualize using matplotlib\n", + "x = np.linspace(-10, 10, 100)\n", + "y = [f(x_i, a, b, c) for x_i in x]\n", + "\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Logarithmic functions:\n", + "\n", + "$$\n", + "f(x) = c\\log_a x\n", + "$$\n", + "\n", + "with $c$ and $a$ being constants, $log_a$ is the logarithm function with base $a$." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# a logarithmic function\n", + "def f(x, a):\n", + " return a*np.log(x) # natural log\n", + "\n", + "# test the function\n", + "x = 2\n", + "a = 3\n", + "\n", + "# visualize using matplotlib\n", + "x = np.linspace(0.1, 10, 100)\n", + "y = [f(x_i, a) for x_i in x]\n", + "\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Exponential functions:\n", + "\n", + "$$\n", + "f(x) = c\\cdot a^x\n", + "$$\n", + "\n", + "with $c$ and $a$ being constants." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# an exponential function\n", + "def f(x, a, c):\n", + " return c*np.exp(a*x)\n", + "\n", + "# test the function\n", + "x = 2\n", + "a = 3\n", + "c = 4\n", + "\n", + "# visualize using matplotlib\n", + "x = np.linspace(-10, 10, 100)\n", + "y = [f(x_i, a, c) for x_i in x]\n", + "\n", + "plt.plot(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Function Roots" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check if a specific function has root. Below we are checking linear function which has a unique root of $x = -c/m$." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(-1.3333333333333333, 0.0, 'x = -c/m-1.3333333333333333')" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# function to find root of a linear function\n", + "\n", + "def f(x, m, c):\n", + " return m*x + c\n", + "\n", + "def has_root(x, m, c):\n", + " return x == -c/m\n", + "\n", + "# generate range of values that includes root of linear function\n", + "x = np.linspace(-10, 10, 100)\n", + "\n", + "# add root to the list\n", + "x = np.append(x, -c/m)\n", + "\n", + "# order the list of values\n", + "x = np.sort(x)\n", + "\n", + "y = [has_root(x_i, m, c) for x_i in x]\n", + "\n", + "# y to visualize\n", + "y = [f(x_i, m, c) for x_i in x]\n", + "\n", + "# visualize using matplotlib, with red dots at roots\n", + "plt.plot(-c/m, f(-c/m, m, c), 'r.')\n", + "plt.plot(x, y)\n", + "\n", + "# label root value with text x = -c/m\n", + "plt.text(-c/m, f(-c/m, m, c), 'x = -c/m'+str(-c/m))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercises:\n", + "\n", + "- A good way to understand function is to understand more closely their properties. Play around with the function by changing values and observe how they behave. Are any of the functions related to each other? How? \n", + "- Write a code that applies a [sigmoid](https://en.wikipedia.org/wiki/Sigmoid_function) function to a given input." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nlp", + "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.7.11" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "3141d6b93f248b667080eb2626ae72379dbce6662ffd106f25825858562b4ef8" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 5de2e10b4356088b05cc2ce5967f24a5d5cbfebb Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 18:51:02 +0000 Subject: [PATCH 65/76] remaining edits --- notebooks/loglin-lm-dataloader.ipynb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/notebooks/loglin-lm-dataloader.ipynb b/notebooks/loglin-lm-dataloader.ipynb index ecaf29e..8d6f66b 100644 --- a/notebooks/loglin-lm-dataloader.ipynb +++ b/notebooks/loglin-lm-dataloader.ipynb @@ -295,6 +295,18 @@ "advertisers and advertising rates for the s&p N issue of the issues pace with rival very small amounts to veto the constitution sen coordinator of the big three the las vegas 's increased activity is only one or for one thing is important as of as many as N million navy contract for the government is by mr. has business conditions and the earnings or N on the firm of that this is that mr. gorbachev 's economic activity and only half of the proposal to reduce interest rates in the he\n", "--finished 5000 sentences\n" ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_1861/185239032.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msent_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_loader\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# CHANGE to all train_data\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mmy_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_sent_loss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msent\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mtrain_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mmy_loss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_1861/2590246674.py\u001b[0m in \u001b[0;36mcalc_sent_loss\u001b[0;34m(sent)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[0mhist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mhist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mnext_word\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0mlogits\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_histories\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 26\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcriterion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlogits\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_targets\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] } ], "source": [ From 3c4dd4cbfa75323916afcf7b0d73b1c538da594b Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 19:01:27 +0000 Subject: [PATCH 66/76] add a few more notebooks --- notebooks/maths/README.md | 1 + notebooks/{ => maths}/algebra.ipynb | 8 +- notebooks/maths/feature-scaling.ipynb | 291 ++++++++++++++++++++++++++ notebooks/maths/mean.ipynb | 127 +++++++++++ 4 files changed, 423 insertions(+), 4 deletions(-) create mode 100644 notebooks/maths/README.md rename notebooks/{ => maths}/algebra.ipynb (99%) create mode 100644 notebooks/maths/feature-scaling.ipynb create mode 100644 notebooks/maths/mean.ipynb diff --git a/notebooks/maths/README.md b/notebooks/maths/README.md new file mode 100644 index 0000000..1ec32e5 --- /dev/null +++ b/notebooks/maths/README.md @@ -0,0 +1 @@ +All notebooks in this folder are tagged as work in progress [WIP] and contain very minimal rough notes and code snippets that may contain innaccuracies and errors. They are not intended to be used as a reference or as a source of truth. \ No newline at end of file diff --git a/notebooks/algebra.ipynb b/notebooks/maths/algebra.ipynb similarity index 99% rename from notebooks/algebra.ipynb rename to notebooks/maths/algebra.ipynb index 61c5666..f38646e 100644 --- a/notebooks/algebra.ipynb +++ b/notebooks/maths/algebra.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Notes for Algebra with Python\n", + "## Notes for Algebra with Python [WIP]\n", "\n", "The following are a set of notes for understanding some foundational concepts of Algebra using Python with a focus on ML. \n", "\n", @@ -486,7 +486,7 @@ ], "metadata": { "kernelspec": { - "display_name": "nlp", + "display_name": "Python 3.9.12 ('base')", "language": "python", "name": "python3" }, @@ -500,12 +500,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.11" + "version": "3.9.12" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "3141d6b93f248b667080eb2626ae72379dbce6662ffd106f25825858562b4ef8" + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" } } }, diff --git a/notebooks/maths/feature-scaling.ipynb b/notebooks/maths/feature-scaling.ipynb new file mode 100644 index 0000000..ac235fc --- /dev/null +++ b/notebooks/maths/feature-scaling.ipynb @@ -0,0 +1,291 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Feature Scaling [WIP]\n", + "\n", + "Deals with normalizing range of features or independent variables of data. In ML, feature scaling is used to \n", + "- ensure features contribute approximately proportionately to the final distance as opposed to one feature dominating; particularly important when euclidean distance is used\n", + "- help gradient descent converge faster, thus helping with the optimization problem and speeding up the learning process\n", + "- penalize coefficients appropriately when regularization is used as part of the loss function\n", + "\n", + "Source: [Wikipedia](https://en.wikipedia.org/wiki/Feature_scaling)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Mean normalization\n", + "\n", + "Mean normalization is a method used in normalization. The formula is as follows:\n", + "\n", + "$$\n", + "x^{\\prime}=\\frac{x-\\operatorname{average}(x)}{\\max (x)-\\min (x)}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([-0.5352, -0.0845, 0.0423, 0.1127, 0.4648])\n", + "tensor([-1.4786, -0.2335, 0.1167, 0.3113, 1.2840])\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "x = torch.Tensor([4, 36, 45, 50, 75])\n", + "x_prime = (x - x.mean()) / (x.max() - x.min()) \n", + "print(x_prime)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Standardization (Z-score Normalization)\n", + "\n", + "This can be used to ensure that the values of each feature in the data have zero-mean and unit-variance. The equation is as follows:\n", + "$$\n", + "x^{\\prime}=\\frac{x-\\operatorname{average}(x)}{\\operatorname{standard deviation}(x)}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([-1.4786, -0.2335, 0.1167, 0.3113, 1.2840])\n" + ] + } + ], + "source": [ + "import torch\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "x = torch.Tensor([4, 36, 45, 50, 75])\n", + "x_prime = (x - x.mean()) / x.std()\n", + "print(x_prime)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Detailed Examples\n", + "Here is an illustrated example with two features. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# x_1 feature with 50 random values in range (0, 5)\n", + "x_1 = torch.rand(50, 1) * 5\n", + "x_2 = torch.rand(50, 1) * 3\n", + "\n", + "# scatter plot\n", + "plt.scatter(x_1.numpy(), x_2.numpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calculate and subtract mean to get zero-mean." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# subtract mean\n", + "x = torch.concat([x_1, x_2], dim=1)\n", + "x_new = x - x.mean(dim=0)\n", + "\n", + "# scatter plot x_new\n", + "plt.scatter(x_new[:, 0].numpy(), x_new[:, 1].numpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now normalize the variances" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# normalize variance\n", + "x_new_normalized = x_new / torch.std(x_new, unbiased=False)\n", + "\n", + "# scatter plot x_new_normalized\n", + "plt.scatter(x_new_normalized[:, 0].numpy(), x_new_normalized[:, 1].numpy())\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is one more basic example where we reproduce the same results from this [scikit-learn tutorial](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([0.5000, 0.5000])\n", + "tensor([[-1., -1.],\n", + " [-1., -1.],\n", + " [ 1., 1.],\n", + " [ 1., 1.]])\n" + ] + } + ], + "source": [ + "x = torch.tensor([[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]])\n", + "x_new = x - x.mean(dim=0)\n", + "print(x.mean(dim=0))\n", + "x_new_normalized = x_new / torch.std(x_new, unbiased=False)\n", + "print(x_new_normalized)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### References\n", + "\n", + "- [Wikipedia - Feature Scaling](https://en.wikipedia.org/wiki/Feature_scaling)\n", + "- [Wikipedia - Standard Deviation](https://en.wikipedia.org/wiki/Standard_deviation)\n", + "- [Normalizing Inputs by DeepLearning.AI](https://www.youtube.com/watch?v=FDCfw-YqWTE&ab_channel=DeepLearningAI)\n", + "- [How To Calculate the Mean and Standard Deviation — Normalizing Datasets in Pytorch](https://towardsdatascience.com/how-to-calculate-the-mean-and-standard-deviation-normalizing-datasets-in-pytorch-704bd7d05f4c)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.12 ('base')", + "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.12" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/maths/mean.ipynb b/notebooks/maths/mean.ipynb new file mode 100644 index 0000000..8b9e953 --- /dev/null +++ b/notebooks/maths/mean.ipynb @@ -0,0 +1,127 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mean [WIP]\n", + "\n", + "Mean also referred to as the arithmetic mean is a measure of the central tendency of a set of numbers. You can calculate the mean of a set of numbers as follows:\n", + "\n", + "\n", + "$$\n", + "m=\\frac{\\text { sum of the terms }}{\\text { number of terms }}\n", + "$$\n", + "\n", + "or\n", + "\n", + "more formally:\n", + "\n", + "$$\n", + "\\bar{x}=\\frac{1}{n}\\left(\\sum_{i=1}^{n} x_{i}\\right)=\\frac{x_{1}+x_{2}+\\cdots+x_{n}}{n}\n", + "$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([[ 0.7317, -1.0386, -0.4281],\n", + " [ 1.1282, -0.7312, 0.2137],\n", + " [-1.4916, -0.6921, 0.7739],\n", + " [ 1.9643, 0.3754, 0.8449],\n", + " [ 1.0241, -0.4198, -0.2965]])\n" + ] + }, + { + "data": { + "text/plain": [ + "tensor([[-0.2450],\n", + " [ 0.2036],\n", + " [-0.4699],\n", + " [ 1.0615],\n", + " [ 0.1026]])" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import torch\n", + "x = torch.randn(5, 3)\n", + "print(x)\n", + "\n", + "# use keepdim=True to preserve dimension\n", + "x.mean(-1, keepdim=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor(42.)\n", + "tensor(42.)\n" + ] + } + ], + "source": [ + "# Example 2:\n", + "import torch\n", + "\n", + "x = torch.Tensor([4, 36, 45, 50, 75])\n", + "\n", + "print(torch.sum(x) / 5) # using sum and manual division\n", + "print(torch.mean(x)) # using mean function" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### References\n", + "\n", + "- [Wikipedia](https://en.wikipedia.org/wiki/Mean)\n", + "- [Basics of Statistics for ML Engineer](https://medium.com/technology-nineleaps/basics-of-statistics-for-machine-learning-engineers-bf2887ac716c)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.12 ('base')", + "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.12" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 0352595da34a51383ed9d3bdd7977214a5ec31aa Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 19:18:27 +0000 Subject: [PATCH 67/76] add changes --- notebooks/maths/algebra.ipynb | 49 +++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/notebooks/maths/algebra.ipynb b/notebooks/maths/algebra.ipynb index f38646e..4b32e45 100644 --- a/notebooks/maths/algebra.ipynb +++ b/notebooks/maths/algebra.ipynb @@ -19,7 +19,7 @@ "source": [ "### Functions\n", "\n", - "In ML, it's important to understand the concept of function as we use them a lot. Functions are used to map from one mathematical object to another. Let's start with some basic and common functions." + "Functions are used to map from one mathematical object to another. In ML, it's important to understand the concept of function as we use them a lot. In fact, for a lot of ML concepts we are essentially tying functions together mapping inputs to outputs. Let's start with some basic concept of functions, then gradually make our way into the more common functions applied in ML." ] }, { @@ -37,7 +37,18 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.9.12 ('base')' requires ipykernel package.\n", + "\u001b[1;31mRun the following command to install 'ipykernel' into the Python environment. \n", + "\u001b[1;31mCommand: 'conda install -n base ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "# import your main libraries\n", "\n", @@ -473,20 +484,48 @@ "plt.text(-c/m, f(-c/m, m, c), 'x = -c/m'+str(-c/m))" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'np' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_11851/1265031101.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlinspace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined" + ] + } + ], + "source": [ + "x = np.linspace(-10, 10, 100)\n", + "plot(x, x**2 + 2*x + 1)" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercises:\n", "\n", + "- Plot the following function: $f(x) = x^2 + 2x + 1$ and find the roots (if any) of the function.\n", "- A good way to understand function is to understand more closely their properties. Play around with the function by changing values and observe how they behave. Are any of the functions related to each other? How? \n", "- Write a code that applies a [sigmoid](https://en.wikipedia.org/wiki/Sigmoid_function) function to a given input." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.9.12 ('base')", + "display_name": "Python ('math')", "language": "python", "name": "python3" }, @@ -500,12 +539,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe" + "hash": "25a19fbe0a9132dfb9279d48d161753c6352f8f9478c2e74383d340069b907c3" } } }, From ac974f6cf184b732a9863a7567a9364d8289050a Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 20:23:14 +0000 Subject: [PATCH 68/76] add changes --- notebooks/maths/algebra.ipynb | 208 +++++++++++++++++++++++++++++----- 1 file changed, 180 insertions(+), 28 deletions(-) diff --git a/notebooks/maths/algebra.ipynb b/notebooks/maths/algebra.ipynb index 4b32e45..b78dc1a 100644 --- a/notebooks/maths/algebra.ipynb +++ b/notebooks/maths/algebra.ipynb @@ -35,20 +35,9 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [ - { - "ename": "", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[1;31mRunning cells with 'Python 3.9.12 ('base')' requires ipykernel package.\n", - "\u001b[1;31mRun the following command to install 'ipykernel' into the Python environment. \n", - "\u001b[1;31mCommand: 'conda install -n base ipykernel --update-deps --force-reinstall'" - ] - } - ], + "outputs": [], "source": [ "# import your main libraries\n", "\n", @@ -484,26 +473,189 @@ "plt.text(-c/m, f(-c/m, m, c), 'x = -c/m'+str(-c/m))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Transformations of Functions\n", + "\n", + "Transformations is an important concept where you take the output of one function and put it through another function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Shifts happen when you move the function up or down, left or right. See example below of a vertical shift:" + ] + }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 9, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'np' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_11851/1265031101.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlinspace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined" - ] + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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lrk7FKepUaOG7dNPP3V3GA6VkpJia968uW3JkiW2Pn362B555BG3xKEeljJISEhgzJgxfPnll/j7+7s7HKc7fvw4X331Fb169cLb29vd4ThFUlISNWvWdHcYYkdmZiYbNmygX79+ed/z8PCgX79+rF692o2RyflKSkoCqJT/53Jycpg1axZpaWn07NnT3eE41Lhx47juuusK/F90ByUspWSz2bjzzju5//776dq1q7vDcaqnnnqKgIAAatWqRXR0NAsXLnR3SE6xZ88e3nvvPe677z53hyJ2JCYmkpOTQ926dQt8v27dusTHx7spKjlfVquVRx99lEsuuYR27dq5OxyH2bp1K4GBgfj6+nL//fczf/582rRp4+6wHGbWrFls3LiRSZMmuTsUJSz/+te/sFgsxT527NjBe++9R0pKChMmTHB3yGVW2veY64knnmDTpk388ssveHp6MnLkSGzluCByWd8fwOHDh7nmmmu49dZbGTNmjJsiL53zeX8i5c24cePYtm0bs2bNcncoDtWyZUuioqJYu3YtY8eOZdSoUfz999/uDsshDh06xCOPPMJXX32Fn5+fu8NRaf6jR49y7NixYts0adKEIUOG8P3332OxWPK+n5OTg6enJ8OHD2f69OnODvW8lfY9+vj4FPp+TEwMkZGRrFq1qtx2c5b1/cXGxnL55Zdz8cUXM23aNDw8ynfefj5/f9OmTePRRx/l5MmTTo7OeTIzM/H392fevHkMGjQo7/ujRo3i5MmTla7nz2KxMH/+/ALvtbJ48MEHWbhwIcuXL6dx48buDsep+vXrR9OmTfnoo4/cHcoFW7BgAYMHD8bT0zPvezk5OVgsFjw8PMjIyChwztm8XPaTyqnQ0FBCQ0NLbPfuu+/y8ssv530dGxtL//79mT17Nj169HBmiBestO/RHqvVCpil3OVVWd7f4cOHueKKK+jSpQtTp04t98kKXNjfX0Xm4+NDly5dWLp0ad5N3Gq1snTpUh588EH3BielYrPZeOihh5g/fz5//PFHpU9WwPwbLc+fl2XRt29ftm7dWuB7o0ePplWrVjz11FMuTVZACUupNWjQoMDXgYGBADRt2pT69eu7IySHW7t2LX/99Re9e/emRo0a7N27l2effZamTZuW296Vsjh8+DCXX345DRs25I033uDo0aN558LCwtwYmeNER0dz/PhxoqOjycnJyasT1KxZs7x/sxXJ+PHjGTVqFF27dqV79+68/fbbpKWlMXr0aHeH5hCpqans2bMn7+v9+/cTFRVFzZo1C33mVETjxo1j5syZLFy4kKCgoLy5RyEhIVSrVs3N0V24CRMmMGDAABo0aEBKSgozZ87kjz/+4Oeff3Z3aA4RFBRUaL5R7vxGt8xDcsvapEpg//79lW5Z85YtW2xXXHGFrWbNmjZfX19bo0aNbPfff78tJibG3aE5xNSpU22A3UdlMWrUKLvv7/fff3d3aOftvffeszVo0MDm4+Nj6969u23NmjXuDslhfv/9d7t/X6NGjXJ3aA5R1P+3qVOnujs0h7jrrrtsDRs2tPn4+NhCQ0Ntffv2tf3yyy/uDsup3LmsucrPYREREZHyr/wP4IuIiEiVp4RFREREyj0lLCIiIlLuKWERERGRck8Ji4iIiJR7SlhERESk3FPCIiIiIuWeEhYREREp95SwiIiISLmnhEVERETKPSUsIiIiUu4pYREREZFy7/8BpW9qgVUpI/4AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "x = np.linspace(-10, 10, 100)\n", - "plot(x, x**2 + 2*x + 1)" + "# function f(x) = x**2\n", + "def f(x):\n", + " return x**2\n", + "\n", + "# test the function\n", + "x = np.linspace(-4, 4, 100)\n", + "\n", + "# visualize using matplotlib\n", + "plt.plot(x, f(x))\n", + "\n", + "# plot function shifted by 1 unit vertically; use red\n", + "plt.plot(x, f(x)+1, 'r')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can do a horizontal shift:" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(-20.0, 20.0)" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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Ql5e3lkV8ho1NTXSsGHDpNmzZ0s1NTVSfX2980PW1tYmJSQkSDfddJN08OBB6d1335VCQkKkV155xY13PngnTpyQioqKpD/96U9SWFiYVFRUJBUVFUnt7e2SJEnS+vXrpVdffVU6cOCAVF5eLr300ktSSEiItGLFCjff+eD82PO2Wq3SuHHjpLlz50rFxcXShg0bpLi4OGn58uVuvnPl7NixQ3r22Wel4uJi6ejRo9Kbb74pxcXFSTfffLO7b01x7777rqTT6aS1a9dKhw4dku644w4pMjJywCozX3P//fdLmzdvlo4fPy59++230pw5c6TY2FipsbHR3bemqPb2dufrF4D0zDPPSEVFRdKJEyckSZKkxx9/XIqMjJQ+/vhjaf/+/dLVV18tZWZmSt3d3W6+88H5oefd3t4u/frXv5by8/Ol48ePS19//bU0adIkafjw4VJPT4+7b/2c3XnnnZJer5c2b9484O90V1eX8zG/+MUvpPT0dOmbb76R9uzZI+Xl5Ul5eXlnVcerAsyaNWskAKf9ONW+ffukWbNmSTqdTkpJSZEef/xxN92xcpYsWXLa571p0yZJkiTpiy++kCZOnCiFhYVJoaGhUnZ2trR69WrJZrO598YH6ceetyRJUmVlpXTZZZdJwcHBUmxsrHT//fdLFovFfTetsMLCQik3N1fS6/VSUFCQNHr0aOmxxx7z6l9wP+SFF16Q0tPTpcDAQGnatGnSzp073X1LQl1//fVSUlKSFBgYKKWkpEjXX3+9VFFR4e7bUtymTZtO+1pesmSJJEmOpdQPPviglJCQIOl0Omn27NlSWVmZe29aAT/0vLu6uqS5c+dKcXFxklarlTIyMqTbb7/d6wP79/2dXrNmjfMx3d3d0l133SVFRUVJISEh0jXXXDNgMOJMqPqKEREREXkNj1iFRERERHQ2GGCIiIjI6zDAEBERkddhgCEiIiKvwwBDREREXocBhoiIiLwOAwwRERF5HQYYIiIi8joMMEREROR1GGCIiIjI6zDAEBERkddhgCEiIiKv8/87dm4DlSGvywAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot function shifted by 2 units horizontally; use green\n", + "x = np.linspace(-10, 10, 50)\n", + "plt.plot(x, x**2)\n", + "plt.plot(x-2, x**2, 'g')\n", + "\n", + "# have fixed x and y scale\n", + "plt.xlim(-20, 20)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Scaling transformation example:" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 128, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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CREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6QaDCREREekGgwkRERHpBoMJERER6YZiweSvf/0rhg8fDn9/f4SGhirVDREREXkQxYJJc3Mzpk6digcffFCpLoiIiMjDmJRq+PnnnwcALFy4UKkuiIiIyMMoFkw6wmq1wmq1ur6vqanRcDRERESkNl0Vv86fPx8hISGur4SEBK2HRERERCpqVzB56qmnIAjCFb8OHz7c4cHMmzcP1dXVrq+CgoIOt0VERETup11LOY899hhmzpx5xcekpqZ2eDBmsxlms7nDzyciIiL31q5gEhUVhaioKKXGQkRERF5OseLX/Px8VFRUID8/H3a7HTk5OQCA7t27IzAwUKluiYiIyI0pFkyeeeYZLFq0yPV9ZmYmAGD9+vUYM2aMUt0SERGRG1PsrpyFCxdCFMWLvhhKiIiI6HJ0dbswEREReTcGEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi0g0GEyIiItINBhMiIiLSDQYTIiIi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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# vertical scaling\n", + "x = np.linspace(-6, 6, 100)\n", + "plt.plot(x, x**2)\n", + "plt.plot(x, (x**2)/2, 'g')\n", + "\n", + "plt.xlim(-6, 6)\n", + "plt.ylim(-2, 4)\n", + "\n", + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 126, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# horizontal scaling\n", + "x = np.linspace(-6, 6, 100)\n", + "plt.plot(x, x**2)\n", + "plt.plot(x, -(x**2)/2, 'g')\n", + "\n", + "plt.xlim(-6, 6)\n", + "plt.ylim(-4, 4)\n", + "\n", + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n" ] }, { @@ -525,7 +677,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python ('math')", + "display_name": "Python 3.8.15 ('math')", "language": "python", "name": "python3" }, @@ -539,12 +691,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "" + "version": "3.8.15" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "25a19fbe0a9132dfb9279d48d161753c6352f8f9478c2e74383d340069b907c3" + "hash": "885f0b8c324fe4d130bb8744e2598b34a480bb115953c09edacbc3cda2096502" } } }, From 26b96293d35d0022f0249abc1b3773b8a3a9110b Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 20 Nov 2022 20:33:28 +0000 Subject: [PATCH 69/76] add changes --- notebooks/maths/algebra.ipynb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/notebooks/maths/algebra.ipynb b/notebooks/maths/algebra.ipynb index b78dc1a..f731c9b 100644 --- a/notebooks/maths/algebra.ipynb +++ b/notebooks/maths/algebra.ipynb @@ -619,6 +619,13 @@ "plt.plot(x*0, x, 'k', alpha=0.2)\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Scaled by negative constant" + ] + }, { "cell_type": "code", "execution_count": 126, From 68523286406a7819658859a59cf61ba2c297bc6f Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 27 Nov 2022 16:20:11 +0000 Subject: [PATCH 70/76] add changes --- notebooks/comp_graphs.ipynb | 4 +- notebooks/maths/algebra.ipynb | 173 +++++++++++++++++++++++++++++++--- 2 files changed, 161 insertions(+), 16 deletions(-) diff --git a/notebooks/comp_graphs.ipynb b/notebooks/comp_graphs.ipynb index a8dce57..f82c1df 100644 --- a/notebooks/comp_graphs.ipynb +++ b/notebooks/comp_graphs.ipynb @@ -298,7 +298,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.11 ('play')", + "display_name": "Python 3.7.13 ('nlp')", "language": "python", "name": "python3" }, @@ -317,7 +317,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "cf9800998463bc980d70cdbacff0c7e9a10687346dc898569e92f016d6e252c9" + "hash": "154abf72fb8cc0db1aa0e7366557ff891bff86d6d75b7e5f2e68a066d591bfd7" } } }, diff --git a/notebooks/maths/algebra.ipynb b/notebooks/maths/algebra.ipynb index f731c9b..e262e63 100644 --- a/notebooks/maths/algebra.ipynb +++ b/notebooks/maths/algebra.ipynb @@ -539,22 +539,22 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(-20.0, 20.0)" + "" ] }, - "execution_count": 64, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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Ql5e3lkV8ho1NTXSsGHDpNmzZ0s1NTVSfX2980PW1tYmJSQkSDfddJN08OBB6d1335VCQkKkV155xY13PngnTpyQioqKpD/96U9SWFiYVFRUJBUVFUnt7e2SJEnS+vXrpVdffVU6cOCAVF5eLr300ktSSEiItGLFCjff+eD82PO2Wq3SuHHjpLlz50rFxcXShg0bpLi4OGn58uVuvnPl7NixQ3r22Wel4uJi6ejRo9Kbb74pxcXFSTfffLO7b01x7777rqTT6aS1a9dKhw4dku644w4pMjJywCozX3P//fdLmzdvlo4fPy59++230pw5c6TY2FipsbHR3bemqPb2dufrF4D0zDPPSEVFRdKJEyckSZKkxx9/XIqMjJQ+/vhjaf/+/dLVV18tZWZmSt3d3W6+88H5oefd3t4u/frXv5by8/Ol48ePS19//bU0adIkafjw4VJPT4+7b/2c3XnnnZJer5c2b9484O90V1eX8zG/+MUvpPT0dOmbb76R9uzZI+Xl5Ul5eXlnVcerAsyaNWskAKf9ONW+ffukWbNmSTqdTkpJSZEef/xxN92xcpYsWXLa571p0yZJkiTpiy++kCZOnCiFhYVJoaGhUnZ2trR69WrJZrO598YH6ceetyRJUmVlpXTZZZdJwcHBUmxsrHT//fdLFovFfTetsMLCQik3N1fS6/VSUFCQNHr0aOmxxx7z6l9wP+SFF16Q0tPTpcDAQGnatGnSzp073X1LQl1//fVSUlKSFBgYKKWkpEjXX3+9VFFR4e7bUtymTZtO+1pesmSJJEmOpdQPPviglJCQIOl0Omn27NlSWVmZe29aAT/0vLu6uqS5c+dKcXFxklarlTIyMqTbb7/d6wP79/2dXrNmjfMx3d3d0l133SVFRUVJISEh0jXXXDNgMOJMqPqKEREREXkNj1iFRERERHQ2GGCIiIjI6zDAEBERkddhgCEiIiKvwwBDREREXocBhoiIiLwOAwwRERF5HQYYIiIi8joMMEREROR1GGCIiIjI6zDAEBERkddhgCEiIiKv8/87dm4DlSGvywAAAABJRU5ErkJggg==", + "image/png": "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B/Hggw/64lBERESkYew4IyIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1WAwISIiItVgMCEiIiLVYDAhIiIi1fBaMFmzZg2mTZuGsLAwREdHe+swRERE5Ee8FkxsNhsWLlyIn//85946BBEREfkZo7ce+MknnwQAbNy40VuHICIiIj/jtWAyEFarFVar1f19c3OzgtUQERGRr6mq+XXdunUwm83ur/T0dKVLIiIiIh/qVzBZuXIldDrdVb9OnDgx4GJWrVoFi8Xi/iovLx/wYxEREZH29Gsq55FHHsHixYuvepvs7OwBF2MymWAymQZ8fyIiItK2fgWT+Ph4xMfHe6sWIiIiCnBea34tKytDQ0MDysrK4HA4UFhYCADIyclBRESEtw5LREREGua1YPLEE0/gL3/5i/v7goICAMDnn3+OmTNneuuwREREpGFeW5WzceNGCILQ64uhhIiIiK5EVcuFiYiIKLAxmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAREZFqMJgQERGRajCYEBERkWowmBAR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", "text/plain": [ "
" ] @@ -565,12 +565,16 @@ ], "source": [ "# plot function shifted by 2 units horizontally; use green\n", - "x = np.linspace(-10, 10, 50)\n", - "plt.plot(x, x**2)\n", - "plt.plot(x-2, x**2, 'g')\n", + "x = np.linspace(-5, 5, 100)\n", + "plt.plot(x, x**2, label='$f(x)=x^2$')\n", + "plt.plot(x, (x-2)**2, label='$f(x)=(x-2)^2$')\n", + "\n", + "plt.xlim(-6, 6)\n", + "plt.ylim(-2, 4)\n", "\n", - "# have fixed x and y scale\n", - "plt.xlim(-20, 20)" + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n", + "plt.legend()\n" ] }, { @@ -628,22 +632,22 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "" ] }, - "execution_count": 126, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAGiCAYAAADTBw0VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABUF0lEQVR4nO3dd3hUVeLG8e9MekiBkEACJIHQewiB0FSKSlOxgV1BV0WxsPpTQVFWV8C6FnSxsXYpiqKLgjQFRDqE3iEQCKEFEtLLzO+PSJQFMQmZnCnv53nmWTO5M/ed2TB5c++551jsdrsdERERESdgNR1ARERE5DQVExEREXEaKiYiIiLiNFRMRERExGmomIiIiIjTUDERERERp6FiIiIiIk5DxURERESchoqJiIiIOA0VExEREXEa1VZMXnjhBSwWCyNHjqyuXYqIiIiLqZZismrVKt59913atWtXHbsTERERF+XwYpKdnc0tt9zC+++/T61atRy9OxEREXFh3o7ewYgRIxg4cCCXXnopzz///Hm3LSgooKCgoOxrm81GRkYGtWvXxmKxODqqiIiIVAG73c6pU6eoV68eVmvFjoE4tJhMnTqVtWvXsmrVqnJtP2HCBJ599llHRhIREZFqkpqaSoMGDSr0GIcVk9TUVB5++GHmzZuHv79/uR4zevRoHnnkkbKvMzMziYmJITU1lZCQEEdFFSm344dTqf2frtjsFrLvX09IzTDTkVySzWZj/fr1ALRv377Cf1HJ71ZP+huJJ+ewsu4NdL7zVdNxRADIysoiOjqa4ODgCj/WYcVkzZo1HDlyhISEhLL7SkpKWLx4MW+99RYFBQV4eXmd8Rg/Pz/8/PzOeq6QkBAVE3EKISGtOegfSX37YfbvWUODnteZjuSSbDYbQUFBQOm/bxWTymtcsIUQPwvhrXvpc1KcTmWGYTjs06BPnz5s3LiR5OTksltiYiK33HILycnJZ5USEVeRFtIegNxdSw0nEU+XefwwsbZUAGLjexlOI1I1HHbEJDg4mDZt2pxxX40aNahdu/ZZ94u4EluDJMicS9DRNaajiIfbm/wT8cB+a31iIqJMxxGpEjp+KlJBdVpfAkBc/laKiwoNpxFPlre79Khd+m9H8UTcgcMvF/6jn3/+uTp3J+IQsc0TyKIGIZYcdm5eQdP4i0xHEg8VenQtAJaYLtW6X7vdTnFxMSUlJdW6X3EuPj4+DhmWUa3FRMQdWL282Ovfivb5qzi+dbGKiRhRWJBPXOF2sEDdNpdU334LCzl06BC5ubnVtk9xThaLhQYNGpQNZK8qKiYilZAbmQgpq/A5uNJ0FPFQezYupYWliBOEEN2kepb7sNls7N27Fy8vL+rVq4evr68mv/RQdrudo0ePcuDAAZo2bVqlR05UTEQqIaTpRZAyiejsDdhtNiy63FWq2cltSwBICWxDh2r6+SssLMRmsxEdHU1gYGC17FOcV0REBCkpKRQVFVVpMdGnqUglxMVfTJHdizpkkJ6603Qc8UB+h0pn1C6ITKz2fWveGYHKzVFSHvrpEqmEgBrB7PVpDMDBDT+bDSMex26zEZOzEYCazTXGSdyLiolIJWWEdQCgZN9yw0nE0xzcs4XaZFJo96Zhu+6m44hUKRUTkUrybdQVgPAT6wwnEU9zaNPPAOzxbYZ/QA2zYUSqmIqJSCXFtO8NQMPiFE5lZhhOI57Evr/0KN3J2h0MJxGpeiomIpUUXi+WNEtdvCx2UpJ/Nh1HPEidk8kA+MV1MxtEqlVqaio9e/akVatWtGvXji+//NJ0JIdQMRG5AGnBpfNHZGtBP6kmmccP01AL93kkb29vXn/9dbZs2cLcuXMZOXIkOTk5pmNVORUTkQtQ0iAJgOAjqw0nEU+Rsv4noHThvrA69Q2ncU0TJ04kNjYWb29vhg0bRp06dUhJSSn342+88UZeffVVxwX8E1FRUcTHxwMQGRlJeHg4GRnudxpZxUTkAtRpfTGgBf2k+uTu+hXQwn2VtX79eh555BEmTZpEamoqtWrVYtCgQTRs2LDczzFmzBjGjRtHZmam44L+hTVr1lBSUkJ0dLSxDI6iYiJyAWJbJJJFIIGWAlK2aHp6cbzQY2YW7nMXs2bNonPnzgwYMIDQ0FAmT57MXXfdVaHnaNOmDY0bN+azzz5zUMrzy8jI4Pbbb+e9994zsn9HUzERuQBWLy9S/FsDcGzLYsNpxN0VFuQTV7ANqN6F+87LbofCHDM3u71CUZs0acKYMWP49ddfsVgshIeH4+fnR5cuZ5a8KVOmEBAQwKFDh8ruGzZsGO3atSs7SnLllVcyderUC3//KrjfgoICrr76akaNGkW3bu45+Flr5YhcoJy6HWHfKnwPaqI1caw9G36p9oX7/lJRLoyvZ2bfT6aBb/nncfn111/p2rUr9913H7feeitPPfUUaWlpZ21344038sILLzB+/HgmTpzI2LFjmT9/PsuXLyc0NBSAzp07M27cOAoKCvDz8zvj8ePHj2f8+PHnzbJlyxZiYmIqtF+73c7QoUPp3bs3t912W7lft6tRMRG5QKEtesK+d4jNTtaCfuJQJ7aUDnxNqdGu2hbucydBQUGkpKTQo0cPIiMjOX78OPXqnV2qLBYL48aN4/rrrycyMpKJEyeyZMkS6tf/fbBxvXr1KCwsJD09ndjY2DMeP3z4cIYMGXLeLJXZ79KlS5k2bRrt2rVj5syZAHz66ae0bdu2om+FU1MxEblAcfEXUzDHh9qWTPbt3EBs83jTkcRN1Ti0AoCC+l0NJ/kDn8DSIxem9l0BGzZsACj7RZ6Xl4e/v/85t73iiito1aoVzz33HHPnzqV169ZnfD8gIACA3Nzcsx4bFhZGWFhYhbKVZ789evTAZrNV6nldiYqJyAXyD6jBZr8WtC7cSPqG+Som4hDFRYU0ztsIFoho09t0nN9ZLBU6nWJScnIyTZo0oUaN0rzh4eGcOHHinNvOmTOHbdu2UVJSQt26dc/6/unLdCMiIs76XmVP5ZRnv55AxwJFqkBW3dL5TLz2/2o4ibirPRuXUcOSTxY1aNiqs+k4Lik5OZn27X+/zLpDhw5s2bLlrO3Wrl3LkCFDmDx5Mn369OHpp58+a5tNmzbRoEEDwsPDz/re8OHDSU5OPu/tXKdyyrNfT6AjJiJVILj5JZD6ATGn1mmciThExpaFAOwJbEe8tz66KyM5OZmrrrqq7Ou+ffsyevRoTpw4Qa1atQBISUlh4MCBPPnkk9x0003ExcXRtWtX1q5dS0JCQtljlyxZwuWXX37O/VTmVE559+sJ9OkpUgUad+hFod2LOmRwcM/Zf4GJXCj/3676yq+n+Usqw2azsXHjxjOOmLRt25aEhASmT58OlJ6e6devH4MGDWLUqFEAJCUl0b9/f5588smyx+Xn5zNz5kzuvvvuKslW3v16CtVukSoQUCOYrb7NaVm0hbT182nQpI3pSOJGSoqLicsrHbhZu7UTjS9xIVar9ZzryjzzzDM89thj3H333YSFhbFt27aztvn+++/P+PrDDz+kc+fOZ81/Ulnl3a+n0BETkSpysk7peX/Lfi3oJ1Vr7+YVhJBLtj2ARm10xKQqDRw4kHvuuYeDBw+W+zE+Pj5MnDjRgak8m46YiFSRoGaXwMGPiM5cZzqKuJljmxfSBNgd0Ib2Pr6m47idkSNHVmj7v/3tb44JIoCOmIhUmbiE3hTbrURylLSU7abjiBvxO7AMgNx6TjR/iYiDqJiIVJEawTXZ7dMUgIPJ8wynEXdhKymhUe56AGq16mk2jEg1UDERqUIZEZ0AsKdonIlUjX3bVlOTbHLtfjRu18N0HBGHUzERqUKBTUtXfK2fucZwEnEXRzaWzl+y2781Pr5+f7G1iOtTMRGpQnEdL6XEbqG+/TCHD+w2HUfcgM+B0tmEs6OSDCcRqR4qJiJVKDg0jD3ejQFIXatxJnJh7DYbsdml40tqtuxlOI1I9VAxEalix8NLx5nYUn4xnERc3f4dydQmk3y7D3HtLzIdR6RaqJiIVDH/JhcDEHVC40zkwqRvWADAbr+W+PkHGk4jUj1UTESqWKOOl2GzW4i2p3EsbZ/pOOLCvFNLx5ecXr1axBOomIhUsdCwCPZ6NwRg3zqNM5HKsdtsxJwqnUU4uMUlhtOIVB8VExEHOBqWCEDxniWGk4irOrBnMxGcoNDuTZMOGvgq5XPNNddQq1Ytrr/+etNRKs2hxWTSpEm0a9eOkJAQQkJC6Nq1K7Nnz3bkLkWcgl/TngDUy1hpNoi4rLS1cwDY5dcS/8Agw2nEVTz88MN88sknlX58amoqPXv2pFWrVrRr144vv/yyCtOVj0OLSYMGDXjhhRdYs2YNq1evpnfv3gwaNIjNmzc7crcixsV16kfJb+NM0lN3mY4jLshn/2IAMqO6G04irqRnz54EBwdX+vHe3t68/vrrbNmyhblz5zJy5EhycnKqMOFfc2gxufLKKxkwYABNmzalWbNmjBs3jqCgIJYvX+7I3YoYF1ornF0+zQDYv1pHCaVibCUlxGWvBaBWm8sMp3E/EydOJDY2Fm9vb4YNG0adOnVISUkp9+NvvPFGXn31VccFNCgqKor4+HgAIiMjCQ8PJyMjo1ozVNsYk5KSEqZOnUpOTg5du557hcyCggKysrLOuIm4qoy6pT/n1r2LDCcRV7Nn0zJqkk22PYAm8RebjuNW1q9fzyOPPMKkSZNITU2lVq1aDBo0iIYNG5b7OcaMGcO4cePIzMx0XFAnsGbNGkpKSoiOjq7W/Tq8mGzcuJGgoCD8/PwYPnw433zzDa1atTrnthMmTCA0NLTsVt1vhkhVCm51KQANs1Zht9kMpxFXcmz9jwDsqhGPt4+v4TTuZdasWXTu3JkBAwYQGhrK5MmTueuuuyr0HG3atKFx48Z89tlnDkppXkZGBrfffjvvvfdete/b4cWkefPmJCcns2LFCu677z7uuOMOtmzZcs5tR48eTWZmZtktNTXV0fFEHKZJQm/y7T6Ec5L929eZjiMuJDCtdHXq/AZaTbgqNWnShDFjxvDrr79isVgIDw/Hz8+PLl26nLHdlClTCAgI4NChQ2X3DRs2jHbt2pUdJbnyyiuZOnVqteavCuV5bQUFBVx99dWMGjWKbt26VXtGhxcTX19fmjRpQseOHZkwYQLt27fnjTfeOOe2fn5+ZVfwnL6JuCr/gBrs9G8LwKHkOYbTiKsoyM+lad5GACI79DOcxr38+uuvxMXF8fLLL3Po0CFuuukmOnbseNZ2N954I82aNWP8+PEAjB07lvnz5zN79mxCQ0MB6Ny5MytXrqSgoOCsx48fP56goKDz3vbv3++Q13jppZcyePBgfvjhBxo0aMCyZcsq9NrsdjtDhw6ld+/e3HbbbQ7J+Fe8q3uHNpvtnP9Hirij7Po9YM9a/FK1bo6Uz641P9HaUsgxahLbPMF0nL9kt9vJLco1su9An0AsFku5tw8KCiIlJYUePXoQGRnJ8ePHqVev3lnbWSwWxo0bx/XXX09kZCQTJ05kyZIl1K9fv2ybevXqUVhYSHp6OrGxsWc8fvjw4QwZMuS8Wc6136owf/78837/r17b0qVLmTZtGu3atWPmzJkAfPrpp7Rt29Yhec/FocVk9OjR9O/fn5iYGE6dOsUXX3zBzz//zI8//ujI3Yo4jfB2l8OeN2mSs47iokKNF5C/lLWldLbglJBEwq3OPwdmblEuQRPMzLOSPTqbGr41yr39hg0bAMp+yebl5eHv73/Oba+44gpatWrFc889x9y5c2nduvUZ3w8ICAAgN/fsUhYWFkZYWFi5c53LqFGjePHFF8+7zdatW2nRokWFn/t8r61Hjx7YDI+Jc2gxOXLkCLfffjuHDh0iNDSUdu3a8eOPP3LZZbr8TTxDXJuuZM6sQaglh23rl9AisY/pSOLkwg6XHnq3NdI09FUtOTmZJk2aUKNGaZkJDw/nxIkT59x2zpw5bNu2jZKSEurWrXvW909fQhsREXHW98aPH192quTPbNmyhZiYmD/9/qOPPsrQoUPP+xxxcXFnfF2eo0d2u/0vX5tpDi0mkydPduTTizg9L29vdtfoSELOYk5snAsqJnIeWSeP06RoO1ggpmN/03HKJdAnkOzR2cb2XRHJycm0b9++7OsOHTqc88qatWvXMmTIECZPnsxHH33E008/fdYMqJs2baJBgwaEh4ef9fiqOJUTERFxztJzPvv37+e2227jyJEjeHt78/TTTzN48OAztinPazOt2seYiHiaotiLYMtiQg79ajqKOLk9q34k3mIn1VKP6JimpuOUi8ViqdDpFJOSk5O56qqryr7u27cvo0eP5sSJE9SqVQuAlJQUBg4cyJNPPslNN91EXFwcXbt2Ze3atSQk/D7mZ8mSJVx++eXn3E9VnMqpjNOztsbHx5Oenk7Hjh0ZMGBA2RGi8r4205z/BKaIi6uXUPqXb9OCLeTlnDKcRpxZwY4FAKSFdTacxP3YbDY2btx4xhGTtm3bkpCQwPTp04HS0zP9+vVj0KBBjBo1CoCkpCT69+/Pk08+Wfa4/Px8Zs6cyd133129L+IvnG/W1vK+NmegIyYiDtYgrjXphBNpOcbG1fNoe8m1piOJk6p7fAUAPk21mnBVs1qt51zz5ZlnnuGxxx7j7rvvJiwsjG3btp21zffff3/G1x9++CGdO3c+a/4TZ/K/s7aW97U5Ax0xEXEwi9XK/pqlfwFnb1tgOI04q2Np+2hoS8Vmt9C4k2uML3EHAwcO5J577uHgwYPlfoyPjw8TJ050YKoLY3LW1qqgIyYi1cAadwms/YGII8v+emPxSCmrfyAc2O3dmKa1ne9KCXc2cuTICm3/t7/9zTFBqoDpWVurgo6YiFSDhp0HABBXvIeTx9INpxFnZN9TutjjsTqu+ctEzHOGWVurgoqJSDUIj4whxRqD1WJnz6rZpuOIk7HbbMScXAlAUMvehtOIqzo9a+vMmTOJj48nPj6ejRs3mo5VYTqVI1JN0sO70PDIfop2/QQMMx1HnEjqrg3EcJwCuw9NEzUBpVSOM8zaWhV0xESkmgS0KJ1cLeb4r9jd4MNDqk7a6lkA7PRvjX+gmendRZyFiolINWmWNJACuw9RHGX/jmTTccSJBO7/CYDsaF0mLKJiIlJNAmoEsz2gHQCH1swynEacRV7OKZrnrQcgquOVhtOImKdiIlKNcqN7AlDjt7+QRXasnIOfpYh0wolp3sF0HBHjVExEqlFUYuk6Hc3zN5CbnWk4jTiD/C1zANgX1g2LVR/JIvpXIFKNYpq2I81SB19LMTtX6rJhgfrHlgLg26Kv4STlZ7fbTUcQJ+ConwMVE5FqZLFaSQ0rnUArf8uPhtOIaQd2baKB/RBFdi+aJA0wHecv+fj4AJCbm2s4iTiDwsJCALy8vKr0eTWPiUg182vRF5bOpMHxpdhtNh2+92AHV/+XBsAOv9a0Dg0zHecveXl5UbNmTY4cOQJAYGAgFovFcCoxwWazcfToUQIDA/H2rtoqoWIiUs2adhlA4S9e1OcwqXs2E92krelIYoj/voUAnGrQ02yQCoiMjAQoKyfiuaxWKzExMVVeTlVMRKpZjeCabPJvS5uCZA6u+k7FxEPl5+XQLDcZLFAn4QrTccrNYrEQFRVFnTp1KCoqMh1HDPL19cXqgCO+KiYiBmRH94RdyQTu+wl4ynQcMWDnyh9paynkCGE0atXJdJwK8/LyqvKxBSKgwa8iRkT+NpFWs7xk8nOzDacRE3I2l14mnFKrq8YZifyB/jWIGBDbPIHD1MbfUsSOFXNMxxED6h37BQDvZlq0T+SPVExEDLBYrez77bLh3C0qJp4mbe82YmwHKbZbadxF09CL/JGKiYgh3s1LJ9Q6PcGWeI7UVd8BsMO3FaG1wg2nEXEuKiYihjTtMpAiuxfR9jQO7tlqOo5UI7+U0suEs+pfYjiJiPNRMRExJDg0jB1+rQA4sOpbw2mkuhTk59IsZy0A4R0GGk4j4nxUTEQMymrQCwD/vfMNJ5HqsmPFHAItBRyjJo3bdjUdR8TpqJiIGFSv09UAtMxbR86pk0azSPXI3fhfAPbU6qHLhEXOQf8qRAyKad6BA5YofC3FbF8603QccTC7zUbsscUA+LbR1Tgi56JiImKQxWrlQJ2eAJRs/d5sGHG43Rt/JZJj5Nr9aNHVdaahF6lOKiYihoXEDwKgaeavFBcVGk4jjnR09UwAttdIxD8wyGwYESelYiJiWLPEPpwgmJpks32VBsG6szppCwAoatrfcBIR56ViImKYt48vu0K7A3BqvS4bdleH9m2ncckeSuwWmnS/1nQcEaelYiLiBLxbDQAg+shP2G02w2nEEfYv+xoone01rE59w2lEnJeKiYgTaNZtEAV2H+rbD5OybY3pOOIAgXt/BCAzVov2iZyPiomIE6gRXJNtgQkAHF75jeE0UtUyTxyjRf4GAOp3ud5wGhHn5tBiMmHCBDp16kRwcDB16tTh6quvZvv27Y7cpYjLyo8rXdQv7MA8w0mkqu389Rt8LCXsszYguklb03FEnJpDi8miRYsYMWIEy5cvZ968eRQVFXH55ZeTk5PjyN2KuKTG3Uv/km5WvIOjaSlmw0iVsmz7AYC0ur0NJxFxft6OfPI5c+ac8fVHH31EnTp1WLNmDRdffLEjdy3icsLrxbLduznNi7ezZ+lXRAz+P9ORpAoUFuTTLGsZWKBWwiDTcUScXrWOMcnMzAQgLCzsnN8vKCggKyvrjJuIJ8mIvhQA/z0/Gk4iVWX7ih8JtuRxnFCaJfQyHUfE6VVbMbHZbIwcOZLu3bvTpk2bc24zYcIEQkNDy27R0dHVFU/EKUR1Lp3fokWuFvVzF7kbSuem2V2rB1YvL8NpRJxftRWTESNGsGnTJqZOnfqn24wePZrMzMyyW2pqanXFE3EKsc0TOGCJxM9SpEX93EDpon2LAPBtrUX7RMqjWorJAw88wKxZs/jpp59o0KDBn27n5+dHSEjIGTcRT1K6qF/p4X7bllmG08iFOr1oX57dlxbdVExEysOhxcRut/PAAw/wzTffsHDhQho1auTI3Ym4hZoJpadzmmf+Qn6ermBzZUdXTANga1CSFu0TKSeHFpMRI0bw2Wef8cUXXxAcHEx6ejrp6enk5eU5crciLq1ZYh+OEEawJY9tv2jtHFdlt9mIOVQ6iNne+hrDaURch0OLyaRJk8jMzKRnz55ERUWV3aZNm+bI3Yq4NKuXF3vqlE5bXrxxhuE0Ulm7Niylvv0weXZfWl6s2V5Fysuh85jY7XZHPr2I26rZaQh8P40WmUvJz8vBP6CG6UhSQcdWTKUpsDW4KwlBoabjiLgMrZUj4oSaJfQinXCCLHlsXaK1c1yN3WYjNn1u6Rc6jSNSISomIk7I6uVFSt3SydZKNqmYuJqdyUuoZz9Crt1Pp3FEKkjFRMRJ1ew0BICWmb+Qn5ttOI1URMbK367GCe5KQI1gw2lEXIuKiYiTap7Qi3QiqGHJZ4tO57iMP57GsbTRaRyRilIxEXFSFqu17HSOfdPXhtNIee1MXkwUR0tP41x0nek4Ii5HxUTEiYUl3QhAy6yl5OWcMpxGyiNjRemyG1tDuus0jkglqJiIOLGm8RdziAgCLQVsXaI5TZyd3Waj4eF5AFjaXGs4jYhrUjERcWIWq5V9kZcDYN8802wY+Uvb1/5EJMfIsfvT6iKNLxGpDBUTESdXu+x0zq86nePkTq6aDsDW0B5aG0ekklRMRJxck/Y9SLPULT2ds/gr03HkT9hKSmj022kcL12NI1JpKiYiTq70dE7f0i82aZyJs9q+ej51OU62PYCWOo0jUmkqJiIuoG73WwFok72MzOOHDaeRczm14lMAttbqqbWNRC6AiomIC4hrk8Rur0b4WorZtuBj03Hkf+TnZtPy+HwAAjrdYjiNiGtTMRFxEUfjSi8/rblDp3OczeafphJsySOdCFp1GWA6johLUzERcRFN+gyj2G6lefE29u9INh1H/sB7Y+mkanvrX4HVy8twGhHXpmIi4iLCI6PZHNgJgIOLPjScRk47lr6fNnmrAWjQc5jhNCKuT8VExIUUt70BgEYHZ2ErKTGcRgB2zf8PXhY7271bEN20vek4Ii5PxUTEhbTudSNZBBLJMbYs+950HAHq7Cld+flks+sNJxFxDyomIi7EP6AGW8NKVxzOW/W54TSye+Ny4mwpFNq9adHndtNxRNyCiomIiwntUvoLsPXJn8g5ddJsGA939JfSsT6bgrsRWruu4TQi7kHFRMTFNE/swwFLFIGWArYs/MJ0HI9VXFRI08OzAbDG32w4jYj7UDERcTEWq5XUmEEABGyZZjiN59q85Gtqk0kGIbS++FrTcUTchoqJiAuK7XUnAK3y15OeustwGs9UvHYKADvq9MPH189wGhH3oWIi4oLqNWzOZt+2WC129i78j+k4HifzxDHanFoKQHj3oWbDiLgZFRMRF5XTcggA0SkzNKdJNds65z38LEXstTakcduupuOIuBUVExEX1eayO8gikAb2dDYtmWk6jsew22xE7SwddHyk+U1YrPoYFalK+hcl4qICg0LZEjEQgJKVHxhO4zm2LJ9DrC2VXLsfrfrdYzqOiNtRMRFxYVF97gegXc4yDYKtJvnL3gNgY+2+BIeGGU4j4n5UTERcWGyLBDb7tsPLYiflx3+bjuP2jqWn0jZrMQDhPe8znEbEPamYiLi4/PihADQ+8DVFhQVmw7i5XXMm4WspYbt3Cxq362Y6johbUjERcXFt+9zCMWoSwQk2LtBMsI5SUlxMw5TpAGS10bo4Io6iYiLi4nz9/NlZ/5rS/07+yGwYN7Zx0VdEcpSTBNG271DTcUTcloqJiBto1HcEJXYLbQqS2b8j2XQct2RZPRmAbXWvxD+ghuE0Iu5LxUTEDUTGNGVjYBIAafM1CLaqpe3dRtvcVQDUv2yE4TQi7k3FRMRNWDrdBUCrI7PIyzllOI172TfvbawWOxv9Eohu0tZ0HBG3pmIi4ibaXHwtaZY6hJDDxrkfmY7jNgryc2meNhOAooQ7zYYR8QAOLSaLFy/myiuvpF69elgsFmbOnOnI3Yl4NC9vb/Y1LF0/p/am/2C32Qwncg8b5vyHMLI4Qhjtet9gOo6I23NoMcnJyaF9+/a8/fbbjtyNiPym1RUPkWv3o3HJHq2fUwVsJSVEbHgXgD1xt+Lt42s4kYj783bkk/fv35/+/fuXe/uCggIKCn6fICorK8sRsUTcVmjtuiyvO4guR6Zj+fUNuORa05Fc2sZFX9Letp9sewCtrhppOo6IR3CqMSYTJkwgNDS07BYdHW06kojLiR34fxTbrbQpSGZn8hLTcVyaz/K3ANgUdS0hNWsbTiPiGZyqmIwePZrMzMyyW2pqqulIIi4nKrY5yaG9Acha8KrhNK5r2+oFtCrcSKHdi7grHzMdR8RjOFUx8fPzIyQk5IybiFRcrctKf5HGZ/3MwT1bDadxTXk//QuA5Fp9qVO/keE0Ip7DqYqJiFSNxm27sMG/E14WOwd+eMl0HJezf0cy7bOXAlC3n46WiFQnFRMRN2W96GEA2h2dRcaRg4bTuJb0Oa9gtdhZF9iN2BYJpuOIeBSHFpPs7GySk5NJTk4GYO/evSQnJ7N//35H7lZEgNZdB7LTuykBlkK2//dfpuO4jGPp+4k/PhuAgEv+bjiNiOdxaDFZvXo1HTp0oEOHDgA88sgjdOjQgWeeecaRuxURwGK1kpVQuq5Ly9Sp5GZnGk7kGnZ+9wq+lmK2+bSiRdLlpuOIeByHFpOePXtit9vPun300UeO3K2I/Cb+8ts4aKlLTbLZ8N+3TMdxetlZJ2id9iUAeZ20WJ+ICRpjIuLGvLy9OdDybwA03v6+Fvf7Cxu/mkAIueyzNqB9n5tMxxHxSComIm4u/qoHOEQEEZxg/QxdofNnThw9RNt9nwBwrOPfsXp5GU4k4plUTETcnJ9/IKntS6/QablnMpknjhlO5Jy2f/UsQZY8dnvF0aHfMNNxRDyWiomIB+h45X3ss0YTSg5bvnredBync/jAbjqkfwVAdo8ndbRExCAVExEP4OXtTUZS6URh7Q98wbF0LffwR/u+HoufpYgtPm1od8l1puOIeDQVExEPEX/ZbezwbkagpYDdM/5hOo7TSN25noTj3wNgvXQsFqs+FkVM0r9AEQ9hsVopuHgMAB2OfENaynbDiZzDke/G4m2xsT4gSfOWiDgBFRMRD9L24kFs8ovH11LCwW800eGu9UvpeOonAIIGPGc4jYiAiomIx/G5bCwACSd/ZN/WNYbTmJUzu/S9WB3ch8ZtuxhOIyKgYiLicZon9mZdYHe8LHZOfjcau81mOpIRm375jvb5qyiyexE5SEdLRJyFiomIBwq76nmK7F60z1tB8vwvTMepdgX5uYQueAKAtRFX06BJG8OJROQ0FRMRDxTbIoHV9W8FIOrXseScOmk2UDVbO+VZou1pHKMmLW992XQcEfkDFRMRDxV/yzjSLHWI5BgbP3/SdJxqc3DPZhJSJgOQkvgUITVrG04kIn+kYiLioQJqBHP0on8CkHhoCns3rzCcyPHsNhvHpz+Mn6WIjX4d6Djgb6Yjicj/UDER8WDte9/Iuho98LbYKJg5EltJielIDrV2zse0y19Fod2bmte/ocnURJyQ/lWKeLioG98g1+5Hi6ItrJ450XQchzmVmUH0ytKrb9bEDCO6aXvDiUTkXFRMRDxcZHQTNjS9H4BmG1/mxNFDhhM5xubPR1GHDA5Youhw87Om44jIn1AxERE6DhnNXmtDapLN7k8fcLu5TbavXkinw9MBONFzPP4BNQwnEpE/o2IiIvj4+lEw4F+U2C0kZs1n9Xf/Nh2pymSeOEbw9/fiZbGzOuRS2l5yrelIInIeKiYiAkCLxD6sbHgvAK3XPce+7clmA1UBu83G7snDqGc/wkFLXZrd+Z7pSCLyF1RMRKRM59vGsckvnkBLASXT7iA/N9t0pAuy8qtXScheTKHdi5wr39ecJSIuQMVERMp4eXsTeccnZBBCnC2F9ZNHmI5UaXs2rSB+84sArG32MM0SLjGcSETKQ8VERM4QXi+WAz1fByDp+EzWzvnIaJ7KyM3OxOvrO/GzFLE+oDOdbxxjOpKIlJOKiYicpV3P61gWdTsATZaPJm3vNsOJKmbzB/cSazvAEcKIufMTrF5epiOJSDmpmIjIOSUOe4Vt3i0JIZeCT28gM+Oo6UjlsvyLf9Lp5GxK7BaOXv42tSKiTEcSkQpQMRGRc/Lx9SP0to85Rk0a2VJIm3QVeTmnTMc6r1Uz36bLjlcAWNn4QVp3G2A4kYhUlIqJiPypqNjmZF0/nSxq0LJoCzveupaiwgLTsc4pef4UOqwrHUuyvO6NdLlVs7uKuCIVExE5r7g2SaT1/4g8uy/t81ay/q2bnW6xvy3LZtNiyYN4W2ysCu1H53v+rQX6RFyU/uWKyF9qkXQ5Oy55myK7F4lZ81n1zj1OM2397g2/Ej1nGP6WItYFdqPDA59qsKuIC1MxEZFyad97COsTJ2CzW0g6+hUr3nvA+JGTnclLqPn1jQRb8tji25aWD3yJt4+v0UwicmFUTESk3BKvvJdVrUYB0CX9cza8MoBTmRlGsqz+77tEf3MNtclkl1djGtz/Lf6BQUayiEjVUTERkQpJumEUqxNeoMDuQ3zecjLeuJjUXRurbf8lxcUse3cEiWsex/+3CdTqPDhP082LuAkVExGpsMSr7mP/1V9zhDBibamEftaXDT/PcPh+M08cY/Mr/eh66DMAltW7gzaPzlYpEXEjKiYiUilNO1yMdfgitvm0IoQcWv90F8vee8ghp3bsNhsbfp5B1psX0S5/FXl2X1Z3eoWu97yJl7d3le9PRMxRMRGRSguPjKHRowtYWWsgXhY7XdM+pvi19iz/4nkK8nOrZB87k5ew+cVetPv5TqLtaaQTzsFrvyFx4N1V8vwi4lyqpZi8/fbbNGzYEH9/f5KSkli5cmV17FZEqoGffyCdHvyMdd3eZr+1PrXIosuOlzn+Yjyr//tupa/cObhnK2tevYamM6+gTUEyhXZvlte9kYAHf6VJ+x5V/CpExFlY7Ha73ZE7mDZtGrfffjvvvPMOSUlJvP7663z55Zds376dOnXqnPexWVlZhIaGcuLECUJCQhwZU0SqQHFRIWu/fYsmWyYSzkkAMghhT1AiJXG9iO00kDr1G2Gz2Vi3bh0AHTp0wGq1UpCfy67VCzi1dR4RR5bRuHg3Vosdm93CmtBLibr6n9Rr2NzgqxOR8srKyqJWrVpkZmZW+Pe3w4tJUlISnTp14q233gLAZrMRHR3Ngw8+yKhRo87YtqCggIKC36e7zsrKIjo6mp9//pmgIF0GKOIqCvNOkbn8Y7pl/UCINZ8s7OzGxh5srLR5cwIv7CWlE7RZvKx4YaetpYhWFmiMlfpYsGJhjb0Fx9sNp3bDdoZfkYhURHZ2Nj179qxUMXHoqLHCwkLWrFnD6NGjy+6zWq1ceumlLFu27KztJ0yYwLPPan0LEVeWW5TLt/tnMZ917LJmU2jPo8j6h79/vP7nf8/Bagcfuze1fQ7Q5dgsrgvxo3mYjpaIeAKHHjFJS0ujfv36/Prrr3Tt2rXs/scff5xFixaxYsWKM7b/syMmOpUj4tx2Ht/JUwufYsn+JRzJPXLObSxYCPYOoIE1kEC8Kc4vAsDb3wcbdtLt+RwtyaHIVnzOx/t5+dE6ojX3JNzDXR3uwqq1cESc1oWcynGq6+z8/Pzw8/M7636r1aoPIREnY7PZeHfNu7z868vsPbn3jO9ZsBATGkPvRr3p27gv3WO60yCkwRmP/d8xJqflF+ezOm01i1IWMWvHLDYc2UBuUS4FJQWsTV/L8B+GM3LuSK5pcQ2vXPYK9ULqVc8LFpFyu5Df2Q4tJuHh4Xh5eXH48OEz7j98+DCRkZGO3LWIOMjJ/JPcN+s+Zm6bSX5Jftn9Ad4B9GzYkzva38F1ra7D21q5jxd/b396xPSgR0wPnrr4KQC2H9vOv1f9m1k7ZrHn5B7yi/OZsmkKUzZNoWV4S1669CWuaH5Flbw+ETHLoYchfH196dixIwsWLCi7z2azsWDBgjNO7YiI8yssLuSe/95D+EvhTN08tayUNA1rykeDPiJ7dDY/3PIDN7S5odKl5M80D2/OG/3fYPfDu9nz0B6uaXENvl6li/VtPbaVK6deSfO3mrM6bXWV7ldEqp/DT+U88sgj3HHHHSQmJtK5c2def/11cnJyGDZsmKN3LSJVwGaz8fyS55mwZEJZGfGyeDGo+SD+1fdfxNaMrdY8jWo14usbvsZmszFx5UReWPoC6dnp7Di+g07vd6Jrg65MuW5KtecSkarh8MuFAd566y1efvll0tPTiY+P58033yQpKekvH3d6HpPKDJ4RkQs3e+dsbv76Zk7mnyy7r3+T/nx2zWeEBYZV+nnPN8akMt5d/S6PzXuMU4WngNIxLje2uZFPrvmkyo/eiMhfu5Df39VSTCpLxUTEjGJbMYOnD2bm9pll93WM6si066fROKzxBT9/VReT08855qcxvLrsVQpLCgEICwhj1k2z6BqtU8ci1elCfn/rUhcROcPPKT8T/lJ4WSkJCwhjybAlrL5ndZWUEkexWq2M7zOezFGZXNPiGgAy8jLo9p9uDPt2GDabzXBCESkPFRMRAUqPONw842Z6fdyLzIJMAG5uczNH/+8oPWJcZ20af29/vr7ha+bcMocg39IZoz9K/oioV6NIPpRsNpyI/CUVExHhWO4xGr7RkCmbpgAQ6hfKT3f8xOfXfe6ycwj1bdKX448dp3+T/gAcyT1Cx/c78u7qdw0nE5Hzcc1PHBGpMstSlxHzWgypWakAXNXsKo49foyeDXuaDVYFfL19+eGWH5h5w0z8vfyx2W0M/344Q2cONR1NRP6EiomIB3tr5Vt0/0938orzsGDhzX5v8u1N37rdlSyDWgxi78i91A+uD8DH6z+m3aR25BbmGk4mIv9LxUTEQ90y4xYenP0gduwEeAewZNgSHkx60HQsh4kMiiRlZAq9G/YGYOORjdR/rT7bj203nExE/kjFRMTD2Gw2uk3uxhebvgAgOiSalIdT6B7T3XAyx/O2erPgjgWM7lG64vnJ/JO0ndSWZalnr3YuImaomIh4kGJbMfHvxrPsQOkv4j6N+pDycAp1guoYTla9xvcZz8wbZuJl8aLIVsRFH17EvN3zTMcSEVRMRDxGfnE+Ld9uycYjG4HSS4Hn3z7fZa+6uVCDWgxi2V3L8LX6UmIvod/n/ZixZYbpWCIezzM/kUQ8THZhNk3ebMKujF0ADO84nM+v+9xwKvM61e/E2nvX4u9desXO4C8H83Hyx6ZjiXg0FRMRN5eRm0HcG3EcPHUQgMe7Pc6kKyYZTuU8WtdpzZb7t1DDpwZ27Az9digTV0w0HUvEY6mYiLix/OJ8Wv27FUdzjwIwvvd4XrzsRcOpnE+jWo3Y8cAOavrXBOChOQ/xyfpPzIYS8VAqJiJuqthWTJt/t+FwzmEAXu/7OqMvGm04lfOqF1KP3Q/uppZ/LQCGzhzKDzt/MJxKxPOomIi4IZvNRtL7Sew+sRuApy9+moe7PGw4lfMLCwxj032bCPQJxI6dq6ZcpUuJRaqZiomIG+r3eT/Wpq8F4N6Ee3mu13OGE7mOeiH1WHvP2rKrdXp+1JOtR7eajiXiMVRMRNzMLTNuYd6e0jk5rmlxDe9c+Y7hRK6neXhzFg9bjJfFi0JbIYnvJ5KWlWY6lohHUDERcSNPLniybEbXHtE9+PqGrw0ncl1JDZL47qbvsGAhtyiXtu+0Jb8433QsEbenYiLiJmZsmcGEXyYA0CK8BYuGLjKcyPUNaDqAj67+CICMvAy6Tu5qNpCIB1AxEXED249t58YZNwJQy78W6+5d57Ezula129vfzuPdHgcgOT2ZoTOHmg0k4ub0ySXi4nILc+kyuQvFtmK8rd6s+NsK/L39TcdyKy9e9mLZqsQfr/+YSas0QZ2Io6iYiLi4pA+SOJl/EoCvBn9F09pNzQZyU/Num0f94PoAjPhhhC4jFnEQFRMRF3bzjJvZdHQTAGMuGsOgFoMMJ3JfVquVtfeUrqtjx06fT/pwJPuI6VgibkfFRMRF/XvVv5myaQoAl8ddzj97/9NwIvdXJ6gO82+bjwULecV5JL6fiM1mMx1LxK2omIi4oJ3Hd/LQ7IcAiA6JZvYtsw0n8hzdY7rzZv83AUjNSuW2b24znEjEvaiYiLgYm81Gjw97UGIvwcfqw8q7V+oKnGr2QOcHGNh0IABfbPqCGVtmGE4k4j70aSbiYq6bfh1HckrHNnx6zadEBkUaTuSZZt44k4jACABu/vpmjTcRqSIqJiIu5JP1nzBz+0wABrcazA1tbjAbyIN5W71ZNHQRVouVwpJCenzYw3QkEbegYiLiIg5kHeCu7+4CICooiqnXTTWcSFpGtOTVy18FYGfGTu7//n7DiURcn4qJiAuw2Wz0+E8Pim3FeFm8WHrnUo0rcRIju4zkkthLAJi0ehLzds8znEjEtemTTcQF3DvrXvZl7gPg3wP/TaNajQwnkj+ae+tcQv1CAbh62tXkFuYaTiTiulRMRJzcqoOr+GDdBwBcFncZ93S8x3Ai+V++3r7Mv31+2UrEV029ynQkEZelYiLixGw2GwO+GABADZ8afHfTd4YTyZ9JrJfIfZ3uA2DB3gVM3zzdcCIR16RiIuLE7vzuTo7lHgNg+uDpWpzPyU3sN5GooCgAhs4cSnZhtuFEIq5HxUTESS1LXcbH6z8GYGDTgQxoOsBwIvkrVquVubfOLZuy/oovrjAdScTlqJiIOCGbzcYVU0p/qQX5BvH1kK8NJ5LyalO3DQ92fhCARfsWMWXjFMOJRFyLw4rJuHHj6NatG4GBgdSsWdNRuxFxS7fPvJ2MvAwAvhr8Fb7evoYTSUW81vc16gfXB+DOb+/UKR2RCnBYMSksLGTw4MHcd999jtqFiFtaun8pn2/8HICrm19N3yZ9DSeSirJarcy7bR4WLOSX5NP/s/6mI4m4DIcVk2effZa///3vtG3b1lG7EHE7NpuNa6ddC0CIXwhfDvnScCKprJYRLfl7178D8EvqL3y77VvDiURcg1ONMSkoKCArK+uMm4gnGb1gNEdySxeDm3LdFLyt3oYTyYV49fJXyxZZvH3m7dhsNsOJRJyfUxWTCRMmEBoaWnaLjo42HUmk2qRnp/PqstJ1V7pHd9dVOG7i9MDlrIIs7pmlyfFE/kqFismoUaOwWCznvW3btq3SYUaPHk1mZmbZLTU1tdLPJeJqrvjiCkrsJXhbvfnuRk2k5i66RndlQJPSkvmfdf9h5/GdhhOJOLcKHSd+9NFHGTp06Hm3iYuLq3QYPz8//Pz8Kv14EVc1ffN01hxaA8DTFz9NWGCY4URSlb4c/CVhL4VRUFLAlVOuZNsDlf8DTsTdVaiYREREEBER4agsIh6p2FbMXd/dBUD94Po8c8kzhhNJVQv0DeRfff/FiB9GsP34diatmlQ2fb2InMlhY0z2799PcnIy+/fvp6SkhOTkZJKTk8nO1vX8In9058zf57mYeeNMs2HEYe7vdD9Nw5oC8MiPj2gFYpE/4bBi8swzz9ChQwfGjh1LdnY2HTp0oEOHDqxevdpRuxRxOVuPbuWzjZ8BpXOWJNZLNJxIHOm/N/23bG6TIV8NMR1HxCk5rJh89NFH2O32s249e/Z01C5FXM61067Fjp0A7wCmXK+py91d8/Dm3BF/BwDf7/yeDYc3GE4k4nyc6nJhEU8yffN0th0vHQT5yuWvaOVgD/H+le9Tw6cGAIO/HGw4jYjzUTERMcBmszF81nAAokOiub/T/YYTSXXxtnrzr77/AmDH8R1a5E/kf6iYiBjw9M9PcyL/BABfXPeF4TRS3e7peA8xoTEA3P/D/ZoRVuQPVExEqll2YTYvL30ZgC71u9AjpofhRGLCF9eWFtKT+Sd5auFThtOIOA8VE5FqduvXt1JkK8JqsWqRPg/WPaY73aO7A/DKslfIytfaYCKgYiJSrXYe38l320unm7+17a00CGlgOJGY9NWQr7BarBTbirnl61tMxxFxCiomItXouunXYceOv7c/71/5vuk4YlhkUCS3t78dgFk7Z7H16FbDiUTMUzERqSazts9i45GNAIzrPQ5fb1/DicQZvDvwXQK8AwBdPiwCKiYi1eb0kveRQZE80vURw2nEWfh6+zKhzwQANh/dzLzd8wwnEjFLxUSkGkxeO5lD2YcAeP8KncKRMz3c5WEiAksXSP3bf/9mOI2IWSomItXgsXmPAdAkrAlXNL/CcBpxRhP7TwRgf+Z+pm2aZjiNiDkqJiIO9tLSl8omU/to0Edmw4jTuqHNDWWTrj04+0HDaUTMUTERcSCbzcZzi54DoH3d9nSP6W44kTizD678AICjuUf596p/G04jYoaKiYgDjVowipyiHAA+v/Zzw2nE2V3W+DJahLcAYPSC0ZqqXjySiomIgxQWF/LGijcA6BHdg9Z1WhtOJK7g02s+BSCrIIt/Lv6n4TQi1U/FRMRB7v/hfgpLCrFg4fPrdLREyiexXiKJUYkAvLD0BYptxYYTiVQvFRMRB8jKz+Kj5I8A6N+kf9mgRpHyOL3idH5xPo/++KjhNCLVS8VExAH+9t+/UWIvwWqxlh2aFymvprWb0rthbwAmrZ5EfnG+4UQi1UfFRKSKZeVnMWPrDACGtBpCWGCY4UTiij6/7nMsWCiyFfHIj5opWDyHiolIFRv+/XBsdhtWi5V3r3jXdBxxUZFBkVwWdxkAk9dNprC40HAikeqhYiJShbILs5m+eToA17S4hhD/EMOJxJVNHjQZCxYKSwrLZg8WcXcqJiJVaMT3I8rGlrx3xXum44iLaxDSgJ4NewLw7pp3dYWOeAQVE5EqkluYyxebSq+muLLZlRpbIlXiw0EfAlBQUsDo+aMNpxFxPBUTkSry0JyHKLYVY8HCB1d9YDqOuInYmrFcFHMRAG+tektHTcTtqZiIVIH84nw+Wf8JUDpvSXhguOFE4k5OHzXJL87nmZ+eMZxGxLFUTESqwN/n/J0iWxEWLEweNNl0HHEzjcMa07VBVwBeX/661tARt6ZiInKBCosL+c+6/wBwWdxlRAZFGk4k7uj0UZO84ryyFatF3JGKicgFemzeYxTaCnW0RByqeXhzOtXrBMAry17RURNxWyomIhfAZrPx/tr3Abgk9hIahDQwnEjc2X+uKj0yl1OUw8SVEw2nEXEMFRORC/DKslfIK84D4L0rNW+JOFabum1oHdEagHFLxhlOI+IYKiYiF+DFpS8C0L5ue5rWbmo4jXiCN/q9AcDR3KPM2DLDcBqRqqdiIlJJn2/8nIy8DADeGvCW4TTiKfrE9Sk7Zfj4vMcNpxGpeiomIpX05IInAYgNjaVHTA/DacSTPN/reQD2nNzDstRlhtOIVC0VE5FKWJyymP2Z+wF48dIXDacRT3NH/B3U9K8JwAM/PGA2jEgVUzERqYQHZpf+MqgdUJsb2txgOI14oke7PgrA2vS17D2x13AakarjsGKSkpLCXXfdRaNGjQgICKBx48aMHTuWwsJCR+1SpFpsP7adjUc2AvBE9ycMpxFP9WSPJ/H38gfg3ln3Gk4jUnUcVky2bduGzWbj3XffZfPmzbz22mu88847PPnkk47apUi1GD5rOAAB3gFlf7WKVDer1crQ+KEAzN8zn5P5J43mEakqDism/fr148MPP+Tyyy8nLi6Oq666iv/7v//j66+/dtQuRRzuWO4xFu1bBMDdCXdjtepsqJjz6uWv4mXxwo5dY03EbVTrp2pmZiZhYWF/+v2CggKysrLOuIk4kwd+eAA7dryt3rx4mQa9ilmBvoFc2exKAKZvnk6xrdhwIpELV23FZNeuXUycOJF77/3zc6ETJkwgNDS07BYdHV1d8UT+UrGtmK+3lh7xG9R8EP7e/oYTicCkKyYBUGQr4vlFzxtOI3LhKlxMRo0ahcViOe9t27ZtZzzm4MGD9OvXj8GDB3P33Xf/6XOPHj2azMzMsltqamrFX5GIg4xfMp4iWxEAb/Z703AakVKRQZF0jOoIwMRVWj9HXJ93RR/w6KOPMnTo0PNuExcXV/bfaWlp9OrVi27duvHee+dfS8TPzw8/P7+KRhKpFm+uKC0jCZEJ1AupZziNyO9e7/c6F314ERl5GXy77VsGtRhkOpJIpVW4mERERBAREVGubQ8ePEivXr3o2LEjH374oQYKisuatX0Wx/OOA/Ba39cMpxE5U4+YHkQFRXEo+xCjFoxSMRGX5rCmcPDgQXr27ElMTAyvvPIKR48eJT09nfT0dEftUsRhnphfOl9JVFAUFze82HAakbOdnlNn27Ft7M7YbTiNSOU5rJjMmzePXbt2sWDBAho0aEBUVFTZTcSV7D2xly3HtgDweHctmibO6cHODxLgHQBomnpxbQ4rJkOHDsVut5/zJuJKTn/I+3v781DnhwynETk3q9XKzW1vBmDennnkFuYaTiRSORr0IXIe+cX5/Lj7RwBuanOTxkmJU3vl8lewYKHEXsJTC58yHUekUvQpK3IeTy18ihJ7CRYs/Kvvv0zHETmvmv416RHTA4DJ6yYbTiNSOSomIufxwdoPAOge3b1smXkRZ3Z6jp1Thaf4ZP0nhtOIVJyKicif+Hzj52QVlC6L8Eb/NwynESmf+Kh4GtZsCMA/fv6H0SwilaFiIvInnv35WQBiQ2NJiEownEak/P5xyT8A2HtyL5uPbDYbRqSCVExEzmHvib3szNgJwOgeow2nEamYO+LvoIZPDQAenfuo4TQiFaNiInIOj/z4CFB6ifDdCX++vpOIsxrSeggAC/YuoLC40HAakfJTMRH5HzabjR92/gDANS2u0SXC4pJeuuwlLFgothUz4ZcJpuOIlJs+cUX+x2vLX6PQVvoX5iuXvWI4jUjlhAeGEx8ZD8C/V//bbBiRClAxEfkfry0vXaSvdURrrSIsLm1c73EAHMk5wtL9Sw2nESkfFRORP0g+lMzBUwcBeLbns4bTiFyY/k37U8u/FgCPz9M6T+IaVExE/uD0FQzBvsFc1+o6w2lELtywDsMAWHZgGdmF2YbTiPw1FROR3+QX57No3yIAbm13q+E0IlXjnz3/idVixY6dpxZo/RxxfiomIr95btFzZevijO8z3nQckSoR6BtI9+juAHyyQVPUi/NTMRH5zXtr3gMgsV6i1sURt/LyZS8DcDL/JLO2zzKcRuT8VExEgIV7F3I87zgAL1z6guE0IlUrqUESkUGRAIz5aYzhNCLnp2IiAjy54EkAagfUpnej3obTiFS9Bzo9AMD6w+vJyM0wnEbkz6mYiMfLLcxlVdoqAO7scKfhNCKO8USPJ/C2egPw1EINghXnpWIiHu/5Jc9js9uwYClblVXE3Xhbvbk45mIApmyaYjiNyJ9TMRGPN3ndZKB00Gugb6DhNCKOc/pqs8yCTObtnmc4jci5qZiIR1udtpojOUcA+EfPf5gNI+JgSQ2SiAiMAOCZn54xnEbk3FRMxKOdHvQa7BvMgKYDDKcRcbw72t8BwMq0leQX5xtOI3I2FRPxWMW2Yn5K+QmAIa2HGE4jUj3G9hyLBQs2u41/Lv6n6TgiZ1ExEY/15oo3KbYVAzC+t2Z6Fc8Q5BtEQlQCAP9Z9x/DaUTOpmIiHmviyokAtAhvQZ2gOobTiFSf01efpWenk3wo2WgWkf+lYiIeae+JvaScTAHg8W5aDl48yxXNryDYNxiAUQtGGU4jciYVE/FIT8x/AgB/L/+ywYAinuT6VtcDpcsx2Gw2w2lEfqdiIh5p1o7Shcz6N+2P1ap/BuJ5Ts9pUmQrKjutKeIM9IksHufzjZ+TV5wHwIuXvmg4jYgZkUGRtKjdAoA3VrxhOI3I71RMxOO8+EtpGYkOiaZp7aaG04iY83/d/g+AvSf3ciDrgOE0IqVUTMSjZBdms+nIJgDu7Xiv4TQiZg2LH4avly8AYxaOMZxGpJSKiXiUcYvHYceO1WLlsW6PmY4jYpTVaqVXw14AzNw202wYkd+omIhH+Xj9xwB0jOqIr7ev4TQi5v2zV+nsr5kFmSxOWWw4jYiKiXiQ7ce2cyj7EACje4w2nEbEOXSq34mwgDAA/rHoH2bDiKBiIh5kzE+l59ADvAO4puU1htOIOI8hrUrXilqyf4nmNBHjHFpMrrrqKmJiYvD39ycqKorbbruNtLQ0R+5S5E/N3jkbgH5N+hlOIuJcnu35LFC6sOW7a941nEY8nUOLSa9evZg+fTrbt29nxowZ7N69m+uvv96RuxQ5p1nbZ5FTlAP8fk5dRErVCapDk7AmQOniliImObSY/P3vf6dLly7ExsbSrVs3Ro0axfLlyykqKnLkbkXOMm7JOADq1qhL6zqtDacRcT73Jd4HwLbj28jIzTCcRjxZtY0xycjI4PPPP6dbt274+Picc5uCggKysrLOuIlcqMLiQlamrQTgtna3GU4j4pweSnoIL4sXAM8uetZwGvFkDi8mTzzxBDVq1KB27drs37+fb7/99k+3nTBhAqGhoWW36OhoR8cTD/D6itex2W1YsPD0xU+bjiPilLyt3nRp0AWAKZumGE4jnqzCxWTUqFFYLJbz3rZt21a2/WOPPca6deuYO3cuXl5e3H777djt9nM+9+jRo8nMzCy7paamVv6VifzmndXvANAqohUh/iGG04g4r9PF/WjuUTYc3mA4jXgq74o+4NFHH2Xo0KHn3SYuLq7sv8PDwwkPD6dZs2a0bNmS6Oholi9fTteuXc96nJ+fH35+fhWNJPKn0rLS2HtyLwAju4w0G0bEyfVt0pcg3yCyC7N5euHTfHvTnx/hFnGUCheTiIgIIiIiKrWz09fHFxQUVOrxIhX1zM/PAOBj9eHO+DsNpxFxflc0vYKpm6cyd89c01HEQzlsjMmKFSt46623SE5OZt++fSxcuJCbbrqJxo0bn/NoiYgjfLPtGwAujr0Yq1XzCYr8led7Pw9AfnE+M7bMMJxGPJHDPqkDAwP5+uuv6dOnD82bN+euu+6iXbt2LFq0SKdrpFokH0omI6/0sscxF2vlVJHyaBzWmMigSABeXfaq4TTiiSp8Kqe82rZty8KFCx319CJ/6bnFzwEQ5BtEz4Y9zYYRcSE3tr6R11e8zsqDK7HZbDraKNVKP23itubuLj1H3rdxX8NJRFzLUxc/BUCJvYT3175vOI14GhUTcUsL9iwom4L+H5f8w2wYERcTHhhOXM3SqyvfXvW24TTiaVRMxC2NXzIegNoBtWlTt43hNCKuZ1iHYQBsOrKJ3MJcw2nEk6iYiNux2Wz8sv8XAK5pcY3hNCKu6ZEuj2DBgh07/1r+L9NxxIOomIjbmbZ5GoW2QgDG9hxrOI2Iawr0DaRNndKjjR+u+9BwGvEkKibidl5b/hoA9YPr0yCkgeE0Iq5rRKcRAOw5uUcrDku1UTERt1JsK2btobUA3NL2FsNpRFzb3Ql3420tnVXi+SXPG04jnkLFRNzKpFWTKLGXADD6otGG04i4NqvVSqd6nQCYummq4TTiKVRMxK1MWj0JgKZhTanpX9NsGBE38Fi3xwA4lH2IvSf2Gk4jnkDFRNxGdmE2245tA0oPQYvIhbum5TX4e/kD8OyiZw2nEU+gYiJu46WlL2HHjtVi5eGkh03HEXEblzS8BIDvtn9nOIl4AhUTcRufbvgUgHZ12+Hr7Ws4jYj7OL0I5on8EyQfSjYbRtyeiom4hYzcDFJOpgBwX+J9ZsOIuJkeMT2o4VMDgPG/jDecRtydiom4hZd/fRkAL4sXd3a403AaEffTp1Ef4PfFMUUcRcVE3MKUTVMAiI+ML5t3QUSqzqgeowDILMgsmytIxBFUTMTlZeRmsC9zH6DTOCKO0jW6K0G+QcDvi2SKOIKKibi8F5a+AJSexhkWP8xwGhH3dWmjSwGYt2ee4STizlRMxOWdnpGyQ2QHrFb9SIs4ypMXPQlAVkEWq9NWG04j7kqf4uLSjuUeIzUrFYAHOj9gOI2Ie+tUvxPBvsEATFgywXAacVcqJuLSJvxS+uHobfXmtna3GU4j4v4ui7sM0OkccRwVE3Fp0zdPByAhMkGncUSqwenFMU8VnmLVwVWG04g70ie5uKwj2Uc4kHUAgBGdRxhOI+IZEuslEuIXAujqHHEMFRNxWaevxvG2enNr21sNpxHxHKdP58zfO99wEnFHKibisk6fxukY1VGncUSq0emrc7ILs1lxYIXhNOJu9GkuLik9O52Dpw4C8GDSg4bTiHiWhKgEQv1Cgd8HoItUFRUTcUmnL1X0tnpzU+ubDKcR8TyXN74cgPl7dDpHqpaKibikGVtnAJAYlajTOCIGjLl4DAA5RTk6nSNVSp/o4nIycjPKTuOM6KSrcURMaFe3XdnVOadX9xapCiom4nJeWfYKULo2zs1tbzacRsRz9W7YG4AFexcYTiLuRMVEXM60zdOA0r/YdBpHxJz/6/Z/AJzMP8nWo1sNpxF3oU91cSm5hbnsPbEXgDs73Gk4jYhn6x7TnUCfQABe+OUFw2nEXaiYiEt5Y8Ub2LFjwcI9CfeYjiPi8bpHdwdg9q7ZhpOIu1AxEZfy6YZPAWge3hxfb1/DaURkZJeRABzNPcr+zP1mw4hbUDERl1FYXMj249sBuL3d7YbTiAjAgKYD8PPyA+DFpS8aTiPuQMVEXMYH6z7AZrdhwaLZXkWcSKd6nQCYuW2m2SDiFlRMxGVMXjsZgEY1GxHkG2Q4jYicdn+n+wFIO5XGsdxjhtOIq6uWYlJQUEB8fDwWi4Xk5OTq2KW4GZvNxvrD6wEY0nqI4TQi8kc3tL4Bb6s3AC8v1WRrcmGqpZg8/vjj1KtXrzp2JW5qyuYplNhLAHi026OG04jIH1mtVtrXbQ/Al1u+NJxGXJ23o3cwe/Zs5s6dy4wZM5g9+/yXkxUUFFBQUFD2dWZmJgBZWVkOzSjOb+LiiZAPUcFR+Bb76mfCxdlsNrKzs4HSf9+aKM/13dz0ZtbsXcPe9L2kHUvT6VYPd/oz2m63V/zBdgdKT0+3169f375q1Sr73r177YB93bp1f7r92LFj7YBuuummm2666eYGt927d1e4O1js9srUmb9mt9sZMGAA3bt3Z8yYMaSkpNCoUSPWrVtHfHz8OR/zv0dMTp48SWxsLPv37yc0NNQRMT1GVlYW0dHRpKamEhISYjqOS9N7WTX0PlYdvZdVR+9l1cjMzCQmJoYTJ05Qs2bNCj22wqdyRo0axYsvnv9a9a1btzJ37lxOnTrF6NGjy/3cfn5++Pn5nXV/aGiofkCqSEhIiN7LKqL3smrofaw6ei+rjt7LqlGZ07QVLiaPPvooQ4cOPe82cXFxLFy4kGXLlp1VNBITE7nlllv4+OOPK7prERERcXMVLiYRERFERET85XZvvvkmzz//fNnXaWlp9O3bl2nTppGUlFTR3YqIiIgHcNhVOTExMWd8HRRUOkK7cePGNGjQoFzP4efnx9ixY895ekcqRu9l1dF7WTX0PlYdvZdVR+9l1biQ99Fhg1//V3kGv4qIiIhnq7ZiIiIiIvJXNKuRiIiIOA0VExEREXEaKiYiIiLiNFRMRERExGm4VDH5/vvvSUpKIiAggFq1anH11VebjuTSCgoKiI+Px2KxkJycbDqOy0lJSeGuu+6iUaNGBAQE0LhxY8aOHUthYaHpaC7h7bffpmHDhvj7+5OUlMTKlStNR3I5EyZMoFOnTgQHB1OnTh2uvvpqtm/fbjqWy3vhhRewWCyMHDnSdBSXdPDgQW699VZq165NQEAAbdu2ZfXq1eV+vMsUkxkzZnDbbbcxbNgw1q9fz9KlS7n55ptNx3Jpjz/+OPXq1TMdw2Vt27YNm83Gu+++y+bNm3nttdd45513ePLJJ01Hc3rTpk3jkUceYezYsaxdu5b27dvTt29fjhw5YjqaS1m0aBEjRoxg+fLlzJs3j6KiIi6//HJycnJMR3NZq1at4t1336Vdu3amo7ikEydO0L17d3x8fJg9ezZbtmzh1VdfpVatWuV/ksqsGlzdioqK7PXr17d/8MEHpqO4jR9++MHeokUL++bNm+1w/lWfpfxeeukle6NGjUzHcHqdO3e2jxgxouzrkpISe7169ewTJkwwmMr1HTlyxA7YFy1aZDqKSzp16pS9adOm9nnz5tkvueQS+8MPP2w6kst54okn7D169Lig53CJIyZr167l4MGDWK1WOnToQFRUFP3792fTpk2mo7mkw4cPc/fdd/Ppp58SGBhoOo5byczMJCwszHQMp1ZYWMiaNWu49NJLy+6zWq1ceumlLFu2zGAy15eZmQmgn8FKGjFiBAMHDjzjZ1Mq5rvvviMxMZHBgwdTp04dOnTowPvvv1+h53CJYrJnzx4A/vGPfzBmzBhmzZpFrVq16NmzJxkZGYbTuRa73c7QoUMZPnw4iYmJpuO4lV27djFx4kTuvfde01Gc2rFjxygpKaFu3bpn3F+3bl3S09MNpXJ9NpuNkSNH0r17d9q0aWM6jsuZOnUqa9euZcKECaajuLQ9e/YwadIkmjZtyo8//sh9993HQw89VKGFe40Wk1GjRmGxWM57O30eH+Cpp57iuuuuo2PHjnz44YdYLBa+/PJLky/BaZT3vZw4cSKnTp1i9OjRpiM7rfK+l3908OBB+vXrx+DBg7n77rsNJRdPNmLECDZt2sTUqVNNR3E5qampPPzww3z++ef4+/ubjuPSbDYbCQkJjB8/ng4dOnDPPfdw9913884775T7ORy2iF95PProowwdOvS828TFxXHo0CEAWrVqVXa/n58fcXFx7N+/35ERXUZ538uFCxeybNmysxZWSkxM5JZbbqlQq3VX5X0vT0tLS6NXr15069aN9957z8HpXF94eDheXl4cPnz4jPsPHz5MZGSkoVSu7YEHHmDWrFksXry43Iukyu/WrFnDkSNHSEhIKLuvpKSExYsX89Zbb1FQUICXl5fBhK4jKirqjN/VAC1btmTGjBnlfg6jxSQiIoKIiIi/3K5jx474+fmxfft2evToAUBRUREpKSnExsY6OqZLKO97+eabb/L888+XfZ2Wlkbfvn2ZNm0aSUlJjozoMsr7XkLpkZJevXqVHcWzWl3i7KhRvr6+dOzYkQULFpRd8m+z2ViwYAEPPPCA2XAuxm638+CDD/LNN9/w888/06hRI9ORXFKfPn3YuHHjGfcNGzaMFi1a8MQTT6iUVED37t3PumR9x44dFfpdbbSYlFdISAjDhw9n7NixREdHExsby8svvwzA4MGDDadzLTExMWd8HRQUBEDjxo31l1YFHTx4kJ49exIbG8srr7zC0aNHy76nv/zP75FHHuGOO+4gMTGRzp078/rrr5OTk8OwYcNMR3MpI0aM4IsvvuDbb78lODi4bIxOaGgoAQEBhtO5juDg4LPG5dSoUYPatWtrvE4F/f3vf6dbt26MHz+eIUOGsHLlSt57770KHU12iWIC8PLLL+Pt7c1tt91GXl4eSUlJLFy4sGLXRotUoXnz5rFr1y527dp1Vqmza9Hu87rhhhs4evQozzzzDOnp6cTHxzNnzpyzBsTK+U2aNAmAnj17nnH/hx9++JenI0UcoVOnTnzzzTeMHj2a5557jkaNGvH6669zyy23lPs5LHZ9goqIiIiT0AlxERERcRoqJiIiIuI0VExERETEaaiYiIiIiNNQMRERERGnoWIiIiIiTkPFRERERJyGiomIiIg4DRUTERERcRoqJiIiIuI0VExERETEafw/HyFF6AYUQ9sAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -662,7 +666,148 @@ "plt.ylim(-4, 4)\n", "\n", "plt.plot(x, x*0, 'k', alpha=0.2)\n", - "plt.plot(x*0, x, 'k', alpha=0.2)\n" + "plt.plot(x*0, x, 'k', alpha=0.2)\n", + "\n", + "plt.plot(x, x**2, label='$f(x)=x^2$')\n", + "plt.plot(x, -(x**2)/2, 'g', label='$f(x)=-\\\\frac{1}{2}x^2$')\n", + "plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plotting sine function" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x = np.linspace(-6, 6, 100)\n", + "plt.plot(x, np.sin(x), label='$f(x)=sin(x)$')\n", + "\n", + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n", + "\n", + "plt.legend()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another example of shifting transformation" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGdCAYAAAAvwBgXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABIkklEQVR4nO3deXxTZb4/8E+WNt3SdN93yl4oUBZZdEBUUNyuCuI4jnAZHL3gDBevI/U6Mtc7gnPVGa+Mgzs4bqDjBeeHysiigALDWvYCFQqlO6VNuiZpcn5/lARqS3PaJnlOms/79errZdOTnm+OtPn0eb7Pc1SSJEkgIiIiEkAtugAiIiLyXwwiREREJAyDCBEREQnDIEJERETCMIgQERGRMAwiREREJAyDCBEREQnDIEJERETCaEUX0BW73Y6ysjLo9XqoVCrR5RAREZEMkiShvr4eSUlJUKu7HvNQdBApKytDamqq6DKIiIioB0pKSpCSktLlMYoOInq9HkDbCwkPDxdcDRH1xoR3JuBY1TH8bdbfMDVzKg4dOgQAyM3NdfkXk79Z8tlhbDhcjn+/uT/mTcoSXQ5Rt5lMJqSmpjrfx7ui6CDimI4JDw9nECHycRXWCiAIGJA0AOHh4QgLCwPQ9vPNINKe0aaFWheC9IQY/u4jnyanrYI//UTkcS2tLahprgEAJIcnC65G+apMZgBAnD5IcCVEnscgQkQeV1ZfBgAI0gYhMihScDXKV1XfFkTiw3WCKyHyPAYRIvK4UlMpACBZn8wVcC60WG0wNlsBcESE/IOie0TkkCQJra2tsNlsokshUrSAgABoNBoh5y6tvxxEOC3jUvXl0ZBArRrhwT7/K5rIJZ/+V26xWFBeXo6mpibRpRApnkqlQkpKirNJ1JuuHhGhrlXVtwAA4vQ6jh6RX/DZIGK323H27FloNBokJSUhMDCQP7RE1yBJEqqrq3HhwgX079/f6yMjF0wXAAAp4V3vJ0BXN6qyP4T8g88GEYvFArvdjtTUVISEhIguh0jxYmNjUVxcDKvV6vUg4pya4YiIS+XGthGRREOw4EqIvMPnm1W5/wCRPCJHDNkjIl9ZXTMAINHARlXyD3wXJyKPY4+IfI4RkaQIjoiQf2AQISKPskt25z4iHBFxrczYNiKSFMEREfIPDCJE5FEXmy7CardCBRUSwxJFl6N45XXsESH/wiBC3VZXV4fRo0djxIgRyMnJwVtvvSW6JFIwx7RMXGgcAjQBgqtRNqvN7ly+m8gREfITPrtqhsTR6/XYvn07QkJC0NjYiJycHNxzzz2Ijo4WXRopkGPpLqdlXKs0tcAuAQEaFWJCuXyX/ANHRARasWIF0tPTodVqMXfuXMTFxaG4uFj282fPno2XX37ZcwVeg0ajcS6ZNpvNkCQJkiR5vQ7yDY4VM9xDxDVHo2qCIQhqNfdFIv/AICLIoUOHsHjxYqxcuRIlJSWIjIzEXXfdhYyMDNnf45lnnsHzzz8Po9HouUKvoa6uDrm5uUhJScGTTz6JmJgYr9dAvoErZuRzLN1NYn8I+REGEUE2bNiAsWPH4rbbboPBYMA777yDefPmdet75OTkoF+/fvjggw88VOW1RURE4NChQzh79iw++ugjVFZWer0G8g3czEw+Lt0lf8QgIkB2djaeeeYZ7Ny5EyqVCjExMdDpdLjuuuvaHffxxx8jODgY5eXlzsfmzp2L4cOHO0dB7rjjDqxZs8at9ck5r0N8fDxyc3OxY8cOYTWQsnEzM/nKuZkZ+aE+FUQkSUKTpdXrH93tj9i5cyeysrLw4osvory8HA888ADy8vI6HDd79mwMGDAAy5YtAwAsXboUmzdvxldffQWDwQAAGDt2LPbs2QOz2dzh+cuWLUNYWFiXH+fPn+/2eSsrK1FfXw8AMBqN2L59OwYOHNita+CKnNdOvoFTM/KVObZ354gI+ZE+tWqm2WrDkGf/4fXzHn9uGkIC5V/KsLAwFBcXY9KkSUhISEBNTQ2SkpI6HKdSqfD888/jvvvuQ0JCAlasWIEdO3YgOfnKL/SkpCRYLBZUVFQgPT293fMfffRRzJo1q8taenLec+fO4ZFHHnE2qT7++OMYNmyY7Ncvh5zXTr6BIyLyXekR4YgI+Y8+FUR8xeHDhwHA+ebd3NyMoKDOf/HcfvvtGDJkCJ577jl8/fXXGDp0aLuvBwe3/eXU1NTU4blRUVGIiorqUY1dnXfs2LEoKCiQ9X2WLFmCP/zhD10ec+LECQwaNKhbNZBvaLQ0oq6lDgBHRORgjwj5oz4VRIIDNDj+3DQh5+2OgoICZGdnIzQ0FAAQExOD2traTo/duHEjCgsLYbPZEB8f3+Hrly5dAtB2Z9UfW7ZsmXNq41qOHz+OtLS0bp9XrieeeAJz5szp8pisrKxOH3dXDSSOYzQkNCAU4bpwwdUoW4vVhkuNFgBcNUP+pU8FEZVK1a0pElEKCgqQm5vr/HzkyJGdrnw5cOAAZs2ahXfeeQerV6/Gb3/7W3z66aftjjl69ChSUlI6XT7b06kZOeeVKzY2ttOQ5Io7ayBxnP0h4clC7/7rCxyjISGBGoQHK//3GJG78F+7AAUFBbjzzjudn0+bNg35+fmora1FZGQkAKC4uBgzZszA008/jQceeABZWVkYP348Dhw4gFGjRjmfu2PHDtxyyy2dnqcnUzNyz+tJSqiB3IObmcl39YoZhjbyJ31q1YwvsNvtOHLkSLsRkWHDhmHUqFH45JNPALRNt0yfPh133XUXlixZAgAYN24cbr31Vjz99NPO57W0tGD9+vWYP3++W2qTe15PUkIN5D5cMSNfqaNRlf0h5Gc4IuJlarUajY2NHR5/9tln8eSTT2L+/PmIiopCYWFhh2O++OKLdp+vWrUKY8eO7bD/SE/JPa8nKaEGch9uZiafs1GV/SHkZxhEFGLGjBk4ffo0SktLkZqaKus5AQEBWLFihYcrI+o5Lt2Vr9x4eWqGd90lP8MgoiCLFi3q1vG/+MUvPFMIkZs477zLERGXyuo4IkL+iT0iROQx5+rOAQDSI9JdHEkcESF/xSBCRB7RbG1GZWPbzRAzIjLEFuMDHCMiiRwRIT/jtSDywgsvQKVSdXv6gYh803lj232MwgLDEBkUKbgaZTO1WNFgbgUAJHFEhPyMV4LI3r178cYbb2D48OHeOB0RKcA54+VpGUM698VwofzyaEhESIBPbMpI5E4eDyINDQ148MEH8dZbbzk36yKivq+4rhgAp2XkKHP0h3BahvyQx4PIggULMGPGDNx0002ePhURKYizUdXARlVXyp0rZjgtQ/7Ho2OAa9aswYEDB7B3715Zx5vNZpjNZufnJpPJU6URkYcVG4sBcEREDq6YIX/msRGRkpIS/PrXv8aHH354zVvc/9jy5cthMBicH3I39iIi5eHSXflK6zg1Q/7LY0Fk//79qKqqwqhRo6DVaqHVarFt2za8+uqr0Gq1sNlsHZ6Tn58Po9Ho/CgpKfFUeUTkYewRkc8xNZPM+8yQH/LY1MzUqVNx5MiRdo/NnTsXgwYNwlNPPQWNRtPhOTqdDjqdzlMlEZGXWGwWlNWXAWCPiBzOqRn2iJAf8lgQ0ev1yMnJafdYaGgooqOjOzxORH1LibEEEiQEaYMQFxonuhxFkyTpyg3vOCJCfog7q5LPq6urw+jRozFixAjk5OTgrbfeEl2S3+MeIvJdarTA3GqHSgXEh3NEhPyPV3fO+fbbb715OvITer0e27dvR0hICBobG5GTk4N77rkH0dHRokvzW+wPkc+xtXtMmA6BWv5tSP6H/+oFWrFiBdLT06HVajF37lzExcWhuLhY9vNnz56Nl19+2SO11dTUdLseb/nx69ZoNAgJCQHQtgRckiRIkuT28/rSNRGNe4jI59jMjNMy5K8YRAQ5dOgQFi9ejJUrV6KkpASRkZG46667kJGRIft7PPPMM3j++edhNBrdXt/zzz/f7XrcYfny5RgzZgz0ej3i4uJw99134+TJk+2O6ex119XVITc3FykpKXjyyScRExPj9tp87ZqI5Jia4YiIa+WXl+5yMzPyVwwigmzYsAFjx47FbbfdBoPBgHfeeQfz5s3r1vfIyclBv3798MEHH7i1tqamph7V05XJkydj9erVLo/btm0bFixYgN27d2PTpk2wWq245ZZb0NjY6Dyms9cdERGBQ4cO4ezZs/joo49QWVnpttoB918TudcD6Pk1EckxNcM9RFxzNKpyDxHyVwwiAmRnZ+OZZ57Bzp07oVKpEBMTA51Oh+uuu67dcR9//DGCg4NRXl7ufGzu3LkYPny48y/fO+64A2vWrHFrfV9++WWP6+mtjRs3Ys6cORg6dChyc3OxevVqnD9/Hvv372933LVed3x8PHJzc7Fjxw631OPgy9dEBI6IyFfmXDHDERHyT30qiEiShEZLo9c/utuPsHPnTmRlZeHFF19EeXk5HnjgAeTl5XU4bvbs2RgwYACWLVsGAFi6dCk2b96Mr776CgaDAQAwduxY7Nmzp93W+A7Lli1DWFhYlx/nz5/v8LwdO3b0uB53c7yZR0VFtXv86tddWVmJ+vp65/Hbt2/HwIED3VqHr10TkVrtrSgxtm1GyB4R18q4qyr5uT51v+kmaxPClod5/bwN+Q0IDQyVfXxYWBiKi4sxadIkJCQkoKamBklJSR2OU6lUeP7553HfffchISEBK1aswI4dO5CcnOw8JikpCRaLBRUVFUhPb/9L/9FHH8WsWbO6rKWz8547d67H9biT3W7HokWLMHHixA57z1z9uisrK/HI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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x = np.linspace(-6, 6, 100)\n", + "plt.plot(x, x**3 - x, label='$f(x)=x^3-x$')\n", + "\n", + "# horizontal shift\n", + "plt.plot(x, (x+2)**3 - (x+2), 'g', label='$f(x)=(x+2)^3-(x+2)$')\n", + "\n", + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n", + "\n", + "plt.ylim(-5, 5)\n", + "plt.legend()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Vertical scaling of sine function:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x = np.linspace(-6, 6, 100)\n", + "\n", + "# sine with vertical scaling\n", + "plt.plot(x, np.sin(x), label='$f(x)=sin(x)$')\n", + "plt.plot(x, 2*np.sin(x), 'g', label='$f(x)=2sin(x)$')\n", + "\n", + "plt.plot(x, x*0, 'k', alpha=0.2)\n", + "plt.plot(x*0, x, 'k', alpha=0.2)\n", + "\n", + "plt.ylim(-5, 5)\n", + "plt.legend()" ] }, { From 91c0d0f634e9a766dbf428fc0f5065d62bc28ea2 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Sun, 1 Jan 2023 23:12:36 +0000 Subject: [PATCH 71/76] readme change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55b9706..301bb43 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🐙 Machine Learning Notebooks -This repo contains machine learning notebooks for different tasks and applications. The notebooks are meant to be minimal and easily reusable and extendable. You are free to use them for educational and research purposes. +This repo contains machine learning notebooks for different tasks and applications. The notebooks are meant to be minimal, easily reusable, and extendable. You are free to use them for educational and research purposes. This repo supports Codespaces! - Spin up a new instance by clicking on the green `"<> Code"` button followed by the `"Configure and create codespace"` option. Make sure to select the dev container config provided with this repo. This setups an environment with all the dependencies installed and ready to go. From 2a8aa8154a2ca4ef15e26a7625bf19a82032fe54 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 6 Jan 2023 10:02:50 -0600 Subject: [PATCH 72/76] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 50e41c2a65931a49555c2e6f55e78bc41cb689c8 Mon Sep 17 00:00:00 2001 From: Elvis Saravia Date: Fri, 6 Jan 2023 10:14:09 -0600 Subject: [PATCH 73/76] Update README.md --- notebooks/maths/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks/maths/README.md b/notebooks/maths/README.md index 1ec32e5..d9e87ff 100644 --- a/notebooks/maths/README.md +++ b/notebooks/maths/README.md @@ -1 +1 @@ -All notebooks in this folder are tagged as work in progress [WIP] and contain very minimal rough notes and code snippets that may contain innaccuracies and errors. They are not intended to be used as a reference or as a source of truth. \ No newline at end of file +All notebooks in this folder are tagged as work in progress [WIP] and contain very minimal rough notes and code snippets that may contain innaccuracies and errors. From a5b5af4a6d918df88a0270a15624184c7c9a9c5c Mon Sep 17 00:00:00 2001 From: Ritvik19 Date: Fri, 26 Jan 2024 11:02:22 +0530 Subject: [PATCH 74/76] Update README.md --- README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 301bb43..958b11d 100644 --- a/README.md +++ b/README.md @@ -288,7 +288,30 @@ This repo supports Codespaces! - + ## LLM Fine-tuning + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionNotebook
Finetuning with LoRAFinetuning a Transformer Model using LoRAKaggle
Finetuning TinyLlama 1.1BFinetuning TinyLlama 1.1B using QLoRAKaggle
Finetuning Mistral 7BFinetuning Mistral 7B using QLoRAKaggle
+ --- If you find any bugs or have any questions regarding these notebooks, please open an issue. We will address it as soon as we can. From d5a23346dff56bb1b7d930ecedd8bd1015171d21 Mon Sep 17 00:00:00 2001 From: Ritvik19 Date: Fri, 26 Jan 2024 17:58:52 +0530 Subject: [PATCH 75/76] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 958b11d..d1606c1 100644 --- a/README.md +++ b/README.md @@ -295,11 +295,11 @@ This repo supports Codespaces! Description Notebook - + Finetuning TinyLlama 1.1B Finetuning TinyLlama 1.1B using QLoRA From 2dbc350cf277b5e1363676b94e2767957dea0f51 Mon Sep 17 00:00:00 2001 From: Ritvik Rastogi <36080978+Ritvik19@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:41:49 +0530 Subject: [PATCH 76/76] Update README.md --- README.md | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d1606c1..55d9158 100644 --- a/README.md +++ b/README.md @@ -288,28 +288,51 @@ This repo supports Codespaces! - ## LLM Fine-tuning + ## Parameter Efficient Fine-tuning + - - - - + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
Name Description Notebook
Finetuning TinyLlama 1.1BFinetuning TinyLlama 1.1B using QLoRAKaggleLoRA BERTAn Implementation of BERT Finetuning using LoRA + Kaggle
LoRA BERT NERAn Implementation of BERT Finetuning using LoRA for token classification task + Kaggle
LoRA T5An Implementation of T5 Finetuning using LoRA + Kaggle
Finetuning Mistral 7BFinetuning Mistral 7B using QLoRAKaggleLoRA TinyLlama 1.1BAn Implementation of TinyLlama 1.1B Finetuning using LoRA + Kaggle
QLoRA TinyLlama 1.1BAn Implementation of TinyLlama 1.1B Finetuning using QLoRA + Kaggle
QLoRA Mistral 7BAn Implementation of Mistral 7B Finetuning using QLoRA + Kaggle
---