神經網絡篇——從代碼出發理解BP神經網絡

2021-01-10 神經網絡研究所

一提到反向傳播算法,我們就不自覺的想到隨機梯度下降、sigmoid激活函數和最讓人頭大的反向傳播法則的推導,即便是把反向傳播神經網絡的原理學了一遍,也還是一頭霧水,在這裡推薦一本小編認為把BP神經網絡講的最通透的教材《Python神經網絡編程》。下面小編將以代碼的方式帶著大家一步一步實現BP神經網絡,並且還會再用框架的方式實現BP網絡,用來和源碼作比較,認識一下TensorFlow2.0的強大。

我們首先要理清建立BP神經網絡的目的,其次,確定BP神經網絡的結構,簡單地以一個輸入層,一個隱藏層,一個輸出層為例,我們來思考一下寫代碼的思路,然後一步一步實現。

在這裡,我們建立BP神經網絡的目的是為了做預測,我們這裡用700條MG時間序列數據作為訓練數據,輸入維度是10,輸出為1,為了方便,我們設置一個隱藏層,這個隱藏層包含10個節點,所以我們的BP神經網絡的結構就是[10,10,1]。接下來,開始思考一下流程:

1、讀取數據,將數據分為訓練集和測試集,注意這裡的數據默認都是np.array()的格式。

2、初始化BP網絡,主要是確定網絡結構,輸入層、隱藏層、輸出層個數,以及隨機初始化相互連接的權值

3、調用訓練方法,傳入數據進行訓練

前向傳播 反向傳播保存模型進行測試 裡面還有很多細節,我們邊寫邊完善,整個程序的框架已經很明確了。從第一步開始,讀取數據,第一步中需要注意的是,讀取的數據最好進行歸一化處理,一方面,這樣做有助於提高預測精度,另一方面,如果使用sigmoid作為激活函數的話,它的輸出是在[0,1]之間的,如果數據不進行歸一化,不在[0,1]區間的數是沒有辦法預測的。這裡我們直接調用sklearn中的最大最小歸一化的方法就可以,為了方便讀者理解代碼,我們將import緊挨著代碼:

#防止數據用科學計數法輸出 np.set_printoptions(suppress=True) #讀取數據 way1 = 'Traindata11.csv' data = np.array(pd.DataFrame(pd.read_csv(way1))) # 歸一化所有數據 from sklearn.preprocessing import MinMaxScaler format_minmax = MinMaxScaler() data = format_minmax.fit_transform(data) x = data[:,:-1] #需要訓練的數據 y = data[:,-1] #label,標籤 #初始化BP網絡 #訓練網絡

第二步,我們要初始化網絡,確定網絡的結構:

def __init__(self, ni, nh, no):

"""

構造神經網絡

:param ni:輸入單元數量

:param nh:隱藏單元數量

:param no:輸出單元數量

"""

self.ni = ni + 1 # +1 是為了偏置節點

self.nh = nh

self.no = no

# 激活值(輸出值)

self.ai = [1.0] * self.ni #這裡會生成一個1*ni維,數值全為1的列表

self.ah = [1.0] * self.nh

self.ao = [1.0] * self.no

# 權重矩陣

self.wi = np.random.randn(self.ni, self.nh) #輸入層到隱藏層

self.wo = np.random.randn(self.nh, self.no) # 隱藏層到輸出層

# 記錄權重矩陣的上次梯度

self.ci = np.zeros([self.ni, self.nh])

self.co = np.zeros([self.nh, self.no])

第三步開始訓練並保存模型:

def train(self,train,lable,max_iterations=1000, N=0.5, M=0.1):

"""

訓練

:param train:訓練集

:param lable:標籤

:param max_iterations:最大迭代次數

:param N:本次學習率

:param M:上次學習率

"""

for i in range(max_iterations): #迭代最大訓練次數(epoch)

for j in range(len(train)): #訓練集

inputs = train[j] #輸入向量

targets = lable[j] #目標值

self.forword_propagation(inputs) #前向傳播訓練

error = self.back_propagation(targets, N, M) #反向傳播訓練,傳入lable

if i % 50 == 0: #每50次輸出一次誤差(loss),loss函數為mse

print('Combined error', error)

winame = 'wi.npy'

woname = 'wo.npy'

np.save(winame, self.wi)

np.save(woname, self.wo)

接下來我們就要實現前向傳播和反向傳播的方法了,我們按照順序從前向傳播開始,前向傳播用到了sigmoid作為激活函數,所以我們把sigmoid函數也一併列出:

