###### tags: `選修` # 人工智慧導論 + 部份範例來源 - [成為python數據分析達人的第一課(自學課程)](http://moocs.nccu.edu.tw/course/123/intro) - 教育部中小學人工智慧教育教學示範例系列-和AI做朋友,從0開始學AI - [Coursera 吴恩达机器学习 课后作业题](https://blog.csdn.net/m0_37867091/category_9817315.html) + 評量方式 - 上課練習 40% - 筆試 40% - 專案 ::: info Kaggle競賽-鐵達尼號生存預測 + [Kaggle](https://www.kaggle.com/) + [Titanic - Machine Learning from Disaster](https://www.kaggle.com/c/titanic) + 分數計算:Score*100 + 你可以參考別人的程式碼,但請搞懂你寫下的每一行。 + 檢核方式為老師會隨機抽問2行程式碼,請你解釋其目的或語法,回答不出來每次-30分。 ::: - 上課表現 20% ## 零、環境 + [Google Colaboratory](https://colab.research.google.com/) - [GPU 加速](https://www.youtube.com/watch?time_continue=2&v=-P28LKWTzrI&feature=emb_logo) * Runtime / Change runtine type / Hardware accelerator / GPU * 執行階段/變更執行階段類型/硬體加速器/GPU - 學習歷程檔案筆記 + [Anaconda](https://www.anaconda.com/) - Jupyter Notebook + 相關套件 - [Scikit-learn](https://scikit-learn.org/stable/) * 建立於 NumPy, SciPy 之上的 Python 機器學習套件,內建許多常見的機器學習演算法 。 - [Pandas](https://pandas.pydata.org/) - [Matplotlib](https://matplotlib.org/) - [openAI gym](https://gym.openai.com/) - [TensorFlow](https://www.tensorflow.org/) - [Keras](https://keras.io/) + 學習歷程檔案 - 最後一週上課結束前如果認證完成,學期總成績加分。 - 檔案下載後(File / Download .ipynb),以Jupyter Notebook打開,存成HTML檔(File/Download as / HTML),再以[PDF24 Tools](https://tools.pdf24.org/zh/)轉成PDF。 - 如果要將PDF插入到Word中,可用同一網站將PDF轉圖像再插入。 ## 一、大數據(Big Data) + [從儲存、挖掘到溝通,引領產業新面貌:大數據(Big Data)](https://www.stockfeel.com.tw/%E5%BE%9E%E5%84%B2%E5%AD%98%E3%80%81%E6%8C%96%E6%8E%98%E5%88%B0%E6%BA%9D%E9%80%9A%EF%BC%8C%E5%BC%95%E9%A0%98%E7%94%A2%E6%A5%AD%E6%96%B0%E9%9D%A2%E8%B2%8C%EF%BC%9A%E5%A4%A7%E6%95%B8%E6%93%9Abig-data/) + [一次搞懂大數據](https://bigdata.nccu.edu.tw/t/topic/76) + 數據分析三階段 - 把想解決的問題化成函數(數學建模) - 以「歷史資料」找出這個函數(迴歸、機器學習、神經網路) - 評估是否準確 <br /> ## 二、人工智慧(Artificial Intelligence,AI) + [人工智慧在臺灣:產業轉型的契機與挑戰|陳昇瑋研究員](https://www.youtube.com/watch?v=OddYM6aq-zM) + [什麼是人工智慧、機器學習和深度學習?](https://medium.com/@chih.sheng.huang821/%E4%BB%80%E9%BA%BC%E6%98%AF%E4%BA%BA%E5%B7%A5%E6%99%BA%E6%85%A7-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E5%92%8C%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-587e6a0dc72a) + [與高中生談人工智慧與深度學習](https://www.slideshare.net/yenlung/ss-82198270) + <font color="red">體驗:</font> - [自動駕駛車](https://vimeo.com/192179726) - [Vision AI 透過機器學習技術取得圖片的深入分析結果](https://cloud.google.com/vision/)([說明](https://ithelp.ithome.com.tw/articles/10214867)) - [Build with AI | DeepAI](https://deepai.org/) - [Deep Dream](https://deepdreamgenerator.com/) - [PaintsChainer 线稿自动上色服务](https://paintschainer.preferred.tech/) - [Comixify - AI driven story telling](https://comixify.ai/?last=month&sortBy=trend) - [Gogoro線上客服](https://support.gogoro.com/tw) ::: info EX_00:找出生活中人工智慧的應用。 (1) 3人一組。 (2) 介紹1~2分鐘。 (3) 簡介完每組3票,投出表現最好的組別(主題最特別、最有創意、最有可能實現、最夢幻、會改變人類社會…),依得票排名計算小組分數。 ::: + <font color="red">療癒系AI(沒三小路用AI):</font> - [老闆探測器](https://mp.weixin.qq.com/s?__biz=MjM5MTQzNzU2NA==&mid=2651647234&idx=1&sn=d3f69f92dc80cb9ecca1ecf8abd913e7&chksm=bd4dca918a3a438747e34ced5ee75c780ed1a9742fe312578c16f234996a2ebf3d2c6209cf2a&scene=21#wechat_redirect) - [響指撩妹燈光](https://mp.weixin.qq.com/s?__biz=MjM5MTQzNzU2NA==&mid=2651664643&idx=1&sn=6e6fd611e8f00f6a3a1bb0634a82f307&chksm=bd4c16908a3b9f8660457a0d04664a7bb11f61aa17d99d3491c099329d72f07d3f7c8c51d94d&scene=21#wechat_redirect) - [佛臉辨識](https://buzzorange.com/techorange/2019/02/22/find-your-budda/?fbclid=IwAR1r_9h9vnfA95pWZc_bFgsT-mFwz5ddLNTm0Gs8ddXumpu5CMy3cOCbmSk)、[Buddha Matching](https://www.nara-u.ac.jp/buddience/matching/?fbclid=IwAR3UpXKhI8wN861bfVoozJhR_esAXKk_bP_UZx-CSDm2361qSN1XJkpj_-0) <br /> ![](https://i.imgur.com/SHtuGvu.png) + 參考網站 - [有趣的機器器學習系列(莫煩Python)](https://morvanzhou.github.io/tutorials/machine-learning/ML-intro/) - [成為python數據分析達人的第一課(自學課程)](http://moocs.nccu.edu.tw/course/123/intro) - [成為 Python AI 深度學習達人的第一堂課(自學課程)](http://moocs.nccu.edu.tw/course/172/intro) - [深度學習 Deep Learning:中文學習資源整理](https://jerrynest.io/deep-learning-resource/) - [以100張圖理解 Neural Network -- 觀念與實踐](https://ithelp.ithome.com.tw/users/20001976/ironman/1395) - [機器學習入門(Hahow課程)](https://medium.com/jameslearningnote/medium-com-jameslearningnote/home) <br /> ## 三、機器學習(Machine Learning)簡介 + 從訓練資料中擷取出資料的特徵(features),建立判斷基準(模型、函數)對未來做預測。 + [人工智慧的黃金年代:機器學習](https://www.stockfeel.com.tw/%E4%BA%BA%E5%B7%A5%E6%99%BA%E6%85%A7%E7%9A%84%E9%BB%83%E9%87%91%E5%B9%B4%E4%BB%A3%EF%BC%9A%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92/) + [【Keras 深度學習】#1 AI、機器學習、深度學習是什麼?](https://www.youtube.com/watch?v=voUdAAwk52c) ### 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) + <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://ithelp.ithome.com.tw/articles/10197248) + 應用:產品需求預測、保險費用預測、犯罪率預測… + 資料視覺化[(1)](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-5%E8%AC%9B-%E8%B3%87%E6%96%99%E8%A6%96%E8%A6%BA%E5%8C%96-matplotlib-seaborn-plotly-75cd353d6d3f)、[(2)](https://kknews.cc/zh-tw/code/kbaypav.html) :::info EX_01_1:完成[線性迴歸學習單](https://drive.google.com/file/d/1zY8r43kOET3ThdWVJpEOhAqJ_66TyXw6/view?usp=sharing),練習線性迴歸原理。 ::: :::info EX_01_2:使用 Scikit-learn(SKlearn) 實作線性迴歸,將一條線擬合到模擬的(x,y)數據。假設函數為f(x)=1.2x+0.8 ::: + [numpy.linspace](https://numpy.org/doc/stable/reference/generated/numpy.linspace.html) + [numpy.random.rand](https://numpy.org/doc/stable/reference/random/generated/numpy.random.rand.html?highlight=random%20rand) + [numpy.random.randn](https://numpy.org/doc/stable/reference/generated/numpy.matlib.randn.html?highlight=randn#numpy.matlib.randn) + [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= # %matplotlib inline 使用Jupyter Notebook時,讓圖直接呈現在網頁上,Google Colab不用 from sklearn.linear_model import LinearRegression import numpy as np import matplotlib.pyplot as plt #1. 產生模擬資料 x = np.linspace(0, 5, 50) # 取0~5間,均勻的取50個點 y = 1.2*x + 0.8 + np.random.randn(50) # randn(50)產生50個常態分布的亂數(平均值0,標準差1),增加noise。試試用rand(50)會如何? plt.scatter(x, y) # scatter產生散點圖 plt.plot(x,1.2*x+0.8,'r') # 畫出原本的完美函數 #2. 用線性迴歸做預測 X=x.reshape(50,1) # x為[x1,x2,....,x50](1x50的陣列),但SKlearn需要[[x1],[x2],....,[x50]](50x1的陣列) reg = LinearRegression() # 初始化線性迴歸模組 reg.fit(X,y) # 讓線性迴歸模組學習,模組的變數名稱.fit(輸入資料,正確答案) y_predicted=reg.predict(X) # y_predicted為線性迴歸模組預測的結果 plt.plot(x,y_predicted,'b') # 藍線畫出預測的結果 # plt.show() Google Colab不用 ``` :::info EX_01_3:Scikit-learn(SKlearn) 內建一些真實世界的數據,以線性迴歸預測波士頓房價[(特徵說明)](https://ithelp.ithome.com.tw/articles/10235449)。 ::: ``` javascript= import matplotlib.pyplot as plt from sklearn.datasets import load_boston from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error #1. 讀入boston房價資料 boston = load_boston() # 了解boston房價資料資料庫 # boston.feature_names # 資料庫中所有的欄位名稱(features) # print(boston.DESCR) # 解釋資料庫內容 # boston.data.shape # 幾列、幾欄 # len(boston.data) # 筆數 # boston.data # 內容 #2. 切分訓練與測試資料 # x指資料,y指答案 x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2) # x_train.shape # x_test.shape #3. 用線性迴歸做預測 ........ # 初始化線性迴歸模組 ........ # 讓線性迴歸模組學習,模組的變數名稱.fit(輸入資料,正確答案) ........ # y_test_predicted=模組的變數名稱.predicted(要預測的資料),y_test_predicted為線性迴歸模組預測的結果 # 以評估指標MSE(mean squared error均方誤差),評估模型的誤差。MSE越接近0越好。 score=mean_squared_error(y_test,y_test_predicted) print("MSE:",score) #4. 畫出真實價格與預測價格 plt.scatter(y_test, y_test_predicted) plt.xlabel('True Price') plt.ylabel('Predicted Price') plt.plot([0,50],[0,50],'r') # 畫(0,0)(50,50)連成的直線。如果預測正確,點會落在對角線上 ``` + [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=(8,10)) # 單位為英吋 for i, feature in enumerate(boston.feature_names): plt.subplot(5, 3, i+1) # 使用子圖,5列,3欄,第幾張圖 plt.scatter(boston.data[:,i], boston.target, s=1) # s->size plt.xlabel(feature) plt.ylabel('price') plt.tight_layout() # 自動調整繪圖區的大小及間距,使繪圖區、標題、坐標軸標籤等都可完整顯示(不會重疊) ``` :::info EX_01_4(作業):嘗試不使用全部的特徵(13個)來訓練模型,觀察MSE的變化。考驗你的觀察、預測能力,看能不能使用更少的特徵,讓MSE小於26.3。 ::: ``` javascript= x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2, random_state=50) # random_state為隨機種子,確保每次切分資料的結果都相同。 x_train_partial=x_train[:,[0,2,9,12]] # 使用第0,2,9,12個特徵 x_test_partial=x_test[:,[0,2,9,12]] ``` <font color="#fff">[1,3,5,6,7,11,12]->25.26</font> ### 2. KNN(K Nearest Neighbor,K最近鄰居法) + <font color=red>分類,監督式學習</font> + [沒有想像中簡單的簡單分類機 KNN](https://www.slideshare.net/ssuserf88631/knn-51511604) + [KD-Tree 演算法筆記 | YuCheng](https://blog.yucheng.me/post/kd-tree/) + [机器学习算法之K-近邻(KNN)](https://www.biaodianfu.com/knn.html) + [K-D Tree: build and search for the nearest neighbor](https://www.youtube.com/watch?v=ivdmGcZo6U8) + [找出新數據附近的K個鄰居,鄰居是哪一類它就是哪一類](https://ithelp.ithome.com.tw/articles/10197110?sc=iThelpR) (物以類聚->西瓜偎大邊) + [sklearn.neighbors.KNeighborsClassifier()函数解析](https://blog.csdn.net/TeFuirnever/article/details/99818078) :::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)[(欄位說明)](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) + [numpy.arange](https://numpy.org/doc/stable/reference/generated/numpy.arange.html) ``` 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() #2. 切分訓練與測試資料 x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=50) # x_train.shape #3. 初始化 knn 分類模組 knn = KNeighborsClassifier() # 預設 K 值為5 iris_knn=knn.fit(x_train,y_train) #4. 預測 y_test_predicted = iris_knn.predict(x_test) print(y_test_predicted) # 預測的分類 print(y_test) # 標準答案的分類 print(accuracy_score(y_test, y_test_predicted)) # 正確率 ``` :::info EX_02_3:使用 KNN 遇到的最大問題和 K-Means 類似,即如何確定K值? 請探討 EX_02_2 使用不同 K 值,對預測正確率的影響。(將k最大值調為資料集樣本數) :mega: K 值過小會降低分類的精確度。K 值越大,對於異常值越不敏感,但也會使類別之間的界限變得模糊。 ::: ``` javascript= from sklearn.datasets import load_iris from sklearn import neighbors from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import numpy as np import matplotlib.pyplot as plt #1. 讀入鳶尾花資料 iris = load_iris() #2. 切分訓練與測試資料 x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=50) #3. 設定 k 的範圍(先設上限為訓練樣本數的20%),試試看調至50%以上時的準確率 range = np.arange(1, round(0.2 * x_train.shape[0]) + 1) # x_train.shape為(120, 4) #4. 嘗試用不同的 k,建立 knn 分類模組,並求其預測的準確率 accuracies = [] for k in range: ........ # 初始化 knn 分類模組,n_neighbors = ?為參數 ........ # 讓分類模組學習,模組的變數名稱.fit(輸入資料,正確答案) ........ # 預測 x_test 資料 acc = accuracy_score(y_test, y_test_predicted) # 正確率 accuracies.append(acc) #5. 不同 k 對準確率的分佈圖 plt.scatter(range, accuracies) ``` :::info EX_02_4(進階): + KD-Tree 可以解決 Brute Force 效率不佳的問題,假設資料集樣本數為 m,特徵數為 n,當 m>=2^n,KD-Tree 搜尋效果會比較好。例如 1000 個樣本且特徵數不超過 10 個(2^10=1024)的資料集。 + 一但特徵過多,KD-Tree的搜尋效率就會大幅下降,最終變得和暴力搜尋差不多。通常 KD-Tree 適合不超過 20 維的資料集。 + [Ball-Tree](https://www.zhihu.com/question/30957691) 是 KD-Tree 在高維情況下效率不佳的一個解決方法。請搜尋 Ball-Tree 相關演算法,簡介其運作原理。 ::: ### 3. 決策樹(Decision trees) + <font color=red>分類,監督式學習</font> + <font color="red">體驗:</font>[決策樹動手玩](https://ppt.cc/f0nBKx)、[R2D3 - A Decision Tree](http://www.r2d3.us/una-introduzione-visuale-al-machine-learning-1/) + 決策樹直覺且執行效率好,適用於classification及regression資料類型的預測。 + [決策樹學習](http://debussy.im.nuu.edu.tw/sjchen/MachineLearning/final/CLS_DT.pdf) + [決策樹 Decision Tree](https://mropengate.blogspot.com/2015/06/ai-ch13-2-decision-tree.html) + [決策樹(Decision Tree)以及隨機森林(Random Forest)介紹](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%AC3-5%E8%AC%9B-%E6%B1%BA%E7%AD%96%E6%A8%B9-decision-tree-%E4%BB%A5%E5%8F%8A%E9%9A%A8%E6%A9%9F%E6%A3%AE%E6%9E%97-random-forest-%E4%BB%8B%E7%B4%B9-7079b0ddfbda) + [Decision tree 決策樹 — 單純、快速、解釋性高的決策術](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/decision-tree-%E6%B1%BA%E7%AD%96%E6%A8%B9-%E5%96%AE%E7%B4%94-%E5%BF%AB%E9%80%9F-%E8%A7%A3%E9%87%8B%E6%80%A7%E9%AB%98%E7%9A%84%E6%B1%BA%E7%AD%96%E8%A1%93-ef28e0e75a55) :::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= from IPython.display import Image import pydotplus from sklearn import tree import pandas as pd #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) #3. 訓練資料及分類答案 x_train=df[['age','income','student']] y_train=df[['buy_computer']] # print(x_train) # print(y_train) #4. 建立決策樹分類模組 dtree = tree.DecisionTreeClassifier() buyPC_dtree = dtree.fit(x_train, y_train) #5. 畫出決策樹 feature_names = x_train.columns dot_data = tree.export_graphviz(buyPC_dtree, 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)[(欄位說明)](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. 預測 y_test_predicted = iris_dtree.predict(x_test) print(y_test_predicted) # 預測的分類 print(y_test) # 標準答案的分類 print(accuracy_score(y_test, y_test_predicted)) # 正確率 ``` ``` javascript= import pydotplus from IPython.display import Image #5. 畫出決策樹 dot_data = tree.export_graphviz(iris_dtree, 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://taweihuang.hpd.io/2016/09/21/%E8%AE%80%E8%80%85%E6%8F%90%E5%95%8F%EF%BC%9A%E4%BB%80%E9%BA%BC%E6%98%AF%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%A9%9F-svm/) + [白話文講解支持向量機(一) 線性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/) + [白話文講解支持向量機(二) 非線性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/) + [支持向量機基礎Foundations of Support Vector Machines (SVM)](http://debussy.im.nuu.edu.tw/sjchen/Project_Courses/ML/SVM.pdf) + [機器學習: 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) - Kernel的手法為在原始空間不好區分的資料(無法線性區分),可以用一個非線性的映射函數,將這些資料轉換到更高維度的空間,或許比較好區分(可線性區分)。 - [SVM with polynomial kernel visualization](https://www.youtube.com/watch?v=3liCbRZPrZA) - [机器学习笔记十四之核函数(Kernel Function)](https://www.devtalking.com/articles/machine-learning-14/) :::info EX_04_1:線性SVM的損失函數為 $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') 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() ``` + [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 svc1 = SVC(C=1,kernel='linear') # 初始化 SVC 分類器,C 為誤差項懲罰系數,核函数選擇線性核 svc1.fit(X,y.flatten()) # 導入數據讓分類模組學習 svc1.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 產生格點 # plt.scatter(xx.flatten(),yy.flatten()) # 畫出平面上的所有點(先試) z = model.predict(list(zip(xx.flatten(),yy.flatten()))) # 或z = model.predict(np.c_[xx.flatten(),yy.flatten()]) zz = z.reshape(xx.shape) plt.contour(xx,yy,zz) plot_boundary(svc1) plot_data() ``` ``` javascript= #3. C=25 ........ # 初始化 SVC 分類器,C 為誤差項懲罰系數(C=25),核函数選擇線性核 ........ # 導入數據讓分類模組學習 ........ # 分類器準確率為 1.0 (perfect) # 繪製決策邊界 plot_boundary(svc25) plot_data() ``` ### 5. K-Means(K-means clustering,K-平均演算法) + <font color=red>分群,非監督式學習</font> + <font color="red">體驗:</font>[Visualizing K-Means Clustering](http://stanford.edu/class/ee103/visualizations/kmeans/kmeans.html) + [【機器學習】聚類分析 K-means Clustering - Jason Chen's Blog](https://jason-chen-1992.weebly.com/home/-k-means-clustering) + [機器學習: 集群分析 K-means Clustering](https://medium.com/@chih.sheng.huang821/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E9%9B%86%E7%BE%A4%E5%88%86%E6%9E%90-k-means-clustering-e608a7fe1b43) + [非監督式學習 K-means](https://chtseng.wordpress.com/2017/03/03/%E9%9D%9E%E7%9B%A3%E7%9D%A3%E5%BC%8F%E5%AD%B8%E7%BF%92-k-means/) :::info EX_05_1:完成[K-Means學習單](https://drive.google.com/open?id=1B5ekbseevr4THHw4532EtltskNxTVlMf),練習K-Means分群原理。 ::: :::info EX_05_2:使用 Scikit-learn(SKlearn) 以 K-Means 實作非監督式學習分群,將平面上的數據分成四群。 ::: ``` javascript= from sklearn.cluster import KMeans from sklearn.datasets import make_blobs # 載入 scikit-learn 套件中的資料集模組,用來產生資料集 import numpy as np import matplotlib.pyplot as plt #1. 分群資料準備,隨機產生4群資料 points, label = make_blobs(n_samples=1500, centers=4, 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做分群 clf = KMeans(n_clusters=4) # 初始化 KMeans 分群模組,n_clusters為要分成幾群,試試看其它數字 y_predicted = clf.fit_predict(points) # 用 K-Means 分群 #3. 畫出分群結果(並列顯示) plt.figure(figsize=(16, 8)) plt.subplot(1,2,1) # 1列,2欄,第1個位子 plt.title('Original data') ........ # 以 plt.scatter 畫出原圖 ........ # Kmeans分類的結果畫在右側,# 1列,2欄,第2個位子 ........ # 標題為'KMeans' ........ # 畫出分群結果 c=y_predicted[:] ``` :::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)[(欄位說明)](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.cluster import KMeans import matplotlib.pyplot as plt iris = load_iris() x = iris.data[:, 2:4] # 為畫圖方便,簡化只取花瓣(Petal)的長度、寬度來預測 plt.scatter(x[:, 0], x[:, 1]) # plt.scatter(x[:, 0], x[:, 1], c=iris.target) plt.xlabel('petal length') plt.ylabel('petal width') # 試試改以花萼長、寬畫圖 ........ # 初始化 KMeans 分群模組,n_clusters為要分成幾群,試試看其它數字 ........ # 用 K-Means分群 ........ # 畫出分群結果(plt.scatter) ........ # x軸 label ........ # y軸 label ``` ### 6. 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_06_1:完成[階層式分群法學習單](https://drive.google.com/open?id=1_2rDD9NYEvA0Hvd0RIkPXR3nKeEgO5T-),練習聚合法(不同群距離計算方式)的分群原理。 ::: :::info EX_06_2:使用 Scikit-learn(SKlearn) 以聚合法 (agglomerative) 實作非監督式學習分群,將平面上的數據分成四群。 ::: ``` javascript= from sklearn import datasets # 載入 scikit-learn 套件中的資料集模組,用來產生資料集 from sklearn import cluster # 載入 scikit-learn 套件中的分群演算法模組 import numpy as np import matplotlib.pyplot as plt #1. 分群資料準備,隨機產生4群資料 points, label = datasets.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 分群模組做分群 hierarchical = cluster.AgglomerativeClustering(n_clusters=4) # 初始化 AgglomerativeClustering 分群模組 y_predicted = hierarchical.fit_predict(points) # 開始分群 #3. 畫出分群結果 plt.scatter(points[:, 0], points[:, 1], c=y_predicted[:]) ``` :::info EX_06_3:K-Means 與階層式分群法都是基於距離的演算法,這類型的分群演算法適合群間距離單純的資料。如果遇到不能單純使用距離來計算群間的相似度時,會發生什麼事呢?試試其它 linkage criterion 是否能正確分群。 ::: ``` javascript= from sklearn import datasets # 載入 scikit-learn 套件中的資料集模組,用來產生資料集 from sklearn import cluster # 載入 scikit-learn 套件中的分群演算法模組 import numpy as np import matplotlib.pyplot as plt # 產生半月形資料 moon_data, moon_data_labels = datasets.make_moons(n_samples=1500, noise=0.05) # plt.scatter(moon_data[:, 0], moon_data[:, 1], c=moon_data_labels) # 先試試看畫出產生的點,依據不同群給予不同顏色 # 預設的linkage參數ward不行。請多加一個參數 linkage='ward',試試其它 linkage criterion(average、complete、single) 能否正確分群。 ........ # 初始化 AgglomerativeClustering 分群模組,增加linkage='ward'參數。 ........ # 開始分群 ........ # 畫出分群結果 ``` <br /> ## 五、深度學習(Deep Learning)簡介 + <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) + 模擬人類大腦神經元的刺激傳導機制,讓機器自己提取特微、試誤。 + [Machine Learning vs Deeping Learning](https://leonardoaraujosantos.gitbook.io/artificial-inteligence/machine_learning/deep_learning) + [【深度學習】如果電腦有神經,可以教它做什麼?](http://research.sinica.edu.tw/deep-learning-2017-ai-month/) + [機器學習的衰頹興盛:從類神經網路到淺層學習](https://www.stockfeel.com.tw/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E7%9A%84%E8%A1%B0%E9%A0%B9%E8%88%88%E7%9B%9B%EF%BC%9A%E5%BE%9E%E9%A1%9E%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF%E5%88%B0%E6%B7%BA%E5%B1%A4%E5%AD%B8%E7%BF%92/) + [類神經網路的復興:深度學習簡史](https://www.stockfeel.com.tw/%E9%A1%9E%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF%E7%9A%84%E5%BE%A9%E8%88%88%EF%BC%9A%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92%E7%B0%A1%E5%8F%B2/) + [神經網路的復興:重回風口的深度學習](https://www.stockfeel.com.tw/%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF%E7%9A%84%E5%BE%A9%E8%88%88%EF%BC%9A%E9%87%8D%E5%9B%9E%E9%A2%A8%E5%8F%A3%E7%9A%84%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92/) + 應用:語音辨識、影像辨識、自然語言處理、天氣預測、醫療影像辨識、金融股市預測、網路異常入侵偵測、自駕車… + [Keras: 基于 Python 的深度学习库](https://keras.io/zh/) <br /> ## 六、深度學習(Deep Learning)之神經網路結構 + [深度学习 (DS-GA 1008 · 2020 春季 · 纽约大学数据科学中心)](https://atcold.github.io/pytorch-Deep-Learning/zh/) + [部份範例來源:成為 Python AI 深度學習達人的第一堂課(自學課程)](http://moocs.nccu.edu.tw/course/172/intro) ### 1. NN(Neural Network) (1) 原理: + [與高中生談人工智慧與深度學習](https://www.slideshare.net/yenlung/ss-82198270) + 不管多麼複雜的函數,都可以用非線性函數組合出近似函數。 (2) <font color="red">體驗:</font> + [MNIST Demo](https://mnistdemo.herokuapp.com/) + [Teachable Machine](https://teachablemachine.withgoogle.com/) - [Epochs(訓練次數)](https://ithelp.ithome.com.tw/articles/10207424):當一個完整的資料集,在神經網路正向傳播及反向傳播一次,稱為一個epoch。 例如將epochs設為50,則資料集會訓練50次。 - [Batch Size](https://ithelp.ithome.com.tw/articles/10221227):一次訓練的樣本數量,每處理完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) + [A Neural Network Playground](http://playground.tensorflow.org/) - [Tensorflow Playground 筆記](https://ithelp.ithome.com.tw/articles/10218185) - [如何通過玩TensorFlow Playground來理解神經網絡](https://kknews.cc/tech/xvrop9.html) - Ratio of training to test data:設定訓練資料與測試資料的比例。 - Back Progagation(反向傳播):根據每次輸出結果和實際結果的誤差,重新調整各個神經元的權重,直至收斂到誤差值(Loss)最小。 - Learning rate(學習率):[learning rate 的改變對訓練過程的影響。](https://ithelp.ithome.com.tw/articles/10220441) - Activation(激活函數):可將輸入數值做非線性轉換。 - Regularization(正規化):用來止overfitting(過度擬合)。 * [Generalization: Peril of Overfitting](https://developers.google.com/machine-learning/crash-course/generalization/peril-of-overfitting) * [防止過度擬合的8種簡單技術](https://kknews.cc/zh-tw/code/kk2qno8.html) * [Overfitting 與 L1 /L2 Regularization](https://ithelp.ithome.com.tw/articles/10219648) * [Regularization for Sparsity: L₁ Regularization](https://developers.google.com/machine-learning/crash-course/regularization-for-sparsity/l1-regularization) * [L1 , L2 Regularization 到底正則化了什麼 ?](https://allen108108.github.io/blog/2019/10/22/L1%20,%20L2%20Regularization%20%E5%88%B0%E5%BA%95%E6%AD%A3%E5%89%87%E5%8C%96%E4%BA%86%E4%BB%80%E9%BA%BC%20_/) - [練習 Neural Networks: Playground Exercises](https://developers.google.com/machine-learning/crash-course/introduction-to-neural-networks/playground-exercises) :::info EX_07_1:A Neural Network Playground練習。 調整各項參數,以最少的隱藏層、神經元完成 Spiral 圖形的訓練(500次Epoch,Test loss < 0.01),將畫面截圖上傳。 ::: + [Keras 模型、函數及參數使用說明](https://ithelp.ithome.com.tw/articles/10191725) + [Activation Function(激活函數)](https://codingnote.cc/zh-tw/p/176736/) - 提供非線性函數的轉換外,也是一種門檻(Threshold)的過濾,讓神經元的參數能更快的收斂。 - 如果沒有激活函數,不管神經網路有多少層,都只能學習到線性方程式。 - [輸出層激活(17:30開始)](https://www.youtube.com/watch?v=JR8bo75U3fc) - [常用激活函數](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會凸顯特徵。 * Tanh(hyperbolic tangent) * sigmoid:由於梯度消失的緣故(反向傳播時,每經過一個sigmoid激活函數,都會衰減至少0.25倍,傳遞越多層,衰減越多),不會使用在隱藏層,會用在輸出層(輸出介於0到1之間)。 * [softmax](https://zhuanlan.zhihu.com/p/25723112) + [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。 + [Optimizer(優化器)](https://keras.io/zh/optimizers/) - 尋找模型參數(權重、偏差值),使Loss function(損失函數)的Loss(損失值)最小的收斂過程。 - [一文弄懂神经网络中的反向传播法——BackPropagation](https://www.cnblogs.com/charlotte77/p/5629865.html) - [【Keras 深度學習】#2 什麼是梯度下降?](https://www.youtube.com/watch?v=TFckEoFW5bE) - [反向傳播的運作原理](https://brohrer.mcknote.com/zh-Hant/how_machine_learning_works/how_backpropagation_work.html) - [梯度下降與自動微分](https://ithelp.ithome.com.tw/articles/10233555) - [梯度下降法 (Gradient Descent)介紹,使用「梯度下降法」決定ML模型中參數修正的「方向」與「步長(step size)](https://ithelp.ithome.com.tw/articles/10218980) - [機器/深度學習-基礎數學(二):梯度下降法(gradient descent)](https://medium.com/@chih.sheng.huang821/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E6%95%B8%E5%AD%B8-%E4%BA%8C-%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D%E6%B3%95-gradient-descent-406e1fd001f) - [機器/深度學習-基礎數學(三):梯度最佳解相關算法(gradient descent optimization algorithms)](https://medium.com/@chih.sheng.huang821/%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) - [常用優化器](https://medium.com/%E9%9B%9E%E9%9B%9E%E8%88%87%E5%85%94%E5%85%94%E7%9A%84%E5%B7%A5%E7%A8%8B%E4%B8%96%E7%95%8C/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92ml-note-sgd-momentum-adagrad-adam-optimizer-f20568c968db) * Stochastic gradient descent, SGD(隨機梯度下降法):GD(梯度下降)是一次使用全部訓練資料計算損失函數的梯度,並更新一次權重,效率差。SBD是一次計算一個Batch(批次),就更新一次權重。 * Momentum:模擬物理動量的概念,在同方向的維度上學習速度會變快,方向改變的時候學習速度會變慢。 * AdaGrad:可根據梯度自動調整學習率。 * Adam:結合Momentum和AdaGrad與的優點,是目前最常使用的優化器。 + [Bias(9:00開始)](https://www.youtube.com/watch?v=JR8bo75U3fc) <br /> :::info EX_07_2:建立標準神經網路程式。 Param 50240、4160、650為需要利用梯度下降來訓練的權重數量,完成 [NN 學習單](https://docs.google.com/drawings/d/13H4BV7pbDtn-YNrPduqh1BVXBkuqPmtwAgpQHnuB8CY/edit?usp=sharing),練習參數數量是如何計算出來。 (每層的權重數量=上一層神經元數量×本層神經元數量+本層每個神經元有一個bias) ::: ``` javascript= 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() ``` :::info EX_07_3:輸出層激活函式練習。 輸出層要使用 softmax 或 sigmoid 激活函式將輸出轉為可能的百分比(總和為1),完成 [softmax & sigmoid 學習單](https://drive.google.com/file/d/1qSgIr_doEkry8yL7-vRKutmQr2x2_Qd7/view?usp=sharing),練習計算過程。 ::: :::info EX_07_4:完成 [Cross Entropy 學習單](https://drive.google.com/file/d/10yI-V85WmXAiRr5RcJrPUX5a9ogbODJ6/view?usp=sharing),練習分類問題損失函數的計算過程。 ::: :::info EX_07_5:完成[正向傳播(forward-propagation)和反向傳播(back-propagation)學習單](https://drive.google.com/file/d/1bQDYZ4nEnwPYBlFJHCVs6eECM1M-zwfC/view?usp=sharing),練習神經網路參數訓練過程。 ::: :::info EX_07_6:以標準神經網路做手寫數字辨識。 ::: ``` javascript= from tensorflow.keras.datasets import mnist from keras.utils import np_utils import tensorflow as tf import numpy as np import matplotlib.pyplot as plt #1. 匯入 MNIST 手寫阿拉伯數字數據庫 (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # 載入MNIST資料庫的訓練資料,並分為「訓練組」及「測試組」 ''' 看看載入的資料長什麼樣子 len(x_train) # 訓練資料有6萬筆 len(x_test) # 測試資料有1萬筆 x_train[9999].shape # 28x28 x_train[9999] # 0白色,255黑色,灰階 plt.imshow(x_train[9999],cmap='Greys') # 顯示出圖檔 y_train[9999] # 正確答案 ''' #2. 輸入、輸出格式整理 x_train_shape = x_train.reshape(60000, 784) # 輸入格式整理,將28*28的矩陣改成784*1的矩陣 x_test_shape = x_test.reshape(10000, 784) y_train_shape = np_utils.to_categorical(y_train,10) # 輸出格式整理,1-hot enconding轉換。例如7->[0,0,0,0,0,0,0,1,0,0],即第7個值為 1 y_test_shape = np_utils.to_categorical(y_test,10) y_train_shape[9999] ``` ``` 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() # 建一個空的神經網路 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(lr=0.1), loss='mse', metrics=['accuracy']) # 損失函數mse為最小平方法,metrics=['accuracy']訓練過程可隨時知道正確率 model.summary() #5. 訓練神經網路(以GPU加速->執行階段/變更執行階段類型) model.fit(x_train_shape, y_train_shape, batch_size=100, epochs=5) # 一次訓練100筆(100筆調一次參數),epochs設定訓練5次。 #6. 模型評估,打分數 score = model.evaluate(x_test_shape, y_test_shape) print('測試資料的loss:',score[0]) print('測試資料的正確率:',score[1]) #7. 成果測試,指定一張圖 y_test_predict = model.predict_classes(x_test_shape) num=101 # 試試其它測資8、38、87、187、877、1062、1068 plt.imshow(x_test[num],cmap="Greys") print('神經網路判斷為',y_test_predict[num]) ``` + [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= from sklearn.metrics import confusion_matrix import pandas as pd import numpy as np #8. 以confusion_matrix統計整體預測狀況 pd.DataFrame(confusion_matrix(y_test,y_test_predict)) #9. 印出預測錯誤的圖片(前100張) false_index=np.nonzero(y_test_predict != y_test)[0] # 預測錯誤的位置 false_img=x_test[false_index] # 預測錯誤的圖片 orig_label=y_test[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, cmap='Greys') if index==100: break ``` ``` javascript= #10. 模型存檔 # 方法一:同時儲存架構與權重 from tensorflow.keras.models import load_model model.save('mymodel.h5') # 同時儲存架構與權重,檔案的類型為HDF5 # 模型載入 del model model.summary() 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() 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() ``` ``` javascript= # 從 Colab 下載、上傳檔案 from google.colab import files files.download('mymodel.h5') # 從 Colab 下載檔案 uploaded = files.upload() # 上傳檔案到 Colab !ls # 用 ls 檢視檔案 ``` :::info EX_07_7:以EX_07_6手寫辨識的程式為範例,改用[Fashion-MNIST 數據庫](https://github.com/zalandoresearch/fashion-mnist/blob/master/README.zh-CN.md),練習建立模型的另一種語法(將所有的網路層放到一個list中,作為tf.keras.models.Sequential的參數),並嘗試調整以下的超參數 (Hyperparamters),並讓神經網路變得更好(訓練速度或準確率)。 1. 改變神經網路結構 - 將隱藏層增加或減少(2層->3層、1層),理論上越多層表示有越多的迴歸線組合,預測應該越準確。多層訓練的時間會較久。 - 改變神經元的數目(128->64、256、512、1024),理論上越多神經元表示迴歸線的特徵數越多,預測應該越準確。 - 加入Dropout層,減少過度擬合。 L1、L2正則化是透過修改損失函數來實現(在損失函數中加上對應的 L1 及 L2 penalty(懲罰項)),而Dropout則是透過修改神經網絡本身的結構來實現(隨機地「刪除」一些神經元)。 ```javascript # 可放在每個全連層後,在訓練週期隨機丟棄25%的神經元,以矯正過度擬合的現象。 tf.keras.layers.Dropout(0.25), ``` 2. 編譯參數調整 - 優化方式由 SGD 改為 adam(加入 momentum、learning rate 變速器)。 - 損失函數由 mse 改為 categorical_crossentropy(分類問題常用)。 - [categorical_crossentropy和sparse_categorical_crossentropy的區別](https://blog.csdn.net/dou3516/article/details/103364900)。 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 ``` 4. 調整[batch_size(64_>128、256)、epochs(5->10、20)](https://medium.com/%E4%B8%89%E5%8D%81%E4%B8%8D%E5%93%AD/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E8%87%AA%E5%AD%B8%E7%AD%86%E8%A8%9809-keras2-0-3e5c9ac1658f)次數。理論上Epoch(訓練次數)越多,預測應該越準確(限epochs 50次內)。 PS. [Deep Learning with TensorFlow 2 and Keras](https://ithelp.ithome.com.tw/articles/10234059)書中的建議。 ::: ``` javascript= import tensorflow as tf import matplotlib.pyplot as plt #1. 匯入 Fashion-MNIST 數據庫 (x_train, y_train),(x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data() #2. Normalization ........ #3. 建立神經網路模型 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation='....'), ........ # Dropout層 tf.keras.layers.Dense(10, activation='softmax') ]) #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. 模型評估,打分數 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 #7. 成果測試,隨機挑10張圖 y_test_predict = model.predict_classes(x_test) pick = np.random.randint(1,9999, 10) # 隨機選10個[1,999)間的數字 category = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker','Bag', 'Ankle boot'] 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]], cmap='Greys') plt.axis("off") ``` ### 2. CNN(Convolutional Neural Network,卷積神經網路) + 可以進行『特徵萃取』,是圖形辨識的超級天王。 + <font color="red">體驗:</font> - [Google AutoDraw](https://www.autodraw.com/) - [Quick, Draw! 限時塗鴉](https://quickdraw.withgoogle.com/) - [百度識圖](http://image.baidu.com/?fr=shitu) - [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&list=PLjq6DwYksrzz_fsWIpPcf6V7p2RNAneKc&index=1) + [[資料分析&機器學習] 第5.1講: 卷積神經網絡介紹](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%AC5-1%E8%AC%9B-%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E7%B5%A1%E4%BB%8B%E7%B4%B9-convolutional-neural-network-4f8249d65d4f) + [卷積神經網路(CNN) 剖析與視覺化](https://ithelp.ithome.com.tw/m/articles/10235547) + [卷積神經網路(Convolutional neural network, CNN) — 卷積運算、池化運算](https://medium.com/@chih.sheng.huang821/%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF-convolutional-neural-network-cnn-%E5%8D%B7%E7%A9%8D%E9%81%8B%E7%AE%97-%E6%B1%A0%E5%8C%96%E9%81%8B%E7%AE%97-856330c2b703) + [Visualizing and Understanding Convolutional Networks](https://darren1231.pixnet.net/blog/post/348281800-visualizing-and-understanding-convolutional-networks) - CNN前面幾層負責識別邊緣或線條等簡單的特徵,後面幾層負責識別更加具體的特徵。 - [學習使用Keras建立卷積神經網路](https://chtseng.wordpress.com/2017/09/23/%E5%AD%B8%E7%BF%92%E4%BD%BF%E7%94%A8keras%E5%BB%BA%E7%AB%8B%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF/) :::info EX_08:[VGG16模型](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) ::: :::danger 上傳圖片至Colab (一) Colab 左側 -> 檔案 ->上傳至工作階段儲存空間 (二) ``` javascript from google.colab import files uploaded = files.upload() # 上傳檔案到 Colab !ls # 用 ls 檢視檔案 for fn in uploaded.keys(): img_name=fn ``` ::: ``` javascript= from tensorflow.keras.applications.vgg16 import VGG16 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions import numpy as np model = VGG16(weights='imagenet', include_top=True) # 使用VGG16模型。include_top=True,表示會載入完整的 VGG16 模型,包括加在最後3層的卷積層 # model.summary() img = image.load_img('dog.jpg', target_size=(224, 224)) # 載入影像,dog.jpg改為自己的檔名,大小調為224x224(內定) # img = image.load_img(img_name, target_size=(224, 224)) # 使用 files_upload()時 # img 印出圖片 x = image.img_to_array(img) # RBG: x.shape = (224, 224, 3) 灰階:(224, 224, 1) # x # x.shape x = np.expand_dims(x, axis=0) # keras 預設是處理批次圖片,所以將圖片的維度改為 x.shape = (1, 224, 224, 3) # x.shape x = preprocess_input(x) # 將數值調整到模型要求的範圍,如0~1或-1~+1 # x preds = model.predict(x) # 預測結果,1000維的向量 print('預測結果:', decode_predictions(preds, top=3)[0]) # 取得前三個最可能的類別及機率。decode the results into a list of tuples (class, description, probability) ``` :::info EX_09_1:CNN結構認識。 (1)Q1:完成[CNN學習單](https://drive.google.com/open?id=1wwPYfZg9ieH0P6NCiU_DtKCQD8sEXj7E),練習CNN卷積層、池化層的運作。 (2)Q2:以下面程式建立簡易CNN,練習參數數量是如何計算出來。 ::: ``` javascript= 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 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_09_2:以CNN做手寫數字辨識。 ::: ``` javascript= import tensorflow as tf import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.datasets import mnist from keras.utils import np_utils #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 = np_utils.to_categorical(y_train,10) # 輸出格式整理,1-hot enconding轉換。例如7->[0,0,0,0,0,0,0,1,0,0],即第7個值為 1 y_test = np_utils.to_categorical(y_test,10) ``` ``` javascript= #3. 打造CNN神經網路(做3次convolution(filter大小3x3),每次都接max-pooling(2x2為一小區塊)) #CNN完成後會送入一個標準的神經網路(1個隱藏層,200個神經元) 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 from tensorflow.keras.optimizers import SGD # 最佳化的方法 model = Sequential() # 建一個空的神經網路(sequential的model) model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(28,28,1), 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加速->執行階段/變更執行階段類型) model.fit(x_train, y_train, batch_size=64, epochs=10) # 一次訓練64筆(64筆調一次參數),epochs設定訓練10次。 ``` ``` javascript= #5. 模型評估,打分數 score = model.evaluate(x_test, y_test) print('測試資料的loss:',score[0]) print('測試資料的正確率:',score[1]) #6.成果測試,隨機挑10張圖 y_test_predict = model.predict_classes(x_test) 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_09_3:以EX_09_2手寫辨識的程式為範例,改用 Cifar-10 [(1)](https://www.cs.toronto.edu/~kriz/cifar.html) 、[(2)](https://blog.csdn.net/u013555719/article/details/79343353),嘗試調整以下的超參數 (Hyperparamters),讓CNN變得更好(訓練速度或準確率)。 ``` javascript= import tensorflow as tf (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data() # x_train.shape為(50000, 32, 32, 3),不需像 MNIST 數據庫要 reshape # 第一層 input_shape要改為(32,32,3) # 因為之前圖沒有reshape,所以如果要看圖不用加reshape plt.imshow(x_test[pick[i]]) ``` 1. 改變CNN結構(可參考[CNN 模型設計](https://ithelp.ithome.com.tw/articles/10192028)) - 將卷積、池化層增加或減少(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)。 - 在深度學習的訓練過程中,Dropout會讓每次batch run都依據機率丟棄一定比例的神經元不予計算。 在3層的卷積與池化後,加入Dropout層,可以減少過度擬合。 ```javascript # 可放在每個全連層後,在訓練週期隨機丟棄25%的神經元,以矯正過度擬合的現象。 model.add(Dropout(0.25)) ``` 2. 調整[batch_size、epochs](https://medium.com/%E4%B8%89%E5%8D%81%E4%B8%8D%E5%93%AD/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E8%87%AA%E5%AD%B8%E7%AD%86%E8%A8%9809-keras2-0-3e5c9ac1658f)次數。 ::: ### 3. RNN(Recurrent Neural Network,遞歸神經網路) + 有記憶的神經網路,能夠處理序列變化的輸入資料。例如某個單字的意思會因為前文內容的不同而有不同的含義。 + <font color="red">體驗:</font> - [少女詩人小冰](https://poem.msxiaobing.com/) + [十分鐘了解RNN的基本概念](https://www.youtube.com/watch?v=6AW80qmaAOk) + [臺北酷課雲 自然語言處理](https://www.youtube.com/watch?v=nBNP4PTQRt0&list=PLm778hWdXOZmpitrb2A-s4u65QTEkMmCF&index=6) + [Recurrent Neural Network 遞迴式神經網路](https://www.slideshare.net/yenlung/recurrent-neural-network-89538572) + [循環神經網路(Recurrent Neural Network, RNN)](https://ithelp.ithome.com.tw/articles/10193469) + 應用:對話機器人、翻譯、生成文章、完成半成品圖 + [長序列訓練過程中會有梯度消失、梯度爆炸的問題](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),進化版 [LSTM](https://www.itread01.com/articles/1476743431.html)、[GRU](https://zhuanlan.zhihu.com/p/32481747) :::info EX_10_1:完成 [RNN 學習單](https://drive.google.com/file/d/1NlET1hwgwXGtNB3EitLTdKXsBu6ZBjsQ/view?usp=sharing),練習 RNN的原理。 ::: :::info EX_10_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) - 把字換成向量(Word Embedding) - 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 TB=pd.read_csv('https://raw.githubusercontent.com/SophonPlus/ChineseNlpCorpus/master/datasets/waimai_10k/waimai_10k.csv') TB # 印出來看看,或以 TB.head() 列出前5筆,TB.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(TB.review[0]) # 看第一列以pattern斷字的結果 myData=[pattern.findall(s) for s in TB.review] # 將TB斷字結果存在myData # myData[0:2] # 看myData前2句的結果 ``` ``` javascript= # 3. 將每個字賦予一個token(標籤化),並將句子以token表示,調整長度 import tensorflow as tf # 3_1. 將myData裏每個不重復的字賦予token tokenizer=tf.keras.preprocessing.text.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:3] 看前3個sequence # 3_3. 將每個sequence處理到一樣長度 myTxtTensor=tf.keras.preprocessing.sequence.pad_sequences( myTxtTensor, # 要處理的sequence padding='post', # 長度不夠補在後面 truncating='post', # 長度過長刪後面 maxlen=30 # 可試試其它數字 ) # myTxtTensor[0:3] # 看前3個sequence經長度處理後的結果 ``` ``` javascript= # 4. 觀察 Embedding layers 轉換出的向量 from tensorflow.keras import layers # 參數設定 numWords=len(tokenizer.index_word) # 單字數量,為embedding layer 的輸入維度 embedding_dim=5 # embedding layer 的輸出維度(自訂),練習完改為250(可試試其它數字) embedding_layer=layers.Embedding(numWords+1,embedding_dim) # 輸入的input_dim為有多少字,因為補0,所以總數+1。 embedding_layer(tf.constant([13,30,1])) # 以[13,30,1]為輸入看embedding layer的結果。13變成[-0.034,0.041,-0.004,0.020,0.043] 5維的vector ``` ``` javascript= # 5. 建立 RNN model RNN_Clf=tf.keras.Sequential() RNN_Clf.add(layers.Embedding(numWords+1,embedding_dim)) RNN_Clf.add(layers.SimpleRNN(units=64)) RNN_Clf.add(layers.Dense(units=2,activation='softmax')) # RNN_Clf.summary() RNN_Clf.compile(optimizer='adam', loss=tf.losses.sparse_categorical_crossentropy, metrics=['accuracy']) RNN_Clf.fit(myTxtTensor,TB.label,epochs=10) ``` ``` javascript= # 6. 輸入自己的評語 newSen=pattern.findall('很好吃,但有點貴。') # newSen newSen=[newSen] # check myTxtTensor[0:3] 輸入為[[],[]]2維,所以把newSen變成2維 # newSen ........ # 3_2. 將句子變成token的組合(sequence) # newSen ........ # 3_3. 將每個sequence處理到一樣長度 # newSen RNN_Clf.predict(newSen) # 各類的機率[第0類(負向)機率,第1類(正向)機率) RNN_Clf.predict_classes(newSen) # 預測為那一類 ``` ## 七、強化學習(Reinforcement Learning) + <font color=red>體驗:</font> - [Generalized advantage estimation demo: learning to run and stand up](https://www.youtube.com/watch?v=SHLuf2ZBQSw) - [Google DeepMind AI Does Parkour - Producing flexible behaviours in simulated environments](https://www.youtube.com/watch?v=g59nSURxYgk) + [強化學習介紹](https://www.itread01.com/content/1540645094.html) + [Open AI Gym 簡介與 Q learning 演算法實作](https://blog.techbridge.cc/2017/11/04/openai-gym-intro-and-q-learning/) + [強化學習 Reinforcement Learning](https://www.slideshare.net/yenlung/reinforcement-learning-90737484) + AlphaGo、自動駕駛 ### 1. 觀念 + 強化學習構想來自心理學的「行為學派」。 + 基於「環境對於機器做出的動作所給予的回饋」學習,在經過學習之後,機器會在不同的環境狀態中選擇最佳的行動(能獲得最多獎勵)。 + 貝爾曼方程(Bellman Equation) - $V(S) = \max_{a}(R(S,a) + \gamma V(S'))$ - $V(S)$:當前狀態的值 - $R(S,a)$:在當前狀態$S$中,選擇行動$a$的獎勵 - $V(S')$:選擇行動$a$,轉移到下個狀態S'的值 - $\gamma$:「衰減係數(discount rate)」(範圍: 0≤γ≤1 ),控制下個狀態的值對當前狀態值的影響力。$\gamma$值愈大,下個狀態的值對當前狀態的值影響愈大。 :::info EX_11_1:完成[Q_Learning學習單](https://drive.google.com/file/d/1LRWXrt3KPj1zAcfeWZYP99SQmr0Ab0UO/view?usp=sharing)第一題,練習貝爾曼方程。 ::: ### 2. Q-Learning + 在 Q-Learning 中,我們把機器在某狀態下執行某行動的「價值」量化為 Q (Quality) 值,這個值愈高愈好。我們會把一個環境下的所有 Q 值存在一個 Q-Table (Q 表) 中。 + ![](https://i.imgur.com/v9L1L2L.png =300x) + 假設某環境下有 3 種狀態,每個狀態下皆可執行 2 種行動,那麼 Q_Table 就會長得像這樣: | Q-Table | ( Action 1 ) | ( Action 2 ) | |---------------|--------------|--------------| | **(State 1)** | $Q(s_1,a_1)$ | $Q(s_1,a_2)$ | | **(State 2)** | $Q(s_2,a_1)$ | $Q(s_2,a_2)$ | | **(State 3)** | $Q(s_3,a_1)$ | $Q(s_3,a_2)$ | + Q 值能夠估計在某狀態下選擇某行動所產生的獎勵( Q 亦稱「價值函數」(Value function) )。 - $Q'(s,a) = R(s,a) + \gamma \max_{a}Q(s_{next},a')$ - $Q'(s,a)$:預估要更新的Q值 - $R(s,a)$:選了這個行動後可以立即獲得的獎勵 - $\max_{a'}Q(s_{next},a')$:經過行動$a$,移動到下一個狀態$s_{next}$後,下一個狀態中 Q 值最大者 + TD(Temporal Difference,時值差異,時間差分)」: TD 值代表新舊 Q 值的差異。 - $TD(s,a) = Q'(s,a) - Q(s,a)$ + 舊的 Q 值加上加權過的 TD 值就是更新後的 Q 值 - $Q^{new}(s,a) = Q(s,a) + \alpha TD(s,a)$ - α (alpha) :「學習速率 (Learning rate)」(範圍: 0<α≤1 ),用來控制 TD 值影響原 Q 值的程度。這個值愈大代表傾向採用新的 Q 值來取代舊 Q 值,也就是變動幅度較大;愈小代表傾向保留舊 Q 值,也就是變動幅度較小。 :::info EX_11_2:完成[Q_Learning學習單](https://drive.google.com/file/d/1LRWXrt3KPj1zAcfeWZYP99SQmr0Ab0UO/view?usp=sharing)第二題,練習Q_Table的更新。 ::: ### 2. [OepnAI Gym](https://gym.openai.com/) + 模擬一個強化學習的環境,讓我們在其上驗證演算法。 + 安裝 OpenAI Gym:Thonny/Tools/Manage plug-ins/Find package from PyPI:「gym」/install :::info EX_12_1:CartPole-v1環境測試([一個隨便亂動的 cartpole](https://www.youtube.com/watch?v=J7E6_my3CHk))。 ::: ``` javascript= import gym env = gym.make('CartPole-v0') # 建立一個 CartPole-v0 環境 env.reset() # 初始化/重設環境狀態 for t in range(200): # 跑 200 個間點 (行動 200 次) env.step(env.action_space.sample()) # sample()可隨機從 action space 中挑選一個動作(往左推或往右推) env.render() # 把目前的環境狀態顯示在畫面上 print('現在是第 {} 個時間點'.format(t+1)) env.close() ``` + 與環境互動 - 機器 (agent)在環境中做出「行動 (action)」後,環境會回傳該行動之「獎勵 (reward)」與該行動完成後環境的「狀態 (observation)」。 - observation: (該行動執行後) 環境的狀態 reward: (該行動執行後) 所獲得的獎勵 done: (該行動執行後) 是否達到終止條件(桿子傾斜得太遠) info: 除錯用的資訊 - ![](https://i.imgur.com/qZqFDeN.png =250x ) :::info EX_12_2:CartPole-v1環境互動測試。每次都隨機採取一個行動,看可以撐多久才死。 ::: ``` javascript= import gym env = gym.make('CartPole-v0') # 建立一個 CartPole-v0 環境 observation = env.reset() # 初始化/重設環境狀態,該函式會回傳環境的初始狀態 total_rewards = 0 for t in range(200): # 讓它跑 200 個間點 (行動 200 次) action = env.action_space.sample() # # sample()可隨機從 action space 中挑選一個動作(往左推或往右推) observation, reward, done, info = env.step(action) # 執行該行動後,回傳獎勵與環境狀態 env.render() # 把目前的環境狀態顯示在畫面上 total_rewards += reward print('現在是第 {} 個時間點,獲得獎勵 {},累計獎勵 {},是否達終止條件? {}'.format(t+1, reward, total_rewards, done)) if done: # 若達終止條件,則結束執行 break env.close() print('已達終止條件,總共獲得獎勵:', total_rewards) ``` + [Space](https://github.com/openai/gym/wiki/CartPole-v0) - Observation Space (狀態空間):存放描述環境的參數。 平台的位置 (-2.4 ~ 2.4) 平台的移動速度 (-∞ ~ +∞) 棒子的傾斜角度 (-41.8° ~ 41.8°) 棒子的末端速度 (-∞ ~ +∞) - Action Space (行動空間):存放有效動作的參數。 Discrete(2)代表該環境中有效的行動為 {0,1},分別代表將平台往左推與往右推。 ::: info EX_12_3:改變移動的策略,看可以撐多久才死。 簡單移動策略:如果棒子向左傾(角度 < 0),則平台向左移以維持平衡;否則往右移。 ::: ``` javascript= # Observation Space 與 Action Space 參數觀察 import gym env = gym.make('CartPole-v0') print(env.observation_space) # Box(4,) print(env.observation_space.high) print(env.observation_space.low) print(env.action_space) # Discrete(2) print(env.action_space.sample()) ``` ``` javascript= # 只往一個方向移動 import gym env = gym.make('CartPole-v0') observation = env.reset() total_rewards = 0.0 for t in range(50): observation, reward, done, info = env.step(0) # action 設為0(往左移)或1(往右移),固定往同一個方向 env.render() total_rewards += reward print("現在是第 {} 個時間點,獲得獎勵 {},累計獎勵 {},是否達終止條件? {}".format(t+1, reward, total_rewards, done)) if done: break env.close() print("環境已達終止條件,總共獲得獎勵:", total_rewards) ``` ``` javascript= import gym import numpy as np env = gym.make('CartPole-v0') # 移動策略:棒子左傾則小車左移,否則右移。 # Bonus:利用其它環境參數,改寫一個比較好的移動策略。 def choose_action(observation): cart_pos, cart_v, pole_ang, pole_v = observation # observation space 中的四個值 return 0 if pole_ang < 0 else 1 # 柱子左傾則小車左移,否則右移 total_rewards = [] for i_episode in range(200): # 一次跑 200 輪測試 observation = env.reset() rewards = 0 for t in range(100): # 每輪最多移動 100 次 observation, reward, done, info = env.step( choose_action(observation) ) env.render() # 註解掉不顯示訓練過程動畫 rewards += reward if done: print("第 {} 輪,移動 {} 次,共獲得獎勵:{}".format(i_episode+1, t+1, rewards) ) total_rewards.append(rewards) break total_rewards = np.array(total_rewards) print("平均獲得獎勵:", total_rewards.mean() ) print("最多的一次:", total_rewards.max() ) # 72 print("最少的一次:", total_rewards.min() ) # 25 ``` + 建立 Q_Table - 建立 Q_Table 時,需要知道「狀態」與「行動」的數量,可以使用 `observation_space` 與 `action_space`。 - Q_Table 中的狀態數量是「有限」的,但是 CartPole-v0 的定義,其四個觀察值都是連續的(「無限」個狀態)。為了克服這個問題,需要將狀態有限化,方法為依觀察值的特性,分成數個「區段」作為狀態。 - 假設某觀察值的上下界是 -40 ~ 40,分成 4 個狀態,可以這樣分配: | 觀察值 | 狀態 | |-------|---------| | -40 ~ -20 | 狀態 1 | | -20 ~ 0 | 狀態 2 | | 0 ~ 20 | 狀態 3 | | 20 ~ 40 | 狀態 4 | - 狀態的數量可以根據「這個狀態是否重要」及「觀察值的分佈程度」而定。若觀察值在某個區間分佈非常密集,而在這個區間中微小的數值差異可能導致結果不同,就可以考慮對這個區間細分多一點狀態。 - 初始化 Q-Table時,一開始表中每個值都是一個固定數字,通常會定為 0;也有[學者指出](http://incompleteideas.net/book/first/ebook/node21.html)給定一個較大的值會有助於學習。 + 行動挑選策略 - 如果只循著 Q 值最高的路(貪婪法)走,就可能會陷入「只會一直走同一條路」的問題。 - 可以採用貪婪法的改良版「ε-貪婪 (ε-greedy, epsilon-greedy)」,讓機器在一定的機率下隨機選擇行動(不參考 Q 值),創造出更多可能性,說不定會發現更好的策略。 + Hyperparameters (超參數) - 相對於由機器在學習過程中自行調整的 parameters (參數,例如 Q-Learning 中的 Q 值),hyperparameters 是機器學習中使用者自行調整的參數 (例如 Q-Learning 的衰減係數與學習速率)。 - 衰減係數與學習速率的大小均要依應用場景調整,為了方便 Q 值收斂,可以將 ε 和學習速率設定成會隨著時間 (episode)而遞減。亦即機器從大膽亂走,到愈來愈相信已經學到的經驗。 ::: info EX_12_4:以Q_Learning實作,讓機器學習到如何讓木棒永遠不會倒。 ::: ``` javascript= import gym import math import numpy as np env = gym.make('CartPole-v0') # 環境中各個觀察值的狀態分配數量 n_buckets = (1, 1, 6, 3) # 四個觀察值分別給予的狀態數量(可自行變更數值,調校看看),1 代表任何值皆表示同一state(也就是這個觀察值其實不重要) # Action 的數量 n_actions = env.action_space.n # 以 Discrete 的 n 屬性,來取得 action 的數量 # 取得各觀察值的上下界 state_bounds = list(zip(env.observation_space.low, env.observation_space.high)) state_bounds[1] = [-0.5, 0.5] # 由於平台移動速度、棒子末端速度原來的上下界是-∞ ~ +∞,範圍過廣,所以自行設定合理的範圍取代(可自行更換數值調校看看) state_bounds[3] = [-math.radians(50), math.radians(50)] #radians() 將角度轉為弧度 # 初始化 Q-Table q_table = np.zeros(n_buckets + (n_actions,)) # np.zeros() 將內部的值都初始化為 0.0,若要用其他值初始化,可以使用 np.full() # 每個 state-action pair 存一個 Q 值,所以產生一個形狀為 (1,1,6,3,2) 的五維陣列,也就是共 1*1*6*3 種「狀態組合」,每種狀態組合會有代表兩種行動的 2 個 Q 值 # 此函式將觀察值轉為狀態組合,用這個狀態組合作為 Q-Table 的索引來找到正確的 Q 值 def get_state(observation, n_buckets, state_bounds): state = [0] * len(observation) for i, s in enumerate(observation): # 依每個觀察值轉為狀態組合 l, u = state_bounds[i][0], state_bounds[i][1] # 每個觀察值範圍的上下限 if s <= l: # 低於下限,分配為值最低的那個狀態 state[i] = 0 elif s >= u: # 高於上限,分配為值最高的那個狀態 state[i] = n_buckets[i] - 1 else: # 範圍內,依比例分配 state[i] = int(((s - l) / (u - l)) * n_buckets[i]) return tuple(state) # 此函式讓機器有 ε 的機率會選擇隨機行動 def choose_action(state, q_table, action_space, epsilon): if np.random.random_sample() < epsilon: # 有 ε 的機率會選擇隨機行動 return action_space.sample() else: # 其他情況下參考 Q-Table 選擇行動 return np.argmax(q_table[state]) # 在 Q-Table 中目前的狀態組合下,選擇擁有最大 Q 值的行動 # 超參數計算(可自行變更調校看看) get_epsilon = lambda i: max(0.01, min(1.0, 1.0 - math.log10((i+1)/25))) # epsilon-greedy,隨時間遞減 get_lr = lambda i: max(0.01, min(0.5, 1.0 - math.log10((i+1)/25))) # 學習速率,隨時間遞減 get_gamma = lambda i: 0.99 # 衰減係數,不隨時間改 # Q-Learning 演算法 for i_episode in range(200): # 跑 200 輪 epsilon = get_epsilon(i_episode) # 取得這一輪的 epsilon-greedy 機率 lr = get_lr(i_episode) # 取得這一輪的學習速率 gamma = get_gamma(i_episode) # 取得這一輪的衰減係數 observation = env.reset() # 每一輪開始都要重設環境狀態 rewards = 0 # 每一輪開始重設累計獎勵 state = get_state(observation, n_buckets, state_bounds) # 計算最初環境是哪個狀態組合 for t in range(250): action = choose_action(state, q_table, env.action_space, epsilon) # 根據目前的狀態組合選擇行動 observation, reward, done, info = env.step(action) # 採取行動,獲得該行動的獎勵及行動後環境的觀察值 env.render() # 註解掉不顯示動畫 next_state = get_state(observation, n_buckets, state_bounds) # 取得下一狀態的狀態組合 rewards += reward # 更新 Q-Table q_next_max = np.amax(q_table[next_state]) # 下一個狀態可以獲得的最大 Q 值 q_table[state + (action,)] += lr * (reward + gamma * q_next_max - q_table[state + (action,)]) # Q_Learning 公式 # 前進下一 state state = next_state if done: # 若達終止條件,則結束執行 print('第 {} 輪,移動 {:3d} 次,共獲得獎勵:{:5.1f} (epsilon={:.4f} learning_rate(alpha)={:.4f} discount_factor(gamma)={:.4f})'\ .format(i_episode+1, t+1, rewards, epsilon, lr, gamma) ) break env.close() ``` <br /> ::: info EX_12_5:以學到的Q_Table,讓木棒永遠不會倒。 ::: ``` javascript= # 程式碼置於env.close()前 observation = env.reset() for t in range(1000): state = get_state(........) # 將觀察值轉為計算狀態組合 action = ........ # 根據 Q-Table 選擇行動,這裡將epsilon參數設為 0.0,防止亂走 ........ # 執行行動 ........ # 把目前的環境狀態顯示在畫面上 print(t) env.close() ``` ## 八、GAN(Generative Adversarial Network,生成對抗網路) + <font color=red>體驗:</font> - [This Person Does Not Exist](https://thispersondoesnotexist.com/) - [A Style-Based Generator Architecture for Generative Adversarial Networks](https://www.youtube.com/watch?v=kSLJriaOumA) - [Image-to-Image Demo](https://affinelayer.com/pixsrv/index.html) - [AI 影像生成動用「GAN 技術」,連舞癡都能跳出超專業舞蹈](https://buzzorange.com/techorange/2018/09/07/ai-makes-video/) - [MakeGirlsMoe - Create Anime Characters with A.I.!](https://make.girls.moe/#/) - [Which Face is Real?](http://www.whichfaceisreal.com/) + [【玩轉GAN模型】什麼是GAN?GAN在紅什麼?](https://www.youtube.com/watch?v=DhjMnFkc5YQ) + [手把手教你生成對抗網路 GAN](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/632449/) + [[機器學習 ML NOTE]Generative Adversarial Network, GAN 生成對抗網路](https://medium.com/%E9%9B%9E%E9%9B%9E%E8%88%87%E5%85%94%E5%85%94%E7%9A%84%E5%B7%A5%E7%A8%8B%E4%B8%96%E7%95%8C/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-ml-note-generative-adversarial-network-gan-%E7%94%9F%E6%88%90%E5%B0%8D%E6%8A%97%E7%B6%B2%E8%B7%AF-c672125af9e6) + [生成對抗模式 GAN 的介紹](https://www.slideshare.net/yenlung/gan-90396897) + [【Keras】基于GAN自动生成动漫头像](https://blog.csdn.net/qq_31804159/article/details/88559101) ::: info EX_13_1:GAN變臉體驗 + [First Order Motion Model for Image Animation](https://aliaksandrsiarohin.github.io/first-order-model-website/) + 以[範例程式](https://colab.research.google.com/drive/12VJNXt4H9WFpkWkTFjEoNJl1eqUJu9GZ?usp=sharing ),自己以手機錄一小段影片,看看變臉效果。 + [MP3care](https://www.pkstep.com/archives/29795) 為影片加聲音 :::