1. 程式人生 > 實用技巧 >OpenAI 多智慧體強化學習環境(multiagent-particle-envs)詳解

OpenAI 多智慧體強化學習環境(multiagent-particle-envs)詳解

multiagent-particle-envsOpenAI開源的多智慧體學習環境。


一、安裝

Link:

簡稱小球環境,也是MADDPG用的環境,基本上可以看做是較為複雜的 gridworld 的環境。 在這個環境涵蓋了ma裡的競爭/協作/通訊場景,你可以根據你的需要設定agent的數量,選擇他們要完成的任務,比如合作進行相互抓捕,碰撞等,你也可以繼承某一個環境來改寫自己的任務。狀態資訊主要包括智慧體的座標/方向/速度等,這些小球的的原始動作空間是連續型的,不過在類屬性裡有個可以強制進行離散的設定,可以把它開啟以後小球的動作就可以被離散為幾個方向的移動了。此外,在這個環境中,小球之間的碰撞都都是模擬剛體的實際碰撞,通過計算動量,受力等來計算速度和位移。(以上內容摘自:https://www.zhihu.com/question/332942236/answer/1295507780,作者:鹹魚天,來源:知乎)。

OpenAI官方的環境,需要依賴gym 0.10.5。 如果不想使用,可以使用我的修改版本,對gym版本沒有限制,並且在安裝後可以直接匯入make_env建立環境。參考百度飛槳開源的強化學習框架Parl為環境增加了obs_shape_n和act_shape_n屬性,可以直接輸出觀測和動作維數。
Link:https://github.com/gingkg/multiagent-particle-envs

安裝: 1、下載檔案 2、cd 3、pip install -e . 即可。

二、simple_world_comm環境詳解

multiagent-particle-envs基於gym開發,所以環境建立流程基本於gym一致。multiagent-particle-envs包含9個環境,分別為simple、simple_adversary、simple_crypto、simple_push、simple_reference、simple_speaker_listener、simple_spread、simple_tag、simple_world_comm。其中simple環境僅作驗證環境是否安裝成功的測試使用,其餘環境的介紹可以自行檢視文件。
下面就simple_world_comm環境進行詳細介紹。 simple_world_comm環境下,包含6個智慧體(agent),2個食物(food)、2個樹林(forests)和1個地標(landmarks)。6個智慧體中有4個捕食者(adversaries)和2個被捕食者(good_agents)。4個捕食者中有1個領導者(leader)。所有智慧體、食物、樹林和地標統稱實體(entity)。所有食物、樹林和地標又統稱地標(landmarks)。

1、各類實體屬性:

捕食者:剛體,可移動,最大速度1(預設),加速度縮放係數3(預設,疑似),速度阻尼0.25,紅色,其中領導者顏色較深一點,
被捕食者:剛體,可移動,最大速度1.3(預設),加速度縮放係數4(預設,疑似),速度阻尼0.25,小綠色 食物:剛體,不可移動,藍色 樹林:非剛體,不可移動,大綠色 地標:剛體,不可移動,黑色

2、實體任務:

捕食者:協同隊友,阻攔被捕食者靠近食物。

被捕食者:在捕食者的攔截下,利用森林及障礙物來儘可能的靠近食物。

食物:被捕食者的目標,靠近可獲得獎勵,獎勵大小與靠近的距離有關。

樹林:可以對進入自身內部的智慧體提供掩護,敵方無法獲取單位的位置座標,除非兩個智慧體位於同一個樹林

地標:不可通過的阻礙物。

3、需訓練的智慧體:

被捕食者:2個,通過靠近食物來獲取獎勵,速度較快,數量較少。

捕食者:4個,需要有一定協同能力,通過阻礙被捕食者獲取獎勵,速度較慢,但數量較多。

原論文中6個智慧體分別用MADDPG演算法來訓練。即訓練成本會隨著智慧體的數量增加,由於交流功能的存在,訓練成本和智慧體數量並不為線性關係。

4、觀測狀態

見檔案:multiagent-particle-envs/multiagent/scenarios/simple_world_comm.py

捕食者的觀測狀態為1*34的向量,具體為自身的速度(x和y兩個方向,2)+自身的位置(x和y兩個方向,2)+所有地標與自己的相對位置(地標位置-自身位置,10)+其他智慧體與自己的相對位置(其他智慧體位置-自身位置,10)+被捕食者的速度(4)+自身是否在樹林裡(2)+交流資訊(4),資料格式float32,Box(34,)。非領導者的交流資訊直接繼承領導者的。

array([ 0.        ,  0.        , -0.81360341,  0.31675768,  0.25026168,
       -0.12137332,  1.26442749, -0.7671077 ,  0.90388104, -1.00294841,
        0.70155893, -0.62365125,  1.09197528, -0.92503425,  1.31906775,
        0.53801265,  1.30256252, -0.5290839 ,  1.3105693 , -0.16847554,
        1.34816312, -0.82404067,  0.61383961, -1.30914401,  0.        ,
        0.        ,  0.        ,  0.        , -1.        , -1.        ,
        0.        ,  0.        ,  0.        ,  0.        ])
被捕食者的觀測狀態為1*28的向量,具體為自身的速度(x和y兩個方向,2)+自身的位置(x和y兩個方向,2)+所有地標與自己的相對位置(地標位置-自身位置,10)+其他智慧體與自己的相對位置(其他智慧體位置-自身位置,10)+其他被捕食者的速度(2)+自身是否在樹林裡(2),資料格式float32,Box(28,)。
array([ 0.        ,  0.        , -0.1997638 , -0.99238633, -0.36357793,
        1.18777069,  0.65058787,  0.54203631,  0.29004143,  0.3061956 ,
        0.08771932,  0.68549276,  0.47813566,  0.38410976, -0.61383961,
        1.30914401,  0.70522814,  1.84715666,  0.68872291,  0.78006011,
        0.69672969,  1.14066847,  0.        ,  0.        , -1.        ,
       -1.        ,  0.        ,  0.        ])

5、動作空間

領導者:MultiDiscrete2,1*9維的向量。第一位無操作,2-5位給定智慧體x,y正負方向上的加速度,6-9位為交流資訊。

np.array([0, 1, 0, 1, 0, 1, 1, 1, 1],dtype=np.float32)

非領導捕食者:Discrete(5),1*9維的向量。第一位無操作,2-5位給定智慧體x,y正負方向上的加速度。

np.array([0, 1, 0, 1, 0], dtype=np.float32)

舉個例子(無碰撞情況),方便理解,對於領導者初始狀態為:

[ 0.          0.          0.28664831  0.451448   -1.17817321 -1.14371152
  0.36545598 -1.0833245  -1.06284931  0.20773417 -0.94155189  0.4072022
 -0.10401275 -1.15910727 -0.19673305 -1.02704632 -0.78517681 -0.25047813
 -0.36542734 -1.31392343 -0.07968565 -0.96594893 -0.95037937 -1.2023333
  0.          0.          0.          0.         -1.         -1.
  0.          0.          0.          0.        ]

即,速度為(0,0);位置為(0.28664831, 0.451448)。

採取的動作為:

np.array([0, 1, 0, 1, 0, 1, 1, 1, 1],dtype=np.float32)

環境預設的週期t=0.1。

下一時刻智慧體的速度和位置計算過程如下(以x方向為例,y方向計算過程相同):
# x方向的加速度
a = 1 - 0
# 乘以比例係數(暫不清楚有何物理意義)
a = a * 3 
# 考慮速度阻尼,上一時刻的速度 v= 0
v = v * (1 - 0.25)
# 計算下一時刻的速度,此處有一個係數mass,預設為1(暫不清楚有何物理意義)
v = v + (a/mass) * t
# 判斷速度是否大於限定最大速度,如果大於,按最大速度在x,y方向上做分解
# 計算位置
p = p + v*t

下一時刻狀態輸出為:

[ 3.00000000e-01  3.00000000e-01  3.16648308e-01  4.81448005e-01
 -1.20817321e+00 -1.17371152e+00  3.35455977e-01 -1.11332450e+00
 -1.09284931e+00  1.77734173e-01 -9.71551887e-01  3.77202198e-01
 -1.34012753e-01 -1.18910727e+00 -1.26733049e-01 -1.05704632e+00
 -8.15176813e-01 -2.80478133e-01 -3.95427343e-01 -1.34392343e+00
 -1.09685649e-01 -9.95948925e-01 -9.70904003e-01 -1.23477175e+00
  5.26459117e-08  2.74805581e-08  9.47537011e-02 -2.43844654e-02
 -1.00000000e+00 -1.00000000e+00  1.00000000e+00  1.00000000e+00
  1.00000000e+00  1.00000000e+00]

6、建立、執行、顯示環境的完整程式碼

import time
import numpy as np
import multiagent.make_env as make_env

env = make_env.make_env('simple_world_comm')
obs = env.reset()
print(env.observation_space)
print(env.action_space)

steps = 0
print(steps)
print(obs)

for _ in range(25):
    steps += 1
    print(steps)
    action_n = [np.array([0, 1, 0, 1, 0, 1, 1, 1, 1],dtype=np.float32),
                np.array([0, 10, 0, 0, 0], dtype=np.float32),
                np.array([0, 0, 0, 0, 0], dtype=np.float32),
                np.array([0, 0, 0, 0, 0], dtype=np.float32),
                np.array([0, 0, 0, 0, 0], dtype=np.float32),
                np.array([0, 0, 0, 0, 0], dtype=np.float32)]
    next_obs_n, reward_n, done_n, _ = env.step(action_n)
    print(next_obs_n)
    print(reward_n)
    print(done_n)
    env.render()
    time.sleep(0.1)
    if all(done_n):
        break

env.close()

需要注意的是,按照環境預設設定,done_n永遠為 false,即環境永遠不會結束,所以需要自己設定最大迴圈次數。