def sigmoid(self,x):

"""

sigmoid 函數,1/(1+e^-x)

:param x:

:return:

"""

return 1.0 / (1.0 + math.exp(-x))

def forword_propagation(self, inputs):

"""

前向傳播進行分類

:param inputs:輸入

:return:類別

"""

if len(inputs) != self.ni - 1: #檢查輸入數據的維度是否和聲明的一致

print('輸入維度有誤,請重新檢查輸入')

for i in range(self.ni - 1): #按順序將n維的input映射到n個輸入節點上

self.ai[i] = inputs[i]

for j in range(self.nh): #遍歷隱藏層節點,每個隱藏層節點的值為n個輸入節點*對應權值(輸入層和隱藏層)的和

sum = 0.0

for i in range(self.ni):

sum += (self.ai[i] * self.wi[i][j])

self.ah[j] = self.sigmoid(sum) #將節點值經過sigmoid函數激活後,變為[0,1]之間的值

for k in range(self.no): #遍歷輸出層節點,每個輸出層節點的值為n個隱藏層節點*對應權值(隱藏層和輸出層)的和

sum = 0.0

for j in range(self.nh):

sum += (self.ah[j] * self.wo[j][k])

self.ao[k] = self.sigmoid(sum) ##將節點值經過sigmoid函數激活後,變為[0,1]之間的值

return self.ao #返回輸出層的值

接下來是反向傳播,反向傳播中需要對sigmoid進行求導,為了方便我們直接寫出sigmoid的求導結果,另外這裡的誤差函數(loss)選擇mse:

def dsigmoid(self,y):

"""

sigmoid 函數的導數

:param y:

:return:

"""

return y * (1 - y)

def back_propagation(self, targets, N, M):

"""

反向傳播算法

:param targets: 實例的類別

:param N: 本次學習率

:param M: 上次學習率

:return: 最終的誤差平方和的一半

"""

# 計算輸出層 deltas,求導數

# dE/dw[j][k] = (t[k] - ao[k]) * s'( SUM( w[j][k]*ah[j] ) ) * ah[j]

output_deltas = [0.0] * self.no #初始化輸出層列表為0

for k in range(self.no):

error = targets[k] - self.ao[k] #計算輸出層誤差

output_deltas[k] = error * self.dsigmoid(self.ao[k]) #計算每一個節點對誤差的影響大小,佔比越大,影響越大

# 根據delta更新隱藏層和輸出層之間的權值

for j in range(self.nh):

for k in range(self.no):

# output_deltas[k] * self.ah[j] 才是 dError/dweight[j][k]

change = output_deltas[k] * self.ah[j] #根據比例計算需要調整的值

self.wo[j][k] += N * change + M * self.co[j][k] #調整權值,調整方法有很多,例如隨機梯度下降,這裡只是簡單寫了一下

self.co[j][k] = change #保存調整的梯度

# 計算隱藏層 deltas

hidden_deltas = [0.0] * self.nh

for j in range(self.nh):

error = 0.0

for k in range(self.no):

error += output_deltas[k] * self.wo[j][k]

hidden_deltas[j] = error * self.dsigmoid(self.ah[j])

# 更新輸入層權值

for i in range(self.ni):

for j in range(self.nh):

change = hidden_deltas[j] * self.ai[i]

# print 'activation',self.ai[i],'synapse',i,j,'change',change

self.wi[i][j] += N * change + M * self.ci[i][j]

self.ci[i][j] = change

# 計算MSE

error = 0.0

for k in range(len(targets)):

error += (targets[k] - self.ao[k]) ** 2

error = error/len(y)

return error

到這裡就差不多實現了一個最簡單的BP神經網絡,不過小編強烈反對用這個代碼來進行實戰,這個代碼只適用於理解BP神經網絡。在下一篇中,我將用Tensorflow框架和Pytorch框架來實現一個通用的BP神經網絡,並且解答一下為什麼要使用激活函數。

不知不覺,2021年到來了,馬上天就要亮了,這一篇是小編的第一篇公眾號,僅以此銘記2021.1.1日凌晨。祝各位讀者,元旦快樂!!!

公眾號「神經網絡研究所」

公眾號發送「BP神經網絡圖書」,即可獲取電子版圖書。

公眾號發送「BP源碼」,即可獲取完整版源碼。

