2:pytorch深度强化学习落地:以打乒乓小游戏为例
前几天买的新书《深度强化学习落地指南》,今天收到了,迫不及待的阅读起来。作者将深度强化学习应用落地分为七步,1、需求分析;2、动作空间设计;3、状态空间设计;4、汇报函数设计;5、算法选择;6、训练调试;7、性能冲刺。读罢,深受启发,总想找个例子实践一下。
思来想去,记得小时候在掌机上玩过一个打乒乓球的小游戏:从上面以一个角度落下来一个小球,遇到屏幕边界后会反弹,底部有一个由方格组成的球拍,玩家移动球拍,接住球得分,接不住则游戏结束。于是,我就想,能不能设计一个神经网络,通过训练使这个智能体学会玩这个游戏?查了一下,网上的素材,尤其是算法方面的素材非常多,典型的如:
Deep Reinforcement Learning超简单入门项目 Pytorch实现接水果游戏AI
实现起来难度不大,于是决定按照《深度强化学习落地指南》这本书的指导,一步一步的实践利用pytorch实现深度强化学习的过程。
一、需求分析
一问是不是:打乒乓的小游戏,是一个典型的单智能体和环境交互的强化学习问题。乒乓球的状态随时间按一定规律运动,玩家每个时间间隔可以做出一个动作,每个动作有左、右两个选择。二问值不值:这个一个运算量要求不大的小例子,以学习和实践为主,主要是体验强化学习、深度学习落地的过程。三问能不能:场景固定、数据廉价。四问边界在哪里:这样一个简单的问题,不存在模块划分的问题,主要决策也只有控制动作这一个问题。
二、动作空间设计
动作空间在事实上决定了任何算法所能达到的性能上限:对于打乒乓这个小游戏而言,动作就两个,移动底下的球拍,朝左运动或者朝右运动。这是一个离散的取值,分别定义为0和1。
三、状态空间设计
状态信息代表了Agent所感知的环境信息及其动态变化:对于打乒乓这个小游戏而言,完整的状态信息就是以像素为代表的整个方格。在这里,我们采用留空式空间编码,可以参考用10*8的一个矩阵来表示,前面9层代表球落的空间,最后一层用3个连续的1代表球拍的位置。如下图所示:
四、回报函数设计
回报信号是人与算法沟通的桥梁:对于打乒乓这个小游戏,回报就是要让底下的三个球拍接住落下来的小球,接住得1分,接不住扣1分。
读到这里,我们就可以开始动手编程了。结合前面写的面向对象编程,我们可以设计一个PingpongEnv类,在这个类里面,我们要首先定义reset方法,用来初始化状态空间和球拍的位置。接着,定义个step方法,用来定义当输入一个动作之后,对状态空间的变化。然后,通过判断球落地还是落到拍子上,确定本次移动的回报值。
class PingpongEnv:
def __init__(self):
self.reset()
def reset(self):
game = np.zeros((10,8))
game[9,3:6] = 1.
self.state = game
self.t = 0
self.done = False
return self.state[np.newaxis,:].copy()
def step(self, action):
reward = 0.
game = self.state
if self.done:
print('Call step after env is done')
if self.t==200:
self.done = True
return game[np.newaxis,:].copy(),10,self.done
# 根据action移动盘子
if action == 0 and game[9][0]!=1:
game[9][0:7] = game[9][1:8].copy()#向左移动
game[9][7] = 0
elif action == 1 and game[9][7]!=1:
game[9