From b8e57595082bcc5495b20fb8701afbaafbc9f23b Mon Sep 17 00:00:00 2001 From: Don Kirkby Date: Tue, 31 Oct 2023 21:51:21 -0700 Subject: [PATCH] Add reprocessing mode to trainer. Also clean up model. --- .../journal/2023/training-100_000-one-hot.png | Bin 0 -> 31232 bytes .../journal/2023/training-100_000-pos-neg.png | Bin 0 -> 31528 bytes docs/journal/2023/training-one-hot.png | Bin 0 -> 34444 bytes docs/journal/2023/training-pos-neg.png | Bin 0 -> 34192 bytes docs/journal/index.md | 48 +++++++++++- zero_play/connect4/neural_net.py | 62 ++++++--------- zero_play/trainer.py | 73 +++++++++++++++--- zero_play/zero_play.py | 26 ++++--- 8 files changed, 150 insertions(+), 59 deletions(-) create mode 100644 docs/journal/2023/training-100_000-one-hot.png create mode 100644 docs/journal/2023/training-100_000-pos-neg.png create mode 100644 docs/journal/2023/training-one-hot.png create mode 100644 docs/journal/2023/training-pos-neg.png diff --git a/docs/journal/2023/training-100_000-one-hot.png b/docs/journal/2023/training-100_000-one-hot.png new file mode 100644 index 0000000000000000000000000000000000000000..ac1e2c41aceef6ff65cce77af8d1abcb37e88f00 GIT binary patch literal 31232 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 OZCJO-@Y)*Z@c#kGCBe}E literal 0 HcmV?d00001 diff --git a/docs/journal/2023/training-100_000-pos-neg.png b/docs/journal/2023/training-100_000-pos-neg.png new file mode 100644 index 0000000000000000000000000000000000000000..bd649af871797e6ffca0fec18cb616bfb3adc108 GIT binary patch literal 31528 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

