目录
前言:寄语
这是一门深度强化学习基础实践课程,为了避免大家被数学公式劝退,理论方面讲的不是太深,科老师是两度世界冠军,说这是目前国内最好的强化学习实践课程也不为过,强化学习是机器学习的最强范式,主要是负责决策,和负责感知的深度学习结合起来,就构成了强人工智能,是未来人工智能最令人激动和期待的地方
基础准备和预习
学习这门课需要以下基础:
1,高等数学
2,线性代数
3,概率论
4,Python面向对象编程
5,Numpy
数学基础不太好的同学可以先跳过部分数学知识点,先从编程算法入手,多Print一下状态信息,对算法流程有一定的理解后,再去看理论推导,看理论的时候一定要看图书,图书歧义少,一般都是经过时间检验的,实践的话推荐看视频上手快。
学习这门课程最好对强化学习理论有一定的基础理论理解,这样上手更快一些,科老师后面的课程不解释这些基础概念
1,状态值函数 state value function
2, 状态-动作值函数 state-action value function
3, bellman方程
第一节课:玩个简单的迷宫游戏吧
游戏目标:让Agent小乌龟自己学会避开所有的陷阱,走到目的地,拿到最终奖励
游戏结果:小乌龟通过不停的action试错,从当前的状态state1,转移到下一个状态state2,获得奖励R,然后综合评价所有的策略,把产生的最大奖励值的作为最优策略,用最少的步数走到目的地,是不是很神奇。
接下来就是谈一下什么是强化学习了,简单来说,强化学习的目的是为了求得最优策略,而深度学习则是为了拟合非线性和感知认知
打个广告:推荐一下百度强化学习框架PARL,支持并行计算,能够让学习速率大大的提升,对于初学者,这是一个非常友好的框架,而且源代码是开源的,学有余力的同学可以去学源码
源码链接
https://github.com/PaddlePaddle/PARL
第二节课:基于表格型方法求解RL
首先解释下我们为什么要求解RL,这个概念非常重要,总的来说,求解RL的本质就是求解状态值函数或者动作状态值函数,只有知道这两个函数里面的任何一个,我们才能找到最优策略,才能告诉Agent怎么走才是最优的,获得的累计奖励最大,当然也可以直接求解优化策略
1, SARSA算法
用白话来讲,SARSA算法的表现形式是Q(S,A),即对某个状态下的一个动作做估值计算,以下是实践代码
pip install gym
import gym
import numpy as np
import time
class SarsaAgent(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):
#
# 1. 请完成sample函数功能
if np.random.uniform(0,1) < (1.0 - self.epsilon):
action = self.predict(obs)
else:
action = np.random.choice(self.act_n)
return action
#
# 根据输入观察值,预测输出的动作值
def predict(self, obs):
# 2. 请完成predict函数功能
Q_list = self.Q[obs, :]
maxQ = np.max(Q_list)
action_list = np.where(Q_list == maxQ)[0]
action = np.random.choice(action_list)
return action
#学习方法,也就是更新Q-table的方法
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是否结束
"""
# 3. 请完成learn函数功能(Sarsa)
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
# 保存Q表格数据到文件
def save(self):
npy_file = './q_table.npy'
np.save(npy_file, self.Q)
print(npy_file + ' saved.')
# 从文件中读取数据到Q表格中
def restore(self, npy_file='./q_table.npy'):
self.Q = np.load(npy_file)
print(npy_file + ' loaded.')``
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
def test_episode(env, agent):
total_reward = 0
obs = env.reset()
while True:
action = agent.predict(obs) # greedy
next_obs, reward, done, _ = env.step(action)
total_reward += reward
obs = next_obs
# time.sleep(0.5)
# env.render()
if done:
break
return total_reward
```python
在这里插入代码片
2,Q-Learning算法
算法展示,总的来说结构和Sarsa很类似,算法最大的区别是更新公式不一样Sarsa选择的是后一个动作整体的期望,Q-Learning选择的是后一个动作的最大值,下面是演示代码
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)