本文介绍如何解决云端运行 Gym 环境时遇到的找不到显示器(NoSuchDisplayException)问题。
OpenAI Gym
OpenAI Gym 是一个用于开发强化学习算法的环境/任务的工具包,里面包括了多个小游戏环境,非常适合做强化学习实验。
本地执行 Gym
我们先在本地环境安装 Gym,然后启动赛车环境 CarRacing-v0
让它随机跑。
注意:运行 CarRacing-v0
换需要安装 box2d,可以使用 pip install 'gym[box2d]'
方式安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import gym env = gym.make('CarRacing-v0') env.reset()
for i in range(100): action = env.action_space.sample() observation, reward, done, info = env.step(action) env.render() print(f'Action: {action} Reward: {reward}') if done: break
env.close()
|
运行后会弹出一个窗口,并且开始渲染赛车环境。赛车会最多执行 100 步,每一步都是随机运动。
云端运行 Gym
接下来我们尝试在 Colab 执行以上代码。执行会有以下的错误提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Track generation: 1113..1395 -> 282-tiles track ------------------------------------------------------------------------permalink: rl_run_gym_on_online_jupyter_colab
--- NoSuchDisplayException Traceback (most recent call last) <ipython-input-2-1149edd96f39> in <module>() 1 import gym 2 env = gym.make('CarRacing-v0') ----> 3 env.reset() 4 5 for i in range(1000):
....
/usr/local/lib/python3.6/dist-packages/pyglet/canvas/xlib.py in __init__(self, name, x_screen) 84 self._display = xlib.XOpenDisplay(name) 85 if not self._display: ---> 86 raise NoSuchDisplayException('Cannot connect to "%s"' % name) 87 88 screen_count = xlib.XScreenCount(self._display)
NoSuchDisplayException: Cannot connect to "None"
|
错误是没有显示器,但是当我们在服务器/云端训练模型时没办法配备显示器。此时我们可以用 pyvirtualdisplay
框架虚拟一个显示器来运行 Gym 环境。
首先安装 pyvirtualdisplay 和需要的依赖。
1 2 3
| !apt-get install xvfb !pip install pyvirtualdisplay !pip install Pillow
|
安装完成后,先启动虚拟显示器。
1 2 3
| from pyvirtualdisplay import Display display = Display(visible=0, size=(1400, 900)) display.start()
|
接下来再执行上面代码就可以正常运行,可以看到 Action 和 Reward 输出,但是没有画面。因为网页是没办法弹出渲染弹窗。我们可以通过以下方式在 Jupyter 内可视化 Gym 环境。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import gym import time from IPython import display from PIL import Image
env = gym.make('CarRacing-v0') env.reset()
for i in range(100): action = env.action_space.sample() observation, reward, done, info = env.step(action) display.clear_output(wait=True) rgb_array = env.render(mode='rgb_array') img = Image.fromarray(rgb_array) display.display(img) time.sleep(0.01) print(f'Action {action} Reward {reward}') if done: break env.close()
|
执行后可以在 Jupyter 中看到图像输出,结果如下图。