资讯详情

入门计算机视觉:CNN核心组件解析

📅 2026/10/24 3:47:17 | 华诺云谱 👁 阅读
入门计算机视觉:CNN核心组件解析
计算机视觉是人工智能的一个分支致力于让计算机从图像或视频中获取、分析和理解信息。其目标是模拟人类视觉系统的功能实现场景识别、物体检测、运动跟踪等任务。对于计算机视觉入门的人来说我觉得应该掌握卷积层激活函数池化层全连接层等下面人我们聊一聊他们都是什么。模型的基本结构输入层输入层比较简单这一层的主要工作就是输入图像等信息因为卷积神经网络主要处理的是图像相关的内容但是我们人眼看到的图像和计算机处理的图像是一样的么很明显是不一样的对于输入图像首先要将其转换为对应的二维矩阵这个二维矩阵就是由图像每一个像素的像素值大小组成的。我们可以看一个例子如下图所示的手写数字 “8” 的图像计算机读取后是以像素值大小组成的二维矩阵存储的图像。上图又称为灰度图像因为其每一个像素值的范围是 0~255由纯黑色到纯白色表示其颜色强弱程度。另外还有黑白图像每个像素值要么是 0表示纯黑色要么是 255表示纯白色。我们日常生活中最常见的就是 RGB 图像有三个通道分别是红色、绿色、蓝色。每个通道的每个像素值的范围也是 0~255表示其每个像素的颜色强弱。但是我们日常处理的基本都是灰度图像因为比较好操作值范围较小颜色较单一有些 RGB 图像在输入给神经网络之前也被转化为灰度图像也是为了方便计算否则三个通道的像素一起处理计算量非常大。当然随着计算机性能的高速发展现在有些神经网络也可以处理三通道的 RGB 图像。卷积层首先我们先了解一下卷积核卷积核就是一个小的权重矩阵在图像上华东用来提取图像特征的工具下面就是一些卷积核。这些是3 * 3 的卷积核其实不只是3 * 3的还有5 * 57 * 7and so on卷积神经网络就是利用卷积在图片上不断滑动扫描提取特征的神经网络每滑到一个位置就算一个值最后生成一张特征图可以看到整个过程就是一个降维的过程通过卷积核的不同移动计算可以提取图像中最有用的特征。这是一张图片经过卷积之后图区的六张特征图可能有的人觉得卷积很神奇经过卷积核的数学计算之后提取出特征图其实我也不知道想知道的可以了解一下顺便打在评论区总之在我看来卷积就是对图片特征的提取池化层首先我们先了解一下池化窗口它和卷积核不太一样它没有参数不用学习只做简单的统计它分为最大池化和平均池化这是一个最大池化将其中具有代表性的特征提取出来可以起到减小过拟合和降低维度的作用下面更加详细的分析一下最大池化就是每次取正方形中所有的最大值这个最大值相当于当前位置最具有代表性的特征平均池化就是每次取正方形中所有的平均值激活层激活层是卷积神经网络中紧跟在卷积层 / 全连接层之后的核心层它的核心作用是给网络引入非线性变换让模型能够学习复杂的特征规律而不是只能做简单的线性拟合。简单来说卷积 / 全连接做的是「线性计算」矩阵相乘、加权求和而激活层给这个线性结果套上一个非线性函数让网络能拟合图像、语音等复杂数据的非线性分布。如果不理解就可以把他堪称一个开关全连接层全连接层一般出现在卷积神经网络的最后部分在卷积层池化层提取特征之后使用简而言之他就是把前面提取出来的图像特征综合起来做最终判断。这就是一个简单的全连接层看起来很复杂其实也不太好理解全连接层的本质是y w(权重* x b(偏置过程假设第一层神经网络神经元个数3 个假设输出值123第二层神经网络神经元个数4 个假设权重第 1 个神经元权重0.10.50.9第 2 个神经元权重0.20.61.0第 3 个神经元权重0.30.71.1第 4 个神经元权重0.40.81.2假设偏置第 1 个偏置0.1第 2 个偏置0.2第 3 个偏置0.3第 4 个偏置0.4第三层神经网络神经元个数4 个假设把第 2 个神经元的值置为 0其余不变第四层神经网络神经元个数2 个假设权重第 1 个输出神经元权重0.20.40.60.8第 2 个输出神经元权重0.10.30.50.7假设偏置第 1 个偏置0.1第 2 个偏置0.2二、开始计算1. 第一层 → 第二层第 1 个神经元1×0.1 2×0.5 3×0.9 0.1 3.9第 2 个神经元1×0.2 2×0.6 3×1.0 0.2 4.6第 3 个神经元1×0.3 2×0.7 3×1.1 0.3 5.3第 4 个神经元1×0.4 2×0.8 3×1.2 0.4 6.0第二层输出3.94.65.36.02. 第二层 → 第三层按假设第 2 个神经元置为 0第三层输出3.905.36.03. 第三层 → 第四层第 1 个输出3.9×0.2 0×0.4 5.3×0.6 6.0×0.8 0.1 8.86第 2 个输出3.9×0.1 0×0.3 5.3×0.5 6.0×0.7 0.2 7.44最终结果第四层神经网络输出8.867.44输出层卷积神经网络的输出层理解起来就比较简单了只需要将全连接层得到的一维向量经过计算后得到识别值的一个概率当然这个计算可能是线性的也可能是非线性的。在深度学习中我们需要识别的结果一般都是多分类的所以每个位置都会有一个概率值代表识别为当前值的概率取最大的概率值就是最终的识别结果。卷积神经网络CNN流程图以上就是卷积神经网络CNN的基本流程然我们通过下图在回忆一遍吧相信你对卷积神经网络CNN有了一定的了解下面我们通过一些简单且经典的模型加固一下我们的认识吧经典模型LeNetLeNet模型背景LeNet由Yann LeCun等人于1998年提出是早期卷积神经网络CNN的代表性模型主要用于手写数字识别任务如MNIST数据集。其结构奠定了现代CNN的基础。LeNet模型结构输入层接收32×32像素的灰度图像原始论文针对邮政手写数字设计。卷积层C1使用6个5×5的卷积核步长为1。输出特征图尺寸28×28×632−5128。激活函数Sigmoid或Tanh原始论文使用Sigmoid。池化层S2平均池化2×2窗口步长为2。输出特征图尺寸14×14×6。卷积层C3使用16个5×5的卷积核步长为1。输出特征图尺寸10×10×16。池化层S4平均池化2×2窗口步长为2。输出特征图尺寸5×5×16。全连接层C5将5×5×16400维特征展平连接120个神经元。激活函数Sigmoid。全连接层F684个神经元用于进一步特征提取。输出层10个神经元对应0~9数字分类使用Softmax激活函数。LeNet模型特点局部感受野通过卷积核捕捉局部特征。权值共享减少参数数量提升效率。下采样池化层降低计算复杂度增强平移不变性。代码实现PyTorch示例import torch.nn as nn class LeNet(nn.Module): def __init__(self): super(LeNet, self).__init__() self.conv1 nn.Conv2d(1, 6, 5) self.pool nn.AvgPool2d(2, 2) self.conv2 nn.Conv2d(6, 16, 5) self.fc1 nn.Linear(16*5*5, 120) self.fc2 nn.Linear(120, 84) self.fc3 nn.Linear(84, 10) def forward(self, x): x self.pool(torch.sigmoid(self.conv1(x))) x self.pool(torch.sigmoid(self.conv2(x))) x x.view(-1, 16*5*5) x torch.sigmoid(self.fc1(x)) x torch.sigmoid(self.fc2(x)) x self.fc3(x) return x应用与局限性应用场景手写字符识别、简单图像分类。局限性参数量较小难以处理复杂图像如高分辨率、多类别任务。AlexNetAlexNet模型背景AlexNet是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton在2012年提出的深度卷积神经网络模型在ImageNet竞赛ILSVRC-2012中以显著优势获胜标志着深度学习在计算机视觉领域的突破性进展。AlexNet核心结构输入层处理224×224像素的RGB图像实际输入为227×227因原始论文存在笔误。卷积层共5层使用ReLU激活函数替代传统Sigmoid提升训练效率。第一层96个11×11卷积核步长4输出55×55特征图。第二层256个5×5卷积核步长1配合最大池化。池化层采用重叠最大池化3×3窗口步长2减少过拟合。全连接层3层包含4096个神经元最后一层输出1000类ImageNet分类结果。Dropout在全连接层引入0.5概率的Dropout防止过拟合。关键技术特点ReLU激活函数解决梯度消失问题加速收敛。多GPU并行模型在训练时分布在两块GPU上提升计算效率。局部响应归一化LRN增强局部特征的区分度后续研究证明效果有限。影响与后续发展AlexNet推动了深度学习在CV领域的广泛应用其架构设计理念如深度堆叠、ReLU、Dropout成为后续模型如VGG、ResNet的基础。当前虽被更高效模型取代但其历史地位不可忽视。代码示例PyTorch实现片段class AlexNet(nn.Module): def __init__(self, num_classes1000, init_weightsFalse): super(AlexNet, self).__init__() self.features nn.Sequential( # Sequential将一系列层结构打包 # 卷积核个数均采用原AlexNet的一半 nn.Conv2d(3, 48, kernel_size11, stride4, padding2), # input[3, 224, 224] output[48, 55, 55] nn.ReLU(inplaceTrue), # inplace可理解为pytorch增加计算量、降低内存使用的一种方法 nn.MaxPool2d(kernel_size3, stride2), # output[48, 27, 27] nn.Conv2d(48, 128, kernel_size5, padding2), # output[128, 27, 27] nn.ReLU(inplaceTrue), nn.MaxPool2d(kernel_size3, stride2), # output[128, 13, 13] nn.Conv2d(128, 192, kernel_size3, padding1), # output[192, 13, 13] nn.ReLU(inplaceTrue), nn.Conv2d(192, 192, kernel_size3, padding1), # output[192, 13, 13] nn.ReLU(inplaceTrue), nn.Conv2d(192, 128, kernel_size3, padding1), # output[128, 13, 13] nn.ReLU(inplaceTrue), nn.MaxPool2d(kernel_size3, stride2), # output[128, 6, 6] ) self.classifier nn.Sequential(# 全连接层 # Dropout加在两个全连接层之间 nn.Dropout(p0.5),# 神经元随机失活的比例0.5 # 展成一维的并且卷积核的个数为原AlexNet的一半 # 因此不是256*6*6而是128 * 6 * 6且FC1的卷积核大小为2048 nn.Linear(128 * 6 * 6, 2048), nn.ReLU(inplaceTrue), nn.Dropout(p0.5), # 第二个全连接层 nn.Linear(2048, 2048), nn.ReLU(inplaceTrue), # 第三个全连接层输出num_classes的数值是训练集类别的个数 # 对于花的数据集num_classes5 nn.Linear(2048, num_classes), ) # 在pytorch中其实并不需要此函数 # pytorch自动使用kaiming_normal_对卷积层和全连接层进行初始化 if init_weights:# 初始化权重函数init_weightsTrue时会执行此函数 self._initialize_weights() # 正向传播 def forward(self, x): x self.features(x) # 展平处理 pytorch的tensor排列顺序为[batch,channel,height,width] # 0维的batch不用故start_dim1也可以使用view函数展平 x torch.flatten(x, start_dim1) # 输入到分类结构中即后面的三个全连接层 x self.classifier(x) return xGoogleNetGoogleNet模型简介GoogleNet也称为Inception v1是2014年由Google团队提出的一种深度卷积神经网络架构。该模型在ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 2014竞赛中取得了优异成绩其核心创新在于Inception模块的设计显著提升了计算效率和特征提取能力。核心特点Inception模块采用多分支结构并行处理不同尺度的卷积1x1、3x3、5x5和池化操作通过拼接concatenation融合多尺度特征。1x1卷积用于降维减少计算量。网络深度与宽度共22层含池化层但参数量仅为AlexNet的1/12约500万参数通过稀疏连接和高效结构设计实现轻量化。辅助分类器在中间层添加两个辅助分类器缓解梯度消失问题增强模型训练稳定性。关键改进全局平均池化替代全连接层减少过拟合风险。高效硬件利用Inception模块通过并行计算优化GPU利用率提升训练速度。后续版本Inception v2/v3引入批量归一化Batch Normalization和卷积分解如将5x5分解为两个3x3。Inception v4结合残差连接ResNet思想进一步优化性能。代码示例class GoogLeNet(nn.Module): def __init__(self, num_classes1000, aux_logitsTrue, init_weightsFalse): super(GoogLeNet, self).__init__() self.aux_logits aux_logits self.conv1 BasicConv2d(3, 64, kernel_size7, stride2, padding3) self.maxpool1 nn.MaxPool2d(3, stride2, ceil_modeTrue) self.conv2 BasicConv2d(64, 64, kernel_size1) self.conv3 BasicConv2d(64, 192, kernel_size3, padding1) self.maxpool2 nn.MaxPool2d(3, stride2, ceil_modeTrue) self.inception3a Inception(192, 64, 96, 128, 16, 32, 32) self.inception3b Inception(256, 128, 128, 192, 32, 96, 64) self.maxpool3 nn.MaxPool2d(3, stride2, ceil_modeTrue) self.inception4a Inception(480, 192, 96, 208, 16, 48, 64) self.inception4b Inception(512, 160, 112, 224, 24, 64, 64) self.inception4c Inception(512, 128, 128, 256, 24, 64, 64) self.inception4d Inception(512, 112, 144, 288, 32, 64, 64) self.inception4e Inception(528, 256, 160, 320, 32, 128, 128) self.maxpool4 nn.MaxPool2d(3, stride2, ceil_modeTrue) self.inception5a Inception(832, 256, 160, 320, 32, 128, 128) self.inception5b Inception(832, 384, 192, 384, 48, 128, 128) if self.aux_logits: self.aux1 InceptionAux(512, num_classes) self.aux2 InceptionAux(528, num_classes) self.avgpool nn.AdaptiveAvgPool2d((1, 1)) self.dropout nn.Dropout(0.4) self.fc nn.Linear(1024, num_classes) if init_weights: self._initialize_weights() def forward(self, x): # N x 3 x 224 x 224 x self.conv1(x) # N x 64 x 112 x 112 x self.maxpool1(x) # N x 64 x 56 x 56 x self.conv2(x) # N x 64 x 56 x 56 x self.conv3(x) # N x 192 x 56 x 56 x self.maxpool2(x) # N x 192 x 28 x 28 x self.inception3a(x) # N x 256 x 28 x 28 x self.inception3b(x) # N x 480 x 28 x 28 x self.maxpool3(x) # N x 480 x 14 x 14 x self.inception4a(x) # N x 512 x 14 x 14 if self.training and self.aux_logits: # eval model lose this layer aux1 self.aux1(x) x self.inception4b(x) # N x 512 x 14 x 14 x self.inception4c(x) # N x 512 x 14 x 14 x self.inception4d(x) # N x 528 x 14 x 14 if self.training and self.aux_logits: # eval model lose this layer aux2 self.aux2(x) x self.inception4e(x) # N x 832 x 14 x 14 x self.maxpool4(x) # N x 832 x 7 x 7 x self.inception5a(x) # N x 832 x 7 x 7 x self.inception5b(x) # N x 1024 x 7 x 7 x self.avgpool(x) # N x 1024 x 1 x 1 x torch.flatten(x, 1) # N x 1024 x self.dropout(x) x self.fc(x) # N x 1000 (num_classes) if self.training and self.aux_logits: # eval model lose this layer return x, aux2, aux1 return x以上就是我要分享的全部内容如果对你有帮助的话请留下你的关注和点赞如果以上内容有问题的话可发至评论区方便大家纠正哦
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