开源项目—如何在浏览器运行深度神经网络?以人脸口罩识别为例进行讲解
Posted AI研习图书馆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开源项目—如何在浏览器运行深度神经网络?以人脸口罩识别为例进行讲解相关的知识,希望对你有一定的参考价值。
一般来说,深度学习都是运行在服务器或者以原生应用的方式运行,而谷歌开源的TensorFlow.js库,则可以让深度学习,高效率的跑在用户的浏览器、Node.js环境甚至微信小程序里面。
前不久,AIZOO大佬开源的口罩数据得到了很多粉丝朋友的关注,作者也将Keras框架训练的模型顺利的转成了PyTorch、TensorFlow、MXNet和Caffe模型,并将其对应的推理代码进行了开源。不过,仍然有不少的朋友好奇如何让人脸口罩检测模型跑在本地浏览器里的。今天,作者
就简单的介绍一下。
为此,我们专门建立了一个极简的web demo,里面包含可以在浏览器内部运行人脸口罩检测的全部核心代码,并将其在Github开源了。
https://github.com/statisticszhang/mask-detection-web-demo
如果要体验完整的网页,建议大家还是进入作者
AIZOO部署在AIZOO.com上的网页,链接如下:
https://aizoo.com/face-mask-detection.html
下面,就让作者来简单介绍一下,如何在浏览器内运行深度学习模型。
在介绍本文的主角TensorFlow.js之前,我们先简单的介绍一下浏览器的三大核心编程语言HTML、CSS和javascript。首先,HTML是超文本标记语言的简称,其主要书写网页的主要内容,比如标题、段落、图片等;CSS是层叠样式表的简称,其主要功能就是给内容增加样式,例如修改字体的大小和颜色、网页背景等样式,让网页更美观;而JavaScript则是一门脚本语言,用于交互,例如添加按钮的事件,与服务器端通信,添加网页动画,可以说JavaScript是让网页动起来的。
JavaScript是一门非常强大的语言,该语言诞生于1995年,由网景公司的Brendan Eich开发而成,这位天才程序员,只用了是10天就完成了初版开发,说该语言集成了Java、C、Perl、Python、Scheme等语言的语法特点,非常简单灵活。JavaScript还有一个标准,叫做EcmaScript(简称ES),ES标准规范了JavaScript的基本语法结构,而且该标准在快速的迭代中,自2015年开始,每年都会更新。而遵循ES标准的,还有大名鼎鼎的Typescript,该语言由微软开发,语法比JavaScript更加严格。而TensorFlow.js,正是使用Typescript开发的。
JavaScript语言不仅可以运行在浏览器,2009年,
Ryan Dahl将谷歌的Chrome V8引擎(谷歌开发的JavaScript的解释器)移植到服务器端,从此,JavaScript不仅可以运行在浏览器内部,还可以运行在服务器端,使得该语言可以与Python、php等脚本语言平起平坐。
好的,关于前端的基本知识,就铺垫这么多,下面,我们介绍一下本文的核心,TensorFlow.js。
谷歌开源的TensorFlow框架,不仅开发了Python、Swift和Java等语言的接口,使得TensorFlow可以运行在PC、ios、安卓等设备,另外,谷歌还为浏览器环境和Node.js环境开发了JavaScript版本,也就是TensorFlow.js。借助TensorFlow.js,我们可以很方便的在浏览器里面进行深度学习的推理,甚至训练。谷歌官方也给出了大量的示例。链接如下:
https://github.com/tensorflow/tfjs-models
在浏览器内使用TensorFlow.js与python比较类似,可以说很多API使用都是非常类似的风格,大家来感受一下:
上图中,我们定义了一个2x2的矩阵,然后将其reshape成4x1维,如果有python使用TensorFlow的经验,可以说非常容易上手TensorFlow.js。在TensorFlow的python接口中常用的add、concat、div、nonMaxSuppression等函数,JS版本都有同名的函数,用起来也非常方便。
限于篇幅原因,这里不再过多介绍TensorFlow.js,具体的大家可以上TensorFlow官网查看教程。下面,我们说一下如何在浏览器实现人脸口罩检测。
可能有些朋友并不是很清楚目标检测模型的推理过程,这里,元峰简单的介绍一下。因为我们使用的是SSD模型架构进行人脸口罩检测,这里就以其为例进行介绍。
Faster-RCNN、SSD、Yolo v3等算法的一个共同点,就是他们都是基于锚点(anchor)的。锚点,简单来说,就是在图像上设置的密集的、不同大小和长宽比的参照框,下面是《动手学深度学习》这本书中的示例图。
如上图所示,是在输出大小为4x4、2x2、1x1大小上进行设置的anchor,每个位置有3个不同大小、不同长宽比的anchor。
当然,
对于一般的网络,
anchor是
非常密集的,
例如,SSD
作者
是在38x
38、
1
9x
1
9、
10
x1
0、
5x5、
3x3、
1
x
1的
特征图上设置
的anchor。
而神经网路的输出,则是相对于anchor的中心点、长和宽的偏移量,以及该anchor内有何种物体(猫和狗)的置信度。所以,在SSD模型推理的时候,也就是根据预设的anchor,
解码出真实的物体坐标,然后做
非最大值抑制操作即可。
所以,基于SSD检测模型推理,我们只需要实现以下三大操作,写三个函数就OK了。
全部anchors生成
网络输出值根据生成的anchors解码
非最大值抑制
我们在Github上开源的代码中,在detection.js文件中,实现了以上三大函数,分别为:
function anchorGenerator()
function decodeBBox()
function nonMaxSuppression()
我们先生成anchors,然后得到网络的输出 -> 解码 -> 非最大抑制 -> 得到输出, 最后将网络的结果画到图片上,整个过程就完成了。
等等,说到这里,我们好像没讲怎么在浏览器得到网络输出。下面,我们介绍一下如何在浏览器运行网络。
我们一般使用TensorFlow或者Keras训练模型,然后保存为pb或者hdf5模型,但是这个模型,并不能直接使用TensorFlow.js加载模型进行前向推理,需要使用工具,转换为TensorFlow.js支持的模型格式。
我们需要先下载相应的转换工具tensorflowjs,然后运行转换tensorflowjs_convert进行模型转换,以keras模型为例:
pip install tensorflowjs // 在本地安装tensorflowjs
// 转换模型
tensorflowjs_convert --input_format keras --output_format tfjs_layers_model /path/to/keras/hdf5/model /path/to/output/folder
模型的输出是一个
model.json
文件和一个或者多个
bin
文件,其中前者保存模型的拓扑,后者保存模型的权重。
接下来,我们在HTML页面添加tensorflow.js文件的引入:
<script src="tfjs.min.js"></script>
我们将检测相关的代码放到detection.js文件中,其中最重要的是要加载模型,我们的模型相对路径为./tfjs-models/model.json,则加载代码为:
model = await tf.loadLayersModel('./tfjs-models/model.json');
对于一个图像,也就是HTML中的image元素,假设该元素名字为imgToPredict,对于模型预测,要先要将image元素转为矩阵,再归一化既可进行前传了。
let img = tf.browser.fromPixels(imgToPredict);
img = tf.image.resizeBilinear(img, [260, 260]);
img = img.expandDims(0).toFloat().div(tf.scalar(255));
const [rawBBoxes, rawConfidences] = model.predict(img);
对于网络的输出,进行解码和非最大抑制,就得到了最终的输出:
const bboxes = decodeBBox(anchors, tf.squeeze(rawBBoxes));
const Results = nonMaxSuppression(bboxes, tf.squeeze(rawConfidences), 0.5, 0.5, width, height);
最终的输出,则包含检测到的物体的坐标和类别,以及相应的置信度,也就是
[xmin, ymin, xmax, ymax, classID, score],我们只需要将结果通过HTML的canvas(画板)控件,将结果画到图像上,结果如下图所示,至此,整个项目就完成了。
关于整个项目的代码,我们已经开源到Github上,感兴趣的用户只需要下载该项目,进入该项目内,打开终端,您可以使用以下方式打开一个web server。
python -m http.server
python -m SimpleHTTPServer
// 您可以使用serve
npm install serve -g //安装serve
serve // 运行该命令即可打开一个web server
// 您也可以使用http-serve
npm install http-server -g
http-server
然后终端会显示本地ip:端口号,例如
127.0.0.1:5000,复制该地址到浏览器,就可以打开网页了,你可以点击“
打开本地图片”按钮选择本地图片,也可以直接拖动一张图片到网页区域,
页面如下。
至此,我们就可以,在浏览器进行口罩检测了。具体代码,大家可以查看我们开源的demo代码。
https://github.com/statisticszhang/mask-detection-web-demo
推荐阅读文章
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
[15]
[16]
[17]
[18]
......
以上是关于开源项目—如何在浏览器运行深度神经网络?以人脸口罩识别为例进行讲解的主要内容,如果未能解决你的问题,请参考以下文章
基于飞桨PaddleHub快速实践口罩人脸检测与分类项目
GitHub开源项目实践人脸口罩检测
深度学习系列18:开源人脸识别库
口罩人脸检测与分类开源代码汇总
MindSpore:不用摘口罩也知道你是谁
给人脸戴上口罩,Python实战项目来了