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

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

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

手寫數(shù)字識(shí)別神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)(2)

CHANBAEK ? 來源:小小研究生 ? 作者:小小研究生 ? 2023-06-23 16:57 ? 次閱讀

在練習(xí)二中,手寫數(shù)字識(shí)別使用數(shù)值微分的方式實(shí)現(xiàn)了神經(jīng)網(wǎng)絡(luò),現(xiàn)在用誤差反向傳播法來實(shí)現(xiàn)。兩者的區(qū)別僅僅是使用不同方法求梯度。

1、2層神經(jīng)網(wǎng)絡(luò)的類

將2層神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)為一個(gè)TwoLayerNet的類(和上次的代碼僅僅是求梯度的方式不同,不同的地方加*表示):

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 初始化權(quán)重
        self.params = {}
        self.params['W1'] = weight_init_std *np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std *np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)
*       #生成層        
*       self.layers = OrderedDict()
*       self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
*       self.layers['Relu1'] = Relu()
*       self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
*       self.lastLayer = SoftmaxWithLoss()
*   def predict(self, x):
        for layer in self.layers.values():
           x = layer.forward(x)
        return x
    # x:輸入數(shù)據(jù), t:監(jiān)督數(shù)據(jù)
    def loss(self, x, t):
        y = self.predict(x)
*       return self.lastLayer.forward(y, t)
    def accuracy(self, x, t):
        y = self.predict(x)
        y = np.argmax(y, axis=1)
*       if t.dim != 1 : t=np.argmax(t,axis=1)
        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy
    # x:輸入數(shù)據(jù), t:監(jiān)督數(shù)據(jù)
    def numerical_gradient(self, x, t):
        loss_W = lambda W: self.loss(x, t)
        grads = {}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
        return grads
*    def gradient(self, x, t):
        # forward
        self.loss(x, t)
        # backward
        dout = 1
        dout = self.lastLayer.backward(dout)      
        layers = list(self.layers.values())
        layers.reverse()
        for layer in layers:
            dout = layer.backward(dout)
        # 設(shè)定
        grads = {}
        grads['W1'], grads['b1'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
        grads['W2'], grads['b2'] = self.layers['Affine2'].dW, self.layers['Affine2'].db
        return grads

只介紹和數(shù)值微分求導(dǎo)法不同的部分:

初始化: layer是保存神經(jīng)網(wǎng)絡(luò)的層的有序字典型變量 。OrderedDict是有序字典, 有序是說它可以記住向字典中添加元素的順序 ,正向傳播只需要按照添加元素的順序調(diào)用各層的forward方法就可以,反向傳播順序相反地順序調(diào)用backward方法。通過layers['Affine1'],layers['Relu1'],layers['Affine2']的形式保存各個(gè)層。還定義了最后一層lastlayer,上一篇中介紹了Affine,Relu,SoftmaxWithLoss函數(shù)的封裝,在這一層中直接定義。

定義predict函數(shù),用于識(shí)別:predict()函數(shù)的參數(shù)是輸入的圖像數(shù)據(jù),按照層的順序(layers的for語句)依次調(diào)用每一層的forward()函數(shù),先是x經(jīng)過Affine1層的forward函數(shù),返回的out值作為Relu層的forward函數(shù)的輸入?yún)?shù),返回的out作為Affine2層的forward函數(shù)的輸入?yún)?shù),返回的out作為最后一層SoftmaxWithLoss層的forward函數(shù)的輸入?yún)?shù),返回的out是最后的輸出,也就是識(shí)別的結(jié)果。

定義損失函數(shù):輸入?yún)?shù)是x輸入圖像和t標(biāo)簽,經(jīng)過predict函數(shù)得到識(shí)別數(shù)據(jù)y,返回值是輸入為y和t的SoftmaxWithLoss()的前向函數(shù)。

