简单的Q-learning|小明的一维世界(1)
简单的Q-learning|小明的一维世界(2)
一维的加速度世界
这个世界,小明只能控制自己的加速度,并且只能对加速度进行如下三种操作:增加1、减少1、或者不变。所以行动空间为: { u 1 = − 1 , u 2 = 0 , u 3 = 1 } \{u_1=-1, u_2=0, u_3=1\} {u1=−1,u2=0,u3=1}
补充:为了不和加速度符号 a a a混淆,此处动作标记全改成 u u u。
此刻,小明除了位置信息,还具有速度信息,所以状态为三维的
s
t
=
<
x
t
,
v
t
,
a
t
>
s_t=<x_t,v_t,a_t>
st=<xt,vt,at>。其中,
x
t
x_t
xt为小明
t
t
t时刻的位置,
v
t
v_t
vt为小明
t
t
t时刻的速度,
a
t
a_t
at为小明在
t
t
t时刻的加速度。此处,小明的加速度空间也是离散的。不失一般性,此处加速度空间设定为
{
a
1
=
−
2
,
a
2
=
−
1
,
a
3
=
0
,
a
4
=
1
,
a
5
=
2
}
\{a_1=-2, a_2=-1, a_3=0, a_4=1, a_5=2\}
{a1=−2,a2=−1,a3=0,a4=1,a5=2}
根据组合原则,小明的状态总共有
21
×
7
×
5
=
735
21\times 7 \times 5=735
21×7×5=735个。状态空间如下所示部分:
S
=
{
s
1
=
<
x
1
,
v
1
,
a
1
>
,
s
2
=
<
x
2
,
v
1
,
a
1
>
,
.
.
.
,
s
147
=
<
x
21
,
v
7
,
a
5
>
}
S=\{s_1=<x_1, v_1, a_1>, s_2=<x_2, v_1, a_1>,...,s_{147}=<x_{21}, v_7, a_5>\}
S={s1=<x1,v1,a1>,s2=<x2,v1,a1>,...,s147=<x21,v7,a5>}
为了加快收敛速度,此处采用稠密奖励函数: r ( s ) = − ∣ x ∣ − ∣ v ∣ − ∣ a ∣ r(s)=-|x|-|v|-|a| r(s)=−∣x∣−∣v∣−∣a∣,当小明在中间石时,并且速度为零时,奖励最大。
此时的 Q t a b l e Q_{table} Qtable为 735 × 3 735\times 3 735×3的矩阵。
- 训练
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def model_update(x, v, a, u):
a = a+u
if a < -2: # 保证加速度在区间[-2,2]
a = -2
if a > 2:
a = 2
v = v+a
if v < -3: # 保证速度在区间[-3,3]
v = -3
if v> 3:
v = 3
x = x+v
if x < -10: # 保证位置在区间[-10, 10]
x = -10
if x > 10:
x = 10
return x, v, a
xt = np.random.randint(-9, 10) # 随机初始化状态
vt = np.random.randint(-2, 3)
at = np.random.randint(-1, 2)
Q_table = np.zeros((735, 3)) # 初始化Q值为零
for i in range(5000000):
u = np.random.randint(0,3)-1
xt1, vt1, at1 = model_update(xt, vt, at, u)
r = -abs(xt1)-abs(vt1)-abs(at1)
Q_table[((at+2)*7+(vt+3))*21+xt+10, u+1] = r+0.9*np.max(Q_table[((at1+2)*7+(vt1+3))*21+xt1+10]) # 更新Q值
xt = xt1
vt = vt1
at = at1
- 利用策略
初始状态为最左,速度最小,也即 s 0 = < − 10 , − 3 , − 2 > s_0=<-10, -3, -2> s0=<−10,−3,−2>
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
at = -2
x = np.arange(-10, 11)
y = np.zeros(21)
for i in range(100):
u = np.argmax(Q_table[((at+2)*7+(vt+3))*21+xt+10])-1
xt1, vt1, at1= model_update(xt, vt, at, u)
print(xt, vt, at, u , xt1, vt1, at1)
xt = xt1
vt = vt1
at = at1
plt.clf()
plt.plot(x, y, 'b')
plt.plot(xt,[0], 'or')
plt.pause(0.1)
if is_ipython:
display.clear_output(wait=True)
display.display(plt.gcf())
steps.
(
x
t
,
v
t
,
a
t
,
u
t
,
x
t
+
1
,
v
t
+
1
,
a
t
+
1
)
(x_t, v_t, a_t, u_t, x_{t+1}, v_{t+1}, a_{t+1})
(xt,vt,at,ut,xt+1,vt+1,at+1)
1.
(
−
10
,
−
3
,
−
2
,
1
,
−
10
,
−
3
,
−
1
)
(-10, -3, -2, 1, -10, -3, -1)
(−10,−3,−2,1,−10,−3,−1)
2.
(
−
10
,
−
3
,
−
1
,
1
,
−
10
,
−
3
,
0
)
(-10, -3, -1, 1, -10, -3, 0)
(−10,−3,−1,1,−10,−3,0)
3.
(
−
10
,
−
3
,
0
,
1
,
−
10
,
−
2
,
1
)
(-10, -3, 0, 1, -10, -2, 1)
(−10,−3,0,1,−10,−2,1)
4.
(
−
10
,
−
2
,
1
,
1
,
−
10
,
0
,
2
)
(-10, -2, 1, 1, -10, 0, 2)
(−10,−2,1,1,−10,0,2)
5.
(
−
10
,
0
,
2
,
−
1
,
−
9
,
1
,
1
)
(-10, 0, 2, -1, -9, 1, 1)
(−10,0,2,−1,−9,1,1)
6.
(
−
9
,
1
,
1
,
0
,
−
7
,
2
,
1
)
(-9, 1, 1, 0, -7, 2, 1)
(−9,1,1,0,−7,2,1)
7.
(
−
7
,
2
,
1
,
−
1
,
−
5
,
2
,
0
)
(-7, 2, 1, -1, -5, 2, 0)
(−7,2,1,−1,−5,2,0)
8.
(
−
5
,
2
,
0
,
0
,
−
3
,
2
,
0
)
(-5, 2, 0, 0, -3, 2, 0)
(−5,2,0,0,−3,2,0)
9.
(
−
3
,
2
,
0
,
0
,
−
1
,
2
,
0
)
(-3, 2, 0, 0, -1, 2, 0)
(−3,2,0,0,−1,2,0)
10.
(
−
1
,
2
,
0
,
−
1
,
0
,
1
,
−
1
)
(-1, 2, 0, -1, 0, 1, -1)
(−1,2,0,−1,0,1,−1)
11.
(
0
,
1
,
−
1
,
0
,
0
,
0
,
−
1
)
(0, 1, -1, 0, 0, 0, -1)
(0,1,−1,0,0,0,−1)
12.
(
0
,
0
,
−
1
,
1
,
0
,
0
,
0
)
(0, 0, -1, 1, 0, 0, 0)
(0,0,−1,1,0,0,0)
13.
(
0
,
0
,
0
,
0
,
0
,
0
,
0
)
(0, 0, 0, 0, 0, 0, 0)
(0,0,0,0,0,0,0)
动态图——绿色的点代表小明
此处测试的初始状态都是取最坏的值,所以,步长可能会长一点。如果是从最左位置出发时,初始速度为0,初始加速度为0,则最后从最左到中间位置的所需步长:加速度世界<速度世界<位置世界。不过这和速度与加速度设定的区间是有关系的。总体来说,加速度世界比速度世界更加灵活,反应更快;而速度世界中,小明的反应又比位置世界中反应快,而不是傻傻的一步一个脚印。
##结语
到此,小明的一维世界系统到此就完结了。从一维的位置世界到一维的速度世界,再到一维的加速度世界。世界从易到难,状态个数从少到多,训练所需步长从少到多。当然,这都是在基于Q-table的Q-learning算法中,如果将Q-table换成表征能力更强的neural network,我们又可以做更复杂更有意思的事情了。