qpython 教程_极简Qlearning教程(附Python源码)

极简Qlearning入门教程

在当前的机器学习中,主流方向为有监督学习、无监督学习以及强化学习,今天我想介绍的就是强化学习的一个小入门Qleaning算法。

回想我们小时候在妈妈的教育下进行学习,首先我们是什么都不会,但是在父母的教育下,慢慢地开始学习起来,比如看见猫,第一次见到不知道这是什么物种,于是妈妈告诉你这是猫,下次见到就知道了,这就是监督学习,当我们做出一个动作,立即得到反馈,而强化学习则不然,当我们做出动作的时候,却不会有立即的反馈,只能到结束才能知道效果,因此本人在学习的过程中,将网上的资料收集了一下,发现这篇文章是特别棒的http://mnemstudio.org/path-finding-q-learning-tutorial.htm

假设有这样的房间

这样看,我们可以将其进行建模:

这就是房间对应的图。我们首先将agent(机器人)处于任何一个位置,让他自己走动,直到走到5房间,表示成功。为了能够走出去,我们将每个节点之间设置一定的权重,能够直接到达5的边设置为100,其他不能的设置为0,这样网络的图为:

Qlearning中,最重要的就是“状态”和“动作”,状态表示处于图中的哪个节点,比如2节点,3节点等等,而动作则表示从一个节点到另一个节点的操作。

首先我们生成一个奖赏矩阵:

-1表示不可以通过

0表示可以通过

100表示直接到达终点

总结就是:R矩阵中非负的表示节点之间是可以相通的。

同时,我们创建一个Q表,表示学习到的经验,与R表同阶,初始化为0矩阵。

根据Q-learning转移方程:

S表示当前的状态

a表示当前的动作

s~表示下一个状态

a~表示下一个动作

λ为贪婪因子,0

下面就是Qlearning的学习步骤:

当Q表学习完以后,就可以根据Q表来选择路径。

看一个实际的例子

首先设定λ=0.8,R:

Q:

随机选择一个状态,比如1,查看状态1所对应的R表,也就是1可以到达3或5,随机地,我们选择5,根据转移方程:

于是,Q表为:

这样,到达目标,一次尝试结束。

接下来再选择一个随机状态,比如3,3对应的下一个状态有(1,2,4都是状态3对应的非负状态),随机地,我们选择1,这样根据算法更新:

这样,Q表为

到达1状态以后,可以直接到达5,这样一次训练也完成了。

这样,我们将上面的解答转换为代码,采用Python编写。

import numpy as np

import random

# 建立 Q 表

q = np.zeros((6, 6))

q = np.matrix(q)

# 建立 R 表

r = np.array([[-1, -1, -1, -1, 0, -1], [-1, -1, -1, 0, -1, 100], [-1, -1, -1, 0, -1, -1], [-1, 0, 0, -1, 0, -1],

[0, -1, -1, 0, -1, 100], [-1, 0, -1, -1, 0, 100]])

r = np.matrix(r)

# 贪婪指数

gamma = 0.8

开始训练:

for i in range(1000):

# 对每一个训练,随机选择一种状态

state = random.randint(0, 5)

while state != 5:

# 选择r表中非负的值的动作

r_pos_action = []

for action in range(6):

if r[state, action] >= 0:

r_pos_action.append(action)

next_state = r_pos_action[random.randint(0, len(r_pos_action) - 1)]

q[state, next_state] = r[state, next_state] + gamma * q[next_state].max()

state = next_state

经过训练后,Q表为

当我们的Q表训练好,就可以根据Q表来进行路径选择。

选择算法如下:

这样,对应的代码如下:

state = random.randint(0, 5)

print('机器人处于{}'.format(state))

count = 0

while state != 5:

if count > 20: # 如果尝试次数大于20次,表示失败

print('fail')

break

# 选择最大的q_max

q_max = q[state].max()

q_max_action = []

for action in range(6):

if q[state, action] == q_max: # 选择可行的下一个动作

q_max_action.append(action)

# 随机选择一个可行的动作

next_state = q_max_action[random.randint(0, len(q_max_action) - 1)]

print("the robot goes to " + str(next_state) + '.')

state = next_state

这样,整个训练效果就是这样。,整体代码如下:

import numpy as np

import random

# 建立 Q 表

q = np.zeros((6, 6))

q = np.matrix(q)

# 建立 R 表

r = np.array([[-1, -1, -1, -1, 0, -1], [-1, -1, -1, 0, -1, 100], [-1, -1, -1, 0, -1, -1], [-1, 0, 0, -1, 0, -1],

[0, -1, -1, 0, -1, 100], [-1, 0, -1, -1, 0, 100]])

r = np.matrix(r)

# 贪婪指数

gamma = 0.8

# 训练

for i in range(1000):

# 对每一个训练,随机选择一种状态

state = random.randint(0, 5)

while state != 5:

# 选择r表中非负的值的动作

r_pos_action = []

for action in range(6):

if r[state, action] >= 0:

r_pos_action.append(action)

next_state = r_pos_action[random.randint(0, len(r_pos_action) - 1)]

q[state, next_state] = r[state, next_state] + gamma * q[next_state].max()

state = next_state

print(q)

# 验证

for i in range(10):

print("第{}次验证".format(i + 1))

state = random.randint(0, 5)

print('机器人处于{}'.format(state))

count = 0

while state != 5:

if count > 20:

print('fail')

break

# 选择最大的q_max

q_max = q[state].max()

q_max_action = []

for action in range(6):

if q[state, action] == q_max:

q_max_action.append(action)

next_state = q_max_action[random.randint(0, len(q_max_action) - 1)]

print("the robot goes to " + str(next_state) + '.')

state = next_state

count += 1

输出效果:

如果觉得这篇文章有用,请留言,谢谢。

你可能感兴趣的:(qpython,教程)