标准卷积的初始化和详细计算步骤,在代码中哪一步开始更新卷积核(权重)

标准卷积的初始化和详细计算步骤,在代码中哪一步开始更新卷积核(权重)

flyfish

卷积 - 感受野(Receptive Field)
在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

卷积操作转换为矩阵乘法
动画展示卷积的计算过程
卷积层的输出

卷积的计算 - numpy的实现 1
卷积的计算 - numpy的实现 2

卷积的计算 - im2col 1
卷积的计算 - im2col 2
卷积的计算 - im2col 3

卷积核的初始化

实践经验,卷积核(权重)常用的初始化方法包括:

  1. 随机初始化
    使用标准正态分布(均值为0,标准差为1)的随机数初始化权重。
    例如:nn.init.normal_(tensor, mean=0, std=1)

  2. 均匀分布初始化
    使用均匀分布的随机数初始化权重。
    例如:nn.init.uniform_(tensor, a=0, b=1)

  3. Xavier初始化(Glorot初始化)
    适用于Sigmoid和Tanh激活函数。
    公式:U[-sqrt(6 / (fan_in + fan_out)), sqrt(6 / (fan_in + fan_out))]
    例如:nn.init.xavier_uniform_(tensor)

  4. He初始化(Kaiming初始化)
    适用于ReLU激活函数。
    公式:N(0, sqrt(2 / fan_in))
    例如:nn.init.kaiming_normal_(tensor, mode='fan_in', nonlinearity='relu')

  5. 常数初始化
    使用常数值初始化权重。
    例如:nn.init.constant_(tensor, val=0)

卷积核初始化代码示例

一个简单的卷积神经网络中初始化卷积核。这里使用了Xavier初始化方法来初始化权重,并将偏置初始化为零。

import torch
import torch.nn as nn
import torch.nn.init as initclass ConvNet(nn.Module):def __init__(self):super(ConvNet, self).__init__()self.conv1 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)self.conv2 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)# Initialize weights using Xavier initializationinit.xavier_uniform_(self.conv1.weight)init.xavier_uniform_(self.conv2.weight)# Initialize biases (if using) to zeroif self.conv1.bias is not None:init.constant_(self.conv1.bias, 0)if self.conv2.bias is not None:init.constant_(self.conv2.bias, 0)def forward(self, x):x = self.conv1(x)x = self.conv2(x)return x# Instantiate the network
net = ConvNet()# Print initialized weights
print("Conv1 weights:", net.conv1.weight)
print("Conv2 weights:", net.conv2.weight)

一个完整的训练示例

import torch
import torch.nn as nn
import torch.optim as optim# 定义一个简单的卷积神经网络
import torch
import torch.nn as nn
import torch.optim as optim# 定义一个简单的卷积神经网络
class SimpleCNN(nn.Module):def __init__(self):super(SimpleCNN, self).__init__()self.conv1 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)self.conv2 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)def forward(self, x):x = self.conv1(x)x = self.conv2(x)return x# 初始化网络、损失函数和优化器
net = SimpleCNN()
criterion = nn.MSELoss()
optimizer = optim.SGD(net.parameters(), lr=0.01)# 示例输入和目标
input_tensor = torch.randn(1, 1, 5, 5)
target_tensor = torch.randn(1, 1, 1, 1)# 示例训练步骤
num_epochs = 3
for epoch in range(num_epochs):print(f'Epoch {epoch+1}/{num_epochs}',":start")optimizer.zero_grad()   # 清空梯度outputs = net(input_tensor)  # 前向传播loss = criterion(outputs, target_tensor)  # 计算损失loss.backward()  # 反向传播,计算梯度print(f'Updated before optimizer.step() conv1 weights: {net.conv1.weight}')optimizer.step()  # 使用优化器更新参数# 打印损失print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')# 打印卷积核的梯度print(f'Gradient of conv1 weights after backward: {net.conv1.weight.grad}')# 打印更新后的卷积核权重print(f'Updated after optimizer.step()conv1 weights: {net.conv1.weight}')

代码解释

对每个 epoch:
1. optimizer.zero_grad():清空之前计算的梯度。
2. outputs = net(input_tensor):前向传播,计算模型输出。
3. loss = criterion(outputs, target_tensor):计算损失。
4. loss.backward():反向传播,计算梯度,并将其存储在参数的 .grad 属性中。
5. optimizer.step():优化器根据存储的梯度和学习率更新模型的参数。

