误差反向传播
1、激活函数层的实现
1.1 Relu反向传播实现
代码如下:
class Relu():
def __init__(self):
self.x = None
def forward(self, x):
self.x = np.maximum(0,x)
out = self.x
return out
# dout 为上一层传过来的导数
def backward(self, dout):
dx = dout
dx[self.x <=0] =0
return dx
1.2 Sigmoid反向传播实现
代码如下:
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 * self.out *(1-self.out)
return dx
2、Affine层的实现(全连接层)
Affine层的一般形式是,其中x是层输入,w是参数,b是一个偏置量,f是一个非线性激活函数。
对于X(矩阵)的求导,可以参考如下公式,需要注意的是,X和 形状相同,W和 形状相同
代码实现如下:
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
3、Softmaxwithloss层的实现
假设网络最后一层的输出为z,经过Softmax后输出为p,真实标签为y(ont-hot编码),其中C表示有C个类别,那么损失函数为:
因为p是z经过Softmax函数计算后的输出,即p=softmax(z),其中
Loss对z的求导为:
代码实现如下:
class SoftmaxWithLoss():
def __init__(self):
self.loss = None
self.p = None
self.y = None
def forward(self,x,y):
self.y = y
self.p = softmax(x)
self.loss = cross_entropy_error(self.p,self.y)
return self.loss
def backward(self, dout= 1):
batch_size = self.y.shape[0]
dx = (self.p - self.y) / batch_size
return dx