<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從0到1實現神經網絡(Python)

新機器視覺 ? 來源:victorzhou.com ? 2023-01-31 17:06 ? 次閱讀

作者 | Victor Zhou

有個事情可能會讓初學者驚訝:神經網絡模型并不復雜!『神經網絡』這個詞讓人覺得很高大上,但實際上神經網絡算法要比人們想象的簡單。

這篇文章完全是為新手準備的。我們會通過用Python從頭實現一個神經網絡來理解神經網絡的原理。本文的脈絡是:

介紹了神經網絡的基本結構——神經元;

在神經元中使用S型激活函數;

神經網絡就是連接在一起的神經元;

構建了一個數據集,輸入(或特征)是體重和身高,輸出(或標簽)是性別;

學習了損失函數和均方差損失;

訓練網絡就是最小化其損失;

用反向傳播方法計算偏導;

用隨機梯度下降法訓練網絡。

磚塊:神經元

首先讓我們看看神經網絡的基本單位,神經元。神經元接受輸入,對其做一些數據操作,然后產生輸出。例如,這是一個2-輸入神經元:

a88e7210-974c-11ed-bfe3-dac502259ad0.png

這里發生了三個事情。首先,每個輸入都跟一個權重相乘(紅色):

然后,加權后的輸入求和,加上一個偏差b(綠色):

最后,這個結果傳遞給一個激活函數f:

激活函數的用途是將一個無邊界的輸入,轉變成一個可預測的形式。常用的激活函數就就是S型函數:

a89d2576-974c-11ed-bfe3-dac502259ad0.png

S型函數的值域是(0, 1)。簡單來說,就是把(?∞, +∞)壓縮到(0, 1) ,很大的負數約等于0,很大的正數約等于1。

一個簡單的例子

假設我們有一個神經元,激活函數就是S型函數,其參數如下:

就是以向量的形式表示?,F在,我們給這個神經元一個輸入。我們用點積來表示:

當輸入是[2, 3]時,這個神經元的輸出是0.999。給定輸入,得到輸出的過程被稱為前饋(feedforward)。

編碼一個神經元

讓我們來實現一個神經元!用Python的NumPy庫來完成其中的數學計算:

importnumpyasnp

defsigmoid(x):
#我們的激活函數:f(x)=1/(1+e^(-x))
return1/(1+np.exp(-x))

classNeuron:
def__init__(self,weights,bias):
self.weights=weights
self.bias=bias

deffeedforward(self,inputs):
#加權輸入,加入偏置,然后使用激活函數
total=np.dot(self.weights,inputs)+self.bias
returnsigmoid(total)

weights=np.array([0,1])#w1=0,w2=1
bias=4#b=4
n=Neuron(weights,bias)

x=np.array([2,3])#x1=2,x2=3
print(n.feedforward(x))#0.9990889488055994

還記得這個數字嗎?就是我們前面算出來的例子中的0.999。

把神經元組裝成網絡

所謂的神經網絡就是一堆神經元。這就是一個簡單的神經網絡:

a8e3fa64-974c-11ed-bfe3-dac502259ad0.png

這個網絡有兩個輸入,一個有兩個神經元(和)的隱藏層,以及一個有一個神經元() )的輸出層。要注意,的輸入就是和的輸出,這樣就組成了一個網絡。

隱藏層就是輸入層和輸出層之間的層,隱藏層可以是多層的。

例子:前饋

我們繼續用前面圖中的網絡,假設每個神經元的權重都是,截距項也相同,激活函數也都是S型函數。分別用表示相應的神經元的輸出。

當輸入時,會得到什么結果?

這個神經網絡對輸入的輸出是0.7216,很簡單。

一個神經網絡的層數以及每一層中的神經元數量都是任意的?;具壿嫸家粯樱狠斎朐谏窠浘W絡中向前傳輸,最終得到輸出。接下來,我們會繼續使用前面的這個網絡。

編碼神經網絡:前饋

接下來我們實現這個神經網絡的前饋機制,還是這個圖:

a92fbaa8-974c-11ed-bfe3-dac502259ad0.png

importnumpyasnp

#...codefromprevioussectionhere

classOurNeuralNetwork:
'''
Aneuralnetworkwith:
-2inputs
-ahiddenlayerwith2neurons(h1,h2)
-anoutputlayerwith1neuron(o1)
Eachneuronhasthesameweightsandbias:
-w=[0,1]
-b=0
'''
def__init__(self):
weights=np.array([0,1])
bias=0

