# 1.17. 神經網絡模型(有監督)
校驗者:
[@火星](https://github.com/apachecn/scikit-learn-doc-zh)
翻譯者:
[@A](https://github.com/apachecn/scikit-learn-doc-zh)
Warning
此實現不適用于大規模應用程序。 特別是 scikit-learn 不支持 GPU。如果想要提高運行速度并使用基于 GPU 的實現以及為構建深度學習架構提供更多靈活性的框架,請參閱 [Related Projects](../related_projects.html#related-projects)。
## 1.17.1. 多層感知器
[\*\*](#id3)多層感知器(MLP)\*\*是一種監督學習算法,通過在數據集上訓練來學習函數 ,其中  是輸入的維數, 是輸出的維數。 給定一組特征  和標簽  ,它可以學習用于分類或回歸的非線性函數。 與邏輯回歸不同的是,在輸入層和輸出層之間,可以有一個或多個非線性層,稱為隱藏層。 圖1 展示了一個具有標量輸出的單隱藏層 MLP。
[](http://sklearn.apachecn.org/cn/0.19.0/_images/multilayerperceptron_network.png)**圖1:單隱藏層MLP.**
最左層的輸入層由一組代表輸入特征的神經元  組成。 每個隱藏層中的神經元將前一層的值進行加權線性求和轉換  ,再通過非線性激活函數  - 比如雙曲正切函數 tanh 。 輸出層接收到的值是最后一個隱藏層的輸出經過變換而來的。
該模塊包含公共屬性 `coefs_` 和 `intercepts_`。`coefs_` 是一系列權重矩陣,其中下標為  的權重矩陣表示第  層和第  層之間的權重。 `intercepts_` 是一系列偏置向量,其中的下標為  的向量表示添加到第  等的偏置值。
多層感知器的優點:
> - 可以學習得到非線性模型。
> - 使用``partial\_fit`` 可以學習得到實時模型(在線學習)。
多層感知器(MLP)的缺點:
> - 具有隱藏層的 MLP 具有非凸的損失函數,它有不止一個的局部最小值。 因此不同的隨機權重初始化會導致不同的驗證集準確率。
> - MLP 需要調試一些超參數,例如隱藏層神經元的數量、層數和迭代輪數。
> - MLP 對特征歸一化很敏感.
解決這些缺點的方法請參閱 [實用使用技巧](#mlp-tips) 部分。
## 1.17.2. 分類
> [`MLPClassifier`](generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier "sklearn.neural_network.MLPClassifier") 類實現了通過 [Backpropagation](http://ufldl.stanford.edu/wiki/index.php/Backpropagation_Algorithm) 進行訓練的多層感知器(MLP)算法。
MLP 在兩個 array 上進行訓練:尺寸為 (n\_samples, n\_features) 的 array X 儲存表示訓練樣本的浮點型特征向量; 尺寸為(n\_samples,) 的 array y 儲存訓練樣本的目標值(類別標簽):
```
>>> from sklearn.neural_network import MLPClassifier
>>> X = [[0., 0.], [1., 1.]]
>>> y = [0, 1]
>>> clf = MLPClassifier(solver='lbfgs', alpha=1e-5,
... hidden_layer_sizes=(5, 2), random_state=1)
...
>>> clf.fit(X, y)
MLPClassifier(activation='relu', alpha=1e-05, batch_size='auto',
beta_1=0.9, beta_2=0.999, early_stopping=False,
epsilon=1e-08, hidden_layer_sizes=(5, 2), learning_rate='constant',
learning_rate_init=0.001, max_iter=200, momentum=0.9,
nesterovs_momentum=True, power_t=0.5, random_state=1, shuffle=True,
solver='lbfgs', tol=0.0001, validation_fraction=0.1, verbose=False,
warm_start=False)
```
擬合(訓練)后,該模型可以預測新樣本的標簽:
```
>>> clf.predict([[2., 2.], [-1., -2.]])
array([1, 0])
```
MLP 可以為訓練數據擬合一個非線性模型。`clf.coefs_` 包含了構建模型的權值矩陣:
```
>>> [coef.shape for coef in clf.coefs_]
[(2, 5), (5, 2), (2, 1)]
```
目前, [`MLPClassifier`](generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier "sklearn.neural_network.MLPClassifier") 只支持交叉熵損失函數,通過運行 `predict_proba` 方法進行概率估計。
MLP 算法使用的是反向傳播的方式。 更準確地說,它使用了通過反向傳播計算得到的梯度和某種形式的梯度下降來進行訓練。 對于分類來說,它最小化交叉熵損失函數,為每個樣本  給出一個向量形式的概率估計 
```
>>> clf.predict_proba([[2., 2.], [1., 2.]])
array([[ 1.967...e-04, 9.998...-01],
[ 1.967...e-04, 9.998...-01]])
```
[`MLPClassifier`](generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier "sklearn.neural_network.MLPClassifier") 通過應用 [Softmax](https://en.wikipedia.org/wiki/Softmax_activation_function) 作為輸出函數來支持多分類。
此外,該模型支持 [多標簽分類](multiclass.html#multiclass),樣本可能有多個類別可能。 對于每個類,原始輸出經過 logistic 函數變換后,大于或等于 0.5 的值將進為 1,否則為 0。 對于樣本的預測輸出,值為 1 的索引位置表示該樣本的分類類別:
```
>>> X = [[0., 0.], [1., 1.]]
>>> y = [[0, 1], [1, 1]]
>>> clf = MLPClassifier(solver='lbfgs', alpha=1e-5,
... hidden_layer_sizes=(15,), random_state=1)
...
>>> clf.fit(X, y)
MLPClassifier(activation='relu', alpha=1e-05, batch_size='auto',
beta_1=0.9, beta_2=0.999, early_stopping=False,
epsilon=1e-08, hidden_layer_sizes=(15,), learning_rate='constant',
learning_rate_init=0.001, max_iter=200, momentum=0.9,
nesterovs_momentum=True, power_t=0.5, random_state=1, shuffle=True,
solver='lbfgs', tol=0.0001, validation_fraction=0.1, verbose=False,
warm_start=False)
>>> clf.predict([[1., 2.]])
array([[1, 1]])
>>> clf.predict([[0., 0.]])
array([[0, 1]])
```
了解更多,請參閱下面的示例和文檔 [`MLPClassifier.fit`](generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier.fit "sklearn.neural_network.MLPClassifier.fit")。
示例:
- [Compare Stochastic learning strategies for MLPClassifier](../auto_examples/neural_networks/plot_mlp_training_curves.html#sphx-glr-auto-examples-neural-networks-plot-mlp-training-curves-py)
- [Visualization of MLP weights on MNIST](../auto_examples/neural_networks/plot_mnist_filters.html#sphx-glr-auto-examples-neural-networks-plot-mnist-filters-py)
## 1.17.3. 回歸
[`MLPRegressor`](generated/sklearn.neural_network.MLPRegressor.html#sklearn.neural_network.MLPRegressor "sklearn.neural_network.MLPRegressor") 類實現了一個多層感知器(MLP),它在使用反向傳播進行訓練時的輸出層沒有使用激活函數,也可以看作是使用身份函數作為激活函數。 因此,它使用平方誤差作為損失函數,輸出是一組連續值。
[`MLPRegressor`](generated/sklearn.neural_network.MLPRegressor.html#sklearn.neural_network.MLPRegressor "sklearn.neural_network.MLPRegressor") 還支持多輸出回歸,其中樣本可以有多個目標。
## 1.17.4. 正則化
[`MLPRegressor`](generated/sklearn.neural_network.MLPRegressor.html#sklearn.neural_network.MLPRegressor "sklearn.neural_network.MLPRegressor") 類和 [`MLPClassifier`](generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier "sklearn.neural_network.MLPClassifier") 類都使用參數 `alpha` 作為正則化( L2 正則化)系數,正則化通過懲罰大數量級的權重值以避免過擬合問題。 下面的圖表展示了不同的 alpha 值情況下的變化。
[](../auto_examples/neural_networks/plot_mlp_alpha.html)
詳細信息,請參閱下面的示例。
示例:
- [Varying regularization in Multi-layer Perceptron](../auto_examples/neural_networks/plot_mlp_alpha.html#sphx-glr-auto-examples-neural-networks-plot-mlp-alpha-py)
## 1.17.5. 算法
MLP 使用 [Stochastic Gradient Descent(隨機梯度下降)(SGD)](https://en.wikipedia.org/wiki/Stochastic_gradient_descent), [Adam](http://arxiv.org/abs/1412.6980), 或者 [L-BFGS](https://en.wikipedia.org/wiki/Limited-memory_BFGS) 進行訓練。 Stochastic Gradient Descent (隨機梯度下降)(SGD) 使用帶有自適應參數的損失函數梯度來更新參數,即

其中  是控制訓練過程參數更新步長的學習率( learning rate )。  是損失函數( loss function )。
更多細節可以在這個文檔中找到 [SGD](http://scikit-learn.org/stable/modules/sgd.html) 。
Adam 類似于 SGD,因為它是 stochastic optimizer (隨機優化器),但它可以根據低階矩的自適應估計自動調整參數更新的量。
使用 SGD 或 Adam ,訓練過程支持在線模式和小批量學習模式。
L-BFGS 是利用 Hessian 矩陣的近似表示的方法,矩陣中是函數的二階偏導數。 它近似用 Hessian 矩陣的逆來進行參數更新。 該實現使用 Scipy 版本的 [L-BFGS](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html)。
如果所選擇的方法是 ‘L-BFGS’,訓練過程不支持在線模式和小批量學習模式。
## 1.17.6. 復雜性
假設有  個訓練樣本,  個特征,  個隱藏層,每個包含  個神經元 - 為簡單起見,  個輸出神經元。 反向傳播的時間復雜度是  ,其中  是迭代次數。 由于反向傳播具有高時間復雜性,最好以較少數量的隱藏層神經元和較少的隱藏層個數開始訓練。
## 1.17.7. 數學公式
給出一組訓練樣本  其中 ,一個單隱藏層單神經元 MLP 學習到的函數是  ,其中  和  是模型參數.  分別是輸入層與隱藏層之間和隱藏層與輸出層之間的權重,  分別是隱藏層和輸出層的偏置值.  是激活函數,默認為雙曲正切函數。 具體形式如下,

對于二分類,  經過 logistic 函數  得到 0 到 1 之間的輸出值。 0.5 的閾值將輸出大于等于 0.5 的樣本分到 positive class (正類),其他的分為 negative class (負類)。
如果多于兩類,則  本身將是一個尺寸為(n\_classes,)的向量。 它需要經過 softmax 函數而不是 logistic 函數進行變換,具體形式如下,

其中  表示 softmax 函數的第  個輸入的元素,它對應于第  類,  是類別的數量。 計算結果是樣本  屬于每個類別的概率的向量。 最終輸出的分類結果是具有最高概率的類別。
在回歸問題中,輸出依然是  ;因此,輸出激活函數就是身份函數。
MLP 根據特定問題使用不同的損失函數。 二分類問題的損失函數的是交叉熵,具體形式如下,

其中  是 L2 正則化的模型復雜度懲罰項;  這個非負的超參數控制懲罰的程度。
對于回歸問題,MLP 使用平方誤差損失函數,具體形式如下,

從隨機初始化權重開始,多層感知器(MLP)不斷更新這些權重值來最小化損失函數。計算完損失之后,從輸出層到前面各層進行反向傳遞,為旨在減小損失函數值的參數提供更新值。
在梯度下降中,計算得到損失函數關于每個權重的梯度  并從權重  中減掉。用公式表示為,

其中  是當前迭代步數,  是大于 0 學習率。
算法停止的條件或者是達到預設的最大迭代次數,或者是損失函數低于某個特定值。
## 1.17.8. 實用技巧
> - 多層感知器對特征的縮放是敏感的,所以它強烈建議您歸一化你的數據。 例如,將輸入向量 X 的每個屬性放縮到到 \[0, 1\] 或 \[-1,+1\] ,或者將其標準化使它具有 0 均值和方差 1。 注意,為了得到有意義的結果,您必須對測試集也應用 *相同的* 縮放尺度。 您可以使用 `StandardScaler` 進行標準化。
>
>
> ```
> >>> from sklearn.preprocessing import StandardScaler
> >>> scaler = StandardScaler()
> >>> # Don't cheat - fit only on training data
> >>> scaler.fit(X_train)
> >>> X_train = scaler.transform(X_train)
> >>> # apply same transformation to test data
> >>> X_test = scaler.transform(X_test)
>
> ```
>
>
>
>
> 一個推薦的可替代的方案是在 `Pipeline` 中使用的 `StandardScaler` 。
> - 最好使用 `GridSearchCV` 找到一個合理的正則化參數  ,通常范圍是在 `10.0 ** -np.arange(1, 7)` 。
> - 據經驗可知,我們觀察到 L-BFGS 收斂速度是更快的并且是小數據集上更好的解決方案。對于規模相對比較大的數據集,Adam 是非常魯棒的。 它通常會迅速收斂,并得到相當不錯的表現。 另一方面,如果學習率調整地正確, 使用 momentum 或 nesterov’s momentum 的 SGD 可以比這兩種算法更好。
## 1.17.9. 使用 warm\_start 的更多控制
如果您希望更多地控制 SGD 中的停止標準或學習率,或者想要進行額外的監視,使用 `warm_start=True` 和 `max_iter=1` 并且自身迭代可能會有所幫助:
```
>>> X = [[0., 0.], [1., 1.]]
>>> y = [0, 1]
>>> clf = MLPClassifier(hidden_layer_sizes=(15,), random_state=1, max_iter=1, warm_start=True)
>>> for i in range(10):
... clf.fit(X, y)
... # additional monitoring / inspection
MLPClassifier(...
```
參考文獻:
- [“Learning representations by back-propagating errors.”](http://www.iro.umontreal.ca/~pift6266/A06/refs/backprop_old.pdf)Rumelhart, David E., Geoffrey E. Hinton, and Ronald J. Williams.
- [“Stochastic Gradient Descent”](http://leon.bottou.org/projects/sgd) L. Bottou - Website, 2010.
- [“Backpropagation”](http://ufldl.stanford.edu/wiki/index.php/Backpropagation_Algorithm)Andrew Ng, Jiquan Ngiam, Chuan Yu Foo, Yifan Mai, Caroline Suen - Website, 2011.
- [“Efficient BackProp”](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf)Y. LeCun, L. Bottou, G. Orr, K. Müller - In Neural Networks: Tricks of the Trade 1998.
- [“Adam: A method for stochastic optimization.”](http://arxiv.org/pdf/1412.6980v8.pdf)Kingma, Diederik, and Jimmy Ba. arXiv preprint arXiv:1412.6980 (2014).
- scikit-learn 0.19 中文文檔
- 用戶指南
- 1. 監督學習
- 1.1. 廣義線性模型
- 1.2. 線性和二次判別分析
- 1.3. 內核嶺回歸
- 1.4. 支持向量機
- 1.5. 隨機梯度下降
- 1.6. 最近鄰
- 1.7. 高斯過程
- 1.8. 交叉分解
- 1.9. 樸素貝葉斯
- 1.10. 決策樹
- 1.11. 集成方法
- 1.12. 多類和多標簽算法
- 1.13. 特征選擇
- 1.14. 半監督學習
- 1.15. 等式回歸
- 1.16. 概率校準
- 1.17. 神經網絡模型(有監督)
- 2. 無監督學習
- 2.1. 高斯混合模型
- 2.2. 流形學習
- 2.3. 聚類
- 2.4. 雙聚類
- 2.5. 分解成分中的信號(矩陣分解問題)
- 2.6. 協方差估計
- 2.7. 經驗協方差
- 2.8. 收斂協方差
- 2.9. 稀疏逆協方差
- 2.10. Robust 協方差估計
- 2.11. 新奇和異常值檢測
- 2.12. 密度估計
- 2.13. 神經網絡模型(無監督)
- 3. 模型選擇和評估
- 3.1. 交叉驗證:評估估算器的表現
- 3.2. 調整估計器的超參數
- 3.3. 模型評估: 量化預測的質量
- 3.4. 模型持久化
- 3.5. 驗證曲線: 繪制分數以評估模型
- 4. 數據集轉換
- 4.1. Pipeline(管道)和 FeatureUnion(特征聯合): 合并的評估器
- 4.2. 特征提取
- 4.3. 預處理數據
- 4.4. 無監督降維
- 4.5. 隨機投影
- 4.6. 內核近似
- 4.7. 成對的矩陣, 類別和核函數
- 4.8. 預測目標 (y) 的轉換
- 5. 數據集加載工具
- 6. 大規模計算的策略: 更大量的數據
- 7. 計算性能
- 教程
- 使用 scikit-learn 介紹機器學習
- 關于科學數據處理的統計學習教程
- 機器學習: scikit-learn 中的設置以及預估對象
- 監督學習:從高維觀察預測輸出變量
- 模型選擇:選擇估計量及其參數
- 無監督學習: 尋求數據表示
- 把它們放在一起
- 尋求幫助
- 處理文本數據
- 選擇正確的評估器(estimator)
- 外部資源,視頻和談話