1. 程式人生 > >【火爐煉AI】深度學習003-構建並訓練深度神經網路模型

【火爐煉AI】深度學習003-構建並訓練深度神經網路模型

【火爐煉AI】深度學習003-構建並訓練深度神經網路模型

(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

前面我們講解過單層神經網路模型,發現它結構簡單,難以解決一些實際的比較複雜的問題,故而現在發展出了深度神經網路模型。

深度神經網路的深度主要表現在隱含層的層數上,前面的單層神經網路只有一個隱含層,而深度神經網路使用>=2個隱含層。其基本結構為:

圖中有兩個隱含層,分別是醬色的圓圈(有4個神經元)和綠色的圓圈(有2個神經元),所以這個深度神經網路的結構就是3-4-2結構。圖片來源於

2017/7/20 朱興全教授學術講座觀點與總結第二講:單個神經元/單層神經網路

對於一些很複雜的深度神經網路,隱含層的個數可能有幾百上千個,比如ResNet網路結構的等,其訓練過程也更復雜,耗時更長。那麼這些模型就非常地“深”了。

使用更深層的神經網路,可以得到更好的表達效果,這可以直觀地理解為:在每一個網路層中,輸入特徵的特點被一步步的抽象出來;下一層網路直接使用上一層抽象的特徵進行進一步的線性組合或非線性組合,從而一步一步地得到輸出。


1. 構建並訓練深度神經網路模型

1.1 準備資料集

本次使用自己生成的一些資料,如下生成程式碼:

# 準備資料集
# 此處自己生成一些原始的資料點
dataset_X=np.linspace(-10,10,100)
dataset_y=2*np.square(dataset_X)+7 # 即label是feature的平方*2,偏置是7
dataset_y /=np.linalg.norm(dataset_y) # 歸一化處理
dataset_X=dataset_X[:,np.newaxis]

該資料集的資料分佈為:

1.2 構建並訓練模型

直接上程式碼:

# 構建並訓練模型
import neurolab as nl
x_min, x_max = dataset_X[:,0].min(), dataset_X[:,0].max()
multilayer_net = nl.net.newff([[x_min, x_max]], [10, 10, 1])
# 模型結構:隱含層有兩層,每層有10個神經元,輸出層一層。
multilayer_net.trainf = nl.train.train_gd # 設定訓練演算法為梯度下降
dataset_y=dataset_y[:,np.newaxis]
error = multilayer_net.train(dataset_X, dataset_y, epochs=800, show=100, goal=0.01)

-------------------------------------輸---------出--------------------------------

Epoch: 100; Error: 2.933891201182385;
Epoch: 200; Error: 0.032819979078409965;
Epoch: 300; Error: 0.040183833367277225;
The goal of learning is reached

--------------------------------------------完-------------------------------------

看來,雖然我們設定要800個迴圈,但是到達目標0.01時,便自動退出。可以畫圖看一下error的走勢

1.3 用訓練好的模型來預測新資料

此處我們沒有新資料,假設原始的dataset_X是新資料,那麼可以預測出這些新資料的結果,並比較一下真實值和預測值之間的差異,可以比較直觀的看出模型的預測效果

# 用訓練好的模型來預測
predict_y=multilayer_net.sim(dataset_X)
plt.scatter(dataset_X,dataset_y,label='dataset')
plt.scatter(dataset_X,predict_y,label='predicted')
plt.legend()
plt.title('Comparison of Truth and Predicted')

可以看出模型的預測值和真實值大致相同,至少表明模型在訓練集上表現比較好。

關於深度神經網路的更具體內容,可以參考博文 神經網路淺講:從神經元到深度學習.

其實,要解決複雜的問題,不一定要增加模型的深度(即增加隱含層數,但每一層的神經元個數比較少,即模型結構是深而瘦的),還可以增加模型的寬度(即一個或少數幾個隱含層,但是增加隱含層的神經元個數,即模型結構是淺而肥的),那麼哪一種比較好?

在文章乾貨|神經網路最容易被忽視的基礎知識一中提到:雖然有研究表明,淺而肥的網路結構也能擬合任何函式,但它需要非常的“肥胖”,可能一個隱含層需要成千上萬個神經元,這樣會導致模型中引數的數量極大地增加。如下比較圖:

從上圖可以看出:當準確率差不多的時候,引數的數量卻相差數倍。這也說明我們一般用深層的神經網路而不是淺層“肥胖”的網路。

########################小**********結###############################

1,深度神經網路的構建和訓練已經有成熟的框架來實現,比如Keras,Tensorflow,PyTorch等,用起來更加的簡單,此處僅僅用來解釋內部結構和進行簡單的建模訓練。

2,為了解決更加複雜的問題,一般我們選用深而瘦的模型結構,不選用淺而肥的模型,因為這種模型的引數數量非常大,訓練耗時長。

#################################################################


注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。

參考資料:

1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