作为深度学习小白一枚,从一开始摸索如何使用深度学习框架,怎么让脚本跑起来,到现在开始逐步读懂论文,看懂模型的网络结构,按照飞桨官方文档进行各种模型训练和部署,整个过程遇到了无数问题。非常感谢飞桨开源社区的大力支持,并热情答复我遇到的各种问题,使得我可以快速上手。特整理本篇学习笔记,以此回馈网友们的无私付出。大家都共享一点点,一起为深度学习的推进添砖加瓦(哈哈,非常正能量,有木有!)

这篇文章详细记录了如何使用百度深度学习平台——飞桨进行SSD目标检测模型的训练、以及如何将模型部署到服务器和移动端。文末给出了笔者认为非常有用的资料链接。

本文的代码基于百度AI Studio官方示例代码,并能够在飞桨 1.7.1上跑通,Python版本是3.7。

SSD模型介绍

如果你对经典的CNN模型比较熟悉的话,那么SSD也并不难理解。SSD大体上来说是将图片分为6种不同大小的网格,找到目标中心的落点,确定物体的位置。在分成不同网格之后,会在此之上取到不同数目的先验框,对先验框进行回归、分类预测。先验框的数目足够多,几乎能够涵盖整个图片,因此我们可以找到包含物体的很多个先验框,最后进行非极大抑制就能得到正确结果。

b图就是我们以每个网格为中心,取到的先验框的示例。c图的回归预测找到了目标的位置信息,分类预测确定了物体的类别。a图代表了最终的结果。

上面的两个图片摘自论文_SSD: Single Shot MultiBox Detector_,在论文中SSD是插入到VGG-16网络中的。

通过一个表格我们能够知道我们从不同层中得到的先验框尺寸和数目:

总共我们会获得8732个先验框。

MobileNet 与 SSD结合

前面说到我们可以很方便地将SSD插入到不同网络,那么考虑到我们的应用场景,我们可以使用诸如MobileNet网络来减少计算量。

MobileNet将卷积分为Depthwise和Pointwise两部分,减少了计算量,同时不会损失过多的精度。也因此在移动设备和嵌入式设备上面有很好的应用前景。更多关于MobileNet的理论信息大家可以在网上找到,这里不做过多讲述。

百度AI Studio上官方开源了基于SSD的目标检测模型的代码,代码非常好读,并可以直接在线运行,同时提供了训练好的SSD模型。从代码中我们可以看到,飞桨提供了paddle.fluid.layers.multi_box_head在不同Feature Map上面提取先验框、计算回归坐标等,paddle.fluid.layers.ssd_loss计算loss,paddle.fluid.initializer.MSRAInitializer实现以MSRA的方式初始化权重等等。这些API能够减轻我们的工作量,方便代码编写。官方代码还可以导出,在本地Python 3和飞桨 1.7上执行。

服务器部署

下面我们来使用Paddle Serving作为模型即服务后端。随着飞桨框架推出1.7版本,Paddle Serving也登上了舞台。Paddle Serving提出了模型即服务的理念,致力于简化模型部署到服务器操作,甚至一行命令实现模型部署。有了Paddle Serving,可以大大减轻搭建部署环境的负担。

需要注意的是Paddle Serving目前不支持arm64架构,并且对一些依赖包的版本有要求,所以强烈建议使用Docker进行部署。

首先我们pull到Docker 镜像:

# Run CPU Docker

docker pull hub.baidubce.com/paddlepaddle/serving:0.2.0

docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:0.2.0

docker exec -it test bash

# Run GPU Docker

nvidia-docker pull hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu

nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu

nvidia-docker exec -it test bash

进入容器之后,由于官方缩减了镜像的大小,我们需要手动安装需要的依赖包:

python3 -m pip install paddle_serving_server sentencepiece opencv-python pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

镜像使用的系统是Centos 7,注意直接运行Python的话指向的是Python 2.7.5,你需要使用python3。(Python 2即将停止维护,pip在后续版本也可能不提供支持)。

