gym 環(huán)境解析:MountainCarContinuous-v0

MountainCarContinuous-v0

1. 概述

細(xì)節(jié):動(dòng)力不足的汽車必須爬上一維小山才能到達(dá)目標(biāo)。 與MountainCar-v0不同丧失,動(dòng)作(應(yīng)用的引擎力)允許是連續(xù)值豺妓。

目標(biāo)位于汽車右側(cè)的山頂上。 如果汽車到達(dá)或超出布讹,則劇集終止琳拭。

在左側(cè),還有另一座山描验。 攀登這座山丘可以用來獲得潛在的能量白嘁,并朝著目標(biāo)加速。 在這第二座山頂上挠乳,汽車不能超過等于-1的位置权薯,好像有一堵墻。 達(dá)到此限制不會(huì)產(chǎn)生懲罰(可能在更具挑戰(zhàn)性的版本中)[1].
類型:連續(xù)控制

2. 環(huán)境

2.1 Observation & state

\begin{array}{|c|l|c|r|} \hline & \ text{Observation} & \text{Min} & \text{Max} \\ \hline 0 & Position & -1.2 & 0.6 \\ \hline 1 &Velocity& -0.07 & 0.07\\ \hline \end{array}
請(qǐng)注意睡扬,速度受到限制以便于探索盟蚣,但在更具挑戰(zhàn)性的版本中可能會(huì)放寬此約束。

注意:Observation是 state的函數(shù)卖怜,二者有時(shí)相同屎开,有時(shí)不同,在此例中马靠,二者是一樣的奄抽,在 Pendulum-v0中,Observation是state的函數(shù)甩鳄。

2.2 Actions

\begin{array}{|c|l|c|r|} \hline n & \text {Action} \\ \hline 0 & 將車推向左側(cè)(負(fù)值)或向右側(cè)(正值) & \\ \hline \end{array}

2.3 Reward

獎(jiǎng)勵(lì)為到達(dá)右側(cè)山丘目標(biāo)的100逞度,減去從開始到目標(biāo)的動(dòng)作平方總和。這個(gè)獎(jiǎng)勵(lì)函數(shù)提出了一個(gè)探索挑戰(zhàn)妙啃,因?yàn)槿绻砣藳]有盡快到達(dá)目標(biāo)档泽,它將會(huì)發(fā)現(xiàn)最好不要移動(dòng),并且不再找到目標(biāo)揖赴。
請(qǐng)注意馆匿,對(duì)于大多數(shù)已發(fā)表的作品而言,這種獎(jiǎng)勵(lì)是不尋常的燥滑,其目標(biāo)是盡可能快地達(dá)到目標(biāo)渐北,因此有利于爆炸戰(zhàn)略。

更多的獎(jiǎng)勵(lì)函數(shù)形式查看這個(gè)Leaderboard

2.4 初始狀態(tài)

位于-0.6和-0.4之間铭拧,無速度赃蛛。

2.5 終止?fàn)顟B(tài)- Episode Termination

位置等于0.5(此值可能被調(diào)整)恃锉。 可以在更具挑戰(zhàn)性的版本中添加對(duì)速度的約束。
添加最大步數(shù)可能是個(gè)好主意呕臂。

2.6 Solved Requirements

獲得超過90的獎(jiǎng)勵(lì)淡喜。此值可能會(huì)被調(diào)整。

3. 代碼

3.1 導(dǎo)入lib

import math
import gym
from gym import spaces
from gym.utils import seeding
import numpy as np

3.2 定義Continuous_MountainCarEnv

class Continuous_MountainCarEnv(gym.Env):
    metadata = {
        'render.modes': ['human', 'rgb_array'],
        'video.frames_per_second': 30
    }
