前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >两种移动端可以实时运行的网络模型

两种移动端可以实时运行的网络模型

作者头像
OpenCV学堂
发布2019-04-29 16:04:42
9100
发布2019-04-29 16:04:42
举报

微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识 觉得文章有用,请戳底部【好看】支持

概述

我们常见的网络模型比如AlexNet、GoogleNet、VGG都因为权重文件太大无法在移动端直接运用,而且因为计算浮点参数过多无法实时运行,所以针对这种情况先后出现了SqueezeNet与MobileNet两种权重参数和文件大小都得到优化的可以在嵌入式边缘设备上运行的网络模型,两种模型都可以通过tensorflow Lite被压缩到2MB大小左右,还依然可以实现比较好的分类与图像检测效果。

SqueezeNet模型

SqueezeNet模型可以达到跟AlexNet相同的图像分类精度,但是文件大小却可以下降50倍以上,SqueezeNet模型有如下三个架构策略:

  • 替换3x3的卷积为1x1的卷积,这个替换步骤可以节省9倍的浮点数参数
  • 对3x3的输入层卷积,通过fire module修改输入层的通道数目,减少3x3卷积的参数
  • 延时下采样,获取更多的激活特征map,从而提高图像分类精度

其中第二个策略fire module的结构如下:

通过1x1与3x3的filter组合有效减少参数,最终通过填充使得1x1与3x3输出feature maps大小一致,叠加输出到下一层。SqueezeNet的网络结构如下:

各层参数与filter的详细说明

另外一个跟AlexNet不一样的地方是,Squeeze是一个全卷积图像分类网络,它去掉全连接层,这样就可以避免更多参数产生。

MobileNet模型

MobileNet网络模型是谷歌提出了适用于移动端应用的深度学习模型,MobileNet采用跟SqueezeNet不一样的机制来降低网络的参数总数,这种技术被称为深度可分离卷积(Depth-Wise Separable Convolution)。MobileNet正式通过这个方法达到减少权重参数,压缩模型体积大小的目标,实现了快速实时的网络模型。

其中a是标准的卷积操作,b是深度分离的卷积操作,c是1x1的卷积操作,标准卷积操作可以拆分为b, c两步完成,这样就可以极大的减少参数总数。假设原图中有10个通道,filter为3x3, 则对于输入N=5, 总的参数为5x3x3x10 = 450参数,采用深度可分离卷积则为 5x3x3+10x1x1x5 =95总的参数下降为95个。最终的MobileNet body的网络结构如下:

值得一提的是两个网络在最后输出层之前都采用了均值池化,而不同于常见网络的最大池化的方法。

预训练的基于SqueezeNet的对象检测模型下载

https://github.com/kvmanohar22/opencv_extra/tree/a0b59f565efd21882dbbf6e84f7183df88cd4e66/dnn_objdetect

OpenCV DNN模块已经支持这两种网络的加载与使用,以MobileNet网络为例

代码语言:javascript
复制
import cv2 as cv

model_bin = "D:/projects/opencv_tutorial/data/models/ssd/MobileNetSSD_deploy.caffemodel";
config_text = "D:/projects/opencv_tutorial/data/models/ssd/MobileNetSSD_deploy.prototxt";
objName = ["background",
"aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor"];

# load caffe model
net = cv.dnn.readNetFromCaffe(config_text, model_bin)
image = cv.imread("D:/images/dog.jpg")
h = image.shape[0]
w = image.shape[1]

# 获得所有层名称与索引
layerNames = net.getLayerNames()
lastLayerId = net.getLayerId(layerNames[-1])
lastLayer = net.getLayer(lastLayerId)
print(lastLayer.type)

# 检测
blobImage = cv.dnn.blobFromImage(image, 0.007843, (300, 300), (127.5, 127.5, 127.5), True, False);
net.setInput(blobImage)
cvOut = net.forward()
print(cvOut)
for detection in cvOut[0,0,:,:]:
    score = float(detection[2])
    objIndex = int(detection[1])
    if score > 0.5:
        left = detection[3]*w
        top = detection[4]*h
        right = detection[5]*w
        bottom = detection[6]*h

        # 绘制
        cv.rectangle(image, (int(left), int(top)), (int(right), int(bottom)), (255, 0, 0), thickness=2)
        cv.putText(image, "score:%.2f, %s"%(score, objName[objIndex]),
                (int(left) - 10, int(top) - 5), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2, 8);

cv.imshow('mobilenet-ssd-demo', image)
cv.waitKey(0)
cv.destroyAllWindows()

运行结果:

代码语言:javascript
复制
博观而约取
厚积而薄发

推荐阅读
2018年原创技术文章汇总
OpenCV调用Faster-RCNN对象检测网络
使用OpenVINO ToolKit 实时推断
Selective Search算法与演示
tensorflow模型导出与OpenCV DNN中使用
DNN模块学习分享
欢迎扫码加入【OpenCV研习社】
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • SqueezeNet模型
  • MobileNet模型
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档