Q-Learning介绍:一种增强学习

最近在训练机器人,学习了Q-learning算法,看到了几篇比较好的文章,好几篇文章已经有人翻译过了,还有一系列好文章还没有翻译版本,这篇文章是medium上的,出处为

An introduction to Q-Learning: reinforcement learning ——ADL

Q-learning是一种基于值的监督式学习算法。在此文中,我们将从以下几方面介绍Q-learning算法

  • 什么是Q-learning
  • Q-learning背后的数学
  • 利用Python实现

Q-learning——简要综述

举个栗子,有一个机器人需要穿越迷宫到达终点,在地图上有一些地雷,机器人每次可以走一步,如果踩到地雷机器人会死掉,我们的问题是需要让机器人在最短的时间到达终点。

评分系统如下所示:

  1. 每走一步机器人损失一分,这么做的目的是让机器人学会走最短路,也就是在最短时间到达
  2. 如果机器人踩到地雷,他会损失100分并且游戏结束
  3. 如果机器人得到能量⚡️,会加一分
  4. 如果机器人到达终点,会得到100分

现在的问题很明显了:我们怎样训练机器人,让他学会在不踩地雷的基础上,走最短路到达终点呢?
地图
所以,我们该怎样解决捏?

Q-table的引入

Q-Table是在每个状态下我们计算最大期望奖励的查询表格。也就是说,这个表会指导我们在每个状态下做哪个动作是最佳的。
在这里插入图片描述
如果机器人不在边上和角落时,他有四个方向可以选择,下面便是我们的Q-table
在这里插入图片描述
每个Q-table的分数是如果机器人在那个状态下采取那个动作会得到的最大期望奖励。这是个迭代过程,也就是我们需要在每次迭代时改进Q-table。

但是问题是:

  • 怎样计算Q-table的值?
  • 这些值是可得的还是预先定义的?

为了得到Q-table中的每个值,我们使用Q-learning算法

数学:Q-learning算法

Q-函数(Q-function)

Q-函数使用Bellman等式并且有两个输入:状态(states(s))和动作(action(a))
在这里插入图片描述
使用上述函数,我们可以得到在表格中Q每个格中的值
初始的时候,Q-table中所有的值为0
然后是一个迭代过程,当我们开始探索环境时,Q-函数可以通过更新表中的数给我们越来越好的近似值
现在,让我们理解更新是怎么做的~

Q-learning算法过程的介绍

在这里插入图片描述
如上图所示,每个带颜色的框就是一步,让我们具体来看~

步骤1:初始化Q-table

我们首先建立一个Q-table。有n列(n是动作的数量)m行(状态数),初始化所有数值为0.
在我们的例子中,我们有四个动作(a=4)和五个状态(s=5)。因此我们建立一个四行五列的表格。

步骤2,3:选择并执行动作

这个步骤的组合在未定义的时间内执行。这意味着这一步在我们停止训练之前,或者在指定训练迭代之内执行
我们在状态(s)下根据Q-table选择一个动作(a)。但是,正如之前提到的,迭代开始之初,所有的Q-值(value)都是0.
此时,探索和开采平衡(exploration and exploitation trade-off)就进入了我们的视线。
我们利用 ϵ \epsilon ϵ贪婪策略(epsilon greedy strategy)
开始的时候, ϵ \epsilon ϵ值是比较高的,因此机器人将会探索环境并且随机选择一些动作。这背后的逻辑是此时机器人对环境一无所知
在探索的过程中,机器人将会对估计Q-值越来越有信心
对于机器人来说,这里一共有四种动作可供选择:上,下,左,右。我们现在开始训练——我们的机器人对环境一无所知,因此他随机选择了一个动作,比如向右
在这里插入图片描述
现在我们利用Bellman等式,更新向右移动之后的Q-值

步骤4和5:评价

现在我们执行一个动作并且观察输出(outcome)和奖励(reward)。我们需要更新函数Q(s,a)
在这里插入图片描述
在这个例子中,分数分配的结构如下:

  • power(能量) = +1
  • mine(地雷) = -100
  • end(到达终点) = +100
