强化学习第三讲

  • 最优控制问题
  • 基于gym的实例

一、最优控制问题

0、基本阐述

最佳控制是要找到一个系统的控制方法,以满足特定的优化准则。控制问题会包括费用泛函(cost functional),是状态以及控制变量的函数。
最佳控制要将费用泛函最小化,会表示成一组描述控制变量路径的微分方程。
例如,对于一个连续系统,往往有一组状态方程来描述:

X˙=f(t,X,U)X(t0)=X0(3.1)\dot{X}=f(t,X,U)\qquad{}X(t_{0})=X_{0}\tag{3.1}

性能指标往往由积分给出:

J[x(t0),t0]=ϕ[x(tf),tf]+t0tfL[x(t),u(t),t](3.2)\small{} J\left[x(t_{0}),t_{0}\right]=\phi{}\left[x(t_{f}),t_{f}\right]+\int_{t_{0}}^{t{f}}L\left[x(t),u(t),t\right]\tag{3.2}

则最优控制的问题即是:

V(X,t)=minuΩ{g[x(tf),tf]+t0tfL[x(t),u(t),t]}(3.3)\footnotesize{} V(X,t)=\underset{u\in{\Omega}}{\min}\left\{g\left[x(t_{f}),t_{f}\right]+\int_{t_{0}}^{t{f}}L\left[x(t),u(t),t\right]\right\}\tag{3.3}

由贝尔曼最优性原理得到哈密尔顿-雅克比-贝尔曼方程(HJB方程):

Vt=minuΩ{g[x(tf),tf]+VXTf[x(t),u(t),t]}(3.4)\footnotesize{} -\frac{\partial{V}}{\partial{t}}=\underset{u\in{\Omega}}{\min}\left\{g\left[x(t_{f}),t_{f}\right]+\frac{\partial{V}}{\partial{X^{T}}}f\left[x(t),u(t),t\right]\right\}\tag{3.4}

其中VV是值函数,gg是过程成本,ff是状态方程。
可参考wiki
注:贝尔曼方程即离散的HJB方程
解决方程(3.4)的思路有如下三种

1、数值求解方法

将值函数进行离散,求解方程的数值解,然后利用贪婪策略得到最优控制。这对应于微分方程的数值解法,如欧拉法,中点法,龙格-库塔法等。

2、微分动态规划(DDP)

利用变分法,将微分方程转化成变分代数方程,在标称轨迹展开,得到微分动态规划DDP(不会所以也只能贴文章了)(汗)

水一个DDP伪代码

首先由方程(3.4)离散得到:

xk+1=f(xk,uk)(3.5)x_{k+1}=f(x_{k},u_{k})\tag{3.5}

Vk=minu[l(xk,uk)+Vk+1(xk+1)](3.6)V_{k}=\underset{u}{\min{}}[l(x_{k},u_{k})+V_{k+1}(x_{k+1})]\tag{3.6}

则:

[1]由给定的控制序列uˉk\bar{u}_{k},正向迭代计算标称轨迹

xˉk+1=f(xˉk,uˉk),lxk,luk,lxxk,lxuk,luuk\bar{x}_{k+1}=f(\bar{x}_{k},\bar{u}_{k}), l_{x_{k}},l_{u_{k}},l_{xx_{k}},l_{xu_{k}},l_{uu_{k}}

[2]反向迭代:由边界条件VxNV_{x_{N}},VxxNV_{xx_{N}}反向迭代计算:VxNVxxNV_{x_{N}}、V_{xx_{N}}QQkkk_kKkK_k得到贪婪策略δuk\delta_{u_{k}^{*}}
[3]正向迭代更新控制序列:

x1=xˉ(1)uk=uˉk+kk+Kk(xkxˉk)xk+1=f(xk,uk)x_1=\bar{x}(1)\\ u_k=\bar{u}_k+k_k+K_k(x_k-\bar{x}_k)\\ x_{k+1}=f(x_k,u_k)

[4]判断是否收敛,否就跳转[1],是就结束

3、伪谱法

利用函数逼近理论,对方程中的回报函数和控制函数进行函数逼近,利用优化方法得到逼近函数(由于与值函数迭代较为不同,在此不进行展开)

二、基于OpenAI gym环境的示例

0、值迭代伪代码

搞忘打了,现在补一个💦

