目录
参考《深入浅出强化学习》
强化学习解决的是智能决策(即序贯决策)问题,也就是说需要连续不断地做出决策,才能实现最终目标。
监督学习解决的是智能感知的问题,学习的是输入长得像什么(特征),以及和它对应的是什么(标签)。需要的是多样化的标签数据。
强化学习不关心输入长什么样,只关心当前输入下应该采取什么动作,才能实现最终目标。需要智能体不断地与环境交互,不断尝试。需要的是带有回报的交互数据。
几个关键时间点:
根据强化学习是否依赖模型:
根据策略的更新和学习方法:
根据环境返回的回报函数是否已知:
其他强化学习:分层强化学习、元强化学习、多智能体强化学习、关系强化学习、迁移强化学习等。
强化学习的发展趋势:
机器学习算法分为三大类:监督学习、无监督学习、强化学习。三类算法联合使用的效果更好,例如基于深度强化学习的对话生成等。
对于不同领域,可以重塑回报函数,或者修改网络结构。代表作:NIPS2016的最佳论文:值迭代网络【Value Iteration Networks,github代码:https://github.com/TheAbhiKumar/tensorflow-value-iteration-networks】。
代表作有:基于深度能量的策略方法、值函数与策略方法的等价性等。
DeepMind和伦敦大学学院是这一流派的代表。
以CartPoleEnv为例:
env = gym.make('CartPole-v0')
env.reset()
env.render()
CartPoleEnv的环境文件位于/gym/gym/envs/classic_control/cartpole.py
注册的代码在/gym/gym/envs/__init__.py
中
智能体需要一次次尝试病积累经验,然后从经验中学到好的动作。每一次尝试称为一条轨迹,或者一个episode。每次尝试都需要达到终止状态,一次尝试结束后,就需要智能体重新初始化。
reset()是重新初始化函数。实现如下:
def reset(self):
self.state = self.np_random.uniform(low=-0.05, high=0.05, size=(4,))
self.steps_beyond_done = None
return np.array(self.state)
即,利用均匀随机分布初始化环境状态,然后设置当前步数为None,病返回环境的初始化状态。
render()扮演图像引擎的角色。为了便于直观显示环境中物理的状态,需要除了物理引擎之外的图像引擎。源码如下:
注释参考:https://github.com/daiwk/reinforcement-learning-code/blob/master/cartpole_notes.py
if self.viewer is None:
from gym.envs.classic_control import rendering
self.viewer = rendering.Viewer(screen_width, screen_height)
# 创建台车
l,r,t,b = -cartwidth/2, cartwidth/2, cartheight/2, -cartheight/2
axleoffset =cartheight/4.0
cart = rendering.FilledPolygon([(l,b), (l,t), (r,t), (r,b)]) ## 填充一个矩形
#添加台车转换矩阵属性
self.carttrans = rendering.Transform()
cart.add_attr(self.carttrans)
#加入几何体台车
self.viewer.add_geom(cart)
#创建摆杆
l,r,t,b = -polewidth/2,polewidth/2,polelen-polewidth/2,-polewidth/2
pole = rendering.FilledPolygon([(l,b), (l,t), (r,t), (r,b)])
pole.set_color(.8,.6,.4)
#添加摆杆转换矩阵属性
self.poletrans = rendering.Transform(translation=(0, axleoffset))
pole.add_attr(self.poletrans)
pole.add_attr(self.carttrans)
#加入几何体
self.viewer.add_geom(pole)
#创建摆杆和台车之间的连接
self.axle = rendering.make_circle(polewidth/2)
self.axle.add_attr(self.poletrans)
self.axle.add_attr(self.carttrans)
self.axle.set_color(.5,.5,.8)
self.viewer.add_geom(self.axle)
#创建台车来回滑动的轨道,即一条直线
self.track = rendering.Line((0,carty), (screen_width,carty))
self.track.set_color(0,0,0)
self.viewer.add_geom(self.track)
if self.state is None: return None
x = self.state
cartx = x[0]*scale+screen_width/2.0 # MIDDLE OF CART
#设置平移属性
self.carttrans.set_translation(cartx, carty)
self.poletrans.set_rotation(-x[2])
return self.viewer.render(return_rgb_array = mode=='rgb_array')
创建完cart的形状,给cart添加平移属性和旋转属性,将车的位移设置到cart的平移属性中,cart就会根据系统的状态变化左右移动。
step()函数扮演物理引擎的角色。
描述了智能体与环境交互的所有信息。利用智能体的运动学模型和动力学模型计算下一步的状态和立即回报,并判断是否达到终止状态。
def step(self, action):
assert self.action_space.contains(action), "%r (%s) invalid"%(action, type(action))
state = self.state
x, x_dot, theta, theta_dot = state # 系统的当前状态
force = self.force_mag if action==1 else -self.force_mag # 输入动作,即作用到车上的力
costheta = math.cos(theta) # cos
sintheta = math.sin(theta) # sin
# 车摆的动力学方程式,即加速度与动作之间的关系
temp = (force + self.polemass_length * theta_dot * theta_dot * sintheta) / self.total_mass
thetaacc = (self.gravity * sintheta - costheta* temp) / (self.length * (4.0/3.0 - self.masspole * costheta * costheta / self.total_mass)) # 摆的角加速度
xacc = temp - self.polemass_length * thetaacc * costheta / self.total_mass # 小车的平移加速度
x = x + self.tau * x_dot
x_dot = x_dot + self.tau * xacc
theta = theta + self.tau * theta_dot
theta_dot = theta_dot + self.tau * thetaacc # 积分球下一步的状态
self.state = (x,x_dot,theta,theta_dot)
done = x < -self.x_threshold \
or x > self.x_threshold \
or theta < -self.theta_threshold_radians \
or theta > self.theta_threshold_radians
done = bool(done)
if not done:
reward = 1.0
elif self.steps_beyond_done is None:
# Pole just fell!
self.steps_beyond_done = 0
reward = 1.0
else:
if self.steps_beyond_done == 0:
logger.warn("You are calling 'step()' even though this environment has already returned done = True. You should always call 'reset()' once you receive 'done = True' -- any further steps are undefined behavior.")
self.steps_beyond_done += 1
reward = 0.0
return np.array(self.state), reward, done, {}
强化学习解决的是序贯决策问题,一般的序贯决策问题可以用马尔科夫决策过程(MDP)的框架来表示。
对于模型已知的MDP问题,动态规划是一个不错的解。由此引出广义策略迭代的方法。而广义策略迭代的方法也适用于无模型的方法,是基于值函数强化学习的基本框架。因此有chap4的基于蒙特卡罗方法、chap5的基于时间查分方法、chap6的基于值函数逼近方法。
无模型的强化学习算法,是整个强化学习算法的核心。基于值函数的强化学习算法的核心是计算值函数的期望。值函数是一个随机变量,其期望的计算可以通过蒙特卡罗方法得到。
基于蒙特卡罗的强化学习算法通过蒙特卡罗模拟计算期望,需要等每次试验结束后再对值函数进行估计,收敛速度漫。而时间差分的方法只需要一步便更新,效率高、收敛速度快。
chap4和chap5介绍的是表格型强化学习,即,状态空间和动作空间都是有限集,动作值函数可以用一个表格来描述,表格的索引分别为状态量和动作量。但当状态空间和动作空间都很大时,甚至两个空间都是连续空间时,这就无法用表格表示,可以用函数逼近理论对值函数进行逼近。本章介绍了DQN及其变种(Double DQN、Prioritized Replay DQN、Dueling DQN等)。
区别于基于值函数的方法,强化学习的第二大类算法是直接策略搜索方法。就是将策略进行参数化,然后在参数空间直接搜索最优策略。直接策略搜索方法中,最直接最简单的方法是策略梯度方法 。
基于策略梯度方法最具挑战性的是更新步长的确定。TRPO方法通过理论分析得到单调非递减的策略更新方法.
当动作空间维数很高时,智能体的探索效率会很低,利用确定性策略可以免除对动作空间的探索,提升算法的收敛速度。
chap7(策略梯度)\8(TRPO)\9(确定性策略搜索)章讲的是无模型的直接策略搜索方法。而对于机器人等复杂系统,无模型的方法随机初始化很难找到成功的解,所以算法很难收敛。此时,可以利用传统控制器来引导策略进行搜索。
很多实际问题,往往不知道回报函数,所以可以通过逆向强化学习来学习回报函数。
将策略梯度方法和值函数方法相组合。
先介绍DQN,然后介绍值迭代网络。
PLICO(probalistic inference for learning control)是一种基于模型的强化学习算法,将模型误差纳入考虑范围内,一般只需要训练几次到几十次就可以成功实现对单摆等典型非线性系统的稳定性控制,而基于无模型的强化学习则需要训练上万次。