文章目錄
- 前言
- 一、環境設計
- 二、動作設計
- 三、狀態設計
- 四、神經網路設計
- 五、效果展示
- 其他問題
- 總結
前言
本學期的大作業,要求完成多智能體PPO的乒乓球對抗環境,這里我使用IPPO的方法來實現。
正好之前做過這個單個PPO與pong環境內置的ai對抗的訓練,具體見:【游戲ai】從強化學習開始自學游戲ai-1非侵入式玩像素小鳥的第一部分。
想著這次做IPPO的自博弈,應該會好上手不少,但是實際情況,這個Pettingzoo里的環境,還是有些bug的,經過修改后,可以達到良好的效果。
效果見:
代碼見:FreeRL_for_play/tree/main/IPPO_for_pong (歡迎star)
一、環境設計
環境見:https://pettingzoo.farama.org/environments/atari/pong/
環境參數:
主要是這里
問題1:
在具體實現訓練中,(右邊是first_0,左邊是second_0),會出現first_0發完第一個球后,若是second_0沒有接到球,則會出現不發球的情況。
解決:
在具體的環境里,有發球這個動作,1:Fire,經過測試,這個發球是遵循環境的規則來發球,讓上一局贏的(得分+1)一方來發球。
于是設計每過200幀判斷當前的分數是否與上一個200幀的分數一致,若是一致,則發球,這樣可以避免上述的環境問題。
并且經過測試,即使雙方在膠著打乒乓時,互相擊球超過了200幀,此時分數沒有變化,此發球動作也不會影響兩者的擊球,即并不會突然停下來發球。
'''
| Action | Behavior |
|:---------:|-----------|
| 0 | No operation |
| 1 | Fire |
| 2 | Move right |
| 3 | Move left |
| 4 | Fire right |
| 5 | Fire left |'
'''
問題2:
此環境如規則所說,不是一個零和環境,在擊球時會出現擊球的一方-1,被擊球的一方0的獎勵,此獎勵在官方Atari
https://ale.farama.org/environments/pong/中也沒有設置此獎勵。
此獎勵或許會導致誤解,在擊球后,在一個準備接球的狀態時獲得一個-1獎勵,導致智能體學不好。
并且有此獎勵時,獎勵函數不會收斂到一個0和的狀態。
解決:
將此獎勵屏蔽掉。
當獎勵出現不是一個為1一個為-1時,將這個獎勵都置為0。
問題3:
當問題1被解決時,又迎來一個新問題,即在環境中出現了一步發球動作,此動作會調用env.step(),此時會導致一個大問題和一個小問題,小問題是:使得環境本身計算出的truncation不準確;大問題是:會偶爾出現剛好這一步之后這一步的truncation為True,所以之后就不應該再進行動作,否則就會出現無圖像的錯誤。
解決:
小問題:手動計算truncation邏輯,將發球的步數也加入在內。
大問題:判斷發球這步是否已結束,結束則跳過后面的動作,重新reset,不結束則繼續,這里有個點要注意一下:關于是否將這發球這步的狀態,動作,加入到經驗池里,我這里沒有加入,因為在動作設計上沒有發球這步,所有我并沒有添加。
最后環境的默認終止條件是一方達到21分時,則一方獲勝,此游戲結束,默認截斷條件是幀數達到100000(max_cycles=100000)時為截斷,為了實際訓練的速度的加快,這里將max_cycles設置為10000。
'''
class ParallelAtariEnv(ParallelEnv, EzPickle):def __init__(self,game,num_players,mode_num=None,seed=None,obs_type="rgb_image",full_action_space=False,env_name=None,max_cycles=100000,render_mode=None,auto_rom_install_path=None,):
'''
二、動作設計
同樣的,這里將動作設計和【游戲ai】從強化學習開始自學游戲ai-1非侵入式玩像素小鳥的第一部分一樣,將動作改成了二維動作,只有下述的2和3的動作。
'''
| Action | Behavior |
|:---------:|-----------|
| 0 | No operation |
| 1 | Fire |
| 2 | Move right |
| 3 | Move left |
| 4 | Fire right |
| 5 | Fire left |'
'''
三、狀態設計
狀態設計,和【游戲ai】從強化學習開始自學游戲ai-1非侵入式玩像素小鳥的第一部分一樣,
參考https://gist.github.com/karpathy/a4166c7fe253700972fcbc77e4ea32c5
裁剪三通道圖基本和參考代碼一致:
def prepro(image_in):image=image_in.copy() # 第1張圖image = image[35:185] # crop # 第2張圖image = image[::2,::2,0] # downsample by factor of 2 # 第3張圖image[image == 144] = 0 # 擦除背景 (background type 1) # 第4張圖image[image == 109] = 0 # 擦除背景image[image != 0] = 1 # 轉為灰度圖,除了黑色外其他都是白色 return image.astype(np.float32).ravel()
此裁剪展示參考代碼:【強化學習】玩轉Atari-Pong游戲
在背景為109的裁剪展示
背景為144的裁剪展示
參考代碼的狀態輸入:
第1幀為obs輸入全為0的圖,展成1維,將當前幀賦給上一幀
第2及之后的幀為obs輸入為當前幀減去上一幀的圖(展成1維),將當前幀賦給上一幀
效果展示為如下:
我的代碼的狀態輸入:
第1幀為obs輸入全為0的圖,展成1維,將當前幀賦給上一幀(第一幀)
第2及之后的幀為obs輸入為當前幀減去上一幀(此幀沒變一直為第一幀)的圖(展成1維)
這是我在實驗時,不小心忘記加入prev_x = cur_x
的結果
效果展示如下:
但是這個效果竟然比參考代碼的收斂效果好一點,于是就一直保留此狀態設計。
效果對比如下,5為參考代碼的效果,4為我的效果。
收斂時間上還是4快,
注:這里4我再測試一次是4.4h,應該是沒選擇用cpu訓練的緣故導致的7h。
四、神經網路設計
這里Actor和Critic網路還是沿用簡單的MLP設計,而沒有使用cnn網路的設計
具體見:【游戲ai】從強化學習開始自學游戲ai-1非侵入式玩像素小鳥的第一部分
原因:
使用cnn網路來訓練時,訓練的效果太慢了
效果如下:
9,15,17為cnn訓練,其余1,2,3,4,9為mlp訓練。
五、效果展示
訓練時,將兩個智能體的獎勵,終局分數,first智能體的勝率進行了保存。
由于這里將環境的截斷設置為10000,會有可能在兩者沒有決出勝負(一方達到21)的情況下進行截斷,所以將勝率設計如下:
## 計算勝率if episode_score[env_agents[0]] > episode_score[env_agents[1]]:win_list.append(1)elif episode_score[env_agents[0]] == episode_score[env_agents[1]]:win_list.append(0.5)else:win_list.append(0)win_rate = sum(win_list) / len(win_list) if len(win_list) < 100 else sum(win_list[-100:]) / 100
最終效果如下:
平滑后的獎勵曲線
平滑后的分數曲線
從上可以看到獎勵曲線,最終都收斂到了0附近,分數曲線收斂到了相近的分數附近,first智能體的勝率為50%左右。
這里分數曲線收斂到了10附近大概率是因為我環境的截斷設置為10000幀的緣故,如果加大這個數目,可能最終兩者都收斂到20附近,(21分獲勝)。
這也符合零和博弈應該的效果,大家都是50%的獲勝概率,50%的概率獲得1分。50%的概率丟一分,那么獎勵曲線就收斂到0附近了。
其他問題
問題:為什么使用常見意義上的MAPPO不能實現此自博弈訓練。
解決:
IPPO和MAPPO的區別
宏觀上 IPPO和MAPPO的區別就是critic的輸入不一樣,MAPPO的critic是global state信息,而IPPO的critic只有local obs。
微觀上 MAPPO的訓練邏輯是訓所有agent的reward 即 (+1 -1 ) +(-1 +1)+ (-1 +1) = 0
IPPO是各自訓自己的 (+1 -1 -1)(第一個和) (-1+1 +1)(第二個和)。
所以導致MAPPO只能用來合作環境,而IPPO既可以合作也可以博弈
老師說可以將MAPPO來當成一個PPO(智能體)來看,另外一個MAPPO當作對手智能體來看,可以這樣學。
這里沒有實現此想法,嘗試用IPPO來做自博弈。
問題:環境的安裝
解決:此環境的安裝在windows上不可行,在WSL上的linux下解決安裝問題
總結
此次項目需要很多前置經驗和知識,是一次難度很大的項目,但是也使我獲益良多,針對各種各樣的環境,強化學習的訓練難點有時即在算法的挑選上,又在環境的搭建上,又可能在獎勵的設計上,也有可能是狀態的挑選上,無論是哪個沒有做到位,都有可能導致項目的失敗。