91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

神經(jīng)網(wǎng)絡(luò)理論到實(shí)踐(2):理解并實(shí)現(xiàn)反向傳播及驗(yàn)證神經(jīng)網(wǎng)絡(luò)是否正確

電子設(shè)計(jì) ? 來源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-10 19:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

專欄中《零神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)》系列持續(xù)更新介紹神經(jīng)元怎么工作,最后使用python從0到1不調(diào)用任何依賴神經(jīng)網(wǎng)絡(luò)框架(不使用tensorflow等框架)來實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò),梯度下降、反向傳播、卷積神經(jīng)網(wǎng)絡(luò)CNN、循環(huán)神經(jīng)網(wǎng)絡(luò)RNN。從0基礎(chǔ)角度進(jìn)行神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)。
上一篇:零基礎(chǔ)神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)(1):單個(gè)神經(jīng)元+隨機(jī)梯度下降學(xué)習(xí)邏輯與規(guī)則
作者:司南牧

實(shí)例介紹反向傳播,為何說深度學(xué)習(xí)離不開反向傳播?

之前介紹了單個(gè)神經(jīng)元如何利用隨機(jī)梯度下降自己調(diào)節(jié)權(quán)重。深度學(xué)習(xí)指的是數(shù)以百千層的層數(shù)很深的神經(jīng)網(wǎng)絡(luò),每層又有數(shù)以百千個(gè)神經(jīng)元。那么深度學(xué)習(xí)是否也可以使用這種形式的梯度下降來進(jìn)行調(diào)節(jié)權(quán)重呢?答:很難。為什么?主要原因是太深了。為何“深”用梯度下降解會(huì)有問題呢?主要是因?yàn)殒準(zhǔn)椒▌t導(dǎo)致計(jì)算損失函數(shù)對(duì)前面層權(quán)重的導(dǎo)數(shù)時(shí),損失函數(shù)對(duì)后面層權(quán)重的導(dǎo)數(shù)總是被重復(fù)計(jì)算,反向傳播就是將那些計(jì)算的值保存減少重復(fù)計(jì)算。不明白?那這篇文章就看對(duì)了。接下來將解釋這個(gè)重復(fù)計(jì)算過程。反向傳播就是梯度下降中的求導(dǎo)環(huán)節(jié),它從后往前計(jì)算導(dǎo)數(shù)重復(fù)利用計(jì)算過的導(dǎo)數(shù)而已。。梯度下降不懂或者神經(jīng)網(wǎng)絡(luò)不懂請(qǐng)先閱讀這個(gè)文章單個(gè)神經(jīng)元+隨機(jī)梯度下降學(xué)習(xí)邏輯與規(guī)則。

文章結(jié)構(gòu):

  1. 為何要使用反向傳播?
  2. 反向傳播優(yōu)化神經(jīng)網(wǎng)絡(luò)權(quán)重參數(shù)實(shí)踐。

為何要使用反向傳播?

我們用一個(gè)最簡單的三層神經(jīng)網(wǎng)絡(luò)(無激活函數(shù))來進(jìn)行解釋為何需要使用反向傳播,所使用的三層神經(jīng)網(wǎng)絡(luò)如下所示:

這里我們有三個(gè)要優(yōu)化的參數(shù):w1,w2,w3。

我們先用傳統(tǒng)的梯度下降方法來看看哪些地方重復(fù)計(jì)算了,而反向傳播就是將這些重復(fù)計(jì)算的地方計(jì)算結(jié)果保存,并且向前面層傳播這個(gè)值以減少運(yùn)算復(fù)雜度。 梯度下降需要先得求損失函數(shù)對(duì)w1,w2,w3的導(dǎo)數(shù),然后根據(jù)導(dǎo)數(shù)來不斷迭代更新w1,w2,w3的值。

第1層:求損失函數(shù)L(w1,w2,w3)對(duì)w1的導(dǎo)數(shù)(更規(guī)范的講是偏導(dǎo)數(shù))。

我們先看看損失函數(shù)L(w1,w2,w3)和w1之間的關(guān)系是什么。

$$L(w1,w2,w3)=1/2 (e-/hat e )^2$$
e=w3 * z
z=w2 * y
y=w1 * x

