# Keras [ Python ]
參考資料:
1. [深度學習-Keras中的Embedding層的理解與使用](http://frankchen.xyz/2017/12/18/How-to-Use-Word-Embedding-Layers-for-Deep-Learning-with-Keras/)
2. [理解Keras参数 input_shape、input_dim和input_length](https://blog.csdn.net/pmj110119/article/details/94739765)
3. [使用Keras、Python、Theano和TensorFlow開發深度學習模型](https://cnbeining.github.io/deep-learning-with-python-cn/)
4. [神經網路中Epoch、Iteration、Batchsize相關理解和說明](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/557816/)
5. [Keras 文檔](https://keras.io/zh/models/model/) (https://keras.io/api/)
6. [Keras 模型、函數及參數使用說明](https://ithelp.ithome.com.tw/articles/10191725)
7. [機器學習自學筆記09: Keras2.0](https://wenwu53.medium.com/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E8%87%AA%E5%AD%B8%E7%AD%86%E8%A8%9809-keras2-0-3e5c9ac1658f)
8. [通過loss曲線診斷神經網路模型](https://www.twblogs.net/a/5e50ddf3bd9eee2117bfe333)
<br>
## Keras NN
### Sequential Model
* keras 提供了兩種 model
1. Functional API:支援多個輸入、多個輸出
2. Sequential Model (順序式模型):就是一種簡單的模型,單一輸入、單一輸出,按順序一層(Dense)一層的由上往下執行。
<br>
### Dense
Dense 就是神經網路最常見的全連接層,output = activation( dot(input, kernel) + bias )
* input_shape 輸入維度
神經網路的第一層要給 input_shape,shape包含維度和長度或是用 input_dim 和 input_length 表示,之後的 Dense input_shape 都會接著前一層的 output_shape,不需要另外設置
```
model.add(Dense(units=32, input_shape(16,)))
model.add(Dense(units=32, input_dim = 3800, input_length =380 )
```
* units 輸出維度
* activation 激活函數
<br>
### Dropout
避免過度擬合,每次訓練都會按照比例拿走一部份神經元,只會在訓練的時候執行
### Compile
compile 編譯,選擇損失函數 loss、優化方法 optimizer 及成效衡量方式 metrics
* loss: 參考 [losses](https://keras.io/api/losses/)
* optimizer : 參考 [optimizers](https://keras.io/api/optimizers/)
* metrics: 參考[metrics](https://keras.io/api/metrics/)
### Summary
* 顯示整個神經網路的架構
```python=
from keras.models import Sequential
from keras.layers.core import Dense,Dropout
# build
model = Sequential()
model.add(Dense(units = 32, input_dim = 3800, input_length =380, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(32, activation='relu')
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
model.summary()
# compile
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
```
train_history = model.fit(X_train, Y_train)
score = model.evaluate(X_test, Y_test, verbose=1)
<br>
### Fit
訓練模型
* epochs 總共要訓練幾輪
* batch_size 每次要訓練的量
* iteration : iteration = 樣本數量 / batch_size
* verbose 是顯示模式,0 = 安静模式, 1 = 進度條, 2 = 每輪一行
* validation_split 介於 0 ~ 1,要分多少比例到 validation
* fit 會回傳一個 train_history
train_history.history 可以看到每個 epoch 的 training accuracy, training loss, validation accuracy, validation loss
```python=
train_history = fit(X_train,Y_train,epochs=10,batch_size=100,verbose=2,validation_split=0.2)
```
### Train History
* 把 training_history 的 training loss 和 validation loss畫出來,可以簡單判斷模型是否有 underfitting 或是 overfitting的問題
```python=
def plot(train_history,train,validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()
plot(train_history, 'accuracy', 'val_accuracy')
plot(train_history, 'loss', 'val_loss')
```
#### Underfit
* training loss下降的非常平緩以致於好像都沒有下降,這說明模型根本沒有從訓練集學到東西

* 訓練結束時候training loss還在繼續下降,這說明還有學習空間,模型還沒來得及學就結束了

#### Overfit
* training loss一直在不斷地下降,而validation loss在某個點開始不再下降反而開始上升了,我們應該在這個拐點處停止訓練

#### Goodfit
* training loss和validation loss都已經收斂並且之間相差很小很小幾乎沒有肉眼的差距,而通常traing loss會更小,他們之間的gap叫做generalization gap。

<br>
### Evaluate
* evaluate 會回傳一個 score ,紀錄誤差和 testing accuracy
```
score = evaluate(X_test, Y_test, verbose=1)
print('testing loss : ', self.score[0])
print('testing accuracy : ', self.score[1])
```
<br>
## Keras Embedding
* Keras提供了一個嵌入層,適用於文本數據的神經網路,輸入的 input 為整數編碼,每個字都只能用一個唯一的整數表示,這個步驟可以使用 Keras 提供的 Tokenizer API 執行
* Keras Embedding 可以單獨使用來學習一個單詞嵌入,並保存在另一個模型中使用;或者作為深度學習模型的一部份,嵌入與模型本身一起學習;也可以把 pretrain 的字典嵌入模型
### Keras Tokenizer
* Tokenizer 可以建立字典,把文字轉換為序列或向量
```python=
from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
# 先建立一個 Tokenizer,預設3800個字
token = Tokenizer(num_words = 3800)
# 根據 texts 更新字典
token.fit_on_texts(train.text)
# token.word_index
# texts_to_sequences文本轉換
x_train_seq = token.texts_to_sequences(train.text)
# 統一資料長度:Padding截長補短
x_train = sequence.pad_sequences(x_train_seq, maxlen=380)
```
<br>
* 嵌入層被定義為神經網路的第一層 hidden layer ,必须指定3個参數:input_dim (總詞彙數量)、output_dim (每個詞會被轉換成幾個維度的向量)、input_length (輸入詞彙的長度)
* 嵌入層會隨機初始化權重,嵌入訓練集中的所有詞彙並學習,如果將模型保存到文件中,嵌入層的權重也會一起被保存
* 如果要接 Dense 層在 Embedding 層後面,要注意如果 Embedding層不是一維向量,必須先使 Flatten 將 Embedding 層轉為一維向量
```python=
model = Sequential()
model.add(Embedding(vocab_size, 8, input_length=max_length))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
model.summary()
```
###### tags: `Python`