強化學習快餐教程(1) - gym環境搭建
欲練強化學習神功,首先得找一個可以操練的場地。
兩大巨頭OpenAI和Google DeepMind都不約而同的以游戲做為平臺,比如OpenAI的長處是DOTA2,而DeepMind是AlphaGo下圍棋。
下面我們就從OpenAI為我們提供的gym為入口,開始強化學習之旅。
OpenAI gym平臺安裝
安裝方法很簡單,gym是python的一個包,通過pip安裝即可。
例:
pip3 install gym --user
源代碼的下載地址在:https://github.com/openai/gym
gym平臺的目的就是提供一個供強化學習進行比較和交流的標準化平臺。
第一個gym游戲:cart pole
cart pole是一個最簡單的小游戲模型,它是一個一維的小車上豎起一根棍子,然后通過調整左右來保證棍子不倒。
我們先來一個隨機輸入的例子,大家先讓這個小游戲跑起來:
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
env.render()
env.step(env.action_space.sample()) # take a random action
env.close()
通過運行可以看到,別說棍子不倒了,繞著圈帶著小車不知道飛到哪里去了。
gym主要為我們提供了兩種元素:環境和操作。
我們首先通過gym.make來生成cartpole的運行環境,然后reset給小車和棍子一個初始化的值。
最后,通過env.step將操作傳給環境去控制小車。
操作
cartpole的操作非常簡單,只有兩種命令,用0和1表示。0是向左推小車,1是向右推小車。小車是處在一個光滑軌道上的,根據牛頓第一定律,在無外力時處于靜止或勻速直線運動的狀態。
剛才我們調用env.action_space.sample(),就是在0和1之間隨機生成兩種狀態之一做為輸入。
除了剛才的隨機策略外,我們也可以采取交替的策略:
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
i = 0
env.render()
env.step( (i+1) % 2)
env.close()
獲取環境信息
但是,有了操作之后是個開環的系統,我們需要通過從環境中讀取信息來更好地決策。
其實,不管是reset還是step,環境都是會返回一系列值給我們的。
reset會返回一個狀態信息給我們。而step會返回一個四元組,分別是狀態信息,獎勵信息,是否已經結束和附加信息。
我們進行一輪迭代,先判斷下是否已經失敗,如果已經倒了就結束游戲,然后統計一下我們活了幾輪:
import gym
env = gym.make('CartPole-v0')
status = env.reset()
for step in range(1000):
i = 0
env.render()
status, reward, done, info = env.step( (i+1) % 2)
if done:
print('dead in %d steps' % step)
break
env.close()
下面我們再進一步,去讀取一下狀態信息。針對cartpole這個問題,狀態信息還是一個4元組,分別是:
- 小車位置
- 小車速度
- 棍的傾斜角度
- 棍的角速度
在本游戲中,如果角度大于12度,或者小車位置超出了2.4,就意味著失敗了,直接結束。
閉環控制
知道了反饋信息之后,我們就可以想辦法進行閉環控制了。
比如我們只取位置參數,如果偏左了就向右推,反之亦然:
def action(status):
pos, v, ang, va = status
print(status)
if pos <= 0:
return 1
else:
return 0
完整代碼如下:
import gym
def action(status):
pos, v, ang, va = status
print(status)
if pos <= 0:
return 1
else:
return 0
env = gym.make('CartPole-v0')
status = env.reset()
for step in range(1000):
i = 0
env.render()
status, reward, done, info = env.step(action(status))
if done:
print('dead in %d steps' % step)
break
env.close()
下面是我運行一次的結果:
[-0.01635101 0.00400916 -0.02452805 -0.01815461]
[-0.01627082 0.19947413 -0.02489114 -0.31847439]
[-0.01228134 0.39494158 -0.03126063 -0.61890199]
[-0.00438251 0.59048591 -0.04363867 -0.9212643 ]
[ 0.00742721 0.78616953 -0.06206395 -1.22733599]
[ 0.0231506 0.59189892 -0.08661067 -0.95472622]
[ 0.03498858 0.3980421 -0.1057052 -0.69046268]
[ 0.04294942 0.2045334 -0.11951445 -0.43283924]
[ 0.04704009 0.0112884 -0.12817124 -0.18009313]
[ 0.04726586 -0.18178868 -0.1317731 0.0695676 ]
[ 0.04363008 -0.37479942 -0.13038175 0.31794448]
[ 0.0361341 -0.56784668 -0.12402286 0.56683387]
[ 0.02477716 -0.76103061 -0.11268618 0.81801468]
[ 0.00955655 -0.95444458 -0.09632589 1.07323592]
[-0.00953234 -1.14817057 -0.07486117 1.33420176]
[-0.03249575 -0.9521891 -0.04817713 1.01906429]
[-0.05153954 -0.7564593 -0.02779585 0.71165164]
[-0.06666872 -0.5609637 -0.01356281 0.41035059]
[-0.077888 -0.36565212 -0.0053558 0.11342282]
[-0.08520104 -0.17045384 -0.00308735 -0.180945 ]
[-0.08861011 0.02471216 -0.00670625 -0.47460027]
[-0.08811587 0.21992817 -0.01619825 -0.76938932]
[-0.08371731 0.41526928 -0.03158604 -1.06712463]
[-0.07541192 0.61079456 -0.05292853 -1.36955102]
[-0.06319603 0.80653727 -0.08031955 -1.67830763]
[-0.04706529 1.0024934 -0.1138857 -1.99488277]
[-0.02701542 1.19860803 -0.15378336 -2.32055915]
[-0.00304326 1.39475935 -0.20019454 -2.65634816]
dead in 27 steps
角策略
上一種策略我們是根據車的位置來進行控制。我們還可以考慮根據角度來進行控制:
import gym
def action_a(status):
pos, v, ang, va = status
print(status)
if ang > 0:
return 1
else:
return 0
env = gym.make('CartPole-v0')
status = env.reset()
for step in range(1000):
i = 0
env.render()
status, reward, done, info = env.step(action_a(status))
if done:
print('dead in %d steps' % step)
break
env.close()
從一些次嘗試來看,角策略比上一個位置策略要更優一些:
[ 0.00780229 -0.02463916 -0.01033269 -0.03445555]
[ 0.00730951 -0.21961142 -0.0110218 0.25494948]
[ 0.00291728 -0.41457429 -0.00592281 0.54413566]
[-0.00537421 -0.60961251 0.0049599 0.83494657]
[-0.01756646 -0.41455866 0.02165883 0.54382761]
[-0.02585763 -0.21974767 0.03253538 0.25804686]
[-0.03025258 -0.02510495 0.03769632 -0.02419899]
[-0.03075468 0.16945669 0.03721234 -0.30475403]
[-0.02736555 0.36402912 0.03111726 -0.58547272]
[-0.02008497 0.55870171 0.01940781 -0.86819324]
[-0.00891093 0.75355429 0.00204394 -1.15471154]
[ 0.00616015 0.94864953 -0.02105029 -1.44675287]
[ 0.02513314 0.75379272 -0.04998535 -1.16072073]
[ 0.040209 0.55935628 -0.07319976 -0.88411992]
[ 0.05139612 0.36530055 -0.09088216 -0.61531734]
[ 0.05870214 0.17155806 -0.10318851 -0.35258554]
[ 0.0621333 -0.02195676 -0.11024022 -0.09414094]
[ 0.06169416 -0.21534017 -0.11212304 0.16182831]
[ 0.05738736 -0.40869329 -0.10888647 0.41714169]
[ 0.04921349 -0.60211728 -0.10054364 0.67361 ]
[ 0.03717115 -0.7957087 -0.08707144 0.93302056]
[ 0.02125697 -0.98955482 -0.06841103 1.19712154]
[ 1.46587604e-03 -1.18372790e+00 -4.44685947e-02 1.46760271e+00]
[-0.02220868 -1.37827822 -0.01511654 1.74607025]
[-0.04977425 -1.57322512 0.01980486 2.03401309]
[-0.08123875 -1.37831278 0.06048513 1.74752417]
[-0.108805 -1.18392804 0.09543561 1.47425204]
[-0.13248357 -0.99009321 0.12492065 1.21283837]
[-0.15228543 -0.796785 0.14917742 0.96176679]
[-0.16822113 -0.60394842 0.16841275 0.71942016]
[-0.1803001 -0.41150733 0.18280116 0.48412211]
[-0.18853024 -0.21937201 0.1924836 0.25416579]
[-0.19291768 -0.02744473 0.19756691 0.02783298]
[-0.19346658 0.16437637 0.19812357 -0.19659389]
[-0.19017905 0.35619437 0.1941917 -0.42082427]
[-0.18305516 0.54811122 0.18577521 -0.64655444]
[-0.17209294 0.74022551 0.17284412 -0.87546311]
[-0.15728843 0.93262987 0.15533486 -1.10920578]
[-0.13863583 1.12540784 0.13315074 -1.34940608]
[-0.11612768 1.31862936 0.10616262 -1.59764218]
[-0.08975509 1.51234492 0.07420978 -1.85542638]
[-0.05950819 1.70657739 0.03710125 -2.12417555]
[-0.02537664 1.90131142 -0.00538226 -2.40517032]
[ 0.01264959 1.7062367 -0.05348567 -2.11414485]
[ 0.04677432 1.51168791 -0.09576856 -1.83845627]
[ 0.07700808 1.31774548 -0.13253769 -1.57698862]
[ 0.10336299 1.12442853 -0.16407746 -1.32840846]
[ 0.12585156 0.9317127 -0.19064563 -1.09123975]
dead in 47 steps