1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 动手学强化学习第六章(Dyna-Q算法)

动手学强化学习第六章(Dyna-Q算法)

时间:2023-01-15 06:46:39

相关推荐

动手学强化学习第六章(Dyna-Q算法)

文章目录

Dyna-Q算法1.理论部分2.代码实践

Dyna-Q算法

文章转载自《动手学强化学习》/chapter/intro

1.理论部分

Dyna-Q 算法是一个经典的基于模型的强化学习算法。

Dyna-Q 使用一种叫做 Q-planning 的方法来基于模型生成一些模拟数据,然后用模拟数据和真实数据一起改进策略。Q-planning 每次选取一个曾经访问过的状态,采取一个曾经在该状态下执行过的动作,通过模型得到转移后的状态以及奖励,并根据这个模拟数据,用 Q-learning 的更新方式来更新动作价值函数。

我的理解是与Q-learning相比就是将过去的交互的数据存在一个字典中,之后训练的时候,每过一段时间从字典中抽取一些数据即(s,a,r,s‘)这种四元组用来更新Q表格,自我感觉和之后DQN中加经验池来利用历史数据的方式有些相识,不同之处在于这里存在字典中的数据相当于从已知模型中获取的数据,说起来就是model-based,而Q-learning,DQN都是model-free。

2.代码实践

代码参考自动手学强化学习(jupyter notebook版本):/boyu-ai/Hands-on-RL

使用pycharm打开的请查看:/zxs-000202/dsx-rl

方便的话给个star~

import matplotlib.pyplot as pltimport numpy as npfrom tqdm import tqdmimport randomimport timeclass CliffWalkingEnv:def __init__(self, ncol, nrow):self.nrow = nrowself.ncol = ncolself.x = 0 # 记录当前智能体位置的横坐标self.y = self.nrow - 1 # 记录当前智能体位置的纵坐标def step(self, action): # 外部调用这个函数来改变当前位置# 4种动作, change[0]:上, change[1]:下, change[2]:左, change[3]:右。坐标系原点(0,0)# 定义在左上角change = [[0, -1], [0, 1], [-1, 0], [1, 0]]self.x = min(self.ncol - 1, max(0, self.x + change[action][0]))self.y = min(self.nrow - 1, max(0, self.y + change[action][1]))next_state = self.y * self.ncol + self.xreward = -1done = Falseif self.y == self.nrow - 1 and self.x > 0: # 下一个位置在悬崖或者目标done = Trueif self.x != self.ncol - 1:reward = -100return next_state, reward, donedef reset(self): # 回归初始状态,起点在左上角self.x = 0self.y = self.nrow - 1return self.y * self.ncol + self.xclass DynaQ:""" Dyna-Q算法 """def __init__(self,ncol,nrow,epsilon,alpha,gamma,n_planning,n_action=4):self.Q_table = np.zeros([nrow * ncol, n_action]) # 初始化Q(s,a)表格self.n_action = n_action # 动作个数self.alpha = alpha # 学习率self.gamma = gamma # 折扣因子self.epsilon = epsilon # epsilon-贪婪策略中的参数self.n_planning = n_planning #执行Q-planning的次数, 对应1次Q-learningself.model = dict() # 环境模型def take_action(self, state): # 选取下一步的操作if np.random.random() < self.epsilon:action = np.random.randint(self.n_action)else:action = np.argmax(self.Q_table[state])return actiondef q_learning(self, s0, a0, r, s1):td_error = r + self.gamma * self.Q_table[s1].max() - self.Q_table[s0, a0]self.Q_table[s0, a0] += self.alpha * td_errordef update(self, s0, a0, r, s1):self.q_learning(s0, a0, r, s1)self.model[(s0, a0)] = r, s1 # 将数据添加到模型中for _ in range(self.n_planning): # Q-planning循环# 随机选择曾经遇到过的状态动作对(s, a), (r, s_) = random.choice(list(self.model.items()))self.q_learning(s, a, r, s_)def DynaQ_CliffWalking(n_planning):ncol = 12nrow = 4env = CliffWalkingEnv(ncol, nrow)epsilon = 0.01alpha = 0.1gamma = 0.9agent = DynaQ(ncol, nrow, epsilon, alpha, gamma, n_planning)num_episodes = 300 # 智能体在环境中运行多少条序列return_list = [] # 记录每一条序列的回报for i in range(10): # 显示10个进度条# tqdm的进度条功能with tqdm(total=int(num_episodes / 10),desc='Iteration %d' % i) as pbar:for i_episode in range(int(num_episodes / 10)): # 每个进度条的序列数episode_return = 0state = env.reset()done = Falsewhile not done:action = agent.take_action(state)next_state, reward, done = env.step(action)episode_return += reward # 这里回报的计算不进行折扣因子衰减agent.update(state, action, reward, next_state)state = next_statereturn_list.append(episode_return)if (i_episode + 1) % 10 == 0: # 每10条序列打印一下这10条序列的平均回报pbar.set_postfix({'episode':'%d' % (num_episodes / 10 * i + i_episode + 1),'return':'%.3f' % np.mean(return_list[-10:])})pbar.update(1)return return_listnp.random.seed(0)random.seed(0)n_planning_list = [0, 2, 20]for n_planning in n_planning_list:print('Q-planning步数为:%d' % n_planning)time.sleep(0.5)return_list = DynaQ_CliffWalking(n_planning)episodes_list = list(range(len(return_list)))plt.plot(episodes_list,return_list,label=str(n_planning) + ' planning steps')plt.legend()plt.xlabel('Episodes')plt.ylabel('Returns')plt.title('Dyna-Q on {}'.format('Cliff Walking'))plt.show()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。