上篇介绍了小明的一维世界模型 、Q-learning的状态空间、行动空间、奖励函数、Q-table、Q table更新公式、以及从Q值导出策略的公式等。最后给出最简单的一维位置世界的Q-learning例子,从给出其状态空间、行动空间、以及稠密与稀疏两种奖励函数的设置方式。下面将继续深入,GO!
一维的速度世界
这个世界,小明只能控制自己的速度,并且只能对速度进行如下三种操作:增加1、减少1、或者不变。所以行动空间为:
此刻,小明除了位置信息,还具有速度信息,所以状态为二维的。其中,为小明时刻的位置,为小明时刻的速度。此处,小明的速度空间和位置空间一样也是离散的。不失一般性,此处速度空间设定为
此处需要注意,我们定义的状态空间,包括了当前的位置和速度信息。我们稍稍想一下,速度和位置对于速度世界的小明来说,都很重要。我偿试过,只利用位置当作状态,奖励函数变为,小明的行动还是对速度进行增减1、或不变三个动作。最后给它一个很大的训练次数,发现仍然收敛不了,最终的策略是,小明从最左往中间走,经过中点继续往右走,到达最右又往左走,这样一直最左到最右、最右到最左反复做简谐振动,就是不会停在中间那块石头上。所以说,对于速度世界,小明自身的速度信息是很重要的,不能不加进状态里。换句话说,小明最终成功的评判与位置和速度有直接关系——到达中间的石头的时候速度也为零。后一节的加速度世界也是这样,小明在到达中间那块石头上时,加速度与速度正好为零,所以下一节,我们将小明的加速度、速度、以及位置都作为状态的必要信息。这是一个简单的世界,我们可以通过这样简单的分析,得到小明它需要哪些信息。那么,对于很复杂的世界,例如小明能够获取视觉信息,一张图片中的每个像素点都是一个信息。但是,不是所有的像素点都和当前任务相关。我们只要从这太过丰富的信息中提取出对任务有用的一小部分信息作为状态就足够了。
简而言之有三:
(1)选择哪些可用的信息作为状态对于Q-learning训练的效率很重要,甚至影响它能不能成功学习到合适的策略。
(2)状态中包括的信息不是越多越好,太多无关的信息会把有用的信息湮没掉,这样会使机器人学不到数据中包含的策略。
(3)真实的Q-learning的有效性,需要很多小trick,例如:特征提取、降维、奖励函数设计等。
根据组合原则,小明的状态总共有个。状态空间如下所示部分:
为了加快收敛速度,此处采用稠密奖励函数:,当小明在中间石时,并且速度为零时,奖励最大。
此时的为的矩阵。
- 训练
import numpy as np
def model_update(x, v, a):
v = v+a
x = x+v
if v < -3: # 保证速度在区间内[-3, 3]
v = -3
if v> 3:
v = 3
if x < -10: #保证位置在区间内[-10, 10]
x = -10
if x > 10:
x = 10
return x, v
xt = np.random.randint(-9, 10) #随机初始状态
vt = np.random.randint(-2, 3)
Q_table = np.zeros((147, 3)) #初始Q table 中的值全为零
for i in range(50000):
a = np.random.randint(0,3)-1
xt1, vt1 = model_update(xt, vt, a)
r = -abs(xt1)-abs(vt1)
Q_table[(vt+3)*21+xt+10, a+1] = r+0.9*np.max(Q_table[(vt1+3)*21+xt1+10]) # 更新Q table
xt = xt1
vt = vt1
复制代码
- 利用策略
初始状态为最左,速度最小,也即
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
is_ipython = 'inline' in matplotlib.get_backend()
if is_ipython:
from IPython import display
plt.ion()
xt = -10
vt = -3
x = np.arange(-10, 11)
y = np.zeros(21)
for i in range(30):
a = np.argmax(Q_table[(vt+3)*21+xt+10])-1
xt1, vt1 = model_update(xt, vt, a)
# print(xt, vt, a, xt1, vt1)
xt = xt1
vt = vt1
plt.clf()
plt.plot(x, y, 'ob')
plt.plot(0.0, 0.0, 'or')
plt.plot(xt,[0], 'og')
plt.pause(1)
if is_ipython:
display.clear_output(wait=True)
display.display(plt.gcf())
复制代码
steps.
1.(-10, -3, 1, -10, -2)
2.(-10, -2, 1, -10, -1)
3.(-10, -1, 1, -10, 0)
4.(-10, 0, 1, -9, 1)
5.(-9, 1, 1, -7, 2)
6.(-7, 2, 1, -4, 3)
7.(-4, 3, -1, -2, 2)
8.(-2, 2, -1, -1, 1)
9.(-1, 1, 0, 0, 1)
10.(0, 1, -1, 0, 0)
11.(0, 0, 0, 0, 0)
动态图——绿色的点代表小明
我们发现,小明从最左到中间点的过程,有一个先加速后减速的过程,跳一格、跳二格、跳三格、跳二格、跳一格。这说明,速度控制是有效的,更加接近我们看到喜欢的事物的真实状态,先加速跑过去,然后减速。但是,有时候人做的不够好,刹不住脚。