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

2.3 OpenAI Gym API

OpenAI(www.openai.com)開發并維護了名為Gym的Python庫。Gym的主要目的是使用統一的接口來提供豐富的RL環境。所以這個庫的核心類是稱為Env的環境也就不足為奇了。此類的實例暴露了幾個方法和字段,以提供和其功能相關的必要信息。在較高層次上,每個環境都提供了下列信息和功能:

  • 在環境中允許執行的一系列動作。Gym同時支持離散動作和連續動作,以及它們的組合。
  • 環境給智能體提供的觀察的形狀[1]和邊界。
  • 用來執行動作的step方法,它會返回當前的觀察、獎勵以及片段是否結束的指示。
  • reset方法會將環境初始化成最初狀態并返回第一個觀察。

是時候詳細討論一下環境的各個組件了。

2.3.1 動作空間

如前所述,智能體執行的動作可以是離散的、連續的,或兩者的組合。離散動作是智能體可以執行的一組固定的操作,比如,網格中的方向移動:向左、向右、向上或向下。另一個例子是按鍵,可以是按下去或釋放。這些狀態都是互斥的,因為離散動作空間的主要特征就是在有限的動作集合中,只能選擇一個動作執行。

連續動作會附上一個數值,例如控制方向盤,它能轉到特定的角度,再比如油門踏板,它能用不同的力度踩壓。連續動作會有一個數值范圍限制的描述。在控制方向盤的場景下,范圍限制為–720°~720°。油門踏板則通常是0~1。

當然,我們并沒有限制說只能執行一個動作。在環境中可以同時執行多個動作,例如同時按下好幾個按鈕,或者控制方向盤的同時踩兩個踏板(剎車和油門)。為了支持這樣的場景,Gym定義了一個特殊的容器類,允許用戶嵌入好幾個動作組成一個組合動作。

2.3.2 觀察空間

如第1章所述,觀察是除了獎勵之外,環境在每一時刻提供給智能體的信息。觀察可以簡單如一串數字,也可以復雜如包含來自多個攝像機彩色圖像的多維張量。觀察甚至可以像動作空間一樣是離散的。離散觀察空間的一個例子是燈泡,它可以處于兩種狀態——開或關,以布爾值的形式提供給我們。

因此,動作和觀察之間存在某種相似性,圖2.1展示了它們的類如何在Gym中表示。

041-01

圖2.1 Gym中Space類的層級

最基本的抽象類Space包含兩個我們關心的方法:

  • sample():從該空間中返回隨機樣本。
  • contains(x):校驗參數x是否屬于空間。

兩個方法都是抽象方法,會在每個Space的子類被重新實現:

  • Discrete類表示一個互斥的元素集,用數字0到n–1標記。它只有一個字段n,表示它包含的元素個數。例如,Discrete(n=4)表示動作空間有四個方向(上、下、左、右)可以移動。
  • Box類表示有理數的n維張量,范圍在[low, high]之間。例如,油門踏板只有一個0.0~1.0之間的值,它能被編碼成Box(low=0.0, high=1.0, shape=(1,), dtype=np.float32)shape參數被賦值成長度為1、值為1的元組,為我們提供了只有一個值的一個一維張量)。dtype參數指定空間的值類型,在此將其指定成NumPy 32-bit float。另一個Box的例子可以是Atari[2]屏幕的觀察(稍后將介紹更多Atari環境),它是一幅210×160的RGB(red, green, blue)圖像:Box(low=0, high=255, shape=(210, 160, 3), dtype=np.uint8)。在這個場景下,shape參數是有三個元素的元組,第一個維度是圖像的高,第二個維度是圖像的寬,第三個維度的值是3,它對應于三原色的紅綠藍。因此,總結來說,每個觀察都是一個有100 800字節的三維張量。
  • 最后一個Space的子類是Tuple類,它允許我們將不同的Space實例組合起來使用。這使我們能夠創建出任何動作空間和觀察空間。例如,想象一下我們要為汽車創建一個動作空間。汽車每時每刻有好幾個可以改變的控制手段,包括:方向盤的方向、剎車踏板的位置,以及油門踏板的位置。這三個控制手段能在一個Box實例中,用三個浮點數來指定。除了這三個最基本的控制手段,汽車還有一些額外的離散控制手段,例如轉向燈(可能的狀態是關閉、右、左)或喇叭(開或關)。為了將所有的這些組合到一個動作空間類中去,可以創建Tuple(spaces=(Box(low=-1.0, high=1.0, shape=(3,), dtype=np.float32), Discrete(n=3), Discrete(n=2)))。這樣過于靈活的用法很少見到,例如,在本書中,你只會看到BoxDiscrete的動作空間和觀察空間,但是Tuple類在某些場景下是很有用的。

Gym中還定義了一些其他的Space子類,但是前述的三個是最有用的。所有子類都實現了sample()contains()方法。sample()方法根據Space類以及傳入的參數進行隨機采樣。它常被用在動作空間,用來選取隨機的動作。contains()方法用來檢驗傳入的參數是否符合Space給定的可選參數,Gym內部會用它來檢驗智能體的動作是否合理。例如,Discrete.sample()返回一個范圍中的隨機離散元素,Box.sample()則會返回一個維度正確的隨機張量,張量的值都會在給定范圍內。

