前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >构建你的强化学习AI智能体(微信“跳一跳”)

构建你的强化学习AI智能体(微信“跳一跳”)

作者头像
算法一只狗
发布2022-11-04 11:34:55
8110
发布2022-11-04 11:34:55
举报
文章被收录于专栏:算法一只狗

最近在学习一些关于强化学习的知识。当然仅仅学习理论知识还是不够的,还是需要从实际案例上进行出发,利用强化学习搭建自己的AI智能体。

一般来说,强化学习第一个案例都是用“cartpole”,也即是在一个平衡木上保持木杆不下落:

但是这个案例一般离我们生活比较远,因此本入门案例使用了微信“跳一跳”作为强化学习的目标。

在本案例中,大体框架如下:

  • 实现“跳一跳”环境交互
  • 实现强化学习算法DDPG,用来构建AI智能体

1.背景知识

首先简要介绍一下强化学习和DDPG算法的一些背景知识。

强化学习不同于传统的有监督学习,它本身没有有标签数据进行学习,只能通过不断的试错,来提升自己。在试错的过程中,就需要不断的与环境进行交互:也就是不断的在环境中做出动作,从而得到相应的反馈和奖励。

基础要素定义

1

Part.1

基础要素定义

首先定义强化学习的几个要素:

  • 环境状态集
  • 动作集
  • 即时奖励
  • 衰减因子
  • 状态转移概率
  • 给定策略 π
  • 评估该策略的状态价值函数 π

最后标记为: 。也即是说,在当前状态 下,智能体给出最适合的动作 , 表示在当前状态下转移到下一个状态的概率,得到对应的奖励 ,最后评估这个策略。而 表示折损因素。

1

Part.2

DDPG算法

DDPG算法本质上是Actor-critic算法的扩展。因此先引入Actor-critic算法

  • Actor网络:给定当前环境状态 ,输出要执行的动作
  • Critic网络:在当前的环境状态 下,评估Actor网络输出的动作 的价值情况,得到价值函数

那接下来就很简单了,Actor和Critic网络可以用我们平常的神经网络进行构造。具体的算法步骤,可以再单独出一期介绍一下。

2.“跳一跳”AI智能体

要构造智能体,首先需要构造环境。在这个案例下,我们可以定义对应的要素:

  • 环境状态 :可以把当前跳一跳的图片进行截图,然后作为状态环境输入
  • 动作 :按压时间
  • 奖励 :这里设置比较简单,如果能够成功跳到下一个位置,则“+1”,否则为“-1
  • main.py:训练智能体主函数入口
  • GetEnv.py:构造智能体环境
  • DDPG.py:强化学习DDPG算法

2

Part.1

智能体环境

这里使用电脑版本的“跳一跳”小程序,这样我们就可以操作鼠标进行游戏。

在python中安装如下几个包:

代码语言:javascript
复制
pyautogui:控制鼠标
win32com:对电脑进行截图
win32gui:对电脑进行截图
cv2:把图片进行灰度化
PIL:剪裁图片

截屏函数:

代码语言:javascript
复制
 def screen_pic(self, promgram_name, jpg_file, jpg_file2):
        """
        截屏窗口图
        """
        hWnd = win32gui.FindWindow(None, promgram_name) #窗口的类名可以用Visual Studio的SPY++工具获取
        # 设置窗口在最前面
        self.set_foreground(hWnd)
        left, top, right, bot = win32gui.GetWindowRect(hWnd)
        # print(right,left, bot,top)
        self.left = left
        self.top = top
        self.right = right
        self.bot = bot
        self.tiao_x = (right + left) // 2
        self.tiao_y = (bot + top) // 2

        # 截屏
        img = pyautogui.screenshot(region=None) # x,y,w,h
        img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
        cv2.imwrite(jpg_file, img)

        # 识别“点击开始游戏”位置
        self.start_x, self.stat_y = self._find_start_btn(jpg_file, self.start_btn_img)
        pyautogui.click(x=self.start_x, y=self.stat_y, duration=0.25)

        time.sleep(1)

        # 重新截屏
        img = pyautogui.screenshot(region=None) # x,y,w,h
        img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
        cv2.imwrite(jpg_file, img)

        # 剪裁
        rangle = (int(left) * pingmu_suofang, int(top) * pingmu_suofang, int(right) * pingmu_suofang, int(bot) * pingmu_suofang)

        img = Image.open(jpg_file)
        jpg = img.convert('RGB')
        jpg = img.crop(rangle)
        jpg.save(jpg_file2)

