強化學習實戰:自定義Gym環境


新手的第一個強化學習示例一般都從Open Gym開始。在這些示例中,我們不斷地向環境施加動作,並得到觀測和獎勵,這也是Gym Env的基本用法:

state, reward, done, info = env.step(action)

 其中state是agent的觀測狀態,reward是采取了action之后環境返回的獎勵,done是判斷后繼狀態是否是終止狀態的flag,info是一些自定義的消息。

當后繼狀態是終止狀態時,需要重置環境,使之回到初始狀態:

env.reset()

如果我們要構建自己的強化學習問題該怎么辦呢?第一步就是自定義環境。接下來,我們就以以上兩個基本用法為目標,自定義一個Gym下的簡單環境:

S0 S1 S2
-1 -1 10

初始狀態S0,終止狀態S2,抵達狀態S0 S1 S2的獎勵分別為-1,-1和10,agent有向左和向右兩個動作。

步驟1:創建文件夾和文件

本人為了做深度學習,使用conda的環境管理功能創建了名為 pytorch1.1的環境,於是來到目錄:D:\Anaconda\envs\pytorch1.1\Lib\site-packages\gym\envs

創建文件夾 user ,用於專門存放自定義的環境,然后進入該目錄:D:\Anaconda\envs\pytorch1.1\Lib\site-packages\gym\envs\user,創建文件 __init__.py 和 basic_env.py。

當然,也可以直接在默認的root環境下操作。來到目錄:D:\Anaconda\Lib\site-packages\gym\envs,創建文件夾user,進入該目錄D:\Anaconda\Lib\site-packages\gym\envs\user,創建文件 __init__.py 和 basic_env.py。

步驟2:編寫 basic_env.py 和 __init__.py

basic_env是我們要寫的簡單環境示例的文件名,內容如下:

import gym
class BasicEnv(gym.Env):
    def __init__(self):    
        self.action_space = ['left', 'right'] # 動作空間
        self.state_space = ['s0', 's1', 's2'] # 狀態空間
        self.state_transition = { # 狀態轉移表
            's0': {'left':'s0', 'right':'s1'},
            's1': {'left':'s0', 'right':'s2'}
        }
        self.reward = {'s0':-1, 's1':-1, 's2':10} # 獎勵
        self.state = 's0'
            
    def step(self, action):
        next_state =  self.state_transition[self.state][action] # 通過兩個關鍵字查找狀態轉移表中的后繼狀態
        self.state = next_state
        reward = self.reward[next_state]
        if next_state == 's2':
            done = True
        else:
            done = False
        info = {}
        return next_state, reward, done, info
                           
    def reset(self):
        self.state = 's0'
        return self.state
    
    def render(self, mode='human'):
        draw = ['-' for i in range(len(self.state_space))]
        draw[self.state_space.index(self.state)] = 'o'
        draw = ''.join(draw)
        print(draw)

__init__.py是引入環境類的入口函數,寫入:

from gym.envs.user.basic_env import BasicEnv

步驟3:注冊環境

來到目錄:D:\Anaconda\envs\pytorch1.1\Lib\site-packages\gym,所有的環境都在__init__.py文件中注冊,打開這個文件,發現很多類似這樣的代碼:

# Toy Text
# ----------------------------------------

register(
    id="Blackjack-v1",
    entry_point="gym.envs.toy_text:BlackjackEnv",
    kwargs={"sab": True, "natural": False},
)

register(
    id="FrozenLake-v1",
    entry_point="gym.envs.toy_text:FrozenLakeEnv",
    kwargs={"map_name": "4x4"},
    max_episode_steps=100,
    reward_threshold=0.70,  # optimum = 0.74
)

register(
    id="FrozenLake8x8-v1",
    entry_point="gym.envs.toy_text:FrozenLakeEnv",
    kwargs={"map_name": "8x8"},
    max_episode_steps=200,
    reward_threshold=0.85,  # optimum = 0.91
)

模仿這個格式,我們添加自己的代碼,注冊自己的環境:

# User
# ----------------------------------------
register(
    id="BasicEnv-v0", # 環境名
    entry_point="gym.envs.user:BasicEnv", #接口
    reward_threshold=10, # 獎勵閾值
    max_episode_steps=10, # 最大步長
)

注冊了的環境,可以通過向gym的通用接口寫入環境名創建。除了環境名和接口兩個基本信息外,獎勵閾值和最大步長則是與訓練相關的參數,還可以自行添加其他參數。

步驟4:測試環境

在測試代碼中,我們設置了一個主循環,讓agent隨機選擇向左或向右,直到抵達終止狀態,或達到了在注冊環境中設置的最大步長max_episode_steps(實現方式是使得done = True),代碼如下:

import gym
import random
import time

from gym import envs
print(envs.registry.all()) # 查看所有已注冊的環境

env = gym.make('BasicEnv-v0')
env.reset() # 在第一次step前要先重置環境 不然會報錯
action_space = env.action_space
while True:
    action = random.choice(action_space) # 隨機動作
    state, reward, done, info = env.step(action)
    print('reward: %d' % reward)
    env.render()
    time.sleep(0.5)
    if done: break

 效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM