参考自知乎(叶强)
Introduction
在实践2中,介绍了gym
环境的定义和使用方法。
在实践1中,介绍了 动态规划DP 求解 价值函数
并没有形成一个策略Policy(pi)来指导agent的动作选取,本节将利用SARSA(0)的学习方法,帮助agent学习到价值函数(表),指导(epsilon)-greedy策略选取动作。
Agent的写法
Agent的三要素是:价值函数、策略、模型 Sarsa(0)是不基于模型的控制,其动作选择策略是(epsilon)-greedy,根据价值函数选择动作。
对于一般问题,Agent包括如下功能
- 对环境的引用
- 自身变量:Q值,状态值的记忆
- 策略方法
- 动作执行方法
- 学习方法:改进策略,这部分是关键
class Agent():
def __init__(self, env: Env):
self.env = env # 个体持有环境的引用
self.Q = {} # 个体维护一张行为价值表Q
self.state = None # 个体当前的观测,最好写成obs.
def performPolicy(self, state): pass # 执行一个策略
def act(self, a): # 执行一个行为
return self.env.step(a)
def learning(self): pass # 学习过程
Agent方法
SARSA(0)的伪算法流程如下:
核心方法:learning
代码语言:javascript复制def learning(self, gamma, alpha, max_episode_num):
# self.Position_t_name, self.reward_t1 = self.observe(env)
total_time, time_in_episode, num_episode = 0, 0, 0
while num_episode < max_episode_num: # 设置终止条件
self.state = self.env.reset() # 环境初始化
s0 = self._get_state_name(self.state) # 获取个体对于观测的命名
self.env.render() # 显示UI界面
a0 = self.performPolicy(s0, num_episode, use_epsilon = True)
time_in_episode = 0
is_done = False
while not is_done: # 针对一个Episode内部
# a0 = self.performPolicy(s0, num_episode)
s1, r1, is_done, info = self.act(a0) # 执行行为
self.env.render() # 更新UI界面
s1 = self._get_state_name(s1)# 获取个体对于新状态的命名
self._assert_state_in_Q(s1, randomized = True)
# 获得A'
a1 = self.performPolicy(s1, num_episode, use_epsilon=True)
old_q = self._get_Q(s0, a0)
q_prime = self._get_Q(s1, a1)
td_target = r1 gamma * q_prime
#alpha = alpha / num_episode
new_q = old_q alpha * (td_target - old_q)
self._set_Q(s0, a0, new_q)
if num_episode == max_episode_num: # 终端显示最后Episode的信息
print("t:{0:>2}: s:{1}, a:{2:2}, s1:{3}".
format(time_in_episode, s0, a0, s1))
s0, a0 = s1, a1
time_in_episode = 1
print("Episode {0} takes {1} steps.".format(
num_episode, time_in_episode)) # 显示每一个Episode花费了多少步
total_time = time_in_episode
num_episode = 1
return
策略方法:performPolicy
通过改变use_epsilon
参数,可以切换SARSA 和 Q-learning
相同在于:
- 都用(epsilon)-greedy策略进行了探索
区别在于:
- Q-learning:更激进,最优更新
- update: (greedy)策略,评估过程的A'没有实际执行
- control:(epsilon-greedy)策略
- SARSA:更新和执行都用(epsilon-greedy)策略
def performPolicy(self, s, episode_num, use_epsilon):
epsilon = 1.00 / (episode_num 1)
Q_s = self.Q[s]
str_act = "unknown"
rand_value = random()
action = None
if use_epsilon and rand_value < epsilon:
action = self.env.action_space.sample()
else:
str_act = max(Q_s, key=Q_s.get)
action = int(str_act)
return action