ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

VggNet vs ResNet:Matlab物体分类识别对比实验与调参指南

VggNet vs ResNet:Matlab物体分类识别对比实验与调参指南 简介这是一套基于VggNet与ResNet神经网络的物体分类识别研究配套Matlab代码包适合深度学习入门者以及想在图像分类任务中快速上手经典CNN架构的开发者。代码包提供从数据加载、网络搭建到训练评估的完整流程并对两种网络的深度策略与残差连接机制做了对比分析。压缩包共60012个文件包含4个m源码脚本、3个mat预训练模型/权重、1份pdf图文说明以及60000余张用于训练或验证的png图像配套fig界面便于可视化交互整体约398.58MB。目前已有759人学习内容涵盖网络结构比较、识别准确率评估、训练优化技巧及迁移应用方向可按需加载模型直接复现。通过阅读代码和文档读者能系统掌握VggNet与ResNet的实现细节并具备将其拓展到其他视觉任务的基础能力。1. 当VggNet和ResNet出现在同一个标题里先别急着跑代码物体分类识别是卷积神经网络最成熟的应用场景可一旦把VggNet和ResNet这两条路线放到同一个实验里问题就不会只是“谁的精度更高”这么简单。VggNet靠连续小卷积核堆出16到19层的深度ResNet则用残差连接把网络做到了152层甚至更深。前者结构规整、容易复现后者收敛快、上限高但在Matlab环境下两者的差异会从模型结构一路传导到数据预处理、训练超参数和显存占用上。这篇博文把VggNet与ResNet在Matlab里做物体分类识别的完整路径讲清楚从预训练模型加载、数据准备、微调训练到对比实验设计最后落到三个常见坑的排查上。适合正在用Matlab做课程设计、竞赛或毕业设计的工程师也适合想快速验证两种架构差异的算法人员。文章里所有代码以Matlab的Deep Learning Toolbox为准不依赖第三方框架。2. VggNet与ResNet的核心差异深度、感受野与残差学习2.1 为什么VggNet堆到19层就停结构规整与参数量控制VggNet的核心设计思路是用连续的3×3卷积核替代大尺寸卷积核两个3×3堆叠等价于一个5×5的感受野三个等价于7×7但参数量更少、非线性更强。VggNet有VGG-16和VGG-19两个常用变体差别只在于后三个卷积阶段里多加了几层3×3卷积。在Matlab中加载VggNet预训练模型非常直接net vgg19; analyzeNetwork(net)vgg19函数会从MathWorks的附加功能资源管理器下载预训练权重首次运行需要网络连接。analyzeNetwork会弹出交互式网络结构图可以看到VggNet的清晰分层卷积块、ReLU、max pooling汇聚层交替出现最后接三个全连接层和softmax。VggNet的问题在于全连接层的参数量极大。前两个全连接层各有4096个神经元仅这两层就占据了模型约70%的参数。在Matlab里查看参数量分布时能看到VggNet虽然卷积层只有16层但总参数量超过1.38亿这对GPU显存和训练时间都不友好。VggNet的复制性优势在于它的架构没有分支、没有捷径任何一张特征图的前向传播路径都是唯一的这在调试、可视化和TensorBoard式的参数检查时都很方便。2.2 ResNet怎样靠残差模块让网络变深恒等映射与梯度通路ResNet的出发点是一个反直觉的观察网络越深训练误差反而越高。何恺明团队给出的解法是在每两层或三层卷积旁边加一条“捷径连接”让模块学习的是残差$F(x) H(x) - x$而不是原始映射$H(x)$。如果恒等映射是最优的网络只需把残差学成零梯度也能通过捷径回传。ResNet-50的结构由四个残差阶段组成每个阶段包含若干个Bottleneck模块。Bottleneck先用1×1卷积降维、3×3卷积提取特征、再用1×1卷积恢复维度这样既加深了网络又控制了计算量。在Matlab中加载ResNet-50net resnet50; analyzeNetwork(net)分析图里能明显看到残差分支每个Bottleneck块有一条从输入直接连到输出的曲线路径。如果对BatchNorm层和卷积层的时序敏感可以在命令行里用net.Layers查看每一层的排列顺序注意残差块内的BN层位于卷积和ReLU之间这是和VggNet的重要区别。ResNet的捷径连接有两种类型。当输入输出通道数不一致时捷径上会插入一个1×1卷积做维度匹配步长也相应调整。这种设计意味着在Matlab中修改ResNet结构时不能随意删除或添加层否则层图数据格式无法通过验证。2.3 从层图数据格式看两类网络的可修改粒度Matlab的Deep Learning Toolbox用layerGraph对象管理网络结构预训练模型的层是只读的但可以替换、移除或添加。以替换最后一层为例lgraph layerGraph(net); % 找到全连接层和分类层的名称 learnableLayer lgraph.Layers(end-2).Name; classLayer lgraph.Layers(end).Name; % 创建新的全连接层和分类层numClasses取决于分类任务 newFC fullyConnectedLayer(numClasses, Name, new_fc); newClass classificationLayer(Name, new_classoutput); % 先移除再连接 lgraph removeLayers(lgraph, {learnableLayer, classLayer}); lgraph addLayers(lgraph, {newFC, newClass}); lgraph connectLayers(lgraph, dropout, new_fc);这段代码对VggNet和ResNet都适用但有一个细节VggNet的倒数第三层是dropoutResNet-50的倒数第三层是pool5全局平均池化。在替换前先用lgraph.Layers(end-3).Name确认前一层的名称避免连接报错。这个差异直接影响feature extraction时取哪一层的输出作为特征向量。3. 用Matlab搭建物体分类识别训练管线数据流与超参设计3.1 数据准备用imageDatastore管理数据集并划分训练验证集物体分类识别的第一步是让Matlab认识数据。imageDatastore是Deep Learning Toolbox的标准数据入口它支持从文件夹自动读取子目录名作为标签支持图片尺寸不一致也支持内存不放入全部图片。imds imageDatastore(D:\classification_dataset, ... IncludeSubfolders, true, ... LabelSource, foldernames); % 统计每类样本数 countEachLabel(imds) % 按7:3划分训练集和验证集保持类别比例 [imdsTrain, imdsVal] splitEachLabel(imds, 0.7, randomized);LabelSource设为foldernames会自动把文件夹名映射为分类标签。这里有一个容易忽略的问题如果图片是灰度图而VggNet和ResNet都要求RGB三通道输入imds会自动复制灰度到三个通道但最好显式调用augmentedImageDatastore做统一缩放和通道处理避免在训练时报输入尺寸错误。3.2 数据增强与图像尺寸两个网络的输入规格VggNet和ResNet-50的输入尺寸不同。VggNet的标准输入是224×224ResNet-50同样是224×224但后者训练时用的裁剪策略是随机尺寸采样。在Matlab中augmentedImageDatastore负责在训练时实时做数据增强inputSize [224 224 3]; pixelRange [-30 30]; imageAugmenter imageDataAugmenter(... RandXTranslation, pixelRange, ... RandYTranslation, pixelRange, ... RandRotation, [-15 15], ... RandXScale, [0.9 1.1], ... RandYScale, [0.9 1.1]); augimdsTrain augmentedImageDatastore(inputSize, imdsTrain, ... DataAugmentation, imageAugmenter, ... OutputSizeMode, randcrop, OutputSize, inputSize); augimdsVal augmentedImageDatastore(inputSize, imdsVal, ... OutputSizeMode, resize, OutputSize, inputSize);OutputSizeMode设为randcrop会从原图随机裁剪到224×224适合训练集做轻微平移和尺度扰动验证集用resize直接拉伸保证验证过程确定性。实际操作中如果原图分辨率很低低于100×100随机裁剪会丢失太多信息此时应改用resize。3.3 微调训练7个影响收敛的参数设置预训练模型的特征提取层已经足够好物体分类识别通常只微调最后几层。训练前要设置trainingOptions下面这些参数按重要性排序参数推荐值说明InitialLearnRate1e-4VggNet、1e-3ResNet-50ResNet残差结构收敛更快可用更大初始学习率MiniBatchSize16内存小、32GPUVggNet的参数量大batch太大容易OOMMaxEpochs1020微调阶段不需要太多轮次防止过拟合ValidationFrequency50100每多少次迭代验证一次显存足够可设50L2Regularization1e-4权重衰减ResNet的Bottleneck块对正则更敏感LearnRateSchedulepiecewise每5轮乘以0.1比余弦退火更易控制Shuffleevery-epoch每轮随机打乱训练数据顺序options trainingOptions(sgdm, ... InitialLearnRate, 1e-3, ... MiniBatchSize, 32, ... MaxEpochs, 15, ... ValidationData, augimdsVal, ... ValidationFrequency, 50, ... L2Regularization, 1e-4, ... LearnRateSchedule, piecewise, ... LearnRateDropFactor, 0.1, ... LearnRateDropPeriod, 5, ... Shuffle, every-epoch, ... Plots, training-progress, ... ExecutionEnvironment, auto); netTrained trainNetwork(augimdsTrain, lgraph, options);执行环境建议用autoMatlab会优先使用GPU。如果GPU显存不足MiniBatchSize从32降到8或16通常能解决。Plots设为training-progress会弹出实时曲线包含损失、验证准确率和学习率变化这条曲线是判断网络是否收敛的第一手依据。3.4 训练中主要看三个信号而不是只看最高准确率首先看训练损失曲线是否平滑下降。VggNet微调时如果初始学习率设成1e-2损失曲线会在前几个迭代迅速发散或震荡此时直接终止训练并降低学习率。其次看验证准确率曲线是否随训练集准确率同步上升如果两者差距持续扩大超过15%需要增大L2Regularization或提前停止。第三看验证频率ValidationFrequency不能设得比总迭代次数还大否则验证集不会生效也就看不到val loss曲线。% 训练完成后在测试集上评估 [YPred, scores] classify(netTrained, augimdsVal); accuracy mean(YPred imdsVal.Labels);classify返回的YPred是预测标签scores是每个类别的softmax概率。按类别打印混淆矩阵能够定位哪些类容易被混淆plotconfusion(imdsVal.Labels, YPred)混淆矩阵中如果某两类交叉严重常见原因是训练数据中这两类的样本数不均匀尤其当一类样本只有另一类的五分之一时VggNet这类参数大的网络很容易把少数类学成噪声。优先做法是用splitEachLabel按比例切分而不是按总数切分保证每个minibatch都有各类别的代表。4. 物体分类识别的对比实验精度、参数量与特征可视化4.1 同一数据集上的量化对比VggNet与ResNet-50当VggNet和ResNet都完成微调后对比实验不能只报一个准确率。下面这些指标在Matlab中都能计算指标VggNet微调后ResNet-50微调后总参数量1.38亿约537MB2550万约98MB单张推理时间CPU约210ms约85ms单张推理时间GPU约30ms约18ms达到90%验证准确率的轮次第11轮第6轮最终验证准确率依数据集而定通常高13个百分点数据来自同一微调配置下的典型结果实际数值随数据集与硬件浮动。ResNet-50在参数量上只有VggNet的六分之一却能达到同量级甚至更高的精度归功于Bottleneck结构。VggNet的优势在于结构透明每一层的激活图尺寸规整做可视化、剪枝和定点化部署都更省事。计算模型大小和推理时间的代码如下% 模型大小直接查看工作区变量大小 whos netTrained % 推理时间使用timeit测量单张图像分类 imgTest read(imdsVal); t timeit(() classify(netTrained, imgTest));timeit会多次执行匿名函数取中位数比tic/toc更稳定。注意classify内部包含了图像预处理augmentedImageDatastore的预处理流程也会计入总时间。4.2 用Grad-CAM对比两个网络的注意力区域精度不能解释一个网络为什么做对或做错。经典的可视化手段有两种一种是直接看卷积层激活图另一种是Grad-CAM后者能在图像上标出网络分类时重点关注的区域。Matlab从2021b开始内置gradCAM函数% 选择一张测试图片 imgTest readimage(imdsTest, 1); % 计算最后一个卷积层对预测类别的注意力热图 lgraphTrained layerGraph(netTrained); scoreMap gradCAM(netTrained, imgTest, imdsTest.Labels(1), ... ReductionLayer, new_fc); figure; heatmap(scoreMap);ReductionLayer需要指定一个全连接层或池化层的名称通常选最后一个卷积块之后的层。VggNet选择fc6前一层pool5ResNet-50选择pool5。对比两者的Grad-CAM图会发现ResNet-50通常能聚焦到物体的核心区域而VggNet的注意力分布更分散边缘背景占有更多权重。这直接解释了ResNet迭代次数少但准确率高的原因也提示了一个调参方向VggNet微调时应增大数据增强的随机裁剪比例迫使它学习更有判别力的局部特征。4.3 什么时候选VggNet什么时候选ResNet如果任务是工业级、样本量在几千到几万ResNet-50通常是默认起点参数少、收敛快、精度高。但有两个场景VggNet更合适。一是CPU部署且对推理延迟不敏感、对模型可解释性要求高时VggNet的规整结构便于逐层分析中间激活比如做噪声鲁棒性测试或针对特定类别找失效模式二是做特征提取器时VggNet的fc6层输出4096维特征向量在很多传统机器学习模型里比ResNet的2048维池化特征表现更好因为向量维度高、线性可分性更强。5. 预训练模型加载异常与输入尺寸不匹配的三个排查方法5.1 预训练模型下载缓慢或中断后的恢复方式vgg19和resnet50首次运行时会自动从MathWorks服务器下载权重文件下载包通常在200MB到500MB。如果网络环境不稳定下载中断后再次执行函数Matlab会报“无法找到支持文件”或“文件损坏”的错误。排查顺序如下% 查看附加功能根目录确认预训练模型存放位置 matlabshared.supportpkg.getSupportPackageRoot找到目录后检查是否存在vgg19或resnet50相关的子目录。文件损坏时最直接的做法是删除对应子目录然后重新运行vgg19或resnet50。删除前注意确认目录路径不要误删用户自己的数据。下载问题解决后可以在命令行用exist验证tf exist(vgg19, file);若返回值为2说明函数在搜索路径上可用若返回值是1说明这是一个变量名而非函数文件检查是否在脚本里给变量起名vgg19覆盖了系统函数。5.2 图像输入尺寸与网络输入层不匹配物体分类识别的常见错误之一是读取原始图像后直接传入classify报错提示输入尺寸应为224×224而实际是其他尺寸。原因是预训练网络对输入层有固定约束但普通imds不会自动缩放。正确做法永远是经由augmentedImageDatastore预处理或者用imresize手动调整imgIn imresize(imgTest, [224 224]);如果原图的长宽比与目标尺寸差异较大imresize会拉伸图片造成几何形变。更好的替代方案是先等比缩放短边到224再居中裁剪到224×224[h, w, ~] size(imgTest); scale 224 / min(h, w); imgResized imresize(imgTest, scale); % 裁剪中心224×224区域 centerCrop imcrop(imgResized, [(size(imgResized,2)-224)/2, ... (size(imgResized,1)-224)/2, 223, 223]);中心裁剪保持内容不变形也更接近预训练模型在ImageNet上的训练分布。这个细节对分类准确率的提升常被低估尤其是目标物体占比大的图片。5.3 训练前先用一个batch验证前向传播训练跑了几十个epoch后才发现模型结构有问题是时间浪费的大头。一种低成本验证方法是在完整训练前把验证集里的一张图单独做一次前向传播确认各层输出尺寸符合预期% 取网络中间层输出验证尺寸 lgraph layerGraph(net); dlnet dlnetwork(lgraph); dlImg dlarray(single(imgIn), SSCB); % 执行第一个卷积块到最后一个池化层检查特征图尺寸 features predict(dlnet, dlImg, Outputs, {pool5});如果Outputs指定了不存在的层名称Matlab会报错列出所有可选层名这时把正确名称补上即可。更稳妥的方式是使用analyzeNetwork提供的层名列表在训练脚本里加入断言辅助排查例如期望pool5输出为7×7×2048对应ResNet-50尺寸不符就立刻终止assert(size(features, 1) 7 size(features, 2) 7, ... pool5输出尺寸异常检查输入图像尺寸参数);predict默认按训练模式执行输出位置取决于Outputs参数指定的层名。这里有一处需要注意如果网络中有Dropout层predict在推理模式下不生效要改用forward配合dlnetwork的Training选项。物体分类识别里这类验证只做一次不纳入训练循环因此多花几秒的代价完全可以接受。本文还有配套的精品资源点击获取
返回列表