Paddle Serving与直接利用模型不同的是,除了需要导出inference model以外还需要生成配置文件,定义Feed和Fetch的内容。如果你非常熟悉保存预测模型的接口,那么这并不是一件难事。从零开始训练一个模型,并应用到Paddle Serving,你可以参考官方的端到端从训练到部署全流程

这里我们可以直接利用上文提到的AI Studio的开源项目进行提取,真正的提取代码仅需要两行:

import paddle_serving_client.io as serving_io

serving_io.save_model(

"ssd_model",

"ssd_client_conf",

{'image': img},

{"prediction": box},

inference_program)

前两行定义了我们的模型和客户端配置文件保存位置,后面的两个dict分别表示feed和fetch的内容,官方文档的例子表示这是我们在训练模型时的输入和输出。这里的img和box即为输入网络的img和网络输出的box,我们看下两个的结构。

img:

name: "img"

type {

type: LOD_TENSOR

lod_tensor {

tensor {

data_type: FP32

dims: -1

dims: 3

dims: 300

dims: 300

}

lod_level: 0

}

}

persistable: false

box:

name: "concat_0.tmp_0"

type {

type: LOD_TENSOR

lod_tensor {

tensor {

data_type: FP32

dims: 1917

dims: 4

}

lod_level: 0

}

}

persistable: false

可以在保存预测模型的时候保存Paddle Serving需要的配置项,或者之后从训练的代码中提取出img和box,进行保存。得到Paddle Serving需要的相关文件之后,利用下面的代码将其部署到服务器上(均在容器内进行,保证生成的模型和客户端配置和服务器脚本在同一目录之下):

import os

import sys

import base64

import numpy as np

import importlib

from paddle_serving_app import ImageReader

from multiprocessing import freeze_support

from paddle_serving_server.web_service import WebService

class ImageService(WebService):

def preprocess(self, feed={}, fetch=[]):

reader = ImageReader(image_shape=[3, 300, 300],

image_mean=[0.5, 0.5, 0.5],

image_std=[0.5, 0.5, 0.5])

feed_batch = []

for ins in feed:

if "image" not in ins:

raise ("feed data error!")

sample = base64.b64decode(ins["image"])

img = reader.process_image(sample)

feed_batch.append({"image": img})

return feed_batch, fetch

image_service = ImageService(name="image")

image_service.load_model_config("./ssd_model/")

image_service.prepare_server(

workdir="./work", port=int(9292), device="cpu")

image_service.run_server()

image_service.run_flask()

在代码中先对得到的image进行了resize,然后交给模型处理。这里使用的是CPU进行预测,需要的话可以修改几行代码使其能够在GPU上预测。使用Paddle Serving并不需要安装飞桨,所以不会对服务器造成负担。Paddle Serving内置了数据预处理功能,因此可以直接对图片进行裁剪等操作。

在客户端上,仅仅需要几行代码就能够从服务端获取预测结果:

import requests

import base64

import json

import time

import os

import sys

py_version = sys.version_info[0]

def predict(image_path, server):

if py_version == 2:

image = base64.b64encode(open(image_path).read())

else:

image = base64.b64encode(open(image_path, "rb").read()).decode("utf-8")

req = json.dumps({"feed": [{"image": image}], "fetch": ["prediction"]})

r = requests.post(

server, data=req, headers={"Content-Type": "application/json"}, timeout=60)

try:

print(r.json()["result"]["prediction"])

except ValueError:

print(r.text)

return r

if __name__ == "__main__":

server = "http://[ip]:[port]/image/prediction"

image_list = os.listdir("./images")

start = time.time()

for img in image_list:

image_file = "./images/" + img

res = predict(image_file, server)

end = time.time()

print(end - start)

对图片进行base64编码,发送到服务端,获取结果,非常简洁和方便。在实际部署的过程中,可以在服务端进行反代和鉴权,只需要写一个中间件即可,这也是模型即服务带给大家的便利之处。

我们国内服务端的配置是单核CPU(限制使用时间和频率),算上网络传输和预测的总用时在0.39秒左右,比较快速。返回的数组第一个值代表了对应类别,第二个值代表置信度,后面的值代表坐标比例,实际使用的时候需要设置阈值,放弃可信度较低的值。

移动端部署

