【强化学习】用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 ...
随机推荐
- Android Dialog对话框
Dialog的基本方法 //创建Dialog AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); //设 ...
- IE打开https网站时,取消证书问题提示
上面介绍了,调用IE来打开对应的网页问题,但是在实际测试中,有些网站是采用https协议的,这时候IE浏览器会弹出如下窗口,一般手动选择后,才可进入登录界面,那么该如何解决呢? 1.点击[继续浏览此网 ...
- (后端)安装mongodb以及设置为windows服务 详细步骤(转)
1.在data文件夹下新建一个log文件夹,用于存放日志文件,在log文件夹下新建文件mongodb.log 2.在 D:\mongodb文件夹下新建文件mongo.config,并用记事本打开mon ...
- VMware虚拟机CentOS7网络通信与无线上网
实现主机和虚拟机网络通信 1.虚拟机设置 VMware界面最上面,选择[虚拟机]->[设置]:将网络连接改为"桥接模式",如下图所示: 2.CentOS7网络设置 自动获取I ...
- powershell脚本执行绕过powershell下脚本执行限制(cmd下执行)以及在cmd下隐藏脚本窗口
powershell脚本执行绕过powershell下脚本执行限制(cmd下执行) powershell脚本运行方式有两种,一种是powshell中运行,另一种是在cmd中(在某些情况下相当有用) p ...
- 【RHEL7.0】软件包管理
1.常用的RPM软件包命令 安装软件的命令格式 rpm –ivh filename.rpm 升级软件的命令格式 rpm –Uvh filename.rpm 卸载软件的命令格式 rpm –e fi ...
- 约瑟夫环简介,问题以及java实现
问题:一群猴子排成一圈,按1,2,--.,n依次编号.然后从第一只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,再把它踢出去-------.,如此不停的进行下去,直到最后只剩下一只猴 ...
- PHP下载网页
<?php /* author:whq 作用:获取网页的内容 */ include "../Snoopy/Snoopy.class.php";class Cute ...
- python3编写网络爬虫19-app爬取
一.app爬取 前面都是介绍爬取Web网页的内容,随着移动互联网的发展,越来越多的企业并没有提供Web页面端的服务,而是直接开发了App,更多信息都是通过App展示的 App爬取相比Web端更加容易 ...
- 12.scrapy框架之递归解析和post请求
今日概要 递归爬取解析多页页面数据 scrapy核心组件工作流程 scrapy的post请求发送 今日详情 1.递归爬取解析多页页面数据 - 需求:将糗事百科所有页码的作者和段子内容数据进行爬取切持久 ...