[1] 输入:状态转移概率PssaP_{ss'}^{a} 、回报函数RsaR_s^a、折扣因子γ\gamma
[2] 初始化值函数: v(s)=0v(s)=0、初始化策略π0\pi_0
[3] Repeatl=0,1,\,Repeat\,l=0,1,\dots{}
[4] for every s do\quad{}for\ every\ s\ do
[5] vk+1(s)=aAπ(as)(Rsa+γsSPssavk(s))\qquad{}\quad{}v_{k+1}(s)=\sum_{a\in{A}}{\pi{}(a\mid{}s)\left(R_{s}^{a}+\gamma{}\sum_{s'\in{S}}{P_{ss'}^{a}v_{k}(s')}\right)}
[6] Untilvk+1=vk\,{}Until\enspace{}v_{k+1}=v_{k}(精度控制)
[7] 输出:π(s)=arg maxaRsa+γsSPssavl(s)\pi(s)=\underset{a}{\argmax{}}R_s^a+\gamma\sum_{s'\in{S}}P_{ss'}^av_l(s')

1、在windows系统下安装gym

(1)anaconda

首先安装anaconda,清华镜像
安装时注意以管理员身份运行(for all users),可自行安装在其他盘。
“自动添加环境变量”这一项可自行斟酌,百度得到的答案是:选了不用那么麻烦去手动添加环境变量,不选的话在后期可能出现“无法定位到动态链接库”的问题……(所以我选择偷懒)
附:手动添加环境变量需要以下五个

E:\Anaconda(Python需要)
E:\Anaconda\Scripts(conda自带脚本)
E:\Anaconda\Library\mingw-w64\bin(使用C with python的时候) E:\Anaconda\Library\usr\bin
E:\Anaconda\Library\bin(jupyter notebook动态库)

(E:\Anaconda是自定义安装anaconda的路径,该路径不要有空格!)
然后win+R调出cmd,输入

1
2
conda --version
python --version

可检查anaconda是否安装正确,并获取python版本号(比如python 3.9.7)
值得注意的是,如果之前已经安装好python,再安anaconda的话,anaconda的python解释器貌似会覆盖之前安好的python(咱也不是很懂)
接下来在cmd里输入

1
2
conda create -n ENV_NAME python=3.9.7
activate ENV_NAME

这一步是创立一个“ENV_NAME”的虚拟环境(自命名),后面用上一步得到的python版本号,会在anaconda\envs\目录下创建一个环境,且在激活环境后可以看到在cmd里前面会显示"(ENV_NAME)",说明激活成功。
接下来输入

1
2
3
pip install gym -i https://pypi.tuna.tsinghua.edu.cn/simple
or
conda install gym -i https://pypi.tuna.tsinghua.edu.cn/simple

第一个不行就第二个(问就是不知道),然后等待下载即可。
下载完gym包可输入

1
pip list

查看已经下载的包(顺带一提,还需要下载pygame这个包,才能运行cartpole等模型,都觉得这个简单到不需要说嘛otz)
对于上面的-i https……一坨就是用镜像源,嫌麻烦可以直接自行换源

1
2
3
4
conda config --set show_channel_urls yes
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2

可参考help
如果要退出虚拟环境可输入

1
conda deactivate

(2)pycharm

安装pycharm自行CSDN……
然后FileSettingsProjectProject Interpreter选择anaconda(点那个齿轮小图标自己添加你下的anaconda位置)
然后可以新建.py文件执行以下代码:

1
2
3
4
5
6
7
8
import gym

env = gym.make('CartPole-v0')
env.reset()
for _ in range(500):
env.render()
env.step(env.action_space.sample())

(如果gym有波浪线说明gym包没下好……)

2、gym环境构建

env.reset()env.render()是每个环境文件均包含的函数

(1)reset()函数

reset()为重新初始化函数,在强化学习算法中,智能体需要一次次地尝试并积累经验,然后从经验中学习好的动作。每次尝试称之为一条轨迹或一个episode,每次尝试需要到达终止状态。一次尝试结束后,需要从头开始,即需要智能体重新初始化

(2)render()函数

一个仿真环境必不可少的两部分是物理引擎和图像引擎。物理引擎模拟环境中物体的运动规律;图像引擎用于显示环境中的物体图像。而render()函数就扮演图像引擎的角色。

已更新,见实例项目


强化学习第三讲
https://zongjy.github.io/2022/03/21/5f92737c9c26/
作者
zongjy
发布于
2022年3月21日
许可协议