赞
踩
卷积神经网络(Convolutional Neural Networks,CNN)是深度学习中一种非常重要的神经网络结构,它在图像识别、图像分类、目标检测等领域取得了巨大成功。本文将介绍卷积神经网络的几个基础模块,包括批归一化、全局平均池化、瓶颈结构和沙漏结构。我们将首先对这些基础模块进行概述,然后介绍其概念及公式,并通过Python实现示例代码进行可视化展示。
批归一化是一种用于神经网络中的技术,旨在减少训练过程中的内部协变量偏移,并且可以作为一个正则化项来降低网络的过拟合程度。通过对每个小批量输入进行归一化,使得网络的输入更加稳定,加快收敛速度,同时提高网络的泛化能力。
全局平均池化是一种用于卷积神经网络中的池化操作,与传统的最大池化或平均池化不同,全局平均池化将输入特征图的每个通道进行平均,得到一个数值作为该通道的输出,从而降低了特征图的维度,减少了参数数量。
瓶颈结构是一种用于深度残差网络(Residual Networks,ResNet)中的设计,通过采用三层卷积的结构,先减少维度再增加维度,有效地降低了网络的计算量和参数数量,提高了网络的性能和效率。
沙漏结构是一种用于人体姿态估计等任务中的网络结构,采用了递归的编码-解码结构,旨在提高网络的特征提取能力和重建精度,同时减少了网络的参数数量和计算量。
批归一化的计算公式如下:
BN ( x ) = x − μ σ 2 + ϵ ∗ γ + β \text{BN}(x) = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} * \gamma + \beta BN(x)=σ2+ϵ x−μ∗γ+β
其中 x x x 是输入特征, μ \mu μ是输入特征的均值, σ \sigma σ 是输入特征的标准差, γ \gamma γ和 β \beta β是可学习的参数, ϵ \epsilon ϵ 是一个很小的数,用于防止分母为零。
全局平均池化的计算公式如下:
GAP ( x ) = 1 H × W ∑ i = 1 H ∑ j = 1 W x i , j \text{GAP}(x) = \frac{1}{H \times W} \sum_{i=1}^{H} \sum_{j=1}^{W} x_{i,j} GAP(x)=H×W1i=1∑Hj=1∑Wxi,j
其中 H H H 和 W W W分别是输入特征图的高度和宽度。
瓶颈结构的计算公式如下:
y = F 3 ( F 2 ( F 1 ( x ) ) ) y = F_3(F_2(F_1(x))) y=F3(F2(F1(x)))
其中 F 1 F_1 F1、 F 2 F_2 F2和 F 3 F_3 F3 分别表示三个卷积层,(x) 是输入特征。
沙漏结构的计算公式如下:
y = F 2 ( F 1 ( x ) ) + x y = F_2(F_1(x)) + x y=F2(F1(x))+x
其中 (F_1) 和 (F_2) 分别表示编码和解码部分的卷积层,(x) 是输入特征。
. 用Python实现示例代码(结果可视化)
import torch import torch.nn as nn import torch.nn.functional as F class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_planes, planes, stride=1): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.shortcut = nn.Sequential() if stride != 1 or in_planes != self.expansion*planes: self.shortcut = nn.Sequential( nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(self.expansion*planes) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x) out = F.relu(out) return out class Bottleneck(nn.Module): expansion = 4 def __init__(self, in_planes, planes, stride=1): super(Bottleneck, self).__init__() self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.conv3 = nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False) self.bn3 = nn.BatchNorm2d(self.expansion*planes) self.shortcut = nn.Sequential() if stride != 1 or in_planes != self.expansion*planes: self.shortcut = nn.Sequential( nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(self.expansion*planes) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = F.relu(self.bn2(self.conv2(out))) out = self.bn3(self.conv3(out)) out += self.shortcut(x) out = F.relu(out) return out class GlobalAveragePooling(nn.Module): def __init__(self): super(GlobalAveragePooling, self).__init__() def forward(self, x): return F.avg_pool2d(x, x.size()[2:]).view(x.size(0), -1) class ResNet(nn.Module): def __init__(self, block, num_blocks, num_classes=10): super(ResNet, self).__init__() self.in_planes = 64 self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(64) self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1) self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2) self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2) self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2) self.linear = nn.Linear(512*block.expansion, num_classes) def _make_layer(self, block, planes, num_blocks, stride): strides = [stride] + [1]*(num_blocks-1) layers = [] for stride in strides: layers.append(block(self.in_planes, planes, stride)) self.in_planes = planes * block.expansion return nn.Sequential(*layers) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = self.layer4(out) out = F.avg_pool2d(out, 4) out = out.view(out.size(0), -1) out = self.linear(out) return out def ResNet18(): return ResNet(BasicBlock, [2,2,2,2]) def ResNet50(): return ResNet(Bottleneck, [3,4,6,3]) # 计算网络参数量 def count_parameters(model): return sum(p.numel() for p in model.parameters() if p.requires_grad) def main(): # 创建ResNet模型 model = ResNet18() print("ResNet18:") print(model) # 计算参数量 parameters = count_parameters(model) print("Parameters:", parameters) # 计算FLOPs device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) inputs = torch.randn(1, 3, 32, 32).to(device) flops = torch.profiler.profile(model, inputs=(inputs,), use_cuda=torch.cuda.is_available()) print("FLOPs:", flops) if __name__ == "__main__": main()
本文介绍了卷积神经网络的几个基础模块,包括批归一化、全局平均池化、瓶颈结构和沙漏结构,并通过Python实现了示例代码进行了可视化展示。这些基础模块在深度学习中起着重要的作用,能够提高网络的性能和效率,为各种计算机视觉任务提供了有力的支持。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。