打印输出

Epoch 1/3 :start
Updated before optimizer.step() conv1 weights: Parameter containing:
tensor([[[[-0.0435, -0.0704,  0.0776],[-0.2496, -0.2133,  0.1125],[-0.0481, -0.2408,  0.1175]]]], requires_grad=True)
Epoch 1/3, Loss: 0.12892843782901764
Gradient of conv1 weights after backward: tensor([[[[ 0.0707, -0.2553, -0.1103],[ 0.3029,  0.4249,  0.3205],[-0.2261, -0.0902,  0.1702]]]])
Updated after optimizer.step()conv1 weights: Parameter containing:
tensor([[[[-0.0442, -0.0679,  0.0787],[-0.2527, -0.2175,  0.1093],[-0.0459, -0.2399,  0.1158]]]], requires_grad=True)
Epoch 2/3 :start
Updated before optimizer.step() conv1 weights: Parameter containing:
tensor([[[[-0.0442, -0.0679,  0.0787],[-0.2527, -0.2175,  0.1093],[-0.0459, -0.2399,  0.1158]]]], requires_grad=True)
Epoch 2/3, Loss: 0.11386992782354355
Gradient of conv1 weights after backward: tensor([[[[ 0.0681, -0.2368, -0.1066],[ 0.2894,  0.4049,  0.2971],[-0.2128, -0.0811,  0.1610]]]])
Updated after optimizer.step()conv1 weights: Parameter containing:
tensor([[[[-0.0449, -0.0655,  0.0797],[-0.2556, -0.2216,  0.1063],[-0.0437, -0.2391,  0.1142]]]], requires_grad=True)
Epoch 3/3 :start
Updated before optimizer.step() conv1 weights: Parameter containing:
tensor([[[[-0.0449, -0.0655,  0.0797],[-0.2556, -0.2216,  0.1063],[-0.0437, -0.2391,  0.1142]]]], requires_grad=True)
Epoch 3/3, Loss: 0.10046691447496414
Gradient of conv1 weights after backward: tensor([[[[ 0.0655, -0.2198, -0.1027],[ 0.2760,  0.3853,  0.2757],[-0.2002, -0.0729,  0.1523]]]])
Updated after optimizer.step()conv1 weights: Parameter containing:
tensor([[[[-0.0455, -0.0633,  0.0808],[-0.2583, -0.2254,  0.1036],[-0.0417, -0.2383,  0.1127]]]], requires_grad=True)

根据输出结果

Updated after optimizer.step()conv1 weights: Parameter containing:
tensor([[[[-0.0442, -0.0679,  0.0787],[-0.2527, -0.2175,  0.1093],[-0.0459, -0.2399,  0.1158]]]], requires_grad=True)
Epoch 2/3 :start
Updated before optimizer.step() conv1 weights: Parameter containing:
tensor([[[[-0.0442, -0.0679,  0.0787],[-0.2527, -0.2175,  0.1093],[-0.0459, -0.2399,  0.1158]]]], requires_grad=True)

net.conv1.weight.grad 存储了 conv1 层的权重梯度,
optimizer.step() 则真正的更新模型的参数。

更新模型参数

在卷积神经网络中,每一层都有若干卷积核。这些卷积核的权重和偏置是在训练过程中更新的。
通过反向传播算法(backpropagation),计算每个参数的梯度,并使用优化算法(如SGD、Adam等)更新这些权重和偏置,以最小化损失函数。其中特征图是通过卷积运算得到的输出,不是模型的参数。使用优化器更新参数 optimizer.step()这步更新的就是卷积核 (权重)和偏置 (如果有的话)

标准卷积操作详细计算

参数
  • 输入特征图:5x5,内容为 1 到 25

  • 卷积核:3x3,内容为 1 到 9

  • 步幅:1

  • 填充:0

输入特征图和卷积核

输入特征图

1   2   3   4   5
6   7   8   9   10
11  12  13  14  15
16  17  18  19  20
21  22  23  24  25

卷积核

1  2  3
4  5  6
7  8  9

使用 PyTorch 计算结果

