感慨多年后回到csdn已经变成了算法开发者,这些年都经历了什么。
玛丽奥作为一代人的童年,陪伴了我们的成长。
如今随着深度强化学习等技术的发展,越来越多的游戏正在被AI征服,那么今天我们一起来从0开始,试着征服超级玛丽吧!
安装超级玛丽软件包,gym_super_mario_bros这个包已经帮我们把游戏的rom封装好了常用的python接口:
root# pip install gym gym_super_mario_bros
用python代码控制马里奥执行随机动作
import gym_super_mario_bros
from gym import wrappers
env = wrappers.Monitor(env,"./gym-results", force=True)
#执行5000个简单的向右随机操作
done = True #游戏结束标志
for step in range(5000):
if done:
#如果游戏结束则重置:
state = env.reset()
state, reward, done, info = env.step(env.action_space.sample())
# 关闭创建的游戏env
env.close()
然后查看./gym-results文件夹下的mp4文件 即为上面代码执行的过程录像。
tips: 也可以在下面网页上直接尝试运行上面代码并可视化运行效果。
https://colab.research.google.com/drive/1ULu0t__0LPl5oI528oNvoOhs50XTZ2Nf?usp=sharing
get_action = load_pytorch_policy(args.fpath)
o, r, d, ep_ret, ep_len, n = env.reset(), 0, False, 0, 0, 0
hidden = (torch.zeros((1, 512), dtype=torch.float).to(device), torch.zeros((1, 512), dtype=torch.float).to(device))
while n < num_episodes:
if render:
env.render()
time.sleep(1e-3)
a, hidden = get_action(o, hidden)
o, r, d, _ = env.step(a.numpy().item())
ep_ret += r
ep_len += 1
if d or (ep_len == max_ep_len):
print('Episode %d \t EpRet %.3f \t EpLen %d' % (n, ep_ret, ep_len))
o, r, d, ep_ret, ep_len = env.reset(), 0, False, 0, 0
hidden=(torch.zeros((1, 512), dtype=torch.float).to(device), torch.zeros((1, 512), dtype=torch.float).to(device))
n += 1
tips: 使用docker 直接运行:
docker run --gpus all -v /tmp/.X11-unix:/tmp/.X11-unix registry.cn-shanghai.aliyuncs.com/tcc-public/super-mario-ppo:localdisplay
如果不会使用docker的话,也可以下载项目源码,自己动手运行(GitHub:https://github.com/gaoxiaos/Supermariobros-PPO-pytorch)
![](https://img-blog.csdnimg.cn/img_convert/39cc981716b7bbddb33d9de8cbb77d94.gif#align=left&display=inline&height=236&margin=[object Object]&originHeight=236&originWidth=254&size=0&status=done&style=none&width=254)
强化学习的思想在生活中很常见,核心思想就是通过不断的尝试来让自己学会某件事情,因此强化学习的方法大致分为两类(value-base 和 Policy-base)
顾名思义,value-base就是“以价值为导向”的优化方法,比如游戏中在某个状态下执行不同的action得到不同的价值“value”,我们向着value高的方向去优化,那么最终就可以得到一个“每次都大概率选择最高价值的动作执行”的模型。
同样的字面意思,policy-base则是“以策略为导向”的优化方法,agent每次选择action时都以当前策略模型比优化前“好多少”为优化方向,“好多少”也有可能是负数(惩罚优化),好的越多那么优化权重(力度)就越大。在很多连续动作空间问题上policy-base方法经常使用,比如本文用到的ppo(近端策略优化)算法就是policy-base方法。
ppo作为强化学习领域研究的benchmark ,往往代表了当前强化学习在待研究场景下达到的基准最好状态。然后在此基础上研究能够超过ppo基准的优化方法。所以熟练掌握ppo是我们当前想要在强化学习做算法研究的必备技能之一。
ppo全名Proximal Policy Optimization,翻译过来“近端策略优化”,策略优化的思想就是上面policy-base方法,而“近端”,也就是“限制新旧策略更新幅度,保证新旧策略要在相近状态”,这样可以保障模型策略更新稳定收敛,否则可能会出现严重抖动难以收敛等问题。
目前网上常见的主要有baselines版、spiningup、莫烦版本、rllib、天授等,每个在实现方式上都不太一样,导致初学者往往会对工程实现上有很多迷惑,比如有的版本Actor和Critic是分离的而有的是共用的,loss计算有的是分开单独做梯度优化的也有的是加在一起做梯度优化,还有“近端约束”有的计算kl散度约束有的直接clip到固定范围,但其实这些不同的实现方式也都在常规的gym环境下达到了很好的效果,所以很长一段时间并没有论文证明ac共享权重好还是分开优化更好,直到今年procgen的发布(procgen旨在解决以往强化学习对环境的记忆>泛化能力而开发的动态环境benchmark),openai对比了不同的工程实现方式,并提出了ppg算法方法,其实就是ac分开优化的同时,增加辅助阶段,用于ac之间共享权重,所以整体来说ac分离与否各有优缺点。所以本文的代码实现为了顺应ppg的发展,将ac分开设计独立优化,构建简化版本方便初学者理解,这样到学习ppg时则仅需在此基础上添加辅助阶段即可。
今天只是借助超级玛丽做简单的入门初体验,如果你觉得这样的形式对你有用,可以查看完整版强化学习训练营(https://tianchi.aliyun.com/specials/promotion/aicamprl),也欢迎入群(添加wx:Z011668)和其他同样的小伙伴交流学习,后续会有更多项目实践文章或视频。
如果你并不满足现状,想做一些超神操作通关所有关卡(目前ppo通关超级玛丽最高记录是29/32,剩余未通关的是4-4、7-4和8-4,因为这几关不仅考验类似走迷宫的能力还要有严谨的进退策略,所以单靠ppo是非常难的),这里给你提供一些参考路径
在某些特别难的关卡现有gym_super_mario_bros抽取出来的游戏环境(状态、action等)不能满足你的需求,这个时候你可以自己添加,其实类似gym_super_mario_bros这样的包或者openai的retro把游戏转化为代码可操作的rl-env都是通过py虚拟机加载游戏RAM,然后针对这个游戏解析RAM的按键(寄存器)地址、状态地址等,比如retro已经解析支持常见的千种游戏解析(但是需要自己添加游戏ram,这里分享一个童年游戏ram集散地:http://www.atarimania.com/)
那么我们想要获得更多的信息,就可以通过查询寄存器地址,自己添加字段来获取信息或执行特殊技能,如超级玛丽部分寄存器地址:
![image.png](https://img-blog.csdnimg.cn/img_convert/60a222e90ad12cfde75b3b85c2285404.png#align=left&display=inline&height=506&margin=[object Object]&name=image.png&originHeight=1013&originWidth=1492&size=338627&status=done&style=none&width=746)
经过上面的探索,你会发现ppo的不同实现方式会有不同的表现,且各有优缺点,比如ac加在一起做loss优化时两者的权重很难定义有可能训练过程中会相互干扰,带来负面的影响,而不共享权重则在复杂的环境下很难训练导致难以收敛,所以在尝试不同的工程效果之后,可以升级ppo算法为ppg(Phasic Policy Gradient),兼顾独立优化的好处外增加一个阶段用于ac间共享权重。官方源码(https://github.com/openai/phasic-policy-gradient)对初学者可读性较差,添加(wx:Z011668)后续为大家分享ppg简化版本代码。