news 2026/8/28 4:39:11

深度学习复试项目-04:卷积神经网络前向传播模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深度学习复试项目-04:卷积神经网络前向传播模型

AlexNet模型:

网络整体结构

输入:227×227×3RGB 图像(注意论文写 224,实际有效输入 227) 一共 8 层可训练层:5 层卷积 + 3 层全连接,最后 Softmax 输出 1000 分类。

卷积配置输出尺寸
Conv1Conv 11×11,stride=4,96,无 padding55×55×96
MaxPool13×3,stride=2(重叠池化)27×27×96
Conv2Conv 5×5,padding=2,25627×27×256
MaxPool23×3,stride=2(重叠池化)13×13×256
Conv3Conv 3×3,padding=1,38413×13×384
Conv4Conv 3×3,padding=1,38413×13×384
Conv5Conv 3×3,padding=1,25613×13×256
MaxPool33×3,stride=2(重叠池化)6×6×256
维度变化说明
FC69216 → 4096ReLU + Dropout0.5
FC74096 → 4096ReLU + Dropout0.5
FC84096 →1000无 ReLU,输出 logits

AlexNet 核心创新点

  1. ReLU 激活函数:替代 Sigmoid/Tanh,解决深层梯度消失,收敛更快
  2. Dropout:全连接层随机失活,抑制过拟合
  3. LRN 局部响应归一化:侧抑制,增强泛化(后续 VGG 证明作用有限,慢慢被弃用)
  4. 重叠池化 Overlapping Pooling:池化核 3×3、步长 2,窗口重叠,降低过拟合
  5. GPU 双卡并行训练:模型拆分两块显卡,大幅加速训练
  6. 数据增强:随机裁剪、翻转、颜色扰动,扩充数据集防过拟合

模型代码

import torchvision.model as models #导入网络模型库 import torch #导入pytorch核心库,创建张量、运算都需要 import torch.nn as nn #导入神经网络模块,卷积、全连接、激活、池化都在这里 alexnet = models.alexnet #加载官方实现的AlexNet print(alexnet) calss MyAlexNet(n.Module): def _init_(self): super(MyAlexNet,self)._init_() self.relu = nn.ReLU() #定义ReLU激活函数 self.drop = nn.Dropout(0.5) #训练时每个神经元0.5概率失活,防止过拟合 #获取卷积、池化对象 self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, padding=2) #in_channels:输入特征图数量;out_channels:输出特征图数量; #kernel_size:卷积核大小;stride步长;padding:边缘补0 self.pool1 = nn.MaxPool2d(3, stride=2) #最大池化,窗口3*3,步长2 self.conv2 = nn.Conv2d(64,192,5,1,2) self.pool2 = nn.MaxPool2d(3, stride=2) self.conv3 = nn.Conv2d(192,384,3,1,1) self.conv4 = nn.Conv2d(384,256,3,1,1) self.conv5 = nn.Conv2d(256, 256, 3, 1, 1) self.pool3 = nn.MaxPool2d(3, stride=2) self.adapool = nn.AdaptiveAvgPool2d(output_size=6) #自适应平均池化,强行输出特征图大小6*6 #获取全连接对象 self.fc1 = nn.Linear(9216,4096) self.fc2 = nn.Linear(4096,4096) self.fc3 = nn.Linear(4096,1000) def forward(slef, x): #对输入张量x开始卷积 x = self.conv1(x) # 经过卷积1 x = self.relu(x) # ReLU激活 x = self.pool1(x) # 池化1 x = self.conv2(x) # 卷积2 x = self.relu(x) # 激活 x = self.pool2(x) # 池化2 x = self.conv3(x) # 卷积3 x = self.relu(x) # 激活 x = self.conv4(x) # 卷积4 x = self.relu(x) # 激活 x = self.conv5(x) # 卷积5 x = self.relu(x) # 激活 x = self.pool3(x) # 池化3 x = self.adapool(x) # 自适应池化,强制变成6×6 x = x.view(x.size()[0], -1)#x.view展平,保留batch维度,其余全部拉成一维 #对输入张量x开始连接 x = self.fc1(x) # 第一层全连接 x = self.relu(x) # 激活 x = self.fc2(x) # 第二层全连接 x = self.relu(x) # 激活 x = self.fc3(x) # 分类输出,后面不用relu retuen x myalexnet = MyAlexNet() #实例化自己写的AlexNet模型对象 img = torch.zeros((4, 3, 224, 224)) #构造模拟图片张量输入 out = myalexnet(img) #将图片送入网络前向传播 print(out.size()) #输出各分类得分

VGGNet模型:

网络整体结构

输入:224×224×3RGB 图像)总可训练层:10 个卷积 + 3 个全连接 =13 层,5 个卷积 Block,5 次 MaxPool (2×2),每个 Block 里面都是2 个 3×3 卷积

