OpenAI 多智慧體強化學習環境(multiagent-particle-envs)詳解
multiagent-particle-envs是OpenAI開源的多智慧體學習環境。
一、安裝
Link:https://github.com/openai/multiagent-particle-envs
簡稱小球環境,也是MADDPG用的環境,基本上可以看做是較為複雜的 gridworld 的環境。 在這個環境涵蓋了ma裡的競爭/協作/通訊場景,你可以根據你的需要設定agent的數量,選擇他們要完成的任務,比如合作進行相互抓捕,碰撞等,你也可以繼承某一個環境來改寫自己的任務。狀態資訊主要包括智慧體的座標/方向/速度等,這些小球的的原始動作空間是連續型的,不過在類屬性裡有個可以強制進行離散的設定,可以把它開啟以後小球的動作就可以被離散為幾個方向的移動了。此外,在這個環境中,小球之間的碰撞都都是模擬剛體的實際碰撞,通過計算動量,受力等來計算速度和位移。(以上內容摘自:https://www.zhihu.com/question/332942236/answer/1295507780,作者:鹹魚天,來源:知乎)。
Link:https://github.com/gingkg/multiagent-particle-envs
安裝: 1、下載檔案 2、cdmultiagent-particle-envs 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環境僅作驗證環境是否安裝成功的測試使用,其餘環境的介紹可以自行檢視文件。1、各類實體屬性:
捕食者:剛體,可移動,最大速度1(預設),加速度縮放係數3(預設,疑似),速度阻尼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,即環境永遠不會結束,所以需要自己設定最大迴圈次數。