[英]Implementing general back-propagation
我正在嘗試為具有任意激活功能的完全連接層實現反向傳播方法。 我理解算法背后的一般思想和數學,但是我對理解矢量化形式有困難......
我需要幫助理解元素的預期尺寸
已知尺寸:
未知大小:對於N = 1 (示例數)
這是我的代碼:
def backward(self, dy):
if self.activator == 'relu':
dz = np.zeros((self.z.shape[0], self.z.shape[1]))
dz[self.z>0] = 1
elif self.activator == 'sigmoid':
dz = self.z * (1 - self.z)
elif self.activator == 'soft-max':
s = self.z.reshape(-1, 1)
dz = np.diagflat(s) - np.dot(s, s.T)
elif self.activator == 'none':
dz = 1
self.d = np.dot((dz * dy), self.W.T) # the error of the layer
self.W_grad = np.dot(self.X.T, dy) # The weight gradient of the layer
self.b_grad = np.sum(dy, axis=0).reshape(1, -1) # The bias gradient of the layer
我相信,你的代碼中有一點點混亂:你寫的是self.z
是激活之前的線性輸出,但由於某種原因使用它來計算你稱之為dz
激活衍生物。 它應該使用激活值。 然后,假設您計算了該值(我稱之為prime
不與我的其他dz
混合),試試這個:
dz = dy * prime
dW = np.dot(dz, self.z.T)
db = np.sum(dz, axis=1, keepdims=True)
d = np.dot(self.W.T, dz)
一對錯誤:
self.b
應該具有self.b is size (10, )
不是(128, 10)
self.b is size (10, )
(128, 10)
(因為偏差是每單位,而不是每單位對)。 self.W_grad
應該是np.dot(self.XT, (dz * dy))
,而不是np.dot(self.XT, dy)
。 對於self.b_grad
- 它應該是np.sum(dz * dy, axis=0)
至於其余的
dy := dL/dy
應為(N, 10)
,因為它包含相對於y中每個元素的損失梯度。
對於元素激活函數, dz := df(z)/d(z)
應為(N, 10)
,因為dz[i]
包含df(z[i])/dz[i]
。
self.d := dL/dX
應為(N, 128)
因為它包含相對於X中每個元素的損失梯度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.