日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【深度学习】神经网络的Python代码实现

發(fā)布時間:2025/3/8 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深度学习】神经网络的Python代码实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:[美]霍布森·萊恩,科爾·霍華德


在學習神經(jīng)網(wǎng)絡之前,我們需要對神經(jīng)網(wǎng)絡底層先做一個基本的了解。我們將在本節(jié)介紹感知機、反向傳播算法以及多種梯度下降法以給大家一個全面的認識。

一、感知機

數(shù)字感知機的本質是從數(shù)據(jù)集中選取一個樣本(example),并將其展示給算法,然后讓算法判斷“是”或“不是”。一般而言,把單個特征表示為xi,其中i是整數(shù)。所有特征的集合表示為,表示一個向量:,

類似地,每個特征的權重表示為? 其中? 對應于與該權重關聯(lián)的特征的下標,所有權重可統(tǒng)一表示為 一個向量:

這里有一個缺少的部分是是否激活神經(jīng)元的閾值。一旦加權和超過某個閾值,感知機就輸出1,否則輸出0。我們可以使用一個簡單的階躍函數(shù)(在圖5-2中標記為“激活函數(shù)”)來表示這個閾值。

一般而言我們還需要給上面的閾值表達式添加一個偏置項以確保神經(jīng)元對全0的輸入具有彈性,否則網(wǎng)絡在輸入全為0的情況下輸出仍然為0。

注:所有神經(jīng)網(wǎng)絡的基本單位都是神經(jīng)元,基本感知機是廣義神經(jīng)元的一個特例,從現(xiàn)在開始,我們將感知機稱為一個神經(jīng)元。

二、反向傳播算法

2.1 代價函數(shù)

很多數(shù)據(jù)值之間的關系不是線性的,也沒有好的線性回歸或線性方程能夠描述這些關系。許多數(shù)據(jù)集不能用直線或平面來線性分割。比如下圖中左圖為線性可分的數(shù)據(jù),而右圖為線性不可分的數(shù)據(jù):

在這個線性可分數(shù)據(jù)集上對兩類點做切分得到的誤差可以收斂于0,而對于線性不可分的數(shù)據(jù)點集,我們無法做出一條直線使得兩類點被完美分開,因此我們?nèi)我庾鲆粭l分割線,可以認為在這里誤差不為0,因此我們需要一個衡量誤差的函數(shù),通常稱之為代價函數(shù):

而我們訓練神經(jīng)網(wǎng)絡(感知機)的目標是最小化所有輸入樣本數(shù)據(jù)的代價函數(shù)

2.2 反向傳播

權重通過下一層的權重()和()來影響誤差,因此我們需要一種方法來計算對誤差的貢獻,這個方法就是反向傳播

下圖中展示的是一個全連接網(wǎng)絡,圖中沒有展示出所有的連接,在全連接網(wǎng)絡中,每個輸入元素都與下一層的各個神經(jīng)元相連,每個連接都有相應的權重。因此,在一個以四維向量為輸入、有5個神經(jīng)元的全連接神經(jīng)網(wǎng)絡中,一共有20個權重(5個神經(jīng)元各連接4個權重)。

感知機的每個輸入都有一個權重,第二層神經(jīng)元的權重不是分配給原始輸入的,而是分配給來自第一層的各個輸出。從這里我們可以看到計算第一層權重對總體誤差的影響的難度。第一層權重對誤差的影響并不是只來自某個單獨權重,而是通過下一層中每個神經(jīng)元的權重來產(chǎn)生的。反向傳播的推導過程較為復雜,這里僅簡單展示其結果:

如果該層是輸出層,借助于可微的激活函數(shù),權重的更新比較簡單, 對于第? 個輸出,誤差的導數(shù)如下

如果要更新隱藏層的權重,則會稍微復雜一點兒:

函數(shù)表示實際結果向量,表示該向量第個位置上的值,,是倒數(shù)第二層第個節(jié)點和輸出第個節(jié)點的輸出,連接這兩個節(jié)點的權重為,誤差代價函數(shù)對求導的結果相當于用(學習率)乘以前一層的輸出再乘以后一層代價函數(shù)的導數(shù)。公式中表示層第個節(jié)點上的誤差項,前一層第個節(jié)點到層所有的節(jié)點進行加權求和。

2.3 多種梯度下降法

到目前為止,我們一直是把所有訓練樣本的誤差聚合起來然后再做梯度下降,這種訓練方法稱為批量學習(batch learning)。一批是訓練數(shù)據(jù)的一個子集。但是在批量學習中誤差曲面對于整個批是靜態(tài)的,如果從一個隨機的起始點開始,得到的很可能是某個局部極小值,從而無法看到其他的權重值的更優(yōu)解。這里有兩種方法來避開這個陷阱。

