反向传播算法的公式推导(BP算法)

  假设训练的样本集包含m个样例,因为此时对于单个样本我们将神经网络的代价函数定义为:

这里写图片描述

  其中hW,b(x)为输入数据x经过神经网络前向传播得到的输出结果,y为期望值。
  所以对于这个包含m个样本集的数据集而言,整体的代价函数应为:

这里写图片描述

  上式关于J(W,b)定义中的第一项是一个均方差项。第二项是一个权重衰减项,其目的是减小权重的幅度,防止过度拟合。nl 表示神经网络的层数。sl表示第 l 层神经元个数,不包含偏置单元。
  在实际应用当中,我们使用批量梯度下降算法按照下面的公式来对神经网络的参数(权重W和偏置b)进行优化:

这里写图片描述

  这里的 α 是学习速率,由上式可以发现问题的关键在于如何求解J(W,b)关于W和b的偏导数。这也就引出了本文所说的反向传播算法,它是计算偏导数的很有效的方法。
  我们知道整体代价函数J(W,b)跟单个样本代价函数的关系,所以可得:

这里写图片描述

  需要说明一点,第一行比第二行多出一项的原因在于权重衰减是作用于 W 而不作用于b上。
  现在把原问题转换成对下面两个式子进行偏导求解:

这里写图片描述

  因为第 l+1 层第 i 个神经元的输出 zi(l+1) 由下面的式子计算出:

这里写图片描述

  所以可以再进一步的将单个样本的代价函数J(W,b;x,y)对W求导化简为:

这里写图片描述

  同理,单个样本的代价函数J(W,b;x,y)对b求导可化简为:

这里写图片描述

  因此问题就被转化为求解每一层每一个神经元所对应的残差。定义第k个样本在第l层第i个神经元上产生的残差如下:

这里写图片描述

  所以此时权值Wij(l)的更新公式为:

这里写图片描述

  偏置bi(l)的更新公式为:

这里写图片描述

  所以现在的核心问题只剩下一个了,就是残差该如何进行求解? 对于第nl层(输出层)的第 i 个神经元,利用下式来求解其对应的残差:

这里写图片描述

  然后计算倒数第二层即第 nl −1层第 i 个神经元的残差:

这里写图片描述

  将上式中的 nl −1与 nl的关系替换为l与l+1的关系,就可以得到:

这里写图片描述

  所以单个样本代价函数的偏导数的结果为:

这里写图片描述

  最后将求解得到的偏导数带入权值W和偏置b更新公式中去得到:

这里写图片描述

  因此,概括下来反向传播算法主要包括以下几个步骤:
  (1)进行前馈传导计算,利用前向传导公式,得到L2、L3直到输出层Ln的激活值。
  (2)对输出层(第nl层),计算其残差:

这里写图片描述

  (3)对于l=nl-1,nl-2,…,2的各层,计算其对应的残差:

这里写图片描述

  (4)计算出每个神经元对应的偏导数值:

这里写图片描述

  (5)将计算得到的偏导数值带入到权重W和偏置b对应的更新公式中去:

这里写图片描述

反向传播算法(Backpropagation)是一种用于训练神经网络的常见优化算法。它通过计算损失函数相对于每个参数的梯度,并使用梯度下降来更新参数。下面我将给出反向传播算法公式推导及示例代码。 1. 反向传播算法公式推导: 首先,定义神经网络的损失函数为L,该函数是由网络输出和真实标签之间的差异计算得出。假设神经网络有多个隐藏层,每个隐藏层的参数为W和b。 1.1 前向传播: 首先,我们通过前向传播计算每一层的输出值。假设输入为x,第l层的输出为a[l],则有: a = x z[l] = W[l] * a[l-1] + b[l] a[l] = g(z[l]) 其中,g()是激活函数。 1.2 反向传播: 接下来,我们需要计算损失函数相对于每个参数的梯度,然后使用梯度下降更新参数。假设我们有L层神经网络,则有以下公式: 输出层的梯度: dz[L] = dL / da[L] * g'(z[L]) 隐藏层的梯度: dz[l] = (W[l+1]的转置 * dz[l+1]) * g'(z[l]) 参数梯度: dW[l] = dz[l] * a[l-1的转置] db[l] = dz[l] 更新参数: W[l] = W[l] - learning_rate * dW[l] b[l] = b[l] - learning_rate * db[l] 其中,dL / da[L]是损失函数对输出层输出的导数,g'()是激活函数的导数。 2. 反向传播算法示例代码: 下面是一个使用反向传播算法进行训练的示例代码: ```python # 假设网络有三个隐藏层 hidden_layers = [10, 20, 30] output_size = 2 # 初始化参数 parameters = {} layers_dims = [input_size] + hidden_layers + [output_size] L = len(layers_dims) - 1 for l in range(1, L + 1): parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) * 0.01 parameters['b' + str(l)] = np.zeros((layers_dims[l], 1)) # 前向传播 def forward_propagation(X, parameters): caches = [] A = X for l in range(1, L): Z = np.dot(parameters['W' + str(l)], A) + parameters['b' + str(l)] A = sigmoid(Z) cache = (Z, A) caches.append(cache) Z = np.dot(parameters['W' + str(L)], A) + parameters['b' + str(L)] AL = softmax(Z) cache = (Z, AL) caches.append(cache) return AL, caches # 反向传播 def backward_propagation(AL, Y, caches): grads = {} dZ = AL - Y m = AL.shape[1] grads['dW' + str(L)] = 1/m * np.dot(dZ, caches[-1][1].T) grads['db' + str(L)] = 1/m * np.sum(dZ, axis=1, keepdims=True) for l in reversed(range(1, L)): dA_prev = np.dot(parameters['W' + str(l+1)].T, dZ) dZ = dA_prev * sigmoid_derivative(caches[l-1][0]) grads['dW' + str(l)] = 1/m * np.dot(dZ, caches[l-1][1].T) grads['db' + str(l)] = 1/m * np.sum(dZ, axis=1, keepdims=True) return grads # 参数更新 def update_parameters(parameters, grads, learning_rate): for l in range(1, L+1): parameters['W' + str(l)] -= learning_rate * grads['dW' + str(l)] parameters['b' + str(l)] -= learning_rate * grads['db' + str(l)] return parameters # 训练模型 def train_model(X, Y, learning_rate, num_iterations): for i in range(num_iterations): AL, caches = forward_propagation(X, parameters) cost = compute_cost(AL, Y) grads = backward_propagation(AL, Y, caches) parameters = update_parameters(parameters, grads, learning_rate) if i % 100 == 0: print("Cost after iteration {}: {}".format(i, cost)) return parameters # 使用示例 parameters = train_model(X_train, Y_train, learning_rate=0.01, num_iterations=1000) ``` 这是一个简单的反向传播算法示例代码,其中的sigmoid()、softmax()、sigmoid_derivative()和compute_cost()函数需要根据具体情况自行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值