3.2.1 定義__init__(self)函數(shù)
def __init__(self):
        self.min_action = -1.0  # 最小動(dòng)作值
        self.max_action = 1.0   # 最大動(dòng)作值
        self.min_position = -1.2 # 最低位置
        self.max_position = 0.6  # 最高位置
        self.max_speed = 0.07  # 最大速度
        self.goal_position = 0.45 # was 0.5 in gym, 0.45 in Arnaud de Broissia's version
        self.power = 0.0015

        self.low_state = np.array([self.min_position, -self.max_speed]) # [-1.2, -0.07]
        self.high_state = np.array([self.max_position, self.max_speed]) # [0.6, 0.07]

        self.viewer = None
        #   聲明observation space和action space的上下限
        self.action_space = spaces.Box(low=self.min_action, high=self.max_action, shape=(1,)) 
        # (low = 1.0, high = 1.0)
        self.observation_space = spaces.Box(low=self.low_state, high=self.high_state)
        # (low = -1.2, high = 0.6 )
  
        self.seed()
        self.reset()
3.2.2 定義隨機(jī)種子函數(shù)seed(self, seed=None)
    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]
3.2.3 定義step(self, action)函數(shù)

step()函數(shù)
該函數(shù)在仿真器中扮演物理引擎的角色诵闭。其輸入是動(dòng)作action輸出是:下一步狀態(tài)澎嚣,立即回報(bào)疏尿,是否終止,調(diào)試項(xiàng)。該函數(shù)描述了 智能體與環(huán)境交互的所有信息易桃,是環(huán)境文件中最重要的函數(shù)褥琐。在該函數(shù)中, 一般利用智能體的運(yùn)動(dòng)學(xué)模型和動(dòng)力學(xué)模型計(jì)算下一步的狀態(tài)和立即回報(bào)晤郑,并判斷是否達(dá)到終止?fàn)顟B(tài)

    def step(self, action):

  1.    position = self.state[0]
  2.    velocity = self.state[1]
        # position, velocity = self.state
  3.    force = min(max(action[0], -1.0), 1.0)

  4.    velocity += force*self.power - 0.0025 * math.cos(3*position)
  5.    if (velocity > self.max_speed): velocity = self.max_speed
  6.    if (velocity < -self.max_speed): velocity = -self.max_speed
  7.    position += velocity
  8.    if (position > self.max_position): position = self.max_position
  9.    if (position < self.min_position): position = self.min_position
  10.   if (position==self.min_position and velocity<0): velocity = 0

  11.   done = bool(position >= self.goal_position)

  12.   reward = 0
  13.   if done:
  14.       reward = 100.0
  15.   reward-= math.pow(action[0],2)*0.1

  16.   self.state = np.array([position, velocity])
  17.   return self.state, reward, done, {}

  1. 初始化位置狀態(tài)
  2. 初始化速度狀態(tài)
  3. 引擎力:內(nèi)層的max(action[0], -1.0)確保動(dòng)作值不低于下界敌呈,即 - 1.0,
    外層的min(max(action[0], -1.0), 1.0)確保動(dòng)作值不高于上界造寝,即 1.0
  4. 計(jì)算速度:注意是速度累加的磕洪,這是微分的概念,把連續(xù)過程離散成很小的片段以進(jìn)行近似
  5. 判斷當(dāng)前速度是否大于最大速度:如果是诫龙,將當(dāng)前速度設(shè)定為最大速度
  6. 判斷當(dāng)前速度是否小于最小速度:如果是析显,將當(dāng)前速度設(shè)定為最小速度
  7. 計(jì)算位置
  8. 判斷當(dāng)前位置是否高于最高位置:如果是,將當(dāng)前位置設(shè)定為最高位置
  9. 判斷當(dāng)前位置是否低于最低位置:如果是签赃,將當(dāng)前位置設(shè)定為最低位置
  10. 如果當(dāng)前位置是最低位置速度小于 0 :將速度設(shè)為0
  11. 判斷布爾類型的谷异,返回True或者False
  12. 初始化 reward = 0
  13. 如果當(dāng)前位置高于目標(biāo)位置,
  14. 給予 agent 值為100的reward
  15. reward = reward - action^ 2*0.1
  16. 這是執(zhí)行動(dòng)作之后得到的新的狀態(tài)
  17. step()函數(shù)返回下一時(shí)刻的觀測(cè)锦聊,回報(bào)歹嘹,是否終止,調(diào)試項(xiàng)
    MountainCarContinuous-v0

