52matlab技术网站,matlab教程,matlab安装教程,matlab下载

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 547|回复: 1

四大经典轻量级网络之二:SqueezeNet

[复制链接]

99

主题

181

帖子

2205

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2205
发表于 2020-9-1 19:00:02 | 显示全部楼层 |阅读模式
本帖最后由 matlab的旋律 于 2020-9-1 19:14 编辑

1.前言
从上世纪90年代以 LeNet为开始代表的卷积神经网络,2012年又以AlexNet为起始点爆发,在深度学习领域中成为炙手可热的网络框架,特别是在机器视觉领域更是超群绝伦。此后的ZF-Net到VGG-Nets,GoogleNet再到ResNet以及DenseNet,以追求提升识别精确率为主要目的,采用手段的主要方向包括加深网络结构和增强卷积模块功能,同时这也导致了整个用于识别的网络越来越复杂,需要的内存和算力也大大增加。SqueezeNet开辟了另外一个方向:在保证模型精度不降低的前提下,最大程度的提高运算速度。它能够在ImageNet数据集上达到近似AlexNet的效果,但是参数量相比AlexNet少了50倍,同时结合模型压缩技术 Deep Compression,SqueezeNet模型文件相比AlexNet小约510倍。
SqueezeNet与几乎同一时期提出的MobileNet、ShuffleNet和Xception被称为当前的四大轻量级模型,但SqueezeNet是最早在arXiv上公开的。
2.网络结构
SqueezeNet创新点在于提出了fire module,包括两个部分,squeeze和expand,如下图所示。
其中的squeeze 在 SqueezeNet的结构中表示一个 squeeze 层,该层采用 1*1 卷积核对上一层 feature map进行卷积,其主要目的是降低feature map 的维数。expand使用的Inception结构,包括1*1和3*3卷积,然后拼接,Matlab实现的代码如下:
  1. lgraph = layerGraph();
  2. tempLayers = [
  3.     convolution2dLayer([1 1],16,"Name","fire2-squeeze1x1")
  4.     reluLayer("Name","fire2-relu_squeeze1x1")];
  5. lgraph = addLayers(lgraph,tempLayers);
  6. tempLayers = [
  7.     convolution2dLayer([3 3],64,"Name","fire2-expand3x3","Padding",[1 1 1 1])
  8.     reluLayer("Name","fire2-relu_expand3x3")];
  9. lgraph = addLayers(lgraph,tempLayers);

  10. tempLayers = [
  11.     convolution2dLayer([1 1],64,"Name","fire2-expand1x1")
  12.     reluLayer("Name","fire2-relu_expand1x1")];
  13. lgraph = addLayers(lgraph,tempLayers);

  14. tempLayers = [
  15. depthConcatenationLayer(2,"Name","fire2-concat")];

  16. lgraph = addLayers(lgraph,tempLayers);
  17. lgraph = connectLayers(lgraph,"fire2-relu_squeeze1x1","fire2-expand3x3");
  18. lgraph = connectLayers(lgraph,"fire2-relu_squeeze1x1","fire2-expand1x1");
  19. lgraph = connectLayers(lgraph,"fire2-relu_expand1x1","fire2-concat/in1");
  20. lgraph = connectLayers(lgraph,"fire2-relu_expand3x3","fire2-concat/in2");
  21. plot(lgraph)%绘图
复制代码
得到的流程图如下图图所示:
由于两个卷积过程使用的stride都是1,因此输出的数据结构仅仅在于通道数上的差异,拼接后的数据是1*1和3*3卷积后的数据在通道上之和。其中所有的1*1和3*3卷积使用的padding方式分别为[0,0,0,0]和[1,1,1,1]。

