萬字離線強化學習總結!(原理、數據集、算法、複雜性分析、超參數調優等)

語言: CN / TW / HK

本文來源自知乎博客,作者丨旺仔搬磚記

轉載自丨深度強化學習實驗室

    

由於內容過長,本文僅展示部分內容,完整系列請查閲博客: http://www.zhihu.com/column/c_1487193754071617536

離線強化學習(Offline RL)作為深度強化學習的子領域,其不需要與模擬環境進行交互就可以直接從數據中學習一套策略來完成相關任務,被認為是強化學習落地的重要技術之一。本文詳細的闡述了強化學習到離線強化學習的發展過程,並就一些經典的問題進行了解釋和説明。

1

深度強化學習

1.1 深度強化學習簡介

強化學習發展的特別早,但一直不温不火,其中Sutton老爺子早在1998年就寫了強化學習領域的聖經書籍:An Introduction : Reinforcement Learning ,但也並未開啟強化學習發展的新局面。

直到2012年,深度學習廣泛興起,大規模的神經網絡被成功用於解決自然語言處理,計算機視覺等領域,人工智能的各個方向才開始快速發展,強化學習領域最典型的就是2013年DeepMind公司的Volodymyr Mnih發表Playing Atari with Deep Reinforcement Learning(DQN技術),可以説開啟了深度強化學習技術發展的新高潮,2015年該論文的加強版Human-level control through deep reinforcement learning 登上Nature, 以及2016年Nature上的AlphaGo: Mastering the game of Go with deep neural networks and tree search 充分證明了深度強化學習技術的發展潛力。

傳統的強化學習和監督學習、非監督學的區別在於,後兩者是通過從已標記(Label)和無標記的數據中學習一套規律(我們可以理解為學習一個函數表達式),而前者強化學習則是通過行為交互來學習一套策略,以最大化累計期望獎勵,結構如圖所示:

image-20220329103307041