11-15 這幾行代碼的意思是:每執(zhí)行一個(gè)step,就會(huì)檢查看自己是否越過了右邊的山峰孔庭,據(jù)此來給done賦值尺上,如果小車沒有越過右邊的山峰,即 done=False史飞,則在這一個(gè)step, reward將會(huì)記為-action^2*0.1尖昏,也就是這一個(gè)時(shí)間步我們耗費(fèi)了多少能量,我們當(dāng)然不希望耗油太多构资。如果小車越過右邊的山峰抽诉,即 done=True,這一個(gè)step就會(huì)馬上得到-action^2*0.1 + 100 的獎(jiǎng)勵(lì)吐绵。


3.2.4 定義reset()函數(shù):

在強(qiáng)化學(xué)習(xí)算法中迹淌,智能體需要一次次地嘗試河绽,累積經(jīng)驗(yàn),然后從經(jīng)驗(yàn)中學(xué)到好的動(dòng)作唉窃。一次嘗試我們稱之為一條軌跡或一個(gè)episode. 每次嘗試都要到達(dá)終止?fàn)顟B(tài). 一次嘗試結(jié)束后耙饰,智能體需要從頭開始,這就需要智能體具有重新初始化的功能纹份。函數(shù)reset()就是這個(gè)作用, agent與環(huán)境交互前調(diào)用該函數(shù)苟跪,確定agent的初始狀態(tài)以及其他可能的一些初始化設(shè)置。此例中在每個(gè)episode開始時(shí)蔓涧,position初始化為[-0.6,-0.4]之間的一個(gè)任意狀態(tài)件已,速度初始化為0.

    def reset(self):
        self.state = np.array([self.np_random.uniform(low=-0.6, high=-0.4), 0])
        return np.array(self.state)

3.2.5 定義_height(self, xs)函數(shù):

此函數(shù)用于下面的render()函數(shù)用來構(gòu)建圖像引擎

    def _height(self, xs):
        return np.sin(3 * xs)*.45+.55
3.2.6 定義render(self, mode='human')函數(shù)

render()函數(shù)是圖像引擎,就是人機(jī)交互界面,進(jìn)行動(dòng)畫演示元暴,一個(gè)仿真環(huán)境必不可少的兩部分 是物理引擎和圖像引擎篷扩。物理引擎模擬環(huán)境中物體的運(yùn)動(dòng)規(guī)律;圖像引擎用來顯示環(huán)境中的物體圖像茉盏。

    def render(self, mode='human'):
        screen_width = 600
        screen_height = 400

        world_width = self.max_position - self.min_position
        scale = screen_width/world_width
        carwidth=40
        carheight=20


        if self.viewer is None:
            from gym.envs.classic_control import rendering
            self.viewer = rendering.Viewer(screen_width, screen_height)
            xs = np.linspace(self.min_position, self.max_position, 100)
            ys = self._height(xs)
            xys = list(zip((xs-self.min_position)*scale, ys*scale))

            self.track = rendering.make_polyline(xys)
            self.track.set_linewidth(4)
            self.viewer.add_geom(self.track)

            clearance = 10

            l,r,t,b = -carwidth/2, carwidth/2, carheight, 0
            car = rendering.FilledPolygon([(l,b), (l,t), (r,t), (r,b)])
            car.add_attr(rendering.Transform(translation=(0, clearance)))
            self.cartrans = rendering.Transform()
            car.add_attr(self.cartrans)
            self.viewer.add_geom(car)
            frontwheel = rendering.make_circle(carheight/2.5)
            frontwheel.set_color(.5, .5, .5)
            frontwheel.add_attr(rendering.Transform(translation=(carwidth/4,clearance)))
            frontwheel.add_attr(self.cartrans)
            self.viewer.add_geom(frontwheel)
            backwheel = rendering.make_circle(carheight/2.5)
            backwheel.add_attr(rendering.Transform(translation=(-carwidth/4,clearance)))
            backwheel.add_attr(self.cartrans)
            backwheel.set_color(.5, .5, .5)
            self.viewer.add_geom(backwheel)
            flagx = (self.goal_position-self.min_position)*scale
            flagy1 = self._height(self.goal_position)*scale
            flagy2 = flagy1 + 50
            flagpole = rendering.Line((flagx, flagy1), (flagx, flagy2))
            self.viewer.add_geom(flagpole)
            flag = rendering.FilledPolygon([(flagx, flagy2), (flagx, flagy2-10), 
            (flagx+25, flagy2-5)])
            flag.set_color(.8,.8,0)
            self.viewer.add_geom(flag)

        pos = self.state[0]
        self.cartrans.set_translation((pos-self.min_position)*scale, self._height(pos)*scale)
        self.cartrans.set_rotation(math.cos(3 * pos))

        return self.viewer.render(return_rgb_array = mode=='rgb_array')