第一種方法是隨機梯度下降法。在隨機梯度下降中,不用去查看所有的訓練樣本,而是在輸入每個訓練樣本后就去更新網(wǎng)絡權重。在這個過程中,每次都會重新排列訓練樣本的順序,這樣將為每個樣本重新繪制誤差曲面,由于每個相異的輸入都可能有不同的預期答案,因此大多數(shù)樣本的誤差曲面都不一樣。對每個樣本來說,仍然使用梯度下降法來調整權重。不過不用像之前那樣在每個訓練周期結束后聚合所有誤差再做權重調整,而是針對每個樣本都會去更新一次權重。其中的關鍵點是,每一步都在向假定的極小值前進(不是所有路徑都通往假定的極小值)。

使用正確的數(shù)據(jù)和超參數(shù),在向這個波動誤差曲面的各個最小值前進時,可以更容易地得到全局極小值。如果模型沒有進行適當?shù)恼{優(yōu),或者訓練數(shù)據(jù)不一致,將導致原地踏步,模型無法收斂,也學不會任何東西。不過在實際應用中,隨機梯度下降法在大多數(shù)情況下都能有效地避免局部極小值。這種方法的缺點是計算速度比較慢。計算前向傳播和反向傳播,然后針對每個樣本進行權重更新,這在本來已經(jīng)很慢的計算過程的基礎上又增加了很多時間開銷。

第二種方法,也是更常見的方法,是小批量學習。在小批量學習中,會傳入訓練集的一個小的子集,并按照批量學習中的誤差聚合方法對這個子集對應的誤差進行聚合。然后對每個子集按批將其誤差進行反向傳播并更新權重。下一批會重復這個過程,直到訓練集處理完成為止,這就重新構成了一個訓練周期。這是一種折中的辦法,它同時具有批量學習(快速)和隨機梯度下降(具有彈性)的優(yōu)點。

三、Keras:用Python實現(xiàn)神經(jīng)網(wǎng)絡

用原生Python來編寫神經(jīng)網(wǎng)絡是一個非常有趣的嘗試,而且可以幫助大家理解神經(jīng)網(wǎng)絡中的各種概念,但是Python在計算速度上有明顯缺陷,即使對于中等規(guī)模的網(wǎng)絡,計算量也會變得非常棘手。不過有許多Python庫可以用來提高運算速度,包括PyTorch、Theano、TensorFlow和Lasagne等。本書中的例子使用Keras。

Keras是一個高級封裝器,封裝了面向Python的API。API接口可以與3個不同的后端庫相兼容:Theano、谷歌的TensorFlow和微軟的CNTK。這幾個庫都在底層實現(xiàn)了基本的神經(jīng)網(wǎng)絡單元和高度優(yōu)化的線性代數(shù)庫,可以用于處理點積,以支持高效的神經(jīng)網(wǎng)絡矩陣乘法運算。

我們以簡單的異或問題為例,看看如何用Keras來訓練這個網(wǎng)絡。

import numpy as np from keras.models import Sequential  # Kera的基礎模型類 from keras.layers import Dense, Activation  # Dense是神經(jīng)元的全連接層 from keras.optimizers import SGD  # 隨機梯度下降,Keras中還有一些其他優(yōu)化器 # Our examples for an exclusive OR. x_train = np.array([[0, 0],[0, 1],[1, 0],[1, 1]])   # x_train是二維特征向量表示的訓練樣本列表 y_train = np.array([[0],[1],[1],[0]])   # y_train是每個特征向量樣本對應的目標輸出值 model = Sequential() num_neurons = 10  # 全連接隱藏層包含10個神經(jīng)元 model.add(Dense(num_neurons, input_dim=2))   #  input_dim僅在第一層中使用,后面的其他層會自動計算前一層輸出的形狀,這個例子中輸入的XOR樣本是二維特征向量,因此input_dim設置為2 model.add(Activation('tanh')) model.add(Dense(1))   # 輸出層包含一個神經(jīng)元,輸出結果是二分類值(0或1) model.add(Activation('sigmoid')) model.summary()

可以看到模型的結構為:

Layer (type) Output Shape Param ================================================================= dense_18 (Dense) (None, 10) 30 _________________________________________________________________ activation_6 (Activation) (None, 10) 0 _________________________________________________________________ dense_19 (Dense) (None, 1) 11 _________________________________________________________________ activation_7 (Activation) (None, 1) 0 ================================================================= Total params: 41.0 Trainable params: 41.0 Non-trainable params: 0.0

model.summary()提供了網(wǎng)絡參數(shù)及各階段權重數(shù)(Param \#)的概覽。我們可以快速計算一下:10個神經(jīng)元,每個神經(jīng)元有3個權重,其中有兩個是輸入向量的權重(輸入向量中的每個值對應一個權重),還有一個是偏置對應的權重,所以一共有30個權重需要學習。輸出層中有10個權重,分別與第一層的10個神經(jīng)元一一對應,再加上1個偏置權重,所以該層共有11個權重。

下面的代碼可能有點兒不容易理解:

sgd = SGD(lr=0.1) model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])

