1. 首页 > 综合百科 > Paddlepaddle从零开始 试用Edgeboard模型

Paddlepaddle从零开始 试用Edgeboard模型

作者 Litchll

摘要:前言 在上一周的测试中,我们按照官方给的流程,使用EasyDl快速实现了一个具有性别检测功能的人脸识别系统,那么 今天,我们将要试一下通过Paddlepaddle从零开始,训练一个自己的多分类模型,并进行嵌入式部署。 整个训练 过程和模型在:https://aistudio.baidu.com/aistudio/projectDetail/61103 下面详细介绍模型训练...

前言

在上一周的测试中,我们按照官方给的流程,使用EasyDl快速实现了一个具有性别检测功能的人脸识别系统,那么

今天,我们将要试一下通过Paddlepaddle从零开始,训练一个自己的多分类模型,并进行嵌入式部署。 整个训练

过程和模型在:https://aistudio.baidu.com/aistudio/projectDetail/61103 下面详细介绍模型训练的过程.

数据集准备

我们使用CIFAR10数据集。CIFAR10数据集包含60,000张32x32的彩色图片,10个类别,每个类包含6,000张。其中

50,000张图片作为训练集,10000张作为验证集。

1.!mkdir‐p/home/aistudio/.cache/paddle/dataset/cifar

2.#wget将下载的文件存放到指定的文件夹下,同时重命名下载的文件,利用‐O

3.!wget"http://ai‐atest.bj.bcebos.com/cifar‐10‐python.tar.gz"‐Ocifar‐10‐python.tar.gz

4.!mvcifar‐10‐python.tar.gz/home/aistudio/.cache/paddle/dataset/cifar/

模型结构

我们选择了以三个卷积层串联一个全连接层的输出,作为猫狗分类的预测,采用固定维度输入,输出为分类数

1.defconvolutional_neural_network(img):

2.#第一个卷积‐池化层

3.conv_pool_1=fluid.nets.simple_img_conv_pool(

4.input=img,#输入图像

5.filter_size=5,#滤波器的大小

6.num_filters=20,#filter的数量。它与输出的通道相同

7.pool_size=2,#池化层大小2*2

8.pool_stride=2,#池化层步长

9.act="relu")#激活类型

10.#第二个卷积‐池化层

11.conv_pool_2=fluid.nets.simple_img_conv_pool(

12.input=conv_pool_1,

13.filter_size=5,

14.num_filters=50,

15.pool_size=2,

16.pool_stride=2,

17.act="relu")

18.#第三个卷积‐池化层

19.conv_pool_3=fluid.nets.simple_img_conv_pool(

20.input=conv_pool_2,

21.filter_size=5,

22.num_filters=50,

23.pool_size=2,

24.pool_stride=2,

25.act="relu")

26.#以softmax为激活函数的全连接输出层,10类数据输出10个数字

27.prediction=fluid.layers.fc(input=conv_pool_3,size=10,act='softmax')

28.returnprediction

训练&验证

接下来在Paddlepaddle fluid上,进行训练。整个训练代码见附件train.py 模型验证,采用附件predict.py的代码进

行验证与运行时间的测量,选取一张狗的图:dog.jpg (可以fork首页链接aistudio平台上的demo) 连续预测10000

次,输出如下:

1.CPU运行结果为:预处理时间为0.0006270000000085929,预测时间为:16.246494

2.Out:

3.im_shape的维度:(1,3,32,32)

4.Theruntimeofimageprocessis

5.0.0006270000000085929

6.Theruntimeofpredictis

7.16.246494

8.results[array([[5.0159363e‐04,3.5942634e‐05,2.5955746e‐02,4.7745958e‐02,

9. 9.9251214e‐03,9.0146154e‐01,1.9564393e‐03,1.2230080e‐02,

10. 4.7619540e‐08,1.8753216e‐04]],dtype=float32)]

11.inferresults:dog

1.GPUV100运行结果为:预处理时间为0.0006390000000067175,预测时间为:15.903074000000018

2.Out:

3.im_shape的维度:(1,3,32,32)

4.Theruntimeofimageprocessis

5.0.0006390000000067175

6.Theruntimeofpredictis

7.15.903074000000018

8.results[array([[5.0159392e‐04,3.5942641e‐05,2.5955772e‐02,4.7746032e‐02,

9. 9.9251205e‐03,9.0146142e‐01,1.9564414e‐03,1.2230078e‐02,

10. 4.7619821e‐08,1.8753250e‐04]],dtype=float32)]

11.inferresults:dog

可以看到,模型可以正确的识别出图片中的动物为狗,接下来,我们就要尝试将这个模型部署到Edgeboard上面。

模型导出