import torch
import torch.nn as nn# 定义输入特征图和卷积核
input_tensor = torch.tensor([[1, 2, 3, 4, 5],[6, 7, 8, 9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20],[21, 22, 23, 24, 25]
], dtype=torch.float32).unsqueeze(0).unsqueeze(0)  # 添加批次维度和通道维度# 定义卷积核
kernel = torch.tensor([[1, 2, 3],[4, 5, 6],[7, 8, 9]
], dtype=torch.float32)# 转换卷积核为与Conv2d兼容的形状
weight = kernel.view(1, 1, 3, 3)  # 1个输出通道,1个输入通道,3x3卷积核# 定义卷积层
conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0, bias=False)# 设置卷积层的权重为我们定义的卷积核
conv.weight = nn.Parameter(weight)# 执行卷积操作
output_tensor = conv(input_tensor)# 打印输出特征图
print(output_tensor)

运行结果应该如下:

tensor([[[[411., 456., 501.],[636., 681., 726.],[861., 906., 951.]]]], grad_fn=<ConvolutionBackward0>)

计算输出特征图尺寸

根据公式:
H out = ⌊ H in + 2 P − K S ⌋ + 1 H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P - K}{S} \right\rfloor + 1 Hout=SHin+2PK+1
W out = ⌊ W in + 2 P − K S ⌋ + 1 W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2P - K}{S} \right\rfloor + 1 Wout=SWin+2PK+1由于步幅 S = 1 S=1 S=1,填充 P = 0 P=0 P=0,卷积核大小 K = 3 K=3 K=3,输入特征图大小 5 × 5 5 \times 5 5×5
H out = ⌊ 5 + 0 − 3 1 ⌋ + 1 = 3 H_{\text{out}} = \left\lfloor \frac{5 + 0 - 3}{1} \right\rfloor + 1 = 3 Hout=15+03+1=3
W out = ⌊ 5 + 0 − 3 1 ⌋ + 1 = 3 W_{\text{out}} = \left\lfloor \frac{5 + 0 - 3}{1} \right\rfloor + 1 = 3 Wout=15+03+1=3
所以输出特征图的尺寸是 3x3。

详细逐位置计算输出特征图

第一位置(左上角,起始点 (0,0))
输入区域:
1   2   3
6   7   8
11  12  13卷积计算:
1*1 + 2*2 + 3*3 + 6*4 + 7*5 + 8*6 + 11*7 + 12*8 + 13*9
= 1 + 4 + 9 + 24 + 35 + 48 + 77 + 96 + 117 = 411
第二位置(水平移动一格,起始点 (0,1))
输入区域:
2   3   4
7   8   9
12  13  14卷积计算:
2*1 + 3*2 + 4*3 + 7*4 + 8*5 + 9*6 + 12*7 + 13*8 + 14*9
= 2 + 6 + 12 + 28 + 40 + 54 + 84 + 104 + 126 = 456
第三位置(水平移动一格,起始点 (0,2))
输入区域:
3   4   5
8   9   10
13  14  15卷积计算:
3*1 + 4*2 + 5*3 + 8*4 + 9*5 + 10*6 + 13*7 + 14*8 + 15*9
= 3 + 8 + 15 + 32 + 45 + 60 + 91 + 112 + 135 = 501
第四位置(垂直移动一格,起始点 (1,0))
输入区域:
6   7   8
11  12  13
16  17  18卷积计算:
6*1 + 7*2 + 8*3 + 11*4 + 12*5 + 13*6 + 16*7 + 17*8 + 18*9
= 6 + 14 + 24 + 44 + 60 + 78 + 112 + 136 + 162 = 636
第五位置(水平移动一格,起始点 (1,1))
输入区域:
7   8   9
12  13  14
17  18  19卷积计算:
7*1 + 8*2 + 9*3 + 12*4 + 13*5 + 14*6 + 17*7 + 18*8 + 19*9
= 7 + 16 + 27 + 48 + 65 + 84 + 119 + 144 + 171 = 681
第六位置(水平移动一格,起始点 (1,2))
输入区域:
8   9   10
13  14  15
18  19  20卷积计算:
8*1 + 9*2 + 10*3 + 13*4 + 14*5 + 15*6 + 18*7 + 19*8 + 20*9
= 8 + 18 + 30 + 52 + 70 + 90 + 126 + 152 + 180 = 726
第七位置(垂直移动一格,起始点 (2,0))
输入区域:
11  12  13
16  17  18
21  22  23卷积计算:
11*1 + 12*2 + 13*3 + 16*4 + 17*5 + 18*6 + 21*7 + 22*8 + 23*9
= 11 + 24 + 39 + 64 + 85 + 108 + 147 + 176 + 207 = 861
第八位置(水平移动一格,起始点 (2,1))
输入区域:
12  13  14
17  18  19
22  23  24卷积计算:
12*1 + 13*2 + 14*3 + 17*4 + 18*5 + 19*6 + 22*7 + 23*8 + 24*9
= 12 + 26 + 42 + 68 + 90 + 114 + 154 + 184 + 216 = 906
第九位置(水平移动一格,起始点 (2,2))
输入区域:
13  14  15
18  19  20
23  24  25卷积计算:
13*1 + 14*2 + 15*3 + 18*4 + 19*5 + 20*6 + 23*7 + 24*8 + 25*9
= 13 + 28 + 45 + 72 + 95 + 120 + 161 + 192 + 225 = 951

