---
# System prepended metadata

title: AI原理講義

---

# AI原理講義

## 1.AI前導
:::spoiler 為什麼要學AI?
(例.)因為透過AI可以節省很多簡單重複的工作，就像人類在工業革命發明蒸汽機讓我們節省大量人力一樣，AI的發明可以讓我們跳過很多工作時細節的步驟，專注於大方向的概念中
:::
### 名詞解釋
1. **Artificial Intelligence(人工智慧)**:
    就是我們所熟知的AI，依據AI能做到的事情還能再細分為兩種類型
    - 弱AI:只能專注解決特定領域的問題
    - 強AI:另一個人類，可以為我們做到所有人類能做的事情
2. **Machine Learning(機器學習)**:
    簡稱為ML，透過演算法、函數等方法讓機器找出規則
3. **Deep Learning(深度學習)**:
    簡稱為DL，一種機器學習的方法
    
我們可以將三者簡單歸類為以下這張圖，簡單來說，ML 是AI 的一個領域，DL 則又是 ML 中的一種方法
![image](https://hackmd.io/_uploads/BymOfRIgC.png)

### 模型訓練
:::spoiler AI的核心概念是什麼?
A:找出最貼合數據的函數(模型)，並依此來預測其他的資料
:::
1. **線性方程式**:
    假設今天在平面座標上有兩點(2,5)和(3,7)我們就可以通過解y=ax+b找到通過兩點的直線
    
    $$
    5 = {2a+b}
    $$
    
    $$
    7 = {3a+b}
    $$
    
    $$
    y={2x+1}
    $$

    當我們知道了線的方程式後，就能夠預測點會出現在哪裡，如x=1時
    
    $$
    y={2*1+1}=3
    $$
    
2. **模型的方程式**:
    接下來讓我們將上面提到的概念延伸
    ![image](https://hackmd.io/_uploads/HJhrhAIeC.png)

    :::spoiler 如何判斷是貓還是狗?
    (e.g)耳朵的形狀、眼睛的顏色、頭型等等...
    :::
    我們能夠輕易辨別兩個物種的不同是因為我們透過經驗學習出了狗與貓的特徵，並在下次遇到類似情況時根據學習到的特徵去辨別是貓還是狗
    
    - 訓練流程:
        接下來讓我們以訓練機器辨認狗為例
    ![image](https://hackmd.io/_uploads/rJ1M0A8eR.png)
    ```flow
    st=>start: 給一張狗的圖片
    e=>end: 訓練完成
    op=>operation: 根據反饋更改參數
    cond=>condition: 模型判斷是狗?

    st->op->cond
    cond(yes)->e
    cond(no)->op
    ```
    訓練完以後我們就能讓模型去判斷其他類似圖片是不是狗了
    ![image](https://hackmd.io/_uploads/H1qc1JDeC.png)
    
3. **實際應用**:
    我們也可以利用上述的方法來預測房價
    
| 坪數 | 房價 |
| ---- | ---- |
| 20   | 300  |
| 27   | 320  |
| 35   | 650  |
| 48   | 600  |
| 79   | 1200 |
|預測圖| ![image](https://hackmd.io/_uploads/rkTAWJDg0.png)|
   
   然而對於房屋來說除了坪數還有很多需要考慮的東西，如屋齡、地段、風水等
   我們把這些因素納入考慮，每個因素都有自己的權重(weight)，我們可以將價格寫成下列這種方程式
   
   $$
   y={w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+....}
   $$
   
   x1:坪數 x2:地段 x3:風水 -> 我們稱這些條件為特徵(feature)
   y:價格 -> 得出的結果稱為標籤(label)
:::spoiler 地段跟風水太過抽象，該怎麼加入模型裡呢?
A:透過一種叫做資料預處理的方式，我們就能夠對這些抽象的條件進行數據化
:::

4. **資料預處理**:

| 坪數 | 風水 | 房價 |
| ---- | ---- | ---- |
| 20   | 吉   | 300  |
| 27   | 兇   | 320  |
| 35   | 小吉 | 650  |
| 48   | 吉   | 600  |
| 79   | 小兇 | 1200 |
    將風水的條件加入後，對於機器來說，吉與兇的差別太過於抽象=>
    
| 坪數 | 風水 | 房價 |
| ---- | ---- | ---- |
| 20   | 2    | 300  |
| 27   | -2   | 320  |
| 35   | 1    | 650  |
| 48   | 3    | 600  |
| 79   | -1   | 1200 |
    若改成數字表示，不僅能更容易讓機器進行運算，也能大致看出資料的相對關係
    
| 地段 | 台北 | 台中 |台南|
| ---- | ---- | ---- |---|
| 台北   | 1   | 0  |0|
| 台南   | 0   | 0  |1|
| 台中   | 0   | 1  |0|
| 台北   | 1   | 0  |0|
| 台中   | 0   | 1  |0|
    我們能夠將地段分類為三個區段，台北、台中、台南
    
| 地段 | 台北 | 台中 |
| ---- | ---- | ---- |
| 台北   | 1   | 0  |
| 台南   | 0   | 0  |
| 台中   | 0   | 1  |
| 台北   | 1   | 0  |
| 台中   | 0   | 1  |
    還能夠進一步將台南刪減，讓0,0等於台南

以上就是簡單的資料預處理概念

## 2.學習方式
### 監督式學習
監督式學習的特色是每筆資料都有正確答案

1. **迴歸(regression)**:
    我們可以把迴歸看成是給機器解的填充題，要機器答出一個預測的精確答案，如同上面提到的一樣，我們希望能夠從給定的資料中找到一個符合資料的模型(函數)
    
    那要如何找到最符合資料的那條線呢?
    ![image](https://hackmd.io/_uploads/SyqMwh8WA.png)
    當今天有多個數據點(x₁, y₁), (x₂, y₂)...(xₙ, yₙ)，且想找出一條直線y=ax+b，讓直線和各個點的距離為最小，也就是函數值減數據值的絕對值(點到線的垂直距離)
    $$  
    {|y_{1}-(ax_{1}+b)|+|y_{2}-(ax_{2}+b)|+...|y_{n}-(ax_{n}+b)|}   
    $$
    雖然我們知道絕對值能夠表示點到線之間的距離，但對於電腦來說，絕對值的運算太過於繁瑣了，因此在實際計算上我們會取平方作為運算，能夠得到一樣的效果
    $$  
    {{(y_{1}-(ax_{1}+b))}^{2}+{(y_{2}-(ax_{2}+b))}^{2}+...{(y_{n}-(ax_{n}+b))}^{2}}   
    $$
    
    對於直線來說，我們可以推導出迴歸直線的公式
    
    $$  
    y-u_{y}=\frac{S_{xy}}{S_{xx}} (x-u_{x}) 
    $$
    其中
    $$
    u_{x}是x的平均值
    u_{y}是y的平均值
    $$
    因為最接近的直線必通過兩點平均值，把兩者平均值帶入會發現等式成立
    $$
    而S_{xx}與S_{xy}就是我們拿來計算最小差距的工具了
    $$
    具體來說式子會長這樣
    $$
    S_{xx}=(x_{1}-u_{x})^{2}+(x_{2}-u_{x})^{2}+...(x_{n}-u_{x})^{2}
    $$
    $$
    S_{xy}=(x_{1}-u_{x})(y_{1}-u_{y})+(x_{2}-u_{x})(y_{2}-u_{y})+...(x_{n}-u_{x})(y_{n}-u_{y})
    $$
    關於為什麼這條線是最相關，詳細的證明高中的二維數據分析會提到，這裡就不多贅述
    
2. **分類(classification)**:
    我們可以把分類想像成一道給機器解的選擇題，讓他判斷給的資料是屬於哪一類
    我們可以依據BMI將人分成過重和沒過重兩類，這時我們可以把資料預處理成下面圖表
    
| BMI  | 18  |   25  |  24   |  30   |  20   | 17  |
| ---- | --- | --- | --- | --- | --- | --- |
| 過重 | 0   |  1   |   1  |   1  |  0   | 0   |
    
    把資料畫成圖並取線性迴歸會長這樣
![image](https://hackmd.io/_uploads/S1W0qDvx0.png)
    對於資料好像不太具有代表性
:::spoiler 有什麼函數可以更貼近於我們的資料呢?
A:如sigmoid、relu、tanhx等激活函數就可以將我們的曲線「掰彎」
:::

3. **激活函數**:
    激活函數的作用在於，將前面產生的函數值映射到0和1之間(和我們上面處理過的資料一樣)，並進一步將模型複雜化，下面我們以sigmoid函數來示範運作情況
    
    $$
    y={w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+.....}
    $$
    
    經過轉換
    
    $$
    sigmoid={\frac{1}{1+e^{-y}}}={\frac{1}{1+e^{-{(w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+.....)}}}}
    $$

    接下來讓我們來看看有無激活函數對模型的區別
    ![image](https://hackmd.io/_uploads/SkAOk_vxA.png)
    加入了激活函數之後，整個函數圖形就像是被摺疊了一樣

4. **最近鄰居法(K-nearest neighbors)**:
    當我們要進行分類的時候，還有一個方法可以使用，就是最近鄰居法(簡稱KNN)
    - 原理:拿到一個新資料點時，找出K個離他最近的資料，投票決勝負
    
    ![image](https://hackmd.io/_uploads/HJ1olOPl0.png)
    以上圖做為舉例，當K=3時，我們會依據離綠點最近的三個點來判斷其屬性，在這裡最近的3個點為1藍2紅，所以我們判斷綠點應為紅色類別。
    然而，當K=5時，最近的5個點為3藍2紅，所以我們判斷綠點應為藍色類別。
    
    >由此例子可以發現，我們根據K的不同，我們會得出不同的答案，因此K值取多少是關鍵
    ```
       在什麼情況適合用較小K值?什麼情況適合用較大K值? 

    ```

### 非監督式學習
非監督式學習的特色是每筆資料都沒有正確答案(標籤)，相對的我們會對每筆資料做分群
1. **分群**:
    我們先假定給機器一堆未知屬性的圖片
    ![image](https://hackmd.io/_uploads/S1hsX_DxA.png)
    我們可以透過觀察圖片特徵來訓練機器將圖片分為兩堆
    ![image](https://hackmd.io/_uploads/rkjcEdwgA.png)
    然而，對於機器來說，他並不了解這兩堆分別代表什麼意思

2. **集群分析(K-Means Clustering)**:
    要將資料分群，我們可以使用集群分析的方法
    1. 先給定一堆未標籤的資料，並隨機取兩點為群心(分成n群就點n個點)，表示分為兩群
        ![image](https://hackmd.io/_uploads/rJS95uDlR.png)
        ![image](https://hackmd.io/_uploads/Hy255ODl0.png)
    2. 對所有資料找到距離最近的群心，如x1到藍色群心距離d1小於x1到紅色群心距離d2，因此將x1標記為藍色
        ![image](https://hackmd.io/_uploads/rJCyqdDeC.png)
    3. 若是判斷到兩點距離遠近，可以直接做兩群心的中垂線(分類線)來判斷屬於哪類
        ![image](https://hackmd.io/_uploads/B1vY5ODgA.png)
    4. 利用新的資料找出新的群心
        ![image](https://hackmd.io/_uploads/BJQZiuvlR.png)
    5. 找出新的分類線
        ![image](https://hackmd.io/_uploads/HyKfi_vgA.png)
    6. 重複2-5步驟直到群心變動不大
    
    對於超過兩群的情況，可以參考以下影片的模擬
    {%youtube 2lZZ_FzlIJY %}
    
### 半監督式學習
半監督式學習結合了以上提到的兩種方法，使用少量有標籤樣本和大量無標籤樣本作為訓練資料
1. **自訓練方法(Self-training)**:
    - 原始訓練資料:有標籤無標籤都有
        ![image](https://hackmd.io/_uploads/r1CHHI5g0.png)
    - 目標:讓模型把所有資料都標上標籤再去訓練新的模型
        ![image](https://hackmd.io/_uploads/r1_jrIqlR.png)
        然而，上圖的方法可能會導致一些較難分類的資料分類錯誤
    - 改進方法:訓練多個世代的模型，每次都標記有把握的資料
        ![image](https://hackmd.io/_uploads/SkCSIU5g0.png)
    - Self-traning的限制
        self-traning無法應用在迴歸上，因為對於機器來說，迴歸的資料無法讓模型進行更新，每一代的模型都會長一樣，因此無法達到self-traning的目的
        ![image](https://hackmd.io/_uploads/S1OWOOZbA.png)
        我們先根據原始資料對其他資料上標籤，然後得到新的資料
        ![image](https://hackmd.io/_uploads/rk1h_O-bA.png)
        然後根據新的資料訓練新的模型，我們會得到與之前迴歸模型結果相同的模型

2. **直推式學習(Transductive learning)**:
    - 原始訓練資料:
        原始資料分為有標籤和無標籤
        ![image](https://hackmd.io/_uploads/H1gNDI9eC.png)
    - 對資料分群:
        先將所有資料視為無標籤，然後利用前面提到的K-means做分群
        ![image](https://hackmd.io/_uploads/HkUBP8qlC.png)
    - 投票選出其他:
        對每一群內進行投票，找到該群最多的分類
        ![image](https://hackmd.io/_uploads/ryOPv8qeC.png)


### 強化式學習
強化式學習的資料通常並沒有固定的標準答案，因此我們透過設計一套獎懲機制來讓AI自我學習，我們可以先從遊玩遊戲的角度來解說這套機制

1. **Space invaders**:
     ![image](https://hackmd.io/_uploads/SkccKR5x0.png)
    space invaders是一款相當古老的電子遊戲，我們可以將遊戲內容作簡單分析
    - 可採取動作: 1.向左 2.向右 3.開火
    - 遊戲中要素: 1.分數 2.生命
    - 分數取得規則: 1.被擊中-5分 2.擊中外星人+5分 3.擊中補給+10分
    - 遊戲目標: 存活並取得更高分數
    在遊玩的過程中，我們會依據上述的規則去更改、改進我們的操作，以避開外星人的攻擊，並盡可能取得高分，經過數場遊玩，我們可能學習到在子彈快到時閃躲、或甚至外星人的排列規律等，這個過程就和強化式學習十分相似
    
2. **強化式學習如何運作**:
    在強化是學習當中，我們可以先簡單分成環境(environment)和主體(actor)，我們可以將兩者看待成上面例子的遊戲環境和玩家的相互關係
    那麼強化式學習的流程就會長得像這個樣子
    ```flow
    st=>start: 環境給出觀察(observation)給主體
    e=>end: 結束
    op=>operation: 主體根據觀察做出動作(action)
    op2=>operation: 環境給主體獎賞(reward)
    st->op->op2->st
    ```
    1. 套用到space invaders:
        以前面的例子來看，我們可以把遊戲當作環境、AI當成主體，這時AI可能會執行以下動作:
        ![image](https://hackmd.io/_uploads/rkt9amGbC.png)
        1. 先向右移動，但因為沒有破壞物件所以沒有獎賞

        ![image](https://hackmd.io/_uploads/BJcfCXGbR.png)
        2. 再執行開火動作擊毀一個敵方，獲得10點的獎賞

        ![image](https://hackmd.io/_uploads/ry5vCmGbC.png)
        3. 把這個過程套用到上面的訓練流程可以得到這個結果

        - 訓練目標:執行很多次遊戲(我們稱一回遊戲為一個episode)並讓reward最大化
    
    2. 套用到象棋:
        學會如何實作強化式學習後，我們將原理應用在訓練象棋AI上
        1. 象棋的遊戲結果只有贏和輸，我們先將贏的獎賞定為1、輸的獎賞定為2
        
        ![image](https://hackmd.io/_uploads/HktdlVzWR.png)
        2. 讓小兵向前移動一步，發現自己沒有贏也沒有輸，獎賞為0
        
        ![image](https://hackmd.io/_uploads/B1z1ZNGZA.png)
        3. 把這個過程套用到上面的訓練流程可以得到這個結果
        
        :::spoiler 這樣的執行步驟有沒有什麼問題呢?
        A:如果將贏或輸的獎賞定為1或-1的話，會有太多步驟不會得到獎賞
        ，我們稱之為稀疏獎勵(sparse reward)
        :::

3. **獎勵塑型(reward shaping)**:
    為了解決稀疏獎勵的問題，我們必須自定義一些獎勵
    - 可能幫助勝利的因素:吃掉對面的棋子
    - 可能導致敗北的因素:棋子被對面吃掉
    簡單歸類出上面兩個類別後我們可以定義出以下獎賞
    
| 棋子類型 | 吃   | 被吃 |
| -------- | ---- | ---- |
|    將(帥)       |   +100   |  -100    |
|     車     |   +15   |   -15   |
|     炮     |   +10   |  -10    |
| ...   | ... | ... |


## 3.深度學習
### 特色
1. **生物神經元**:
深度學習的特色是模擬生物的神經元互動方式
![image](https://hackmd.io/_uploads/SJK0EzZm0.png)
神經細胞會透過軸突和樹突不斷傳遞信號給下一個細胞，在深度學習中，我們就是模仿這種方式一層一層的傳遞資料最後得到輸出
我們可以簡單分成下列三種層級:

輸入層:  接受資訊，以數字型態儲存，傳到下一層

隱藏層:  分析並處理前一層資料，傳到下一層

輸入層:  拿到分析完後的結果
![image](https://hackmd.io/_uploads/HypYIGbXA.png)
從上圖可以發現，每一個神經元都與下一層的「每個」神經元相連 
2. **神經元的輸入**:
對於一個神經元，可以接收上一層的所有神經元的數據，並給他一個權重
![image](https://hackmd.io/_uploads/S1FkvMb70.png)
最後經由上面提到的激活函數(如sigmoid)處理
![image](https://hackmd.io/_uploads/HkCJuMWm0.png)
複習一下sigmoid函數是長這樣
    $$
    y={w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+.....}
    $$
    
經過轉換
    
$$
    sigmoid={\frac{1}{1+e^{-y}}}={\frac{1}{1+e^{-{(w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+.....)}}}}
$$

3. **讀取圖片**:
若我們現在想要讓機器辨識出圖片中是什麼數字該怎麼做呢?
![image](https://hackmd.io/_uploads/ByanuzWQR.png)

首先我們會把圖片切割成一格一格的，並用數字表示該像素的顏色
![image](https://hackmd.io/_uploads/S1W7KMb7R.png)

然後將這些格子編號
![image](https://hackmd.io/_uploads/S1BLYz-XC.png)

最後轉向就可以當成輸入的資料了
![image](https://hackmd.io/_uploads/r1_KFzZXC.png)

在實際的圖片當中很可能不只有黑跟白兩種顏色，因此我們利用灰階值取代，灰階值是介於0到1的數值，數字越大就越亮(接近白色)
![image](https://hackmd.io/_uploads/SJYKcMZQR.png)

4. **輸出層**:
輸出層有10個神經元，分別代表數字0~9的出現機率，我們的目標就是要讓對應正確答案的神經元機率為最高
![image](https://hackmd.io/_uploads/Hk48sfbmC.png)

5. **隱藏層**:
除了最左邊的輸入層以及最右邊的輸出層以外，剩下的都屬於隱藏層
![image](https://hackmd.io/_uploads/HJikOSz7R.png)
觀察一下上圖的特徵，我們發現了兩個特別的地方
- 為什麼需要那麼多層呢?
- 為什麼第二層隱藏層神經元數量變少了?

要解釋這個問題，我們可以先從研究8這個數字開始
首先，我們將8拆解為兩個部分
![image](https://hackmd.io/_uploads/Sk9adrfX0.png)
然後我們分別指定這兩個部件到一個神經元
![image](https://hackmd.io/_uploads/SyUZFHMmA.png)

如果以上兩個部件的出現機率都很高，我們可以推導出8這個數字的出現機率也很高
- 那為什麼這兩個神經元會是放在第二層呢?

對於機器來說，分出的這兩塊其實已經算是非常大的區塊了，我們還可以對其中一個圓形拆解，例如下圖
![image](https://hackmd.io/_uploads/HktaFrz7C.png)
這時我們也分別指定一個神經元給四個圈圈的部件，因為是圈圈的部件，所以應該要在圈圈的前一層
![image](https://hackmd.io/_uploads/r1FmqHGXC.png)

總結來說，數字由數個特徵組成(8 = 上圈圈 + 下圈圈)

而特徵又由數個子特徵組成(圈圈 = 左上圓弧 + 左下圓弧 + 右下圓弧 + 右上圓弧)

- 而這種使用子特徵的好處在哪裡呢?

接下來讓我們導入另一個數字5到這個模型當中，我們一樣先拆分部件與子部件
![image](https://hackmd.io/_uploads/rk5RcHMXA.png)
這時神奇的事情發生了，我們會發現原來子部件還可以重複進行利用(兩個圓弧)
![image](https://hackmd.io/_uploads/HyF-sHfQR.png)

### 梯度下降
在上面提到的模型裡，我們會需要讓模型不斷改動每一格的權重，那我們為了要找出一個最棒的函式，就需要利用梯度下降法去尋找特定的權重數值

1. 成本函數
前面我們有提到找到算出距離的算法(平方)，並想辦法使他最小
$$  
    {{(y_{1}-(ax_{1}+b))}^{2}+{(y_{2}-(ax_{2}+b))}^{2}+...{(y_{n}-(ax_{n}+b))}^{2}}   
$$

而我們定義成本函數(cost)就是上面的式子再除以n個點(取平均)

$$  
    成本函數=\frac{{(y_{1}-(ax_{1}+b))}^{2}+{(y_{2}-(ax_{2}+b))}^{2}+...{(y_{n}-(ax_{n}+b))}^{2}}{n}   
$$
當成本函數(cost)的數值越小，這個函數就越貼近我們的需求
因此，我們的目標就是找到最好的a和b
![image](https://hackmd.io/_uploads/BJE3IUzQC.png)
我們以上圖做為代表，計算a和b代入後的cost
首先我們先簡化問題撇除b不看
![image](https://hackmd.io/_uploads/rJLDPUzXA.png)

| a   | cost    |
| --- | ------- |
| 13  | 14218.2 |
| 14  | 8676.8  |
| 15  | 7495.0  |
| 16  | 10672.8 |

像這樣不斷地帶入點之後，我們繪製在圖表上後發現，這是一條拋物線
![image](https://hackmd.io/_uploads/r10UuUz70.png)
但是我們要如何找到最棒的a值呢?

2. 梯度下降
如果使用窮舉，會耗費太多的時間，因此我們要使用梯度下降這個計算方式
- 我們先取隨機一點為起始點
在這裡我們取a=11作為起點
![image](https://hackmd.io/_uploads/HJVLKIGXA.png)

- 求出該點的切線斜率
我們只要取出該點的斜率，就能夠得知該函數的傾斜方向，如下圖中低點是在起點的右邊，因此斜率為負
![image](https://hackmd.io/_uploads/HyPpFLzQC.png)

- 找到新的起始點

$$
    a_{new}=a_{old}-m
$$
$$
    a_{new}=11-(-3)=14
$$
- 再次計算斜率，重複進行上面步驟
![image](https://hackmd.io/_uploads/HyVqqUzQC.png)
$$
    a_{new}=a_{old}-m
$$
$$
    a_{new}=14-(-1.5)=15.5
$$
![image](https://hackmd.io/_uploads/Sye7jUfX0.png)
$$
    a_{new}=a_{old}-m
$$

$$
    a_{new}=15.5-(0.5)=15
$$
