Q-learning在OpenAI Gym的FrozenLake环境中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import time
import numpy as np
import gym

env = gym.make("FrozenLake-v1")

# 初始化Q表
qtable = np.zeros((env.observation_space.n, env.action_space.n))

train_mode = True # 控制是否进行训练

if train_mode:
start_time = time.time()

# 参数设定
total_episodes = 10000 # 训练的总回合数
learning_rate = 0.1 # 学习率
gamma = 0.98 # 折扣因子

for episode in range(total_episodes):
state = env.reset()
done = False

step = 0

while not done:
action = np.argmax(qtable[state, :] + np.random.randn(1, env.action_space.n)*(1./(step+1)))

# 执行动作并得到反馈
new_state, reward, done, info = env.step(action)

# 更新 Q-table 为 Q(s,a)
qtable[state, action] = qtable[state, action] + learning_rate * (reward + gamma * np.max(qtable[new_state, :]) - qtable[state, action])

state = new_state

step += 1

np.save('qtable.npy', qtable)

print("--- 训练耗时: %s 秒 ---" % (time.time() - start_time))

else:
qtable = np.load('qtable.npy')


start_time = time.time()

successes = 0

for episode in range(10000):
state = env.reset()
done = False

while not done:
action = np.argmax(qtable[state, :])
state, reward, done, info = env.step(action)

# 如果reward为1,代表成功到达目标
if reward == 1:
successes += 1

env.close()

print("成功完成目标次数: " + str(successes))

print("--- 测试耗时: %s 秒 ---" % (time.time() - start_time))

这段代码使用Q-Learning的强化学习算法在OpenAI Gym的FrozenLake环境中进行训练和测试。下面详细解释这段代码的每一部分:

首先,我们导入需要的库,包括时间库time,科学计算库numpy,以及gym库。

接着,我们创建一个FrozenLake环境。FrozenLake是一个网格世界,目标是从起点移动到目标点,避免落入洞中。

然后,我们初始化一个Q表。Q表是一个二维数组,大小为state的数量xaction的数量。这个表用于存储每个state-action对应的Q值。

train_mode变量决定我们是否进行训练。

如果train_mode为真,我们将进行训练。我们首先记录训练开始的时间,然后设定一些训练参数,包括训练的总回合数、学习率和折扣因子。

在训练的每一回合中,我们首先重置环境,然后在每一步中,我们选择一个动作,这个动作是当前state对应的Q表中Q值最大的动作,然后加上一个噪声,这个噪声随着时间逐渐减小,这样既保证了一定的探索性,又能让agent随着时间的推移越来越依赖已学习的经验。

在执行这个动作后,我们会获得一个新的状态、奖励、是否结束的标志以及一些其他的信息。然后我们更新Q表。

Q表的更新公式为:

Q(s,a) = Q(s,a) + lr * [R(s,a) + γ * maxQ(s',a') - Q(s,a)]

其中,

  • s是当前状态
  • a是当前动作
  • R(s,a)是执行动作a在状态s后得到的奖励
  • s'是新的状态
  • a'是在新的状态s'下Q值最大的动作
  • γ是折扣因子,决定了未来奖励的影响力
  • lr是学习率,决定了我们在更新Q值时,新的信息占据的比例。

如果train_mode为假,我们将加载已经训练好的Q表进行测试。

在测试中,我们将选择Q值最大的动作进行执行,不再加入噪声。测试完成后,我们将统计成功达到目标的次数。

至于代码中的两个time.time(),主要是用于计算训练和测试所花费的时间。

总的来说,这是一个基于Q-Learning的强化学习例子,通过不断的试错和学习,agent能够学会在FrozenLake环境中如何行动以达到目标。