所以這是個(gè)復(fù)合函數(shù)的求導(dǎo)。根據(jù)高中學(xué)習(xí)到的復(fù)合函數(shù)求導(dǎo)法則(也是大家可能經(jīng)常聽到的鏈?zhǔn)椒▌t),復(fù)合函數(shù)求導(dǎo)等于各級(jí)復(fù)合函數(shù)導(dǎo)數(shù)的乘積,也就是這樣

第2層:求損失函數(shù)L(w1,w2,w3)對(duì)w2的導(dǎo)數(shù)。
我們再看看損失函數(shù)L(w1,w2,w3)和w2之間的關(guān)系是什么。

$$L(w1,w2,w3)=1/2 (e-/hat e )^2$$
e=w3 * z
z=w2 * y

根據(jù)復(fù)合函數(shù)求導(dǎo)可得:

第3層:求損失函數(shù)L(w1,w2,w3)對(duì)w3的導(dǎo)數(shù)。
我們再看看損失函數(shù)L(w1,w2,w3)和w3之間的關(guān)系是什么。

$$L(w1,w2,w3)=1/2 (e-/hat e )^2$$
e=w3 * z

根據(jù)復(fù)合函數(shù)求導(dǎo)可得:

我們將這三層的損失函數(shù)對(duì)相應(yīng)層權(quán)重導(dǎo)數(shù)列在一起看看哪兒重復(fù)計(jì)算了:


我們再看看這個(gè)圖:

所搭建的最簡單的三層神經(jīng)網(wǎng)絡(luò)

你會(huì)發(fā)現(xiàn),如果將損失函數(shù)也看做是一層的話。即我們認(rèn)為e->L(w1,w2,w3)這也算一層。

找規(guī)律

反向傳播過程理解

前面我們提到了可以從后面往前面計(jì)算,將公共部分的導(dǎo)數(shù)往前傳。這只是解決了求導(dǎo)問題,那怎么進(jìn)行參數(shù)更新呢?答:參數(shù)更新跟梯度下降完全一樣,都是這個(gè)公式。反向傳播就是梯度下降中的求導(dǎo)環(huán)節(jié),它重復(fù)利用計(jì)算過的導(dǎo)數(shù)而已。

我們看看反向傳播版的使用梯度下降進(jìn)行參數(shù)更新是怎樣的。

損失函數(shù)L(w1,w2,w3)是這樣:$$L(w1,w2,w3)=1/2 (e-/hat e )^2$$

其他的幾層函數(shù)如下所示:

第3層:e=w3 * z
第2層:z=w2 * y
第1層:y=w1 * x

在這篇文章“單個(gè)神經(jīng)元+隨機(jī)梯度下降學(xué)習(xí)邏輯與規(guī)則”介紹了,權(quán)重更新是一個(gè)不斷猜(迭代更新)的過程。下一次權(quán)重值 = 本次權(quán)重值 - 學(xué)習(xí)率* 損失函數(shù)對(duì)該權(quán)重的導(dǎo)數(shù)。定義學(xué)習(xí)率為α. 接下來我們只需要知道怎么利用后面層數(shù)傳遞過來的值來求“損失函數(shù)對(duì)當(dāng)前層權(quán)重wi的導(dǎo)數(shù)”即可。

則各層網(wǎng)絡(luò)更新權(quán)重的步驟為如下所示:

1.更新第3層權(quán)重參數(shù)w3.

2.更新第2層權(quán)重參數(shù)w2

3.更新第1層權(quán)重參數(shù)w1.

所以,將上面3步用偽代碼寫可以寫成下面這樣。

終于可以告別可怕的公式了,越難的東西你堅(jiān)持了,你的不可替代性就越強(qiáng)。加油你不是一個(gè)人在奮斗。

反向傳播實(shí)踐

我們將上面的偽代碼轉(zhuǎn)成Python代碼。我們希望這個(gè)神經(jīng)網(wǎng)絡(luò)能自己學(xué)習(xí)到的功能是輸入x輸出的e=-x.

我們提供訓(xùn)練集數(shù)據(jù)(我們只有兩條數(shù)據(jù)):


重復(fù)訓(xùn)練次數(shù)epoch = 160。

好開工實(shí)現(xiàn)它。

