乐趣区

关于深度学习:PaddlePaddle在-Serverless-架构上十几行代码实现-OCR-能力


飞桨 (PaddlePaddle) 以百度多年的深度学习技术钻研和业务利用为根底,是中国首个自主研发、性能齐备、开源凋谢的产业级深度学习平台,集深度学习外围训练和推理框架、根底模型库、端到端开发套件和丰盛的工具组件于一体。

飞桨深度学习框架采纳基于编程逻辑的组网范式,对于一般开发者而言更容易上手,同时反对申明式和命令式编程,兼具开发的灵活性和高性能。另外飞桨不仅宽泛兼容第三方开源框架训练的模型部署,并且为不同的场景的生产环境提供了齐备的推理引擎。

包含实用于高性能服务器及云端推理的原生推理库 Paddle Inference,面向分布式、流水线生产环境下主动上云、A/B 测试等高阶性能的服务化推理框架 Paddle Serving,针对于挪动端、物联网场景的轻量化推理引擎 Paddle Lite,以及在浏览器、小程序等环境下应用的前端推理引擎 Paddle.js。同时,透过与不同场景下的支流硬件高度适配优化及异构计算的反对, 飞桨的推理性能也当先绝大部分的支流实现。

装置飞桨


飞桨能够被认为是一个 Python 的依赖库,官网提供了 pip,conda,源码编译等多种装置办法。以 pip 装置办法为例,飞桨提供了 CPU 和 GPU 两个版本装置办法:

  • CPU 版本装置办法:

pip install paddlepaddle

  • GPU 版本装置办法:

pip install paddlepaddle-gpu

实际:手写数字辨认工作


MNIST 是十分有名的手写体数字辨认数据集,在无论是 Tensorflow 的官方网站还是 PaddlePaddle 的新手入门,都是通过它做实战解说,它由手写体数字的图片和绝对应的标签组成,如:


MNIST 数据集分为训练图像和测试图像。训练图像 60000 张,测试图像 10000 张,每一个图片代表 0-9 中的一个数字,且图片大小均为 28*28 的矩阵。这一大节将会以 PaddlePaddle 官网提供的 MNIST 手写数字辨认工作为例,进行 PaddlePaddle 框架的根本学习。与其余深度学习工作一样,飞桨同样要通过以下四个步骤实现一个绝对残缺的深度学习工作:

  1. 数据集的筹备和加载;
  2. 模型构建;
  3. 模型训练;
  4. 模型评估。

    加载内置数据集

飞桨框架内置了一些常见的数据集,在这个示例中,开发者能够加载飞桨框架的内置数据集,例如本案例所波及到的手写数字体数据集。这里加载两个数据集,一个用来训练模型,一个用来评估模型。

import paddle.vision.transforms as T
transform = T.Normalize(mean=[127.5], std=[127.5], data_format=’CHW’)
下载数据集
train_dataset = paddle.vision.datasets.MNIST(mode=’train’,
transform=transform)
val_dataset =  paddle.vision.datasets.MNIST(mode=’test’, > transform=transform)

模型搭建

通过 Sequential 将一层一层的网络结构组建起来。留神,须要先对数据进行 Flatten 操作,将 [1, 28, 28] 形态的图片数据扭转形态为 [1, 784]。

mnist = paddle.nn.Sequential(
paddle.nn.Flatten(),
paddle.nn.Linear(784, 512),
paddle.nn.ReLU(),
paddle.nn.Dropout(0.2),
paddle.nn.Linear(512, 10))

模型训练

在训练模型前,须要配置训练模型时损失的计算方法与优化办法,开发者能够应用飞桨框架提供的 prepare 实现,之后应用 fit 接口来开始训练模型。

# 预计模型构造生成模型对象,便于进行后续的配置、训练和验证
model = paddle.Model(mnist)
_# 模型训练相干配置,筹备损失计算方法,优化器和精度计算方法_model.prepare(paddle.optimizer.Adam(parameters=model.parameters()), paddle.nn.CrossEntropyLoss(),                
paddle.metric.Accuracy())
# 开始模型训练
model.fit(train_dataset,
epochs=5,
batch_size=64,
verbose=1)

训练后果:

The loss value printed in the log is the current step, and the metric is the average value of previous steps.Epoch 1/5step 938/938 [==============================] – loss: 0.1801 – acc: 0.9032 – 8ms/stepEpoch 2/5step 938/938 [==============================] – loss: 0.0544 – acc: 0.9502 – 8ms/stepEpoch 3/5step 938/938 [==============================] – loss: 0.0069 – acc: 0.9595 – 7ms/stepEpoch 4/5step 938/938 [==============================] – loss: 0.0094 – acc: 0.9638 – 7ms/stepEpoch 5/5step 938/938 [==============================] – loss: 0.1414 – acc: 0.9670 – 8ms/step

模型评估

开发者能够应用事后定义的验证数据集来评估前一步训练失去的模型的精度。

model.evaluate(val_dataset, verbose=0)

后果如下:

{‘loss’: [2.145765e-06], ‘acc’: 0.9751}