SGD是之前導入的隨機梯度下降優(yōu)化器,模型用它來最小化誤差或者損失。lr是學習速率,與每個權重的誤差的導數(shù)結合使用,數(shù)值越大模型的學習速度越快,但可能會使模型無法找到全局極小值,數(shù)值越小越精確,但會增加訓練時間,并使模型更容易陷入局部極小值。損失函數(shù)本身也定義為一個參數(shù),在這里用的是binary_crossentropy。metrics參數(shù)是訓練過程中輸出流的選項列表。用compile方法進行編譯,此時還未開始訓練模型,只對權重進行了初始化,大家也可以嘗試一下用這個隨機初始狀態(tài)來預測,當然得到的結果只是隨機猜測:

model.predict(x_train) [[ 0.5 ][ 0.43494844][ 0.50295198][ 0.42517585]]

predict方法將給出最后一層的原始輸出,在這個例子中是由sigmoid函數(shù)生成的。

之后再沒什么好寫的了,但是這里還沒有關于答案的任何知識,它只是對輸入使用了隨機權重。接下來可以試著進行訓練。

model.fit(x_train, y_train, epochs=100)   # 從這里開始訓練模型 Epoch 1/100 4/4 [==============================] - 0s - loss: 0.6917 - acc: 0.7500 Epoch 2/100 4/4 [==============================] - 0s - loss: 0.6911 - acc: 0.5000 Epoch 3/100 4/4 [==============================] - 0s - loss: 0.6906 - acc: 0.5000 ... Epoch 100/100 4/4 [==============================] - 0s - loss: 0.6661 - acc: 1.0000

提示

在第一次訓練時網(wǎng)絡可能不會收斂。第一次編譯可能以隨機分布的參數(shù)結束,導致難以或者不能得到全局極小值。如果遇到這種情況,可以用相同的參數(shù)再次調用model.fit,或者添加更多訓練周期,看看網(wǎng)絡能否收斂。或者也可以用不同的隨機起始點來重新初始化網(wǎng)絡,然后再次嘗試fit。如果使用后面這種方法,請確保沒有設置隨機種子,否則只會不斷重復同樣的實驗結果。

當網(wǎng)絡一遍又一遍地學習這個小數(shù)據(jù)集時,它終于弄明白了這是怎么回事。它從樣本中“學會”了什么是異或!這就是神經(jīng)網(wǎng)絡的神奇之處。

model.predict_classes(x_train) 4/4 [==============================] - 0s [[0][1][1][0]] model.predict(x_train) 4/4 [==============================] - 0s [[ 0.0035659 ][ 0.99123639][ 0.99285167][ 0.00907462]]

在這個經(jīng)過訓練的模型上再次調用predict(和predict_classes)會產(chǎn)生更好的結果。它在這個小數(shù)據(jù)集上獲得了 100%的精確度。當然,精確率并不是評估預測模型的最佳標準,但對這個小例子來說完全可以說明問題。接下來展示了如何保存這個異或模型:

import h5py model_structure = model.to_json()  # 用Keras的輔助方法將網(wǎng)絡結構導出為JSON blob類型以備后用with open("basic_model.json", "w") as json_file:json_file.write(model_structure)model.save_weights("basic_weights.h5")  # 訓練好的權重必須被單獨保存。第一部分只保存網(wǎng)絡結構。在后面重新加載網(wǎng)絡結構時必須對其重新實例化

同樣也有對應的方法來重新實例化模型,這樣做預測時不必再去重新訓練模型。雖然運行這個模型只需要幾秒,但是在后面的章節(jié)中,模型的運行時間將會快速增長到以分鐘、小時甚至天為單位,這取決于硬件性能和模型的復雜度,所以請準備好!

本文內(nèi)容經(jīng)出版社授權發(fā)布,節(jié)選自《自然語言處理實戰(zhàn)》一書,由霍布森·萊恩,科爾·霍華德所著。理論與實戰(zhàn)結合,有具體的代碼可以參考,對于理解算法過程很有幫助。

往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統(tǒng)計學習方法》的代碼復現(xiàn)專輯 AI基礎下載機器學習的數(shù)學基礎專輯 獲取本站知識星球優(yōu)惠券,復制鏈接直接打開: https://t.zsxq.com/qFiUFMV 本站qq群704220115。加入微信群請掃碼: 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的【深度学习】神经网络的Python代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。