Block卷积数量输出尺寸
Block1Conv3×3‑64 ×2112×112
Block2Conv3×3‑128 ×256×56
Block3Conv3×3‑256 ×228×28
Block4Conv3×3‑512 ×214×14
Block5Conv3×3‑512 ×27×7
输入维度输出维度操作
FC6250884096Linear → ReLU → Dropout(0.5)
FC740964096Linear → ReLU → Dropout(0.5)
FC840961000Linear,无 ReLU、无 Dropout

VGGNet 核心创新点

  1. 堆叠多个 3×3 小卷积核,替代大尺寸卷积核(5×5、7×7)相同感受野下:多层小卷积,①参数量更少;②引入更多 ReLU,增强网络非线性表达能力。
  2. 卷积统一配置:kernel=3,padding=1,stride=1padding=1 保证卷积操作前后特征图尺寸不变;仅依靠 MaxPool2d (2,2) 做下采样,尺寸减半,网络结构规整统一。
  3. 舍弃 AlexNet 的 LRN 局部响应归一化实验证明 LRN 带来提升很小,还增加计算开销,直接弃用。
  4. 多尺度训练(尺度抖动)训练时输入图像尺寸随机变化,提升模型泛化能力。
  5. 模块化分组,5 个卷积 Block,每个 Block 末尾接池化结构清晰,便于网络加深、复现。

模型代码

import torch import torchvision.models as models import torch.nn as nn vgg = models.vgg13() print(vgg) class vggLayer(nn.Module): def __init__(self,in_cha, mid_cha, out_cha): super(vggLayer, self).__init__() self.relu = nn.ReLU() self.pool = nn.MaxPool2d(2) self.conv1 = nn.Conv2d(in_cha, mid_cha, 3, 1, 1) self.conv2 = nn.Conv2d(mid_cha, out_cha, 3, 1, 1) def forward(self,x): x = self.conv1(x) x= self.relu(x) x = self.conv2(x) x = self.relu(x) x = self.pool(x) return x class MyVgg(nn.Module): def __init__(self): super(MyVgg, self).__init__() self.layer1 = vggLayer(3, 64, 64) self.layer2 = vggLayer(64, 128, 128) self.layer3 = vggLayer(128, 256, 256) self.layer4 = vggLayer(256, 512, 512) self.layer5 = vggLayer(512, 512, 512) self.adapool = nn.AdaptiveAvgPool2d(7) self.relu = nn.ReLU() self.fc1 = nn.Linear(25088, 4096) self.fc2 = nn.Linear(4096, 4096) self.fc3 = nn.Linear(4096, 1000) def forward(self,x): x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.layer5(x) x = self.adapool(x) x= self.adapool(x) x = x.view(x.size()[0], -1) x = self.fc1(x) x = self.relu(x) x = self.fc2(x) x = self.relu(x) x = self.fc3(x) x = self.relu(x) return x myVgg = MyVgg() img = torch.zeros((1, 3, 224,224)) out = myVgg(img) print(out.size())

ResNet(残差网络)模型:

网络整体结构

输入:224×224×3 RGB 图像 总可训练层:17 个卷积 + 1 个全连接 =18 层,4 组卷积 Layer,1 次 MaxPool (3×3),使用 BasicBlock 残差块

模块块配置输出尺寸
Conv1Conv7×7‑64,stride=2,padding=3,BN,ReLU112×112
MaxPoolMaxPool3×3,stride=2,padding=156×56
Layer1BasicBlock(64→64) ×256×56
Layer2BasicBlock (64→128) ×2,第一个块 stride=228×28
Layer3BasicBlock (128→256) ×2,第一个块 stride=214×14
Layer4BasicBlock (256→512) ×2,第一个块 stride=27×7
AvgPoolAdaptiveAvgPool2d (1) 全局平均池化1×1×512
输入维度输出维度操作
FC5121000Linear,无 ReLU、无 Dropout

ResNet核心创新点

  1. 残差捷径连接(Shortcut Connection)不再学习直接映射 \(H(x)\),学习残差 \(F(x)=H(x)-x\),输出 \(H(x)=F(x)+x\)。解决深度网络退化问题(网络加深训练集精度下降,不是过拟合),可以训练几十上百层深度网络。
    • 通道、尺寸一致:直接恒等映射;
    • 通道 / 尺寸不一致:用1×1 卷积 + BN做投影变换匹配维度。
  2. 批量归一化 BN (BatchNorm2d)每个卷积之后接 BN,卷积后、ReLU 前;缓解内部协变量偏移,加速收敛,有轻微正则效果。
  3. 全局平均池化 GAP(AdaptiveAvgPool2d)替代 VGG/AlexNet 的大尺度 feature map 展平,大幅降低全连接层参数量;最后只保留一层 FC。