能够看出,初步训练失去的模型成果在 97.5% 左近,在逐步理解飞桨后,开发者能够通过调整其中的训练参数来晋升模型的精度。

与 Serverless 架构联合

PaddlePaddle 团队首次开源文字辨认模型套件 PaddleOCR,指标是打造丰盛、当先、实用的文本辨认模型 / 工具库。该模型套件是一个实用的超轻量 OCR 零碎。次要由 DB 文本检测、检测框改正和 CRNN 文本辨认三局部组成。该零碎从骨干网络抉择和调整、预测头部的设计、数据加强、学习率变换策略、正则化参数抉择、预训练模型应用以及模型主动裁剪量化 8 个方面,采纳 19 个无效策略,对各个模块的模型进行成果调优和瘦身,最终失去整体大小为 3.5M 的超轻量中英文 OCR 和 2.8M 的英文数字 OCR。

本地开发

# index.py
import base64
import bottle
import random
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_gpu=False)
@bottle.route(‘/ocr’, method=’POST’)
def login():
filePath = ‘./temp/’ + (”.join(random.sample(‘zyxwvutsrqponmlkjihgfedcba’, 5)))
with open(filePath, ‘wb’) as f:
f.write(base64.b64decode(bottle.request.body.read().decode(“utf-8”).split(‘,’)[1]))
ocrResult = ocr.ocr(filePath, cls=False)    
return {‘result’: [line[1, float(line1)] for line in ocrResult]}
bottle.run(host=’0.0.0.0′, port=8080)

开发实现之后,运行该我的项目:

python index.py


能够看到服务曾经启动:



而后通过 Postman 工具进行测试,首先筹备一张图片(此处以 PaddleOCR 我的项目内置的测试图片为例):


通过将图片转换为 Base64 编码,并以 POST 办法申请刚刚启动的 Web 服务,能够看到 PaddleOCR 的执行后果:

部署到 Serverless 架构

目前各大云厂商的 FaaS 平台均曾经逐步反对容器镜像部署。所以,能够将我的项目打包成镜像,并通过 Serverless Devs 部署到阿里云函数计算。

部署前筹备


首先须要实现 Dockerfile 文件:

FROM python:3.7-slim
RUN apt update && apt install gcc libglib2.0-dev libgl1-mesa-glx libsm6 libxrender1 -y && pip install paddlepaddle bottle scikit-build paddleocrle scikit-build paddleocr
# Create app directory
WORKDIR /usr/src/app
# Bundle app source
COPY . .


编写合乎 Serverless Devs 标准的 Yaml 文档:

# s.yaml
edition: 1.0.0
name: paddle-ocr
access: default
services:
paddle-ocr:
component: fc
props:
region: cn-shanghai
service:
name: paddle-ocr
description: paddle-ocr service
function:
name: paddle-ocr-function
runtime: custom-container
caPort: 8080
codeUri: ./
timeout: 60
customContainerConfig:
image: ‘registry.cn-shanghai.aliyuncs.com/custom-container/paddle-ocr:0.0.1’
command: ‘[“python”]’
args: ‘[“index.py”]’
triggers:

  • name: httpTrigger
    type: http
    config:
    authType: anonymous
    methods:
  • GET
  • POST
    customDomains:
  • domainName: auto
    protocol: HTTP
    routeConfigs:
  • path: /*
我的项目部署

首先构建镜像,此处能够通过 Serverless Devs 进行构建:

s build –use-docker


构建实现之后,能够通过工具间接进行部署:

s deploy –push-registry acr-internet –use-local -y

部署实现,能够看到零碎返回的测试地址:

我的项目测试

此时,能够通过该测试地址进行测试,同样失去了预期成果:

我的项目优化

通过对部署在 Serverless 架构上的我的项目进行申请,能够看到冷启动和热启动的工夫耗费:


通过冷启动与热启动的比照,咱们能够发现,在热启动时,整个零碎的性能是绝对优良的。然而遇到冷启动整个我的项目的响应时常是不可控的,此时能够考虑一下路径进行优化:

  1. 缩减容器镜像的体积,缩小不必要的依赖、文件等,清理掉装置依赖时留下的缓存等;因为函数计算的冷启动包含镜像拉取工夫;
  2. 局部流程进行优化,例如在 PaddleOCR 我的项目中有明确阐明:“paddleocr 会主动下载 ppocr 轻量级模型作为默认模型”,所以这就意味着该我的项目在 Serverless 架构的冷启动过程中,绝对比热启动还减少了一个模型下载和解压的流程,所以这一部分在必要时是能够打入到容器镜像中,进而缩小冷启动带来的影响;
  3. 开启镜像减速,能够无效升高容器镜像的冷启动,在阿里云函数计算官网文档中有相干镜像减速的性能测试形容:“开启函数计算的镜像减速后,可提速 2~5 倍,将分钟级的镜像拉取缩短至秒级”;
  4. 实例预留,最大水平上升高冷启动率。通过实例预留,能够通过多种算法 / 策略进行实例的预热和预启动,能够最大水平上升高 Serverless 架构冷启动带来的影响;

退出移动版