官术网_书友最值得收藏!

2.5 Gym的額外功能:包裝器和監(jiān)控器

到目前為止,我們已經(jīng)討論了Gym核心API的三分之二,以及編寫智能體所需的基礎(chǔ)功能。剩下的API你可以不學(xué),但是它們能讓你更輕松地編寫整潔的代碼。所以還是簡單介紹一下剩余的API!

2.5.1 包裝器

很多時候,你希望以某種通用的方式擴展環(huán)境的功能。例如,想象一個環(huán)境,它給了你一些觀察,但是你想將它們累積緩存起來,用以提供智能體最近N個觀察。這在動態(tài)計算機游戲中是一個很常見的場景,比如單一一幀不足以了解游戲狀態(tài)的完整信息。例如,你希望能裁剪或預(yù)處理一些圖像像素以便智能體來消化這些信息,又或者你想以某種方式歸一化獎勵值。有相同結(jié)構(gòu)的場景太多了,你可能想要將現(xiàn)有的環(huán)境“包裝”起來并附加一些額外的邏輯。Gym為這些場景提供了一個方便使用的框架——Wrapper類。

類的結(jié)構(gòu)如圖2.4所示。

048-01

圖2.4 Gym中Wrapper類的層級

Wrapper類繼承自Env類。它的構(gòu)造函數(shù)只有一個參數(shù),即要被“包裝”的Env類的實例。為了附加額外的功能,需要重新定義想擴展的方法,例如step()reset()。唯一的要求就是需要調(diào)用超類中的原始方法。

為了處理更多特定的要求,例如Wrapper類只想要處理環(huán)境返回的觀察或只處理動作,那么用Wrapper的子類過濾特定的信息即可。它們分別是:

  • ObservationWrapper:需要重新定義父類的observation(obs)方法。obs參數(shù)是被包裝的環(huán)境給出的觀察,這個方法需要返回給予智能體的觀察。
  • RewardWrapper:它暴露了一個reward(rew)方法,可以修改給予智能體的獎勵值。
  • ActionWrapper:需要覆蓋action(act)方法,它能修改智能體傳給被包裝環(huán)境的動作。

為了讓它更實用,假設(shè)有一個場景,我們想要以10%的概率干涉智能體發(fā)出的動作流,將當(dāng)前動作替換成隨機動作。這看起來不是一個明智的決定,但是這個小技巧可以解決第1章提到的利用與探索問題,它是最實用、最強大的方法之一。通過發(fā)布隨機動作,讓智能體探索環(huán)境,時不時地偏離它原先策略的軌跡。使用ActionWrapper類很容易就能實現(xiàn)(完整的例子見Chapter02/03_random_action_wrapper.py)。

049-01

先通過調(diào)用父類的__init__方法初始化包裝器,并保存epsilon(隨機動作的概率)。

049-02

我們需要覆蓋這個方法,并通過它來修改智能體的動作。每一次都先擲骰子,都會有epsilon的概率從動作空間采樣一個隨機動作,用來替換智能體傳給我們的動作。注意,這里用了action_space和包裝抽象,這樣就能寫抽象的代碼了,這適用于Gym的任意一個環(huán)境。另外,每次替換動作的時候必須將消息打印出來,以驗證包裝器是否生效。當(dāng)然,在生產(chǎn)代碼中,這不是必需的。

049-03

是時候應(yīng)用一下包裝器了。創(chuàng)建一個普通的CartPole環(huán)境,并將其傳入Wrapper構(gòu)造函數(shù)。然后,將Wrapper類當(dāng)成一個普通的Env實例,用它來取代原始的CartPole。因為Wrapper類繼承自Env類,并且暴露了相同的接口,我們可以任意地嵌套包裝器。這是一個強大、優(yōu)雅且通用的解決方案。

049-04

除了智能體比較笨,每次都選擇同樣的0號動作外,代碼幾乎相同。通過運行代碼,應(yīng)該能看到包裝器確實在生效了:

050-01

如果愿意,可以在包裝器創(chuàng)建時指定epsilon參數(shù),驗證這樣的隨機性平均下來,會提升智能體得到的分?jǐn)?shù)。

繼續(xù)來看Gym中隱藏的另外一個有趣的寶藏:Monitor(監(jiān)控器)。

2.5.2 監(jiān)控器

另一個應(yīng)該注意的類是Monitor。它的實現(xiàn)方式與Wrapper類似,可以將智能體的性能信息寫入文件,也可以選擇將智能體的動作錄下來。之前,還可以將Monitor類的記錄結(jié)果上傳到https://gym.openai.com,查看智能體和其他智能體對比的結(jié)果排名(見圖2.5),但不幸的是,在2017年8月末,OpenAI決定關(guān)閉此上傳功能并銷毀所有原來的結(jié)果。雖然有好幾個提供相同功能的網(wǎng)站,但是它們都還沒完全準(zhǔn)備好。希望這個窘境能很快被解決,但是在撰寫本書時,還無法將自己的智能體和他人的進(jìn)行比較。

