1. 基本概念
1.1 概率論的基礎知識
a. 隨機變數
概念:是一個未知的量,值是由隨機事件結果來決定的。
-
使用大寫 X 來表示隨機變數
如在拋硬幣之前我是不知道硬幣結果是什麼,但是我知道事件的概率
-
使用小寫 x 來表示隨機變數 X 的觀測值,只是表示一個數,沒有隨機性,如下面觀測到三次拋硬幣的結果
觀測值:當隨機事件結束,會表徵出一個結果,比如硬幣落地後是正 / 反面朝上
- x1 = 0
- x2 = 1
- x3 = 1
b. 概率密度函式
Probability Density Function,PDF.
意義:隨機變數再某個確定的取值點附近的可能性。
舉例理解:
連續分佈:
如高斯分佈這個連續分佈
μ 為均值,σ 為標準差。
橫軸是隨機變數 X 取值,縱軸是概率密度,曲線是高斯分佈概率密度函式P(X),說明在原點附近概率取值比較大,在遠離原點附近概率取值比較小
離散分佈:
對於離散隨機變數:X∈1,3,7
則對應的 PDF 為:
性質:
-
隨機變數 X 作用域定義為花體 \(\mathcal{X}\)
-
如果 X 是連續的變數分佈,則可對概率密度函式做定積分,值為1。
\[\int_{\mathcal{X}}p(x)dx=1 \] -
如果 X 是離散的變數分佈,則可對 p(x) 做一個加和,值為1。
\[\sum_{x\in \mathcal{X}}p(x) = 1 \]
c. 期望
-
對於作用域 \(\mathcal{X}\) 中的隨機變數 X
-
對於連續分佈,函式 f(x) 的期望為:
\[\mathbb{E}[f(x)]=\int_{\mathcal{X}}p(x) \cdot f(x) dx \] -
對於離散分佈,函式$$f(x)$$的期望為:
\[\mathbb{E}[f(x)]=\sum_{x\in \mathcal{X}}p(x)\cdot f(x) \]p(x) 是概率密度函式
d. 隨機抽樣
Random Sampling.
假設有10個球,2紅,5綠,3藍,隨機抽一個球,會抽到哪個球?
在抽之前,抽到球的顏色就是個隨機變數$$X$$,有三種可能取值紅\綠\藍。抽出一個球,是紅色,這時候就有了一個觀測值 x 。上述過程就叫隨機抽樣
換一個說法:
箱子裡有很多個球,也不知道有多少個。做隨機抽樣,抽到紅色球概率是0.2,綠色球概率是0.5,藍色球概率是0.3。抽一個球,記錄顏色,然後放回去搖勻,重複一百次,大概會有20個是紅色,50個是綠色,藍色有30個。這樣就有統計意義。
模擬一下過程:
from numpy.random import choice
# choice函式用於抽樣
samples = choice(['R','G','B'], size = 100, p = [0.2, 0.5, 0.3])
print(samples)
# 輸出為
['G' 'G' 'G' 'B' 'G' 'G' 'G' 'R' 'B' 'G' 'R' 'B' 'G' 'G' 'G' 'B' 'B' 'G'
'G' 'G' 'R' 'R' 'R' 'G' 'B' 'G' 'R' 'B' 'R' 'G' 'R' 'G' 'B' 'B' 'G' 'G'
'B' 'R' 'R' 'G' 'G' 'G' 'G' 'B' 'G' 'B' 'G' 'G' 'G' 'B' 'G' 'B' 'R' 'R'
'G' 'G' 'B' 'B' 'G' 'G' 'B' 'B' 'R' 'G' 'G' 'G' 'B' 'B' 'G' 'G' 'B' 'G'
'G' 'G' 'G' 'G' 'B' 'G' 'R' 'B' 'G' 'G' 'G' 'B' 'G' 'R' 'B' 'R' 'B' 'G'
'G' 'B' 'G' 'R' 'G' 'G' 'G' 'G' 'G' 'G']
1.2 強化學習術語 / Terminologies
a. state與action
假設在玩超級瑪麗
狀態state $$s$$ 可以表示為當前遊戲這一幀的畫面
觀測到狀態後可以做出相應動作action $$ a \in {{left, right, up} }$$
這個例子中馬里奧被稱為agent,若在自動駕駛中,汽車就被稱為agent。動作誰做的就被稱為agent。
b. 策略policy
$policy \space \pi \(,指根據觀測到的狀態,然後做出決策,來控制 agent 運動。\)\(\pi\)$是一個概率密度函式。
-
數學定義:\(\pi :(s,a) \mapsto [0,1]:\)\(\pi(a|s) = \mathbb{P}(A=a|S=s)\)
-
意思給定狀態 \(s\),做出動作 \(a\) 的概率密度
-
比如給定一個馬里奧的執行狀態圖
\(\pi(left|s) =0.2\)向左概率是0.2
\(\pi(right|s)=0.1\)向右概率是0.1
\(\pi(up|s)=0.7\)向上概率是0.7
-
如果讓策略函式自動來操作,它就會做一個隨機抽樣,0.2的概率向左,0.1的概率向右,0.5的概率向上。
-
強化學習就是學習這個策略函式。
-
給定觀測到的狀態state \(S=s\),agent的action \(A\)可以是隨機的(最好是隨機)
c. 獎勵reward
agent做出一個動作,遊戲就會給一個獎勵,獎勵通常需要自己來定義。獎勵定義好壞非常影響強化學習結果。
例如在馬里奧例子中:
- 馬里奧吃到一個金幣:\(R=+1\)。
- 贏了這場遊戲:\(R=+10000\)。
- 碰到敵人 goomba,game over:\(R=-10000\)。
- 啥也沒發生:\(R=0\)。
強化學習目標就是獎勵獲得的總額儘量要高。
d. 狀態轉移 state transition
當前狀態下,馬里奧做一個動作,遊戲就會給出一個新的狀態。比如馬里奧跳一下,螢幕當前幀就不一樣了,也就是狀態變了。這個過程就叫狀態轉移。
-
狀態轉移可以確定的也可以是隨機的。
-
狀態轉移的隨機性來自於環境,這裡環境就是遊戲的程式,程式決定下一個狀態是什麼。
-
狀態轉移函式:\(p(s'|s,a)=\mathbb{P}(S'=s'|(S=s,A=a))\)
意為觀測到當前狀態 \(s\) 與動作 \(a\) ,\(p\) 函式輸出狀態 \(s'\) 的概率。
如果馬里奧向上跳後,goomba向左和向右的概率分別是0.8和0.2,這個狀態轉移函式只有環境知道,玩家是不知道的。
e. 互動
agent environment interaction.
- 環境告訴Agent一個狀態\(s_t\)
- agent看到狀態$$s_t$$之後,做出一個動作\(a_t\)
- agent做出動作後,環境會更新狀態為\(s_{t+1}\),同時給出一個獎勵\(r_t\)。
1.3 強化學習中的隨機性
隨機性有兩個來源:
- agent動作的隨機性
- 狀態轉移的隨機性
第一個隨機性是從agent動作來的,因為動作是根據 policy 函式隨機抽樣得來的。
-
\(\pi(left / s)=0.2\)
-
\(\pi(right / s)=0.1\)
-
\(\pi(up / s)=0.7\)
-
agent可能做其中任何一箇中動作,但動作概率有大有小。
另一個隨機性來源是狀態轉移。
- 假定agent做出一個動作,那麼環境就要生成一個新狀態\(S'\)。
- 環境用狀態轉移函式 \(p\) 算出概率,然後用概率來隨機抽樣來得到下一個狀態
1.4 用AI玩遊戲
通過強化學習得到的 policy 函式\(\pi\),來控制 agent:
-
觀測到當前的狀態 s1
-
ai 通過 policy 函式 隨機抽樣 做出 動作 a1(例子中的 左、右、上)
-
environment 會生成一個 下一個狀態 s2,並給 agent 一個獎勵 r1
值得注意的是,這個 \(r_1\) 是什麼時候給的?
是在狀態 state \(s_2\) 的時候給的。
-
ai 繼續以新的狀態 作為輸入,生成下一個動作 a2
-
.......
-
迴圈直到遊戲結束(贏或者輸)
通過上面的步驟可以得到一個 (state, action, reward) 軌跡Trajectory(序列):
s1,a1,r1,s2,a2,r2,⋯,st,at,rt
1.5 Reward && Return
Reward 在上面介紹過, Return 是 Reward 的線性組合。
a. Return 的定義
Return 回報,又被稱為cumulative future reward,未來的累計獎勵
-
\[U_t = R_t+R_{t+1}+R_{t+2}+\cdots \]
把從 t 時刻開始的獎勵全都加起來,一直加到遊戲結束的最後一個獎勵。
不過我們要想一個事情:
對於 Ut 而言,Rt 和 Rt+1 同樣重要嗎?
- 假設有兩個選項
- 立馬給你一百塊
- 一年後給你一百塊
一般大多數人會選立刻拿到100塊,因為未來的不確定性很大。
如果改成現在給你80,或者一年後給你100塊,這時候就不像上面那麼肯定了。
這說明, Ut 的各個求和項,未來的獎勵不如現在的獎勵好,應當打一個折扣。即:Rt+1 的 權重Weights 要小於 Rt。
所以我們針對這個考慮進行一個調整,對 Rt+1 以後進行一個權重調整,也即 強化學習中的 Discounted Return.
Discounted Return,折扣回報,也被稱為:cumulative discounted future reward
-
折扣率稱為 \(\gamma\),該值介於0到1之間,是一個超引數,決定未來回報的重要程度。
-
調整之後的 Return 為:
\[U_t=R_t+\gamma R_{t+1}+\gamma^2 R_{t+2}+\gamma^3 R_{t+3}+\cdots \]
關於公式的字母表達問題:
假如遊戲已經結束了,所有的獎勵都觀測到了,那麼獎勵就都是數值,用小寫 r 表示。
如果在 t 時刻遊戲還沒有結束,這些獎勵就還都是隨機變數,就用大寫字母 R 來表示獎勵。
回報 U 依賴於獎勵 R,所以它也是個隨機變數,也要用大寫字母表示。
b. 回報的隨機性 Randomness in Returns
- \(U_t = R_t + \gamma{}R_{t+1}+\gamma^2 R_{t+2} + \gamma^3 R_{t+3} + ...\)
上面1.3 提到 隨機性 有兩個來源:
-
動作是隨機的
\(\mathbb{P}[A=a|S=s]=\pi(a|s)\)
-
下一個狀態是隨機的
\(\mathbb{P} [S'=s'|S=s,A=a]=p(s'|s,a)\)
對於任意時刻的 $ i\geq t$,獎勵 \(R_i\) 取決於 \(S_i\) 和 $$A_i$$,而回報 \(U\) 又是未來獎勵的總和。
因此,觀測到 t 時刻狀態 \(s_t\),回報 \(U_t\) 就依賴於如下隨機變數
- $ A_t, A_{t+1}, A_{t+2},\cdots $$和 $$S_{t+1},S_{t+2},\cdots$
1.6 價值函式
a. 由來
Action-Value Function \(Q(s,a)\)
上面說到Discounted Return 折扣回報,cumulative discounted future reward
- \(U_t=R_t+\gamma R_{t+1}+\gamma^2 R_{t+2}+\gamma^3 R_{t+3}+\cdots\)
\(U_t\)是個隨機變數,在 t 時刻並不知道它的值是什麼,那如何評估當前形勢?
可以對$$U_t$$求期望,把裡面的隨機性都給積掉,得到的就是個實數。打個比方就是拋硬幣之前,不知道結果是什麼,但知道正反面各有一半的概率,正面記作1,反面記作0,得到的期望就是0.5。
同樣對 \(U_t\) 求期望,就可以得到一個數,記作 \(Q_\pi\)
這個期望怎麼求的?
-
把 \(U_t\) 當作未來所有動作 \(A\) 和狀態 \(S\) 的一個函式,未來動作 \(A\) 和狀態 \(S\) 都有一個隨機性;
-
動作 \(A\) 的概率密度函式是策略函式 (policy函式)
$ \mathbb{P}(A=a|S=s) = \pi(a|s)$ ;
-
狀態$$S$$的概率密度函式是狀態轉移函式 \(\mathbb{P}(S'=s'|S=s,A=a) = p(s'|s,a)\)
-
期望就是對這些 \(A\) 和 \(S\) 求的,把這些隨機變數都用積分給積掉,這樣除了 \(S_t\) 與 \(A_t\),其餘所有的隨機變數 (\(A_{t+1},A_{t+2},\cdots\) 和 \(S_{t+1},S_{t+2},\cdots\)) 都被積掉了。
求期望得到的函式就被稱為動作價值函式
\(Q_\pi(s_t,a_t)=\mathbb{E}[U_t | S_t=s_t,A_t = a_t]\).
-
價值函式依賴於什麼呢?
-
\(S_t\) 和 \(A_t\)
\(S_t\) 與 \(A_t\) 被當作被作為觀測到的數值來對待,而不是隨機變數,所以沒有被積分積掉。 $$Q_\pi$$ 的值依賴於 \(S_t\) 和 \(A_t\) 。
-
策略函式 Policy
積分的時候會用到 Policy 函式\(\pi\)。
-
b. 動作價值函式
Action-value function.
對於策略 \(\pi\),動作價值函式定義如下
- \(Q_\pi(s_t,a_t) = \mathbb{E}[U_t|S_t=s_t,A_t=a_t]\)
- \(Q_\pi\)依賴於當前動作\(a_t\)與狀態\(s_t\),還依賴於策略函式\(\pi\) (積分時會用到它,\(\pi\)不一樣,得到的\(Q_\pi\)就不一樣)。
- 直觀意義:如果用策略函式\(\pi\),那麼在\(s_t\)這個狀態下做動作\(a_t\),是好還是壞。它會給當前狀態下每個動作打分,這樣就知道哪個動作好那個動作差。
動作價值函式依賴於\(\pi\),那麼如何去掉 \(\pi\) ?
可以對 \(Q_\pi\) 關於 \(\pi\) 求最大化。意思就是可以有無數種策略函式 \(\pi\),但我們要採用最好的那一種策略函式,即讓 \(Q_\pi\) 最大化的那個函式。
\(Q_{\pi}\)最大化的那個函式為:最優動作價值函式 Optimal action-value Function 。
- \(Q^*(s_t,a_t) = \mathop{max}\limits_{\pi}Q_\pi(s_t,a_t)\)
- 直觀意義:對動作 a 做評價,如果當前狀態是 \(s_t\),\(Q*\) 會告訴我們動作 \(a_t\) 好不好。agent就可以拿 Q* 對動作的評價來作決策。
c. 狀態價值函式
State-value function. 狀態價值函式 \(V_\pi\)是動作價值函式\(Q_\pi\)的期望。
- \(V_π(s_t)=E_A[Q_π(s_t,A)]\)
- 而\(Q_\pi\) 與策略函式 \(\pi\) ,狀態 \(s_t\) 和動作 \(a_t\) 都有關,可以將 A 作為隨機變數,對 A 求期望消掉 A, 這樣 \(V_\pi\) 就只與 \(\pi\) 和 \(s\) 有關。
直觀意義:告訴我們當前局勢好不好,比如下圍棋,當前是快贏了還是快輸了。評價的是當前的 state。
這裡期望是關於隨機變數 A 求的,它的概率密度函式是
\(π(⋅∣s_t)\),根據期望定義(線性可加性),可以寫成連加或者積分的形式。
如果動作是離散的,如上下左右:
-
\(V_\pi(s_t) = \mathbb{E_A}[Q_\pi(s_t,A)]=\sum_a\pi(a|s_t)\cdot{Q_\pi}(s_t,a)\)
這裡動作是離散的。
如果動作是連續的,如方向盤角度,從正90度到負90度。
-
\(V_\pi(s_t) = \mathbb{E_A}[Q_\pi(s_t,A)]=\int\pi(a|s_t)\cdot {Q_\pi}(s_t,a)da\)
這裡動作是連續的
d. 總結
-
動作價值函式\(Q_\pi(s_t,a_t) = \mathbb{E}[U_t|S_t=s_t,A_t=a_t]\)
它跟策略函式 \(\pi\),狀態 \(s_t\),動作 \(a_t\)有關,是 \(U_t\) 的條件期望。
能告訴我們處於狀態 s 時採用動作 a 是否明智,可以給動作 a 打分。
-
狀態價值函式\(V_{\pi}(s_t) = \mathbb{E}_A[Q_\pi(s_t,A)]\)
它是把\(Q_\pi\)中把 A 用積分給去掉,這樣變數就就只剩狀態 s 。它跟策略函式 \(\pi\),狀態 \(s_t\) 有關,跟動作 \(a_t\) 無關。
能夠評價當前局勢是好是壞,也能評價策略函式的好壞,如果 \(\pi\) 越好,則 \(V_\pi\) 期望值\(\mathbb{E}_S[V_\pi(S)]\)越大。
1.7 如何用強化學習玩遊戲
a. 兩種學習方式
假設在馬里奧遊戲中,目標在於儘可能吃金幣,避開敵人,通關。如何做?
-
一種是學習一個策略函式 \(\pi(a|s)\),這叫 policy basement learning 策略學習,然後基於此來控制agent做動作。
每觀測到一個狀態 \(s_t\),就把 \(s_t\) 作為 \(\pi(\cdot|s)\) 函式輸入,\(\pi\) 函式輸出每一個動作的概率,基於概率來 隨機取樣 獲取動作 \(a_t\),讓agent 來執行這個\(a_t\)。
-
另一種是學習最優動作價值函式\(Q^*(s,a)\),這叫 value basement learning 價值學習,它告訴如果處於狀態s,做動作a是好還是壞。
每觀測到一個狀態 \(s_t\),把 \(s_t\) 作為 \(Q^*(s,a)\) 函式輸入,讓 \(Q^*(s,a)\) 對每一個動作做一個評價,得到每個動作的 Q 值。選擇輸出值最大的動作,\(a_t = argmax_a Q^*(s_t,a)\),因為 Q 值是對未來獎勵總和的期望,如果向上動作 Q 值比其他動作 Q 值要大就說明向上跳的動作會在未來獲得更多的獎勵。
b. OpenAI Gym
OpenAI Gym https://gym.openai.com 是強化學習最常用的標準庫。如果得到了 \(\pi\) 函式或者 \(Q*\) 函式,就可以用於Gym的控制問題和小遊戲,來測試演算法的優劣。
按照官方文件,安裝 gym,就可以用 python 呼叫 gym 的函式。
安裝 gym 想專門另開一篇筆記來記錄,目前跑視訊教程裡的demo還是可以的。
簡易安裝過程:
pip install gym==0.15.7 -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
截止2022-07-03,gym最新版本是0.21,但由於我的 python 環境為 3.6.4,所以我的 gym版本需要下降。
我的 pip 最近總是連線不到遠端庫,執行
pip install 庫
會報錯:Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAI LED] certificate verify failed (_ssl.c:726)'),)': /packages/0f/fb/6aecd2c8c9d0ac 83d789eaf9f9ec052dd61dd5aea2b47ffa4704175d7a2a/psutil-5.4.8-cp27-none-win_amd64. whl
所以需要命令列後面的部分。
然後其他的東西我還沒有裝。如果裝了會更新在安裝筆記裡。參考教程為:
- https://blog.csdn.net/weixin_33654339/article/details/113538141
- Gym Documentation (gymlibrary.ml)
- https://github.com/openai/gym
c. gym 例程
import gym
import time
# 生成 CartPole 環境
env = gym.make('CartPole-v0')
# 重置環境
state = env.reset()
# 這裡的迴圈就是上面 s,a,r的過程
for t in range(10000):
# 彈出視窗來顯示遊戲情況
env.render()
print(state)
# 隨機均勻抽樣一個動作記為 action
# 這裡是為了圖方便,實際應用應該通過policy函式或者Q*來選擇。
action = env.action_space.sample()
# 把action輸入到step()函式,即agent執行這個動作
state,reward,done,info = env.step(action)
# 為了不讓視窗太快消失
time.sleep(1)
if done:
print("Finished")
break
env.close()
執行效果:
如何在Typora 中使用行內公式:
- 以前只會使用行間公式,但在這篇筆記裡十分不方便,查了一下。
- 在偏好設定-> markdown -> 勾選內聯公式。
- 需要關閉檔案重啟一下才能看到效果。