深度学习入门(基于python实现)--第五章 误差反向传播 02

tech2022-09-26  62

# _*_ coding:UTF-8 _*_ # 文件名:Error_BackPropagation_02.py # 开发工具:PyCharm import numpy as np """ 在01中讲到了计算节点的反向传播的计算方式,下面来说说激活函数节点的反向传播计算方式 对于ReLU函数(x大于0时输出x,小于0时输出0),我们对其求导数可以很容易得到当大于0时导数值为1,小于等于0时导数值为0 所以当上游传过来导数时,若这个节点正向传播时的x大于0,那么导数原封不动向下游传过去,反之为0 x大于0 x小于0 x-------》 -------》y x-------》 -------》0 relu relu d《------ 《------ 导数值d 0《------ 《------ 导数值d """ class Relu: """Relu的反向传播和正向传播实现""" def __init__(self): self.mask = None def forward(self, x): self.mask = (x <= 0) # 小于0的地方会变True,大于0的地方会变False out = x.copy() out[self.mask] = 0 # True的地方会变0,也就是小于0的地方会变0 return out def backward(self, dout): dout[self.mask] = 0 # 将原来小于0的节点的传来导数值变为0,其他的不变 dx = dout return dx """ sigmoid函数的反向传播 x-------》 -------》y sigmoid d*y*(1-y)《------ 《------ 导数值d """ def sigmoid(x): return 1 / (1 + np.exp(-x)) class Sigmoid: def __init__(self): self.out = None def forward(self, x): out = sigmoid(x) self.out = out return out def backward(self, dout): dx = dout * (1.0 - self.out) * self.out return dx """ Affine层实现反向传播 对于矩阵乘法顺便加上偏置的节点 """ class Affine: def __init__(self, W, b): """ 初始化矩阵 :param W: 权值 :param b: 偏置 """ self.W = W self.b = b self.x = None self.dW = None self.db = None def forward(self, x): """ 前项传播 :param x: 输入,矩阵 :return: 矩阵乘法和偏置相加后结果 """ x = x.reshape(x.shape[0], -1) self.x = x out = np.dot(self.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 """ 实现soft-with-loss层 """ def softmax(x): x = x - np.max(x, axis=-1, keepdims=True) return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True) def cross_entropy_error(y, t): if y.ndim == 1: t = t.reshape(1, t.size) y = y.reshape(1, y.size) # 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換 if t.size == y.size: t = t.argmax(axis=1) batch_size = y.shape[0] return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size 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] if self.t.size == self.y.size: dx = (self.y - self.t) / batch_size else: dx = self.y.copy() dx[np.arange(batch_size), self.t] -= 1 dx = dx / batch_size return dx
最新回复(0)