New Q(start,right) = Q(start, right + alpha[some ... Delta value])
some ... Delta value = R(start, right) + max(Q'(nothing,down), Q'(nothing,left), Q'(nothing,right))- Q'(start,right)
some... Delta value = 0 +0.9 * 0 - 0 = 0
 New Q(start,right) = 0 + 0.1 * 0 = 0

我们将一次又一次重复这个过程直到学习过程结束。在这个过程中Q-table将会更新

Q-learning的python实现

概念和代码实现在作者的YouTube视频中

最终总结

  • Q-learning是一种基于值的监督式学习算法,他是利用Q-函数寻找选择最优动作策略的
  • 我们的目标时最大化价值函数Q的
  • Q-table帮助我们寻找在每个状态下的最佳动作
  • 它通过选择最优动作最大化期望奖励
  • Q(state,action)返回在指定状态和动作情况下的期望奖励
  • 函数可以通过Q-Learning估计,是通过Bellman等式迭代更新Q(s,a)的
  • 最初我们需要探索(explore)环境并且更新Q-table。当Q-table得到之后,机器人(agent)就可以开发(exploit)环境并且可以采用更好的动作了
1Error:Internal error: (java.lang.IllegalAccessError) class com.intellij.util.io.FileChannelUtil (in unnamed module @0x79ad8b2f) cannot access class sun.nio.ch.FileChannelImpl (in module java.base) because module java.base does not export sun.nio.ch to unnamed module @0x79ad8b2f java.lang.IllegalAccessError: class com.intellij.util.io.FileChannelUtil (in unnamed module @0x79ad8b2f) cannot access class sun.nio.ch.FileChannelImpl (in module java.base) because module java.base does not export sun.nio.ch to unnamed module @0x79ad8b2f at com.intellij.util.io.FileChannelUtil.setupUnInterruptibleHandle(FileChannelUtil.java:26) at com.intellij.util.io.FileChannelUtil.<clinit>(FileChannelUtil.java:18) at com.intellij.util.io.ReadWriteDirectBufferWrapper$FileContext$1.execute(ReadWriteDirectBufferWrapper.java:50) at com.intellij.util.io.ReadWriteDirectBufferWrapper$FileContext$1.execute(ReadWriteDirectBufferWrapper.java:42) at com.intellij.openapi.util.io.FileUtilRt.doIOOperation(FileUtilRt.java:945) at com.intellij.util.io.ReadWriteDirectBufferWrapper$FileContext.<init>(ReadWriteDirectBufferWrapper.java:42) at com.intellij.util.io.ReadWriteDirectBufferWrapper.create(ReadWriteDirectBufferWrapper.java:27) at com.intellij.util.io.DirectBufferWrapper.getBuffer(DirectBufferWrapper.java:24) at com.intellij.util.io.ReadWriteDirectBufferWrapper.getBuffer(ReadWriteDirectBufferWrapper.java:16) at com.intellij.util.io.PagedFileStorage$StorageLock.createValue(PagedFileStorage.java:631) at com.intellij.util.io.PagedFileStorage$StorageLock.get(PagedFileStorage.java:558) at com.intellij.util.io.PagedFileStorage$StorageLock.access$500(PagedFileStorage.java:466) at com.intellij.util.io.PagedFileStorage.getBufferWrapper(PagedFileStorage.java:407) at com.intellij.util.io.PagedFileStorage.getReadOnlyBuffer(PagedFileStorage.java:375) at com.intellij.util.io.PagedFileStorage.getInt(PagedFileStorage.java:155) at com.intellij.util.io.ResizeableMappedFile.getInt(ResizeableMappedFile.java:217) at com.intellij.util.io.PersistentEnumeratorBase.<init>(PersistentEnumeratorBase.java:212) at com.intellij.util.io.PersistentBTreeEnumerator.<init>(PersistentBTreeEnumerator.java:73) at com.intellij.util.io.PersistentEnumeratorDelegate.<init>(PersistentEnumeratorDelegate.java:47) at com.intellij.util.io.PersistentHashMap.<init>(PersistentHashMap.java:149) at com.intellij.util.io.PersistentHashMap.<init>(PersistentHashMap.java:138) at com.intellij.util.io.PersistentHashMap.<init>(PersistentHashMap.java:129) at com.intellij.util.io.PersistentHashMap.<init>(PersistentHashMap.java:121) at com.intellij.util.io.PersistentHashMap.<init>(PersistentHashMap.java:114) at org.jetbrains.jps.incremental.storage.AbstractStateStorage.createMap(AbstractStateStorage.java:124) at org.jetbrains.jps.incremental.storage.AbstractStateStorage.<init>(AbstractStateStorage.java:27) at org.jetbrains.jps.incremental.storage.FileTimestampStorage.<init>(FileTimestampStorage.java:27) at org.jetbrains.jps.incremental.storage.ProjectStamps.<init>(ProjectStamps.java:39) at org.jetbrains.jps.incremental.storage.ProjectTimestamps.<init>(ProjectTimestamps.java:19) at org.jetbrains.jps.cmdline.BuildRunner.load(BuildRunner.java:92) at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:274) at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:130) at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:232) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583)
最新发布
03-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值