DQN算法实战-小车上山
案例分析
如图1所示,一个小车在一段范围内行驶。在任一时刻,在水平方向看,小车位置的范围是[-1.2,0.6],速度的范围是[-0.07,0.07]。在每个时刻,智能体可以对小车施加3种动作中的一种:向左施力、不施力、向右施力。智能体施力和小车的水平位置会共同决定小车下一时刻的速度。当某时刻小车的水平位置大于0.5时,控制目标成功达成,回合结束。控制的目标是让小车以尽可能少的步骤达到目标。一般认为,如果智能体在连续100个回合中的平均步数≤110,就认为问题解决了。
在绝大多数情况下,智能体简单向右施力并不足以让小车成功越过目标。假设智能体并不知道环境确定小车位置和速度的数学表达式。事实上,小车的位置和速度是有数学表达式的。记第t时刻(t=0,1,2,…)小车的位置为 X t ( X t ∈ [ − 1.2 , 0.6 ] ) X_t(X_t∈[-1.2,0.6]) Xt(Xt∈[−1.2,0.6]),速度为 V t ( V t ∈ [ − 0.07 , 0.07 ] ) V_t(V_t∈[-0.07,0.07]) Vt(Vt∈[−0.07,0.07]),智能体施力为 A t ∈ 0 , 1 , 2 A_t∈{0,1,2} At∈0,1,2,初始状态 X 0 ∈ [ − 0.6 , − 0.4 ) , V 0 = 0 X_0∈[-0.6,-0.4),V_0=0 X0∈[−0.6,−0.4),V0=0。从t时刻到 t + 1 t+1 t+1时刻的更新式为
其中限制函数clip()限制了位置和速度的范围:
实验环境
Gym库内置的环境’MountainCar-v0’已经实现了小车上山环境。在这个环境中,每一步的奖励都是-1,回合的回报的值就是总步数的负数。导入这个环境,并查看其状态空间和动作空间,以及位置和速度的参数。
import numpy as np
np.random.seed(0)
import pandas as pd
import matplotlib.pyplot as plt
import gym
import tensorflow.compat.v2 as tf
tf.random.set_seed(0)
from tensorflow import keras
env = gym.make('MountainCar-v0')
env.seed(0)
print('观测空间 = {}'.format(env.observation_space))
print('动作空间 = {}'.format(env.action_space))
print('位置范围 = {}'.format((env.unwrapped.min_position,
env.unwrapped.max_position)))
print('速度范围 = {}'.format((-env.unwrapped.max_speed,
env.unwrapped.max_speed)))
print('目标位置 = {}'.format(env.unwrapped.goal_position))
使用这个环境。在代码清单2中的策略总是试图向右对小车施力。程序运行结果表明,仅仅简单地向右施力,是不可能让小车达到目标的。为了避免程序无穷尽地运行下去,这里限制了回合最大的步数为200。
positions, velocities = [], []
observation = env.reset()
while True:
positions.append(observation[0])
velocities.append(observation[1])
next_observation, reward, done, _ = env.step(2)
if done:
break
observation = next_observation
if next_observation[0] >