#這里是來自前一節的神經元類
self.h1=Neuron(weights,bias)
self.h2=Neuron(weights,bias)
self.o1=Neuron(weights,bias)

deffeedforward(self,x):
out_h1=self.h1.feedforward(x)
out_h2=self.h2.feedforward(x)

#o1的輸入是h1和h2的輸出
out_o1=self.o1.feedforward(np.array([out_h1,out_h2]))

returnout_o1

network=OurNeuralNetwork()
x=np.array([2,3])
print(network.feedforward(x))#0.7216325609518421

結果正確,看上去沒問題。

訓練神經網絡 第一部分

現在有這樣的數據:

姓名 體重(磅) 身高 (英寸) 性別
Alice 133 65 F
Bob 160 72 M
Charlie 152 70 M
Diana 120 60 F

接下來我們用這個數據來訓練神經網絡的權重和截距項,從而可以根據身高體重預測性別:

a9507856-974c-11ed-bfe3-dac502259ad0.png

我們用0和1分別表示男性(M)和女性(F),并對數值做了轉化:

姓名 體重 (減 135) 身高 (減 66) 性別
Alice -2 -1 1
Bob 25 6 0
Charlie 17 4 0
Diana -15 -6 1

我這里是隨意選取了135和66來標準化數據,通常會使用平均值。

損失

在訓練網絡之前,我們需要量化當前的網絡是『好』還是『壞』,從而可以尋找更好的網絡。這就是定義損失的目的。

我們在這里用平均方差(MSE)損失:,讓我們仔細看看:

是樣品數,這里等于4(Alice、Bob、Charlie和Diana)。

表示要預測的變量,這里是性別。

是變量的真實值(『正確答案』)。例如,Alice的就是1(男性)。

變量的預測值。這就是我們網絡的輸出。

被稱為方差(squared error)。我們的損失函數就是所有方差的平均值。預測效果越好,損失就越少。

更好的預測 = 更少的損失!

訓練網絡 = 最小化它的損失。

損失計算例子

假設我們的網絡總是輸出0,換言之就是認為所有人都是男性。損失如何?

Name y_true y_pred (y_true - y_pred)^2
Alice 1 0 1
Bob 0 0 0
Charlie 0 0 0
Diana 1 0 1

代碼:MSE損失

下面是計算MSE損失的代碼:

importnumpyasnp

defmse_loss(y_true,y_pred):
#y_trueandy_predarenumpyarraysofthesamelength.
return((y_true-y_pred)**2).mean()

y_true=np.array([1,0,0,1])
y_pred=np.array([0,0,0,0])

print(mse_loss(y_true,y_pred))#0.5

如果你不理解這段代碼,可以看看NumPy的快速入門中關于數組的操作。

好的,繼續。

訓練神經網絡 第二部分

現在我們有了一個明確的目標:最小化神經網絡的損失。通過調整網絡的權重和截距項,我們可以改變其預測結果,但如何才能逐步地減少損失?

這一段內容涉及到多元微積分,如果不熟悉微積分的話,可以跳過這些數學內容。

為了簡化問題,假設我們的數據集中只有Alice:

假設我們的網絡總是輸出0,換言之就是認為所有人都是男性。損失如何?

姓名 體重 (減 135) 身高 (減 66) Gender
Alice -2 -1 1

那均方差損失就只是Alice的方差:

也可以把損失看成是權重和截距項的函數。讓我們給網絡標上權重和截距項:

a9507856-974c-11ed-bfe3-dac502259ad0.png

這樣我們就可以把網絡的損失表示為:

假設我們要優化,當我們改變時,損失會怎么變化?可以用來回答這個問題,怎么計算?

接下來的數據稍微有點復雜,別擔心,準備好紙和筆。

首先,讓我們用來改寫這個偏導數:

因為我們已經知道,所以我們可以計算

現在讓我們來搞定。分別是其所表示的神經元的輸出,我們有:

由于只會影響(不會影響),所以:

對,我們也可以這么做:

在這里,是身高,是體重。這是我們第二次看到(S型函數的導數)了。求解:

稍后我們會用到這個。

我們已經把分解成了幾個我們能計算的部分:

這種計算偏導的方法叫『反向傳播算法』(backpropagation)。

好多數學符號,如果你還沒搞明白的話,我們來看一個實際例子。

例子:計算偏導數

我們還是看數據集中只有Alice的情況:

Name
Alice 1 0 1
姓名 身高 (minus 135) 體重 (minus 66) Gender
Alice -2 -1 1

