原文鏈接:http://tecdat.cn/?p=15850
在本部分中,您將發現如何使用標准深度學習模型(包括多層感知器(MLP),卷積神經網絡(CNN)和遞歸神經網絡(RNN))開發,評估和做出預測。
開發多層感知器模型
多層感知器模型(簡稱MLP)是標准的全連接神經網絡模型。
它由節點層組成,其中每個節點連接到上一層的所有輸出,每個節點的輸出連接到下一層節點的所有輸入。
通過一個或多個密集層創建MLP 。此模型適用於表格數據,即表格或電子表格中的數據,每個變量一列,每個變量一行。您可能需要使用MLP探索三個預測建模問題;它們是二進制分類,多分類和回歸。
讓我們針對每種情況在真實數據集上擬合模型。
二進制分類的MLP
我們將使用二進制(兩類)分類數據集來演示用於二進制分類的MLP。
該數據集涉及預測結構是否在大氣中或不給定雷達回波。
數據集將使用Pandas自動下載。
我們將使用LabelEncoder將字符串標簽編碼為整數值0和1。該模型將適合67%的數據,其余的33%將用於評估,請使用train_test_split()函數進行拆分。
最好將' relu '激活與' he_normal '權重初始化一起使用。在訓練深度神經網絡模型時,這種組合可以大大克服梯度消失的問題。
該模型預測1類的可能性,並使用S型激活函數。
下面列出了代碼片段。
-
# mlp二分類包
-
from pandas import read_csv
-
from sklearn.model_selection import train_test_split
-
from sklearn.preprocessing import LabelEncoder
-
from tensorflow.keras import Sequential
-
from tensorflow.keras.layers import Dense
-
# 加載數據
-
path = 'osph.csv'
-
df = read_csv(path, header=None)
-
# 分割輸入和輸出
-
X, y = df.values[:, :-1], df.values[:, -1]
-
# ensure all data are floating point values
-
X = X.astype('float32')
-
# 文本轉換數字變量
-
y = LabelEncoder().fit_transform(y)
-
# 分割訓練測試集
-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
-
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
-
# 定義輸入變量維度
-
n_features = X_train.shape[1]
-
#定義模型
-
model = Sequential()
-
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
-
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
-
model.add(Dense(1, activation='sigmoid'))
-
# compile the model
-
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
-
# 擬合模型
-
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=0)
運行示例將首先報告數據集的形狀,然后擬合模型並在測試數據集上對其進行評估。最后,對單行數據進行預測。
鑒於學習算法的隨機性,您的具體結果會有所不同。嘗試運行該示例幾次。
在這種情況下,我們可以看到該模型實現了約94%的分類准確度,然后預測單行數據屬於1類的概率為0.9。
-
(235, 34) (116, 34) (235,) (116,)
-
Test Accuracy: 0.940
-
Predicted: 0.991
用於多類分類的MLP
我們將使用鳶尾花多類分類數據集來演示用於多類分類的MLP。
該問題涉及在給定花的度量的情況下預測鳶尾花的種類。
數據集將使用Pandas自動下載,但您可以在此處了解更多信息。
- 鳶尾花數據集(csv)
- 鳶尾花數據集描述(csv)
鑒於它是一個多類分類,因此該模型在輸出層中的每個類必須具有一個節點,並使用softmax激活函數。損失函數是' sparse_categorical_crossentropy ',它適用於整數編碼的類標簽(例如,一個類為0,下一類為1,等等)
下面列出了在鳶尾花數據集上擬合和評估MLP的代碼片段。
-
-
# 預測
-
row = [5.1,3.5,1.4,0.2]
-
yhat = model.predict([row])
-
print('Predicted: %s (class=%d)' % (yhat, argmax(yhat)))
運行示例將首先報告數據集的形狀,然后擬合模型並在測試數據集上對其進行評估。最后,對單行數據進行預測。
鑒於學習算法的隨機性,您的具體結果會有所不同。嘗試運行該示例幾次。
在這種情況下,我們可以看到該模型實現了約98%的分類精度,然后預測了屬於每個類別的一行數據的概率,盡管類別0的概率最高。
-
(100, 4) (50, 4) (100,) (50,)
-
Test Accuracy: 0.980
-
Predicted: [[0.8680804 0.12356871 0.00835086]] (class=0)
回歸的MLP
我們將使用波士頓住房回歸數據集來演示用於回歸預測建模的MLP。
這個問題涉及根據房屋和鄰里的屬性來預測房屋價值。
數據集將使用Pandas自動下載,但您可以在此處了解更多信息。
這是一個回歸問題,涉及預測單個數值。因此,輸出層具有單個節點,並使用默認或線性激活函數(無激活函數)。擬合模型時,均方誤差(mse)損失最小。
-
-
# 預測
-
row = [0.00632,18.00,2.310,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98]
-
yhat = model.predict([row])
-
print('Predicted: %.3f' % yhat)
運行示例首先報告數據集的形狀,然后擬合模型並在測試數據集上對其進行評估。最后,對單行數據進行預測。
鑒於學習算法的隨機性,您的具體結果會有所不同。嘗試運行該示例幾次。
在這種情況下,我們可以看到該模型實現了約60的MSE,即約7的RMSE。然后,對於單個示例,預測值約為26。
-
(339, 13) (167, 13) (339,) (167,)
-
MSE: 60.751, RMSE: 7.794
-
Predicted: 26.983
開發卷積神經網絡模型
卷積神經網絡(簡稱CNN)是一種專為圖像輸入而設計的網絡。
它們由具有卷積層的模型組成,這些卷積層提取特征(稱為特征圖),並匯集將特征分解為最顯着元素的層。
盡管CNN可以用於將圖像作為輸入的各種任務,但它們最適合圖像分類任務。
流行的圖像分類任務是MNIST手寫數字分類。它涉及成千上萬個手寫數字,必須將其分類為0到9之間的數字。
tf.keras API提供了便捷功能,可以直接下載和加載此數據集。
下面的示例加載數據集並繪制前幾張圖像。
-
-
pyplot.subplot(5, 5, i+1)
-
# 繪制原始像素
-
pyplot.imshow(trainX[i], cmap=pyplot.get_cmap('gray'))
-
# 顯示圖片
-
pyplot.show()
運行示例將加載MNIST數據集,然后匯總默認的訓練和測試數據集。
-
Train: X=(60000, 28, 28), y=(60000,)
-
Test: X=(10000, 28, 28), y=(10000,)
然后創建一個圖,顯示訓練數據集中的手寫圖像示例網格。
MNIST數據集中的手寫數字圖
我們可以訓練CNN模型對MNIST數據集中的圖像進行分類。
注意,圖像是灰度像素數據的陣列;因此,在將圖像用作模型的輸入之前,必須向數據添加通道維度。原因是CNN模型期望圖像采用通道最后格式,即網絡的每個示例均具有[行,列,通道]的尺寸,其中通道代表圖像數據的彩色通道。
訓練CNN時,將像素值從默認范圍0-255縮放到0-1也是一個好主意。
下面列出了在MNIST數據集上擬合和評估CNN模型的代碼片段。
-
-
# 預測
-
image = x_train[0]
-
yhat = model.predict([[image]])
-
print('Predicted: class=%d' % argmax(yhat))
運行示例將首先報告數據集的形狀,然后擬合模型並在測試數據集上對其進行評估。最后,對單個圖像進行預測。
首先,報告每個圖像的形狀以及類別數;我們可以看到每個圖像都是28×28像素,並且我們有10個類別。
在這種情況下,我們可以看到該模型在測試數據集上實現了約98%的分類精度。然后我們可以看到該模型預測了訓練集中的第一幅圖像的5類。
-
(28, 28, 1) 10
-
Accuracy: 0.987
-
Predicted: class="5"
開發遞歸神經網絡模型
遞歸神經網絡(簡稱RNN)旨在對數據序列進行操作。
事實證明,它們對於自然語言處理問題非常有效,在自然語言處理問題中,將文本序列作為模型的輸入。RNN在時間序列預測和語音識別方面也取得了一定程度的成功。
RNN最受歡迎的類型是長期短期記憶網絡,簡稱LSTM。LSTM可用於模型中,以接受輸入數據序列並進行預測,例如分配類別標簽或預測數值,例如序列中的下一個值或多個值。
我們將使用汽車銷售數據集來證明LSTM RNN用於單變量時間序列預測。
這個問題涉及預測每月的汽車銷售數量。
數據集將使用Pandas自動下載,但您可以在此處了解更多信息。
我們將用最近五個月的數據窗口作為問題的框架,以預測當月的數據。
為了實現這一點,我們將定義一個名為split_sequence()的新函數,該函數會將輸入序列拆分為適合擬合監督學習模型(如LSTM)的數據窗口。
例如,如果順序是:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
然后,用於訓練模型的樣本將如下所示:
-
Input Output
-
1, 2, 3, 4, 5 6
-
2, 3, 4, 5, 6 7
-
3, 4, 5, 6, 7 8
-
...
我們將使用最近12個月的數據作為測試數據集。
LSTM期望數據集中的每個樣本都具有兩個維度。第一個是時間步數(在這種情況下為5),第二個是每個時間步的觀測數(在這種情況下為1)。
因為這是回歸型問題,所以我們將在輸出層中使用線性激活函數(無激活函數)並優化均方誤差損失函數。我們還將使用平均絕對誤差(MAE)指標評估模型。
下面列出了針對單變量時間序列預測問題擬合和評估LSTM的示例。
-
# lstm 時間序列預測庫
-
from numpy import sqrt
-
from numpy import asarray
-
from pandas import read_csv
-
from tensorflow.keras import Sequential
-
from tensorflow.keras.layers import Dense
-
from tensorflow.keras.layers import LSTM
-
-
# 分割樣本
-
def split_sequence(sequence, n_steps):
-
X, y = list(), list()
-
for i in range(len(sequence)):
-
# find the end of this pattern
-
end_ix = i + n_steps
-
if end_ix > len(sequence)-1:
-
break
-
#合並輸入和輸出
-
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
-
X.append(seq_x)
-
y.append(seq_y)
-
return asarray(X), asarray(y)
-
-
# 加載數據
-
path = 'sales.csv'
-
df = read_csv(path, header=0, index_col=0, squeeze=True)
-
# retrieve the values
-
values = df.values.astype('float32')
-
#定義窗口大小
-
n_steps = 5
運行示例將首先報告數據集的形狀,然后擬合模型並在測試數據集上對其進行評估。最后,對單個示例進行了預測。
鑒於學習算法的隨機性,您的具體結果會有所不同。嘗試運行該示例幾次。
在這種情況下,模型的MAE約為2,800,並從測試集中預測序列中的下一個值為13,199,其中預期值為14,577(非常接近)。
-
(91, 5, 1) (12, 5, 1) (91,) (12,)
-
MSE: 12755421.000, RMSE: 3571.473, MAE: 2856.084
-
Predicted: 13199.325
注意:優良作法是在擬合模型之前對數據進行差分和使其穩定。
如何使用高級模型功能
在本節中,您將發現如何使用一些稍微高級的模型功能,例如查看學習曲線並保存模型以備后用。
如何可視化深度學習模型
深度學習模型的架構可能很快變得龐大而復雜。
因此,對模型中的連接和數據流有一個清晰的了解非常重要。如果您使用功能性API來確保確實按照預期的方式連接了模型的各層,那么這一點尤其重要。
您可以使用兩種工具來可視化模型:文本描述和繪圖。
文字說明
可以通過在模型上調用summary()函數來顯示模型的文本描述。
下面的示例定義了一個三層的小模型,然后總結了結構。
-
-
# 定義模型
-
model = Sequential()
-
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(8,)))
-
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
-
model.add(Dense(1, activation='sigmoid'))
-
# 摘要
-
model.summary()
運行示例將打印每個層的摘要以及總摘要。
這是用於檢查模型中輸出形狀和參數(權重)數量的診斷。
-
Model: "sequential"
-
_________________________________________________________________
-
Layer (type) Output Shape Param #
-
=================================================================
-
dense (Dense) (None, 10) 90
-
_________________________________________________________________
-
dense_1 (Dense) (None, 8) 88
-
_________________________________________________________________
-
dense_2 (Dense) (None, 1) 9
-
=================================================================
-
Total params: 187
-
Trainable params: 187
-
Non-trainable params: 0
-
_________________________________________________________________
模型架構圖
您可以通過調用plot_model()函數來創建模型圖。
這將創建一個圖像文件,其中包含模型中各層的方框圖和折線圖。
下面的示例創建一個小的三層模型,並將模型體系結構的圖保存到包括輸入和輸出形狀的' model.png '。
-
-
# 可視化摘要
-
plot_model(model, 'model.png', show_shapes=True)
運行示例將創建一個模型圖,該圖顯示具有形狀信息的每個圖層的框,以及連接圖層的箭頭,以顯示通過網絡的數據流。
神經網絡架構圖
如何繪制模型學習曲線
學習曲線是神經網絡模型隨時間變化的曲線圖,例如在每個訓練時期結束時計算的曲線。
學習曲線圖可洞悉模型的學習動態,例如模型是否學習得很好,模型是否適合訓練數據集或模型是否適合訓練數據集。
您可以輕松地為您的深度學習模型創建學習曲線。
首先,您必須更新對fit函數的調用,以包括對驗證數據集的引用。這是訓練集的一部分,不用於擬合模型,而是用於在訓練過程中評估模型的性能。
您可以手動拆分數據並指定validation_data參數,也可以使用validation_split參數並指定訓練數據集的拆分百分比,然后讓API為您執行拆分。后者目前比較簡單。
fit函數將返回一個歷史對象,其中包含在每個訓練時期結束時記錄的性能指標的痕跡。這包括選擇的損失函數和每個配置的度量(例如准確性),並且為訓練和驗證數據集計算每個損失和度量。
學習曲線是訓練數據集和驗證數據集上的損失圖。我們可以使用Matplotlib庫從歷史對象創建此圖。
下面的示例將小型神經網絡適合於合成二進制分類問題。在訓練期間,使用30%的驗證比例來評估模型,然后使用折線圖繪制訓練和驗證數據集上的交叉熵損失。
-
# 繪制學習曲線
-
pyplot.title('Learning Curves')
-
pyplot.xlabel('Epoch')
-
pyplot.ylabel('Cross Entropy')
-
pyplot.plot(history.history['loss'], label='train')
-
pyplot.plot(history.history['val_loss'], label='val')
-
pyplot.legend()
-
pyplot.show()
運行示例使模型擬合數據集。運行結束時,將返回歷史對象,並將其用作創建折線圖的基礎。
可以通過“ 損失 ”變量訪問訓練數據集的交叉熵損失,並通過歷史對象的歷史記錄屬性上的“ val_loss ”訪問驗證數據集的損失。
深度學習模型的交叉熵損失學習曲線
如何保存和加載模型
訓練和評估模型很棒,但是我們可能希望稍后使用模型而不必每次都對其進行重新訓練。
這可以通過將模型保存到文件中,然后加載它並使用它進行預測來實現。
這可以通過使用模型上的save()函數來保存模型來實現。稍后可以使用load_model()函數加載它。
模型以H5格式(一種有效的陣列存儲格式)保存。因此,您必須確保在工作站上安裝了h5py庫。這可以使用pip來實現;例如:
pip install h5py
下面的示例將一個簡單模型擬合為合成二進制分類問題,然后保存模型文件。
-
# 保存模型樣例
-
from sklearn.datasets import make_classification
-
from tensorflow.keras import Sequential
-
from tensorflow.keras.layers import Dense
-
from tensorflow.keras.optimizers import SGD
-
# 數據集
-
X, y = make_classification(n_samples=1000, n_features=4, n_classes=2, random_state=1)
-
# determine the number of input features
-
n_features = X.shape[1]
-
# 定義模型
-
model = Sequential()
-
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
-
model.add(Dense(1, activation='sigmoid'))
-
# 編譯模型
-
sgd = SGD(learning_rate=0.001, momentum=0.8)
-
model.compile(optimizer=sgd, loss='binary_crossentropy')
-
# 擬合
-
model.fit(X, y, epochs=100, batch_size=32, verbose=0, validation_split=0.3)
-
# 保存
-
model.save('model.h5')
運行示例將適合模型,並將其保存到名為“ model.h5 ”的文件中。
然后,我們可以加載模型並使用它進行預測,或者繼續訓練它,或者用它做我們想做的任何事情。
下面的示例加載模型並使用它進行預測。
-
# 加載保存的模型
-
from sklearn.datasets import make_classification
-
from tensorflow.keras.models import load_model
-
# 數據
-
X, y = make_classification(n_samples=1000, n_features=4, n_classes=2, random_state=1)
-
# 加載模型
-
model = load_model('model.h5')
-
# 預測
-
row = [1.91518414, 1.14995454, -1.52847073, 0.79430654]
-
yhat = model.predict([row])
-
print('Predicted: %.3f' % yhat[0])
運行示例將從文件中加載圖像,然后使用它對新的數據行進行預測並打印結果。
Predicted: 0.831
如何獲得更好的模型性能
在本部分中,您將發現一些可用於改善深度學習模型性能的技術。
改善深度學習性能的很大一部分涉及通過減慢學習過程或在適當的時間停止學習過程來避免過度擬合。
如何減少過度擬合:Dropout
這是在訓練過程中實現的,在訓練過程中,一些圖層輸出被隨機忽略或“ 掉線 ”。
您可以在要刪除輸入連接的圖層之前,在新模型中將Dropout添加為模型。
這涉及添加一個稱為Dropout()的層,該層接受一個參數,該參數指定前一個輸出的每個輸出下降的概率。例如0.4表示每次更新模型都會刪除40%的輸入。
您也可以在MLP,CNN和RNN模型中添加Dropout層,盡管您也可能想探索與CNN和RNN模型一起使用的Dropout的特殊版本。
下面的示例將一個小型神經網絡模型擬合為一個合成二進制分類問題。
在第一隱藏層和輸出層之間插入一個具有50%濾除率的濾除層。
-
# dropout樣例
-
from sklearn.datasets import make_classification
-
from tensorflow.keras import Sequential
-
from tensorflow.keras.layers import Dense
-
from tensorflow.keras.layers import Dropout
-
from matplotlib import pyplot
-
# 數據
-
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
-
# determine the number of input features
-
n_features = X.shape[1]
-
# 模型
-
model = Sequential()
-
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
-
model.add(Dropout(0.5))
-
model.add(Dense(1, activation='sigmoid'))
-
# 編譯模型
-
model.compile(optimizer='adam', loss='binary_crossentropy')
-
# 擬合模型
-
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
如何通過批量歸一化來加速訓練
某一層的輸入的規模和分布會極大地影響該層的訓練程度。
這通常就是為什么在使用神經網絡模型進行建模之前先標准化輸入數據是一個好主意的原因。
批處理規范化是一種用於訓練非常深的神經網絡的技術,該技術可將每個輸入標准化。這具有穩定學習過程並顯着減少訓練深度網絡所需的訓練時期的數量的效果。
您可以在網絡中使用批量歸一化,方法是在希望具有標准化輸入的層之前添加一個批量歸一化層。您可以對MLP,CNN和RNN模型使用批標准化。
下面的示例定義了一個用於二進制分類預測問題的小型MLP網絡,在第一隱藏層和輸出層之間具有批處理歸一化層。
-
# 標准化
-
from sklearn.datasets import make_classification
-
from tensorflow.keras import Sequential
-
from tensorflow.keras.layers import Dense
-
from tensorflow.keras.layers import BatchNormalization
-
from matplotlib import pyplot
-
# 數據
-
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
-
# 輸入特征定義
-
n_features = X.shape[1]
-
# 定義模型
-
model = Sequential()
-
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
-
model.add(BatchNormalization())
-
model.add(Dense(1, activation='sigmoid'))
-
# 編譯模型
-
model.compile(optimizer='adam', loss='binary_crossentropy')
-
#擬合模型
-
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
如何在適當的時間停止訓練並盡早停止
神經網絡具有挑戰性。
訓練太少,模型不適合;訓練過多,模型過度適合訓練數據集。兩種情況都導致模型的有效性降低。
解決此問題的一種方法是使用提前停止。這涉及監視訓練數據集和驗證數據集(訓練集的子集未用於擬合模型)的損失。一旦驗證集的損失開始顯示過度擬合的跡象,訓練過程就可以停止。
通過首先確保您具有驗證數據集,可以對模型使用提前停止。您可以通過fit()函數的validation_data參數手動定義驗證數據集,也可以使用validation_split並指定要保留以進行驗證的訓練數據集的數量。
然后,您可以定義EarlyStopping並指示它監視要監視的性能度量,例如“ val_loss ”以確認驗證數據集的損失,以及在采取措施之前觀察到的過度擬合的時期數,例如5。
然后,可以通過采用回調列表的“ callbacks ”參數將已配置的EarlyStopping回調提供給fit()函數。
這使您可以將時期數設置為大量,並確信一旦模型開始過度擬合,訓練就會結束。您可能還想創建一條學習曲線,以發現更多有關跑步和停止訓練的學習動態的見解。
下面的示例演示了有關合成二進制分類問題的小型神經網絡,該問題在模型開始過度擬合后(約50個歷元后)立即使用停止功能停止訓練。
-
-
#停止訓練
-
es = EarlyStopping(monitor='val_loss', patience=5)
-
# 擬合模型
-
history = model.fit(X, y, epochs=200, batch_size=32, verbose=0, validation_split=0.3, callbacks=[es])
參考文獻
1.r語言用神經網絡改進nelson-siegel模型擬合收益率曲線分析
3.python用遺傳算法-神經網絡-模糊邏輯控制算法對樂透分析
4.用於nlp的python:使用keras的多標簽文本lstm神經網絡分類
7.用於NLP的seq2seq模型實例用Keras實現神經機器翻譯