layout: post
title: 深度學(xué)習(xí)入門(mén) 基于Python的理論實(shí)現(xiàn)
subtitle: 第五章 誤差反向傳播法
tags: [Machine learning, Reading]
第五章 誤差反向傳播法
上一章介紹了神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)靡努,并通過(guò)數(shù)值微分計(jì)算了神經(jīng)網(wǎng)絡(luò)的權(quán)重參數(shù)的梯度鸠信,數(shù)值微分雖然簡(jiǎn)單丙挽,但是計(jì)算起來(lái)比較浪費(fèi)時(shí)間。本章使用一個(gè)能夠高效計(jì)算權(quán)重參數(shù)的梯度的方法--誤差反向傳播法滑肉。
正確理解反向傳播法,有兩種方法屡限,一種基于計(jì)算圖尘喝,一種基于數(shù)學(xué)式。后者是比較常見(jiàn)的方法送滞,本章通過(guò)計(jì)算圖來(lái)理解侠草。
5.1 計(jì)算圖
5.1.1 用計(jì)算圖求解
我們嘗試用計(jì)算圖解決問(wèn)題,目的是為了讓大家熟悉計(jì)算圖犁嗅。
問(wèn)題1:太郎在超市買(mǎi)了 2 個(gè) 100 日元一個(gè)的蘋(píng)果边涕,消費(fèi)稅是 10%,請(qǐng)計(jì)算支付金額褂微。
計(jì)算圖通過(guò)節(jié)點(diǎn)和箭頭表示計(jì)算過(guò)程功蜓,節(jié)點(diǎn)用圓圈表示,圓圈內(nèi)是計(jì)算的內(nèi)容宠蚂。將計(jì)算的中間結(jié)果寫(xiě)在箭頭上方式撼,表示各個(gè)節(jié)點(diǎn)的計(jì)算結(jié)果從左向右傳遞,對(duì)于上述問(wèn)題求厕,求解過(guò)程如圖所示著隆。
開(kāi)始時(shí)扰楼,蘋(píng)果的100日元流到 節(jié)點(diǎn),變成200日元美浦,然后傳遞到下一個(gè)節(jié)點(diǎn)弦赖,流向 節(jié)點(diǎn),變成220日元抵代。因此答案是220日元腾节。
上圖中把 整體擴(kuò)起來(lái),不過(guò)只用圓圈表示 也是可以的荤牍,此時(shí)案腺,可以將 2 和 1.1 分別作為變量“蘋(píng)果的個(gè)數(shù)”和“消費(fèi)稅”表在外面。
問(wèn)題2:太郎在超市買(mǎi)了兩個(gè)蘋(píng)果三個(gè)橘子康吵,其中劈榨,蘋(píng)果每個(gè)100日元。橘子每個(gè)150日元晦嵌,消費(fèi)稅是10%同辣,請(qǐng)計(jì)算支付金額。按照上面的思路惭载,求解過(guò)程如圖所示旱函。
綜上,用計(jì)算圖解題的流程如下:
1.構(gòu)建計(jì)算圖
2.在計(jì)算圖上從左向右計(jì)算
第二部的“從左向右計(jì)算”是一種正方向上的傳播過(guò)程描滔,稱為正向傳播棒妨,與之相對(duì)應(yīng)的是反向傳播。
5.1.2 局部計(jì)算
計(jì)算圖可以通過(guò)傳遞“局部計(jì)算”獲得最終結(jié)果含长。下面是一個(gè)局部計(jì)算的例子券腔。
這個(gè)圖也很好理解,結(jié)論是拘泞,無(wú)論全局計(jì)算有多么復(fù)雜纷纫,只要按照步驟,都可以最終計(jì)算出結(jié)果陪腌。
5.1.3 為何用計(jì)算圖解題
優(yōu)點(diǎn)一:局部計(jì)算辱魁,無(wú)論全局多么復(fù)雜的計(jì)算,都可以通過(guò)局部計(jì)算使各個(gè)節(jié)點(diǎn)致力于簡(jiǎn)單的計(jì)算诗鸭。
優(yōu)點(diǎn)二:通過(guò)反向傳播計(jì)算導(dǎo)數(shù)商叹。
我們重新思考問(wèn)題1,假設(shè)我們想知道蘋(píng)果價(jià)格的波動(dòng)會(huì)在多大程度上影響最終支付的金額只泼,也就是求“支付金額關(guān)于蘋(píng)果價(jià)格的導(dǎo)數(shù)”,設(shè)蘋(píng)果價(jià)格為 ,支付金額為 卵洗,則相當(dāng)于求 请唱。
現(xiàn)在使用計(jì)算圖的反向傳播求這個(gè)導(dǎo)數(shù)弥咪。
如上圖所示,反向傳播使用與正方向相反的箭頭(粗線)表示十绑。反向傳播傳遞“局部導(dǎo)數(shù)”聚至,將導(dǎo)數(shù)值寫(xiě)在下方,這里墜重支付金額關(guān)于蘋(píng)果價(jià)格的導(dǎo)數(shù)是2.2本橙,也就是說(shuō)蘋(píng)果價(jià)格每上升1元扳躬,最終支付金額會(huì)上漲2.2元。
5.2 鏈?zhǔn)椒▌t
5.2.1 計(jì)算圖的反向傳播
假設(shè)存在 的計(jì)算甚亭,這個(gè)計(jì)算的反向傳播如圖所示贷币。
反向傳播的計(jì)算順序是,將信號(hào)E乘以節(jié)點(diǎn)的局部導(dǎo)數(shù) 亏狰,然后將結(jié)果傳遞給下一個(gè)節(jié)點(diǎn)役纹,這里所說(shuō)的局部導(dǎo)數(shù)是指正向傳播中 的導(dǎo)數(shù),也就是y關(guān)于x的導(dǎo)數(shù) 暇唾。比如促脉,假設(shè) ,
則局部導(dǎo)數(shù)為 策州。把這個(gè)局部導(dǎo)數(shù)乘以上游傳過(guò)來(lái)的值( 本 例 中 為 E )瘸味, 然后傳遞給前面的節(jié)點(diǎn)。
5.2.2 鏈?zhǔn)椒▌t
介紹鏈?zhǔn)椒▌t之前够挂,先要從復(fù)合函數(shù)說(shuō)起旁仿,復(fù)合函數(shù)是多個(gè)函數(shù)構(gòu)成的函數(shù),比如 是由以下兩個(gè)式子構(gòu)成的下硕。
鏈?zhǔn)椒▌t是關(guān)于復(fù)合函數(shù)的導(dǎo)數(shù)的性質(zhì)丁逝,定義如下。
如果某個(gè)函數(shù)由復(fù)合函數(shù)表示梭姓,則該復(fù)合函數(shù)的導(dǎo)數(shù)可以用構(gòu)成復(fù)合函數(shù)的各個(gè)函數(shù)的導(dǎo)數(shù)的乘積表示
這就是鏈?zhǔn)椒▌t的原理霜幼,用上面的表達(dá)式為例,(z關(guān)于x的導(dǎo)數(shù))可以用 (z關(guān)于t的導(dǎo)數(shù))和 (t關(guān)于x的導(dǎo)數(shù))的乘積表示誉尖。數(shù)學(xué)表示如下:
式子中的 可以相互抵消罪既。
現(xiàn)在我們用鏈?zhǔn)椒▌t,試著求上面表達(dá)式的導(dǎo)數(shù)铡恕,接下來(lái)要求式子中的局部導(dǎo)數(shù)(偏導(dǎo)數(shù))
于是可以得到:
5.2.3 鏈?zhǔn)椒▌t和計(jì)算圖
現(xiàn)在我們嘗試將鏈?zhǔn)椒▌t的計(jì)算用計(jì)算圖表達(dá)出來(lái)琢感。
如圖所示,計(jì)算圖的反向傳播從右往左傳播信號(hào)探熔,反向傳播的計(jì)算順序是驹针,先將節(jié)點(diǎn)的輸入信號(hào)乘以節(jié)點(diǎn)的偏導(dǎo)數(shù),然后再傳遞給下一個(gè)節(jié)點(diǎn)诀艰。比如柬甥,反向傳播時(shí)饮六,“**2”節(jié)點(diǎn)的輸入是 ,將其乘以局部導(dǎo)數(shù) 因?yàn)檎騻鞑サ妮斎胧莟苛蒲,輸出是z卤橄,所以這個(gè)節(jié)點(diǎn)的局部導(dǎo)數(shù)是 然后傳遞給下一個(gè)節(jié)點(diǎn)。
在圖中最左邊是反向傳播的結(jié)果臂外,他的計(jì)算基于上面的規(guī)則窟扑,因此有 ,對(duì)應(yīng)z關(guān)于x的導(dǎo)數(shù)。代入得到 的結(jié)果是
5.3 反向傳播
5.3.1 加法節(jié)點(diǎn)的反向傳播
首先看一下加法節(jié)點(diǎn)的反向傳播這漏健,這里以 為對(duì)象嚎货,觀察反向傳播。 的導(dǎo)數(shù)可以由下式計(jì)算出來(lái)漾肮。
上面兩個(gè)式子都等于1厂抖,用計(jì)算圖表示如下所示。
下面來(lái)看一個(gè)具體的例子克懊。假設(shè)有“”這樣的計(jì)算忱辅,加法節(jié)點(diǎn)的反向傳播只是將信號(hào)輸出到下一個(gè)節(jié)點(diǎn)。
5.3.2 乘法節(jié)點(diǎn)的反向傳播
用同樣的方式看乘法節(jié)點(diǎn)谭溉。假設(shè) 于是有
下面看一個(gè)具體的例子墙懂, 。
5.3.3 蘋(píng)果的例子
接著來(lái)思考一下蘋(píng)果的例子扮念。這里要解的問(wèn)題是蘋(píng)果的價(jià)格损搬、蘋(píng)果的個(gè)數(shù)、消費(fèi)稅這3個(gè)變量各自如何影響最終支付的金額柜与。這個(gè)問(wèn)題相當(dāng)于求“支付金額關(guān)于蘋(píng)果的價(jià)格的導(dǎo)數(shù)”“支付金額關(guān)于蘋(píng)果的個(gè)數(shù)的導(dǎo)數(shù)”“支付金額關(guān)于消費(fèi)稅的導(dǎo)數(shù)”巧勤。
5.4 簡(jiǎn)單層的實(shí)現(xiàn)
本節(jié)用python實(shí)現(xiàn)前面的蘋(píng)果例子,乘法節(jié)點(diǎn)稱為“乘法層”弄匕,加法節(jié)點(diǎn)稱為“加法層”颅悉。
5.4.1 乘法層的實(shí)現(xiàn)
class MulLayer:
def __init__(self):
self.x = None
self.y = None
def forward(self, x, y):
self.x = x
self.y = y
out = x * y
return out
def backward(self, dout):
dx = dout * self.y
dy = dout * self.x
return dx,dy
init() 中會(huì)初始化實(shí)例變量 x 和 y,它們用于保存正向傳播時(shí)的輸入值迁匠。 forward() 接收 x 和 y 兩個(gè)參數(shù)剩瓶,將它們相乘后輸出质和。backward() 將從上游傳 來(lái)的導(dǎo)數(shù)(dout)乘以正向傳播的翻轉(zhuǎn)值狭莱,然后傳給下游。
參照上圖可以作如下實(shí)現(xiàn)蝉绷。
apple = 100
apple_num = 2
tax = 1.1
#layer
mul_apple_layer = MulLayer()
mul_tax_layer = MulLayer()
#forward
apple_price = mul_apple_layer.forward(apple,apple_num)
price = mul_tax_layer.forward(apple_price,tax)
print(price)
#backward
dprice = 1
dapple_price,dtax = mul_tax_layer.backward(dprice)
dapple,dapple_num = mul_apple_layer.backward(dapple_price)
print(dapple,dapple_num,dtax)
5.4.2 加法層的實(shí)現(xiàn)
class AddLayer:
def __init__(self):
pass
def forward(self,x,y):
out = x + y
return out
def backward(self,dout):
dx = dout * 1
dy = dout * 1
return dx,dy
使用之前的方法進(jìn)行實(shí)現(xiàn)亡哄。
apple = 100
orange = 150
apple_num = 2
orange_num = 3
tax = 1.1
#layer
mul_apple_layer = MulLayer()
mul_orange_layer = MulLayer()
add_apple_orange_layer = AddLayer()
mul_tax_layer = MulLayer()
#forward
apple_price = mul_apple_layer.forward(apple,apple_num)
orange_price = mul_orange_layer.forward(orange,orange_num)
all_price = add_apple_orange_layer.forward(apple_price,orange_price)
price = mul_tax_layer.forward(all_price,tax)
#backward
dprice = 1
dall_price,dtax = mul_tax_layer.backward(dprice)
dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price)
dorange,dorange_num = mul_orange_layer.backward(dorange_price)
dapple,dapple_num = mul_apple_layer.backward(dapple_price)
print(price)
print(dapple_num,dapple,dorange,dorange_num,dtax)
5.5 激活函數(shù)層的實(shí)現(xiàn)
現(xiàn)在把計(jì)算圖的思想應(yīng)用到神經(jīng)網(wǎng)絡(luò)枝缔。
5.5.1 ReLU層
激活函數(shù)ReLU數(shù)學(xué)表達(dá)式如下:
可以求出y關(guān)于x的導(dǎo)數(shù):
根據(jù)上面的表達(dá)式可以得知,正向傳播時(shí)如果輸入x大于零蚊惯,則反向傳播會(huì)將上游的值原封不動(dòng)的傳遞魂仍,當(dāng)正向傳播的值x小于0時(shí)拐辽,會(huì)將信號(hào)停留在此處。
下面是是實(shí)現(xiàn):
class Relu:
def __init__(self):
self.mask = None
def forward(self, x):
self.mask = (x <= 0)
out = x.copy()
out[self.mask] = 0 #True的位置變成0 也就是小于0的變成0
return out
def backward(self,dout):
dout[self.mask] = 0
dx = dout
return dx
x = np.array([[1,-0.5],[-2.0,3.0]])
print(x)
mask = (x<=0)
out = x.copy()
out[mask] = 0
print(out)
5.5.2 Sigmoid 層
接下來(lái)是sigmoid函數(shù)的實(shí)現(xiàn)
計(jì)算圖如下:
下面簡(jiǎn)單看一下反向傳播的流程:
步驟1
“/”節(jié)點(diǎn)表示 導(dǎo)數(shù)如下:
因此如下圖所示
步驟2
下面的節(jié)點(diǎn)是加法節(jié)點(diǎn)擦酌,原封不動(dòng)的傳給下游
步驟3
“exp”節(jié)點(diǎn)表示 , 他的導(dǎo)數(shù)由下式表示。
步驟4
乘法節(jié)點(diǎn)翻轉(zhuǎn)相乘菠劝。
根據(jù)上面的計(jì)算赊舶,簡(jiǎn)化后,得到如圖所示的圖赶诊,和上面的計(jì)算結(jié)果相同笼平。
進(jìn)一步作整理:
$$
\frac{\partial L}{\partial y}y^2exp(-x) = \frac{\partial L}{\partial y}\frac{1}{(1+exp(-x))^2}exp(-x) \
=\frac{\partial L}{\partial y}\frac{1}{1+exp(-x)}\frac{exp(-x)}{1+exp(-x)} \
=\frac{\partial L}{\partial y}y(1-y)
$$
因此,我們可以簡(jiǎn)化如下:
以下是實(shí)現(xiàn):
class Sigmoid:
def __init__(self):
self.out = None
def forward(self, x):
out = 1 / (1 + np.exp(-x))
self.out = out
return out
def backward(self, dout):
dx = dout * (1.0 - self.out) * self.out
return dx
5.6 Affine/Softamx層的實(shí)現(xiàn)
5.6.1 Affine層
上一章講解了矩陣的乘法舔痪,使用Y= np.dot(X, W) + B計(jì)算寓调,這里把這個(gè)運(yùn)算表達(dá)出來(lái)。
現(xiàn)在考慮上圖的反向傳播锄码。對(duì)于加法節(jié)點(diǎn)來(lái)說(shuō)夺英,原封不動(dòng)的傳遞 ,對(duì)于dot節(jié)點(diǎn),交換乘轉(zhuǎn)置滋捶,得到 痛悯。同理得到:
轉(zhuǎn)置的概念不再贅述。
簡(jiǎn)化上面的表達(dá)式重窟,可以得到:
5.6.2 批版本的Affine層
前面介紹的X是以單個(gè)數(shù)據(jù)為對(duì)象的载萌,現(xiàn)在考慮N個(gè)數(shù)據(jù)一起正向傳播的情況。
實(shí)現(xiàn):
class Affine:
def __init__(self, W, b):
self.W = W
self.b = b
self.x = None
self.dW = None
self.db = None
def forward(self, x):
self.x = x
out = np.dot(x, self.W) + self.b
return out
def 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
5.6.3 Softmax-with-Loss 層
最后介紹輸出層的softmax函數(shù)巡扇。手寫(xiě)數(shù)字識(shí)別的時(shí)候扭仁,整個(gè)神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)如圖所示。
下面實(shí)現(xiàn)Softmax層厅翔,考慮到這里也包含交叉熵誤差乖坠,所以也稱為Softmax-with-Loss層。以下是計(jì)算圖和簡(jiǎn)化版:
實(shí)現(xiàn):
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(t*np.log(y + delta))
def softmax(x):
exp_x = np.exp(x-np.max(x))
sum_exp_x = np.sum(exp_x)
return exp_x/sum_exp_x
class SoftmaxWithLoss:
def __init__(self):
self.loss = None
self.y = None
self.t = None
def forward(self, x, t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y,self.t)
return self.loss
def backward(self,dout=1):
batch_size = self.t.shape[0]
dx = (self.y - self.t) / batch_size
return dx
5.7 誤差反向傳播法的實(shí)現(xiàn)
5.7.1 神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)的全貌
前提
神經(jīng)網(wǎng)絡(luò)中有合適的權(quán)重和偏置知给,調(diào)整權(quán)重和偏置以便擬合訓(xùn)練數(shù)據(jù)的 過(guò)程稱為學(xué)習(xí)瓤帚。神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)分為下面 4 個(gè)步驟。
步驟1(mini-batch)
從訓(xùn)練數(shù)據(jù)中隨機(jī)選擇一部分?jǐn)?shù)據(jù)涩赢。
步驟2(計(jì)算梯度)
計(jì)算損失函數(shù)關(guān)于各個(gè)權(quán)重參數(shù)的梯度戈次。
步驟3(更新參數(shù))
將權(quán)重參數(shù)沿梯度方向進(jìn)行微小的更新。
步驟4(重復(fù))
重復(fù)步驟 1筒扒、步驟 2怯邪、步驟 3。
5.7.2 對(duì)應(yīng)誤差反向傳播法的神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)
下面是TwoLayerNet的代碼實(shí)現(xiàn):
import sys, os
sys.path.append(os.pardir) # 為了導(dǎo)入父目錄的文件而進(jìn)行的設(shè)定
import numpy as np
from common.layers import *
from common.gradient import numerical_gradient
from collections import OrderedDict
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['W'],self.params['b2'])
self.lastlayer = SoftmaxWithLoss()
def predict(self, x):
for layer in self.layers.values():
x = layer.forward(x)
return x
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
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):
self.loss(x, t)
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'] = self.layers['Affine1'].dW
grads['b1'] = self.layers['Affine1'].db
grads['W2'] = self.layers['Affine2'].dW
grads['b2'] = self.layers['Affine2'].db
return grads
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# 讀入數(shù)據(jù)
(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_backprop = network.gradient(x_batch, t_batch)
# 求各個(gè)權(quán)重的絕對(duì)誤差的平均值
grad_numerical = network.numerical_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))
計(jì)算后的結(jié)果如下:
W1:3.5949338619330523e-10
b1:2.239133814485334e-09
W2:5.190797970067163e-09
b2:1.4008290402101054e-07
結(jié)果表明花墩,使用數(shù)值微分和誤差反向傳播法求出的梯度的差非常小悬秉。也就是說(shuō)澄步,反向傳播法是正確的。
5.7.4 使用誤差反向傳播法的學(xué)習(xí)
實(shí)現(xiàn):
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.1
train_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.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)
最大的變化是計(jì)算速度顯著提高和泌。
5.8 小結(jié)
本章我們介紹了將計(jì)算過(guò)程可視化的計(jì)算圖村缸,并使用計(jì)算圖,介紹了神經(jīng)網(wǎng)絡(luò)中的誤差反向傳播法武氓,并以層為單位實(shí)現(xiàn)了神經(jīng)網(wǎng)絡(luò)中的處理梯皿。
- 通過(guò)使用計(jì)算圖,可以直觀地把握計(jì)算過(guò)程县恕。
- 計(jì)算圖的節(jié)點(diǎn)是由局部計(jì)算構(gòu)成的东羹。局部計(jì)算構(gòu)成全局計(jì)算。
- 計(jì)算圖的正向傳播進(jìn)行一般的計(jì)算忠烛。通過(guò)計(jì)算圖的反向傳播属提,可以計(jì)算各個(gè)節(jié)點(diǎn)的導(dǎo)數(shù)。
- 通過(guò)將神經(jīng)網(wǎng)絡(luò)的組成元素實(shí)現(xiàn)為層美尸,可以高效地計(jì)算梯度(反向傳播法)冤议。
- 通過(guò)比較數(shù)值微分和誤差反向傳播法的結(jié)果,可以確認(rèn)誤差反向傳播法的實(shí)現(xiàn)是否正確(梯度確認(rèn))火惊。