# 人工智慧導論

Q:何謂regression 問題、模型?
Regression問題是預測一個連續值的問題。
eg. 預測房價、氣溫、銷售等都是回歸問題。回歸模型試圖找出輸入特徵和目標值之間的關係,從而使預測值與實際值之間的誤差最小化。在深度學習中,回歸模型可能是一個神經網絡,最後一層沒有激活函數或使用線性激活函數。
Q:何謂classification 問題、模型?
Classification問題是預測一個離散標籤的問題。
eg. 判定一張圖片是貓還是狗、或者一封郵件是垃圾郵件還是正常郵件。分類模型試圖根據輸入特徵將每個實例分配到一個或多個類別。在深度學習中,分類模型經常使用softmax激活函數在最後一層,以得到每個類別的概率。
Q: 資料如何輸入神經網路中?
Q: 如何提高神經網路正確性?
=> 透過FP(Forword Propagation,前項傳遞)進行訓練,可以提升神經網路(NN)正確性

[基本概念]

- K-fold Cross-Validation
在 K-Fold 的方法中我們會將資料切分為 K 等份,K 是由我們自由調控的,以下圖為例:假設我們設定 K=10,也就是將訓練集切割為十等份。這意味著相同的模型要訓練十次,每一次的訓練都會從這十等份挑選其中九等份作為訓練資料,剩下一等份未參與訓練並作為驗證集。因此訓練十回將會有十個不同驗證集的 Error,這個 Error 通常我們會稱作 loss 也就是模型評估方式。模型評估方式有很多種,以回歸問題來說就有 MSE、MAE、RMSE…等。最終把這十次的 loss 加總起來取平均就可以當成最終結果。透過這種方式,不同分組訓練的結果進行平均來減少方差,因此模型的性能對數據的劃分就不會那麼敏感。

- 訓練神經網路後續步驟
1. 初始化NN的weight、bias
2. 輸入多筆資料進去model,獲得結果(每輸入一筆x,經過運算可得到一筆誤差)
3. 
4. 若誤差很大,表示weight、bias配置須要修正
- 訓練NN過程中,是不斷的修正所有weight matrix 和 bias
- 是為了找到「可讓總誤差(指Loss function)的值極小化」的最佳權重配置
5. 當找到一組最佳權重配置的模型後,就可以用來實際預測答案。稱為**已訓練好的模型(Trained model)**。

## 用Loss function來計算誤差(error)
=> 當Loss function的值很大時,代表模型的預測值和正確值間的誤差很大,就需要修正weight,直到Loss function的值極小化為止。

### Loss function 函數
| model\problem | Regression | Classification |
| -------- | -------- | -------- |
| | MSE (均方誤差,Mean square error) | Cross Entropy(交叉熵) |
| | MAE (平均絕對值誤差,Mean absolute error) | |
- MSE (Mean square error,均方誤差):
-> 通常用在處理regression problem


```
import numpy as np
def mean_square_error(y,y_hat): ##y_hat是指正確的(驗證集)
return (1.0/2.0)*np.sum(np.square(y-y_hat))
a = np.random.randint(0,10,5)
b = np.random.randint(0,10,5)
print(mean_square_error(a,b))
```
### Cross Entropy 交叉熵
-> 通常用於處理Classification problem
=> 原本用於表達原子在空間當中的分布狀況,當原子分布越混亂,Entropy越高(越多不確定性存在)。
- Cross Entropy 主要用於計算「預測出來的機率分布」與「真實機率分布」之間的總誤差
- 當預測出的機率機率分布與真實分布愈接近,Cross Entropy會相對較小



