资讯详情

Matlab物体分类实战:VggNet与ResNet迁移学习对比

📅 2026/10/25 11:00:41 | 华诺云谱 👁 阅读
Matlab物体分类实战:VggNet与ResNet迁移学习对比
简介这份资源面向深度学习入门者与计算机视觉方向的学生和研究者围绕VggNet与ResNet两种经典卷积神经网络在物体分类识别中的应用展开提供可运行的Matlab代码实现帮助读者从理论理解过渡到动手实践。压缩包共包含60012个文件以60002个png图像数据为主另有4个m脚本、3个mat权重文件、1个pdf说明文档及fig、jpg等辅助文件整体约398.58MB规模较大适合完整复现训练与测试流程。目前已有759人学习下载。资源重点比较了VggNet逐层加深结构与ResNet残差连接的设计差异涵盖网络搭建、预训练权重加载、前向与反向传播、参数初始化、正则化与优化器选择等训练策略并给出物体分类准确率的实验对比。读者可据此掌握两种网络的Matlab实现方法、代码解读思路与迁移学习技巧为后续目标检测、语义分割等任务打下基础。1. VggNet 与 ResNet 做物体分类为什么这两个网络值得放在一起对比如果你手头有一批物体图片想用 Matlab 跑一个能落地的分类模型大概率会卡在同一个问题上选 VggNet 还是 ResNet这不是学术层面的“谁更强”而是工程层面的“谁更适合你现在的数据量、显存和交付时间”。VggNet 结构规整16 到 19 层全是 3×3 卷积堆叠特征提取路径清晰改起来不容易翻车ResNet 靠残差连接把梯度直接短路传下去能堆到 50 层甚至 152 层还不退化预训练模型在 ImageNet 上的迁移效果通常更稳。把这两个网络放在同一套物体分类识别流程里跑一遍你能直观看到同样一批图VggNet 收敛慢但可解释性强ResNet 收敛快但对输入尺寸和归一化更敏感。这篇笔记就按“数据准备 → 网络加载 → 训练调参 → 避坑排查 → 进阶技巧”的顺序把 Matlab 代码和参数含义拆开讲适合正在做图像处理大作业、或者要把分类模型塞进实际检测流程的工程师。2. 数据准备与两种网络的输入规范从图片文件夹到可训练的数据存储2.1 物体分类数据集怎么组织才不报错Matlab 的imageDatastore对文件夹结构有硬性要求每个类别一个子文件夹文件夹名就是标签名。常见做法是建一个根目录下面按类别分文件夹比如dataset/apple/、dataset/banana/。图片格式支持 jpg、png、bmp但不要混入 gif 或带透明通道的 png否则imread读出来是四通道后面augmentedImageDatastore会直接报维度不匹配。% 假设数据集根目录为 dataset下面有 apple、banana、orange 三个子文件夹 imds imageDatastore(dataset, ... IncludeSubfolders, true, ... LabelSource, foldernames); % 查看类别分布防止某类样本过少导致训练偏斜 labelCount countEachLabel(imds); disp(labelCount); % 按 7:3 划分训练集和验证集保证每类比例一致 [imdsTrain, imdsVal] splitEachLabel(imds, 0.7, randomized);这段代码的逻辑是imageDatastore自动遍历子文件夹并打标签countEachLabel用来检查类别是否均衡。如果某类只有十几张图后面要么做数据增强要么直接合并到相似类。splitEachLabel的第三个参数randomized很关键不加的话默认按文件名顺序切容易把某一类全切进训练集。2.2 VggNet 与 ResNet 的输入尺寸差异及预处理VggNet 在 Matlab 里通常加载vgg16或vgg19输入层要求 224×224×3。ResNet 的resnet18、resnet50同样接受 224×224但resnet50对输入归一化更敏感它用的是 ImageNet 的均值减法不是简单的 0-1 归一化。Matlab 的augmentedImageDatastore可以统一做尺寸缩放但归一化方式要跟网络匹配。% 定义目标尺寸 inputSize [224 224 3]; % 数据增强随机翻转、随机缩放、随机旋转 augmenter imageDataAugmenter( ... RandXReflection, true, ... RandYReflection, false, ... RandScale, [0.9 1.1], ... RandRotation, [-15 15]); % 构建增强后的数据存储 augimdsTrain augmentedImageDatastore(inputSize, imdsTrain, ... DataAugmentation, augmenter); augimdsVal augmentedImageDatastore(inputSize, imdsVal);参数说明RandXReflection对物体分类通常安全因为左右翻转不改变类别RandYReflection要慎用上下翻转可能把“杯子”变成“倒扣的杯子”语义变了。RandScale控制在 0.9 到 1.1 之间模拟拍摄距离变化。RandRotation给 ±15 度再大就可能把物体转出画面。注意augmentedImageDatastore只做几何变换不做像素归一化ResNet 需要的均值减法要在网络内部或训练选项里处理。提示如果显存不足把inputSize降到 [128 128 3] 能跑但 VggNet 的全连接层参数量不变显存瓶颈在最后三层降输入尺寸救不了多少。3. 加载预训练模型与迁移学习VggNet 和 ResNet 的 Matlab 实现3.1 用vgg16和resnet50替换最后三层Matlab 的 Deep Learning Toolbox 支持直接加载预训练模型前提是你已经安装了对应的支持包。加载后不要从头训练而是把最后三层全连接、softmax、分类输出替换成自己的类别数。VggNet 和 ResNet 的层名不同替换方式也有差异。% 加载预训练网络 netVgg vgg16; netRes resnet50; % 查看最后几层确认层名 layersVgg netVgg.Layers; layersRes netRes.Layers; disp(layersVgg(end-4:end)); disp(layersRes(end-4:end)); % 获取类别数 numClasses numel(categories(imdsTrain.Labels)); % 替换 VggNet 最后三层 lgraphVgg layerGraph(netVgg); newLayersVgg [ fullyConnectedLayer(numClasses, Name, new_fc, ... WeightLearnRateFactor, 10, BiasLearnRateFactor, 10) softmaxLayer(Name, new_softmax) classificationLayer(Name, new_classoutput)]; lgraphVgg replaceLayer(lgraphVgg, fc8, newLayersVgg(1)); lgraphVgg replaceLayer(lgraphVgg, prob, newLayersVgg(2)); lgraphVgg replaceLayer(lgraphVgg, output, newLayersVgg(3)); % 替换 ResNet50 最后三层 lgraphRes layerGraph(netRes); newLayersRes [ fullyConnectedLayer(numClasses, Name, new_fc, ... WeightLearnRateFactor, 10, BiasLearnRateFactor, 10) softmaxLayer(Name, new_softmax) classificationLayer(Name, new_classoutput)]; lgraphRes replaceLayer(lgraphRes, fc1000, newLayersRes(1)); lgraphRes replaceLayer(lgraphRes, prob, newLayersRes(2)); lgraphRes replaceLayer(lgraphRes, ClassificationLayer_predictions, newLayersRes(3));逻辑说明replaceLayer是按层名替换VggNet 的全连接层叫fc8ResNet50 的叫fc1000。WeightLearnRateFactor设为 10 是让新加的全连接层学得快一点因为它是随机初始化的而前面的卷积层已经预训练好了学习率要低。这一步如果层名写错Matlab 会报 “Layer not found”所以先用disp把最后几层名字打出来确认。3.2 冻结早期层与微调策略物体分类数据集通常只有几千张图直接微调所有层容易过拟合。常见做法是冻结前几个卷积块只训练后面的层。VggNet 的卷积层按conv1_1到conv5_4命名ResNet50 按conv1、bn_conv1、res2a_branch1等命名。冻结的方式是把对应层的WeightLearnRateFactor和BiasLearnRateFactor设为 0。% 冻结 VggNet 前 10 层对应 conv1 到 conv3 的部分 layersVgg lgraphVgg.Layers; for i 1:10 if isprop(layersVgg(i), WeightLearnRateFactor) layersVgg(i).WeightLearnRateFactor 0; layersVgg(i).BiasLearnRateFactor 0; end end lgraphVgg layerGraph(layersVgg); % 冻结 ResNet50 的前 20 层 layersRes lgraphRes.Layers; for i 1:20 if isprop(layersRes(i), WeightLearnRateFactor) layersRes(i).WeightLearnRateFactor 0; layersRes(i).BiasLearnRateFactor 0; end end lgraphRes layerGraph(layersRes);参数说明冻结层数没有固定标准一般看数据集大小。5000 张图以下VggNet 冻到conv4之前ResNet50 冻到res3之前。如果验证集准确率一直上不去再解冻一两层试试。注意 ResNet 的 Batch Normalization 层在冻结时也要把WeightLearnRateFactor设 0否则均值和方差还在更新等于没冻住。4. 训练参数设置与两种网络的收敛对比4.1trainingOptions里必须调的五个参数Matlab 的trainingOptions参数很多但物体分类迁移学习真正影响结果的只有五个InitialLearnRate、MiniBatchSize、MaxEpochs、ValidationFrequency、ExecutionEnvironment。VggNet 和 ResNet 对这五个参数的敏感度不同。% VggNet 训练选项 optionsVgg trainingOptions(sgdm, ... InitialLearnRate, 1e-4, ... MiniBatchSize, 16, ... MaxEpochs, 20, ... Shuffle, every-epoch, ... ValidationData, augimdsVal, ... ValidationFrequency, 30, ... Verbose, false, ... Plots, training-progress, ... ExecutionEnvironment, auto); % ResNet50 训练选项 optionsRes trainingOptions(sgdm, ... InitialLearnRate, 1e-4, ... MiniBatchSize, 16, ... MaxEpochs, 20, ... Shuffle, every-epoch, ... ValidationData, augimdsVal, ... ValidationFrequency, 30, ... Verbose, false, ... Plots, training-progress, ... ExecutionEnvironment, auto);参数说明InitialLearnRate用 1e-4 是迁移学习的常用起点VggNet 可以稍高到 5e-4ResNet 建议不超过 1e-4否则残差分支容易震荡。MiniBatchSize设 16 是显存和梯度稳定性的折中显存够就上 32。MaxEpochs设 20 是因为预训练模型收敛快超过 30 轮基本过拟合。ValidationFrequency设 30 表示每 30 个迭代验证一次太小会拖慢训练速度。4.2 训练过程监控看损失曲线判断是否翻车training-progress窗口里重点看两条线训练损失和验证准确率。VggNet 的损失曲线通常前 5 轮下降明显之后变缓ResNet 前 2 轮就能降到很低但验证准确率可能波动大。如果训练损失一直不降检查学习率是不是太小如果验证准确率远低于训练准确率说明过拟合要加数据增强或冻结更多层。% 训练 VggNet netVggTrained trainNetwork(augimdsTrain, lgraphVgg, optionsVgg); % 训练 ResNet50 netResTrained trainNetwork(augimdsTrain, lgraphRes, optionsRes); % 在验证集上评估 predVgg classify(netVggTrained, augimdsVal); predRes classify(netResTrained, augimdsVal); accVgg mean(predVgg imdsVal.Labels); accRes mean(predRes imdsVal.Labels); fprintf(VggNet 验证准确率: %.2f%%\n, accVgg * 100); fprintf(ResNet50 验证准确率: %.2f%%\n, accRes * 100);这段代码把两个网络跑完并对比验证准确率。注意classify的输出是 categorical 类型直接和imdsVal.Labels比较即可。如果 VggNet 准确率比 ResNet 低 5 个点以上不用惊讶这是常态如果低 20 个点检查 ResNet 的输入归一化是不是没做对。5. 避坑与排查物体分类训练中最容易翻车的五个地方5.1 现象训练一开始就报 “Out of memory”原因MiniBatchSize设太大或者inputSize没降下来。VggNet 的全连接层fc6有 4096 个神经元参数量约 1 亿显存占用比 ResNet50 还高。解决把MiniBatchSize降到 8或者用resnet18替代resnet50。如果还是不够把inputSize改成 [128 128 3]但 VggNet 的全连接层不会因此变小所以优先换网络。5.2 现象验证准确率一直停在 50% 左右像随机猜原因标签没对上。imageDatastore的LabelSource设成foldernames后标签是文件夹名但splitEachLabel之后imdsTrain.Labels和imdsVal.Labels的类别顺序可能不一致。解决在训练前用categories(imdsTrain.Labels)和categories(imdsVal.Labels)对比一下确保完全一样。如果不一样用subset重新切。5.3 现象ResNet 训练损失出现 NaN原因学习率太大残差连接把梯度放大后导致数值溢出。解决把InitialLearnRate从 1e-3 降到 1e-4或者加GradientThreshold, 1做梯度裁剪。Matlab 的trainingOptions支持GradientThreshold参数设 1 到 5 之间比较安全。5.4 现象VggNet 训练很慢一个 epoch 要十几分钟原因ExecutionEnvironment设成了cpu或者没装 GPU 支持。解决用gpuDevice检查 GPU 是否可用然后在trainingOptions里显式设ExecutionEnvironment, gpu。如果 GPU 显存小于 6GBVggNet 基本跑不动换 ResNet18 或降MiniBatchSize。5.5 现象验证集准确率比训练集高原因数据增强只加在训练集上验证集是原始图模型在验证集上反而“看到”了更清晰的样本。解决这不是 bug是正常现象但如果差距超过 10 个点说明训练集增强太狠把RandRotation范围缩小到 ±10 度或者关掉RandScale。6. 进阶技巧用混淆矩阵和特征可视化判断模型到底学到了什么训练完两个网络后别只看准确率。用混淆矩阵看哪些类别容易混用activations提取中间层特征做 t-SNE 可视化能判断模型是学到了物体形状还是背景颜色。Matlab 的confusionchart和tsne函数可以直接用。% 混淆矩阵 figure; cmVgg confusionchart(imdsVal.Labels, predVgg); title(VggNet 混淆矩阵); figure; cmRes confusionchart(imdsVal.Labels, predRes); title(ResNet50 混淆矩阵); % 提取 ResNet50 的全局平均池化层特征 layerName avg_pool; features activations(netResTrained, augimdsVal, layerName, ... OutputAs, rows); % t-SNE 降维可视化 figure; tsneFeatures tsne(features); gscatter(tsneFeatures(:,1), tsneFeatures(:,2), imdsVal.Labels); title(ResNet50 特征 t-SNE 可视化);逻辑说明confusionchart的输入是真实标签和预测标签对角线越深越好。如果某两类互相混说明它们的视觉特征太接近要么加更多样本要么在分类层前加一个注意力模块。activations提取的是avg_pool层的输出ResNet50 在这一层已经是 2048 维向量直接做 t-SNE 计算量大可以先pca降到 50 维再tsne。gscatter按类别着色如果同一类聚成一团说明模型学到了区分性特征如果混在一起说明特征空间没分开。注意tsne对大数据集很慢验证集超过 2000 张图时先随机采样 500 张再跑。我自己的习惯是每次训完一个分类模型先看混淆矩阵再看 t-SNE最后才看准确率。准确率会骗人但混淆矩阵和特征分布不会。VggNet 和 ResNet 没有绝对的好坏只有跟你的数据、显存和交付时间匹配不匹配。如果数据集小、可解释性要求高VggNet 更稳如果追求精度、能接受调参成本ResNet 上限更高。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

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

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

你可能需要的服务

订阅华诺云谱资讯周报

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

↑