# -*- coding: UTF-8 -*-
"""
@author 知乎:@Ai醬
"""
class NeuralNetwork:

    def __init__(self):
        self.LEARNING_RATE = 0.05 # 設(shè)置學(xué)習(xí)率
        # 初始化網(wǎng)絡(luò)各層權(quán)重(權(quán)重的初試值也會(huì)影響神經(jīng)網(wǎng)絡(luò)是否收斂)
        # 博主試了下權(quán)重初始值都為0.2333是不行的
        self.w3 = -0.52133
        self.w2 = -0.233
        self.w1 = 0.2333
        self.data = [1, -1] # 輸入數(shù)據(jù)
        self.label= [-1, 1]

    def train(self):
        epoch = 160
        for _ in range(epoch):
            # 逐個(gè)樣本進(jìn)行訓(xùn)練模型
            for i in range(len(self.data)):
                x = self.data[i]
                e_real = self.label[i]

                self.y = self.w1 * x #計(jì)算第1層輸出
                self.z = self.w2 * self.y # 計(jì)算第2層輸出
                self.e = self.w3 * self.z # 計(jì)算第3層輸出

                # 開始反向傳播優(yōu)化權(quán)重
                self.result3 = self.e - e_real
                self.w3 = self.w3 - self.LEARNING_RATE * self.result3 * self.z

                self.result2 = self.result3 * self.w3
                self.w2 = self.w2 - self.LEARNING_RATE * self.result2 * self.y

                self.w1 = self.w1 - self.LEARNING_RATE * self.result2 * self.w2 * x

    def predict(self,x):
        self.y = self.w1 * x #計(jì)算第1層輸出
        self.z = self.w2 * self.y # 計(jì)算第2層輸出
        self.e = self.w3 * self.z # 計(jì)算第3層輸出
        return 1 if self.e>0 else -1
nn = NeuralNetwork()
nn.train()
print(1,',',nn.predict(1))
print(-1,',',nn.predict(-1))
'''
輸出:
1 , -1
-1 , 1
'''

如何檢驗(yàn)反向傳播是否寫對(duì)?

手動(dòng)推導(dǎo),人工判斷

前面提到了反向傳播本質(zhì)是梯度下降,那么關(guān)鍵在于導(dǎo)數(shù)必須對(duì)。我們現(xiàn)在網(wǎng)絡(luò)比較小可以直接手動(dòng)計(jì)算導(dǎo)數(shù)比對(duì)代碼中對(duì)各權(quán)重導(dǎo)數(shù)是否求對(duì)。

比如上面代碼中三個(gè)參數(shù)的導(dǎo)數(shù)將代碼中的result*展開表示就是:

dw3 = (self.e - e_real) * self.z
    = (self.e - e_real) * self.w2 * self.y
    =  (self.e - e_real) * self.w2 * self.w1 * x
    = (self. w3 * self.w2 * self.w1 * x - e_real) * self.w2 * self.w1 * x

dw2 = (self.e - e_real) * self.w3* self.y
    = (self.e - e_real) * self.w3* self.w1 * x
    = (self. w3 * self.w2 * self.w1 * x - e_real) * self.w3* self.w1 * x

dw3 =  self.result3 * self.z
    = (self.e - e_real) * self.w2 * self.w1 * x
    = (self. w3 * self.w2 * self.w1 * x - e_real)* self.w2 * self.w1 * x

而損失函數(shù)展開可以表示為: $$L(w1,w2,w3) = 1/2 (w3 * w2 * w1 * x - /hat e)^2$$

對(duì)各權(quán)重參數(shù)求導(dǎo)為:

$${dL}/ {dw3} = (w3 * w2 * w1 * x - /hat e) * w2 * w1$$

$${dL}/ {dw2} = (w3 * w2 * w1 * x - /hat e) * w3 * w1$$

$${dL}/ {dw1} = (w3 * w2 * w1 * x - /hat e) * w3 * w2$$

可以發(fā)現(xiàn)我們代碼展開,與我們實(shí)際的公式求導(dǎo)是一致的證明我們代碼是正確的。

但是,一旦層數(shù)很深,那么我們就不能這么做了

我們需要用代碼自動(dòng)判斷是否反向傳播寫對(duì)了

代碼自動(dòng)判斷反向傳播的導(dǎo)函數(shù)是否正確

這個(gè)和手工判斷方法類似。反向傳播是否正確,關(guān)鍵在于dL/dwi是否計(jì)算正確。根據(jù)高中學(xué)過的導(dǎo)數(shù)的定義,對(duì)于位于點(diǎn)θ的導(dǎo)數(shù)有:

$$f'(/theta) = /lim_{/epsilon/to 0} {f(/theta + /epsilon) + f(/theta - /epsilon) } /{2/epsilon}$$

