让我们从零开始做一个机械手臂(强化学习)

我有做过一个分享机器学习内容的网页, 叫做 莫烦Python, 最近有很多朋友在上面留言说想看看一些将学到的知识实践的教程, 于是我第一反应就是, 做一个强化学习的实战, 把这个"自己学习"的机器手臂给做出来. 于是我就在 这里 写下了自己制作机器手臂的全程直播. 哈哈. 但是 莫烦python 出了新教程是没有订阅提醒的, 看着我知乎上挺多粉丝的, 我就将自己网站上的 "机械手臂" 开篇 分享到知乎上.

并且提前告知大家 "从零开始制作机械手臂教程" 囊括的内容包括.

这篇知乎, 也就是以下内容是上面5节内容的第一节 "搭建结构". 接着的4节内容不会写在知乎里了(转起来麻烦). 有兴趣的朋友可以直接在上面的链接中查看.

为什么做这个实践

做这个实践的主要目的就是让我们活学活用, 从0开始搭建一个强化学习框架. 之前我们在强化学习系列教程中学习到了很多强化学习的知识, 了解了各种算法应该怎样运用, 从最简单的 Q-Learning 到结合神经网络的 DQN, 再到做连续动作的 DDPG 以及分布式训练的 A3CDPPO. 但是我们却没有真正意义上的实践过一次, 因为在那个系列中大多数时候我们只关注了算法本身. 但是搭建模拟环境, 调整参数也同样重要. 所以我们在这个系列中将会做到这些, 让你真正意义上入门了强化学习.

要做成怎样

这个实践很简单, 我使用的是我自己一年前编写的训练代码, 让机器人手臂学会到达某一个预设点.

不过这次, 我优化了代码结构, 将这个自己做过的练习给大家呈现一遍, 让你也能一步步知道在做强化学习的时候要考量些什么, 怎么样做一个合理的环境. 所以我将从下面几个方面来阐述这些.

代码主结构

在做每一个强化学习的时候, 我们最好先规划好要怎么分解这一个 task. 一般来说我们尽量不要把所有代码 (环境, 强化学习算法, 学习主循环) 放在一个脚本中. 拆分成三个脚本分开管理将会更有效率, 更加方便管理, 而且眼睛也不会花了. 这也是我在自己强化学习系列教程中一直给大家呈现的方式.

具体来说, 这三方面的脚本可以是这样:

  • 环境脚本 (env.py)
  • 强化学习脚本 (rl.py)
  • 主循环脚本 (main.py)

我们在主循环脚本中将会 import 环境和强化学习方法, 所以主循环脚本将上面两者给串联了起来. 如果你看到这次教学的 代码, 你会发现我将每一步分别打包, part1, part2… 中都有上述三个脚本文件. 我们将在每个 part 中一一添加必要的部分.

这一节, 我们从最基本的 main.py 开始说. 这里涉及了程序的主循环, 也是学习的部分. 怎个学习的框架可以被简化成下面这样, 我采取了 gym 模块的形式. 所以如果使用过 gym 的朋友, 你会发现无比的熟悉.

# main.py 
# 导入环境和学习方法 
from part1.env 
import ArmEnv 
from part1.rl import DDPG 

# 设置全局变量 
MAX_EPISODES = 500 
MAX_EP_STEPS = 200 

# 设置环境 
env = ArmEnv() 
s_dim = env.state_dim 
a_dim = env.action_dim 
a_bound = env.action_bound 

# 设置学习方法 (这里使用 DDPG) 
rl = DDPG(a_dim, s_dim, a_bound) 

# 开始训练 
for i in range(MAX_EPISODES): 
    s = env.reset() # 初始化回合设置 
    for j in range(MAX_EP_STEPS): 
        env.render() # 环境的渲染 
        a = rl.choose_action(s) # RL 选择动作 
        s_, r, done = env.step(a) # 在环境中施加动作 
        
        # DDPG 这种强化学习需要存放记忆库 
        rl.store_transition(s, a, r, s_) 
        if rl.memory_full: 
            rl.learn() # 记忆库满了, 开始学习 
        s = s_ # 变为下一回合
复制代码

写到这个时候, 我们明白了, 在 rl.py 和 env.py 中, 我们必须有这样几个 function 和 attribute.

  • rl.py
    • rl.choose_action(s)
    • rl.store_transition(s, a, r, s_)
    • rl.learn()
    • rl.memory_full
  • env.py
    • env.reset()
    • env.render()
    • env.step(a)
    • env.state_dim
    • env.action_dim
    • env.action_bound

有了这些准则, 我们就能在 rl.py 和 env.py 中进行前期规划了. 所以你可以另外创建一个 env.py 的脚本, 先写好下面这个 ArmEnv 的 class. 然后给他加上上面提到的功能.

# env.py

class ArmEnv(object):
    def __init__(self):
        pass
    def step(self, action):
        pass
    def reset(self):
        pass
    def render(self):
        pass
复制代码

然后再创建一个 rl.py 脚本, 用来存放你要使用的 RL 的方法. 因为我想要将这个手臂环境设置成一个连续动作的环境(机器人旋转手臂时的角度是一个连续值), 所以我会选用 DDPG 的算法. 但是如果你想设置的环境是一个离散动作(比如机器人只能选上下左右4个键), 你可能需要选择不同的 RL 算法, 对环境也要有不同的应对方式.

# rl.py

class DDPG(object):
    def __init__(self, a_dim, s_dim, a_bound,):
        pass
    def choose_action(self, s):
        pass
    def learn(self):
        pass
    def store_transition(self, s, a, r, s_):
        pass 
复制代码

有了这些框架, 我们的主结构就大功告成了, 接着我们就开始继续往下面添砖加瓦吧. 看看如何搭建一个模拟环境.

实战:从头开始搭建训练机器人手臂

猜你喜欢

转载自juejin.im/post/6844903518172626958