0
点赞
收藏
分享

微信扫一扫

nndl学习笔记(一)反向传播公式总结


  • ​​nndl是什么?​​
  • ​​反向传播算法简介​​
  • ​​定义&公式​​
  • ​​基本思想​​
  • ​​Back Propagation四个基本方程​​
  • ​​算法表示​​
  • ​​Python实现​​

nndl是什么?

《神经网络与深度学习》(《Neural Network and Deep Learning》)是机器学习大神

​​Michael Nielsen​​​介绍神经网络入门的一本教材,英文地址:​​http://neuralnetworksanddeeplearning.com/​​​在此感谢译者​​Xiaohu Zhu​​​和​​Freeman Zhang​​​。有对机器学习和神经网络有关内容感兴趣的读者,点​​这里​​获取相关资源。

P.S.: 本文仅对该书第二章进行总结,其中的描述会不全面,想详细了解请点击链接下载学习。

nndl学习笔记(一)反向传播公式总结_权重

反向传播算法简介

反向传播算法(Backpropagation Algorithm),最初在二十世纪70年代被提出,但真正得到重视是在1986年。反向传播被应用于计算损失函数(代价函数)的梯度,具有稳定、速度快等特点。

定义&公式

权重(Weight) 代表从层的第 个神经元到 层的第 个神经元的连接上的权重(注意 代表的意义从位置上看是反过来的,这样做是为了方便矩阵乘积直接计算而不用进行转置操作,一开始不太好理解;还有上面的层数 指的是到达层的位置,故前一层 需要减去 )。

偏置(Bias) 表示在第 层第

带权输入 :中间变量,表示层第个神经元的带权输入,即:

误差(Error) 中间量,表示层第个神经元上的误差。

Hadamard 乘积 矩阵或向量的对应元素相乘,即

激活函数(Activation Function) Sigmoid函数 其导数可表示为:

激活值(Activation) 表示第 层第 个神经元的激活值,由激活函数定义可记为:

层的第 个神经元的激活值 层的激活值之间的联系:

二次代价函数(Cost Function) :

基本思想

反向传播的目标是计算代价函数分别关于权重和偏置的偏导

  • 第一个假设:代价函数可以被写成一个在每个训练样本上的代价函数的均值。其原因是反向传播实际上是对一个独立的训练样本计算,然后我们通过在所有训练样本上进行平均化获得
  • 第二个假设:代价函数可以写成神经网络输出的函数,例如:

Back Propagation四个基本方程

  1. 输出层的误差(注意输出层使用大写L记号) 矩阵表示:
  2. 使用下一层的误差 来表示当前层的误差

  1. 代价函数关于网络中任意偏置的改变率
  2. 代价函数关于任何一个权重的改变率 矩阵形式:

算法表示

  1. 输入:为输入层设置激活值
  2. 前向传播:对每个计算相应的
  3. 输出层误差:计算向量
  4. 反向传播误差:对每一个计算
  5. 输出:代价函数的梯度

Python实现

仅反向传播部分的代码,完整代码请见该书第二章。

import numpy as np

def sigmoid(z):
return 1. / (1. + np.exp(-z))
def sigmoid_prime(z):
return sigmoid(z) * (1 - sigmoid(z))

class Network(object):
"""
省略其余方法的实现
"""
def backprop(self, x, y):
# 初始化权重向量和偏置向量,一般为零矩阵
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]

# 初始化激活值以及z向量(神经元的值z组成的向量)
activation = x
activations = [x]
z_vectors = []

# 开始循环计算z向量及激活向量
for b, w in zip(self.biases, self.weights):
z = np.dot(w, activation) + b
z_vectors.append(z)
activation = sigmoid(z)
activations.append(activation)

# 开始计算输出层的误差,应用第一个方程
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(z_vectors[-1])
nabla_b[-1] = delta
nabla_w[-1] = np.dot(delta, activations[-2].T)

# 开始向前计算误差并存入梯度b及梯度w,应用第二个方程
for l in range(2, self.num_layers):
z = z_vectors[-l]
delta = np.dot(self.weights[-l + 1].T, delta) * sigmoid_prime(z)
nabla_b[-l] = delta
nabla_w[-l] = np.dot(delta, activations[-l-1].T)
return nabla_b, nabla_w

def cost_derivative(self, output_activations, y):
# 定义代价函数的导数(梯度),本例中使用二次代价函数,故其导数为(输出层激活向量-y)
return output_activations -


举报

相关推荐

0 条评论