N<>xPAyZ&U94|en>6vRC!n;pzK=_y-;4B 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 z z!9fjJ5VEtRKY=k}cv$@*(4n{co%J8A4vd#*vdmxIo^{@Vwmb{qm_Wy^A}B~B&r|5h zen^chL&Ty~BBd!NiyjzyKaT|7jHpPiuLnO1`A?Dg6_qD5P#D-gg}a?U@qqk1G#+ZUe^P-A;`-=8u7RVKSB>hGlBF=L?| zi(x$eJ?4*ZE1wy`*aR_f!|{%kJP|ERyEU4b%QMEE9O6%qQVL?tN>Ev1s}7>I zxjugEJ^c;cNM&dsJ!N3u+c)Pwnh|aLbch7ScE=)a>e2h|pPJ!?+m9vdIce6N)~H%v zf_hSY2sYEWRJ^L$D(?Jvel7mz!wIT0&xi5%U;X!UVQ_54c&C^_#_Ffn3Hdf^N`K1L z1gv&AwjX)VPLCj~j+)>QklP*uj)9q_U8>10@=YxsYlq0bOH$ETq%Pqj4LB8~1oqcj zkUMvbeAVw^I1{wzES|vku}ae80x3Yfgo9fI3>K33KWss@CU8K9&bbfyhJSmZWNK9= z87e9$9NU7Ykb;B58ffKb%ytL8AUI?EBI1uQ`x`=YFoY@avCdc9FY6@1z_)bYk6 z3S((X2YQ>JW)K5Z4Fg?c<==_;d46aHV~+ssAnl+URT53dO@4lWE+cuBE+&7T9O={6AV3hlsbwh& z6rd$q$eV;3vGsN5#p_f3Lb2AuZn(>c{nQ!Vzmxs=Ki}ENM?Of14Ws>AM$`S!cGY-y z6>+MIKF!{_Cd+MWVBbVYe1+{+%h2wEqK@l?soFjt2 z@1n6hmF8#h--?uf(<-yc^*s!6bejJTg$_K8aPN<~|L9$=*=OYMC0p$EX~&+g5cbXw z|5vhd3{Gh&lLLp5B>VZUfNOm$4aI5PC9~KrvutBk2bD$~FcO2Y+9)2cwi()|T8l1wJb2pe2n0+^$|3NL$_oU8r?09wNU=0rx?=@pU6LOxrSjX>vbRQfp=w1w2uD7;b)X?gfI zLp@|lq~ClfgSAAhUjI_vW-tQ{w3G0ZdBA*jW`u#0DfvNe+U7&NySqDKN0!9#rY%`w zxKL~Onu9`ObU{(2l)^N24=0>D8PxF0=u>WSe^$H{Qf5tI%>A>xjFO?QTd7E#k(p0# zRJ-}o^ua5w?dHVjw7^)oq~c#l)BT81He-wzbbWw{>{bC@lm(nO0s*D8%n|@S!jodm zF9Zi?(HGTsG2DeXPEDWn)a^ZAbs~1A2LMjE+5j8bv>Odne){_QOQ1&I@|6J`MS?uI z!mch@p|}vhF@1?53GP3F*RJn6xWGX_cG~qM$d(riAf`dK6@wV#~?EvS&05Mz-&=l+$o_2@hQVCh(NlHoGOH!`+4=U{L=@|!tLU1NV z4`}HH=cIt%p((DPpcxJb_uB{5_}aBAPe~`<=Tv6zui^&U?!JmTZte4Nw4`IJkPhZ5 z_5P2z%8scl1?nFdC~#ivSZkP_nPHZYX#I8qTDGu(&?a5No7ck9a(Q(%6g+2PQIU>* zM_wKT&M-lMK1|SNVPKvCbjjvGTPPNIEe0Af^2cp~$b{(6`ubK1kbu%SEp}A;ArH*Z zagxz|dgN%G5IJ?V6xUU0?!@-wcrk;jVVf{)uOsYwg~U=6oX@h^{C|}9<>6HJYumS> zGBlA?rVORQP>M>1B&moZA|yr1JVY|f6h%_WR1!%@NM=eh6cL5UOd%OdA>liJdiFEy z{p|g|$NPQ%yvOG_o-x+4*1GTOcU|Xo4yLO;(EmXcv^HxBpTlXenL# zAHp=-TLuQIgftz{;CxkS6ejtCc~X9oudr#(Y8{$m+&?&JlouXZU99~_~>z4PIN5h0O+rCSW^k|d4Lzt#8L>egJlX3adRy}dm;%N4REVjR=~ zWeU6{PJHig1dD2EJy^;Qva$&~2m6v5x!8opXFq29NsY8zE-NiF$-}C{&!)%igc}@J zpu}{Bd`s(XDQ7ve(u(=O9%aL=Y2|&k`JDW}C_;&<`4a^R#|OTZ|upwuGotK0S`i)5>D95w5B-HOkR!iQ@Yx|S6+<#!rnT6hsLGShYlyxrv}L1k%KUgCxHeucMx=8cT?9C6%pao#>k^d1S4Qy z5&GomH+NssRs5KkprKeD)tvxwn4vE=75rtJf0I0 z;_5_AA*%Ca8_^0t?FYvWMJ1(+gVMsn!o=x=SVBNtcp)}cpejn{5-zwqC`G-s35Swz z38|@E+qe4MBeNy*hkAWi2DKG_p<~>;x8nKe$`fSMIkeF1(qPoWMJeE4?pKUkQV4E* zy^cVXWA_T^`3c$iQ)Ve_@J_Prx(onV}vFUb9cZ(C%B>+U3t ze}5r?HpD9}DW;~Zf^oyB$@wSxs{JhJIrebUXISzRNGp~QX6Me5GE{-o-|KQu0^S)*@9huwq@kNDZA<5W-$~E>I)nQo0sX;utY$$+pTCZ`>{Qa>X`LG2 zl5JcPbZRQ1^T>>`b>?A?yaWXWBZImKLBiYmi93(zi#=%QHX0OC@ZKW&hThf!Db(*k z48!Jt9_}?MD`?i%s`=yyGzt7D*g0`vkig<%f^#U8|RnqSxBKks*+FX`~2cH+~3@guZJ*0OmUG2Eg& z@Sg&*vePv>dlV$9_6wHysam3G)o=KsbU?cG<$_HK^lMU1cHBDl`c6}kYgn2r`=sbS z`J*usXV3V9y{nNl4;8r+Qk>k?TIEEspcJ<)YHw0qU(^z{mfE-knHvXE%g~OROJ4I9 zN!v#-q+30fhCMk=sah|^-js32=7}qwS|nA)E66{4s^aon0!JWLumB13pDG0RZy1M0 zd%;*M9fgx)-YqGIhiSg7Y6CXu8HGYqx*Z?gL~QsZm+4lmIVLnSXJN*fAv27b0XQka;-ew%6dx->yWqq_Q3N*t`?J)WaS28Ih*gaGh)|oor3BjG~T}2kPmJ=r} zeZ}ycrCE%YE$a$zG_3l`>dd@#6LYF$H~W^dX8A+&mX_LC6e$;j7bl0#3Fc9=<}+!A zWuuwQo)lgf_|F_BTxhaY`ZdXk&PS))F&Zc}{&7^KU)q7w|HzzN%R=(OFQCBK3p-59!zd4wXw1B^Y`D0N@tcUqoA=Ufz5b% zOB|!3gNbL8q))?0kA?Z4v8>@UsCUe)|UxbXXqYiU!jjT(-;sM#x8 zB38Lu+{(zuc;R|+dyPBcv8x|6DDPF!_?-AH@_Sd%j#6-j1L3a0K$yaM58a#A!l7dJ zZL$PflB-JbE0(a}mj=-?bD;n6BE|6NZp}AbN z2xspq5oVvQvxoM7_h3SRD?++QwhnNnmQ8v825ObqeGW{@QcoHoO z`8ToP?ma5qZ{2jHaCm3(=tJHQ>?T*jj(A`i&5nq=;5B06r}C;^rpV!#qOO+N(M`Pr z#+Ca{qkltZkqRj!c@X}FwI6e(f~mqJuY3Tc-UZ7JrQx!TnW-wq37mb?c3DNt!)VNM z&$nlH`d1B}?lFFDbj9!fRUVVa_7G}-bqgKmw@lz;pMp7dD`=FKDEjyCnE8^w`e`L% zMC156<(U@Fgj_CuKZZbklrj+O7evY~WGSC!9we?OiWRB-rcz$Gya%1@@TGxK>_ z>gGy?$UE%0N^8%!uq57a^7c!=+?&2aCXVBF2c%_NmMm&B{?3q_wKyX-BquFWMM0xS zLx{!&Mliv*ZUy4DjCP-yhLDF@{m`K_>kfIB?~SJ7ixh#1hz^6MG?^PMS;jTzHrtL*0IAY^W^=I@CL`FoWk5 zfdc0);+YS73exx$`>{y0s6ux7NUeOtZtEiHmP)#WoZaKN5XqGTVjP#>0dUgnD35C) zlDS(lcD*zH-uu3m=T=06{JPK;Io}i%eDUdS1iQMbs*0juyNB~SmRN{2qzPc)Fv9?) zpxJREwwT#fr`<<(j6LSEa#4rSitH;ly#n%2^cRF(#K%WN0V#N&*A!h*U{qZ%zYxw4 zN$2{ioZAGEV9kE&z_`Q29pHPY^@o!r&~Vm9z*K`+n0 zWn^L1D&sC&B~hljxV5#-&i6Ccg8v|Q=%RWuMI8(^P3w_g4}Hn*(0gaYTI1*VK6dcg zU#`ECKk*o5HrdJk^xPhJI}!gKK*s?XkBVNtOep2pqoARSy@WKE2C$Cf8a<_pgp=0Q z#T-0zQTK??_+W!Qsr#G#8_zkq3P)_eKkTyMK)^sZjdE*Q7(8-JR5W7L6RI=Jv;^H1 zYI$FtRL5;|y2sKh=yspCz|g|NSLc%r;;#ybB~f49p87>y`rh?cCN%hlu2FwCD~pT< zx-fK#XbrV;JE69NbB|_{8ZeRY^bA(3`6gb5Lko*N)do5~-IrIrGgoM#-tM8GMeP&z z@u{71v@t2hF>*&wkVgtR^y%|bwD!BSwU-Nv2ssFRhf9aS`^P5Ma0N8sHx0wJE!{KZ z&*)Z}I;6h-@XBe^r`fulBJlFQ0wsucEjau@48^}627e^a^q87}AtQi3-e z(!};iZRHft%z}h@Y4gDK)8?nnmwsnQH)X5N$WoV!RvF5yWZRF>)oHpd!XwvLwagu8 zwiuRWq38cr2^)iuK*8S1JrF1%1>- zz0^g0-t3=yW}@Jo@g{Ad%IeCuG=UEsE2Q`n^YJ`z0eM(?b}@^@-odl%)>-L=dsjM8 za&VS8Wp%P^D8OY^%Q^+yvwT+vWz=mi9*kLPmy#5-%aC)_Y9L_Rg5ys51@2cy5}V3` z{5aM=JR+xHB*)IQ;-}8Gq7)y)9M?D=_M=^~ElV>)>`!(^LPRp<$(~q{<@N zT2(T!Y9#Ha9Ig3vJWbi+-}5ZL&j!%R6yWYM%XV1@-dfif5b*9sE%0ll!^g(5t)L!X+ z4JKT+sTo(Em&z~XjB6}Nu@!fCmR!(sJ?H4m8EXgDYMn3 z<6E9BZxdWw$29)+@D`NuuJ&V}wmA!NjwCozcegpLnK=Iq7?hob@da7^!0Nn^CELX_ zKYFtPh5C!gYCc8E(%HdgfB2oWw>Y$kXg$F}L3(jYBm3zl`|b}P+KKoF;%j1%Np&hL zgNBuBhZ`3R7PT#It_QY#b>C`IZ*f)|*0h|%rBip7O*vW~b%Pi@XX{V5KShct7qqp(p5Z$=}etl2Y zukqjroD0Dr(ZOJV;mM)FY6gmO24?2B7T1*G;Hf8PXJ?mOx8jdQTKFG}G-DW5E%5Y; zquupBC;CIKM~7>~F40geZFqI+RlF#x@t#kxvKseO{P739u)#>3bYY?jpFg9;;XkBe zu2xie_-CJ`8I4rPO*2l`Isr{p>Z7e>#1@N-vmKzEqT*a7_yGpyow2cbhNjpox$63L zwzX_b4ULTpe&X_93o6YmtvqMD zm%mFEE44QZxT-EvwYsOXp-z~qAi_U8vN1bc(=YPK($}h)SCl)>TK$Yk3S_OS@3wxV z-aKjg(Ak1%Ou4(KDK&A4m77(fBjY&1HJpbE(4db$yE`~a%!&SNa-t)NLCGk&R(Yx6 z?565LUvZwKN4I66_9PqDQR1$fS@KP9@< zAeriClQUGNi8@RhafH!&<2(+XdHg%td^JPPEn|}&KV!;-0|RFS7mT8a;?&+9+K zL&=$~L5i_Ep;bqF;L@hNMdQqGvboHzqYu{YR|yITtIDEod+AD4ykcp~iMu^Z z1*RTyd~z&VdoVOcTWF^Z%N4a%g4Zt$)^!-H+Y?`!Ic&l&yIms9CwceOPxIlg7TSN{ zFdNsdy=_Fh~{n2!?&~~C^_1-+)06?Yqls(e39gk-%?sA6+(NK-L@f#EmhP1*nkH9?ZfF4DW2;3V>ePd$Th%9 zpqp^2>XuZNA}0$<4glR)v{jJM&m)e?KYzNk%x{Ih><-{~hDD3!@v45wJ~t9G=%}vF z3MWN_lP7&(0-%|ws;jGuUF=eP4A$1x9Yco?y3|Yf8v}Q-Nw+^`F5+`=&fm{ zF?5NfsEgup*>+OPAafh(Q4w304|@-@6%*MvMusQLBO~|Kw7jK}(UpwRQWib7OJhZl zILB5&!MQ*eXer`vb~M*6;jqkW>96zOynQQ1EE4bDjfQUuu$F3-PN>VgHGaId2!z8P zXdVDjg!S{6qv?4LRiTjP8tUhe`-~SnlYyIzvU@_p|6Hy7WbYdkrHJYD@o%?WByf`K zR@4`J#4MhDC|VJ9ym5}H(K1u(csZ||v=W=X)@JMKc?vMD*mm^_4KL3YrOndy@_JA1 zX$kFlY;IJtqI`CE+Xz2h$WO_$+IRIlN>3L9eqr96%@W8Vk!X7ho+x7lA9QcjhKxX# z%gYd?v4(;;nLzB=Dc)Dt#pr*wQFncHQpnp~72xoCKbD4RNMTJ$8=e&ua*aH9O=ie&(^l<~?-<7gjf$U%&Dw{>pv=<`bI%ST1B+chKe+6wpw>z=~m? zJOcYq;%=B&qX?n0CN#{26(t<{qV-{Kk|dRsGPd2mc_|jJ@T>$~{KK}Lrj}`zBG26q zy|_DUohr9^kFvP^!Dr8R&e@|phig!VE4etO+t}X9g|8+y@i6Ujz}$eiKV98H&6;FA z&_2(%%ePj$3m;Ho(SE_*z#{Cvr#{E__2AugyZZyBvaj1N^ADfM4%VEVo5D3I`vi7u zWNjp-o^{PnepP9=?+zOFhz8wg|AIN_A9IUq%IWL3-t~>sxviaiShr(7M~>dY9gnhKBZ^7UnpOT9!chUY@cOlyVqVlLpB6#k7CkOqm5w1 z{)h5_ZS<=M31)byC)Uixn^`BmIb36Z1D8hcfaZwyuH?gVmcetwC&sQ8N!!Rg*L7gB z7D`&Yb;wV~-+@Vdj7JhjaZhXB$p-6h^i*`(tvNc9y3Z;anZVqsDc|j4nfyV0m63Fv zKEn@U%nQ>5sAVZ?t5vH4PPt(W&-JJ2KxYZSmfP?1qC~dS6COE%4wuBU?c*13O=r3i zhWB)Z<2IX#xr5i&2cyyfQN8+znYi2(j7dD&vS;(Wr4ic`t6%NB8O<-N_3WAYv+xRy zB-CZN?(xFK9fX^=ExPaED@H>@Bk_J4_EWi4I_oZEMRK)Tc5>f=uj1K#DaXf$r(e8d zAmEcwg5$W*H&NC%#VIG5PsC$L`NZi^US|R{Z9UaaAEUit4iG$<){`RipT9(Ix@3CbK`lW|h^|0}6J`jk} z&Zv8tK-WW#6%!>dvULNRV_2`Bp3}0r`;q-38Zw*T8f-a~b7+aw+<-L>Q}cDcif?ZF&?+^j(OX*ZIk}FfJji+ z;pzqKQB&Udf#R2O7p}jz@mf*cVMZ<8)jVb$ z_nV>)MUz?Lr=t)jc^0_D;0n2OUAgAPdoI<(-KULCE?o23-CeV=T#szG$Jnc@&Zn_{82H_wt(1~xX0 z=aoda8)1-iH8v~sTI-iBC9C5OzPP(+;MwPakKUn^Sqe7$)^)O`+w_|XV(RLARVjr# zwip{+P0OHbA+(m6?AGa;7Z*v5I4*Hs3hvzVtDjeK><)?5S68P6;09ZL9+e33gupGp z*3}jynr0`Z_>o#xAbXD;!T8Y}#wBm8^orBz?La#He6|LjX zI_UMGU!E=WbZ~IIB3@(9RoimzJ^VD%+#)qqm1JhJJ9aC%(lICJhNdKqIM6v%(Tl`U zU(p%w?ETAX>t0o-*b9uBO?k{=nSntc>0i&P@>!l*hIWJR>Y0nyQo28#WCT{4I9##; z!uf8~m$a|VJGz!~i!9CcwwBX9RiNCgu{qIo%@s7V&)&XG_l<-Jm%@Vc3j8%KyK)Nh zEPPG^fwlQ`R#a5*l5(rw{;HC?QE5~&!nGuAs%`jnMgx)ihiSK&H*CzG9L(G1FvtZ% zvt>rgw>TM6I>tk?`0cErHRIAMvNs4j#QYUYmz1#WiYP@*!ml0dinxNKvp^ zSeJExKiE2OR*}vQ_R1}p{^}f03D$&ed>4%RXF)6gzl#&nIA?QZd^O|ft;dHuUc8(* z#W9AB?3G)$lAUkCN($&<-Rw!=cfVV69ZfR~Xf9s5WS_F*N3Q@z@=yAqFp86vebNoE z9A6R-l^COW85X&ykpHrWHW(F_B|L2XY7bWbyUoc*&Ly#<;>Y}mQ>rLr@btiXwGbZD z)IkjmZ9OLxOf7*_kxiYmTMiL;N@-t7q8wKW8hrSJ`76(YLY&KCr~T272fYUGFo_S ze#0b;mBjEGHkkDD<`EZfGReU&8f)W2$0y*&a2)Q~vt$VPC1C>+4YWY}iA&DIfTX0P zRzpC>#6Jsegm<(;Gcq#ta~?Il$9uyfp#jH-I#UTO65u`+-6R;I1Vd7f-rioOwk6!$ z$yz)VUc!*BEUW^F_Y-z!6$833HAM0O;c}7f_}X>r9KF*~fB6$96YYeu-(Lw1K96z* z^Rr$HhhM{zkPEhUNw|u`q=1<->_J5HJWrK_J-MEZ2|nKZ>(?`Zi$TFtlPqTmr)``EO}fJF z-5uDjzq7a$5a9jvse8_&Hn&L;;soE-^|d+^hcG&eqQ=IYqAA4pEd4&e{Nop$NxqcI z+yv?04M1QW{UEV8vMm%Qo3x#A4gWey;KHM$5L)C7Ace%cP{Z%dQtki%CqV!kPZTqd z)))?TrGQlN4gFn+G6we`vO1K?Bp zz1WKzX#CaY*Ss<^+_?02!e4Q_!(ag19$OTGii;KY#?9>49)tlFaeE`yWaQk1eOoGw zQb@)~N-H>h@{8#MR_=JxEQZ}U$zUOoGZ@NGx8_UY5RG&24<#j@FL4PYFNHU-dF<*C z+WQI%PWTd+Ugn-G+>Tdp8QzIn*(tb%z&tq@(zFlNL!)hlD>o^h{F{XTb3OSl%FX}6 zKknO4n|-2$>70`jJWPo(KFlm#3?|?_N(?1&pAl#s$3k3|JN8}J9y%Xzd2xFRcjO@J{HIrR73mIP|==RX=M84kx&B3c+-t!`+QEE6!ssBXfwg>xT~? zbYzZ^E5mS;6Yc%ONi5*bVz1q@1%|r#C-^*C<59i6rwhJNi5%+$*0;i?q)*vQ|c-9w2oA7;wjg3cA79ySiO=@r5SF1k*RTP|hPm4#C-?m#l z>t&=~@(XDB%}st5YU-1t)z-z0AMe}>b3QxJxJe)gUWnM~>S)tC7~TH`b~4TSw)1~p zPD9G+h+?4q!w1}=^n{B8X4OZ*-yLYbfpE_!F0L`Qee2d`u!kYe`RI&!&P8d){cb-5 z?C;&_mVY2Izg6=;XyF=b*^s=oTSJ2lJRyqu1L_%;nVy~|c@A*Ee%QpmVg+!JnMs}= z*a^Zp4=zZN4=)3{0?tevIjL0l88_G&k55c!YQq&*5;U<2i_nUX8Q*v5N7^59{L2}o zi8E@0y#Xr&MY@D)?I3p5^o;v63Y>4XtX*(RS2_sN4u^=Qy zS_tjv@FMM<5wGG9n9;;w_S2_N#CjZfI`NprpY;kltr8TJUq7`*YvA8jTN(-`!q(sW zkGR0@^F>vaZ(g31@B9^>XgzwrwI?5Y$^&?Wm=WSy27}KFoQmeuHE<6EG2}N=_LWKf zFEZzb4RS097>;{aNZ1PI=ZJri9u0#{W<%=nT_Nv()!sUPJ#8&;{;9?DR=)z`)zn;^%s9IaK35C62PN3?l|n za3a^|MvFUJonbOsS3W`dzq+OPG@2iqERo-}iCk?Fxuw{FsCsgR{_^lFeK1&B9Ez;Jq zv)}vYwl)xJ!~zSv$ObIyT!WxX0QZs>XH>xe>P``^;_AmHhlt-P;B3$EBPGXYz29uo zX3fs1k*n#7v5wUyhmRa_l{mWLm*M$;$JOnRk{ws{1#XSxb0Tjq`oZ4Jr$73Vdf#UV z!S>S{rypuu2jaN29~tfYD<^W<`jEc!Jx7k>9m!Dt=O-sNZfozC+^AiIzTPYnDU1l@ zTd;F+Dx%~HTxSM%_tz#YfhDKD%gAo*+n+Z#=j$CM?dj0V%1WOL7v|w6jtSMS*T@qP z5D>%N`Qqajj^xPlU)uu`E<$uJs`(WU+ru|Oi}F{-B9oTZJEpcSaCZ~FoP61aehlSt z`huVdG(VUUo}pOb1B|qtB+SMA^Zx}e|Gnp~98%^EqyK}5*s|qU&r9?uvpsLY7mtQ- zlSAZLkam-5)h4@b`*zvKBB02CR6yc&x*JhDS?XL#p(|ES!|kGo9Fl7IEDImaW&4x0 zHzR&cMT`Sfd&WEcU9h$uZaj7SIEV-h*){^Iw`BuC#pdt``zZr^RZMjy7*gQWpUAng zx4oUhSb;P4<~AEzy1DZ`a3RLT#u5`+X{^vwv$D3T@}gS#&5y<&?%%-Oqrc$p1E)^D zj*>|`{(PS~`EdO(8 zSV+PBZw}G_3%lBXLI>_ut?~eFPw-ic{0K=PNW;7vZTXIy-)CAdBbW>y{0W5MIZe*l zSqRr`5W409uti zi-@q`$Dq_a8je_vPO$fhL=L|j(3;~g6fdZMO=g@IVgE(g1wt2=Z?{|9>hxKJGz`x? z=aAw9@8E@U{ZqQRcI#xv+vx&0B$yBgPz0DW2-I{Ec}kIf1y{zujk~x-p1u85KnwME z>d4%pF*L*i=-#Y!4Gf}1b8u#Hp!t|ZAFRyGn9*J18w{JXZ7?SK!g3ZR`koNd8UK<` zq5BWLBs^`X&N!n$#Y5k&xl@o=V!>`?Y%Krx-JdHmny3>Of)miGhy6#C!fvu6Q|5j^ zdU|@R+iz`i`A@BXpa#wWhlU)S@HS}dX+h`$Hut5LzG};5XdWCu!o#Q&4{RH8LA3Yw zGWaW~$Cj1MLS0o+sBCK8+6t~#4Mt9KU?58cOGVxjVK}$2y#UPECD77mftVhc0-n&=w?W38LFxqk6MCWaM9R7VxP(<&fHe zvJ;bA+AH(R@bdo-LRdhdRUwIFgm!k$(eVzd9LXkvu9k(3jh;f@S1BezF+gI-BzNCf=7lCH-kpM1|o%{;b>_% zaZZHEx^BnvuO`pI3ZJ)Jf<|BYgTL)>t=CLb09YVwvCL7f(vbSg6t#S)FPPz;^t@T9 zgMNi8sCoEW!4BOOzWyep`*ZX^M+e&44l66@wu;;Qj`t4P${)4SGC+YvD8kL%u z(=EnKhP~l)0BvBxF)%U7ySU{4jmEoN3PooE>USZhEc#?jah* zPd9jlo`=1=iMM|ze{io1ieVD|Op6=&48}mW{v{dcMxGg?=215{SyZ^x6D1d!#@sQP zl2m09s!fi{8#iuXP*G4*3qG&=ek0d*JBH21uL{AjX2Gv z$FIiZyTGj{LvCP0-;X5V^(3eb;$poX8Vb7l?|8EX8Hz1EID+W?}~ouX*F6-D5gQbwtrq zM0TuAH*Vb$!EMF7V`}soi%!EZ^h%7BH;!gTPu@~3(NJc{*Xu)a>^@zkvM&1D}>#C(AMrh=$vfBzQ`3|80BAnRar)vEM50 zvPq;b;fC={OA*|;m{{bJ&oGE zTIv*p0%^c6-0~SOjKm?}>-77_>-62H?1lBR7o)+MMOI%&EpTvfK-;n+rRG}$EP&x2 zJr}x;1ps?<)3)JsOifMoK=#x<)ms-ad*PZbM5-AiW5BC-@HqF231mH)hN1Lx{2&>< zNRScYWJn%z+Nsw(rMc|TB7QDSzmbN7dVtB6Qil3xT3x=XkeCnT@$9m--2`?lGc4j! zM!tSMdbBjkcmGG%k&nM~Prt z!GP*bl2X0lt=+XHmnUg$J>?DEPhUA=9GFP7GNSu7+}But91m6mnQP#?UZ;LEXUm`# z6a*9O4q%ws2Y`aT@B8NZjG;E{v}g_WuMyo4iRb}uR~|@=50Do`hwrT(IQ1Y&m7l@W z;BNCZ^i6&N9wfT*e+F>O>W1-QOPt;8=f~rRv`2~MNYud6aoreNz58jAiV7O>!}^5^ zwb2Ch#AjO9WNc|^c^6rSbt?Tdt77JsVD*Ng=d=jLi|YIcVw=_p9FX|<2qHI(K)v3A z83e&CM?M8qR_Jg1fVK*3*l-{P6biHIC$7#Ylg|-#jnmj^a`UE58<8E3w+tuvaqti_ zoZoAp7hp-` zJSNvRkr@N>aw-ek;Vv8H_QT|+j59mrUS)usgF`}2R)1Z^@5BpH&v{geM}Vv7k*-)! zHZ#>WgQ5)xj%*i)WKc?r@Uny%Jb4N2-Ls&e;7Vv{eA82qGO;&df;%?8o8;XNBl4{+ zYXL=aQRK$9<26&f{jCLgrB&Dbdev-jqD!pB6j+F9;9I67aMq~F$;r^2#0hgBh4QDUu;aqD$~r+D}4K z#{?)EaC0Gg0boEtH#eP*^!GF6a3&8;unoxOTDOosS5lIOB6}NT%HDy23W;eUARVx^;3x16QF3Q zi)nNW*N=D2X|H7FrR2nD7gN#8X&9)30Tey8R`K`mV)3A;5(YWS;{-kVwx?oGj%5AV Sd?|^-*S_7V3J>KCJpT{RB4Tv_ literal 0 HcmV?d00001 diff --git a/docs/journal/2023/training-pos-neg.png b/docs/journal/2023/training-pos-neg.png new file mode 100644 index 0000000000000000000000000000000000000000..2b3b5ab357e526086bf66c8ea8965b43864a851a GIT binary patch literal 34192 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 G_5T8AG#qsR literal 0 HcmV?d00001 diff --git a/docs/journal/index.md b/docs/journal/index.md index 637cfa4..f9a0834 100644 --- a/docs/journal/index.md +++ b/docs/journal/index.md @@ -36,10 +36,56 @@ Restore the tool to plot win rates between different numbers of MCTS iterations. Switch MCTS search to limit by time instead of iterations, since that will make more sense when comparing neural network with random playouts. -### July 2023 +### Jul 2023 Resurrect the old neural network training code, but start by going through the painful Tensorflow installation of [GPU support]. After that worked, the old training code was broken, so try basing it on a [regression tutorial]. [GPU support]: https://stackoverflow.com/a/54567428/4794 [regression tutorial]: https://www.tensorflow.org/tutorials/keras/regression + +### Oct 2023 +The training code runs, but doesn't seem to learn much. Here's the loss function +as it trains on 10,000 board positions for 19s. + +![Training with positive/negative] + +Several tutorials used the one-hot format to store their board positions, so I +switched to that, and saw no improvement. This training took 17s. + +![Training with one hot] + +Training on 100,000 board positions seems to give better results, but it takes +about 3 hours to generate that much data. There doesn't seem to be a noticable +difference between the +/- and the one-hot format. Here's the +/- training that +runs for about 2.5 minutes. + +![Training +/- on 100,000] + +Here's the one-hot training for the same data. + +![Training one hot on 100,000] + +The next steps are to see if the model trains better with more layers, and see +if the model can learn nearly as well on less data, so we can spend less than +3 hours generating position data for each iteration. + +Here are results from learning on subsets of that same data set with both the +positive / negative position data, as well as the one-hot position data. + +| position count | +/- avg. loss | +/- time(s) | 1-hot avg. loss | 1-hot time(s) | +|----------------|---------------|-------------|-----------------|---------------| +| 10,000 | 0.159 | 17 | 0.156 | 18 | +| 20,000 | 0.134 | 31 | 0.124 | 32 | +| 40,000 | 0.128 | 61 | 0.139 | 62 | +| 60,000 | 0.123 | 90 | 0.119 | 92 | +| 80,000 | 0.115 | 120 | 0.115 | 122 | +| 100,000 | 0.129 | 152 | 0.121 | 163 | + +It looks like we don't get much improvement past 50,000 positions, and I don't +see much difference between the two different data formats. + +[Training with positive/negative]: 2023/training-pos-neg.png +[Training with one hot]: 2023/training-one-hot.png +[Training +/- on 100,000]: 2023/training-100_000-pos-neg.png +[Training one hot on 100,000]: 2023/training-100_000-one-hot.png diff --git a/zero_play/connect4/neural_net.py b/zero_play/connect4/neural_net.py index 84d0043..ccebba4 100644 --- a/zero_play/connect4/neural_net.py +++ b/zero_play/connect4/neural_net.py @@ -5,6 +5,8 @@ import numpy as np # noinspection PyUnresolvedReferences +from tensorflow.keras import optimizers +# noinspection PyUnresolvedReferences from tensorflow.keras import Sequential, regularizers # noinspection PyUnresolvedReferences from tensorflow.keras.callbacks import TensorBoard @@ -12,6 +14,7 @@ from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten # noinspection PyUnresolvedReferences from tensorflow.keras.models import load_model +from tensorflow.python.keras.callbacks import EarlyStopping from zero_play.game_state import GridGameState, GameState from zero_play.heuristic import Heuristic @@ -20,7 +23,7 @@ class NeuralNet(Heuristic): - def __init__(self, start_state: GameState): + def __init__(self, start_state: GameState) -> None: if not isinstance(start_state, GridGameState): raise ValueError(f'{start_state.__class__} is not a subclass of GridGameState.') super().__init__() @@ -39,38 +42,23 @@ def __init__(self, start_state: GameState): self.checkpoint_name = 'random weights' self.args = args - num_channels = 512 + num_channels = 64 kernel_size = [3, 3] - dropout = 0.3 - model = Sequential() - # regularizer = regularizers.l2(0.00006) regularizer = regularizers.l2(0.0001) - model.add(Conv2D(num_channels, - kernel_size, - padding='same', - activation='relu', - input_shape=(self.board_height, self.board_width, 1), - activity_regularizer=regularizer)) - # model.add(Conv2D(num_channels, - # kernel_size, - # padding='same', - # activation='relu', - # activity_regularizer=regularizer)) - # model.add(Conv2D(num_channels, - # kernel_size, - # activation='relu', - # activity_regularizer=regularizer)) - # model.add(Conv2D(num_channels, - # kernel_size, - # activation='relu', - # activity_regularizer=regularizer)) - # model.add(Dropout(dropout)) - # model.add(Dropout(dropout)) - model.add(Flatten()) - model.add(Dense(64)) # Remove to match paper? - model.add(Dense(64)) # Remove to match paper? - model.add(Dense(self.action_size + 1)) - model.compile('adam', 'mean_squared_error') + input_shape = (self.board_height, self.board_width, 1) + model = Sequential( + [Conv2D(num_channels, + kernel_size, + padding='same', + activation='relu', + input_shape=input_shape, + activity_regularizer=regularizer), + Flatten(), + Dense(64, activation='relu'), + Dense(64, activation='relu'), + Dense(self.action_size + 1)]) + model.compile(loss='mean_absolute_error', + optimizer=optimizers.Adam(0.001)) self.model = model def get_summary(self) -> typing.Sequence[str]: @@ -109,20 +97,17 @@ def load_checkpoint(self, folder=None, filename='checkpoint.h5'): file_path = folder_path / filename self.model = load_model(file_path) - def train(self, boards: np.ndarray, outputs: np.ndarray, log_dir=None): + def train(self, boards: np.ndarray, outputs: np.ndarray): """ Train the model on some sample data. :param boards: Each entry is a board position. :param outputs: Each entry is an array of policy values for the moves, as well as the estimated value of the board position. - :param log_dir: Directory for TensorBoard logs. None disables logging. """ self.checkpoint_name += ' + training' - if log_dir is None: - callbacks = None - else: - callbacks = [TensorBoard(log_dir)] + + callbacks = [EarlyStopping(patience=5)] history = self.model.fit( np.expand_dims(boards, -1), @@ -130,6 +115,7 @@ def train(self, boards: np.ndarray, outputs: np.ndarray, log_dir=None): verbose=0, initial_epoch=self.epochs_completed, epochs=self.epochs_completed+self.epochs_to_train, - validation_split=0.2) # TODO: Add callbacks? + validation_split=0.2, + callbacks=callbacks) self.epochs_completed += self.epochs_to_train return history diff --git a/zero_play/trainer.py b/zero_play/trainer.py index dc7cd1f..b9344b8 100644 --- a/zero_play/trainer.py +++ b/zero_play/trainer.py @@ -3,8 +3,11 @@ from datetime import datetime from itertools import count from pathlib import Path +from statistics import mean +import numpy as np import pandas as pd +from matplotlib import pyplot as plt from zero_play.connect4.game import Connect4State from zero_play.connect4.neural_net import NeuralNet @@ -16,11 +19,43 @@ logger = logging.getLogger(__name__) +def plot_loss(history): + plt.plot(history.history['loss'], label='loss') + plt.plot(history.history['val_loss'], label='val_loss') + average_loss = mean(history.history['val_loss'][-10:]) + print(f'Final average validation loss: {average_loss}') + plt.ylim(bottom=0) + plt.title('Loss Function During Training on 100,000 Positions') + plt.xlabel('Epoch') + plt.ylabel('Error [angle]') + plt.legend() + plt.grid(True) + plt.show() + + +def convert_one_hot(boards_path: Path, boards_hot_path: Path): + boards_df = pd.read_csv(boards_path) + np_boards = boards_df.to_numpy() + np_boards = np_boards[:, 1:] + board_count, column_count = np_boards.shape + hot_column_count = 2*column_count + np_hot = np.zeros((board_count, hot_column_count), np_boards.dtype) + np_hot[:, :column_count] = np_hot[:, column_count:] = np_boards + pos_hot = np_hot[:, :column_count] + neg_hot = np_hot[:, column_count:] + pos_hot[pos_hot < 0] = 0 + neg_hot[neg_hot > 0] = 0 + neg_hot *= -1 + one_hot_df = pd.DataFrame.from_records(np_hot) + one_hot_df.to_csv(boards_hot_path) + + def train(search_milliseconds: int, training_size: int, comparison_size: int, min_win_rate: float, - data_folder: str): + data_folder: str, + is_reprocessing: bool = False): start_state = Connect4State() data_path = Path(data_folder) checkpoint_path = data_path / f'{start_state.game_name}-nn' @@ -61,21 +96,37 @@ def train(search_milliseconds: int, players=[training_player, best_player]) search_manager = SearchManager(start_state, training_net) for i in count(): - logger.info('Creating training data.') - boards, outputs = search_manager.create_training_data( - milliseconds=search_milliseconds, - data_size=training_size) - boards_path = data_path / 'boards.csv' outputs_path = data_path / 'outputs.csv' - boards_df = pd.DataFrame(boards.reshape(training_size, 6*7)) - outputs_df = pd.DataFrame(outputs) - boards_df.to_csv(boards_path) - outputs_df.to_csv(outputs_path) + if is_reprocessing: + boards_df = pd.read_csv(boards_path) + outputs_df = pd.read_csv(outputs_path) + boards = boards_df.to_numpy()[:training_size, 1:] + outputs = outputs_df.to_numpy()[:training_size, 1:] + else: + logger.info('Creating training data.') + boards, outputs = search_manager.create_training_data( + milliseconds=search_milliseconds, + data_size=training_size) + + boards_df = pd.DataFrame.from_records(boards) + outputs_df = pd.DataFrame.from_records(outputs) + boards_df.to_csv(boards_path) + outputs_df.to_csv(outputs_path) + + boards = boards.reshape(training_size, 6, 7) + + start = datetime.now() filename = f'checkpoint-{i:02d}.h5' logger.info('Training for %s.', filename) - training_net.train(boards, outputs, './logs') + history = training_net.train(boards, outputs) + training_time = datetime.now() - start + print(f'Trained for {training_time}.') + + if is_reprocessing: + plot_loss(history) + return logger.info('Testing.') wins_vs_base, base_ties, base_wins = base_controller.play( diff --git a/zero_play/zero_play.py b/zero_play/zero_play.py index 869b5a8..bd8556f 100644 --- a/zero_play/zero_play.py +++ b/zero_play/zero_play.py @@ -21,11 +21,17 @@ QSizePolicy, QDialog, QWidget, QLabel, QComboBox) from alembic import command from alembic.config import Config -from pkg_resources import iter_entry_points, EntryPoint +from importlib.metadata import entry_points from sqlalchemy import create_engine from sqlalchemy.orm import Session as BaseSession from sqlalchemy.util import immutabledict +try: + os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1' # Warning and above. + import tensorflow as tf # noqa Triggers Tensorflow warning messages. +except ImportError: + raise + import zero_play from zero_play.about_dialog import Ui_Dialog from zero_play.game_state import GameState @@ -182,10 +188,7 @@ def get_collection_name() -> str: return 'Zero Play' @staticmethod - def filter_games( - entries: typing.Iterable[EntryPoint]) -> typing.Generator[EntryPoint, - None, - None]: + def filter_games(entries): yield from entries @property @@ -225,7 +228,7 @@ def load_game_list(self, game_layout: QGridLayout): if child.widget(): child.widget().deleteLater() games = self.all_displays - all_entries = iter_entry_points('zero_play.game_display') + all_entries = entry_points(group='zero_play.game_display') filtered_entries = self.filter_games(all_entries) for game_entry in filtered_entries: display_class = game_entry.load() @@ -422,6 +425,7 @@ def on_cancel(self): self.ui.stacked_widget.setCurrentWidget(self.ui.game_page) def on_network1(self): + # noinspection PyUnresolvedReferences file_name, _ = QFileDialog.getOpenFileName( self.ui.players_page, "Open a file for player 1's neural network.", @@ -550,7 +554,7 @@ def on_choose_training_path(self) -> None: settings.setValue('training_data_path', str(data_path)) self.ui.training_path.setText(file_name) - def on_start_training(self) -> None: + def on_start_training(self, is_reprocessing: bool = False) -> None: ui = self.ui if not ui.training_path.text(): ui.training_message.setText('Choose a data folder.') @@ -560,7 +564,8 @@ def on_start_training(self) -> None: ui.training_size.value(), ui.training_comparison.value(), ui.training_win_rate.value() / 100, - ui.training_path.text()) + ui.training_path.text(), + is_reprocessing) def on_game_ended(self, game_state: GameState): if (self.is_history_dirty or @@ -700,6 +705,7 @@ def get_file_dialog_options(): kwargs = {} if 'SNAP' in os.environ: # Native dialog restricts paths for snap processes to /run/user. + # noinspection PyUnresolvedReferences kwargs['options'] = QFileDialog.DontUseNativeDialog return kwargs @@ -723,7 +729,9 @@ def main(): window = ZeroPlayWindow() if args.train: window.ui.training_path.setText(str(args.data.expanduser())) - window.on_start_training() + window.ui.training_size.setValue(50_000) + window.ui.training_comparison.setValue(200) + window.on_start_training(is_reprocessing=False) else: window.show() return app.exec()