【强化学习】python 实现 q-learning 例一
本文作者:hhh5460
本文地址:https://www.cnblogs.com/hhh5460/p/10134018.html
问题情境
-o---T
# T 就是宝藏的位置, o 是探索者的位置
这一次我们会用 q-learning 的方法实现一个小例子,例子的环境是一个一维世界,在世界的右边有宝藏,探索者只要得到宝藏尝到了甜头,然后以后就记住了得到宝藏的方法,这就是他用强化学习所学习到的行为。
Q-learning 是一种记录行为值 (Q value) 的方法,每种在一定状态的行为都会有一个值 Q(s, a),就是说 行为 a 在 s 状态的值是 Q(s, a)。s 在上面的探索者游戏中,就是 o 所在的地点了。而每一个地点探索者都能做出两个行为 left/right,这就是探索者的所有可行的 a 啦。
致谢:上面三段文字来自这里:https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/2-1-general-rl/
要解决这个问题,下面的几个事情要先搞清楚:
0.相关参数
epsilon = 0.9 # 贪婪度 greedy
alpha = 0.1 # 学习率
gamma = 0.8 # 奖励递减值
1.状态集
探索者的状态,即其可到达的位置,有6个。所以定义
states = range(6) # 状态集,从0到5
那么,在某个状态下执行某个动作之后,到达的下一个状态如何确定呢?
def get_next_state(state, action):
'''对状态执行动作后,得到下一状态'''
global states # left, right = -1,+1 # 一般来说是这样,不过要考虑首尾两个位置
if action == 'right' and state != states[-1]: # 除最后一个状态(位置),皆可向右(+1)
next_state = state + 1
elif action == 'left' and state != states[0]: # 除最前一个状态(位置),皆可向左(-1)
next_state = state -1
else:
next_state = state
return next_state
2.动作集
探索者处于每个状态时,可行的动作,只有"左"或"右"2个。所以定义
actions = ['left', 'right'] # 动作集。也可添加动作'none',表示停留
那么,在某个给定的状态(位置),其所有的合法动作如何确定呢?
def get_valid_actions(state):
'''取当前状态下的合法动作集合,与rewards无关!'''
global actions # ['left', 'right'] valid_actions = set(actions)
if state == states[-1]: # 最后一个状态(位置),则
valid_actions -= set(['right']) # 去掉向右的动作
if state == states[0]: # 最前一个状态(位置),则
valid_actions -= set(['left']) # 去掉向左
return list(valid_actions)
3.奖励集
探索者到达每个状态(位置)时,要有奖励。所以定义
rewards = [0,0,0,0,0,1] # 奖励集。只有最后的宝藏所在位置才有奖励1,其他皆为0
显然,取得状态state下的奖励就很简单了:rewards[state] 。根据state,按图索骥即可,无需额外定义一个函数。
4.Q table
最重要。Q table是一种记录状态-行为值 (Q value) 的表。常见的q-table都是二维的,基本长下面这样:
(注意,也有3维的Q table)
所以定义
q_table = pd.DataFrame(data=[[0 for _ in actions] for _ in states],
index=states, columns=actions)
5.环境及其更新
考虑环境的目的,是让人们能通过屏幕观察到探索者的探索过程,仅此而已。
环境环境很简单,就是一串字符 '-----T'!探索者到达状态(位置)时,将该位置的字符替换成'o'即可,最后重新打印整个字符串!所以
def update_env(state):
'''更新环境,并打印'''
global states env = list('-----T')
if state != states[-1]:
env[state] = 'o'
print('\r{}'.format(''.join(env)), end='')
time.sleep(0.1)
6.最后,Q-learning算法
Q-learning算法的伪代码

中文版的伪代码:

图片来源:https://www.hhyz.me/2018/08/05/2018-08-05-RL/
Q value的更新是根据贝尔曼方程:
$$Q(s_t,a_t) \leftarrow Q(s_t,a_t) + \alpha[r_{t+1} + \lambda \max _{a} Q(s_{t+1}, a) - Q(s_t,a_t)] \tag {1}$$
好吧,是时候实现它了:
# 总共探索13次
for i in range(13):
# 0.从最左边的位置开始(不是必要的)
current_state = 0
#current_state = random.choice(states) # 亦可随机
while current_state != states[-1]:
# 1.取当前状态下的合法动作中,随机(或贪婪)地选一个作为 当前动作
if (random.uniform(0,1) > epsilon) or ((q_table.ix[current_state] == 0).all()): # 探索
current_action = random.choice(get_valid_actions(current_state))
else:
current_action = q_table.ix[current_state].idxmax() # 利用(贪婪)
# 2.执行当前动作,得到下一个状态(位置)
next_state = get_next_state(current_state, current_action)
# 3.取下一个状态所有的Q value,待取其最大值
next_state_q_values = q_table.ix[next_state, get_valid_actions(next_state)]
# 4.根据贝尔曼方程,更新 Q table 中当前状态-动作对应的 Q value
q_table.ix[current_state, current_action] += alpha * (rewards[next_state] + gamma * next_state_q_values.max() - q_table.ix[current_state, current_action])
# 5.进入下一个状态(位置)
current_state = next_state print('\nq_table:')
print(q_table)
好了,这就是大名鼎鼎的Q-learning算法!
注意,贝尔曼方程中,取奖励是用了 rewards[next_state],再强调一下:next_state
当然,我们希望能看到探索者的探索过程,那就随时更新(打印)环境即可:
for i in range(13):
#current_state = random.choice(states)
current_state = 0 update_env(current_state) # 环境相关
total_steps = 0 # 环境相关 while current_state != states[-1]:
if (random.uniform(0,1) > epsilon) or ((q_table.ix[current_state] == 0).all()): # 探索
current_action = random.choice(get_valid_actions(current_state))
else:
current_action = q_table.ix[current_state].idxmax() # 利用(贪婪) next_state = get_next_state(current_state, current_action)
next_state_q_values = q_table.ix[next_state, get_valid_actions(next_state)]
q_table.ix[current_state, current_action] += alpha * (reward[next_state] + gamma * next_state_q_values.max() - q_table.ix[current_state, current_action])
current_state = next_state update_env(current_state) # 环境相关
total_steps += 1 # 环境相关 print('\rEpisode {}: total_steps = {}'.format(i, total_steps), end='') # 环境相关
time.sleep(1) # 环境相关
print('\r ', end='') # 环境相关 print('\nq_table:')
print(q_table)
7.完整代码
'''
-o---T
# T 就是宝藏的位置, o 是探索者的位置
'''
# 作者: hhh5460
# 时间:20181217
import pandas as pd
import random
import time epsilon = 0.9 # 贪婪度 greedy
alpha = 0.1 # 学习率
gamma = 0.8 # 奖励递减值 states = range(6) # 状态集。从0到5
actions = ['left', 'right'] # 动作集。也可添加动作'none',表示停留
rewards = [0,0,0,0,0,1] # 奖励集。只有最后的宝藏所在位置才有奖励1,其他皆为0 q_table = pd.DataFrame(data=[[0 for _ in actions] for _ in states],
index=states, columns=actions) def update_env(state):
'''更新环境,并打印'''
global states env = list('-----T') # 环境,就是这样一个字符串(list)!!
if state != states[-1]:
env[state] = 'o'
print('\r{}'.format(''.join(env)), end='')
time.sleep(0.1) def get_next_state(state, action):
'''对状态执行动作后,得到下一状态'''
global states # l,r,n = -1,+1,0
if action == 'right' and state != states[-1]: # 除非最后一个状态(位置),向右就+1
next_state = state + 1
elif action == 'left' and state != states[0]: # 除非最前一个状态(位置),向左就-1
next_state = state -1
else:
next_state = state
return next_state def get_valid_actions(state):
'''取当前状态下的合法动作集合,与reward无关!'''
global actions # ['left', 'right'] valid_actions = set(actions)
if state == states[-1]: # 最后一个状态(位置),则
valid_actions -= set(['right']) # 不能向右
if state == states[0]: # 最前一个状态(位置),则
valid_actions -= set(['left']) # 不能向左
return list(valid_actions) for i in range(13):
#current_state = random.choice(states)
current_state = 0 update_env(current_state) # 环境相关
total_steps = 0 # 环境相关 while current_state != states[-1]:
if (random.uniform(0,1) > epsilon) or ((q_table.ix[current_state] == 0).all()): # 探索
current_action = random.choice(get_valid_actions(current_state))
else:
current_action = q_table.ix[current_state].idxmax() # 利用(贪婪) next_state = get_next_state(current_state, current_action)
next_state_q_values = q_table.ix[next_state, get_valid_actions(next_state)]
q_table.ix[current_state, current_action] += alpha * (rewards[next_state] + gamma * next_state_q_values.max() - q_table.ix[current_state, current_action])
current_state = next_state update_env(current_state) # 环境相关
total_steps += 1 # 环境相关 print('\rEpisode {}: total_steps = {}'.format(i, total_steps), end='') # 环境相关
time.sleep(2) # 环境相关
print('\r ', end='') # 环境相关 print('\nq_table:')
print(q_table)
8.真正的最后,效果图