每個環境都有兩個類型為Space的成員:action_spaceobservation_space。這使得我們能夠創建適用于任何環境的通用代碼。當然,處理屏幕上的像素和處理離散的觀察會有所不同(例如前面那個例子,你可能更想用卷積層或其他計算機視覺的工具庫來處理圖像),大多時候,Gym并不會阻止我們去編寫通用的代碼,一般只有為特定的環境或一組環境優化代碼時才需要定制代碼。

2.3.3 環境

如上所述,在Gym中環境用Env類表示,它包含下面這些成員:

  • action_spaceSpace類的一個字段,限定了環境中允許執行的動作。
  • observation_space:也是Space類的一個字段,但是限定了環境中允許出現的觀察。
  • reset():將環境重置到初始狀態,返回一個初始觀察的向量。
  • step():這個方法允許智能體執行動作,并返回動作結果的信息——下一個觀察、立即獎勵以及片段是否結束的標記。這個方法有一點復雜,我們會在本節后面詳細討論。

Env類中還有一些我們不會用到的實用方法,例如render(),它允許我們獲得人類可讀形式的觀察。你可以在Gym的文檔中找到這些方法的完整列表,在本書中我們還是要集中關注Env的核心方法:reset()step()

到目前為止,你已經見過代碼如何獲取環境的動作和觀察信息,因此現在你需要熟悉動作本身了。通過stepreset可以和環境進行交互。

由于reset更加簡單,我們會從它開始。reset()方法沒有參數,它命令環境將自己重置成初始狀態,并返回初始觀察。注意,必須在環境創建后調用reset()。你應該還記得第1章中說的,智能體和環境的交互可能是會終止的(比如屏幕上顯示“游戲結束”)。這樣的一個時間段稱為片段,而智能體在片段結束后,需要重新開始。該方法返回的值是環境中的第一個觀察。

step()方法是環境的核心部分。它在一次調用中會完成多項操作,如下所示:

  • 告訴環境下一步將要執行哪一個動作。
  • 在執行動作后獲取該動作產生的新的觀察。
  • 獲取智能體在這一步獲得的獎勵。
  • 獲取片段是否結束的標記。

第一項(動作)是該方法的唯一參數,剩余幾項是step()方法的返回值。準確地說,這是一個包含4個元素(observation, reward, done, info)的元組(這是Python元組而不是前一節所討論的Tuple類)。它們的類型和意義如下:

  • observation:包含觀察數據的NumPy向量或矩陣。
  • reward:浮點數的獎勵值。
  • done:布爾值標記,如果是True則片段結束。
  • info:包含環境信息的任何東西,它和具體的環境有關。通常的做法是在通用RL方法中忽略這個值(不考慮和特定環境相關的一些細節信息)。

你可能從智能體的代碼中已經知道環境怎么用了——在環境中,我們會不停地指定動作來調用step()方法,直到方法返回的done標記為True。然后調用reset()方法重新開始。唯一遺漏的部分就是一開始如何創建Env對象。

2.3.4 創建環境

每個環境都有唯一的名字,形式為環境名-vN。N用來區分同一個環境的不同版本(例如,一些環境修復了bug或有重要的更新時會升級版本)。為了創建環境,gym包提供了函數make(env_name),它唯一的參數就是字符串形式的環境名。

在撰寫本文時,Gym的版本是0.13.1,包含859個不同名字的環境。當然,并不是有這么多獨立的環境,因為包含了環境的多個版本。此外,同樣的環境在不同的版本下設置或觀察空間可能會有變化。例如,Atari的Breakout游戲有這么多環境名字:

  • Breakout-v0、Breakout-v4:最原始的Breakout游戲,球的初始位置和方向是隨機的。
  • BreakoutDeterministic-v0、BreakoutDeterministic-v4:球的初始位置和速度矢量總是一樣的Breakout游戲。
  • BreakoutNoFrameskip-v0、BreakoutNoFrameskip-v4:每一幀都展示給智能體的Breakout游戲。
  • Breakout-ram-v0、Breakout-ram-v4:取代屏幕像素,用內存模擬(128字節)觀察的Breakout游戲。
  • Breakout-ramDeterministic-v0、Breakout-ramDeterministic-v4
  • Breakout-ramNoFrameskip-v0、Breakout-ramNoFrameskip-v4

總體而言,一共有12個Breakout游戲的環境。游戲的截圖如圖2.2所示(以防你從來沒有玩過)。

044-01

圖2.2 Breakout的游戲截圖