把所有的權重和截距項都分別初始化為1和0。在網絡中做前饋計算:

網絡的輸出是,對于Male(0)或者Female(1)都沒有太強的傾向性。算一下

提示:前面已經得到了S型激活函數的導數。

搞定!這個結果的意思就是增加也會隨之輕微上升。

訓練:隨機梯度下降

現在訓練神經網絡已經萬事俱備了!我們會使用名為隨機梯度下降法的優化算法來優化網絡的權重和截距項,實現損失的最小化。核心就是這個更新等式:

是一個常數,被稱為學習率,用于調整訓練的速度。我們要做的就是用減去

如果是正數,變小,會下降。

如果是負數,會變大,會上升。

如果我們對網絡中的每個權重和截距項都這樣進行優化,損失就會不斷下降,網絡性能會不斷上升。

我們的訓練過程是這樣的:

從我們的數據集中選擇一個樣本,用隨機梯度下降法進行優化——每次我們都只針對一個樣本進行優化;

計算每個權重或截距項對損失的偏導(例如、等);

用更新等式更新每個權重和截距項;

重復第一步;

代碼:一個完整的神經網絡

我們終于可以實現一個完整的神經網絡了:

姓名 身高 (減 135) 體重 (減 66) Gender
Alice -2 -1 1
Bob 25 6 0
Charlie 17 4 0
Diana -15 -6 1

aa02b3ae-974c-11ed-bfe3-dac502259ad0.png

importnumpyasnp

defsigmoid(x):
#Sigmoidactivationfunction:f(x)=1/(1+e^(-x))
return1/(1+np.exp(-x))

defderiv_sigmoid(x):
#Derivativeofsigmoid:f'(x)=f(x)*(1-f(x))
fx=sigmoid(x)
returnfx*(1-fx)

defmse_loss(y_true,y_pred):
# y_true和y_pred是相同長度的numpy數組。
return((y_true-y_pred)**2).mean()

classOurNeuralNetwork:
'''
Aneuralnetworkwith:
-2inputs
-ahiddenlayerwith2neurons(h1,h2)
-anoutputlayerwith1neuron(o1)

***免責聲明***:
下面的代碼是為了簡單和演示,而不是最佳的。
真正的神經網絡代碼與此完全不同。不要使用此代碼。
相反,讀/運行它來理解這個特定的網絡是如何工作的。
'''
def__init__(self):
#權重,Weights
self.w1=np.random.normal()
self.w2=np.random.normal()
self.w3=np.random.normal()
self.w4=np.random.normal()
self.w5=np.random.normal()
self.w6=np.random.normal()

#截距項,Biases
self.b1=np.random.normal()
self.b2=np.random.normal()
self.b3=np.random.normal()

deffeedforward(self,x):
# X是一個有2個元素的數字數組。
h1=sigmoid(self.w1*x[0]+self.w2*x[1]+self.b1)
h2=sigmoid(self.w3*x[0]+self.w4*x[1]+self.b2)
o1=sigmoid(self.w5*h1+self.w6*h2+self.b3)
returno1

deftrain(self,data,all_y_trues):
'''
-dataisa(nx2)numpyarray,n=#ofsamplesinthedataset.
-all_y_truesisanumpyarraywithnelements.
Elementsinall_y_truescorrespondtothoseindata.
'''
learn_rate=0.1
epochs=1000#遍歷整個數據集的次數

forepochinrange(epochs):
forx,y_trueinzip(data,all_y_trues):
#---做一個前饋(稍后我們將需要這些值)
sum_h1=self.w1*x[0]+self.w2*x[1]+self.b1
h1=sigmoid(sum_h1)

sum_h2=self.w3*x[0]+self.w4*x[1]+self.b2
h2=sigmoid(sum_h2)

sum_o1=self.w5*h1+self.w6*h2+self.b3
o1=sigmoid(sum_o1)
y_pred=o1

#---計算偏導數。
#---Naming:d_L_d_w1represents"partialL/partialw1"
d_L_d_ypred=-2*(y_true-y_pred)

#Neurono1
d_ypred_d_w5=h1*deriv_sigmoid(sum_o1)
d_ypred_d_w6=h2*deriv_sigmoid(sum_o1)
d_ypred_d_b3=deriv_sigmoid(sum_o1)

d_ypred_d_h1=self.w5*deriv_sigmoid(sum_o1)
d_ypred_d_h2=self.w6*deriv_sigmoid(sum_o1)

