本文作者:Ovien
自由團隊將從0到1 手把手教各位讀者學會(1)Python基礎語法、(2)Python Web 網頁開發框架 – Django 、(3)Python網頁爬蟲 – 周易解夢網、(4)Tensorflow AI語言模型基礎與訓練 – LSTM、(5)實際部屬AI解夢模型到Web框架上。
AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源
在訓練模型時有分參數 & 超參數,所謂的參數就是模型的 weight、bias,能透過向前、向後傳播自己去更新的參數,而超參數就是透過人工調動的參數 : 學習率 (learning rate)、迭代 (iterations)、隱藏層數目 (L) 、隱藏單元數 (?^[1] 、 ?^[2] …),還有之前課程講到的批次量 (batch size)。
上面的重要程度,是筆者在建模型時的習慣,大家可以多做幾次就會找到調超參數的習慣、方法
梯度下降卡在某個局部極小值,而找不到全域極值 (global optimum)
在梯度下降時,因為loss
越來越小,以上圖來說,坡度會逐漸平緩,導數會越來越小,直到趨近於0為止,更新的會極為緩慢,導致梯度不更新,有很多優化器可以解決此問題 : Adam、Rmsprop。
梯度下降是一個複雜的問題,越難分類的任務、深度神經網路越深層,會有越複雜的波峰、波谷、鞍點...。
softmax迴歸是一個可以處理多重標籤決策邊界 (multi-label decision boundaries) 問題。
簡單來說 multi-class 的 label 只會有一類,反之 multi-label 可以有多類;但因考量到本次解夢專題實作需求,本系列教學僅以 multi-class 預測作為教學。
我們要怎麼去分類多個標籤?大家還記得在前面的 binary 的分類時,我們都用 0.5 作為一個 threshold,大於0.5為1,反之為 0 ;multi 的方式也一樣,只是最後輸出,會根據你有n個類別,輸出n個類神經元。
每個類神經元代表的是一類,雲、太陽、月亮這樣是3類,就會有3個類神經元在output layer,如果今天是multi-label,就是像下面英文描述那樣,大於 0.5 的為True,反之為 0 ;Muiti-class 的問題,通常我們會選擇最大的類神經元的作為輸出,不過後來有人發明了softmax,活化輸出;softmax 是一種正規化方式,會將每類答案轉換成 0~1之間的值,而每一類的答案相加後和為1。
%matplotlib inline %config Inline Backend.figure_format = 'retina' import matplotlib.pyplot as plt import pandas as pd import numpy as np import seaborn as sns import warnings from datetime import datetime from matplotlib.colors import ListedColormap from sklearn.datasets import make_classification, make_moons, make_circles from sklearn.metrics import confusion_matrix, classification_report, mean_squared_error, mean_absolute_error, r2_score from sklearn.linear_model import LogisticRegression from sklearn.utils import shuffle from keras.models import Sequential from keras.layers import Dense, Dropout, BatchNormalization, Activation from keras.optimizers import Adam from keras.utils.np_utils import to_categorical import keras.backend as K from keras.wrappers.scikit_learn import KerasClassifier
def make_multiclass(N=500, D=2, K=3): np.random.seed(1) X = np.zeros((N*K, D)) y = np.zeros(N*K) for j in range(K): ix = range(N*j, N*(j+1)) # radius r = np.linspace(0.0,1,N) # theta t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 X[ix] = np.c_[r*np.sin(t), r*np.cos(t)] y[ix] = j fig = plt.figure(figsize=(6, 6)) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlGn, alpha=0.8) plt.xlim([-1,1]) plt.ylim([-1,1]) return X, yX, y = make_multiclass(K=3)
print
出來看一下print(y)
可以發現多了一個2,有3種類別(0,1,2)
model = Sequential() model.add(Dense(128, activation='relu')) model.add(Dense(64, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(16, activation='relu')) model.add(Dense(3, activation='softmax')) model.compile(Adam(lr=0.01), 'categorical_crossentropy', metrics=['accuracy'])
y_cat = to_categorical(y)
print(y_cat,y_cat.shape)
shape
是只有矩陣的維度(只有array與np.array可以,一般list沒有這樣的指令)[[1. 0. 0.] [1. 0. 0.] [1. 0. 0.] ... [0. 0. 1.] [0. 0. 1.] [0. 0. 1.]] (1500, 3)
history = model.fit(X, y_cat, verbose=1, epochs=50) plot_loss_accuracy(history)
Epoch 1/50 47/47 [==============================] - 0s 2ms/step - loss: 0.6006 - accuracy: 0.6880 Epoch 2/50 47/47 [==============================] - 0s 2ms/step - loss: 0.2525 - accuracy: 0.8940 Epoch 3/50 47/47 [==============================] - 0s 2ms/step - loss: 0.0524 - accuracy: 0.9800 . . . Epoch 47/50 47/47 [==============================] - 0s 2ms/step - loss: 0.0213 - accuracy: 0.9927 Epoch 48/50 47/47 [==============================] - 0s 2ms/step - loss: 0.0127 - accuracy: 0.9947 Epoch 49/50 47/47 [==============================] - 0s 2ms/step - loss: 0.0128 - accuracy: 0.9940 Epoch 50/50 47/47 [==============================] - 0s 2ms/step - loss: 0.0150 - accuracy: 0.9947
Tip: 如果覺得訓練的進度條很擾人,可以把verbose
設成0
def plot_multiclass_decision_boundary(model, X, y): x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1 y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 101), np.linspace(y_min, y_max, 101)) cmap = ListedColormap(['#FF0000', '#00FF00', '#0000FF']) Z = model.predict_classes(np.c_[xx.ravel(), yy.ravel()], verbose=0) Z = Z.reshape(xx.shape) fig = plt.figure(figsize=(8, 8)) plt.contourf(xx, yy, Z, cmap=plt.cm.RdYlGn, alpha=0.8) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlGn) plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plot_multiclass_decision_boundary(model, X, y)
y_pred = model.predict_classes(X, verbose=0) print(classification_report(y, y_pred))
precision recall f1-score support 0.0 0.98 1.00 0.99 500 1.0 1.00 0.99 0.99 500 2.0 1.00 0.99 0.99 500 accuracy 0.99 1500 macro avg 0.99 0.99 0.99 1500 weighted avg 0.99 0.99 0.99 1500
※ 本實作為經典 multi-class 的範例,因 multi-label 不會在本次專題中使用,因此暫不做進一步教學,未來若有推出其他實作專題,我們會再與各位讀者進行介紹囉!
自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/
文章同步發布於:第十二屆 IT 挑戰賽部落格