強(qiáng)化學(xué)習(xí)算法可以不用圖像引擎鉴未,這里我們不做解釋了。

3.2.7 定義close(self)函數(shù)
    def close(self):
        if self.viewer:
            self.viewer.close()
            self.viewer = None

參考:

  1. https://github.com/openai/gym/wiki/MountainCarContinuous-v0

  2. https://github.com/openai/gym/blob/master/gym/envs/classic_control/continuous_mountain_car.py

  3. https://applenob.github.io/mountain_car.html

  4. https://blog.csdn.net/u013745804/article/details/78403912

  5. 強(qiáng)化學(xué)習(xí)實(shí)踐二 理解gym的建模思想

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸠姨,一起剝皮案震驚了整個(gè)濱河市铜秆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌讶迁,老刑警劉巖羽峰,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異添瓷,居然都是意外死亡梅屉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門鳞贷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坯汤,“玉大人,你說我怎么就攤上這事搀愧《枘簦” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵咱筛,是天一觀的道長(zhǎng)搓幌。 經(jīng)常有香客問我,道長(zhǎng)迅箩,這世上最難降的妖魔是什么溉愁? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮饲趋,結(jié)果婚禮上拐揭,老公的妹妹穿的比我還像新娘撤蟆。我一直安慰自己,他們只是感情好堂污,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布家肯。 她就那樣靜靜地躺著,像睡著了一般盟猖。 火紅的嫁衣襯著肌膚如雪讨衣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天式镐,我揣著相機(jī)與錄音值依,去河邊找鬼。 笑死碟案,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的颇蜡。 我是一名探鬼主播价说,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼风秤!你這毒婦竟也來了鳖目?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤缤弦,失蹤者是張志新(化名)和其女友劉穎领迈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碍沐,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狸捅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了累提。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尘喝。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖斋陪,靈堂內(nèi)的尸體忽然破棺而出朽褪,到底是詐尸還是另有隱情,我是刑警寧澤无虚,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布缔赠,位于F島的核電站,受9級(jí)特大地震影響友题,放射性物質(zhì)發(fā)生泄漏嗤堰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一度宦、第九天 我趴在偏房一處隱蔽的房頂上張望梁棠。 院中可真熱鬧置森,春花似錦、人聲如沸符糊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽男娄。三九已至行贪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間模闲,已是汗流浹背建瘫。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尸折,地道東北人啰脚。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像实夹,于是被迫代替她去往敵國和親橄浓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,089評(píng)論 1 32
  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,128評(píng)論 3 23
  • 1亮航、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_x閱讀 15,968評(píng)論 3 119
  • @fz 我和你的故事就只是我和你的故事.沒有任何一對(duì)情侶演繹的到.我們?cè)谝黄鸬那耙?..
    噠噠噠小馨馨閱讀 383評(píng)論 0 0
  • 好多年前的一個(gè)秋天荸实,我一時(shí)興起買了盤中國十大古典音樂磁帶,天天聽不夠缴淋,尤其是二泉映月准给,聽著悠揚(yáng)的音樂,如醉如癡重抖,漸...
    藍(lán)色印跡閱讀 262評(píng)論 1 5