#Neuronh1
d_h1_d_w1=x[0]*deriv_sigmoid(sum_h1)
d_h1_d_w2=x[1]*deriv_sigmoid(sum_h1)
d_h1_d_b1=deriv_sigmoid(sum_h1)

#Neuronh2
d_h2_d_w3=x[0]*deriv_sigmoid(sum_h2)
d_h2_d_w4=x[1]*deriv_sigmoid(sum_h2)
d_h2_d_b2=deriv_sigmoid(sum_h2)

#---更新權重和偏差
#Neuronh1
self.w1-=learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_w1
self.w2-=learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_w2
self.b1-=learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_b1

#Neuronh2
self.w3-=learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_w3
self.w4-=learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_w4
self.b2-=learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_b2

#Neurono1
self.w5-=learn_rate*d_L_d_ypred*d_ypred_d_w5
self.w6-=learn_rate*d_L_d_ypred*d_ypred_d_w6
self.b3-=learn_rate*d_L_d_ypred*d_ypred_d_b3

#---在每次epoch結束時計算總損失
ifepoch%10==0:
y_preds=np.apply_along_axis(self.feedforward,1,data)
loss=mse_loss(all_y_trues,y_preds)
print("Epoch%dloss:%.3f"%(epoch,loss))

#定義數據集
data=np.array([
[-2,-1],#Alice
[25,6],#Bob
[17,4],#Charlie
[-15,-6],#Diana
])
all_y_trues=np.array([
1,#Alice
0,#Bob
0,#Charlie
1,#Diana
])

#訓練我們的神經網絡!
network=OurNeuralNetwork()
network.train(data,all_y_trues)

隨著網絡的學習,損失在穩步下降。

aa150b30-974c-11ed-bfe3-dac502259ad0.png

現在我們可以用這個網絡來預測性別了:

#做一些預測
emily=np.array([-7,-3])#128磅,63英寸
frank=np.array([20,2])#155磅,68英寸
print("Emily:%.3f"%network.feedforward(emily))#0.951-F
print("Frank:%.3f"%network.feedforward(frank))#0.039-M

接下來?

搞定了一個簡單的神經網絡,快速回顧一下:

介紹了神經網絡的基本結構——神經元;

在神經元中使用S型激活函數;

神經網絡就是連接在一起的神經元;

構建了一個數據集,輸入(或特征)是體重和身高,輸出(或標簽)是性別;

學習了損失函數和均方差損失;

訓練網絡就是最小化其損失;

用反向傳播方法計算偏導;

用隨機梯度下降法訓練網絡;

接下來你還可以:

機器學習庫實現更大更好的神經網絡,例如TensorFlow、Keras和PyTorch;

其他類型的激活函數;

其他類型的優化器;

學習卷積神經網絡,這給計算機視覺領域帶來了革命;

學習遞歸神經網絡,常用于自然語言處理;

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 神經網絡
    +關注

    關注

    42

    文章

    4584

    瀏覽量

    99083
  • 網絡
    +關注

    關注

    14

    文章

    7258

    瀏覽量

    87564
  • 函數
    +關注

    關注

    3

    文章

    4049

    瀏覽量

    61392
  • 神經元
    +關注

    關注

    1

    文章

    286

    瀏覽量

    18345
  • python
    +關注

    關注

    52

    文章

    4692

    瀏覽量

    83539