整个SqueezeNet的结构使用Matlab中plot函数对深度学习网络结构的表示如下图所示:
从图中可以看出SqueezeNet中一共包含了8个fire module,其中在第3和第5个fire module使用了3*3的最大池化,对应池化层的stride都为2*2,将进行下采样的池化层下移动的原因是作者认为较大的Feature Map含有更多的信息。当然这样的操作虽然会提升网络的精度,但同时也带来一个问题,也就是会导致网络的计算量增加。
3.模型迁移
在深度学习行业内一个普遍存在的问题就是在面对某一领域的某一特定问题时,找到足够充分的训练数据非常困难。因此,如果能够使用其他数据集训练得到的成熟模型,经过一定的修改和完善,然后可以复用在与之类似的领域,这样就可以大大的缓解数据源不足导致的问题。当前,能够解决这个问题的一个关键技术就是迁移学习。
迁移学习主要过程包括:
1)      使用现成的数据集训练好模型,保存为预训练模型;
2)      在预训练模型中定位输出为可复用特征(feature)的层次(layer);
3)      将可复用特征的层次的输出作为新模型的输入,进行重新训练。
其中,这里进行预训练的数据集和迁移学习的数据集可以对应完全不同的待解问题,例如样本的尺寸相同,样本标签数目却不一样等。由于此前的预训练模型已经学习得到了数据的组织模式,因此进行迁移学习的网络只需要学习数据集中针对某一特定问题的相关性问题就可以了。简而言之,迁移学习具有的优势可以总结为:
1)      适应小样本,迁移学习能够将大样本数据进行训练的模型迁移到只有小样本的数据领域,实现小样本数据的落地。
2)      提高鲁棒性,通过迁移学习所得到的模型具有普适性,可以迁移到多个不同的领域而不至于产生显著的性能下降。
3)      个性化定制,对应每个问题的个性化样本规模可能不大,但是在通过大数据训练的模型基础上进行迁移学习,就能很好的解决个性化的问题,也可以形象的比如为站在巨人的肩膀上。

下面使用小迈步视频课程上的一个例子,对SqueezeNet进行迁移学习用于Cap、Cube、MWBottle、NFSQ、PlayingCards、Screwdriver和Torch七大类物品的识别。对应的迁移学习步骤和代码如下:
  1. %加载Squeezenet模型并修改
  2. net = squeezenet();

  3. lgraph = layerGraph(net);
  4. inputSize = net.Layers(1).InputSize;
  5. numClasses = numel(categories(imdsTrain.Labels));

  6. % 删除squeezenet的最后5层   
  7. lgraph = removeLayers(lgraph, {'conv10', 'relu_conv10', ...
  8. 'pool10', 'prob', 'ClassificationLayer_predictions'});

  9. %定义一个卷积核大小为2的卷积层           
  10. conv10 = convolution2dLayer( ...
  11.                 1, numClasses, ...
  12.                 'Stride', 1, ...
  13.                 'Padding', 0, ...
  14.                 'Name', 'conv10');

  15. relu_conv10 = reluLayer('Name', 'relu_conv10');

  16. pool10 = averagePooling2dLayer( 14, 'Stride', 1, 'Padding', 0, 'Name', 'pool10');

  17. %其中新网络的最后5层如下:
  18. newLayers = [
  19.                 conv10
  20.                 relu_conv10
  21.                 pool10
  22.                 softmaxLayer('Name', 'softmax')
  23.                 classificationLayer('Name', 'classoutput')];

  24. % 添加并连接到网络的最后一层 'drop9'层
  25. lgraph = addLayers(lgraph, newLayers);
  26. lgraph = connectLayers(lgraph, 'drop9', 'conv10');
复制代码
4.实验结果
对上述迁移学习的模型进行训练,其中具体训练的参数设置可以点击阅读原文参看对应的Matlab源码。其中训练过程详细图示如下图。可以看出经过20轮训练集和验证集都达到了100%的准确率,损失函数值也收敛到了近0值,另外使用的时间仅为42秒。
如下图所示,通过对测试集4张图片的识别其结果也完全正确,这些也说明轻量级网络SqueezeNet在迁移学习上高效性,以及部署到性能较低的单片机上的可行性。
参考文献:
论文:SQUEEZENET: ALEXNET-LEVEL ACCURACYWITH 50X FEWER PARAMETERS AND <0.5MB MODEL SIZE
欢迎加入深度学习算法交流群学习交流。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

