该博客主要用于个人学习记录,部分内容参考自:【cs231n】详解神经网络中的反向传播、CS231n笔记三:神经网络之反向传播、超详细斯坦福CS231n课程笔记(第四课)——反向传播和神经网络 反向传播是链式法则的递归调用 图中绿色的值是传入的参数值和计算图向前计算得到的值,红色值是利用计算图反向计算时得到的梯度值 对于一个节点,计算本地梯度并存储跟踪下来,在反向传播的时候接受从上游传回来的梯度值,直接用这个梯度值乘以本地梯度然后得到需要传回前一个连接点的值【local gradient × upstream gradient】,在下一个节点进行传播时,不用考虑除了直接相连的节点之外的任何东西。 在这个图中,x和y是前面的节点传入该节点的值,z是节点的输出值,进行反向传播时,从输出方向传入上游的梯度值,我们只需要将在向前传播过程中计算好的梯度值(即本地梯度)和从上游传过来的梯度值利用链式法则相乘即可得到我们想要的结果,再将这个结果传入到前面的直接相连的节点中去。 节点\(\frac{1}{x}\) 节点\(+1\) 节点\(exp\) 节点\(*\) 将上图中几个简单的节点用一个大节点替换 在反向传播过程中,当涉及多个上游节点的梯度汇聚到同一个下游节点时,需要将所有上游节点的梯度相加作为这个本地节点的总上游梯度。这可以解释为:因为在前向传播计算函数值时,这个本地节点的取值会影响与之相连的之后所有节点,因而在反向传播的过程中,之后所有节点的梯度也都会反过来影响这个本地节点的梯度取值。 假设X是2维向量,W是2*2矩阵 在此前我们已经使用了很多这种分数函数:\(f=W·x\) 计算图里的节点相互连接,我们需要输入“信号x”,所有x的输入量比如x0、x1、x2等,采用比如赋予权重W的方法,叠加汇合到一起,将结果整合起来后得到一个激活函数,将激活函数应用在神经元的端部,得到的值作为输出。 几种常用的激活函数 两层神经网络也可以叫单隐藏层网络,三层神经网络也是双隐藏层网络 神经网络可以近似任何连续函数一、反向传播backpropagation
(一)反向传播backpropagation
例子1
节点
例子2
sigmoid函数: \(\sigma(x)=\frac{1}{1+e^{-x}}\) → \(\frac{d\sigma(x) }{dx}=(1-\sigma(x))\sigma(x)\) patterns in backward flow
gradients add at branches
(二)高维矩阵反向传播
雅可比矩阵Jacobian matrix
例子
每个变量的梯度的维度应当和这个变量的维度保持一致。(三)模块化设计
前向传播和反向传播API
class ComputationalGraph(object):
#...
def forward(inputs):
# 1. pass inputs to input gates...
# 2. forward the computational graph:
for gate in self.graph.nodes_topologically_sorted():
gate.forward()
return loss # the final gate in the graph outputs the loss
def backward():
for gate in reversed(self.graph.nodes_topologically_sorted()):
gate.backward()
return inputs_gradients
以乘法门为例
class ComputationalGraph(object):
#...
def forward(x,y):
z = x * y
self.x = x
self.y = y
return z
def backward(dz):
dx = self.y * dz
dy = self.x * dz
return [dx , dy]
二、神经网络 Neural Network
现在使用一个2层的神经网络:\(f=W_2max(0,W_1x)\)
或者使用一个3层的神经网络:\(f=W_3max(0,W_2max(0,W_1x))\)