Q-learning
Q-learningQ-learning也是采用Q表格的方式存储Q值(状态动作价值),决策部分与Sarsa是一样的,采用ε-greedy方式增加探索。Q-learning跟Sarsa不一样的地方是更新Q表格的方式。Sarsa是on-policy的更新方式,先做出动作再更新。Q-learning是off-policy的更新方式,更新learn()时无需获取下一步实际做出的动作next_action,
·
Q-learning
Q-learning也是采用Q表格的方式存储Q值(状态动作价值),决策部分与Sarsa是一样的,采用ε-greedy方式增加探索。
Q-learning跟Sarsa不一样的地方是更新Q表格的方式。
Sarsa是on-policy的更新方式,先做出动作再更新。
Q-learning是off-policy的更新方式,更新learn()时无需获取下一步实际做出的动作next_action,并假设下一步动作是取最大Q值的动作。
Q-learning的更新公式为:
agent.py
import numpy as np
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):
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]
action=np.random.choice(action_list)
return action
#学习方法,也就是更新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,:])
self.Q[obs,action]+=self.lr*(target_Q-predict_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.')
trian.py
import gym
from gridworld import CliffWalkingWapper,FrozenLakeWapper
from agent import QLearningAgent
import time
def run_episode(env,agent,render=False):
total_steps=0;
total_reward=0
obs=env.reset()
while True:
action=agent.sample(obs) #根据算法选择一个动作
next_obs,reward,done,_=env.step(action)
agent.learn(obs,action,reward,next_obs,done)
obs=next_obs
total_reward+=reward
total_steps+=1
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)
next_obs,reward,done,_=env.step(action)
total_reward+=reward
obs=next_obs
time.sleep(0.5)
env.render()
if done:
print('test reward = %.1f' % (total_reward))
break
def main():
env = gym.make("CliffWalking-v0") # 0 up, 1 right, 2 down, 3 left
env = CliffWalkingWapper(env)
agent=QLearningAgent(obs_n=env.observation_space.n,
act_n=env.action_space.n,
learning_rate=0.1,
gamma=0.9,
e_greed=0.1)
is_render=False
for episode in range(500):
ep_reward, ep_steps = run_episode(env, agent, is_render)
print('Episode %s: steps = %s , reward = %.1f' % (episode, ep_steps,
ep_reward))
# 每隔20个episode渲染一下看看效果
if episode % 20 == 0:
is_render = True
else:
is_render = False
# 训练结束,查看算法效果
test_episode(env, agent)
if __name__ == "__main__":
main()
更多推荐
所有评论(0)