一般性理论+反向求导程序实现(二分类均方差损失函数、二分类交叉熵损失函数)。(欢迎指正)
1.两层神经网络
1.1网络结构
1.2正向传播
1.3规律
1.4正向传播公式
1.5单样本_反向传播公式
1.6反向传播
1.7.m个样本_反向传播_代码实现
2.实例(二分类均方差损失函数):
2.1前提
- 两层神经网络;
- 第一层激活函数:tanh
- 第二层激活函数:sigmoid
- 损失函数:均方差损失函数
2.2前向传播
2.3反向求导
2.4代码实现
#前向传播较为简单,这里就略掉。
#以下为反向求导:
class MSELoss(Module):
def __call__(self, output, target):
assert(target.ndim == 2)
self.A = output
self.Y = target
self.m = target.shape[0]
return self.forward(self.A, self.Y)
def forward(self, A, Y):
self.loss = np.sum(np.square(A - Y)) / self.m
return self
def float(self):
return self.loss
def backward(self):
#第二层
dA2 = 2 * (self.A - self.Y)/self.m
dZ2 = dA2 * (self.A * (1 - self.A))
x_input = self.get_cache_input()
A1 = next(x_input)
dW2 = np.dot(dZ2.T, A1) / self.m
dB2 = np.sum(dZ2.T, axis=1,keepdims=True) #
# 第一层
params = self.parameters()
W2 = next(params).weight
dA1 = np.dot(dZ2, W2)
dZ1 = dA1 * (1 - np.square(A1))
X1 = next(x_input)
dW1 = np.dot(dZ1.T, X1) / self.m
dB1 = np.sum(dZ1.T, axis=1, keepdims=True)
return {"dW2":dW2, "dB2":dB2, "dW1":dW1, "dB1":dB1}
3.实例(二分类交叉熵损失函数)
3.1前提
- 两层神经网络;
- 第一层激活函数:tanh
- 第二层激活函数:sigmoid
- 损失函数:二分类交叉熵差损失函数
3.2前向传播
3.3反向求导
3.4代码实现
#前向传播较为简单,这里就略掉。
#以下为反向求导:
class BCELoss(Module):
def __call__(self, output, target):
self.A = output
self.Y = target
self.m = target.shape[0]
return self.forward(self.A, self.Y)
def forward(self, A, Y):
self.loss = -np.sum(Y*np.log(A) + (1 - Y) * np.log(1 - A))/ self.m
return self
def float(self):
return self.loss
def backward(self):
dA2 = (1 - self.Y) / (1 - self.A) - self.Y / self.A
dZ2 = dA2 * (self.A * (1 - self.A))
x_input = self.get_cache_input()
A1 = next(x_input)
dW2 = np.dot(dZ2.T, A1) / self.m # 一批样本的平均导数
dB2 = np.sum(dZ2.T, axis=1, keepdims=True) #
# 往前求第一层的导数
params = self.parameters()
W2 = next(params).weight
dA1 = np.dot(dZ2, W2)
# 用的是tanh激活
dZ1 = dA1 * (1 - np.square(A1))
X1 = next(x_input)
dW1 = np.dot(dZ1.T, X1) / self.m
dB1 = np.sum(dZ1.T, axis=1, keepdims=True)
return {"dW2": dW2, "dB2": dB2, "dW1": dW1, "dB1": dB1}