Q-learning原理及其实现方法

news/2024/11/28 6:54:56/

Q_learning原理及其实现方法

    • 声明
    • 前期回顾
    • 简介
    • Q_learning算法
    • Q_learning算法流程
    • Q_learning算法理解
    • Q_learning算法实现
    • 知识拓展

声明

学习博客快乐的强化学习1——Q_Learning及其实现方法,加之自己的理解写成,同时欢迎大家访问原博客

前期回顾

python单独运行查看py文件中类里面的函数功能

简介

Q-Learning是一种 value-based 算法,即通过判断每一步 action 的 value来进行下一步的动作,以人物的左右移动为例,Q-Learning的核心Q-Table可以按照如下表示:

环境向左向右
100.1
20.20.15
30.320.5

其中,在环境1下,向左得分为0,向右得分为0.1

在进行初始化时,给予一个概率值 e_greedy, 当处于环境1时,按照算法中的策略进行动作选择的概率为 e_greedy,而为了避免局部最优以及进行更多的探索,仍按照 1- e_greedy 的概率进行随机选择。

Q_learning算法

在这里插入图片描述

Q_learning算法流程

在这里插入图片描述

Q_learning算法理解

  1. 建立Q表,行是每种状态,列是每种状态的行为,值是某状态下某行为估计获得的奖励
  2. 每次进行状态转移时有e_greedy概率选当前状态最优方法,有 1- e_greedy选随机方法
  3. 选完之后就更新当前状态下对应所选行为的Q值(估计值)
  4. 更新方法:其自身= 其自身+学习率*(估计-现实) —> (实际更新 = 实际未更新+学习率*(预测-实际发生))
    在这里插入图片描述
    现实值也是其自身, 估计值是选择当前行为后的奖励及下一状态中选择与当前状态具有相同行为的Q值

PS:建议结合以下的例子理解。

Q_learning算法实现

以小男孩取得玩具为例子,讲述Q-Learning算法的执行过程。
在这里插入图片描述
在一开始的时候假设小男孩不知道玩具在哪里,他的Q_Table一片空白,此时他开始观测自己所处的环境,这个环境是环境1,并将这个环境加入到Q_Table中。此时,他不知道左右两个环境的情况,所以向左走向右走的得分都是0, 这两个得分都是小男孩心中预测出来的,并不是真实的左右两个环境的得分,我们给这个得分一个名字叫做q_predict。

环境向左向右
100

往左走往右走都是有可能的,如果他往左走,他会到达环境0,环境0是一个深渊,然后小男孩就挂了。此时环境会给他一个反馈得分,由于他掉入了深渊,所以他的得分是-1, 这个得分是环境0的实际得分,与上面小男孩处于环境1对环境0的预测得分不同,我们给这个得分一个名字叫做q_target, 由于这个得分与上一步预测的环境0的得分不同,所以我们需要对上一个表格进行更新,此时他的Q_Table表为:

环境向左向右
1-0.010

此时小男孩重生了,在这一轮假设他会选择往右走,此时他到达了环境2,并将这个环境加入到Q_Table中。此时,他不知道这个新环境的情况,向左走和向右走对他来说是一样的,所以这个新环境的左右两个Actions得分都是0。

环境向左向右
1-0.010
200

此时他会随机选择一个方向走,之后不断重复探测新环境和走回旧环境的过程,如果他在不断测试中找到了最后的toys,他会得到正数得分,这个得分会一步一步驱使他走向toys。在经过许多次的尝试之后,小男孩会找到一条最快通向玩具的道路。假设环境4就是玩具,小男孩在经过多次尝试后,最后的Q_Table可能是这样。

环境向左向右
1-0.020.033
20.0010.154
300.547

对于Q-Learning算法的主体而言,Q-Learning算法主要由两个对象组成,分别是Q-Learning的大脑和大环境。
Q-Learning的大脑包括以下部分,其对应的功能为

模块名称作用/功能
初始化初始化学习率、可执行动作、Q_table等参数
动作选择根据小男孩当前所处的环境和Q_table进行动作选择
学习根据小男孩当前所处的环境对其它环境的预测情况q_predict和下一步环境的实际情况q_target更新Q_table表
确认是否存在该环境由于在学习之前环境是未知的,当进入一个新环境时,需要生成一个得分都为0的动作表格

大环境包括以下部分,其对应的功能为

模块名称作用/功能
初始化初始化环境参数、用于构建环境
图画更新用于更新当前的图画,便于用户观察
环境观察用于返回当前环境情况
终点观察用于返回是否到达终点
更新坐标用于更新当前所处位置
下一环境获取用于获取下一步的环境的实际情况
参数归零用于每一个步坐标和当前行走步数的归零

在完成两个对象的构建后,需要有一个主函数将两个对象联系起来使用,主函数需要完成以下功能,以伪代码的形式呈现:

初始化测试环境对象
初始化Q-Learning的大脑对象
for episode in range(TIMES):环境观察图画更新while(1):终点观察if(到达终点):打印当前进行世代数,共使用多少步数参数归零break;动作选择获取下一步的环境的实际情况学习更新坐标图画更新

在观察完Q_Learning算法的伪代码后我们可以发现, 大脑在获取下一步环境的实际情况之后再进行学习,学习函数对Q-Table表更新的重要参数之一就是获取下一步的环境的实际情况。 具体来说,在进行学习过程时,Q-Learning的大脑对象会根据所处的当前环境对各个动作的预测得分和下一步的环境的实际情况(最大得分)对当前环境的Q-Table表进行更新,具体的代码如下所示


1.QL.py

import numpy as np
import pandas as pdclass QL:def __init__(self, actions, learning_rate=0.05, reward_decay=0.9, e_greedy=0.9):self.actions = actions      #初始化可以进行的各种行为,传入为列表self.lr = learning_rate     #学习率,用于更新Q_table的值self.gamma = reward_decay   #当没有到达终点时,下一环境对当前环境的影响self.epsilon = e_greedy     #随机选择几率为1-e_greedy,当处于e_greedy内时,不随机选择。self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64)     #生成q_table,列向量为columnsdef choose_action(self,observation):self.check_observation(observation)        #检测是否到达过这个点,如果没到达过,在Q表中增加这个节点action_list = self.q_table.loc[observation,:]           #取出当前observation所在的不同方向if(np.random.uniform() < self.epsilon):    #如果在epsilon几率内action = np.random.choice(action_list[action_list == np.max(action_list)].index)    #选出当前observation中Q值最大的方向else:action = np.random.choice(self.actions)      #如果不在epsilon内,则随机选择一个动作return action                                    #返回应当做的actiondef learn(self,observation_now,action,score,observation_after,done):self.check_observation(observation_after)        #检查是否存在下一环境对应的方向状态q_predict = self.q_table.loc[observation_now,action]        #获得当前状态下,当前所作动作所对应的预测得分if done:q_target = score     #如果完成了则q_target为下一个环境的实际情况得分,本例子中此时score为1else:q_target = score + self.gamma * self.q_table.loc[observation_after, :].max()  #如果未完成则取下一个环境若干个动作中的最大得分作为这个环境的价值传递给当前环境#根据所处的当前环境对各个动作的预测得分和下一步的环境的实际情况更新当前环境的q表self.q_table.loc[observation_now, action] += self.lr * (q_target - q_predict)  def check_observation(self,observation):if observation not in self.q_table.index:               #如果不存在 self.q_table = self.q_table.append(                 #则通过series函数生成新的一列pd.Series([0]*len(self.actions),index=self.actions,name=observation,))

2. Env.py

import numpy as np
import pandas as pd
import time class Env:def __init__(self,column,maze_column):self.column = column                        #表示地图的长度self.maze_column = maze_column - 1          #宝藏所在的位置self.x = 0                                  #初始化xself.map = np.arange(column)                #给予每个地点一个标号self.count = 0                              #用于技术一共走了多少步def draw(self):a = []for j in range(self.column) :               #更新图画if j == self.x:a.append('o')elif j == self.maze_column:a.append('m')else:a.append('_')interaction = ''.join(a)print('\r{}'.format(interaction),end = '')def get_observation(self):return self.map[self.x]                     #返回现在在所def get_terminal(self):if self.x == self.maze_column:              #如果得到了宝藏,则返回已经完成done = Trueelse:done = Falsereturn donedef update_place(self,action):self.count += 1                              #更新的时候表示已经走了一步if action == 'right':                                  if self.x < self.column - 1:self.x += 1elif action == 'left':   #leftif self.x > 0:self.x -= 1def get_target(self,action):if action == 'right':                        #获得下一步的环境的实际情况if self.x + 1 == self.maze_column:score = 1pre_done = Trueelse:score = 0pre_done = Falsereturn self.map[self.x + 1],score,pre_doneelif action == 'left':   #leftif self.x - 1 == self.maze_column:score = 1pre_done = Tureelse:score = 0pre_done = Falsereturn self.map[self.x - 1],score,pre_donedef retry(self):            #初始化self.x = 0self.count = 0

3. run_this.py

from Env import Env
from QL import QL
import timeLONG = 6                    #总长度为6
MAZE_PLACE = 6              #宝藏在第六位
TIMES = 15                  #进行15次迭代people = QL(['left','right'])       #生成QLearn主体的对象,包含left和right
site = Env(LONG,MAZE_PLACE)         #生成测试环境
for episode in range(TIMES):state = site.get_observation()  #观察初始环境site.draw()                     #生成图像time.sleep(0.3)                 #暂停while(1):done = site.get_terminal()  #判断当前环境是否到达最后if done:                    #如果到达,则初始化interaction = '\n第%s次世代,共使用步数:%s。'%(episode+1 ,site.count)print(interaction)site.retry()time.sleep(2)breakaction = people.choose_action(state)                        #获得下一步方向state_after,score,pre_done = site.get_target(action)        #获得下一步的环境的实际情况people.learn(state,action,score,state_after,pre_done)       #根据所处的当前环境对各个动作的预测得分和下一步的环境的实际情况更新当前环境的q表site.update_place(action)                                   #更新位置state = state_after                                         #状态更新site.draw()                                                 #更新画布time.sleep(0.3)print(people.q_table)

