全网最好的-反向传播算法理解和推导(BP)

反向传播算法理解和推导(BP)


反向传播就是梯度不断分解的过程。(如果想不通没关系,因为这个说法并不严谨)

简单理解一下

首先第一次前向传播,参数通过随机赋予或者人为设定的权重w和偏置通过前向传播一直到输出层的参数,此时输出y和标签很大可能有偏差&,那么开始考虑如何更新参数呢从小减小&呢,思考一下,既然输入层可以前向传播到输出层,反过来想,我们的目的是最小化误差&,那么如果我们找到一种方式可以使得误差在尽可能小,因为影响误差&的参数就是前面所有的w和b,以及各网络层的输出。进一步思考,我们把误差从后向前传播当然条件就是使得误差&尽可能小。这里有一个很重要的思想,就是损失函数J在各个参数各自的梯度方向上更新参数,那么J的值更新的的越快(梯度方向由向量表示,多个梯度方向的向量和即为损失函数值更新最快的方向),这里就涉及到了梯度下降法。
(如果某一个w和b对最后的判断结果产生了重大的影响,那么当这个判断结果有偏差的时候,那么这个w和b一定也是对这个偏差有重大影响的。所以希望减小偏差时,优先调整那些对偏差有重大影响的参数。反向传播传的是偏差的信息,把偏差传递到各个参数上,根据参数对偏差贡献的大小,相应的承担修改的责任)“就是说J由多个参数决定,假设有三个参数决定,那么在一个四维空间中,a,b,c共同决定了J的大小,那么我们希望J的值开始变小,那么只要a,b,c不论哪个往负梯度方向改变,那么J都会变小,如果他们同时往负梯度方向改变,那么J减小的速率是最快的。”

梯度下降法

梯度

在这里插入图片描述
在这里插入图片描述

偏导

在这里插入图片描述
在这里插入图片描述
首先构造损失函数J,如下图所示:
在这里插入图片描述
进一步简化J如下:
在这里插入图片描述
这时如果对J求梯度,它其实代表了增大最快的那个方向,负梯度方向也就是减小最快的那个方向。对其求梯度,如下图:
在这里插入图片描述
在这里插入图片描述

w我们希望J最快的减小,也即希望最后输出层a和标签y的差值最小,或者说希望a沿着负梯度方向最快走一截,但是a由w和b以及上一层的a决定,所以将a(也可以理解为J)的负梯度方向分解为w的负梯度方向,b的负梯度方向,a的负梯度方向,这样w和b就可以进行更新了,并且他两的变化的目标就是使J朝着最快的方向减小一段。而a的变化还要取决于上一层的w和b,这时可以构造新的损失函数,使得误差继续向上一层传递(这里有一种新的理解就是a的值始终由w和b决定,那么只需要朝着负梯度方向不断更新w和b,自然a的值也会不断地更新,当然a也可以理解为只是个中间值,作用就是帮助反向传播误差),当输出层的w和b更新完成后,继续开启下一轮,此时输出层的w和b暂时不发生变化,相当于已经完成它这一次更新的任务,当然a也是要求它沿着负梯度方向走一截,而它的梯度方向又可以分解为新的w,b,a,误差就这样一直方向传递,直到输入层,w和b也一直更新直到全部更新一遍。到这里所有的参数都能在梯度方向上修改一遍。
在这里插入图片描述

链式求导

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
第一步肯定是对J求梯度,
在这里插入图片描述
新建一个虚拟的l+1层,这个并不是真的有一个感知机,而是把这个分量当做是一个新的误差函数便于梯度进行分解,而这个感知机只对第一个有效。
在这里插入图片描述
在这里插入图片描述
该调整调整,该向前传播向前传播。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这,神经网络的第一层学习完成了一遍,除第一层输出外,所有系数的更新迭代完成了一遍。

反向传播算法(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、付费专栏及课程。

余额充值