本文作者: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. OkHttp3源码详解(六) Okhttp任务队列工作原理

    1 概述 1.1 引言 android完成非阻塞式的异步请求的时候都是通过启动子线程的方式来解决,子线程执行完任务的之后通过handler的方式来和主线程来完成通信.无限制的创建线程,会给系统带来大量 ...

  2. testNG安装一直失败解决方法

    1.在eclipse界面选择“Help”--"Eclipse Marketplace"中进行查找TestNG 然后进“install” (成功) 2.在eclipse界面选择“He ...

  3. eclipse安装中java环境的搭建

    转自博客园:amandaj  做了小小改动. 一.java 开发环境的搭建 这里主要说的是在windows 环境下怎么配置环境. 1.首先安装JDK java的sdk简称JDK ,去其官方网站下载最近 ...

  4. [Python][小知识][NO.4] wxPython 字体选择对话框(O.O 不知道放到那里就放到这个分类的)

    1.前言 O.O 前两天回家浪了两天,断更了 哎~~~ o.o 有时候,有木有想改标签或编辑框中内容的字体呀?(o.o 反正我是没有). wxpython也可以说是所在的操作系统,有字体选择器,给我们 ...

  5. C# DBHelper类 参考

    using System;using System.Collections.Generic;using System.Text;using System.Configuration;using Sys ...

  6. c/c++ 链栈

    c/c++ 链栈 链栈 下面的代码实现了以下功能 函数 功能描述 push 压入 pop 弹出 show_list 打印 clear 释放所有内存空间 destroy 释放所有内存空间 nodesta ...

  7. Windows Server 2016-Wbadmin命令行备份域控制器

    在上一章我们讲到Windows Server 2016-图形化备份域控制器的方法,本章我们聊聊如何通过命令行Wbadmin对域控制器进行备份.在Windows Server Active Direct ...

  8. python shell与反弹shell

    python shell与反弹shell 正常shell需要先在攻击端开机情况下开启程序,然后攻击端运行程序,才能连接 反弹shell,攻击端是服务端,被攻击端是客户端正常shell,攻击端是客户端, ...

  9. spring拦截器(interceptor)简介

    1. 拦截器用途 (1)拦截未登录用户直接访问某些链接 (2)拦截日志信息 (3)拦截非法攻击,比如sql注入 2. 涉及jar.类 (1)spring-webmvc.jar (2)HandlerIn ...

  10. [Hive_9] Hive 的排序

    0. 说明 全排序(order by) | 部分排序(sort by) | hash 分区(distribute by)  | cluster by 1. 前期准备 1.1 建表 create tab ...