最终输出特征图

通过上述计算步骤,我们得到输出特征图为:

411  456  501
636  681  726
861  906  951

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

互联网盲盒小程序的市场发展前景如何?

近几年来&#xff0c;盲盒成为了大众热衷的消费市场。盲盒是一个具有随机性和惊喜感&#xff0c;它能够激发消费者的好奇心&#xff0c;在拆盲盒的过程中给消费者带来巨大的愉悦感&#xff0c;在各种的吸引力下&#xff0c;消费者也愿意为各类盲盒买单。如今&#xff0c;随着盲…

VSCode里python代码不扩展/级联了的解决办法

如图 解决办法&#xff1a;重新下载新的扩展工具 步骤如下 1、在左边工具栏打开Extensions 2、搜索框输入python&#xff0c;选择别的扩展工具&#xff0c;点击Install - 3在扩展工具所在的目录下&#xff0c;新建一个文件&#xff0c;就可以用了

iis部署前后端分离项目(React前端,Node.js后端)

iis虽然已经有点过时&#xff0c;但不少用户还在用&#xff0c;故总结一下。 1. 安装iis 如果电脑没有自带iis管理器&#xff0c;打开控制面板->程序->启用或关闭Windows功能&#xff0c;勾选iis安装即可 2. 部署前端项目 打开iis&#xff0c;添加网站&#xff0c;物理…

Docker加速器配置指南:提升镜像下载速度的秘诀 加速安装Mysql Redis ES

在安装 Docker 镜像时&#xff0c;由于官方镜像下载速度较慢&#xff0c;我们可以使用阿里云的镜像加速器来提升下载速度。 使用阿里云镜像加速器 首先&#xff0c;找到并配置阿里云的镜像加速器。安装教程如下&#xff1a; 登录阿里云&#xff0c;进入容器镜像服务。直达链…

05 docker 镜像

目录 1. 镜像 2. 联合文件系统 3. docker镜像加载原理 4. 镜像分层 镜像分层的优势 5. 容器层 1. 镜像 镜像是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖打包好行程一个可交付的运行环境&#xf…

AMEYA360代理:海凌科60G客流量统计雷达模块 4T4R出入口绊数计数

数字化时代&#xff0c;不管是大型商城还是各种连锁店&#xff0c;客流统计分析都可以帮助企业更加精准地了解顾客需求和消费行为。 海凌科推出一款专用于客流量统计的60G雷达模块&#xff0c;4T4R&#xff0c;可以实时进行固定范围内的人体运动轨迹检测&#xff0c;根据人体的…

聊一聊领域驱动和贫血

写在前面 前段时间跟领导讨论技术债概念时不可避免地提到了代码的质量&#xff0c;而影响代码质量的因素向来都不是单一的&#xff0c;诸如项目因素、管理因素、技术选型、人员素质等等&#xff0c;因为是技术债务&#xff0c;自然就从技术角度来分析&#xff0c;单纯从技术角…

亚马逊跟卖僵尸选品采集,批量多站点,多关键词同时采集获取!

