FEATURED · 精选文章

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

发布时间 / 2026/8/28 4:39:14
来源 / 创域科博编辑部
栏目 / 资讯中心
深度学习复试项目-04:卷积神经网络前向传播模型 AlexNet模型:网络整体结构输入:2272273RGB 图像(注意论文写 224,实际有效输入 227) 一共 8 层可训练层:5 层卷积 + 3 层全连接,最后 Softmax 输出 1000 分类。层卷积配置输出尺寸Conv1Conv 1111,stride=4,96,无 padding555596MaxPool133,stride=2(重叠池化)272796Conv2Conv 55,padding=2,2562727256MaxPool233,stride=2(重叠池化)1313256Conv3Conv 33,padding=1,3841313384Conv4Conv 33,padding=1,3841313384Conv5Conv 33,padding=1,2561313256MaxPool333,stride=2(重叠池化)66256层维度变化说明FC69216 4096ReLU + Dropout0.5FC74096 4096ReLU + Dropout0.5FC84096 1000无 ReLU,输出 logitsAlexNet 核心创新点ReLU 激活函数:替代 Sigmoid/Tanh,解决深层梯度消失,收敛更快Dropout:全连接层随机失活,抑制过拟合LRN 局部响应归一化:侧抑制,增强泛化(后续 VGG 证明作用有限,慢慢被弃用)重叠池化 Overlapping Pooling:池化核 33、步长 2,窗口重叠,降低过拟合GPU 双卡并行训练:模型拆分两块显卡,大幅加速训练数据增强:随机裁剪、翻转、颜色扰动,扩充数据集防过拟合模型代码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模型:网络整体结构输入:2242243RGB 图像)总可训练层:10 个卷积 + 3 个全连接 =13 层,5 个卷积 Block,5 次 MaxPool (22),每个 Block 里面都是2 个 33 卷积Block卷积数量输出尺寸Block1Conv33‑64 2112112Block2Conv33‑128 25656Block3Conv33‑256 22828Block4Conv33‑512 21414Block5Conv33‑512 277层输入维度输出维度操作FC6250884096Linear ReLU Dropout(0.5)FC740964096Linear ReLU Dropout(0.5)FC840961000Linear,无 ReLU、无 DropoutVGGNet 核心创新点堆叠多个 33 小卷积核,替代大尺寸卷积核(55、77)相同感受野下:多层小卷积,①参数量更少;②引入更多 ReLU,增强网络非线性表达能力。卷积统一配置:kernel=3,padding=1,stride=1padding=1 保证卷积操作前后特征图尺寸不变;仅依靠 MaxPool2d (2,2) 做下采样,尺寸减半,网络结构规整统一。舍弃 AlexNet 的 LRN 局部响应归一化实验证明 LRN 带来提升很小,还增加计算开销,直接弃用。多尺度训练(尺度抖动)训练时输入图像尺寸随机变化,提升模型泛化能力。模块化分组,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(残差网络)模型:网络整体结构输入:2242243 RGB 图像 总可训练层:17 个卷积 + 1 个全连接 =18 层,4 组卷积 Layer,1 次 MaxPool (33),使用 BasicBlock 残差块模块块配置输出尺寸Conv1Conv77‑64,stride=2,padding=3,BN,ReLU112112MaxPoolMaxPool33,stride=2,padding=15656Layer1BasicBlock(6464) 25656Layer2BasicBlock (64128) 2,第一个块 stride=22828Layer3BasicBlock (128256) 2,第一个块 stride=21414Layer4BasicBlock (256512) 2,第一个块 stride=277AvgPoolAdaptiveAvgPool2d (1) 全局平均池化11512层输入维度输出维度操作FC5121000Linear,无 ReLU、无 DropoutResNet核心创新点残差捷径连接(Shortcut Connection)不再学习直接映射 \(H(x)\),学习残差 \(F(x)=H(x)-x\),输出 \(H(x)=F(x)+x\)。解决深度网络退化问题(网络加深训练集精度下降,不是过拟合),可以训练几十上百层深度网络。通道、尺寸一致:直接恒等映射;通道 / 尺寸不一致:用11 卷积 + BN做投影变换匹配维度。批量归一化 BN (BatchNorm2d)每个卷积之后接 BN,卷积后、ReLU 前;缓解内部协变量偏移,加速收敛,有轻微正则效果。全局平均池化 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)
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