神经网络中卷积层前向传播forward和反向传播backward计算梯度python实现

本文详细介绍了神经网络中卷积层的前向传播和反向传播过程,通过理论推导和Python代码实现,特别是探讨了在反向传播中如何计算梯度,以及如何利用这些梯度更新权重和偏置。提供了PyTorch环境下手动初始化的卷积层进行对比验证。
摘要由CSDN通过智能技术生成

1.理论推导

参考博客如下,写得很好。

https://www.cnblogs.com/pinard/p/6422831.html

https://www.cnblogs.com/pinard/p/6494810.html

关键点就在于,反向传播的过程中,得到了top的梯度后,如何反向来传。个人的理解是首先得求出top一层的误差在bottom一层关于变量的梯度DX,然后再求出bottom层的dW和dbias,即:

根据第L层的DX求出第L-1层的DX,bp的时候一直回传的是某一层的DX。而bp过程中需要更新的是W和b的值,因此在每一层中,例如根据第L层的DX分别计算在第L-1层的dW和dbias,然后用此层的两个参数的梯度更新这两个参数。而如何求取这几个梯度,上述博文和下面的python代码中都有提到,这几个计算都可以写成是卷积的操作,从而方便实现。

2.python代码

import numpy as np
import torch
import torch.nn as nn
from torch.autograd import Variable

x=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
kernel1=np.array([[3,2,1],[1,4,2],[0,1,0]])
kernel2=np.array([[1,0,2],[0,2,1],[0,3,2]])
bias1=3
b
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
反向传播算法是神经网络常用的一种训练方法,其本质是利用链式法则求导,来更新网络参数使得损失函数最小化。下面是用 Python 实现反向传播算法的基本步骤: 1. 前向传播计算损失函数,得到网络输出值。 2. 计算每个输出节点对输入的偏导数。 3. 计算每个间节点对输入的偏导数。 4. 计算每个权重对输入的偏导数。 5. 利用梯度下降法更新每个权重。 下面是一个简单的神经网络反向传播算法的 Python 代码实现: ```python import numpy as np # 1. 定义神经网络 class NeuralNetwork: def __init__(self, input_size, hidden_size, output_size): self.W1 = np.random.randn(input_size, hidden_size) / np.sqrt(input_size) self.b1 = np.zeros((1, hidden_size)) self.W2 = np.random.randn(hidden_size, output_size) / np.sqrt(hidden_size) self.b2 = np.zeros((1, output_size)) # 2. 前向传播计算损失函数 def forward(self, X): self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = np.tanh(self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 self.y_hat = np.exp(self.z2) / np.sum(np.exp(self.z2), axis=1, keepdims=True) # 3. 计算每个输出节点对输入的偏导数 def backward_output(self, X, y): self.delta3 = self.y_hat self.delta3[range(X.shape[0]), y] -= 1 # 4. 计算每个间节点对输入的偏导数 def backward_hidden(self): self.delta2 = np.dot(self.delta3, self.W2.T) * (1 - np.power(self.a1, 2)) # 5. 计算每个权重对输入的偏导数 def gradient(self, X): self.dW2 = np.dot(self.a1.T, self.delta3) self.db2 = np.sum(self.delta3, axis=0, keepdims=True) self.dW1 = np.dot(X.T, self.delta2) self.db1 = np.sum(self.delta2, axis=0) # 6. 利用梯度下降法更新每个权重 def update(self, learning_rate): self.W1 -= learning_rate * self.dW1 self.b1 -= learning_rate * self.db1 self.W2 -= learning_rate * self.dW2 self.b2 -= learning_rate * self.db2 # 测试 X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.array([0, 1, 1, 0]) nn = NeuralNetwork(2, 3, 2) for i in range(10000): nn.forward(X) nn.backward_output(X, y) nn.backward_hidden() nn.gradient(X) nn.update(0.01) print(nn.y_hat) ``` 上面的代码实现了一个简单的两层神经网络,并且用反向传播算法训练了一个异或门。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值