【强化学习】python 实现 q-learning 例一的更多相关文章
- 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird
深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-fu ...
- 机器学习之强化学习概览(Machine Learning for Humans: Reinforcement Learning)
声明:本文翻译自Vishal Maini在Medium平台上发布的<Machine Learning for Humans>的教程的<Part 5: Reinforcement Le ...
- 【转】【强化学习】Deep Q Network(DQN)算法详解
原文地址:https://blog.csdn.net/qq_30615903/article/details/80744083 DQN(Deep Q-Learning)是将深度学习deeplearni ...
- 深度强化学习(Deep Reinforcement Learning)入门:RL base & DQN-DDPG-A3C introduction
转自https://zhuanlan.zhihu.com/p/25239682 过去的一段时间在深度强化学习领域投入了不少精力,工作中也在应用DRL解决业务问题.子曰:温故而知新,在进一步深入研究和应 ...
- [Reinforcement Learning] 强化学习介绍
随着AlphaGo和AlphaZero的出现,强化学习相关算法在这几年引起了学术界和工业界的重视.最近也翻了很多强化学习的资料,有时间了还是得自己动脑筋整理一下. 强化学习定义 先借用维基百科上对强化 ...
- Deep Learning专栏--强化学习之从 Policy Gradient 到 A3C(3)
在之前的强化学习文章里,我们讲到了经典的MDP模型来描述强化学习,其解法包括value iteration和policy iteration,这类经典解法基于已知的转移概率矩阵P,而在实际应用中,我们 ...
- 深度强化学习(DRL)专栏(一)
目录: 1. 引言 专栏知识结构 从AlphaGo看深度强化学习 2. 强化学习基础知识 强化学习问题 马尔科夫决策过程 最优价值函数和贝尔曼方程 3. 有模型的强化学习方法 价值迭代 策略迭代 4. ...
- (转) 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文)
本文转自:http://mp.weixin.qq.com/s/aAHbybdbs_GtY8OyU6h5WA 专题 | 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文) 原创 201 ...
- 强化学习论文(Scalable agent alignment via reward modeling: a research direction)
原文地址: https://arxiv.org/pdf/1811.07871.pdf ======================================================== ...
- Ubuntu下常用强化学习实验环境搭建(MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2)
http://lib.csdn.net/article/aimachinelearning/68113 原文地址:http://blog.csdn.net/jinzhuojun/article/det ...
随机推荐
- 我的第一个个人博客网站 -> wizzie.top
从去年下半年实习结束,到找到第一个属于自己的工作,我就开始着手搭建自己的网站. 使用阿里云学生服务器,域名,备案解析后,开始设计网站结构和页面布局. 因为临近毕业,网站真的是写的页面怎么多怎么写,所以 ...
- 【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
上一篇很水的介绍完了TreeMap,这一篇来看看更水的TreeSet. 本文将从以下几个角度进行展开: 1.TreeSet简介和使用栗子 2.TreeSet源码分析 本篇大约需食用10分钟,各位看官请 ...
- recovery log直接输出到串口
我们在调试recovery升级的时候,我们经常需要查看recovery的log,google的原始逻辑中,recovery的log并非直接输出到串口,我们需要输入命令才能获取,我们有三种方式: 第一种 ...
- ALSA声卡驱动的DAPM(二)-建立过程
在上一篇文章中,我们重点介绍了widget.path.route之间的关系及其widget的注册: http://www.cnblogs.com/linhaostudy/p/8509899.html ...
- oracle count函数
用来返回查询的行数. 当指定distinct时,不能接order_by_clause: 如果指定表达式,count返回表达式不为空的值: 当指定*号时,它返回所有行,含重复行和空值.count从不返回 ...
- Beta冲刺(5/5)(麻瓜制造者)
今日已完成 邓弘立:完成了图书馆新功能 符天愉:完成管理员用户查询,删除商品/需求以及注销功能 江郑:进行后台管理员的web开发 刘双玉:修改了商品搜索中数据返回类型不对的错误,添加了图书馆查询接口 ...
- [原创]Javascript模拟“类”的综合实现方式以及部分细节【截至ES6】
[原创]Javascript模拟“类”的综合实现方式以及部分细节[截至ES6] 前言 最近几个旧项目里使用的图片编辑插件出现Bug, 经Review 后确定需要在其内外均做些改动,但是头疼的发现部 ...
- mysql 创建 mb4 字符集数据库
create database sina default character set utf8mb4 collate utf8mb4_unicode_ci; show variables like ' ...
- 2017-2018-2 20155314《网络对抗技术》Exp5 MSF基础应用
2017-2018-2 20155314<网络对抗技术>Exp5 MSF基础应用 目录 实验内容 实验环境 基础问题回答 预备知识 实验步骤--基于Armitage的MSF自动化漏洞攻击实 ...
- redsi一主两从三哨兵
1.前提准备 防火墙,selinux,主机名解析,所有主机安装gcc [root@localhost ~]# vim /etc/hosts 192.168.122.135 redis_master ...