相關焦點

  • 神經網絡篇——用TensorFlow2.0框架實現BP網絡
    那這個感知器模型和BP網絡有什麼關係呢?在我們所看到的BP網絡的結構圖中,其實是被簡化了的,下面小編畫了一個邏輯更清晰一點的圖:這樣我們就可以看出來,其實BP網絡是由一個一個的感知器組成,也就構成了一個真正的神經網絡,自然就能理解為什麼要使用激活函數了。接下來我們來看一下TensorFlow實現BP神經網絡到底有多簡單!
  • AI從入門到放棄:BP神經網絡算法推導及代碼實現筆記
    導數符號不變,讓神經網絡訓練容易收斂。這裡只說我們用到的激活函數:求一下它的導數把,因為後面講bp算法會直接套用它:先祭出大殺器,高中數學之複合函數求導法則:它的導數圖像:▌五. 沙漠中心的風暴:BP(Back Propagation)算法1.
  • BP神經網絡
    其實在其他領域也是一樣,隨著神經網絡學習資料庫的範圍變大,學習程度的深入,使得神經網絡在更多領域得到運用,神經網絡正在成為一種有效的工具。由於財務風險預警的複雜性以及對決策的重要影響,國內外有大量的研究預測工作,採用各種方法來優化財務風險預警模型。
  • PyTorch可視化理解卷積神經網絡
    如今,機器已經能夠在理解、識別圖像中的特徵和對象等領域實現99%級別的準確率。生活中,我們每天都會運用到這一點,比如,智慧型手機拍照的時候能夠識別臉部、在類似於谷歌搜圖中搜索特定照片、從條形碼掃描文本或掃描書籍等。造就機器能夠獲得在這些視覺方面取得優異性能可能是源於一種特定類型的神經網絡——卷積神經網絡(CNN)。
  • 一文詳解神經網絡 BP 算法原理及 Python 實現
    所謂的鏈式求導法則,就是求複合函數的導數: 鏈式求導法則 放個例題,會更加明白一點: 鏈式求導的例子 神經網絡的結構 神經網絡由三部分組成,分別是最左邊的輸入層,隱藏層(實際應用中遠遠不止一層)和最右邊的輸出層。
  • 人工神經網絡的本質(物理或數學意義)是什麼?
    從數學的角度講,人工神經網絡的本質從機器學習的過程可理解為通過參數求最佳解得過程。同樣也是一個負反饋的過程,以最簡單的負反饋神經網絡bp神經網絡(back propagation)為例,其本質可以形象的理解為這樣一個過程:我們假設這個剛搭建的好的機器人叫
  • 神經網絡模型預測值 論文_bp神經網絡預測模型建模步驟 - CSDN
    這些形式的連接經常被手工重新進行設置,從而可以清除神經網絡的狀態。和常規連接的主要區別是,這種連接會持續不斷地改變,即便這個神經網絡當前沒有處於訓練狀態。下圖展示了以上所介紹的神經網絡及其連接方式。以下內容將詳細介紹25個神經網絡模型,如果你想閱讀關於它們的原始論文,請在微信中回復「神經網絡」,即可獲得打包的PDF文件。
  • 一篇文章教你用11行Python代碼實現神經網絡
    聲明:本文是根據英文教程 (用 11 行 Python 代碼實現的神經網絡)學習總結而來,關於更詳細的神經網絡的介紹可以參考我的另一篇博客:。A Neural Network in 11 lines of Python從感知機到人工神經網絡如果你讀懂了下面的文章,你會對神經網絡有更深刻的認識,有任何問題,請多指教。
  • BP人工神經網絡實驗,蠓蟲分類(美國1989年建模賽題)
    1、用BP人工神經網絡擬合函數 y=0.12e^(-0.23x)+0.54e^(-0.17x)sin(1.23x).要求給出真實數據點,用*表示,給出BP神經網絡擬合後的曲線。同時用CFTOOL和1stopt驗證。
  • 人工智慧算法:訓練神經網絡中的批量歸一化(附代碼)
    而且,如果您還沒有這樣做的話,本文將解釋BN的基本直覺,包括其起源以及如何使用TensorFlow和Keras在神經網絡中實現它。對於那些熟悉BN技術並且只想專注於實現的人,可以跳到下面的「代碼」部分。
  • 一份完全解讀:是什麼使神經網絡變成圖神經網絡?
    本文將就「為什麼圖有用」、「為什麼很難在圖上定義卷積」、「是什麼使神經網絡成為了圖神經網絡」這些問題進行討論。首先,讓我們簡單回顧一下什麼是圖?圖 G 是由有向或無向邊連接的一組節點(頂點)。節點和邊通常是由專家依據知識經驗或是對問題的直覺進行設置的。
  • 一文看懂系列之深入理解 RNN——神經圖靈機(附代碼)
    原標題:一文看懂系列之深入理解 RNN——神經圖靈機(附代碼) 1 新智元推薦 當然,深度學習中有很多種網絡結構,像多層網絡結構(multi layered)可能大家比較熟悉,相信很多人接觸神經網絡是從下圖這樣的結構開始的,這也是deep learning中「deep」的來源。好友YJango也在專欄中寫了一系列很好的介紹深層神經網絡的文章,也以新穎的觀點分析了深層學習為什麼要deep。
  • 多變量多因子的非線性模型|BP神經網絡模型
    神經網絡模型的靈感來源於生物體內的神經網絡,大量的神經元(可以理解為變量)之間相互聯繫,共同協作處理問題。通過不斷調整輸入神經元的權重,達到目標結果,這也就是訓練的過程二、BP神經網絡BP的全稱是Backpropagation,譯為反向傳播,是目前應用最為廣泛的神經網絡模型之一。
  • 理解卷積神經網絡中的輸入與輸出形狀(Keras實現)
    即使我們從理論上理解了卷積神經網絡,在實際進行將數據擬合到網絡時,很多人仍然對其網絡的輸入和輸出形狀(shape)感到困惑。本文章將幫助你理解卷積神經網絡的輸入和輸出形狀。讓我們看看一個例子。CNN的輸入數據如下圖所示。
  • 為什麼神經網絡難以理解生命遊戲?
    我們可以發現對生命遊戲顯然有效的,幾組神經網絡的初始參數解;但隨機輸入初始參數和選擇樣本的神經網絡,卻極難理解生命遊戲,成功收斂到最優解需要一定「運氣」。我們也可以選擇,提高神經網絡的複雜性,得到較優解,但這使資金和能耗水漲船高,不可持續。這種現狀要求我們探索新的學習算法。
  • 【乾貨】用神經網絡識別歌曲流派(附代碼)
    作者:Navdeep Singh編譯:肖琴【新智元導讀】本文手把手教你如何構建一個能夠識別歌曲類型的神經網絡。MFCC值將被直接輸入神經網絡。了解MFCC讓我們用兩個例子來說明MFCC。請通過Stereo Surgeon下載Kick Loop 5[2]和Whistling[3]。其中一個是低音鼓聲,另一個是高音口哨聲。它們明顯不同,你可以看到它們的MFCC數值是不同的。讓我們轉到代碼(本文的所有代碼文件都可以在Github連結中找到)。
  • 代碼詳解:基於Python建立任意層數的深度神經網絡 - 讀芯術
    圖1 神經網絡構造的例子(符號說明:上標[l]表示與第l層;上標(i)表示第i個例子;下標i表示矢量第i項)單層神經網絡圖2 單層神經網絡示例神經元模型是先計算一個線性函數(z=Wx+b),接著再計算一個激活函數。一般來說,神經元模型的輸出值是a=g(Wx+b),其中g是激活函數(sigmoid,tanh, ReLU, …)。
  • 基於神經網絡算法 羊毛_基於pso算法和bp算法訓練神經網絡 - CSDN
    圖神經網絡是用於圖結構數據的深度學習架構,將端到端學習與歸納推理相結合,業界普遍認為其有望解決深度學習無法處理的因果推理、可解釋性等一系列瓶頸問題,是未來 3 到 5 年的重點方向。2019 年圖神經網絡有哪些研究成果值得關注?2020 年它又將朝什麼方向發展?讓我們一起來一探究竟。
  • 理解神經網絡:從神經元到RNN、CNN、深度學習
    隨著時間的推移,證明了神經網絡在精度和速度方面,比其他的算法性能更好。並且形成了很多種類,像CNN(卷積神經網絡),RNN,自編碼,深度學習等等。神經網絡對於數據科學和或者機器學習從業者,就像線性回歸對於統計學家一樣。因此,對神經網絡是什麼有一個基本的理解是有必要的,比如,它是怎麼構成的,它能處理問題的範圍以及它的局限性是什麼。
  • 代碼詳解:使用NumPy,教你9步從頭搭建神經網絡
    本文介紹了使用NumPy從頭搭建神經網絡的9個步驟,即從數據預處理到反向傳播這一「必經之路」。對機器學習、人工神經網絡、Python語法和編程邏輯有些基本理解最好,(但這也不是必需條件,你可以邊讀邊學)。1. 初始化導入NumPy。