【强化学习】用pandas 与 numpy 分别实现 q-learning, saras, saras(lambda)算法
本文作者:hhh5460
本文地址:https://www.cnblogs.com/hhh5460/p/10159331.html
特别感谢:本文的三幅图皆来自莫凡的教程 https://morvanzhou.github.io/
pandas是基于numpy的,但是两者之间的操作有区别,故在实现上述算法时的细节有出入。故记录之
几点说明:
1). 为了更好的说明问题,采用最简单的例一。
2). 分离了环境与个体,采用类编程的形式。
3). 调整了环境与个体的变量、函数的位置,使得Agent完全不需要改动!
4). 个体与环境的互动逻辑更符合实际
〇、效果图

一、pandas实现
1.q-learning

class RLQLearning(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.4):
'''学习'''
print('q-learning算法')
for _ in range(episode):
s = self.env.reset()
is_win = False
while not is_win:
a = self.observe(s, epsilon)
r, s1, is_win = self.env.step(a)
self.Q.ix[s, a] += alpha * (r + gamma * self.Q.ix[s1, self.env.get_valid_actions(s1)].max() - self.Q.ix[s, a])
s = s1
2.saras

class RLSaras(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras算法')
for _ in range(episode):
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
self.Q.ix[s, a] += alpha * (r + gamma * self.Q.ix[s1, a1] - self.Q.ix[s, a])
s, a = s1, a1
3.saras(lambda)

class RLSarasLambda(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env)
self.E = self.Q.copy() # 复制Q table def learn(self, alpha=0.01, gamma=0.9, lambda_=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras(lambda)算法,lambda_为衰减值')
for _ in range(episode):
self.E *= 0
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
delta = r + gamma * self.Q.ix[s1, a1] - self.Q.ix[s, a]
#self.E.ix[s, a] += 1 # 效果不如下两句
self.E.ix[s] *= 0
self.E.ix[s, a] = 1
for s_ in self.env.states:
for a_ in self.env.actions:
self.Q.ix[s_, a_] += alpha * delta * self.E.ix[s_, a_]
self.E.ix[s_, a_] *= gamma * lambda_
s, a = s1, a1
4.完整代码
import pandas as pd
import random
import time '''
-o---T
# T 就是宝藏的位置, o 是探索者的位置
''' # 作者:hhh5460
# 时间:20181221
# 地点:Tai Zi Miao class Env(object):
'''环境'''
def __init__(self):
'''初始化'''
self.board = list('-----T')
self.states = range(6)
self.actions = ['left', 'right']
self.rewards = [0,0,0,0,0,1] def get_valid_actions(self, state):
'''取当前状态下所有的合法动作'''
valid_actions = []
if state != 5: # 除末状态(位置),皆可向右
valid_actions.append('right')
if state != 0: # 除首状态(位置),皆可向左
valid_actions.append('left')
return valid_actions def _step(self, action):
'''执行动作,到达新状态'''
if action == 'right' and self.state != self.states[-1]: # 除末状态(位置),向右+1
self.state += 1
elif action == 'left' and self.state != self.states[0]: # 除首状态(位置),向左-1
self.state -= 1 def reset(self):
'''重置环境,返回状态0'''
self.board = list('-----T')
self.state = 0
self.board[self.state] = 'o'
print('\r ', end='')
print('\r{}'.format(''.join(self.board)), end='')
return self.state def step(self, action, step_time=0.1):
'''执行动作 返回奖励、新状态、胜利标志'''
self.board[self.state] = '-' # 擦除旧位置'o'
self._step(action) # 到达新位置
self.board[self.state] = 'o' # 改变新位置 reward = self.rewards[self.state] # 奖励
is_win = [False, True][self.state == self.states[-1]] # 胜利标志
if is_win == True:
print('\r{} WIN!'.format(''.join(self.board)), end='') # 胜利,则加特写镜头
else:
print('\r{}'.format(''.join(self.board)), end='')
time.sleep(step_time) return reward, self.state, is_win class Agent(object):
'''智能体'''
def __init__(self, env):
'''初始化'''
# 环境
self.env = env
# 大脑
self.Q = pd.DataFrame(data=[[0 for _ in self.env.actions] for _ in self.env.states],
index=self.env.states,
columns=self.env.actions) def observe(self, state, epsilon=0.4):
'''观察'''
# 根据自身所处状态,按某种策略选择相应的动作
if random.uniform(0,1) < epsilon: # 贪婪
s = self.Q.ix[state].filter(items=self.env.get_valid_actions(state))
action = random.choice(s[s==s.max()].index) # 可能多个最大值!
else: # 探索
action = random.choice(self.env.get_valid_actions(state))
return action def learn(self,*args, **kw):
'''学习'''
pass def play(self, step_time=0.5):
'''玩耍'''
# 学有所成
s = self.env.reset()
is_win = False
while not is_win:
a = self.observe(s, epsilon=1.) # 1.,100%贪婪,即利用
_, s1, is_win = self.env.step(a, step_time)
s = s1
print() class RLQLearning(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.4):
'''学习'''
print('q-learning算法')
for _ in range(episode):
s = self.env.reset()
is_win = False
while not is_win:
a = self.observe(s, epsilon)
r, s1, is_win = self.env.step(a)
self.Q.ix[s, a] += alpha * (r + gamma * self.Q.ix[s1, self.env.get_valid_actions(s1)].max() - self.Q.ix[s, a])
s = s1 class RLSaras(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras算法')
for _ in range(episode):
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
self.Q.ix[s, a] += alpha * (r + gamma * self.Q.ix[s1, a1] - self.Q.ix[s, a])
s, a = s1, a1 class RLSarasLambda(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env)
self.E = self.Q.copy() # 复制Q table def learn(self, alpha=0.01, gamma=0.9, lambda_=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras(lambda)算法,lambda_为衰减值')
for _ in range(episode):
self.E *= 0
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
delta = r + gamma * self.Q.ix[s1, a1] - self.Q.ix[s, a]
#self.E.ix[s, a] += 1 # 效果不如下两句
self.E.ix[s] *= 0
self.E.ix[s, a] = 1
for s_ in self.env.states:
for a_ in self.env.actions:
self.Q.ix[s_, a_] += alpha * delta * self.E.ix[s_, a_]
self.E.ix[s_, a_] *= gamma * lambda_
s, a = s1, a1 if __name__ == '__main__':
env = Env() # 环境 agent = RLQLearning(env) # 个体
agent.learn(episode=13) # 先学
agent.play() # 再玩 agent2 = RLSaras(env) # 个体2
agent2.learn(episode=13) # 先学
agent2.play() # 再玩 agent3 = RLSarasLambda(env) # 个体3
agent3.learn(episode=13) # 先学
agent3.play() # 再玩
二、numpy实现
1.q-learning
2.saras
3.saras(lambda)
4.完整代码
import numpy as np
import time '''
-o---T
# T 就是宝藏的位置, o 是探索者的位置
''' # 作者:hhh5460
# 时间:20181221
# 地点:Tai Zi Miao class Env(object):
'''环境'''
def __init__(self):
'''初始化'''
self.board = list('-----T')
self.states = range(6)
self.actions = ['left', 'right'] # 索引[0,1]
self.rewards = [0,0,0,0,0,1] def get_valid_actions(self, state):
'''取当前状态下所有的合法动作(索引)'''
valid_actions = []
if state != self.states[0]: # 除首状态(位置),皆可向左
valid_actions.append(self.actions.index('left'))
if state != self.states[-1]: # 除末状态(位置),皆可向右
valid_actions.append(self.actions.index('right'))
return valid_actions def _step(self, action):
'''执行动作(索引),到达新状态'''
if self.actions[action] == 'left' and self.state > self.states[0]: # 除首状态(位置),向左-1
self.state = self.state - 1
elif self.actions[action] == 'right' and self.state < self.states[-1]: # 除末状态(位置),向右+1
self.state = self.state + 1 def reset(self):
'''重置环境,返回状态0'''
self.board = list('-----T')
self.state = 0
self.board[self.state] = 'o'
print('\r ', end='')
print('\r{}'.format(''.join(self.board)), end='')
return self.state def step(self, action, step_time=0.1):
'''执行动作 返回奖励、新状态、胜利标志'''
self.board[self.state] = '-' # 擦除旧位置'o'
self._step(action) # 到达新位置
self.board[self.state] = 'o' # 改变新位置 reward = self.rewards[self.state] # 奖励
is_win = [False, True][self.state == self.states[-1]] # 胜利标志
if is_win == True:
print('\r{} WIN!'.format(''.join(self.board)), end='') # 胜利,则加特写镜头
else:
print('\r{}'.format(''.join(self.board)), end='')
time.sleep(step_time) return reward, self.state, is_win class Agent(object):
'''智能体'''
def __init__(self, env):
'''初始化'''
# 环境
self.env = env
# 大脑
self.Q = np.zeros((len(self.env.states), len(self.env.actions)), dtype=np.float32) def observe(self, state, epsilon=0.8):
'''观察'''
# 根据自身所处状态,按某种策略选择相应的动作(索引)
valid_actions = self.env.get_valid_actions(state)
arr = self.Q[state, valid_actions]
if (np.random.uniform() > epsilon
or arr.max() == 0
or len(arr[arr==arr.max()]) > 1):
action = np.random.choice(valid_actions) # 探索
else:
action = self.Q[state].argmax() # 利用
return action def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.8):
'''学习'''
pass def play(self, step_time=0.5):
'''玩耍'''
# 学有所成
s = self.env.reset()
is_win = False
while not is_win:
a = self.observe(s, epsilon=1.) # 1.,100%贪婪,即利用
_, s1, is_win = self.env.step(a, step_time)
s = s1
print() class RLQLearning(Agent):
'''智能体'''
def __init__(self, env):
'''初始化'''
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.8):
'''学习'''
print('q-learning算法')
for _ in range(episode):
s = self.env.reset()
is_win = False
while not is_win:
a = self.observe(s, epsilon)
r, s1, is_win = self.env.step(a)
self.Q[s, a] += alpha * (r + gamma * self.Q[s1, self.env.get_valid_actions(s1)].max() - self.Q[s, a])
s = s1 class RLSaras(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env) def learn(self, alpha=0.01, gamma=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras算法')
for _ in range(episode):
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
self.Q[s, a] += alpha * (r + gamma * self.Q[s1, a1] - self.Q[s, a])
s, a = s1, a1 class RLSarasLambda(Agent):
'''Agent的子类'''
def __init__(self, env):
super().__init__(env)
self.E = self.Q.copy() # 复制Q table def learn(self, alpha=0.01, gamma=0.9, lambda_=0.9, episode=100, epsilon=0.4):
'''学习'''
print('saras(lambda)算法,lambda_为衰减值')
for _ in range(episode):
self.E *= 0
s = self.env.reset()
a = self.observe(s, epsilon)
is_win = False
while not is_win:
r, s1, is_win = self.env.step(a)
a1 = self.observe(s1, epsilon)
delta = r + gamma * self.Q[s1, a1] - self.Q[s, a]
#self.E.ix[s, a] += 1 # 效果不如下两句
self.E[s] *= 0
self.E[s, a] = 1
for s_ in self.env.states:
for a_ in range(len(self.env.actions)): # 遍历动作索引!!
self.Q[s_, a_] += alpha * delta * self.E[s_, a_]
self.E[s_, a_] *= gamma * lambda_
s, a = s1, a1 if __name__ == '__main__':
env = Env() # 环境
agent = RLQLearning(env) # 个体
agent.learn(episode=13) # 先学
agent.play() # 再玩 agent2 = RLSaras(env) # 个体2
agent2.learn(episode=13) # 先学
agent2.play() # 再玩 agent3 = RLSarasLambda(env) # 个体3
agent3.learn(episode=13) # 先学
agent3.play() # 再玩
【强化学习】用pandas 与 numpy 分别实现 q-learning, saras, saras(lambda)算法的更多相关文章
- 强化学习之QLearning
注:以下第一段代码是 文章 提供的代码,但是简书的代码粘贴下来不换行,所以我在这里贴了一遍.其原理在原文中也说得很明白了. 算个旅行商问题 基本介绍 戳 代码解释与来源 代码整个计算过程使用的以下公式 ...
- 【转】【强化学习】Deep Q Network(DQN)算法详解
原文地址:https://blog.csdn.net/qq_30615903/article/details/80744083 DQN(Deep Q-Learning)是将深度学习deeplearni ...
- (转) 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文)
本文转自:http://mp.weixin.qq.com/s/aAHbybdbs_GtY8OyU6h5WA 专题 | 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文) 原创 201 ...
- 【转载】 强化学习(四)用蒙特卡罗法(MC)求解
原文地址: https://www.cnblogs.com/pinard/p/9492980.html ------------------------------------------------ ...
- 深度学习-强化学习(RL)概述笔记
强化学习(Reinforcement Learning)简介 强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益.其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予 ...
- 强化学习(Reinfment Learning) 简介
本文内容来自以下两个链接: https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/ https: ...
- 5G网络的深度强化学习:联合波束成形,功率控制和干扰协调
摘要:第五代无线通信(5G)支持大幅增加流量和数据速率,并提高语音呼叫的可靠性.在5G无线网络中共同优化波束成形,功率控制和干扰协调以增强最终用户的通信性能是一项重大挑战.在本文中,我们制定波束形成, ...
- 数据分析之Pandas和Numpy学习笔记(持续更新)<1>
pandas and numpy notebook 最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...
- 深度强化学习:Policy-Based methods、Actor-Critic以及DDPG
Policy-Based methods 在上篇文章中介绍的Deep Q-Learning算法属于基于价值(Value-Based)的方法,即估计最优的action-value function $q ...
随机推荐
- 小程序实践(六):view内部组件排版
涉及知识点: 1.垂直排列,水平排列 2.居中对齐 示例: 1.默认排版 , 一个父组件里面两个子view 显示效果: 2.先给父view设置一个高度和颜色值,用于看效果 3.实现水平排列和垂直排列的 ...
- OkHttp的封装和使用详解
Github地址 compile 'cn.yuan.yu:library:1.0.2' 第一步:初始化我们的工具类 public class MyApplication extends Applica ...
- 关于ARM CM3的启动文件分析
下面以ARM Cortex_M3裸核的启动代码为例,做一下简单的分析.首先,在启动文件中完成了三项工作: 1. 堆栈以及堆的初始化 2. 定位中断向量表 3. 调用Reset Handler. ...
- g4e基础篇#4 了解Git存储库(Repo)
章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git 分布式版本控制系统的优势 Git 安装和设置 了解Git存储库(Repo) 起步 1 – 创建分支和保存代码 起步 2 – 了解Git ...
- ORACLE实际执行计划与预估执行计划不一致性能优化案例
在一台ORACLE服务器上做巡检时,使用下面SQL找出DISK_READ最高的TOP SQL分析时,分析过程中,有一条SQL语句的一些反常现象,让人觉得很奇怪: SELECT SQL_ID, ...
- mssql sqlserver 模拟for循环的写法
转自:http://www.maomao365.com/?p=6567 摘要: 下文讲述sql脚本模拟for循环的写法,如下所示: /* for样例 for('初始值','条件','执行后自增') 通 ...
- Android WebSocket开发
一,在模块build.gradle中添加webSocket的依赖包 //WebSocket 依赖包 implementation 'com.neovisionaries:nv-websocket-cl ...
- c/c++ 标准库 vector
c/c++ 标准库 vector 标准库 vector的小例子 test1~test7 #include <iostream> #include <vector> using ...
- PostgreSQL远程访问设置
数据库版本:9.3.23(Windows xp系统) 步骤: 1.需要修改数据库安装目录下的pg_hba.conf文件 修改成: 2.并使用psql执行pg_ctl reload重新加载配置文件
- php笔记(一)php介绍及数据类型
php 官方手册:http://php.net/manual/zh/ 1.PHP(全称 Hypertext Preprocessor,超文本预处理器的字母缩写)是一种服务器端脚本语言,它可嵌入到 HT ...