所以我們可以看反向傳播求的導(dǎo)函數(shù)值和用導(dǎo)數(shù)定義求的導(dǎo)函數(shù)值是否接近。

即我們需要讓代碼判斷這個(gè)式子是否成立:$${dL}/ {dwi} /approx {L(wi+ 10^{-4}) - L(wi- 10^{-4})} /{2* 10^{-4}}$$

左邊的dL/dwi是反向傳播求得,右邊是導(dǎo)數(shù)定義求的導(dǎo)數(shù)值。這兩個(gè)導(dǎo)數(shù)應(yīng)當(dāng)大致相同。

實(shí)踐:程序自動(dòng)檢驗(yàn)導(dǎo)函數(shù)是否正確:

新增了一個(gè)梯度檢驗(yàn)函數(shù)check_gradient(),如下所示:

# -*- coding: UTF-8 -*-
"""
@author 知乎:@Ai醬
"""
class NeuralNetwork:

    def __init__(self):
        self.LEARNING_RATE = 0.05 # 設(shè)置學(xué)習(xí)率
        # 初始化網(wǎng)絡(luò)各層權(quán)重(權(quán)重的初試值也會(huì)影響神經(jīng)網(wǎng)絡(luò)是否收斂)
        # 博主試了下權(quán)重初始值都為0.2333是不行的
        self.w3 = -0.52133
        self.w2 = -0.233
        self.w1 = 0.2333

        self.data = [1, -1] # 輸入數(shù)據(jù)
        self.label= [-1, 1]
    def L(self,w1,w2,w3,x,e_real):
        '''
        損失函數(shù) return 1/2 * (e - e_real)^2
        '''
        return 0.5*(w1*w2*w3*x - e_real)**2

    def train(self):
        epoch = 160
        for _ in range(epoch):
            # 逐個(gè)樣本進(jìn)行訓(xùn)練模型
            for i in range(len(self.data)):
                x = self.data[i]
                e_real = self.label[i]

                self.y = self.w1 * x #計(jì)算第1層輸出
                self.z = self.w2 * self.y # 計(jì)算第2層輸出
                self.e = self.w3 * self.z # 計(jì)算第3層輸出

                # 開始反向傳播優(yōu)化權(quán)重
                self.result3 = self.e - e_real
                self.w3 = self.w3 - self.LEARNING_RATE * self.result3 * self.z

                self.result2 = self.result3 * self.w3
                self.w2 = self.w2 - self.LEARNING_RATE * self.result2 * self.y

                self.w1 = self.w1 - self.LEARNING_RATE * self.result2 * self.w2 * x
                self.check_gradient(x,e_real)

    def check_gradient(self,x,e_real):
        # 反向傳播所求得的損失函數(shù)對(duì)各權(quán)重的導(dǎo)數(shù)
        dw3 = self.result3 * self.z
        dw2 = self.result2 * self.y
        dw1 = self.result2 * self.w2 * x

        # 使用定義求損失函數(shù)對(duì)各權(quán)重的導(dǎo)數(shù)
        epsilon = 10**-4 # epsilon為10的4次方
        # 求損失函數(shù)在w3處的左極限和右極限
        lim_dw3_right = self.L(self.w1, self.w2, self.w3+epsilon, x, e_real)
        lim_dw3_left = self.L(self.w1, self.w2, self.w3-epsilon, x, e_real)
        # 利用左右極限求導(dǎo)
        lim_dw3 = (lim_dw3_right - lim_dw3_left)/(2*epsilon)

        lim_dw2_right = self.L(self.w1, self.w2+epsilon, self.w3, x, e_real)
        lim_dw2_left = self.L(self.w1, self.w2-epsilon, self.w3, x, e_real)
        lim_dw2 = (lim_dw2_right - lim_dw2_left)/(2*epsilon)

        lim_dw1_right = self.L(self.w1+epsilon, self.w2, self.w3, x, e_real)
        lim_dw1_left = self.L(self.w1-epsilon, self.w2, self.w3, x, e_real)
        lim_dw1 = (lim_dw1_right - lim_dw1_left)/(2*epsilon)

        # 比對(duì)反向傳播求的導(dǎo)數(shù)和用定義求的導(dǎo)數(shù)是否接近
        print("dl/dw3反向傳播求得:%f,定義求得%f"%(dw3,lim_dw3))
        print("dl/dw2反向傳播求得:%f,定義求得%f"%(dw2,lim_dw2))
        print("dl/dw1反向傳播求得:%f,定義求得%f"%(dw1,lim_dw1))

    def predict(self,x):
        self.y = self.w1 * x #計(jì)算第1層輸出
        self.z = self.w2 * self.y # 計(jì)算第2層輸出
        self.e = self.w3 * self.z # 計(jì)算第3層輸出
        return 1 if self.e>0 else -1