今天给卖家分享下亚马逊跟卖选择僵尸链接&#xff0c;现在很多卖家&#xff0c;找僵尸链接是不是都是通过亚马逊前端页面找或者是通过搜索&#xff0c;这样不但费时费力&#xff0c;还找不出几个僵尸链接&#xff0c;而且就算是找到了&#xff0c;也需要各种检查&#xff0c;非…

Electron、Win11静默打印与PowerShell:技术融合与应用探索

Electron、Win11静默打印与PowerShell&#xff1a;技术融合与应用探索 在现代软件开发与办公环境中&#xff0c;技术的融合与创新不断推动着工作效率的提升和用户体验的优化。本文将深入探讨Electron框架、Windows 11&#xff08;Win11&#xff09;静默打印技术以及PowerShell…

java版本工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统

工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的…

【操作系统期末速成】 EP03 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点五&#xff1a;进程的概念及特征2.1 考点六&#xff1a;进程的状态与切换 一、前言&#x1f680;&#x1f680;&#x1f680; ☀️ 回报不在行动之后&#xff0c;回报在行动…

linux内核编译流程、驱动加载顺序

内核编译 根据顶层Makefile找到vmlinux目标开始分析&#xff1a; vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE$(call if_changed,link-vmlinux)vmlinux-deps : $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) 根据这个展开 …

GCN结合Transformer炸场!性能暴涨74%,效率翻3倍

最近发现了两篇效果很妙的GCN结合Transformer的最新工作&#xff0c;分享给大家&#xff1a; MP-GT&#xff1a;通过结合GCN和Transformer方法来增强App使用预测的准确性&#xff0c;实现了74.02%的性能提升&#xff0c;且训练时间减少了79.47%。 MotionAGFormer&#xff1a;结…

MySQL 图形化界面

填完信息之后&#xff0c;圆圈处可以验证是否可以连接数据库 展示所有数据库&#xff08;因为有的可能连上&#xff0c;却没有数据库显示&#xff09;

“小红书、B站崩了”,背后的阿里云怎么了?

导语&#xff1a;阿里云不能承受之重 文 | 魏强 7月2日&#xff0c;“小红书崩了”、“B站崩了”等话题登上了热搜。 据第一财经、财联社等报道&#xff0c;7月2日&#xff0c;用户在B站App无法使用浏览历史关注等内容&#xff0c;消息界面、更新界面、客服界面均不可用&…

【python】PyQt5事件机制、定时器原理分析和实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

2025秋招NLP算法面试真题(十四)-RoBERTa-Bert的改进

RoBERTa:更大更多更强 今天分享一个Bert的改进工作RoBERTa。RoBERTa是训练充分的Bert。 主要掌握以下几点,与Bert相比较,RoBERTa预训练的时候: 动态掩码:comparable or slightly better去掉NSP任务并且更改数据输入格式为全部填充可以跨越多个文档更多数据,更大bsz,更…

《浔川AI社 AI 产品上线公告》——浔川总社(浔川周报第一期 24.7.2pm)

《浔川 Python 社 AI 产品上线公告》 尊敬的用户&#xff1a; 您好&#xff01; 我们非常高兴地向您宣布&#xff0c;浔川 AI 社经过不懈的努力和创新&#xff0c;现已成功上线 3 款令人瞩目的 AI 产品&#xff01; 这 3 款 AI 产品分别是&#xff1a; 浔川AI翻译v3.0&#xff…

Qt时间日期处理与定时器使用总结

一、日期时间数据 1.QTime 用于存储和操作时间数据的类&#xff0c;其中包括小时(h)、分钟(m)、秒(s)、毫秒(ms)。函数定义如下&#xff1a; //注&#xff1a;秒(s)和毫秒(ms)有默认值0 QTime::QTime(int h, int m, int s 0, int ms 0) 若无须初始化时间数据&#xff0c;可…

redis 消息订阅命令

在 Redis 中&#xff0c;消息订阅和发布是一种用于实现消息传递的机制。主要命令包括 SUBSCRIBE、UNSUBSCRIBE、PUBLISH 和 PSUBSCRIBE 等。下面是如何使用这些命令的详细说明和示例。 1. SUBSCRIBE 命令 SUBSCRIBE 命令用于订阅一个或多个频道&#xff0c;以接收这些频道发布…