定義識(shí)別精度:經(jīng)過predict()之后的輸出y是識(shí)別結(jié)果,如果與標(biāo)簽一致說明結(jié)果準(zhǔn)確,識(shí)別精度就是準(zhǔn)確的次數(shù)與輸入圖像數(shù)量之比,即準(zhǔn)確的概率。批處理時(shí)假設(shè)一次處理N張,y的形狀是(N,10),有兩個(gè)方向,a[1]是按行方向索引,argmax是找到最大值所在的位置。按行找到到最大值的索引值,就對(duì)應(yīng)每一張圖片識(shí)別到最大可能性的結(jié)果對(duì)應(yīng)的分類。將該分類與標(biāo)簽進(jìn)行比較,求識(shí)別正確的概率。

定義了數(shù)值微分求導(dǎo)的過程,這個(gè)是數(shù)值微分的方法,如果用誤差反向傳播法需要將這段注釋掉;或者后續(xù)要比較兩個(gè)方法求導(dǎo)的結(jié)果。

定義了誤差反向傳播法求導(dǎo)的方法:先求dout=1通過lastlayer層的backward函數(shù)的輸出,返回dx。由于反向傳播經(jīng)過的層和正向相反,正向的有序字典變量需要reverse反向,這樣通過for語句調(diào)用每一層的backward函數(shù)經(jīng)過的層順序就是affine2,relu,affine1,此時(shí)的輸出就是最后的求導(dǎo)結(jié)果。

將神經(jīng)網(wǎng)絡(luò)用層的方式實(shí)現(xiàn),將每一層模塊化,是非常方便的,即使層很多,也只需要接好每一層的接口。通過各個(gè)層內(nèi)部的forward和backward函數(shù)就可以識(shí)別或者計(jì)算梯度。

2、數(shù)值微分的計(jì)算耗時(shí),但是計(jì)算簡單不易出錯(cuò)。誤差反向傳播法的實(shí)現(xiàn)相對(duì)復(fù)雜容易出錯(cuò)。所以比較兩者的結(jié)果可以確認(rèn)誤差反向傳播法是否正確。這個(gè)比較的操作成為梯度確認(rèn)。梯度確認(rèn)的代碼:

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
x_batch = x_train[:3]
t_batch = t_train[:3]
grad_numerical = network.numerical_gradient(x_batch, t_batch)
grad_backprop = network.gradient(x_batch, t_batch)
for key in grad_numerical.keys():
    diff = np.average( np.abs(grad_backprop[key] - grad_numerical[key]) )
    print(key + ":" + str(diff))

通過numerical_gradient函數(shù)得到的數(shù)值微分求導(dǎo)結(jié)果保存在grad_numerical中,通過gradient函數(shù)得到的誤差反向傳播結(jié)求導(dǎo)結(jié)果保存在grad_backprop中。通過求對(duì)應(yīng)位置的數(shù)值的絕對(duì)值的平均值,判斷誤差反向傳播求導(dǎo)結(jié)果是否正確。

W1:3.705434371413955e-10

b1:2.37776902256894e-09

W2:5.412727643613116e-09

b2:1.396563151026542e-07

輸出的誤差很小,所以是正確的。

3、使用誤差反向傳播法的學(xué)習(xí)

和數(shù)值微分的方法一樣,因?yàn)椴煌巸H僅是求梯度。

因此在練習(xí)二中的代碼,把數(shù)值微分求梯度的代碼注釋掉,用誤差反向傳播法求梯度的代碼就可以了。

總結(jié):通過買水果的例子介紹了誤差反向傳播法的原理,介紹了神經(jīng)網(wǎng)絡(luò)中的誤差反向傳播法,原理一樣只是不用標(biāo)量用矩陣。將relu,softmaxwithloss,affine,softmax層封裝成模塊,內(nèi)部實(shí)現(xiàn)了forward和backward方法。只需要搭建神經(jīng)網(wǎng)絡(luò)的每一層,通過內(nèi)部的forward和backward函數(shù),將數(shù)據(jù)正向或反向傳播就可以求導(dǎo)。