即使刪除了這些重復項,0.13.1版本的Gym仍提供了154個獨立環境,分成以下幾組:

  • 經典控制問題:這些是玩具任務,用于最優控制理論和RL論文的基準或演示。它們一般比較簡單,觀察空間和動作空間的維度比較低,但是在快速驗證算法的實現時它們還是比較有用的。將它們看作“RL”的“MNIST”(MNIST是Yann LeCun創建的手寫數字識別數據集,參見http://yann.lecun.com/exdb/mnist/)。
  • Atari 2600:來自20世紀70年代的經典游戲平臺上的游戲,一共有63個。
  • 算法:這些問題旨在執行小的計算任務,例如復制觀察到的序列或數字相加。
  • 棋盤游戲:圍棋和六角棋。
  • Box2D:這些環境使用了Box2D物理引擎來模擬學習走路或汽車的控制。
  • MuJoCo:另一個用于連續控制問題的物理模擬環境。
  • 參數調優:用于調優NN的參數的RL。
  • 玩具文本:簡單的網格世界文本環境。
  • PyGame:使用PyGame引擎實現的幾個環境。
  • Doom:基于ViZDoom實現的九個小游戲。

完整的環境列表可以在https://gym.openai.com/envs找到,也可以在項目GitHub倉庫的wiki頁面上找到。OpenAI Universe(目前已經被OpenAI廢棄)包含更大的環境集,它提供了一個通用的連接器,用于連接智能體和跑在虛擬機中的Flash、原生游戲、瀏覽器以及其他真實的應用。OpenAI Universe擴展了Gym的API,但是還遵循同樣的設計原則和范式。你可以訪問https://github.com/openai/universe來了解它。由于要處理MiniWoB和瀏覽器自動化,我們會在第13章中進一步使用Universe。

理論已足夠!是時候用Python來處理一種Gym環境了。

2.3.5 車擺系統

我們來應用學到的知識探索Gym提供的最簡單的RL環境。

045-01

這里,我們導入了gym庫,創建了一個叫作CartPole(車擺系統)的環境。該環境來自經典的控制問題,其目的是控制底部附有木棒的平臺(見圖2.3)。

045-02

圖2.3 車擺環境

這里的難點是,木棒會向左或向右倒,你需要在每一步,通過讓平臺往左或往右移動來保持平衡。

這個環境的觀察是4個浮點數,包含了木棒質點的x坐標、速度、與平臺的角度以及角速度的信息。當然,通過應用一些數學和物理知識,將這些數字轉換為動作來平衡木棒并不復雜,但問題是如何在不知道這些數字的確切含義、只知道獎勵的情況下,學會平衡該系統?這個環境每執行一步,獎勵都是1。片段會一直持續,直到木棒掉落為止,因此為了獲得更多的累積獎勵,我們需要以某種避免木棒掉落的方式平衡平臺。

這個問題看起來可能比較困難,但是在接下來的兩章中,我們會編寫一個算法,在無須了解所觀察的數字有什么含義的情況下,在幾分鐘內輕松解決CartPole問題。我們會通過反復試驗并加上一點RL魔術來做到這一點。

我們來繼續編寫代碼。

046-01

這里,先重置一下環境并獲得第一個觀察(在新創建環境時,總會重置一下它)。正如我所說,觀察結果是4個數字,我們來看一下如何提前知道這個信息。

046-02

action_space字段是Discrete類型,所以動作只會是0或1,其中0代表將平臺推向左邊,1代表推向右邊。觀察空間是Box(4,),這表示大小為4的向量,其值在[-inf, inf]區間內。

046-03

現在,通過執行動作0可以將平臺推向左邊,然后會獲得包含4個元素的元組:

  • 一個新的觀察,即包含4個數字的新向量。
  • 值為1.0的獎勵。
  • done的標記為False,表示片段還沒有結束,目前的狀態多少還是可以的。
  • 環境的額外信息,在這里是一個空的字典。

接下來,對action_spaceobservation_space調用Space類的sample()方法。

046-04

這個方法從底層空間返回一個隨機樣本,在Discrete動作空間的情況下,這意味著為0或1的隨機數,而對于觀察空間來說,這意味著包含4個數字的隨機向量。對觀察空間的隨機采樣看起來沒什么用,確實是這樣的,但是當不知道如何執行動作的時候,從動作空間進行采樣是有用的。在還不知道任何RL方法,卻仍然想試一下Gym環境的時候,這個方法尤其方便。現在你知道如何為CartPole環境實現第一個行為隨機的智能體了,我們來試一試吧!


[1]原文是shape,表示一個多維數組的形狀,比如二維數組[[1,2], [3,4]]的shape是(2,2)。——譯者注

[2]Atari是美國諾蘭·布什內爾在1972年成立的電腦公司,街機、家用電子游戲機和家用電腦的早期拓荒者。——譯者注

主站蜘蛛池模板: 个旧市| 临安市| 灵丘县| 资溪县| 清徐县| 兴文县| 桃江县| 康平县| 望江县| 嘉鱼县| 乌拉特前旗| 武清区| 车险| 勃利县| 永德县| 法库县| 南皮县| 大安市| 德兴市| 汕尾市| 孙吴县| 杨浦区| 大足县| 聂荣县| 庄浪县| 华阴市| 阿瓦提县| 朝阳区| 元氏县| 柯坪县| 延吉市| 万州区| 读书| 满城县| 遵化市| 邵阳市| 林周县| 乃东县| 罗定市| 镇赉县| 海晏县|