强化学习与OpenAI Gym环境

机器学习领域,特别是强化学习这一分支,OpenAI Gym提供了一个用于开发和比较不同算法的工具包。它支持多种环境,包括经典的游戏、棋盘游戏、二维和三维物理模拟等,使得可以训练智能体、比较它们或开发新的机器学习算法(强化学习)。

OpenAI是一个人工智能研究公司,部分资金来自埃隆·马斯克。其明确的目标是推动和发展对人类有益的友好AI(而不是消灭人类)。

安装OpenAI Gym

本文将使用OpenAI gym,这是一个开发和比较强化学习算法的优秀工具包。它为学习智能体提供了许多交互环境。

在安装工具包之前,如果使用virtualenv创建了隔离环境,首先需要激活它:

$ cd $ML_PATH # 机器学习工作目录(例如,$HOME/ml) $ source my_env/bin/activate # 在Linux或MacOS上 $ .my_envScriptsactivate # 在Windows上

接下来,安装OpenAI Gym(如果不使用虚拟环境,需要添加--user选项,或者拥有管理员权限):

$ python3 -m pip install -U gym

根据系统,可能还需要安装Mesa OpenGL Utility(GLU)库(例如,在Ubuntu 18.04上需要运行apt install libglu1-mesa)。这个库将被需要来渲染第一个环境。

Python环境和库的准备

打开Python shell或Jupyter notebook或Google Colab,将首先导入所有必要的库,然后使用make()创建一个环境:

# Python ≥3.5是必需的 import sys assert sys.version_info >= (3, 5) # Scikit-Learn ≥0.20是必需的 import sklearn assert sklearn.__version__ >= "0.20"

确保TensorFlow ≥2.0是必需的:

import tensorflow as tf from tensorflow import keras assert tf.__version__ >= "2.0"

如果没有检测到GPU,卷积神经网络(CNNs)在没有GPU的情况下可能会非常慢。如果是在Colab上,可以更改运行时并选择GPU硬件加速器。

环境和观察

让列出所有可用的环境:

gym.envs.registry.all()

Cart-Pole是一个非常简单的环境,由一个可以左右移动的小车和一个垂直放置在其上的杆组成。智能体必须移动小车来保持杆的直立。

env = gym.make('CartPole-v1')

通过调用reset()方法初始化环境,这将返回一个观察结果:

env.seed(42) obs = env.reset()

观察结果因环境而异。在这种情况下,它是一个由4个浮点数组成的1D NumPy数组:它们代表小车的横向位置、速度、杆的角度(0 = 垂直)和角速度。

obs

环境可以通过调用其render()方法进行可视化,可以选择渲染模式(渲染选项取决于环境)。

env.render()

在这个例子中,将设置mode="rgb_array"以获取环境的图像作为一个NumPy数组:

img = env.render(mode="rgb_array") img.shape

(400, 600, 3)

与环境的交互

智能体需要从“动作空间”(可能的动作集合)中选择一个动作。让看看这个环境的动作空间是什么样的:

env.action_space

Discrete(2)意味着可能的动作是整数0和1,分别代表向左加速(0)或向右加速(1)。其他环境可能有更多的离散动作,或其他类型的动作(例如,连续的)。由于杆向右倾斜(obs[2] > 0),让向右加速小车:

action = 1 # 向右加速 obs, reward, done, info = env.step(action)

注意到小车现在正在向右移动(obs[1] > 0)。杆仍然向右倾斜(obs[2] > 0),但它的角速度现在是负的(obs[3] < 0),所以它可能会在下一步向左倾斜。

硬编码策略和结果分析

让硬编码一个简单的策略,当杆向左倾斜时向左加速,当杆向右倾斜时向右加速。将运行这个策略,看看它在500个episode中获得的平均奖励:

env.seed(42) def basic_policy(obs): angle = obs[2] return 0 if angle < 0 else 1

这个策略非常简单:当杆向左倾斜时,智能体将向左加速;当杆向右倾斜时,智能体将向右加速。将运行这个策略,并观察它在500个episode中获得的平均奖励。

totals = [] for episode in range(500): episode_rewards = 0 obs = env.reset() for step in range(200): action = basic_policy(obs) obs, reward, done, info = env.step(action) episode_rewards += reward if done: break totals.append(episode_rewards)

代码应该是自解释的。让看看结果:

np.mean(totals), np.std(totals), np.min(totals), np.max(totals)

(41.718, 8.858356280936096, 24.0, 68.0)

def update_scene(num, frames, patch): patch.set_data(frames[num]) return patch, def plot_animation(frames, repeat=False, interval=40): fig = plt.figure() patch = plt.imshow(frames[0]) plt.axis('off') anim = animation.FuncAnimation( fig, update_scene, fargs=(frames, patch), frames=len(frames), repeat=repeat, interval=interval) plt.close() return anim plot_animation(frames)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485