深度學習框架Keras入門保姆教程
theme: smartblue
公眾號:尤而小屋
作者:Peter
編輯:Peter
大家好,我是Peter~
本文介紹3個案例來幫助讀者認識和入門深度學習框架Keras。3個案例解決3個問題:迴歸、二分類、多分類
目錄
為什麼選擇Keras
相信很多小夥伴在入門深度學習時候首選框架應該是TensorFlow或者Pytorch。在如今無數深度學習框架中,為什麼要使用 Keras 而非其他?整理自Keras中文官網:
- Keras 優先考慮開發人員的經驗
- Keras 被工業界和學術界廣泛採用
- Keras 可以輕鬆將模型轉化為產品
- Keras 支持多個後端引擎
- Keras 擁有強大的多 GPU 和分佈式訓練支持
- Keras 的發展得到關鍵公司的支持,比如:谷歌、微軟等
詳細信息見中文官網:https://keras.io/zh/why-use-keras/
主要步驟
使用Keras解決機器學習/深度學習問題的主要步驟:
- 特徵工程+數據劃分
- 搭建神經網絡模型add
- 查看網絡架構summary
- 編譯網絡模型compile
- 訓練網絡fit
- 保存模型save
- 評估模型evaluate
- 評價指標可視化visualize
導入庫
```python import pandas as pd import numpy as np
import matplotlib.pyplot as plt %matplotlib inline
from sklearn import datasets
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import tensorflow as tf from keras import models from keras import layers from keras.models import load_model
np.random.seed(1234) ```
迴歸案例
迴歸案例中使用的是Keras自帶的波士頓房價數據集。
導入數據
In [2]:
```python from keras.datasets import boston_housing
(train_X, train_y), (test_X, test_y) = boston_housing.load_data() ```
In [3]:
train_X.shape # 數據形狀
Out[3]:
(404, 13)
In [4]:
train_X[:3] # 特徵向量值
Out[4]:
python
array([[1.23247e+00, 0.00000e+00, 8.14000e+00, 0.00000e+00, 5.38000e-01,
6.14200e+00, 9.17000e+01, 3.97690e+00, 4.00000e+00, 3.07000e+02,
2.10000e+01, 3.96900e+02, 1.87200e+01],
[2.17700e-02, 8.25000e+01, 2.03000e+00, 0.00000e+00, 4.15000e-01,
7.61000e+00, 1.57000e+01, 6.27000e+00, 2.00000e+00, 3.48000e+02,
1.47000e+01, 3.95380e+02, 3.11000e+00],
[4.89822e+00, 0.00000e+00, 1.81000e+01, 0.00000e+00, 6.31000e-01,
4.97000e+00, 1.00000e+02, 1.33250e+00, 2.40000e+01, 6.66000e+02,
2.02000e+01, 3.75520e+02, 3.26000e+00]])
In [5]:
train_y[:3] # 標籤值
Out[5]:
array([15.2, 42.3, 50. ])
數據標準化
神經網絡中一般輸入的都是較小數值的數據,數據之間的差異不能過大。現將特徵變量的數據進行標準化處理
In [6]:
train_X[:3] # 處理前
Out[6]:
python
array([[1.23247e+00, 0.00000e+00, 8.14000e+00, 0.00000e+00, 5.38000e-01,
6.14200e+00, 9.17000e+01, 3.97690e+00, 4.00000e+00, 3.07000e+02,
2.10000e+01, 3.96900e+02, 1.87200e+01],
[2.17700e-02, 8.25000e+01, 2.03000e+00, 0.00000e+00, 4.15000e-01,
7.61000e+00, 1.57000e+01, 6.27000e+00, 2.00000e+00, 3.48000e+02,
1.47000e+01, 3.95380e+02, 3.11000e+00],
[4.89822e+00, 0.00000e+00, 1.81000e+01, 0.00000e+00, 6.31000e-01,
4.97000e+00, 1.00000e+02, 1.33250e+00, 2.40000e+01, 6.66000e+02,
2.02000e+01, 3.75520e+02, 3.26000e+00]])
針對訓練集的數據做標準化處理:減掉均值再除以標準差
In [7]:
```python mean = train_X.mean(axis=0) # 均值 train_X = train_X - mean # 數值 - 均值
std = train_X.std(axis=0) # 標準差 train_X /= std # 再除以標準差
train_X # 處理後 ```
針對測集的數據處理:使用訓練集的均值和標準差
In [8]:
test_X -= mean # 減掉均值
test_X /= std # 除以標準差
構建網絡
In [9]:
train_X.shape
Out[9]:
(404, 13)
In [10]:
```python model = models.Sequential() model.add(tf.keras.layers.Dense(64, activation="relu", input_shape=(train_X.shape[1], ))) model.add(tf.keras.layers.Dense(64, activation="relu"))
model.add(tf.keras.layers.Dense(1)) # 最後的密集連接層,不用激活函數 model.compile(optimizer="rmsprop", # 優化器 loss="mse", # 損失函數 metrics=["mae"] # 評估指標:平均絕對誤差 ) ```
網絡架構
In [11]:
model.summary()
訓練網絡
In [12]:
python
history = model.fit(train_X, # 特徵
train_y, # 輸出
epochs = 100, # 模型訓練100輪
validation_split=0.2,
batch_size=1,
verbose=0 # 靜默模式;如果=1表示日誌模式,輸出每輪訓練的結果
)
保存模型
In [13]:
```python model.save("my_model.h5") # 保存模型
del model # 刪除現有的模型 ```
In [14]:
model = load_model('my_model.h5') # 加載模型
評估模型
返回的是loss和mae的取值
In [15]:
model.evaluate(test_X, test_y)
4/4 [==============================] - 0s 6ms/step - loss: 16.1072 - mae: 2.5912
Out[15]:
[16.107179641723633, 2.5912036895751953]
history對象
In [16]:
type(history) # 回調的History對象
Out[16]:
keras.callbacks.History
In [17]:
type(history.history) # 字典
Out[17]:
dict
In [18]:
查看history.history字典對象中的信息:keys就是每個評價指標,values其實就是每次輸出的指標對應的值
python
for keys,_ in history.history.items():
print(keys)
loss
mae
val_loss
val_mae
In [19]:
len(history.history["loss"])
Out[19]:
100
In [20]:
history.history["loss"][:10]
Out[20]:
python
[197.65003967285156,
32.76368713378906,
22.73907470703125,
18.689529418945312,
16.765336990356445,
15.523008346557617,
14.131484985351562,
13.04631519317627,
12.62230396270752,
12.256169319152832]
loss-mae
In [21]:
```python
損失繪圖
import matplotlib.pyplot as plt
history_dict = history.history loss_values = history_dict["loss"] mae_values = history_dict["mae"]
epochs = range(1,len(loss_values) + 1)
訓練
plt.plot(epochs, # 循環輪數
loss_values, # loss取值
"r", # 紅色
label="loss"
)
plt.plot(epochs,
mae_values,
"b",
label="mae"
)
plt.title("Loss and Mae of Training") plt.xlabel("Epochs") plt.legend()
plt.show() ```
二分類
使用的是sklearn中自帶的cancer數據集
導入數據
In [22]:
cancer=datasets.load_breast_cancer()
cancer
部分數據信息截圖
```python
生成特徵數據和標籤數據
X = cancer.data y = cancer.target ```
數據標準化
In [24]:
X[:2] # 轉換前
Out[24]:
python
array([[1.799e+01, 1.038e+01, 1.228e+02, 1.001e+03, 1.184e-01, 2.776e-01,
3.001e-01, 1.471e-01, 2.419e-01, 7.871e-02, 1.095e+00, 9.053e-01,
8.589e+00, 1.534e+02, 6.399e-03, 4.904e-02, 5.373e-02, 1.587e-02,
3.003e-02, 6.193e-03, 2.538e+01, 1.733e+01, 1.846e+02, 2.019e+03,
1.622e-01, 6.656e-01, 7.119e-01, 2.654e-01, 4.601e-01, 1.189e-01],
[2.057e+01, 1.777e+01, 1.329e+02, 1.326e+03, 8.474e-02, 7.864e-02,
8.690e-02, 7.017e-02, 1.812e-01, 5.667e-02, 5.435e-01, 7.339e-01,
3.398e+00, 7.408e+01, 5.225e-03, 1.308e-02, 1.860e-02, 1.340e-02,
1.389e-02, 3.532e-03, 2.499e+01, 2.341e+01, 1.588e+02, 1.956e+03,
1.238e-01, 1.866e-01, 2.416e-01, 1.860e-01, 2.750e-01, 8.902e-02]])
In [25]:
``` ss = StandardScaler()
X = ss.fit_transform(X) X[:2] # 轉換後 ```
Out[25]:
python
array([[ 1.09706398e+00, -2.07333501e+00, 1.26993369e+00,
9.84374905e-01, 1.56846633e+00, 3.28351467e+00,
2.65287398e+00, 2.53247522e+00, 2.21751501e+00,
2.25574689e+00, 2.48973393e+00, -5.65265059e-01,
2.83303087e+00, 2.48757756e+00, -2.14001647e-01,
1.31686157e+00, 7.24026158e-01, 6.60819941e-01,
1.14875667e+00, 9.07083081e-01, 1.88668963e+00,
-1.35929347e+00, 2.30360062e+00, 2.00123749e+00,
1.30768627e+00, 2.61666502e+00, 2.10952635e+00,
2.29607613e+00, 2.75062224e+00, 1.93701461e+00],
[ 1.82982061e+00, -3.53632408e-01, 1.68595471e+00,
1.90870825e+00, -8.26962447e-01, -4.87071673e-01,
-2.38458552e-02, 5.48144156e-01, 1.39236330e-03,
-8.68652457e-01, 4.99254601e-01, -8.76243603e-01,
2.63326966e-01, 7.42401948e-01, -6.05350847e-01,
-6.92926270e-01, -4.40780058e-01, 2.60162067e-01,
-8.05450380e-01, -9.94437403e-02, 1.80592744e+00,
-3.69203222e-01, 1.53512599e+00, 1.89048899e+00,
-3.75611957e-01, -4.30444219e-01, -1.46748968e-01,
1.08708430e+00, -2.43889668e-01, 2.81189987e-01]])
數據集劃分
In [26]:
``` X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=123)
X_train.shape ```
Out[26]:
(455, 30)
In [27]:
y_train.shape
Out[27]:
(455,)
In [28]:
python
X_test.shape # 測試集長度是114
Out[28]:
(114, 30)
構建網絡
這是一個二分類的問題,最後一層使用sigmoid作為激活函數
In [29]:
```python model = models.Sequential()
輸入層
model.add(tf.keras.layers.Dense(16, activation="relu", input_shape=(X_train.shape[1],)))
隱藏層
model.add(tf.keras.layers.Dense(16, activation="relu"))
輸出層
model.add(tf.keras.layers.Dense(1, activation="sigmoid")) ```
網絡架構
In [30]:
model.summary()
編譯模型
在keras搭建的神經網絡中,如果輸出是概率值的模型,損失函數最好使用:交叉熵crossentropy
常用目標損失函數的選擇:
- binary_crossentropy:針對二分類問題的交叉熵
- categorical_crossentropy:針對多分類問題的交叉熵
兩種不同的指定方法:
```python
方法1
model.compile(loss='mean_squared_error', optimizer='rmsprop')
方法2
from keras import losses model.compile(loss=losses.mean_squared_error, optimizer='rmsprop') ```
常用的性能評估函數:
- binary_accuracy: 針對二分類問題,計算在所有預測值上的平均正確率
- categorical_accuracy:針對多分類問題,計算再所有預測值上的平均正確率
- sparse_categorical_accuracy:與categorical_accuracy相同,在對稀疏的目標值預測時有用
In [31]:
```python
配置優化器
from keras import optimizers
model.compile(optimizer="rmsprop", # 優化器 loss="binary_crossentropy", # 目標損失函數 metrics=["acc"] # 評價指標函數 acc--->accuracy ) ```
訓練網絡
In [32]:
len(X_train)
Out[32]:
455
In [33]:
python
history = model.fit(X_train, # 特徵向量
y_train, # 標籤向量
epochs=20, # 訓練輪數
batch_size=25 # 每次訓練的樣本數
)
history
評估模型
In [34]:
model.evaluate(X_test, y_test)
4/4 [==============================] - 0s 3ms/step - loss: 0.0879 - acc: 0.9825
Out[34]:
[0.08793728798627853, 0.9824561476707458]
可以看到模型的精度達到了驚人的98.2%!
loss-acc
In [35]:
for keys, _ in history.history.items():
print(keys)
loss
acc
In [36]:
```python
損失繪圖
import matplotlib.pyplot as plt
history_dict = history.history loss_values = history_dict["loss"] acc_values = history_dict["acc"]
epochs = range(1,len(loss_values) + 1)
訓練
plt.plot(epochs, # 循環輪數
loss_values, # loss取值
"r", # 紅色
label="loss"
)
plt.plot(epochs,
acc_values,
"b",
label="acc"
)
plt.title("Loss and Acc of Training") plt.xlabel("Epochs") plt.legend()
plt.show() ```
可以看到:隨着輪數的增加loss在逐漸降低,而精度acc在逐漸增加,趨近於1
多分類案例
多分類的案例使用sklearn中自帶的iris數據集,數據集不多介紹。最終結果是存在3個類的。
導入數據
In [37]:
iris = datasets.load_iris()
In [38]:
```
特徵數據和標籤數據
X = iris.data y = iris.target
X[:2] ```
Out[38]:
array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2]])
In [39]:
y[:3]
Out[39]:
array([0, 0, 0])
數據標準化
In [40]:
ss = StandardScaler()
X = ss.fit_transform(X)
數據集劃分
In [41]:
``` X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=123)
X_train.shape ```
Out[41]:
(120, 4)
標籤向量化
In [42]:
y_test[:5] # 轉換前
Out[42]:
array([1, 2, 2, 1, 0])
In [43]:
```
內置方法實現標籤向量化
from keras.utils.np_utils import to_categorical
y_train = to_categorical(y_train) y_test = to_categorical(y_test) ```
In [44]:
y_test[:5] # 轉換後
Out[44]:
array([[0., 1., 0.],
[0., 0., 1.],
[0., 0., 1.],
[0., 1., 0.],
[1., 0., 0.]], dtype=float32)
In [45]:
X_train[:3]
Out[45]:
array([[ 1.88617985, -0.59237301, 1.33113254, 0.92230284],
[ 0.18982966, -1.97355361, 0.70592084, 0.3957741 ],
[-1.38535265, 0.32841405, -1.22655167, -1.3154443 ]])
構建模型
In [46]:
``` model = models.Sequential() model.add(tf.keras.layers.Dense(64, activation="relu", input_shape=(X_train.shape[1],)))
model.add(tf.keras.layers.Dense(64, activation="relu"))
model.add(tf.keras.layers.Dense(3, activation="softmax")) ```
模型編譯
多分類問題一般是使用categorical_crossentropy作為損失函數。它是用來衡量網絡輸出的概率分佈和標籤的真實概率分佈的距離。
In [47]:
python
model.compile(optimizer="rmsprop",
loss="categorical_crossentropy",
metrics=["accuracy"]
)
訓練網絡
In [48]:
len(X_train)
Out[48]:
120
In [49]:
python
history = model.fit(X_train,
y_train,
epochs=10,
batch_size=15
)
history
評估模型
In [50]:
model.evaluate(X_test, y_test)
1/1 [==============================] - 0s 414ms/step - loss: 0.1799 - accuracy: 1.0000
Out[50]:
[0.17986173927783966, 1.0]
loss-acc曲線
In [51]:
for keys, _ in history.history.items():
print(keys)
loss
accuracy
In [52]:
```python
損失繪圖
import matplotlib.pyplot as plt
history_dict = history.history loss_values = history_dict["loss"] acc_values = history_dict["accuracy"]
epochs = range(1,len(loss_values) + 1)
訓練
plt.plot(epochs, # 循環輪數
loss_values, # loss取值
"r", # 紅色
label="loss"
)
plt.plot(epochs,
acc_values,
"b",
label="accuracy"
)
plt.title("Loss and Accuracy of Training") plt.xlabel("Epochs") plt.legend()
plt.show() ```
待補充學習
上面的方案只是從最基本的方式來通過Keras進行神經網絡的建模,還有很多可以深入學習和挖掘的點:
- 驗證集數據的引入
- 加入正則化技術,防止模型過擬合
- 如何評估訓練的輪次,使得模型在合適時機停止
- 激活函數的選擇等
- 基於機器學習分類算法的鋼材缺陷檢測分類
- JSON數據,Python搞定!
- 邏輯迴歸:信貸違規預測!
- kaggle實戰-腫瘤數據統計分析
- Pandas操作mysql數據庫!
- 數學公式編輯神器-Mathpix Snipping Tool
- 精選20個Pandas統計函數
- 露一手,利用Python分析房價
- 德國信貸數據建模baseline!
- Python函數傳參機制詳解
- Python爬蟲周遊全國-蘭州站
- 一道Pandas題:3種解法
- 機器學習實戰:基於3大分類模型的中風病人預測
- 利用seaborn繪製柱狀圖
- 機器學習實戰:基於MNIST數據集的二分類問題
- 基於深度學習Keras的深圳租房建模
- 機器學習高頻使用代碼片段
- Python入門:Python變量和賦值
- 深度學習框架Keras入門保姆教程
- kaggle實戰:極度不均衡的信用卡數據分析