Open AI Gym教程(7): Gym 内置二维图形渲染系统

我们使用Open AI Gym 来测试人工智能或是机器学习的算法。尽管Gym以及Gym retro提供了数以千计的环境可供测试。但我们实际的问题总有gym没有提供的情形。因此Open AI Gym 通常有两种问题,一是如果把我们遇到的实际问题转化成Gym 场景,然后利用已有的Gym 机器学习的算法来解决实际问题二是如何选择和设计算法来解决Gym的场景。

我们很都人都玩过魔法,在没有完成三层之前,看到别人完成三层的时候,觉得好牛啊:-),实际情况并非如此。

实际上玩魔方,可能在完成第一层时,还可能需要动点脑筋,后面二层,三层基本上做为玩家来说,基本是套用口诀,判断当前魔方所处的状态,然后套用口诀,并没有任何智能可言。记得魔方所处的状态越多,恢复三层速度越快,这点和我们使用机器学习算法解决问题非常类似。

人工智能和机器学习目前是能够解决不少问题,当在实际应用时,可以除了少许研究人员来说,设计新的算法(类似于发现魔方新的口诀)还需要大量的脑力劳动,对于一般的应用开发。基本是也是套用现成的算法,判断下问题的性质,是supervised learning(监督学习),unsupervised learning(无监督学习) ,还是使用Reinforcement learning(强化学习)。可能在调整算法的超级参数(hyper parameters),还需要一些思考(就想玩魔方的第一层),后面基本也是套路。

机器学习的一个主要特点是无需事先设计好预定的算法,而是通过大量的数据来训练神经网络,而且很多时候数据量的多少可以弥补算法的不足,和我们常规的算法大不相同。

因此在解决实际问题时候,把问题构造成Open AI Gym场景相对显得更为重要,而且需要更多的”智能”。就像当初设计出魔方的人。

Gym的一个重要的方法是render,也就是显示出场景。可以是图像,内存(rgb_array)或是文字。

Gym的经典场景比如(cartpole),以及atari游戏的显示,Open AI Gym提供了一个比较简单的二维图形渲染系统,我们如果自定义场景也可以使用同样的图形系统作为显示:

gym.envs.classic_control.rendering

定义了这个图型系统,简单的说一个是矢量图像(Viewer),一个是光栅图像(SimpleImageViewer)显示,Atari游戏有自己的图像显示,因此直接使用SimpleImageViewer,显示图像imshow(image)。
Gym的经典场景使用矢量图像(Viewer),它提供一些简单的二维图像显示,比如点,线,面,坐标变换等:

下面的代码为CartPole的例子改写而来,旋转平衡杆720度。

from gym.envs.classic_control.rendering import *

length = 0.5

x_threshold = 2.4

screen_width = 600
screen_height = 400

world_width = x_threshold * 2
scale = screen_width / world_width
carty = 100  # TOP OF CART
polewidth = 10.0
polelen = scale * (2 * length)
cartwidth = 50.0
cartheight = 30.0

viewer = Viewer(screen_width, screen_height)

l, r, t, b = -cartwidth / 2, cartwidth / 2, cartheight / 2, -cartheight / 2
axleoffset = cartheight / 4.0
cart = FilledPolygon([(l, b), (l, t), (r, t), (r, b)])
carttrans = Transform()
cart.add_attr(carttrans)
viewer.add_geom(cart)
l, r, t, b = -polewidth / 2, polewidth / 2, polelen - polewidth / 2, -polewidth / 2
pole = FilledPolygon([(l, b), (l, t), (r, t), (r, b)])
pole.set_color(.8, .6, .4)
poletrans = Transform(translation=(0, axleoffset))
pole.add_attr(poletrans)
pole.add_attr(carttrans)
viewer.add_geom(pole)
axle = make_circle(polewidth / 2)
axle.add_attr(poletrans)
axle.add_attr(carttrans)
axle.set_color(.5, .5, .8)
viewer.add_geom(axle)
track = Line((0, carty), (screen_width, carty))
track.set_color(0, 0, 0)
viewer.add_geom(track)

l, r, t, b = -polewidth / 2, polewidth / 2, polelen - polewidth / 2, -polewidth / 2
pole.v = [(l, b), (l, t), (r, t), (r, b)]

cartx = screen_width / 2.0  # MIDDLE OF CART
carttrans.set_translation(cartx, carty)
poletrans.set_rotation(0)
rotate = 720

while rotate > 0:
    poletrans.set_rotation(rotate * math.pi / 180.0)
    rotate -= 1
    viewer.render()

viewer.close()

CartPole由Cart(Polygon),Pole(Polygon),Axis(Circle),Track(Line)构成,

这些简单的几何图像类型都是Geom 的子类,Geom可以定义几个属性,如颜色,线宽,坐标转换的Matrix(比如实现Pole的旋转)。Gym 图像显示是记忆pyglet(OpenGL)。如果你属性OpenGL,这些都是非常容易理解的。