1 基础知识
1 概率論基礎
1.1 隨機變量
隨機變量是一個不確定量,它的值取決于一個隨機事件的結果。比如拋一枚硬幣,正面朝上記為0,反面朝上記為1.
拋硬幣是個隨機事件,其結果記為隨機變量X。X有兩種取值結果:0/1.拋硬幣之前X是未知的且帶有隨機性。拋硬幣之后,X便有了觀測值,記作x(小寫)。
1.2 概率密度函數
概率密度函數(PDF)描述一個連續概率分布——即變量的取值范圍X 是個連續集合。正態分布是最常見的一種連續概率分布,隨機變量X 的取值范圍是所有實數R。正態分布的概率密度函數是:
此處的μ 是均值,σ 是標準差。
這些都是大學學過的 一筆帶過~
1.3 期望
p(x)是概率密度函數
1.4 隨機抽樣
強化學習中常用到隨機抽樣,此處給一個直觀的解釋。如圖所示,箱子里有10個球,其中2 個是紅色,5 個是綠色,3 個是藍色。我現在把箱子搖一搖,把手伸進箱子里,閉著眼睛摸出來一個球。當我睜開眼睛,就觀測到球的顏色,比如紅色。這個過程叫做隨機抽樣,本輪隨機抽樣的結果是紅色。如果把抽到的球放回,可以無限次重復隨機抽樣,得到多個觀測值。
可以用計算機程序做隨機抽樣。假設箱子里有很多個球,紅色球占20%,綠色球占50%,藍色球占30%。如果我隨機摸一個球,那么抽到的球服從這樣一個離散概率分布:?
下面的Python 代碼按照概率質量p 做隨機抽樣,重復100 次,輸出抽樣的結果:
from numpy.random import choice samples = choice(['R', 'G', 'B'],###隨機變量集合為[R,G,B]size = 100,###重復抽樣100次p = [0.2, 0.5, 0.3])##R,G,B被選中的概率分別為0.2,0.5,0.3 print(samples) samples = samples.tolist() print(samples.count('R')/100) print(samples.count('G')/100) print(samples.count('B')/100)輸出:
2 強化學習中的術語
2.1 state和action
2.1.1 state狀態
在每個時刻,環境有一個狀態(state),可以理解為對當前時刻環境的概括。在超級瑪麗的例子中,可以把屏幕當前的畫面(或者最近幾幀畫面)看做狀態。玩家只需要知道當前畫面(或者最近幾幀畫面)就能夠做出正確的決策,決定下一步是讓超級瑪麗向左、向右、或是向上。因此,狀態是做決策的依據。
再舉一個例子,在中國象棋、五子棋游戲中,棋盤上所有棋子的位置就是狀態,因為當前格局就足以供玩家做決策。假設你不是從頭開始一局游戲,而是接手別人的殘局。你只需要仔細觀察棋盤上的格局,你就能夠做出決策。知道這局游戲的歷史記錄(即每一步是怎么走的),并不會給你提供額外的信息。
2.1.2 action動作
動作(action)是智能體基于當前的狀態所做出的決策。在超級瑪麗的例子中,假設瑪麗奧只能向左走、向右走、向上跳。那么動作就是左、右、上三者中的一種。在圍棋游戲中,棋盤上有361 個位置,于是有361 種動作,第i 種動作是指把棋子放到第i 個位置上。動作的選取可以是確定性的也可以是隨機的。隨機是指以一定概率選取一個動作,后面將會具體討論。
2.2 policy π策略
策略的意思是根據觀測到的狀態,如何做出決策,即如何從動作空間中選取一個動作。舉個例子,假設你在玩超級瑪麗游戲,當前屏幕上的畫面是上上圖,請問你該做什么決策?有很大概率你會決定向上跳,這樣可以避開敵人,還能吃到金幣。向上跳這個動作就是你大腦中的策略做出的決策。
實際上,π(a|s)是一個概率密度函數(概率分布),是給定狀態s,做出動作a的概率密度。agent一般會進行隨機抽樣來執行動作,三個動作都有可能執行。 強化學習就是agent學習policy的過程。
2.3 reward獎勵
獎勵是指在智能體執行一個動作之后,環境返回給智能體的一個數值。獎勵往往由我們自己來定義,獎勵定義得好壞非常影響強化學習的結果。比如可以這樣定義,瑪麗奧吃到一個金幣,獲得獎勵+1;如果瑪麗奧通過一局關卡,獎勵是+1000;如果瑪麗奧碰到敵人,游戲結束,獎勵是-1000;如果這一步什么都沒發生,獎勵就是0。怎么定義獎勵就見仁見智了。我們應該把打贏游戲的獎勵定義得大一些,這樣才能鼓勵瑪麗奧通過關卡,而不是一味地收集金幣。
通常假設獎勵是當前狀態s、當前動作a、下一時刻狀態s′ 的函數,把獎勵函數記作r(s, a, s′)。 有時假設獎勵僅僅是s 和a 的函數,記作r(s, a)。我們總是假設獎勵函數是有界的,即對于所有a∈A 和s, s′∈S,有|r(s, a, s′)| < ∞。
2.4 state transition狀態轉移
指智能體從當前t 時刻的狀態s 轉移到下一個時刻狀態為s′ 的過程。在超級瑪麗的例子中,基于當前狀態(屏幕上的畫面),瑪麗奧向上跳了一步,那么環境(即游戲程序)就會計算出新的狀態(即下一幀畫面)。
狀態轉移可以是確定的也可以是隨機的。通常認為其實隨機的。
可以將狀態轉移表示為一個條件概率:
即當前狀態為s,執行動作a,下一狀態為s'的概率。
2.5 agent與env(環境)的交互
馬里奧游戲中,我們將當前游戲界面看出當前狀態St,agent看到狀態St,執行動作at,執行之后,環境更新狀態為St+1。同時環境會反饋給agent一個獎勵rt.
2.7 trajectory軌跡
軌跡(trajectory)是指一回合(episode)游戲中,智能體觀測到的所有的狀態、動作、獎勵:
下圖描繪了軌跡中狀態、動作、獎勵的順序。在t 時刻,給定狀態St = st,下面這些都是觀測到的值:
而下面這些都是隨機變量(尚未被觀測到):
一個trajectory:
3 強化學習中的隨機性
3.1 動作的隨機性
動作的隨機性來自于隨機決策。給定當前狀態s,策略函數π(a|s) 會算出動作空間A 中每個動作a 的概率值。智能體執行的動作是隨機抽樣的結果,所以帶有隨機性。
3.2 狀態轉移的隨機性
狀態的隨機性來自于狀態轉移函數。當狀態s 和動作a 都被確定下來,下一個狀態仍然有隨機性。環境(比如游戲程序)用狀態轉移函數p(s′|s, a) 計算所有可能的狀態的概率,然后做隨機抽樣,得到新的狀態。
4 rewards and returns
4.1 回報return
4.1.1 return
又叫做未來的累計獎勵。把t 時刻的回報記作隨機變量Ut。如果一回合游戲結束,已經觀測到所有獎勵,那么就把回報記作ut。設本回合在時刻n 結束。定義回報為:
回報有什么用呢?回報是未來獲得的獎勵總和,所以智能體的目標就是讓回報盡量大,越大越好。強化學習的目標就是尋找一個策略,使得回報的期望最大化。這個策略稱為最優策略(optimum policy)。?
4.1.2 折扣回報 discounted return
思考一個問題:在t 時刻,請問獎勵rt 和rt+1 同等重要嗎?假如我給你兩個選項:第一,現在我立刻給你100 元錢; 第二,等一年后我給你100 元錢。你選哪個?理性人應該都會選現在得到100 元錢。這是因為未來的不確定性很大,即使我現在答應明年給你100 元,你也未必能拿到。大家都明白這個道理:明年得到100 元不如現在立刻拿到100元。
要是換一個問題,現在我立刻給你80 元錢,或者是明年我給你100 元錢。你選哪一個?或許大家會做不同的選擇,有的人愿意拿現在的80,有的人愿意等一年拿100。如果兩種選擇一樣好,那么就意味著一年后的獎勵的重要性只有今天的γ = 0.8 倍。這里的γ = 0.8 就是折扣率(discount factor)。這些例子都隱含獎勵函數是平穩的。
同理,在MDP 中,通常使用折扣回報(discounted return),給未來的獎勵做折扣。這是折扣回報的定義:
這里的γ∈[0, 1] 叫做折扣率。對待越久遠的未來,給獎勵打的折扣越大。 是一個超參數,需要我們自己調節。
return的隨機性來源:
5 value function價值函數
5.1 動作價值函數Q(s,a)
Ut是個隨機變量,它依賴于未來所有的動作與狀態。
我們可以對Ut求期望,(積分掉其中的隨機性),定義動作價值函數:
注:在概率論和統計學中,數學期望是試驗中每次可能的結果的概率乘以結果值的總和。
這里就是將隨機性積分掉,隨機性來源于未來所有狀態與動作:
這樣,未來的所有動作與狀態都被積掉,Qπ只依賴于當前的St和at。
當然,在不同policy下,得到的Qπ值是不同的。我們將最好的policy函數定義為使得Q取得最大值的函數:
稱之為最優動作價值函數。
可以通過該函數對當前動作a做出評價,當前狀態為St,則該函數會告訴我們執行動作at好不好。
5.2 狀態價值函數V(s)
將之定義為動作價值函數的期望。這里EA表示對A求期望,消掉A的影響。
A的概率密度函數是π(·|st)。
如果動作是離散的:
動作是連續的:
狀態價值函數用于評價當前狀態的好壞。如果π固定,當前狀態S越好,Vπ就越大。
同時,Vπ可用于評價policy函數好壞,π越好,Vπ的平均值
就越大。
6 Play games using reinforcement learning
我們如何控制AI來玩游戲呢?
一種辦法是學習一個policy π(a|s),這種方法稱為policy-based learning策略學習。
另一種辦法是學習一個最優動作價值函數。成為value-based learning價值學習。
7 openAI gym庫
如果你設計出一種新的強化學習方法,你應該將其與已有的標準方法做比較,看新的方法是否有優勢。比較和評價強化學習算法最常用的是OpenAI Gym,它相當于計算機視覺中的ImageNet 數據集。Gym 有幾大類控制問題,比如經典控制問題、Atari 游戲、機器人等。
Gym 中第一類是經典控制問題,都是小規模的簡單問題,比如Cart Pole 和Pendulum,見下圖。Cart Pole 要求給小車向左或向右的力,移動小車,讓上面的桿子能豎起來。Pendulum 要求給鐘擺一個力,讓鐘擺恰好能豎起來。Cart Pole 和Pendulum 都是典型的無限期MDP,即不存在終止狀態。
第二類問題是Atari 游戲,就是八、九十年代小霸王游戲機上拿手柄玩的那種游戲,Pong 中的智能體是乒乓球拍,球拍可以上下運動,目標是接住對手的球,盡量讓對手接不住球。Space Invader 中的智能體是小飛機,可以左右移動,可以發射炮彈。Breakout 中的智能體是下面的球拍,可以左右移動,目標是接住球,并且把上面的磚塊都打掉。Atari 游戲大多是有限期MDP,即存在一個終止狀態,一旦進入該狀態,則游戲終止。
第三類問題是機器人連續的控制問題,比如控制螞蟻、人、獵豹等機器人走路。這個模擬器叫做MuJoCo,它可以模擬重力等物理量。機器人是智能體,AI 需要控制這些機器人站立和走路。MuJoCo 是付費軟件,但是可以申請免費試用license。
舉個栗子:
下面的程序以Cart Pole 這個控制任務為例,說明怎么樣使用Gym 標準庫。
import gym env = gym.make('CartPole-v0')##生成環境。此處的環境是CartPole游戲程序。 state = env.reset()##重置環境,讓小車回到起點。并輸出初始狀態。 for t in range(100):env.render()##彈出窗口,把游戲中發生的顯示到屏幕上。print(state)action = env.action_space.sample()##方便起見,此處均勻抽樣生成一個動作。在實際應用中,應當依據狀態,用策略函數生成動作。state, reward, done, info = env.step(action)#智能體真正執行動作。然后環境更新狀態,并反饋一個獎勵。if done:#done等于1意味著游戲結束;done等于0意味著游戲繼續。print('Finished')break env.close()輸出:
?
可見輸出的是一個四維的tensor。在其他游戲中會有維度很多的情況。
接下來,我們通過小車上山的例子來說明:
首先看看該任務的觀測空間與動作空間:
import gym env = gym.make('MountainCar-v0') print('觀測空間 = {}'.format(env.observation_space)) print('動作空間 = {}'.format(env.action_space)) print('觀測范圍 = {} ~ {}'.format(env.observation_space.low,env.observation_space.high)) print('動作數 = {}'.format(env.action_space.n))輸出:
由輸出可知,觀測空間是形狀為(2,)的浮點型numpy數組,動作空間是離散的取值為{0,1,2}的int型數值。
接下里自己實現agent:
class BespokeAgent:def __init__(self, env):passdef decide(self, observation): # 決策position, velocity = observationlb = min(-0.09 * (position + 0.25) ** 2 + 0.03,0.3 * (position + 0.9) ** 4 - 0.008)ub = -0.07 * (position + 0.38) ** 2 + 0.07if lb < velocity < ub:action = 2else:action = 0return action # 返回動作def learn(self, *args): # 學習passagent = BespokeAgent(env)agent的decide()方法實現了決策功能,learn()實現了學習功能。
讓agent與環境交互:
def play_montecarlo(env, agent, render=False, train=False):episode_reward = 0. # 記錄回合總獎勵,初始化為0observation = env.reset() # 重置游戲環境,開始新回合while True: # 不斷循環,直到回合結束if render: # 判斷是否顯示env.render() # 顯示圖形界面,圖形界面可以用 env.close() 語句關閉action = agent.decide(observation)next_observation, reward, done, _ = env.step(action) # 執行動作episode_reward += reward # 收集回合獎勵if train: # 判斷是否訓練智能體agent.learn(observation, action, reward, done) # 學習if done: # 回合結束,跳出循環breakobservation = next_observationreturn episode_reward # 返回回合總獎勵上面代碼中的?play_montecarlo?函數可以讓智能體和環境交互一個回合。這個函數有?4?個參數:
- env?是環境類
- agent?是智能體類
- render是?bool?類型變量,指示在運行過程中是否要圖形化顯示。如果函數參數?render為?True,那么在交互過程中會調用?env.render()?以顯示圖形化界面,而這個界面可以通過調用?env.close()?關閉。
- train是?bool?類型的變量,指示在運行過程中是否訓練智能體。在訓練過程中應當設置為?True,以調用?agent.learn()?函數;在測試過程中應當設置為?False,使得智能體不變。
這個函數有一個返回值?episode_reward,是?float?類型的數值,表示智能體與環境交互一個回合的回合總獎勵。
接下來,我們使用下列代碼讓智能體和環境交互一個回合,并在交互過程中圖形化顯示,可用?env.close()?語句關閉圖形化界面并求出連續交互100回合的平均獎勵:
env.seed(0) # 設置隨機數種子,只是為了讓結果可以精確復現,一般情況下可刪去 episode_reward = play_montecarlo(env, agent, render=True) print('回合獎勵 = {}'.format(episode_reward)) env.close() # 此語句可關閉圖形界面episode_rewards = [play_montecarlo(env, agent) for _ in range(100)] print('平均回合獎勵 = {}'.format(np.mean(episode_rewards)))輸出:
總結一下?Gym?的用法:使用?env=gym.make(環境名)?取出環境,使用?env.reset()初始化環境,使用env.step(動作)執行一步環境,使用?env.render()顯示環境,使用?env.close()?關閉環境。
總結
- 上一篇: 量子计算机可以预测未来吗,这台量子计算机
- 下一篇: 揭秘硅谷传奇:惠普的创业故事