```
import numpy as np
def cross_entropy(y,y_hat): #y_hat是正確的(驗證集)
return -1*np.sum(y_hat*np.log(y+1e-7)) #因ln 0 無法計算,所以加上一個極小值10**-7
a = np.random.random(5)
b = np.random.randint(0,2,5)
print(cross_entropy(a,b))
```
## 修正weight的方法: 梯度下降(Gradient Descent)
=>隨機找一組參數,並計算周圍是否有更好的參數組合,若有就移動過去。
GD是最佳化理論裡面的一個一階找最佳解的一種方法,主要是希望用梯度下降法找到函數的局部最小值,因為梯度的方向是走向局部最大的方向,所以在**梯度下降法中是往梯度的反方向走**。

[缺點]:有可能找到的點並非真正最好的點,而是所謂的Local minimum(區域最小值),解決方法之一就是多由不同起點來試看看(靠運氣)

可參考:https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E6%95%B8%E5%AD%B8-%E4%BA%8C-%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D%E6%B3%95-gradient-descent-406e1fd001f
### Gradient Descent 步驟:

2. 利用斜率,當作指引的方向(指引到低點)
=> 由一階導函數切線斜率來決定方向

3.

4.

[問題]
1.

2.

3.

4.

## 計算梯度






























SGD:https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E6%95%B8%E5%AD%B8-%E4%B8%89-%E6%A2%AF%E5%BA%A6%E6%9C%80%E4%BD%B3%E8%A7%A3%E7%9B%B8%E9%97%9C%E7%AE%97%E6%B3%95-gradient-descent-optimization-algorithms-b61ed1478bd7

## Learning rate來決定 行走步伐 大小

## 優化Learning rate的演算法(Optimization Algorithm)
- SGD
- Momentum
- Adagrad
- RMSProp
- **Adam (最常用)**
## CNN (Convolutional Neural Network,卷積神經網路)
用於模擬人類大腦視覺系統的神經網路模型
## RNN (Recurrent Neural Network,循環神經網路)
> 為了處理sequential data而設計出來的模型,他可以記住過去的資訊,並用來處理新的事件。
> 但只能記住短期記憶。長期會忘
### 不同類型的序列建模:
- 一對一(Many-to-one)

- 一對多(One-to-many)

- 多對多(Many-to-many)


#### 將RNN 展開




#### RNN 不一定要從hidden layer 做recurrent,也可以有其他方法

#### RNN LSTM比較


- RNN 的下一個輸出會考慮上一層,所以很適合處理時間與序列的問題,但會遇到以下困難:
1. 梯度消失
2. 梯度爆炸
#### 梯度下降/ 消失 / 爆炸
1. 梯度下降(Gradient Descent)
- 如果變數是線性關係,Gradient Descent 是一種找最小 Loss Function 的工具
- 通常起始點是隨機選一個斜率開始使用一個樣本資料去更新,稱隨機梯度下降法(Stochastic Gradient Descent)。但可能會卡在局部最小值(Local Minimum)而非全域最小值(Global Minimum),解決方案如下:
1. 批次梯度下降(Batch Gradient Descent):但每次更新都要用一個 Batch 的資料
2. 牛頓法、momentum 或是 Adam
3. 或是根據問題調整 Learning rate 、Update 次數等
#### 梯度消失(Gradient Vanishing)

- 針對上面這個DNN:
1. 本層輸出 = f(上層輸出 * 本層權重 + Bias)
2. 從輸入到輸出的前向傳導公式

3. 我們如果使用標準化初始的權重(w1)對本層權重求 Gradient 可以看出來是從輸出到輸入層反向求出。而這種從後面輸出往前找、往前調整的動作,叫做 Back propagation ,當 layer 越多參數越多,越難找到至關重要的調整處(Activation function 的導數也是 0~1 之間的數,在反向傳播中,當梯度由後往前傳時,其連乘後結果會變的很小,最後變為零),稱為梯度消失
- 解決方案:
1. 如設計較好的 Activation function ,如 Relu
2. 設計一個較好的 Gradient descent Algorithm
#### 梯度爆炸(Gradient Exploding)
> 如果一開始的 w 很大,大到後面的Activation function 的導數比 1 更大,這樣結果也會很大,學習不穩定,找不到最好的參數
#### 所以 RNN…
- 如果輸入的資料太長,就會記不住前面的資料,導致梯度消失
- 如果資料太長,權重一不小心沒調好就會爆掉,導致梯度爆炸
## LSTM (Long short-term memory)
>可以克服RNN難以保持長期記憶的問題
>
>[關鍵技術]: cell state (細胞狀態)
>
>
>
>
>有三種gate:
>1. Forget gate
>2. Input gate
>3. Output gate
>
>
>
>
>
>
>
>
>
## GRU(Gate Recurrent Unit)

