服务器无法调用gym中的render,采用Monitor保存视频的方法解决

Posted 躁动的风儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务器无法调用gym中的render,采用Monitor保存视频的方法解决相关的知识,希望对你有一定的参考价值。

问题

由于服务器上没有图形化界面,所以在调用gym中的render()函数时,会报错pyglet.canvas.xlib.NoSuchDisplayException: Cannot connect to "None"
思路是:把视频保存下来,下载到本地再看。

解决方案

直接调用gym.wrappers.Monitor把视频保存到本地
代码示例如下:

# test.py

import gym
from gym.wrappers import Monitor

outdir = 'video_record'
env = gym.make('MountainCar-v0')
env = Monitor(env, outdir, video_callable=lambda episode_id: True,  force=True) # 主要是修改这行代码,把env传递给Monitor函数
state = env.reset()
done = False
while not done:
    action = env.action_space.sample()
    state_next, reward, done, info = env.step(action)
env.close()

outdir为视频保存路径;video_callable表示多少个episode记录一次视频,可将True改为指定的episode数,只记录特定的episodeforce为是否覆盖之前的视频。

然后在终端输入:

xvfb-run -a -s "-screen 0 640x480x24" python test.py 

如果不适用xvfb运行的话,还是会报错

可能遇到的问题

当运行之后,发现视频无法打开,那是因为在源码中有一个bug,参考Fix video recording
gym/wrappers/monitoring/video_recorder.py源代码如下:

if frame.dtype != np.uint8:
	raise error.InvalidFrame("Your frame has data type , but we require uint8 (i.e. RGB values from 0-255).".format(frame.dtype))

	self.proc.stdin.write(frame.tobytes())

应该修改为:

if frame.dtype != np.uint8:
	raise error.InvalidFrame("Your frame has data type , but we require uint8 (i.e. RGB values from 0-255).".format(frame.dtype))

self.proc.stdin.write(frame.tobytes())

即:找到gym包的安装目录,把video_recorder.py中的self.proc.stdin.write(frame.tobytes())这一行代码放到if代码块外面来

总结

  • 调用Monitor保存录像
  • 要使用xvfb-run运行代码
  • 修改gym源码中的一个bug

参考资料

gym 搭建 RL 环境

gym调用

gym的调用遵从以下的顺序

  1. env = gym.make('x')
  2. observation = env.reset()
  3. for i in range(time_steps):
    env.render()
    action = policy(observation)
    observation, reward, done, info = env.step(action)
    if done:
    ……
    break
  4. env.close()

例程

例程是一个简单的策略,杆左斜车左移,右斜则右移。

import gym
import numpy as np
env = gym.make('CartPole-v0')
t_all = []
action_bef = 0
for i_episode in range(5):
    observation = env.reset()
    for t in range(100):
        env.render()
        cp, cv, pa, pv = observation
        if abs(pa)<= 0.1:
            action = 1 -action_bef
        elif pa >= 0:
            action = 1
        elif pa <= 0:
            action = 0
        observation, reward, done, info = env.step(action)
        action_bef = action
        if done:
            # print("Episode finished after {} timesteps".format(t+1))
            t_all.append(t)
            break
        if t ==99:
            t_all.append(0)
env.close()
print(t_all)
print(np.mean(t_all))


gym的搭建

gym的函数构成

一个完整的gym环境包括以下函数:类构建、初始化、

  • class Cartpoleenv(gym.env)
    • def __ init __(self):
    • def reset(self):
    • def seed(self, seed = None): return [seed]
    • def step(self, action): return self.state, reward, done, {}
    • def render(self, mode='human'): return self.viewer.render()
    • def close():

功能函数

  • 参数限位 vel = np.clip(vel, vel_min, vel_max)
  • action输入校验
    self.action_space.contains(action)

  • action和observation空间定义
    Discrete: 0,1,2
    low = np.array([min_0,min_1],dtype=np.float32)
    high = np.array([max_0,max_1],dtype=np.float32)

    self.action_space = spaces.Discrete(3)
    self.observation_space = spaces.Box(
    self.low, self.high, dtype=np.float32)

以上是关于服务器无法调用gym中的render,采用Monitor保存视频的方法解决的主要内容,如果未能解决你的问题,请参考以下文章

强化学习 --gym env.render()报错

jupyter lab中显示gym的游戏动图

python 笔记 :Gym库 (官方文档笔记)

强化学习笔记:Gym入门--从安装到第一个完整的代码示例

一旦上传到服务器,render() 调用中的 Django TypeError

Gym