【强化学习-蘑菇书-2】通过具体的例子来学习如何与 Gym 库进行交互——小车上山(MountainCar-v0)
欢迎去各大电商平台选购纸质版蘑菇书《Easy RL:强化学习教程》
文章是根据 蘑菇书EasyRL 以及新版本的gym编写的可运行代码和示例,
0.安装环境,
文章所使用的python版本为py310
库版本如下
cloudpickle==3.1.1
Farama-Notifications==0.0.4
gym-notices==0.0.8
gymnasium==1.1.1
numpy==2.2.4
pygame==2.6.1
typing_extensions==4.13.2
效果:
代码:
import gymnasium as gym
import numpy as np
class SimpleAgent:
def __init__(self, env):
pass
def decide(self, observation): # 决策
position, velocity = observation
lb = min(-0.09 * (position + 0.25) ** 2 + 0.03, 0.3 * (position + 0.9) ** 4 - 0.008)
ub = -0.07 * (position + 0.38) ** 2 + 0.07
if lb < velocity < ub:
action = 2
else:
action = 0
return action # 返回动作
def learn(self, *args): # 学习
pass
def play(env, agent, seed_id,train=False):
episode_reward = 0. # 记录回合总奖励,初始值为0
observation, info = env.reset(seed=seed_id) # 重置游戏环境,开始新回合
while True: # 不断循环,直到回合结束
action = agent.decide(observation)
observation, reward, terminated, truncated, info= env.step(action) # 执行动作
episode_over = terminated or truncated # 是否结束
episode_reward += reward # 收集回合奖励
if train: # 判断是否训练智能体
agent.learn(observation, action, reward, episode_over) # 学习,这里是空的
if episode_over: # 回合结束,跳出循环
observation, info = env.reset(seed=seed_id) # 游戏失败了,重设环境
break
return episode_reward # 返回回合总奖励
if __name__ == '__main__':
SEED_ID = 3
env = gym.make("MountainCar-v0", render_mode="human")
print('观测空间 = {}'.format(env.observation_space))
print('动作空间 = {}'.format(env.action_space))
print('观测范围 = {} ~ {}'.format(env.observation_space.low,
env.observation_space.high))
print('动作数 = {}'.format(env.action_space.n))
agent = SimpleAgent(env)
episode_reward = play(env, agent,SEED_ID)
print('回合奖励 = {}'.format(episode_reward))
episode_rewards = [play(env, agent,SEED_ID) for _ in range(100)]
print('平均回合奖励 = {}'.format(np.mean(episode_rewards)))
env.close() # 关闭图形界面
输出:
SimpleAgent 类对应策略的平均回合奖励在 110 左右,而对于小车上山任务,只要连续 100 个回合的平均回合奖励大于 110,就可以认为该任务被解决了
测试智能体在 Gym 库中某个任务的性能时,出于习惯使然,学术界一般最关心 100 个回合的平均回合奖励。
对于有些任务,还会指定一个参考的回合奖励值,当连续 100 个回合的奖励大于指定的值时,则认为该任务被解决了。而对于没有指定的参考的回合奖励值的任务,就无所谓任务被解决了或没有被解决。
对 Gym 库的用法进行总结:
使用 env=gym.make(环境名)取出环境,使用 env.reset()初始化环境,使用 env.step(动作)执行一步环境,使用 env.render()显示环境,使用 env.close()关闭环境.