移动端部署采用了之前开源的Real-time Object Detector,当时源码中使用的是YOLO v3模型,这里我们将使其适配SSD模型。在端侧部署方面我们使用的是Paddle Lite,这是飞桨系列中的多平台高性能深度学习预测引擎,提供了多平台架构下的预测解决方案,还支持C++/Java/Python等语言。

从上次发文到现在,Paddle Lite已经推出了新的版本,2.3版本对很多东西进行了优化,利用手上的安卓手机(麒麟 810)进行SSD目标检测的用时仅为500ms。这次我们还能够直接使用官方提供的预编译库进行预测,并不需要自己手动编译一次。下载下来之后我们会得到和上次一样的文件,PaddlePredictor.jar和一些so链接库,参考之前的推送文章:如何基于Flutter和Paddle Lite实现实时目标检测,放到相应位置即可。

因为SSD模型的输入和YOLO v3不一样,我们需要对安卓端的Predictor.java进行修改,主要考虑输入的尺寸问题。

// MainActivity.java L41

protected long[] inputShape = new long[]{1, 3, 300, 300};

protected float[] inputMean = new float[]{0.5f, 0.5f, 0.5f};

protected float[] inputStd = new float[]{0.5f, 0.5f, 0.5f};

// Predictor.java L214

// Set input shape

Tensor inputTensor = getInput(0);

inputTensor.resize(inputShape);

// Predictor.java L258

inputTensor.setData(inputData);

// Predictor.java L303

float rawLeft = outputTensor.getFloatData()[i + 2];

float rawTop = outputTensor.getFloatData()[i + 3];

float rawRight = outputTensor.getFloatData()[i + 4];

float rawBottom = outputTensor.getFloatData()[i + 5];

同时我们对于描框的函数进行修改:

// main.dart L127 var ratioW = sizeRed.width / 300; var ratioH = sizeRed.height / 300;

如果在运行的时候出现了空指针错误,很可能你没有升级到最新的预编译库,jar和so文件均需要更新。由于上次发布源码的时候没有在Gradle脚本中设置自动下载库,所以需要手动放置预测库。

写在最后

从一开始熟悉怎么去使用飞桨深度学习平台,怎么让脚本跑起来,到现在开始逐步读懂论文,了解模型的架构,看官方文档,过程中遇到了不少问题。通过分析飞桨官方图像分类示例,查看和修改源码,输出调试信息,还在飞桨官方QQ群中得到了不少帮助,学到了很多东西,并最终完成了这次实践。非常感谢提供帮助的朋友们。飞桨经过多轮更新,在模型训练和部署上也变得非常简单,相信会吸引越来越多的开发者使用。

参考链接:

如果您加入官方QQ群,您将遇上大批志同道合的深度学习同学。飞桨PaddlePaddle交流3群:703252161。

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

官网地址:

飞桨开源框架项目地址:

GitHub:

Gitee:

java移动端部署_飞桨实战笔记:自编写模型如何在服务器和移动端部署相关推荐

  1. 移动端调取摄像头上面如何给出框_飞桨实战笔记:自编写模型如何在服务器和移动端部署...

    ​ 作为深度学习小白一枚,从一开始摸索如何使用深度学习框架,怎么让脚本跑起来,到现在开始逐步读懂论文,看懂模型的网络结构,按照飞桨官方文档进行各种模型训练和部署,整个过程遇到了无数问题.非常感谢飞桨开 ...

  2. 飞桨模型保存_飞桨实战笔记:自编写模型如何在服务器和移动端部署

    ​ 作为深度学习小白一枚,从一开始摸索如何使用深度学习框架,怎么让脚本跑起来,到现在开始逐步读懂论文,看懂模型的网络结构,按照飞桨官方文档进行各种模型训练和部署,整个过程遇到了无数问题.非常感谢飞桨开 ...

  3. output怎么用_性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库

    允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 假如问在深度学习实践中,最难的部分是什么?猜测80%的开发者都会说: "当然是调参啊." 为什么难呢?因为调参就像厨师根 ...

  4. 性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库

    允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 假如问在深度学习实践中,最难的部分是什么?猜测80%的开发者都会说: "当然是调参啊." 为什么难呢?因为调参就像厨师根 ...

  5. PaddlePaddle飞桨OCR文本检测——检测模型训练(二)

    上一篇安装https://blog.csdn.net/weixin_42845306/article/details/112688405 飞桨的OCR模型分为检测.识别和分类,先看检测. 检测就是将( ...

  6. pyqt label 设值时会进行加法_飞桨与PyQt的碰撞,图形化目标检测So Easy

    还记得3月份的时候我给大家介绍了PaddleDetection的环境部署.训练及可视化.模型导出.但那只是一个算法程序,一个完整的项目需要在算法的基础上将可视化操作开发成型.今天我给大家带来如何利用P ...

  7. 飞桨框架2.0正式版重磅发布,一次端到端的“基础设施”革新

    在人工智能时代,深度学习框架下接芯片,上承各种应用,是"智能时代的操作系统".近期,我国首个自主研发.功能完备.开源开放的产业级深度学习框架飞桨发布了2.0正式版,实现了一次跨时代 ...

  8. texstudio自动拼写检测_飞桨PaddleDetection物体检测统一框架详解

    目标检测是机器视觉领域的核心问题之一.7 月 3 日百度 AI 开发者大会,飞桨核心框架 Paddle Fluid v1.5 宣布开源了 PaddleDetection 物体检测统一框架,用户可以非常 ...

  9. 飞桨模型保存_飞桨对话模型工具箱(二):对话自动评估模块ADE

    1. 对话自动评估 随着对话系统的不断发展和成熟,如何评价对话系统的回复质量,成为了一个新的研究方向. 对话自动评估技术,能够帮助企业或个人快速评估对话系统的回复质量,减少人工评估成本,具有重要的商业 ...

  10. 强烈推荐 | 基于飞桨的五大目标检测模型实战详解

    机器视觉领域的核心问题之一就是目标检测(object detection),它的任务是找出图像当中所有感兴趣的目标(物体),确定其位置和大小.对于人类来说,目标检测是一个非常简单的任务.然而,计算机能 ...

最新文章

  1. D1net阅闻:思科占全球交换路由器53%市场份额
  2. [转]学习Objective-C: 入门教材
  3. 启动oracle em命令
  4. Unable to resolve dependency for xxx, Could not resolve project
  5. Apache Ignite本机持久性,简要概述
  6. centos mysql 服务器_服务器数据库搭建流程(CentOs+mysql)
  7. IDEA 安装JUnitGenerator V2.0 插件 帮助生成单元测试
  8. 面试准备——Java回顾:高级编程(多线程、常用类、集合、泛型、IO流、反射、动态代理、新特性)
  9. 单片机最小系统着实让人着迷
  10. python股票交易接口是什么_python 股票交易接口【怎样用 Python 写一个股票自动交易的程序】...
  11. 学术会议将变革?Hinton 呼吁 AI 界召开远程会议
  12. 报表数据源之Hadoop
  13. 区块链主要的核心内容
  14. cygwin安装linux教程,Cygwin,让你拥有Windows下的Linux环境
  15. ArrayBuffer DataView
  16. IDempiere 富文本编辑器优化
  17. (转)当AI变成宣传武器:继续深扒大数据公司Cambrige Analytica
  18. jquery加载页面的几种方法(页面加载完成就执行)
  19. Verilog 语法(二)···············简单入门
  20. 对于区块链的曲解和误会,多半停留在人们对于其呈现方式的狭隘的认识上

热门文章

  1. cortex a7 a9 linux,cortex a7 a8 a9区别
  2. 空间域和频域结合的图像增强技术及实现
  3. windows10 给指定扩展名扩展名添加右键菜单
  4. 字根校对-中文校对软件
  5. vmware服务器虚拟化培训视频教程,目前网上关于vSphere最详细的视频教程 vSphere全套经典培训视频教程 VMware课程超清...
  6. 北京大学王悦博士给学生的话
  7. 艾永亮:产品创新的重要性,创新的意义和思路
  8. 让ImageMagick支持png和jpeg格式
  9. 上传图片到腾讯云(海外服务器)com.qcloud5.5.4版本
  10. TP4056调试笔记