# 專題 強化學習 1. https://www.terasoft.com.tw/support/tech_articles/reinforcement_learning_a_brief_guide.asp 2. https://medium.com/%E9%9B%9E%E9%9B%9E%E8%88%87%E5%85%94%E5%85%94%E7%9A%84%E5%B7%A5%E7%A8%8B%E4%B8%96%E7%95%8C/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-ml-note-reinforcement-learning-%E5%BC%B7%E5%8C%96%E5%AD%B8%E7%BF%92-dqn-%E5%AF%A6%E4%BD%9Catari-game-7f9185f833b0 3. https://collegeplus.itri.org.tw/2021/02/12/%E5%BC%B7%E5%8C%96%E5%AD%B8%E7%BF%92%E7%9A%84%E7%B0%A1%E4%BB%8B%E5%8F%8A%E5%85%B6%E6%87%89%E7%94%A8%E6%83%85%E5%A2%83%E8%88%87%E9%AB%98%E6%95%88%E8%A8%93%E7%B7%B4%E6%B3%95/ 4. https://en.wikipedia.org/wiki/Reinforcement_learning 5. https://zh.wikipedia.org/wiki/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0 6. https://ithelp.ithome.com.tw/articles/10234272 7. https://darren1231.pixnet.net/blog/post/350072401-actor-critic-%E5%8E%9F%E7%90%86%E8%AA%AA%E6%98%8E 8. https://zhuanlan.zhihu.com/p/73083240 9. https://www.twblogs.net/a/5b7c53e02b71770a43da75bf 10. https://towardsdatascience.com/temporal-difference-learning-47b4a7205ca8 11. http://incompleteideas.net/book/RLbook2018.pdf 12. https://docs.ray.io/en/latest/index.html 13. https://github.com/dennybritz/reinforcement-learning 14. https://gym.openai.com/ 15. https://iter01.com/546104.html 16. https://zh.wikipedia.org/wiki/%E8%B2%9D%E7%88%BE%E6%9B%BC%E6%96%B9%E7%A8%8B 17. https://zh.wikipedia.org/wiki/%E9%A9%AC%E5%B0%94%E5%8F%AF%E5%A4%AB%E9%93%BE ## 激活函數 1. Sigmoid-https://zh.wikipedia.org/wiki/S%E5%87%BD%E6%95%B0 ## 超參數 * 參數:就是模型的輸入。 比如,深度學習的權重,偏差等 * 超參數:就是用來確定模型的一些參數。超參數不同,模型是不同的(這個模型不同的意思就是有微小的區別,比如假設都是CNN模型,如果層數不同,模型不一樣,雖然都是CNN模型哈。),超參數一般就是 在深度學習中,超參數有:學習速率,迭代次數,層數,每層神經元的個數等等。 ## 隱馬爾可夫模型HMM > http://www.huaxiaozhuan.com/%E7%BB%9F%E8%AE%A1%E5%AD%A6%E4%B9%A0/chapters/15_HMM.html > https://zhuanlan.zhihu.com/p/85454896 隱馬爾可夫模型是關於時序的概率模型,描述由一個 隱藏的馬爾可夫鏈 隨機生成不可觀測的狀態隨機序列,再由各個狀態生成一個觀察而產生觀察隨機序列的過程。 > 隱藏的馬爾可夫鏈 => 狀態隨機序列 => 觀察隨機序列 (=> 生成) * 基本定義 * Q = {q1,q2,...} => 所有可能狀態的集合 * ## model * Q-learning: * https://ithelp.ithome.com.tw/articles/10234661 * https://zh.wikipedia.org/wiki/Q%E5%AD%A6%E4%B9%A0 * 記錄下學習過的策略 => 採取什麼行動會有最大的獎勵值 * 找到一個可以最大化所有步驟的獎勵期望的策略 * Q: S × A → R * ![](https://i.imgur.com/8uXH4Sy.png) * 演算法初始化階段,Q初始值為零(由設計者設計)。在時間t時,環境的狀態為S~t~,智慧型代理人選擇一個行為a~t~,並且獲得獎勵r~t~,環境因為代理人的行為導致狀態改變為新的狀態S~t+1~,此時便可根據以下公式更新Q值。演算法的核心為簡單的==利用過去與最近的權重平均值==來迭代更新數值。 * 其中 r~t~ 代表從狀態 s~t~ 到狀態 s~t+1~ 所得到的獎勵值,α 為學習率(0 < α < 1)。γ為衰減系數(0 < γ < 1), * γ 數值越大時,智慧型代理人便更加重視未來獲得的長期獎勵 * γ 數值越小時,智慧代理人便更加短視近利,只在乎目前可獲得的獎勵。 * Q-學習最簡單的實現方式就是將獎勵值存儲在一個表格(Q-table)中,但是這種方式受限於狀態和動作空間的數目。 * ![](https://i.imgur.com/w72HiG1.png) * SARSA: https://en.wikipedia.org/wiki/State%E2%80%93action%E2%80%93reward%E2%80%93state%E2%80%93action * ![](https://i.imgur.com/7TrAJPr.png) * 基於策略的學習算法 * Q-learning 更新了對最佳狀態-動作值函數的估計Q^*^基於可用操作的最大獎勵。 * 學習率 (alpha) : * 決定了在何種程度上學習的資訊覆蓋舊的資訊。因子為 0 將使代理不學習任何東西,而因子為 1 將使代理僅考慮最近的訊息。 * 折扣因子 (gamma) : * 折扣因子決定了未來獎勵的重要性。折扣因子因子為 0 會使代理“投機取巧”或“短視”,例如[4],僅考慮當前的獎勵,而接近 1 的因子將使其爭取長期的高獎勵。如果折扣係數達到或超過 1,則{\displaystyle Q}問 值可能會有所不同。 * 初始條件 ( Q ( s~0~ , a~0~ ) ) * 低初始值,也稱為“樂觀初始條件”,可以鼓勵探索:無論發生什麼動作,更新規則都會使其具有比其他替代方案更高的值,從而增加他們的選擇概率 * 蒙特卡羅學習(MonteCarlo) * 所求解的問題本身具有內在的隨機性,藉助電腦的運算能力可以直接類比這種隨機的過程。 * 所求解問題可以轉化為某種隨機分布的特徵數, * 比如隨機事件出現的機率, * 或者隨機變數的期望值。 * 通過隨機抽樣的方法,以隨機事件出現的頻率估計其機率,或者以抽樣的數字特徵估算隨機變數的數字特徵,並將其作為問題的解。 * 執行 * 用蒙地卡羅方法類比某一過程時,需要產生各種機率分布的隨機變數。 * 用統計方法把模型的數字特徵估計出來,從而得到實際問題的數值解。 * 時間差異學習(Temporal difference learning) * https://zhuanlan.zhihu.com/p/75246419 * https://zhuanlan.zhihu.com/p/73083240 * https://blog.csdn.net/coffee_cream/article/details/70194456 * https://www.twblogs.net/a/5b7c53e02b71770a43da75bf * https://www.g8787856.me/ * https://www.g8787856.me/post/6 * https://zhuanlan.zhihu.com/p/73083240 ```python= import numpy as np import pandas as pd #------------------------------------------------------ class QLearningTable: def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9): self.actions = actions # a list动作集 self.lr = learning_rate #学习率 self.gamma = reward_decay #回报的衰减系数 self.epsilon = e_greedy #贪婪系数 self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64) #定义q表 #------------------------------------------------------ def choose_action(self, observation): self.check_state_exist(observation) # action selection if np.random.uniform() < self.epsilon: # choose best action state_action = self.q_table.loc[observation, :] # some actions may have the same value, randomly choose on in these actions action = np.random.choice(state_action[state_action == np.max(state_action)].index) else: # choose random action action = np.random.choice(self.actions) return action #------------------------------------------------------ def learn(self, s, a, r, s_): self.check_state_exist(s_) q_predict = self.q_table.loc[s, a] if s_ != 'terminal': q_target = r + self.gamma * self.q_table.loc[s_, :].max() # next state is not terminal else: q_target = r # next state is terminal self.q_table.loc[s, a] += self.lr * (q_target - q_predict) # update #------------------------------------------------------ def check_state_exist(self, state): if state not in self.q_table.index: # append new state to q table self.q_table = self.q_table.append( pd.Series( [0]*len(self.actions), index=self.q_table.columns, name=state, ) ) ``` ## 貝爾曼方程式 ## 馬可夫決策過程 * 馬可夫決策過程是一個4元組{S , A , P~a~ , R~a~ } ## 馬可夫鍊(Markov Chains) 初始定義 * 狀態集 S: 包含所有狀態s,記做 S = {s0,s1,s2,...} * 初始狀態 s0: 一開始的狀態 * 轉移矩陣 : 描述上一狀態如何轉至下一個狀態,記做 T(s,s') ### 馬可夫性質(Markov Property) 狀態的轉移只和現在的狀態有關,與過去無關。 > 有n個事件,以機率的方式描述 > => Pr(Sn|Sn-1,Sn-2,...) = Pr(Sn|Sn-1) so 馬可夫鍊指在符合馬可夫性質的事件,可以使用Sn = S ‧ T^n^計算第n次的狀態。 ```python= import numpy as np #兩種狀態 s0 s1 Matrix_trans = np.array([[0.9,0.1],[0.5,0.5]]) def Matrix_trans_step_n(n): return np.linalg.matrix_power(Matrix_trans,n) for i in [1,5,10,100]: print(Matrix_trans_step_n(i)) ``` ![](https://i.imgur.com/32maPso.png) 轉移矩陣收斂 => 再加上其他狀態照樣收斂 But 除了要遵守馬可夫性質,還有 * a. 任意狀態皆能轉移至任意其他狀態(直接或間接) * b. 狀態轉移不是固定周期 => * 只滿足 a => 最終不收斂,卡在重複循環中 * 只滿足 b => 只會在連通的部分收斂 * 都不滿足 => 在連通的狀態出現重複週期 ## 馬可夫決策過程 初始定義 * 狀態集 S : 所有可能的狀態, 記做 S = {s0,s1,s2,...} * 初始狀態 : s0 * 動作集 A: 所有可能動作, 記做 A = {a0,a1,a2,...} * 轉移模型 T : 轉移至下個狀態之模型 T(s,a,s') * 獎勵函數 R: 憑藉決策的結果, 記做 r(s,a,s') ### 獎勵函數 名詞定義 * 行動step: 表示完成「獲得狀態、決定動作、移動到新狀態」整個流程。 * 策略 (π):將狀態與動作對應到機率的函數。表示某狀態下,採取某動作的機率,記做π (a|s) * 回饋 (Gt): * T 不趨近於無限: * ![](https://i.imgur.com/c2YaDBa.png) * T 趨近無限 * ![](https://i.imgur.com/EUjnaMH.png) * so γ -> 0 or T -> ∞ 只有一個成立(存在) * ![](https://i.imgur.com/W67gXPN.png) * 只在乎這次行動,可以獲得多少回饋。 * ![](https://i.imgur.com/Ne9qrML.png) * 在乎多次行動後,可以獲得的回饋總量。 * 價值函數定義 ![](https://i.imgur.com/rAN8rMR.png) 在某個策略 π 之下,處於這個狀態 s 有多少價值,而價值是由未來可能獲得的回饋總和決定。 => 透過狀態價值函數,得知一個狀態的價值。相同的,亦可評估一個狀態下,採取某動作的價值。 * 動作價值函數 (action-value function) ![](https://i.imgur.com/hxU4ovG.png) 評估在某狀態下的某個動作的價值。 ## 求價值函數 * 動態規劃 (Dynamic programming) * 蒙地卡羅方法 (Monte Carlo method) * Temporal-Difference learning 狀態價值函數:![](https://i.imgur.com/rAN8rMR.png) 動作價值函數:![](https://i.imgur.com/hxU4ovG.png) ## 動態規劃 DP 推導公式 我們將 G~t~ 代入狀態價值函數,得到 ![](https://i.imgur.com/Qqx4ldn.png) 取出第一個回饋R~t+1~,得到 ![](https://i.imgur.com/VdULmch.png) > 離散情況下,期望值的定義。 > ![](https://i.imgur.com/alVeRcF.png) 將定義帶入 ![](https://i.imgur.com/RMG9cEs.png) 式子的組成,就是 「機率 x 該機率下的數值」 ![](https://i.imgur.com/4TkFkFe.png) and ![](https://i.imgur.com/7r32c6O.png) 是狀態價值函數的定義 ![](https://i.imgur.com/rAN8rMR.png) so ![](https://i.imgur.com/zQQXflT.png) => 貝爾曼方程 > 個人想法 > π(a|s): 表示s狀態下,採取動作a的機率 > p(s'|s,a): 從s經動作a到s'的機率 ### 策略迭代 ![](https://i.imgur.com/zQQXflT.png) 迭代的目標是狀態價值,而狀態價值受策略 (π) 影響。 => ![](https://i.imgur.com/fBVEKg8.png) 實現「根據現在的價值函數,估計新的價值函數。藉由重複獲得新的價值函數,逼近真實的狀態價值。」 * 以策略為單位進行更新,也就是說經過一次迭代,所有的狀態價值都會更新,因此稱為策略迭代。 * 所有新的價值函數,都是由舊的價值函數計算的,沒有先計算先更新的問題。 > eg 現在有狀態 A, B, C。更新 A 的價值後,若計算 B 時需要 A 的價值,仍使用舊的價值進行計算。 #### 策略增進 (Policy Improvement) 計算完狀態價值後,我們可以使用「狀態價值」與「動作價值函數」,計算在每個狀態下,每個動作的動作價值。 ###### 貪婪法 (greedy method) 最好的動作,產生其他動作機率為 0 為了方便,將使用貪婪法的這個策略記作π',並將透過貪婪法決定的動作記為π'(s) ![](https://i.imgur.com/j7TcVIB.png) 現在有更好的動作,可以再回去更新狀態價值,如此一來,我們對狀態價值的判斷,就會比原本隨機動作的情況更準確。 ![](https://i.imgur.com/KsFeRIM.png) so 回到策略迭代,透過找到每個狀態下最好的動作,我們可以找出最接近真實情況的狀態價值函數 重複這個過程的話,最終我們可以逼近各狀態的價值、各狀態下最適合的動作 => 重複進行「策略評估」與「策略增進」這兩個步驟 > code: https://github.com/ChampDBG/LearnRL/blob/master/Policy_Iteration.py ### 價值迭代 (Value Iteration) 在策略迭代的方法中,使用「策略增進」來決定最佳的動作,並送到「策略評估」中。 價值迭代的方法中,我們在評估狀態價值時,不像「策略評估」只執行最好的動作,而是計算所有動作,並選擇價值最高者,做為新的狀態價值 ![](https://i.imgur.com/oYFgAAq.png) 初始狀態下(所有狀態價值皆為0) ```python= while Δ > θ: for s in S: v_now = v v = T * (reward + v_now*γ) best_action = T*reward Δ = max(Δ,|v-v_now|) ``` > code: https://github.com/ChampDBG/LearnRL/blob/master/Value_Iteration.py 注意這邊不需考慮動作機率,因為我們只做最佳動作 ### DP 優缺點 * 優點 * 更新所有狀態價值,是由價值函數的定義,衍伸出來的解決方案。 * 因此滿足這個條件(更新所有狀態價值)時,我們可以確保得到的狀態估計值,可以代表狀態價值, * 缺點 * 更新所有狀態價值,計算量會隨著狀態數量而改變。 * 面對大數量,執行時間久 更新所有狀態價值,確保我們得到數值的意義,但也限制我們問題的大小。過於複雜的問題,可能不適合使用這個方法。 事實上,這個限制來自於動態規劃本身 > https://en.wikipedia.org/wiki/Curse_of_dimensionality if 我們不更新狀態價值 = > 從數學上來說,不更新所有狀態價值時,將不滿足價值函數定義。所以計算出來的出來的數值不一定代表真實的狀態價值,造成動作決策錯誤。 ### 迭代輪流更新狀態價值與策略 * 優點 * 我們可以確保評估價值與策略,是往同一個方向、有相同目標。 * 缺點 * 透過迭代更新,代表我們必須不斷與環境互動,以更新價值狀態與策略。想像以下情境 ## 蒙地卡羅 使用大量模擬測試,逼近數值的方法。 估計價值函數時,需要找與價值函數有關,且可以使用大量試驗獲得數值 => 例如: 回饋(Gt) 獎勵函數定義: ![](https://i.imgur.com/NEzSMon.png) Gt 指的是從現在這個狀態,到整個過程結束時,我們可以獲得的回饋 回到價值函數定義 => ![](https://i.imgur.com/rAN8rMR.png) 透過重複試驗,取得多次的Gt => 再取平均 => 狀態價值函數 > eg.GridWorld (γ = 0.9): > 1 -> 0 > 1 -> 5 -> 4 -> 0 > => > Gt = -1×1 + 0 = -1 > Gt = (-1×1)+(-1×0.9)+(-1×0.81) = -2.71 > V(s) = (-1 + -2.75)/2 狀態價值意義: 在DP中,動作價值定義 ![](https://i.imgur.com/hxU4ovG.png) => 變成遞迴形式 ![](https://i.imgur.com/0bPWlRb.png) 因為計算動作價值需要狀態價值,所以計算狀態價值有意義 But 蒙特卡羅並非用遞迴形式求解,而大量模擬求平均 * 逼近狀態價值,使用 * 起始狀態 * 動作 * 回饋 * 轉移矩陣 * 逼近動作價值 * 起始狀態 * 起始動作 * 回饋 * 轉移矩陣 * 決定初始動作 => 避免因為第一動導致結果難易度 ### 蒙地卡羅控制 決策方式 ![](https://i.imgur.com/lQueyeU.png) 1. 初始化動作價值函數、策略、以及回饋 2. 以 episode 為單位,開始收集各狀態下的狀態、動作 => 回饋,進行動作價值估算。 3. 再透過估算出的動作價值,決定「下次遇到相同的狀態時,執行具有最佳動作價值的動作」。 But 上述的策略,是建立在我們模擬準確的情況下 > eg. ![](https://i.imgur.com/G0P3vZb.png) > q(1, 左)、q(4, 上)、q(11, 下)、q(14, 右),以上四個動作價值,不需要經過模擬,就已經知道是零。 > 選到這幾個狀態與動作時,我們之後就可以找到最好的策略。 > however > 假設起始於狀態 2 、動作往左,並走以下路線 > 2 > 1 > 5 > 4 > 0 > 我們不會評價 q(1, 左),而且 q(1, 下) 表現得也不錯,最終可能會收斂在 q(1, 下) 是最佳策略。 錯誤收斂 * Q(s,a) 的初始化 * 如果初始化是給予隨機範圍的負值,現在 q(1, 下) 大約為 -3 ,只要給予的隨機值小於 -3 ,未來就不可能選到 q(1, 左) 這個情況。 * 獎勵函數的給予機制 => 在蒙地卡羅方法中使用貪婪法,可能不會收斂於最佳動作的情況。 ### ε-greedy 貪婪法可能會不收斂於最佳動作 <= 讓最佳動作沒有被選到的機會 (不會被選擇到,所以不會被更新) so , 增加其他動作被選擇的機會 => 更新該動作價值 => 間接讓最佳動作有機會被選到 => 不採取貪婪法的選擇 => 有機會採取其他選擇 ![](https://i.imgur.com/WRg9pll.png) 主要差異在(c) 選擇a^ * ^的方法 * 1-ε+(ε/|A(s)|) 的機率採取貪婪決定的動作 * ε-(ε/|A(s)|) 的機率採取其他動作,各動作機率為(ε/|A(s)|)