2.1 MDP、状态价值&Q表格
2.1.1 MDP(马尔可夫决策过程)四元组<S,A,P,R>
2.1.2 Q表格:状态动作价值
Q表格就像是一本生活经验手册,上面记录着不同情况(State)下,不同行动(Action)所带来的价值(Reward)。往往同一个行动在不同情况下会产生不同的价值,生活中也是如此。
为了实现最大效益,我们往往不能只看眼前效益,很多时候我们需要关注一系列行动所带来的未来总收益,但只关注未来总收益未必合理,因此,引入了衰减因子γ(伽马),让模型更贴近实际情况。
2.2 背景知识:Q表格、强化概念、状态价值、TD单步更新&Agent介绍
2.2.1 悬崖问题
Tip: Gt表示从t时刻开始往后的所有收益总和
2.2.2 Q表格指导每一步动作
在最开始,因为我们还不知道每个state(位置)的action(行动,上下左右)带来的reward(收益)是多少,因此,需要新建一张数值全部为零的空表格。可通过下面的代码新建一个空的Q表格。
self.Q = np.zeros((obs_n, act_n)) # obs_n为状态数量,act_n为动作数量
2.2.3 强化概念
从条件反射这一生理现象中,我们可以发现强化学习背后的原理:在不断重复试验之后,下一个状态的价值可以不断强化影响上一个状态的价值。
2.2.4 状态价值迭代
https://cs.stanford.edu/people/karpathy/reinforcejs/gridworld_td.html
在这个例子中,灰色是“墙壁”,标注了R值的格子表示小球到达该格子所能得到的reward值(-1/1)。
小球在刚开始探索时是没有明确方向的,在经过多轮探索之后,小球发现了几条通往高价值格子的路径(R=1.0的格子),R=1.0格子附近格子的价值也因此提升。最终,在小球不断往持续更新的高价值格子的移动过程中,小球发现一条通往R=1.0格子的最优路径。
2.2.5 Temporal Difference时序差分(TD单步更新)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nT1WAVpM-1593056949853)(/home/kevinpang/Documents/强化学习——学习笔记/Lesson2/image-20200622144645386.png)]
特点:
- 用下一步的Q值来更新这一步的Q值
- 更新方式为软更新
- 需要的信息:当前的状态,当前的行动,下一状态的收获,下一状态,下一状态的行动。
2.2.6 Agent——与环境交互的智能体
agent的主要工作:
- 根据Q表格选取动作
- 更新Q表格
2.3 Sarsa
2.3.1 Sarsa训练每一个episode的主要工作&流程
2.3.2 Sarsa Agent
2.3.2.1 ε-greedy方法的Exploration(探索)&Exploitation(利用)
Function:
predict根据已有数据预测sample采样要含有Q值的探索数据
# 根据输入观察值,采样输出的动作值,带探索
def sample(self, obs):
if np.random.uniform(0, 1) < (1.0 - self.epsilon): #根据table的Q值选动作
action = self.predict(obs)
else:
action = np.random.choice(self.act_n) #有一定概率随机探索选取一个动作
return action
# 根据输入观察值,预测输出的动作值
def predict(self, obs):
Q_list = self.Q[obs, :]
maxQ = np.max(Q_list)
action_list = np.where(Q_list == maxQ)[0] # maxQ可能对应多个action
action = np.random.choice(action_list)
return action
2.3.2.2 Sarsa Agent——更新Q表格
def learn(self, obs, action, reward, next_obs, next_action, done):
""" on-policy
obs: 交互前的obs, s_t
action: 本次交互选择的action, a_t
reward: 本次动作获得的奖励r
next_obs: 本次交互后的obs, s_t+1
next_action: 根据当前Q表格, 针对next_obs会选择的动作, a_t+1
done: episode是否结束
"""
predict_Q = self.Q[obs, action]
if done:
target_Q = reward # 没有下一个状态了
else:
target_Q = reward + self.gamma * self.Q[next_obs,
next_action] # Sarsa
self.Q[obs, action] += self.lr * (target_Q - predict_Q) # 修正q
2.3.3 Sarsa Train——单步更新的Sarsa
在对Sarsa进行训练的过程中,单步更新(TD)的Sarsa每一个Step都输出一个动作并更新learn一次(agent.learn)
def run_episode(env, agent, render=False):
total_steps = 0 # 记录每个episode走了多少step
total_reward = 0
obs = env.reset() # 重置环境, 重新开一局(即开始新的一个episode)
action = agent.sample(obs) # 根据算法选择一个动作
while True:
next_obs, reward, done, _ = env.step(action) # 与环境进行一个交互
next_action = agent.sample(next_obs) # 根据算法选择一个动作
# 训练 Sarsa 算法
agent.learn(obs, action, reward, next_obs, next_action, done)
action = next_action
obs = next_obs # 存储上一个观察值
total_reward += reward
total_steps += 1 # 计算step数
if render:
env.render() #渲染新的一帧图形
if done:
break
return total_reward, total_steps
2.4 Q-learning
2.4.1 Q-learning&Sarsa流程对比——Target的区别
2.4.2 Q-learning Agent
2.4.2.1 Q-learning Agent——根据Q表格选动作
class QLearningAgent(object):
def __init__(self,
obs_n,
act_n,
learning_rate=0.01,
gamma=0.9,
e_greed=0.1):
self.act_n = act_n # 动作维度,有几个动作可选
self.lr = learning_rate # 学习率
self.gamma = gamma # reward的衰减率
self.epsilon = e_greed # 按一定概率随机选动作
self.Q = np.zeros((obs_n, act_n))
# 根据输入观察值,采样输出的动作值,带探索
def sample(self, obs):
if np.random.uniform(0, 1) < (1.0 - self.epsilon): #根据table的Q值选动作
action = self.predict(obs)
else:
action = np.random.choice(self.act_n) #有一定概率随机探索选取一个动作
return action
# 根据输入观察值,预测输出的动作值
def predict(self, obs):
Q_list = self.Q[obs, :]
maxQ = np.max(Q_list)
action_list = np.where(Q_list == maxQ)[0] # maxQ可能对应多个action
action = np.random.choice(action_list)
return action
2.4.2.2 Q-learning Agent——更新Q表格
def learn(self, obs, action, reward, next_obs, done):
""" off-policy
obs: 交互前的obs, s_t
action: 本次交互选择的action, a_t
reward: 本次动作获得的奖励r
next_obs: 本次交互后的obs, s_t+1
done: episode是否结束
"""
predict_Q = self.Q[obs, action]
if done:
target_Q = reward # 没有下一个状态了
else:
target_Q = reward + self.gamma * np.max(
self.Q[next_obs, :]) # Q-learning
self.Q[obs, action] += self.lr * (target_Q - predict_Q) # 修正Q(更新Q值)
2.4.3 Q-learning Train的TD更新
def run_episode(env, agent, render=False):
total_steps = 0 # 记录每个episode走了多少step
total_reward = 0
obs = env.reset() # 重置环境, 重新开一局(即开始新的一个episode)
while True:
action = agent.sample(obs) # 根据算法选择一个动作
next_obs, reward, done, _ = env.step(action) # 与环境进行一个交互
# 训练 Q-learning算法
agent.learn(obs, action, reward, next_obs, done)
obs = next_obs # 存储上一个观察值
total_reward += reward
total_steps += 1 # 计算step数
if render:
env.render() #渲染新的一帧图形
if done:
break
return total_reward, total_steps
2.5 On-Policy & Off-Policy
On-Policy策略:
- 使用策略π与环境交互产生经验,由于需要兼顾探索,策略π并不稳定
- 代表算法:Sarsa
Off-Policy策略(目标策略π和行为策略μ):
- 目标策略π用于学习最优策略
- 行为策略μ更具探索性,与环境交互产生经验轨迹
- 代表算法:Q-learning, DQN
Lesson2 小结
补充:
gridworld.py使用指南
# 环境1:FrozenLake, 可以配置冰面是否是滑的
env = gym.make("FrozenLake-v0", is_slippery=False) # 0 left, 1 down, 2 right, 3 up
env = FrozenLakeWapper(env)
# 环境2:CliffWalking, 悬崖环境
env = gym.make("CliffWalking-v0") # 0 up, 1 right, 2 down, 3 left
env = CliffWalkingWapper(env)
# 环境3:自定义格子世界,可以配置地图, S为出发点Start, F为平地Floor, H为洞Hole, G为出口目标Goal
gridmap = [
'SFFF',
'FHFF',
'FFFF',
'HFGF' ]
env = GridWorld(gridmap)