深度學習(魚書)day08--誤差反向傳播(后三節)

深度學習(魚書)day08–誤差反向傳播(后三節)

在這里插入圖片描述

一、激活函數層的實現

這里,我們把構成神經網絡的層實現為一個類。先來實現激活函數的ReLU層和Sigmoid層。

  1. ReLU層

    激活函數ReLU(Rectified Linear Unit)由下式表示。
    y={x(x>0)0(x≤0) y = \begin{cases} x & (x > 0) \\ 0 & (x \leq 0) \end{cases} y={x0?(x>0)(x0)?
    y關于x的導數:
    ?y?x={1(x>0)0(x≤0) \frac{\partial y}{\partial x} = \begin{cases} 1 & (x > 0) \\ 0 & (x \leq 0) \end{cases} ?x?y?={10?(x>0)(x0)?
    在這里插入圖片描述

    class ReLU:def __init__(self):self.mask = Nonedef forward(self, x):self.mask = (x <= 0)out = x.copy()out[self.mask] = 0def backward(self, dout):dout[self.mask] = 0dx = doutreturn dx
    

    這個變量mask是由True/False構成的NumPy數組,它會把正向傳播時的輸入x的元素中小于等于0的地方保存為True,其他地方(大于0的元素)保存為False。

    如果正向傳播時的輸入值小于等于0,則反向傳播的值為0。因此,反向傳播中會使用正向傳播時保存的mask,將從上游傳來的dout的mask中的元素為True的地方設為0。

    ReLU層的作用就像電路中的開關一樣。正向傳播時,有電流通過的話,就將開關設為 ON;沒有電流通過的話,就將開關設為 OFF。反向傳播時,開關為ON的話,電流會直接通過;開關為OFF的話,則不會有電流通過。

  2. Sigmoid層

    在這里插入圖片描述

    正向傳播:

在這里插入圖片描述

反向傳播:

步驟1

“/”節點表示 在這里插入圖片描述
,它的導數可以解析性地表示為下式。

在這里插入圖片描述

反向傳播時,會將上游的值乘以-y 2 (正向傳播的輸出的平方乘以?1后的值)后,再傳給下游。計算圖如下所示。
在這里插入圖片描述

步驟2

“+”節點將上游的值原封不動地傳給下游。計算圖如下所示。

在這里插入圖片描述

步驟3

“exp”節點表示y = exp(x),它的導數由下式表示。
在這里插入圖片描述

上游的值乘以正向傳播時的輸出(這個例子中是exp(?x))后,再傳給下游。
在這里插入圖片描述

步驟4

×”節點將正向傳播時的值翻轉后做乘法運算。因此,這里要乘以?1。

在這里插入圖片描述

集約化的“sigmoid”節點。可以不用在意Sigmoid層中瑣碎的細節,而只需要專注它的輸入和輸出,這一點也很重要。

在這里插入圖片描述

進一步整理如下:

在這里插入圖片描述

因此,Sigmoid層的反向傳播,只根據正向傳播的輸出就能計算出來。
在這里插入圖片描述

代碼實現:


class Sigmoid:def __init__(self):self.out = Nonedef forward(self, x):out = 1 / (1 + np.exp(-x))self.out = outreturn outdef backward(self, dout):dx = dout * (1.0 - self.out) * self.outreturn dx

二、Affine/Softmax層的實現

  1. Affine層

    神經網絡的正向傳播中進行的矩陣乘積運算在幾何學領域被稱為“仿射變換”。因此,這里將進行仿射變換的處理實現為“Affine層”。

    現在將這里進行的求矩陣的乘積與偏置的和的運算用計算圖表示出來。將乘積運算用“dot”節點表示的話,則np.dot(X, W) + B的運算可用下圖所示的計算圖表示出來。在各個變量的上方標記了它們的形狀(計算圖上顯示了X的形狀為(2,),X·W的形狀為(3,))。

在這里插入圖片描述

現在我們來考慮圖5-24的計算圖的反向傳播。以矩陣為對象的反向傳播,按矩陣的各個元素進行計算時,步驟和以標量為對象的計算圖相同。實際寫一下的話,可以得到下式:

在這里插入圖片描述

嘗試寫出計算圖的反向傳播,如圖所示:


在這里插入圖片描述

  1. 批版本的Affine層

    前面介紹的Affi ne層的輸入X是以單個數據為對象的。現在我們考慮N個數據一起進行正向傳播的情況,也就是批版本的Affine層。先給出批版本的Affine層的計算圖,如圖所示。

    在這里插入圖片描述

    正向傳播時,偏置會被加到每一個數據(第1個、第2個……)上。因此,反向傳播時,各個數據的反向傳播的值需要匯總為偏置的元素。用代碼表示的話,如下所示。

在這里插入圖片描述

這里使用了np.sum()對第0軸(以數據為單位的軸,axis=0)方向上的元素進行求和。

class Affine:def __init__(self, W, b):self.W =Wself.b = bself.x = Noneself.dW = Noneself.db = Nonedef forward(self, x):self.x = xout = np.dot(x, self.W) + self.breturn outdef backward(self, dout):dx = np.dot(dout, self.W.T)self.dW = np.dot(self.x.T, dout)self.db = np.sum(dout, axis=0)return dx

輸入數據為張量(四維數據)的情況:

class Affine:def __init__(self, W, b):self.W =Wself.b = bself.x = Noneself.original_x_shape = None# 權重和偏置參數的導數self.dW = Noneself.db = Nonedef forward(self, x):# 對應張量self.original_x_shape = x.shapex = x.reshape(x.shape[0], -1)self.x = xout = np.dot(self.x, self.W) + self.breturn outdef backward(self, dout):dx = np.dot(dout, self.W.T)self.dW = np.dot(self.x.T, dout)self.db = np.sum(dout, axis=0)dx = dx.reshape(*self.original_x_shape)  # 還原輸入數據的形狀(對應張量)return dx
  1. Softmax-with-Loss 層

    softmax函數會將輸入值正規化之后再輸出。比如手寫數字識別時,Softmax層的輸出如圖所示。

在這里插入圖片描述

神經網絡中進行的處理有推理(inference)和學習兩個階段。神經網絡的推理通常不使用 Softmax層。比如,用圖 5-28的網絡進行推理時,會將最后一個 Affine層的輸出作為識別結果。神經網絡中未被正規化的輸出結果有時被稱為“得分”。也就是說,當神經網絡的推理只需要給出一個答案的情況下,因為此時只對得分最大值感興趣,所以不需要 Softmax層。不過,神經網絡的學習階段則需要 Softmax層。

這里也包含作為損失函數的交叉熵誤差(cross entropy error),所以稱為“Softmax-with-Loss層”。Softmax-with-Loss層(Softmax函數和交叉熵誤差)的計算圖如圖所示。

在這里插入圖片描述
在這里插入圖片描述

  • 這里假設要進行3類分類,從前面的層接收3個輸入(得分)。Softmax層將輸入(a1, a2, a3)正規化,輸出(y1, y2, y3)。Cross Entropy Error層接收Softmax的輸出(y1, y2, y3)和教師標簽(t1, t2, t3),從這些數據中輸出損失L。

  • 注意反向傳播的結果:Softmax層的反向傳播得到了(y1 ? t1, y2 ? t2, y3 ? t3)這樣“漂亮”的結果。由于(y1, y2, y3)是Softmax層的輸出,(t1, t2, t3)是監督數據,所以(y1 ? t1, y2 ? t2, y3 ? t3)是Softmax層的輸出和教師標簽的差分。神經網絡的反向傳播會把這個差分表示的誤差傳遞給前面的層,這是神經網絡學習中的重要性質

  • 考慮一個具體的例子,比如教師標簽是 (0, 1, 0),Softmax層的輸出是 (0.3, 0.2, 0.5)的情形。因為正確解標簽處的概率是0.2(20%),這個時候的神經網絡未能進行正確的識別。此時,Softmax層的反向傳播傳遞的是(0.3, ?0.8, 0.5)這樣一個大的誤差。因為這個大的誤差會向前面的層傳播,所以Softmax層前面的層會從這個大的誤差中學習到“大”的內容。

  • 回歸問題中輸出層使用“恒等函數”,損失函數使用“平方和誤差”,也是出于同樣的理由。也就是說,使用“平方和誤差”作為“恒等函數”的損失函數,反向傳播才能得到(y1 ?t1, y2 ? t2, y3 ? t3)這樣“漂亮”的結果。

  • 再舉一個例子,比如思考教師標簽是 (0, 1, 0),Softmax層的輸出是 (0.01, 0.99, 0)的情形(這個神經網絡識別得相當準確)。此時Softmax層的反向傳播傳遞的是 (0.01, ?0.01, 0)這樣一個小的誤差。這個小的誤差也會向前面的層傳播,因為誤差很小,所以Softmax層前面的層學到的內容也很“小”

Softmax-with-Loss層的實現:

class SoftmaxWithLoss:def __init__(self):self.loss = Noneself.y = Noneself.t = Nonedef forward(self, x, t):self.t = tself.y = softmax(x)self.loss = cross_entropy_error(self.y, self.t)return self.lossdef backward(self, dout=1):batch_size = self.t.shape[0]if self.t.size == self.y.size:  # 監督數據是one-hot-vector的情況dx = (self.y - self.t) / batch_sizeelse:dx = self.y.copy()dx[np.arange(batch_size), self.t] -= 1dx = dx / batch_sizereturn dx

注意反向傳播時,將要傳播的值除以批的大小(batch_size)后,傳遞給前面的層的是單個數據的誤差。

三、誤差反向傳播法的實現

通過像組裝樂高積木一樣組裝上一節中實現的層,可以構建神經網絡。本節我們將通過組裝已經實現的層來構建神經網絡。

  1. 神經網絡學習的全貌圖

在這里插入圖片描述

步驟2中,之前我們利用數值微分求得了這個梯度。數值微分雖然實現簡單,但是計算要耗費較多的時間。和需要花費較多時間的數值微分不同,誤差反向傳播法可以快速高效地計算梯度

  1. 對應誤差反向傳播法的神經網絡的實現

    import sys, os
    sys.path.append(os.pardir)  # 為了導入父目錄的文件而進行的設定
    import numpy as np
    from common.layers import *
    from common.gradient import numerical_gradient
    from collections import OrderedDictclass TwoLayerNet:def __init__(self, input_size, hidden_size, output_size, weight_init_std = 0.01):# 初始化權重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:輸入數據, t:監督數據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.ndim != 1 : t = np.argmax(t, axis=1)accuracy = np.sum(y == t) / float(x.shape[0])return accuracy# x:輸入數據, t:監督數據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 gradsdef gradient(self, x, t):# forwardself.loss(x, t)# backwarddout = 1dout = self.lastLayer.backward(dout)layers = list(self.layers.values())layers.reverse()for layer in layers:dout = layer.backward(dout)# 設定grads = {}grads['W1'], grads['b1'] = self.layers['Affine1'].dW, self.layers['Affine1'].dbgrads['W2'], grads['b2'] = self.layers['Affine2'].dW, self.layers['Affine2'].dbreturn grads
    

在這里插入圖片描述

OrderedDict是有序字典,“有序”是指它可以記住向字典里添加元素的順序。因此,神經網絡的正向傳播只需按照添加元素的順序調用各層的forward()方法就可以完成處理,而反向傳播只需要按照相反的順序調用各層即可。因為Affine層和ReLU層的內部會正確處理正向傳播和反向傳播,所以這里要做的事情僅僅是以正確的順序連接各層,再按順序(或者逆序)調用各層

  1. 誤差反向傳播法的梯度確認
    在確認誤差反向傳播法的實現是否正確時,是需要用到數值微分的。數值微分的優點是實現簡單,一般情況下不太容易出錯。而誤差反向傳播法的實現很復雜,容易出錯。所以,經常會比較數值微分的結果和誤差反向傳播法的結果,以確認誤差反向傳播法的實現是否正確。確認數值微分求出的梯度結果和誤差反向傳播法求出的結果是否一致(嚴格地講,是非常相近)的操作稱為梯度確認(gradient check)。

    import sys, os
    sys.path.append(os.pardir)  # 為了導入父目錄的文件而進行的設定
    import numpy as np
    from dataset.mnist import load_mnist
    from two_layer_net import TwoLayerNet# 讀入數據
    (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))
    

在這里插入圖片描述

通過數值微分和誤差反向傳播法求出的梯度的差非常小。所以誤差反向傳播法求出的梯度是正確的。

  1. 使用誤差反向傳播法的學習

    和之前的實現相比,不同之處僅在于通過誤差反向傳播法求梯度這一點。

    # coding: utf-8
    import sys, os
    sys.path.append(os.pardir)import numpy as np
    from dataset.mnist import load_mnist
    from two_layer_net import TwoLayerNet# 讀入數據
    (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)iters_num = 10000
    train_size = x_train.shape[0]
    batch_size = 100
    learning_rate = 0.1train_loss_list = []
    train_acc_list = []
    test_acc_list = []iter_per_epoch = max(train_size / batch_size, 1)for i in range(iters_num):batch_mask = np.random.choice(train_size, batch_size)x_batch = x_train[batch_mask]t_batch = t_train[batch_mask]# 梯度#grad = network.numerical_gradient(x_batch, t_batch)grad = network.gradient(x_batch, t_batch)# 更新for key in ('W1', 'b1', 'W2', 'b2'):network.params[key] -= learning_rate * grad[key]loss = network.loss(x_batch, t_batch)train_loss_list.append(loss)if i % iter_per_epoch == 0:train_acc = network.accuracy(x_train, t_train)test_acc = network.accuracy(x_test, t_test)train_acc_list.append(train_acc)test_acc_list.append(test_acc)print(train_acc, test_acc)
    

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917171.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917171.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917171.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# 中生成隨機數的常用方法

1. 使用 Random 類&#xff08;簡單場景&#xff09; 2. 使用 RandomNumberGenerator 類&#xff08;安全場景&#xff09; 3. 生成指定精度的隨機小數 C# 中生成隨機數的常用方法&#xff1a; 隨機數類型實現方式示例代碼特點與適用場景隨機整數&#xff08;無范圍&#xf…

Flink 算子鏈設計和源代碼實現

1、JobGraph &#xff08;JobManager&#xff09; JobGraph 生成時&#xff0c;通過 ChainingStrategy 連接算子&#xff0c;最終在 Task 中生成 ChainedDriver 鏈表。StreamingJobGraphGeneratorcreateJobGraph() 構建jobGrapch 包含 JobVertex setChaining() 構建算子鏈isCha…

對接八大應用渠道

背景最近公司想把游戲包上到各個渠道上&#xff0c;因此需要對接各種渠道&#xff0c;渠道如下&#xff0c;oppo、vivo、華為、小米、應用寶、taptap、榮耀、三星等應用渠道 主要就是對接登錄、支付接口&#xff08;后續不知道會不會有其他的&#xff09;&#x…

學習:入門uniapp Vue3組合式API版本(17)

42.打包發行微信小程序的上線全流程 域名 配置 發行 綁定手機號 上傳 提交后等待&#xff0c;上傳 43.打包H5并發布上線到unicloud的前端頁面托管 完善配置 unicloud 手機號實名信息不一致&#xff1a;請確保手機號的實名信息與開發者姓名、身份證號一致&#xff0c;請前往開…

SOLIDWORKS材料明細表設置,屬于自己的BOM表模板

上一期我們了解了如何在SOLIDWORKS工程圖中添加材料明細表?接下來&#xff0c;我們將進行對SOLIDWORKS材料明細表的設置、查看縮略圖、模板保存的深度講解。01 材料明細表設置菜單欄生成表格后左側菜單欄會顯示關于材料明細表的相關設置信息。我們先了解一下菜單欄設置詳情&am…

全棧:Maven的作用是什么?本地倉庫,私服還有中央倉庫的區別?Maven和pom.xml配置文件的關系是什么?

Maven和pom.xml配置文件的關系是什么&#xff1a; Maven是一個構建工具和依賴管理工具&#xff0c;而pom.xml&#xff08;Project Object Model&#xff09;是Maven的核心配置文件。 SSM 框架的項目不一定是 Maven 項目&#xff0c;但推薦使用 Maven進行管理。 SSM 框架的項目可…

超越 ChatGPT:智能體崛起,開啟全自主 AI 時代

引言 短短三年,生成式 AI 已從對話助手跨越到能自主規劃并完成任務的“智能體(Agentic AI)”時代。這場演進不僅體現在模型規模的提升,更在于系統架構、交互范式與安全治理的全面革新。本文按時間線梳理關鍵階段與核心技術,為您呈現 AI 智能體革命的脈絡與未來趨勢。 1. …

一杯就夠:讓大腦瞬間在線、讓肌肉滿電的 “Kick-out Drink” 全解析

一杯就夠&#xff1a;讓大腦瞬間在線、讓肌肉滿電的 “Kick-out Drink” 全解析“每天清晨&#xff0c;當鬧鐘還在哀嚎&#xff0c;你舉杯一飲&#xff0c;睡意像被扔出擂臺——這&#xff0c;就是 Kick-out Drink 的全部浪漫。”清晨 30 分鐘后&#xff0c;250 mL 常溫水里溶解…

系統開機時自動執行指令

使用 systemd 創建一個服務單元可以讓系統開機時自動執行指令&#xff0c;假設需要執行的指令如下&#xff0c;運行可執行文件&#xff08;/home/demo/可執行文件&#xff09;&#xff0c;并輸入參數&#xff08;–input/home/config/demo.yaml&#xff09;&#xff1a; /home/…

Docker 初學者需要了解的幾個知識點 (七):php.ini

這段配置是 php.ini 文件中針對 PHP 擴展和 Xdebug 調試工具的設置&#xff0c;主要用于讓 PHP 支持數據庫連接和代碼調試&#xff08;尤其在 Docker 環境中&#xff09;&#xff0c;具體解釋如下&#xff1a;[PHP] extensionpdo_mysql extensionmysqli xdebug.modedebug xdebu…

【高階版】R語言空間分析、模擬預測與可視化高級應用

隨著地理信息系統&#xff08;GIS&#xff09;和大尺度研究的發展&#xff0c;空間數據的管理、統計與制圖變得越來越重要。R語言在數據分析、挖掘和可視化中發揮著重要的作用&#xff0c;其中在空間分析方面扮演著重要角色&#xff0c;與空間相關的包的數量也達到130多個。在本…

dolphinscheduler中一個腳本用于從列定義中提取列名列表

dolphinscheduler中&#xff0c;我們從一個mysql表導出數據&#xff0c;上傳到hdfs, 再創建一個臨時表&#xff0c;所以需要用到列名定義和列名列表。 原來定義兩個變量&#xff0c;不僅繁鎖&#xff0c;還容易出現差錯&#xff0c;比如兩者列序不對。 所以考慮只定義列定義變量…

JavaWeb(蒼穹外賣)--學習筆記16(定時任務工具Spring Task,Cron表達式)

前言 本篇文章是學習B站黑馬程序員蒼穹外賣的學習筆記&#x1f4d1;。我的學習路線是Java基礎語法-JavaWeb-做項目&#xff0c;管理端的功能學習完之后&#xff0c;就進入到了用戶端微信小程序的開發&#xff0c;用戶端開發的流程大致為用戶登錄—商品瀏覽&#xff08;其中涉及…

靈敏度,精度,精確度,精密度,精準度,準確度,分辨率,分辨力——概念

文章目錄前提總結前提 我最近在整理一份數據指標要求的時候&#xff0c;總是混淆這幾個概念&#xff1a;靈敏度&#xff0c;精度&#xff0c;精確度&#xff0c;精密度&#xff0c;精準度&#xff0c;準確度&#xff0c;分辨率&#xff0c;分辨力&#xff0c;搜了一些文章&…

python-異常(筆記)

#后續代碼可以正常運行 try:f open("xxx.txt","r",encodingutf-8)except:print("except error")#捕獲指定異常&#xff0c;其他異常報錯程序中止&#xff0c;管不到 try:print(name) except NameError as you_call:print("name error"…

[lvgl_player] 用戶界面(LVGL) | 播放器核心設計

docs&#xff1a;基于LVGL的音樂播放器 本項目是為嵌入式設備設計的音樂播放系統&#xff0c;采用LVGL圖形庫構建用戶界面。 系統支持播放WAV格式音頻文件&#xff0c;具備播放列表管理功能&#xff0c;可實現播放/暫停控制、曲目切換等核心操作。 用戶可通過交互界面實時調…

數據賦能(354)——數據分析——多角度分析原則

概述重要性如下&#xff1a;獲得全面理解&#xff1a;多角度分析原則避免僅從單一角度解讀數據&#xff0c;從不同角度、不同維度對數據進行分析&#xff0c;以獲得更全面的理解。發現潛在規律&#xff1a;通過多角度分析&#xff0c;發現數據中的潛在規律和趨勢&#xff0c;為…

【華為機試】127. 單詞接龍

文章目錄127. 單詞接龍描述示例 1&#xff1a;示例 2&#xff1a;提示&#xff1a;解題思路算法分析問題本質分析單向BFS算法詳解雙向BFS算法詳解鄰居單詞生成過程算法流程圖邊界情況分析各種解法對比時間復雜度分析空間復雜度分析關鍵優化點實際應用場景圖構建策略雙向BFS優化…

仿艾莫迅MODBUS調試工具寫一個上位機

公司采購了一個夾具&#xff0c;項目負責人想要試探這個夾具的性能&#xff0c;于是想要我這邊寫一個烤機的程序&#xff0c;小編結合官網資料 https://wiki.amsamotion.com/?title196&doc222查看其pdf說明文檔和調試工具并按照其工具寫一個烤機上位機根據項目負責人的要求…

云展廳:開啟數字化展示新時代

在科技飛速發展的今天&#xff0c;數字化浪潮正席卷各個行業&#xff0c;展覽展示領域也不例外。云展廳作為一種全新的展覽形式&#xff0c;正逐漸嶄露頭角&#xff0c;以其獨特的優勢和創新的技術應用&#xff0c;為觀眾帶來前所未有的觀展體驗&#xff0c;也為企業和機構提供…