nn = NeuralNetwork()
nn.train()
print(1,',',nn.predict(1))
print(-1,',',nn.predict(-1))
'''
輸出:
dl/dw1反向傳播求得:-0.026729,定義求得-0.026727
dl/dw3反向傳播求得:0.003970,定義求得0.004164
dl/dw2反向傳播求得:-0.032617,定義求得-0.033257
dl/dw1反向傳播求得:-0.027502,定義求得-0.027499
dl/dw3反向傳播求得:0.004164,定義求得0.004367
dl/dw2反向傳播求得:-0.033272,定義求得-0.033932
dl/dw1反向傳播求得:-0.028291,定義求得-0.028288
dl/dw3反向傳播求得:0.004367,定義求得0.004579
dl/dw2反向傳播求得:-0.033947,定義求得-0.034625
dl/dw1反向傳播求得:-0.029097,定義求得-0.029094
... ...
1 , -1
-1 , 1
'''

可以發(fā)現(xiàn)反向傳播求得損失函數(shù)對(duì)各參數(shù)求得的導(dǎo)數(shù)和我們用高中學(xué)的定義法求導(dǎo)數(shù),兩者基本一致,證明我們反向傳播求得的導(dǎo)數(shù)沒有問題。

附上上面的易讀版代碼的github代碼下載地址:從本質(zhì)如何理解機(jī)器學(xué)習(xí)?

框架化反向傳播

每個(gè)程序員都有一個(gè)寫框架的夢想,不如我們將前面的代碼寫個(gè)類似TensorFlow這種框架的反向傳播簡單框架吧。附上框架版的代碼github下載地址:https://github.com/varyshare/newbie_neural_network_practice/blob/master/backpropagation/backpropagation_framework.py


# -*- coding: utf-8 -*-
"""
框架化反向傳播編程
@author: 知乎@Ai醬
"""

import random
class Layer(object):
    '''
    本文中,一層只有一個(gè)神經(jīng)元,一個(gè)神經(jīng)元只有一個(gè)輸入一個(gè)輸出
    '''
    def __init__(self,layer_index):
        '''
        layer_index: 第幾層
        '''
        self.layer_index = layer_index
        # 初始化權(quán)重[0,1] - 0.5 = [-0.5,0.5]保證初始化有正有負(fù)
        self.w = random.random() - 0.5 
        # 當(dāng)前層的輸出
        self.output = 0
        
    def forward(self,input_var):
        '''
        前向傳播:對(duì)輸入進(jìn)行運(yùn)算,并將結(jié)果保存
        input_var: 當(dāng)前層的輸入
        '''
        self.input = input_var
        self.output = self.w * self.input
        
    
    def backward(self, public_value):
        '''
        反向傳播:計(jì)算上層也會(huì)使用的導(dǎo)數(shù)值并保存
        假設(shè)當(dāng)前層的計(jì)算規(guī)則是這樣output = f(input),
        而 input == 前一層的輸出,
        因此,根據(jù)鏈?zhǔn)椒▌t損失函數(shù)對(duì)上一層權(quán)重的導(dǎo)數(shù) = 后面層傳過來的公共導(dǎo)數(shù)* f'(input) * 前一層的導(dǎo)數(shù)
        也就是說,后面層傳過來的公共導(dǎo)數(shù)值* f'(input) 是需要往前傳的公用的導(dǎo)數(shù)值。
        由于本層中對(duì)輸入做的運(yùn)算為:output = f(input) = w*input
        所以, f'(input) = w.
        public_value: 后面?zhèn)鬟^來的公共導(dǎo)數(shù)值
        '''
        # 當(dāng)前層要傳給前面層的公共導(dǎo)數(shù)值 = 后面?zhèn)鬟^來的公共導(dǎo)數(shù)值 * f'(input)
        self.public_value = public_value * self.w
        # 損失函數(shù)對(duì)當(dāng)前層參數(shù)w的導(dǎo)數(shù) = 后面?zhèn)鬟^來的公共導(dǎo)數(shù)值 * f'(input) * doutput/dw
        self.w_grad = self.public_value * self.input
    
    def upate(self, learning_rate):
        '''
        利用梯度下降更新參數(shù)w
        參數(shù)迭代更新規(guī)則(梯度下降): w = w - 學(xué)習(xí)率*損失函數(shù)對(duì)w的導(dǎo)數(shù)
        learning_rate: 學(xué)習(xí)率
        '''
        self.w = self.w - learning_rate * self.w_grad
    
    def display(self):
        print('layer',self.layer_index,'w:',self.w)