99

主题

181

帖子

2205

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2205
 楼主| 发表于 2020-9-1 19:16:49 | 显示全部楼层
本帖最后由 matlab的旋律 于 2020-9-1 19:20 编辑

用于迁移学习测试的实例程序
  1. %准备训练及测试用图片集
  2. %载入图库
  3. imds = imageDatastore('TrainData',...
  4.     'IncludeSubfolders',true,...
  5.     'LabelSource','foldernames');
  6. [imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

  7. %加载Squeezenet模型并修改
  8. net = squeezenet();

  9. lgraph = layerGraph(net);
  10. inputSize = net.Layers(1).InputSize;
  11. numClasses = numel(categories(imdsTrain.Labels));

  12. % Remove last 5 layers   
  13. lgraph = removeLayers(lgraph, {'conv10', 'relu_conv10', ...
  14. 'pool10', 'prob', 'ClassificationLayer_predictions'});

  15. % define a conv layer with a filter size of 2           
  16. conv10 = convolution2dLayer( ...
  17.                 1, numClasses, ...
  18.                 'Stride', 1, ...
  19.                 'Padding', 0, ...
  20.                 'Name', 'conv10');

  21. relu_conv10 = reluLayer( ...
  22.                 'Name', 'relu_conv10');

  23. pool10 = averagePooling2dLayer( ...
  24.                 14, ...
  25.                 'Stride', 1, ...
  26.                 'Padding', 0, ...
  27.                 'Name', 'pool10');

  28. % Last 5 layers of the new network would be
  29. newLayers = [
  30.                 conv10
  31.                 relu_conv10
  32.                 pool10
  33.                 softmaxLayer('Name', 'softmax')
  34.                 classificationLayer('Name', 'classoutput')];

  35. % Add and connect to the last layer of the network 'drop9'
  36. lgraph = addLayers(lgraph, newLayers);
  37. lgraph = connectLayers(lgraph, 'drop9', 'conv10');
  38. plot(lgraph)

  39. %调整图库
  40. pixelRange = [-30 30];
  41. scaleRange = [0.9 1.1];
  42. imageAugmenter = imageDataAugmenter( ...
  43.     'RandXReflection',true, ...
  44.     'RandXTranslation',pixelRange, ...
  45.     'RandYTranslation',pixelRange, ...
  46.     'RandXScale',scaleRange, ...
  47.     'RandYScale',scaleRange);
  48. augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,...
  49.     'DataAugmentation',imageAugmenter);

  50. augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

  51. %进行模型训练
  52. options = trainingOptions('sgdm',...
  53.     'ExecutionEnvironment','gpu',...
  54.     'MiniBatchSize',10,...
  55.     'MaxEpochs',20,...
  56.     'InitialLearnRate',0.0001,...
  57.     'ValidationData',augimdsValidation,...
  58.     'ValidationFrequency',3,...
  59.     'ValidationPatience',Inf,...
  60.     'Verbose',false,...
  61.     'Plots','training-progress',...
  62.     'ExecutionEnvironment','gpu');    % 此处为GPU训练,可改为CPU或PCT

  63. net = trainNetwork(augimdsTrain,lgraph,options);

  64. %测试训练好的模型

  65. [YPred,scores] = classify(net,augimdsValidation);
  66. idx = randperm(numel(imdsValidation.Files),4);
  67. figure
  68. for i = 1:4
  69.     subplot(2,2,i)
  70.     I = readimage(imdsValidation,idx(i));
  71.     imshow(I)
  72.     label = YPred(idx(i));
  73.     title(string(label));
  74. end
复制代码


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|52matlab技术网站 ( 粤ICP备14005920号-5 )

GMT+8, 2020-10-21 07:56 , Processed in 0.063305 second(s), 21 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表