重启游戏:

观察游戏是否失败,首先可以看到失败之后,会出现下面这个图标:

我们把图标保存后,然后利用cv2.matchTemplate查找相似的图标,如果找到则进行点击返回主页面:

代码语言:javascript
复制
def _find_start_btn(self, screen_shot_im, find_shot_im):
    """
    找到开始游戏位置的图标
    """
    screen_shot_im = cv2.imread(screen_shot_im, cv2.IMREAD_GRAYSCALE)
    result = cv2.matchTemplate(screen_shot_im,
                               find_shot_im,
                               cv2.TM_CCOEFF_NORMED)
    if result.max() > 0.8:
        y,x = np.unravel_index(result.argmax(),result.shape)
        y += find_shot_im.shape[0] // 2
        x += find_shot_im.shape[1] // 2
        return x, y
    else:
        return -1, -1

最后利用pyautogui控制鼠标点击多少秒就可以了。

2

Part.2

DDPG算法实现

在Actor网络中,输入的是跳一跳的截图图片,输出动作为控制鼠标点击多少秒,这里主要用了tanh函数控制输出值在-1~1之间。最后乘上对应的系数,控制鼠标按压时间为“最低按压0.3s,最高按压1.1s”。

而在Critic网络中,输入“跳一跳的截图图片” + “Actor网络的输出”;输出“价值函数”,用来评估当前执行的动作价值。

DDPG比Actor-critic网络还多了两个,分别是Actor目标网络和Critic目标网络,这两个网络主要是为了解耦合的,参数从Actor-critic网络中进行复制更新过来。

具体的网络实现代码可以参考我的项目代码,这里需要注意的是,为了避免AI智能体从一开始收敛在某个区域而学习不到有用的信息,因此在Actor网络输出后还加了一个noise:

代码语言:javascript
复制
def add_noise(self, x, mu, theta, sigma):
     return theta * (mu - x) + sigma * np.random.randn(1)[0]

Replay经验回放:经验回放的目的是为了让网络可以重新记住之前采取过的策略,这样就可以像有监督学习一样扩充样本进行学习。在经验回放时,分别更新四个网络:Actor网络,Actor目标网络、Critic网络、Critic目标网络。

3.AI智能体效果

最后,在学习了大概700次迭代后,耗时大约在3小时左右,模型已经可以不断跳跃50次而不失败:

在人类来看,面积最小的,往往也是最难跳稳得,但是对应AI来说,能够较为容易的跳上去:

随着训练迭代次数的增多,跳的步数也越来越多,说明AI智能体在一定程度上学到了某种共性:

在实际中,Actor网络会输出负数 ,但在后面进行更正为最终按压的毫秒数 :

可以发现,在不同的状态环境下,给定不同的按压时间,可以得到对应的价值评估函数图,从下图可以发现价值函数有明显的区分效果。

以第一列第三个图为例,其评估函数图为第二列第三个图:当 ,即按压时间为 ,该策略执行的价值最大化,符合实际情况。(实际中由于上下位置比较接近,因此不能按压较长时间)

总结

上面是本次“跳一跳”AI智能体的简单介绍,更多的代码细节我已经上传的github上:

https://github.com/llq20133100095/deep-tiaotiao

或者在公众号回复“跳一跳”进行项目下载。

实际上这个项目比较粗糙,之后也可以考虑比如

  • 实现多个Agent
  • 如果跳到下一个块的中间位置,奖励更多

这次从头开始实现强化学习算法,还是收获比较多的,大家感兴趣可以下载下来玩一玩。

我是leo,我们下期再见~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档