為了讓你大致了解Gym的網(wǎng)頁,圖2.5給出了CartPole環(huán)境的排行榜。

050-02

圖2.5 Gym網(wǎng)站上的CartPole提交頁面

在網(wǎng)頁上的每次提交都包含了訓(xùn)練的動態(tài)詳情。例如,圖2.6是我訓(xùn)練《毀滅戰(zhàn)士》迷你游戲時得到的結(jié)果記錄。

051-01

圖2.6 DoomDefendLine環(huán)境提交后的動態(tài)顯示

盡管如此,Monitor仍然很有用,因為你可以查看智能體在環(huán)境中的行動情況。所以,還是看一下如何將Monitor加入隨機CartPole智能體中,唯一的區(qū)別就是下面這段代碼(完整的代碼見Chapter02/04_cartpole_random_monitor.py):

051-02

傳給Monitor類的第二個參數(shù)是監(jiān)控結(jié)果存放的目錄名。目錄不應(yīng)該存在,否則程序會拋出異常(為了解決這個問題,要么手動刪除目錄,要么將force=True的參數(shù)傳入Monitor的構(gòu)造函數(shù))。

Monitor類要求系統(tǒng)中有FFmpeg工具,用來將觀察轉(zhuǎn)換成視頻文件。這個工具必須存在,否則Monitor將拋出異常。安裝FFmpeg的最簡單方式就是使用系統(tǒng)的包管理器,每個操作系統(tǒng)安裝的方式都不同。

要執(zhí)行此示例的代碼,還應(yīng)該滿足以下三個前提中的一個:

  • 代碼應(yīng)該在帶有OpenGL擴展(GLX)的X11會話中運行。
  • 代碼應(yīng)該在Xvfb虛擬顯示器中運行。
  • 在SSH連接中使用X11轉(zhuǎn)發(fā)。

這樣做的原因是Monitor需要錄制視頻,也就是不停地對環(huán)境繪制的窗口進(jìn)行截屏。一些環(huán)境使用OpenGL來畫圖,所以需要OpenGL的圖形模式。云虛擬機可能會比較麻煩,因為它們沒有顯示器以及圖形界面。為了解決這個問題,可以使用特殊的“虛擬”顯示器,它被稱為Xvfb(X11虛擬幀緩沖器),它會在服務(wù)器端啟動一個虛擬的顯示器并強制程序在它里面繪圖。這足以使Monitor愉快地生成視頻了。

為了在程序中使用Xvfb環(huán)境,需要安裝它(通常需要安裝xvfb包)并執(zhí)行特定的腳本xvfb-run

052-01

從前面的日志可以看到,視頻已經(jīng)成功寫入,因此可以通過播放來窺視智能體的某個部分。

另一個錄制智能體動作的方法是使用SSH X11轉(zhuǎn)發(fā),它使用SSH的能力在X11客戶端(想要顯示圖形信息的Python代碼)和X11服務(wù)器(能訪問物理顯示器并知道如何顯示這些圖形信息的軟件)之間構(gòu)建了一個X11通信隧道。

在X11架構(gòu)中,客戶端和服務(wù)器能被分離到不同的機器上。為了使用這個方法,需要:

1)一個運行在本地機器上的X11服務(wù)器。X11服務(wù)器是Linux上的標(biāo)準(zhǔn)組件(所有的桌面環(huán)境都使用X11)。在Windows機器上,可以使用第三方X11實現(xiàn),比如開源軟件VcXsrv(https://sourceforge.net/projects/vcxsrv/)。

2)通過SSH登錄遠(yuǎn)程機器的能力,傳入-X命令行選項:ssh -X servername。該命令會建立X11隧道,并允許所有在這個會話中啟動的程序訪問本地的顯示器輸出圖像。

然后,你就能啟動使用Monitor類的程序,它會捕獲智能體的動作,并保存成視頻文件。

主站蜘蛛池模板: 南通市| 霍州市| 延川县| 沾益县| 大同市| 名山县| 灵宝市| 营口市| 营山县| 宁德市| 丰镇市| 温泉县| 长沙县| 海淀区| 台北县| 绥江县| 汶上县| 定陶县| 株洲县| 麻江县| 东山县| 井研县| 嘉祥县| 三亚市| 台中市| 于田县| 三亚市| 广昌县| 南乐县| 利川市| 滦平县| 阿拉尔市| 岳普湖县| 壶关县| 来安县| 青岛市| 武穴市| 铁力市| 玛曲县| 泰来县| 固原市|