# 機器學習
###### tags: `Domain Knowledge`, `Machine Learning`, `課堂筆記`
[toc]
## [Machine Learning Glossary 連結](https://developers.google.com/machine-learning/glossary)
## TensorFlow [筆記](https://hackmd.io/DerAx3y4SUiz6bV3jo1LcQ)
## 前導知識
### 人工智慧 vs. 機器學習 vs. 深度學習
參考資料: [探討機器學習與深度學習之差異](https://www.wpgdadatong.com/tw/blog/detail?BID=B0286)

* 機器學習 Machine Learning
* 種類 
* Supervised Learning
* 輸入辨識物件與答案,作為訓練資料
* 函式的 Loss: 錯誤率,有多種算法
* Reinforcement Learning
* 不給資料、但告訴他答案(結果好或不好)(獎懲機制、成效評估)
* 比如下棋,為了要贏,機器會自己去嘗試不同的下法
* Unsupervised Learning
* 給資料、但不給答案 (可能也因為沒有答案)
* 給多張女生的圖片,生出一張女生的圖片
* 給一堆圖片,同一類的分在一堆
* Semi-supervised Learning
* 部份給答案,但沒答案的 >> 有答案的
* 為沒答案的推測出答案
* Neural Network類神經網路: 
* 發展出 RNN 遞迴神經網路、 LSTM 長短時記憶網路、 RBF 神經網路等等算法,我們所認知的卷積神經網路(CNN)也是從中發展而來,其中類神經網路最具代表性的設計為反向傳遞的機制 ,經由不斷迭代,對比預測值與實際值之間的誤差,以修正模組中的權重,竟而達到最佳化之目的
* NN 還不算是 DL,要夠深才算是 (有一層 hidden layer 應該就可以算)
* 深度學習 Deep Learning
* 對於有效的特徵數據一直都是機器學習中一個較難的課題,近年來深度學習的出現簡化了這項問題
* 所謂的深度學習與機器學習最大的差異,就是輸入端的特徵提取!! 而深度學習將會透過卷積的方式,取代了特徵提取這個環節
* 
* 卷積神經網路(Convolutional Neural Network, CNN )
* 為具代表性的深度學習算法之一,是由類神經網路演化而來
* 經由研究得知只要架構的深度夠深,對於模型的準確度越高,故而稱為深度學習 (但太深也不好)
* 卷積層(convolution layer):利用隨機產生的遮罩進行特徵提取。
* 池化層(pooling layer):對不同位置的特徵進行統計,並取平均值或最大值作為最佳參考點,以減少資料特徵維度。
* 全連接層(fully connected layer):是將之前的卷積與池化後之結果進行平坦化,並接到最基本的神經網絡。
* 
* 機器學習就是自動找函式: 給一段語音,函式輸出文字、給一張圖片,函式輸出種類等等
* 機器學習部分概分
* Regression: 輸出一個數值
* Classification: 選擇題,如果是 2 選 1,就是 binary classification,如果是多個類別,則是 classification
* 當你預測的目標為連續的數值,我們稱其為迴歸;若目標為離散的,稱其為分類
* Generation: 產生有結構的複雜東西 (創造)
## 課堂筆記: [李宏毅老師的機器學習](https://speech.ee.ntu.edu.tw/~hylee/ml/2020-spring.html)
李宏毅老師開了幾年的課程,每年講的東西不太一樣,我是去看 2020 年的課程網站,因為裡面統整了各個主題,包括過去多年的影片以及 2020 年的作業
可以配合不同年度的課程網站做搭配,裡面有一些 2020 年沒有整理到的影片、主題,或是同一個主題,但是不同的授課內容
* 兩張學習路線圖
* 
* 
### Regression: output a scalar
Regression 的精神在 step 3,不斷的修改參數(weight),尋找最佳解
* 測試步驟: 前三步就是機器學習建立的三個步驟
* step 1: 猜測 model: y=b+w\*x,產生多個 function (不同的 b,w)
* 其中可能會有多個 x 乘以多個 w,w 就是 weights
* 在寫程式上就是 dot(x,w)
* step 2: 設計 loss function: 評估各個 function 的好壞,評估方式可以有多種方式
* step 3: 找出最好的 function: 使用 Gradient Descent
* 這一步會透過 iteration 不斷的 GD,找到最好的 weights
* theta 為 weights, n 為 learning rate, 倒三角L 就是 gradient (對 loss function 做偏微分) 
* Gradient Descent: 每次往最好的方向走: 對 loss function 偏微分,往斜率負的方向走),算出來的值就是 Gradient Descent
* 如果不用 GD,而是暴力去試所有的參數,會太花時間
* step 4: 用 test set 測試
* step 5: 結果不好的話,重新設計 model,重複以上步驟
* overfitting: 過於吻合 training 而導致 test 結果不好
* learning rate:
* n 就是 learning rate, theta 是 parameters (weights)
* loss function 舉例: 
* 是指 GD 的改變速率的係數
* learning rate 太大太小都不好,隨著時間動態調整可能比較好
* 有很多方式可以設定這個 rate,比如固定的 rate、隨著時間變慢的 rate、跟過去的 GD 有關的 rate 等等
* Adagrad
* bias & variance
* bias: 遠離真實值
* variance: 分布廣泛
* 愈簡單的模型,因為參數愈少,愈不容易受到 data 影響(比如 y=c 完全不受參數影響),因此 bias 低
* variance 愈大,分布範圍愈廣,愈有可能包含正確的值
* 評估你的模型問題出在哪,才能去做調整
* 如果你的模型連 traning data 都無法吻合,則有 large bias -> underfitting
* 如果你可以吻合 training data,但跟 testing 有大誤差的話,則有 large variance -> overfitting
* bias 高 -> underfitting (左圖)
* variance 高 -> overfitting (右圖)
* (藍線是多種 function 的平均,黑線是真實值) 
* 解決方法
* large bias
* 增加 feature 當作 input
* 設計更複雜的 model
* large variance
* more data (一次拿更多 data 去找去 function)
* regularization: 設計 loss function 追求更平滑的曲線
* 比如說可以讓 loss function 考慮 weight 的影響,希望 weight 小一點 (結果會導致某些 neuron 沒用到(或幾乎沒用到)),讓 model 更簡單: weight regularization
* 通常要將 bias, variance 做 trade-off
* cross validation
* 把 training set 再分成 training 和 validation set,接著把 testing set 當作最後的驗證(當作 private testing set,這樣測出來的結果會比較接近真實的 private testing set)
* n-fold corss validation
* 把 training set 分成 n 組,每次取一組當作 val,其他為 train
* 找出不管怎麼分組,結果都很好(平均好)的 model 當作正確的 model
* 
* Gradient 實作上還有一些細節要注意,可以參考這裡的[影片](https://www.youtube.com/watch?v=yKKNr-QKz2Q)、[投影片](https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/Gradient%20Descent%20(v2).pdf),同時也介紹了操作原理
### Overfitting and Underfitting
參考: TensorFlow 官網: [Overfit and underfit](https://www.tensorflow.org/tutorials/keras/overfit_and_underfit)
介紹 overfitting and underfitting,並且說明怎麼解決
* As always, the code in this example will use the tf.keras API, which you can learn more about in the TensorFlow Keras guide.
In both of the previous examples—classifying text and predicting fuel efficiency — we saw that the accuracy of our model on the validation data would peak after training for a number of epochs, and would then stagnate or start decreasing.
In other words, our model would overfit to the training data. Learning how to deal with overfitting is important. Although it's often possible to achieve high accuracy on the training set, what we really want is to develop models that generalize well to a testing set (or data they haven't seen before).
The opposite of overfitting is underfitting. Underfitting occurs when there is still room for improvement on the train data. This can happen for a number of reasons: If the model is not powerful enough, is over-regularized, or has simply not been trained long enough. This means the network has not learned the relevant patterns in the training data.
If you train for too long though, the model will start to overfit and learn patterns from the training data that don't generalize to the test data. We need to strike a balance. Understanding how to train for an appropriate number of epochs as we'll explore below is a useful skill.
To prevent overfitting, the best solution is to use more complete training data. The dataset should cover the full range of inputs that the model is expected to handle. Additional data may only be useful if it covers new and interesting cases.
A model trained on more complete data will naturally generalize better. When that is no longer possible, the next best solution is to use techniques like regularization. These place constraints on the quantity and type of information your model can store. If a network can only afford to memorize a small number of patterns, the optimization process will force it to focus on the most prominent patterns, which have a better chance of generalizing well.
* The simplest way to prevent overfitting is to start with a small model: A model with a small number of learnable parameters (which is determined by the number of layers and the number of units per layer). In deep learning, the number of learnable parameters in a model is often referred to as the model's "capacity".
Intuitively, a model with more parameters will have more "memorization capacity" and therefore will be able to easily learn a perfect dictionary-like mapping between training samples and their targets, a mapping without any generalization power, but this would be useless when making predictions on previously unseen data.
Always keep this in mind: deep learning models tend to be good at fitting to the training data, but the real challenge is generalization, not fitting.
On the other hand, if the network has limited memorization resources, it will not be able to learn the mapping as easily. To minimize its loss, it will have to learn compressed representations that have more predictive power. At the same time, if you make your model too small, it will have difficulty fitting to the training data. There is a balance between "too much capacity" and "not enough capacity".
Unfortunately, there is no magical formula to determine the right size or architecture of your model (in terms of the number of layers, or the right size for each layer). You will have to experiment using a series of different architectures.
To find an appropriate model size, it's best to start with relatively few layers and parameters, then begin increasing the size of the layers or adding new layers until you see diminishing returns on the validation loss.
* Training vs. Validation (plot and compare)
* It's normal for there to be a small difference.
* If both metrics are moving in the same direction, everything is fine.
* If the validation metric begins to stagnate while the training metric continues to improve, you are probably close to overfitting.
* If the validation metric is going in the wrong direction, the model is clearly overfitting.
* Conclusions
* To recap: here are the most common ways to prevent overfitting in neural networks:
* Get more training data. (讓廣度更夠)
* Reduce the capacity of the network. (不要太多層、每層不要太多 neuron)
* Add weight regularization. (weight 小一點)
* Add dropout. (訓練時不要每個 weight 都去用到(直接忽略),下一張圖片(或下一個 batch?)重新選擇忽略的 weight)(test 的時候不忽略)
* Two important approaches not covered in this guide are:
* data-augmentation
* batch normalization
* Remember that each method can help on its own, but often combining them can be even more effective.
* Example: 這個 model 太大,因此在裡面加一些修正,避免 overfitting
* l2 regularization
* dropout
```
combined_model = tf.keras.Sequential([
layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
activation='elu', input_shape=(FEATURES,)),
layers.Dropout(0.5),
layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
activation='elu'),
layers.Dropout(0.5),
layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
activation='elu'),
layers.Dropout(0.5),
layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
activation='elu'),
layers.Dropout(0.5),
layers.Dense(1)
])
```
### Classification: Probabilistic Generative Model
* x 這個物件(已經用數值 vector x 表示)為 C1 class 的機率: 
* 其中 P(C1|x) 就是下面的 Gaussian Distribution
* P(C1|x) 和 P(C2|x) 的 u 和 Sigma 不同,但是當 Sigma 相同時,會有比較好的結果
* If P(C1|x) > 0.5, output: class 1, otherwise, output: class 2
* maximum likelihood
* 想法是這樣的,一個物品是否屬於某個類別,需要有一個衡量方式,而這個方式我們選用高斯分布。高斯分布的參數設計方式(可以想乘訓練方式)為: 從已知的這個類別的物體去找出 maximum likelihood
* 算出這個高斯分布後,以後有新的物體都可以用上面的 P(C1|x) 去算出屬於 C1 的機率
* likelihood of a Gaussian: 把所有的物件 x 帶到 Gaussian Distribution 裡面算出來的機率相乘,就是 likelihood
* Gaussian Distribution (2-D) 
* maximum likelihood 發生在 
* u 為 1x2 vector, Sigma 為 2x2 matrix
* 三步驟設計模型 (機器學習也是這樣):
* 設計 model -> function set
* 評估 function 的好壞
* loss function
* likelihood
* 找出最好的 function
* Logistic Regression
* 是把上面的 classification 整理後的結果: 變成 sigmoid function

-> 
-> 
* 可以看到 logistic regression 和 linear regression 很像 
* 差在 logistic regression 的 output 介於 0~1
* logistic 的 loss function 是用 cross entropy 
* 不選用和 linear 一樣的 Square Error 是因為距離目標(中心)遠的時候,update 的太慢 
* 以上兩種方法分別稱為 Discriminative(Logistic) 和 Generative(假設是 Gaussian) 法
* 大部分情況 Generative 會比較好
* 資料量少時用 Discriminative 可能比較好,因為他會去從資料中推算出其他可能性,這在資料量少時會有補足資料的效果
* Multi-class Classification
* 同一個 input x,要去推算他是 C1 C2 C3 哪一個 class,則就是帶進去三個 function,看誰的結果比較好
* 希望結果 y 符合 1>yi>0 & sigma(yi)=1 -> 用 softmax
* 
* 取 e 的原因是要拉大之間的差距
* loss function 用 cross entropy 
* logistic regression 有一個大限制,就是輸出結果 >0.5 或 <0.5 的分界是一條線,這樣會導致有時分不開目標 
* (補充說明: 只有兩維時,我們可以用眼睛看出來那條線要放哪,把他分類分的好,但是多維時,我們就不能視覺化了,所以要借助電腦去幫我們分類)
* 解決方法是做 Feature Transformation: 轉換到另一個平面上 
* 但是怎麼轉換不好找,因此要借助電腦幫我們找: cascading logistic regression models 
* 前面在做 feature transformation
* 後面做 classification
* 每一組 logistic regression 就被稱作 Neuron,多個 Neuron 稱為 Neural Network
### Deep Learning
* 一樣三步驟
* step 1: neural network (function set)(model)
* step 2: goodness of function
* step 3: pick the best function
* 每一個 neural (logistic regression) 都有 weights 和 bias (parameters) 
* 不同的 neural 連接方式形成不同的 neural networks
* fully connect example 
* 中間每一層 layer 的 neuron 數不需要一樣
* matrix operation 中間的每一步可以變成一連串的矩陣運算,交給 GPU 做運算

* deep = many hidden layers (有人說一層就算 deep)

* 現在比較少用 sigmoid function,而是其他的,而這個功能叫做 activation function
* 中間的 hidden layer 可以看作於 feature extractor,而 output layer 就是做 softmax (上面都有解釋) 
* example: 
* 一些好問題:
* Q: 中間要有幾層、要有幾個 neuron?
* A: 需要不斷的嘗試還有經驗
* 所以本來要手工嘗試 feature transformation 變成手工嘗試 network 的架構,而 feature transformation 就交給機器去做
* 是否有變的更簡單,可能也要 case by case
* Q: 是否可以讓機器自己去尋找 network 架構?
* A: 可以,只是目前效果不好 ( Evolutionary Artificial Neural Networks)
* Q: 是否可以不是 fully connection,而是其他各種連接法?
* A: 可以,後面 CNN 會講到
* Q: 做深層真的有用嗎? 深層可以看做成更多參數而已,variance 大,bias 小,結果當然可能比較好?
* A: 有個理論是說其實一個 hidden layer 的 neuron 夠多,就可以表示任何的 function,所以不用 deep,但真的是這樣嗎? 老師[後面](https://hackmd.io/_IbqKcgkT_6v1_divco8mA?both#Why-Deep-Learning)會講到
* 理論上可以,但是 performance 不好,也就是說同樣多的參數,分配到多層裡的結果會比較好,如果你只用一層,也許需要 100000 倍的 neuron 才能做到一樣的事
* step 1: design a neural network
* neural network = model = function set
* step 2: goodness of function
* 把 output 跟 true answer 做 cross entropy,跟 logistic regression 一模一樣 
* 接著把好幾張圖片的 C 加總變成 total loss
* 目標就是尋找一個 function 使得 total loss 最小,也就是尋找好的 parameters
* step 3: pick the best function
* 那如何尋找這個 function 呢? 一樣用 Gradient Descent (對每一個參數做偏微分)
* 但是對幾百萬個參數做偏微分太慢,因此有一個比較有效率的方法叫做 Backpropagation
### Backpropagation
有效計算 Gradient Descent 的演算法
其實我也不太懂,底下筆記看看就好
* 利用 chain rule 去計算 forward pass 和 backward pass
* 把原本要算的偏微分用 chain rule 分解 
* forward pass: 從前面算 
* backward pass: 從後面算回來 
* summary 
### Some Tips (Issues)
* recipe of Deep Learning
* 
* 第一步要先確定 trainging data 的結果好才繼續往下測 testing data
* 如果連 training data 都沒有好結果的話,那就要重新設計模醒
* 如果 training data 的結果不好,那不會 overfitting,不要甚麼都怪 overfitting
* 老師認為,也不應該稱為 underfitting,只有當參數過少出現不準確時才可以稱為 underfitting
* 結果不好時的一些解決辦法: 
* 愈多層結果愈差? 
* 可能出在 activation function 問題 
* 愈前面的層去做 gradient 的效果愈差,因為經過了多次的 sigmoid 後,影響微乎其微,所以前面的層變動不大,都是後面的層在變
* 解決方法: 更換 activation function (也就是把 sigmoid 換掉)
* 換成 ReLU 或是它的變形 
* 幾個好處: 計算快速、相當於無限多個 biased 的 sigmoid 和成、生物上的理由(?)
* 換成 Maxout (輸出一組中大的那個)
* 換成 Learnable activation function (可以是各種 function)
* adaptive learning rate
* Adagrad: 跟時間還有過去的 gradient 有關 
* RMSProp: 也是跟過去有關(比例自己調)
* Momentum: 慣性: 也就是現在的移動方向會受到前一次的影響 
* Adam: RMSProp + Momentum
* early stopping: 在 validation set 的 loss 增加時,停止訓練

* regulization: 改變 loss function,使得找到的 weight 不只要可以讓 total loss 變小,也要讓找到的 weight 接近 0
* 也就是在本來的 loss function 後面加上一項東西 (詳細去看投影片)

* dropout: 每次只選其中一些 neuron 去做訓練,因此每次只會更新部分 parameters
* 所以 network 的結構一直在變 (只選其中一些訓練)
* 但是 parameter (weight) 會一直延續下去用
* 最後 testing 時,全部的 neuron 都要使用,只是所有的 weight 都要乘以 1-p (p(比例) 被 dropped),用期望值去思考這件事情比較容易 (因為 weight 不是每次都去選)
* 最後 testing 時全部 neuron 都去使用的結果(右圖),接近於各種 NN 下去算的平均(左圖) 
* 為甚麼要 dropout? 我覺得應該是因為模型太大的話算起來會太複雜,所以要把它切分成小的來算,不論是上圖中的左邊方法還是右邊方法 (但左邊方法運算量還是太大,所以會用右邊的方法)(像 random forest 也是用多種 tree 下去看統計結果)
* 老師還有一個解釋是,當每次只選一些 neuron 時,他們要 carry 全部,所以會好好做,然後所有 neuron 都有這種想法時,整體結果就會好
* Dropout Rate: They define the fraction of input to drop as a precaution for overfitting. Recommended range: 0.2–0.5.
### Why Deep Learning?
* one example: 只用一層,參數用很多,效能還是比不過多層 
* Universality Theorem: 只用一層 hidden layer 可以達到所有的 function
* 理論上對,但效能不好 (需要用更多的 neuron 達成這件事)
* 可以把 deep learning 想成模組化架構,同樣的 neuron 會被多個 neuron 使用
* 如果你 input 直接接最後的 classifier (一層,但是多 neuron),當你某個類別的資料量少時,會訓練的不好
* 但你如果是多層,且每層 neuron 少時,資料量少的那個類別會先跟別的類別分在一起,因此資料量夠多
* 用電路去做比喻:
* 只要兩層的 logic gates 就可以表示所有的 Boolean function,但用更多層的話會更容易,也可以用更少的 gates
* neural network 也一樣,用更多層的話,會更容易,可以用更少的 parameter,甚至更少的 data
### CNN
* CNN 雖然看起來複雜,但它其實是比 DNN 還要更簡單的
* 每一個 neuron 都可以想成一個 classifier
* 有時只要圖片中的某個部分的 pattern,所以每個 neuron 其實不用看整張照片
* 同一個 pattern 在圖片的不同位置,會用不同 neuron 處理,但是 parameter 可以一樣
* subsampling: 把圖片縮小,處理起來可能還是差不多,但是 parameter 會變少
* 架構圖 
* convolution: filter
* 性質 1: 某些 pattern 比整張圖片小
* 性質 2: pattern 可能會出現在圖片的不同位置
* max pooling: output max of a region (可以用其他 pooling)
* 性質 1: subsampling 不會改變 object
* convolution 其實也是 neuron network,只是不是 fully connected 每一個 pixel
* 同一個 filter 會有多個 neuron,共享 weights
* 
* flattern: 平坦化,也就是拉成一個 vector
* CNN in Keras
* 注意: 25 個 filter 變 50 就是真的變 50,不是 25\*50
* 
* 
* CNN 真的是無法解釋內部在做甚麼的嗎?
* 其實可以去計算訓練好的模型中,degree of the activation of the k-th filter,也就是經過一個 filter 後產生的結果總和
* 去找出一張圖片,能使得這個 degree 最大,那麼這張照片,就是這個 filter 想找出來的目標
* 比如這是其中 12 個 filter 找出最大 degree 的 image。所以說這幾個 filter 就是要找出這些紋路的圖片 
* 不過發現,辨識 0~9 的 CNN 最後一層 output layer 的最佳圖片是長這樣
* 這不是我們人類理解的樣子,因此需要去對它做一些限制,產生的圖片才是我們要的數字,比如說白色的區域要愈少愈好,白色要連在一起 (白色是寫字的部分)
* 
* CNN 使用案例:
* 甚麼樣的東西可以拿給 CNN 訓練、辨識呢? 跟圖片有同樣性質的東西
* 某些 pattern 比整張圖片小
* pattern 可以出現在任何地方
* 拿掉某幾行某幾列也不會怎樣
* 那為甚麼 Alpha Go 可以呢?
* "叫吃" 符合特性 1,2
* 但是不符合特性 3,老師去看 paper 發現他們使用的 CNN 沒有使用 Max Pooling
* 在其他領域使用 CNN 時,也要去思考使用上的意義,比如說 filter 移動的方向要往哪、是否有意義
#### 程式碼範例:
1. 手寫辨識 with Fully Connected: Keras, [github](https://github.com/Sakura-gh/ML-notes/blob/master/code/Digits-Detection/digits-detection.py)
2. 影像辨識 with CNN: Pytorch, [colab](https://colab.research.google.com/drive/16a3G7Hh8Pv1X1PhZAUBEnZEkXThzDeHJ)
* 以下說明 (2) Pytorch 版本
* 模型架構 
* 繼承自 nn (沒有指定是 cnn,cnn 要自己建構)
* fc 表示 fully connected
* 訓練過程 
* 初始 parameters 可能是依循某個原則設定,或是亂數吧
* 訓練整個過程是這樣:
* 一張圖片一張圖片拿進去訓練,每一張結束後,更新 parameters
* 全部圖片跑完後,再重頭跑,但是 parameters 是沿用,繼續更新
* 總共跑 epoch 次
* 結果顯示 
* batch 指的是幾張照片跑完後,加總 loss,才去做 Gradient Descent
* 比如 batch=100,表示隨機選一百個 (要隨機)
* batch size 設比較大時,一個 epoch 需要的時間比較少
* 比如 50000 examples:
* (batch size, update) = (1,50000) -> 166s/epoch
* (batch size, update) = (10,5000) -> 17s/epoch
* 可以看到 batch size 高時,每個 epoch 運算時間比較短,但是相同時間內,update 次數是差不多的
* batch size 10 的比較穩定、performance 也比較好
* batch size 愈高會愈快是因為 GPU 可以平行運算,但是 batch size 開太高就沒辦法了
* 下面是 GPU 平行運算 
* batch size 太高也會陷入 local minimum (因為隨機性太低)(應該是指隨機選照片)
* epoch 是指全部照片拿去訓練一次叫一個 epoch,你總共要訓練幾次
* 輸入_x(圖片) 如果有一萬張圖片,分別是 28x28,則 train_x 維度會是 10000x28x28(x3)
* 一些 (1) 手寫辨識 with Fully Connected: Keras 的注意事項,來源: [github](https://github.com/Sakura-gh/ML-notes/blob/master/code/Digits-Detection/digits-detection.py)
1. batch_size=100,epochs=20为宜,batch_size过大会导致loss下降曲线过于平滑而卡在local minima、saddle point或plateau处,batch_size过小会导致update次数过多,运算量太大,速度缓慢,但可以带来一定程度的准确率提高
2. hidden layer数量不要太多,不然可能会发生vanishing gradient(梯度消失),一般两到三层为宜
3. 如果layer数量太多,则千万不要使用sigmoid等缩减input影响的激活函数,应当选择ReLU、Maxout等近似线性的activation function(layer数量不多也应该选这两个)
4. 每一个hidden layer所包含的neuron数量,五六百为宜
5. 对于分类问题,loss function一定要使用cross entropy(categorical_crossentropy),而不是mean square error(mse)
6. 优化器optimizer一般选择adam,它综合了RMSProp和Momentum,同时考虑了过去的gradient、现在的gradient,以及上一次的惯性
7. 如果testing data上准确率很低,training data上准确率比较高,可以考虑使用dropout,Keras的使用方式是在每一层hidden layer的后面加上一句model.add(Dropout(0.5)),其中0.5这个参数你自己定;注意,加了dropout之后在training set上的准确率会降低,但是在testing set上的准确率会提高,这是正常的
8. 如果input是图片的pixel,注意对灰度值进行归一化,即除以255,使之处于0~1之间
9. 最后的output最好同时输出在training set和testing set上的准确率,以便于对症下药
### RNN (Recurrent Neural Network)
* 有記憶力的 network
* input 是 sequence (有順序的輸入) 就可能要用 RNN,比如一串文字、語音辨識系統、翻譯系統等等
* 現在用 RNN 就是用 LSTM (下面會解釋)
* Keras supports 三種 RNN "LSTM", "GRU", "SimpleRNN"
* 使用案例: 你想判斷一句話中的地點是出發地還是目的地
* "arrive Taipei on November 2nd" or "leave Taipei on November 2nd"
* Taipei 有兩種可能,所以要去紀錄前面(或後面)出現的字是 arrive or leave
* 可以有多種架構,不過概念上都是會把階段的 output 儲存起來,當作未來某一次某個 neuron 的 I
* Elman Network: 
* hidden layer 的 neuron 會把結果儲存到 memory 裡面,當下次有新的 input 進來時,memory 儲存的結果會被拿出來當另一個 input (也就是 input 不只一個)
* Jordan Network: 據說效果比較好 
* 所以當你 input 輸入順序調換,結果就會不一樣
* Bidirectional RNN: 讀取方向可以兩個方向同時進行,避免只讀到一半就要判斷
* y 是 ouput layer 
* Long Short-Term Memory (LSTM)
* 架構圖 
* 模擬輸入流程可以去看投影片
* 不同的 gate 是來自於同一個 input,只是乘以不同的 weights (matrix)
* 
* 一個 LSTM 就是代表一個 neuron
* 參數量是一般的 neuron 的四倍 
* 輸入 x^t 的流程 
* 前面是簡單版,這個應該是比較正常的版本,然後左右再更廣、上下更深(deep)
* 下面的 c h x 應該是串接在一起去計算的
* 
* 現在說到用 RNN 就是用 LSTM
* RNN 也是用 Gradient Descent (但是是用某種 backpropagation)
* RNN-based network 是比較難 train 的
* RNN 使用 LSTM 而不是一般的 RNN 是因為 LSTM 可以解決 gradient vanishing 問題
* RNN memory 裡面的值會一直被洗掉
* 在 LSTM 裡面,你的 weight 會影響到 memory,除非選擇洗掉,不然會一直都在
* weight 累計相乘會使 weight 影響很大,所以不會有 gradient vanishing 的問題
* (其實我還是沒有很懂)
* 一開始的 LSTM 就是要來解決 gradient vanishing 的問題的
### Seq2Seq
* 用 RNN 產生資料
* 給定一開始的輸入,它會自動產生下一個、下一個輸出
* 文字、圖片(一個、一個 pixel 輸出)等等都可以
* conditional generation: 我們希望可以產生某個情境的句子
* 也就是 Sequence 2 Sequence
* image caption generation:
* 先把圖片變成 vector
* 輸入 model 裡
* 輸出文字,而這個文字跟這個圖片有關
* 輸入文字,輸出相關文字:
* 把輸入文字丟到另一個 RNN 裡,得到一個輸出 (Encoder)
* 把這個輸出丟到目標 RNN 裡,產生我們要的句子 (Decoder)
* 但其實這兩個 RNN 也可以一樣(相反),但可能會降低準確度
* 大多數常見的 sequence-to-sequence (seq2seq) model 為 encoder-decoder model,主要由兩個部分組成,分別是 Encoder 和 Decoder,而這兩個部分則大多使用 recurrent neural network (RNN) 來實作,主要是用來解決輸入和輸出的長度不一樣的情況
* Encoder 是將一連串的輸入,如文字、影片、聲音訊號等,編碼為單個向量,這單個向量可以想像為是整個輸入的抽象表示,包含了整個輸入的資訊
* Decoder 是將 Encoder 輸出的單個向量逐步解碼,一次輸出一個結果,直到將最後目標輸出被產生出來為止,每次輸出會影響下一次的輸出,一般會在開頭加入 "< BOS >" 來表示開始解碼,會在結尾輸出 "< EOS >" 來表示輸出結束
* 
* 根據更久之前的情況,去產生輸出,比如:
```
A: Hello
B: Hi
A: Hi
```
* 但其實我們不希望 A 再回覆 Hi,所以我們不能只考慮 B 剛剛說甚麼,要考慮更久之前的 A 說過的話
* 可以把 Encoder 的輸出串連在一起,當作第二次 A 的輸入
* Attention: Dynamic Conditional Generation
* 比如 "機器學習" 翻譯成 "Machine Learning"
* 其實只要 "機器" 就可以翻成 "Machine",而不需要整句 "機器學習"
* 所以在輸入時,一開始只要輸入 "機器",翻譯完再輸入 "學習"
* 而這會是一個動態改變輸入的過程
* 但其實一直都是 "機器學習" 做為輸入,只是 Encoder 會有一個 function 去改變權重
* Memory Network
* 講到輸入一個文章,給一個問題,輸出答案
* 後面還有講到蠻多,但我先跳過
* 一些寫程式注意相關的事情,或是 model 介紹,可以看[作業內容](https://colab.research.google.com/drive/11iwJbQv9iScRo6kGP7YfyHaaorlHhzMT)
### Semi-supervised Learning
* 通常發生在 unlabeled data (U) >> labeled date (R\)
* 我們 data 通常可以很多、容易,難是難在 label,因此如果我們可以把 unlabeled data 發揮作用,會很好
* Semi-supervised Learning for Generative Model
* (我不太懂 Generatibe Model 是甚麼,不過跟條件機率有關)
* (這種方法好像是 regression)
* 概念上是這樣: 先假設一些參數,然後用這些參數去計算 unlabeled data,接著再用算出來的結果去更新參數,最後收斂
* step 0: 初始化參數 (可以用 labeld data 去算) 
* step 1: 計算 unlabeled 的結果 
* step 2: 更新 parameters,然後回到 step 1 
* 我覺得整個過程可以看做把 unlabeled 給 labeled,並且是一個連續的數值 (不像下面的是離散的 0 或是 1)
* Low-density Separation Assumption
* 當資料有很明確的分界時,叫做 low-density,比如非黑即白
* self-training
* 是一個 neural network
* 用 labeled data 去 train model
* 然後用這個 model 去預測 unlabeled 資料
* 用結果把 unlabeled 變成 labeled 的,再回去 train 新的 model
* 過程跟 Semi-supervised Learning for Generative Model 很像,但差別在於 unlabeled -> labeled 的方法
* soft label: [0.7 0.3] 還是 [0.7 0.3]
* hard label: [0.7 0.3] 變成 [1 0]
* self-training 用 hard label,如果用 soft 會無效
* Semi-supervised Learning for Generative Model(regression) 用 soft label,如果用 hard 會無效 (其實我不太懂這個)
* entropy-based regularization
* 不只要計算本來的 loss function,還有多加入另一個東西
* 另一個東西是在計算 unlabeld data 的輸出結果的分散程度,愈分散的話愈不好
* 
* Smoothness Assumption
* 基本想法: x1 x2 很像的話,預期他們的結果也會相似
* 很像的定義: 不是距離很近,而是要在一個高密度(連續) 的區域裡
* 舉例:
* x2 雖然跟 x3 比較近,但他們在不同高密度區 
* 兩種 2 之間是可以過度過去的 
* 兩個人的左側面可能相較於一個人的左側面與右側面的還像,但是同一個人的左側面與右側面其實是可以過度過去的(各種角度拍攝),所以不應該把兩個人的左側面規為同一類
* graph-based approach
* 圖形上連在一起才算一類
* 可以想辦法把資料變成圖形
* 比如把超連結之間的連起來
* 距離多近的連起來
* 最近的幾點連起來
* 舉例:
* 紅點藍點雖然近,但不連續
* Better Representation
* 藉由觀察某些相關現象,來為他們分類。這些現象就是 better representation
* 在 unsupervised 的部分會講到
### Explainable AI (跳過)
### Adversarial Attack
* 攻擊是指輸入一張惡意圖片,讓模型誤以為是其他東西,比如說輸入一個竄改過的貓的圖片,雖然看起來像貓,但結果卻輸出鉛筆
* 訓練模型 vs. 攻擊模型 行為差異
* loss function
* 正常模型希望 L 結果愈小愈好
* 攻擊模型希望 -L 愈小愈好 (才會離 true 愈遠)
* 攻擊目標分兩種: 一種是讓圖片辨識成隨便的東西,一種是辨識成某個特定東西 (loss function 要加上 C(惡意圖片,錯誤答案),然後希望 L(C\) 愈小愈好)
* 調整方式
* 正常模型訓練過程是去調參數
* 攻擊模型是去對已經訓練好的模型做攻擊,所以不會調參數,而是會去改變輸入圖片
* 限制
* 攻擊模型時,輸入圖片希望跟本來的圖片類似,小於某一個值,這樣才可以做到欺騙的作用 (人肉眼看不出來)
* 加雜訊給圖片,並不是肉眼看起來愈雜對機器來說就真的雜
* 比如說給一張圖片加某些特定雜訊,人眼看不出來,但機器卻完全辨識錯誤
* 給一張圖片加人眼很明顯看出的雜訊,辨識結果卻不會差太多
* 一個解釋方式是這樣: 特定方向的變化才大 
* 不同的方法差在 optimization methods 還有 different constraints
* L' 可以指負的 L (差距愈大愈好),或是其他
* 
* 分成兩種攻擊方式
* white box attack: 知道參數,可以算 gradient descent
* black box attack: 不知道參數
* 如果知道辨識目標,則可以創造一個類似的 network,並且用這個 proxy network 去做 white box attack,往往可以得到不錯的效果
* universal adversarial attack: 所有圖片加同一個雜訊,效果都好
* 即使是用攝影機拍攝,不是用程式把圖片輸入,也有可能可以欺騙成功
* defense
* passive defense: 可以在圖片輸入時,加入 filter,比如說變平滑, resize, padding 等等,則原圖或是惡意圖片,都可以辨識成功
* proactive defense: 找出哪些惡意圖片(input_x)會造成錯誤結果(false_y),則把這個 (input_x,true_y) 加入模型,再次訓練,訓練完後要再次去找,反覆下去
* 但是防護方式被知道後,就容易被突破
* 防禦的 A 攻擊,可能會對 B 減少防禦
### Network Compression
* 有些 device 運算能力沒這麼強、記憶體空間不大
* 軟體、硬體方面解決
* network pruning
* network 通常有過多 parameter (over-parameterized)
* 把 weight 不重要的 prune 掉
* 舉例: 如果 neuron 輸出幾乎都是 0,那它可能不重要
* 希望 accuacy 不要降太多,因此 prune 之後可以再去 tune 它,可以把訓練資料再去 update 一次,往往可以修復損傷
* 一次 prune 不會太多,如果不夠,就再重複以上步驟
* 
* 為甚麼不一開始就 train 一個小的 model 呢?
* 因為大的比較好 train
* 實作上,不要真正把那些 weight 拿掉,設成 0 會比較好
* distillation
* parameter quantization
* using less bits to represent a value
* weight clustering: 類似的 weight,用同一個 weight 表示
* huffman encoding
* architecture design
* 舉例: 在 fully connected 兩層之間插一層 hidden layer (linear,沒有 activation function),可以減少參數量 (K 夠小 的話)
* dynamic computation
* train 很多不同大小 network,根據電量不同選擇不同,但是這樣要儲存很多 network,所以要想其他方法
* 希望一個 network 可以符合這些條件: 讓它在中間層的輸出就可以使用了
* 但是這樣會對 accuracy 有所犧牲
### Dimension Reduction
* unsupervised learning
* 將輸入的維度做降維
* 因為我們可能不需要這麼多維度,也可以表示一個圖片、文字
* 平常在做模型的時候,如果模型有太多的Feature會造成幾個訓練上的困難: [參考](https://medium.com/@jimmywu0621/dimension-reduction-%E5%BF%AB%E9%80%9F%E4%BA%86%E8%A7%A3pca%E7%9A%84%E5%8E%9F%E7%90%86%E5%8F%8A%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95-f0ce2dd28660)
* 計算繁重:每個模型對於資料量的時間複雜度可能會不同,因此增加維度或是資料量可能會讓訓練變得更加繁重
* 特徵變得不敏感:Feature變多雖然代表著訊息量增加,但是換個角度來思考其實也增加了模型的雜訊
* 因此在做哪種模型時,通常不會End-to-End的直接將資料喂進模型之中去跑,會先將資料做一些正規化、降維的程序以提升模型的效能。
* Principle Component Analysis (PCA)
* PCA的中心思想就是“用最少的維度捕捉最大的變異”
* 比如底下這張圖,本來用二維表示,但你只要對它做轉換,就可以只用 W1' 一維就可以大致表示它
* 相反的,如果你是只用 W2' 去表示它,所有點的 W2' 都會差不多,接近原點,變的分不出彼此了
* 因此“用最少的維度捕捉最大的變異”的選擇就是 W1'
* 
* z = Wx
* x 是輸入,乘上 matrix W,輸出 z
* z 看你要變成幾維
* 我們希望降維後的分布愈分散愈好,這樣才能保留一些資訊在裡面,不然混乘一團,就沒辦法做區分
* W 的計算過程去看投影片
* PCA 可以想成把一個輸入拆解乘幾個元件的相加或相減
* 7 這個數字可以分解成 u1, u3, u5 組成
* 底下的 C 應該就是輸出 z (weight)
* 
* PCA 應該是只有一層 hidden layer,多層的話看下面的 Deep Auto-Encoder 
* 其他例子: 可以注意,它有正有負,不是全部都是相加 
### Neighbor Embedding
* Unsupervised Learning
* 非線性的降維 (dimension reduction)
* 跟前面一樣,目的就是降維、分群,但是主要都是數學運算,我就不寫在這了 (而且我也不太懂)
### Word Embedding
* dimension reduction
* word to vector
* 1-of-N Encoding 幾個字就幾維 (vector),這樣不好,因為會看不出每個字之間的關聯性 (每個字只在自己那一維是 1,其他是 0)
* 我們希望透過 word embedding (降維) 的方式,把相關 (類似語意) 在圖上是比較接近的
* unsupervised-learning: 只要讓機器閱讀大量文章,它就可以知道詞彙中 embedding 的 feature vector 應該長甚麼樣子
* 一個簡單概念是這樣:
* 十萬個字就給它十萬維,而把它餵近 NN 時可以輸出一個結果
* 那類似的輸入,希望可以有類似的輸出,所以在 hidden layer 時,就要先把它們分到同一類,這樣輸出才會類似
* 因此,我們可以把第一個 hidden layer 的結果拿來當作這個輸入的 embedding vector (取代掉十萬維的 vector)
* 類似的字,比如"男人"、"女人",的 embedding vector 會類似
* 希望可以透過前後幾個 word 去預測某一個位置會是甚麼 word
* 詳細去看投影片,這邊只簡單紀錄
### Deep Auto-Encoder
* 複習一下 PCA: 
* Upsupervised Learning
* 其實應該就是把 PCA 加深 (有興趣可以去查差別)
* 從下圖可以看到 Deep Auto-Encoder 比 PCA 只有一層還要更深,做出來的效果也更好
* 中間的 30 就是 code (降維後的結果)
* 
* 用下面的方法 可以把圖分得更開 
* (symmetric is not necessary) 
* 如何找出 Encoder?
* 我們知道輸入(9),但是不知道 code 是甚麼,所以無法單獨做出 Encoder 和 Decoder,但是我們可以讓他們一起被做出來
* 找到之後 Encoder 就是我們要的 dimension reduction function
* 
* 找一個詞彙跟文章的關係,或是在一個文章中搜尋一個詞彙,可以用 auto-encoder 變成 vector,然後看分布是否在附近 
* 以圖搜圖也是,如果是看 pixel 之間的歐幾里得距離的話,結果會不好,但如果是用 auto-encoder 的 vector 的話,結果會比較好 (至少用人臉會找出人臉)
* 也可以用 CNN 版本的 auto-encoder 來處理圖片 
* 訓練中找到的 decoder 也可以用來產生東西: 用已經得到的 code,在他附近找其他 code,放到 decoder 裡面,可以得到類似的結果 
### Anomaly Detection
* 異常偵測,但不代表是偵測出不好的,而是偵測出不一樣的,可能特別好,也可能特別差
* 不能把異常偵測當作二元分類: 因為沒辦法把各種異常都收集到,把它們分為同一類,所以要想其他辦法: 比如說信心指數低的話,才被歸類為 unknown
* 幾種分類方式 
* with classifier:
* 分類的結果不只輸出哪一類 (機率分布),也輸出信心指數
* 如果不屬於任何一類,機率分布會很平均 (都一樣有可能=都一樣不可能)
* 信心指數可以選擇機率分布最高的值,或是你可以想其他方法
* 不能單純計算正確率 (accuracy),因為你可能正常資料很多,異常資料很少,然後當這兩種都被分為正常時,正確率會很高,但其實只是全部歸為正確而已 (要避免因為數據量差距懸殊而導致的錯誤評估)
* 可以去考慮 false positive, false negative,至於哪個比較重要,你可以自己去設權重
* 比如看醫生,可以誤判你有得病,但不要沒看出來你有得病,嚴重性差很多
* 用分類器還會有一個問題,就是你異常圖片可能比正常圖片的特徵更明顯,所以不會被認為是異常
* 比如老虎可能比貓更像貓,就會被分類為貓狗分類器的貓
* 有一些解決方法,不過老師講的沒有很清楚
* without labels
* 可以用高斯分布 (Gaussian Distribution) 去找出正常範圍
* Generative Model (上面有[講過](https://hackmd.io/_IbqKcgkT_6v1_divco8mA?both#Classification-Probabilistic-Generative-Model))
* 找到滿足最高的 likelihood 的高斯分布
* 找到之後,如果某一點帶進去高斯分布裡面,機率太低 (低於某個 threshold),那就可以視為異常
* 圖片右上角的箭頭是指 threshold (lambda) 的分界 
* 也可以用 deep-learning based 的方法,比如 auto-encoder
* 訓練出來的 auto-encoder 要可以把正常的圖片 reconstruct
* 如果餵進去異常圖片,會無法 reconstruct
### Transfer Learning
* 利用不直接相關的資料,幫助我把目標資料訓練好
* 所以叫做 transfer?
* 比如說我要辨識台語,但是我資料很少,此時我會拿中文、英文等語言幫助我訓練辨識台語
* 
* fine-tuning
* target data 少,source data 多
* 可以先用 source data 去 train,train 完後的 parameter 當作 target data 的 initial parameter 給 -> fine tune
* 也可以用 layer transfer,就是把 source data train 出來的其中幾層 layer 給 target data 用,這樣只需要 train 剩下來的就好 (避免 overfitting)
* 問題是要拿哪幾層呢? 可以思考這個 model 的意義
* 如果是語音轉文字 model,複製後面幾層 (後面就是在處理文字,不是聲音了)
* 如果是圖片辨識 model,複製前面幾層 (前面幾層是在抽取 pattern,可以重複使用)
* multitask learning
* 希望 target, source 不會因為前面 tune 完後,只剩其中一種可以辨識
* 
* domain-adversarial training (去看投影片,我也不太懂)
* zero-shot learning
* 不要把圖片直接歸為某一類,而是找出他有那些 attribute 
* 建好一個 database,裡面包括各種動物
* train 的時候只拿猩猩和狗,但是 test 的時候可以找出魚
* 當有不認識的圖片輸入時,透過 attribute 去找到這個動物,假如沒有,可以找接近的,可能就是他
* attribute 太多可以做 embedding
* self-taught learning, self-taught clustering
* 老師幾乎沒講
### Meta Learning
* Learn to learn
* 目標是找到一個 Function F,只要把測試資料丟進去,他就會找到一個 model,也就是平常 ML 我們要去手動設計還有自動找參數的那個 model
* 測試資料(task) 指的是,比如說
* task 1: speech recognition
* task 2: image recognition
* 目標是用一些 task 去找到 F,然後當今天有新的 task 進來時,可以自己設計出專屬於他的 model
* 比較
* life-long learning: 找出一個 model 可以解決所有 task
* meta learning: 找出一個 function,可以自動找出 model
* 設計時一樣要三步驟:
* define a set of Function F
* goodness of F
* pick the best F
* 在之前的 ML 中,我們要自己去設計 network structure, learning rate, init parameters 等等,現在希望 Meta Learning 可以自己找到
* 不過不同 Meta Learning 演算法可能找的是不同部分
* Meta Learning 一樣分成訓練跟測試,只是個別裡面又分成 train 和 test,為了避免搞混,有換名稱
* training tasks
* train(support set), test(query set)
* testing tasks
* train(support set), test(query set)
* support set 和 query set 都是一組資料
* N-ways K-shot classification: In each training and test tasks, there are N classes, each has K examples.
* MAML: 一個 Meta Learning 演算法,只專注於找 init parameters
### Life-long Learning
* 終身學習,你訓練的模型透過不斷調整,可以解多個不同的 task
* 不是一開始把所有 task 混在一起拿去訓練,而是訓練好一個 model 之後,有新的 task 進來,去調參數,然後可以把新的跟舊的問題都解決
* Knowledge Retetion but not intransigence
* 訓練了 task2 後忘記 task 1 的例子:

* 混在一起訓練會比較好,可是第一是運算上資料大,第二是舊資料的保存問題
* Multi-task training can be considered as the upper bound of LLL.
* Curriculum Learning
* 從上面的例子可以知道,訓練的順序會影響結果 (先訓練 task 2 再訓練 task 1,會得到 90%(task 1) 97% (task 2)的準確率)
* 因此學習的順序很重要
* 如果每個 task 都各自訓練一個 model 呢?
* 會導致太多 model 需要儲存
* 沒辦法讓知識在 task 間傳遞 (比如學會線代後學 Machine Learning)
* Elastic Weight Consolidation (EWC)
* 某些重要的參數不要去動,而是去動那些不影響前面 task 的參數
* loss function  
* 先訓練 task 1 再訓練 task 2 會發現動 theta 1 比較好
* 每個參數的重要性下面會講怎麼計算 (這張的話看圖看的出來)
* 愈深的地方 loss 愈大,所以 theta* 在 task 1, task 2 都要讓 loss 小

* Generating Data
* 既然 multi-task 一起訓練結果會比較好,因此想辦法產生一個 generative model,可以產生過去各個 task 的資料 (training data)
* 當有新的 task 進來時,就拿新 task 的資料去跟generative model 產生出來的資料一起訓練
* 修改 generative model,讓他也可以產生新的 task 的資料
* 不同 task 要的架構不同怎麼辦,老師有給 reference,但沒有講
* Knowledge Transfer
* Life-long Learning 跟 Transfer Learning 有點像,都是可以把過去訓練好的參數,去做 fine-tune,但是 Transfer Learning 不在意過去的 task 還好不好辨識
* Evaluation of LLL model
* 可以從一些面向去評估,比如說:
* Accuracy: 最終的模型對各個 task 的 accuracy 的平均
* Backward Transfer: 全部訓練完後回去測和某個 task 剛訓練完時,差了多少
* Forward Transfer: 某個 task 正要訓練前的準確率和大家都還沒訓練時這個 task 的準確率差多少 (評估看看訓練別人可不可以幫助這個 task 去做判斷 (知識轉移))
* Model Expansion
* 如果 model 已經學不了新的 task 了,可能是因為 neuron 數不夠
* 老師有提出幾個方法,不過 LLL 是一個蠻新的主題,所以講得不多
* 有的方法是增加 neuron 數,但是盡量不影響本來的 accuracy,有的是在大 model 裡面針對每個 task 各自建立 model,但是會做知識轉移
### Reinforcement Learning
* 有人說 AI = RL + DL = Deep Reinforcement Learning
* 在 80 年代時 RL 就蠻完整的了,只是以前都是查表,現在變成 NN 作為 actor (看下面說明)
* 但查表不可能包括所有狀況,所以用 NN 的一個好處就是可以處理未知狀況
* AlphaGo is supervised learning + reinforcement learning
* 透過 action 得到一個 reward,並從這個 reward 得知剛剛的 action 做得好不好,進而去修改這個 actor/policy
* Reinforcement Learning 就是在 learn 這個 actor,如果這個 actor 是 neural network 架構,那這就是 Deep Reinforcement Learning
* 比如訓練機器玩遊戲,輸入就是畫面 pixel,輸出是動作,reward 是贏或輸
* 但是你做某一個動作不見得會馬上得到 reward,或是只是暫時得到不好的 reward,因此你需要去考慮長遠的結果
* 當不考慮長遠的情況下: 如果 A 動作會得到正向 reward,B 動作沒有 reward(=0),則 actor 永遠不會去做 B
* 又或是暫時做犧牲,長遠得到更好的結果
* Reinforcement Learning 分成兩大塊: Policy-based & Value-based
* Policy-based = Learning an actor
* Value-based = Learning a critic
* 上面兩個交集 = actor + critic
* AlphaGo = policy-based + value-based + model-based
* Policy-based: actor
* neural network as actor

* 用這種方式可以處理未知的狀態,而不是定好一個 table 決定甚麼情況要幹嘛
* goodness of actor: 玩多次之後平均的 reward 高低
* pick the best actor: 去對機率做 gradient (詳細去看投影片,這裡就不紀錄了)
* 在 policy gradient 的方法中,需要不斷的嘗試(收集資料),修改 model,再用新的 model 去不斷的嘗試,如此重複好幾次
* Value-based: critic
* 不會去決定 actor
* 給他一個 actor,他會去評估他的好壞
* 可以透過 critic 找到一個 actor: Q-learning
### Support Vector Machine(SVM) (不懂,有空再上網查)
* Hinge Loss + Kernel Method = Support Vector Machine
* (SVM 沒有聽得很懂,不過跟 logistic regression 的差別應該是在於 loss function 不同而已)
* logistic regression 是用 cross entropy
* SVM 是用 hinge loss
### Generative Adversarial Network (GAN)
* basic idea of GAN
* 期望透過輸入一個 vector,可以產生出你要的圖片、文字 (看你這個 GAN 的目的是產生甚麼)
* 不過更希望的是輸入一個圖片、句子(其實也是 vector),產生出你要的目標
* GAN 是透過不斷調整、訓練 generator 和 discriminator 兩個部份去訓練出一個好的 GAN
* generator 做的事是把輸入 vector,產生出一個圖片、文字等等 (其實就是一個高維)
* discriminator 做的事是把圖片(高維),輸出一個 scalar (分數)
* 評分這張圖片真不真實
* 概念上像是這樣: generator 和 discriminator 各自進化,來對抗對方 
* 演算法:
* step 0: 隨機產生 generator G 和 discriminator D
* step 1: 固定 G,訓練 D
* 訓練方法為輸入隨機 input,利用 G 產生出圖片 (一開始產生得圖片很醜,因為還沒訓練 G)
* 此時要去調整 D,讓產生出來的圖片的輸出值接近 0,而真實的圖片(訓練資料)的輸出值接近 0
* 等同於 binary classifier
* step 2: 固定 D,訓練 G
* 調整 G,讓你不論輸入甚麼 vector,都可以讓 D 輸出的結果接近 1 (也就是騙 D,讓他以為這是真實圖片)
* 不斷重複 step 1, 2,讓最後 generator 產生出來的圖片很像真的
* 雖然說是隨機產生 input,但事實做上可能是讓他從常態分布(甚麼分布不太重要)產生出來
* 更多說明可以看下面的 theory behind GAN
*  
* generator + discriminator 合起來其實就是一個大 network = GAN
* GAN 的使用上就是抽出中間 hidden layer 的結果
* 
* GAN as structured learning
* structured learning 的意思是產生出的是 sequence, matrix, graph 等等,不是像 regression 或 classification 產生出純量或 class
* can generator learn by itself? (單純用 generator 就做到圖片生成)
* 可以只用 generator 產生圖片,類似 auto-encoder 中的 decoder,只是會有一些問題
* 比如只用 generator 運練出來的結果會認為 1 pixel error 比較好,但其實對我們人來說 6 pixel errors 的那兩張比較好,筆試筆畫增長而已 
* 也就是說 generator 沒辦法去考慮 component 之間的關係 (中間不能空格之類的),除非你要加深這個 NN,讓他更 deep,考慮更多
* can discriminator generate? (單純用 discriminator 就做到圖片生成)
* 可以只用 discriminator 產生圖片,但是一樣會有一些問題
* 先假設你有一個訓練好的 D,你只要給它各種圖片,看哪些結果是好的,就是你要的圖片
* 但是窮舉圖片很難,所以會去找一個式子讓你知道怎樣的圖片輸入進去之後結果是好的
* 但是這個式子很難找,可能要做一堆假設,但這就有了限制
* 再來的問題是,你要怎麼訓練這個 D,因為你只有好的圖片,不好的圖片從哪裡來?
* 你可以用下面的演算法去產生出不好的圖片,但是因為是用我們假設的受限制的式子產生出的圖片來當做不好的圖片,因此不好的圖片就受到了限制
* 演算法:
* 隨機產生圖片 (不好的圖片)
* 訓練這個 D,讓它可以分辨好跟不好的圖片
* 再利用這個 D 根據式子產生出它認為好的圖片
* 再利用這些圖片當成不好的圖片,拿去重新訓練 D
* 如此循環下去
* generator vs. discriminator
* generator
* pros: 容易產生圖片 (就跟平常我們做訓練一樣,算 loss function 去做修正)
* cons: 產生的圖片無法考慮到 component 之間的關係
* discriminator
* pros: 能考慮 component 之間的關係
* cons: 難以產生不好的圖片來訓練
* generator + discriminator = GAN
* 因為 discriminator 的好式子很難找,因此這時就可以用 generator 來產生各種圖片,也就是用 generator 來解這個式子
* benefit of GAN
* 從 discriminator 的觀點來看: 利用 generator 來產生 negative samples
* 從 generator 的觀點來看: 利用 discriminator 去考慮 component 之間的關係
* theory behind GAN
* 實際上真實圖片會有一個高維空間上的分布,但它只占高維空間的一個小區域,你很難找到這個區域
* 你的目標是 train 一個 generator,它產生的圖片可以落在這個區域中
* 前面的 distribution 是甚麼不太重要,因為 G 會把它扭成你要的形狀
* PG, Pdata 是我們從 generator 和 database sample 一些出來的分布
* 
* 在每次 train D 和 G 的過程中,D 大約 update 5 次左右,G 只要 1 次
* 
* conditional generation GAN
* text to image: 輸入一段文字,產生一個圖片
* 不同於上面的 GAN 的 D 只要去辨識圖片是不是 realistic,現在還要去看是否符合這段文字
* 所以現在的 D 變成需要兩個輸入: 圖片 + 文字 (object + condition),只有 sample input pair 才是 1,其他都是 0
* 傳統的 supervised learning 會有問題: 把一段文字透過 NN 產生的圖片,會去盡量跟某一張,或是某一群圖片像,結果會變成只像其中一張,或是某一群的平均(會很奇怪),而且會很模糊(因為是平均)
* 用 GAN 的話會產生各式各樣的圖片
* (應該是因為除了輸入文字外,還會從某個 distribution "隨機"挑一個 vector 去做圖片產生)
* 然後只要看起來 realistic 且跟文字有 match 就可以
* 所以變化性高且看起來合理
* conditional GAN 的演算法去看[影片](https://www.youtube.com/watch?v=LpyL4nZSuqU&list=PLJV_el3uVTsMq6JEFPW35BCiOQTsoqwNw&index=2) (投影片沒有)
* 也可以做 image to image, speech enhancement, video generation 等等
* image to image (其中 cloese 那張是用一般的 NN 訓練出來的結果)(z 是 noise (應該是一個分布)) 
* video generation: 給多個 frame,透過 G 預測下一個 frame,再把產生出來的 frame 拿去 D 判斷真不真實,同時也把這個 frame 跟前幾個 frame 拿去看是否 match (避免產生一個完全不相關的 frame)
* 此外,如果 discriminator 看整張圖片的話,參數會太多,所以有一種技術叫 patch GAN,就是一次只看一小塊
* 我覺得 GAN 相較一般 supervised learning 厲害的點在於,它不是只是去算跟真實質是否接近,而是去思考,看起來真不真實、是否跟你輸入的條件有關 (不要只是各種真實值的平均,那樣會很奇怪)
* 為了達到判斷真不真實、跟條件是否有關,在上面的方法中需要先有訓練資料,如同上圖右上角那兩個圖片就是訓練資料 (pair)
* unsupervised conditional GAN
* 想要把 A 照片轉成 B 照片的風格,但你沒有真實的轉換範例,你只有兩堆照片
* 方法 1: direct transformation
* 要避免輸入 A 照片,透過 generator 直接產生 B 照片,所以需要去對它做限制 
* cycle GAN: 要讓產生出來的圖片可以轉換回原圖片
* 方法 2: projection to common space

* 轉換成 attribute,這樣可以產生的圖片變化比較大

* 訓練 encoder 和 decoder,上下兩個模型各自訓練
* 避免上下兩種產生的 attribute 不相關
* 這樣會導致雖然輸出是卡通風格,但跟輸入沒關
* 比如說一個第一維代表的是性別,一個代表的是頭髮長度
* 一個解決辦法是讓 encoder 的最後幾層共用,以及 decoder 的前幾層共用
* discriminator 可以放在右邊最後面,或是接在中間 attribute 的結果
* cycle GAN 
* 其他還有講到 fGAN, LSGAN, WGAN, EBGAN 等各種解決 GAN 的一些問題的方法
* InfoGAN: 希望輸入的 vector 可以代表某些意義,比如手寫字的字體寬窄
* VAE-GAN: VAE + GAN: 利用 VAE(auto-encoder) 的 minimize reconstruction error 的優點以及 GAN 的 discriminator 的真實的優點
* BiGAN, Triple GAN 等等
* Feature Extration: 把比如聲音訊號中的語意跟語者的資訊分開來,各有各的用途 (不太懂 Feature Extraction 跟 GAN 有甚麼關係)(跟 domain-adversarial training 有關)
* intelligent photo editing
* 希望可以從圖片反推出他的 vector
* method 1: 找出各種 vector 產生的圖片跟原圖最像
* method 2: 在 generator 前面 learn 一個 encoder (可以用 discriminator 作為初始值) 
* method 3: 用 method 2 的結果作為 method 1 初始值
* 把短髮照片變長髮 (底下的方法應該是已知一個 generator,並且學出 encoder)
* 算出多張短髮照片的 vector 平均
* 算出多張長髮照片的 vector 平均
* 算出之間的向量差
* 把目標短髮照片轉成 vector,然後 + 向量差 = 得到新 vector,再放到 generator 轉成圖片
* 給照片某個條件後產生新圖片 (比如某個地方變紅色)
* 考慮三件事:
* 條件要符合
* 新圖跟原圖不能差太遠
* 圖片要真實
* 
* 上面兩個方法不同,我覺得差別在於
* 短髮變長髮可行是因為兩種照片很像 (而且是用同一個 generator)
* 但鞋子跟紅色一撇差很多,沒辦法用向量的方式轉過去,而且沒有一個 generator 可以產生鞋子又產生紅色一撇
* maximum likelihood = minimum cross-entropy
* GAN 其實可以做到的事情很多,很多應用都可以用 GAN 去做,而 GAN 還有一個好處,就是可以用 unsupervised 的方法去訓練
* 只要把輸入跟目標分為兩個不同 domain,拿去訓練就好
* 兩個 domain 不一定要有配對關係 (unsupervised)
* 產生的品質可能不會比 supervised 好,但是當你給他一點 labeled 的資料時 (semi-supervised),可能會做得比 supervised 更好
* 比如給他一堆文章跟一堆其他摘要,要他訓練去產生出摘要
* improving sequence generation by GAN
* conditional sequence generation: 用 chatbot 來作例子
* reinforcement learning: 由人類來為產生出來的句子評分,目標為訓練出一個評分高的 model,但會有一個問題就是需要很多人力來做這件事
* GAN: 由 discriminator 來評分
* 訓練的結果 GAN 會產生比較長且複雜的句子,RL 會產生比較短的句子(類似於產生圖片時非 GAN 會比 GAN 模糊一樣,因為是一個平均的結果),但沒有證據顯示 GAN 產生的句子更好
* unsupervised conditional sequence generation
* text style transfer (比如把負面句子變正面): 作法跟上面的 unsupervised conditional GAN 一樣
* unsupervised abstractive summarization (摘要總結): 可以是 unsupervised 
* unsupervised translation (翻譯)
* evaluation
* 如何去評估一個 GAN 的好壞,不要只是看 paper 貼幾個漂亮的圖就覺得他做得很好
* 可以從 likelihood 和 quality 去思考,但是 GAN 的 likelihood 很難算,或是 quality 很高但是變化性很低也不好
* 常見的方法是把你訓練出來的圖(或其他結果)拿去用別人 train 好的 model (比如 VGG)去評估,評估的方向有兩個:
* 可以清楚辨識出屬於哪一個 class
* sample 出來的結果,各種 class 分布要平均 (不要只產生某一種圖)
* 但是我們不希望 GAN 只是產生出 database 的複製品而已
* 很難用產生出的圖片跟 database 去做比對,只要圖片 shift 你就無法 pixel-wise 比對了
* 這是目前尚待解決的問題
* GAN 的結果很好,可能只是 copy databse 而已
* flow-based generative model (這我沒有看得很懂)
### Ensemble
* bagging 是用在強的 model 上,避免 overfitting,而 boosting 是用在弱的 model 上,提升效能
* bagging
* sample 出 N 個 dataset,每個 dataset 有 N' 比 data,接著訓練出 N 個 model
* testing data 放進這幾個 model,把算出的結果做平均或是投票 (voting)
* 訓練出來的結果 bias 小、variance 小
* 當你的 model 複雜、容易 overfitting 時,適合用 bagging 解決
* decision tree 很容易 overfitting,而 random forest 就是 bagging 版的 decision tree
* 單純的分出 N 個 model 不夠
* 隨機選擇 features/questions 要不要去做分支,這樣每棵 tree 都會長得不太一樣
* boosting
* 當你的 model 在測試資料上 error rate < 50%,則用 boosting 之後測試資料可以很快就把 error rate 降為 0%
* 概念上就是先訓練一個 classifier,然後再訓練其他 classifier 來幫助他,所以不像 bagging 的 model 是分開訓練的,boosting 有順序性
* AdaBoost: 會先訓練一個 f1,然後把本來的測資的 weight 調整,讓他會使 f1 的 error=0.5,再去訓練 f2 處理這筆資料,反覆下去後會得到多個 f
* 訓練完的多個 f 要怎麼合作?
* 可以用平均,但不合理
* 可以給各自一個 weight,取決於錯誤率
* 
* 測資和 f 的 weight 都和 error rate 有關
* 多個 classifier 合起來可以很快把 error rate 降為 0
* training error 已經變成 0 之後,繼續訓練 testing error 可以持續下降
* gradient boosting
* stacking
* 多個 model 做 voting 時,有人做得好有人做不好,所以要給他們權重,可以看做把他們的結果乘上一個 weight 經過一個 final classifier (neuron)
## 其他知識
### Object Detection: R-CNN, Fast-RCNN, Faster R-CNN
[參考來源](https://medium.com/@ccshenyltw/object-detection-r-cnn-fast-rcnn-faster-rcnn-mask-rcnn-retinanet-to-be-continued-71b67640445)
* R-CNN (Region Convolution Neural Network)
* 
* 
* 利用 selective search 找出 2000~3000 個 region proposal
* selective search: 會先對圖像做 segmentation,再用 hierarchical grouping algorithm 合併,演算法可以去看參考來源
* 
* 調整成固定大小後,每個拿進去 CNN 做判斷
* 後面的 CNN 應該就跟一般我們使用的 CNN 是一樣的
* 最後還需要對 bounding box 做回歸 (修正位置、大小)
* R-CNN 很花時間,因為要把每個 region proposal 拿進去判斷
* Fast R-CNN
* 對 R-CNN 的缺點去做改進
* CNN 只要算一次,把特徵提取後,讓 selective search 找出來的 region proposal 去做使用
* 其他不同去看文章
* 
* Faster R-CNN
* 改進 region 選取方式,改用 RPN
* 引進了 anchor box
* 對同一點為中心去做不同的區域選取
* 然後做 bounding box regression
* 然後選取符合標準的 anchor (不會每個都選)
* 
### VGG16? ResNet50? and others?
[參考 1: ithelp](https://ithelp.ithome.com.tw/articles/10192162), [參考 2: VGG16学习笔记](http://deanhan.com/2018/07/26/vgg16/)
* 這些都是一些知名的 CNN model 架構,參加比賽可能有得獎
* 可以在 keras 等程式中直接 call 它們
```
model = VGG16(weights='imagenet', include_top=True)
```
* call 它們的意思是使用它們定好的架構,除此之外,你還可以選擇它們幫你 traing 好的 weight
* 比如說 `weights='imagenet'` 就可以用 VGG 訓練好的 ImageNet 100 萬張圖片,共 1000 種類別
* `include_top=True` 意思是要不要最後的全連接層
* 你可以完全不用 call 這些 function,自己定好每一層之間怎麼連結、需要幾個 neuron 就可以
* VGG 又分成很多種架構
* D 是 VGG16, E 是 VGG19 (最有名)
* 