---
# System prepended metadata

title: '[RL] Q learning 與 Deep Q Network(DQN)'
tags: [Deep Learning Algorithms, ReinforcementLearning, RL]

---

 
 
### [AI / ML領域相關學習筆記入口頁面](https://hackmd.io/@YungHuiHsu/BySsb5dfp)
#### Reinforcement learning

- [[RL] Fine-Tuning Language Models from Human Preferences (RLHF)論文筆記](https://hackmd.io/@YungHuiHsu/Sy5Ug7iV6)
- [[RL] Proximal Policy Optimization(PPO)](https://hackmd.io/@YungHuiHsu/SkUb3aBX6)
- [[RL] Q learning 與 Deep Q Network(DQN)](https://hackmd.io/@YungHuiHsu/BJgnMHbUH6)
---

在2023年底大型語言模型當道的時代簡單回顧強化學習領域的經典論文與演算法


DQN的原始論文沒有開放下載，推薦看李宏毅老師的課程影片

- [MACHINE LEARNING AND HAVING IT DEEP AND STRUCTURED 2018 SPRING](https://speech.ee.ntu.edu.tw/~hylee/mlds/2018-spring.php)
    - DRL Lecture 3: Q-learning (Basic Idea)
        - [video]((https://www.youtube.com/watch?v=o_g9JUMw1Oc&list=PLJV_el3uVTsODxQFgzMzPLa16h6B8kWM_&index=4))
        - [pdf](https://speech.ee.ntu.edu.tw/~tlkagk/courses/MLDS_2018/Lecture/PPO%20(v3).pdf)

### Q Learning

:::info
引導機器學習著如何根據當前的狀態（例如在迷宮的哪個位置）來**選擇最佳的行動**（例如向左、向右、向前走）。這個選擇是基於一個叫做"Q值"的獎勵，它代表在某個特定狀態下採取某個行動可能得到的獎勵。演算法的目標是**最大化整體獎勵(Q值)，進而學習最佳行動策略**。


:::

Q Learning是一種基於價值的強化學習方法，其核心是學習一個價值函數$Q(s, a)$，代表在狀態$s$下執行行動$a$所期望的未來獎勵。Q函數通過以下更新規則來學習：

$$
Q(s, a) \leftarrow Q(s, a) + \alpha [R(s, a) + \gamma \max_{a'} Q(s', a') - Q(s, a)]
$$

其中：
- $Q(s, a)$ 是當前狀態s下執行行動a的Q值。
- $\alpha$ 是學習率，決定了新獲得的資訊對現有Q值的影響程度。
- $R(s, a)$ 是執行行動a後獲得的即時獎勵。
- $\gamma$ 是折扣因子，用於平衡即時獎勵和未來獎勵的重要性。
- $s'$ 是執行行動a後的新狀態。
- $\max_{a'} Q(s', a')$ 是新狀態下的最大Q值。


:::warning
在傳統的Q learning中，Q值是從一個狀態和一個行動計算出來的，並且通常是通過查表或者簡單的函數來實現的。但當狀態和行動的數量非常大時，這種方法變得不可行。
:::




#### demo code
- code
    :::spoiler
    ```python=
    import random

    class QLearningAgent:
        def __init__(self, alpha, gamma, n_states, n_actions):
            self.alpha = alpha
            self.gamma = gamma
            self.n_states = n_states
            self.n_actions = n_actions
            self.q_table = dict()

        def learn(self, state, action, reward, next_state):
            # 初始化當前狀態-行動對的Q值（如果還未存在）
            self.q_table.setdefault((state, action), 0)

            # 計算max_a' Q(s', a')
            max_q_next = max([self.q_table.get((next_state, a), 0) for a in range(self.n_actions)])

            # Q Learning更新公式
            self.q_table[(state, action)] += self.alpha * (reward + self.gamma * max_q_next - self.q_table[(state, action)])

        def choose_action(self, state, epsilon):
            # ε-greedy策略
            if random.uniform(0, 1) < epsilon:
                return random.randint(0, self.n_actions - 1)
            else:
                q_values = [self.q_table.get((state, a), 0) for a in range(self.n_actions)]
                return q_values.index(max(q_values))

    # 示例：初始化Q Learning Agent
    agent = QLearningAgent(alpha=0.1, gamma=0.9, n_states=10, n_actions=2)

    # 假設某一次交互
    current_state = 0
    action_taken = agent.choose_action(current_state, epsilon=0.1)
    reward_received = 1  # 這裡假設獲得的獎勵
    next_state = 1  # 假設的下一狀態

    # 更新Q值
    agent.learn(current_state, action_taken, reward_received, next_state)

    ```
        
    - `q_table`是一個字典（Python中的dict），用於存儲和表示Q值。
        - 在這個字典中，每個鍵（key）是一個由狀態（state）和行動（action）組成的元組（tuple）。
        - 每個鍵對應的值（value）是該狀態-行動對應的Q值。
        - 例如，如果我們有一個狀態為0、行動為1的情況，並且這個狀態-行動對應的Q值為0.5，則`q_table`中將包含一個條目：`q_table[(0, 1)] = 0.5`。


    - `self.n_actions`是一個整數，表示在給定的環境中可能的行動總數。
        - 這個數字代表了代理（agent）在任何給定狀態下可以選擇的不同行動的數量。
        - 例如，如果`self.n_actions`是2，這意味著對於任何狀態，代理有兩種行動可以選擇，通常可以表示為0和1（如果是雙行動系統的話）。
    - `def choose_action()`
        `choose_action`函數是實現ε-greedy策略的關鍵部分，它用於決定代理（agent）在給定狀態下應該採取哪個行動
        - `state`: 這個參數代表當前的環境狀態。
        - `epsilon`: 這是ε-greedy策略中的ε值，它是一個0到1之間的數字，決定了探索（隨機選擇行動）與利用（選擇已知最佳行動）之間的平衡。
        - 
    在上述程式碼中，當代理需要做出決策時，它會查看`q_table`中當前狀態下每個可能行動的Q值，然後根據ε-greedy策略來選擇行動。若`q_table`中還沒有特定狀態-行動對的Q值，則會假設該Q值為0（這是通過`get`方法的預設值實現的）。這種方法確保了即使在學習初期，當Q表還未充分填充時，代理也能做出決策。
    ##### ε-greedy策略的工作原理
    1. **隨機探索**:
       - `if random.uniform(0, 1) < epsilon:` 這一行檢查一個從0到1均勻分布的隨機數字是否小於`epsilon`。
       - 如果是，則代表這次決策將採取隨機探索的行動。
       - `return random.randint(0, self.n_actions - 1)`這一行隨機選擇一個行動返回。這裡的行動是在0到`self.n_actions - 1`（包含）之間隨機選擇的，其中`self.n_actions`是可能行動的總數。

    2. **基於知識的利用**:
       - 如果隨機數字不小於`epsilon`，代表這次決策將基於已知的資訊來選擇最好的行動。
       - `q_values = [self.q_table.get((state, a), 0) for a in range(self.n_actions)]`這一行創建了一個列表，其中包含當前狀態下每個可能行動的Q值。
       - 如果某個行動的Q值還未在`q_table`中出現過，則假設它的Q值為0（這是通過`get`方法的默認值實現的）。
       - `return q_values.index(max(q_values))`這一行選擇並返回具有最大Q值的行動的索引。這代表在當前狀態下，基於目前所學到的資訊，這個行動被認為是最好的選擇。

    ε-greedy策略通過在探索（exploration）和利用（exploitation）之間進行權衡，使得代理在學習過程中既能嘗試新的行動以獲得更多的資訊，又能利用其已經學到的知識來做出最佳決策。這是強化學習中常用的一種策略。
    ::: 

 
 



### Deep Q Network (DQN)
:::info
DQN通過使用深度學習來解決傳統Q Learning在面對大型或高維度狀態空間時Q值表格過大的問題。在DQN中，深度神經網絡（例如多層感知器，MLP）接受環境的狀態作為輸入，並直接輸出該狀態下每個可能行動的Q值。選擇最適合的行動是基於這些Q值進行的，這是DQN決策過程的關鍵部分。這種方法使得DQN可以有效地處理那些對於傳統Q Learning來說過於複雜的任務。

同时，DQN也會透過策略如ε-greedy來平衡探索（exploration）和利用（exploitation），確保既能學習新知識又能利用已有知識，以此來選擇適合2的Q值
:::

 
 
DQN將Q Learning的概念與深度學習相結合。這裡，Q函數不再是一個簡單的表格，而是通過一個深度神經網絡來逼近。神經網絡的輸入是環境的狀態s，輸出是所有可能行動的Q值。

DQN的關鍵創新之一是引入了經驗重放（experience replay）。這意味著在訓練過程中，我們不是直接使用當前的經驗來更新網絡，而是將這些經驗存儲在一個記憶庫中，並隨機抽取之前的經驗來進行學習。這有助於打破資料之間的相關性，並穩定學習過程。

DQN的另一個創新是目標網絡（target network）。在DQN中，有兩個神經網絡：一個是正在訓練的網絡，另一個是固定的目標網絡，用於估計Q值更新公式中的 $\max_{a'} Q(s', a')$。這有助於穩定訓練過程，因為目標網絡的參數會比較慢地更新。

DQN的訓練目標是最小化以下損失函數：

$$L(\theta) = \mathbb{E}_{(s, a, r, s') \sim U(D)} \left[ \left( r + \gamma \max_{a'} Q(s', a'; \theta^-) - Q(s, a; \theta) \right)^2 \right]$$

其中：
- $\theta$ 表示神經網絡的參數。
- $\theta^-$ 表示目標網絡

的參數。
- $U(D)$ 表示從經驗重放記憶庫中抽取的一個樣本。
- $r$ 是獎勵。

 

## Reference & Supplementary
### 原始論文
1. **Q Learning**: Watkins, C.J.C.H. and Dayan, P. (1992). Q-learning. Machine Learning, 8(3-4), 279-292.
2. **Deep Q Network (DQN)**: Mnih, V., Kavukcuoglu, K., Silver, D., et al. (2015). [Human-level control through deep reinforcement learning.](https://www.nature.com/articles/nature14236?wm=book_wap_0005) Nature, 518(7540), 529-533.
 
  
### [2023.09。Basics of Reinforcement Learning for LLMs](https://cameronrwolfe.substack.com/p/basics-of-reinforcement-learning)

很好的說明強化學習在LLM客製化應用的基礎，從不可微分的離散式獎勵(經典的Q Learning)到連續的、基於梯度(可微分的)RLHF與PPO
![image](https://hackmd.io/_uploads/BJa88xPBa.png)

 

 
> - RL演算法可以用來微調LLM，使得LLM能夠產生更符合人類偏好的文本。具體來說，我們可以將LLM視為代理人，將文本序列視為狀態(state)，將下一個字元視為動作(action)，將人類對文本的評分視為回饋。這樣，我們就可以用RL算法來更新LLM的參數，使得LLM能夠生成更高品質的文本。
 
![image](https://hackmd.io/_uploads/HkjmgnAH6.png)


![image](https://hackmd.io/_uploads/SJBMenRr6.png)

![image](https://hackmd.io/_uploads/SyPay30S6.png)
![image](https://hackmd.io/_uploads/rJ0Tk3ABT.png)
![image](https://hackmd.io/_uploads/Bk6AyhCS6.png)
![image](https://hackmd.io/_uploads/Sydxgn0Sa.png)