原文標題:從 0 到 1 實現神經網絡(Python)

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    labview BP神經網絡實現

    請問:我在用labview做BP神經網絡實現故障診斷,在NI官網找到了機器學習工具包(MLT),但是里面沒有關于這部分VI的幫助文檔,對于”BP神經網絡分類“這個范例有很多不懂的地方,比如
    發表于 02-22 16:08

    AlexNetMobileNet,帶你入門深度神經網絡

    分辨率、轉換、遷移、描述等等都已經可以使用深度學習技術實現。其背后的技術可以一言以蔽之:深度卷積神經網絡具有超強的圖像特征提取能力。其中,風格遷移算法的成功,其主要基于兩點:1.兩張圖像經過預訓練
    發表于 05-08 15:57

    【PYNQ-Z2申請】基于PYNQ-Z2的神經網絡圖形識別

    神經網絡的學習,講解其工作原理。4.基于PYNQ-Z2,用python實現一個神經網絡。5.訓練和測試神經網絡,完成
    發表于 01-09 14:48

    【PYNQ-Z2試用體驗】神經網絡基礎知識

    python語言,可以很輕松地實現復雜的數學運算,降低編程難度。下一篇文章,將通過具體代碼,演示基于神經網絡的手寫圖形識別。
    發表于 03-03 22:10

    【案例分享】基于BP算法的前饋神經網絡

    傳播的,不會回流),區別于循環神經網絡RNN。BP算法(Back Propagation):誤差反向傳播算法,用于更新網絡中的權重。BP神經網絡思想:表面上:1. 數據信息的前向傳播,
    發表于 07-21 04:00

    人工神經網絡實現方法有哪些?

    人工神經網絡(Artificial Neural Network,ANN)是一種類似生物神經網絡的信息處理結構,它的提出是為了解決一些非線性,非平穩,復雜的實際問題。那有哪些辦法能實現人工神經
    發表于 08-01 08:06

    簡單神經網絡實現

    最簡單的神經網絡
    發表于 09-11 11:57

    如何構建神經網絡?

    原文鏈接:http://tecdat.cn/?p=5725 神經網絡是一種基于現有數據創建預測的計算系統。如何構建神經網絡?神經網絡包括:輸入層:根據現有數據獲取輸入的層隱藏層:使用反向傳播優化輸入變量權重的層,以提高模型的預測
    發表于 07-12 08:02

    matlab實現神經網絡 精選資料分享

    神經神經網絡,對于神經網絡實現是如何一直沒有具體實現一下:現看到一個簡單的神經網絡模型用于訓
    發表于 08-18 07:25

    神經網絡移植STM32的方法

    神經網絡移植STM32最近在做的一個項目需要用到網絡進行擬合,并且將擬合得到的結果用作控制,就在想能不能直接在單片機上做神經網絡計算,這樣就可以實時計算,不依賴于上位機。所以要解決
    發表于 01-11 06:20

    Python從頭實現一個神經網絡來理解神經網絡的原理1

    有個事情可能會讓初學者驚訝:神經網絡模型并不復雜!『神經網絡』這個詞讓人覺得很高大上,但實際上神經網絡算法要比人們想象的簡單。 這篇文章完全是為新手準備的。我們會通過用Python
    的頭像 發表于 02-27 15:05 ?493次閱讀
    用<b class='flag-5'>Python</b>從頭<b class='flag-5'>實現</b>一個<b class='flag-5'>神經網絡</b>來理解<b class='flag-5'>神經網絡</b>的原理1

    Python從頭實現一個神經網絡來理解神經網絡的原理2

    有個事情可能會讓初學者驚訝:神經網絡模型并不復雜!『神經網絡』這個詞讓人覺得很高大上,但實際上神經網絡算法要比人們想象的簡單。 這篇文章完全是為新手準備的。我們會通過用Python
    的頭像 發表于 02-27 15:06 ?426次閱讀
    用<b class='flag-5'>Python</b>從頭<b class='flag-5'>實現</b>一個<b class='flag-5'>神經網絡</b>來理解<b class='flag-5'>神經網絡</b>的原理2

    Python從頭實現一個神經網絡來理解神經網絡的原理3

    有個事情可能會讓初學者驚訝:神經網絡模型并不復雜!『神經網絡』這個詞讓人覺得很高大上,但實際上神經網絡算法要比人們想象的簡單。 這篇文章完全是為新手準備的。我們會通過用Python
    的頭像 發表于 02-27 15:06 ?508次閱讀
    用<b class='flag-5'>Python</b>從頭<b class='flag-5'>實現</b>一個<b class='flag-5'>神經網絡</b>來理解<b class='flag-5'>神經網絡</b>的原理3

    Python從頭實現一個神經網絡來理解神經網絡的原理4

    有個事情可能會讓初學者驚訝:神經網絡模型并不復雜!『神經網絡』這個詞讓人覺得很高大上,但實際上神經網絡算法要比人們想象的簡單。 這篇文章完全是為新手準備的。我們會通過用Python
    的頭像 發表于 02-27 15:06 ?484次閱讀
    用<b class='flag-5'>Python</b>從頭<b class='flag-5'>實現</b>一個<b class='flag-5'>神經網絡</b>來理解<b class='flag-5'>神經網絡</b>的原理4

    卷積神經網絡python代碼

    的卷積操作,將不同層次的特征進行提取,從而通過反向傳播算法不斷優化網絡權重,最終實現分類和預測等任務。 在本文中,我們將介紹如何使用Python實現卷積
    的頭像 發表于 08-21 16:41 ?711次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>