Python实现的Q-Learning入门Demo

强化学习及Q-Learning算法的简单理解

首先明确学习的概念,学习是系统为了适应环境而做出的长久的变化,以便在未来更有效率的处理类似的问题

强化学习就是通过算法和训练,让程序的产生相应的变化,未来更好地处理类似问题。

强化学习主要分为两部分:

  1. 学习系统本身(即学习程序)
  2. 环境(即学习程序要解决的问题所处的环境)

强化学习的流程:

  1. 系统判定当前状态,根据策略采取行动
  2. 系统获得环境的反馈
  3. 系统根据反馈,更新策略
  4. 重复上述步骤,直到问题解决

强化学习的特点:

  1. 强化学习是一种无监督学习
  2. 在状态S下,不同的行动A会有不同的反馈R
  3. 反馈R的获得,通常是有延时的
  4. 当前行动A,会对系统后续的行为产生影响

Q-Learning就是其中一种简单的系统实现,通过Q-Table的不断更新,来产生长久的变化。

在强化学习中,通常用Q(S, A)来表示状态S下,采取动作A所带来的价值,所以这个算法就用Q-Learning作了它的名字。

Q-Learning核心思想:

关键点:状态、策略、行动、反馈

  • 通过Q-Table来记录每个状态S可以采用的行动A,Q-Table是一个二维矩阵,每一行代表一个状态,每一列代表一个行动,Q(S,A)的值表示在状态S下,采取行动A的权重(或者说成是能取得的收益)。
  • 特定的策略,在状态S下,通过Q-Table和策略,决定行动A;通常使用的策略是,在状态S下,找到Q(S, A)值最大的那一个A作为当前行动,为避免初始状态下的局部最优情况,通常还会引入随机性。
  • 反馈的获得,可以通过「反馈表」或者是「反馈算法」来获得环境对行动A的反馈R(S, A)。R(S, A)表示在状态S下,采取行动A,获得的反馈。
  • 策略更新,通过贝尔曼方程进行计算,更新Q-Table

Q-Table更新公式:

Q(s,a)Q(s,a)+α[r+γmaxaQ(s,a)Q(s,a)]

参数说明:

α是学习速率,在[0,1]区间取值,表示反馈对当前策略的影响程度。0表示完全不考虑反馈,1表示只看反馈,不看历史经验。

r表示R(S, A),通过「反馈表」或者「反馈算法」获得的反馈值

maxaQ(s,a) 解释:s是状态S时采取行动A之后到达的状态;maxaQ(s,a) 表示在s′状态时,能获得的最大Q值,即历史经验,或者说是记忆中的利益

γ表示折扣因子,代表历史经验中未来利益的重要性,如果为0,表示只看眼前利益r

 

实现步骤:

  1. 初始化Q-Table
  2. 定义Reward获取方法
  3. 制定策略,即在状态S下,如何通过Q-Table选取行动A
  4. 初始化状态S,可以固定,也可以随机
  5. 根据当前状态S,采取行动A,并获得反馈R
  6. 使用更新公式,对Q-Table进行更新
  7. 重复步骤5,6,直到命中退出条件(比如成功、失败、走出了迷宫、到达了目的地等等)
  8. 重复4-7流程N次,N代表训练的回合数

 

Demo:

"-----T"

比如上面的一个字符串,机器人从任意一点进入字符串,可以向左或者向右走一步,最终的目标是走到字母T的位置。

我们的code进行20次训练,得到更新后Q-Table,这时机器人再进入字符串,就能以最效率的方式,走到字母T

 

import numpy as np
#by Jarek.Tan ALPHA
= 0.1 GAMMA = 0.9 EPSILON = 0.9 EPOCH = 20 N_STATE = 6 ACTIONS = ["left", "right"] np.random.seed(2) Q_Table = np.zeros((N_STATE, len(ACTIONS))) def get_reward(S, A): if S == 5: R = 1 elif S == 4 and A == 'right': # S!=5 R = 1 else: R = 0 return R def take_action(S): if S == 0: return 1, 'right', np.max(Q_Table[1, :]) maxQ = np.max(Q_Table[S, :]) if maxQ == 0 or np.random.uniform() > EPSILON: if maxQ == 0: print("maxQ is 0") else: print("Random 0.1 hit") action = np.random.choice(ACTIONS) else: idx = np.argmax(Q_Table[S, :]) print("IDX:", idx) action = ACTIONS[idx] if action == 'left': SN = S - 1 else: SN = S + 1 maxQ = np.max(Q_Table[SN, :]) return SN, action, maxQ def get_value(S, A): if A == 'left': return Q_Table[S, 0] else: return Q_Table[S, 1] def set_value(S, A, V): if A == 'left': Q_Table[S, 0] = V else: Q_Table[S, 1] = V def update_q(S, A, MQ): value = (1 - ALPHA) * get_value(S, A) + ALPHA * (get_reward(S, A) + GAMMA * MQ) set_value(S, A, value) for loop in range(EPOCH): print("Loop:", loop) S = 0 step = 0 steps = [] while S != 5: SN, action, maxQ = take_action(S) update_q(S, action, maxQ) S = SN step += 1 steps.append(action) print("State:", S, "TotalSteps:", step, "\nDetail:", steps) print("Q_Table:", Q_Table)

 

posted @ 2020-04-17 01:20  JarekTan  阅读(546)  评论(0编辑  收藏  举报