class Network(object):
    def __init__(self,layers_num):
        '''
        構(gòu)造網(wǎng)絡(luò)
        layers_num: 網(wǎng)絡(luò)層數(shù)
        '''
        self.layers = []
        # 向網(wǎng)絡(luò)添加層
        for i in range(layers_num):
            self.layers.append(Layer(i+1))#層編號(hào)從1開始
    
    def predict(self, sample):
        '''
        sample: 樣本輸入
        return 最后一層的輸出
        '''
        output = sample
        for layer in self.layers:
            layer.forward(output)
            output = layer.output
        return 1 if output>0 else -1
    
    def calc_gradient(self, label):
        '''
        從后往前計(jì)算損失函數(shù)對(duì)各層的導(dǎo)數(shù)
        '''
        # 計(jì)算最后一層的導(dǎo)數(shù)
        last_layer = self.layers[-1]
        # 由于損失函數(shù)=0.5*(last_layer.output - label)^2
        # 由于backward中的public_value = 輸出對(duì)輸入的導(dǎo)數(shù)
        # 對(duì)于損失函數(shù)其輸入是last_layer.output,損失函數(shù)對(duì)該輸入的導(dǎo)數(shù)=last_layer.output - label
        # 所以 最后一層的backward的public_value = last_layer.output - label
        last_layer.backward(last_layer.output - label)
        public_value = last_layer.public_value
        for layer in self.layers:
            layer.backward(public_value) # 計(jì)算損失函數(shù)對(duì)該層參數(shù)的導(dǎo)數(shù)
            public_value= layer.public_value
            
    def update_weights(self, learning_rate):
        '''
        更新各層權(quán)重
        '''
        for layer in self.layers:
            layer.upate(learning_rate)
        
    
    def train_one_sample(self, label, sample, learning_rate):
        self.predict(sample) # 前向傳播,使得各層的輸入都有值
        self.calc_gradient(label) # 計(jì)算各層導(dǎo)數(shù)
        self.update_weights(learning_rate) # 更新各層參數(shù)
        
    def train(self, labels, data_set, learning_rate, epoch):
        '''
        訓(xùn)練神經(jīng)網(wǎng)絡(luò)
        labels: 樣本標(biāo)簽
        data_set: 輸入樣本們
        learning_rate: 學(xué)習(xí)率
        epoch: 同樣的樣本反復(fù)訓(xùn)練的次數(shù)
        '''
        for _ in range(epoch):# 同樣數(shù)據(jù)反復(fù)訓(xùn)練epoch次保證權(quán)重收斂
            for i in range(len(labels)):#逐樣本更新權(quán)重
                self.train_one_sample(labels[i], data_set[i], learning_rate)

nn = Network(3)
data_set = [1,-1]
labels   = [-1,1]
learning_rate = 0.05
epoch = 160
nn.train(labels,data_set,learning_rate,epoch)
print(nn.predict(1)) # 輸出 -1
print(nn.predict(-1)) # 輸出 1

歡迎關(guān)注我的知乎專欄適合初學(xué)者的機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)理論到實(shí)踐。
上一篇為零基礎(chǔ)神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)(1):單個(gè)神經(jīng)元+隨機(jī)梯度下降學(xué)習(xí)邏輯與規(guī)則
下一篇為適合初學(xué)者的神經(jīng)網(wǎng)絡(luò)理論到實(shí)踐(3):打破概念束縛:強(qiáng)化學(xué)習(xí)是個(gè)啥?