结果为:

_____o
第1次迭代,共使用步数:44
_____o
第2次迭代,共使用步数:11
_____o
第3次迭代,共使用步数:6
_____o
第4次迭代,共使用步数:6
_____o
第5次迭代,共使用步数:5
_____o
第6次迭代,共使用步数:7
_____o
第7次迭代,共使用步数:5
_____o
第8次迭代,共使用步数:5
_____o
第9次迭代,共使用步数:5
_____o
第10次迭代,共使用步数:5
_____o
第11次迭代,共使用步数:5
_____o
第12次迭代,共使用步数:5
_____o
第13次迭代,共使用步数:5
_____o
第14次迭代,共使用步数:5
_____o
第15次迭代,共使用步数:5left     right
0  0.000000  0.000452
5  0.000000  0.000000
1  0.000000  0.004429
2  0.000000  0.031661
3  0.000000  0.159344
4  0.001327  0.536709

知识拓展

快捷键批量注释/取消注释、缩进/取消缩进
python中join函数
Python中format函数用法说明
python中format函数


http://www.ppmy.cn/news/516609.html

相关文章

Django Q查询

1、导入Q对象 from django.db.model import Q Q 对象可以使用c&(AND)和|(OR)操作符组合起来。 当一个操作符在两个Q 对象上使用时&#xff0c;它产生一个新的Q 对象。 2、例子 Q(question__startswithWho) | Q(question__startswithWhat) 等同于SQL语句 WHERE quest…

电感的Q值知多少

电感Q值&#xff0c;也是电感的基本参数之一。不过在DCDC电路设计中&#xff0c;我们很少去考虑它&#xff0c;厂家一般也不会标注。那么电感的Q值到底是什么意思呢&#xff1f;我们什么时候要考虑呢&#xff1f; 还有这几个问题&#xff1a; ①为什么DC-DC电路设计中&#x…

基于C语言的Q格式使用详解

用过DSP的应该都知道Q格式吧; 文章目录 1 前言2 Q数据的表示2.1 范围和精度2.2 推导3 Q数据的运算3.1 0x7FFF3.2 0x80003.3 加法3.4 减法3.5 乘法3.6 除法4 常见Q格式的数据范围5 0x5f3759df6 总结</

现有16张牌:红桃A、Q、4;黑桃J、8、4、2、7、3;草花K、Q、5、4、6;方块A、5.抽出其中一张告诉甲点数,告诉乙花色。甲说,我不知道这张牌,乙说,我知道你不知道

排除掉甲一拿到就能知道花色得牌 比如排除黑桃J 8 2 7 3 草花K 6 这样甲就会在开局说不知道 而乙说“我知道你不知道”&#xff0c;也就是说乙所知道的花色内的数字一定不包含被排除的哪些数字中 那么乙手中的花色一定是黑桃和方块 紧接着甲说知道了那么甲手中的数字肯定很特殊…

NUCLEO-F411RE RT-Thread 体验 (9) - GCC环境 PWM的驱动移植以及简单使用

NUCLEO-F411RE RT-Thread 体验 (9) - GCC环境 PWM的驱动移植以及简单使用 驱动移植 驱动位于drv_pwm.c文件中&#xff0c;components层代码位于rt_drv_pwm.c中。 修改Makefile文件 修改配置文件rtconfig.h LED2链接PA5&#xff0c;而TIM2_CHANNEL1可从PA5输出PWM&#xff0…

nodejs q模块

nodejs module q q模块 promiseq模块的安装promise的使用 then 函数流式操作组合操作 Promise的创建 Using QfcallUsing DeferredsUsing QPromise 实际例子 测试服务器并行请求串行请求延时操作 接触nodejs时间不长&#xff0c;如果有所纰漏&#xff0c;请大家批评指正 nod…

08年4Q的购书清单

11月&#xff0c;12月在卓越亚马逊网站够了些书&#xff0c;应同事要求&#xff0c;放到blog里晒一晒。 订单时间&#xff1a;2008-12-02 商品&#xff1a;数学大师--从芝诺到庞加莱/当代科普名著系列/哲人石丛书 (1)中国科普名家名作-图形和逻辑的故事 (1)费曼的彩虹&#xf…

网站调研及分析工具4Q

网站调研及分析工具4Q Survey 2015年9月17日 BY 蓝鲸 LEAVE A COMMENT 4Q Survey是一个网站调研及分析工具。我的博客从2010年开始使用这个免费的用户调研工具。访问过我博客的朋友中20%的人应该都被这个工具“骚扰”过&#xff0c;4Q会在你开始阅读页面之前跳出来询问你本次…