本文作者: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)算法的更多相关文章

  1. 强化学习之QLearning

    注:以下第一段代码是 文章 提供的代码,但是简书的代码粘贴下来不换行,所以我在这里贴了一遍.其原理在原文中也说得很明白了. 算个旅行商问题 基本介绍 戳 代码解释与来源 代码整个计算过程使用的以下公式 ...

  2. 【转】【强化学习】Deep Q Network(DQN)算法详解

    原文地址:https://blog.csdn.net/qq_30615903/article/details/80744083 DQN(Deep Q-Learning)是将深度学习deeplearni ...

  3. (转) 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文)

    本文转自:http://mp.weixin.qq.com/s/aAHbybdbs_GtY8OyU6h5WA 专题 | 深度强化学习综述:从AlphaGo背后的力量到学习资源分享(附论文) 原创 201 ...

  4. 【转载】 强化学习(四)用蒙特卡罗法(MC)求解

    原文地址: https://www.cnblogs.com/pinard/p/9492980.html ------------------------------------------------ ...

  5. 深度学习-强化学习(RL)概述笔记

    强化学习(Reinforcement Learning)简介 强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益.其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予 ...

  6. 强化学习(Reinfment Learning) 简介

    本文内容来自以下两个链接: https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/ https: ...

  7. 5G网络的深度强化学习:联合波束成形,功率控制和干扰协调

    摘要:第五代无线通信(5G)支持大幅增加流量和数据速率,并提高语音呼叫的可靠性.在5G无线网络中共同优化波束成形,功率控制和干扰协调以增强最终用户的通信性能是一项重大挑战.在本文中,我们制定波束形成, ...

  8. 数据分析之Pandas和Numpy学习笔记(持续更新)<1>

    pandas and numpy notebook        最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...

  9. 深度强化学习:Policy-Based methods、Actor-Critic以及DDPG

    Policy-Based methods 在上篇文章中介绍的Deep Q-Learning算法属于基于价值(Value-Based)的方法,即估计最优的action-value function $q ...

随机推荐

  1. loadrunner 脚本优化-参数化方法

    脚本优化-参数化方法 by:授客 QQ:1033553122 方法一 1.确定需要参数化的内容 2.选中需要参数化的内容 3.右键选中的内容->Replace with a Parameter- ...

  2. 30分钟彻底弄懂flex布局

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由elson发表于云+社区专栏 目前在不考虑IE以及低端安卓机(4.3-)的兼容下,已经可以放心使用flex进行布局了.什么是flex布 ...

  3. 「破解」Xposed强

    「破解」Xposed强 Hook Hook Hook! 两张图片,第一张是我的微信截图,第二张是我从微信Hook出的一些类名. 一段代码,Hook这些类名出来的源码. 知道这些我们能干嘛,当然是分析( ...

  4. Android开启相机预览获取Yuv视频流数据

    自定义SurfaceView 主要步骤: 实现SurfaceHolder.Callback接口,创建SurfaceView的生命周期 实现Camera.PreviewCallback接口,创建预览回调 ...

  5. AndroBench手机性能测试

    AndroBench是一个基准测试应用程序,可以衡量你的Android设备的存储性能. AndroBench提供两种方式,第一种可以快速与其他设备的存储进行比较. 第二种 SQLite可以查询数据库表 ...

  6. python拟合数据,并通过拟合的曲线去预测新值的方法

    from scipy import interpolate import matplotlib.pyplot as plt import numpy as np def f(x): x_points ...

  7. VBR的部署

    一.实验拓扑图 二.实验目标 通过部署Veeam Backup & replication,实现虚拟机的备份和还原. 三实验要求 1.  如图所示,开启实验环境.(请参考公众号以前的相关文档) ...

  8. centos7如何安装gcc5.4

    由于需要使用到cilk plus和std=c++14,所以决定将编译器升级. 基本教程如下: 1.下载GCC源码: wget ftp://mirrors.kernel.org/gnu/gcc/gcc- ...

  9. 分布式UUID的生成

    背景 最近有个项目:涉及到分布式计算,tps相对较高,流程之间是异步调用,流程间相互依赖的对象(涉及记录外键)需要持久化.这就衍生出了需要在JVM中快速生成分布式UUID的问题 方案 1.通过JDK标 ...

  10. 【Linux基础】大B和小b

    1.小b(bit) 在计算机科学中,bit(比特)是表示信息的最小单位,叫做二进制位,一般用0和1表示. 2.大B(Byte) Byte叫做字节,由8个位(8bit)组成一个字节(1Byte),用于表 ...