其學習過程可以歸納為通過agent獲取環境狀態, 根據自身學習到的知識做出action反饋給環境,並得到一個獎勵,不斷地迭代出一個可以一直玩遊戲並且不會死的智能體。原理就是從一個四元組$<s, a,="" r,="" s^{'}="">$中學習出策略,不論出發點在哪裏都可以得到一個最優的軌跡(trajectory)模型(不論起點,目前測試中一般通過多個隨機seed去測試),具體可以參考博主的另外篇博文深度強化學習簡介.

1.1.1 On-Policy和off-Policy區別

On-policy和Off-policy這兩個詞在強化學習領域非常重要,知乎上有很多關於其討論強化學習中on-policy 與off-policy有什麼區別?,最典型的莫過於李宏毅老師下棋形象例子解釋,還可以從以下方式解釋:

【補充】 兩者在學習方式上的區別 :若agent與環境互動,則為 On-policy (此時因為agent親身參與,所以互動時的policy和目標的policy一致);若agent看別的agent與環境互動,自己不參與互動,則為 Off-policy (此時因為互動的和目標優化的是兩個agent,所以他們的policy不一致)。 兩者在採樣數據利用上的區別On-policy :採樣所用的policy和目標policy一致,採樣後進行學習,學習後目標policy更新,此時需要把採樣的policy同步更新以保持和目標policy一致,這也就導致了需要重新採樣。 Off-policy :採樣的policy和目標的policy不一樣,所以你目標的policy隨便更新,採樣後的數據可以用很多次也可以參考。

其實最經典的莫過於Sutton老爺子Introduction中的解釋:

原文:On-policy methods attempt to evaluate or improve the policy that is used to make decisions, whereas off-policy methods evaluate or improve a policy different from that used to generate the data.

此外莫過於Q-learning和sarsa算法的解釋

最終總結一下兩者的優缺點

on-policy優點是直接了當,速度快,劣勢是不一定找到最優策略。off-policy劣勢是曲折,收斂慢,但優勢是更為強大和通用。

本文之所以解釋On-policy或者off-policy的相關內容,目的在於後文討論以下幾個問題:

  • 如何從採樣軌跡(trajectory)中高效學習

  • Off-policy採樣效率高,收斂慢,仍然是最重要的解決問題方法

1.1.2 Online和Offline學習的本質

監督學習中通常利用已知(已標記)的數據進行學習,其本質是從數據中總結規律,這和人從學1+1=2基本原理一致,強化學習的過程也是如此,仍然是從數據中學習,只不過強化學習中學習的數據是一系列的軌跡

所以重點來了,這裏的 數據 才是最關鍵的一部分,這也強化學習中Online和offline學習中的關鍵, Online一方面是與環境有交互,通過採集數據學習、然後丟棄,而offline則是不用交互,直接通過採集到的軌跡數據學習,這也是off-policy到offline轉換的重要原因。

1.2 落地應用的困難?

目前atari, mujoco物理引擎等各類遊戲中的模擬數據很輕鬆拿到,這也就是目前強化學習在遊戲領域非常成功的原因之一,也是各種state of the art刷榜的體現,因為遊戲數據可以很輕鬆就100million,總結起來就是

有模擬器,易產生數據,好用!

但強化學習在落地過程中就可能遇到很多問題,比如下圖這個大傢伙,

總不可能讓他產生100 million數據吧(不知道他的額定壽命是多少次),因此產生如下幾個問題:

  1. 由於樣本收集很困難,或者很危險。所以實時的和環境進行交互是不太可能的,那麼可否有一種僅利用之前收集的數據來訓練的方法去學習策略呢?

  2. 不管它是on-policy還是off_policy,我只要經驗回放池中的 交互歷史數據 ,往大一點就是logg數據庫中的數據(此處就不能探索exploration),去擬合函數是否可行?

  3. 僅利用軌跡數據學習的策略能否和Online算法的媲美?

所以有這樣的方法嗎?

答案: 有,OfflineRL,此處有礦,趕緊來挖!

2.離 線強化學習

離線強化學習最初英文名為: Batch Reinforcement Learning [3], 後來Sergey Levine等人在其2020年的綜述中使用了 Offline Reinforcement Learning(Offline RL) , 現在普遍使用後者表示。下圖是離線強化學習近年來論文的發表情況,間接反應發展狀態。

2.1 離線強化學習原理

Offline RL 可以被定義為 data-driven 形式的強化學習問題,即在智能體(policy函數?)不和環境交互的情況下,來從獲取的軌跡中學習經驗知識,達到使目標最大化,其和Online的區別如圖所示:

圖片來源自:Offline Reinforcement Learning

後來Sergey在論文中歸納如下圖所示:

本質上,智能體是通過靜態的數據集 $<s_{t}^{i},a_{t}^{i},s_{t+1}^{i},r_{t}^{i}>

\pi(a|s)\pi_{\beta}Ds,a \in Ds \sim d^{\pi_{\beta}}(s)a\sim \pi_{\beta}(a|s)J(\pi)$</s_{t}^{i},a_{t}^{i},s_{t+1}^{i},r_{t}^{i}>

2.2 離線強化學習分類及區別

2.2.1 如何判斷 Offline RL

圖中很明確的從 數據 可否store以及reused解釋了是純Online還是offline, 以及使用經驗回放的NFQ等,其本質還是是否利用trajectory去學習優化模型。

備註:離線強化學習去學習數據可以使 專家數據、預訓練(Pre-Train)模型產生的數據、隨機(random)數據 等。

2.2.2 offline RL的分類

2.2.3 Offline RL&模仿學習的區別

模仿學習(Imitation Learning, IL) 是指通過從專家(通常指人類的決策數據)提供的範例中學習,,每個決策包含狀態和動作序列 $\tau_{i}= \mathcal{D}=\left\{\left(s_{1}, a_{1}\right),\left(s_{2}, a_{2}\right),\left(s_{3}, a_{3}\right), \ldots\right\}$。之後就可以把狀態作為特徵,動作作為標記進行離散動作/連續動作的學習而得到最優的策略模型,模型的訓練目標是使模型生成的 狀態-動作軌跡分佈輸入的軌跡分佈 相匹配,最典型的就是自動駕駛的例子(此過程中一般稱為行為克隆behavior clone)。

可能有人會問,模仿學習不也是從專家數據中學習一套策略嗎?它和offline RL不就是一回事了?其實它們與息息相關,但有幾個關鍵的區別:

  • Offline RL 算法(到目前為止)建立在標準的off-policy深度強化學習算法之上,這些算法傾向於優化某種形式的貝爾曼方程或TD誤差。

  • 大多數 IL 問題假設有一個最優的,或者至少是一個高性能的提供數據的演示器,而Offline RL 可能必須處理高度次優(subopt)的數據。

  • 大多數 IL 問題沒有獎勵函數。Offline RL 有獎勵,而且可以事後處理和修改。

  • 一些 IL 問題需要將數據標記為專家與非專家。Offline RL 不做這個假設(可以是專家、已訓練好的模型產生的軌跡,隨機數據)。

另外一方面在數據組成方面有如下區別:

2.3 離線強化學習很難學習的原因

2.3.1 無法探索(Explore)

強化學習在與環境中交互學習的過程中,最關鍵的一個問題便是“ Exploration vs Exploitation Dilemma ”, Exploration是為了收集更多信息(嘗試一些不可能等),而Exploitation則根據當前信息做出最佳決策,正如Sliver總結的:

這兩者可以説對一個算法的訓練精度、速度等各方面有重要影響, 而Offline RL算法中需要完全的依賴於靜態數據集 ,但是沒有辦法提高exploration,因為不和環境進行交互,就無法知道探索得到的數據是否有效,是否有高質量的獎勵反饋等 ,所以 Offline RL不可能通過探索發現高獎勵的區域。而且,並沒有辦法解決此問題,這就變成了2.3.2中的經驗最小化的問題了

2.3.2 數據質量(擬合與過擬合)

深度學習的成功可以歸結為數據集(ImageNet等)的準確強大,offline RL也不例外,思考以下問題:

  • 如果軌跡(數據)全部是專家數據,Offline RL算法會學習到好策略嗎?

  • 如果軌跡全是預訓練好的模型(比如訓練好的PPO模型)產生的,Offline RL算法會學習到好策略嗎?

  • 如果軌跡全是沒有任何經驗,而是隨機產生的,Offline RL算法會學習到好策略嗎?

  • 如果軌跡是上述三種的混合,具體的比例多少才能訓練出通用、高效的offline RL算法?

這個問題其實Fujimoto在2019年的時候就提到了(如圖所示),但直到現在仍然對Offline RL算法的訓練非常大的影響。

備註: Final buffer : train a DDPG agent for 1 million time steps, adding N (0, 0.5) Gaussian noise to actions for high exploration, and store all experienced transitions. Concurrent :train the off-policy and behavioral DDPG agents, for 1 million time steps. To ensure sufficient exploration, a standard N (0, 0.1) Gaussian noise is added to actions taken by the behavioral policy.

2.3.3 分佈偏移(Distribution shift)

2.3.3.1 關於分佈偏移

分佈偏移(Distribution shift) 在監督學習中一般指的是訓練分佈與測試分佈不同,在離線強化學習中指的是訓練策略與行為策略不一致。(Distribution shifts, in which the training distribution differs from the testing distribution, training policy are inconsist:ent with behavioral policy in offline reinforcement learning.),下面我們進行解釋

在監督學習中,訓練一個模型通常追求經驗風險最小化(Empirical Risk Minimization,ERM),即:

也就是讓圖中的左子圖的平均損失函數最小化,那麼這裏就存在一個問題,給定一個最優的, 那麼也是最優的嗎?(注意這裏:)

  • 如果  , 則是最小的

  • 如果, 則不是,因為對於普通的

那麼問題就變成了:如何在不同的下能夠同樣能夠達到

同樣的情況,在Offline RL中obejctive函數則變成了:

其中的是我們從offline data中學習的策略, 而我們希望, 這樣就可以達到學習目的了。

總結起來就是: 別走偏了,每一步都儘量讓兩個分佈之間距離最小化的問題,不然累計起來不知道走哪裏 (有點TRPO的感覺)

2.3.3.2 分佈偏移對OfflineRL算法收斂的影響

對2.3.3.1中的定義, 我們換種表達方式為,考慮時間步為的情況下,在離線強化學習中誤差上界和時間步之間是平方關係,直覺上造成這樣的原因是因為,學習策略可能會進入和訓練分佈差距很遠的狀態,這將導致和差距非常大。

那麼,當策略在時刻遇到了分佈之外(數據集中沒見過)的狀態時,策略在之後的個時刻就有可能不斷的犯錯,所以累計誤差,而且每一個時間步,都有可能進入分佈外的狀態,造成整體誤差為, 這對於算法的收斂來説無異於雪上加霜,關於解決這個問題的BCQ、CQL等算法將來後續博客講解!(by Sergey)

2.4 Offline RL 發展時間線

下面是一些2012年前的offline reinforcement learning算法,最新的算法將在後面博客中詳解。

至此,關於offline RL的簡介到這裏,下一篇是關於offline RL 中常用(最典型)的數據集D4RL的安裝過程以及其中遇到的一些坑,以及如何設計一個高效的Offline RL算法

關於D4RL Benchmarks數據集[Github], [Paper]

2.5為什麼選擇 D4RL?

(1) D4RL 收集了大型數據集,包括交互式環境中智能體的記錄(即自動駕駛Carla、AntMaze、Mujoco等),且有簡單和複雜分類,種類非常豐富,例如:

  • 通過人工演示或硬編碼控制器生成的數據。

  • 具有不同策略的異構混合的數據

  • 數據觀察智能體在同一環境中完成各種目標。

Environment

(2)  D4RL提供了非常簡單的API接口,方便於學習者直接去獲取數據集完成智能體的訓練。

import d4rl  # Import required to register environments

env = gym.make( 'maze2d-umaze-v1' )

dataset = env.get_dataset()

(3)  D4RL定義了標準的衡量指標

(4)  D4RL提供了豐富的baseline基準,包括了常見的Offline算法,包括BCQ、BEAR、BRAC等等

Baseline score

2.6 D4RL數據集製作影響因素

D4RL數據集目前來説是離線強化學習涵蓋數據集非常豐富的一個數據集,數據質量非常高。其中最主要的是數據的採集綜合了6類因素

  • Narrow and biased data distributions

  • Undirected and multitask data

  • Sparse rewards

  • Suboptimal data.

  • Non-representable behavior policies, non-Markovian behavior policies, and partial observ- ability.

  • Realistic domains

2

D4RL安裝與使用

2.1 官方安裝指導(有坑)

D4RL 的安裝相對來説比較容易,但其中也有很多的坑

git clone http://github.com/rail-berkeley/d4rl.git

cd d4rl

pip install -e .

另外一種簡單的安裝方法

pip install git+http://github.com/rail-berkeley/[email protected]#egg=d4rl

其中會有很多坑,導致安裝失敗。

下面我們根據初始化安裝文件setup.py分析安裝

from distutils.core  import setup

from platform  import platform

from setuptools  import find_packages

setup(

name= 'd4rl' ,

version= '1.1' ,

install_requires=[ 'gym' ,

'numpy' ,

'mujoco_py' ,

'pybullet' ,

'h5py' ,

'termcolor' ,   # adept_envs dependency

'click' ,   # adept_envs dependency

'dm_control' if 'macOS' in platform()  else

'dm_control @ git+git://github.com/deepmind/[email protected]#egg=dm_control' ,

'mjrl @ git+git://github.com/aravindr93/[email protected]#egg=mjrl' ],

packages=find_packages(),

package_data={ 'd4rl' : [ 'locomotion/assets/*' ,

'hand_manipulation_suite/assets/*' ,

'hand_manipulation_suite/Adroit/*' ,

'hand_manipulation_suite/Adroit/gallery/*' ,

'hand_manipulation_suite/Adroit/resources/*' ,

'hand_manipulation_suite/Adroit/resources/meshes/*' ,

'hand_manipulation_suite/Adroit/resources/textures/*' ,

]},

include_package_data= True ,

)

2.2 有效安裝過程(避坑)

上述過程安裝後我們會發現遇到很多問題,下面我就自己的安裝過程以及遇到的問題一一列舉

安裝環境:Ubuntu18.04, anaconda3

第一步:安裝mujoco210(針對沒有安裝mujoco)

# 下載地址 http://github.com/deepmind/mujoco/releases/tag/2.1.0

cd ~/Downloads/

wget http://github.com/deepmind/mujoco/releases/download/ 2.1.0 /mujoco210-linux-x86_64.tar.gz

mv mujoco210-linux-x86_64.tar.gz mujoco210

tar -zxvf mujoco210-linux-x86_64.tar.gz

mkdir ~/mujoco

cp -r mujoco210 ~/mujoco

# 添加環境變量

sudo gedit ~/.bashrc

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.mujoco/mujoco210/bin

export MUJOCO_KEY_PATH=~/.mujoco${MUJOCO_KEY_PATH}

source ~/.bashrc

# 測試

cd ~/.mujoco/mujoco210/bin/

./simulate ../model/humanoid.xml

image-20220317113717084

坑1:can't find /.mujoco/lib/libmujoco.so.2.1.1(可能安裝mujoco200的夥伴會遇到)

解決辦法:

(1)下載mujoco211安裝包,解壓

(2)在mujoco210/lib下找到libmujoco.so.2.1.1,並複製在~/.mujoco/bin在~/.bashrc下

(3)添加環境變量並source

export MJLIB_PATH=~/.mujoco/lib/libmujoco.so .2.1.1

source ~/.bashrc

第二步:安裝mujoco_py

# 本步跳過conda環境創建,直接進入虛擬環境(conda create -n d4rl python=3.7)

conda create -n d4rl python= 3.7

conda activate d4rl

pip install mujoco_py

python

Python  3.7.11 (default, Jul  27 202114 : 32 : 16

[GCC  7.5.0 ] :: Anaconda, Inc. on linux

Type  "help""copyright""credits" or "license" for more information.

>>>  import mujoco_py

>>> 

# 備:沒有報錯表示安裝成功

image-20220328171507687

坑2:如果是fatal error: GL/osmesa.h: No such file or directory,那就安裝libosmesa6-dev

Python  3.7.11 (default, Jul  27 202114 : 32 : 16

[GCC  7.5.0 ] :: Anaconda, Inc. on linux

Type  "help""copyright""credits" or "license" for more information.

>>>  import mujoco_py

running build_ext

building  'mujoco_py.cymj' extension

gcc -pthread -B /home/jqw/anaconda3/envs/d4rl/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py -I/home/jqw/.mujoco/mujoco210/include -I/home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/numpy/core/include -I/home/jqw/anaconda3/envs/d4rl/include/python3 .7 m -c /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/cymj.c -o /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/generated/_pyxbld_2 .1.2.14 _37_linuxcpuextensionbuilder/temp.linux-x86_64 -3.7 /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/cymj.o -fopenmp -w

gcc -pthread -B /home/jqw/anaconda3/envs/d4rl/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py -I/home/jqw/.mujoco/mujoco210/include -I/home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/numpy/core/include -I/home/jqw/anaconda3/envs/d4rl/include/python3 .7 m -c /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/gl/osmesashim.c -o /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/generated/_pyxbld_2 .1.2.14 _37_linuxcpuextensionbuilder/temp.linux-x86_64 -3.7 /home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/gl/osmesashim.o -fopenmp -w

/home/jqw/anaconda3/envs/d4rl/lib/python3 .7 /site-packages/mujoco_py/gl/osmesashim.c: 1 : 10 : fatal error: GL/osmesa.h: No such file  or directory

1#include <GL/osmesa.h>

|          ^~~~~~~~~~~~~

compilation terminated.

Traceback (most recent call last):

File  "<stdin>" , line  1in <module>

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/__init__.py" , line  2in <module>

from mujoco_py.builder  import cymj, ignore_mujoco_warnings, functions, MujocoException

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  504in <module>

cymj = load_cython_ext(mujoco_path)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  110in load_cython_ext

cext_so_path = builder.build()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  226in build

built_so_file_path = self._build_impl()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  278in _build_impl

so_file_path = super()._build_impl()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  249in _build_impl

dist.run_commands()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/dist.py" , line  966in run_commands

self.run_command(cmd)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/dist.py" , line  985in run_command

cmd_obj.run()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/Cython/Distutils/old_build_ext.py" , line  186in run

_build_ext.build_ext.run(self)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/command/build_ext.py" , line  340in run

self.build_extensions()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/mujoco_py/builder.py" , line  149in build_extensions

build_ext.build_extensions(self)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/site-packages/Cython/Distutils/old_build_ext.py" , line  195in build_extensions

_build_ext.build_ext.build_extensions(self)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/command/build_ext.py" , line  449in build_extensions

self._build_extensions_serial()

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/command/build_ext.py" , line  474in _build_extensions_serial

self.build_extension(ext)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/command/build_ext.py" , line  534in build_extension

depends=ext.depends)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/ccompiler.py" , line  574in compile

self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)

File  "/home/jqw/anaconda3/envs/d4rl/lib/python3.7/distutils/unixccompiler.py" , line  120in _compile

raise CompileError(msg)

distutils.errors.CompileError: command  'gcc' failed  with exit status  1

解決辦法:

sudo apt install libosmesa6-dev

# 補充命令:sudo apt-get install libgl1-mesa-glx libosmesa6

坑3:如果是fatal error: GL/glew.h: No such file or directory,那麼就安裝Glew庫

解決辦法

sudo apt-get install libglew-dev glew-utils

坑4:如果是FileNotFoundError: [Errno 2] No such file or directory: 'patchelf': 'patchelf', 那就安裝patchelf

解決辦法:

sudo apt-get -y install patchelf

安裝成功是這樣的效果

image-20220328174928475

第三步:安裝dm_control

pip install dm_control

第四步:安裝d4rl

克隆D4RL倉庫

git clone http://github.com/rail-berkeley/d4rl.git

找到到d4rl目錄下的setup.py文件,註釋mujoco_py, dm_control

install_requires=[ 'gym' ,

'numpy' ,

# 'mujoco_py',

'pybullet' ,

'h5py' ,

'termcolor' ,   # adept_envs dependency

'click' ,   # adept_envs dependency

# 'dm_control' if 'macOS' in platform() else

# 'dm_control @ git+git://github.com/deepmind/[email protected]#egg=dm_control',

'mjrl @ git+git://github.com/aravindr93/[email protected]#egg=mjrl' ],

然後直接安裝並測試

# installing

pip install -e .

# 測試,創建test_d4rlpy.py並添加如下內容 vim test_d4rl.py

import gym

import d4rl  # Import required to register environments

# Create the environment

env = gym.make( 'maze2d-umaze-v1' )

# d4rl abides by the OpenAI gym interface

env.reset()

env.step(env.action_space.sample())

# Each task is associated with a dataset

# dataset contains observations, actions, rewards, terminals, and infos

dataset = env.get_dataset()

print(dataset[ 'observations' ])  # An N x dim_observation Numpy array of observations

# Alternatively, use d4rl.qlearning_dataset which

# also adds next_observations.

dataset = d4rl.qlearning_dataset(env)

python test_d4rlpy.py

坑5:如果遇到:下面問題,那就單獨安裝mjrl

ERROR: Could  not find a version that satisfies the requirement mjrl (unavailable) ( from d4rl) ( from versions: none)

ERROR: No matching distribution found  for mjrl (unavailable)

安裝命令

pip install git+http://github.com/rail-berkeley/[email protected] #egg=d4rl

最後的D4RL安裝結果結果

image-20220317180305194

最後貼出我的~/.bashrc文件,歡迎參考

# cuda、anaconda等環境變量可以設置在本部分以前

# 環境變量次序也很重要

# mujoco(這裏我安裝了兩部分)

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.mujoco/mujoco210/bin

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.mujoco/mujoco211/bin

export MUJOCO_KEY_PATH=~/.mujoco${MUJOCO_KEY_PATH}

export MJLIB_PATH=~/.mujoco/lib/libmujoco.so .2.1.1

# nvidia

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/nvidia

export LD_PRELOAD=~/anaconda3/envs/d3rlpy/lib/python3 .7 /site-packages/d3rlpy/dataset.cpython -37 m-x86_64-linux-gnu.so

# export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libGLEW.so:/usr/lib/nvidia-465/libGL.so

export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libGLEW.so

更多的坑大家可以參閲issue:  http://github.com/rail-berkeley/d4rl/issues

坑6:有的夥伴可能會用pycharm去運行mujoco會出現一個問題就是:有nvidia的環境變量沒有mujoco的,有mujoco的沒有nvidia的

Exception: 

Missing path to your environment variable. 

Current values LD_LIBRARY_PATH=

Please add following line to .bashrc:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jqw/.mujoco/mujoco210/bin

# 或者這樣的

Exception: 

Missing path to your environment variable. 

Current values LD_LIBRARY_PATH=LD_LIBRARY_PATH:/usr/lib/nvidia

Please add following line to .bashrc:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jqw/.mujoco/mujoco210/bin

解決辦法

直接在pycharm運行配置中修改環境變量:python文件上右鍵後進入 Modify Run Configuration

image-20220328180705232

重點就是兩個變量之間用 冒號隔開":",不是分號";", 然後就ok了

PYTHONUNBUFFERED= 1 ;LD_LIBRARY_PATH=LD_LIBRARY_PATH:/usr/lib/nvidia:$LD_LIBRARY_PATH:/home/jqw/.mujoco/mujoco210/bin

TD3+BC算法詳解

論文信息 :Scott Fujimoto, Shixiang Shane Gu: “A Minimalist Approach to Offline Reinforcement Learning”, 2021; arXiv:2106.06860.

本文是Google Brain團隊和McGill大學合作,由 TD3、BCQ 的作者 Fujimoto 提出並發表在NeurIPS2020 頂會上的文章,本文方法最大的優點是: 方法簡單、無任何複雜數學公式、可實現性強(開源)、對比實驗非常充分 (滿分推薦),正如標題一樣(A minimalist approach)。

摘要 :相比於幾篇博客講過的BCQ(通過擾動網絡生成動作,不斷將學習策略和行為策略拉進)、BEAR(通過支撐集匹配避免分佈匹配的問題)、BRAC(通過VP和PR兩個方法正則化)以及REM(通過隨機集成混合方法對多個值函數求取凸優化最優的魯棒性)方法。本文作者提出的TD3+BC方法,結構簡單,僅在值函數上添加一個行為克隆(BC)的正則項,並對state進行normalizing,簡單的對TD3修改了幾行代碼就可以與前幾種方法相媲美,結果表明:TD3+BC效果好,訓練時間也比其他少很多。

1. Offline RL的一些挑戰。

  • 實現和Tune的複雜性(Implementation and Tuning Complexities) , 在強化學習中,算法的實現、論文的復現都是一個非常難的問題,很多算法並沒法去復現,即使相同的seed有時候未必也能達到效果。同樣在Offline中仍然存在,此外在Offline中還要解決分佈偏移、OODd等之外的一些問題。

  • **額外算力需求(Extra Computation Requirement)**,由於過於複雜的數學優化、過多的超參數等算法的執行帶來了很長的訓練時間,導致不得不增加計算資源來學習算法使得其收斂。

  • **訓練策略的不穩定性(Instability of Trained Policies)**,強化學習領域的不穩定性眾所周知,所以Offline RL如何才能與Supervised leanring一樣很穩定是一個重要的研究問題。

  • **Offline RL改進問題(algorithmic/Coding/Optimization)**,包括了代碼層次的優化改進和理論結構方面的改進等。

其實上述的這些問題並不是去解決offline RL中的一些諸如分佈偏移、OOD、過估計以及等等這些問題,而是去解決 如何簡單、快速、高效的實現算法的實現與高效運行問題 ,因此作者面對這些問題,發出疑問並給出方法:

2. TD3+BC原理

2.1 TD3+BC相比於其他的優勢

下圖是TD3+BC算法相對於CQL、Fish-BRC算法的複雜性對比,從表中我們可以看到CQL和Fish-BRC在算法(algorithmic)上有了很多的變種,使用生成網絡,近似等,而TD3+BC僅僅添加了一個BC term和Normalized state,足夠的簡單。

2.2 理論部分

對於經典的DDPG、TD3等算法來講, 策略梯度的計算根據David sliver提出的如下定義,即求解狀態-動作值函數的期望值。

本文中,作者為了儘可能的讓兩個動作接近添加了一個正則項以及  ,

個人看法 : 有點像 BCQ 中的讓學習策略和行為策略之間的距離減少那種意思,只不過添加到正則項裏面.

另外一個技術點就是從代碼執行層面的優化,即 Normalize State ,具體的Normalize過程如公式所示:

其中的表示一個normalization常量,作者在文中使用了,和表示期望和標準差(standard deviation)。

實驗效果(關於縱座標Percent difference後文有説明,本部分只看效果)

最後一個技術點就是關於  的求解,作者給出了計算公式,並在後文中説取值為的時候效果最好, 實驗部分有作者做的ablation實驗證明。

最後貼出作者在 TD3 代碼上的改動部分==》 TD3+BC算法實現

2.3 經典的Rebuttal場面

此外,我們看一下作者如何rebuttle這些OpenReview提出的審稿意見[1],[2]

其實這部分蠻有意思的,我們發現大多數普通人的工作還是集中在對算法的小部分優化(數學大佬和代碼大神略過),這裏作者教你手把手給審稿人回覆(建議收藏,熱別是第2條)

審稿人:

(1)首先,該方法的新穎性似乎有點有限。作者似乎直接使 RL+BC 適應離線設置,只是他們添加了狀態歸一化,這也不是新的。作者也沒有從理論上證明這種方法的合理性。例如,作者應該證明該方法可以保證安全的策略改進,並且享有可比或更好的策略改進保證 w.r.t.先前的方法。如果沒有理論依據,並且考慮到該方法的當前形式,我認為該方法有點增量。

(2)此外,實證評估並不徹底。作者僅在 D4RL 中的簡單 mujoco 環境中評估了該方法。目前尚不清楚該方法是否可以很好地執行更多無向多任務數據集,例如螞蟻迷宮和廚房,以及更復雜的操作任務,例如 D4RL 中的 adroit。似乎該方法在隨機數據集上表現不佳。這是一個主要限制嗎?我還認為作者應該將狀態歸一化添加到所有基線以確保公平比較,因為狀態歸一化不是 RL 中的新技術。

(3)最後,我認為比較不完整。作者還應該將該方法與最近的無模型離線 RL 方法(如 [1])和基於模型的方法(如 [2,3])進行比較,後者在隨機和中等重放數據集上獲得了更好的性能。 總的來説,鑑於上述評論,我會投票支持弱拒絕。

下面我們看作者的神奇巧妙回覆

作者回復:

(1)關於新穎性:我們完全不同意我們的算法在新穎性方面是遞增的(我們在相關工作中強調了許多類似的算法)。然而,我們的主要主張/貢獻與其説這是最好的離線 RL 算法,或者説它特別新穎,不如説是令人驚訝的觀察,即使用非常簡單的技術可以匹配/優於當前算法。希望 TD3+BC 可以用作易於實現的基線或其他添加(例如 S4RL)的起點,同時消除更復雜方法所需的許多不必要的複雜性、超參數調整或計算成本. 

(2)關於經驗評估:據我們所知,我們最強的基線 Fisher-BRC 被認為是無模型算法的 SOTA,最近在 ICML 上發表。

(3)由於 D4RL 結果的標準化,我們可以直接與建議的基線進行比較(我們會將這些結果包含在最終草案中)。我們在下面報吿這些,但我們想説明兩點:

(4)MOReL 和 MOPO 來自不同的方法系列(基於模型),並且都使用特定於環境的超參數。S4RL 與我們的方法相切,只需將 CQL 替換為 TD3+BC,就可以很容易地將其添加到我們的方法中。我們的方法可以説更適合基礎算法的這些類型的添加,因為超參數更少,這意味着我們不必擔心變化之間的交互作用。 最終,我們沒有發現添加狀態歸一化可以為基線提供相同水平的好處,這可能是因為這些方法需要超參數調整來補償額外的修改。

挺有意思的,學習收藏吧!

3. 實驗及過程分析

3.1 實驗超參數

這部分是作者實驗的一些基礎,挺良心的,具體到了每一個實驗環境的版本號

這部分特意説明一下作者的良心部分:代碼版本都放出來了

3.2 衡量指標:百分比差異(Percent Difference)

這部分公式是作者實驗的參考基準計算方式,其中在博客也提出了關於 差距百分比 的疑問,特意查了了一下計算過程[3](備註,有的地方可能用了絕對值):

3.3 實驗驗證與結果簡要分析

説明:關於D4RL數據集的組成、安裝和解釋請參考博文 離線強化學習(Offline RL)系列2: (環境篇)D4RL數據集簡介、安裝及錯誤解決

本實驗參數 HC = HalfCheetah, Hop = Hopper, W = Walker, r = random, m = medium, mr = medium-replay, me = medium-expert, e = expert. While online algorithms (TD3) typically have small episode variances per trained policy (as they should at convergence),

3.3.1 D4RL驗證討論

3.3.2 運行訓練時間討論

可以從實驗結果中很直白的看到,CQL、FishBRC與TD3+BC()的運行時間, 其實這與算法的複雜性緊密相關,對於TD3來説只需要去根據超參數學習網絡即可,但對於CQL等算法,需要學習一堆的參數。

3.3.3 消融(ablation)實驗(如何確定?)

這部分其實對比了vanillaBC方法和區別,同時就參數做了對比得出了最好的。

2. Offline RL誤差的來源

2.1 分佈偏移(distribution shift)

分佈偏移最主要的原因是 learned policybehavior policy 之間的偏移(從圖中我們可以清晰的看到兩者之間的區別),這也是offlineRL相比於Online RL在不能交互學習的情況下造成的。

2.2 OOD(out-of-distribution) action問題

OOD問題在Offline RL中非常常見,簡單的可以理解為 狀態-動作 對可能不在我們的offline Dataset中,對應的分佈也一樣,即學習分佈遠在(far outside)訓練(training distribution)分佈之外。

那麼訓練和優化過程如下:

結合上圖,其實真正解決這個問題,第一直觀的想法就是增大數據集的數量,讓數據集儘可能包含訓練分佈,這樣學習分佈基本可能會在範圍內,然而這個方法並不奏效:

作者在實驗中使用了大小不一樣的數量實驗,結果表明 即使增大train samples, 算法的性能並沒有得到有效提升 ,同時也會引發下一個 累計誤差 問題:

此外Q值誤差居高不下,是什麼原因造成的?

2.3 貝爾曼誤差(Bellman error)

這就是本文的核心問題了,深度強化學習中動態規規劃(MC,TD)最核心的就是Q函數,我們知道在Q-learning中學習的時候,目標函數Q的計算通常是利用自舉(bootstrapping)的方式,從訓練集分佈中去最大化函數估計,但由於OOD之外的數據,導致這個過程的error不斷累積,最終導致嚴重偏離學習策略。

我們在Online RL中知道,最優函數遵循最優貝爾曼方程,如下所示:

然後,強化學習對應於最小化該等式左側和右側之間的平方差,也稱為均方貝爾曼誤差 (MSBE),得到:

MSBE 在由行為策略生成的數據集中的轉換樣本上最小化。儘管最小化 MSBE 對應於有監督的迴歸問題,但該回歸的目標本身是從當前函數估計中得出的。於是對於迭代次的Q-learning來説, 總誤差(error) 可以定義為:

其中當前的貝爾曼誤差(Bellman error)為:

那麼我們就可以得出以下結論:

所以説,當一個狀態-動作分佈處於OOD之外時,我們其實是希望  很高,因為我們的優化目標是不斷將處於分佈之外的策略分佈與訓練分佈距離最小化。為了緩解這個問題,作者提出了一個解決方法就是讓 學習策略輸出的動作處於訓練分佈的支撐集(Support-set)中

所謂的 Support-set , 其實就是"學習策略只有在行為策略的密度大於閾值,而不是對密度和的值的接近約束。" 原話:

下面我們結合例子解釋一下 分佈匹配(Distribution-matching支撐集匹配(Support-set matching) 的區別,以及原理。

3. 從一個例子原因分析開始

考慮一維的Lineworld Environment問題,我們從點出發到達點,動作集分為“向左”和“向右”兩種,對應的獎勵在上圖中有標記。

那麼,行為策略在和之間的狀態下執行次優動作,可能性為 0.9,但是動作和的狀態都在分佈內(in-distribution)。

個人理解原因

3.1 Distribution-matching

如上圖,分佈匹配約束(distribution matching constraint)的學習策略可以是任意次優的,事實上,通過推出該策略達到目標 G 的概率非常小,並且隨着環境的建立而趨於 0 較大。

3.2 Support-constraint

然而,在support-constraint中,作者表明支持約束可以恢復概率為 1 的最優策略(其實原因很簡單,就是閾值的原因, 只要動作在訓練行為策略分佈的支持集內就可以)。

那麼為什麼 Distribution-matching 在這裏會失敗?

  • 如果懲罰被嚴格執行,那麼智能體將被迫在和之間的狀態中主要執行錯誤的動作,導致次優行為。

  • 如果懲罰沒有嚴格執行,為了實現比行為策略更好的策略,智能體將使用 OOD之外的action在左側的狀態執行backups,這些backups 最終會影響 狀態S下的Q值。這種現象將導致不正確的 Q 函數,從而導致錯誤的策略——可能是從 S 開始向左移動而不是向 G 移動的策略,因為 OOD 動作backups與高估偏差相結合Q-learning 可能會使狀態 S 的動作看起來更可取。如下圖所示,一些狀態需要強懲罰/約束(以防止 OOD backups),而其他狀態需要弱懲罰/約束(以實現最優性)才能使分佈匹配起作用,但是,這無法通過傳統的分佈匹配來實現方法。

通過上述分析,我們得出一個結論:我們希望的 不是學習策略和行為策略越像越好,而是學習策略能夠在行為策略的支撐集的範圍內去進行優化 , 如果學習策略和行為策略無限接近那不就是Behavior clone了,但offline無法無限的去逼近online,所以問題仍然存在。

下圖就是關於Distribution-matching 和support constraint選擇動作的區別

從圖中我們可以看到:以紅色的行為策略為基準,在distribution-matching中則僅有紫色的學習策略相符,但在support-matching中黃色的都是可以匹配的learned policy, 所以更通用。

那麼support-set matching更通用,具體是怎麼matching的呢?下文我們從論文的理論部分開始分析。

4. 理論設計及分析(核心:建議閲讀)

4.1 Support-set Matching(支撐集匹配方法)

4.1.1 支撐集匹配原理

第一步 :解決策略集定義及收斂,定義 Distribution-constraint operators 概念,如下所示:

這裏面 最關鍵 的有以下幾個地方:

  • 定義了一個策略集,且動作空間,而不是定義策略

  • 根據原始的MDP問題重新定義了一個新的 MDP" 問題,原理和bellman operator一樣,同樣利用了不動點去證明收斂性。

為了分析在近似誤差下執行backup的 次優(suboptimality) 問題,作者提出兩個方面:

  • 次優偏置(suboptimality bias) , 也就是最優的學習策略如果在行為策略支撐集之外的話,仍然能夠找到次優策略。

  • 次優常數(suboptimality constant) ,分佈偏移、OOD之外的次優問題,次優常數相當於做了一個限定(which measures how faris from), 越小,policy set 距離optimal policy 的距離越小。】

這裏定義了一個 Concentrability越小,就説明policy set 中的policy 與 behavior policy 越相似】

第二步 :最後作者給出了一個邊界(bound)

證明過程如下:

這裏的[Error Bounds for Approximate Value Iteration] 中解釋了

We choose policies only lying in high support regions of the behaviour policy . Allows for a tradeoff between : Keeping close to the data (minimizing amount of propagated error) Having freedom to find the optimal policy

這裏作者不是對所有策略執行最大化,而是對集合 Pi_eps 執行受限最大值,為了實際執行此操作,使用執行支撐匹配的約束。

其中作者原話是:

We change the policy improvement step, where instead of performing a maximization over all policies, we perform the restricted max over the setand in order to do this practically, we use a constrained formulation, where we use a constraint that performs support matching. We constrain the maximum mean discrepancy distance between the dataset and the actor to a maximal limit, using samples.

4.1.2 為什麼要從選取動作?

通過以上的方法,問題最終化解為一個求解最優問題:

4.2 Maximum Mean Discrepancy (MMD)

4.2.1 MMD原理

MMD [A Kernel Two-Sample Test] 方法是一種統計測試以確定兩個樣本是否來自不同的分佈,檢驗統計量是再現 kernel Hilbertspace (RKHS) 的單位球中函數的最大期望差異。

4.2.2 MMD代碼求解

def gaussian_kernel(x, y, sigma=0.1):

return exp(-(x - y).pow(2).sum() / (2 * sigma.pow(2)))

def compute_mmd(x, y):

k_x_x = gaussian_kernel(x, x)

k_x_y = gaussian_kernel(x, y)

k_y_y = gaussian_kernel(y, y)

return sqrt(k_x_x.mean() + k_y_y.mean() - 2*k_x_y.mean())

4.2.3 與KL divergence的區別

4.3 雙梯度下降(Dual Gradient Descent)(可跳過)

4.3.1 DGD原理及圖解[Dual Gradient Descent]

雙梯度下降是一種在約束條件下優化目標的流行方法。在強化學習中,它可以幫助我們做出更好的決策。

5. BEAR算法執行過程

5.1 BEAR原版

5.2 BEAR修補版

6. 部分結果分析

7. Pytorch代碼實現部分淺析

本代碼由原作者開源 [Github]

7.1 Installing & running

python main.py --buffer_name=buffer_walker_300_curr_action.pkl --eval_freq=1000 --algo_name=BEAR

--env_name=Walker2d-v2 --log_dir=data_walker_BEAR/ --lagrange_thresh=10.0

--distance_type=MMD --mode=auto --num_samples_match=5 --lamda=0.0 --version=0

--mmd_sigma=20.0 --kernel_type=gaussian --use_ensemble_variance="False"

本文來源自: http://www.zhihu.com/column/c_1487193754071617536

「其他文章」