【强化学习】用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 ...
随机推荐
- WPF:Metro样式ProgressBar(圆点横向移动),自适应宽度
先看效果图: 最直观的,这是4个圆点在移动,就用一个横向的StackPanel表示这四个点吧. <StackPanel Orientation="Horizontal"> ...
- Javac编译原理 《深入分析java web 技术内幕》第四章
javac编译的四个主要的流程: 词法分析器:将源码转换为Token流 将源代码划分成一个个Token(找出java语言中的关键字) 语法分析器:将Token流转化为语法树 将上述的一个个Token组 ...
- html + css3 demo
最近,在做一个比较大的网站,主要服务于欧美地区,全站为英文版本,因为是电子产品,因此,要展示产品内在美(扯个蛋!)仿照小米.錘子.苹果等网站,着重于css3动效效果,搜集整理了一些网站中用到的动效图, ...
- recovery 界面汉化过程详解
一. 主要是针对recovery汉化,主要汉化对象是界面显示为中文. 二. 基于中文的汉化,有两种方式,一种是基于GB2312的编码格式汉化,另外一种是基于unicode编码格式汉化.下面介绍unic ...
- DataGridView的单元格如何嵌入多个按钮控件
前段时间我有一个朋友面试公司的时候遇到这个面试题,他也给了份原题给我瞧瞧,并没有什么特别的要点,关于这一类问题,如何在网格上的单元格嵌入多个控件(如按钮.超链接等)问题,我在网上搜索了下这类问题,发现 ...
- 根据标签中动态获取的值绑定特定的class
数据有mock数据获取 mock文件: index文件: 引入文件index: 获取数据函数: 根据获取的标签内容给定不同的样式:
- [20180928]如何能在11g下执行.txt
[20180928]如何能在11g下执行.txt --//链接问的问题: http://www.itpub.net/thread-2105467-1-1.html create table test( ...
- raid1 raid2 raid5 raid6 raid10的优缺点和做各自raid需要几块硬盘
Raid 0:一块硬盘或者以上就可做raid0优势:数据读取写入最快,最大优势提高硬盘容量,比如3快80G的硬盘做raid0 可用总容量为240G.速度是一样.缺点:无冗余能力,一块硬盘损坏,数据全无 ...
- CentOS6.5内 MySQL5.7.19编译安装
作为博主这样的Linux菜鸟,CentOS下最喜欢的就是yum安装.但有时候因为特殊情况(例如被墙等),某些软件可能没办法直接通过yum来安装,这时候我们可以使用编译安装或者直接二进制文件安装. 本博 ...
- 【底层原理】深入理解Cache (下)
得到了我的PC的cache参数如下: L1 Cache : 32KB , 8路组相连,linesize为 64Byte 64个组 L2 Cache:256KB 8路组相连,linesize为 64By ...