###### tags: `選修`
# 人工智慧導論
+ 部份範例來源
- [Python實現人工智慧](https://ctld.video.nccu.edu.tw/km/1172)
- [成為 Python 數據分析達人的第一課](https://ctld.video.nccu.edu.tw/km/1399)
- [2021 北一女 Python 人工智慧工作坊](https://www.youtube.com/playlist?list=PLpltJwWB6egIKy68TSew5cbKamQdjccEE)
- [教育部中小學人工智慧教育教學示範例系列-和AI做朋友,從0開始學AI](https://market.cloud.edu.tw/list/ai.jsp)
- [Coursera 吴恩达机器学习 课后作业题](https://blog.csdn.net/m0_37867091/category_9817315.html)
+ 自學參考網站
- [深度學習 Deep Learning:中文學習資源整理](https://jerrynest.io/deep-learning-resource/)
- [LeeMeng - 由淺入深的深度學習資源整理](https://leemeng.tw/deep-learning-resources.html)
- [國立聯合大學資訊管理學系 機器學習課程](http://debussy.im.nuu.edu.tw/sjchen/ML_final.html)
- [機器學習首部曲](https://www.youtube.com/playlist?list=PLy7MS-q4l3xDYoR8MACYA3YyidUbEiz6j)、[二部曲](https://www.youtube.com/playlist?list=PLy7MS-q4l3xC1UbPAhuIRrStZuKV-xaPR)
- [以100張圖理解 Neural Network -- 觀念與實踐](https://ithelp.ithome.com.tw/users/20001976/ironman/1395)
- [有趣的機器器學習系列(莫煩Python)](https://mofanpy.com/tutorials/machine-learning/ML-intro/)
- [CS583: Deep Learning](https://github.com/wangshusen/DeepLearning)
- [深度学习 (DS-GA 1008 · 2020 春季 · 纽约大学数据科学中心)](https://atcold.github.io/pytorch-Deep-Learning/zh/)
- 李宏毅教授 ML ([2021](https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.php)、[YouTube](https://www.youtube.com/playlist?list=PLJV_el3uVTsMhtt7_Y6sgTHGHp1Vb2P2J))[(2022)](https://speech.ee.ntu.edu.tw/~hylee/ml/2022-spring.php)
- [Machine Learning Crash Course | Google Developers](https://developers.google.com/machine-learning/crash-course)
+ 評量方式
- 上課練習 50%
- 專案 30%(10%+10%+10%)
- 筆試 20%
+ 修課建議目標
- 低:真實了解人工智慧。
- 中:對申請入學有幫助(修課紀錄、學習歷程自述、面試)。
- 高:能產出課程學習成果。
::: info
專案一:[Kaggle競賽 - 鐵達尼號生存預測(Titanic - Machine Learning from Disaster)](https://www.kaggle.com/c/titanic)
+ [Kaggle](https://www.kaggle.com/)
+ 分數計算:Score*100
+ 作業格式
1. 最高分數截圖。
2. 增加處理說明(需列出參考網站、分數截圖和程式碼)(每項加4分,不完整不予計分)。
3. 完整程式碼(從colab裏複製貼上,不要貼截圖)。
+ 分數提昇參考:[(1)](http://ielab.ie.nthu.edu.tw/108_IIE_project/2/108IIE_proj2_4_PPT.pdf)、[(2)](https://yulongtsai.medium.com/https-medium-com-yulongtsai-titanic-top3-8e64741cc11f)、[(3)](https://hackmd.io/@f820920/BJH6xeihu)、[(4)](https://hackmd.io/@Go3PyC86QhypSl7kh5nA2Q/Hk4nXFYkK#%E7%89%B9%E5%BE%B5%E5%B7%A5%E7%A8%8B)
- 有做特徵工程(Feature Engineering):填補遺漏值、調整數據型態範圍、創造有利分析新特徵...,分數才會更高。
- 如果想要增加的特徵中有遺漏值,如 Age、Fare…,不會寫程式處理,可以直接修改train.csv、test.csv,填入適當的數值。
+ 簡略參考架構如下(不做資料前處理,只看 Pclass 和 Sex 兩個特徵)。
:::
``` javascript=
import numpy as np
import pandas as pd
from sklearn import tree
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
# 讀入檔案
train=pd.read_csv('train.csv')
test=pd.read_csv('test.csv')
# 將文字轉成數字
train['Sex'],_=pd.factorize(train['Sex'])
test['Sex'],_=pd.factorize(test['Sex'])
# 只看 Pclass 和 Sex 兩個特徵
x_train=train[['Pclass','Sex']]
y_train=train[['Survived']]
x_test=test[['Pclass','Sex']]
# 以「KNN(0.76)」或「決策樹」或「SVM」或「DNN」預測
~
~
~
# 產生匯出檔案
submission_df=pd.DataFrame({
'PassengerId':test['PassengerId'],
'Survived':y_test_predict
})
submission_df.to_csv('submission.csv', index=False)
```
::: info
專案二:[Kaggle競賽 - Digit Recognizer](https://www.kaggle.com/c/digit-recognizer)
+ 分數計算
1. DNN ((Score-0.98)/0.015)*15+80
2. CNN ((Score-0.99)/0.015)*15+80
3. Score 0.95 以下者皆為 50 分
+ 作業格式
1. 分數截圖。
2. 增加處理說明(需列出參考網站、分數截圖和程式碼)(每項加4分,不完整不予計分)。
3. 完整程式碼(從colab裏複製貼上,不要貼截圖)。
+ 分數提昇參考:[(1)](https://www.kaggle.com/code/cdeotte/25-million-images-0-99757-mnist/notebook)、[(2)](https://www.kaggle.com/code/loveunk/kaggle-digit-recognizer-keras-cnn-100-accuracy/notebook)、[(3)](https://www.kaggle.com/competitions/digit-recognizer/discussion/61480)、[(4)](https://www.kaggle.com/code/jedrzejdudzicz/mnist-dataset-100-accuracy/notebook)、[(5)](https://www.kaggle.com/code/barindersingh/digit-recognizer-with-100-accuracy-with-keras)
+ 避免 Overfitting
- BatchNormalization [(1)](https://medium.com/ching-i/batch-normalization-%E4%BB%8B%E7%B4%B9-135a24928f12)、[(2)](https://www.youtube.com/watch?v=BABPWOkSbLE)
``` python
# 需匯入相對的模組
model.add(BatchNormalization())
```
- Dropout
``` python
# 需匯入相對的模組
model.add(Dropout(0.3))
```
- EarlyStopping [(1)](https://ithelp.ithome.com.tw/m/articles/10361486)、[(2)](https://blog.csdn.net/yangwohenmai1/article/details/123274494)
``` python
# 需匯入相對的模組
early = EarlyStopping(monitor="val_accuracy", min_delta=0, patience=20, verbose=1, mode="max")
history = model.fit(x_train, y_train, batch_size=100, epochs=300, validation_split=0.2, callbacks=[early])
```
+ 簡略參考架構如下
- DNN 的部分請參考 EX_08_6 的程式碼。
- CNN 的部分請參考 EX_10_2 的程式碼。
+ 訓練、測試資料可上傳至 Colab 或 Google 雲端硬碟。
- 上傳至Colab:Colab 左側 -> 檔案 ->上傳至工作階段儲存空間。
- 上傳至雲端硬碟:Colab 左側 -> 檔案 -> 掛接雲端硬碟。(登入Google帳號後,將授權金鑰貼過來)
檔案路徑:'drive/MyDrive/檔案名'
:::
``` javascript=
import numpy as np
import pandas as pd
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.optimizers import SGD, Adam
# 讀入檔案
# 先將檔案上傳至 Colab
train=pd.read_csv('train.csv')
test=pd.read_csv('test.csv')
# 先將檔案上傳至自己的雲端硬碟
# train=pd.read_csv('drive/MyDrive/train.csv')
# test=~
# 第1欄(label)為答案
y_train = train['label']
# 删除「label」列
x_train = train.drop(labels=['label'], axis=1)
# 輸入格式整理
# 如果用標準神經網路,要 reshape 成 784*1 的矩陣
x_train = x_train.values.reshape(-1, 784, 1)
x_test = test.values.reshape(-1, 784, 1)
# 如果用CNN,要 reshape 成 28*28*1 的矩陣
# x_train = x_train.values.reshape(-1, 28, 28, 1)
# x_test = test.values.reshape(-1, 28, 28, 1)
# nomarlization
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
# 將答案轉換為 One-hot encoding
y_train = to_categorical(y_train, num_classes=10)
# 打造標準(EX_08_6 程式碼區塊2 5-17行) 或 CNN 神經網路(EX_10_2 程式碼區塊2 7-26行),編譯,訓練
# 如果要用 EX_08_7 神經網路為 Sequential 的參數的寫法,因為輸入不是圖檔,已經是784*1的矩陣,所以不用加 flatten 層,且第一個 Dense 層要有 input_shape=(784,)
~
# 預測結果(EX_08_6 程式碼區塊2 28行)
~
# 產生匯出檔案
submission_df = pd.DataFrame({
'ImageId': list(range(1,len(y_test_predict)+1)),
'Label': y_test_predict
})
submission_df.to_csv('submission.csv', index=False)
```
::: info
專案三:[Kaggle競賽 - Dogs vs. Cats Redux: Kernels Edition](https://www.kaggle.com/competitions/dogs-vs-cats-redux-kernels-edition/)
+ 分數計算:100-Score*20
+ 作業格式
1. 分數截圖。
2. 增加處理說明(需列出參考網站、分數截圖和程式碼)(每項加4分,不完整不予計分)。
有利用 ImageDataGenerator 進行數據增強 + 20分。
3. 完整程式碼(從 Kaggle 裏複製貼上,不要貼截圖)。
+ 簡略參考架構如下:CNN 的部分請參考 EX_10_2 的程式碼。
+ 因 Colab RAM(13GB)不足,本專案請在 Kaggle Notebook(30GB,還是吃緊) 或其它資源上實作,或把圖片格式壓小一點。
:::
``` javascript=
# 解壓縮訓練圖檔
!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip -d /kaggle/working/
```
``` javascript=
# 解壓縮測試圖檔
!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip -d /kaggle/working/
```
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
import os
from tqdm import tqdm
from tensorflow.keras.preprocessing import image
from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D
# 1. 訓練資料的檔名和標籤
train_file_lists = os.listdir('/kaggle/working/train') # 所有訓練集的檔案名稱
test_file_lists = os.listdir('/kaggle/working/test')
labels = np.array([1 if 'dog' in file else 0 for file in train_file_lists])
# 2. 讀取圖片並轉換為 numpy array
def load_images(dir, file_lists):
images = []
for file in tqdm(file_lists): # tqdm 有進度條
img_path = os.path.join(dir, file)
img = image.load_img(img_path, target_size=(140,140))
img_array = image.img_to_array(img) / 255.0 # 正規化到 [0,1]
images.append(img_array)
return np.array(images)
# 加載所有訓練及測試圖片
train_images = load_images('/kaggle/working/train',train_file_lists)
test_images = load_images('/kaggle/working/test',test_file_lists)
# 3. 將訓練資料分為訓練集和驗證集
x_train, x_val, y_train, y_val = train_test_split(train_images, labels, test_size=0.2, random_state=50)
```
``` javascript=
# 4. 打造 CNN 神經網路(EX_10_2 程式碼區塊2 7-26行),編譯,訓練
~
# 二分類問題,輸出層一個神經元即可,激發函數用 sigmoid
model.add(Dense(units=1, activation='sigmoid'))
# 二分類問題,損失函數改用 'binary_crossentropy' 是否會比較好?categorical_crossentropy 預期輸出是多分類 one-hot 編碼形式,但在二分類問題中,輸出為一個純量(0 或 1),可能無法正確解釋這樣的輸出,導致損失值計算不合理或不穩定。。
model.compile(optimizer='adam', loss='~', metrics=['accuracy'])
# EX_10_2的寫法 history = model.fit(x_train, y_train, batch_size=64, epochs=10, validation_split=0.2) 每次訓練會隨機分配 20% 的資料作為驗證集,不需事先分配驗證集,方便快速檢查模型性能。
history = model.fit(x_train, y_train, batch_size=100, epochs=10, validation_data=(x_val, y_val)) # 驗證集已先分割好,確保每次訓練過程中的驗證集保持不變,較能準確比較模型。
```
``` javascript=
# 5. 對測試集進行預測,並產生匯出檔案
predictions = model.predict(test_images)
predictions = predictions.flatten() # 將預測結果展平為一維數組
submission_df = pd.DataFrame({
'id': [int(filename.split('.')[0]) for filename in test_file_lists],
'label': predictions
})
submission_df.to_csv('submission.csv', index=False)
```
::: info
專案四:[Kaggle競賽 - Bag of Words Meets Bags of Popcorn](https://www.kaggle.com/competitions/word2vec-nlp-tutorial)
+ 分數計算:Score*100
+ 作業格式
1. 分數截圖。
2. 增加處理說明(需列出參考網站、分數截圖和程式碼)(每項加4分,不完整不予計分)。
3. 完整程式碼(從 Kaggle 裏複製貼上,不要貼截圖)。
+ 分數提昇參考:[(1)](https://medium.com/kkproject/%E6%96%87%E5%AD%97%E6%8E%A2%E5%8B%98-%E9%9B%BB%E5%BD%B1%E8%A9%95%E8%AB%96%E6%83%85%E7%B7%92%E5%88%86%E6%9E%90keras%E5%AF%A6%E4%BD%9C-eef01316a76e)
+ 簡略參考架構如下:RNN 的部分請參考 EX_11_2 # 5. 建立 RNN model,編譯,訓練。
+ 本專案請在 Kaggle Notebook 上完成。
:::
``` javascript=
# 解壓縮訓練集
!unzip /kaggle/input/word2vec-nlp-tutorial/labeledTrainData.tsv.zip -d /kaggle/working/
```
``` javascript=
# 解壓縮測試集
!unzip /kaggle/input/word2vec-nlp-tutorial/testData.tsv.zip -d /kaggle/working/
```
``` javascript=
import pandas as pd
import numpy as np
import tensorflow as tf
import csv
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
# 1. 載入資料
train = pd.read_csv('/kaggle/working/labeledTrainData.tsv', delimiter='\t', quoting=3)
test = pd.read_csv('/kaggle/working/testData.tsv', delimiter='\t', quoting=3)
# 2. 資料預處理
train_texts = train['review'].values
train_labels = train['sentiment'].values
test_texts = test['review'].values
# 3. 文字向量化
max_vocab_size = 20000 # 詞彙表大小
max_sequence_length = 300 # 每個序列的最大長度
tokenizer = Tokenizer(num_words=max_vocab_size)
tokenizer.fit_on_texts(train_texts)
x_train = tokenizer.texts_to_sequences(train_texts)
x_test = tokenizer.texts_to_sequences(test_texts)
x_train = pad_sequences(x_train, maxlen=max_sequence_length)
x_test = pad_sequences(x_test, maxlen=max_sequence_length)
y_train = np.array(train_labels)
```
``` javascript=
# 4. 建立 LSTM 模型(EX_11_2 #5),編譯,訓練
embedding_dim = 128
~
```
``` javascript=
# 5. 對測試集進行預測,並產生匯出檔案
predictions = np.argmax(model.predict(x_test), axis=1) # 將概率轉為類別
submission_df = pd.DataFrame({
'id': test['id'],
'sentiment': predictions
})
submission = submission_df.to_csv('submission.csv', index=False, quoting=csv.QUOTE_NONE)
```
## 零、環境
+ [Google Colaboratory](https://colab.research.google.com/)
- [GPU 加速](https://www.youtube.com/watch?v=-P28LKWTzrI)
* Runtime / Change runtine type / Hardware accelerator / GPU
* 執行階段/變更執行階段類型/硬體加速器/GPU
- `ctrl + /`:多行註解
- `Tab、Shift+Tab`:增、減縮排
+ 相關套件
- [Scikit-learn](https://scikit-learn.org/stable/)
* 建立於 NumPy, SciPy 之上的 Python 機器學習套件,內建許多常見的機器學習演算法 。
* [Choosing the right estimator](https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html)
- [TensorFlow](https://www.tensorflow.org/)
- [Pandas](https://pandas.pydata.org/)
- [Matplotlib](https://matplotlib.org/)
- [openAI gym](https://gym.openai.com/)
+ 學習歷程檔案(修課記錄、課程學習成果)(Bonus)
- 最後一週上課結束前如果認證完成,學期總成績加分。
- [撰寫「課程學習成果」參考資源](https://hackmd.io/@cube/HkCv90e19)。
<br />
## 一、人工智慧(Artificial Intelligence,AI)
+ [人工智慧在臺灣:產業轉型的契機與挑戰|陳昇瑋研究員](https://www.youtube.com/watch?v=OddYM6aq-zM)
+ 關於AI的種種傳聞 & 機器學習的七個步驟 & 任務分類(PPT)
+ <font color="red">體驗</font>
- [自動駕駛車](https://vimeo.com/192179726)
- [超級實用!精選 15 款文本、繪圖、音樂、影音剪輯等領域的 AI 工具,賦予創作者前所未有的便利性 - 映CG 媒體 | InCG Media](https://www.incgmedia.com/spotlight/15-featured-ai-tools-introduction)
- [人類還剩幾集可以逃?ChatGPT + Midjourney + Clipchamp AI大軍聯合玩內容創作 (文稿/插圖/配樂/配音/字幕全包)
](https://www.youtube.com/watch?v=9T8Dn2cY_04&t=205s)
- [Leonardo.ai](https://leonardo.ai/)
- [PaintsChainer 线稿自动上色服务](https://paintschainer.preferred.tech/)
- [Vision AI 透過機器學習技術取得圖片的深入分析結果](https://cloud.google.com/vision/)([說明](https://ithelp.ithome.com.tw/articles/10214867))
<br />
![](https://i.imgur.com/SHtuGvu.png)
<br />
## 二、機器學習(Machine Learning)簡介
+ 從訓練資料中擷取出資料的特徵(features),建立判斷基準(模型、函數)對未來做預測。
+ [機器學習大補帖](https://ithelp.ithome.com.tw/articles/10265942)
### 1. 任務類型
+ 分類(classification)、迴歸(regression)、分群(clustering)
- 分類(classification):將未知的新訊息歸納進已知的資訊中。
- 分群(clustering):將特徵相似的資料歸類於同一組,事先並不知道會依那些特徵進行分組。
<a href="https://www.researchgate.net/figure/Examples-of-real-life-problems-in-the-context-of-supervised-and-unsupervised-learning_fig8_319093376"><img src="https://www.researchgate.net/profile/Sinan_Kaplan2/publication/319093376/figure/fig8/AS:526859928834054@1502624603775/Examples-of-real-life-problems-in-the-context-of-supervised-and-unsupervised-learning.png"/></a>
<br />
### 2. 不同的訓練方法
+ 監督式學習(Supervised)(分類、迴歸)
- 給予「有標籤」的資料,例如給機器各看1000張有標示貓和狗的照片,讓機器學會判斷照片中是貓還是狗。
+ 非監督式學習(Unsupervised)(分群)
- 給予「無標籤」的資料,讓機器自行找出資料規律。
+ 半監督式學習(Semi-supervised)
- 少部分資料有標籤,大部分資料沒有標籤,以資料分群來說先以有標籤的資料切出一條分界線,再利用剩下沒標籤資料的整體分布調整分界線。
+ 強化學習(Reinforcement)(分類)
- 使用未標記的資料,透過獎勵函數,讓機器知離正確答案越來越近還是遠。
<br />
## 三、機器學習(Machine Learning)演算法
### 1. [Linear regression(線性迴歸)](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)(PPT)
+ <font color=red>迴歸,監督式學習</font>
+ [線性迴歸(Linear Regression)](https://medium.com/@chih.sheng.huang821/%E7%B7%9A%E6%80%A7%E5%9B%9E%E6%AD%B8-linear-regression-3a271a7453e)
- [微積分到底在幹嘛?讓我們從微分開始](https://home.gamer.com.tw/creationDetail.php?sn=4946297)
- [微分公式參考](http://www.math.ncu.edu.tw/~yu/ecocal95/boards/lec12_c_95.pdf)
- $\displaystyle Loss(\hat\beta_0,\hat\beta_1)=\sum_{i=1}^{n}(y_i-\hat y_i)^2=\sum_{i=1}^{n}(y_i-(\hat\beta_0+\hat\beta_1 x_i))^2$
- 為了推估$\beta_0$,對 $Loss(\hat\beta_0,\hat\beta_1)$ 做 $\beta_0$ 偏微分等於 0
$\begin{align*}
& \displaystyle \frac{\partial oss(\hat\beta_0,\hat\beta_1)}{\partial \beta_0}=\frac{\partial \displaystyle \sum_{i=1}^{n}(y_i-\hat\beta_0-\hat\beta_1 x_i)^2} {\partial\beta_0}=0 \\
& \displaystyle \Rightarrow \sum_{i=1}^{n}2(y_i-\hat\beta_0-\hat\beta_1 x_i)(-1)=0 \\
& \displaystyle \Rightarrow -2\sum_{i=1}^{n}(y_i-\hat\beta_0-\hat\beta_1 x_i)=0 \\
& \displaystyle \Rightarrow \sum_{i=1}^{n}(y_i-\hat\beta_0-\hat\beta_1 x_i)=0 \\
& \displaystyle \Rightarrow n\hat\beta_0=\sum_{i=1}^{n}(y_i-\hat\beta_1 x_i) \\
& \displaystyle \Rightarrow \hat\beta_0=\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat\beta_1 x_i) \\
& \Rightarrow \hat\beta_0=\bar y-\hat\beta_1 \bar x
\end{align*}$
- 為了推估$\beta_1$,對 $Loss(\hat\beta_0,\hat\beta_1)$ 做 $\beta_1$ 偏微分等於 0
$\begin{align*}
& \displaystyle \frac{\partial Loss(\hat\beta_0,\hat\beta_1)}{\partial \beta_1}=\frac{\partial \displaystyle \sum_{i=1}^{n}(y_i-\hat\beta_0-\hat\beta_1 x_i)^2} {\partial\beta_1}=0 \ ,先將上式求得的\hat\beta_0代入 \\
& \displaystyle \Rightarrow \frac{\partial \displaystyle \sum_{i=1}^{n}(y_i-(\bar y-\hat\beta_1 \bar x)-\hat\beta_1 x_i)^2} {\partial\beta_1}=\frac{\partial \displaystyle \sum_{i=1}^{n}((y_i-\bar y)-\hat\beta_1 (x_i-\bar x))^2} {\partial\beta_1}=0 \\
& \displaystyle \Rightarrow \sum_{i=1}^{n}2((y_i-\bar y)-\hat\beta_1(x_i-\bar x))(-1)(xi-\bar x)=0 \\
& \displaystyle \Rightarrow \sum_{i=1}^{n}-2(x_i-\bar x)(y_i-\bar y)+2\hat\beta_1(x_i-\bar x)^2=0 \\
& \displaystyle \Rightarrow \hat\beta_1 \sum_{i=1}^{n}(x_i-\bar x)^2=\sum_{i=1}^{n}(x_i-\bar x)(y_i-\bar y) \\
& \displaystyle \Rightarrow \hat\beta_1 = \frac{ \displaystyle \sum_{i=1}^{n}(y_i-\bar y)(x_i-\bar x)}{ \displaystyle \sum_{i=1}^{n}(x_i-\bar x)^2}
\end{align*}$
+ [用人话讲明白线性回归 LinearRegression](https://zhuanlan.zhihu.com/p/72513104)
+ [用人话讲明白梯度下降 Gradient Descent(以求解多元线性回归参数为例)](https://zhuanlan.zhihu.com/p/137713040)
+ [資料視覺化](https://ithelp.ithome.com.tw/articles/10264416)
+ 應用:產品需求預測、保險費用預測、犯罪率預測…
:::info
EX_01_1:完成[線性迴歸學習單(5~7)](https://docs.google.com/spreadsheets/d/1EoCpDRgVxW-aULNg9ya9IaZZJU9M8zsa/edit?usp=sharing&ouid=118043800222804360069&rtpof=true&sd=true),練習以線性代數公式求參數。
:::
:::info
EX_01_2:呈上題,練習以程式求參數,看看答案是否看上題相同。
+ $y=\beta_0+\beta_1 x,y=6.8762+0.0401x$
:::
+ [簡明 Python Numpy 入門教學](https://blog.techbridge.cc/2020/08/24/numpy-zen-intro-tutorial/)
+ [Routines — NumPy v1.22 Manual](https://numpy.org/doc/stable/reference/routines.html)
``` javascript=
x=[1,2,3]
y=[4,5,6]
print('3*x:', 3*x)
print('x+y:', x+y)
print('x加總:', sum(x))
```
``` javascript=
import numpy as np
x=np.array([1,2,3])
y=np.array([4,5,6])
print('x+10:', x+10)
print('3*x:', 3*x)
print('x+y:', x+y)
print('x*y:', x*y)
print('x加總:', np.sum(x))
print('x平均:', np.average(x))
print('x的長度:', x.size)
```
+ [matplotlib.pyplot.scatter](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html?highlight=scatter#matplotlib.pyplot.scatter)
+ [matplotlib.pyplot.plot](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html?highlight=plot#matplotlib.pyplot.plot)
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
x=np.array([24.3, 19.5, 18.8, 20.1, 22.2, 29.8, 26.3, 28.3, 31.9, 26.9]) # 油價
y=np.array([7.9, 7.7, 7.6, 7.7, 7.7, 8.2, 7.8, 7.9, 8.1, 8.1]) # 民眾搭捷運平均里程
plt.scatter(x, y) # plt.scatter 產生散點圖
X=x-np.average(x)
Y=~
b1=np.sum(X*Y)/~
b0=~
print(b0,b1)
plt.plot(x, b0+b1*x, 'r') # 以 plt.plot 畫出函數 y=b0+b1*x
```
:::info
EX_01_3:呈上題,練習以 [Gradient Descent](https://ithelp.ithome.com.tw/articles/10266246) 求參數,看看答案是否看上題相同。
+ 先試試用梯度下降法逼近多項式函數的最小值。
![](https://i.imgur.com/YhdM5bH.png =200x)
+ 多元回歸公式 $\hat\beta=(X^TX)^{-1}X^TY$ 維度多時算反矩陣時間複雜度很大,也可能X沒有反矩陣,因此用梯度下降法找答案。
+ 以 MSE(均方誤差) 為損失函數
$\begin{align*}
\displaystyle L&=\frac{1}{n}\sum_{i=1}^{n}{(y_i-\hat y)^2}\\
\displaystyle &=\frac{1}{n}\sum_{i=1}^{n}(y_i-(\beta_0+\beta_1 x_i))^2\\
\displaystyle &=\frac{1}{n}\sum_{i=1}^{n}(y_i-\beta_0-\beta_1 x_i)^2
\end{align*}$
+ $\displaystyle \frac{\partial L}{\partial \beta_0}=-\frac{2}{n}\sum_{i=1}^{n}(y_i-\beta_0-\beta_1 x_i)$
+ $\displaystyle \frac{\partial L}{\partial \beta_1}=-\frac{2}{n}\sum_{i=1}^{n}(y_i-\beta_0-\beta_1 x_i)x_i$
+ $\displaystyle \beta_0=\beta_0-\eta*\frac{\partial L}{\partial \beta_0}$
+ $\displaystyle \beta_1=\beta_1-\eta*\frac{\partial L}{\partial \beta_1}$
+ $\eta$ (eta):學習率
:::
``` javascript=
# 先試試用梯度下降法逼近多項式函數的最小值
import numpy as np
import matplotlib.pyplot as plt
def f(x): # 定義多項式函數
return x**4-70*x**2-80*x+90
def f_prime(x): # 定義多項式函數的導函數
~
x0,lr=-10,0.0001 # 梯度下降的起點,學習率
nx=[] # 儲存梯度下降每一步的 x 座標
for i in range(100): # 執行梯度下降次數
nx.append(x0)
~ # 梯度下降
NX=np.array(nx) # 將 list 轉成 numpy array
# 畫出梯度下降的更新路徑
plt.figure(figsize=(10,5))
x=np.linspace(-10,10,100) # 取 x 坐標軸的數據點
plt.plot(x,f(x),'r') # 多項式函數
plt.plot(x,f_prime(x),'b') # 導函數
~ # 以scatter畫出梯度下降每一步的座標點
plt.xlabel('x')
plt.ylabel('y')
```
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
x=np.array([24.3, 19.5, 18.8, 20.1, 22.2, 29.8, 26.3, 28.3, 31.9, 26.9]) # 油價
y=np.array([7.9, 7.7, 7.6, 7.7, 7.7, 8.2, 7.8, 7.9, 8.1, 8.1]) # 民眾搭捷運平均里程
~ # 以 plt.scatter 產生散點圖
#1. 以 Gradient Descent 求參數
b0,b1,lr=5.0,5.0,0.001 # 初值隨機選取,試試b0,b1不同初值(例如500,500)是否可得到答案,如果不行,增加次數或調高lr看看?
for i in range(100000): # Gradient Descent 次數
b0=b0-lr*-2/x.size*np.sum(y-b0-b1*x)
b1=~
print(b0,b1)
~ # 以 plt.plot 畫出函數 y=b0+b1*x
```
``` javascript=
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print('a:\n', a)
print('a.shape:', a.shape)
x=np.array([1,2,3,4,5,6])
print('x:\n', x)
print('x.shape:', x.shape)
xx=x.reshape(6,1) # xx=x.reshape(3,2)
print('xx:\n', xx)
print('xx.shape:', xx.shape)
```
``` javascript=
#2. 用 SKlearn 線性迴歸模組做預測
XX=x.reshape(10,1) # 若 x 為[x1,x2,....,x50](1x50的陣列),但 SKlearn 需要[[x1],[x2],....,[x50]](50x1的陣列)
regModel = LinearRegression() # 初始化線性迴歸模組
regModel.fit(XX, y) # 讓線性迴歸模組學習,模組的變數名稱.fit(輸入資料,正確答案)
y_predict = regModel.predict(XX) # y_predict為線性迴歸模組預測的結果
plt.plot(x, y_predict, 'b' ,alpha=0.4)
```
:::info
(進階) EX_01_4:將上題的程式碼改以向量的方式完成(容易推廣至多元回歸)。
+ [參考網站](https://github.com/yaojenkuo/ml-newbies/blob/master/05-regression.ipynb)
+ 多元迴歸方程的一般形式為$y=\beta_0+\beta_1x_1+\beta_2x_2+...+\beta_dx_d$
可以簡寫為矩陣形式 $\textbf{Y}=\textbf{X}\mathbf{\beta}$ 其中,
$\textbf{Y}=
\begin{bmatrix}
y_1 \\
y_2 \\
\vdots \\
y_n \\
\end{bmatrix}
,
\textbf{X}=
\begin{bmatrix}
1 & x_{11} & \cdots & x_{1d} \\
1 & x_{21} & \cdots & x_{2d} \\
\vdots & \vdots & & \vdots \\
1 & x_{n1} & \cdots & x_{nd} \\
\end{bmatrix}
,
\mathbf{\beta}=
\begin{bmatrix}
\beta_0 \\
\beta_1 \\
\vdots \\
\beta_d \\
\end{bmatrix}$
+ 將 $L(\beta)$ 對於 $\beta$ 的偏微分式子展開
$\begin{align*}
\displaystyle \frac{\partial L}{\partial \beta}&=\frac{1}{n}\frac{\partial}{\partial \beta}(\left\| Y-\hat Y \right\|^2)\\
\displaystyle &=\frac{1}{n}\frac{\partial}{\partial \beta}(\left\| Y-X\beta\right\|^2)\\
\displaystyle &=\frac{1}{n}\frac{\partial}{\partial \beta}(Y-X\beta)^T(Y-X\beta)\\
\displaystyle &= \frac{1}{n}\frac{\partial}{\partial \beta}(Y^TY-Y^TX\beta-\beta^TX^TY+\beta^TX^TX\beta)\\
\displaystyle &= \frac{1}{n}(-(Y^TX)^T-X^TY+(X^TX+(X^TX)^T)\beta)\\
\displaystyle &= \frac{1}{n}(-X^TY-X^TY+2X^TX\beta)\\
\displaystyle &= \frac{1}{n}(2X^TX\beta-2X^TY)\\ \displaystyle &= \frac{2}{n}(X^TX\beta-X^TY)\\ \displaystyle &=\frac{2}{n}X^T(X\beta-Y)\\ \displaystyle &=\frac{2}{n}X^T(\hat{Y}-Y)
\end{align*}$
+ $\displaystyle \beta_0=\beta_0-\eta*\frac{\partial L}{\partial \beta_0},\beta_1=\beta_1-\eta*\frac{\partial L}{\partial \beta_1}$
以係數向量的外觀表示$\displaystyle \beta=\beta-\eta*\frac{\partial L}{\partial \beta}=\beta-\eta*\frac{2}{n}X^T(\hat{Y}-Y)$
+ 矩陣相關公式
- $(A+B)^T=A^T+B^T$
- $(AB)^T=B^TA^T$
+ 矩陣偏微分相關公式[(1)](https://blog.csdn.net/crazy_scott/article/details/80557814)[(2)](https://www.mdnice.com/writing/e8944e0cca324a46b31f19a656c6ae7c)
- $\frac{\partial X^T}{\partial X}=I$
- $\frac{\partial X^TA}{\partial X}=A$
- $\frac{\partial AX^T}{\partial X}=A$
- $\frac{\partial AX}{\partial X}=A^T$
- $\frac{\partial XA}{\partial X}=A^T$
- $\frac{\partial X^TAX}{\partial X}=(A+A^T)X$
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
x=np.array([24.3, 19.5, 18.8, 20.1, 22.2, 29.8, 26.3, 28.3, 31.9, 26.9]) # 油價
y=np.array([7.9, 7.7, 7.6, 7.7, 7.7, 8.2, 7.8, 7.9, 8.1, 8.1]) # 民眾搭捷運平均里程
plt.scatter(x, y) # 以 plt.scatter 產生散點圖
# 將x轉換為向量X,參考網站 [12]
~ # 先產生一個(10x1),全都是1的陣列x0
~ # 將x reshape為(10x1) 的陣列x1
~ # 將x0,x1合併成向量X
lr=0.001
np.random.seed(50)
~ # 隨機初始化向量b,參考網站 [13]
# Gradient Descent
for i in range(100000):
~ # 計算y_hat,參考網站 (6)[14]
~ # 計算gradients(梯度),參考網站 (34)[16]
~ # 更新向量b,參考網站 (35)[18]
print(b)
plt.plot(x, b[0]+b[1]*x, 'r') # 以 plt.plot(紅色線條) 畫出函數 y=b0+b1*x
```
:::info
EX_01_5:Scikit-learn(SKlearn) 內建一些真實世界的數據,以線性迴歸預測加州房價。[(特徵說明)](https://inria.github.io/scikit-learn-mooc/python_scripts/datasets_california_housing.html)
:::
``` javascript=
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
#1. 讀入加州房價資料
housing = fetch_california_housing()
# 了解加州房價資料資料庫
# housing.feature_names # 資料庫中所有的欄位名稱(features)
# print(housing.DESCR) # 解釋資料庫內容
# housing.data.shape # 幾列、幾欄
# len(housing.data) # 筆數
# housing.data # 內容(8個屬性)
# housing.target # 房價
#2. 切分訓練與測試資料(x指資料,y指答案)
x_train, x_test, y_train, y_test = train_test_split(housing.data, housing.target, test_size=0.2, random_state=50) # random_state為隨機種子,確保每次切分資料的結果都相同。
# x_train.shape
# x_test.shape
#3. 用線性迴歸做預測
~ # 初始化線性迴歸模組
~ # 讓線性迴歸模組學習,模組的變數名稱.fit(輸入資料,正確答案)
~ # y_test_predict=模組的變數名稱.predict(要預測的資料),y_test_predict為線性迴歸模組預測的結果
# 以評估指標MSE(mean squared error均方誤差),評估模型的誤差。MSE越接近0越好。
score=mean_squared_error(y_test,y_test_predict)
print("MSE:",score) # MSE: 0.5124
#4. 畫出真實價格與預測價格
plt.scatter(y_test, y_test_predict, s=0.5) # s->size
plt.xlabel('True Price')
plt.ylabel('Predicted Price')
plt.plot([0,5],[0,5],'r') # 畫(0,0)(5,5)連成的直線。如果預測正確,點會落在對角線上
```
+ [Python enumerate() 函数 | 菜鸟教程](https://www.runoob.com/python/python-func-enumerate.html)
+ [視覺化資料 - Matplotlib - legend、subplot、GridSpec、annotate](https://ithelp.ithome.com.tw/articles/10201670)
+ [matplotlib subplot 子圖繪製](https://www.itread01.com/content/1541685249.html)
``` javascript=
#5. 畫出個別屬性和房價關係
plt.figure(figsize=(10,5)) # 單位為英吋
for i, feature in enumerate(housing.feature_names):
plt.subplot(2, 4, i+1) # 使用子圖,2列,4欄,第幾張圖
plt.scatter(housing.data[:,i], housing.target, s=0.1) # s->size
plt.xlabel(feature)
plt.ylabel('price')
plt.tight_layout() # 自動調整繪圖區的大小及間距,使繪圖區、標題、坐標軸標籤等都可完整顯示(不會重疊)
```
:::info
(進階) EX_01_6:特徵關聯分析。
+ 嘗試不使用全部的特徵(8個)來訓練模型,觀察 MSE 的變化。考驗你的觀察、預測能力,看能不能使用更少的特徵,讓 MSE 小於0.5124。
:::
``` javascript=
x_train_partial=x_train[:,[0,1,6]] # 使用第0,1,6個特徵
x_test_partial=x_test[:,[0,1,6]]
```
+ Hint:以相關係數來看,應該選擇?
- 計算相關係數的方法預設為pearson(皮爾森相關係數),為兩個特徵的共變異數與標準差乘積的關係。
- 皮爾森相關係數的值介於 -1 ~ 1,0 表示兩個特徵沒相關,越接近 1 表示正相關越強,越接近 -1 表示負相關越強,所以絕對值越大表示相關性越大。皮爾森相關係數適用於線性分布且常態分布的特徵值。
``` javascript=
import pandas as pd
import seaborn as sns
dfHousing=pd.DataFrame(housing.data, columns=housing.feature_names) # columns 指定欄標籤名稱
dfHousing['MEDV']=housing.target
# dfHousing.head() 印出前5項來看看
corr_matrix=dfHousing.corr().round(2)
plt.figure(figsize=(12, 10))
sns.heatmap(corr_matrix, annot=True) # annot 為 True 會將數值寫入每個儲存格裏
```
<font color="#fff">[0,1,2,3,6,7]->0.5121</font>
### 2. [KNN(K Nearest Neighbor,K 最近鄰居法)](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html) (PPT)
+ <font color=red>分類,監督式學習</font>
+ <font color="red">體驗</font>:[K-Nearest Neighbors Demo](http://vision.stanford.edu/teaching/cs231n-demos/knn/)
+ [KNN 演算法](https://ithelp.ithome.com.tw/articles/10269826)
1. 決定 K 值。
2. 求每個鄰居跟自己之間的距離。
3. 找出跟自己最近的 K 個鄰居,鄰居多數是哪一類自己就是哪一類。
+ [沒有想像中簡單的簡單分類機 KNN](https://www.slideshare.net/ssuserf88631/knn-51511604)
+ [KD-Tree 演算法筆記](https://blog.yucheng.me/post/kd-tree/)
+ [機器學習中的幾種距離度量方法比較](https://www.itread01.com/content/1545370955.html)
- 標準化歐氏距離 (Standardized Euclidean Distance)
* Normalization:經過 Normalization 之後,資料的範圍會介在 0~1 之間,原本的最大值變為 1,最小值變為 0。
$X_{nom} = \frac{X-X_{min}}{X_{max}-X_{min}} \in [0,1]$
* Standardization:經過 Z分數標準化後,資料會符合標準常態分佈(Standard Normal Distribution),轉換後的平均值=0、標準差=1。
$Z=\frac{X-\mu}{\sigma} \sim N(0,1)$
$\mu:平均數,\sigma:標準差\sqrt \frac{\sum(X-\mu)^2}{n}$
* [【資料科學】 - 資料的正規化與標準化](https://aifreeblog.herokuapp.com/posts/54/data_science_203/)
* [[資料分析&機器學習] 第2.4講:資料前處理(Missing data, One-hot encoding, Feature Scaling)](https://medium.com/jameslearningnote/%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E7%AC%AC2-4%E8%AC%9B-%E8%B3%87%E6%96%99%E5%89%8D%E8%99%95%E7%90%86-missing-data-one-hot-encoding-feature-scaling-3b70a7839b4a):One-hot 編碼可消除數值的大小關係。
- (進階) [馬氏距離(Mahalanobis Distance)](http://mccormickml.com/2014/07/22/mahalanobis-distance/)
* [標準差、變異數、期望值](https://www.learnmode.net/flip/video/7226)
* [相關係數與共變異數(Correlation Coefficient and Covariance)](https://chih-sheng-huang821.medium.com/%E7%9B%B8%E9%97%9C%E4%BF%82%E6%95%B8%E8%88%87%E5%85%B1%E8%AE%8A%E7%95%B0%E6%95%B8-correlation-coefficient-and-covariance-c9324c5cf679)
:::info
EX_02_1:完成 [KNN學習單](https://drive.google.com/file/d/1PIiHIqWXHskAUh68j8L16021uCS3HOjF/view?usp=sharing),練習 KNN 分類原理。
:::
:::info
EX_02_2:使用 Scikit-learn(SKlearn) 實作 KNN ,將[鳶尾花卉 Iris 資料集](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E6%A3%AE%E9%B8%A2%E5%B0%BE%E8%8A%B1%E5%8D%89%E6%95%B0%E6%8D%AE%E9%9B%86)(欄位說明[(1)](https://blog.yeshuanova.com/2018/10/dataset-iris/)[(2)](https://medium.com/jameslearningnote/%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E7%AC%AC2-1%E8%AC%9B-%E5%A6%82%E4%BD%95%E7%8D%B2%E5%8F%96%E8%B3%87%E6%96%99-sklearn%E5%85%A7%E5%BB%BA%E8%B3%87%E6%96%99%E9%9B%86-baa8f027ed7b))分類並預測。
:::
+ [淺談機器學習的效能衡量指標 (1) -- 準確率(Accuracy)、精確率(Precision)、召回率(Recall)](https://ithelp.ithome.com.tw/articles/10228941)
``` javascript=
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
#1. 讀入鳶尾花資料
iris = load_iris()
# 了解鳶尾花資料庫
# iris.feature_names # 資料庫中所有的欄位名稱(features)
# print(iris.DESCR) # 解釋資料庫內容
# iris.data.shape # 幾列、幾欄
# len(iris.data) # 筆數
# iris.data # 內容
# iris.target # 內容
#2. 切分訓練與測試資料
~
# x_train.shape
#3. 初始化 knn 分類模組
knnModel = KNeighborsClassifier() # 預設 K 值為5
~ # 讓KNN模組學習,模組的變數名稱.fit(輸入資料,正確答案)
#4. 預測
~ # y_test_predict=模組的變數名稱.predict(要預測的資料),y_test_predict為KNN模組預測的結果
print(y_test_predict) # 預測的分類
print(y_test) # 標準答案的分類
print(accuracy_score(y_test, y_test_predict)) # 正確率 0.9
```
:::info
EX_02_3:使用 KNN 遇到的最大問題和 K-Means 類似,即如何確定 K 值? 請探討 EX_02_2 使用不同 K 值,對預測正確率的影響。(將 K 最大值調為資料集樣本數)
+ K 值過小會降低分類的精確度。K 值越大,對於異常值越不敏感,但也會使類別之間的界限變得模糊。
+ [Machine Learning-交叉驗證(Cross Validation)-找到KNN中適合的K值-Scikit Learn一步一步實作教學 | by Chwang | Medium](https://chwang12341.medium.com/machine-learning-%E4%BA%A4%E5%8F%89%E9%A9%97%E8%AD%89-cross-validation-%E6%89%BE%E5%88%B0knn%E4%B8%AD%E9%81%A9%E5%90%88%E7%9A%84k%E5%80%BC-scikit-learn%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E5%AF%A6%E4%BD%9C%E6%95%99%E5%AD%B8-4109bf470340)
:::
+ [numpy.arange](https://numpy.org/doc/stable/reference/generated/numpy.arange.html)
``` javascript=
# 預設的 k 值,但以交叉驗証計算準確率
# 以避免上例留出法(holdout cross validation)的缺點:
# 如果只做一次劃分,不同的劃分方式,可能會有不同的準確率。
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
iris = load_iris()
x = iris.data
y = iris.target
knnModel = KNeighborsClassifier() # 預設 K 值為5
# 做交叉驗証計算準確率
accuracy = cross_val_score(knnModel, x, y, cv=10, scoring='accuracy') # cv:將資料分成幾組。
print(accuracy)
print(accuracy.mean())
# 從 accuracy 中,可看到不同組的準確度差很大。如果EX_02_2的程式取到第一組的狀況,還會誤以為 K 值選對了。
```
``` javascript=
# 對每一個 k 做實驗
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
iris = load_iris()
x = iris.data
y = iris.target
k_range = range(1,31)
accuracies = []
for ~ # 對每一個 k 做實驗
~ # 初始化 knn 分類模組,n_neighbors = ?為參數
~ # 使用交叉驗証計算準確率
~ # 將每次的準確率平均加入 accuracies 串列
print('K值: ' + str(k) + ' Accuracy: ' + str(accuracy.mean()))
print('最佳 K 值: ' , accuracies.index(max(accuracies))+1)
plt.plot(k_range, accuracies)
plt.xlabel('Value of K for KNN')
plt.ylabel('Cross-Validated Accuracy')
```
+ [GridSearchCV 函數](https://ithelp.ithome.com.tw/articles/10234203)
``` javascript=
# 使用 GridSearchCV 函數自動找出最佳參數組合(GridSearchCV會自動作Cross Validation)
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
iris = load_iris()
x = iris.data
y = iris.target
parameter={'n_neighbors':[1,3,5,7,9,11,13,15]}
knnModel=KNeighborsClassifier()
grid=GridSearchCV(estimator=knnModel,param_grid=parameter,cv=5) # cv 為交叉驗證參數,表示將資料分成 n 段, default 為 3
grid.fit(x,y)
print(f'最佳的 K 值參數為:{grid.best_params_} ,準確率為:{grid.best_score_:.3f}')
```
+ [numpy axis概念整理筆記](http://changtw-blog.logdown.com/posts/895468-python-numpy-axis-concept-organize-notes)
+ [關於Python 中 axis](https://itselementary993.wordpress.com/2017/05/26/%E9%97%9C%E6%96%BCpython-%E4%B8%AD-axis/)
+ ![](https://i.imgur.com/g7P4yqa.png =450x)
:::info
EX_02_4:將鳶尾花卉 Iris 資料集 sepal length (cm) normalization ,sepal width (cm) standardization。
:::
``` javascript=
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
x = pd.DataFrame(iris['data'], columns=iris['feature_names'])
y = pd.DataFrame(iris['target'], columns=['target_names'])
data = pd.concat([x,y], axis=1)
data.head()
# normalization
data['sepal length (cm)'] = (data['sepal length (cm)'] - data['sepal length (cm)'].min())/(~ - ~)
data.head()
# standardization
data['sepal width (cm)'] = (data['sepal width (cm)'] - data['sepal width (cm)'].mean())/ ~ # std() 求標準差
data.head()
```
``` javascript=
# 可直接使用 SKlearn 的 MinMaxScaler、StandardScaler 模組
from sklearn.datasets import load_iris
iris = load_iris()
iris.data
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
iris_scaled = scaler.fit_transform(iris.data)
iris_scaled
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
iris_scaled = scaler.fit_transform(iris.data)
iris_scaled
```
:::info
(進階) EX_02_5:Ball Tree 簡介報告。
+ k-d tree 可以解決 brute force 效率不佳的問題,假設資料集樣本數為 n,特徵數為 d,當 n>>2^d,k-d tree 搜尋效果會比較好。例如 1000 個樣本且特徵數不超過 10 個(2^10=1024)的資料集。
+ 一但特徵過多,k-d tree 的搜尋效率就會大幅下降,最終變得和暴力搜尋差不多。通常 k-d tree 適合不超過 20 維的資料集。
+ 一個導致性能下降的最核心因素是因為 k-d tree 中被分割的子空間是一個個的超方體,計算距離使用歐式距離(Euclidean Distance),會形成超球體的判斷空間。超方體與超球體相交的可能性極高。如下圖所示,凡是相交的子空間,都需要進行檢查,大大的降低運行效率。
[![](https://i.imgur.com/Sg3bSGm.png =100x)](https://www.jianshu.com/p/2e6f3ca6e3e7)
+ ball tree 通過超球體劃分空間,劃分和搜尋超球體相交的機率會大大降低,能解決 k-d tree 高維效率不佳的問題。請搜尋 ball tree 相關文章,完成 ball tree 簡介報告(觀念、建樹演算法、搜尋演算法、為何可以解決 k-d tree的問題…,文後附上參考文獻)。
- [kNN里面的两种优化的数据结构:kd-tree和ball-tree,在算法实现原理上有什么区别?](https://www.zhihu.com/question/30957691)
- [KNN的核心算法kd-tree和ball-tree](https://www.jianshu.com/p/2e6f3ca6e3e7)
- [KNN算法常见问题总结](https://www.jianshu.com/p/da5e38fee345)
- [Ball tree - Wikipedia](https://en.wikipedia.org/wiki/Ball_tree)
- [Mohamad Dolatshah, Ali Hadian, Behrouz Minaei-Bidgoli, "Ball*-tree: Efficient spatial indexing for constrained nearest-neighbor search in metric spaces", ArXiv e-prints, Nov 2015.](https://arxiv.org/abs/1511.00628)
- 其它(請自行搜尋)
:::
### 3. Decision Trees(決策樹)
+ <font color=red>分類,監督式學習</font>
+ <font color="red">體驗</font>:[R2D3 - A Decision Tree](http://www.r2d3.us/%E5%9B%BE%E8%A7%A3%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/)
+ [決策樹直覺且執行效率好,適用於 classification 及 regression 資料類型的預測。](https://ithelp.ithome.com.tw/articles/10276079)
- 吉尼係數表示模型的不純度(亂度)。基尼係數越高越不純,越低越純。
- 假設集合 S 包含 n 個類別,吉尼係數$\displaystyle Gini(S)=1-\sum_{j=1}^{n}p_j^2$。
$p_j$ 為在 S 中的值,屬於類別 j 的機率。
- 若利用屬性 A 分割集合 S 為 S~1~ 與 S~2~,則 $\displaystyle Gini_A(S)=\frac{|S_1|}{S}Gini(S_1)+\frac{|S_2|}{S}Gini(S_2)$
- 挑選吉尼不純度 $Gini_A(S)$ 最小的屬性為分割的屬性。
:::info
EX_03_1:完成[Decision_Tree學習單](https://drive.google.com/file/d/19Y6cpKMhNJcH4ncOCbBTa8-wLwJ4CTyq/view?usp=sharing),練習如何挑選每個節點分類的屬性。
:::
:::info
EX_03_2:以[EX_03_1學習單的資料](https://drive.google.com/file/d/1K7JBIwb8YsQTCGYe3lEnCqtsnUT2nLVG/view?usp=sharing)實作決策樹,比對計算結果和程式實作是否相同。
(1) 上傳檔案至Colab:Colab 左側 -> 檔案 ->上傳至工作階段儲存空間。
(2) 使用自己的雲端硬碟檔案:Colab 左側 -> 檔案 -> 掛接雲端硬碟。(登入Google帳號後,將授權金鑰貼過來)
檔案路徑:'drive/My Drive/檔案名'
:::
+ [pandas.factorize](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.factorize.html)
``` javascript=
import pandas as pd
import pydotplus
from IPython.display import Image
from sklearn import tree
#1. 將csv檔讀入pandas的DataFrame
df = pd.read_csv('Decision_Tree_data.csv') # 先將檔案上傳至 Colab
# df = pd.read_csv('drive/My Drive/Decision_Tree_data.csv') # 先將檔案上傳至自己的雲端硬碟
# print(df)
#2. factorize函數將Series中的字串,映射為一組數字;相同的字串映射為相同的數字
df['age'],_ = pd.factorize(df['age'])
df['income'],_ = pd.factorize(df['income'])
df['student'],_ = pd.factorize(df['student'])
df['buy_computer'],uniques = pd.factorize(df['buy_computer']) # uniques->the unique value in an array
# print(df)
# print(uniques)
"""
亦可使用 SKlearn 的 LabelEncoder 模組
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['age'] = le.fit_transform(df['age'])
le.classes_ # 查詢轉換後數值代表的特徵值
"""
#3. 訓練資料及分類答案
x_train=df[['age','income','student']]
y_train=df[['buy_computer']]
# print(x_train)
# print(y_train)
#4. 建立決策樹分類模組
dtreeModel = tree.DecisionTreeClassifier()
dtreeModel.fit(x_train, y_train)
#5. 畫出決策樹
feature_names = x_train.columns
dot_data = tree.export_graphviz(dtreeModel, out_file=None, feature_names=feature_names, class_names=uniques, filled=True, rounded=True, special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())
```
:::info
EX_03_3:使用 Scikit-learn(SKlearn) 實作決策樹,將[鳶尾花卉 Iris 資料集](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E6%A3%AE%E9%B8%A2%E5%B0%BE%E8%8A%B1%E5%8D%89%E6%95%B0%E6%8D%AE%E9%9B%86)(欄位說明[(1)](https://blog.yeshuanova.com/2018/10/dataset-iris/)[(2)](https://medium.com/jameslearningnote/%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E7%AC%AC2-1%E8%AC%9B-%E5%A6%82%E4%BD%95%E7%8D%B2%E5%8F%96%E8%B3%87%E6%96%99-sklearn%E5%85%A7%E5%BB%BA%E8%B3%87%E6%96%99%E9%9B%86-baa8f027ed7b))分類並預測。
:::
``` javascript=
from sklearn.datasets import load_iris
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
#1. 讀入鳶尾花資料
~
# print(iris.data) 150個樣本,每個樣本4個特徵
# print(iris.target)
#2. 切分訓練與測試資料
~
#3. 建立決策樹分類模組
~
~
#4. 預測
~ # 預測 x_test 資料
print(y_test_predict) # 預測的分類
print(y_test) # 標準答案的分類
print(accuracy_score(y_test, y_test_predict)) # 正確率
```
``` javascript=
import pydotplus
from IPython.display import Image
#5. 畫出決策樹
dot_data = tree.export_graphviz(dtreeModel, out_file=None, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True, special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png()) # gini屬性用於測量節點的不純度(亂度),如果一個節點包含的都是同一類,此節點gini=0
```
### 4. SVM(Support Vector Machine,支持向量機)
+ <font color=red>分類,監督式學習</font>
+ <font color="red">體驗</font>:[Dash-Support Vector Machine (SVM) Explorer](https://dash-gallery.plotly.host/dash-svm/) [(參數說明)](https://cloud.tencent.com/developer/article/1065624)
+ [白話文講解支持向量機(一) 線性SVM](https://notes.andywu.tw/2020/%E7%99%BD%E8%A9%B1%E6%96%87%E8%AC%9B%E8%A7%A3%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%A9%9F%E4%B8%80-%E7%B7%9A%E6%80%A7svm/)
- $loss_1(\theta^Tx)=max(0,1-\theta^Tx))$
* 紅色點離決策線越近,損失會越大。
* 例如在 $\theta_0+\theta_1x_1+\theta_2x_2=1$ 以下的點,帶入方程式的值會 <1。值為 0.4(離決策線近) 損失為 0.6(大),值為 0.8(離決策線遠) 損失為 0.2(小)。
- $loss_0(\theta^Tx)=max(0,1+\theta^Tx))$
* 藍色點離決策線越近,損失會越大。
* 例如在 $\theta_0+\theta_1x_1+\theta_2x_2=-1$ 以上的點,帶入方程式的值會 >-1。值為 -0.4(離決策線近) 損失為 0.6(大),值為 -0.8(離決策線遠) 損失為 0.2(小)。
- 結合上兩個式子,損失函數為
$\displaystyle \min_{θ} \sum_{i=1}^{m} [ y^{(i)} * loss_1(θ^Tx^{(i)}) + (1-y^{(i)}) * loss_0(θ^Tx^{(i)}) ]$
* y為練資料的類別 (1或0),如果是類別 1,後面 (1-y) 會讓 $loss_0$ 沒作用,只計算 $loss_1$;反之如果是類別 0,前面 $loss_1$ 沒作用,只計算 $loss_0$。
* 為了處理離群值,加入正規化項,並以超參數 C,控制前半的分類損失和後半正規化項的比例。
+ [白話文講解支持向量機(二) 非線性SVM](https://notes.andywu.tw/2020/%E7%99%BD%E8%A9%B1%E6%96%87%E8%AC%9B%E8%A7%A3%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%A9%9F%E4%BA%8C-%E9%9D%9E%E7%B7%9A%E6%80%A7svm/)
+ [(進階)Kernel 函數](https://medium.com/@chih.sheng.huang821/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-kernel-%E5%87%BD%E6%95%B8-47c94095171)的手法為在原始空間不好區分的資料(無法線性區分),可以用一個非線性的映射函數,將這些資料轉換到更高維度的空間,或許比較好區分(可線性區分)。
- [SVM with polynomial kernel visualization](https://www.youtube.com/watch?v=3liCbRZPrZA)
:::info
EX_04_1:線性SVM的損失函數為
$\displaystyle \min_{θ} C \sum_{i=1}^{m} [ y^{(i)} * loss_1(θ^Tx^{(i)}) + (1-y^{(i)}) * loss_0(θ^Tx^{(i)}) ] + \frac{1}{2} \sum_{j=1}^{n} θ_j^2$
請下載 [ex4data.mat](https://drive.google.com/file/d/1K9Th2WgzLwYfrb6RCccLloPod6NjlScM/view?usp=sharing) 數據集,觀察誤差項懲罰系數 C 對決策邊界的影嚮(C越大,容錯率越低,越易過擬合)。
:::
- [numpy.ravel()和numpy.flatten()的區別](https://www.itread01.com/content/1541532855.html)
``` javascript=
#1. 先畫出原始數據分佈,左上角的那個數據點為異常點。
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
data = sio.loadmat('ex4data.mat')
# print(data)
X,y = data['X'],data['y']
def plot_data():
plt.scatter(X[:,0],X[:,1], c=y.flatten(), cmap='jet') # X[:,0] 表示所有列的第0欄,即所有點的x座標。
plt.xlabel('x1')
plt.ylabel('y1')
plot_data()
```
+ [numpy.linspace](https://numpy.org/doc/stable/reference/generated/numpy.linspace.html)
+ [meshgrid(p.98)](https://github.com/yenlung/Python-3-Data-Analysis-Basics/blob/master/%E6%8A%95%E5%BD%B1%E7%89%87/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%89%93%E9%96%8BPython%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90%E5%A4%A7%E9%96%80.pdf)
+ [Python3 zip() 函数](https://www.runoob.com/python3/python3-func-zip.html)
+ [numpy中np.c_和np.r_](https://blog.csdn.net/yj1556492839/article/details/79031693)
+ [資料視覺化之 contour ( matplotlib.pyplot ) 教學與用法](https://tree.rocks/python-matplotlib-plt-contour-or-contourf-tutorial-with-sklearn-e4497f76280)
+ [Hello Matplotlib!(2)](https://ithelp.ithome.com.tw/articles/10225391)
``` javascript=
#2. 使用 Scikit-learn SVM,kernel=‘linear’,C=1
from sklearn.svm import SVC
svcModel = SVC(C=1,kernel='linear') # 初始化 SVC 分類器,C 為誤差項懲罰系數,核函数選擇線性核
svcModel.fit(X,y.flatten()) # 導入數據讓分類模組學習
svcModel.score(X,y.flatten()) # 分類器準確率0.9803921568627451
# 繪製決策邊界
def plot_boundary(model):
x_min,x_max= -0.5,4.5
y_min,y_max= 1.3,5
xx,yy = np.meshgrid(np.linspace(x_min,x_max,40), np.linspace(y_min,y_max,40)) # 以 meshgrid 產生格點,xx,yy的表示法請參考講義
# plt.scatter(xx.flatten(),yy.flatten()) # 畫出平面上的所有點(先試)
z = model.predict(list(zip(xx.flatten(),yy.flatten()))) # 將xx,yy組成點。print(list(zip(xx.flatten(),yy.flatten())))
# 或z = model.predict(np.c_[xx.flatten(),yy.flatten()])
zz = z.reshape(xx.shape) # 將預測結果調整成xx的形狀,為等高線圖每個點的深度
plt.contourf(xx,yy,zz,alpha=0.3)
plot_boundary(svcModel)
plot_data()
```
``` javascript=
#3. C=25
~ # 初始化 SVC 分類器,C 為誤差項懲罰系數(C=25),核函数選擇線性核
~ # 導入數據讓分類模組學習
~ # 分類器準確率為 1.0 (perfect)
# 繪製決策邊界
plot_boundary(svcModel)
plot_data()
```
### 5. [K-Means Clustering(K-平均演算法)](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html)(PPT)
+ <font color=red>分群,非監督式學習</font>
+ <font color="red">體驗</font>:[Visualizing K-Means Clustering](https://www.youtube.com/watch?v=nXY6PxAaOk0)
+ [K-means 演算法](https://ithelp.ithome.com.tw/articles/10266672)
1. 初始化:指定 K 個分群,並隨機挑選 K 個資料點的值當作群組中心點。
2. 分配資料點:每個資料點與距離最近的中心點同群。
3. 計算平均值:重新計算每個分群的中心點。
重複步驟2、3,直到資料點不再變換群組為止。
+ [K-means 怎麼選 K ?](https://blog.v123582.tw/2019/01/20/K-means-%E6%80%8E%E9%BA%BC%E9%81%B8-K/)
+ [Kmeans 分群演算法 與 Silhouette 輪廓分析](https://jimmy-huang.medium.com/kmeans%E5%88%86%E7%BE%A4%E6%BC%94%E7%AE%97%E6%B3%95-%E8%88%87-silhouette-%E8%BC%AA%E5%BB%93%E5%88%86%E6%9E%90-8be17e634589)
- Silhouette Coefficient(輪廓係數)表示資料點和所屬群之間的相似度([-1, 1])。Silhouette 值接近1,表示資料點與所屬群之間有密切聯繫;反之則接近-1。
- $\displaystyle S=\frac{b-a}{max(a,b)}$,S 越大越好,代表分得越清楚。
- a 為點和同群之間點的平均距離(越小表示樣本在該群中越集中), b 為點和不同群之間點的平均距離(越大表示資料點越不屬於其它群)。
:::info
EX_05_1:完成[K-Means學習單](https://drive.google.com/open?id=1B5ekbseevr4THHw4532EtltskNxTVlMf),練習K-Means分群原理。
:::
:::info
EX_05_2:使用 Scikit-learn(SKlearn) 以 K-Means 實作非監督式學習分群,將平面上的數據分群,並探討 K 值該如何選取。
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs # 載入 scikit-learn 套件中的資料集模組,用來產生資料集
#1. 分群資料準備,隨機產生 5 群資料
points, label = make_blobs(n_samples=1500, centers=5, cluster_std=2, random_state=170) # make_blobs()隨機產生一群一群圓形的資料。cluster_std為群中資料點離群中央的距離標準差,值愈大資料愈分散。random_state為隨機種子。
# print(points)
# print(label)
# plt.scatter(points[:, 0], points[:, 1], c=label) # 先試試看畫出產生的點,依據不同群給予不同顏色
#2. 用 K-Means 做分群
kmeansModel = KMeans(n_clusters=5) # 初始化 KMeans 分群模組,n_clusters為要分成幾群,試其它數字
y_predict = kmeansModel.fit_predict(points) # 用 K-Means 分群
#3. 畫出分群結果(並列顯示)
plt.figure(figsize=(10, 5))
plt.subplot(1,2,1) # 1列,2欄,第1個位子
plt.title('Original data')
~ # 以 plt.scatter 畫出原圖
~ # Kmeans分類的結果畫在右側,# 1列,2欄,第2個位子
~ # 標題為'KMeans'
~ # 畫出分群結果 c=y_predict
# print(kmeansModel.cluster_centers_) # 標示各群的中心點
plt.scatter(kmeansModel.cluster_centers_[:, 0], kmeansModel.cluster_centers_[:, 1], s=200, c="r", marker='*')
```
+ [Python 繪製折線圖 Plot Line Charts
](http://homepage.ntu.edu.tw/~weitingc/fortran_lecture/Lecture_P_2_1Dplot.slides.html)
``` javascript=
from sklearn.metrics import silhouette_score
#4. Silhouette Coefficient
silhouette = []
for i in range(2,11): # 試分成2~10群
kmeansModel = KMeans(~指定分幾群).fit(~資料) # n_clusters=? 指定分幾群
silhouette.append(silhouette_score(points, ~分群結果)) # kmeansModel.labels_ 有為分群的結果,不用再設一個變數y_predict
plt.plot(range(2,11), silhouette, "b-o") # "b-o" 為 style_code(顏色代碼、線條樣式代碼、符號樣式代碼)
plt.xlabel("k")
plt.ylabel("Silhouette score")
```
:::info
EX_05_3:使用 Scikit-learn(SKlearn) 以 K-Means 實作非監督式學習分群,將[鳶尾花卉 Iris 資料集](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E6%A3%AE%E9%B8%A2%E5%B0%BE%E8%8A%B1%E5%8D%89%E6%95%B0%E6%8D%AE%E9%9B%86)(欄位說明[(1)](https://blog.yeshuanova.com/2018/10/dataset-iris/)[(2)](https://medium.com/jameslearningnote/%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E7%AC%AC2-1%E8%AC%9B-%E5%A6%82%E4%BD%95%E7%8D%B2%E5%8F%96%E8%B3%87%E6%96%99-sklearn%E5%85%A7%E5%BB%BA%E8%B3%87%E6%96%99%E9%9B%86-baa8f027ed7b))分群。
:::
``` javascript=
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
iris = load_iris()
x = iris.data[~, ~] # 為畫圖方便,簡化只取花瓣(Petal)的長度、寬度來預測
plt.scatter(x[~], x[~]) # 花瓣的長為 x 軸,寬為 y 軸。plt.scatter(x[~], x[~], c=iris.target)
plt.xlabel('petal length')
plt.ylabel('petal width')
```
| ![](https://i.imgur.com/GACyPuN.png) | ![](https://i.imgur.com/5QZxJqQ.png) |
|--|--|
``` javascript=
~ # 初始化 KMeans 分群模組,n_clusters為要分成幾群,試試看其它數字
~ # 用 K-Means分群
~ # 畫出分群結果(plt.scatter)
~ # x軸 label
~ # y軸 label
```
![](https://hackmd.io/_uploads/BkHtGrLkyx.png =30x)
``` javascript=
# 改以『花萼』長、寬分群,且並列顯示兩張圖。
```
![](https://hackmd.io/_uploads/B1gEfHL11g.png)
``` javascript=
# 使用『花萼+花瓣』分群,且並列顯示兩張圖(以花萼長、寬繪圖)(分群效果更好)。
```
![](https://hackmd.io/_uploads/ryKXzBLJ1l.png)
### 6. Density-Based Clustering(密度集群法)
+ <font color=red>分群,非監督式學習</font>
+ <font color="red">體驗</font>:[Visualizing DBSCAN Clustering](https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/)
+ DBSCAN(Density-based spatial clustering of applications with noise)
- 以資料的密度來分群,使用者不需要設定群組數。
- 能夠自動處理 noise。
- min_samples:最少樣本數。
- eps($ε$):半徑長度。
- Core Point (核心點):以該點為圓心,$ε$為半徑所圍繞出來的
範圍內有超過 min_samples 個點,則該點為核心點。
- Border Point (Non-Core Point、邊緣點):若該點被其它核心點所包含,但它
為圓心卻沒辦法包含超過 min_samples 個點,則該點即為邊緣點。
- Noise Point (Outlier、雜訊點):不屬於核心點,也不屬於邊界點。
+ [DBSCAN 演算法](https://www.youtube.com/watch?v=RDZUdRSDOok)
1. 挑選一個尚未分群的資料點,如果該點是核心點,則給予一個新的群組標籤並進行步驟2,否則標為雜訊點(並重新挑選點)。
2. 拜訪此核心點的所有鄰居點(距離小於$ε$),如果該點尚未分群,則設為同群。
3. 如果鄰居點也是核心點,以該點為圓心重複步驟2,直到沒有其它核心點。
4. 將該群周圍的邊緣點加入該群(不再從邊緣點往外擴充)。
5. 重複步驟1~4,直到所有資料點均處理完畢。
+ [不要再用K-means! 超實用分群法DBSCAN詳解. sklearn DBSCAN使用介紹](https://axk51013.medium.com/%E4%B8%8D%E8%A6%81%E5%86%8D%E7%94%A8k-means-%E8%B6%85%E5%AF%A6%E7%94%A8%E5%88%86%E7%BE%A4%E6%B3%95dbscan%E8%A9%B3%E8%A7%A3-a33fa287c0e)
+ [Data science and machine learning](http://yltang.net/tutorial/dsml/14/)
:::info
EX_06_1:K-Means 演算法會計算資料點的中心,沒有方向性,因此適合處理凸型群組, 對於分散、歪斜、或凹形群組的效果不佳,例如月形資料,群組中心會在凹形尖端。改用DBSCAN看看結果會如何。
:::
``` javascript=
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons # 載入 scikit-learn 套件中的資料集模組,用來產生資料集
from sklearn.cluster import KMeans
# 產生半月形資料
x, y = make_moons(n_samples=200, noise=0.05, random_state=0)
kmeansModel = KMeans(n_clusters=2)
y_predict = kmeansModel.fit_predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_predict)
plt.scatter(kmeansModel.cluster_centers_[:, 0], kmeansModel.cluster_centers_[:, 1], s=200, c=['b', 'r'], marker='*',) # 標示各群的中心點
```
``` javascript=
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons # 載入 scikit-learn 套件中的資料集模組,用來產生資料集
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
x, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# 執行 DBSCAN 演算法的資料需標準化,使用 StandardScaler 物件的 fit_transform()方法轉換,不用自己算
scaler = StandardScaler()
X_scaled = scaler.fit_transform(x)
dbscanModel = DBSCAN() # DBSCAN 使用預設參數(eps=0.5, min_samples=5)。試試 eps=0.3、eps=0.7 的分群結果。
y_predict = dbscanModel.fit_predict(X_scaled)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_predict)
```
### 7. Hierarchical Clustering(階層式分群法)
+ <font color=red>分群,非監督式學習</font>
+ [Clustering method 4. Hierarchical Clustering ](https://medium.com/ai-academy-taiwan/clustering-method-4-ed927a5b4377)
+ 階層式分群法通常分為兩種作法:聚合法 (agglomerative, bottom-up, 小群到大群) 與分裂法 (divisive, top-down, 大群到小群)兩種。
+ [linkage: 各群間距離的計算方式(linkage criteria)](http://mirlab.org/jang/books/dcpr/dcHierClustering.asp?title=3-2%20Hierarchical%20Clustering%20(%B6%A5%BCh%A6%A1%A4%C0%B8s%AAk)&language=chinese):
- [ward (預設值)](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html): 在將兩群合併後,各點到合併後的群中心的距離平方和為兩群之距離。
- single: 不同群中最接近兩點間的距離為兩群之距離。
- complete: 不同群中最遠兩點間的距離作為兩群之距離。
- average: 不同群中各點與各點間之平均距離作為兩群之距離。
:::info
EX_07_1:完成[階層式分群法學習單](https://drive.google.com/open?id=1_2rDD9NYEvA0Hvd0RIkPXR3nKeEgO5T-),練習聚合法(不同群距離計算方式)的分群原理。
:::
:::info
EX_07_2:使用 Scikit-learn(SKlearn) 以聚合法 (agglomerative) 實作非監督式學習分群,將平面上的數據分成四群。
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs # 載入 scikit-learn 套件中的資料集模組,用來產生資料集
from sklearn.cluster import AgglomerativeClustering
#1. 分群資料準備,隨機產生4群資料
points, label = make_blobs(n_samples=1500, centers=4, cluster_std=2, random_state=170) # make_blobs()隨機產生一群一群圓形的資料。cluster_std為群中資料點離群中央的距離標準差,值愈大資料愈分散(試試1~10)。random_state為隨機種子。
# plt.scatter(points[:, 0], points[:, 1], c=label) # 先試試看畫出產生的點,依據不同群給予不同顏色
#2. 以 Agglomerative Clustering 分群模組做分群
aggModel = AgglomerativeClustering(n_clusters=4) # 初始化 AgglomerativeClustering 分群模組
y_predict = aggModel.fit_predict(points) # 開始分群
#3. 畫出分群結果
plt.scatter(points[:, 0], points[:, 1], c=y_predict)
```
<br />
## 四、深度學習(Deep Learning)之神經網路結構
+ Teachable Machine 體驗
+ <font color="red">體驗</font>:[有學習能力的電腦帶來的美好例駭人影響](https://www.ted.com/talks/jeremy_howard_the_wonderful_and_terrifying_implications_of_computers_that_can_learn/transcript?fb_ref=talk&language=zh-tw)
+ [【深度學習】如果電腦有神經,可以教它做什麼?](http://research.sinica.edu.tw/deep-learning-2017-ai-month/)
+ 應用:語音辨識、影像辨識、自然語言處理、天氣預測、醫療影像辨識、金融股市預測、網路異常入侵偵測、自駕車…
### 1. DNN(Deep Neural Network,深度神經網路)
(1) 原理(PPT)
+ 模擬人類大腦神經元的刺激傳導機制,讓機器自己提取特微、試誤。
+ 不管多麼複雜的函數,都可以用非線性函數組合出近似函數。[機器學習就是讓機器自動找出函數](https://www.youtube.com/watch?v=yXd2D5J0QDU#t=2m38s)。
+ [Why "Deep", not "Fat"?](https://www.youtube.com/watch?v=yXd2D5J0QDU#t=9m18s)
+ 3Blue1Brown Neural networks:[①神經網路是什麼?](https://www.youtube.com/watch?v=aircAruvnKk) [②神經網路如何學習?梯度下降](https://www.youtube.com/watch?v=IHZwWFHWa-w) [③反向傳播](https://www.youtube.com/watch?v=Ilg3gGewQ5U)[(計算)](https://www.youtube.com/watch?v=tIeHLnjs5U8)
(2) <font color="red">體驗&參數</font>
+ [Teachable Machine](https://teachablemachine.withgoogle.com/)
- [Epochs(訓練次數)](https://medium.com/%E4%BA%BA%E5%B7%A5%E6%99%BA%E6%85%A7-%E5%80%92%E5%BA%95%E6%9C%89%E5%A4%9A%E6%99%BA%E6%85%A7/epoch-batch-size-iteration-learning-rate-b62bf6334c49):當一個完整的資料集,在神經網路正向傳播及反向傳播一次,稱為一個 epoch。
* 例如將 epochs 設為 50,則資料集會訓練 50 次。
- Batch Size:一次訓練的樣本數量,每處理完 batch size 的樣本數量後,將重新計算模型的損失值並調整模型的參數(權重和偏差)。
* 例如資料集有 80 個樣本, batch size 如果是 16,則處理完 16 個樣本後會調整模型參數;資料集會分成 80/16=5 批,當 5 批資料餵入模型訓練,即完全一個 epoch。
- [Learning Rate(學習率)](https://kknews.cc/zh-tw/code/936ylkj.html):學習率的大小決定優化演算法的優化步代。
* 若學習率過大,會使每次參數更新的步長過大,可能會躍過最佳值並且離底部愈來愈遠。
* 若學習率過小,優化的效率可能過低,經過長時間訓練仍無法找到最佳值。
* [Google Machine Learning Crash Course 的 Learning Rate 實驗](https://developers.google.com/machine-learning/crash-course/fitter/graph)
* [高維的梯度下降無法可視化,以 loss 來判斷 learning rate 是否適當(p.5)](https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/Gradient%20Descent%20(v2).pdf)。
+ [A Neural Network Playground](http://playground.tensorflow.org/)
- [Tensorflow Playground 筆記](https://ithelp.ithome.com.tw/articles/10218185)
- Ratio of training to test data:設定訓練資料與測試資料的比例。
- Regularization(正規化):用來止 [overfitting(過度擬合,訓練資料的loss小,測試資料的loss大)](https://developers.google.com/machine-learning/crash-course/overfitting/overfitting?hl=zh-tw)。
* [防止過度擬合的 8 種簡單技術](https://kknews.cc/zh-tw/code/kk2qno8.html)
* L1 Regularization 會讓某些權重變成 0(也會保留大的權重)。
* [L2 Regularization 會讓權重接近 0(不會有太突出的權重)](https://developers.google.com/machine-learning/crash-course/overfitting/regularization?hl=zh-tw)。
* [(進階) Regularization 公式說明](https://www.youtube.com/watch?v=xki61j7z-30#t=57m43s):L1、L2正則化是透過修改損失函數來實現,在損失函數中加上對應的 L1 及 L2 penalty(懲罰項)。
:::info
EX_08_1:[Neural Networks: Playground Exercises](http://playground.tensorflow.org/) 練習。
+ 『分類問題/Circle』,[「互動式練習」說明](https://developers.google.com/machine-learning/crash-course/neural-networks/interactive-exercises?hl=zh-tw)。
+ 完成『分類問題/Spiral』,將畫面截圖上傳。(最多 1000 次 Epoch)
- 可嘗試增加其它特徵,增加或刪除隱藏層和神經元、更改學習率、正則化、批量大小…等參數,可以獲得的最佳測試損失是多少?模型輸出表面有多光滑?
:::
(3) [Keras 模型、函數及參數使用說明](https://ithelp.ithome.com.tw/articles/10191725)
+ [Activation Function(激發函數)](https://codingnote.cc/zh-tw/p/176736/)
- 提供非線性函數的轉換外(如果沒有激發函數,不管神經網路有多少層,都只能學習到線性方程式),也是一種門檻(Threshold)的過濾,讓神經元的參數能更快的收斂。
- [常用激發函數](https://en.wikipedia.org/wiki/Activation_function)
* [ReLU(Rectifie Linear Units)](https://mropengate.blogspot.com/2017/02/deep-learning-role-of-activation.html):定義為 f(x)=max(0,x),將負數變為0會凸顯特徵。(好計算、等同無窮多 sigmoid 疊加,可以處理梯度消失)
* Tanh(hyperbolic tangent)
* sigmoid:反向傳播時,每經過一個 sigmoid 激發函數,都會衰減至少 0.25 倍([sigmoid微分後的上限為0.25](https://ithelp.ithome.com.tw/m/articles/10237661)),傳遞越多層,衰減越多。由於梯度消失的緣故,不會使用在隱藏層,會用在輸出層(輸出介於 0 到 1 之間)。
* [softmax](https://zhuanlan.zhihu.com/p/25723112):[輸出層激發函數(17:30)](https://www.youtube.com/watch?v=JR8bo75U3fc#t=17m30s)
+ [Loss Function(損失函數)](https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8-%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E4%BB%8B%E7%B4%B9-%E6%90%8D%E5%A4%B1%E5%87%BD%E6%95%B8-loss-function-2dcac5ebb6cb)
- 用來計算模型預測值與預期輸出之間的差異程度,看離目標差多少。
- 迴歸問題常用 [MSE(Mean Squared Error,均方誤差,將誤差值取平方)或 MAE(Mean Absolute Error,平均絕對誤差,將誤差值取絕對值)](https://medium.com/@CinnamonAITaiwan/cnn%E6%A8%A1%E5%9E%8B-%E6%90%8D%E5%A4%B1%E5%87%BD%E6%95%B8-loss-function-647e13956c50)。
- 二元分類問題常用 [Binary Cross-Entropy](https://ithelp.ithome.com.tw/articles/10218158)。
- 多類別分類問題常用 [Categorical Cross-Entropy](https://blog.csdn.net/xg123321123/article/details/80781611)。
$\displaystyle loss=-\frac{1}{N}\sum_{i=1}^{N} y_{i1}log (\hat y_{i1}) + y_{i2}log (\hat y_{i2}) + \cdots +y_{im}log (\hat y_{im})$
+ [Optimizer(優化器)](https://keras.io/zh/optimizers/)
- [梯度下降](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):根據每次輸出結果和實際結果的誤差,重新調整各個神經元的權重、偏差值,使 Loss Function(損失函數)的 Loss(損失值)最小的收斂過程。
- SGD
* Batch Gradient Descent(BGD,批量梯度下降)是一次使用全部訓練資料計算損失函數的梯度,並更新一次權重,效率差。
* Stochastic Gradient Descent(SGD,隨機梯度下降法)是一次隨機抽取一個樣本,計算出一次梯度就更新一次。
* Mini-Batch SGD 是跑小批次(mini-batch)樣本後更新一次。
* BGD、SGD、Mini-Batch SGD 比較
* [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)
* [(進階) 不同 Batch Size 影響比較(p.18~29)](https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/small-gradient-v7.pdf) [(youtube解說)](https://www.youtube.com/watch?v=zzbr1h9sF54)。
- [Momentum(22:41)](https://www.youtube.com/watch?v=zzbr1h9sF54#t=22m41s)
* 模擬物理動量的概念。參數更新方向前會考慮前一次參數更新的方向,如果當下梯度方向和歷史參數更新的方向一致,則會增強這個方向的梯度;若方向不一致,則梯度會衰退。
$v_{t+1}=\alpha v_t-\eta\frac{\partial L}{\partial W_t}$
$W_{t+1}=W_t+v_{t+1}$
* 可以[抑制震盪](https://iace.fun/2019/11/28/shen-du-xue-xi-zhi-you-hua-suan-fa/)加速收斂,並且有[擺脫局部最佳解](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)的能力。
* [Interactive Visualization of Optimization Algorithms in Deep Learning](https://emiliendupont.github.io/2018/01/24/optimization-visualization/)(Momentum:藍)
- (進階) [AdaGrad(9:22)](https://www.youtube.com/watch?v=HYUXEeh3kwY#t=9m22s)
* 解決 SGD 中學習率不能調整的問題,將學習率除以歷史梯度平方和的平方根,使得更新每次參數時的學習率不同。
$\displaystyle w^{t+1}=w^t - \frac{\eta}{\sqrt{\sum_{i=0}^{t}(g^i)^2}}g^t$
* 隨著迭代的次數增加,學習率會逐漸變小,符合直觀上接近最優解時,函數的坡度會越平緩,也必須走的更慢來確保不會穿過最優解。
* 缺點為訓練中後期,分母上梯度平方的累加會越來越大,會導致學習率過早、過量的減少,使得訓練提前結束。
- (進階) [RMSProp(17:18)](https://www.youtube.com/watch?v=HYUXEeh3kwY#t=17m17s)
* 和 AdaGrad 的差別為累積歷史梯度的方法不同。RMSProp 不像 AdaGrad 直接累加梯度平方,而是加了一個衰減係數來控制歷史梯度訊息要獲取多少。
* 改進 AdaGrad 學習率下降過快的問題。
* [Interactive Visualization of Optimization Algorithms in Deep Learning](https://emiliendupont.github.io/2018/01/24/optimization-visualization/)(RMSProp:紅)
- (進階) Adam
* 結合 RMSProp 和 Momentum 的優點,是目前最常使用的優化器。
* [Interactive Visualization of Optimization Algorithms in Deep Learning](https://emiliendupont.github.io/2018/01/24/optimization-visualization/)(Adam:綠)
- (進階) [A Visual Explanation of Gradient Descent Methods (Momentum, AdaGrad, RMSProp, Adam)](https://towardsdatascience.com/a-visual-explanation-of-gradient-descent-methods-momentum-adagrad-rmsprop-adam-f898b102325c)
+ [Backpropagation(反向傳播)](https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2017/Lecture/BP.mp4)
- 反向傳播(誤差反向傳播),是一種與梯度下降法結合使用的方法。當神經網路的構造很複雜時,計算梯度的過程會有大量的重複計算,反向傳播藉由微積分的鏈鎖率(Chain Rule),從神經網路的末端開始計算誤差與各權重的關係,由後往前更新,藉此減少運算量。說明網站參考 [(1)](https://medium.com/ai-academy-taiwan/back-propagation-3946e8ed8c55)、[(2)](https://medium.com/%E4%BA%BA%E5%B7%A5%E6%99%BA%E6%85%A7-%E5%80%92%E5%BA%95%E6%9C%89%E5%A4%9A%E6%99%BA%E6%85%A7/%E5%8F%8D%E5%90%91%E5%82%B3%E6%92%AD%E7%AE%97%E6%B3%95-backpropagation-algorithm-71a1845100cf)、[(3)](https://www.cnblogs.com/charlotte77/p/5629865.html)
- 神經網路圖示
![](https://i.imgur.com/rcpoAyZ.png)
* $w^2_{21}$:上標 2 表示第 2 層的權重。下標 2 表示後一層第 2 個神經元,下標 1 表示前一層第 1 個神經元。
* $z^1_1$:上標 1 表示第 1 層,下標 1 表示此層第 1 個神經元。$z^1_1$ 表示第 1 層 activation function 的輸入 ($z^1_1=x_1w_{11}^1+x_2w_{12}^1$)。
* $a_1^1$:上下標意義與 $z_1^1$ 相同,差別為$a_1^1$ 為 activation function 的輸出 ($a_1^1=\sigma(z_1^1)$)。
* 假設訓練資料只有一筆。
- $\displaystyle \quad \ \hat w_{11}^1=w_{11}^1-\eta \frac{\partial L}{\partial w_{11}^1}$
$\displaystyle \quad \frac{\partial L}{\partial w_{11}^1} =\frac{\partial L}{\partial z_{1}^1} \frac{\partial z_1^1}{\partial w_{11}^1} \ (根據\ Chain\ Rule)$
* 後一項為 Forward pass,對每個參數,計算$\frac{\partial z}{\partial w}$。
例如 $z^1_1=x_1w_{11}^1+x_2w_{12}^1$,$\frac{\partial z_1^1}{\partial w_{11}^1}=x_1$。
所以 Forward pass 會等於此參數的輸入。
* 前一項為 Backward pass,對每個激發函數的輸入z,計算$\frac{\partial L}{\partial z}$。需以 Chain Rule 不斷拆解。
$\begin{align*}
\displaystyle \frac{\partial L}{\partial w_{11}^1} &=\underline{\frac{\partial L}{\partial z_{1}^1}} \frac{\partial z_1^1}{\partial w_{11}^1} \\
&=[\frac{\partial L}{\partial a_{1}^1} \frac{\partial a_1^1}{\partial z_{1}^1}] \frac{\partial z_1^1}{\partial w_{11}^1} \quad (\ \because a_1^1=\sigma(z_1^1) \ \therefore \frac{\partial a_1^1}{\partial z_{1}^1} 為 \sigma^\prime(z_{1}^1)\ )\\
&=[\frac{\partial L}{\partial a_{1}^1} \sigma^\prime(z_{1}^1)] \frac{\partial z_1^1}{\partial w_{11}^1} \\
&=[(\underline{\frac{\partial L}{\partial z_{1}^2}} \frac{\partial z_1^2}{\partial a_{1}^1} + \underline{\frac{\partial L}{\partial z_{2}^2}} \frac{\partial z_2^2}{\partial a_{1}^1}) \sigma^\prime(z_{1}^1)] \frac{\partial z_1^1}{\partial w_{11}^1}\\
&=[(\underline{\frac{\partial L}{\partial z_{1}^2}} w_{11}^2 + \underline{\frac{\partial L}{\partial z_{2}^2}} w_{21}^2) \sigma^\prime(z_{1}^1)] \frac{\partial z_1^1}{\partial w_{11}^1}\\
\end{align*}$
* 上式概念圖示
![](https://i.imgur.com/BKTu2GA.png)
* 如果紅色神經元已經是輸出層
![](https://i.imgur.com/iMyucXA.png =450x)
$\displaystyle \frac{\partial L}{\partial z_{1}^2}=\frac{\partial L}{\partial \hat y_1}\ \frac{\partial \hat y_1}{\partial z_{1}^2} = \frac{\partial L}{\partial \hat y_1}\ \sigma^\prime(z_{1}^2) \quad \quad \frac{\partial L}{\partial z_{2}^2}=\frac{\partial L}{\partial \hat y_2}\ \frac{\partial \hat y_2}{\partial z_{2}^2}$
* 如果紅色神經元不是輸出層(不斷往後展開$\frac{\partial L}{\partial z}$,直到遇到輸出層)
![](https://i.imgur.com/8DTvB3k.png)
- Backpropagation - Backward Pass
* 由輸出層往前,對每個激發函數的輸入z,計算$\frac{\partial L}{\partial z}$,即可節省計算量。
![](https://i.imgur.com/zeNeGzS.png)
- Backpropagation相關公式
* Chain Rule [(教學1)](http://ocw.nctu.edu.tw/course_detail-v.php?bgid=1&gid=1&nid=490&v5=xj8d1cAaJWA)([教學2)](http://aca.cust.edu.tw/online/calculusI/05/05_03_12.html)
$① \quad u=g(x) \quad y=f(u)=f(g(x))
\\ \quad \quad \bigtriangleup x \rightarrow \bigtriangleup u \rightarrow \bigtriangleup y \quad \quad \frac{dy}{dx}=\frac{dy}{du}\frac{du}{dx}$
$② \quad x=g(t) \quad y=h(t) \quad z=f(x,y)$
$\quad \quad$![](https://i.imgur.com/XtN70kf.png =160x)$\quad \ \ \frac{dz}{dt}=\frac{\partial z}{\partial x}\frac{dx}{dt}+\frac{\partial z}{\partial y}\frac{dy}{dt}$
* [Sigmoid 函數($\frac{1}{1+e^{-x}}$)微分](https://blog.csdn.net/weixin_44331401/article/details/103081979)
$\begin{align*}
\sigma^\prime(x) &= \frac{d}{dx}(1+e^{-x})^{-1}\\
&=-(1+e^{-x})^{-2}(-e^{-x})\\
&=\frac{e^{-x}}{(1+e^{-x})^2}\\
&=\frac{1}{1+e^{-x}}\frac{e^{-x}}{1+e^{-x}}\\
&=\sigma(x)(1-\sigma(x))\end{align*}$
* 其它微分公式
[$\displaystyle \frac{d(f(x))^n}{dx}=n(f(x))^{n-1} \times f'(x)$](http://www.math.ncu.edu.tw/~yu/ecocal95/boards/lec12_c_95.pdf)
[$\displaystyle \frac{d}{dx}e^{f(x)}=f'(x)e^{f(x)}$](https://socratic.org/questions/derivative-of-e-2x)
<br/>
:::info
EX_08_2:建立神經網路程式。
Param 50240、4160、650為需要利用梯度下降來訓練的權重數量,完成 [DNN 學習單](https://docs.google.com/spreadsheets/d/1Bc3fuejyCHChblISU96On1HiT8U19uVP/edit?usp=sharing&ouid=118043800222804360069&rtpof=true&sd=true),練習參數數量是如何計算出來。
(每層的權重數量=上一層神經元數量×本層神經元數量+本層每個神經元有一個bias)
:::
``` javascript=
# 以 Sequential Model API 建立標準神經網路
from tensorflow.keras.models import Sequential # Sequential Model(順序式模型)是一種簡單的模型,是將神經網路層線性堆疊的建模方式。單一輸入、單一輸出,按順序一層(Dense)一層的由上往下執行。
from tensorflow.keras.layers import Dense # Dense為全連階層
model = Sequential() # 建一個空的神經網路(sequential的model)
model.add(Dense(units=64, activation='relu', input_shape=(784,))) # 增加第一層隱藏層,64個神經元,Activation Function 用relu,第一層需要定義輸入尺寸(input_shape)
model.add(Dense(units=64, activation='relu')) # 第二隱藏層
model.add(Dense(units=10, activation='softmax')) # 輸出層有10個神經元,輸出總和為1,使用 softmax activation function,將結果分類
model.summary()
```
``` javascript=
# 以 Functional Model API(Advanced) 建立標準神經網路。
# 更複雜,但也更靈活,明確將一層的輸出連接到另一層的輸入,每個連接都要被指定。
from tensorflow.keras import Model
from tensorflow.keras import layers
# define the layers
x_in = layers.Input(shape=(784,))
x = layers.Dense(64, activation='relu')(x_in)
x = layers.Dense(64, activation='relu')(x)
x_out = layers.Dense(10, activation='softmax')(x)
# define the model
model = Model(inputs=x_in, outputs=x_out)
model.summary()
```
:::info
EX_08_3:輸出層激發函數練習。
輸出層要使用 softmax 或 sigmoid 激發函數將輸出轉為可能的百分比(總和為1),完成 [softmax & sigmoid 學習單](https://drive.google.com/file/d/1qSgIr_doEkry8yL7-vRKutmQr2x2_Qd7/view?usp=sharing),練習計算過程。
:::
:::info
EX_08_4:完成 [Cross Entropy 學習單](https://drive.google.com/file/d/10yI-V85WmXAiRr5RcJrPUX5a9ogbODJ6/view?usp=sharing),練習分類問題損失函數的計算過程。
+ 如果輸出層用 softmax 激發函數輸出各分類機率,一般會用 categorical_crossentropy 作為損失函數。
+ [tf.keras.losses.BinaryCrossentropy
](https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy)
+ [tf.keras.losses.CategoricalCrossentropy
](https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy)
:::
``` javascript=
# 以程式驗證計算是否正確
import tensorflow as tf
import numpy as np
y_true = np.array([1, 0, 1])
y_pred = np.array([0.7, 0.2, 0.6])
bce = tf.keras.losses.BinaryCrossentropy(from_logits=False)
bce(y_true, y_pred).numpy()
```
``` javascript=
import tensorflow as tf
import numpy as np
y_true = np.array([[1,0,0],[0,1,0],[1,0,0],[0,0,1]])
y_pred = np.array([[0.7,0.1,0.2],[0.1,0.8,0.1],[0.9,0.1,0],[0.4,0.3,0.3]])
cce = tf.keras.losses.CategoricalCrossentropy()
cce(y_true, y_pred).numpy()
```
:::info
EX_08_5:完成[正向傳播(forward-propagation)和反向傳播(back-propagation)學習單](https://docs.google.com/spreadsheets/d/10su--e3odIWrMou0nFVQD-5N5ens7iBR/edit?usp=sharing&ouid=118043800222804360069&rtpof=true&sd=true),練習神經網路參數訓練過程。
:::
:::info
EX_08_6:以標準神經網路做手寫數字辨識。
+ [MNIST Demo](https://ufal.mff.cuni.cz/~straka/courses/npfl129/2223/demos/mnist_web.html)
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
#1. 匯入 MNIST 手寫阿拉伯數字數據庫
(x_train, y_train), (x_test, y_test) = mnist.load_data() # 載入MNIST資料庫的訓練資料,並分為「訓練組」及「測試組」
''' 看看載入的資料長什麼樣子
len(x_train) # 訓練資料有6萬筆
len(x_test) # 測試資料有1萬筆
x_train.shape # (60000, 28, 28)
x_train[9999].shape # 28x28
x_train[9999] # 0白色,255黑色,灰階
plt.imshow(x_train[9999], cmap='Greys') # 顯示出圖檔
y_train[9999] # 正確答案
'''
#2. 輸入、輸出格式整理
x_train = x_train.reshape(60000, 784) # 輸入格式整理,將28*28的矩陣改成784*1的矩陣
x_test = x_test.reshape(10000, 784)
y_test_ori=y_test # 保留原始 y_test 後面confusion_matrix 統計時會用到
y_train = to_categorical(y_train,10) # 輸出格式整理,One-hot encoding轉換。例如7->[0,0,0,0,0,0,0,1,0,0],即第7個值為 1
y_test = to_categorical(y_test,10)
# y_train[9999]
```
+ [tf.keras.Model](https://www.tensorflow.org/versions/r2.1/api_docs/python/tf/keras/Model#fit)
+ [np.argmax](https://www.cnblogs.com/zhouyang209117/p/6512302.html)
``` javascript=
from tensorflow.keras.models import Sequential # Sequential Model(順序式模型)是一種簡單的模型,是將神經網路層線性堆疊的建模方式。單一輸入、單一輸出,按順序一層(Dense)一層的由上往下執行。
from tensorflow.keras.layers import Dense, Activation # Dense為全連階層
from tensorflow.keras.optimizers import SGD # 優化器的方法
#3. 建立神經網路模型(2層hidden layers,每層128個神經元)
model = Sequential() # 建一個空的神經網路ze=100, epochs=5) # 一次訓練100筆(100筆調一次
model.add(Dense(units=128, activation='sigmoid', input_shape=(784,))) # 增加第一層隱藏層,128個神經元,,Activation Function 用sigmoid
model.add(Dense(units=128, activation='sigmoid')) # 增加第二層隱藏層,Activation Function 用sigmoid
model.add(Dense(units=10, activation='softmax')) # 有10個神經元,輸出總和為1,使用 softmax activation function,將結果分類
#4. 編譯:選擇優化器(optimizer),損失函數(loss function),learning rate,效能衡量指標(metrics)的類別
model.compile(optimizer=SGD(learning_rate=0.1), loss='mse', metrics=['accuracy']) # 損失函數mse為最小平方法,metrics=['accuracy']訓練過程可隨時知道正確率
model.summary()
#5. 訓練神經網路(以GPU加速->執行階段/變更執行階段類型)
model.fit(x_train, y_train, batch_size=100, epochs=5) # 一次訓練100筆(100筆調一次參數),epochs設定訓練5次。
# 每次訓練完會輸出訓練成果數據(loss、accuracy、val_loss、val_accuracy)。
#6. 模型評估,打分數
score = model.evaluate(x_test, y_test)
print('測試資料的loss:',score[0])
print('測試資料的正確率:',score[1])
#7. 成果測試,指定一張圖
# model.predict(x_test)
# model.predict(x_test)[101]
# np.argmax(model.predict(x_test)[101])
y_test_predict = np.argmax(model.predict(x_test), axis=1)
num=101 # 試試其它測資8、38、87、187、877、1062、1068
plt.imshow(x_test[num].reshape(28,28), cmap="Greys")
print('神經網路判斷為', y_test_predict[num])
#8. 成果測試,改用interact_manual互動輸入
from ipywidgets import interact_manual
def judge(測試編號):
plt.imshow(x_test[測試編號].reshape(28,28), cmap="Greys")
print('神經網路判斷為', y_test_predict[測試編號])
interact_manual(judge, 測試編號=(0,9999))
```
+ [confusion_matrix](https://blog.csdn.net/m0_38061927/article/details/77198990)
+ [pandas.DataFrame](https://oranwind.org/python-pandas-ji-chu-jiao-xue/)
+ [numpy.nonzero](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/366994/)
``` javascript=
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
#9. 以confusion_matrix統計整體預測狀況
pd.DataFrame(confusion_matrix(y_test_ori,y_test_predict))
#10. 印出預測錯誤的圖片(前100張)
false_index=np.nonzero(y_test_predict != y_test_ori)[0] # 預測錯誤的位置
false_img=x_test[false_index] # 預測錯誤的圖片
orig_label=y_test_ori[false_index] # 預測錯誤的原始y值
pred_label=y_test_predict[false_index] # 預測錯誤的預測值
col = 10 # 一列放10張圖(欄)
row = len(false_index)//10 + 1 # 列數用計算的
plt.figure(figsize=(25,500)) # 指定每張圖的寬和高,單位為英吋
for (index,img) in enumerate(false_img):
plt.subplot(row,col,index+1) # plt.subplot(總列,總欄,第幾張圖)
plt.title("Pred:[" + str(pred_label[index])+ "] , Ans:["+ str(orig_label[index]) + "]" )
plt.axis("off")
plt.imshow(img.reshape(28,28), cmap='Greys')
if index==100:
break
```
``` javascript=
#11. 以 Gradio 來展示
!pip install gradio
```
``` javascript=
import gradio as gr
def recognize_digit(img):
img = img.reshape(1,784)
prediction = model.predict(img).flatten() #[[p1,p2...]]->[p1,p2...]
labels = list('0123456789')
return {labels[i]: float(prediction[i]) for i in range(10)} #return 字典
gr.Interface(fn=recognize_digit, inputs="sketchpad", outputs="label").launch()
```
``` javascript=
#12. 模型存檔
# 方法一:同時儲存架構與權重
from tensorflow.keras.models import load_model
model.save('mymodel.h5') # 同時儲存架構與權重,檔案的類型為HDF5
# 模型載入
del model
model.summary() # model 刪除所以未定義
model = load_model('mymodel.h5')
model.summary()
# 方法二:架構與權重分開存
from tensorflow.keras.models import model_from_json
model_jason=model.to_json() # 將神經網路架構轉成json格式
open('mymodel_architecture.json','w').write(model_jason) # 存架構
model.save_weights('mymodel_weights.h5') # 存權重
# 模型載入
del model
model.summary() # model 刪除所以未定義
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.models import model_from_json
with open("mymodel_architecture.json", "r") as input_file:
json_string = input_file.read()
model = Sequential()
model = model_from_json(json_string)
model.load_weights("mymodel_weights.h5", by_name=False)
model.summary()
```
:::info
EX_08_7:以EX_08_6手寫辨識的程式為範例,改用 [Fashion-MNIST 數據庫](https://github.com/zalandoresearch/fashion-mnist/blob/master/README.zh-CN.md),練習建立模型的另一種語法(將所有的網路層放到一個 list 中,作為 Sequential 的參數),並嘗試調整超參數 (Hyperparamters),讓神經網路準確率提昇(0.89 ⭡)。
+ Hyperparameters(超參數):相對於由機器在學習過程中自行調整的parameters(參數),超參數是機器學習中使用者自行調整的參數(例如學習速率、Batch Size、層數、神經元數目…)。
1. 改變神經網路結構
- 改變神經元的數目(128->64、256、512、1024),理論上越多神經元表示迴歸線的特徵數越多,預測應該越準確。
- 將隱藏層增加或減少(2層->3層、1層),理論上越多層表示有越多的迴歸線組合,預測應該越準確。多層訓練的時間會較久。
- 當訓練集loss下降,驗證集loss上升表示過擬合,可[加入 Dropout 層(每次 batch run 隨機丟棄某比例的神經元不予計算),減少過度擬合(1:10:29)](https://www.youtube.com/watch?v=xki61j7z-30#t=1h10m29s)。[<font color="#f77777">Demo</font>](https://colab.research.google.com/drive/1Hn2Q4TxrxNI1BJY4QjatX5MCasNP0TDZ?usp=sharing)
```javascript
# 每個隱藏層後都可加入 dropout 層,看看測試資料的準確率是否會上升。
model.add(Dropout(0.3)) # 隨機丟棄 30% 的神經元
```
2. 編譯參數調整
- 損失函數由 mse 改為 [categorical_crossentropy](https://blog.csdn.net/dou3516/article/details/103364900)(分類問題常用)。
- 優化方式由 SGD 改為 adam(結合 RMSProp 和 Momentum 的優點)。準確率上升的速度會變快。
3. 更換activation function
- activation 用 relu 取代 sigmoid。
- 需把輸入的資料做 normalization(標準化):每張數字圖片是784維,數字介於0~255,把每個數字壓縮到 [0,1] 間,公式為 (x - min) / (max - min),因為顏色範圍為 0~255,所以公式化簡為 x / 255。
``` javascript
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
```
- 輸入做 normalization 也可避免輸入特徵因為不同單位,造成數值大的影響過大。
- 實驗在其它條件不變下,將神經網路加到 10 層,如果激發函數用 sigmoid,準確率會上升或下降?。
PS1. [Deep Learning with TensorFlow 2 and Keras](https://ithelp.ithome.com.tw/articles/10234059) 書中的建議。
PS2. [KerasTuner 超參數優化起手式](https://flag-editors.medium.com/kerastuner-%E8%B6%85%E5%8F%83%E6%95%B8%E5%84%AA%E5%8C%96%E8%B5%B7%E6%89%8B%E5%BC%8F-43c72cb5aa7a)
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten, Dropout
from tensorflow.keras.optimizers import SGD, Adam
#1. 匯入 Fashion-MNIST 數據庫
(x_train, y_train),(x_test, y_test) = fashion_mnist.load_data()
#2. 輸入、輸出格式整理
# 輸入格式整理,將28*28的矩陣改成784*1的矩陣
~
# 多做normalization(標準化),讓數字壓縮到 [0,1] 間。
~
# 輸出格式整理,One-hot encoding轉換。
~
#3. 建立神經網路模型
~
#4. 編譯:選擇優化器(optimizer)、損失函數(loss)、效能衡量指標(metrics)的類別
model.compile(optimizer='....', loss='....', metrics=['accuracy'])
#5. 模型訓練(訓練資料切成兩份,分為訓練集(讀書)和驗證集(20%)(模擬考))
history = model.fit(x_train, y_train, batch_size=100, epochs=5, validation_split=0.2)
#6. 模型評估,打分數
~
# 對訓練過程的準確度繪圖
plt.plot(history.history['accuracy'], 'r') # red
plt.plot(history.history['val_accuracy'], 'b') # blue
# 對訓練過程的損失函數繪圖
plt.plot(history.history['loss'], 'y') # yellow
plt.plot(history.history['val_loss'], 'c') # cyan
```
``` javascript=
#3. 以Sequential函式建立神經網路模型
model = Sequential([
Flatten(input_shape=(28, 28)), # 直接用flatten層,將28*28的矩陣改成784*1的矩陣。所以不需先將28*28的矩陣改成784*1的矩陣
Dense(128, activation='sigmoid'),
Dense(259, activation='sigmoid'),
Dropout(0.5), # 增加 Dropout 層
Dense(10, activation='softmax')
])
```
``` javascript=
#7. 成果測試,隨機挑10張圖
y_test_predict = np.argmax(model.predict(x_test), axis=1)
pick = np.random.randint(1,9999, 10) # 隨機選10個[1,999)間的數字
category = ["T-shirt/top(T恤)", "Trouser(褲子)", "Pullover(套衫)", "Dress(裙子)", "Coat(外套)", "Sandal(涼鞋)", "Shirt(汗衫)", "Sneaker(運動鞋)", "Bag(包)", "Ankle boot(踝靴)"]
plt.figure(figsize=(10,5))
for i in range(10):
plt.subplot(2,5,i+1) # 將圖像區域分為2列5欄,目前位置為i+1
plt.title(category[y_test_predict[pick[i]]]) # 印出預測的種類(英文)
plt.imshow(x_test[pick[i]].reshape(28,28), cmap='Greys')
plt.axis("off")
```
:::success
(進階) 在 matplotlib 中顯示中文
1. 使用一個免費中文字型(如[台北黑體](https://sites.google.com/view/jtfoundry/))到 Colab。
``` javascript
# 下載台北黑體字型
!wget -O taipei_sans_tc_beta.ttf https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download
```
2. 把中文字型加入 matplotlib 字型家族。
``` javascript
import matplotlib
import matplotlib.pyplot as plt
# 新增字體
matplotlib.font_manager.fontManager.addfont('taipei_sans_tc_beta.ttf')
# 設定中文字型及負號正確顯示
plt.rcParams['font.sans-serif'] = 'Taipei Sans TC Beta'
plt.rcParams["axes.unicode_minus"] = False
```
3. 查看 matplotlib 字型名稱,確定已安裝好。
``` javascript
[f.name for f in matplotlib.font_manager.fontManager.ttflist]
```
:::
### 2. CNN(Convolutional Neural Network,卷積神經網路)(PPT)
+ 可以進行『特徵萃取』,是圖形辨識的天王。
- [用全連接神經網路來做影像處理,會需要太多的參數。CNN可簡化神經網路的架構。(討論1~3)](http://debussy.im.nuu.edu.tw/sjchen/AIIntro/NNDL_CNN.pdf)
+ <font color="red">體驗</font>
- [Google AutoDraw](https://www.autodraw.com/)
- [Quick, Draw! 限時塗鴉](https://quickdraw.withgoogle.com/)
- [以圖搜尋](https://www.google.com.tw/imghp?hl=zh-TW&tab=ri&authuser=0&ogbl)
- [APP - Object Detector and Classifier - TensorFlow](https://play.google.com/store/apps/details?id=hash.tf.objectdetection)
- [Yolo:基於深度學習的物件偵測 (含YoloV3) ](https://mropengate.blogspot.com/2018/06/yolo-yolov3.html)
- [圖形辨識的運用-機器手臂(18:00)](https://www.youtube.com/watch?v=UwsrzCVZAb8#t=18m00s)
- [AI 輔助醫療鑑別診斷(21:41)](https://www.youtube.com/watch?v=t-P6bCXz-c4#t=29m41s)
+ 卷積層:擷取局部特徵
- 將濾波器(filter)在輸入圖片上滑動並進行矩陣內積,得到的圖片稱之為特徵圖(feature map)。
- [觀察不同濾波器對圖片卷積運算的結果](https://demo.leemeng.tw/)。
- Q1:filter是人決定還是神經網路自己學習?
* [![](https://i.imgur.com/ErDoBt8.png =100x)](https://i.imgur.com/ErDoBt8.png)
* 卷積層其實只是「不完全連接」的神經網路,神經元的運算方式同DNN。
- Q2:如果有多個卷積層,filter的數量是32→64→128,還是128→64→32、64→64→64會比較好?
* [CNN前面幾層負責識別邊緣或線條等簡單的特徵,後面幾層負責識別更加具體的特徵](http://hk.noobyard.com/article/p-afdkrifz-sd.html)
+ 池化層:降低取樣
- <font color="red">體驗</font>:[2D Visualization of a Convolutional Neural Network](https://adamharley.com/nn_vis/cnn/2d.html)
- 一個特徵相對於其它特徵的粗略位置才是重要的。[subsampling the pixels will not change the object (p.27)](https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/cnn_v4.pdf)
- 池化層會把圖片變小,因此參數的數量和計算量也會下降,降低過擬合問題。
- 如果要偵測的物件很細微,池化層也會讓表現變差。隨著運算能力愈強,近年影像辨識的神經網路架構會不加池化層。
+ Q:CNN在影像放大縮小或旋轉時,還能正確辨識嗎?
- [CNN is not invariant to scaling and rotation (we need data augmentation) (p.35)](https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/cnn_v4.pdf)
- [(進階) Spatial Transformer Layer](https://youtu.be/SoCywZ1hZak
)
+ Q:圖形辨識無敵?如何欺騙神經網路[(1)](https://www.techbang.com/posts/85040-openai-machine-vision-adversarial-typographic-attacka-clip) [(2)](https://finance.ettoday.net/news/1288118)?
- [[李宏毅教授演講]今天的人工智慧 其實沒有你想的那麼厲害(5:21)](https://www.youtube.com/watch?v=YjfzJdimPDA#t=5m21s)
- [(進階) Explainable AI / Adversarial Attack(李宏毅教授 ML 2021 Spring)](https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.html)
+ (進階)[Residual Network](https://medium.com/%E8%BB%9F%E9%AB%94%E4%B9%8B%E5%BF%83/deep-learning-residual-leaning-%E8%AA%8D%E8%AD%98resnet%E8%88%87%E4%BB%96%E7%9A%84%E5%86%A0%E5%90%8D%E5%BE%8C%E7%B9%BC%E8%80%85resnext-resnest-6bedf9389ce):模型更深時,可以進行更加複雜的特徵模式的提取,理論上會有更好的結果,但是更深的網路有時反而帶來更差的效果。
- [Resnet 原理解說](https://www.youtube.com/watch?v=6Ru8RggInsU#t=1h20m28s)
:::info
EX_09:[ResNets 模型(2015年冠軍)](https://ithelp.ithome.com.tw/articles/10192162)可辨識 [1000種類別](https://gist.github.com/yrevar/942d3a0ac09ec9e5eb3a),自己找任意一張圖片,看看 CNN 辨識為?
PS.[預先訓練好的模型 (Keras Applications)](https://ithelp.ithome.com.tw/m/articles/10236654)
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions
model = ResNet50()
# model.summary()
img = load_img('dog.jpg', target_size=(224, 224)) # 載入影像,dog.jpg改為自己的檔名,大小調為224x224(內定)
# img 印出圖片
x = img_to_array(img) # RBG: x.shape = (224, 224, 3) 灰階:(224, 224, 1)
# x
# x.shape
# plt.imshow(x/255)
x = x.reshape(1, 224, 224, 3) # keras 預設是處理批次圖片,所以將圖片的維度改為 x.shape = (1, 224, 224, 3)
# x.shape
x = preprocess_input(x) # 預處理,讓影像辨識度更高(每種模型不同,如明亮度、對比、色調調整…)
# x
# plt.imshow(x.reshape(224, 224, 3)/255)
preds = model.predict(x) # 預測結果,1000維的向量
# preds
print('預測結果:', decode_predictions(preds, top=3)[0])
```
+ [Gradio](https://gradio.app/)
+ [說明文件](https://gradio.app/docs/)
``` javascript=
# 以 Gradio 來展示
!pip install gradio
```
``` javascript=
import gradio as gr
from urllib.request import urlretrieve
# 抓 ImageNet 1000種類別的標籤
urlretrieve("https://raw.githubusercontent.com/yenlung/Deep-Learning-Basics/master/data/imagnet-classes.txt", "imagnet-classes.txt")
with open('imagnet-classes.txt') as f:
labels = [line.strip() for line in f.readlines()] # strip()移除字串頭尾特定的字元(預設為為空格或換行)
# labels
def classify_image(img):
img = img.reshape((-1, 224, 224, 3)) # -1由程式自己判斷
img = preprocess_input(img)
preds = model.predict(img).flatten()
return {labels[i]: float(preds[i]) for i in range(1000)}
gr.Interface(fn=classify_image, inputs=gr.inputs.Image(shape=(224, 224)), outputs=gr.outputs.Label(num_top_classes=3)).launch()
```
:::info
EX_10_1: CNN 結構認識。
(1) 完成 [CNN 學習單](https://drive.google.com/open?id=1wwPYfZg9ieH0P6NCiU_DtKCQD8sEXj7E),練習 CNN 卷積層、池化層的運作。
(2) 以下面程式建立簡易 CNN,練習參數數量是如何計算出來。
:::
``` javascript=
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(28,28,4), activation='relu')) # 為了構建一個非常深的網路,使用填充可以在正向傳播的過程中讓特徵圖的大小保持不變,只使用池化層來縮小。否則就會使得輸入迅速的變小。
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu')) # 第二層64個3x3filter。
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten()) # Flatten 層把多維的輸入一維化,常用在從卷積層到全連接層的過渡。
model.add(Dense(units=256, activation='relu')) # 隱藏層256個神經元
model.add(Dense(units=10, activation='softmax')) # 輸出層有10個神經元,輸出總和為1,使用 softmax activation function,將結果分類。
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
```
:::info
EX_10_2:以 CNN 做手寫數字辨識。
:::
``` javascript=
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
#1. 匯入 MNIST 手寫阿拉伯數字數據庫
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # 載入MNIST資料庫的訓練資料,並分為「訓練組」及「測試組」
#2. 輸入、輸出格式整理
x_train = x_train.reshape(60000, 28, 28, 1) # 輸入格式整理,將28*28的矩陣改成28*28*1的矩陣(灰階只有一個矩陣,正常的圖有RGB三個矩陣)
x_test = x_test.reshape(10000, 28, 28, 1)
x_train = x_train.astype('float32')/255 # nomarlization
x_test = x_test.astype('float32')/255
y_train = to_categorical(y_train,10) # 輸出格式整理,One-hot encoding轉換。例如7->[0,0,0,0,0,0,0,1,0,0],即第7個值為 1
y_test = to_categorical(y_test,10)
```
+ [padding='same' (p.216) ](https://drive.google.com/file/d/1W56bpTuiiJlodAFSwjrf5bQJqJ1cPLEQ/view?fbclid=IwAR13z_93x1lmZhIqLzF0lvEqhZZcwoSpje0B39rLYcUQXeiUjKpMT6LRAuQ)
``` javascript=
#3. 打造CNN神經網路(做3次convolution(filter大小3x3),每次都接max-pooling(2x2為一小區塊))。完成後會送入一個標準的神經網路(1個隱藏層,256個神經元)
from tensorflow.keras.models import Sequential # Sequential Model(順序式模型)是一種簡單的模型,是將神經網路層線性堆疊的建模方式。單一輸入、單一輸出,按順序一層(Dense)一層的由上往下執行。
from tensorflow.keras.layers import Dense, Activation, Flatten # Dense為全連階層,Flatten為CNN完成後的結果為矩陣,要拉成向量再送進一般NN
from tensorflow.keras.layers import Conv2D, MaxPooling2D
model = Sequential() # 建一個空的神經網路(sequential的model)
model.add(Input(shape=(28, 28, 1))) # Keras 不建議將 input_shape 直接傳遞給 Conv2D 或其他層,而應該使用 Input 層來指定輸入形狀。
model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', activation='relu')) # 第一層32個3x3filter。padding='same'輸出大小維持(藉由邊緣補零強化特徵圖邊緣的影響力),
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu')) # 第二層64個3x3filter。
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu')) # 第三層128個3x3filter。
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten()) # Flatten 層把多維的輸入一維化,常用在從卷積層到全連接層的過渡。
model.add(Dense(units=256, activation='relu')) # 隱藏層256個神經元
model.add(Dense(units=10, activation='softmax')) # 輸出層有10個神經元,輸出總和為1,使用 softmax activation function,將結果分類。
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 優化方式使用 adam 可以更快收斂, 並提高準確率。損失函數分類問題常用 categorical crossentropy。
model.summary()
#4. 訓練神經網路(以GPU加速->執行階段/變更執行階段類型)
history = model.fit(x_train, y_train, batch_size=64, epochs=10, validation_split=0.2) # 一次訓練64筆(64筆調一次參數),epochs設定訓練10次。
#5. 模型評估,打分數
score = model.evaluate(x_test, y_test)
print('測試資料的loss:',score[0])
print('測試資料的正確率:',score[1])
# 對訓練過程的準確度繪圖
plt.plot(history.history['accuracy'], 'r') # red
plt.plot(history.history['val_accuracy'], 'b') # blue
# 對訓練過程的損失函數繪圖
plt.plot(history.history['loss'], 'y') # yellow
plt.plot(history.history['val_loss'], 'c') # cyan
```
``` javascript=
#6.成果測試,隨機挑10張圖
y_test_predict = np.argmax(model.predict(x_test), axis=1)
pick = np.random.randint(1,9999, 10) # 隨機選10個[1,999)間的數字
for i in range(10):
plt.subplot(2,5,i+1) # 將圖像區域分為2列5欄,目前位置為i+1
plt.title(y_test_predict[pick[i]])
plt.imshow(x_test[pick[i]].reshape(28,28), cmap='Greys')
plt.axis("off")
```
:::info
EX_10_3:以EX_10_2手寫辨識的程式為範例,改用 Cifar-10 [(1)](https://www.cs.toronto.edu/~kriz/cifar.html) 、[(2)](https://paperswithcode.com/sota/image-classification-on-cifar-10),並調整超參數(Hyperparamters),讓 CNN 準確率提昇(0.75 ⭡)。
+ 程式碼先要修改的地方
- from tensorflow.keras.datasets import cifar10
- (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
- x_train.shape 為 (50000, 32, 32, 3),即是正確輸入,不需像 MNIST 數據庫要 reshape
- CNN 第一層輸入層 shape=(32, 32, 3)
- 預測的結果為數字,請改成文字。
category = ["airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck"]
- plt.title(y_test_predict[pick[i]]) 要改成?
因為之前圖沒有reshape,所以如果要看圖不用加reshape,plt.imshow(x_test[pick[i]])
<br />
調整 CNN 結構(可參考[ CNN 模型設計](https://ithelp.ithome.com.tw/articles/10192028))
[![](https://i.imgur.com/LVgbc2l.png =300x)](https://i.imgur.com/LVgbc2l.png)
+ 將卷積層、池化層增加或減少(3層->2層、4層)。
+ 將 filter(濾波器)增加或減少(32->16、64),
+ 將 kernel_size 增加或減少(3x3->5x5)。
- 較大的 kernel size 會使解析度降低、參數減少、準確度降低。
+ 不一定要每個卷積層後都要加池化層。
+ 將 pool_size 增加或減少(2x2->3x3)。
+ 將 pooling function 改用平均。
- 一般而言,最大池化層保留更多的紋理資訊,而平均池化層保留更多的背景資訊。
```javascript
from tensorflow.keras.layers import AveragePooling2D
model.add(AveragePooling2D(pool_size=(2, 2)))
```
+ 調整最後的全聯結層的單元(256->512)。
+ 在3層的卷積與池化後,加入 Dropout 層,減少過度擬合。
```javascript
model.add(Dropout(0.25))
```
PS1. [[Keras] 使用 CNN 建立 Cifar-10 的分類器 (實戰篇)](https://clay-atlas.com/blog/2019/10/03/python-chinese-tutorial-keras-cnn-cifar10/)
:::
:::info
(進階)EX_10_4:利用 CNN 模型進行 Kaggle 「Dogs vs. Cats」分類
+ 學習『[參考程式](https://colab.research.google.com/drive/1frZC2twBMUBlhjO90BbGed7GXAPV5Fyf?usp=sharing)』裏真實世界圖片的訓練過程。
+ 學習如何以 Dropout、Data Augmentation、遷移學習解決 overfitting。
+ [Batch Normalization](https://www.youtube.com/watch?v=BABPWOkSbLE):可以在較短的時間達到同樣的準確率。
- [Batch Normalization 介紹](https://medium.com/ching-i/batch-normalization-%E4%BB%8B%E7%B4%B9-135a24928f12)
- [深度學習中 Batch Normalization](https://iter01.com/556333.html)
- [什么是批标准化 (Batch Normalization) | 莫烦Python](https://mofanpy.com/tutorials/machine-learning/torch/intro-batch-normalization/)
:::
### 3. RNN(Recurrent Neural Network,循環神經網路)(PPT)
+ 有記憶的神經網路,能夠處理序列變化的輸入資料。例如某個單字的意思會因為前文內容的不同而有不同的含義。可應用在對話機器人、翻譯、生成文章、完成半成品圖、video captioning。
+ <font color="red">體驗</font>:[少女詩人小冰](https://poem.xiaoice.com/)
+ [十分鐘了解RNN的基本概念](https://www.youtube.com/watch?v=6AW80qmaAOk)
![](https://i.imgur.com/DzQy6Gj.png =345x) ![](https://i.imgur.com/2pzsvKC.png =330x)
+ RNN 的問題
- 長序列訓練過程中會有[梯度消失或梯度爆炸](https://www.youtube.com/watch?v=rTqmWlnwz_0#t=13m53s)的問題。
- RNN 會忘掉很早之前看過的訊息。
- RNN 的變形 LSTM (Long Short Term Memory) 與 GRU (Gated Recurrent Units)。
- Bidirectional LSTM:當有一個句子,一般的 LSTM 只會從前面掃過去,但 Bidirectional LSTM 除了從前面掃過去,也會從後面掃過來,類似從後文回推前文。與一般的 LSTM 相比 Bidirectional LSTM 在一些語音辨識、NLP 應用上有更好的效果。
+ [LSTM](https://medium.com/@tengyuanchang/%E6%B7%BA%E8%AB%87%E9%81%9E%E6%AD%B8%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF-rnn-%E8%88%87%E9%95%B7%E7%9F%AD%E6%9C%9F%E8%A8%98%E6%86%B6%E6%A8%A1%E5%9E%8B-lstm-300cbe5efcc3)
- [台大資訊 深度學習之應用 | ADL 4: Gating Mechanism 帶你了解LSTM與GRU的細節](https://www.youtube.com/watch?v=9gW__8-NfU8)
- [LSTM和GRU很難?別擔心,這有一份超生動的圖解](https://kknews.cc/code/vegon84.html)
- [如何从RNN起步,一步一步通俗理解LSTM
](https://blog.csdn.net/v_JULY_v/article/details/89894058)
- 一般 RNN cell 的 hidden state 可視為短期記憶。LSTM 新增的 cell state 可視為長期記憶,並讓其容易一直傳下去(不經過非線性轉換)。
- LSTM 結構, 為什麼可以解決 RNN 的問題?
![](https://i.imgur.com/UX1RoDi.png =330x) ![](https://i.imgur.com/boRwKNS.png =250x)
- 忘記門($f_t$) → 控制上一個步驟的 cell state 要保留多少比例到現在的 cell state。
![](https://i.imgur.com/JlxLh3g.png)
- 輸入門($i_t$) →控制現在新產生的 cell state暫態($\widetilde{C}_t$),有多少比例要被寫入現在的 cell state ($C_t$)。($\widetilde{C}_t$ 即 Vanilla RNN)
![](https://i.imgur.com/BeWI3hs.png)
cell state ($C_t$) update:舊資訊 ($f_t$ 決定之前有多少資訊要忘掉) + 新資訊 ($i_t$ 決定有多少新資訊要更新進來)
![](https://i.imgur.com/ela1621.png)
- 輸出門($o_t$) → 控制上一步驟的結果 $C_t$,有多少資訊要被當成隱藏層輸出。
![](https://i.imgur.com/SuFMGNn.png)
+ [GRU](https://clay-atlas.com/blog/2020/06/02/machine-learning-cn-gru-note/):記憶門、重設門。
:::info
EX_11_1:RNN 結構認識。
(1) 完成 [RNN 學習單](https://drive.google.com/file/d/1NlET1hwgwXGtNB3EitLTdKXsBu6ZBjsQ/view?usp=sharing),練習 RNN 的原理。
(2) 以下面程式建立簡易 RNN 和 LSTM,練習參數數量是如何計算出來。
+ [每個 LSTM cell 參數數量是 RNN 的 4 倍。(p.27)](https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/RNN%20(v2).pdf)
:::
``` javascript=
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, SimpleRNN, LSTM
model=Sequential()
model.add(Embedding(1000, 128)) # 1000 個字,每個字經 One-hot encoding 為 1000 維的向量,轉變成 128 維向量
model.add(SimpleRNN(units=64))
# model.add(LSTM(units=64))
model.add(Dense(units=2,activation='softmax'))
model.summary()
```
:::info
EX_11_2:利用 RNN 進行語句分類(情感/觀點/評論傾向性分析),判斷用戶的評價為正評或負評。
+ 資料集:[中文自然語言處理 Chinese NLP Corpus](https://github.com/InsaneLife/ChineseNLPCorpus) 裏 [waimai_10k 資料集(某外賣平台收集的用戶評價,正向 4000 條,負向約 8000 條)](https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/waimai_10k/intro.ipynb)
+ 架構圖(範例來源2:40)
- 把字換成向量([Text processing and word embedding](https://github.com/wangshusen/DeepLearning/blob/master/Slides/9_RNN_1.pdf))
- RNN Layer
- Classification Layer
![](https://i.imgur.com/eWPLPcZ.jpg =250x)
+ 範例來源:[(1)](https://www.youtube.com/watch?v=ubDtr6dh0c8)、[(2)](https://www.youtube.com/watch?v=SyYIuVJ9BhQ)
:::
``` javascript=
# 1. 載入資料
import pandas as pd
df=pd.read_csv('https://raw.githubusercontent.com/SophonPlus/ChineseNlpCorpus/master/datasets/waimai_10k/waimai_10k.csv')
# df 印出來看看
# df.head() 列出前5筆,df.tail() 列出後5筆
```
+ [Python正则表达式指南](https://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html)
``` javascript=
# 2. 以正則斷字
import re
pattern=re.compile('.{1}') # 告訴compile以這個pattern斷字(每一個字)
# pattern.findall(df.review[0]) 取review這個欄位,看第一列以pattern斷字的結果
myData=[pattern.findall(s) for s in df.review] # 將df斷字結果存在myData
# myData[0:5] 看myData前5句的結果
```
``` javascript=
# 3. 將每個字賦予一個token(標籤化),並將句子以token表示,調整長度
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.preprocessing.text import Tokenizer
# 3_1. 將myData裏每個不重復的字賦予token
tokenizer=Tokenizer(filters='') # filters=''表全部都處理(包含標點符號)
tokenizer.fit_on_texts(myData)
# tokenizer.index_word 每個字都有一個index
# len(tokenizer.index_word) 共有2537個字
# 3_2. 將句子變成token的組合(sequence)
myTxtTensor=tokenizer.texts_to_sequences(myData)
# myTxtTensor[0:5] 看前 5 個sequence
# 3_3. 將每個sequence處理到一樣長度
myTxtTensor=sequence.pad_sequences(
myTxtTensor, # 要處理的sequence
padding='post', # 長度不夠補在後面,補前面?請Google
truncating='post', # 長度過長刪後面
maxlen=30 # 可試試其它數字
)
# myTxtTensor[0:5] 看前3個sequence經長度處理後的結果
```
``` javascript=
# 4. 觀察 Embedding layers 轉換出的向量
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, SimpleRNN, LSTM
# 參數設定
numWords=len(tokenizer.index_word) # 單字數量,為embedding layer 的輸入維度
embedding_dim=5 # embedding layer 的輸出維度(自訂),練習完改為128(可試試其它數字)
embedding_layer=Embedding(numWords+1,embedding_dim) # 輸入的input_dim為有多少字,因為補0,所以總數+1。
# import tensorflow as tf
# embedding_layer(tf.constant([13,30,1])) 輸出維度為5的向量
```
``` javascript=
# 5. 建立 RNN model,編譯,訓練
model = Sequential()
model.add(Embedding(numWords+1,embedding_dim))
model.add(SimpleRNN(units=128)) # 最原始RNN,或 model.add(LSTM(units=128)),神經元數量可與embedding_dim不同
model.add(Dense(units=2,activation='softmax'))
# model.summary()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # sparse_categorical_crossentropy 適用於整數編碼形式的標籤,categorical_crossentropy 適用於 one-hot encoded 形式的標籤。
model.fit(myTxtTensor,df.label,epochs=5)
```
``` javascript=
# 6. 輸入自己的評語
newSen=pattern.findall('又油又咸,很难吃') # 評語轉成簡體
# newSen
newSen=[newSen] # check myTxtTensor[0:5] 輸入為[[],[]]2維,所以把newSen變成2維
# newSen
~ # 3_2. 將句子變成token的組合(sequence)
# newSen
~ # 3_3. 將每個sequence處理到一樣長度
# newSen
model.predict(newSen) # 各類的機率[第0類(負向)機率,第1類(正向)機率)
```
``` javascript=
# 7_1. 改用 Bidirectional LSTM
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, LSTM, Bidirectional
model.add(Bidirectional(LSTM(units=128)))
# 7_2. 或接2層以上
model.add(SimpleRNN(units=128, return_sequences=True)) # return_sequences=True 可讓第一層SimpleRNN返回完整的序列,以便作為第二層SimpleRNN的輸入
model.add(SimpleRNN(units=128))
```
+ [RNN任務類型](https://ithelp.ithome.com.tw/articles/10267429)
+ (進階) [文本生成(Text generation)](https://youtu.be/10cjvcrU_ZU)
+ [機器翻譯(Machine translation),Sequence-to-Sequence Model(Seq2Seq)](https://youtu.be/gxXJ58LR684) (PPT)
- 常見的 sequence-to-sequence (Seq2Seq) model 為 encoder-decoder model,把兩個 RNN 結合在一起。
- 訓練階段模型
![](https://i.imgur.com/Hs6Rl0w.png)
- 預測階段模型
![](https://i.imgur.com/CklRz0o.png)
- Encoder 可將連續的輸入(如文字、聲音訊號…),壓縮成指定長度的向量,這個向量可以想像為整個輸入的抽象表示,包含了原序列的重要訊息。
- Decoder 接受 Encoder 輸出的向量來生成文字,一次輸出一個結果,每次的輸出會影響下一次的輸出。
+ [Attention Mechanism (注意力機制)](https://www.youtube.com/watch?v=XhWdv7ghmQQ) (PPT)
- Attention 是為了解決訊息過長,訊息遺忘的問題。透過注意力機制,Decoder 在生成新序列的每個元素時都能動態地考慮自己要看哪些 Encoder 的向量。
- 把輸入的每個文字視為 <Key, Value> 所構成,輸出的每個文字視為 Query。透過計算 Query 和每個 Key 的相似性,得到每個 Key 對應 Value 的權重係數 $\alpha$ (代表輸入訊息的重要性),Context vector 為 Value 的加權和 。
* Q:query( 前一個 Decoder 的輸出狀態,要去 match Enocder 狀態)
* K:key( 要被 match 的 Encoder 狀態)
* V:value( Encoder 狀態要被抽取出來的資訊)
+ [Self-attention](https://www.youtube.com/watch?v=Vr4UNt7X6Gw) (PPT)
:::info
(進階)EX_11_3:利用 Seq2Seq 模型進行機器翻譯(英翻中)。
+ 學習『[參考程式](https://colab.research.google.com/drive/16F23DXr0xuwjKrLdabjS6xps95qrAP6D?usp=sharing)』,理解Seq2Seq 模型的建模方式。([參考網站](https://blog.csdn.net/PIPIXIU/article/details/81016974))
+ 下載訓練資料 [cmn.txt](https://drive.google.com/file/d/16IkKs9FYItP9Umnonk5yrGSUGUmWDerr/view?usp=sharing) 上傳至 Colab。
- 訓練資料由 [Anki](https://www.manythings.org/anki/) 中取前5000筆(全部使用Colab會記憶體不足)
:::
### 4. Transformer(PPT)
+ Transformer 為基於自注意力機制(self-attention mechanism)的 Sequence-to-sequence(Seq2seq) 模型,解決RNN無法有效平行運算的問題。近年在圖像描述、聊天機器人、語音辨識以及機器翻譯等各大領域大放異彩。
+ <font color="red">體驗</font>
- [InferKit's text generation](https://app.inferkit.com/demo)
- [Hokkien Translation](https://huggingface.co/spaces/facebook/Hokkien_Translation)
- [ChatGPT](https://openai.com/blog/chatgpt/)
* [原理說明:一路到 ChatGPT: 生成語言 AI 的原理與應用](https://www.youtube.com/watch?v=kexXNAWvugg)
* [终于有人把chatGPT说清楚了——全网最深入浅出的chatGPT原理科普,包你看懂
](https://www.youtube.com/watch?v=DI4J2n1nfPw)
+ [Transformer(1)](https://www.youtube.com/watch?v=aButdUV0dxI)[ (筆記)](https://andy6804tw.github.io/2021/07/27/attention-without-rnn/)、[(2)](https://www.youtube.com/watch?v=aJRsr39F4dI)
+ [详解Transformer (Attention Is All You Need)](https://zhuanlan.zhihu.com/p/48508221)
+ [李宏毅教授【機器學習2021】自注意力機制 (Self-attention) (上)](https://www.youtube.com/watch?v=hYdO9CscNes)、[(下)](https://www.youtube.com/watch?v=gmsMY5kc-zw)、[Transformer (上)](https://www.youtube.com/watch?v=n9TlOhRjYoc)、[(下)](https://www.youtube.com/watch?v=N6aRv06iv2g)
+ [七天看懂自然語言處理的七年演進](https://tw.coderbridge.com/series/2ec9cf0af3f74ed99371952f4849ae33)
+ [淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中](https://leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html)
+ [自然語言處理技術簡介 – 那些常見的 NLP 分析處理技術與範例](https://inbound.technology/%E8%87%AA%E7%84%B6%E8%AA%9E%E8%A8%80%E8%99%95%E7%90%86%E6%8A%80%E8%A1%93%E7%B0%A1%E4%BB%8B-%E9%82%A3%E4%BA%9B%E5%B8%B8%E8%A6%8B%E7%9A%84-nlp-%E5%88%86%E6%9E%90%E8%99%95%E7%90%86%E6%8A%80%E8%A1%93/)
+ [BERT(預訓練 Transformer 模型)](https://www.youtube.com/watch?v=UlC6AjQWao8) (PPT)
+ [ELMO, BERT, GPT](https://www.youtube.com/watch?v=UYPa347-DdE)
+ [3Blue1Brown:But what is a GPT? Visual intro to transformers(Deep Learning Chapter 5)](https://www.youtube.com/watch?v=wjZofJX0v4M&t=705s)
+ [3Blue1Brown:Attention in transformers, visually explained(Deep Learning Chapter 6)](https://www.youtube.com/watch?v=eMlx5fFNoYc)
:::info
EX_12_1:[體驗 Transformers](https://zhuanlan.zhihu.com/p/390819358)
+ [Hugging Face 的 Transformers](https://huggingface.co/transformers) 提供很多套件,pipeline API 將模型的預處理、後處理等步驟包裝起來,指定好任務名稱後,輸出文本,即可直接得到結果。
+ 目前支持的 pipeline 如下:
- feature-extraction(get the vector representation of a text)(特徵抽取)
- fill-mask(填字)
- ner(named entity recognition)(命名實體識別)
- question-answering(問答)
- sentiment-analysis(情意分析)
- summarization(摘要)
- text-generation(文本生成)
- translation(翻譯)
- zero-shot-classification(零樣本分類)
+ 練習『[參考程式](https://colab.research.google.com/drive/18610AJjSVt4VWG198WpqXhsyCRYIJzYJ?usp=sharing)』裏 Transformers 的應用。
:::
:::info
EX_12_2:[體驗 BERT](https://axk51013.medium.com/%E5%BF%AB%E9%80%9F%E4%BD%BF%E7%94%A8%E8%B6%85%E5%BC%B7nlp-model-bert-db9c2a331b0f)
+ [Sentence-Transformers](https://sbert.net/) 將 BERT 常見的操作整理成 Package。
``` javascript=
pip install -U sentence-transformers
```
+ [clip-ViT-B-32](https://huggingface.co/sentence-transformers/clip-ViT-B-32) 這個模組可以同時encode圖片跟文字,並計算文字敘述跟圖像內容的相似程度。
:::
<br />
## [五、強化學習(Reinforcement Learning、RL)](https://hackmd.io/@cube/r1v4t7wvs)
## 六、GAN(Generative Adversarial Network,生成對抗網路)