import torch import torch.nn as nn import torchvision.models as models resNet = models.resnet18() print(resNet) class Residual_block(nn.Module): #@save def __init__(self, input_channels, out_channels, down_sample=False, strides=1): super().__init__() self.conv1 = nn.Conv2d(input_channels, out_channels, kernel_size=3, padding=1, stride=strides) self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, stride= 1) if input_channels != out_channels: self.conv3 = nn.Conv2d(input_channels, out_channels, kernel_size=1, stride=strides) else: self.conv3 = None self.bn1 = nn.BatchNorm2d(out_channels) self.bn2 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU() def forward(self, X): out = self.relu(self.bn1(self.conv1(X))) out= self.bn2(self.conv2(out)) if self.conv3: X = self.conv3(X) out += X return self.relu(out) class MyResNet18(nn.Module): def __init__(self): super(MyResNet18, self).__init__() self.conv1 = nn.Conv2d(3, 64, 7, 2, 3) self.bn1 = nn.BatchNorm2d(64) self.pool1 = nn.MaxPool2d(3, stride=2, padding=1) self.relu = nn.ReLU() self.layer1 = nn.Sequential( Residual_block(64, 64), Residual_block(64, 64) ) self.layer2 = nn.Sequential( Residual_block(64, 128, strides=2), Residual_block(128, 128) ) self.layer3 = nn.Sequential( Residual_block(128, 256, strides=2), Residual_block(256, 256) ) self.layer4 = nn.Sequential( Residual_block(256, 512, strides=2), Residual_block(512, 512) ) self.flatten = nn.Flatten() self.adv_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Linear(512, 1000) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.pool1(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.adv_pool(x) x = self.flatten(x) x = self.fc(x) return x myres = MyResNet18() x = torch.rand((1,3,224,224)) out = resNet(x) out = myres(x)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 4:38:23

深入理解C++ I/O流:从基础概念到文件操作与错误处理实战

1. 从“Hello World”到“Hello System”&#xff1a;C输入输出的本质很多朋友学C&#xff0c;都是从一行cout << "Hello World"开始的。这行代码简单直观&#xff0c;仿佛输入输出就是理所当然的事情。但当你真正开始写一个需要处理用户输入、读取配置文件、或…

作者头像 李华
网站建设 2026/8/28 4:34:38

Python 中如何实现多线程?

接口速度明明不迟缓, 单个请求只需200毫秒, 然而批量运行5000个, 居然需要十几分钟。有不少这样的代码, 是我见过很多的, 看一下打开之后, 基本上都是从开头一直怼整个流程呈现持续状态, 运用的是一个for循环操作:for user_id in user_ids: profile load_user_profile(user_id…

作者头像 李华
网站建设 2026/8/28 4:33:47

C++函数模板实战:从距离计算到泛型编程核心原理

1. 从“硬编码”到“泛型计算”&#xff1a;为什么我们需要函数模板在C编程实践中&#xff0c;计算两点间的距离是一个再常见不过的需求。无论是游戏开发中的碰撞检测、图形学中的坐标变换&#xff0c;还是数据分析中的聚类算法&#xff0c;这个基础操作无处不在。最初接触这个…

作者头像 李华
网站建设 2026/8/28 4:32:33

浏览器鼓机音序器进阶:Web Audio时钟调度与架构拆解

用浏览器做一款鼓机音序器&#xff0c;听起来像是个“玩具项目”&#xff0c;但真正做过的人会明白&#xff0c;它比大多数前端应用都要难。难的不是画界面&#xff0c;而是如何在浏览器里把声音精确到毫秒级触发&#xff0c;如何在标签页切走之后依然保持稳定节奏&#xff0c;…

作者头像 李华
网站建设 2026/8/28 4:29:56

做弱电工程,这些线材一定要认识

做弱电工程,很多人首先想到的就是网线。办公室里布网络要用网线,监控摄像机要用网线,门禁设备也可能用网线,久而久之,网线似乎成了弱电施工中最常见、也最重要的线材。 但真正进入一个完整的弱电项目之后,就会发现事情远没有这么简单。 一栋办公楼、一个学校、一个园区…

作者头像 李华
网站建设 2026/8/28 4:29:23

基于Django与Python的适老化健康预警系统:架构设计与工程实践

简介&#xff1a;在Web应用开发领域&#xff0c;Django作为一款成熟的全栈框架&#xff0c;以其“开箱即用”的特性&#xff0c;为构建数据密集型管理系统提供了高效解决方案。其核心原理在于遵循MTV模式&#xff0c;通过强大的ORM&#xff08;对象关系映射&#xff09;抽象数据…

作者头像 李华