我们需要将模型保存为模型文件model以及权重文件params,可以采用如下Paddle的API进行保存如图所示,在AiStudio的左侧打开模型文件所在的文件夹,下载mlp-model、mlp-params两个文件。

在Edgeboard上部署模型,完成预测

1、新建工程文件夹,目录结构如下(可以仿照sample里的resnet、inception例程):

1.‐sample_image_catdog

2.‐build

3.‐image

4.‐include

5.‐paddlepaddle‐mobile

6.‐...

7.‐lib

8.‐libpaddle‐mobile.so

9.‐model

10.‐mlp

11.‐model

12.‐params

13.‐src

14.‐fpga_cv.cpp

15.‐main.cpp

2、将AiStudio上导出来的模型放置在model里的mlp文件夹,修改名字为model、params

3、新建 CMakeLists.txt

1.cmake_minimum_required(VERSION3.5.1)

2.project(paddle_edgeboard)

3.set(CMAKE_CXX_STANDARD14)

4.set(CMAKE_EXE_LINKER_FLAGS"${CMAKE_EXE_LINKER_FLAGS}‐pthread")

5.add_definitions(‐DPADDLE_MOBILE_FPGA_V1)

6.add_definitions(‐DPADDLE_MOBILE_FPGA)

7.set(PADDLE_LIB_DIR"${PROJECT_SOURCE_DIR}/lib")

8.set(EASYDL_INCLUDE_DIR"${PROJECT_SOURCE_DIR}/include")

9.set(PADDLE_INCLUDE_DIR"${PROJECT_SOURCE_DIR}/include/paddle‐mobile")

10.set(APP_NAME"paddle_edgeboard")

11.aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/srcSRC)

12.find_package(OpenCVQUIETCOMPONENTScorevideoiohighguiimgprocimgcodecsmlvideo)

13.include_directories(SYSTEM${OpenCV_INCLUDE_DIRS})

14.#list(APPENDCaffe_LINKER_LIBS${OpenCV_LIBS})

15.message(STATUS"OpenCVfound(${OpenCV_CONFIG_PATH}),${OpenCV_LIBS}")

16.#add_definitions(‐DUSE_OPENCV)

17.include_directories(${EASYDL_INCLUDE_DIR})

18.include_directories(${PADDLE_INCLUDE_DIR})

19.LINK_DIRECTORIES(${PADDLE_LIB_DIR})

20.add_executable(${APP_NAME}${SRC})

21.target_link_libraries(${APP_NAME}paddle‐mobile)

22.target_link_libraries(${APP_NAME}${OpenCV_LIBS})

4、main.cpp

1.#include

<

iostream

>

2.#include"io/paddle_inference_api.h"

3.#include"math.h"

4.#include

<

stdlib.h

>

5.#include

<

unistd.h

>

6.#include

<

fstream

>

7.#include

<

ostream

>

8.#include

<

fstream

>

9.#include

<

iomanip

>

10.#include

<

typeinfo

>

11.#include

<

typeindex

>

12.#include

<

vector

>

13.#include

<

ctime

>

14.#include"fpga/KD/float16.hpp"

15.#include"fpga/KD/llapi/zynqmp_api.h"

16.usingnamespacepaddle_mobile;

17.#include

<

opencv2/highgui.hpp

>

18.#include

<

opencv2/imgproc.hpp

>

19.usingnamespacecv;

20.cv::Matsample_float;

21.staticstd::vector

<

std::string

>

label_list(10);

22.voidreadImage(std::stringfilename,float*buffer){

23.Matimg=imread(filename);

24.if(img.empty()){

25.std::cerr

<

<

"Can'treadimagefromthefile:"

<

<

filename

<

<

std::endl;

26.exit(1);

27.}

28.Matimg2;

29.resize(img,img2,Size(32,32));

30.img2.convertTo(sample_float,CV_32FC3);

31.intindex=0;

32.for(introw=0;row

<

sample_float.rows;++row){

33.float*ptr=(float*)sample_float.ptr(row);

34.for(intcol=0;col

<

sample_float.cols;col++){

35.float*uc_pixel=ptr;

36.//uc_pixel[0]‐=102;

37.//uc_pixel[1]‐=117;

38.//uc_pixel[1]‐=124;

39.floatr=uc_pixel[0];

40.floatg=uc_pixel[1];

41.floatb=uc_pixel[2];

42.buffer[index]=b/255.0;

43.buffer[index+1]=g/255.0;

44.buffer[index+2]=r/255.0;

45.//sum+=a+b+c;

46.ptr+=3;

47.//DLOG

<

<

"r:"

<

<

r

<

<

"g:"

<

<

g

<

<

"b:"

<

<

b;

48.index+=3;

49.}

50.}

51.//returnsample_float;

52.}

