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

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

一提到反向傳播算法,我們就不自覺的想到隨機梯度下降、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源碼」,即可獲取完整版源碼。

相關焦點

  • 如何教神經網絡玩 21 點遊戲(附代碼)?
    神經網絡是高度靈活的算法——像軟粘土一樣,神經網絡調整自己,以適應數據的輪廓。神經網絡可以很容易地處理那些會給線性回歸等帶來麻煩的數據。此外,網絡中的層和神經元將學習數據中可能存在的任何深度嵌入的非線性關係。然而,這種功能是有代價的——神經網絡是一個黑箱模型。與回歸不同的是,我們可以通過觀察回歸係數來了解模型是如何做出決策的,神經網絡並不具備這種透明性。
  • 實戰|手把手入門神經網絡,74行代碼實現手寫數字識別
    因此,本文直接用Michael Nielsen先生的代碼作為例子,給大家展現神經網絡分析的普遍過程:導入數據,訓練模型,優化模型,啟發式理解等。本文假設大家已經了解python的基本語法,並在自己機器上運行過簡單python腳本。
  • BP人工神經網絡實驗,蠓蟲分類(美國1989年建模賽題)
    1、用BP人工神經網絡擬合函數 y=0.12e^(-0.23x)+0.54e^(-0.17x)sin(1.23x).要求給出真實數據點,用*表示,給出BP神經網絡擬合後的曲線。同時用CFTOOL和1stopt驗證。
  • 什麼是人工神經網絡(ANN)?
    但是直到最近幾年,神經網絡的承諾才變為現實,並幫助AI行業擺脫了漫長的冬季。儘管神經網絡幫助AI取得了飛躍,但它們也常常被誤解。這時您需要了解的有關神經網絡的所有信息。人工和生物神經網絡之間的相似性人工智慧先驅的最初願景是複製人類大腦的功能,這是自然界最聰明,最複雜的已知創造。
  • 圖神經網絡的十大學習資源分享
    字幕組雙語原文:【乾貨】圖神經網絡的十大學習資源分享英語原文:Top 10 Learning Resources for Graph Neural Networks翻譯:雷鋒字幕組(聽風1996)圖神經網絡(GNNs)是深度學習的一個相對較新的領域,從最近開始越來越流行。
  • ...MIT神經科學教授James DiCarlo談如何通過人類神經理解神經網絡
    全體大演講:靈長類視覺理解的反向工程人類大腦根據視覺輸入可以理解物體的類別、位置、姿態等等信息。教授這時也發自內心進行了感謝,深度神經網絡方面的技術發展、建立的優秀的模型幫助神經科學家更好地了解人類大腦中的原理。來自神經網絡的新分歧
  • 【乾貨】用神經網絡識別歌曲流派(附代碼)、國外首提「千腦智力理論」或顛覆AI:理解人類新大腦皮層
    MFCC值將被直接輸入神經網絡。讓我們用兩個例子來說明MFCC。請通過Stereo Surgeon下載Kick Loop 5[2]和Whistling[3]。其中一個是低音鼓聲,另一個是高音口哨聲。它們明顯不同,你可以看到它們的MFCC數值是不同的。讓我們轉到代碼(本文的所有代碼文件都可以在Github連結中找到)。
  • 用TensorFlow基於神經網絡實現井字棋(含代碼)
    為了展示如何應用神經網絡算法模型,我們將使用神經網絡來學習優化井字棋(Tic Tac Toe)。
  • 神經網絡及其背後的數學——簡化概念,人人都可以理解
    神經元的概念1.感知器:神經網絡的基本構件感知器可以被理解為一個二進位模型,它基本上模仿了一個生物神經元。1905年,科學家弗蘭克·羅森布拉特受到沃倫·麥卡洛克和沃爾特·皮茨早期研究的啟發,首次提出了這個概念,並於1960年提出。感知器模式化一個決策模型,該模型可以根據給定的一組二進位輸入輸出不同的結果。
  • 【乾貨】圖神經網絡的十大學習資源分享
    字幕組雙語原文:【乾貨】圖神經網絡的十大學習資源分享英語原文:Top 10 Learning Resources for Graph Neural Networks>翻譯:雷鋒字幕組(聽風1996)圖神經網絡(GNNs)是深度學習的一個相對較新的領域,從最近開始越來越流行。
  • TensorFlow什麼的都弱爆了,強者只用Numpy搭建神經網絡
    大數據文摘出品作者:蔣寶尚很多同學入門機器學習之後,直接用TensorFlow調包實現神經網絡,對於神經網絡內在機理知之甚少。程式語言與技術框架變化更新非常之快,理解背後的原理才是王道。下面文摘菌和大家一起用Numpy實現一步一步實現神經網絡。
  • 機器學習之神經網絡(1)
    其實神經網絡技術的靈感來自人體內的神經結構。(可以細細體會一下~)由此,神經網絡的理論開始大放異彩,再加上如今硬體設備的發達以及網絡結構的不斷簡化,神經網絡得到了很好的發展。多層前饋神經網絡單層感知器也就是「神經元」是所有神經網絡的核心,由上面的介紹可以知道,其主要由一個加法器和一個激活函數組成。
  • 乾貨分享|使用JAX創建神經網絡的對抗性示例(附詳細代碼)
    在本教程中,我們將看到如何創建使用JAX訓練神經網絡的對抗示例。首先,讓我們看一些定義。有哪些例子?簡而言之,對抗性示例是神經網絡的輸入,這些輸入經過優化以欺騙算法,即導致目標變量分類錯誤。通過向目標變量添加「適當的」噪聲,我們可以對目標變量進行錯誤分類。下圖演示了該概念。
  • 圖神經網絡最新發展
    圖 1:圖像卷積與圖卷積。卷積神經網絡(Convolutional Neural Network,CNN)和圖神經網絡(Graph Neural Network,GNN)的主要區別是什麼?簡單來說,就是輸入數據。你可能還記得,CNN 所需的輸入是一個固定大小的向量或矩陣。然而,某些類型的數據自然是用圖表示的,如分子、引用網絡或社交媒體連接網絡都可以用圖數據來表示。
  • 詳解:遞歸神經網絡和LSTM網絡那些事兒
    這就是為什麼它們是像時間序列、語音、文本、財務數據、音頻、視頻、天氣等時序數據的首選算法,因為它們可以形成對序列及其上下文的深入理解的算法。  遞歸神經網絡在連續數據中產生預測結果,而其他算法則不能。  但是,你何時需要使用循環神經網絡?  「每當有數據序列時,連接數據的時間動態都比每個幀的空間內容更重要。」
  • AI的人工神經網絡
    人工神經網絡是模擬人和動物的神經網絡的某種結構和功能的模擬,所以要了解神經網絡的工作原理,所以我們首先要了解生物神經元。其結構如下圖所示: 從上圖可看出生物神經元它包括,細胞體:由細胞核、細胞質與細胞膜組成;軸突:是從細胞體向外伸出的細長部分,也就是神經纖維。
  • 圖神經網絡加速晶片進入倒計時 全球首款商用圖神經網絡加速IP核...
    因此,該IP核是全球首款圖神經網絡加速IP核,專注於高效加速圖神經網絡的推斷階段。  適合圖神經網絡的算力  此款圖神經網絡加速IP核代號為「GCU Zero」,主要研究人員之一是中科院計算所特別研究助理嚴明玉博士,其畢業於中科院計算所,曾在美國加州大學聖巴巴拉分校 SEAL 實驗室訪學,主要從事圖計算和圖神經網絡加速結構研究。
  • 注視、效價和期望共享但可分離的神經代碼
    注視、效價和期望共享但可分離的神經代碼 作者:小柯機器人 發布時間:2020/9/25 21:48:16 以色列魏茲曼科學研究所Rony Paz研究組取得最新進展。他們的最新研究揭示了注視、效價和期望共享但可分離的神經代碼。
  • 神經網絡理論基礎及 Python 實現
    一、多層前向神經網絡多層前向神經網絡由三部分組成:輸出層、隱藏層、輸出層,每層由單元組成;輸入層由訓練集的實例特徵向量傳入
  • Siamese network 孿生神經網絡:一個簡單神奇的結構
    孿生神經網絡大家可能會有疑問:共享權值是什麼意思?左右兩個神經網絡的權重一模一樣?答:是的,在代碼實現的時候,甚至可以是同一個網絡,不用實現另外一個,因為權值都一樣。對於siamese network,兩邊可以是lstm或者cnn,都可以。大家可能還有疑問:如果左右兩邊不共享權值,而是兩個不同的神經網絡,叫什麼呢?答:pseudo-siamese network,偽孿生神經網絡,如下圖所示。