Ⅰ 從零開始用python構建神經網路
從零開始用Python構建神經網路
動機:為了更加深入的理解深度學習,我們將使用 python 語言從頭搭建一個神經網路,而不是使用像 Tensorflow 那樣的封裝好的框架。我認為理解神經網路的內部工作原理,對數據科學家來說至關重要。
這篇文章的內容是我的所學,希望也能對你有所幫助。
神經網路是什麼?
介紹神經網路的文章大多數都會將它和大腦進行類比。如果你沒有深入研究過大腦與神經網路的類比,那麼將神經網路解釋為一種將給定輸入映射為期望輸出的數學關系會更容易理解。
神經網路包括以下組成部分
? 一個輸入層,x
? 任意數量的隱藏層
? 一個輸出層,?
? 每層之間有一組權值和偏置,W and b
? 為隱藏層選擇一種激活函數,σ。在教程中我們使用 Sigmoid 激活函數
下圖展示了 2 層神經網路的結構(注意:我們在計算網路層數時通常排除輸入層)
2 層神經網路的結構
用 Python 可以很容易的構建神經網路類
訓練神經網路
這個網路的輸出 ? 為:
你可能會注意到,在上面的等式中,輸出 ? 是 W 和 b 函數。
因此 W 和 b 的值影響預測的准確率. 所以根據輸入數據對 W 和 b 調優的過程就被成為訓練神經網路。
每步訓練迭代包含以下兩個部分:
? 計算預測結果 ?,這一步稱為前向傳播
? 更新 W 和 b,,這一步成為反向傳播
下面的順序圖展示了這個過程:
前向傳播
正如我們在上圖中看到的,前向傳播只是簡單的計算。對於一個基本的 2 層網路來說,它的輸出是這樣的:
我們在 NeuralNetwork 類中增加一個計算前向傳播的函數。為了簡單起見我們假設偏置 b 為0:
但是我們還需要一個方法來評估預測結果的好壞(即預測值和真實值的誤差)。這就要用到損失函數。
損失函數
常用的損失函數有很多種,根據模型的需求來選擇。在本教程中,我們使用誤差平方和作為損失函數。
誤差平方和是求每個預測值和真實值之間的誤差再求和,這個誤差是他們的差值求平方以便我們觀察誤差的絕對值。
訓練的目標是找到一組 W 和 b,使得損失函數最好小,也即預測值和真實值之間的距離最小。
反向傳播
我們已經度量出了預測的誤差(損失),現在需要找到一種方法來傳播誤差,並以此更新權值和偏置。
為了知道如何適當的調整權值和偏置,我們需要知道損失函數對權值 W 和偏置 b 的導數。
回想微積分中的概念,函數的導數就是函數的斜率。
梯度下降法
如果我們已經求出了導數,我們就可以通過增加或減少導數值來更新權值 W 和偏置 b(參考上圖)。這種方式被稱為梯度下降法。
但是我們不能直接計算損失函數對權值和偏置的導數,因為在損失函數的等式中並沒有顯式的包含他們。因此,我們需要運用鏈式求導發在來幫助計算導數。
鏈式法則用於計算損失函數對 W 和 b 的導數。注意,為了簡單起見。我們只展示了假設網路只有 1 層的偏導數。
這雖然很簡陋,但是我們依然能得到想要的結果—損失函數對權值 W 的導數(斜率),因此我們可以相應的調整權值。
現在我們將反向傳播演算法的函數添加到 Python 代碼中
為了更深入的理解微積分原理和反向傳播中的鏈式求導法則,我強烈推薦 3Blue1Brown 的如下教程:
Youtube:https://youtu.be/tIeHLnjs5U8
整合並完成一個實例
既然我們已經有了包括前向傳播和反向傳播的完整 Python 代碼,那麼就將其應用到一個例子上看看它是如何工作的吧。
神經網路可以通過學習得到函數的權重。而我們僅靠觀察是不太可能得到函數的權重的。
讓我們訓練神經網路進行 1500 次迭代,看看會發生什麼。 注意觀察下面每次迭代的損失函數,我們可以清楚地看到損失函數單調遞減到最小值。這與我們之前介紹的梯度下降法一致。
讓我們看看經過 1500 次迭代後的神經網路的最終預測結果:
經過 1500 次迭代訓練後的預測結果
我們成功了!我們應用前向和方向傳播演算法成功的訓練了神經網路並且預測結果收斂於真實值。
注意預測值和真實值之間存在細微的誤差是允許的。這樣可以防止模型過擬合並且使得神經網路對於未知數據有著更強的泛化能力。
下一步是什麼?
幸運的是我們的學習之旅還沒有結束,仍然有很多關於神經網路和深度學習的內容需要學習。例如:
? 除了 Sigmoid 以外,還可以用哪些激活函數
? 在訓練網路的時候應用學習率
? 在面對圖像分類任務的時候使用卷積神經網路
我很快會寫更多關於這個主題的內容,敬請期待!
最後的想法
我自己也從零開始寫了很多神經網路的代碼
雖然可以使用諸如 Tensorflow 和 Keras 這樣的深度學習框架方便的搭建深層網路而不需要完全理解其內部工作原理。但是我覺得對於有追求的數據科學家來說,理解內部原理是非常有益的。
這種練習對我自己來說已成成為重要的時間投入,希望也能對你有所幫助
Ⅱ net=newff(p_train,t_train,[],{'logsig'},'traingd'); 以此想建立一個單隱層的神經網路,隱層神經元個數
一般情況下,隱層神經元個數是根據經驗確定的,可以根據下列條件來確定
在一個最佳的隱層單元數。以下4個公式可以用於選擇最佳隱層單元數時的參考公式。
,其中,為樣本數, 為隱層單元數,為輸入單元數。如果,.
(2)其中, 為輸入神經元數,為之間的常數。
(3,其中,為訓練樣本的個數。
(4),其中,為輸入的神經元個數。
Ⅲ 如何用python和scikit learn實現神經網路
1:神經網路演算法簡介
2:Backpropagation演算法詳細介紹
3:非線性轉化方程舉例
4:自己實現神經網路演算法NeuralNetwork
5:基於NeuralNetwork的XOR實例
6:基於NeuralNetwork的手寫數字識別實例
7:scikit-learn中BernoulliRBM使用實例
8:scikit-learn中的手寫數字識別實例
一:神經網路演算法簡介
1:背景
以人腦神經網路為啟發,歷史上出現過很多版本,但最著名的是backpropagation
2:多層向前神經網路(Multilayer Feed-Forward Neural Network)
Ⅳ 如何用 Python 構建神經網路擇時模型
import math
import random
random.seed(0)
def rand(a,b): #隨機函數
return (b-a)*random.random()+a
def make_matrix(m,n,fill=0.0):#創建一個指定大小的矩陣
mat = []
for i in range(m):
mat.append([fill]*n)
return mat
#定義sigmoid函數和它的導數
def sigmoid(x):
return 1.0/(1.0+math.exp(-x))
def sigmoid_derivate(x):
return x*(1-x) #sigmoid函數的導數
class BPNeuralNetwork:
def __init__(self):#初始化變數
self.input_n = 0
self.hidden_n = 0
self.output_n = 0
self.input_cells = []
self.hidden_cells = []
self.output_cells = []
self.input_weights = []
self.output_weights = []
self.input_correction = []
self.output_correction = []
#三個列表維護:輸入層,隱含層,輸出層神經元
def setup(self,ni,nh,no):
self.input_n = ni+1 #輸入層+偏置項
self.hidden_n = nh #隱含層
self.output_n = no #輸出層
#初始化神經元
self.input_cells = [1.0]*self.input_n
self.hidden_cells= [1.0]*self.hidden_n
self.output_cells= [1.0]*self.output_n
#初始化連接邊的邊權
self.input_weights = make_matrix(self.input_n,self.hidden_n) #鄰接矩陣存邊權:輸入層->隱藏層
self.output_weights = make_matrix(self.hidden_n,self.output_n) #鄰接矩陣存邊權:隱藏層->輸出層
#隨機初始化邊權:為了反向傳導做准備--->隨機初始化的目的是使對稱失效
for i in range(self.input_n):
for h in range(self.hidden_n):
self.input_weights[i][h] = rand(-0.2 , 0.2) #由輸入層第i個元素到隱藏層第j個元素的邊權為隨機值
for h in range(self.hidden_n):
for o in range(self.output_n):
self.output_weights[h][o] = rand(-2.0, 2.0) #由隱藏層第i個元素到輸出層第j個元素的邊權為隨機值
#保存校正矩陣,為了以後誤差做調整
self.input_correction = make_matrix(self.input_n , self.hidden_n)
self.output_correction = make_matrix(self.hidden_n,self.output_n)
#輸出預測值
def predict(self,inputs):
#對輸入層進行操作轉化樣本
for i in range(self.input_n-1):
self.input_cells[i] = inputs[i] #n個樣本從0~n-1
#計算隱藏層的輸出,每個節點最終的輸出值就是權值*節點值的加權和
for j in range(self.hidden_n):
total = 0.0
for i in range(self.input_n):
total+=self.input_cells[i]*self.input_weights[i][j]
# 此處為何是先i再j,以隱含層節點做大循環,輸入樣本為小循環,是為了每一個隱藏節點計算一個輸出值,傳輸到下一層
self.hidden_cells[j] = sigmoid(total) #此節點的輸出是前一層所有輸入點和到該點之間的權值加權和
for k in range(self.output_n):
total = 0.0
for j in range(self.hidden_n):
total+=self.hidden_cells[j]*self.output_weights[j][k]
self.output_cells[k] = sigmoid(total) #獲取輸出層每個元素的值
return self.output_cells[:] #最後輸出層的結果返回
#反向傳播演算法:調用預測函數,根據反向傳播獲取權重後前向預測,將結果與實際結果返回比較誤差
def back_propagate(self,case,label,learn,correct):
#對輸入樣本做預測
self.predict(case) #對實例進行預測
output_deltas = [0.0]*self.output_n #初始化矩陣
for o in range(self.output_n):
error = label[o] - self.output_cells[o] #正確結果和預測結果的誤差:0,1,-1
output_deltas[o]= sigmoid_derivate(self.output_cells[o])*error#誤差穩定在0~1內
#隱含層誤差
hidden_deltas = [0.0]*self.hidden_n
for h in range(self.hidden_n):
error = 0.0
for o in range(self.output_n):
error+=output_deltas[o]*self.output_weights[h][o]
hidden_deltas[h] = sigmoid_derivate(self.hidden_cells[h])*error
#反向傳播演算法求W
#更新隱藏層->輸出權重
for h in range(self.hidden_n):
for o in range(self.output_n):
change = output_deltas[o]*self.hidden_cells[h]
#調整權重:上一層每個節點的權重學習*變化+矯正率
self.output_weights[h][o] += learn*change + correct*self.output_correction[h][o]
#更新輸入->隱藏層的權重
for i in range(self.input_n):
for h in range(self.hidden_n):
change = hidden_deltas[h]*self.input_cells[i]
self.input_weights[i][h] += learn*change + correct*self.input_correction[i][h]
self.input_correction[i][h] = change
#獲取全局誤差
error = 0.0
for o in range(len(label)):
error = 0.5*(label[o]-self.output_cells[o])**2 #平方誤差函數
return error
def train(self,cases,labels,limit=10000,learn=0.05,correct=0.1):
for i in range(limit): #設置迭代次數
error = 0.0
for j in range(len(cases)):#對輸入層進行訪問
label = labels[j]
case = cases[j]
error+=self.back_propagate(case,label,learn,correct) #樣例,標簽,學習率,正確閾值
def test(self): #學習異或
cases = [
[0, 0],
[0, 1],
[1, 0],
[1, 1],
] #測試樣例
labels = [[0], [1], [1], [0]] #標簽
self.setup(2,5,1) #初始化神經網路:輸入層,隱藏層,輸出層元素個數
self.train(cases,labels,10000,0.05,0.1) #可以更改
for case in cases:
print(self.predict(case))
if __name__ == '__main__':
nn = BPNeuralNetwork()
nn.test()
Ⅳ python定義的神經網路類裡面的一個函數,手機提問沒有顯示縮進,都是一個函數下的,見諒一下
我知道你這個代碼,你沒有貼全,源頭是GitHub上的對吧。
self.hidden_layer.inspect(),這裡面的inspect應該不是遞歸,不然感覺會遞歸到時間盡頭的。
應該是:
definspect(self):
#print該層神經元的信息
print('Neurons:',len(self.neurons))
forninrange(len(self.neurons)):
print('Neuron',n)
forwinrange(len(self.neurons[n].weights)):
print('Weight:',self.neurons[n].weights[w])
print('Bias:',self.bias)
上面這段代碼的inspect。
所以,
self.hidden_layer.inspect()
是輸出隱層的層數和偏置項
有的代碼要藉助ide才能理解的,手機看有點勉強了。
Ⅵ 有沒有用python實現的遺傳演算法優化BP神經網路的代碼
下面是函數實現的代碼部分:
clc
clear all
close all
%% 載入神經網路的訓練樣本 測試樣本每列一個樣本 輸入P 輸出T,T是標簽
%樣本數據就是前面問題描述中列出的數據
%epochs是計算時根據輸出誤差返回調整神經元權值和閥值的次數
load data
% 初始隱層神經元個數
hiddennum=31;
% 輸入向量的最大值和最小值
threshold=[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1];
inputnum=size(P,1); % 輸入層神經元個數
outputnum=size(T,1); % 輸出層神經元個數
w1num=inputnum*hiddennum; % 輸入層到隱層的權值個數
w2num=outputnum*hiddennum;% 隱層到輸出層的權值個數
N=w1num+hiddennum+w2num+outputnum; %待優化的變數的個數
%% 定義遺傳演算法參數
NIND=40; %個體數目
MAXGEN=50; %最大遺傳代數
PRECI=10; %變數的二進制位數
GGAP=0.95; %代溝
px=0.7; %交叉概率
pm=0.01; %變異概率
trace=zeros(N+1,MAXGEN); %尋優結果的初始值
FieldD=[repmat(PRECI,1,N);repmat([-0.5;0.5],1,N);repmat([1;0;1;1],1,N)]; %區域描述器
Chrom=crtbp(NIND,PRECI*N); %初始種群
%% 優化
gen=0; %代計數器
X=bs2rv(Chrom,FieldD); %計算初始種群的十進制轉換
ObjV=Objfun(X,P,T,hiddennum,P_test,T_test); %計算目標函數值
while gen
Ⅶ 怎樣用python構建一個卷積神經網路
用keras框架較為方便
首先安裝anaconda,然後通過pip安裝keras
Ⅷ 如何通過Python進行深度學習
作者 | Vihar Kurama
編譯 | 荷葉
來源 | 雲棲社區
摘要:深度學習背後的主要原因是人工智慧應該從人腦中汲取靈感。本文就用一個小例子無死角的介紹一下深度學習!
人腦模擬
深度學習背後的主要原因是人工智慧應該從人腦中汲取靈感。此觀點引出了「神經網路」這一術語。人腦中包含數十億個神經元,它們之間有數萬個連接。很多情況下,深度學習演算法和人腦相似,因為人腦和深度學習模型都擁有大量的編譯單元(神經元),這些編譯單元(神經元)在獨立的情況下都不太智能,但是當他們相互作用時就會變得智能。
我認為人們需要了解到深度學習正在使得很多幕後的事物變得更好。深度學習已經應用於谷歌搜索和圖像搜索,你可以通過它搜索像「擁抱」這樣的詞語以獲得相應的圖像。-傑弗里·辛頓
神經元
神經網路的基本構建模塊是人工神經元,它模仿了人類大腦的神經元。這些神經元是簡單、強大的計算單元,擁有加權輸入信號並且使用激活函數產生輸出信號。這些神經元分布在神經網路的幾個層中。
inputs 輸入 outputs 輸出 weights 權值 activation 激活
人工神經網路的工作原理是什麼?
深度學習由人工神經網路構成,該網路模擬了人腦中類似的網路。當數據穿過這個人工網路時,每一層都會處理這個數據的一方面,過濾掉異常值,辨認出熟悉的實體,並產生最終輸出。
輸入層:該層由神經元組成,這些神經元只接收輸入信息並將它傳遞到其他層。輸入層的圖層數應等於數據集里的屬性或要素的數量。輸出層:輸出層具有預測性,其主要取決於你所構建的模型類型。隱含層:隱含層處於輸入層和輸出層之間,以模型類型為基礎。隱含層包含大量的神經元。處於隱含層的神經元會先轉化輸入信息,再將它們傳遞出去。隨著網路受訓練,權重得到更新,從而使其更具前瞻性。
神經元的權重
權重是指兩個神經元之間的連接的強度或幅度。你如果熟悉線性回歸的話,可以將輸入的權重類比為我們在回歸方程中用的系數。權重通常被初始化為小的隨機數值,比如數值0-1。
前饋深度網路
前饋監督神經網路曾是第一個也是最成功的學習演算法。該網路也可被稱為深度網路、多層感知機(MLP)或簡單神經網路,並且闡明了具有單一隱含層的原始架構。每個神經元通過某個權重和另一個神經元相關聯。
該網路處理向前處理輸入信息,激活神經元,最終產生輸出值。在此網路中,這稱為前向傳遞。
inputlayer 輸入層 hidden layer 輸出層 output layer 輸出層
激活函數
激活函數就是求和加權的輸入到神經元的輸出的映射。之所以稱之為激活函數或傳遞函數是因為它控制著激活神經元的初始值和輸出信號的強度。
用數學表示為:
我們有許多激活函數,其中使用最多的是整流線性單元函數、雙曲正切函數和solfPlus函數。
激活函數的速查表如下:
反向傳播
在網路中,我們將預測值與預期輸出值相比較,並使用函數計算其誤差。然後,這個誤差會傳回這個網路,每次傳回一個層,權重也會根絕其導致的誤差值進行更新。這個聰明的數學法是反向傳播演算法。這個步驟會在訓練數據的所有樣本中反復進行,整個訓練數據集的網路更新一輪稱為一個時期。一個網路可受訓練數十、數百或數千個時期。
prediction error 預測誤差
代價函數和梯度下降
代價函數度量了神經網路對給定的訓練輸入和預期輸出「有多好」。該函數可能取決於權重、偏差等屬性。
代價函數是單值的,並不是一個向量,因為它從整體上評估神經網路的性能。在運用梯度下降最優演算法時,權重在每個時期後都會得到增量式地更新。
兼容代價函數
用數學表述為差值平方和:
target 目標值 output 輸出值
權重更新的大小和方向是由在代價梯度的反向上採取步驟計算出的。
其中η 是學習率
其中Δw是包含每個權重系數w的權重更新的向量,其計算方式如下:
target 目標值 output 輸出值
圖表中會考慮到單系數的代價函數
initial weight 初始權重 gradient 梯度 global cost minimum 代價極小值
在導數達到最小誤差值之前,我們會一直計算梯度下降,並且每個步驟都會取決於斜率(梯度)的陡度。
多層感知器(前向傳播)
這類網路由多層神經元組成,通常這些神經元以前饋方式(向前傳播)相互連接。一層中的每個神經元可以直接連接後續層的神經元。在許多應用中,這些網路的單元會採用S型函數或整流線性單元(整流線性激活)函數作為激活函數。
現在想想看要找出處理次數這個問題,給定的賬戶和家庭成員作為輸入
要解決這個問題,首先,我們需要先創建一個前向傳播神經網路。我們的輸入層將是家庭成員和賬戶的數量,隱含層數為1, 輸出層將是處理次數。
將圖中輸入層到輸出層的給定權重作為輸入:家庭成員數為2、賬戶數為3。
現在將通過以下步驟使用前向傳播來計算隱含層(i,j)和輸出層(k)的值。
步驟:
1, 乘法-添加方法。
2, 點積(輸入*權重)。
3,一次一個數據點的前向傳播。
4, 輸出是該數據點的預測。
i的值將從相連接的神經元所對應的輸入值和權重中計算出來。
i = (2 * 1) + (3* 1) → i = 5
同樣地,j = (2 * -1) + (3 * 1) → j =1
K = (5 * 2) + (1* -1) → k = 9
Python中的多層感知器問題的解決
激活函數的使用
為了使神經網路達到其最大預測能力,我們需要在隱含層應用一個激活函數,以捕捉非線性。我們通過將值代入方程式的方式來在輸入層和輸出層應用激活函數。
這里我們使用整流線性激活(ReLU):
用Keras開發第一個神經網路
關於Keras:
Keras是一個高級神經網路的應用程序編程介面,由Python編寫,能夠搭建在TensorFlow,CNTK,或Theano上。
使用PIP在設備上安裝Keras,並且運行下列指令。
在keras執行深度學習程序的步驟
1,載入數據;
2,創建模型;
3,編譯模型;
4,擬合模型;
5,評估模型。
開發Keras模型
全連接層用Dense表示。我們可以指定層中神經元的數量作為第一參數,指定初始化方法為第二參數,即初始化參數,並且用激活參數確定激活函數。既然模型已經創建,我們就可以編譯它。我們在底層庫(也稱為後端)用高效數字型檔編譯模型,底層庫可以用Theano或TensorFlow。目前為止,我們已經完成了創建模型和編譯模型,為進行有效計算做好了准備。現在可以在PIMA數據上運行模型了。我們可以在模型上調用擬合函數f(),以在數據上訓練或擬合模型。
我們先從KERAS中的程序開始,
神經網路一直訓練到150個時期,並返回精確值。
Ⅸ 求教pytorch,深度神經網路中這段代碼的隱藏層是那段代碼
這個線性回歸程序沒有隱藏層是一個單層神經網路,隱藏層是在多層感知機中引入的,
並且一般要在隱藏層中使用ReLU函數作為激活函數,否則,雖然引入隱藏層,仍然等價於一個單層神經網路.
下面是一種激活函數ReLU(見圖),它只保留正數元素,負數元素清零.