53.PaddleMobileConfigGetConfig(){

54.PaddleMobileConfigconfig;

55.config.precision=PaddleMobileConfig::FP32;

56.config.device=PaddleMobileConfig::kFPGA;

57.//config.model_dir="../models/mobilenet/";

58.config.prog_file="../model/mlp/model";

59.config.param_file="../model/mlp/params";

60.config.thread_num=4;

61.returnconfig;

62.}

63.intmain(){

64.clock_tstartTime,endTime;

65.zynqmp::open_device();

66.std::cout

<

<

"open_devicesuccess"

<

<

std::endl;

67.PaddleMobileConfigconfig=GetConfig();

68.std::cout

<

<

"GetConfigsuccess"

<

<

std::endl;

69.autopredictor=

70.CreatePaddlePredictor

<

PaddleMobileConfig,

71.PaddleEngineKind::kPaddleMobile

>

(config);

72.std::cout

<

<

"predictorsuccess"

<

<

std::endl;

73.startTime=clock();//计时开始

74.floatdata[1*3*32*32]={1.0f};

75.readImage("../image/cat.jpg",data);

76.endTime=clock();//计时结束

77.std::cout

<

<

"Theruntimeofimageprocessis:"

<

<

(double)(endTime‐startTime)/

78.CLOCKS_PER_SEC

<

<

"s"

<

<

std::endl;

79.PaddleTensortensor;

80.tensor.shape=std::vector

<

int

>

({1,3,32,32});

81.tensor.data=PaddleBuf(data,sizeof(data));

82.tensor.dtype=PaddleDType::FLOAT32;

83.std::vector

<

PaddleTensor

>

paddle_tensor_feeds(1,tensor);

84.PaddleTensortensor_out;

85.tensor_out.shape=std::vector

<

int

>

({});

86.tensor_out.data=PaddleBuf();

87.tensor_out.dtype=PaddleDType::FLOAT32;

88.std::vector

<

PaddleTensor

>

outputs(1,tensor_out);

89.std::cout

<

<

"beforepredict"

<

<

std::endl;

90.predictor‐

>

Run(paddle_tensor_feeds,&outputs);

91.std::cout

<

<

"afterpredict"

<

<

std::endl;

92.//assert();

93.endTime=clock();//计时结束

94.std::cout<<"Theruntimeofpredictis:"<<(double)(endTime‐startTime)/CLOCKS_PER_SEC

95.<

<

"s"

<

<

std::endl;

96.float*data_o=static_cast

<

float*

>

(outputs[0].data.data());

97.for(size_tj=0;j

<

outputs[0].data.length()/sizeof(float);++j){

98.std::cout

<

<

"output["

<

<

j

<

<

"]:"

<

<

data_o[j]

<

<

std::endl;

99.}

100.intindex=0;

101.floatmax=0.0;

102.for(inti=0;i

<

10;i++){

103.floatval=data_o[i];

104.if(val

>

max){

105.max=val

>

max?val:max;

106.iindex=i;

107.}

108.}

109.label_list={"airplane","automobile","bird","cat","deer","dog","frog","horse",

110."ship","truck"};

111.std::cout

<

<

"Result"

<

<

"is"

<

<

label_list[index]

<

<

std::endl;

112.return0;

113.}

5、编译运行

1.insmod/home/root/workspace/driver/fpgadrv.ko

2.cd/home/root/workspace/sample/sample_image_catdog

3.mkdirbuild

4.cdbuild

5.rm‐rf*

6.cmake..

7.make

8../paddle_edgeboard

修改main文件要预测的图像:

6、修改main文件后重复执行预测,可得结果如下:图像处理时间大概为:0.006秒,预测时间大概为:0.008秒

7、连续预测10000次所用时间为:23.7168

性能对比(连续预测10000次 单位:秒)

优点:

1. EdgeBoard内置的Paddle-Mobile,可以与Paddle训练出来的模型进行较好的对接。

2. 预测速度上: Edge在预测小模型的时候,能与双核CPU和GPU在一个数量级,估计是模型较小,batch size也

为1,gpu,cpu的性能优势抵不过通信的开销,后续将进行大模型、高batch size的测试。

3. 提供的demo也足够简单,修改起来难度很低。

不足:

1. Paddle-Mobile相关文档具有一定门槛,且较为分散。初次使用的时候会走一些弯路出现问题的时候往往是个

黑盒,不易于定位。在这次进行模型训练的尝试中,出现过一次op不支持的情况,我们在官网上甚至没有找

到支持的op列表,这个在开发哥们的支持下升级版本后解决。如果后续能在稳定的固件版本下使用,并有比

较易用的sdk,开发门槛可能会进一步降低。