>過程:

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
---
## GAN (對抗式生成網路,Generative Adversial Network)
> 主要用途:
> 1. 生成圖片
> 2. 圖像轉譯(image-to-image translation)
> 3. 顏色修補
> 
#### [原理]


#### 訓練步驟
1. 先訓練 Discriminator,而Generator先不動


2. 再訓練 Generator


3. 以此類推,反覆訓練。

> - 直到Generator的假樣本(生成出來的)與訓練集的真樣本(真實資料)完全無法區別
>- Discriminator 只能隨機猜測sample是True or False (50% accuracy)
#### GAN 基礎



> GAN 的基礎 – 訓練過程:
• 在高維度非凸 (nonconvex) 中,要訓練好 GAN 並非易事
• 訓練 GAN,只能不斷嘗試錯誤

---
GAN學習資源:
1. https://github.com/GANs-in-Action/gans-in-action
2. https://mgubaidullin.github.io/deeplearning4j-docs/generative-adversarial-network.html
3. https://developers.google.com/machine-learning/gan/gan_structure
---
[GAN演進]
### Autoencoder (自編碼器)
> 是最早的Generator
>
https://jason-chen-1992.weebly.com/home/-autoencoder

### VAE (變分自編碼器, Varational AutoEncoder)

>VAE 是一種基於 Bayesian machine learning 的技術,
試著找出合適的規則 (平均值與標準差) 來界定資料
於潛在空間的分布區域
• 使用深度學習套件 – Keras
• 利用 Keras Functional API 來建構 VAE

### DCGAN (深度卷積生成對抗網絡,Deep Convolutional Generative Adversarial Networks)
> 結合了GAN的基本原理與深度卷積神經網絡(CNN)。DCGAN通過改進GAN的架構,提高了訓練穩定性和生成圖像的質量。
> 

[結合CNN遇到的問題&解法]
>
> 解法: DCGAN在Generator的所有層中使用ReLU激活函數,並在最後一層使用tanh。在Discriminator中,則使用LeakyReLU激活函數。有助於提高模型的效能



>DCGAN在生成器和判別器的大部分層中引入了批量標準化,這有助於緩解訓練過程中的梯度消失和梯度爆炸問題,從而促進模型的穩定訓

> 這邊的"逆向操作"指的是轉置卷積(Transposed Convolution)。
>
> DCGAN特別強調使用轉置卷積來進行上採樣(upsampling)和改善生成圖像的質量。DCGAN的設計中去除了任何池化(Pooling)層,並且全面採用了批量標準化和轉置卷積層來提高模型性能和穩定訓練過程。
>
> 使用一系列卷積層(在這裡實際上是反卷積層或轉置卷積層)來將這個噪聲向量轉化成圖像。
每個轉置卷積層逐漸將特徵圖放大,形成最終的圖像

> 判別器通過卷積層逐漸降低特徵圖的空間維度,最終輸出一個單一的預測值,表示輸入圖像是真實還是假的。
### GAN 面臨挑戰



### CGAN (Conditional GAN)
> 在訓練中,利用附加的條件資訊來制約 Generator and Discriminator
• 條件資訊可以是任意形式:
• 類別標籤
• 特徵描述
• 說明文件
### Cycle GAN

https://github.com/phillipi/pix2pix