美文网首页
误差的反向传播

误差的反向传播

作者: 0xFFFFFG | 来源:发表于2019-06-19 12:32 被阅读0次

计算图

用计算图求解

  • eg.1 太郎在超市买了2个100日元/个的苹果,消费税10%,计算支付金额的过程可以表示成


    太郎买苹果

    也可以表示成如下形式


    太郎买苹果2
  • eg.2 太郎买了2个100日元/个的苹果和3个150日元/个的橘子,消费税10%,计算支付金额的过程


    太郎买苹果和橘子

    图中新增了加法节点,构建计算图后从左向右进行计算,到达最后一个节点后计算结束

  • 综上,用计算图解题时需要按照如下流程
    1. 构建计算图
    2. 在计算图上自左向右进行计算

这里"自左向右进行计算"叫做正向传播,从计算图的出发点到结束点的传播.
如果从图中自右向左看的方式叫做"反向传播",反向传播可以用于导数计算

局部计算

"局部"表示与自己相关的范围,无论全局其他地方发生了什么,局部计算只能根据和自己相关的信息输出接下来的结果.
eg.3 太郎买了2个苹果很其他很多东西


太郎买了2个苹果很其他很多东西

这里各个节点的计算都是局部计算,意味着图中(1)处只需要关心4000和200的求和运算,至于4000是怎么来的不需要关心.所以计算图可以集中精力于局部计算,也意味着可以将其他部分的运算结果作为整体缓存起来.这里我们设苹果的单价为x,支付金额为L,偏导数\frac{\partial L}{\partial x}可以通过反向传播求解

反向传播计算支付金额对苹果单价的偏导数

结果是2.2

链式法则

计算图的反向传播

假设存在函数y = f(x)

计算图的反向传播
将这个局部导数乘以上游传过来的值(E),然后传给前面的节点

链式法则的定义

复合函数:z = (x+y)^2可以认为由多个函数构成的函数
z = t^2 \\ t = (x+y)
复合函数求导法则:
\frac{\partial z}{\partial x} = \frac{\partial z}{\partial t}\frac{\partial z}{\partial x}
现在我们将这个函数用计算图表示

复合函数的计算图表示


由于,可知

反向传播

加法节点的反向传播

对于z=x+y,\frac{\partial z}{\partial x}=1,\frac{\partial z}{\partial y}=1,即加法节点的反向传播只乘以1,输入值会原封不到地(反向)传给下一个节点

加法节点的反向传播
一个具体的例子,如果某次计算图一个加法节点的正向传播如左,从上游两个节点分别传来10和15正向传播传递15给下游;反向传播如右,上游传来1.3,则改节点将1.3和1.3传给下游2个节点
加法节点正反向传播的具体例子

乘法节点的反向传播

这里我们考虑z=xy,导数如下\frac{\partial z}{\partial x}=y\qquad \frac{\partial z}{\partial y}=x

乘法节点的反向传播
乘法节点反向传播的具体例子
乘法节点进行反向传播计算时需要传入正向传播时的输入信号值

指数函数和对数函数的反向传播

指数函数
f(x) =e^x ;\qquad \frac{\partial f}{\partial x} = e^x
对数函数
f(x)=ln(x); \qquad \frac{\partial f}{\partial x} =x^{-1}

指数和对数函数反向传播

反向传播计算苹果的例子

反向传播计算苹果的例子

如上可知,对于总支付金额L,苹果价格的偏导是2.2,苹果个数的偏导是110,消费税的偏导是200
对于苹果和橘子的例子,正向传播和反向传播的流程如下


苹果和橘子的正向传播和反向传播

简单层的实现

class MultiLayer:
    def __init__(self):
        self.x = None
        self.y = None

    def forward(self, x, y):
        self.x = x
        self.y = y
        return x * y

    def backward(self, dout):
        dx = dout * self.y
        dy = dout * self.x
        return dx, dy

class AddLayer:
    def __init__(self):
        self.x = None
        self.y = None

    def forward(self, x, y):
        self.x = x
        self.y = y
        return x + y

    def backward(self, dout):
        dx = dout
        dy = dout
        return dx, dy

