-
Machine Learning
-
Reinforcement Learning
Machine Learning
機器學習能夠解決的問題
問題需求 | 適用的機器學習種類 |
---|---|
要將資料配適到某個函數或函數近似的議題 | 監督式學習 (Supervised learning) |
針對無任何回饋的資料進行結果揣測 | 非監督式學習 (Unsupervised learning) |
隨著時間累積而讓結果的獎勵最大化 | 增強式學習 (Reinforcement Learning) |
演算法種類
演算法 | 所屬的機器學習種類 | 演算法類別 | 受限偏向 | 適用偏向 |
---|---|---|---|---|
K-最近鄰法 (K-Nearest Neighbors) | 監督式學習 | 實例式 | 受限於維度詛咒 | 適用於距離形式的問題 |
單純貝式分類 (Naive Bayesian Classification) | 監督式學習 | 機率(Probabilistic) | 處理輸入內容呈現彼此獨立的問題 | 每種機率大於零的問題 |
決策樹 (Decision Trees) | 監督式學習 | Tree | 受限於 covariance | 適用於種類性資料的問題 |
大致上列舉幾種演算法還有許多的學習演算法並未列出
Reinforcement Learning
-由分數來決定要做的方法
比如老師會根據我的開心程度來打分, 我開心時, 可以得到高分, 我不開心時得到低分. 有了這些被打分的經驗, 我就能判斷為了拿到高分, 我應該選擇一張開心的臉, 避免選到傷心的臉. 這也是強化學習的核心思想. 可以看出在強化學習中, 一種行為的分數是十分重要的. 所以強化學習具有分數導向性. 我們換一個角度來思考.這種分數導向性好比我們在監督學習中的正確標籤
通過價值選行為的演算法
- Q-learning
- Sarsa
- Deep Q Network (DQN)
Q-Learning
Q-Learning
- alpha 是一個小於1的數
- gamma 是對未來的 reward 的衰減值
- Epsilon greedy 是用在決策上的一種策略
Deep Q Network (DQN)
DQN 是一個記憶庫用於學習之前的經歷,主要解決了不用紀錄表格 (action & state) 因為 action 和 state 如果直接用表格紀錄,記憶體可能會有問題。 而在機器學習中有一種方法是可以用來規劃,也就是神經網路,將狀態以及動作當成神經網路的輸入,透過神經網路生成 Q 值,這樣就可以不用在表格中紀錄 Q 值。
Deep Deterministic Policy Gradient (DDPG)
- 介紹
DDPG 是由 Google DeepMind 提出的一種使用 Actor-Critic 結構,但輸出不是機率而是具體的行為,用於連續動作 (continuous action)的預測。
- 算法
$$\bigtriangledown {\theta^{\mu }}J\approx \frac{1}{N}\sum^{ }\bigtriangledown {a}Q(s,a|\theta^{Q})|,a = \mu(s_{i})^{ }\bigtriangledown_{\theta^{\mu }}\mu)(s|\theta^{\mu })|s_{i}$$
關於 Actor 部分,參數更新同樣涉及到 critic ,上面是關於 Actor 參數的更新,算式的前半部分 grad(Q) 是從 Critic 產生。 Actor 的動作移動,才能獲得更大的 Q 值。 而後半部分 gead[u] 是從 Actor 產生,Actor 要修改自己參數使得 Actor 更有可能做這個動作。所以兩個結合就會變成使: Actor 朝著更有可能獲得大的 Q 的方向修改動作參數。
$$\textbf{set} y_{i} = r^{i}+\gamma {Q}'(s_{i+1},{{\mu }}'(s_{i+1}|\theta^{\mu{}'})|\theta^{Q{}'}) $$ $$\textbf{update cricitic by minimizing the loss:} L = \frac{1}{N}\sum_{i}(y_{i}-Q(s_{i},a_{i}|\theta^{Q}))^{2}$$
這個式子是關於 critic 的更新,參考 DQN 的方式,使用兩個 Q 的神經網路,Q target 中依據下一個狀態,由 Actor 來選擇動作,這時 Actor 也有一個 Actor_target ,使用這種方法獲得的 Q_target 能像 DQN 切斷相關性,提高收斂性。
- 主結構
class Actor(object): def __init__(self): ... with tf.variable_scope('Actor'): # 這個網路用於即時更新網路 self.a = self._build_net(S, scope='eval_net', trainable=True) # 這個網路不及時更新參数, 用于預測 Critic 的 Q_target 中的 action self.a_ = self._build_net(S_, scope='target_net', trainable=False) ... class Critic(object): def __init__(self): with tf.variable_scope('Critic'): # 這個網路用於即時更新參數 self.a = a # 這個 a 是来自 Actor 的, 但是 self.a 在更新 Critic 的时候是之前選擇的 a 而不是来自 Actor 的 a. self.q = self._build_net(S, self.a, 'eval_net', trainable=True) # 這個網路不及時更新參数, 给出 Actor 更新參数时的 Gradient ascent 强度 self.q_ = self._build_net(S_, a_, 'target_net', trainable=False)
- Actor Critic
由圖可以看到兩個 eval_net ,Actor class 的寫法
with tf.variable_scope('policy_grads'): # 這是在計算 (dQ/da) * (da/dparams) self.policy_grads = tf.gradients( ys=self.a, xs=self.e_params, # 計算 ys 對於 xs 的梯度 grad_ys=a_grads # 這是從 Critic 来的 dQ/da ) with tf.variable_scope('A_train'): opt = tf.train.AdamOptimizer(-self.lr) # 父的學習率是為了使我們計算梯度向上, 和 Policy Gradient 中的方式是同一個性質 self.train_op = opt.apply_gradients(zip(self.policy_grads, self.e_params)) # 對 eval_net 的參數更新
# 計算 target Q with tf.variable_scope('target_q'): self.target_q = R + self.gamma * self.q_ # self.q_ 根據 Actor 的 target_net 来的 # 計算誤差並反向傳遞誤差 with tf.variable_scope('TD_error'): self.loss = tf.reduce_mean(tf.squared_difference(self.target_q, self.q)) # self.q 又基於 Actor 的 target_net with tf.variable_scope('C_train'): self.train_op = tf.train.AdamOptimizer(self.lr).minimize(self.loss)
最後把建立好的 actor 以及 critic 融合再一起
actor = Actor(...) critic = Critic(..., actor.a, actor.a_) # 將 actor 同它的 eval_net/target_net 產生的 a/a_ 傳給 Critic actor.add_grad_to_graph(critic.a_grads) # 将 critic 產出的 dQ/da 加入到 Actor 的 Graph 中
- 記憶 Merory
建立一個 class 進行存取
class Memory(object): def __init__(self, capacity, dims): """numpy 初始化""" def store_transition(self, s, a, r, s_): """保存每次記億到 numpy array""" def sample(self, n): """隨機從記憶庫中抽取 n 個記憶進行學習"""
- 每回合算法 (部分)
var = 3 # 初始化一個方差用於增强 actor 的探索性 for i in range(MAX_EPISODES): ... for j in range(MAX_EP_STEPS): ... a = actor.choose_action(s) a = np.clip(np.random.normal(a, var), -2, 2) # 增强探索性 s_, r, done, info = env.step(a) M.store_transition(s, a, r / 10, s_) # 記憶庫 if M.pointer > MEMORY_CAPACITY: # 記憶庫滿了以後 var *= .9998 # 逐漸降低探索性 b_M = M.sample(BATCH_SIZE) ... # 將 b_M 拆分成下面的输入信息 critic.learn(b_s, b_a, b_r, b_s_) actor.learn(b_s) # 將現在的 state 取代舊的 S s = s_ if j == MAX_EP_STEPS-1: break
以上部分資料參考於 youtube 一位 python 的教學課程還有一些書本的資料 參考網址
Comments
comments powered by Disqus