聲明:本文內(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)投訴
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4733

    瀏覽量

    100420
  • 數(shù)值
    +關(guān)注

    關(guān)注

    0

    文章

    80

    瀏覽量

    14340
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4277

    瀏覽量

    62325
  • 數(shù)字識(shí)別
    +關(guān)注

    關(guān)注

    2

    文章

    19

    瀏覽量

    10130
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于BP神經(jīng)網(wǎng)絡(luò)的手勢識(shí)別系統(tǒng)

      摘 要:本文給出了采用ADXL335加速度傳感器來采集五個(gè)手指和手背的加速度三軸信息,并通過ZigBee無線網(wǎng)絡(luò)傳輸來提取手勢特征量,同時(shí)利用BP神經(jīng)網(wǎng)絡(luò)算法進(jìn)行誤差分析來實(shí)現(xiàn)手勢識(shí)別
    發(fā)表于 11-13 16:04

    【PYNQ-Z2申請(qǐng)】基于PYNQ-Z2神經(jīng)網(wǎng)絡(luò)圖形識(shí)別

    對(duì)神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí),講解其工作原理。4.基于PYNQ-Z2,用python實(shí)現(xiàn)一個(gè)神經(jīng)網(wǎng)絡(luò)。5.訓(xùn)練和測試神經(jīng)網(wǎng)絡(luò),完成
    發(fā)表于 01-09 14:48

    【PYNQ-Z2試用體驗(yàn)】神經(jīng)網(wǎng)絡(luò)基礎(chǔ)知識(shí)

    前言前面我們通過notebook,完成了在PYNQ-Z2開發(fā)板上編寫并運(yùn)行python程序。我們的最終目的是基于神經(jīng)網(wǎng)絡(luò),完成手寫數(shù)字識(shí)別
    發(fā)表于 03-03 22:10

    【PYNQ-Z2試用體驗(yàn)】基于PYNQ-Z2神經(jīng)網(wǎng)絡(luò)圖形識(shí)別[結(jié)項(xiàng)]

    前言前面我們簡單講解了神經(jīng)網(wǎng)絡(luò)的基本概念和工作原理,接下來,將通過具體的python代碼來完成基于神經(jīng)網(wǎng)絡(luò)的圖形識(shí)別。這里使用手寫數(shù)字圖像
    發(fā)表于 03-18 21:51

    【案例分享】ART神經(jīng)網(wǎng)絡(luò)與SOM神經(jīng)網(wǎng)絡(luò)

    是一種常用的無監(jiān)督學(xué)習(xí)策略,在使用改策略時(shí),網(wǎng)絡(luò)的輸出神經(jīng)元相互競爭,每一時(shí)刻只有一個(gè)競爭獲勝的神經(jīng)元激活。ART神經(jīng)網(wǎng)絡(luò)由比較層、識(shí)別層、
    發(fā)表于 07-21 04:30

    人工神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)方法有哪些?

    人工神經(jīng)網(wǎng)絡(luò)(Artificial Neural Network,ANN)是一種類似生物神經(jīng)網(wǎng)絡(luò)的信息處理結(jié)構(gòu),它的提出是為了解決一些非線性,非平穩(wěn),復(fù)雜的實(shí)際問題。那有哪些辦法能實(shí)現(xiàn)人工神經(jīng)
    發(fā)表于 08-01 08:06

    matlab實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò) 精選資料分享

    習(xí)神經(jīng)神經(jīng)網(wǎng)絡(luò),對(duì)于神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)是如何一直沒有具體實(shí)現(xiàn)一下:現(xiàn)看到一個(gè)簡單的神經(jīng)網(wǎng)絡(luò)模型用于訓(xùn)
    發(fā)表于 08-18 07:25

    如何使用STM32F4+MPU9150實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)識(shí)別手勢?

    如何使用STM32F4+MPU9150實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)識(shí)別手勢?
    發(fā)表于 11-19 07:06

    人工神經(jīng)網(wǎng)絡(luò)手寫數(shù)字識(shí)別系統(tǒng)的詳細(xì)資料概述

    逼近未知非線性對(duì)象的特點(diǎn),使其為手寫數(shù)字識(shí)別提供了一種新的方法。本論文采用一編制了一套基于神經(jīng)網(wǎng)絡(luò)手寫
    發(fā)表于 05-27 08:00 ?18次下載
    人工<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b><b class='flag-5'>手寫</b><b class='flag-5'>數(shù)字</b><b class='flag-5'>識(shí)別</b>系統(tǒng)的詳細(xì)資料概述

    谷歌向神經(jīng)網(wǎng)絡(luò)手寫數(shù)字識(shí)別發(fā)起挑戰(zhàn),竟用量子計(jì)算識(shí)別

    神經(jīng)網(wǎng)絡(luò)做 MNIST 手寫數(shù)字識(shí)別是機(jī)器學(xué)習(xí)小白用來練手的入門項(xiàng)目,業(yè)內(nèi)最佳準(zhǔn)確率已經(jīng)達(dá)到了 99.84%。但最近,谷歌向這個(gè)「古老」的數(shù)據(jù)集發(fā)起了一項(xiàng)新的挑戰(zhàn):用量子計(jì)算來進(jìn)行
    的頭像 發(fā)表于 08-17 17:17 ?1583次閱讀
    谷歌向<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b><b class='flag-5'>手寫</b><b class='flag-5'>數(shù)字</b><b class='flag-5'>識(shí)別</b>發(fā)起挑戰(zhàn),竟用量子計(jì)算<b class='flag-5'>識(shí)別</b>

    神經(jīng)網(wǎng)絡(luò)入門:使用Python+Flux+Julia來實(shí)現(xiàn)手寫數(shù)字識(shí)別

    使用 MNIST 數(shù)據(jù)集對(duì) 0 到 9 之間的數(shù)字進(jìn)行手寫數(shù)字識(shí)別神經(jīng)網(wǎng)絡(luò)的一個(gè)典型入門教程。 該技術(shù)在現(xiàn)實(shí)場景中是很有用的,比如可以把該
    的頭像 發(fā)表于 11-03 22:02 ?675次閱讀

    使用PyhonFluxJulia實(shí)現(xiàn)手寫數(shù)字識(shí)別神經(jīng)網(wǎng)絡(luò)入門教程

    使用 MNIST 數(shù)據(jù)集對(duì) 0 到 9 之間的數(shù)字進(jìn)行手寫數(shù)字識(shí)別神經(jīng)網(wǎng)絡(luò)的一個(gè)典型入門教程。該技術(shù)在現(xiàn)實(shí)場景中是很有用的,比如可以把該技
    發(fā)表于 12-08 00:23 ?7次下載

    手寫數(shù)字識(shí)別神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)(1)

    對(duì)MNIST數(shù)據(jù)集使用2神經(jīng)網(wǎng)絡(luò)(1層隱藏層)實(shí)現(xiàn)。
    的頭像 發(fā)表于 06-23 16:57 ?523次閱讀
    <b class='flag-5'>手寫</b><b class='flag-5'>數(shù)字</b><b class='flag-5'>識(shí)別</b><b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的<b class='flag-5'>實(shí)現(xiàn)</b>(1)

    卷積神經(jīng)網(wǎng)絡(luò)如何識(shí)別圖像

    多層卷積層、池化層和全連接層。CNN模型通過訓(xùn)練識(shí)別并學(xué)習(xí)高度復(fù)雜的圖像模式,對(duì)于識(shí)別物體和進(jìn)行圖像分類等任務(wù)有著非常優(yōu)越的表現(xiàn)。本文將會(huì)詳細(xì)介紹卷積神經(jīng)網(wǎng)絡(luò)如何識(shí)別圖像,主要包括以下
    的頭像 發(fā)表于 08-21 16:49 ?1873次閱讀

    神經(jīng)網(wǎng)絡(luò)在圖像識(shí)別中的應(yīng)用

    隨著人工智能技術(shù)的飛速發(fā)展,神經(jīng)網(wǎng)絡(luò)在圖像識(shí)別領(lǐng)域的應(yīng)用日益廣泛。神經(jīng)網(wǎng)絡(luò)以其強(qiáng)大的特征提取和分類能力,為圖像識(shí)別帶來了革命性的進(jìn)步。本文將詳細(xì)介紹
    的頭像 發(fā)表于 07-01 14:19 ?587次閱讀