From 094b6715cca70ee4bf42000701e0157bd5a7f40a Mon Sep 17 00:00:00 2001 From: HokageM Date: Fri, 17 Nov 2023 13:15:48 +0100 Subject: [PATCH 1/7] initial iq learn --- src/irlwpython/DiscreteMaxEntropyDeepIRL.py | 11 +++++------ src/irlwpython/IQLearnIRL.py | 13 +++++++++++++ src/irlwpython/MaxEntropyIRL.py | 2 +- src/irlwpython/MountainCar.py | 2 +- .../learning_curves/maxent_30000_network.png | Bin 9234 -> 23218 bytes src/irlwpython/main.py | 3 ++- 6 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 src/irlwpython/IQLearnIRL.py diff --git a/src/irlwpython/DiscreteMaxEntropyDeepIRL.py b/src/irlwpython/DiscreteMaxEntropyDeepIRL.py index 66bf723..02abe64 100644 --- a/src/irlwpython/DiscreteMaxEntropyDeepIRL.py +++ b/src/irlwpython/DiscreteMaxEntropyDeepIRL.py @@ -1,4 +1,3 @@ -import gym import numpy as np import torch import torch.optim as optim @@ -16,7 +15,7 @@ def __init__(self, num_inputs, num_output, hidden_size): def forward(self, x): x = nn.functional.relu(self.fc1(x)) x = nn.functional.relu(self.fc2(x)) - return self.fc3(x) # torch.nn.functional.softmax(self.fc3(x)) + return self.fc3(x) class CriticNetwork(nn.Module): @@ -36,7 +35,7 @@ def forward(self, x): class DiscreteMaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, feature_matrix=None, learning_rate=0.001, gamma=0.99, + def __init__(self, target, state_dim, action_dim, feature_matrix=None, learning_rate=0.01, gamma=0.99, num_epochs=1000): self.feat_matrix = feature_matrix self.one_feature = 20 @@ -75,7 +74,7 @@ def maxent_irl(self, expert, learner): self.optimizer_critic.zero_grad() # Loss function for critic network - loss_critic = torch.nn.functional.mse_loss(learner, expert) + loss_critic = torch.nn.functional.mse_loss(learner, expert) * self.learning_rate loss_critic.backward() self.optimizer_critic.step() @@ -142,10 +141,10 @@ def train(self): torch.save(self.critic_network.state_dict(), "./results/discretemaxentdeep_30000_critic.pth") def test(self): - assert 1 == 0 # TODO: not implemented yet + self.actor_network.load_state_dict(torch.load("./results/discretemaxentdeep_30000_actor.pth")) + self.critic_network.load_state_dict(torch.load("./results/discretemaxentdeep_30000_critic.pth")) episodes, scores = [], [] - for episode in range(10): state = self.target.env_reset() score = 0 diff --git a/src/irlwpython/IQLearnIRL.py b/src/irlwpython/IQLearnIRL.py new file mode 100644 index 0000000..e70c5c4 --- /dev/null +++ b/src/irlwpython/IQLearnIRL.py @@ -0,0 +1,13 @@ +import numpy as np +import matplotlib.pyplot as plt + + +class MaxEntropyIRL: + def __init__(self, target): + self.target = target + + def train(self, theta_learning_rate): + pass + + def test(self): + pass \ No newline at end of file diff --git a/src/irlwpython/MaxEntropyIRL.py b/src/irlwpython/MaxEntropyIRL.py index f415bdd..8a2c4ac 100644 --- a/src/irlwpython/MaxEntropyIRL.py +++ b/src/irlwpython/MaxEntropyIRL.py @@ -1,5 +1,5 @@ # -# This file is hardly inspired by the IRL implementation of: +# This file is a refactored implementation of the Maximum Entropy IRL from: # https://github.com/reinforcement-learning-kr/lets-do-irl/tree/master/mountaincar/maxent # It is a class type implementation restructured for our use case. # diff --git a/src/irlwpython/MountainCar.py b/src/irlwpython/MountainCar.py index 981e426..0f66c5e 100644 --- a/src/irlwpython/MountainCar.py +++ b/src/irlwpython/MountainCar.py @@ -1,5 +1,5 @@ # -# This file is hardly inspired by the IRL implementation of: +# This file is a refactored implementation of the environment form: # https://github.com/reinforcement-learning-kr/lets-do-irl/tree/master/mountaincar/maxent # It is a class type implementation restructured for our use case. # diff --git a/src/irlwpython/learning_curves/maxent_30000_network.png b/src/irlwpython/learning_curves/maxent_30000_network.png index 273e9aec7e47114093514a90c2809b7835fc510d..73cb168faa2845dcaf32051f23eef0d18044edc0 100644 GIT binary patch literal 23218 zcmeFZbyQVt`!2c`AR%4St%M*5C|yb_NC?uQfPi#&igbsdw1j}L=#WO~7U>4*?uNyF zrtkOd^Zm~L?J@Q^W1REXag2BP%35>IXFhS?*L_{rO^C9hEbeW}+b|dm_nDm3OBf8r z7Y2jRW1@qfJRY200)GiQN^3f*+L$=Hys>`^d-2B6*3!n&@|_{Q^ILm|cQ)3%oC2KO z9Q0<6jaeC{5Q~l@I3L{cQBYX-7~2tYOX2U zGcK+q%aiDP!dS+V@|e*C&&^PN*S%I&AqgRPUZR5b7Y%iswd@)2( z?l;H~a7g8Uq2!>4GsH`F5|A1d&CZXk=@ieuZ|%wY{h zVFZ78aBU{w!QfA4!#IqHkdW{*4wVG-LEIZuIVmYAV;)Ob2>4hb5SJc&8q-w*zYASP z!RHG;m11r|kA^Nb{{Juj|6;;arJP|*JzZTtCdy4!zNxXfy18{lN`iH8%V51-q~8!4 zO3MCoYAU7U=Q!-nPw*u|O3M4f=wRVUo7abORch?tPH<?y_JL61p*ieJRB2Qly^9!IqGp-^>)%*##yjEeMxBrvL7}cgM>;zKMx>F54)E zhS^eJC*y-1EN5C))>>w!vM=B$cR5|Ri_&z($U+A0h6mm4RYR>NpBbz-CErVgBb+~g zfKX)toPysm$D5TxLfQqg5h!Wy&vi~uT@08R84pCjfpIkciH7iAChZvTI;ByrD$KK) zMcWv*GvEZDb3mWp<=&r7Z*qLrOMn9Fh(axHSh-LDZ{!BOk(_(2ru*C?%V94C0(qqR zx&?jA1PpWl8fehdr#r}++oZm4dn%3OFj#~Tx~rT#agWCgEH*iw1fkzR zdA3BHE6s?d?@e*`2ixj;O~p+sxYMB&Ox5S#IfvC=`+u5GwkIz(i^G^?jYWzZZ(ps7 zN7BhZgY)n#Eio_-w1F4I;4~QBFiq>a8LPI!mXdzAS!r%pE0E=O?eu!z(CWH_u2P6= z>;n0z;8guOe>u@a$ExylSfePI`TddAn)2%(C{|u`Vi_t-D&hyhn#jYbO9#Rj zQ(j}#@f>+FwfvX2yuH2il)s={9IgA8n+^zBI;{O-5IGq)+B-ayG&5uU`Xbr6!&|*b zH$=#3qj_KeAD4=+wLOAr=9nm$TDRs;y;n{)OkY0}d2agp_ubX)PKMZ`X16I?0W>4G-MnX@vr?SjP zzKvJg(0x@(kNotBoI|^!v#PI1ukKg5snXHz932K8wS=+pT}CD*yQNM-3a$_ZMVd{7 zao5k?0yCBQUkp}Wf20OAqZ`9%aeLDch>i}_2igMGLm7T&H)y_}d1n$Mf<@93Gg(8o z2m&gdx3#5YWEe$7X{5vMw7tKD{m}c$^)3rb%jqcnyTQRh%?9_!M8w2!*i4;EN2SGB ziTAbplsB#S*_%i2exqTNarO=!Y9rLq(9q}~KPE*Yk^MezjBis=__i@_R9VsNu006X zDyO!=>FWHIgcWPCrP++kZY|Q2(A3{{>d@0$&MjX<2E`tI%7Qj2?2vsI(N2#bo6t#jU{J|U&0jXXPZJq=(% zAt25gxzzx_%bz6!R}#%ZV4w-u%&FNfb_nzNh$CH3SMYx+F03xW?CgsAWTaN!jHBCb zjhC{jWTJH^JP6CqzFVkO-hNWEv}7F5Wib23!%0+7@H}lQFMZ&JySq@KdO?eSUWwR^ zZo%f5%T8m{B_6Ae`Y^vW%xP1|_q=@^>E?A5lga4i4skRy( zST&jcZb$yuJl<-?ys``{`>AU2=F4JK#{gba-%wKN>n;|Fu_6hn51VOG)GyL->JKBU z8lBkpmg3xQE>yBwHT^z+ZnkOKm*XTPO|y=Kq2IdoMKM+A)N|Zm$dqe!^g;ak`Z~eG$Ak8SNc=K zK72q+5pudcRc#|XkS4m{jEX;=RIT6O{$p&6?E3PwV=zm$)brfFH%)YEVQpq_p{3OA z(4;p-kT@hHBse7G$83WKw{a(d7FUFVSr-w)`^IZbY)qaDF6v>vnZnk3Y|>BSa`kPr zknJpH>^5oZK@i>T^sr#e&>z%7j&kp&st_-~Dp0f;ma>j~d!>qwN1c}<=+OSA&L0E+ zew5fno?)qG{PU0Z*;I2C8;lIt)eDu)$BGbV7Z>-BH^(&iEXSjZIr8)KZ^Q0Aeq5D+<_TLVP|q*ES2u;u4RxbL7L^wU0-IMnn(;pfo<3hhUvfFX!{q$vom_^8C zPRf|G9=(LX6&Fq_Q=s0wGn1Kct~y@979CB$@jIt&@LqTNfH>LMa=zF#$=cl9WV;s z;j?Nzm=+up#UOMO1Mnbr`a46ytk4;o!ZUb%z0~#LKy&sp`$O`!?vE11`jZ#aHAU&> zHlrK}qw>%&R3XP-qbx5_ zGP9PK^IyqxY!}bmW$b2$-Y9Pox$btB&ud!YzVH-49XBoGsYV*JIend|5csUOjy5%H zGNz+ffzMAW-UqzWG{=J%1tXi=M|n?gy`JE)YEWgNfBZ_HR?GVg?z+Kdb&aS#;>HfT z*7WC5lq8NR1?a=RTqUc*9qH*Nc4xO-i9b6Ls{wty$ zI-mGt|KM;4DkdYevPMYnclN|+++1@h=Y;0*^7{Q!u5p{bCr0bK#cg%n$M2V~y1d-g z$6g$~96{CG7G_^g5K{_(p?$f0qA^QnlWK0okD!5+!GZCBqB2wbU$vE0Vx9sIy=v=4 zT#S5ZGOuIaGG<&Z6017dNBZ68l|F|@0OM}u%t#jcdK zQ#=liZ=s+{H&~}mb4VFOFmhV1;gal^iNnKCU)bwSb*ly+pAL!_B0s)JN*u0CUSvFJ z-kLZ#SPBqgbu$0P*Yt>R@ERH))1^hHNpEywRt8u=YC_dl1uKF>Z8U-?kE{z3_|$nf z$&Rp&T_(}#R0XN_`5e}hj=QYlh3f1mC@9fMNwtVJr<-eXLyPW2AkSr; zQC0<9mFohz@7*#RlCe(vDd0VAS6kQU6)|!JpLC7w>XLA-g5DKEZquyn@*Kx}H#Sdn zYcgNFJzb2tprqp}Mqa5>pQ}c-Hy#m{7>5kY-QuxGQ0LO5=fWVQfFL54`DlD<#$MWezt@baeRz6xXxMDQWHGA1p_KM_yFlk9Ss^KV!tCu1}1{ZO@Ioek$$bY|*aG(o5TJ$kFAowT>y5wpfuEfP3o*->5Ha$gfFolao5q#Xt}+_8WSn9C3OsLo&`#e(Nx2|FlU9s_AA@imI+^?h%1@k8#!8!zmf)NXF}rDP z>D8jCean8)LPm>cIZn?X#~x0@o}i^A@$~&Lt5miFH0Q5(^%363uiON65zk3G-lz#V zlc>gbIj$2aH`b3{Ra#(J&T{a_6&!8m;`SY`B)`lei0Ow;oIf~m7l`VmW!s=eFTb6c z%Hs@rH?1OF!g8a$K7*+$3Eh->ksVNjXdUi~ZJ?($d)JF7k)vIBH(ora#zku_ zdHCha&VcRmZRMgAK3VHD~L)-Yo>L?cmJ7zUJm;J&R-BJ2-gy(~7Jf zBv;HR(G&8kt1ALZ%FuU1UuX7@*)@u!QiYu6S671qaj6U!+as)>E1EcLCuzD++%3g=1@L>+8Wx=_)Jd?a6>NQIAZY8>E2kJPbf^LJEoyCfUgE zhxekp(9pXT=k>|B%#Zo!VCh~f7pn^L4wlHDKU>wDOcoZiaJ#Y+lWl|Ld~l{<){_-j zI@Q)~;S{_(XVYW`o_^usIG!gHrg;WUV(v$4es5X=-z3a@_zcRCcHRLIe}GxCtY>On zcN9PJrV5Xxa``LJ3u+YzJH;kS2L8`5LC@CZG?19UoMc&fZZSbLUfJU`kgG8u z#-5;FK%N*AyyhHe2^&Zkj~dhWz`Z#i@KLUJ-4_<4qoa%Bvzlxk+c7NoH_&EdtFoG` zv{>D9T3A>Jj*4p9JOqoP0;Pns%CBMraU5y^f(M|kaZ3Id*j_N&a6dq_aJx(~ zPatjktPG8e2nh&Ydwl5rUY3euI>m?J)Ox9p_t|6so$?WZlOmq-*KmhZpF`&P-QveS zFOory6*v_Pze^8;3O@sHHhyfv^*C$F=Cw65K%~qZ#(eq|Ea-<&K2OaR9~ z`j}z}F=4(VFWW0MHIj?tO_u>H^Wi+d?Wt-eF)`XZVQmWz;MJPtxf(v?$R{%1y^FRw zknVC;UrS3wWT>-J6>)Jst;vxfoR+xeJ)Gas>wYva`;i^gOUM@>&wUc9vCU=W1lD1(Zdkdz4R z%BKMPmx7WvoKBn;JX&^8XHmKScvR=?WXc9i114;3wn4bapefR6b9CZlq}Ivek@+wt zRLZH|0TrmPFD(1(*PnB9b0NjCBGNK}X09;q>rc7;5;1gGSbsHXK`1%EbQ`+ zMmDH>jyK@4Q9?{#R!cNnPhTHzG=~sF$pB-n$;t7yK=C)V{P*a%l;gCZdPIkbfJmFC zTf+m(&?wg5J3f}aL0;P(t*LMrG*UxbowaVAJP@BQvM-t6Xr=eFoPvUsf&$LT&P*7? ziN+Q&X{-=G`|Exx3HzaJECQ+m1i!^snjbv{g&Y}bY>4v$z2rUvYg%_XjvJ(oIS%7* zhL*>^ZeS<*f@<>5QdgYWY`tJ+X69bM@b3Kam_fDG5O{r0P=IMxm=RL)TZcn)SfEiX zgL?ejiIL@OgB?+%rK*qD5E40B1Xm-;a9pqVK}=rF)U%CRjG#o)xwuP3?fKlWB!r?A zYTtu)UD$#md=m?wVd(no%~=Din7Oy7o3i4B)-)4IaW4wc4C z9@R2Rx4xi{pb8t>m1;e;X_f>?bvioQ`?~BIGWjdee>|j=;5%Vl3yZrRt7e1en zZ>8rwVM0!=vALZgowQI2$kR}AM!6Ppds(pB*W-0jR>)zObavrXs-F|OI5s#VEgSY$ z{Z5HZI!L+MbRZz>8uwEp()eD0S1WjVOS4Q$XLnqMN|=x!LjEf=E+_ghUL8})zR%EKF>)2(-RS2kS>(R=_xE#HU0UX;|v=oSa8T8(C!$E`5@r7Qz^}{q2y>fbPV^ zRA0Hn9~j!A4qxl3rS3xMo8@v5AF(qcuaB2G^{N0}lOt2VM8ceeF*Y1bb{sBk;fU(j z&Yman$q5hIVu#iVKT|;$m8V*v z#$$|yb_sD#cBi65JikAB$Xj=z==i%}C2Ib@Zg&@957E7)75durJXQp)Ac*V#ToPw& zY~~bp=fIv|IUouju)Z7L1!@4zcnyuB>vGrPSeC8}OoYZvUD)zSfrNGv*epx>;Js3e z_YD!&!*XCc>O&(&HcE|_m+2W#p~bk{)m27Ju&mS-E0O;)Q@`}7^&LigE`YTZV?W+Y zxDy5t$~hq|XF?)ph~JlxPHN~`THBM*H8VkU=EoK9z>CKuL&)d-J^6}@8JC2<;NW&Yi zUP1%Fm*n#WFIQo ze3roxC&V>G%l<-`jxmg2c}b;u5++Y~;@P0Z^&l^Uqxk}`v@l)cP}TA4i=#$mPFRnYkL{=T-TYYEu=0ffX%2@?~|O5)EV zo=RE226WuUa6YR}6-N@ERVYZyO!71za3wrFMJ6lWp&A$%Om+NhX|cOHv&+uT9g zR+QQz*3!~KXmexjoqTlUsEJSy!Whg`(Y{_u2AhafrrH|P1G2K9tvtrNL@M7Bh$~rc z(x(jQ8E6UsT5JKsvXniGjf+!haCZtSW;1B4-*)ix^OI9ltn%vhPG0g*SS6sM3Ud)` z$Cz39#Q=^^N|yFxJISFmQHWVDSYN>e?A{R#zwvz zq(3DDAP;&`(U}~IjtHut;bFC@#YY_q^q_VM%c-{ZP71zl(n(O-+X+Kn$V0p1!3;G# zJT&xallS#b&5H=i$M)B*1?q_Cj~@e?Zje+EaR!#c7J20sWHtOBEMB`|Y4cCF#x>6F zk8!EKdA5Q07@3(;G^Do*^&bG#P!kORQAP$m+O1opYZk;rMDyF*5%cq}VStS#Z;zsj z>g`n^d7w=KBOoIS!l3gc0Mk%qRb@35NXR5JenJd>T2fN-vw?u;WA;s>OA04OQG7gW^`qxGhC_J+06aJ0~C9E z<6H*&NMBg9`K|7RTbz2asezs6(AQL(rQCr;p!O{u1fBljFaDayT_3~OX8-6)w^;%E zF;x+h=-)Z9RcyLE-7J*`0=f!(V&H0#+MLMLqbGcR;rEkJ0#Pp?m{l%^nxTgck{I|qsphaiUCr#~(-aO%WiRQjEbrMxt% z2ERG=fl51U=#p%i2xAs{`-ni?wu93-D1fbk5UK{_H8Fc^3S&?r{pY|&((r(dUv5Xg z_H=86)58xI|wU5%tBd5Hz2>h=FPwV?&KC77jnW}*U=ww);!ka7gc zs3bB`I=hMF4Gd}ogLSRWY{A~2uk>Bg-yDT|U7}1?_bC4P3<5Ffdw0hVovID{f$Fl- zAo8!2TT<+uuQrb&%HmuhHSoN`y%MS}9-znQoSnfK7&4Jaj~cB`5$jnrK1+h*@`3KY zKl$KJ%R|DuW=`p1AS~2`U3htKQ`(-FO>-FI+1dTMMA*O0kj9>P2gzxfo`0N_jrjo2 zJ_6Dlc;xlG-!H=@sNs z)~4c%eV4o7d1*?b*He`R-?2jeuCExVtVV2_9&lmA)CGJ9R{a6nn=rL6k6!KWf~zBl z9xL6{-hl=^UZ+tYi23MqguBqrmR5~mr$bu@YFC$UlQ2O5)%IiNv{IR6Cd=W46sbshIBjHcNm2H(mS$HN#9rW#AJ7Keih!$Xe$z!y?z4 z?%>T1I=x}jku=~W#^$Rqm0m64gQp!*3&2u@?iD@8#ZOFahc;R_)1{!wYF}KUzuebn zajiTovc01cOB@^Pb9gkqf7+H!xKY87+>FH;-11+7Rp}Zo&2q-w`hW#q&U9hj;1uYd z@v<6407GQsKQ<3u_CvLIh+aM0=BMXY(KY&pC!|;eG)2}Z5@`@x$&Vp?akeoJ2kjNx00S~G<3Tbvfa-F z+sJZb*v4uStge0er;s;P%|IT^0FPuRt<%O`Ny&0*6^K2uBpK+#~#$1rALQxU>>DKC^Ez)~zTh z>L-ineSy`DfLi=(3y&J-C)f> z1F*TBw={L@T?rc-8_9*8Ie@G&|4ZOxZ4gzXNcRT_^M~F!*V5Aqyi zc6QcmvV!ftTAnW+jgY`2dq^)FFZuE>y%1mmYEk#$suzF7LYjYxh4lnH;YwnI8#)-# zA()Ye@Tqhn=5F>hZQ5wwEu zYbAO<+NSF=)oxz-2gtxRVlMv{2u0?O*0ryDd7&-xLOGi6Eg9FBuU8jyH@>?~WRIyN zPJvKGPD6vs#Z~Mf287iZhfTx6{l$*On$JZB#{z#X6*pJICS zXgFs;_5y@ifJ@gklKBkXP70@~jYUAfoS2Zvl9A|3DjWI~Wo?ZT@}IcDc4t};CLvl^ zD!_3E8)7NICWJ}I$zeM0&Tj8j0(PLHUP0s{ix02qdM85tHP zsi`@xmp%nRjA1Fs+HuVOt9(XbcnoqF!HyK@?nN`{H%66nb2z?V;#82A?xARXr~G#x z+kE}O>1ju^A1b%qA1O#u?TDi5$j~_?YS{aU4fBNrbs+t%4dvoPc;taj)$5-hu*gMR zOAvlk0G=tP2>5XuwbOHR6CSP(bO4jhL;EGUcf}D$rkBnLS}|Qvorqfemg2a%kT=KS ziH@LZOI@rqhaYeDC>kjSTEO710kQ_i83Qs81kt)<<|?NC1WzR-C&z^C?eG5p0C{0? z(I2RvM>{iA(4l00kz_n2d%Q7H`lbaPOvM+w#r98v4$NZLN2-xu zRZSL7YH8{O!FY{x%jV(}#3?Xl<*7a6@VQd4#`|4NBkUVbVuw4Ah?$ln0#Vdu|8PLN z@7Yes&hAHz)`NE3`9IP%T5{>bLrpO;f7%&hfk-o`mz@)GuULhlJGpvp)V%IlTre#7 z-P}JZue$?!*6-?45zVLAu%iCNA@U$A`C?xz! zS~{LCCdSZhIrP)IpIlBFa(nu7;>a2t0#iokRs;@ho?!(ECz21SmZq8Tzi21*x{sK|g0)McP1b!_K~Amhi)YjBLye#u?eW^&ViYQr;i8$KMO3M)+Cr0R z=W{O9G(VO9e#fFtiZta2^h7K%D;t!CGP_DkmVM9i#ZI4v2rroR4*0r*0sjt zy*N|?AVs9d7Y=boHYGe%;O+SNe1(qoTC_#2lIp2Vvhh&#vV%d?N;3p*E!xM=_3`YB zZ?5sjOC^UbVaFl38F+0S7RTT14(vZ^wS|JH>V{572dSYp)2#g1H3O5ChO}$#5q=o7 z(W!yq2+4~e zI`q6@K5=1-q=m3s?q@N*f{v)fME~i+&V0TXZQ!0iTPiPl0ejNh>Yc)ahw@@c z1P+%7A<9G^$O9C63?S^7>R3@9D!F?*x^l;4#h`iQvsHJfY~=U3ADpt2pWAwHtfAle+L;frMGY3~opf<@kJZG(dd^5u&}*qySWUkxSj;hOIPh?QRY zB3`p-b)P*yfR@q}tS}W*W0U=LSCef38~Jwv`b97D)E!8?##AskZu!RE1ANJW*+%n; zpkO2uO|)reFUjH!T;$pU4Fpe@t#LR=g}QVeCtIafF8?>z)iO^`d-q3nm0U%dv-9&W zKoS|x8&Y{bRXz5X;n_3J&o}I9(hSjEjgf5yOcwz$)8pGU&5<buTCqOO1M5@+V2S+SkRz89l@?^~CtD%N>&r!uR)WLBrGVWkl3I{) zGiPQb;eocOQD8lFnu1DenHn1?U_?^g*~0LAMqV=H=lU=)Rm!9v^~kFXSBn{S_x4Hw zGv-6bHRby2lPQ?*E$ln5ug>-Xw-C6CD2U9;$|`j~HU~8;3ar*;H_~FP=*{)Tag~=S z@X45g3hfT3?x)<(saM_9A6dWPs@gB05RfeW&gK0Wj$^g*5syYd zk2Hq;fe!l7I@3mjhu=!y@(ROhXFocSzgw;>XSW0r5VSRi*E+>GE@*qs;8|@q$W!t9 zgKqY!sJ4!dtQX0ARV((_$@ZAQ^*o}nMS5E7hBa%V2 z$N8d^ROXDQ7h_GW2P-cWoz}5P+U!p7dCZaLdujQRZe-KDOsE;X&^-V-!*^vSA;Dl00PaPl{owco!BdG00}EuyrtkeJgNixI3y;m{0a_9Sb?|aGJdsl{(q5uH8)Uk1l}CQYIJJT(pA3K_ zssq3^Yy)@L55paS**o? zI5yx zA9_?xi>N*9hzyBg^Ym&v9+sg{321312W}QrtvQLAI#hP`;ERtMz;NL(rRtHADeYIt zp>oLL*V*v=BT>X_sQ%i0aDrQncDSRt+J z!sCOdC1^sA|44I3Kcv7{x}gLNhJV?O|8jBD(()e3NI?%s{9-3#^OIx7I4p`VEG*yZ z>cxj|A#($+`HeSXMeX@5BcIxz-kP@=?W4>`D&CO`R(#wCicvz8IOom=v(Xz=Gi4Bc zNAmLz?8zrSU};vga~T0}YV|u;B1`%7EL!(0AvqFGn=MZC?TN@x@tZ-xFgKeDT6-oW|3% zX^wc80*x?`W>G)h2Q=)hR`g%<)-NnkB*HtS&NUkAL5^Qh2Wr8A%O|_NqvHKi_@nQV zK@}GZLCebzDKGhx#Jm9K&A9D8{V&nr%VnJ-)_9HT@Jwx2-_u(i;C@@HD2?u~^zpJN zfK!>}1vnVNt@9@vII>3VoqbPFtF2SbMydFn>ltFg18_4i$REiSoR4YFZp|Y8`jiM_ zlq4UAlb?0q6vO;>eMn?V0tRTHylH;4tFH zrZ*1(=|TI`o1kCRV+k5-vRSZP+P@Wt+Uf`@zi^xkXR8c-(TR6?565Bdn3u_vAbusb zVE$uN22@<|BQY@v<>6l=;bvlDYL9@9vW4VUsf zTuSTRU)3r2A1$`y+MyB5uNx>eqyO^9p(`4p5$^8!;*!j7;q;jYK)sl(aZLoRu)028 z_sl4w`FK;pjCD2R6wMMQ+F7Wj-S951p4#1IITS2Fd~)nPzn3{u4Tb^J9FDm*O{6`h z>C6Azx@CO8e1AykzOy9ix~$CeurE6JVywb&!WnsgbVIkJJb?=-d)ClV*a6r@Z&261TwPZtKe3*T zPnPCN;27NKiUU9;Qv^t%R2D@R8u=;;R&!#1qjw6Eyek0Lv|A0Q6&EqGOUu8oFSXEx zfa}6Pc&FITh+as0xalhM#S@vG9NO#6aY9yg1?xNZoLtf>Bohqb-Tz5*B+{^GoMcrd zU;9jskpU=FIdStKIGmmZBTxBB3JM+$iNB=BVM)Lg>uu#+yuHiaW}h4EqcsNMm_zb~ z>#32mtfhr-uZDn&;cd<@jLLIWE>0Fkufr4c1THeC=eHl)XHScmIBb0~Lwb4%Hr0b( zi?szJ;(yAvqq~pP0QT=LU`YdMn)GIGM_lwi@+%~7>C1|Dv!lbDxXS^vN zl~2^D76jpa1TT58J7v=rbD2W@w?ydmce!x~XNx%l@7rxyUvf_m!_eBGcHfYkRQt=? zM-S~X^G>%>0cB`Tttw!LA}2?HK_KLkkQ%7#hns;FPMI@uc?w+63adsDHNZamYgti$z>i$Unc3K|K<5jq ze!T!tg}H&$Wc>E6pk=vH2i_x#Q5@hQerz$?N_6S>N2C`O-|RS)^uWH;elbw<0PiW| z;>%>B0#e|gw7#R1i_{Un1XRkBP@t#q)^I*C;I>MybADxnd1MB>U zUE|^5f!H+;y;>4L)%_6Otv8y2GAbAgkV>W)85rP9GU3g>aMY4E$<-Ia?rH@drwNIY zRT=c4WXa3Wu0%<5lNnC;z76P7{;1rGRXTbx{eNO*ko zKw%WkDoZVqvw8ostHS}i?a9Yr))y9|#AR%4A12M!wlDzY2XLPik9}YSw6u7@O_EiO z7XX1vy*g*SOFVph+4>7pCC=YNLvJdzX=r5*_B*t#z9v7}QX=*GTT!UF-jhdB{Th6+ z_Xg-jODp?Qpi;mCl|n;({oahr+yX%4tU!tcCa{MVqa2pA^%Ov*g8BZNn9~z|;aP13 z42{-#WZ^T+e0+D{aCnt$-VgNn%{haDZ6z#^+H{{$a{~iVzI6gGi0}PZQrE>k@M^u; z7Xh~Gv3!<*P#^dTcr76zN_~C(Q%?ZTpQ@1H(29`%`0?Xxzk{ySK=QdTzHUW_VV3+aOXIPeLWUqt$II}s6jlI4@i0hHy;M2rS3ES zI74Y^=`RLN-lx-FWg;lY8@+@f+A%(!WXkRG{BV^Cc;)32Ii*1h0YvVChX)ml`XEJM z^mp&JR;h`bG(~_75<2s?-6E_FCF}=Rim)wg?~wS|q8NU9&T@*m@v4Zqq1V5Y>9Ga6 zZu-&Ql!@ZLenSO-dm!Cg>K6E=U z)&(&cOaROm;8387L8Mxh6`%F=T1nJD$dvS=a_w^)3dw`}D{Xzx}RD2n&sld@i<|LUnph#o?6emc#WG5?lR%fB=Sv4+(%!-S)#DV;>xH zqocLKsyBMD4Dho&jbd7eUIPw#!=8i(5HpL8Pirasp5Jy}A_W8)qxSG8hK7tQ1L;wu z?CP(xvA%|A)@v3}@h2p<&}?D+NE0^zJ^BxSmWf~YSbP;tUucI96Ej6I4Sz4?^BzqRH0)(jT3XC{LD9DB$T;A5 zlt)gitm3RT|CWhW489`_uhWxcT`O5kZ)1P&NLx52YdlD@wS@idWfvXRwL%`KnlUB_2(4{C(Ddm@W zZBsZ7;G0w&&d3huANvN(V~r7v-{h>mo5KR(#?2Q#;9(^dUk9A;wh!-M+n)1q-E@XM z(D5}*gLfxl0N1dt@bojDr)k#+C5lS@FAERT8`M>Gh#Mk4ioV4(w;2?!Ny+D1id2 zc$YQe%)3G{O6LPeM5!`_4u-2o*c(NC*C)=D*AsObk9>gFdV8uzQE~^gX~JN_F6PH| zyWKqt92?D}kYo6X)PWk}cKu0GUbQvpSY3<^&=E_SlnXyib1ZpV!n)cAlsH7!O`>m; z0*ROL^U44Q5HI_(d?}>|i*8mTcvf1`qb>QYhc|?rmX=vLF5l4UdjZVO7&|aU1&-42 zYQI}M1)iyZvx4sZ#Z7D}sZK>n9v~W1T{6J>Q{xh|N@T)+ZB)<3-tiB1%+%q}aC1;; zx@r8x(7H98<+DA7n)4jg1CVJ5|xfspv$qgC6Y$l zs^asL*tp7CRThvDttpaxS_+;5TO5Qj9?6mM~-3ff`hmLvm z)aR8}$?E0jOqtV#T1-hzTbA@ZFP$k*wJV=<=v4FB{N2gjBNxZoqLAEw{xRu(!ins| zkl?M4>=@w`OdDse9o)*IG)gzIp}6!jAKlSjsQB`lE}3+(A3HvdLJ|%()Za8ZZ&bV3 zI7}1RgH*Q7LL~uoRF~t$DD9c=pq_R681rQWp#yYgsf*QZTn+=yjd+sROLCz1;Y}aq z;2NLRZM9-fVcagT$9BFwBS!H3>^wg~)fh-+hfMb^#7bto^nI!9)|mUoBG>XKYV%6eZo8!5DhHgR`5Ev5AY`!(rdA zuK?Z8Xymp^lkxPHO4G$R(^-N{zABLm+53FHjt1Z+PKPU?ujS*Q2^Rz7`7nBy`7Lz3 z_~f>UA_ELQDX8?la`N&H|HmkoGiXP-wnCjwnE8QB5f5)0Xm>eEb221mM&GRC7|2_NPQ+);}BM z`@h2ak}DMsS3$s(O3Sd&*cWaCq^$Rio^#UsuI`ud8T9)?Rn{Lc*ay{~pcGBD6}tMbQB}M%PTTpE|?t&NIWK_(7C>74&y@UNknDWK#`4v;Zk-gIzjAQ zFy=gG$D__A9Jk+=JJU6gBhCBf+NC#{A73&M=ZU2y$MZSLyrTaHaCWIPhREQv-M?8R zZp%;V1*qSN2nB~$(@}vJt=2-LM(g0|U*fep;-A*;^JBm*8v(;3h$NE0o3Xc&Y?G;! zE`~P+wZ{6RJWPnE4`89Z&fb$mleT|~<>N)Sr#@sL4 zTK}cP+ubejjd)IU;cn*3oC?)n?U#zoj9HrXgaI%;hcY& zW6biKuDr=l4vrhf0^mAI#u0^EV zMdHDGTzXPXV7)l%)(cd0%zNbUG;rPIN!6JiYn=-X|` zen4S?FP&ta#j`EWt}-(^-2XQ?L>2nZHL*_ugz#%}rG*jK@rr|P;|6ZHdfV5Qh z#)RthTWlCHGpO&o`?7=_(9e!F>{1Plv%&Utv4rLS+FJeNwED?+L$B%H^Y6QYA;B-DZ4#a#hG@w(^pNu{+Fq#&@Mp`g+y_sC4%B0AMWxI^8~L z&S%VA1OG|%Ustw8dQkA1_h=ERENXe#Qi}JBe^3N9GT;DUAHj$=MwxUBYMbA-Ig^z$ zhayr^E~=%B4=q3Cxop|qe9EKZgMI!ikt$@^XqZ_KjpDIYl6pa|bcz+o%L#6MxP&q0 zD+*Q;7qp@kZ@x`00D23Emu#S!AXYWvFF{qeA_yGa=6KG}rQGKMQqp1G0Q0fGICEGJ zIv$hxpxpiU`$HpnUq;x~1wapol8{fjlvKdT7gW#>nwP7D0Xnj;9jqr9lbX#(T4|c4 z+yFF4*%{|X?95D^UuqO{alC9jzXT1y;g2m^D}RCCgCHpRB@O9yqQ!lST16j7{<)yA zxywr|r{vOisP=6s=^8XptJT;yf8x%JjKbivcARl|YaGnB4g)*w3V1a+xlJS0#gC#7 zPb|b|emDE|PjL~(l-J*gL2mll20a(a&Xa9J%umq-+&5e*-e6S|A-Wx(&Uw~*+lD73 z68s$!oYFQ$1zKNJaETw#4bF3}aXPYQy7NLF5TD_+W zUh8PL)97>Y42PeX98(1O-Qo1bN^`Y}Jw=#wohmK3d4qslRU_PU!yg-#5|b6@($iNg}+-fH@vQ}ZCa{vO#C zP@hg4PVgX#bog%!(i6UpSWS|M;Sf@2!Ou-r;V)g zVyWxO=Q`QO{J7pNU_espZp*h;|H$EaVwu{6v3G^QEgEZ1!UvN z?|ZAjzaP6?P~19G7aH3{@f1w8)fCFx?(fW0pM!QNn?dVjJ&20rkIa;d{_TVO@0i*Z zFhuYhtt6(ZtYV_0eSxbT2%+%tvbSMY$pGOQ4doVv2 zbo!jnp7Z&fKhHnsKbLvuec$JOp7-~AzPD{2v`>&0qW@IX(UFtE5}tC|x+T&;t)QT= z-2cNas!pMe`T&zg^HlmLn549Bo^a0hRTUe}{4MDe+X}yYsc*hHQ&*?u)|KTK5TMHA z@rt51*xb<*OiWk<`CMjT9uLLYdW1drPL_>!m#YFND#APZhzjtnqFg4EsR|J55Im3{ zlGQadEGgGv$m^eSdF(dpZy*^wp|bbn$ye2;vq@nJKF2g^G++PM6hT0)jk-bU_$P1c zn`V)&l@-!`!-pr{eqfvzT1j_PDHUmd>0|@daBEiC%V66mbZrK#9L8A$XckTj5s!Ee zepTS&PFy&_Y>QkUY0zkQfxT4(Hn!Zd&7EuAug^FOtuuV_dL)v_s&X+Nx~sGHulF|{ z6}^(2Jlr%xxs$7;q{R1<1pq9o<@Wk{=04!(PrPNl6-tfKX16+f`yH6m9SgTIOFAnY zk=fWX_#!t2uY4o8NiM*XHC~_K7*$?Z_KB`QObVKs zk<{o_8qRM|*{xZ#W?S%F#e+KHqqrR4*8Bc_wBtk8FGou~q21$szT}l!ZgK}LEL@|T z&*_F4`yLqJJmyI*&EQA+|4_`~xNO1e=^8*VCOb>`r|N`6$W?6w*6ZMa;5gV_wz|LS za=4b9EJyNDicH)f;RFXll|QseR?FG@I8*G_@otU7;o*!yzCxCTVT-x>n#m3@>La+uIOr|1uiG>Rn8kK9v*i3&KG3OlD{rIj~TzrXqEvDTjhx_vhy#4c$ z6H!DTtYn&u0(0UrEVF>0PhdB+LfbQAa@y!np!#SlWpxXJ}KB3iFZru%R+SgS5zyRW+T0b?DFMDfQ!6r!K;#(@8Bce1aX9$)DyKGlApGc^2BT;&Y+)3h6ZyCC1G zq1L~<%(LL!s;XdB7HO4h=bD@T6@XCRd~dG7#K(-0U1_>E{?pPB_tMvA-Be z+CQV2E3Ku(DUr6pJ9Ta?6NUO^gUnXyIiGXFj8*~V9mq6>QG*eM(`^gQxpAly(1EGbg{|l z4&lJ}$>wBNG0dmMViw352 z_CZjx>U4U@hk^1PNOX%)!bp?}#@lQI`=gNR_HGUfS3ecL$9F7a_up`kCxS#WR0RU| z5Ktb3s6mivY(3cOb=19eujyiZz>IwBKxX1yP=LVikcqZTR_}R=Q$xt!gxZuEu+el0 zoM@nD|LTl=pL{7x@r#$>tN(f4;eN>uO4NRHX_1gt=Y-@-xUjLkfqW}|U1PX}{hFhd z{?J4tzfYU6n0;;7d&6(EnjR{BoOQL6zpMV=VgR+h`FL3)!f9LJpIeCptjt~U^^n%Y zkocs#{in7ifAB*%d~c4OxitA+l#WZq#oC%3+_M&pUz;8m zozdDfO^&Wso=@Tym!8;_yi~!grFt z;8xpBzz3+sl2wOFchke0Jm|DYyw# z6BewOuL*04Q!xxZvcb6Zezt9bGy0Yudn7X><8_Ro{7w*1`KOxK$0}u)SRW{3uKrAoAKvy_BG}Qlzt`o$BN7p&mS|4i4@x?^4;YL8389C)T1utv|c`tbU)O^&r+<=9or2hRw^@dy}o zf)zURvJ?SqkuW>d3Fh>b;$kiQ5QbJHf@efPJCR=(ZoW1=eER%&t96Ob$SQD+j5?2U zP=Jaw+Wnr13x^3Hm}QesBkqO7w8WrZt)bIp(c$?{`T^pKNlsQ%UdDsx^9QtmpNATF2+n&AWjUR} zi$!lroST@aKl%fUX7^dy1&%KxZ6T&6Mko(mstuR1P}BWY6eOLb^Ce{cnejo(j%Qu{ zm_0Uk>?y=iNbCkp*LMBR{aPV;|n`b88UUr%S%^+@Vbl_9SHyZPBr z8l4894qZ{~!I-ZBTM_qy0HvA8IJvzg2|!4lU*tr1KbOQZ)QFPzixAyqqMuk{?6x5RtBi?atRXNSC zB4*D-s&N@QrHq?58`wRXX1e3jixsvK zR?}IXI%AI%eZLldBvKPRvREk|@!$ZK#thu$BOP69QS<#4_(%y(hF}jp@XvytFoic? zIv<9iSLEHhTf?e9n!#a(GseRufW9Q=%41z{)KTzzNV&Yo*?H?==IOQ|vHA0_+vGdO zHkZBv#tNIZI7y#`#^Yh4T~Gu;-|+R^^imUie6*y$KtDnXhUgsSyaj>qeLXAnViG$I z^J(fsOfupsK^jdxyI&I#H2Om?a@Ao9tC)Nf*Jt1 z&7l2u$)#Ooc%jHanykX&a5&GoPWuoJ7!*V0xmF410v6Ozqmg`r?_FM6=_5k=EhpS1 zR+Qx}+rry;D%r3QD`S-7x!yxo9r+mnSfvR)55h3`%Mlc5jiJ2`ldnpGiseBFoAYL- z2GY1EO1tr-A|*H@MaP1OfJjpi5otzx31M_p1R;weK#&MQdI%(t#$9{nKIb~;oadgu_j%_2aECzhW#{|WyWX%BUV?nk7r-MRIp7%r!o(wwY8xZ8{ z?Y=R@^L(IpfWNM`p|+0J#xp@d=K_szIKO|qKs(^P7w&zYtO+c#{M=s0Km?IFiT;zw zHOuiv5H-?1^B<3frH%Izf3uq<&aqomCvGhbH5jR1l)q8^`(vuf(kt5cs(spO*}eWn zXRfBD+7X@YMi&a#AK8Z2!zbw7Tzy)Hu%@IwS^80u_kuAq>csj}>$Yzh$-8ck^5vwB- z$Qrf(zkIU?x?%Se4mTPZ8#8A++{ltLCOdxq`Ddw!UC1l^TZ&d6k=LuJclN0C`lMm6 zla82|>^h|)?+=eW_gt2KSKrW3kzVB4kUVxxxB2a5>2){k?CnoGxCGmk_;loJ2lhoy zR*iN06f~_i6Hev5c(GGS_w<1h_u4q3tCg*-tvu%PNyW=2*M2^8_AH5sFO17o*xz|ey7sLXZndpPrAS*qv zc~@cZXgj>#;u_Wr-xtPA7#*gaI=_SuwdjGK6uM;_})eQN3oNWQ+8#g$?@aI7jHz?E}vvz+v0b(KXX#J zx#eIz&CR^VJ11TK*|TTtfq0yyd5ui;)Wx|k8fNQCd(Q8_rebQ8Xfpk_Y~;yPcUE(H zB(blgq~wgB-}ny*5_ixhdWrDLP6LC`tJK)H41a(B#MoE|*KqY{F(;EIu~hlH1@Yv9 zN&r<9;v79c$Zj^CtTCX@H~D9V&QA{(27P^B?P7xL#%iWoBMLZIWp#CR)5Ob{FT2v+ zyu7@Ul9FoR*uS&QIh3H=Y^YYvEiS07zop6JZ|lFIzCY{XLv^z|ckV>^nIeej;R(Ei z^NTY!A3uJaG4$#wBM4@k?dGasx&yGq~?ghUKR%_{L)Teg)|czAep^RLTgRU0T_ zvs;)AeGmswI_w|Yzf+!kVtcw{RAJ_3}PD?c-MVJ1gn^aYqqTNK( zA^%!;cXyeXKgtQrh?;&^)_-B;001;m!7WP1{@HOkYco-h^Z9q`qF_Y?k<8jEdG71` zhwM-iFI30-{R96=(pVwQomrQ_9uFWHZ?Vo$&dH395Hiig9#CASZGC-Erlal8;tM@! zb-!O)$&6J?j78g40xp^zkHUt>x{n|;6J$nZ>!noLKanLiyo)P0h%`@<#{n$~Po$k2hdM>8>`NX^o8y6S8U9d3jn} z4y7qVW0-FWaG&bWzd~h13oOjdlRc{_tC5(Wj_z=iAbppRkYMBHhJ}Z=wl>V{>@51s zIAjbuy{)yW9=Zf8lN4>j>j`8JXOruKJ6sf2%4@wPUEp=KMC+@Bf4N@9>x*RGa&Wz> zks0-aytcC<+C6QuEmwW{EP>2CzLB@gY~sn|$5(G@I!qK+<>zakZcN2sFis`DSLZn_ z+Q_G;9-Yrm57PhY%vVGa$kKv@ZCEv+Oecq8&Fa2x+@9W$CI5Cm@`u?+c5@$Yj<1>}GPsh#=y z!DG1fzKxAd+j!cgl?ru9+iZbnYQMa@2_gk*%kb-in*%YDt7At-M#=`0o%sH32(kna z{T!OXP~&Y`4y$F709~Gg0%e?A-QM1AIQ!AoqcK&dFj~Yfn{9VuYP!w;9K}>(49BZW zB5SX`maK}A@qmti!Pq!CRdnnM?G1J?H?M@37Q#oGPLKe1S+M>D9Pifc+Y>wzcWoIN z9cB8s3648Qe0@ly_(NG9PRc~MmjTnYIr!Pf@Vce|6#JJz|Mf42}Xt5Zzm%el&V7#18({ige0XfFW1}bXlSdO&PS8VwU*GsrCzaev} zARu$B3TZCr{h~p)Muk)h>2+pT<4TmpgwsU+(H8iM-mq zH5JLr%ez)zUms0pKt~#Aa1);&>n_&hGDr)5Vvw1eofta3Ie7Q-K}_BwV`ViyEbg<^-?DM@)~tPK*i?1S%eHLs5>Tm zN>;_nJo#4^h67V;2hB)JYr1Pd>n!w88z?0$i+Fuu3A<6ZrDoF=8pm zV7aw7B#;%B`;tAocH;)#JbCsk0Z070zmO>4RyEJpJ5;Y>2>N(g)zxAdJOfVJy(Shz zU=VrZAHI>{S$TQBScg@J^yWzh=Hk)_iAxVa%WgT4`n*Fx@9xe5NRcXvi;K;YmmsZA zxbGXF z@lOHJh>uTHFLM2s4XdgddOqznUS@)>G7*=~ys%PxnBcFS67Q_tG3o;(Yz-uQ>((tB zN5`%LfivuJTKLdy0;kD<_Ate@yFeg?C~k$9V9h}o`O-_auUAsa&dydNU7DO@Gd<>} zK4UP2VAG)Xt-v?Xn$wLrfhezmd9iVDQ1HqKKkW?Gg~09dLa}FVo|K$i_v6wHJHNXE zn}Lg)Zg~X~zXr7dov!c(-P4W0j_Y(!*WA(b;ieXabA}XwFxXxx~%m?w4F+{9$9Cqpt>|JF3z8& z(Gn5M=1{5;1MtaU)ScdEX zEF<_QJh;*s>M71^Sm~jzQ6sjQ-K>A34Oa|l_FKfuTO2%ikQ`W-pw!_bh#a`8F|gEZ z?#G@Gx*rB}-P18BB&4qY^+jOXIm^bo1_5LmkPtMTsuC$A=9j}eB#t>ct^CXJUr+ner=tdiW@d;K;<3=!=#bP zpWj@ustH&qVI*!a&H}L8}#4=|mg5__O{+dspG zt@e-r*toi?Y~Q|J5T&kz?060;uGQ`pcmSEdk7)ZtpQdK5{Ljkmrl%uX6ofC=tt_EG zLaaaobIAAq4BE|oYB#R`;@N-z@~*(48qgyUEy+cu8wB)KhK)SVaR)x??IWSa#e-}r zU)meubl}d;Z6$tmd8mcar=F;SgL`5O#%hBc24kg6FrUQ9Bli%wUWZpzpUuQfGj~Wq*l)1n9f^hmvCtHKqdu>6o4c5a zeCx_?NWVe@n-bryHBarI#R(>`&IZ3OYszf!av19vG373v;Xbvn=AXAgiG5 z0vk74EJ{$`^@Eg*in5hT_^D_*8qcU^6&C6&RJ>xO{1MH}c0-aP_0y04h-TA}RKA_C4J)!SHy2K)P@&+V>}Tlz{f7RfD8gWK`o7I?emjw2Eb~QVKq|X#nnbTHabXvmnA`(x7+=1bcxeOQXqxfF(w zKzjWQU8)+5O<~nSh@Cr03!+F8+8(lo@e*UJY~i+lyeL(R2BK(50zT&2ORME{y_&~# z#6WFXAORZ?WUKx@seS-BhHT0`<{UX*49PLt$m58XG>A?mx;Wc~m^r^tR z7D1|VHZD5H9;mfBa^yYp%$YO8#UecrTPOo6xQ3lH;WX-^Wr=c03vnXwx@VUww)E7y z8)v+|-;n{4u1>N*P}^b|i1zUpThE?78%@KQhdrPQd>i8sl%Y)(paxa%2K#h%s6nv~S7(t|e zy|C<+42p8J`TbAsfx+lR3+EK^QDG2Wf*J`K>%=rQH5CT3nuTdsWi>3ly}i-c&7Ugb z&W$)w*TWwYLK#GZ{3>p@B82(Mp*;jaWpb~ZLWSaDB#t)08_$U5&R$QEyS)-uxg$Q- z)DrY@bn`on%${-7jj>o!EMvyIL;$%j1R#!Z*CFkWUY^iv-!DDBAEpAO0v+i$JEXIx z&=CRd(?0gLca$U!Z{bl(gW)xTbQ;zA_fk052Tgb~ zta6fJi|9@G#P^Up^Lj%)KIYm)3O8%XS@7h}ZCbbU%wgq_&XbZ=*Dl!F+Yg!T5WNbY zz%~aioXZeg;RvZvd@>5gwJa5L*IPH5U+gMVq~KZ zUgF<{w5KxtK%0w)0>oRuGo#g{T|GB|igGeJe6ot?4n2+l-j+7?`3-Zds3q~4Q)!4X z58}(KZ&n*?!63$6z#S)^TU>h|*UW)DQ2{*wCpL7BK#H)dI znP|SjB%9$gqWND{SOv$6zfZ*ThYkB)xXl846hoAz9;0m;ck zjkRFn#twbWDkHriS2MBRTao&_s?=i=R;jWx;&xo*FXVS z;R^0t(D`ivYZTYuh3DKJgO=L_>89H$us1CfHk0NBw>{3*NpT5rw0Chy7tQ3DHDwUF zU1LzqZ$TvYjrVjFd3mAHsXV3&ownc&FATIQu)=}RyC60#0*B#6<$o%m1Q17^x_;ZV zhXR30MS)Dti6~wLqv_}U`-=n<6}U)ttwPa$?efh}b93L8`1f{?3(gqxq>86V8EXI+-M7<~?|@S&+FfpXrY+0#EA;)Y<}R^DPGV{eGM$<~r0t zenSswK85t|5Pts4SdN*<`@KYG2MabHCOlo4qOQ!@zJZlJA0OKmEm=``r?M>* z>XUJ9ed9uyh-uu_^RZ9yqhU!=+*(|;P6I`2bZo2<@*N6HvGhm_+;Mu5vvvv*@c8wj z+Sb)o#Ec3Ku%s8}x?dONVW_;zulx}cD!1FGYq%}D2s+v(nBQGPgv&T`I|OJ}4Otro zje-X>i){=r<_~8xr{2hrL8lLv`t_9QRKq#efr!Z* zTS$s5tu|?)7Jx5bZ8UtZ&nZg62jtxBXh-NSD|Erzx?U5r%71K!FgEtXA>-|4BoGO0 zkZ^k*f>To_3E8F@JTj%)u%#Ee)m2EX(TTyWV1>KYMlI>-=>+jSi}uOEZ39g?@Bl+A z=@(~ORhbdJ#fgj=Sn8Mx#;l`GEn+^rmJg*Ak z;y(t6upXq;d7<*Ir(h{Y6sJiiY^wiQ*}0RGxH}ir5ZTf&_Q2L{+rAQZ?%X-kB~HXKx_+1%psPLf7;OsB~Uf>`%0Zi?ikvT20q$akEalS3g|5MaY%!62lIrAR>`U~ zauVz#4VuY1U^u|)53LRNvC=BTOLjb$-+p{8=qS_Xbq4;$Nc?tj(SX8}1 zk@#aB?Cj)Vc7kRu+L?#^dSB`-q-tb@sb;|B44pkdsODg2X|8C6*Q8kebqlT|fV~X+unmL>nvrKd#k1kaNT1n09 zNQACvB9wY}@O*h*Ns0a+-SF$fl+$u@a*mJ!C3`xC09w3Y`qSJ(ntrEI^!nmbFZ3J! z(UuH)&h06Mu_w@&K+L0N`gK0vbk{Vp#7y!-1FIZ@TjSBZA__`ePYVhrr}=(9K1#oN zXe}nPBgDk~MdCBEF=Iucec>8+jYIwQqvoan2wD}xS@9H9Qjiuv8WzRA1$LXJqdxqP zMn}VQ3w*kr$AU4 z4<^}CQrx1;%~n6WH#-#GCyJQ#7fw(mw~dT+6@(H^)Zzc;=+FcDZN=$ diff --git a/src/irlwpython/main.py b/src/irlwpython/main.py index a877472..13e2cb7 100644 --- a/src/irlwpython/main.py +++ b/src/irlwpython/main.py @@ -35,7 +35,8 @@ def parse_args(args): version=f"IRLwPython {__version__}", ) parser.add_argument('algorithm', metavar='ALGORITHM', type=str, - help='Currently supported training algorithm: [max-entropy, discrete-max-entropy-deep]') + help='Currently supported training algorithm: [max-entropy, discrete-max-entropy-deep,' + ' iq-learn]') parser.add_argument('--training', action='store_true', help="Enables training of model.") parser.add_argument('--testing', action='store_true', help="Enables testing of previously created model.") From a40fe8ddd158945046615a6d44f358020f908c2a Mon Sep 17 00:00:00 2001 From: HokageM Date: Wed, 22 Nov 2023 20:01:14 +0100 Subject: [PATCH 2/7] update Max entropy algorithms --- .../DiscreteMaxEntropyDeepActionOutput.py | 201 ++++++++++++++++++ src/irlwpython/DiscreteMaxEntropyDeepIRL.py | 170 --------------- .../DiscreteMaxEntropyDeepWActionInput.py | 189 ++++++++++++++++ src/irlwpython/MaxEntropyIRL.py | 6 +- src/irlwpython/MountainCar.py | 12 +- src/irlwpython/main.py | 32 ++- 6 files changed, 430 insertions(+), 180 deletions(-) create mode 100644 src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py delete mode 100644 src/irlwpython/DiscreteMaxEntropyDeepIRL.py create mode 100644 src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py diff --git a/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py b/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py new file mode 100644 index 0000000..cbd81a8 --- /dev/null +++ b/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py @@ -0,0 +1,201 @@ +import math +import os + +import gym +import numpy as np +import torch +import torch.optim as optim +import torch.nn as nn +import matplotlib.pyplot as plt + + +class ActorNetwork(nn.Module): + def __init__(self, num_inputs, num_output, hidden_size): + super(ActorNetwork, self).__init__() + self.fc1 = nn.Linear(num_inputs, hidden_size) + self.fc2 = nn.Linear(hidden_size, hidden_size) + self.fc3 = nn.Linear(hidden_size, num_output) + + def forward(self, x): + x = torch.relu(self.fc1(x)) + x = torch.relu(self.fc2(x)) + x = self.fc3(x) + return x + + +class QNetwork(nn.Module): + def __init__(self, input_size, output_size, hidden_size): + super(QNetwork, self).__init__() + + # Define the layers of your neural network + self.layers = nn.Sequential( + nn.Linear(input_size, hidden_size), + nn.ReLU(), # You can use other activation functions here + nn.Linear(hidden_size, hidden_size), + nn.ReLU(), + nn.Linear(hidden_size, output_size), + nn.Softmax() + ) + + def forward(self, x): + # Define the forward pass of your neural network + return self.layers(x) + +class DiscreteMaxEntropyDeepIRL: + def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.05, gamma=0.99, + num_epochs=1000): + self.feat_matrix = feature_matrix + self.one_feature = 20 + + self.target = target + self.state_dim = state_dim + self.action_dim = action_dim + self.learning_rate = learning_rate + + #self.actor_network = ActorNetwork(2, 3, 100) + self.actor_network = QNetwork(2, 3, 100) + self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=0.01) + + self.gamma = gamma + self.num_epochs = num_epochs + + self.theta = theta + + def get_reward(self, state, action): + state_idx = self.target.state_to_idx(state) + irl_rewards = self.feat_matrix.dot(self.theta).reshape((400,)) + return irl_rewards[int(state_idx)] + + def expert_feature_expectations(self, demonstrations): + feature_expectations = np.zeros(self.feat_matrix.shape[0]) + + for demonstration in demonstrations: + for state_idx, _, _ in demonstration: + feature_expectations += self.feat_matrix[int(state_idx)] + + feature_expectations /= demonstrations.shape[0] + return feature_expectations + + def maxent_irl(self, expert, learner): + gradient = expert - learner + self.theta += self.learning_rate * gradient.detach().numpy() + + # Clip theta + for j in range(len(self.theta)): + if self.theta[j] > 0: # log values + self.theta[j] = 0 + + def update_q_network(self, state_array, action, reward, next_state): + self.optimizer_actor.zero_grad() + + state_tensor = torch.tensor(state_array, dtype=torch.float32) + next_state_tensor = torch.tensor(next_state, dtype=torch.float32) + + #soft = nn.Softmax() + #q_state = soft(self.actor_network(state_tensor)) + q_state = self.actor_network(state_tensor) + + + + #next_q_state = soft(self.actor_network(next_state_tensor)) + next_q_state = self.actor_network(next_state_tensor) + print("Next QSTATE", next_q_state) + + q_1 = q_state[action] + q_2 = reward + self.gamma * torch.max(next_q_state) + q_1 + + #if action == 0: + # loss = torch.nn.functional.mse_loss(torch.tensor([q_2, 0, 0], requires_grad=True), q_state) + #if action == 1: + # loss = torch.nn.functional.mse_loss(torch.tensor([0, q_2, 0], requires_grad=True), q_state) + #if action == 2: + # loss = torch.nn.functional.mse_loss(torch.tensor([0, 0, q_2], requires_grad=True), q_state) + + loss = torch.nn.functional.mse_loss(q_2, q_1) + + loss = loss #* q_1 + print("LOSS", loss) + #loss = loss.sum() + #print("LOSS", loss) + loss.backward() + + self.optimizer_actor.step() + + def train(self): + demonstrations = self.target.get_demonstrations() + expert = self.expert_feature_expectations(demonstrations) + expert = torch.Tensor(expert) + learner_feature_expectations = torch.zeros(400) + episodes, scores = [], [] + + steps = 0 + for episode in range(20):#self.num_epochs): + state, info = self.target.env_reset() + score = 0 + + iteration = 0 + while True: + steps += 1 + iteration += 1 + if iteration > 2000: + scores.append(-1000) + episodes.append(episode) + break + state_idx = self.target.state_to_idx(state) + state_discrete = self.target.discretize_state(state) + + state_tensor = torch.tensor(state_discrete, dtype=torch.float32) + + q_state = self.actor_network(state_tensor) + + #action = torch.argmax(q_state).item() + action = torch.multinomial(q_state, 1).item() + next_state, reward, done, _, _ = self.target.env_step(action) + + next_state_discrete = self.target.discretize_state(next_state) + + # Actor update + irl_reward = self.get_reward(state, action) + #os.system('clear' if os.name == 'posix' else 'cls') + print(episode) + print("STATE", state_discrete) + print("ACTION", action) + print("Q state", q_state) + print("Reward", irl_reward) + self.update_q_network(state, action, irl_reward, next_state_discrete) + + learner_feature_expectations = learner_feature_expectations + torch.Tensor( + self.feat_matrix[int(state_idx)]) + + score += reward + state = next_state + if done: + scores.append(score) + episodes.append(episode) + break + + # Critic update + if episode != 0: + learner = learner_feature_expectations / episode + else: + learner = learner_feature_expectations + self.maxent_irl(expert, learner) + + if episode == 99: + print("Expert", expert) + print("Learner", learner) + for state_1 in range(20): + for action_1 in range(20): + print("State: ", state_1, action_1, "Q Values", + self.actor_network(torch.tensor([state_1, action_1], dtype=torch.float32)), + "Reward: ", self.get_reward(state, action)) + + + if episode % 1 == 0: + score_avg = np.mean(scores) + print('{} episode score is {:.2f}'.format(episode, score_avg)) + plt.plot(episodes, scores, 'b') + # plt.savefig("./learning_curves/discretemaxentdeep_30000.png") + + torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") + diff --git a/src/irlwpython/DiscreteMaxEntropyDeepIRL.py b/src/irlwpython/DiscreteMaxEntropyDeepIRL.py deleted file mode 100644 index 02abe64..0000000 --- a/src/irlwpython/DiscreteMaxEntropyDeepIRL.py +++ /dev/null @@ -1,170 +0,0 @@ -import numpy as np -import torch -import torch.optim as optim -import torch.nn as nn -import matplotlib.pyplot as plt - - -class ActorNetwork(nn.Module): - def __init__(self, num_inputs, num_output, hidden_size): - super(ActorNetwork, self).__init__() - self.fc1 = nn.Linear(num_inputs, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, num_output) - - def forward(self, x): - x = nn.functional.relu(self.fc1(x)) - x = nn.functional.relu(self.fc2(x)) - return self.fc3(x) - - -class CriticNetwork(nn.Module): - def __init__(self, num_inputs, hidden_size): - super(CriticNetwork, self).__init__() - self.fc1 = nn.Linear(num_inputs, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, 1) - - self.theta_layer = nn.Linear(hidden_size, 3) - - def forward(self, x): - x_ = nn.functional.relu(self.fc1(x)) - x_ = nn.functional.relu(self.fc2(x_)) - theta_ = self.theta_layer(x_) - return self.fc3(x_) + torch.matmul(theta_, x) - - -class DiscreteMaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, feature_matrix=None, learning_rate=0.01, gamma=0.99, - num_epochs=1000): - self.feat_matrix = feature_matrix - self.one_feature = 20 - - self.target = target - self.state_dim = state_dim - self.action_dim = action_dim - self.learning_rate = learning_rate - - self.gamma = gamma - self.num_epochs = num_epochs - self.actor_network = ActorNetwork(state_dim, action_dim, 100) - self.critic_network = CriticNetwork(state_dim + 1, 100) - self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=learning_rate) - self.optimizer_critic = optim.Adam(self.critic_network.parameters(), lr=learning_rate) - - def get_reward(self, state, action): - state_action = list(state) + list([action]) - state_action = torch.Tensor(state_action) - return self.critic_network(state_action) - - def expert_feature_expectations(self, demonstrations): - feature_expectations = torch.zeros(400) - - for demonstration in demonstrations: - for state, _, _ in demonstration: - state_tensor = torch.tensor(state, dtype=torch.float32) - feature_expectations += state_tensor.squeeze() - - feature_expectations /= demonstrations.shape[0] - return feature_expectations - - def maxent_irl(self, expert, learner): - # Update critic network - - self.optimizer_critic.zero_grad() - - # Loss function for critic network - loss_critic = torch.nn.functional.mse_loss(learner, expert) * self.learning_rate - loss_critic.backward() - - self.optimizer_critic.step() - - def update_q_network(self, state_array, action, reward, next_state): - self.optimizer_actor.zero_grad() - - state_tensor = torch.tensor(state_array, dtype=torch.float32) - next_state_tensor = torch.tensor(next_state, dtype=torch.float32) - - q_values = self.actor_network(state_tensor) - q_1 = self.actor_network(state_tensor)[action] - - q_2 = reward + self.gamma * max(self.actor_network(next_state_tensor)) - next_q_values = reward + self.gamma * (q_2 - q_1) # self.actor_network(next_state_tensor) - - loss_actor = nn.functional.mse_loss(q_values, next_q_values) - loss_actor.backward() - self.optimizer_actor.step() - - def train(self): - demonstrations = self.target.get_demonstrations() - expert = self.expert_feature_expectations(demonstrations) - - learner_feature_expectations = torch.zeros(400, requires_grad=True) - episodes, scores = [], [] - - for episode in range(self.num_epochs): - state, info = self.target.env_reset() - score = 0 - - while True: - state_tensor = torch.tensor(state, dtype=torch.float32) - - q_state = self.actor_network(state_tensor) - action = torch.argmax(q_state).item() - next_state, reward, done, _, _ = self.target.env_step(action) - - # Actor update - irl_reward = self.get_reward(state, action) - self.update_q_network(state, action, irl_reward, next_state) - - score += reward - state = next_state - if done: - scores.append(score) - episodes.append(episode) - break - - # Critic update - state_idx = state[0] + state[1] * self.one_feature - learner_feature_expectations = learner_feature_expectations + torch.Tensor( - self.feat_matrix[int(state_idx)]) - learner = learner_feature_expectations / episode - self.maxent_irl(expert, learner) - - if episode % 1 == 0: - score_avg = np.mean(scores) - print('{} episode score is {:.2f}'.format(episode, score_avg)) - plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/discretemaxentdeep_30000.png") - - torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") - torch.save(self.critic_network.state_dict(), "./results/discretemaxentdeep_30000_critic.pth") - - def test(self): - self.actor_network.load_state_dict(torch.load("./results/discretemaxentdeep_30000_actor.pth")) - self.critic_network.load_state_dict(torch.load("./results/discretemaxentdeep_30000_critic.pth")) - - episodes, scores = [], [] - for episode in range(10): - state = self.target.env_reset() - score = 0 - - while True: - self.target.env_render() - state_tensor = torch.tensor(state, dtype=torch.float32).unsqueeze(0) - - action = torch.argmax(self.actor_network(state_tensor)).item() - next_state, reward, done, _, _ = self.target.env_step(action) - - score += reward - state = next_state - - if done: - scores.append(score) - episodes.append(episode) - plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/discretemaxentdeep_test_30000.png") - break - - if episode % 1 == 0: - print('{} episode score is {:.2f}'.format(episode, score)) diff --git a/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py b/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py new file mode 100644 index 0000000..9072f9c --- /dev/null +++ b/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py @@ -0,0 +1,189 @@ +import math +import os + +import gym +import numpy +import numpy as np +import torch +import torch.optim as optim +import torch.nn as nn +import matplotlib.pyplot as plt + + +class ActorNetwork(nn.Module): + def __init__(self, num_inputs, num_output, hidden_size): + super(ActorNetwork, self).__init__() + self.fc1 = nn.Linear(5, hidden_size) + self.fc2 = nn.Linear(hidden_size, hidden_size) + self.fc4 = nn.Linear(hidden_size, hidden_size) + self.fc3 = nn.Linear(hidden_size, 1) + + def forward(self, x): + x = torch.relu(self.fc1(x)) + x = torch.relu(self.fc2(x)) + x = self.fc4(x) + x = self.fc3(x) + return x + + +class DiscreteMaxEntropyDeepIRL: + def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.01, gamma=0.9, + num_epochs=1000): + self.feat_matrix = feature_matrix + self.one_feature = 20 + + self.target = target + self.state_dim = state_dim + self.action_dim = action_dim + self.learning_rate = learning_rate + + self.actor_network = ActorNetwork(5, 1, 100) + self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=0.01) + + self.gamma = gamma + self.num_epochs = num_epochs + + self.theta = theta + + def get_reward(self, state, action): + state_idx = self.target.state_to_idx(state) + irl_rewards = self.feat_matrix.dot(self.theta).reshape((400,)) + return irl_rewards[int(state_idx)] + + def expert_feature_expectations(self, demonstrations): + feature_expectations = np.zeros(self.feat_matrix.shape[0]) + + for demonstration in demonstrations: + for state_idx, _, _ in demonstration: + feature_expectations += self.feat_matrix[int(state_idx)] + + feature_expectations /= demonstrations.shape[0] + return feature_expectations + + def maxent_irl(self, expert, learner): + gradient = expert - learner + self.theta += self.learning_rate * gradient.detach().numpy() + + # Clip theta + for j in range(len(self.theta)): + if self.theta[j] > 0: # log values + self.theta[j] = 0 + + def update_q_network(self, state_array, action, reward, next_state): + self.optimizer_actor.zero_grad() + + state_action = list(state_array) + if action == 0: + state_action += [1.0, 0.0, 0.0] + if action == 1: + state_action += [0.0, 1.0, 0.0] + if action == 2: + state_action += [0.0, 0.0, 1.0] + + state_action_tensor = torch.tensor(state_action, dtype=torch.float32) + + state_0 = list(next_state) + state_0 += [1.0, 0.0, 0.0] + state_1 = list(next_state) + state_1 += [0.0, 1.0, 0.0] + state_2 = list(next_state) + state_2 += [0.0, 0.0, 1.0] + + state_0_tensor = torch.tensor(state_0, dtype=torch.float32) + state_1_tensor = torch.tensor(state_1, dtype=torch.float32) + state_2_tensor = torch.tensor(state_2, dtype=torch.float32) + + next_q_state = torch.tensor([self.actor_network(state_0_tensor), + self.actor_network(state_1_tensor), + self.actor_network(state_2_tensor)]) + soft = nn.Softmax() + temperatur = 1.5 + next_state_abs = torch.Tensor(soft(next_q_state / temperatur)) + print("Next Q State Softmax", next_state_abs) + + q_1 = self.actor_network(state_action_tensor) + q_2 = torch.tensor([reward + self.gamma * torch.max(next_state_abs) + q_1]) + + loss = torch.nn.functional.mse_loss(q_2, q_1) + print("Loss", loss) + loss.backward() + self.optimizer_actor.step() + + def train(self): + demonstrations = self.target.get_demonstrations() + expert = self.expert_feature_expectations(demonstrations) + expert = torch.Tensor(expert) + learner_feature_expectations = torch.zeros(400) + episodes, scores = [], [] + + for episode in range(self.num_epochs): + state, info = self.target.env_reset() + score = 0 + + iteration = 0 + while True: + iteration += 1 + if iteration > 300: + scores.append(-1000) + episodes.append(episode) + break + state_idx = self.target.state_to_idx(state) + state_discrete = self.target.discretize_state(state) + + state_0 = list(state_discrete) + state_0 += [1.0, 0.0, 0.0] + state_1 = list(state_discrete) + state_1 += [0.0, 1.0, 0.0] + state_2 = list(state_discrete) + state_2 += [0.0, 0.0, 1.0] + + state_0_tensor = torch.tensor(state_0, dtype=torch.float32) + state_1_tensor = torch.tensor(state_1, dtype=torch.float32) + state_2_tensor = torch.tensor(state_2, dtype=torch.float32) + + q_state = torch.tensor([self.actor_network(state_0_tensor), + self.actor_network(state_1_tensor), + self.actor_network(state_2_tensor)]) + + soft = nn.Softmax() + action_probs = torch.Tensor(soft(q_state)) + + action = torch.multinomial(action_probs, 1).item() + next_state, reward, done, _, _ = self.target.env_step(action) + + next_state_discrete = self.target.discretize_state(next_state) + + # Actor update + irl_reward = self.get_reward(state, action) + os.system('clear' if os.name == 'posix' else 'cls') + print("State", state_discrete) + print("Action", action) + print("Reward", reward, "IRL_reward", irl_reward) + print("Q State", q_state) + # print("Q State Softmax", action_probs) + self.update_q_network(state, action, irl_reward, next_state_discrete) + + learner_feature_expectations = learner_feature_expectations + torch.Tensor( + self.feat_matrix[int(state_idx)]) + + score += reward + state = next_state + if done: + scores.append(score) + episodes.append(episode) + break + + # Critic update + if episode > 4: + learner = learner_feature_expectations / episode + else: + learner = learner_feature_expectations + self.maxent_irl(expert, learner) + + if episode % 1 == 0: + score_avg = np.mean(scores) + print('{} episode score is {:.2f}'.format(episode, score_avg)) + plt.plot(episodes, scores, 'b') + # plt.savefig("./learning_curves/discretemaxentdeep_30000.png") + + torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") diff --git a/src/irlwpython/MaxEntropyIRL.py b/src/irlwpython/MaxEntropyIRL.py index 8a2c4ac..dcfe81f 100644 --- a/src/irlwpython/MaxEntropyIRL.py +++ b/src/irlwpython/MaxEntropyIRL.py @@ -111,7 +111,7 @@ def train(self, theta_learning_rate): # One Step in environment state = state[0] while True: - state_idx = self.target.idx_to_state(state) + state_idx = self.target.state_to_idx(state) action = np.argmax(self.q_table[state_idx]) # Run one timestep of the environment's dynamics. @@ -119,7 +119,7 @@ def train(self, theta_learning_rate): # get pseudo-reward and update q table irl_reward = self.get_reward(self.n_states, state_idx) - next_state_idx = self.target.idx_to_state(next_state) + next_state_idx = self.target.state_to_idx(next_state) self.update_q_table(state_idx, action, irl_reward, next_state_idx) # State counting for densitiy @@ -153,7 +153,7 @@ def test(self): state = state[0] while True: self.target.env_render() - state_idx = self.target.idx_to_state(state) + state_idx = self.target.state_to_idx(state) action = np.argmax(self.q_table[state_idx]) next_state, reward, done, _, _ = self.target.env_step(action) diff --git a/src/irlwpython/MountainCar.py b/src/irlwpython/MountainCar.py index 0f66c5e..2543615 100644 --- a/src/irlwpython/MountainCar.py +++ b/src/irlwpython/MountainCar.py @@ -27,7 +27,7 @@ def get_demonstrations(self): env_high = self.env.observation_space.high env_distance = (env_high - env_low) / self.one_feature - raw_demo = np.load(file="expert_demo/expert_demo.npy") + raw_demo = np.load(file="src/irlwpython/expert_demo/expert_demo.npy") demonstrations = np.zeros((len(raw_demo), len(raw_demo[0]), 3)) for x in range(len(raw_demo)): for y in range(len(raw_demo[0])): @@ -40,7 +40,7 @@ def get_demonstrations(self): return demonstrations - def idx_to_state(self, state): + def state_to_idx(self, state): """ Converts state (pos, vel) to the integer value using the mountain car environment. :param state: @@ -55,6 +55,14 @@ def idx_to_state(self, state): state_idx = position_idx + velocity_idx * self.one_feature return state_idx + def discretize_state(self, state): + env_low = self.env.observation_space.low + env_high = self.env.observation_space.high + env_distance = (env_high - env_low) / self.one_feature + position_idx = int((state[0] - env_low[0]) / env_distance[0]) + velocity_idx = int((state[1] - env_low[1]) / env_distance[1]) + return [position_idx, velocity_idx] + def env_action_space(self): return self.env.action_space diff --git a/src/irlwpython/main.py b/src/irlwpython/main.py index 13e2cb7..ac7d3d0 100644 --- a/src/irlwpython/main.py +++ b/src/irlwpython/main.py @@ -1,11 +1,16 @@ import argparse import logging +import pickle + import numpy as np import sys + +from irlwpython.DiscreteMaxEntropyDeepActionOutput import DiscreteMaxEntropyDeepIRL +from irlwpython.IQLearnIRL import IQLearnIRL +from irlwpython.GAILIRL import GAILIRL from irlwpython.MountainCar import MountainCar from irlwpython.MaxEntropyIRL import MaxEntropyIRL -from irlwpython.DiscreteMaxEntropyDeepIRL import DiscreteMaxEntropyDeepIRL from irlwpython import __version__ @@ -77,9 +82,12 @@ def main(args): gamma = 0.99 q_learning_rate = 0.03 - # Theta works as Critic + # Theta works as Rewards theta_learning_rate = 0.05 - theta = -(np.random.uniform(size=(n_states,))) + #theta = -(np.random.uniform(size=(n_states,))) + theta = np.full((n_states,), -0.1) + + #print("THETA", theta) if args.render: car = MountainCar(True, one_feature) @@ -90,8 +98,8 @@ def main(args): state_dim = 2 # Run MaxEnt Deep IRL using MountainCar environment - maxent_deep_irl_agent = DiscreteMaxEntropyDeepIRL(car, state_dim, n_actions, feature_matrix) - maxent_deep_irl_agent.train() + trainer = DiscreteMaxEntropyDeepIRL(car, state_dim, n_actions, feature_matrix, theta) + trainer.train() # maxent_deep_irl_agent.test() if args.algorithm == "discrete-max-entropy-deep" and args.testing: @@ -107,6 +115,20 @@ def main(args): trainer = MaxEntropyIRL(car, feature_matrix, one_feature, q_table, q_learning_rate, gamma, n_states, theta) trainer.test() + if args.algorithm == "gail" and args.training: + trainer = GAILIRL(car) + trainer.train() + + if args.algorithm == "iq-learn" and args.training: + car = MountainCar(True, one_feature) + eval_car = MountainCar(True, one_feature) + + trainer = IQLearnIRL(car, eval_car) + trainer.train() + + if args.algorithm == "iq-learn" and args.testing: + pass + _logger.info("Script ends here") From 7231acb6ba96f50abd0d90973641e0db0d38c547 Mon Sep 17 00:00:00 2001 From: HokageM Date: Sat, 25 Nov 2023 14:46:09 +0100 Subject: [PATCH 3/7] version using max not softmax with working grad --- expert_deep.png | Bin 0 -> 251 bytes expert_flat.png | Bin 0 -> 251 bytes feature_matrix_deep.png | Bin 0 -> 488 bytes feature_matrix_flat.png | Bin 0 -> 488 bytes learner_deep.png | Bin 0 -> 354 bytes learner_flat.png | Bin 0 -> 447 bytes .../DiscreteMaxEntropyDeepActionOutput.py | 163 ++++++++++-------- .../DiscreteMaxEntropyDeepWActionInput.py | 70 ++++---- src/irlwpython/main.py | 16 +- theta_deep.png | Bin 0 -> 488 bytes theta_flat.png | Bin 0 -> 488 bytes 11 files changed, 124 insertions(+), 125 deletions(-) create mode 100644 expert_deep.png create mode 100644 expert_flat.png create mode 100644 feature_matrix_deep.png create mode 100644 feature_matrix_flat.png create mode 100644 learner_deep.png create mode 100644 learner_flat.png create mode 100644 theta_deep.png create mode 100644 theta_flat.png diff --git a/expert_deep.png b/expert_deep.png new file mode 100644 index 0000000000000000000000000000000000000000..99392c4f7dc1a1f8c8c382e2d809dfa6076c627b GIT binary patch literal 251 zcmVQuuPCxH3==U~0FJf^@RJC7UbvUfoNVNaD?pET&MKW~!QG|FfjKAW!1=rxtB9MFPd zHmx!jiv8W)EcIg1l`+GfxjO$PK$KROl;Sh8)&rHnID^>^Mw|cu002ovPDHLkV1f=^ BYvup| literal 0 HcmV?d00001 diff --git a/expert_flat.png b/expert_flat.png new file mode 100644 index 0000000000000000000000000000000000000000..99392c4f7dc1a1f8c8c382e2d809dfa6076c627b GIT binary patch literal 251 zcmVQuuPCxH3==U~0FJf^@RJC7UbvUfoNVNaD?pET&MKW~!QG|FfjKAW!1=rxtB9MFPd zHmx!jiv8W)EcIg1l`+GfxjO$PK$KROl;Sh8)&rHnID^>^Mw|cu002ovPDHLkV1f=^ BYvup| literal 0 HcmV?d00001 diff --git a/feature_matrix_deep.png b/feature_matrix_deep.png new file mode 100644 index 0000000000000000000000000000000000000000..dc27a4aab6c2fd2c3bfb135f67dd4f617019b653 GIT binary patch literal 488 zcmVP)ORL=j2?;-b{ONP&DZ$?Im+@8$fP`tNB7Awu{!y?YzZj=!@%FmtRwT4;t4@iX*1N$6lXKC0AR~O@V+z8U3(S1@I^cs z6aB?w4+O3g)@?vimlv4=-%iO4{-XX$AMOIiImp!vj0UU~1n+8L*rn(KT4Xi=upMpE zIArscQx*URpa^CyZeX};0YT*&4%UjNIT85+7P2vQOnSx@i~%6}K4b)EQ@T6XHo!9* zA4aiE8q5JP@Gu@|vL7F!NM-`2CF`=rg!X0xWzAwCmkKh76sg5!37EXYvsVXD0VL`m z`M`7Y7|_E+3U~paNsU^n%L0(j?N1>Dwh%?;YP1@In)~p<7t8|Okm*;sU_KXkp(H!q ew{V7f@h+#DIKsZ_&LKPi0000P)ORL=j2?;-b{ONP&DZ$?Im+@8$fP`tNB7Awu{!y?YzZj=!@%FmtRwT4;t4@iX*1N$6lXKC0AR~O@V+z8U3(S1@I^cs z6aB?w4+O3g)@?vimlv4=-%iO4{-XX$AMOIiImp!vj0UU~1n+8L*rn(KT4Xi=upMpE zIArscQx*URpa^CyZeX};0YT*&4%UjNIT85+7P2vQOnSx@i~%6}K4b)EQ@T6XHo!9* zA4aiE8q5JP@Gu@|vL7F!NM-`2CF`=rg!X0xWzAwCmkKh76sg5!37EXYvsVXD0VL`m z`M`7Y7|_E+3U~paNsU^n%L0(j?N1>Dwh%?;YP1@In)~p<7t8|Okm*;sU_KXkp(H!q ew{V7f@h+#DIKsZ_&LKPi000040*Dluw2i5E~>W(G#|M8?EY+XA}qL?Wg0w~%-d4*^Wa`CX{NmGAOdz5oEt zh1U3+wlb(Z1Uj$?+5p_N4O2AzRVHcc%&(+Uk5v4il7po0s?K$mYo>1ulWgI$#7%r0 z$f`mEK)Tw?F0FjB^qp0b3jkR4v()=EPQB}V5pp6RvLn5&9v&w18cd-ihK7g*KV7~I zmdBCYShH^0s}q5bstR{v8lgVfz`RkiHm+J-zY&^v!S3nsc9t06O5 z(5x9DI=z04L{XY&8a8tgW@QNgcDLPERl0ZXQ)i?(&k@1A8^N`miOo99p$QFofKgL2 zH?%1m!Gw_kA^_|0(U4n)z_4w_;WVj`tAg-PUlOLIks`soMF0Q*07*qoM6N<$f|&}M A3;+NC literal 0 HcmV?d00001 diff --git a/learner_flat.png b/learner_flat.png new file mode 100644 index 0000000000000000000000000000000000000000..b735f5b93c52053f9b79f6b7961c3d46580777a6 GIT binary patch literal 447 zcmV;w0YLtVP)F<{{Qy$@fWzD1h1f&m>>_s+mCPV+=Z%Ukrm`qQUCXw zN$L9~4#A5*A%Yz2YC6w;asL0!?s}1xH$- zz+x3{u=U=%6Wj$Sr#&|L_}lp8F9rq{A?|GotGac?(-}6zebfEHpmXsr1C!AAvnu>2 zw{diOoHhES&cmfF#lXPyMd;f_mOg;CC&x3qAh2;nf311_p-xrK>OA{>#WF$nouO+(ox9e^?k87#stCOqurS`;RZW pEPI8%BEnjA+N*6>m&q{T0RX1Gn*w?mEM))y002ovPDHLkV1kKI-C+O# literal 0 HcmV?d00001 diff --git a/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py b/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py index cbd81a8..dab53ec 100644 --- a/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py +++ b/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py @@ -1,5 +1,6 @@ import math import os +import random import gym import numpy as np @@ -7,21 +8,7 @@ import torch.optim as optim import torch.nn as nn import matplotlib.pyplot as plt - - -class ActorNetwork(nn.Module): - def __init__(self, num_inputs, num_output, hidden_size): - super(ActorNetwork, self).__init__() - self.fc1 = nn.Linear(num_inputs, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, num_output) - - def forward(self, x): - x = torch.relu(self.fc1(x)) - x = torch.relu(self.fc2(x)) - x = self.fc3(x) - return x - +import PIL class QNetwork(nn.Module): def __init__(self, input_size, output_size, hidden_size): @@ -30,19 +17,23 @@ def __init__(self, input_size, output_size, hidden_size): # Define the layers of your neural network self.layers = nn.Sequential( nn.Linear(input_size, hidden_size), - nn.ReLU(), # You can use other activation functions here + #nn.ReLU(), # You can use other activation functions here + nn.Linear(hidden_size, hidden_size), nn.Linear(hidden_size, hidden_size), - nn.ReLU(), + #nn.Linear(hidden_size, hidden_size), + #nn.Linear(hidden_size, hidden_size), + #nn.ReLU(), nn.Linear(hidden_size, output_size), - nn.Softmax() + #nn.Softmax() ) def forward(self, x): # Define the forward pass of your neural network return self.layers(x) + class DiscreteMaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.05, gamma=0.99, + def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.05, gamma=0.9, num_epochs=1000): self.feat_matrix = feature_matrix self.one_feature = 20 @@ -52,8 +43,8 @@ def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=Non self.action_dim = action_dim self.learning_rate = learning_rate - #self.actor_network = ActorNetwork(2, 3, 100) - self.actor_network = QNetwork(2, 3, 100) + # self.actor_network = ActorNetwork(2, 3, 100) + self.actor_network = QNetwork(2, 3, 200) self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=0.01) self.gamma = gamma @@ -61,7 +52,16 @@ def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=Non self.theta = theta - def get_reward(self, state, action): + def tensor_to_image(self, tensor, name): + tensor = tensor * 255 + tensor = np.array(tensor, dtype=np.uint8) + if np.ndim(tensor) > 3: + assert tensor.shape[0] == 1 + tensor = tensor[0] + tensor_img = PIL.Image.fromarray(tensor) + tensor_img.save(f"{name}.png", "PNG") + + def get_reward(self, state): state_idx = self.target.state_to_idx(state) irl_rewards = self.feat_matrix.dot(self.theta).reshape((400,)) return irl_rewards[int(state_idx)] @@ -80,56 +80,58 @@ def maxent_irl(self, expert, learner): gradient = expert - learner self.theta += self.learning_rate * gradient.detach().numpy() + + #print("EXPERT", expert) + #print("LEARNER", learner) + #print("THETA", self.theta) + self.tensor_to_image(expert.reshape(20,20), "expert_deep") + self.tensor_to_image(learner.reshape(20,20), "learner_deep") + self.tensor_to_image(self.theta.reshape(20,20), "theta_deep") + # Clip theta for j in range(len(self.theta)): if self.theta[j] > 0: # log values self.theta[j] = 0 - def update_q_network(self, state_array, action, reward, next_state): - self.optimizer_actor.zero_grad() - - state_tensor = torch.tensor(state_array, dtype=torch.float32) - next_state_tensor = torch.tensor(next_state, dtype=torch.float32) - - #soft = nn.Softmax() - #q_state = soft(self.actor_network(state_tensor)) - q_state = self.actor_network(state_tensor) + def update_q_network(self, q_state_0: torch.tensor, q_state_1, q_state_2, action, reward, next_q_state): + q_2 = reward + self.gamma * torch.max(next_q_state) - - - #next_q_state = soft(self.actor_network(next_state_tensor)) - next_q_state = self.actor_network(next_state_tensor) - print("Next QSTATE", next_q_state) - - q_1 = q_state[action] - q_2 = reward + self.gamma * torch.max(next_q_state) + q_1 - - #if action == 0: + if action == 0: + # q_state_0.requires_grad = True + q_1 = q_state_0 # loss = torch.nn.functional.mse_loss(torch.tensor([q_2, 0, 0], requires_grad=True), q_state) - #if action == 1: + if action == 1: + # q_state_1.requires_grad = True + q_1 = q_state_1 # loss = torch.nn.functional.mse_loss(torch.tensor([0, q_2, 0], requires_grad=True), q_state) - #if action == 2: + if action == 2: + # q_state_2.requires_grad = True + q_1 = q_state_2 # loss = torch.nn.functional.mse_loss(torch.tensor([0, 0, q_2], requires_grad=True), q_state) - loss = torch.nn.functional.mse_loss(q_2, q_1) + loss = torch.nn.functional.mse_loss(0.01*(q_2 - q_1), q_1) + + self.optimizer_actor.zero_grad() + + loss.backward(retain_graph=True) - loss = loss #* q_1 - print("LOSS", loss) - #loss = loss.sum() - #print("LOSS", loss) - loss.backward() + # Print the gradients for each parameter + for name, param in self.actor_network.named_parameters(): + if name == "layers.3.bias": + if param.grad is not None: + pass + #print(name, param.grad) self.optimizer_actor.step() def train(self): demonstrations = self.target.get_demonstrations() expert = self.expert_feature_expectations(demonstrations) - expert = torch.Tensor(expert) - learner_feature_expectations = torch.zeros(400) + expert = torch.Tensor(expert).detach() + learner_feature_expectations = torch.zeros(400).detach() episodes, scores = [], [] - steps = 0 - for episode in range(20):#self.num_epochs): + for episode in range(20): # self.num_epochs): state, info = self.target.env_reset() score = 0 @@ -138,31 +140,43 @@ def train(self): steps += 1 iteration += 1 if iteration > 2000: - scores.append(-1000) - episodes.append(episode) - break + #while True: + pass + #scores.append(-2000) + #episodes.append(episode) + #break state_idx = self.target.state_to_idx(state) state_discrete = self.target.discretize_state(state) - state_tensor = torch.tensor(state_discrete, dtype=torch.float32) + # Forward Pass + state_tensor = torch.tensor(state_discrete, dtype=torch.float32, requires_grad=True) + q_state_0, q_state_1, q_state_2 = self.actor_network(state_tensor) - q_state = self.actor_network(state_tensor) + # Epsilon Greedy Action Selection + epsilon = 0.1 + if random.uniform(0, 1) > epsilon: + #alpha = 0.3 + #probs = torch.softmax(torch.tensor([q_state_0, q_state_1, q_state_2]) / alpha, dim=0) + #action = torch.multinomial(probs, 1).item() # sample action from softmax + action = torch.argmax(torch.tensor([q_state_0, q_state_1, q_state_2])).item() + else: + action = random.randint(0, 2) - #action = torch.argmax(q_state).item() - action = torch.multinomial(q_state, 1).item() next_state, reward, done, _, _ = self.target.env_step(action) - next_state_discrete = self.target.discretize_state(next_state) + next_state_tensor = torch.tensor(next_state_discrete, dtype=torch.float32) + next_q_state = self.actor_network(next_state_tensor).detach() # Actor update - irl_reward = self.get_reward(state, action) + irl_reward = self.get_reward(state) #os.system('clear' if os.name == 'posix' else 'cls') - print(episode) - print("STATE", state_discrete) - print("ACTION", action) - print("Q state", q_state) - print("Reward", irl_reward) - self.update_q_network(state, action, irl_reward, next_state_discrete) + #print("Episode", episode) + #print("STATE", state_discrete) + #print("ACTION", action) + #print("Q state", q_state_0, q_state_1, q_state_2) + #print("Next Q state", next_q_state) + #print("Reward", irl_reward) + self.update_q_network(q_state_0, q_state_1, q_state_2, action, irl_reward, next_q_state) learner_feature_expectations = learner_feature_expectations + torch.Tensor( self.feat_matrix[int(state_idx)]) @@ -175,13 +189,14 @@ def train(self): break # Critic update - if episode != 0: + if (episode != 0 and episode == 4) or (episode > 4 and episode % 4 == 0): learner = learner_feature_expectations / episode + self.maxent_irl(expert, learner) else: learner = learner_feature_expectations - self.maxent_irl(expert, learner) - if episode == 99: + if episode == 19: + print("Theta", self.theta) print("Expert", expert) print("Learner", learner) for state_1 in range(20): @@ -190,12 +205,10 @@ def train(self): self.actor_network(torch.tensor([state_1, action_1], dtype=torch.float32)), "Reward: ", self.get_reward(state, action)) - - if episode % 1 == 0: + if episode % 19 == 0: score_avg = np.mean(scores) print('{} episode score is {:.2f}'.format(episode, score_avg)) plt.plot(episodes, scores, 'b') - # plt.savefig("./learning_curves/discretemaxentdeep_30000.png") + plt.savefig("./src/irlwpython/learning_curves/discretemaxentdeep_30000.png") torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") - diff --git a/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py b/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py index 9072f9c..5841786 100644 --- a/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py +++ b/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py @@ -8,7 +8,7 @@ import torch.optim as optim import torch.nn as nn import matplotlib.pyplot as plt - +import random class ActorNetwork(nn.Module): def __init__(self, num_inputs, num_output, hidden_size): @@ -69,42 +69,31 @@ def maxent_irl(self, expert, learner): if self.theta[j] > 0: # log values self.theta[j] = 0 - def update_q_network(self, state_array, action, reward, next_state): - self.optimizer_actor.zero_grad() - - state_action = list(state_array) - if action == 0: - state_action += [1.0, 0.0, 0.0] - if action == 1: - state_action += [0.0, 1.0, 0.0] - if action == 2: - state_action += [0.0, 0.0, 1.0] - - state_action_tensor = torch.tensor(state_action, dtype=torch.float32) - - state_0 = list(next_state) + def update_q_network(self, q_state, action, reward, next_state_dicrete): + state_0 = list(next_state_dicrete) state_0 += [1.0, 0.0, 0.0] - state_1 = list(next_state) + state_1 = list(next_state_dicrete) state_1 += [0.0, 1.0, 0.0] - state_2 = list(next_state) + state_2 = list(next_state_dicrete) state_2 += [0.0, 0.0, 1.0] - state_0_tensor = torch.tensor(state_0, dtype=torch.float32) - state_1_tensor = torch.tensor(state_1, dtype=torch.float32) - state_2_tensor = torch.tensor(state_2, dtype=torch.float32) + state_0_tensor = torch.tensor(state_0, dtype=torch.float32).detach() + state_1_tensor = torch.tensor(state_1, dtype=torch.float32).detach() + state_2_tensor = torch.tensor(state_2, dtype=torch.float32).detach() next_q_state = torch.tensor([self.actor_network(state_0_tensor), self.actor_network(state_1_tensor), - self.actor_network(state_2_tensor)]) - soft = nn.Softmax() - temperatur = 1.5 - next_state_abs = torch.Tensor(soft(next_q_state / temperatur)) - print("Next Q State Softmax", next_state_abs) + self.actor_network(state_2_tensor)]).detach() + + #action = torch.max(q_state.detach()).item() + #print("Next Q State Softmax", next_state_abs) + #print(torch.max(next_q_state).detach()) - q_1 = self.actor_network(state_action_tensor) - q_2 = torch.tensor([reward + self.gamma * torch.max(next_state_abs) + q_1]) + q_1 = q_state + q_2 = reward + self.gamma * torch.max(next_q_state) loss = torch.nn.functional.mse_loss(q_2, q_1) + self.optimizer_actor.zero_grad() print("Loss", loss) loss.backward() self.optimizer_actor.step() @@ -137,21 +126,26 @@ def train(self): state_2 = list(state_discrete) state_2 += [0.0, 0.0, 1.0] - state_0_tensor = torch.tensor(state_0, dtype=torch.float32) - state_1_tensor = torch.tensor(state_1, dtype=torch.float32) - state_2_tensor = torch.tensor(state_2, dtype=torch.float32) + state_0_tensor = torch.tensor(state_0, dtype=torch.float32, requires_grad=True) + state_1_tensor = torch.tensor(state_1, dtype=torch.float32, requires_grad=True) + state_2_tensor = torch.tensor(state_2, dtype=torch.float32, requires_grad=True) q_state = torch.tensor([self.actor_network(state_0_tensor), self.actor_network(state_1_tensor), - self.actor_network(state_2_tensor)]) + self.actor_network(state_2_tensor)], requires_grad=True) + - soft = nn.Softmax() - action_probs = torch.Tensor(soft(q_state)) + # Epsilon Greedy Action Selection + epsilon = 0.1 + if random.uniform(0, 1) > epsilon: + action = torch.argmax(q_state.detach()).item() + else: + action = random.randint(0, 2) - action = torch.multinomial(action_probs, 1).item() next_state, reward, done, _, _ = self.target.env_step(action) next_state_discrete = self.target.discretize_state(next_state) + #next_state_tensor = torch.tensor(next_state_discrete, dtype=torch.float32) # Actor update irl_reward = self.get_reward(state, action) @@ -160,8 +154,8 @@ def train(self): print("Action", action) print("Reward", reward, "IRL_reward", irl_reward) print("Q State", q_state) - # print("Q State Softmax", action_probs) - self.update_q_network(state, action, irl_reward, next_state_discrete) + print("Next Dircete", next_state_discrete) + self.update_q_network(q_state, action, irl_reward, next_state_discrete) learner_feature_expectations = learner_feature_expectations + torch.Tensor( self.feat_matrix[int(state_idx)]) @@ -174,11 +168,11 @@ def train(self): break # Critic update - if episode > 4: + if (episode != 0 and episode == 4) or (episode > 4 and episode % 4 == 0): learner = learner_feature_expectations / episode + self.maxent_irl(expert, learner) else: learner = learner_feature_expectations - self.maxent_irl(expert, learner) if episode % 1 == 0: score_avg = np.mean(scores) diff --git a/src/irlwpython/main.py b/src/irlwpython/main.py index ac7d3d0..04af053 100644 --- a/src/irlwpython/main.py +++ b/src/irlwpython/main.py @@ -5,7 +5,6 @@ import numpy as np import sys - from irlwpython.DiscreteMaxEntropyDeepActionOutput import DiscreteMaxEntropyDeepIRL from irlwpython.IQLearnIRL import IQLearnIRL from irlwpython.GAILIRL import GAILIRL @@ -84,10 +83,10 @@ def main(args): # Theta works as Rewards theta_learning_rate = 0.05 - #theta = -(np.random.uniform(size=(n_states,))) - theta = np.full((n_states,), -0.1) + theta = -(np.random.uniform(size=(n_states,))) + #theta = np.full((n_states,), -0.1) - #print("THETA", theta) + # print("THETA", theta) if args.render: car = MountainCar(True, one_feature) @@ -115,15 +114,8 @@ def main(args): trainer = MaxEntropyIRL(car, feature_matrix, one_feature, q_table, q_learning_rate, gamma, n_states, theta) trainer.test() - if args.algorithm == "gail" and args.training: - trainer = GAILIRL(car) - trainer.train() - if args.algorithm == "iq-learn" and args.training: - car = MountainCar(True, one_feature) - eval_car = MountainCar(True, one_feature) - - trainer = IQLearnIRL(car, eval_car) + trainer = IQLearn() trainer.train() if args.algorithm == "iq-learn" and args.testing: diff --git a/theta_deep.png b/theta_deep.png new file mode 100644 index 0000000000000000000000000000000000000000..ab66388cc183deec9b960308097ebafd841d3320 GIT binary patch literal 488 zcmVP)N&hk}h!wZy4jI&DZ$?HMr&Ror^bs7{|jzm^Ae6 z2FAY}0F*)ZQv6Nb+aJ)9#0fayIXx9i;Q+PKw7K;;K?cKmILce>7`QB+Btig0o7tno zvVjXa;HAnv#-}jFV+kn&Jh50|ro_nb2~NuH^SZkBdr;$f03fFY*)kx8%Qg9W!vYTp z`SVg%4*;M>;X?{&2RJ+{WYvzH&SUYyA^id;CfLSUTu(YY`GPWo&NB_7t8|Okm*;sU`Hj5uP{L7 ew{V7f@h+!`f5u^`EQf3W0000P)hg z2FAY}0I75vt0Zm&8c+Mp)C^1QKR^{r;Q;ma0L&|PaxUn#VghLPFv2pPBtige-~8U< z%Bnnf0pI{<#k)VuYzZj=y~^LZiU$9x0U|I=Y%pd56| zB}w0iSRC~Fl>c8SYF)K!1fclP-StsmJ25Ge9K-jcOkKn0$^jtrI(7VCOt?MSIl(m@ zAV#rG9nJwU@FpU3su~-iNN5D7DDbhvc=vP!WzAw4ml!*P6Ryf=5u>@fBV`Cs0VL`m z`MqxVAJN4^3v>COQH@%v%L0(j?N1~OxCc1fUZ)s}qWkc{7t93Qxan6*{o@>FjY~p+ ew{XCEqCKbmCCBFf83%R%0000 Date: Sun, 26 Nov 2023 14:35:36 +0100 Subject: [PATCH 4/7] working MaxEntropyDeepIRL --- expert_deep.png | Bin 251 -> 0 bytes expert_flat.png | Bin 251 -> 0 bytes feature_matrix_deep.png | Bin 488 -> 0 bytes feature_matrix_flat.png | Bin 488 -> 0 bytes learner_deep.png | Bin 354 -> 0 bytes learner_flat.png | Bin 447 -> 0 bytes src/irlwpython/ContinuousMaxEntropyDeepIRL.py | 193 ---------------- .../DiscreteMaxEntropyDeepActionOutput.py | 214 ------------------ .../DiscreteMaxEntropyDeepWActionInput.py | 183 --------------- src/irlwpython/IQLearnIRL.py | 13 -- src/irlwpython/MaxEntropyDeep.py | 175 ++++++++++++++ src/irlwpython/MaxEntropyIRL.py | 19 +- src/irlwpython/MountainCar.py | 2 +- theta_deep.png | Bin 488 -> 0 bytes theta_flat.png | Bin 488 -> 0 bytes 15 files changed, 192 insertions(+), 607 deletions(-) delete mode 100644 expert_deep.png delete mode 100644 expert_flat.png delete mode 100644 feature_matrix_deep.png delete mode 100644 feature_matrix_flat.png delete mode 100644 learner_deep.png delete mode 100644 learner_flat.png delete mode 100644 src/irlwpython/ContinuousMaxEntropyDeepIRL.py delete mode 100644 src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py delete mode 100644 src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py delete mode 100644 src/irlwpython/IQLearnIRL.py create mode 100644 src/irlwpython/MaxEntropyDeep.py delete mode 100644 theta_deep.png delete mode 100644 theta_flat.png diff --git a/expert_deep.png b/expert_deep.png deleted file mode 100644 index 99392c4f7dc1a1f8c8c382e2d809dfa6076c627b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmVQuuPCxH3==U~0FJf^@RJC7UbvUfoNVNaD?pET&MKW~!QG|FfjKAW!1=rxtB9MFPd zHmx!jiv8W)EcIg1l`+GfxjO$PK$KROl;Sh8)&rHnID^>^Mw|cu002ovPDHLkV1f=^ BYvup| diff --git a/expert_flat.png b/expert_flat.png deleted file mode 100644 index 99392c4f7dc1a1f8c8c382e2d809dfa6076c627b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmVQuuPCxH3==U~0FJf^@RJC7UbvUfoNVNaD?pET&MKW~!QG|FfjKAW!1=rxtB9MFPd zHmx!jiv8W)EcIg1l`+GfxjO$PK$KROl;Sh8)&rHnID^>^Mw|cu002ovPDHLkV1f=^ BYvup| diff --git a/feature_matrix_deep.png b/feature_matrix_deep.png deleted file mode 100644 index dc27a4aab6c2fd2c3bfb135f67dd4f617019b653..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmVP)ORL=j2?;-b{ONP&DZ$?Im+@8$fP`tNB7Awu{!y?YzZj=!@%FmtRwT4;t4@iX*1N$6lXKC0AR~O@V+z8U3(S1@I^cs z6aB?w4+O3g)@?vimlv4=-%iO4{-XX$AMOIiImp!vj0UU~1n+8L*rn(KT4Xi=upMpE zIArscQx*URpa^CyZeX};0YT*&4%UjNIT85+7P2vQOnSx@i~%6}K4b)EQ@T6XHo!9* zA4aiE8q5JP@Gu@|vL7F!NM-`2CF`=rg!X0xWzAwCmkKh76sg5!37EXYvsVXD0VL`m z`M`7Y7|_E+3U~paNsU^n%L0(j?N1>Dwh%?;YP1@In)~p<7t8|Okm*;sU_KXkp(H!q ew{V7f@h+#DIKsZ_&LKPi0000P)ORL=j2?;-b{ONP&DZ$?Im+@8$fP`tNB7Awu{!y?YzZj=!@%FmtRwT4;t4@iX*1N$6lXKC0AR~O@V+z8U3(S1@I^cs z6aB?w4+O3g)@?vimlv4=-%iO4{-XX$AMOIiImp!vj0UU~1n+8L*rn(KT4Xi=upMpE zIArscQx*URpa^CyZeX};0YT*&4%UjNIT85+7P2vQOnSx@i~%6}K4b)EQ@T6XHo!9* zA4aiE8q5JP@Gu@|vL7F!NM-`2CF`=rg!X0xWzAwCmkKh76sg5!37EXYvsVXD0VL`m z`M`7Y7|_E+3U~paNsU^n%L0(j?N1>Dwh%?;YP1@In)~p<7t8|Okm*;sU_KXkp(H!q ew{V7f@h+#DIKsZ_&LKPi000040*Dluw2i5E~>W(G#|M8?EY+XA}qL?Wg0w~%-d4*^Wa`CX{NmGAOdz5oEt zh1U3+wlb(Z1Uj$?+5p_N4O2AzRVHcc%&(+Uk5v4il7po0s?K$mYo>1ulWgI$#7%r0 z$f`mEK)Tw?F0FjB^qp0b3jkR4v()=EPQB}V5pp6RvLn5&9v&w18cd-ihK7g*KV7~I zmdBCYShH^0s}q5bstR{v8lgVfz`RkiHm+J-zY&^v!S3nsc9t06O5 z(5x9DI=z04L{XY&8a8tgW@QNgcDLPERl0ZXQ)i?(&k@1A8^N`miOo99p$QFofKgL2 zH?%1m!Gw_kA^_|0(U4n)z_4w_;WVj`tAg-PUlOLIks`soMF0Q*07*qoM6N<$f|&}M A3;+NC diff --git a/learner_flat.png b/learner_flat.png deleted file mode 100644 index b735f5b93c52053f9b79f6b7961c3d46580777a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 447 zcmV;w0YLtVP)F<{{Qy$@fWzD1h1f&m>>_s+mCPV+=Z%Ukrm`qQUCXw zN$L9~4#A5*A%Yz2YC6w;asL0!?s}1xH$- zz+x3{u=U=%6Wj$Sr#&|L_}lp8F9rq{A?|GotGac?(-}6zebfEHpmXsr1C!AAvnu>2 zw{diOoHhES&cmfF#lXPyMd;f_mOg;CC&x3qAh2;nf311_p-xrK>OA{>#WF$nouO+(ox9e^?k87#stCOqurS`;RZW pEPI8%BEnjA+N*6>m&q{T0RX1Gn*w?mEM))y002ovPDHLkV1kKI-C+O# diff --git a/src/irlwpython/ContinuousMaxEntropyDeepIRL.py b/src/irlwpython/ContinuousMaxEntropyDeepIRL.py deleted file mode 100644 index 046d68f..0000000 --- a/src/irlwpython/ContinuousMaxEntropyDeepIRL.py +++ /dev/null @@ -1,193 +0,0 @@ -import gym -import numpy as np -import torch -import torch.optim as optim -import torch.nn as nn -import matplotlib.pyplot as plt - - -class ActorNetwork(nn.Module): - def __init__(self, num_inputs, num_output, hidden_size): - super(ActorNetwork, self).__init__() - self.fc1 = nn.Linear(num_inputs, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, num_output) - - def forward(self, x): - x = nn.functional.relu(self.fc1(x)) - x = nn.functional.relu(self.fc2(x)) - return self.fc3(x) # torch.nn.functional.softmax(self.fc3(x)) - - -class CriticNetwork(nn.Module): - def __init__(self, num_inputs, hidden_size): - super(CriticNetwork, self).__init__() - self.fc1 = nn.Linear(num_inputs, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, 1) - - self.theta_layer = nn.Linear(hidden_size, 3) - - def forward(self, x): - x_ = nn.functional.relu(self.fc1(x)) - x_ = nn.functional.relu(self.fc2(x_)) - theta_ = self.theta_layer(x_) - return self.fc3(x_) + torch.matmul(theta_, x) - - -class MaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, learning_rate=0.001, gamma=0.99, num_epochs=1000): - self.target = target - self.state_dim = state_dim - self.action_dim = action_dim - self.learning_rate = learning_rate - # self.theta = torch.rand(state_dim + 1, requires_grad=True) - self.gamma = gamma - self.num_epochs = num_epochs - self.actor_network = ActorNetwork(state_dim, action_dim, 100) - self.critic_network = CriticNetwork(state_dim + 1, 100) - self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=learning_rate) - self.optimizer_critic = optim.Adam(self.critic_network.parameters(), lr=learning_rate) - - def get_reward(self, state, action): - state_action = list(state) + list([action]) - state_action = torch.Tensor(state_action) - return self.critic_network(state_action) - - def expert_feature_expectations(self, demonstrations): - feature_expectations = torch.zeros(self.state_dim) - - for demonstration in demonstrations: - for state, _, _ in demonstration: - state_tensor = torch.tensor(state, dtype=torch.float32) - feature_expectations += state_tensor.squeeze() - - feature_expectations /= demonstrations.shape[0] - return feature_expectations - - def maxent_irl(self, expert, learner): - # Update critic network - - self.optimizer_critic.zero_grad() - - # Loss function for critic network - loss_critic = torch.nn.functional.mse_loss(learner, expert) - loss_critic.backward() - - self.optimizer_critic.step() - - def update_q_network(self, state_array, action, reward, next_state): - self.optimizer_actor.zero_grad() - - state_tensor = torch.tensor(state_array, dtype=torch.float32) - next_state_tensor = torch.tensor(next_state, dtype=torch.float32) - - q_values = self.actor_network(state_tensor) - # q_1 = self.actor_network(state_tensor)[action] - # q_2 = reward + self.gamma * max(self.actor_network(next_state_tensor)) - next_q_values = reward + self.gamma * self.actor_network(next_state_tensor) - - loss_actor = nn.functional.mse_loss(q_values, next_q_values) - loss_actor.backward() - self.optimizer_actor.step() - - def get_demonstrations(self): - env_low = self.target.observation_space.low - env_high = self.target.observation_space.high - env_distance = (env_high - env_low) / 20 # self.one_feature - - raw_demo = np.load(file="expert_demo/expert_demo.npy") - demonstrations = np.zeros((len(raw_demo), len(raw_demo[0]), 3)) - for x in range(len(raw_demo)): - for y in range(len(raw_demo[0])): - position_idx = int((raw_demo[x][y][0] - env_low[0]) / env_distance[0]) - velocity_idx = int((raw_demo[x][y][1] - env_low[1]) / env_distance[1]) - state_idx = position_idx + velocity_idx * 20 # self.one_feature - - demonstrations[x][y][0] = state_idx - demonstrations[x][y][1] = raw_demo[x][y][2] - - print(demonstrations) - return demonstrations - - def get_expert_state_frequencies(self): - raw_demo = np.load(file="expert_demo/expert_demo.npy") - expert_state_frequencies = [] - return expert_state_frequencies - - def train(self): - demonstrations = self.get_demonstrations() - expert = self.expert_feature_expectations(demonstrations) - - expert_state_frequencies = self.get_expert_state_frequencies() - - learner_feature_expectations = torch.zeros(self.state_dim, requires_grad=True) # Add requires_grad=True - episodes, scores = [], [] - - for episode in range(self.num_epochs): - state, info = self.target.reset() - score = 0 - - if (episode != 0 and episode == 10) or (episode > 10 and episode % 5 == 0): - learner = learner_feature_expectations / episode - self.maxent_irl(expert, learner) - - while True: - state_tensor = torch.tensor(state, dtype=torch.float32) - - q_state = self.actor_network(state_tensor) - action = torch.argmax(q_state).item() - next_state, reward, done, _, _ = self.target.step(action) - - irl_reward = self.get_reward(state, action) - self.update_q_network(state, action, irl_reward, next_state) - - print("Q Actor Network", state, q_state) - print("Reward", reward, "IRL Reward", irl_reward) - - learner_feature_expectations = learner_feature_expectations + state_tensor.squeeze() - - print(expert) - print(learner_feature_expectations) - - score += reward - state = next_state - if done: - scores.append(score) - episodes.append(episode) - break - - if episode % 1 == 0: - score_avg = np.mean(scores) - print('{} episode score is {:.2f}'.format(episode, score_avg)) - plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/maxent_30000_network.png") - - torch.save(self.q_network.state_dict(), "./results/maxent_30000_q_network.pth") - - def test(self): - episodes, scores = [], [] - - for episode in range(10): - state = self.target.reset() - score = 0 - - while True: - self.target.render() - state_tensor = torch.tensor(state, dtype=torch.float32).unsqueeze(0) - - action = torch.argmax(self.q_network(state_tensor)).item() - next_state, reward, done, _, _ = self.target.step(action) - - score += reward - state = next_state - - if done: - scores.append(score) - episodes.append(episode) - plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/maxent_test_30000_network.png") - break - - if episode % 1 == 0: - print('{} episode score is {:.2f}'.format(episode, score)) diff --git a/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py b/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py deleted file mode 100644 index dab53ec..0000000 --- a/src/irlwpython/DiscreteMaxEntropyDeepActionOutput.py +++ /dev/null @@ -1,214 +0,0 @@ -import math -import os -import random - -import gym -import numpy as np -import torch -import torch.optim as optim -import torch.nn as nn -import matplotlib.pyplot as plt -import PIL - -class QNetwork(nn.Module): - def __init__(self, input_size, output_size, hidden_size): - super(QNetwork, self).__init__() - - # Define the layers of your neural network - self.layers = nn.Sequential( - nn.Linear(input_size, hidden_size), - #nn.ReLU(), # You can use other activation functions here - nn.Linear(hidden_size, hidden_size), - nn.Linear(hidden_size, hidden_size), - #nn.Linear(hidden_size, hidden_size), - #nn.Linear(hidden_size, hidden_size), - #nn.ReLU(), - nn.Linear(hidden_size, output_size), - #nn.Softmax() - ) - - def forward(self, x): - # Define the forward pass of your neural network - return self.layers(x) - - -class DiscreteMaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.05, gamma=0.9, - num_epochs=1000): - self.feat_matrix = feature_matrix - self.one_feature = 20 - - self.target = target - self.state_dim = state_dim - self.action_dim = action_dim - self.learning_rate = learning_rate - - # self.actor_network = ActorNetwork(2, 3, 100) - self.actor_network = QNetwork(2, 3, 200) - self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=0.01) - - self.gamma = gamma - self.num_epochs = num_epochs - - self.theta = theta - - def tensor_to_image(self, tensor, name): - tensor = tensor * 255 - tensor = np.array(tensor, dtype=np.uint8) - if np.ndim(tensor) > 3: - assert tensor.shape[0] == 1 - tensor = tensor[0] - tensor_img = PIL.Image.fromarray(tensor) - tensor_img.save(f"{name}.png", "PNG") - - def get_reward(self, state): - state_idx = self.target.state_to_idx(state) - irl_rewards = self.feat_matrix.dot(self.theta).reshape((400,)) - return irl_rewards[int(state_idx)] - - def expert_feature_expectations(self, demonstrations): - feature_expectations = np.zeros(self.feat_matrix.shape[0]) - - for demonstration in demonstrations: - for state_idx, _, _ in demonstration: - feature_expectations += self.feat_matrix[int(state_idx)] - - feature_expectations /= demonstrations.shape[0] - return feature_expectations - - def maxent_irl(self, expert, learner): - gradient = expert - learner - self.theta += self.learning_rate * gradient.detach().numpy() - - - #print("EXPERT", expert) - #print("LEARNER", learner) - #print("THETA", self.theta) - self.tensor_to_image(expert.reshape(20,20), "expert_deep") - self.tensor_to_image(learner.reshape(20,20), "learner_deep") - self.tensor_to_image(self.theta.reshape(20,20), "theta_deep") - - # Clip theta - for j in range(len(self.theta)): - if self.theta[j] > 0: # log values - self.theta[j] = 0 - - def update_q_network(self, q_state_0: torch.tensor, q_state_1, q_state_2, action, reward, next_q_state): - q_2 = reward + self.gamma * torch.max(next_q_state) - - if action == 0: - # q_state_0.requires_grad = True - q_1 = q_state_0 - # loss = torch.nn.functional.mse_loss(torch.tensor([q_2, 0, 0], requires_grad=True), q_state) - if action == 1: - # q_state_1.requires_grad = True - q_1 = q_state_1 - # loss = torch.nn.functional.mse_loss(torch.tensor([0, q_2, 0], requires_grad=True), q_state) - if action == 2: - # q_state_2.requires_grad = True - q_1 = q_state_2 - # loss = torch.nn.functional.mse_loss(torch.tensor([0, 0, q_2], requires_grad=True), q_state) - - loss = torch.nn.functional.mse_loss(0.01*(q_2 - q_1), q_1) - - self.optimizer_actor.zero_grad() - - loss.backward(retain_graph=True) - - # Print the gradients for each parameter - for name, param in self.actor_network.named_parameters(): - if name == "layers.3.bias": - if param.grad is not None: - pass - #print(name, param.grad) - - self.optimizer_actor.step() - - def train(self): - demonstrations = self.target.get_demonstrations() - expert = self.expert_feature_expectations(demonstrations) - expert = torch.Tensor(expert).detach() - learner_feature_expectations = torch.zeros(400).detach() - episodes, scores = [], [] - steps = 0 - for episode in range(20): # self.num_epochs): - state, info = self.target.env_reset() - score = 0 - - iteration = 0 - while True: - steps += 1 - iteration += 1 - if iteration > 2000: - #while True: - pass - #scores.append(-2000) - #episodes.append(episode) - #break - state_idx = self.target.state_to_idx(state) - state_discrete = self.target.discretize_state(state) - - # Forward Pass - state_tensor = torch.tensor(state_discrete, dtype=torch.float32, requires_grad=True) - q_state_0, q_state_1, q_state_2 = self.actor_network(state_tensor) - - # Epsilon Greedy Action Selection - epsilon = 0.1 - if random.uniform(0, 1) > epsilon: - #alpha = 0.3 - #probs = torch.softmax(torch.tensor([q_state_0, q_state_1, q_state_2]) / alpha, dim=0) - #action = torch.multinomial(probs, 1).item() # sample action from softmax - action = torch.argmax(torch.tensor([q_state_0, q_state_1, q_state_2])).item() - else: - action = random.randint(0, 2) - - next_state, reward, done, _, _ = self.target.env_step(action) - next_state_discrete = self.target.discretize_state(next_state) - next_state_tensor = torch.tensor(next_state_discrete, dtype=torch.float32) - next_q_state = self.actor_network(next_state_tensor).detach() - - # Actor update - irl_reward = self.get_reward(state) - #os.system('clear' if os.name == 'posix' else 'cls') - #print("Episode", episode) - #print("STATE", state_discrete) - #print("ACTION", action) - #print("Q state", q_state_0, q_state_1, q_state_2) - #print("Next Q state", next_q_state) - #print("Reward", irl_reward) - self.update_q_network(q_state_0, q_state_1, q_state_2, action, irl_reward, next_q_state) - - learner_feature_expectations = learner_feature_expectations + torch.Tensor( - self.feat_matrix[int(state_idx)]) - - score += reward - state = next_state - if done: - scores.append(score) - episodes.append(episode) - break - - # Critic update - if (episode != 0 and episode == 4) or (episode > 4 and episode % 4 == 0): - learner = learner_feature_expectations / episode - self.maxent_irl(expert, learner) - else: - learner = learner_feature_expectations - - if episode == 19: - print("Theta", self.theta) - print("Expert", expert) - print("Learner", learner) - for state_1 in range(20): - for action_1 in range(20): - print("State: ", state_1, action_1, "Q Values", - self.actor_network(torch.tensor([state_1, action_1], dtype=torch.float32)), - "Reward: ", self.get_reward(state, action)) - - if episode % 19 == 0: - score_avg = np.mean(scores) - print('{} episode score is {:.2f}'.format(episode, score_avg)) - plt.plot(episodes, scores, 'b') - plt.savefig("./src/irlwpython/learning_curves/discretemaxentdeep_30000.png") - - torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") diff --git a/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py b/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py deleted file mode 100644 index 5841786..0000000 --- a/src/irlwpython/DiscreteMaxEntropyDeepWActionInput.py +++ /dev/null @@ -1,183 +0,0 @@ -import math -import os - -import gym -import numpy -import numpy as np -import torch -import torch.optim as optim -import torch.nn as nn -import matplotlib.pyplot as plt -import random - -class ActorNetwork(nn.Module): - def __init__(self, num_inputs, num_output, hidden_size): - super(ActorNetwork, self).__init__() - self.fc1 = nn.Linear(5, hidden_size) - self.fc2 = nn.Linear(hidden_size, hidden_size) - self.fc4 = nn.Linear(hidden_size, hidden_size) - self.fc3 = nn.Linear(hidden_size, 1) - - def forward(self, x): - x = torch.relu(self.fc1(x)) - x = torch.relu(self.fc2(x)) - x = self.fc4(x) - x = self.fc3(x) - return x - - -class DiscreteMaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_dim, feature_matrix=None, theta=None, learning_rate=0.01, gamma=0.9, - num_epochs=1000): - self.feat_matrix = feature_matrix - self.one_feature = 20 - - self.target = target - self.state_dim = state_dim - self.action_dim = action_dim - self.learning_rate = learning_rate - - self.actor_network = ActorNetwork(5, 1, 100) - self.optimizer_actor = optim.Adam(self.actor_network.parameters(), lr=0.01) - - self.gamma = gamma - self.num_epochs = num_epochs - - self.theta = theta - - def get_reward(self, state, action): - state_idx = self.target.state_to_idx(state) - irl_rewards = self.feat_matrix.dot(self.theta).reshape((400,)) - return irl_rewards[int(state_idx)] - - def expert_feature_expectations(self, demonstrations): - feature_expectations = np.zeros(self.feat_matrix.shape[0]) - - for demonstration in demonstrations: - for state_idx, _, _ in demonstration: - feature_expectations += self.feat_matrix[int(state_idx)] - - feature_expectations /= demonstrations.shape[0] - return feature_expectations - - def maxent_irl(self, expert, learner): - gradient = expert - learner - self.theta += self.learning_rate * gradient.detach().numpy() - - # Clip theta - for j in range(len(self.theta)): - if self.theta[j] > 0: # log values - self.theta[j] = 0 - - def update_q_network(self, q_state, action, reward, next_state_dicrete): - state_0 = list(next_state_dicrete) - state_0 += [1.0, 0.0, 0.0] - state_1 = list(next_state_dicrete) - state_1 += [0.0, 1.0, 0.0] - state_2 = list(next_state_dicrete) - state_2 += [0.0, 0.0, 1.0] - - state_0_tensor = torch.tensor(state_0, dtype=torch.float32).detach() - state_1_tensor = torch.tensor(state_1, dtype=torch.float32).detach() - state_2_tensor = torch.tensor(state_2, dtype=torch.float32).detach() - - next_q_state = torch.tensor([self.actor_network(state_0_tensor), - self.actor_network(state_1_tensor), - self.actor_network(state_2_tensor)]).detach() - - #action = torch.max(q_state.detach()).item() - #print("Next Q State Softmax", next_state_abs) - #print(torch.max(next_q_state).detach()) - - q_1 = q_state - q_2 = reward + self.gamma * torch.max(next_q_state) - - loss = torch.nn.functional.mse_loss(q_2, q_1) - self.optimizer_actor.zero_grad() - print("Loss", loss) - loss.backward() - self.optimizer_actor.step() - - def train(self): - demonstrations = self.target.get_demonstrations() - expert = self.expert_feature_expectations(demonstrations) - expert = torch.Tensor(expert) - learner_feature_expectations = torch.zeros(400) - episodes, scores = [], [] - - for episode in range(self.num_epochs): - state, info = self.target.env_reset() - score = 0 - - iteration = 0 - while True: - iteration += 1 - if iteration > 300: - scores.append(-1000) - episodes.append(episode) - break - state_idx = self.target.state_to_idx(state) - state_discrete = self.target.discretize_state(state) - - state_0 = list(state_discrete) - state_0 += [1.0, 0.0, 0.0] - state_1 = list(state_discrete) - state_1 += [0.0, 1.0, 0.0] - state_2 = list(state_discrete) - state_2 += [0.0, 0.0, 1.0] - - state_0_tensor = torch.tensor(state_0, dtype=torch.float32, requires_grad=True) - state_1_tensor = torch.tensor(state_1, dtype=torch.float32, requires_grad=True) - state_2_tensor = torch.tensor(state_2, dtype=torch.float32, requires_grad=True) - - q_state = torch.tensor([self.actor_network(state_0_tensor), - self.actor_network(state_1_tensor), - self.actor_network(state_2_tensor)], requires_grad=True) - - - # Epsilon Greedy Action Selection - epsilon = 0.1 - if random.uniform(0, 1) > epsilon: - action = torch.argmax(q_state.detach()).item() - else: - action = random.randint(0, 2) - - next_state, reward, done, _, _ = self.target.env_step(action) - - next_state_discrete = self.target.discretize_state(next_state) - #next_state_tensor = torch.tensor(next_state_discrete, dtype=torch.float32) - - # Actor update - irl_reward = self.get_reward(state, action) - os.system('clear' if os.name == 'posix' else 'cls') - print("State", state_discrete) - print("Action", action) - print("Reward", reward, "IRL_reward", irl_reward) - print("Q State", q_state) - print("Next Dircete", next_state_discrete) - self.update_q_network(q_state, action, irl_reward, next_state_discrete) - - learner_feature_expectations = learner_feature_expectations + torch.Tensor( - self.feat_matrix[int(state_idx)]) - - score += reward - state = next_state - if done: - scores.append(score) - episodes.append(episode) - break - - # Critic update - if (episode != 0 and episode == 4) or (episode > 4 and episode % 4 == 0): - learner = learner_feature_expectations / episode - self.maxent_irl(expert, learner) - else: - learner = learner_feature_expectations - - if episode % 1 == 0: - score_avg = np.mean(scores) - print('{} episode score is {:.2f}'.format(episode, score_avg)) - plt.plot(episodes, scores, 'b') - # plt.savefig("./learning_curves/discretemaxentdeep_30000.png") - - torch.save(self.actor_network.state_dict(), "./results/discretemaxentdeep_30000_actor.pth") diff --git a/src/irlwpython/IQLearnIRL.py b/src/irlwpython/IQLearnIRL.py deleted file mode 100644 index e70c5c4..0000000 --- a/src/irlwpython/IQLearnIRL.py +++ /dev/null @@ -1,13 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt - - -class MaxEntropyIRL: - def __init__(self, target): - self.target = target - - def train(self, theta_learning_rate): - pass - - def test(self): - pass \ No newline at end of file diff --git a/src/irlwpython/MaxEntropyDeep.py b/src/irlwpython/MaxEntropyDeep.py new file mode 100644 index 0000000..e4b9da5 --- /dev/null +++ b/src/irlwpython/MaxEntropyDeep.py @@ -0,0 +1,175 @@ +import math +import os +import random + +import gym +import numpy as np +import torch +import torch.optim as optim +import torch.nn as nn +import matplotlib.pyplot as plt +import PIL + + +class QNetwork(nn.Module): + def __init__(self, input_size, output_size): + super(QNetwork, self).__init__() + self.fc1 = nn.Linear(input_size, 128) + self.relu1 = nn.ReLU() + # self.fc2 = nn.Linear(128, 128) + # self.relu2 = nn.ReLU() + self.output_layer = nn.Linear(128, output_size) + + def forward(self, state): + x = self.fc1(state) + x = self.relu1(x) + # x = self.fc2(x) + # x = self.relu2(x) + q_values = self.output_layer(x) + return q_values + + +class MaxEntropyDeepIRL: + def __init__(self, target, state_dim, action_size, feature_matrix=None, one_feature=None, theta=None, learning_rate=0.05, gamma=0.9, + num_epochs=1000): + self.feature_matrix = feature_matrix + self.one_feature = one_feature + + self.target = target + self.state_dim = state_dim + self.action_dim = action_size + + self.q_network = QNetwork(state_dim, action_size) + self.target_q_network = QNetwork(state_dim, action_size) + self.target_q_network.load_state_dict(self.q_network.state_dict()) + self.optimizer = optim.Adam(self.q_network.parameters(), lr=learning_rate) + + self.gamma = gamma + self.num_epochs = num_epochs + + self.theta_learning_rate = 0.05 + self.theta = theta + + def tensor_to_image(self, tensor, name): + tensor = tensor * 255 + tensor = np.array(tensor, dtype=np.uint8) + if np.ndim(tensor) > 3: + assert tensor.shape[0] == 1 + tensor = tensor[0] + tensor_img = PIL.Image.fromarray(tensor) + tensor_img.save(f"{name}.png", "PNG") + + def select_action(self, state, epsilon): + if np.random.rand() < epsilon: + return np.random.choice(3) + else: + with torch.no_grad(): + q_values = self.q_network(torch.FloatTensor(state)) + return torch.argmax(q_values).item() + + def get_reward(self, n_states, state_idx): + """ + Returns the achieved reward. + :param n_states: + :param state_idx: + :return: + """ + irl_rewards = self.feature_matrix.dot(self.theta).reshape((n_states,)) + return irl_rewards[state_idx] + + def expert_feature_expectations(self, demonstrations): + feature_expectations = np.zeros(self.feature_matrix.shape[0]) + + for demonstration in demonstrations: + for state_idx, _, _ in demonstration: + feature_expectations += self.feature_matrix[int(state_idx)] + + feature_expectations /= demonstrations.shape[0] + return feature_expectations + + def maxent_irl(self, expert, learner): + """ + Max Entropy Learning step. + :param expert: + :param learner: + :param learning_rate: + :return: + """ + gradient = expert - learner + self.theta += self.theta_learning_rate * gradient + + # Clip theta + for j in range(len(self.theta)): + if self.theta[j] > 0: # log values + self.theta[j] = 0 + + def update_q_network(self, state, action, reward, next_state, done): + state = torch.FloatTensor(state) + next_state = torch.FloatTensor(next_state) + q_values = self.q_network(state) + next_q_values = self.target_q_network(next_state) + + target = q_values.clone() + if not done: + target[action] = reward + self.gamma * torch.max(next_q_values).item() + else: + target[action] = reward + + loss = nn.MSELoss()(q_values, target.detach()) + self.optimizer.zero_grad() + loss.backward() + self.optimizer.step() + + def update_target_network(self): + self.target_q_network.load_state_dict(self.q_network.state_dict()) + + def train(self, n_states, episodes=10000, max_steps=10000, + epsilon_start=1.0, + epsilon_decay=0.995, epsilon_min=0.01): + epsilon = epsilon_start + episode_arr, scores = [], [] + + demonstrations = self.target.get_demonstrations() + expert = self.expert_feature_expectations(demonstrations) + learner_feature_expectations = np.zeros(n_states) + + for episode in range(episodes): + state, info = self.target.env_reset() + total_reward = 0 + + # Mini-Batches: + if (episode != 0 and episode == 1000) or (episode > 1000 and episode % 500 == 0): + # calculate density + learner = learner_feature_expectations / episode + # Maximum Entropy IRL step + self.maxent_irl(expert, learner) + + for step in range(max_steps): + action = self.select_action(state, epsilon) + + next_state, reward, done, _, _ = self.target.env_step(action) + # Real Reward + total_reward += reward + + # IRL + state_idx = self.target.state_to_idx(state) + irl_reward = self.get_reward(n_states, state_idx) + + self.update_q_network(state, action, irl_reward, next_state, done) + self.update_target_network() + + # State counting for densitiy + learner_feature_expectations += self.feature_matrix[int(state_idx)] + + state = next_state + if done: + scores.append(total_reward) + episode_arr.append(episode) + break + + epsilon = max(epsilon * epsilon_decay, epsilon_min) + print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") + + if episode == episodes - 1: + plt.plot(episode_arr, scores, 'b') + plt.savefig("./learning_curves/maxent_30000.png") diff --git a/src/irlwpython/MaxEntropyIRL.py b/src/irlwpython/MaxEntropyIRL.py index dcfe81f..0fe39b0 100644 --- a/src/irlwpython/MaxEntropyIRL.py +++ b/src/irlwpython/MaxEntropyIRL.py @@ -6,7 +6,7 @@ import numpy as np import matplotlib.pyplot as plt - +import PIL class MaxEntropyIRL: def __init__(self, target, feature_matrix, one_feature, q_table, q_learning_rate, gamma, n_states, theta): @@ -19,6 +19,15 @@ def __init__(self, target, feature_matrix, one_feature, q_table, q_learning_rate self.gamma = gamma self.n_states = n_states + def numpy_to_image(self, array, name): + array = array * 255 + array = np.array(array, dtype=np.uint8) + if np.ndim(array) > 3: + assert array.shape[0] == 1 + array = array[0] + tensor_img = PIL.Image.fromarray(array) + tensor_img.save(f"{name}.png", "PNG") + def get_feature_matrix(self): """ Returns the feature matrix. @@ -62,6 +71,10 @@ def maxent_irl(self, expert, learner, learning_rate): gradient = expert - learner self.theta += learning_rate * gradient + #self.numpy_to_image(expert.reshape((20,20)), "expert_flat") + #self.numpy_to_image(learner.reshape((20, 20)), "learner_flat") + #self.numpy_to_image(self.theta.reshape((20, 20)), "theta_flat") + # Clip theta for j in range(len(self.theta)): if self.theta[j] > 0: # log values @@ -136,8 +149,8 @@ def train(self, theta_learning_rate): score_avg = np.mean(scores) print('{} episode score is {:.2f}'.format(episode, score_avg)) plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/maxent_30000.png") - np.save("./results/maxent_30000_table", arr=self.q_table) + # plt.savefig("./learning_curves/maxent_30000.png") + # np.save("./results/maxent_30000_table", arr=self.q_table) def test(self): """ diff --git a/src/irlwpython/MountainCar.py b/src/irlwpython/MountainCar.py index 2543615..5c1dcf7 100644 --- a/src/irlwpython/MountainCar.py +++ b/src/irlwpython/MountainCar.py @@ -27,7 +27,7 @@ def get_demonstrations(self): env_high = self.env.observation_space.high env_distance = (env_high - env_low) / self.one_feature - raw_demo = np.load(file="src/irlwpython/expert_demo/expert_demo.npy") + raw_demo = np.load(file="./expert_demo/expert_demo.npy") demonstrations = np.zeros((len(raw_demo), len(raw_demo[0]), 3)) for x in range(len(raw_demo)): for y in range(len(raw_demo[0])): diff --git a/theta_deep.png b/theta_deep.png deleted file mode 100644 index ab66388cc183deec9b960308097ebafd841d3320..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmVP)N&hk}h!wZy4jI&DZ$?HMr&Ror^bs7{|jzm^Ae6 z2FAY}0F*)ZQv6Nb+aJ)9#0fayIXx9i;Q+PKw7K;;K?cKmILce>7`QB+Btig0o7tno zvVjXa;HAnv#-}jFV+kn&Jh50|ro_nb2~NuH^SZkBdr;$f03fFY*)kx8%Qg9W!vYTp z`SVg%4*;M>;X?{&2RJ+{WYvzH&SUYyA^id;CfLSUTu(YY`GPWo&NB_7t8|Okm*;sU`Hj5uP{L7 ew{V7f@h+!`f5u^`EQf3W0000P)hg z2FAY}0I75vt0Zm&8c+Mp)C^1QKR^{r;Q;ma0L&|PaxUn#VghLPFv2pPBtige-~8U< z%Bnnf0pI{<#k)VuYzZj=y~^LZiU$9x0U|I=Y%pd56| zB}w0iSRC~Fl>c8SYF)K!1fclP-StsmJ25Ge9K-jcOkKn0$^jtrI(7VCOt?MSIl(m@ zAV#rG9nJwU@FpU3su~-iNN5D7DDbhvc=vP!WzAw4ml!*P6Ryf=5u>@fBV`Cs0VL`m z`MqxVAJN4^3v>COQH@%v%L0(j?N1~OxCc1fUZ)s}qWkc{7t93Qxan6*{o@>FjY~p+ ew{XCEqCKbmCCBFf83%R%0000 Date: Sun, 26 Nov 2023 15:34:05 +0100 Subject: [PATCH 5/7] refactor --- .../GenerateDemonstrationsMountainCar.py | 44 ++++++++++++++++++ src/irlwpython/MaxEntropyDeep.py | 11 +++-- src/irlwpython/MaxEntropyIRL.py | 4 +- .../learning_curves/maxent_30000.png | Bin 14834 -> 0 bytes .../learning_curves/maxent_30000_flat.png | Bin 0 -> 15548 bytes .../learning_curves/maxent_30000_network.png | Bin 23218 -> 0 bytes src/irlwpython/main.py | 28 +++-------- 7 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 src/irlwpython/GenerateDemonstrationsMountainCar.py delete mode 100644 src/irlwpython/learning_curves/maxent_30000.png create mode 100644 src/irlwpython/learning_curves/maxent_30000_flat.png delete mode 100644 src/irlwpython/learning_curves/maxent_30000_network.png diff --git a/src/irlwpython/GenerateDemonstrationsMountainCar.py b/src/irlwpython/GenerateDemonstrationsMountainCar.py new file mode 100644 index 0000000..3e37c0c --- /dev/null +++ b/src/irlwpython/GenerateDemonstrationsMountainCar.py @@ -0,0 +1,44 @@ +import gym +import readchar +import numpy as np + +# # MACROS +Push_Left = 0 +No_Push = 1 +Push_Right = 2 + +# Key mapping +arrow_keys = { + '\x1b[D': Push_Left, + '\x1b[B': No_Push, + '\x1b[C': Push_Right} + +env = gym.make('MountainCar-v0')#, render_mode="human") + +trajectories = [] +episode_step = 0 + +for episode in range(1): # n_trajectories : 20 + trajectory = [] + step = 0 + + env.reset() + print("episode_step", episode_step) + + while True: + env.render() + print("step", step) + + key = readchar.readkey() + if key not in arrow_keys.keys(): + break + + action = arrow_keys[key] + state, reward, done, _, _ = env.step(action) + + if state[0] >= env.env.goal_position and step > 129: # trajectory_length : 130 + break + + trajectory.append((state[0], state[1], action)) + step += 1 + print(trajectory) diff --git a/src/irlwpython/MaxEntropyDeep.py b/src/irlwpython/MaxEntropyDeep.py index e4b9da5..f672a9e 100644 --- a/src/irlwpython/MaxEntropyDeep.py +++ b/src/irlwpython/MaxEntropyDeep.py @@ -30,7 +30,8 @@ def forward(self, state): class MaxEntropyDeepIRL: - def __init__(self, target, state_dim, action_size, feature_matrix=None, one_feature=None, theta=None, learning_rate=0.05, gamma=0.9, + def __init__(self, target, state_dim, action_size, feature_matrix=None, one_feature=None, theta=None, + learning_rate=0.05, gamma=0.9, num_epochs=1000): self.feature_matrix = feature_matrix self.one_feature = one_feature @@ -168,8 +169,12 @@ def train(self, n_states, episodes=10000, max_steps=10000, break epsilon = max(epsilon * epsilon_decay, epsilon_min) - print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") + + if episode % 50 == 0: + print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") if episode == episodes - 1: plt.plot(episode_arr, scores, 'b') - plt.savefig("./learning_curves/maxent_30000.png") + plt.savefig(f"./learning_curves/maxentdeep_{episodes}_qdeep.png") + + torch.save(self.q_network.state_dict(), f"./results/maxentdeep_{episodes}_q_network.pth") diff --git a/src/irlwpython/MaxEntropyIRL.py b/src/irlwpython/MaxEntropyIRL.py index 0fe39b0..4d8df5b 100644 --- a/src/irlwpython/MaxEntropyIRL.py +++ b/src/irlwpython/MaxEntropyIRL.py @@ -149,8 +149,8 @@ def train(self, theta_learning_rate): score_avg = np.mean(scores) print('{} episode score is {:.2f}'.format(episode, score_avg)) plt.plot(episodes, scores, 'b') - # plt.savefig("./learning_curves/maxent_30000.png") - # np.save("./results/maxent_30000_table", arr=self.q_table) + plt.savefig("./learning_curves/maxent_30000_qtable.png") + np.save("./results/maxent_30000_table", arr=self.q_table) def test(self): """ diff --git a/src/irlwpython/learning_curves/maxent_30000.png b/src/irlwpython/learning_curves/maxent_30000.png deleted file mode 100644 index 1ea3b08232f8c4c18ad87c31b718e1e8ae75a2c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14834 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 G=zjn|bkM^9 literal 0 HcmV?d00001 diff --git a/src/irlwpython/learning_curves/maxent_30000_network.png b/src/irlwpython/learning_curves/maxent_30000_network.png deleted file mode 100644 index 73cb168faa2845dcaf32051f23eef0d18044edc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23218 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 Date: Wed, 29 Nov 2023 22:20:21 +0100 Subject: [PATCH 6/7] refactor demos --- README.md | 74 +++++- demo/expert_demo/expert_demo_mountaincar.npy | Bin 0 -> 64128 bytes .../expert_state_frequencies_mountaincar.png | Bin 0 -> 11139 bytes .../learner_maxentropydeep_10000_episodes.png | Bin 0 -> 24956 bytes .../learner_maxentropydeep_1000_episodes.png | Bin 0 -> 11741 bytes .../learner_maxentropydeep_15000_episodes.png | Bin 0 -> 25067 bytes .../learner_maxentropydeep_20000_episodes.png | Bin 0 -> 11925 bytes .../learner_maxentropydeep_25000_episodes.png | Bin 0 -> 11968 bytes .../learner_maxentropydeep_29000_episodes.png | Bin 0 -> 25043 bytes .../learner_maxentropydeep_5000_episodes.png | Bin 0 -> 24645 bytes .../rewards_maxentropydeep_10000_episodes.png | Bin 0 -> 12956 bytes .../rewards_maxentropydeep_1000_episodes.png | Bin 0 -> 12971 bytes .../rewards_maxentropydeep_15000_episodes.png | Bin 0 -> 12953 bytes .../rewards_maxentropydeep_20000_episodes.png | Bin 0 -> 12919 bytes .../rewards_maxentropydeep_25000_episodes.png | Bin 0 -> 12914 bytes .../rewards_maxentropydeep_29000_episodes.png | Bin 0 -> 12914 bytes ...learner_maxentropy_deep_29000_episodes.png | Bin 0 -> 13226 bytes ...tropydeep_29000_episodes_model_results.png | Bin 0 -> 18026 bytes ...test_maxentropydeep_best_model_results.png | Bin 0 -> 19739 bytes ...el_maxentropydeep_29000_episodes_model.pth | Bin 0 -> 5456 bytes .../model_maxentropydeep_best_model.pth | Bin 0 -> 5456 bytes .../qtable_maxentropy_30000_episodes.npy | Bin 0 -> 9728 bytes src/__init__.py | 0 src/irlwpython/MaxEntropyDeep.py | 93 ++++--- .../learning_curves/maxent_test_30000.png | Bin 18346 -> 0 bytes src/irlwpython/main.py | 9 +- src/irlwpython/results/maxent_300_table.npy | Bin 9728 -> 0 bytes src/irlwpython/results/maxent_q_table.npy | Bin 9728 -> 0 bytes .../scripts/direct_train_deep_max_entropy.py | 237 ++++++++++++++++++ 29 files changed, 363 insertions(+), 50 deletions(-) create mode 100644 demo/expert_demo/expert_demo_mountaincar.npy create mode 100644 demo/heatmaps/expert_state_frequencies_mountaincar.png create mode 100644 demo/heatmaps/learner_maxentropydeep_10000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_1000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_15000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_20000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_25000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_29000_episodes.png create mode 100644 demo/heatmaps/learner_maxentropydeep_5000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_10000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_1000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_15000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_20000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_25000_episodes.png create mode 100644 demo/heatmaps/rewards_maxentropydeep_29000_episodes.png create mode 100644 demo/learning_curves/learner_maxentropy_deep_29000_episodes.png create mode 100644 demo/test_results/test_maxentropydeep_29000_episodes_model_results.png create mode 100644 demo/test_results/test_maxentropydeep_best_model_results.png create mode 100644 demo/trained_models/model_maxentropydeep_29000_episodes_model.pth create mode 100644 demo/trained_models/model_maxentropydeep_best_model.pth create mode 100644 demo/trained_models/qtable_maxentropy_30000_episodes.npy create mode 100644 src/__init__.py delete mode 100644 src/irlwpython/learning_curves/maxent_test_30000.png delete mode 100644 src/irlwpython/results/maxent_300_table.npy delete mode 100644 src/irlwpython/results/maxent_q_table.npy create mode 100644 src/irlwpython/scripts/direct_train_deep_max_entropy.py diff --git a/README.md b/README.md index 8999b97..dbdf1a1 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,72 @@ Inverse Reinforcement Learning Algorithm implementation with python. -Implemented Algorithms: -- Maximum Entropy IRL: [1] -- Discrete Maximum Entropy Deep IRL: [2, 3] -- IQ-Learn +# Implemented Algorithms -Experiment: -- Mountaincar: [gym](https://www.gymlibrary.dev/environments/classic_control/mountain_car/) +## Maximum Entropy IRL: [1] -The implementation of MaxEntropyIRL and MountainCar is based on the implementation of: -[lets-do-irl](https://github.com/reinforcement-learning-kr/lets-do-irl/tree/master/mountaincar/maxent) +## Maximum Entropy Deep IRL -# References +# Experiments -[1] [BD. Ziebart, et al., "Maximum Entropy Inverse Reinforcement Learning", AAAI 2008](https://cdn.aaai.org/AAAI/2008/AAAI08-227.pdf). +## Mountaincar-v0 +[gym](https://www.gymlibrary.dev/environments/classic_control/mountain_car/) + +The expert demonstrations for the Mountaincar-v0 are the same as used in [lets-do-irl](https://github.com/reinforcement-learning-kr/lets-do-irl/tree/master/mountaincar/maxent). + +*Heatmap of Expert demonstrations with 400 states*: + + + +### Maximum Entropy Inverse Reinforcement Learning + +IRL using Q-Learning with a Maximum Entropy update function. + +[//]: # () + +### Deep Maximum Entropy Inverse Reinforcement Learning + +IRL using Deep Q-Learning with a Maximum Entropy update function. + +#### Training + +*Learner training for 29000 episodes*: + + + +#### Heatmaps + +*Learner state frequencies after 1000 episodes*: -[2] [Wulfmeier, et al., "Maximum entropy deep inverse reinforcement learning." arXiv preprint arXiv:1507.04888 (2015).](https://arxiv.org/abs/1507.04888) + -[3] [Xi-liang Chen, et al., "A Study of Continuous Maximum Entropy Deep Inverse Reinforcement Learning", Mathematical Problems in Engineering, vol. 2019, Article ID 4834516, 8 pages, 2019. https://doi.org/10.1155/2019/4834516](https://www.hindawi.com/journals/mpe/2019/4834516/) +*Learner state frequencies after 29000 episodes*: + + + +*State rewards heatmap after 1000 episodes*: + + + +*State rewards heatmap after 29000 episodes*: + + + +#### Testing + +*Testing results of the model after 29000 episodes*: + + + +### Deep Maximum Entropy Inverse Reinforcement Learning with Critic + +Coming soon... + +# References +The implementation of MaxEntropyIRL and MountainCar is based on the implementation of: +[lets-do-irl](https://github.com/reinforcement-learning-kr/lets-do-irl/tree/master/mountaincar/maxent) + +[1] [BD. Ziebart, et al., "Maximum Entropy Inverse Reinforcement Learning", AAAI 2008](https://cdn.aaai.org/AAAI/2008/AAAI08-227.pdf). # Installation @@ -38,7 +86,7 @@ usage: irl [-h] [--version] [--training] [--testing] [--render] ALGORITHM Implementation of IRL algorithms positional arguments: - ALGORITHM Currently supported training algorithm: [max-entropy, discrete-max-entropy-deep] + ALGORITHM Currently supported training algorithm: [max-entropy, max-entropy-deep] options: -h, --help show this help message and exit diff --git a/demo/expert_demo/expert_demo_mountaincar.npy b/demo/expert_demo/expert_demo_mountaincar.npy new file mode 100644 index 0000000000000000000000000000000000000000..9614e5bcbbdfab942cde61972574538bda6d0cd1 GIT binary patch literal 64128 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 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/expert_state_frequencies_mountaincar.png b/demo/heatmaps/expert_state_frequencies_mountaincar.png new file mode 100644 index 0000000000000000000000000000000000000000..f7947b5c5680900c51d3f217daa00b54d75588d7 GIT binary patch literal 11139 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 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/learner_maxentropydeep_1000_episodes.png b/demo/heatmaps/learner_maxentropydeep_1000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..6542af49746296c7687c9caacad20c6d4c0fc752 GIT binary patch literal 11741 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 Lxh-?cfz$s7a9RBK literal 0 HcmV?d00001 diff --git a/demo/heatmaps/learner_maxentropydeep_20000_episodes.png b/demo/heatmaps/learner_maxentropydeep_20000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..d6df19615b734110ed0c8614a32a854a93b656c3 GIT binary patch literal 11925 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 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/learner_maxentropydeep_5000_episodes.png b/demo/heatmaps/learner_maxentropydeep_5000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..3f9f4ec5cbfe32731ccdba75d55dde4241b70fec GIT binary patch literal 24645 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 P7)tSq@@2xs+YkN&wp<9j literal 0 HcmV?d00001 diff --git a/demo/heatmaps/rewards_maxentropydeep_1000_episodes.png b/demo/heatmaps/rewards_maxentropydeep_1000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff7728c0cd68e53008d34c9d65807c4f1e68982 GIT binary patch literal 12971 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 AV*mgE literal 0 HcmV?d00001 diff --git a/demo/heatmaps/rewards_maxentropydeep_20000_episodes.png b/demo/heatmaps/rewards_maxentropydeep_20000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..b3b12aba89a848661d6fbcb6b80759b4917e42f9 GIT binary patch literal 12919 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 literal 0 HcmV?d00001 diff --git a/demo/test_results/test_maxentropydeep_29000_episodes_model_results.png b/demo/test_results/test_maxentropydeep_29000_episodes_model_results.png new file mode 100644 index 0000000000000000000000000000000000000000..9546bcbffb7af392374793dda1e8108f018d640f GIT binary patch literal 18026 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 ms+xuwiF^vfF`}}7fS3^j zix`-$s%8~*Q5O@eVnV^Z1k*kvcLw(EC%(6<_kFkKtLd++tNwHP^r>);uRvab!%_0{*PKp&R30fKw6=M??A`Y>RTN3T&>cpA*|0)@B zp`o$S(ZW!1RBTMVs*fm4C=!NEj|vs5(i}^FnrjiLDpf5!lxLkJjEaa9({iEWSW#%C zbx?vhDmq>@NF-d85EUI3Bo@ZR$BKdy?Nn)b3yVNy>8N;V&yWZqtuQb|)h#+UL>w^C zs7fmaa;1H2X{A7U=`}PifmZh7aK*HWpMWFC5XfcILj-aHZZ@sDCQ_z~nwVDir!@j) zwvy?yC@LhL){K-2i&TglfbnRpNM%8WnAYxRWYIbTZWcXsV7#uF9_CLE57d>8k4+HA zC5VHfLzW3e|9-I%gHU#~UZk>DhE$)CGM2m`Bb(NjswLIOV1Q>RrbqeHMu9qC^7<7U zJ&0yckC7@SFQ$$AVOg|^Ofk~|&{#1&&Yw0*NTbIG4w1rwmI}oovQJB!_rJK*n$lJd zZJ9<-=(lU4P!uoyT=YZ%H@@F^QghIg(rBy5{uV`PXOS>Efk#`X(KZ8Z>e9B)Uz)Z} zqj~+065fg&B&l&$!`7+bl*t)rzeoeS^#&{*S5NEU9@ZzD}#MPWf(0GV9@^*7T z`DLq_F+nY0)r>aDjwgG_)4U|6GLU+$QNw+py9Z?F)u8_$6gAy)D z(Fct7337_UW!55OIN7k$gEFvPgD(^-@ndz{iJ!0yATZ4q{`koT99BF>40q^bXRp|U z1>5A2BYIxK?+$*4_Iv7~#gE@mnLqc!3Dc6%(_3>H=Xc#qN^%J>B}Y(cGkYa7k57cB z_U3@*0uH5>*9OjQp8}>;_`$g$$El9k6vBh~4a_jigGE*W{D9s9bncIR{N;_IWHyz< ze_EYMP8-X0z0kM{TrJgR%S-nH#oP>L*DWWoRwa+fd|d!d9u`o1+r1L7H-WnE{zQ@( zl*x|PNG1#vbvOZr>NMx2z1ZOl~!|LFP?7dUVBnm$DOtGIP>GGZ;o($ba zj-9&=#&yj>rCBTZ%QQaW^=DN{J8v3HjC%*p?|*>aSIp)6&UOWz`ddMs!UF2X#XeO2 zF;en!^ckZhnWeOy^{hGro14#4 zUN6?dPG$k6lN&)|eN*^vetZw~%jC$+6Z3F<#5TY^Hy4;QuW)hRPMAP$pb{O#q#A!# zeU_#=nvzwz!5lp0s^ zC($m_PT?46WaY@IH@AaPBXudc*x}^4suO@$)dS}IpiY4ZEz0etifemZ2houc$vB=4 zc8S{I0j_7MvnPa~P*u7y=3%GL0+TW@qcwy&Fuj|4+6gGyvx(WdxTM^?RVfe@Ty|EM%447xhN zPM=du^X8$;^3~o`Vr%uUVLl6A-v(L|HlA1<8g67y* z#tkzk)$;fNrEVjdo9~f_mua~6y3dErzB8#q7WqI;-VqO;oC8OUs-RL7O_BJ96Tf~> z1-$5O#44F-leb#h$vf4TVD`cEs*q;Fe!cy6v1->~uwY}dLb ze}I!S)`N};BV>I$5p4T-hB-RE5|ocAgg(1MK+4Mn%=`9<$iHwjG}r)`$SMZj!*fA! z_(@oC&6q6QxJ#nHh{jb)Zm0!fiTs8ivlK1A(`_%VCQ2U=xX*HoXxIh zE?;Q^r`{i93L1`rHbqtFG4l>y9;pHkhOGiuoQERY;CNc8VXJB@t{eg z52$S75QSs4;N(s@c&oMp{vM+b>*J4+*j_uhN%9W-&`?Zr7UV&J-Zh{Kkh!U!7%gQN7&TJ~)_Dvg&pprp_dAneMnf*>tvvuwcqtO8SM{KB%~7y?`W|5U z@n`7mq=xT&s|{mF4tTt~g-Bw3VIjE1^jLKh8=uVw-uH*0lFBr&_>~--cccY)!z>^u zQb6_CGobEa2q#JIgSuKxccWZtV>A2wl$Z+2bbS&?}LzoeCt$PC|ZCFqJDwqX0 zVI)ZQQz9o6zXslKKass}dco2gpFqrS1!T_w5vaOt1lAs135J)y296y&NGFvFGN5%8 z%)Xd~w~uos�dTRwFbm;s%FqmxW1G6-QBP=pl}>FiSHV+4*0AYmrzLUGH<11|IsA%W zE;Y$;H*|5`NE!$2K;iSIAx^RbYvpAk z4lv^?PeG@jf~j%KOYrqgjgqMW7bu@SfZ%B8g8fT&P=Ybj3AgQg0X}yom9|<3o0Fmj z+m779-X!@k@l&6otQQOMoWKdp@*R3irTG;}_^FpDVR#$GL=lKP%?O#a79dB%Fow0L zqJH-hp_fj*)H0<8iSBQFysbG4za2tTx38>#sW1DOpoCOpjRMK07IzeGGaG8Os<6(T zPbH$=zY+1}Z_qqtUR{`tIgW`-F~{fMq0-7~mzcdxm~Y$-%B*m-PAbd>Yb6qRp@Kv2aTr3S8H zKIC@-mkZjG9=SEZ%)AlHc;$|UJaNPlqt~GsA0d?+x((g5-A%q@4F+%EZ`)37J%jgw9*>q6yZxdtW{}Qn{9Vt7M8BwTYNzk(Csd zLE|^Q{MgGOy1+PFmpZ=-V|M6>sO+B)kDyDNAigKKa8a~~HOBx||JF^h03D9D; zM|h*vv;*JdUM*~n%8)$UUW8&F%|YqWdC2YX0z`EdNfPUwP{B?NPtY1JxgW5UF-gtE z-Bt#mAF|3B7i}S~qhyYDH9W$W{;Y|PcW$D5AE!#fK2+7+d|gO2mAkRFCdFWD?F5Ri zPGFZ_=n)T>8}XN%>A)tbJ_4Kl=i~H+4VbyZI^@&p!(cscC7LT-CHG=mC0dGgNbQ6Y z-*cBY3cD4JeldQI9FZo@iE*Ij7)(TGmxoZE;Y#?<)?XM-(tYg3j|VBwYd^!aC#TgQWJq>kt8~>t*7zFy#hKe^mD>(UUTHWU z;iAePqg}yV_Q05JDUB#Ty&AVqPNyokX2_@P0{-Y1MSht_GJZZd3~vQ_@%0$gINKx0@ja+?d~Y_bFB4ais3y7C%^|T0zzw8HJ8; z6HwgVvsijY4H~Cc$-L!uV|O%6F`dpN42MJ5UnRRGcU0xE=h|W9(f#>M?tGZN*;^Oe^RG~i=L$;KcLHnl4nSVgNo4&hU$WxV0V=4k7rwpu zhR6{ZGoJDV_$0HV%!EC8B$iqZu2^Z34=uA{J#LJwa$``7@DQH%iz#Iyu=p@|+!Q z9UOR5c+L(y=gB-r9&d`R<7E5E_EQ|}Y$rR~P3Fn8GcQQG4 literal 0 HcmV?d00001 diff --git a/demo/trained_models/model_maxentropydeep_best_model.pth b/demo/trained_models/model_maxentropydeep_best_model.pth new file mode 100644 index 0000000000000000000000000000000000000000..87c251ab580b3789a5f4ab7ec0477a96c9c06a6e GIT binary patch literal 5456 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 RC{R;Z+-b^xivGiW{|A?UGP?i( literal 0 HcmV?d00001 diff --git a/demo/trained_models/qtable_maxentropy_30000_episodes.npy b/demo/trained_models/qtable_maxentropy_30000_episodes.npy new file mode 100644 index 0000000000000000000000000000000000000000..0dfdea8018402fc6b934806e94b439e7935045df GIT binary patch literal 9728 zcmeI0c{El3+xJO^NEtE@nT}(2=5vt97@}E*%xM%-%9yE0MW#sRGBjvVhG;l%QsUd7 ziAs`0A!RHodiL+1`}ynpto3`=@3-#fx$k@b^K$KF@AFyv8s67+WjbwiT;s~iv!5rD zyv2X7UkKS)g}iJlhpeYU-Wn9LFT^L%D=1`(|3B{A_yp|rC+_dv?i1`!*jfwOMh8PC!IgLrb9OEi2Xy{L> z8s&a2s(RUdWQ_YgYGsF4$tmv4$-ex?=Cl9%od0p){~mw5$}l-+o&JM6o*$a=NoAJ% z%v5~a`m{Oj)05W^%`DV{mCcD;i|>=sRCv}kNI?sSj}N#FIcsB~=wsnoL2alDXgtx@ z)yBMORe_-n9enfo&6jgb7cP{wOLiaC#rpmJXCA)SN0V`ZOE1d+b`}w4nj`}V-tQ17 zEj5HsSu3UPnjyZX?)B1oV2Co0&u--h^l&k>$~1nz9+cm3bUd^5@MvOLQn)Y)9KWgH zVVV~9tZk`@->n7mvv$Q?NjaRzn$KABSpyxhnGI$X68Naa?{6!}V>V3Oq4cdfmZX`< zJ?~OSLgWpd13WT_(B8PNc}^M&=d8kOMP(3Ek=$xlUHxA!4lac&@2LDn1^?ZdUzuO2 zh}y7R^CMyNuw*2b7E#e_do>|EmkL=*#ACbDRQP>7v!gbaiqm)EHdTdDae3nW8P_N( zro8nhZEn-xUu1XhY#j~R^@(1hwKNQ7w@n}b!Xpk9x@S?$ihLEKaRvm>j z+zC0osV$cVlif8Ms;6i$k1oyYE~dkYCr?ARhz|8fucF9hbmUv-8uD7uF=JowL))B= zi#}Tyq?*wYCw)(+y^@M~*1!1DV`)$}FZdXcOv8h8=|FEgU8HT(@-3FtN6pGJ0j9?K zcynzicEu4@$XPb?X}=+%TUWI=aQ9jNlUw+6RYGC$um5l2;8;_*;lA}$Ts#tZq|cR#J2Qv;{WefRE4jAAd6Wt_ z-bw21FI33fk_}orLPhk1Nc+4&8YT)e_Johnur@uOa(0-8bMJ3U^-9z6pyi0fN`lc5 zT|RM3=(y3o&2qMgh8LcLN|%di_`Es9C77@o8!{;mjOkcaD9vZJo{k-VNx5F{~a zKYNImfhjF@r9fc@TkC?j2X!BAKtRcgn__k%$}b!bo8&i z&}npwf%ZvWCG9)J|FyrFmlI6KFZ~$yD;)+@>Fa(S(_)~GZ*1v`OEf%cUa&1qpN=0H zlJ`Xn>FAg$5sS?oLmfJidED48zk9*y68vdX0f0UX2T)Z0%w=NWQE4t7ys;9pv z%bA8!tEOkeUIe2H10sBAsGb(zl<7%>sEuQ})Fci0%pyf!f?G+A4Wua=jB5^_4sN1B zefoC&IA}0zw_mTpr9m%YxV&L09TbhlPd&8g(7lt~P_IV^ZT5TmU;PY7AJUfS8em{_ zNtW=RZw&b9+o}eAX5goFW7>1#{3(Y#-1`&Ulh#Qf9*%-@2ZsStR=`bc(r!_aSqnQx+Y+th5h7LvX zoj%-FItKQPd)xj+N4W7}w&Z0R1SU&{uXWLJQ{nEKc7prtUWfcxtAp$m?r1Di59$65 zF*{f2LB!#Zlj#Kw#0=eXEK1Wr>`88G%ry->xIPh@n=J$LdX9iHTL#;X=5C|<$lyOq z?OEUSIN8}$jJ%fgzjTrcl6GWb9l_60396@FQt^6>C+F!YyhGlY!A&CUjoL?ox6Y;XlLc+Hqih+Ot-vFu03|MH2 zVHnD{-A zYuR?01?yb*TfMhgkXO&{IZN=#<qyL!o(4P6h? zqB0vcbdo=5WZSZ_ZrbJccEaxt-ir>?3BQy4ILsq^nW&NOb-zgDaZqqk*7Z0#HoESA zH9wvXiLM$M-Gy|FNQEKVosIy#tpU_cbflkjIb5??2Ss7M)?3DPA^6s7bA_}XO1Y2U z_}y2>ti8>YZHYR5#y{|rhB`cM_vP8Fmch=6ftbWx8MwaqwdxAv-|zR7u$i@YQmC-% zY5n!!1Qi~vDc*;vR5X-c{Pt!!6%VWP`Y*1eBJPH9^;v5wsed_ z9Ttv-sf&aWG;Q>KB&y58^9-?%9Df$3za%bQLvX}kX?U<73tk~+<4;@Js3Fe`zHehA zqb&LU$2vARf5d19pRvGSnWuEJlZ6up8;;F;&BDCGf=%nLv9L)vL2BD|7ECNTbqR#M zf9@-z*@Xq6F0$?d;=K~>OMWU6JkRy->8W8tsN(R&qd%Bfqo;0?LeNI(?2VqEbhy`* zh!1?HL*>gI$s_X_*sQ$f$xSsXO5IgBDiKtqB(CdhI8245(zZ1Y-C8hy851)5QwwpQ z4L|9NY2(UFX!tOsyoPM&e(V z?+3!+`{w|mi`MqqQV}%lFFhasKAeWiMT&L?^KQPv5=tloJUxI1w#(s1=f5P za%&bisk*Zf`-J1j*~!Lie9{%IU2F_%+EmCMW#iCWa|0GZO2~(2Jjd8Lxuv6NpC}77 zzw+FB1d~5@o!%nOLMJ>Y4dR&SGLfO4J;=n+**&4o1mn6YpRMmA;-px6xx_o-_uuEN zKHAN~@T8{PbU6e3QV)%+J}|JKCtOwP9Rud?M}A$oMZ???U)@2Xu5a2Q>SS?)hSq|i zWP^SB5Zk>&PY6B1c@)PTN;yTBT9V{Oq-TCuR>-qt@R_&+|4VxVfIZ4VC(Jy~r`mA|M+-(A;l`H%|bAIKrMP>~j%Xwh%Tz+Mw(La8PL&L>OtrYQ_u zWCYb(ZQ)=@&6*!2V*xjV`RhFQ?x zJ65u!lMT5jlJNN+!Y{(J)}o79xb&NJtJ9r@zAZf-;vOvA&q-KSNaX9WcdCZ{9c&y3 zjyGOLymu$>HqYTS4x-mIIRCoJLCG$jLd#mhR<?H;-oH8vm910a0ui8>>o&#jx=x@N_{Eq318W zig!Kx&4lKnDCq%0_dgD9dGYu+4fk*H?3xs$Lt$mFn2Qh{HDdgnC@Tsyd+ltcHc~Kd ze!6?yi-IUB`HtbFHbS#18#b%!KyLh8YQ~^8^p1O}E~1jK<*-^shX@J3tJX?V3`nqB zdMe`+G5;?sQSg4aLKfE-D|c;elm$~~U9s0ga4Qw&42evIr&Xd{p$ZlDM}@*;)-teQ=$+j^ z_&R*}Mc*n0QQs17Tp{vng~`E4-_2}na2S}H_GH8KNEp9?I|o(K@|i;frwhtkVhFx^ zscy;jG(p+a@gF-qOt9Qujn~@D1WMO-i*oi7dB*a7yl^8Mq$J_6!u4!OuN3%`C~XAi ztm`kmmKtO1_2BOH1cOpE&IlzLf%@G$>DyH!=mz{r^CtM9?d7M8S~l8fI+TqqY*<{) zoi3|kqa?X{(L@Ln@q4aGkoGaL^LvD24`F}qUf_L#&8sHs7W{fm=jmy(z&X6t zsHT_&hx3sX)w4uB->{9hqLhU>Gf8>lK0=3{-IY=QOvm!hS@(Mbbd)rk`o5k|!_MsB zKi(~^*W1luH z)EigF`{?XEWeY_FJ*U+!A}M0Z@%8a_k_4CWx*6>i0#A3;*y3qHJYZUfzswW-+j`!# z_*)aVm5QQm${{a^JcUe-;tHa_`l|lq%zX;cXUVvD3J{bM`{>}OM}^H3Tbf5E9V<_) zIX9F>N1%ArWAlS_g#M1CS$c6`U|Zb_}e+c_o%gkSr)R1$i8sn(wP4?CB^K19rkZ0D6-Hs5Htapz9a05K;jh?E=r z_)fu)(w6kHDGDn0xJf%sP(YHs^ZXLgf4S2vN1}6e@m`UnPj*55#Lo{7WM9R z)VK;pb|{?sKBs~#^DK?^T52#g`0&?56E&ptoH@5*r5YB5xyW}Ol)xG}QLadW1gxBo zQ3ulgUay;+nbJPr3;Msvlg-{CKwY{oS2%=zr zuJ5u(i>T<#TItw2K!NPz!7Z7DU2#YH-VmXOOg_)I13TELuPdEX*u#eQqEuJ5HV1FE zYNsC~NDhqrl1}1)wzoC@s;3baI$E`A`5M7gSf$gNZ3MmYvq9-(A`S-ae2!~z&{Uon zts=|8!T@8Vl8eT;T^%eJMzGj@UDdTRV`5L0t;-*31Yi15>(l@vNQ$gIb$O=|zJ4qG zeBXlub((54MnrK1-|H?f6m_!p~sDR+)vnqRTCF53=##QHuS^ zeQcb5x!b`ZmW_uECr@=uFmWJ6MQ?D53CSKZdxEg-;;fHeb0X%)`!=#-YiL+gk-i|_ zkDA0bbLos#ke!$Nui-CNKgKd7$j8;>W7UD3M~R#FNLkN za1q=rW`=d=E&AL1Wvkn^o%?8jE4+?Mf_(-sSa@1@r=$TYG@s4BHlpC`^iL6r2?e9M zLL!xl6i9D=(sj;{ICtOW-^B#K>tASB{A~bbre;j-1Ot%=`bNS(GH@wV<$;P9QO9Qv zQ`m&ACfHW5So@w0Q5T(cj)eZ&*9>PnK4W7*XWzC(&)MLf7^$-$`r^G*_MtD5Y%H;; z6P_o*hPi(M|4L&1Q4G3sbi#lG&Y5KmBpTsw^JgBX3EOs`+cBF)4pIt=#gn-lga^*E z)y(4{G4FRcON;})M~aIs{~+q}ezk6!g~W52J}b1IGco+r<68e~CK}x27RGilu~N&U zwrrdY@1v`i%n;|zTetkez6mzSR;{%(V!kUps3m_kjDhSrTE>x^bYyK9I}rVx26tFi z`@JE^3i4RnO~c~1m#eKt^wF{=f1u!tJ~p-SIz9cR58DfmcTb$q!obbrOQsUEaMk3L zpGA%q++O)GojA%c=%KXaQI#>{R<6zWTM2hAl%5T)kwTWh3vvlTi!*W}lk!p+=nuMQ z@|hR1`n8Ha1HAY!x%+xMi}!E+Tm5Q`9p`NTu{N)uC0+*LoATc|=3#(VGC3r_O&=LP zo@M?7r<_M(&S~m{u5)w)f4l*9*@ujff(_8zDsk?XqaM7oc~)2U6LAovS97j9@Wt~Lg(4LHACGA`<|PkeBEL;e#{qn zVM08=;Ax+~zX%%>E}W>XL_hWR%VdQiK?6U7u5eb&KBKVk(7y(8yx^NonP>tlai zhbjw;PF#4q|2-2|EbUrCx|x`eZ|I2dVj{}qT7G^W9b(KIK{YwVe$G=qd?c3+e!Bpr zwN_N*dzDVLn^7TA=5qF(I|YG!y5SyM^uTMnw`tB*4@>48vOlfSgLZkfVzsb3jz+B6 zGbpK!`930TU-H!O*MgHab+07Au&T(d`YHj@g3hFZRB^n#K6RR%x)7c>_V`U@Ed=>U zkm`>L(8dwXTl*{r$%tDMtt087i?un~j9DWcY~=S0mvYiY-5y4; zbpZuIG?S`~Hxy#u$8@nH>iVmRX|byVOzi&E=;c35e8-fVp`XT>*u+Wpy+ri8Phy55 zL!Yw{TxV=Da)*UDL63w8qQ5O`iq*6w>gd!Nx#*{Ice?#RRbzJG}ao^RX`sAzW5gNR|W^Ljj<_yj5%7eNDFSdKRH2Lb`ZP+iB za&J8d&16^=ll5S{(fsSHLJ~wKNydTeRN>_*wtcvYgqO~u`|I_ku}^5%2P*?j5s$Q9iFz>@2Y#z_Iw=}elZFk zFVun8lZk7)JT#%`dRcy$u8ITwPdrP=sz8y|cF`nx%xz!T*jgozj-Crq_ioDLaLn89 zv87TNTP-3G*(!me6T31Znj}D@l9MLYC6NB%$ph(4qDVg-r~Q|+C|b@Z%zN6&hx4O? zP3h|2xf%1$^QU~D;zo>h^BkTV<%&fFWL@eVAM)2K9hquqkSk*?ZN?xsv#$#fG%pN_s(Be0`yw$_L zyn{9OytQCDQ1ecFxdG}ew0j6HvCp;rRg_0fe00uD|In<3 zOhKppJQ6xE|75C|Ma-dLrE&egDH^b1t>3seQWHZ}!3QTYG;x0Eg=4xQYEb^x|H3^+ z1)eifeCmNJsFI)+%WPA^K&(<>-Lxz`0wp_c?v_KzL1~Lte>r?zsx46ZMhX$*6;a8$Z0`4_Ej$bBCn$AFgQmlY3%CL)>@6=h|)*4{;;XaeF!XQt z@88AA0^@!D{$lFL317LrQ(PSvf8PD`jo_Yzqxl^nBpj3Bc;$zZ@YqmS=$4NZo>lTcQ0y9ewI6 zH?{C-;DEP)pqr~Y<{kQ6r7o_9>EInl4veT`RngXE%UVZ z_ubDV3ss!AP&)E)MiKPyrdsyAO5mORlG4PdfZk5p>c&}V*lbzvlJ-j)Z)O(hTPI22 zM~IPPT!a+rM=o6)IUt3i>^ydwu^5tesuf=>5`$QL-oAm;B1ouyc&_oaQUNvr;ThsyDA0LKC0f=n5qEBhs?&2MmaPmMdbgLD~G4= z<1DB(axh=wr(0eiji;0jC%==jkkhXJaVA3++v~r6+PqH+JB4mM{v#xXW0On$>%^sC zsH&eAm?(ks2B8@RITBdhoW&3;l7QejmBaJv#Zm9n{A~32U9LlkTn0P(F1PER+Ug?l S|9<}ZcgMs3y#N3F1^yTNgtO)V literal 0 HcmV?d00001 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/irlwpython/MaxEntropyDeep.py b/src/irlwpython/MaxEntropyDeep.py index f672a9e..5873f69 100644 --- a/src/irlwpython/MaxEntropyDeep.py +++ b/src/irlwpython/MaxEntropyDeep.py @@ -1,8 +1,3 @@ -import math -import os -import random - -import gym import numpy as np import torch import torch.optim as optim @@ -31,14 +26,11 @@ def forward(self, state): class MaxEntropyDeepIRL: def __init__(self, target, state_dim, action_size, feature_matrix=None, one_feature=None, theta=None, - learning_rate=0.05, gamma=0.9, - num_epochs=1000): + learning_rate=0.001, gamma=0.99): self.feature_matrix = feature_matrix self.one_feature = one_feature - self.target = target - self.state_dim = state_dim - self.action_dim = action_size + self.target = target # Environment self.q_network = QNetwork(state_dim, action_size) self.target_q_network = QNetwork(state_dim, action_size) @@ -46,20 +38,10 @@ def __init__(self, target, state_dim, action_size, feature_matrix=None, one_feat self.optimizer = optim.Adam(self.q_network.parameters(), lr=learning_rate) self.gamma = gamma - self.num_epochs = num_epochs self.theta_learning_rate = 0.05 self.theta = theta - def tensor_to_image(self, tensor, name): - tensor = tensor * 255 - tensor = np.array(tensor, dtype=np.uint8) - if np.ndim(tensor) > 3: - assert tensor.shape[0] == 1 - tensor = tensor[0] - tensor_img = PIL.Image.fromarray(tensor) - tensor_img.save(f"{name}.png", "PNG") - def select_action(self, state, epsilon): if np.random.rand() < epsilon: return np.random.choice(3) @@ -124,22 +106,25 @@ def update_q_network(self, state, action, reward, next_state, done): def update_target_network(self): self.target_q_network.load_state_dict(self.q_network.state_dict()) - def train(self, n_states, episodes=10000, max_steps=10000, + def train(self, n_states, episodes=30000, max_steps=200, epsilon_start=1.0, epsilon_decay=0.995, epsilon_min=0.01): - epsilon = epsilon_start - episode_arr, scores = [], [] - demonstrations = self.target.get_demonstrations() expert = self.expert_feature_expectations(demonstrations) + plt.imshow(expert.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig("src/irlwpython/heatmap/expert_deep.png") + learner_feature_expectations = np.zeros(n_states) + epsilon = epsilon_start + episode_arr, scores = [], [] + for episode in range(episodes): state, info = self.target.env_reset() total_reward = 0 # Mini-Batches: - if (episode != 0 and episode == 1000) or (episode > 1000 and episode % 500 == 0): + if (episode != 0 and episode == 10000) or (episode > 10000 and episode % 5000 == 0): # calculate density learner = learner_feature_expectations / episode # Maximum Entropy IRL step @@ -164,17 +149,63 @@ def train(self, n_states, episodes=10000, max_steps=10000, state = next_state if done: - scores.append(total_reward) - episode_arr.append(episode) break + scores.append(total_reward) + episode_arr.append(episode) epsilon = max(epsilon * epsilon_decay, epsilon_min) + print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") - if episode % 50 == 0: - print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") + if episode % 1000 == 0 and episode != 0: + score_avg = np.mean(scores) + print('{} episode average score is {:.2f}'.format(episode, score_avg)) + plt.plot(episode_arr, scores, 'b') + learner = learner_feature_expectations / episode + plt.savefig(f"src/irlwpython/learning_curves/maxent_{episodes}_{episode}_qnetwork_class.png") + plt.imshow(learner.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/learner_{episode}_deep_class.png") + plt.imshow(self.theta.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/theta_{episode}_deep_class.png") + plt.imshow(self.feature_matrix.dot(self.theta).reshape((20, 20)), cmap='viridis', + interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/rewards_{episode}_deep_class.png") + + torch.save(self.q_network.state_dict(), f"./results/maxent_{episodes}_{episode}_network_class.pth") if episode == episodes - 1: plt.plot(episode_arr, scores, 'b') - plt.savefig(f"./learning_curves/maxentdeep_{episodes}_qdeep.png") + plt.savefig(f"src/irlwpython/learning_curves/maxentdeep_{episodes}_qdeep_class.png") + + torch.save(self.q_network.state_dict(), f"src/irlwpython/results/maxentdeep_{episodes}_q_network_class.pth") + + def test(self, model_path, epsilon=0.01): + """ + Tests the previous trained model + :return: + """ + self.q_network.load_state_dict(torch.load(model_path)) + #self.q_network #.eval() + + episodes, scores = [], [] + + for episode in range(10): + state, info = self.target.env_reset() + score = 0 + + while True: + self.target.env_render() + action = self.select_action(state, epsilon) + next_state, reward, done, _, _ = self.target.env_step(action) + + score += reward + state = next_state + + if done: + scores.append(score) + episodes.append(episode) + plt.plot(episodes, scores, 'b') + plt.savefig("src/irlwpython/learning_curves/test_maxentropydeep_best_model_results.png") + break - torch.save(self.q_network.state_dict(), f"./results/maxentdeep_{episodes}_q_network.pth") + if episode % 1 == 0: + print('{} episode score is {:.2f}'.format(episode, score)) diff --git a/src/irlwpython/learning_curves/maxent_test_30000.png b/src/irlwpython/learning_curves/maxent_test_30000.png deleted file mode 100644 index 5c84ed9dffa902158af78d98ed51c381074095dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18346 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 diff --git a/src/irlwpython/scripts/direct_train_deep_max_entropy.py b/src/irlwpython/scripts/direct_train_deep_max_entropy.py new file mode 100644 index 0000000..55fbf75 --- /dev/null +++ b/src/irlwpython/scripts/direct_train_deep_max_entropy.py @@ -0,0 +1,237 @@ +import torch +import torch.nn as nn +import torch.optim as optim +import gym +import numpy as np +import matplotlib.pyplot as plt + +class QNetwork(nn.Module): + def __init__(self, input_size, output_size): + super(QNetwork, self).__init__() + self.fc1 = nn.Linear(input_size, 128) + self.relu1 = nn.ReLU() + # self.fc2 = nn.Linear(128, 128) + # self.relu2 = nn.ReLU() + self.output_layer = nn.Linear(128, output_size) + + def forward(self, state): + x = self.fc1(state) + x = self.relu1(x) + # x = self.fc2(x) + # x = self.relu2(x) + q_values = self.output_layer(x) + return q_values + + +# Define the DQN Agent +class DQNAgent: + def __init__(self, state_size, action_size, theta, feature_matrix, one_feature, learning_rate=0.001, gamma=0.99): + self.q_network = QNetwork(state_size, action_size) + self.target_q_network = QNetwork(state_size, action_size) + self.target_q_network.load_state_dict(self.q_network.state_dict()) + self.optimizer = optim.Adam(self.q_network.parameters(), lr=learning_rate) + self.gamma = gamma + + self.theta_learning_rate = 0.05 + self.theta = theta + self.feature_matrix = feature_matrix + self.one_feature = one_feature + + def select_action(self, state, epsilon): + if np.random.rand() < epsilon: + return np.random.choice(3) + else: + with torch.no_grad(): + q_values = self.q_network(torch.FloatTensor(state)) + return torch.argmax(q_values).item() + + def update_q_network(self, state, action, reward, next_state, done): + state = torch.FloatTensor(state) + next_state = torch.FloatTensor(next_state) + q_values = self.q_network(state) + next_q_values = self.target_q_network(next_state) + + target = q_values.clone() + if not done: + target[action] = reward + self.gamma * torch.max(next_q_values).item() + else: + target[action] = reward + + loss = nn.MSELoss()(q_values, target.detach()) + self.optimizer.zero_grad() + loss.backward() + self.optimizer.step() + + def update_target_network(self): + self.target_q_network.load_state_dict(self.q_network.state_dict()) + + def state_to_idx(self, env, state): + """ + Converts state (pos, vel) to the integer value using the mountain car environment. + :param state: + :return: + """ + """ """ + env_low = env.observation_space.low + env_high = env.observation_space.high + env_distance = (env_high - env_low) / self.one_feature + position_idx = int((state[0] - env_low[0]) / env_distance[0]) + velocity_idx = int((state[1] - env_low[1]) / env_distance[1]) + state_idx = position_idx + velocity_idx * self.one_feature + return state_idx + + def discretize_state(self, env, state): + env_low = env.observation_space.low + env_high = env.observation_space.high + env_distance = (env_high - env_low) / self.one_feature + position_idx = int((state[0] - env_low[0]) / env_distance[0]) + velocity_idx = int((state[1] - env_low[1]) / env_distance[1]) + return [position_idx, velocity_idx] + + def get_demonstrations(self, env): + """ + Parses the demonstrations and returns the demonstrations. + :param one_feature: + :return: + """ + env_low = env.observation_space.low + env_high = env.observation_space.high + env_distance = (env_high - env_low) / self.one_feature + + raw_demo = np.load(file="../expert_demo/expert_demo.npy") + demonstrations = np.zeros((len(raw_demo), len(raw_demo[0]), 3)) + for x in range(len(raw_demo)): + for y in range(len(raw_demo[0])): + position_idx = int((raw_demo[x][y][0] - env_low[0]) / env_distance[0]) + velocity_idx = int((raw_demo[x][y][1] - env_low[1]) / env_distance[1]) + state_idx = position_idx + velocity_idx * self.one_feature + demonstrations[x][y][0] = state_idx + demonstrations[x][y][1] = raw_demo[x][y][2] + return demonstrations + + def expert_feature_expectations(self, demonstrations): + feature_expectations = np.zeros(self.feature_matrix.shape[0]) + + for demonstration in demonstrations: + for state_idx, _, _ in demonstration: + feature_expectations += self.feature_matrix[int(state_idx)] + + feature_expectations /= demonstrations.shape[0] + return feature_expectations + + def get_reward(self, n_states, state_idx): + """ + Returns the achieved reward. + :param n_states: + :param state_idx: + :return: + """ + irl_rewards = self.feature_matrix.dot(self.theta).reshape((n_states,)) + return irl_rewards[state_idx] + + def maxent_irl(self, expert, learner): + """ + Max Entropy Learning step. + :param expert: + :param learner: + :param learning_rate: + :return: + """ + gradient = expert - learner + self.theta += self.theta_learning_rate * gradient + + print("Theta", self.theta) + + # Clip theta + for j in range(len(self.theta)): + if self.theta[j] > 0: # log values + self.theta[j] = 0 + + +# Training Loop +def train(agent, env, expert, learner_feature_expectations, n_states, episodes=30000, max_steps=10000, epsilon_start=1.0, + epsilon_decay=0.995, epsilon_min=0.01): + epsilon = epsilon_start + episode_arr, scores = [], [] + + for episode in range(episodes): + state, info = env.reset() + total_reward = 0 + + # Mini-Batches: + if (episode != 0 and episode == 10000) or (episode > 10000 and episode % 5000 == 0): + # calculate density + learner = learner_feature_expectations / episode + # Maximum Entropy IRL step + agent.maxent_irl(expert, learner) + + for step in range(max_steps): + action = agent.select_action(state, epsilon) + + next_state, reward, done, _, _ = env.step(action) + # Real Reward + total_reward += reward + + # IRL + state_idx = agent.state_to_idx(env, state) + irl_reward = agent.get_reward(n_states, state_idx) + + agent.update_q_network(state, action, irl_reward, next_state, done) + agent.update_target_network() + + # State counting for densitiy + learner_feature_expectations += agent.feature_matrix[int(state_idx)] + + state = next_state + if done: + break + + scores.append(total_reward) + episode_arr.append(episode) + epsilon = max(epsilon * epsilon_decay, epsilon_min) + print(f"Episode: {episode + 1}, Total Reward: {total_reward}, Epsilon: {epsilon}") + + if episode % 1000 == 0 and episode != 0: + score_avg = np.mean(scores) + print('{} episode average score is {:.2f}'.format(episode, score_avg)) + plt.plot(episode_arr, scores, 'b') + plt.savefig(f"../learning_curves/maxent_{episodes}_{episode}_qnetwork.png") + learner = learner_feature_expectations / episode + plt.imshow(learner.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"../heatmap/learner_{episode}_deep.png") + plt.imshow(theta.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"../heatmap/theta_{episode}_deep.png") + plt.imshow(feature_matrix.dot(theta).reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"../heatmap/rewards_{episode}_deep.png") + + torch.save(agent.q_network.state_dict(), f"../results/maxent_{episodes}_{episode}_network_main.pth") + + if episode == episodes - 1: + plt.plot(episode_arr, scores, 'b') + plt.savefig(f"../learning_curves/maxentdeep_{episodes}_qdeep_main.png") + + torch.save(agent.q_network.state_dict(), f"../results/maxentdeep_{episodes}_q_network_main.pth") + + +# Main function +if __name__ == "__main__": + env = gym.make('MountainCar-v0') + state_size = env.observation_space.shape[0] + action_size = 3 # env.action_space.n + + # Feature Matrix + n_states = 400 # 20 * 20 + one_feature = 20 # number of state per one feature + feature_matrix = np.eye(n_states) + + # Theta works as Rewards + theta_learning_rate = 0.01 + theta = -(np.random.uniform(size=(n_states,))) + + agent = DQNAgent(state_size, action_size, theta, feature_matrix, one_feature) + + demonstrations = agent.get_demonstrations(env) + expert = agent.expert_feature_expectations(demonstrations) + learner_feature_expectations = np.zeros(n_states) + + train(agent, env, expert, learner_feature_expectations, n_states) From 5db026f940625359b2f8aa7511d44b93ce2c86ce Mon Sep 17 00:00:00 2001 From: HokageM Date: Wed, 29 Nov 2023 23:03:45 +0100 Subject: [PATCH 7/7] final MaxEntropyDeep --- README.md | 33 ++++++++++++++- .../heatmaps/leaner_maxent_29000_episodes.png | Bin 0 -> 11953 bytes .../heatmaps/learner_maxent_1000_episodes.png | Bin 0 -> 12017 bytes .../learner_maxent_15000_episodes.png | Bin 0 -> 11964 bytes .../heatmaps/rewards_maxent_1000_episodes.png | Bin 0 -> 12955 bytes .../rewards_maxent_15000_episodes.png | Bin 0 -> 12989 bytes .../rewards_maxent_29000_episodes.png | Bin 0 -> 12958 bytes .../leaner_maxent_29000_episodes.png | Bin 0 -> 12531 bytes .../test_maxent_29000_episodes.png | Bin 0 -> 18464 bytes src/irlwpython/MaxEntropyIRL.py | 38 ++++++++---------- src/irlwpython/MountainCar.py | 2 +- src/irlwpython/learning_curves/maxent_300.png | Bin 21355 -> 0 bytes .../learning_curves/maxent_30000_flat.png | Bin 15548 -> 0 bytes .../learning_curves/maxent_test.png | Bin 21157 -> 0 bytes .../learning_curves/maxent_test_300.png | Bin 20091 -> 0 bytes src/irlwpython/results/maxent_30000_table.npy | Bin 9728 -> 0 bytes 16 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 demo/heatmaps/leaner_maxent_29000_episodes.png create mode 100644 demo/heatmaps/learner_maxent_1000_episodes.png create mode 100644 demo/heatmaps/learner_maxent_15000_episodes.png create mode 100644 demo/heatmaps/rewards_maxent_1000_episodes.png create mode 100644 demo/heatmaps/rewards_maxent_15000_episodes.png create mode 100644 demo/heatmaps/rewards_maxent_29000_episodes.png create mode 100644 demo/learning_curves/leaner_maxent_29000_episodes.png create mode 100644 demo/test_results/test_maxent_29000_episodes.png delete mode 100644 src/irlwpython/learning_curves/maxent_300.png delete mode 100644 src/irlwpython/learning_curves/maxent_30000_flat.png delete mode 100644 src/irlwpython/learning_curves/maxent_test.png delete mode 100644 src/irlwpython/learning_curves/maxent_test_300.png delete mode 100644 src/irlwpython/results/maxent_30000_table.npy diff --git a/README.md b/README.md index dbdf1a1..8a50521 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,37 @@ The expert demonstrations for the Mountaincar-v0 are the same as used in [lets-d ### Maximum Entropy Inverse Reinforcement Learning IRL using Q-Learning with a Maximum Entropy update function. - -[//]: # () + +#### Training + +*Learner training for 29000 episodes*: + + + +#### Heatmaps + +*Learner state frequencies after 1000 episodes*: + + + +*Learner state frequencies after 29000 episodes*: + + + +*State rewards heatmap after 1000 episodes*: + + + +*State rewards heatmap after 29000 episodes*: + + + +#### Testing + +*Testing results of the model after 29000 episodes*: + + + ### Deep Maximum Entropy Inverse Reinforcement Learning diff --git a/demo/heatmaps/leaner_maxent_29000_episodes.png b/demo/heatmaps/leaner_maxent_29000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..5157a670c98a3addffe30198e61c1eaac9036454 GIT binary patch literal 11953 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 QZU{lCX`jhCb@}H11IAbBtN;K2 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/learner_maxent_1000_episodes.png b/demo/heatmaps/learner_maxent_1000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce1594ddbe30a7a4240fbabae9fecaa3c2dafee GIT binary patch literal 12017 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 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/learner_maxent_15000_episodes.png b/demo/heatmaps/learner_maxent_15000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..bc6de44ea28470f348102b0a9551952b349923c9 GIT binary patch literal 11964 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 TwGdh-IfA~SdOhvOJ5T-(nLz|6 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/rewards_maxent_1000_episodes.png b/demo/heatmaps/rewards_maxent_1000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..212f6363f0e286868b2c89391c0092cbefe36506 GIT binary patch literal 12955 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 literal 0 HcmV?d00001 diff --git a/demo/heatmaps/rewards_maxent_29000_episodes.png b/demo/heatmaps/rewards_maxent_29000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..d68c1a7b338959e296d455c66c0940d031d647dc GIT binary patch literal 12958 zcmeHtXIPVIw{B3;Q3ufh3rHDKbRr#f>;e*01VV4pf=UxY zu_G-^vf$=jayd7gEz`@Yw@e?eD+Z5Q`06bi+r zi8-f_LTw2~p;-EV*bcu)HTDd`hn%O{B~JqvTTgd)Rb?j8;< zcnMKiQSo1Yw)gaO^^g}6bN;_4h`PAji8W<&D8fy4x?(PSpit~q$REoKm2?Lb>eOz{ zb7u^%lO}tE%v%|~o3kS<3klnw-(SPbX{;n`zjFG?*dXG5ZOun%2~n9G?V@t`oX?I! z#v3oluW}gH=hK}{Fc!v+?OFsgOX-vbxr-z0%Y# zUjE3s7lnFz>i-}3-%N=%MuR<=T197!FV7C_+PyoXW@voW4TTaJlnvF5SI+6^xWvlp zru0Rc^Rzi}pfXHYRFs@ti9+S;YiizKU7DsfS|`L_M7e3cfBzn>X|g`EllAtULLuR6 z{SF)gn#7y8cm?F92p>WQG5V@v5+;}rT8irK=nTbowFKrFleR-u;VBKhkz7@B-OZR< zmDlfU72`|SameYeR&+}j>>){V2PPEFtLT{;PKr|--q7lj-DDMzt61|(3g^+RRuON& zP-prC9}Tv&OWLpJZ_WlN-L*I#{05CJojlCR-8H`DP*2{wkC@FbyB4FX#_+>pmo?`~ z>Nwv%#t-kha^XedmX78g?RR*Iksi0h_ruXXs&$;FxqeN3m*Za+a3m$Nm}7s-hgvwn zBk1Vu+fhED6gq_qM*WyuVx*L5(;G7AeJ7HYLay6Q=Ft#U^6l@v~+Y@;qF~N?kH5lzT?3bZ$0Xj(pTn3 z=zV_EtzPXG=|)+`8Fuw?)z#IG?(6kI8y-4Qr_{m}=kAfq7EP5HEe0jCpAQ%KugrPJ z@t{zi+jdkn@1ay3w-8nY3#n72M-D#AB{igR~d3Ry&W555vH>7CUE8!zx|iT zN4j2G-6B_PtcLpj0F%jk5kw;=k7W78)-oD^;ELCdvZ;LE~E zL4H;g2$I!!wuq2H$pu$r-^T5L0Oa1)15xNulcyp>Y_4l9X`d`k!$pUajIb6iXbqyR zt$#g+dNV!98omV1H`b}UmrHrYgp=xT)jNiSqdnEl|I-M3gjWeAU$i8YYedjnGPdz| z6>4jcYzi*0El*#;e^nHaBXV*&AG3Qqm~49!&8yT}iJ?}rmpj4uMG2HggA2;$IQTy^ z=z&4r)8=08k-UhSG`IaHD!ARy`#|WrDvUhj3u!tQWANMcH%FIM-2AOi?_D|*b(U<1~ z$;P}vI>#VcGRd0a zMNd17e{<$8J3rpNqI>dL_oTG=F~FxQ=CG7Jl^1<|OZozt&Sii}+>$Sb;sa){E3VFb zVBgQd(Y&1la>eQQ``?OQ`TG90?>eKsz->Ss*(KT8+CBJV7$M+49!1}Ts+KeWN0`VWfuov9X?gDxv|F&fIlJN0*Vs+RM$U{|^lFS7A;_)Wxe{0o6;^=4zyDYY$C!yi#qqAXxZ?umK|f!1{8xE6>PH z+}zw8cW>av$_Qg^zP_mO9KhG(zk#p+XUbNw`%um|-4(-kWj#67*KJ3)OMJliPN*C_ zR3#@%>4Qzws$srNkitGnjEp@A8%Jy-@Ig4~-YrqsAD*2f5WFe@U-9r|;VJ8iy1TNE z_iwNzyPjTjK-+C}s31Epk``l+9;t23VVb&=%lO%(iSvs?$p{d<&)$?EO4#3u%Jt~0 z#~l@sCf=sr6%K}7@+=Xx1%qhO>=`Z?M8tx#UxyAnX#S{;|acWR$T;JUdk&7@`(5LmJT%@c~8u% zSFgAgufMddkIVV??P>*XetsU}v}Lq>aPZpD$Ouy@jZD@xGBOI0hQuxh`8fEu-?rJ< z+2Q7g>r9K?Q-KhBbvqZ0EsQnmki~?B4GawplbK0LNruM8!%Ou5*Z+kb603($sME|u zlsC(X6DOkOJkr!dxKrUV&RzMM`}glRtq3f8rDENfq?VbTz2JQG=+V!w0hXEH2rPs% zK)u=;5>>rm!j3IzXlP`WmX}|fc6;T@%UsW5T7T{pLg&Lu%LqXAgq!vaM{Yax5P*zjITA6S3%PH^N*}Mb_k1z z=ny6Cs5~O3`Cp1Q-tFLT8Lo?AOyt#%N9ZXxHl>~~u&d_-N620uPB%jY+V_8 z0) z!*+|Hbp|g3gxYC^B$yjqJK5Pg$kMXUXQ_@PXCPrmbxOVu2Y((AxdM;-L*M<*b^7Hs z-dUy_aoJrpBdisZ_DWo)O$}@oCFQp$RN^Iw5hkuV5Xf5RyC9HTn+e&_A$lYe%MUX(a z9BYpjRFYnL|4{U7okMOQ4!tvW-=CK7|3SZUG&OEb@DMI*O-~0e z5s(uLl15%6!z;aV_~>aRS!1v*A-f<-_sZq-y%Me#0;_7iW8Wdj<sc0dRw2j#uzkv>`9H0dBzhwy+62>;x zMoFymaq#hxZ|z`T#Z%15(y{wcsBL=yQTB3ib&f8E1+7_I1Tb2;RRT+C*5;y-Ny*9G zzLF@^-r(!I-#pC7&25L|?@0?-lJYakEh#bGy8Xus=H{d{y?An%^6HDu9uO{o22x$H zBS!|^c`C<7k6fXyGU$xy&5daxQBh+jC#MM9-2A-PXv2{ZZYiy&PoJ)K)(56JcNdN& zhbilCZmh>B+Kx4)nie{B`YeSN(;Zj|xZaT+DzT>RnFIAh8RNESLErupuo{Np{6I!u zyu&;~k7@T@7Le=B{2ik^<17W_-W3d&=PDhZDxOJtcyc)!7!J{JZVVVHi5Lg8^u$E2 zt-E9H$)$@=_+;WGiStVX`{3uXxR_0Qbo%nVvby_t7M-!0(r$G5a>mSzt3cGK;+riU zpGqN*YiVlEnr)y@{7YIhxb*y=&>F6{qA4$4V9W}g8qHkFT9XD!{z7RMDW503YbL#m zydm}PMZuG9XIqw;A}q5d!@$gwR5{Rimp|~u^XJc{qd`S&`w3RHIlmiA1(=Pl$UKaU4)p?@&woLs3bDRVK z)JvcRj7)+vVSJ%Mg|cB6ACLxmI18vzBsQ=ZQH#6^-lHXSGOj)xFn0%l^ghtA&noyw zsWmk?Pv*)<5tofd5}S^|?Mjj~ z(ZJZZ7=X*2G5>t$E|-%L0uKE++wvv)#kDB-dCuSe3x-OYJ}(KWyLG+J|Gpw`drAA3 zVs4?jYo8`hE|fm;Ja(!BL;WV_f*_VnZYo!m8$*f^*C)mg8fCd0sCHkMses%l>CK-? zPW}l2IxFvs^2ApbEt$Mj$T#9LnC`&YbDtPllHsnpzw%Zb-sl~h?d#BhPdzmS%Q0-~ z?masM5LPmiYj~(?g{~_gPDGoShk%Bi9HustC`H^=oh?BKUmFkiDh?-AE~OwapU4r$ zUF9&d9nl6AWe4rhBWbyTPU!T+G|SuS#0D<6e{Bq&d<&7P)10Pb;N+AI2qEp%(O_RO zAZuEB{ngd0S6h-b*daBKK{7sAYw_yp?d^MbUNkgZIEqHwFHQA2F96#+osfvy{w6w_ z`%`5l?$d+)I#ZitdO?}kwQmPa3ml(%Pj;nRmieBLle=6{P!K55{?E;wkM|3Gfie6X zd;zu9TubXgT;Qrh-E;AQ(tyx`(c1?t8wSEu$YagvxRw_eeHpDLUTe#<^JLCAdhtkH z^V-V1*L2y^IBewzQep6oSZ2sDd-At@`A~?gMKLC5Ed4WK&z>#NtLJw2~`(OV`CM4^!dWl ztE`n*201E%jQ>jSiF!E!UwZe~rp|$bcEi~G9l#jE;Q2t-&J(L^Y7X~eEiI?ImvX-w zJ^crG1vDYT^=)iYU4&1Za2Nt}7h!k`ug=`senMW}6zrUGW@ct)KCWH#=&@tcKH4zt zpgW$cS6(l(92y>8RZ=JR;EUdW_;A=6uJ!mP5zImcC z(%GUu-z;gDzHHbsG;xhkp2n&O!GI#Wy699rm37012gQspUyf1_ zL=h-nuTTpRe}*lt0Xw9>27i(`FlmccCvuj}C;!`^6%l@gY=l-5DQ{s z5T9pP`yO#32h)L0oi8pV@q*;B3ojNs(izbQsq(`BxM3Lm1#bzOfXUP-Vt5tqDXzxo z(ti6r&C+241t;jKkWVv4s*elEeIms8^=ACifzfVbj|aUK(3REwI^TMxMxBOIDme&^11rPa}7#5(q6jHkjTu7g}z8OHA-?Ez%Nz1TdY@au=W zMYDe(z@dIeM@LS6{@ne-#-yTYU`|~{F7a{KzwHFcrRP${c(#X6@rAfJpjq@|64thG&a<{6or_b6|L6ZedK=T)w5 za3*4SKsZVlR}>Z+7xlP5yu;2C+xDr!d|F1g$ZVj(re-p0l$ydtSqb4aSIZCEX z5h1e_yW8a9>I2UE0FrBAFb%;hTk`|geE|V-tE^8+NEA4Ao=TQLJiT{jZ!O*)9Lfcf zB_}5*vY|^RO!slid%oDiuRKAhOHzAic=_^Jx0aTcsR9Vr(Vscr>P|hJBLEk5?tHCg zV(zB)P$Dxc%WLq$Y zU%Yv9iH(hIb+x^MjM&@-?UoUh0~Z0MpnPD6#ZK2e2cUc=hMl6UgBOLPx8=zDF1+xb z=t$&}ustp-d&$AU;SZ4P2PnqZ$0Zf|B6NEhm7EUuBzgZYF^kw4vc6Ab$5L6>jqF%`=4qc2eQC##x!+JXxiTVg;zq3 z=<70NgSNZ+88M-rP$*#0zh=^rQ%tr8Tt(X%^Z{cdE@&Yxdry$ey#HKFjGtxF{MSDL zT>b^G{m$E5)|Afl(kVqk$)hxLcxzE%$%y&x=r}OcbINUF!%1!xHHgDjQZN3K$8i9=r_vbz4pS1rQra8k{K zS_?s+MXF55U`hz{Svb%12wRh|dQ!vA|Ax4Im&$KZMb6#QIx*5Z;OqeEK|w_|d3~wJ zBkXtUsrt!@|1oU~Y}bae7#L6GlOZyF_R=1`C0^BEzBCYzp3eux0pv~?D4d|~^ObZk zOHW@Jpt1bu3f2yYCkOA4?nz@$&jmF*Wq5Y9N>KS!*^;GZ6L7Hws>1YfaGJxE7B6KD z!~VPx2EcgQ(lQQYWIEW;V>fp2HDnm1uaR@UlQA%)1}S34k7IzXRoB-q`I!UL0t&?a zJHG+b#2xXvvU1Baq2{$dD5%m1^}?q_;xA#9&4a6dSBryU)I4+KnyszSFTcDm`t<1& zR{&!5u7f8nNLcD6FgN@Lzl3v3IX)qmuR4OmUQ4TS{7+xz(Vv%BO2J)zzQb;+aP zt&O-u+S=L?ObTI|EN=bzxQt9YA-ar`@N11J(Ye*7^SA*_H* zFyKrwxeYP)VigGEV7OP;)wP2A=2a)veq2tjGg9242@O794?#gdK(%6nk;|wS&K(7^ z+_sfn5n*jKJyyU{a!CDOQ#P#s9v1|Qz|vD*?%!Gl)xOLZFD`%vKq@BbalTskqHaQM zxPXS|+@L0H@^YT-ShJo=>$gu2p#+)Mn5=;~f+Oo!fd7w1!`Siff7=OpYF6&? zuWg<{Xb71ji7C4Shfc5Gs)jHS4cA)`JRjCKkCC30C@w(RBVJ@2@q14V1iFCo!DS+3 z=3DhNR~6UV)3XqWo?RS{==5W=j}YqC)zA(>xwRU31}P__SzJJK^wED%7)B1r>T0mx zpr&VLY5|cb8E@A+{=&{a>$Uk1Ue!SJqJZw9Dxbg(Fsz6z{o9}f_fi@$r@TCT9t|p% zG4{akoEw_=p!Aqr7obV;S<_H=-ME?LkfLG_=9oM?8TBWb_*a5~#l@uQ#H0aN zD>fH(?s%El7#La8I=EOXQNLVgUgA0CLkH2)_c;uDS+?zh9G8`maS>|&&_2*OxB&@K z-OSkd8IYv%#e!U^7=^1J@2OWh)5^<4K7-6+Ii8ZdzKZYW9OAmfpM|%DPGF6t2cIYbIYUC z$Hxtgj9R~Q1#p=kn^^j&Sy@??%u^L&EFwWcPE0tl9hTMx$OLmM3Qw7o=9P6l4X5bv zML=oarsi2JA;|Tf#+f5=#&u;I)cB(DWsd;ofm^U*v`zm?SXPTT?^+Bs6W5325rZ~m zNPkreG{ncK)r;Bec(3MB`w`Q`Pq45<+nv^>TMCRsFDFBul_v8bG`&=yRNeiiqXn$% zm`oO4hL{&P2QC7-%5NE%d)b|smF+zqX;jP}c|kJD`^e?Xm!p;Z3eT#l!V3_INl;mL zL`ayfZX2wO;l+!I40=0L$@Z^I`Ls$z!u|#`_K|;MW(Tk0^$S3GaI>%eV$oYw;6Q-( z;0ZW&SUHxP$hkFQ71;>XDJz$Msx&q+p+n8%!TtLVx2hm@{O%WkXOGY=z&N7erAsev z-n^-2U{2Ed7eBDf-s=`;bw4k+UPSI&Ko4*zbb(EeD;%G19%(V2XoLvR&u zckLQf{y@IM`e-(F72t+sLup$GzyU$QHxZc7?x1!4d^4mRPA;wtaPEv02vdgFu3hU^ zf~30l|{xz1fyju0)2kBYcRUQF6Fkc^r9*qYtyCW zm-egHDN1XuF6PsqitN+;GhFnfgZ?<2WO6sC6CoQ@(jFpKZOPLJQ^VrpoX~>f1+K`g zDR%MV#QBi03J3H^_V}Yg@DBdN3`;k307ESGD#)SEwG_y|Pan>QE``oJZ7O83>p0ld zigvYiDJ6LItEERm0mpy`R?Qufrx6X!0@^UTsyb!iJXJj&J!ZJ6mB9=d52{YAOI6Q+ zLid#^xxm$Y!1+#Y39Mv&+=>SEAhzD>VC08QAM=|?@#bGOZIxQ)hVrYBU%ot9Y_1cu zgoXY1=8Y^clH-bsrLlreu~c~lk0P;Qd{C^{;%QR18&9lqfGKdVUAw+wz&JCM^Ob;-Y=n!ci+CoMuCJ|7gqkJNzEDDVq6vRs5_;X zS4r!kS6gQkB|x0Oq-W<5+KL;!W>vxJKt22KD6pvwcyHXYt_cv{PXV2JDFhkHMx6|; zW#;RL{oLG{kjx#y=$n)rQ?aqN9Y2pz{g-EK!*>2QujJbQc7E8q*xdAut5pPDVcgv1f9xGPkKsNpOn|cTU1-#h zav#Jn##_(ByhTgcg~E*YISr>O(zK}}n!q3HeI$U24&5wv4xoxj5)A4Iku|AyaXz12 zZ2d?s{pQel_u7lzb^-{``Ded20u4iyJ(Lz>L1JspxC7AL#c z$!t&N*V9$jGa73_g%VQ$HCL6=1gKs*Iw9W%1`4izdT?xMb0J-&RV;9JcaCX+7R7r~ zKi9JC35k^5)n!@{B@z&l|7pUGNm^sHBou-3V1zHXrh z`}~xRRx(%L^??vuiS7Xs)_%%kL_|acGW1^(Uw7NcVf&9PqKyD#vC!_aiuY6G6O@*2 zgU$^n_jL&${9J*vGZqjNwQxt?$97JPN*Ai&5FHu@806!%$+cQ zZtxCbz5xkw(>wV68;V!Qvv_mcy9YN;%eE6qMYO!ErkN#o4{vF?UnR^b_tUCQDIL4jRtBd-VFQ3pHZ%)_C1Cu37>dIRb zkYWe0G{OG~>#{CY-}Cp$`xUL=#`SVKonByD$BooNKo|wKv%W7@HnFlw1Rc*ETMvDA z;9)N-#YfI@JBUHm3eFjakjbN)&iUhnfz6M%=f>Y*JDj$I@A_$=@N*RDz4h?(U$KU* zU;RJuA#I@ls5x+R&tJcOeIUn$9a{1b+ZA6tbO0&+2DT%V0TOZ78@J@P?8^eV?OARE zpT}S=C#7*`&)$5UmxpxD<(L=iLpw{!WMQ`_yz8;{9p6^^pj%EzNXWBZX=&MlIga|=d`s>%Pf$aqgD{TkTw4;(tumMKkBCl5I1t#T~6$u?Z zs)o4Oj2qXfSf8Q&@Q^W(XinZ1Ka*TKjsl57$v3^fz1yq*?Ty`mZO5P{cK<$@yaS&@ zn!yaoinR3Ag#H3Uv#=AINZo9G>BYrl#7}40y4@biTL-gDNtf8c7mS3I&1$sK6f*IQvv>Cvd zrd6m_dehrJ|zS!*xwF*i5hJ*ul*A@8!mcQQpof_>F z1OKidlt=Cx;m&C}8un6|Zvmo_fv6PzK1i_a^$}V-e;Lw}1;u;i`|cISKB)k2(V^y< zNXfSc!lop*#1S(;Sul}wW95h7Uh*SND&*^7ToUTDv$G<~(tD{gC2vAEPH=i!Li>Ri zkT<~n$+eaGAnyaeUg}?%>g|T!Fc0WBFJGy1kq71e+-04Ab6G2e*ONDYoE`qZcEO zQCyq(pc@!iZUEzR>U{mF7`pyqkEq^}MXFgN_%M&a#E}Oe>cHx4hPsp8Q1w$CThEUx z+o@_S=dwzdzdfWHnOF>YPWSb4DR^h+d5q}N%4Y{E6+A|$&R~45GN@2pi=FDFC_v6} z1yK^~9k7;7V4M-h;1AM*9=lf+zHaRJYlpDy%qQdNSc};;PmxGoUT`-qpp~KW7p5t7Zt`a!8WH3Rz<{q`GQF| zE5cKeE1<9(Z!#$Vjf5R7{w5nb-*jF~4(c?n094Vnqxa_7NHxH}o6{l>0pZzu;csd- m|DpM>1ga?=V3<> zWS8b8HGKqO4n`2B!ELPY9qE?dVfde%`$c1S11GGz*DY6TMEjPz^Ia$RySBFvds@4? z**ZC5#AL-JMGxD!yF0tdi;Fw_`2}K5t~l}5to@4cCfl7anYbayo?GaDOfOW@Z4pG` zrl#8YYu?1Ez99E&9)TM(lr3kX5whU9kAgghvqa9PJik@<=q110sKjSte&gk}AB49Z zS}wf#!FkK;Q+kmOvUR2$941X~2FG8C4S(y(3@(-n{ba($q8`W^ottfZ;K|dPhNmHd z5=k_Hvqd|%Y&ppNk-994+uiFousB;1E!T$=B8;7>;bKCNY97r{3%E)|OpJLi{PoP1 z!w3>=z3m))tA1}Ve2qPV!0SX+5oQE2{u$YVAbC5Pwjsz(?*IP-e|VR!(A30{>OJC| zVdH~u@0WgkC^GC?vaf=7Uay9WPtH}XtE=ns<*#d72ldqvW=>h}?@wJ_UH4V&H2&JA ztI}a;WF9kSjmYj`-kVp=VPtk>yl3Oqf^Wrki(S5%Hd2{HA}^KBI@o#-itH(3eXjMVFKcRE)zNu$N<>7r z?7D|X;q2_}V?6%()ns+scR%lPsf~~{E%$!)`t|F_@$s3z{dOT>zD2_YlbxL%FJ+4_ zx5#a6ZM|k{nweX*&UjGbg9LMIJ2!Yhrq4ZkH=q20Meo6TY>yKXUP@ZkTw*L#c}oPY zdhg;sqqb|;uFTBL*49)ldaIVW9Hr~Eb=c+0m(h2c>M43zTx|T|!-wvCTqMT8#3W;+ zKF)sRQ%q)VuF*hc0LM;Nk8htPaoE-rO}o2yuW4&XbY|a3*G@QVTNBQGkhYx(nO9`3 zHt}$Ge-a+PbMF0qUD=iES;n_o+uF4K{L1p3zWf$~UHbloywK-0;PCL_!>>7pdU`jp zWTI`jZ|H zPSVUfKJ&=5w6tP3<&|%k3VP>_Q>RaBH)mEQJ$%T%?5|9XijIyRJI;iN9VutoX5Wyc zVrh`Bqcqu&ckA8PH%8f}sZ1=aV^oz5pWeW#f!x^G*x~^5p1`V&ER2uG9 zJ8y#<{r=^h3q>|?wb=B=4bohhfrUlR>(^&+3Oo_}?jZ;p(>D7%ckY}#c5H}9g)uC& zi%Gjecs@KlTx@mk+_^|)#tV4`1(KDtv^0;he=(dciO}6`+L$2IB$u0(rVg*c!|aK` zHNdxpmY%n~n3$ZD_FK41<$;s6v$4?&46GE)$jQ-pWqf7p)~z_Rvf81j+95eAdOt#( zm{@RnMn>syEaUgs_+_U)2Q2mp74>Adw(3itJ!{t(FYUX~g&XSk@Ed#fpulBFU5Vaq zU}tByIo9hdH2dk^61-qseX7sg=y;t_Qu}0XRZd@-m;I;5!k@_G>n<*@1a05{@!@? zT%*jP$XctM^4ZJzce`G-d4@d88b3xIYh=(ThaT15mYiD}icDx|xH2^3 z-7r-&;0VJvgheOQKwtkhya)$RG2yI3yqxRsN1whORf#MIS#mLhvtQ2CJW)^~;`kMW5Gc z+6ieS1ut|^N@zGwM~f(#MTEd-wBAJRW~Vme+HkV(DvG z%_Kd3VZqZXTyh7esKhaiN8t*zM89dtw>O)+_!T^}2pHU>{D80Tw?~sm4yR6?3YV-Y zC@drl58p8`H=keBm5XQD0*6PuXG2hpK?s}Ni*j9xIGtn)cd zP0i9TKOcG=6O*biU99T2@XZB#;n}b15j?3d?>I{du4_^}hE`U|7z1NtF0ZMZ5-;>l z3TjS_jp?bXs`g&d*T=K(*g+!v{4=YEr)N#$@W_bm_rbU1D_-3_Jsc70L;MKhegwH^ z;J-Rki%&__iko;<%imV&G5Ht(w#Ttd8}=YR#aWj3U=W@-BA2TykN55ajg&o71nV<0nZ?CkVKIim%Y z7-PxtvM$eO=jICSI!=|Ci5VIh2`!0{wS9a_jz;}5w>00TyT3vZsXm_K_52`WCOSuL zqO@liG|6M`ewN^qcfW*ppDLutuPE_H{=Dl@8Vsivel>8zHmP%paVKYh=C!U!Z!0~0 z`t+=C#bs@6!(5As_LoMvjyRo4bq$RN-QC?^`?o6kq$%)6YVb!=vliKryn{64Hy&Y{lj~kr~Ar=l(TOb7#st>@{`r! zy?TJRy*vPo2exeytXnS9NeumPJ2N}m0}H=o3~(How%*<>xK0HOf)K^~nYQSBq5DeP zcZ!}id95ZVC&zQ<&M&Z%1vS0;JmLgxSC?i=7rO1GeP-_%UcY{dclRWEE<`yuqE|n* zF+P==6l4Lj*DM~itku!cVLR1bXj&CmG3OK$6EhCTOnD+{CFS|eSZS^S!x&9)l5*&l z(!>MC+1h4&`t+&2Dk#XO!a`|j@ILz%X2!T~kZ)8HH*!w*Ji^@fA~RE;)?a~sHlLF3 zHF$tCU%oW(^(__5Fv_(sEpjAbn-a6n9e!FFurh&u)_z^ZFJ{MNWQ-;$xs-Q%RI+eM z0oT!;9k^IFAk4K>9<$i%7OA|k>UP?q-1v*LG0abAO~j!gWv*E`X%S&z&HX|;*MPYI za{wOWGLyIyITtyE!m~JY^&SzPh)>ix;eDYWC+R1A<;I?QlbGW61hW3C@qBlyvF2y4 zC1x&>*7dO;8ozZHY8CamhUx3;KaP%0hGT8Z0es0WFIP-WNwH~vakV?|mTIqyRXAW} zR#uj1YFb)mUY?#n!2H$TEB5v;PiV&r=2Bi36iCIy#!kTQuKX^u3&~?;+D3c}X9@tm zTP~7Kz`t3JGeTYZ9}`>5jW>6%YHEgF*3v2rSn=dIco5~bn?MDOyU>5xHQTI2pH8Pw z^c3a7@jl{H7;U%`FQpj~5s{gZ(E?CYVB2=0@rmTnSHo}eQ%SxF zL>*mGj>TVC4Gj&)VabtS>77i0m15{v)YElvCu;{h$+?w`PXu96(eN@XVDQNUctK$G zx?h}S9c!p_8Bd>969C@fp0vSpNF;!&IDY(iMrGytZv#?DHG9SW3S>}!elcicv2>>9 zPzOAX4qdM=j*N`RyN~_4zMQmSfL}B$ zVD7W-dZ^G}=H*1E4Ga**b>Q&A>}DKwr$Rtl8Pxh9-=6FRZMQllmHo{^j%6!NG$}(*bygDJ8-sUf#lt@NPMr6%`frEId4%<}nR}@%ZuMVSk0Qd$*0XXb2eM zaOwEy=;NCIfc=)}fFxqR7c3|Ypc7bSSy))8^ZjD-Rge$%3*WlP(g5)7&CO3&SN%2h z&CN--Up--GXD1h1MAjaQtevZv=0KX~W=`K6JOB!$NpUXRbGkPpQf1vZw|w>?f8f%s zwZ4Hh(tfYSKCh%+$09h#j?bT809ucA;gTZ!C{xcK@V5eh0UOo@lBB5>C)Tk-tI92L zqh7|FiN%dJCZr1``Rk(!$&=QfEo_i>QbFMcC_a43569GPe*0;AymCP48^^v(AoD1T zE?w;Riy@H$T9OVS=k`R6MIK>^i-)ak0J04hD)0cwW9s1&8}qswci>KO$`t)0hMZIA zIc4hBC{5ui>Tyti#B1A`YboHR$Qeec6$t9RgT?XypLVQT^Mqx@D>F9|XBm&j?`zAo zR2icCHo|k*5Oqw0Jejye=Pl;id?ex|YXs#lFsyz^gQl9|3eD5^YY-0 z>VHXNrP`#RsK|bPtOdZh`<0bO?VehB8rH4_t`?q%4^z$FaeTPR=K zb?EGSKA9SunXez<8PK=0%LHadhe7|)Sn%eJ9Y}qYt7vJV8@h6xF}Wi!7eV~?23MPi z8t0t@k0pI7QazbRC9wSGo!rl1Gyt7!$6Hf<$5Z2ogwr?PfPPj>O-=2t3@CdT7G`K> zmZjvkAd3M)U|Q*4ay`c^gTe5nPxTmqpsszy=Y|FNPpPRZv9W1j z(a55H1lTb80Rd|vWw(%EL)6Tv;nF6_8|GshAMVJF4taOW8jG!&n(W^F;2jRw?NS|; zWQ%QndfuhhZ*e+%eQiYn(+9V}NQx)I4?&tkke{SEPn&`a_UP0wFo*^rAcxvwfaakV zvy0cSUOkf3L{;4M#Qqtjg;5bcz+N{r^PcYz1{;o^Oq^w)2|ycgSeM$eH*0}ab2zVm zx4oc1jTN`d0Z3}?QU-qx_HbvGN%D_BGHL`xK)&IUHK$?&^8&*o}FJ_UdE@Cmdby) zEr~nb2OBtjt0;mzQVU|=THFrnkyfC~R0J{zlnVy9Wj?Nne{N-9qaO~qc6Fhs$^(1W zssFC;;cS zY)RH25w`C?@#K(W@!NI^B|&9lxoNakW&M?~u&`XN-(VZzPjChszLG7eDP3i4TsIy> z8jy2o=fQJ8OJ%1Q=lZ~VV8BxLQd;8 z!of{wgFj|P9FhT*`+)#r(MZZ`+N>{dWeNtY^?m4mAV0HVzE!|!K3IoKhFWa-r$z(& zzoyYJR?`%;?zW3x(HPDNK(TeWF4_a+X))m+z^Mm_keIl*^v916MDR#oK6Li(FA9#~ zEnh!`0m7xWw_oGnewbkE;Lwqx89hw*1zMX1URJ;wopNwJjS1;IjNEe!KP01L zPsuR^=ve>$KxM3IeX?r4C}^dKJOk1e*p2P8K76Jn0aQLg>N0>ma5^}ANC=9fF=X*Po8=6<}7M@ zz09q&3zx)#Xj8{`q2Bi#NIsspdTSuM&g99+|HX7&DAmhf{_Nj^wD*Ong`t-bmXia< z`4aHe8`0(nysMufSC?qfeZkpA`*ZagMNtM#?+v6_!<}v zU_mw&kAgjNF}bCf4MEHSVs~aGf^vhbUdrW(ugUdLjwz5WzWSzhJI zhPqnaf5dD5!b|0-E3C-8KhVZkHZ4a>%yROT7J!l}g-l1f>E+_E>N62w$70Z>N)^I(s_qp}(pnvU-7 z3E}|XCc$*;MD5iu)NTfQ9`*oTHhHZA2Hf7?O{(_A=>u&1Y;eY!lvlD)ElkQ?2?@5 zJ0T2Idy`UZtSw3dmTBVaM_S8$=H|irn4nWEDPVg@TYowLzAY;9@KU$mZ_|DvalS2G zmjVGrq0bz)k)&V*R5tf@e!e)vjRhGyvTsfD&Y*rigfSS$UfDK~I_ShUKT~Z40nz|Y z!G9x{jjPiwWLfI}cXHXhkGQ1czFU!CEvElBxncEDw%vmNMHc`T;B1``usOES7FRi7wfD; zcM3NKYep1eL7Fk#$Uw&H*R8{&qw+m}>^l6%v3R*H>37?q)B+c^4P0OST5x^keo;F* zF;G>N&-WJ~{`)L#`yXa$Jis1NFZj=4+95PdL$*}D3tFcJO@P*K1BOlt027WtAh@`h z_k3|)LSrkH<#J5pP9CX~)84Q~P)7onrU3ETL-k~rJqS{|_pg22hYHl{dn{H+%@^Uk<_R(n1<0!a*%zHaOe*CDXu3jV8$Pc#pP)&pZBwyDdsY^*&lBs987t9Z) z7g*q@&_#F6z#tjkQAA0pkC2g_-2o6socoh^t65S~0=5Qf-To-f6M;?;5LM5dmd?&J z5M3iwsuupw@atSd_fzEeQA~6zH9~>|mN+GxAA+12d(-3C22nXZVPI7~DQLX}6(dc( zki`bLmi3{}7&!JQ0SELuJ8fR{fZzAhAsI(76O_QBJ8{~)^ct;dqjHo?643;OiE{8n z|5?onP=(zUenn_T`0d+Wn0GC_dN|iJV7@kt`Ef{DUIKy60uy2awwIx&=fcGRs6;4T zdam;GPBS~W8`gpzE3#c=l0qX;*Sm`RktMUAL>gaP*XxvZb{E=%abRWzeh0UlYl=x# zU_kGTu_%^5Xw@Z}K(Iw$y|&P!?dImz+W_Lk7Fh0;s=&2y%A_>xGK|I}UZC0&3_9-y zBX`wz_p0-fv_$pDJCyp?>mmnLH#4@js&#v{wltspXnnvuH~*60(cCz&5`>5T^R0xu zk7QD)1rs=J=b&5Qv(TjmirQKD@c-Z%NZ(Rz(5eQiLqP3DLi3=M)CF`268!dbU4dOZ zQkNnXXMcGlpu#UR2W5w`nnO;HYlm9E>CEnUX_VwiI%wg29&B4fFdcxN6?jZ`77qa< zK$8Qho7D&ed%CFAuBBBUQfi0uZE`YTP2~u90IsyCU;nma_?L=4|?# zF`E%(Qgk0mgD21$1OFf7X%@eGyYo|J;n3%B!GH~SN>tPx%frLd-qpn|1NKPz+xu*P z>j!M9eDHrx%vK7LRM7k|U&<>>D%g}M<}66)GM9<#RC3mo#H+EMZlnBv-- z=IpQi&~|cu^;gvd^0+B<5DIiBJp;~AXp0I#i45Dm*jP>odQj&dvYQDQk|KS{5;STqfK2)GjvoYmFUxnMv+pkyDzfD8k!A$B!vbv}7pBk#1{0qG z+QoE@L2m<>*aHNS-Ry83@QZ7*yq#8&N@;R#qq4MeC?aSzsce*UiW)z)T%U~tDcA;h zRT#MDOC1mfQ+sW3AQ$W%n{S_A`Hm8Bn<5tL|?et*lxv2DwI z8)${+D&j~m|Iro!RaUW!ivvL$8|&SVmuh>Qsvx2TGBo-~VOj#%ICil59(H|oIW0dQ zGcE5_wf2Tv$+y6ztPl0Xu^pL)>1#KdlopBHir#tXci|#ND;E316aweRuFk!*T>F%g zo}Qo_z<6T0`t{%_P+zKt$|?_+*-rTKdkbO9f>3bS;mw#!^WjIXO@}pe(t|TpZJ0g_ zT?FgZornLs>TK0##NrC9wVoR>A(sT9wAI`c7(2#+Ap1i9x-*y8o}P39Wut0Ptkc@X zzdFTs0YMi2Gh24S9IU(WW;sp*$V~<2y}=yH8;UI=z`vn5^LsC>T24zxdC}?FZtmHj z0av=p+ysZvK{m!T>|# zZjLf4G&Tfx0bz~{{d@S_;W?G_Vs>SNMiYyB9P9aZJ=D$OomV5#Zt&cAWRT*TF^)=T zDj~j;IDQd==J`{I*)-_gGkO0M4-d`{$kA^UL|yXVoA_;bO)PG{*KK3*^w<2Yof%Y; zJk3?pZ}IZ}6aFiUC2nO^SV~ch?pf4-J3qD*U}R2r zC`kOP*+eBZf}^ywJOhFR7LCFRbS2P2m)^P`n0& z6-e5|0ufqTYwuK6Rb@0>1A{q!JG*NazR7EJ2pGunfESU;EEBdG+bMBzBNG!sejgAw z&<{2n>ualf=8hlbi8uxHG%1i_8@cS6A*l{Ob=A|;^LZTepaRH|MZ}H zuB8>Wid(8U^?OaAU`;tGxAwidE=2c!?UbK3*jS1czYE_S+(-2+i%CjCTUaKHJs;h?k1TpUNq|l&h9sN`M|*=W%Dbf z1rTZS%D6%2u#te#U}4><2gFXwJ zqu|EsD0qHrMoo)qmOW$HMg6YWrBddlFm6Pt^YbgKMzlgP1#k2O7_{x_H#i&L2*}f63tn*cZ!lc z`MC>~){pp=K2bQTx4sQx-;Iz_j#vPm{MvF;kj}h5GU)dOcJ>1v@Wy=U6CT~^dN)i> zhZk4&7i88C^p?04I`+v|fFdZJ$b3nJe8LjW1zhp41eN7wh=cnAl}aCx9H1(7N?JMw zz3Ly~s!wim1^fccYR!z;M?ZKVHgeX@ne9d#)0~JosQUSAf(h- zBPMj^;|?V?;h^uu=Qh@SggT?LF{eUC`(h0s+O#1r_5lM-`|w_gd*`a<0zq}U^?6VT zVDcsKDR@4C8H)#754xPw4gOG@f?}icXp{!Oq(I=(GoLRZ2d_Zer~%Sp5_e?|vaS!^ zws%TUfWd;ZT{GpG08T_aSY+ZYTBV|z6AQ1P0fifdxO~*8iV>r!t1AN?JISi058@3_ z!1$Uo2U+_QD1W_6NlS~r$HEp5LOKDR7ediMU{5%|Qg?BmBh;euii47Oz%2;cj%K#A pe3u}ZH8cAoeE6SVgC}h4`J_(bU{|*?hu;R#yr`p=bK&NX{{|ZrNqztT literal 0 HcmV?d00001 diff --git a/demo/test_results/test_maxent_29000_episodes.png b/demo/test_results/test_maxent_29000_episodes.png new file mode 100644 index 0000000000000000000000000000000000000000..7a9a1772be4b4cbc39fbdd79a024606ccdd4b391 GIT binary patch literal 18464 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 3: - assert array.shape[0] == 1 - array = array[0] - tensor_img = PIL.Image.fromarray(array) - tensor_img.save(f"{name}.png", "PNG") - def get_feature_matrix(self): """ Returns the feature matrix. @@ -71,13 +63,9 @@ def maxent_irl(self, expert, learner, learning_rate): gradient = expert - learner self.theta += learning_rate * gradient - #self.numpy_to_image(expert.reshape((20,20)), "expert_flat") - #self.numpy_to_image(learner.reshape((20, 20)), "learner_flat") - #self.numpy_to_image(self.theta.reshape((20, 20)), "theta_flat") - # Clip theta for j in range(len(self.theta)): - if self.theta[j] > 0: # log values + if self.theta[j] > 0: # log values self.theta[j] = 0 def update_q_table(self, state, action, reward, next_state): @@ -93,7 +81,7 @@ def update_q_table(self, state, action, reward, next_state): q_2 = reward + self.gamma * max(self.q_table[next_state]) self.q_table[state][action] += self.q_learning_rate * (q_2 - q_1) - def train(self, theta_learning_rate): + def train(self, theta_learning_rate, episode_count=30000): """ Trains a model. :param theta_learning_rate: @@ -108,7 +96,7 @@ def train(self, theta_learning_rate): learner_feature_expectations = np.zeros(self.n_states) episodes, scores = [], [] # For every episode - for episode in range(30000): + for episode in range(episode_count): # Resets the environment to an initial state and returns the initial observation. # Start position is in random range of [-0.6, -0.4] state = self.target.env_reset() @@ -145,12 +133,20 @@ def train(self, theta_learning_rate): episodes.append(episode) break - if episode % 1000 == 0: + if episode % 1000 == 0 and episode != 0: score_avg = np.mean(scores) print('{} episode score is {:.2f}'.format(episode, score_avg)) plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/maxent_30000_qtable.png") - np.save("./results/maxent_30000_table", arr=self.q_table) + plt.savefig(f"src/irlwpython/learning_curves/maxent_{episode}_qtable.png") + np.save(f"src/irlwpython/results/maxent_{episode}_qtable", arr=self.q_table) + learner = learner_feature_expectations / episode + plt.imshow(learner.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/learner_{episode}_qtable.png") + plt.imshow(self.theta.reshape((20, 20)), cmap='viridis', interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/theta_{episode}_qtable.png") + plt.imshow(self.feature_matrix.dot(self.theta).reshape((20, 20)), cmap='viridis', + interpolation='nearest') + plt.savefig(f"src/irlwpython/heatmap/rewards_{episode}_qtable.png") def test(self): """ @@ -177,8 +173,8 @@ def test(self): scores.append(score) episodes.append(episode) plt.plot(episodes, scores, 'b') - plt.savefig("./learning_curves/maxent_test_30000.png") + plt.savefig("src/irlwpython/learning_curves/maxent_test_30000_maxentropy.png") break if episode % 1 == 0: - print('{} episode score is {:.2f}'.format(episode, score)) \ No newline at end of file + print('{} episode score is {:.2f}'.format(episode, score)) diff --git a/src/irlwpython/MountainCar.py b/src/irlwpython/MountainCar.py index 5c1dcf7..2543615 100644 --- a/src/irlwpython/MountainCar.py +++ b/src/irlwpython/MountainCar.py @@ -27,7 +27,7 @@ def get_demonstrations(self): env_high = self.env.observation_space.high env_distance = (env_high - env_low) / self.one_feature - raw_demo = np.load(file="./expert_demo/expert_demo.npy") + raw_demo = np.load(file="src/irlwpython/expert_demo/expert_demo.npy") demonstrations = np.zeros((len(raw_demo), len(raw_demo[0]), 3)) for x in range(len(raw_demo)): for y in range(len(raw_demo[0])): diff --git a/src/irlwpython/learning_curves/maxent_300.png b/src/irlwpython/learning_curves/maxent_300.png deleted file mode 100644 index c444b6ba7d968df9d45b248bdf6b9cf06d1eb214..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21355 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 diff --git a/src/irlwpython/learning_curves/maxent_30000_flat.png b/src/irlwpython/learning_curves/maxent_30000_flat.png deleted file mode 100644 index fcf019d7a2631af74c2d29ad3359036501186e06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15548 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 G=zjn|bkM^9 diff --git a/src/irlwpython/learning_curves/maxent_test.png b/src/irlwpython/learning_curves/maxent_test.png deleted file mode 100644 index 57a2b2b6263bbf514487eadec380d573eb1f302a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21157 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 diff --git a/src/irlwpython/learning_curves/maxent_test_300.png b/src/irlwpython/learning_curves/maxent_test_300.png deleted file mode 100644 index 9e53fcd6d718a1b0eeed80b644e5e03f4c2970d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20091 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 OGkCiCxvXBW&Bvgh(ic-dWqXEr^ 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