激活函数层的实现

ReLU

ReLU函数反向传播示意图
class Relu:
    def __init__(self):
        self.x = None
        self.mask = None

    def forward(self, x):
        self.mask = (x <= 0)
        return x * (1 - self.mask)

    def backward(self, dout):
        return dout * (1 - self.mask)

sigmoid函数

y=sig(x)=(1+e^{-x})^{-1} \\ \frac{\partial y}{\partial x} = e^x(1+e^x)^{-2} \\ 也可以写成\quad \frac{\partial y}{\partial x}= y(1-y)\\ 或者\quad \frac{\partial y}{\partial x}= y^2e^{-x}\\

sigmoid函数的反向传递
实现:
class Sigmoid:
    def __init__(self):
        self.y = None

    def forward(self, x):
        y = (1 + np.exp(-x)) ** (-1)
        self.y = y
        return y

    def backward(self, d_out):
        dx = d_out * (1. - self.y) * self.y
        return dx

Affine层的实现

矩阵仿射变换
Y = W·X + B \\ X(n,);W(n,o);B(o,);Y(o,)
的计算图如下(假设n=2,o=3)

矩阵的反射变换
偏导如下:

带反向传播的计算图
带反向传播的计算图

batch版本的仿射变换

batch版本的仿射变换
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
        return X.dot(self.W) + self.b

    def backward(self, d_out):
        dx = d_out.dot(self.W.T)
        dW = self.X.T.dot(d_out)
        db = np.sum(d_out, axis=0)
        self.dW = dW
        self.db = db
        return dx

softmax-with-loss

一个典型的2层神经网络结构如下


典型的2层神经网络

softmax和entropy层的正向和反向传播结构如下


softmax和entropy层结构
代码实现:
class SoftmaxWithLoss:

    def _softmax(x):
        if x.ndim == 2:
            x = x.T
            x = x - np.max(x, axis=0)
            y = np.exp(x) / np.sum(np.exp(x), axis=0)
            return y.T

        x = x - np.max(x)  # 溢出对策
        return np.exp(x) / np.sum(np.exp(x))

    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

    def __init__(self):
        self.loss = None
        self.y = None
        self.t = None

    def forward(self,x,t):
        self.t = t
        self.y = self._softmax(x)
        self.loss = self._cross_entropy_error(self.y,self.t)

    def backward(self,dout=1):
        batch_size = self.t.shape[0]
        dx = (self.y - self.t) / batch_size
       
## 反向传播实现二层神经网络






相关文章

  • 神经网络

    神经网络的正向&&反向传播 通过正向传播后得到的误差来进行反向传播,反向传播时通过求导的方式更新权值,获得误差更小...

  • 深度学习基础--反向传播

    Model 前向传播 反向传播 求误差 求对J的影响 求对J的影响 误差反传 参考: 深度学习 — 反向传播(BP...

  • 神经网络之反向传播算法(BP)详细公式推导

    反向传播算法详细推导 反向传播(英语:Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种...

  • xxx

    误差反向传播法 各个层的实现

  • 误差的反向传播

    计算图 用计算图求解 eg.1 太郎在超市买了2个100日元/个的苹果,消费税10%,计算支付金额的过程可以表示成...

  • BP算法

    BP算法:误差反向传播算法。通过比较输出值与标记值,将误差反向由输出层向输入层传播,利用梯度下降算法进行参数调整。...

  • 反向传播梯度求解推导

    1. 引入 反向传播是一场以误差(Error)为主导的反向传播(Back Propagation)运动,目的在于优...

  • 机器学习分享——反向传播算法推导

    反向传播(英语:Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种与最优化方法(如梯度下...

  • 反向传播

    反向传播(英語:Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种与最优化方法(如梯度下...

  • 梯度消失和梯度爆炸问题详解

    1.为什么使用梯度下降来优化神经网络参数? 反向传播(用于优化神网参数):根据损失函数计算的误差通过反向传播的方式...

网友评论

      本文标题:误差的反向传播

      本文链接:https://www.haomeiwen.com/subject/myyhqctx.html