From f4af48b76565ecd9a628b95dce7c66f17693a3f5 Mon Sep 17 00:00:00 2001 From: Ilya Kostrikov Date: Wed, 27 Sep 2017 08:20:19 -0400 Subject: [PATCH] Add MuJoCo --- README.md | 60 +++++++++-- envs.py | 8 +- imgs/{beamrider.png => a2c_beamrider.png} | Bin imgs/{breakout.png => a2c_breakout.png} | Bin imgs/{qbert.png => a2c_qbert.png} | Bin imgs/{seaquest.png => a2c_seaquest.png} | Bin imgs/acktr_beamrider.png | Bin 0 -> 21391 bytes imgs/acktr_breakout.png | Bin 0 -> 19882 bytes imgs/acktr_qbert.png | Bin 0 -> 20963 bytes imgs/acktr_seaquest.png | Bin 0 -> 20287 bytes imgs/ppo_halfcheetah.png | Bin 0 -> 18546 bytes imgs/ppo_hopper.png | Bin 0 -> 22356 bytes imgs/ppo_reacher.png | Bin 0 -> 17658 bytes imgs/ppo_walker.png | Bin 0 -> 20720 bytes kfac.py | 13 ++- main.py | 43 +++++--- model.py | 126 ++++++++++++++++++++-- running_stat.py | 44 ++++++++ storage.py | 15 ++- vizualize_atari.py => visualize.py | 17 ++- 20 files changed, 275 insertions(+), 51 deletions(-) rename imgs/{beamrider.png => a2c_beamrider.png} (100%) rename imgs/{breakout.png => a2c_breakout.png} (100%) rename imgs/{qbert.png => a2c_qbert.png} (100%) rename imgs/{seaquest.png => a2c_seaquest.png} (100%) create mode 100644 imgs/acktr_beamrider.png create mode 100644 imgs/acktr_breakout.png create mode 100644 imgs/acktr_qbert.png create mode 100644 imgs/acktr_seaquest.png create mode 100644 imgs/ppo_halfcheetah.png create mode 100644 imgs/ppo_hopper.png create mode 100644 imgs/ppo_reacher.png create mode 100644 imgs/ppo_walker.png create mode 100644 running_stat.py rename vizualize_atari.py => visualize.py (88%) diff --git a/README.md b/README.md index 5e2c36a..157b968 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # pytorch-a2c-ppo-acktr +## Update 09/27/2017: now supports both Atari and MuJoCo/Roboschool! + This is a PyTorch implementation of * Advantage Actor Critic (A2C), a synchronous deterministic version of [A3C](https://arxiv.org/pdf/1602.01783v1.pdf) * Proximal Policy Optimization [PPO](https://arxiv.org/pdf/1707.06347.pdf) @@ -13,47 +15,85 @@ This implementation is inspired by the OpenAI baselines for [A2C](https://github Contributions are very welcome. If you know how to make this code better, don't hesitate to send a pull request. Also see a todo list below. +Also I'm searching for volunteers to run all experiments on Atari and MuJoCo (with multiple random seeds). + +## Disclaimer + +It's extremely difficult to reproduce results for Reinforcement Learning methods. See ["Deep Reinforcement Learning that Matters"](https://arxiv.org/abs/1709.06560) for more information. I tried to reproduce OpenAI results as closely as possible. However, majors differences in performance can be caused even by minor differences in TensorFlow and PyTorch libraries. + ### TODO -* Add MuJoCo and continuous actions +* Improve this README file. Rearrange images. * Improve performance of KFAC, see kfac.py for more information * Run evaluation for all games and algorithms ## Usage -### A2C +### Atari +#### A2C ``` python main.py --env-name "PongNoFrameskip-v4" ``` -### PPO +#### PPO ``` python main.py --env-name "PongNoFrameskip-v4" --algo ppo --use-gae --num-processes 8 --num-steps 256 --vis-interval 1 --log-interval 1 ``` -### ACKTR +#### ACKTR ``` python main.py --env-name "PongNoFrameskip-v4" --algo acktr --num-processes 32 --num-steps 20 ``` +### MuJoCo +#### A2C + +``` +python main.py --env-name "Reacher-v1" --num-stack 1 --num-frames 1000000 +``` + +#### PPO + +``` +python main.py --env-name "Reacher-v1" --algo ppo --use-gae --vis-interval 1 --log-interval 1 --num-stack 1 --num-steps 2048 --num-processes 1 --lr 3e-4 --entropy-coef 0 --ppo-epoch 10 --batch-size 64 --gamma 0.99 --tau 0.95 --num-frames 1000000 +``` + +#### ACKTR + +ACKTR requires some modifications to be made specifically for MuJoCo. But at the moment, I want to keep this code as unified as possible. Thus, I'm going for better ways to integrate it into the codebase. + ## Results ### A2C -![BreakoutNoFrameskip-v4](imgs/breakout.png) +![BreakoutNoFrameskip-v4](imgs/a2c_breakout.png) -![SeaquestNoFrameskip-v4](imgs/seaquest.png) +![SeaquestNoFrameskip-v4](imgs/a2c_seaquest.png) -![QbertNoFrameskip-v4](imgs/qbert.png) +![QbertNoFrameskip-v4](imgs/a2c_qbert.png) -![beamriderNoFrameskip-v4](imgs/beamrider.png) +![beamriderNoFrameskip-v4](imgs/a2c_beamrider.png) ### PPO -Coming soon. + +![BreakoutNoFrameskip-v4](imgs/ppo_halfcheetah.png) + +![SeaquestNoFrameskip-v4](imgs/ppo_hopper.png) + +![QbertNoFrameskip-v4](imgs/ppo_reacher.png) + +![beamriderNoFrameskip-v4](imgs/ppo_walker.png) + ### ACKTR -Coming soon. +![BreakoutNoFrameskip-v4](imgs/acktr_breakout.png) + +![SeaquestNoFrameskip-v4](imgs/acktr_seaquest.png) + +![QbertNoFrameskip-v4](imgs/acktr_qbert.png) + +![beamriderNoFrameskip-v4](imgs/acktr_beamrider.png) diff --git a/envs.py b/envs.py index 1d221a7..626bb15 100755 --- a/envs.py +++ b/envs.py @@ -4,7 +4,7 @@ import gym from gym.spaces.box import Box from baselines import bench -from baselines.common.atari_wrappers import * +from baselines.common.atari_wrappers import wrap_deepmind def make_env(env_id, seed, rank, log_dir): @@ -14,8 +14,10 @@ def make_env(env_id, seed, rank, log_dir): env = bench.Monitor(env, os.path.join(log_dir, "{}.monitor.json".format(rank))) - env = wrap_deepmind(env) - env = WrapPyTorch(env) + # Ugly hack to detect atari. + if env.action_space.__class__.__name__ == 'Discrete': + env = wrap_deepmind(env) + env = WrapPyTorch(env) return env return _thunk diff --git a/imgs/beamrider.png b/imgs/a2c_beamrider.png similarity index 100% rename from imgs/beamrider.png rename to imgs/a2c_beamrider.png diff --git a/imgs/breakout.png b/imgs/a2c_breakout.png similarity index 100% rename from imgs/breakout.png rename to imgs/a2c_breakout.png diff --git a/imgs/qbert.png b/imgs/a2c_qbert.png similarity index 100% rename from imgs/qbert.png rename to imgs/a2c_qbert.png diff --git a/imgs/seaquest.png b/imgs/a2c_seaquest.png similarity index 100% rename from imgs/seaquest.png rename to imgs/a2c_seaquest.png diff --git a/imgs/acktr_beamrider.png b/imgs/acktr_beamrider.png new file mode 100644 index 0000000000000000000000000000000000000000..c95f3e4489c25dbec13b6acc1c5407acaf98525c GIT binary patch literal 21391 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 E0+fkdi2wiq literal 0 HcmV?d00001 diff --git a/imgs/acktr_breakout.png b/imgs/acktr_breakout.png new file mode 100644 index 0000000000000000000000000000000000000000..d6264df3fb8feeec3134cc9a8a9ddcb7cddbe889 GIT binary patch literal 19882 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 literal 0 HcmV?d00001 diff --git a/imgs/acktr_qbert.png b/imgs/acktr_qbert.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2472c08f9e9ab3184ef4615b7262111eaefaa5 GIT binary patch literal 20963 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 literal 0 HcmV?d00001 diff --git a/imgs/acktr_seaquest.png b/imgs/acktr_seaquest.png new file mode 100644 index 0000000000000000000000000000000000000000..a009c88545587dca5e84a040b59640c011a4f9a0 GIT binary patch literal 20287 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 literal 0 HcmV?d00001 diff --git a/imgs/ppo_halfcheetah.png b/imgs/ppo_halfcheetah.png new file mode 100644 index 0000000000000000000000000000000000000000..071953449fa9bafe8168fa5506de8fa633de7441 GIT binary patch literal 18546 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 Ov=ifh=sG0Wzf6&14} z3;QE(K0ZELCSh?Q9x+Z{KAxW!LBhnu#J-D7hJ!=K^ML9B&wu)L`voAlgS3F`i-JT4 zAQK>=5Fp*Q0knwwL__-13;4Ge5;6)Z8al=uOsuRQ* z0F?lZ@Bz0pI+2<&2Aw@I&zs2fJM@oBTS(N0_8E9h9Q-h`Nbix6Q!qYcVrF6G;};MV z5*B&#R7O@#UP1ANhNhObj;_`ZMaRU(#ee*i zkdc{{os*lFUr<(FQCU@8Q(O17wXMCQv#Yyjcw}^JeB%4$)Z)_e%Iezs#^%<+;nDHQ z>Dl?kXvLj3+suwUdNK*)uRii(1Y@l!4&WLHE(AwWfYz>Q8Qt%hN2PejM_ z<__`W$n??{OnP4ReG(IgAuLh`zD34^pQ8Oqvj025{Qi(+|1Q{n$TbCEqaYzB4}}1b z1kNs*GkmfBr~UVj0bA^On1LJNbw|O#n*J`f9p=$;hYGGF>$;aw5#;h!Y4(=3o~ECY zxn-Uzvc91h99%@+ibD9(PJ~E`=97$_a*cvfFMj5my;n}Z# zf0BP3j7&^d#dIr;j`1C+s7C}3rEtrI+)F%#jGAU_D~j3vNP8G)#?UHo*H!Dl@^omrLx8b0 zqe|aK2MvBswxi0JuorCGAnM6iZP!(5xH|c%Mb89d$NK}XMByfg6{_Na1lk3N)nxt!P1)<62`(-((x^7xVyK}0 zxED*7RXh#PxH_bl*@i)9v3!brkQ?O@QAn!Z*e&o5qInCXPZ-<+%>vMC6JHS#wxqv$ zH~d_-(&&=fdEn~E{1)h7M#;>m9r)$FzdGrEF7@9tR)WRWu)X^hoM}OBI)30-6qc5* zg-d+A#iwyqN2XO2l{}vdl9vsAwT%f&R@}al|K7*>^ zL3$g7$@_TM(aku}@0`=OfDDI|2B0QG{0ExDk(bo|N#o4;@Jv@(JIjZ_82bo26%Ui* zM=@{`2PSp=^W?CMAS6^|T&{8hB_ODRF6Xu z4-N<7c8H%N{mn+wb$$!9-AkbzDat90RM)Pde9QbG23au`+^J%<*)kdxv?Ze$lw`14 zCbGr$cHcIvL`<~}f0$TG= zR2TpSA><4Mo~SxXi)8#T!Mf4%hNeyHRlq%8=t}ZA1m5B@f5`&LD0clKd8l%Yn8}y* zwl~C;L%(y&2yv95C)US&Taa6z&^A2{7y8S|+M>T`!tblmU#r;4-bsB|6N9DRQ%59o zj&ia5H%9_gVbBHSVthwy&Y)Yso+!aj`NYzDT~~%!gH*ezj#SUPZyLLZfbX3-`4lER zb}fG~*t0pX93rTdd8LpUw`o9S*C{N~%-l8bYy!00n_anYlm1DQMuQ-Y!*BBC9hwI7 zeHhc{fdGBg4<3^riJ@Nvf;O`SRj`x_ukT$8_iABf%^1m?H=mnWKeTtu)alQqQ*yHN zDZnu(!b6>b4ZJ;G!kne@d4V!Y!T>&oU3O%wCK|pvUhPA@4i_ISiq~j5=z7`NTm80o zdcxs>9mZ1TQHkiQnyL|;G`YS*#@-)WkI99vYfC`;@q5ljga%BFjNVZ#hrUvwZ4e>Lsdc9(&($x zgX*=6Vy$~`IYZ~)9(QAQ<6l6}y4h~nTpBKeMj+pgEt@QuR{VmP^Vr!2B-m`?MxIq0 z77h2F)A>P@J*XW#M!DzR&SWb;k;+F6FD8?j;`dgpRktd|afH5hd7bm*v)CVDPLFzoHOJa&WA6Xx06jc19C-*R*ot}MN}~$ktp@$r)D8iw z!v&`~ulTZ798INUsnJO1 zQ#D6cz}HDRnY+ET`I7zBX&03F({Qp@{MzB%S-4(#%t(=S15xpYcHLVA+tWhxdq@FK zt$jruXI?eZ4Ct0Oj~4G(&nD<=h9)hqKIm9&*=sjBpKrxnx+_#nv6v~K*0cC{-A4nT zcRH39=5Pz(I6tvp67BkE+HH34o2uK_+>;x&3`^~tt?B~3n_FPTQM!&qlc90^_^R?+ zC9yN%d)d&ma%Cb#@{jLJA7ph31@Jz1bzNIZ(2AD43ytY5gRrdnJ^cZzx2HWn(H`g9 zIN|zGr`To3VJ$K8<*MCamo^1QZ-4zqgUnK)O`;8<0krAeEua{Xk>>zAhK2^Ks5J9V z>%i|__evn$0#UAuC0A(E(2eZkpxSxh7U&k;pSbbcZ9Z0?kTEc~_&<%ZmQQ|uZ%#&q z2WWRI_LZacDtrgqd2TzU0V%o#hP8hE!Wd>{H$A!8Yw_BY<8(D{bs_5MPEb#{ultOf z(1LRpU~)d8949|@$0ny7jNG_IccI4D^2}=T<>Z6G{Vbeiq5S0o<*bB)$zVu2kwImG zA&C)V?sFws3F}Ep9n)f-JN*zk+q+vf6E2aA?0^we<5Iipyuz-BJ=R~4R+wCtzo1ZWpvWm7DCgvQlQg(Y zsL9!t@n^RcWQaz*LuUzKYLZ>3r3wj}`f0WJdn}qLMqk@he6*RH*bxzP=(IWzC4V?0 zknhZjY|Mju*EH#1xQgE!c|eDa@!OOipM?}@-MiC;o2NEua6TlZf3B%3;hf--No_kB zUA3zkS8uVUr(Hav2dDNrdxW}geJ?J}Iv;mPPf&`NKNS61YoM(~o;B@heO6CZleH41 zzjwx#;xF^++~;T)PCfGDL$893fB2P7%Z;O+W*_6L5fPJ%D2tJ_y-%P0o?ifn09&cghuLuEX@{GNhag~ z!QGS!vdz!tq~;pTb!A7*J&cX@h)7Gq>!~TZV+cCWY&$cgk7M*3XO`$D);}YWWTUa; zoq^L8xYc)7eRCGaz3WQf8-f9f3iEKqI`#-6T@e4isFJDef4Z98qgK+#qEK#9NuyDxc(L>qbZhu6oYl znxo^I)vDbTLz5+f7yiU*x|C?dYEpmM)CrM*$mn5T(jewEY$(Bb&~&Sw2WX~~;ms;R zfm}$GgXa~B?k#|)4QHO#4WCa@Fm>E={XDS28XmR)(ta_-_k7WCHAk5KfzLB!xg{v; zhL>PgQ{dv2vWS9~+&h6aHD3jjPTFLrZdty2E(p7)qEoAcf5mvdVW~`(fJw)MG+MI8 z)?3LH=qjT1zIuGhkFhU?i@hC*vL|Zc?GA7)yxOK>R0%g$*Lm=ry_pXc4M;m5S;rh$Qt=vQ629Gu5gz z2wFTJmADX&YvAUgY$yz7BaSC~6O3%g-#=`Bl4~WoaSISQb$fW{e6^6MSGkis}~lhv3sMXb^*CNs=TPrA^PdAzLOUqL;C=H%JH`Jx^OydmLVj z=B#1o&q#70YIJm?qG;tSi_m(;`hghs0pl z)#inlZnBp+;I<~ZF^-Q7gnXEkB=irSzilb*sD&bJC}g_1u%N;i;tS&OB13D{{Am@p zSRpla;qhj}gD`I)`lIaT11dxD zV3naMUI_2JUyG0JtiPmyx4W39cA8rbH~&Y zEu<)M@)5>WW=W%qdf`2}1pQ9in#Dpz#b$PwxLd$|b4d2{*GQ&W87v9ER2h=Bl=Kcm zLrTeDEpA_|+0D5ZMAK_7s6NaX%b;Wj8gVXj^w=V4j70v}r6i9Zx~6(0)QW|q~6^hH{gUq7Tdnb_oR);0 zup)|!A-#W^xWqJia<}Vl{#bU@Jq*fGFmM^xpzUqY+&YwsJ|z!b&Fq;!zk>QZlQhvO z_q8_?1kkX&P*>7&mlLvJxmgL)eM6ffT>A!mOeDDwcV{TjQpoui^%4P~XlJCSx^ zzaT}FS66>?YPP{_UbSXs!9|vg>B7gk=lsRfM41ECz#pp-JX?OT94&wqoMzXNE8G(V`;gE9g_` zJ~hS{6V`^>OBK`0o}n6qlI1i*iPVo&p~H1{r493$w*c4ZYI|?o-7#qDhDSCrA8`s|K<|q zzA(Dc_r?Jn;lG^ySIF!a%l@mSM;w!MxZMNQj+a!9h_`lA7zFt1pA!VX#Cy$r3p}hB zsf(Evb|@EdCXqk7pAp20gPd9OQGZ%Vn4BQp0mBP>G&X)oG;gOtFkh7(?XJxN?dkh3 zv>)zk$`~pTFtEfst}~4IAQuj^!O!Y!E3q~-_qi$<5*?sU;*R95=+OmggI$fryDKP5xX$p}8a>-?ulJEA4qbg*b*f7|{- z5oR?JfyaV0Cy?8>drjr-T{u!0a-NR&X^|SC9X*S*$MlyIvZTtIN=<RMuW!5}Z>s8p@e1MJ^6dZF679TmLx0DHkQWs>J;g8FmW@K(XdR z?`bMdXJU=TGEweKj=3c+p;f)frxxd6NLUhh^1wD0nIQV@XcBlj)oM%m=JN<{218#- z^!gr3f%R-^PmTDKXXWG0CFDwCEG*TP!QIhykKR{FU*_dka=37aE?Q^#m_jY7 z-~_!`n`wXP@f=Qd=o@qv)5mzWA5*tMW{zV)?`E`RorV*Wg}P6qWr($2y)})b3(bo3 z%kcZwnTFD6=RuN1^Qinle41OnlJX7qYwcK_QDUKM>CQ@ngOU%s>@ORK7_^9Hbn4kZ zQ93vv->BeiZtF`BkK7;j5;Q}_tY}bT53Cmj6eN2$(45*uoN6!Y^^b&2$MhN!vpp|& z+)4A7VA`64yT>j(VlJDBfh*;)uUeSue6>sL6ZT5Hlm#;Pzb8E8B)YYOlcMy!fooY=j; z1YLg{uKk2@dE44J=IK`Vn5PZdEU8t~vE&QK2F~Xe^xXtsI9{u{gW;%;ZvnkJNP?w% zq}pLi^FxQZyXDrjZ2|-x=YeX&T8k63orw6;i;Ib@2}+LI5ii}vr^X?Z-LJia()cH} zYCbqBDAnEQhEa$`+V9)~Px)u*5$Y7HCe8lM4xsM4v&jx&uqh5f(s~ggm&YHvbn%V` ze+(3cRBd{#zY4F6-{10lyLeG#qq@g#LxBX}L-olTWkrw)F0aC11qI$?{Y|yDG(KlC z6{UNg-q>U(z2=wNa<0y3p;^`1Ja-m9DAm(^(PqmtlrDD5Y~`M6{$xY47YwFCdM9+b zmW+B4Q^z$#1S*!JDLFAmP>@;=*KFUXUC9Mh3fV`EmjU9ZNj{aUP1yT$*{=DP9xKMC zRrfIZ7(YMff_fb<4>v|-`pr@5ywlq6#C{n?$d84tqKYzC$6`V)BvhQsZ@`nU&g(7t zEh>n)*fEPaBMA7}SmO$_^|nQv;sk^GP~VYaeHX)*lk^8=Bv^~4^Cgsv?X`=DuLn9~ ziap6TybF;_VXCWsR=kAE+lfludH?b(NAf*oTlM8*9@!?XsupDPwWrUeC9Wr+P_T9W z_g-^X{5VWmYRnGL3B1hnhs!Dly|Zm8Dv?&MQm_XmJ3|W#j)Nym)P+^aI*NFyOG-}y zVB{T;=tWzj?a~cIc+)O<(V#k1NP-rsY%+ffyeiJAwWYeQqA+O87+r9@NIigAKnb8A z@=)kv^LBwq0&@mpr$3xl#ngvPxzrZ;NAC5F4ZeATQ{-vtv6AEsX*!@Onxc8*oR{@j z`yD4i7!so&LY>kVAWFfiSkpHJ4}+GpqqOD7=pCs{y}3br*{n`86Hd)9;)=jp8Sml| zp!zA;jZoN`8b!A*R2g#2ok6ZBz_R5bJA~D1>3x zYn0a1FqT3QUeHvQR4g4faVxTpLUrYA@r<5JY-1Y8xdryW>b$DupN5LtUVJpflF-|Z zYg`>llSUBX6*z%E9a(xIFL4S{yTZ1u(G5|#tTqN-*>j-ugL0+*rfjlFW;A6eI) ziP3m(j}?+$N$C#|ThJFHaBjmfD-pMb zA@vh~{)Vtbe)G&MP*VS{i}xoL{oktk>tB{X8J*)+v%i z_JS)RF%>aT(`h4ERzwu=6<@dC<7ji+@B@1=HWynGD~pM@zoQRw=q<2Feoq~nf8}t7 z0Dc6%)H*inzQ^D6ejP?@$*8a-tTQhEo#zpD z5w0{wdR~cj)M_1I<0UoDuK6M0aF$Dh=uBQzbxn1H zm4kJd8rtEJQfhzi6KOK*l%9>G^N47_L@vEV(-=*q=w>PrU+`qMJbN(*&FqQ`k^<#4 zYD!WJY^>HhYG?XnDCx)b+~k>phgB%vdqN&J)@znl$+))%&hXftYY84&l3r`hC8uo` z4hOj#!GROWSQ|uSM7>yO zvU8M(9iJX31|8JJni)rY*_STNiv-IJqG=}@$W%)K_TfAm(^XZ zcqGwvE8q+dS7IE`${Hc-^vlp&%sb${b_AxXbPl+lOJ!^#kn?ZH+7T zh|MW01?uw8OWNRy&qBx47|*bF3#_h6Lj^}pZhfiHA{w*%`TjUT}zy5Vy{guD86y``^W`0`p#6v4P?B{+va#GziHBB) zk{=^_?`AwO(YSbBfVVOKsYC|GI^r~&YHFrfPD5yCFHulGpIO+Niqv%~~>z!Vo<< zI9}atua#mRHDg+R`qC(WAlyNbQ*`$d9+-WOq}#xITCEOqb!1U*b?7Rk4#~XK(QtlurH%TG{cE3N4Dmu8cVB~AI1X8H#~QQZrIw)K}rZG zI}xp@ydNAUaHnzjk;Ge3h2kB4vN8XxW9=JUY)wnGBSl)&zNt%Te{HsNa! z!u<@(w>S-Gl_{+-4hTRE4Xk;Nx2+9{%Bszo|1_y6_E~Kw0^uv5B~^!G#Ai){T&tP` zo_h;-o)qVlc`4^`mMl(B^XTx(>SCSXHuJ#K)ZM@@M4AKHZK+#(4&JcP&QsBjY7OWq zoZ236>uEyji~<50U%E}Hvb7{+dbC#`y_AI6PH-InKlaP@Z-IgKHZ|}BC*E` z?QxyjK6*Ng#zgs^3a>vwx&DDbRK3_ltG3HH4MSN&U5e0yq}lu^S*&KLSadr@c#yN; zc{o~;M=;FKu$`il90`jMsb6HBspMQMAaS9lau3z=aF#ryUVbg=eiqRFJ(fwl=EXG3 zQRJRKXC)L@x$t{MNxr_p`=wx3q$&LM)Mu$Zjb=O9EQ+eulA^qwRuy2fcH2E4gs&B_>9N3NcW2}0iwOmr{6vpr8`V+}wsMTMbKw`n7=so$bW~6R-ybJS6 zM9M=)!DZqiSXvG#yEAN2BTj7fw(qBk3-*_WALCP{kwIjy%vsRh zpOC10?26!M(mrSWPQJ;Xe^z{VF}XUTZW;_Xyl%c)ms|$zns18mSB1nYy*8y=Tl_)m zj)DDs!P8#vtL2Lr&+k1>GX=7sVniI2Br@+OfFy`~YY_N`13c1P&G$XnUF-5K>WqU+ zEMUG*GBLrJIU@sJh7#&2(B&r3)rJuH$qsxBno6EwqE#J$V}>fRd^IfGGup?|FCpF- z*DJGhG(__F@t*EZCt989GD_awTPqZtIhA(D8XjQ3@#;p6a3TD`Tf zcO&PDl4L|;Qy*&td2nWk3Bfs{Xam&YmCinxDc0s{W7kjk3%|y{j-1{Tz97bzlK6yj zaH*}7OQF!u1u03H@?m1lXYG5eIAK|$d~%K3k1!)BgMYzH{u7u;EuUPNuBGsmehuB6 zl5c_kho{VxWLu7OfJo9Hxc_H_1>F? zQ*G_oEH{6yZg`i<>NYMjkWQYz9l0-?abW4{0XiyZiWROp(#IlqK=1{Ds~~5vI#ra# zc+AB@7D@a0(Tkcm=4;`cmi2j~VqH5Q`J)MOk+^8$yzhM#^xO3$jM!|$sabboGMM)Io9X2C3}+6hOrtyj_cXB>y-)< zo#P;~TqpuQkL~*N{AEgyzn`ZM5Lyp^?5O=9 zfXz*v3@pDSU8!~tNiGdJRmOB>x}IN6K^Ki!O&;M!{zn$kKb|pE%+@xzC78l8Vojtv zockrpQ?8~y;UO|F`O6k`%5~<)NpCBNdL|$SxgiVgG#v`Zja)BAG~~-$@|CIV14Uhg zIAL*Q_R|4;NYJmmiK)1qY|_{~{Oz3y5sJf1pVpfWi)JG9nIukXb*G4X?K7t3Pr_Yr(He1Kjp9eW8UX#gXPsNu%mQrfvne_|#c6Xya=svdPws5nkcP|`sWlnU^8M+J7JDd}w z0JFOiM)+u%QF?fUL?5pY!>njYn4(b>M|@;jEIEalLLw_YoWxcR43jp>=;?pbAK5Er*@7{RbFyZI^;S;f)#h|sT*+@{hKhoZ z>G}K5i77)l&oqsXtnQV4!-W5Ed2>ktTZBw-mJE;wr=rWysBux zqm5l?r0y*iR&AZ)$Q!{dkVvr{6}<mNW!@Op(;;tt& zu76xz9Xo9^8cDAIjp;L%s^O&`#$k?z?@k$*n^7bt=1okVo_CwU&^&5 zYZ*41l?CDDEI0j(MX-C_K-(tXMoa|b?p?0cz$-_`E1MYV8865N&-H)IuOrxA1nBMh zewa$5oNr-B-1d&Smqp*QHU#EQ@5^p$Y#OyUMAgty~n}5V~{_eT|;O6$TfaqwCdP^WQPrpKt zgL*EJ&eoFsRUA%-{41Tav?W>Y`zTRQmdT9`-x`c(FRYAmapr<-H7k`8-xnL+bqRbK z$4#b1nF+oH*dtClWB~pBEJ6Hp7Zhjg&ofF4BRx@RvN#OI>#Nw)(i{;y@~9~N5W)6p z?v}!HcX+2auQYVM=X9J%g;4ULS-0tvYZamGetQsOXyN2!r!C{mna!tfXOym03SzsO zROVDj!$r?Akj%}U_}Qq%zRz;3Ry8_%^AEjwCyT*LV*F4bN?m@$LYU?w$>RaV(H|Ab zf=X58bycIU`GR|u3O^WI4COd$QX2TuI)?MI$}cmaH;M!SD`EnnjwN!g=&8^j~NAkIfKC_)@5Dg%KXe@F`Lf5Rw05 z$4;Wr@m#CjL9a}rayb!)Bk3mW>jQ5da6q(>6f|{&Kbtw1tuZb~Gi%hEdMVbhvci;Ibaw9Pr}k~u#qX=SDN9Wh--9b!z?pZ_a{@Yiepzc8dv+?}ao zW6oYs$zkz@c>DG_N?`jP9+Zg5<)P_Tax`fuAuQ;Uf&cX_kS4zAW!G^!*DC!Xv47M? zQ-@{cX+!C?P;mxx6q!2nD7!_vrkoUpw7wVd_38!J5i~NeQ@ckp@fKjb2+s&&BeMH* z2lZe1|39(t!l1akWFFxjke2X~dgx8J(}R?A`*`9lsdb+f^h7SO9?s9@=)1+M#a&LV z4o_UMZof!X4&#?Sis&#^eN?rBZ%8MwONNcB!YxH@{TtSrU`a>xZ>|}BSg&MM3eg%i z&?}PfWw?)Krp@@?E7LUM9x50^7?!NxruQ&Ni$h!Ib7_e(R`Qi6N>)B$s^K!=jecJ}{fhEu3t)N2=9pfkexBo!sVfBIaV7?dqiV zLOoZk1VW;iS{_=0m|Hepsek39{`s~4X%mbTS!6-4uY13Cv_!qb^l-gAxR;=(v4!z& zNEj}ez1ovSh`h5*!#zP|Vpkqe=c{i`&m3!B_Dg^!MQ0XD$xWpCY}BO4JdFHde1%=+ zVQX6&RiR52ep)Z6%Y@NlAEl+%0W&(jj~?;r^Dr|{0{b38-oGiq|5Y_mx0#NyyTPKG z644G@;y$r8qTcW8Y!^4j&f!e+*vIe{G~I*j#j^c?Y`W;$rNek?hZU|97zgV&%S)N$ zkF;A4_x$8E;;bx!I+HewK~X3*n<>pkY3q7+s&jF@ zm!+Y)l|STMZw#jQ10tqW{Ap8b<_uCR49X8XWLMrEZ=Uqos>wWES!H4x9VU1l6!bIy zKtcM?>5zZ*|Gz&VL;uMFtzWEBLc1eF^W6r@^e>eCW3OQkW->*=1nG{K;jR3e_)n-S z8|)sxp$mOX7v_uP%hoT31OH^d$S;;19qo>$ZC;c?5Ev4_WdQNyv~C;klu!)q zKzJwrW^C`ZU`5ctVs#++9X_pUfYyME6E^e(NCu?fsJQYXkl{7r#{N#d;h#}*e^dw6 z4CIGoYNgoaQN)FX@~!SRpRmC%Zvk#8^xl$-?Rz)-(2me}qoZ-ItA$%2)YxESjxlb_ z^8SH#^j%RNnbSMdCedG4QtX8K$&{sx@wJZ(0@fRTjjY>W%D!2erIaZh-o2L2{(dD#yUiWu;W?iBy#eu*0_j~mge^d< zn?q&5$w^!IlnarDFzET@7HAP`zK)jr!<|TQIz!eDsDDJ>l%|K5>$Nzp-2$e)NA97l zyPZ=)ov{;QKTg+`b_{tDe!ywqE#T)4y?FSi2S@xObLRgC`UH*t5Hruzk#R-{+t;); zH*I_RtT0@_G}y&w(8IQ0beT#k{tu7jKW|R{byw1@v+fKzp}aAixB@>3zY^KBu7;ZS zcztW7sxLhalN<+A9S?W_yB5WczszQMsoMbj?G!B>a}`n1nE-5T{6F2L+?g$$d~@Pb zrsT9Ekm)pZMBfJ99pmm6px_GLr9zZvcL;5#j3P}98La<0-?SzNsW%uElGj8CYt+q$ zG&Cxx*oV=B$=dQ+bYbmt)9){QoPo;Dn@Q;2G}NCK5`I;73(O-bCa_xn-eM7yn4mo~ zLp*cySBl{WL;SxW6VFCNAEvZ}?D+@I^oRIH}ieyXHULY~tU~ zW1r+P9{angf`1MrUX1Yz@r8=-agxeD?+S_xX$adPA(6{}1$aYfl@CIjGE16*rVKMJ zU4kFjR@|xb^W)K8by+9uknXr6ZiOhNbLy@Hu|Iizko`>%f99)c|JMWgGPKtYNYj3v z=KOuSZqT+!x8*AzPiv;$*et>fBY9ndanuXxz_t6*De~Q~?Zc$V@emIk!OQjMx_(w? zla9?jdqMd1Wr!-DAHVk(j22`us^}qaf9q5VOWzGe`dagG1^hJWkENk==8~M4SoSH9 zfubf7$g=zdhbGVUn-{S->FJy2E(CV|z#7HKtQ`1EqE z#j21_gnP&~4ThFGd6>7iKj3_f2y<#THCB%}T_tYkqq>|9@s-uWNz|gC4>T%Z4&v%d zp5|rsrFH&IdBZcjhDy8UA7GDM3_Y_Juws^7m;NOA9#R}5+?*O|R9##|ca;`oxtlN6Yxqp*Iw~2GDMLNDmv%G={ zK78AQJF`;6ni=-CN*VB={x#5LJae8iJpCeS2v(fHY#ub_S*dww9H(4QP&QrWn)^VW zvO^x$vr^*4pEuy`ZA&zT2p}14;T!eQi(+PSU+Bt!YF^GM9_oPY7Z#qQmwc$4m29nJ zmbLHMlZMrFvQ0F)(2f+bHy`c%-1C0oHDgZCWWz!~N-Cs!fc9p>W~HansjQ$Zlc; z^WU`^P2Hdh(Q&v_XaivEn+uCewZ6c;q#c>a++=kaE-`g1Tm>aug=^|GN1G_Ea#@CS+d``eo%u)R<3Q*)O~4i0|-{a@T)bUu}7y!rSMh z*`=@$Nm@da4zaJfX%dYKd*S~9<70p6g0p$#$MuQt+D3m>Q9E~&G;G54&g$Hs}32)nc2uJy0kJna> zM+_BqGlS;VTx|uFBNZ4IzfyNH2x z?x+XYSVIbtgWbrbozF8zgC_UKKM8~`PK!${W?H5_E&?;;ucYu`zyPbE{{j+73nS=S z89`h%CdUqyc~+!sJh?B|Do4}lYWK+1TBm!u!yDpLUa8D%zA zlQcWx#l#<%ZtZEGfA>R1eQlk0)fEbP3{K{n5DLvLFz)+Mf^TT8EX9+&ua_|^-X4Xr zBbpWav$olkJOeViVsuyTCY)=SYe%`e#zIjl9yh9O!=)O?S*3Z&1Ft=%LDJ3LS95k9_VpniuBUm7`;_zFE2|3gvxma^MU@=l-XIr<$diwjV=!hu z3qwaDBTvI|J#YyoM%J}?7|si;jya7gY67#E8L=0`rG%DK#ys}4%St~79j>l~u>=)a z89UPRI;oLS_Cm`;_T83BIlQPoQ_A+o+l-&(yU3>I1UpAtiTKldIv%YH?}lhqRc3V; zFeXJ91bY^;MLME}(|$~^D#P!MjL`gUCugu81oYM)WPffPwsx9!=b}`L9I+46(D9>^ z*pY2}Bu4U*`&vduXW|5=EuS)|w;AX9$Y4h9bvVcN)0TO0ji;?t&I5~Tn{W~V*Hi6b zBlq%Fj&DZw(@;u<*7Nabi1Z zm7#|f45wkRml!*4O&3v)Ot-4xvqPx*8YLCnE-}(x$8qvaU>_uJ8Yk=TI<4rdm=;Y* z`kZ7xYv;9qsKz}*(km4h|Jk&_MSRtSr&!T)52)TT<;HP(a8QgR;KgZwLM?*v8uRcI za6a3b)743;JZ-@7Fj{j@%q(|`S}YNy5O=x>3%ph; zCW(2U@N9>rCWKRnx_cv+{8HODZD2|E;|I*FaoiCPm*VvaK+U*D(7Y|FvS=@5p zjpuNR%_UIFpOd4+f3@zew!neU>JoG5Cj}r7-1;VE)&Z$XOeQ;7`nA{Dk)A4pU?fwV zX@`q@qKnPKb?v}wO(i3WbDtliDQt%ibZ8co*a>ArDZEd$%#fV^`)<-1s31bMDb+3>G06RL20>6ut+e~gN-$9iz=7|jqN^p=Z-$I z7I7Xa#qiR)ODxJg4Y#RP?X9|h_8U%3&8kRyYX+Po^B-LW^6Mpv)jCbogR6s!wP8w? qAC>Pr1u;(vr6WmA1@*5=cc=<=FJMjm*Dudu0SO-g z)(TL=?-K>#mlyEwF9bv+WE501bPP-^_=JjE03res5+X7Z3JNkZe6~CMJb;XkLO{zQ zfqGk6AMLI+A?Le@G;})2(k3F6p?!L;*EZf5n8bHTNXhQqXJBMv=H}t$;};N=dL%6) zD<}W>`3qGwbq!4|gExjo#&1nbZSCwG9G#q9eBS%|`3HOmjEstoiH-XhpOBuBnU$TB zo0nhqxxAvX>PvM^b4zPmdq-zi_wdN**!aZc)b!%g^2+Mk`o`wg!Qs*I$?4ho#pQRp z5CEiK$%4QCO4v_y;lt@dL`FtJM*B_|0-_^)AmJmU&~l&>NGPM}Ti?FR`3{{>G9shyiDpjOkvO z|2O{iJYea&R?Y6pbCZmDy$_8k?4k-Fy*o-jdF!Is+rP&$@j$OgX_#m3wSw-QM+;M;gO2XS!f7m#;+YXIjuww%8O9_jE{hIV;ZCESc$4 z84XTVuVZ{As8fu&(*0`KMD*U6@RMXRuLT%jNGbK$Y|6-+`vGg9>SNh8R3+4<4sYu) zTXD+uX%KWA9ICo3ltGxnM*Q z+19f&D9H%eQd=Qmcl=_n?&D&_Wa|MlXG#)LfO$9{!k5rg0|Twmiriye=^gIv4R-GR z`=KV+e%fOp@7^eZTP>BuyYtBXrP=_yV|9j%E&TKTb@ixTg%n)#z-jc;kk6uXhoUYK zN9hLq-4)b0OMweb5lx7!*0Szy0f7&Rq-Pre5e{)mLqcV7ls|Y7(T#Cm*pqUf??GOk za#TZN4LKQ?Bda?p!upFQkaDKxaAXxqc=_ZVjf-BsoYg7ErhC|sQvQLXA_#+yT!P*p zoOj}RK@+&Uds-$VXPV}Dovx>5Ur!OwHo$AOdE~`w^Pp624Fz25}K^EZOV_wlwkn+cmWKM0$0NT4|5oB z4ripDy1-u_rvCB5|6A-|%`?=qsUqmOMO{Gs@bexnbNB`ovYj9mXj7@)KmFi}5x6Zo zvL4($LKr(mLQ1|Tihk8my=5i@#V=Ba`s><4ucu(ZL7>B4CdVodS-Ae* znz`IpEG7gBu0l>pcW<%C-cl*`3HN%}9QG^*`4TtGUZ2RfJ<5P5T5JolQYjN68YqKe z8O6E<4&22$INCBN*^^ z?rdmCXZ@$U{fQWHN=l;spN{<%f&aJ6-xmHqk2fKUUp1J-_7k>0;ax2MswSD~rEb)& zws}quq#Ej?d+crXk%v3Q$&$q7f?!ey^1w(1Oo3cvBaZ} z>Ng>u3WqXzEErilEvfZ^AOUS_IJ3c_g2y?=lR7=suLHfe4yU{Dcfogkb(>k_nj{Pc zZRazc4MG`WR#Za}SX=i~?Yq)@+5Lx&*lt|8*4icJVFS5~Mxo>%Ea^~ERjaWwCmi|6y76iQcmfQiPG*>t>ZOA@3fk*|Z zeTk0xn%q1jtz0>7H`8fxuj;F}2ITWPXT79>i2E0@7!1CW83mgYqP`iYy_N~vCTzzq z&OZ2GAHQ$+I1mve8>yN&4yw(ptQ;*eN`3;7Tg85cs;Fq1^VoWhlTPhZWhD38!YMb2 z%qB-`Gu||0TkTY5)fsYxj^`s^uG@@F<^=}rnX&_g8W>x%j`$}jWo*<%oJiAD64m8> z3XpfE1qE4xxtbLQ(X8&dOk zosbOhc&Zg#7lsuMLEkuVtBGbTfw&%zg3Q6Ij1!E*tRF9k#QWvXn%Zp6#BS~GvOlV! z3bJjwMh-KYMQ*p@@SYm3C84yqZ;&7gpna5tK^*(kP=#2m)MI_Zl z>|J;p60dw?b?FW?2BTAwaPn=&4$Coq1y#c0@Tw)IuF#k~`Hx z>~A!(HPWffX84T}NNPQ%qbw7;d``WDnt_adf4^-%nYLz+xrt714_6RBs-I)aW#qEr z{PluR(C@8RF4q=occJ znI%4dFk5S}aJa{@Y}uoWYSK9`#hyL+#jWBpo)4MOp>bs$>9bbIeZ($9OOchpD>p`0gpLOuRh|13c91j( zB7iuJ46EG2ArlrZmlOwzVg#%85wt_)3W@PS-b%r%97pc+?4 z33`SyY>l}Roh0b?4+kDi2|rzCBc0yU99)hZmc&;<)5&mHRiL2uIA2jo`4ELF@3}}- zdqv+`ROcJO`RSONUBuZVeEbMuDt~whlN%u?z+#RPQoIX=;zT-&P~v-W?qELIG>Qi|DW?aE}dVuk^Xs+ALQN*pB2~ zGr4P-sSRJG-5BA?WiMn11+w_)-EtavTImCUQfnS&-yKZq*P~{+mFb1CeSZ8+rRb~` z%Zc9E+}!Ajb5}ns!OHo<%H>^$WqZol>YV%H$wwH#auq)}^wKV&AqH^H>WnCl{a zGWUosn1I*7r?aUaV_9@8-=3PHFMe^zoHmS_m7uS>Usgo|X@AMz-z@*C>Gf-9&sAu1 z0u0!i*)SVOJ)jP?TvZ08wGdR(kScqrWUO`38!+T-CO;L(KDY^%QglkKHkk$0E0K2( zuzj&>T(J?2UkWSW$%wpaJIVd}LT}dc91SYJ;McHo2LuDsV{4e#-H>1a{a%aSDOM#6 z7*fzBvQ46uCR9TBTjQzc3Fw%6%M1n-Sf-`odNzt3KD&mS_*b=-H-r^K>O$YBFBm+? zU_gm(6*N$5BNs>ygj?(1juK(1r8%*dAxXpD!|qvWd=zh=BaTxNv9RUfygD0uvyJjS ztkyX7XBy>Im|bLyl&;iAds^+j@+?_7wxsGgce>}lh7MTK!%h2@s>7)H_^@kndF!A! zM$C{8a${G&NUi$E`Kj~7mbg3NVwZL`TO_?D#u)61HvAXz$1tG7?Ai8WbOBO!Vu1o; zR|z+(w(%1Ie&O}v&EuKL=W1)oVV6c?8o9d}IBIb0G^**;B00)#=skTynjX||#H{KN zS{E_H(_^Yfn5v+ydAw~Hk)W=b_Hof0`<1t#v551AS!(S*)jOxyh>EmOA@jx8pn41@ygMdCRAd;^q5?i zPO-E$VQajf#5nQBApKjF0MytMVBGQN>V60 zG?7FfZw^L+0SwWbFseLh{I)UeErO9WE*K9enIsPa3_LdCSrFJ(<6erIz zgb$rARX++-=WXvyBr{dd*hDz1by--i-m+b@ZW4gNfbkAz=?8@a-8YcjabhY5h&wJV zlw51RbuZskUEQ&m#-RpaAwnXzvf+TwEv!5@D=5b%fBAq33w^HEG7{I}WIzd>lD}9X z-8U$|#-~}?U5waStt!)j)aRqxjJ3!HG-JgNpi6pQI=zG0)!C6V70 zDSEJ9ukkOKc8eqXEsMD0I1)a0$`7G0KPI$_9szCDod{^d0RL&6xy%v?3lN#S+H-nY zdIMp=2?_ZCN`x}dqKh;3H2zCj^uykWZut(HP({){2ksZF(yFKN87(TVZ4?6MhS_3M z*b`jcLyrf9#OA-Ck*L_VbIgoh9+Vb2@yU%Bfl?!HqfL2fBvT;X^28gi!DMs_EXwIC zVHKfIP@c^~jmVy%)i7rZCux21NQyP}6{1T-hYMJkCnJQde5@outJL5#g|`zuRqEAv z5mAb8ZGw$#X=iau5_UW?#L>!E@=;l@Vr1$%79`T;azfS8lBlT8VP7VX(3FVK4zSB( z%n^)AY2AIoBuR}~(zz7M*lOLL>yw__c%A=wQ_wA9HbYaQasxs17T!bL_ztaV>Bk`A zVb_@Sk)2ehmB3--NXAyVZIansK}Hd4h#ILBlNyjmLKBLfmF_n)OQ7&N$uBBrGq%Xg z(1h?|^}PsLY(<^R;rkIeZ60w$Q>}4K)X`6-~5z3O*j zA1ZQdOzy_hq0zW=x~R&#(WO59lEgfv@aXl$9Sg!sgu$zmqI{2 ztL=AS8_?665@Mfxdr_`JqWWMb@pb{u^PTO}A?ld5vzg<~6psprK$D7+1VyV%W?W7* ziZD|xCTzy^KtM83gF{Kvg+PF?{5Q#$KNd0n>OM?HCt!fuf|NJ~4EPamgB^de;lDBd zMrJN2q3;Y&6Q|H;9XiN@%R@HME{J;jmPp<7Turh!?hH@M494%SzqnZ1xxF3LkGHJV z9GqEQsoR^Q_0X-hzQwYhu03*IYf?k_EPM|AZkU7H>P1;2LdxRiF7wy+iY2i-w23X& z6kDCKrovb1xexORjroy? z%JYYPZe}glU_j61Y&&tNq!%qHftq0%ZxoUUBj^|Mtm0#;e5}M49n+!`cWsh{qVhtx1 zJ9)8#AW>T5q*%=jT78NBbhkXnxoLPQaEj zk(PJNhPKO^Sjh|%A`B?Jkm!<02S#!(cq#;4Y`a_wE=xnSV%@?$j;@8f>Vy`rKCG5c zR1_4%pCATrBKx0NSwOc=`N4q$3MC`cGM~%5=Q6L>7@K1+m$yvkh`92YzCQM4Y|@0w zRWsoS;r_D}=Z{mG?}7C{U=HMVa)WooRY~bj2`dK9N0hG6d@Xsa_P}>`4%nTIJowL= z820nuJ7=cXLSamERs$4blZZL)F%I^H4G@+VI+TVhpfAsM`0Mh;j-exykR$h|X z|0=XWG_jxXa6!^O-gQ(1j^`x%3=EKFvwH!k-z%1)%32OVY?q#+tm$#sPI&?nI~xR7 ze%Zs5wa!29QJ;7d;n9cSE{J}a5}n7eISKOdYtDrC(bR zDoX=@+W6I@Jo}YmVEy_(xtsr1$?eyeBImi@jkY@uU<>`p6jU$#lsFQ{AK-QvKU8Ev z3FTpLJq6xO2z?`oce`gP>_ec_MGrY)^-Lv-TaF$*2~q24nKsWNew$$CJLmP>3P{oS z>2QIhdb7Nx^ClVR&rr$@d1(1AjkU`~do&(?i!YrJHDYM#dqhX=q)FEPno-T%Ea_}sQ ztsSgO!jDs^Ted=Rm@SEZN=M|2=4DhhDhHjZOL+$3b>)+973z6BMIZCQwqGOCk@y68 z5cM={iJ!;$`kk?(35$3Y2itHiXKM$-gc*fHC%=9~IG5JmFWzAePj-xUbg_OcB-K?L z!SGgvgEd1hmfTDrZOG(cmP8?|)gbf7h-2zB?F$0rVl|(9*73~j?f|a?N82+A z3%TC{BrGYU(rJ{>v0ub+MMZx~QAs00&jr7eCVUb7r`etFHtvtGJ%vvd+gyxd*4@*x z4UpSOA1MjM@vWQ$n5li%b7~o{v%qT^uK3Szervz6zqMriTHKQ+~wM zXhCAG1x}_5SJPf`)VtU)Kx^Fp;5M|<2)?l2#7T`{!k?~`->vX}Uoo8>^6hCKe6Yt# zqLXr{@M?1NSg^`|^fn^V)BuQ{to_1PW#Lq;490^;!jBFfojG0-`?~wfv$7XkECs%e zzUy63jREk##&s!8#XbB>+W+?viYbob4c8J?2~26`zGh7anXr}D>*z(zq4e1=!gutWik}tp9q`6myDnY%fOwPNgmNdPjqeVd*#)DZ zKB{UmB>k4u$rUwVg(vqtH3!yveDH}ZVQ%ihq`G32?|S#VfA!%+1~;vTDh+|C`7(uV z+eRJr;zxFZC2Cv~{Qgi%dIiQ77Nl?qtZ>`;vYl%j3Toquge?K?9yu^=WmV`xk5!aa z(}FcT#V!4^btMpJNI&;pSNf`;a3f%zl`v#UgCUk!!)YbuR#4Hz63!`Vfl<^&f@~hn zFY;7>qn^5YWKU%m1}JM!>6dHsV@j-of+->wxGZcWSAy~4yqM>U7Uynjv9K3pOzO## z#mH1w$zz6zYfvbmQ2$`(MyV)n_JZ7$t+%;3JQo7Wy6ZYIkcf9 zL0$Xc=#=AaQZbcOxDg!l#JGg|Jvi?fIpN7o5A2-$vtZU=e&LC!*roZt$mD3(OF!$1B)jiQZ;5G6>}KxOmSsTpsxE+Fgy-HjJvBYJiCQ5yPFe z4bbSTdS^a`SJNS_e#5LPaB_S!9@vw=ae8N1CQBI%8kWo$Bt|1dXgwD@i##V4TaWWM zh&l?9c2RXM_7Zb;U2K^a!_*3Eg%m$7GQEjeflE%$Hb{B{VvRd|_nrEMJ6#@f?fy+i|B6WKj{&uRLH*x9e?}+e_`tU7CY{+L{6s}=TeUZ9yf^Kyg`cj*4@0oB64=)E+z+d|reByz znLfL^ZeZA%^zS}AN^00TvtJkbycfz$E{35ot;_1?8V^|_2y&GV{Fq9RlJXXlWIdek zwwD|UAp)vz(N-K;NLF@!<@*H_7+~qY)7i5MbdvGTb~p&Pw%}B+zthsH3MhX{Sf~Xq z)i%cxny1}W<>JXgF@=_Xw zoQ4WdS)9s!U)kYWph9fk%JYy6Z}a5`9lWNjnf;NcV)LXo05oPnEyjcI#!kl01LekE zAD+21f=9!@siFJ{-~Xu@Orm{X-fQ+Dyt6ch6S_-vOC8VV@~QoXmKJCd!gUwVq$<3A z@{vUvuIeiA0?Pj$pwfHI_cR5^jbChw8vlBfY>OpnA3$21@biKJsqo&0Ab4-XYpw4a zy!oGvOwzwZqzBn}X@sM?*jTHK-tpX0zd3=v_QHwNI~sp*^$iAukh3?e7wVlg!2q)6 z>Y+LXw$WjUrQ-X<4sU{X@GILGe7l6dSto>D;kD@<^LwreiX9ZWfAWm?5L+>X+`A6j zhXGt^Q}!@G^ODxG=%|gofAbTYDDT^ z!hkrat8vc-N7Z!A2J~d&YT=4872EQMXz{<=i})9W7|h26EYlGp3^@JNU9)@~g49;S z8)T3*bM7PamK8EQ&vie7_H}NWjNBKBZ!Va%rw>TsJ-)6|FrZ1e;X3Mn0P-OWIDGm`-~CVI%KlH8L{v2EG$2zF zxDBT`(S7V|<-$(9I+b}B@y<=^@xmv^cK)IV{}3zx7=iqAR{3l<6GpnlclovWwB4Wj z)P8uz0@@XQ5$`A9XaJ$`ENmCpOg=`KhBt)&EJo_r2PrpbF zW3;7C#WhlV9Ha*c!BvEiXIIYML@^#7U`OtDOvAyJda(6`NG?)EdiB7Mk``@S7Q4iI z>v_%)2d{6xMasyvh)KYUCQ$Wx<=E7x|Mzx0d5T%s6+A(;0PoSm6rG?xGlX~agP=tI ze|N7~xP!%Z;SBbexn{i5@tli;-c+5dQU5(gmy%Dn&<{&nD6hRbENhmC@b*Os6%bOD zQGA7FO5>{ih6$zm1L?G6Y4ZzWBi6pgEqVInl_(7u@S{wBB5M$JeR>(X({Ki9Ximg^ ztVpYpHW`lI)Xt&N@Z)uU9qn)MZ@#7-!NZL27RZb8$F$u>0bk3d=HRtJw#j{cjl8S$6Q&-c%qd{ZkEGS_(>*5I@VB05rM%1LJCFqK~5a$GcV zncQ7g&z-3JtIRNjSaRVlJ_rT*O>sA*|6Z_9@GX}y7;tMd%CttqZ)#cLqXljC`>rJ4 zrHD6}lPgG7$fx~g31x7n`r+7Q1z2ZK?5s{P26keRv zAE4BVn0n{&c5{*>2DOLx-ZzmXn;@HBdEt2@I|(qPUt!LOa*rSkM$6g^6h_jD`*0YL z*Y$ho5D+d4Po!wNF;BEdfVJjzG@RpNjaXC_a-1Ud*!j=GUn5iI%18+Fa?IDt3lrQO zTOMVz;G?eUuo>#MDy2Ch9T&zeJmjLdyut*wH{i@Dc6YVR-aO-*P(g=4(oGC)ubDIG zp^|wfS}QJDt)~Nqjt2Ia^hGFx;_ZC>s?n-;I+q=(7R z3)zb1MLIeOI#$u5DXY6QRAnjA%oBiP!JkXgE!784vnq4$WoYYiD-95ppP3e{w6G>R z&>2>}*?T4#&KDe^9n-jijvO}VjV!NSF1zoxQ_+-5V6o?j^ZjP;Z$>3Xjkj&7SB)sJK6SxSAqlqyP7AFj~H(mu^KqW z5A=9TelkwjCgy36)bL~?xD`pV6bjUoq&0FNWdpmA$}j$@#>1YG}D&&xi9Tt7Fl z&dW-e(PdScl{dp#X1?I;qk?QS@a}|!bt&Ptc$=~rw-J-+?vxA|+FGA74zD?VcYs&y$cnskXdMP$-JXhV$@fDMJc(g^zM3`pnKRk%Rs*h6XD}^W29uL01sNg z^}Sp(E#JQGmh8Hy8CjyQy}R=kiFYFvTHXtV%30*vWC+^<6QU1CZYxiiXK60G6Z6C_ z&dE#>w$qF13Gid5uHb68jQa%@NP*vu*Cf?FmnLeq)K~)qkAiPukS>poBiCczse$aK z*;^?aj;d@D(?!usk`Sdw(WOPA7=)(D<`I2fEaC)_w^X{gx5$i$`)ahyKkpKLgQo?I zeJ>^bvqvEw(Rm^i-&Keu@N!l=8U+W{C;PP| z>!l*9Y3Yz%LlZJ*wsHQVtcdAHr1qHk@{Q|(t)KU?OvcYRrcFOuLP++^uV>tQEOOI` z?;;^?5rQc4+C>Cvv(KNIu}My!F00(RE$wJ)cLh2{5+-4Q(79O+m@G(CPs~ggD1#1%21d>CMW+ zm%JHt*~=8UrO5p5lOX}GoR}L8&I1EWi?_AF5hAG-Bdoixs=tIzQE88V@Tqsn{ou#H zozk2!a?NbMw^N*1e`M^Z9lv&$EnPj4w6SX%6+lX{O*T_dA8x2X2{@`NE}QGHJ#(~} zN{P#Dw;lIl;tOOmuR9*oB6m)UWh7q&0 z8a4$LVF~={rEmL&tL17C+#*aJZ9S|WJ7O?s>87Vu*?=<=0k^{+Nu*{4$=oSOLC|~h zVsEWHS!2pRX)PGL6^Xctv( z@5RnF5lU$Fy=(cb&Pd&_QzqqOt}%|U`zk>#NY?a*@<_qQ`DAE5C)`8aofX;z?&A)T zZA1mr{^*A|IeoMTcfI5qXTqK7kHjh6{W4IquoMt=@(VzBm!{>&`3L4AUPKJMjIk(n y6H4nzYq6z>GkcgIzDcNDZY_!Uu7W73+b1~LI;xTA?>u1mN99icMe9(*rv43YyWPG3 literal 0 HcmV?d00001 diff --git a/imgs/ppo_walker.png b/imgs/ppo_walker.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab33b10c7fb0f2f1cf10d873ae740b100237769 GIT binary patch literal 20720 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 literal 0 HcmV?d00001 diff --git a/kfac.py b/kfac.py index f15e6a6..19f875a 100644 --- a/kfac.py +++ b/kfac.py @@ -11,8 +11,6 @@ import torch.optim as optim def _extract_patches(x, kernel_size, stride, padding): - #result = P.im2col(Variable(x), kernel_size, stride, padding).data - #return result.view(result.size(0), -1, result.size(-2), result.size(-1)) if padding[0] + padding[1] > 0: x = F.pad(x, (padding[1], padding[1], padding[0], padding[0])).data # Actually check dims @@ -164,7 +162,6 @@ class KFACOptimizer(optim.Optimizer): raise NotImplementedError( 'Layer {} is not supported'.format(classname)) - #@profile def step(self): # Add weight decay if self.weight_decay > 0: @@ -187,10 +184,12 @@ class KFACOptimizer(optim.Optimizer): self.m_aa[m].cpu().double(), eigenvectors=True) self.d_g[m], self.Q_g[m] = torch.symeig( self.m_gg[m].cpu().double(), eigenvectors=True) - self.d_a[m], self.Q_a[m] = self.d_a[ - m].float().cuda(), self.Q_a[m].float().cuda() - self.d_g[m], self.Q_g[m] = self.d_g[ - m].float().cuda(), self.Q_g[m].float().cuda() + self.d_a[m], self.Q_a[m] = self.d_a[m].float(), self.Q_a[m].float() + self.d_g[m], self.Q_g[m] = self.d_g[m].float(), self.Q_g[m].float() + if self.m_aa[m].is_cuda: + self.d_a[m], self.Q_a[m] = self.d_a[m].cuda(), self.Q_a[m].cuda() + self.d_g[m], self.Q_g[m] = self.d_g[m].cuda(), self.Q_g[m].cuda() + self.d_a[m].mul_((self.d_a[m] > 1e-6).float()) self.d_g[m].mul_((self.d_g[m] > 1e-6).float()) diff --git a/main.py b/main.py index 1fbacfc..f09877c 100755 --- a/main.py +++ b/main.py @@ -15,9 +15,9 @@ from arguments import get_args from baselines.common.vec_env.subproc_vec_env import SubprocVecEnv from envs import make_env from kfac import KFACOptimizer -from model import ActorCritic +from model import CNNPolicy, MLPPolicy from storage import RolloutStorage -from vizualize_atari import visdom_plot +from visualize import visdom_plot args = get_args() @@ -59,7 +59,12 @@ def main(): obs_shape = envs.observation_space.shape obs_shape = (obs_shape[0] * args.num_stack, *obs_shape[1:]) - actor_critic = ActorCritic(obs_shape[0], envs.action_space) + if envs.action_space.__class__.__name__ == 'Discrete': + actor_critic = CNNPolicy(obs_shape[0], envs.action_space) + action_shape = 1 + else: + actor_critic = MLPPolicy(obs_shape[0], envs.action_space) + action_shape = envs.action_space.shape[0] if args.cuda: actor_critic.cuda() @@ -71,13 +76,15 @@ def main(): elif args.algo == 'acktr': optimizer = KFACOptimizer(actor_critic) - rollouts = RolloutStorage(args.num_steps, args.num_processes, obs_shape, envs.action_space.n) - + rollouts = RolloutStorage(args.num_steps, args.num_processes, obs_shape, envs.action_space) current_state = torch.zeros(args.num_processes, *obs_shape) + def update_current_state(state): - state = torch.from_numpy(np.stack(state)).float() - current_state[:, :-1] = current_state[:, 1:] - current_state[:, -1] = state + shape_dim0 = envs.observation_space.shape[0] + state = torch.from_numpy(state).float() + if args.num_stack > 1: + current_state[:, :-shape_dim0] = current_state[:, shape_dim0:] + current_state[:, -shape_dim0:] = state state = envs.reset() update_current_state(state) @@ -103,7 +110,6 @@ def main(): # Obser reward and next state state, reward, done, info = envs.step(cpu_actions) - reward = torch.from_numpy(np.expand_dims(np.stack(reward), 1)).float() episode_rewards += reward @@ -115,17 +121,24 @@ def main(): if args.cuda: masks = masks.cuda() - current_state *= masks.unsqueeze(2).unsqueeze(2) + + if current_state.dim() == 4: + current_state *= masks.unsqueeze(2).unsqueeze(2) + else: + current_state *= masks update_current_state(state) rollouts.insert(step, current_state, action.data, value.data, reward, masks) next_value = actor_critic(Variable(rollouts.states[-1], volatile=True))[0].data + if hasattr(actor_critic, 'obs_filter'): + actor_critic.obs_filter.update(rollouts.states[:-1].view(-1, *obs_shape)) + rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.tau) if args.algo in ['a2c', 'acktr']: - values, action_log_probs, dist_entropy = actor_critic.evaluate_actions(Variable(rollouts.states[:-1].view(-1, *obs_shape)), Variable(rollouts.actions.view(-1, 1))) + values, action_log_probs, dist_entropy = actor_critic.evaluate_actions(Variable(rollouts.states[:-1].view(-1, *obs_shape)), Variable(rollouts.actions.view(-1, action_shape))) values = values.view(args.num_steps, args.num_processes, 1) action_log_probs = action_log_probs.view(args.num_steps, args.num_processes, 1) @@ -164,6 +177,8 @@ def main(): advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-5) old_model.load_state_dict(actor_critic.state_dict()) + if hasattr(actor_critic, 'obs_filter'): + old_model.obs_filter = actor_critic.obs_filter for _ in range(args.ppo_epoch): sampler = BatchSampler(SubsetRandomSampler(range(args.num_processes * args.num_steps)), args.batch_size * args.num_processes, drop_last=False) @@ -171,8 +186,8 @@ def main(): indices = torch.LongTensor(indices) if args.cuda: indices = indices.cuda() - states_batch = rollouts.states[:-1].view(-1, *rollouts.states.size()[-3:])[indices] - actions_batch = rollouts.actions.view(-1, 1)[indices] + states_batch = rollouts.states[:-1].view(-1, *obs_shape)[indices] + actions_batch = rollouts.actions.view(-1, action_shape)[indices] return_batch = rollouts.returns[:-1].view(-1, 1)[indices] # Reshape to do in a single forward pass for all steps @@ -183,7 +198,7 @@ def main(): ratio = torch.exp(action_log_probs - Variable(old_action_log_probs.data)) adv_targ = Variable(advantages.view(-1, 1)[indices]) surr1 = ratio * adv_targ - surr2 = ratio.clamp(1.0 - args.clip_param, 1.0 + args.clip_param) * adv_targ + surr2 = torch.clamp(ratio, 1.0 - args.clip_param, 1.0 + args.clip_param) * adv_targ action_loss = -torch.min(surr1, surr2).mean() # PPO's pessimistic surrogate (L^CLIP) value_loss = (Variable(return_batch) - values).pow(2).mean() diff --git a/model.py b/model.py index 515c8af..918f066 100755 --- a/model.py +++ b/model.py @@ -3,6 +3,8 @@ import math import torch import torch.nn as nn import torch.nn.functional as F +from torch.autograd import Variable +from running_stat import ObsNorm def weights_init(m): @@ -28,9 +30,9 @@ class AddBias(nn.Module): return x + bias -class ActorCritic(torch.nn.Module): +class CNNPolicy(torch.nn.Module): def __init__(self, num_inputs, action_space): - super(ActorCritic, self).__init__() + super(CNNPolicy, self).__init__() self.conv1 = nn.Conv2d(num_inputs, 32, 8, stride=4, bias=False) self.ab1 = AddBias(32) self.conv2 = nn.Conv2d(32, 64, 4, stride=2, bias=False) @@ -41,19 +43,20 @@ class ActorCritic(torch.nn.Module): self.linear1 = nn.Linear(32 * 7 * 7, 512, bias=False) self.ab_fc1 = AddBias(512) - num_outputs = action_space.n self.critic_linear = nn.Linear(512, 1, bias=False) self.ab_fc2 = AddBias(1) + num_outputs = action_space.n self.actor_linear = nn.Linear(512, num_outputs, bias=False) self.ab_fc3 = AddBias(num_outputs) self.apply(weights_init) - self.conv1.weight.data.mul_(math.sqrt(2)) # Multiplier for relu - self.conv2.weight.data.mul_(math.sqrt(2)) # Multiplier for relu - self.conv3.weight.data.mul_(math.sqrt(2)) # Multiplier for relu - self.linear1.weight.data.mul_(math.sqrt(2)) # Multiplier for relu + relu_gain = nn.init.calculate_gain('relu') + self.conv1.weight.data.mul_(relu_gain) + self.conv2.weight.data.mul_(relu_gain) + self.conv3.weight.data.mul_(relu_gain) + self.linear1.weight.data.mul_(relu_gain) self.train() @@ -97,3 +100,112 @@ class ActorCritic(torch.nn.Module): dist_entropy = -(log_probs * probs).sum(-1).mean() return values, action_log_probs, dist_entropy + + +def weights_init_mlp(m): + classname = m.__class__.__name__ + if classname.find('Linear') != -1: + m.weight.data.normal_(0, 1) + m.weight.data *= 1 / torch.sqrt(m.weight.data.pow(2).sum(1, keepdim=True)) + if m.bias is not None: + m.bias.data.fill_(0) + +class MLPPolicy(torch.nn.Module): + def __init__(self, num_inputs, action_space): + super(MLPPolicy, self).__init__() + + self.obs_filter = ObsNorm((1, num_inputs), clip=5) + self.action_space = action_space + + self.a_fc1 = nn.Linear(num_inputs, 64, bias=False) + self.a_ab1 = AddBias(64) + self.a_fc2 = nn.Linear(64, 64, bias=False) + self.a_ab2 = AddBias(64) + self.a_fc_mean = nn.Linear(64, action_space.shape[0], bias=False) + self.a_ab_mean = AddBias(action_space.shape[0]) + self.a_ab_logstd = AddBias(action_space.shape[0]) + + self.v_fc1 = nn.Linear(num_inputs, 64, bias=False) + self.v_ab1 = AddBias(64) + self.v_fc2 = nn.Linear(64, 64, bias=False) + self.v_ab2 = AddBias(64) + self.v_fc3 = nn.Linear(64, 1, bias=False) + self.v_ab3 = AddBias(1) + + self.apply(weights_init_mlp) + + tanh_gain = nn.init.calculate_gain('tanh') + #self.a_fc1.weight.data.mul_(tanh_gain) + #self.a_fc2.weight.data.mul_(tanh_gain) + self.a_fc_mean.weight.data.mul_(0.01) + #self.v_fc1.weight.data.mul_(tanh_gain) + #self.v_fc2.weight.data.mul_(tanh_gain) + + self.train() + + def cuda(self, **args): + super(MLPPolicy, self).cuda(**args) + self.obs_filter.cuda() + + def forward(self, inputs): + inputs.data = self.obs_filter(inputs.data) + + x = self.v_fc1(inputs) + x = self.v_ab1(x) + x = F.tanh(x) + + x = self.v_fc2(x) + x = self.v_ab2(x) + x = F.tanh(x) + + x = self.v_fc3(x) + x = self.v_ab3(x) + value = x + + x = self.a_fc1(inputs) + x = self.a_ab1(x) + x = F.tanh(x) + + x = self.a_fc2(x) + x = self.a_ab2(x) + x = F.tanh(x) + + x = self.a_fc_mean(x) + x = self.a_ab_mean(x) + action_mean = x + + # An ugly hack for my KFAC implementation. + zeros = Variable(torch.zeros(x.size()), volatile=x.volatile) + if x.is_cuda: + zeros = zeros.cuda() + + x = self.a_ab_logstd(zeros) + action_logstd = x + + return value, action_mean, action_logstd + + def act(self, inputs): + value, action_mean, action_logstd = self(inputs) + + action_std = action_logstd.exp() + + noise = Variable(torch.randn(action_std.size())) + if action_std.is_cuda: + noise = noise.cuda() + + action = action_mean + action_std * noise + return value, action + + def evaluate_actions(self, inputs, actions): + assert inputs.dim() == 2, "Expect to have inputs in num_processes * num_steps x ... format" + + value, action_mean, action_logstd = self(inputs) + + action_std = action_logstd.exp() + + action_log_probs = -0.5 * ((actions - action_mean) / action_std).pow(2) - 0.5 * math.log(2 * math.pi) - action_logstd + action_log_probs = action_log_probs.sum(1, keepdim=True) + dist_entropy = 0.5 + math.log(2 * math.pi) + action_log_probs + dist_entropy = dist_entropy.sum(-1).mean() + + return value, action_log_probs, dist_entropy diff --git a/running_stat.py b/running_stat.py new file mode 100644 index 0000000..41fe711 --- /dev/null +++ b/running_stat.py @@ -0,0 +1,44 @@ +import random + +import torch + +class ObsNorm(object): + def __init__(self, shape, demean=True, destd=True, clip=10.0): + self.demean = demean + self.destd = destd + self.clip = clip + + self.count = torch.zeros(1).double() + 1e-2 + self.sum = torch.zeros(shape).double() + self.sum_sqr = torch.zeros(shape).double() + 1e-2 + + self.mean = torch.zeros(shape) + self.std = torch.ones(shape) + + def cuda(self): + self.count = self.count.cuda() + self.sum = self.sum.cuda() + self.sum_sqr = self.sum_sqr.cuda() + + self.mean = self.mean.cuda() + self.std = self.std.cuda() + + def update(self, x): + self.count += x.size(0) + self.sum += x.sum(0, keepdim=True).double() + self.sum_sqr += x.pow(2).sum(0, keepdim=True).double() + + self.mean = self.sum / self.count + self.std = (self.sum_sqr / self.count - self.mean.pow(2)).clamp(1e-2, 1e9).sqrt() + + self.mean = self.mean.float() + self.std = self.std.float() + + def __call__(self, x): + if self.demean: + x = x - self.mean + if self.destd: + x = x / self.std + if self.clip: + x = x.clamp(-self.clip, self.clip) + return x diff --git a/storage.py b/storage.py index e449fd8..325b58e 100644 --- a/storage.py +++ b/storage.py @@ -2,13 +2,19 @@ import torch class RolloutStorage(object): - def __init__(self, num_steps, num_processes, obs_shape, action_shape): + def __init__(self, num_steps, num_processes, obs_shape, action_space): self.states = torch.zeros(num_steps + 1, num_processes, *obs_shape) self.rewards = torch.zeros(num_steps, num_processes, 1) self.value_preds = torch.zeros(num_steps + 1, num_processes, 1) self.returns = torch.zeros(num_steps + 1, num_processes, 1) - self.actions = torch.LongTensor(num_steps, num_processes, 1) - self.masks = torch.zeros(num_steps, num_processes, 1) + if action_space.__class__.__name__ == 'Discrete': + action_shape = 1 + else: + action_shape = action_space.shape[0] + self.actions = torch.zeros(num_steps, num_processes, action_shape) + if action_space.__class__.__name__ == 'Discrete': + self.actions = self.actions.long() + self.masks = torch.ones(num_steps + 1, num_processes, 1) def cuda(self): self.states = self.states.cuda() @@ -30,8 +36,7 @@ class RolloutStorage(object): self.value_preds[-1] = next_value gae = 0 for step in reversed(range(self.rewards.size(0))): - delta = self.rewards[step] + gamma * self.value_preds[step + - 1] * self.masks[step] - self.value_preds[step] + delta = self.rewards[step] + gamma * self.value_preds[step + 1] * self.masks[step] - self.value_preds[step] gae = delta + gamma * tau * self.masks[step] * gae self.returns[step] = gae + self.value_preds[step] else: diff --git a/vizualize_atari.py b/visualize.py similarity index 88% rename from vizualize_atari.py rename to visualize.py index c67c3b8..ef80268 100644 --- a/vizualize_atari.py +++ b/visualize.py @@ -106,12 +106,20 @@ def visdom_plot(viz, win, folder, game, name, bin_size=100, smooth=1): fig = plt.figure() plt.plot(tx, ty, label="{}".format(name)) - plt.xticks([4*1e6, 4*2e6, 4*4e6, 4*6e6, 4*8e6, 4*10e6], - ["1M", "2M", "4M", "6M", "8M", "10M"]) + + # Ugly hack to detect atari + if game.find('NoFrameskip') > -1: + plt.xticks([4*1e6, 4*2e6, 4*4e6, 4*6e6, 4*8e6, 4*10e6], + ["1M", "2M", "4M", "6M", "8M", "10M"]) + plt.xlim(0, 40e6) + else: + plt.xticks([1e5, 2e5, 4e5, 6e5, 8e5, 1e5], + ["0.1M", "0.2M", "0.4M", "0.6M", "0.8M", "1M"]) + plt.xlim(0, 1e6) + plt.xlabel('Number of Timesteps') plt.ylabel('Rewards') - plt.xlim(0, 40e6) plt.title(game) plt.legend(loc=4) @@ -130,5 +138,4 @@ def visdom_plot(viz, win, folder, game, name, bin_size=100, smooth=1): if __name__ == "__main__": from visdom import Visdom viz = Visdom() - visdom_plot( - viz, None, '/tmp/gym/', 'BreakOut', 'a2c', bin_size=100, smooth=1) + visdom_plot(viz, None, '/tmp/gym/', 'BreakOut', 'a2c', bin_size=100, smooth=1)