審核編輯:符乾江
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    神經(jīng)網(wǎng)絡(luò)的初步認(rèn)識(shí)

    日常生活中的智能應(yīng)用都離不開深度學(xué)習(xí),而深度學(xué)習(xí)則依賴于神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)。什么是神經(jīng)網(wǎng)絡(luò)?神經(jīng)網(wǎng)絡(luò)的核心思想是模仿生物神經(jīng)系統(tǒng)的結(jié)構(gòu),特別是大
    的頭像 發(fā)表于 12-17 15:05 ?335次閱讀
    <b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的初步認(rèn)識(shí)

    自動(dòng)駕駛中常提的卷積神經(jīng)網(wǎng)絡(luò)是個(gè)啥?

    在自動(dòng)駕駛領(lǐng)域,經(jīng)常會(huì)聽到卷積神經(jīng)網(wǎng)絡(luò)技術(shù)。卷積神經(jīng)網(wǎng)絡(luò),簡稱為CNN,是一種專門用來處理網(wǎng)格狀數(shù)據(jù)(比如圖像)的深度學(xué)習(xí)模型。CNN在圖像處理中尤其常見,因?yàn)閳D像本身就可以看作是由像素排列成的二維網(wǎng)格。
    的頭像 發(fā)表于 11-19 18:15 ?2079次閱讀
    自動(dòng)駕駛中常提的卷積<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>是個(gè)啥?

    CNN卷積神經(jīng)網(wǎng)絡(luò)設(shè)計(jì)原理及在MCU200T上仿真測試

    數(shù)的提出很大程度的解決了BP算法在優(yōu)化深層神經(jīng)網(wǎng)絡(luò)時(shí)的梯度耗散問題。當(dāng)x&gt;0 時(shí),梯度恒為1,無梯度耗散問題,收斂快;當(dāng)x&lt;0 時(shí),該層的輸出為0。 CNN
    發(fā)表于 10-29 07:49

    NMSIS神經(jīng)網(wǎng)絡(luò)庫使用介紹

    NMSIS NN 軟件庫是一組高效的神經(jīng)網(wǎng)絡(luò)內(nèi)核,旨在最大限度地提高 Nuclei N 處理器內(nèi)核上的神經(jīng)網(wǎng)絡(luò)的性能最??大限度地減少其內(nèi)存占用。 該庫分為多個(gè)功能,每個(gè)功能涵蓋特定類別
    發(fā)表于 10-29 06:08

    構(gòu)建CNN網(wǎng)絡(luò)模型優(yōu)化的一般化建議

    通過實(shí)踐,本文總結(jié)了構(gòu)建CNN網(wǎng)絡(luò)模型優(yōu)化的一般化建議,這些建議將會(huì)在構(gòu)建高準(zhǔn)確率輕量級(jí)CNN神經(jīng)網(wǎng)絡(luò)模型方面提供幫助。 1)避免單層神經(jīng)網(wǎng)絡(luò)
    發(fā)表于 10-28 08:02

    在Ubuntu20.04系統(tǒng)中訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型的一些經(jīng)驗(yàn)

    本帖欲分享在Ubuntu20.04系統(tǒng)中訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型的一些經(jīng)驗(yàn)。我們采用jupyter notebook作為開發(fā)IDE,以TensorFlow2為訓(xùn)練框架,目標(biāo)是訓(xùn)練一個(gè)手寫數(shù)字識(shí)別的神經(jīng)網(wǎng)絡(luò)
    發(fā)表于 10-22 07:03

    CICC2033神經(jīng)網(wǎng)絡(luò)部署相關(guān)操作

    在完成神經(jīng)網(wǎng)絡(luò)量化后,需要將神經(jīng)網(wǎng)絡(luò)部署到硬件加速器上。首先需要將所有權(quán)重?cái)?shù)據(jù)以及輸入數(shù)據(jù)導(dǎo)入到存儲(chǔ)器內(nèi)。 在仿真環(huán)境下,可將其存于一個(gè)文件,并在 Verilog 代碼中通過 readmemh 函數(shù)
    發(fā)表于 10-20 08:00

    液態(tài)神經(jīng)網(wǎng)絡(luò)(LNN):時(shí)間連續(xù)性與動(dòng)態(tài)適應(yīng)性的神經(jīng)網(wǎng)絡(luò)

    1.算法簡介液態(tài)神經(jīng)網(wǎng)絡(luò)(LiquidNeuralNetworks,LNN)是一種新型的神經(jīng)網(wǎng)絡(luò)架構(gòu),其設(shè)計(jì)理念借鑒自生物神經(jīng)系統(tǒng),特別是秀麗隱桿線蟲的神經(jīng)結(jié)構(gòu),盡管這種微生物的
    的頭像 發(fā)表于 09-28 10:03 ?1226次閱讀
    液態(tài)<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>(LNN):時(shí)間連續(xù)性與動(dòng)態(tài)適應(yīng)性的<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    神經(jīng)網(wǎng)絡(luò)的并行計(jì)算與加速技術(shù)

    隨著人工智能技術(shù)的飛速發(fā)展,神經(jīng)網(wǎng)絡(luò)在眾多領(lǐng)域展現(xiàn)出了巨大的潛力和廣泛的應(yīng)用前景。然而,神經(jīng)網(wǎng)絡(luò)模型的復(fù)雜度和規(guī)模也在不斷增加,這使得傳統(tǒng)的串行計(jì)算方式面臨著巨大的挑戰(zhàn),如計(jì)算速度慢、訓(xùn)練時(shí)間長等
    的頭像 發(fā)表于 09-17 13:31 ?1130次閱讀
    <b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的并行計(jì)算與加速技術(shù)

    基于神經(jīng)網(wǎng)絡(luò)的數(shù)字預(yù)失真模型解決方案

    在基于神經(jīng)網(wǎng)絡(luò)的數(shù)字預(yù)失真(DPD)模型中,使用不同的激活函數(shù)對(duì)整個(gè)系統(tǒng)性能和能效有何影響?
    的頭像 發(fā)表于 08-29 14:01 ?3474次閱讀

    無刷電機(jī)小波神經(jīng)網(wǎng)絡(luò)轉(zhuǎn)子位置檢測方法的研究

    摘要:論文通過對(duì)無刷電機(jī)數(shù)學(xué)模型的推導(dǎo),得出轉(zhuǎn)角:與三相相電壓之間存在映射關(guān)系,因此構(gòu)建了一個(gè)以三相相電壓為輸人,轉(zhuǎn)角為輸出的小波神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)轉(zhuǎn)角預(yù)測,采用改進(jìn)遺傳算法來訓(xùn)練網(wǎng)絡(luò)結(jié)
    發(fā)表于 06-25 13:06

    神經(jīng)網(wǎng)絡(luò)專家系統(tǒng)在電機(jī)故障診斷中的應(yīng)用

    摘要:針對(duì)傳統(tǒng)專家系統(tǒng)不能進(jìn)行自學(xué)習(xí)、自適應(yīng)的問題,本文提出了基于種經(jīng)網(wǎng)絡(luò)專家系統(tǒng)的步電機(jī)故障診斷方法。本文將小波神經(jīng)網(wǎng)絡(luò)和專家系統(tǒng)相結(jié)合,充分發(fā)揮了二者故障診斷的優(yōu)點(diǎn),很大程度上降低了對(duì)電機(jī)
    發(fā)表于 06-16 22:09

    神經(jīng)網(wǎng)絡(luò)RAS在異步電機(jī)轉(zhuǎn)速估計(jì)中的仿真研究

    眾多方法中,由于其結(jié)構(gòu)簡單,穩(wěn)定性好廣泛受到人們的重視,且已被用于產(chǎn)品開發(fā)。但是MRAS仍存在在低速區(qū)速度估計(jì)精度下降和對(duì)電動(dòng)機(jī)參數(shù)變化非常敏感的問題。本文利用神經(jīng)網(wǎng)絡(luò)的特點(diǎn),使估計(jì)更為簡單、快速
    發(fā)表于 06-16 21:54

    基于FPGA搭建神經(jīng)網(wǎng)絡(luò)的步驟解析

    本文的目的是在一個(gè)神經(jīng)網(wǎng)絡(luò)已經(jīng)通過python或者M(jìn)ATLAB訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)模型,將訓(xùn)練好的模型的權(quán)重和偏置文件以TXT文件格式導(dǎo)出,然后通過python程序?qū)xt文件轉(zhuǎn)化為coe文件,(coe
    的頭像 發(fā)表于 06-03 15:51 ?1218次閱讀
    基于FPGA搭建<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的步驟解析

    NVIDIA實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)渲染技術(shù)的突破性增強(qiáng)功能

    近日,NVIDIA 宣布了 NVIDIA RTX 神經(jīng)網(wǎng)絡(luò)渲染技術(shù)的突破性增強(qiáng)功能。NVIDIA 與微軟合作,將在 4 月的 Microsoft DirectX 預(yù)覽版中增加神經(jīng)網(wǎng)絡(luò)著色技術(shù),讓開
    的頭像 發(fā)表于 04-07 11:33 ?1188次閱讀