PaddlePaddle 移动端(一),在Android shell下运行PaddlePaddle

企业动态
这篇文章以Android shell下运行图像分类模型为例子来讲述如何入门PaddlePaddle移动端。

 我们可以在https://github.com/PaddlePaddle/Mobile/ 找到关于PaddlePaddle应用于移动端的demo和例子。这篇文章以Android shell下运行图像分类模型为例子来讲述如何入门PaddlePaddle移动端。

内容

  • PaddlePaddle训练移动端的分类模型
  • 对PaddlePaddle进行Android 交叉编译
  • Android shell 下运行分类模型

PaddlePaddle训练移动端的分类模型

在Android shell下运行PaddlePaddle 模型,我们要准备一个适用于一个移动端的分类模型。Repo 下提供了适用于移动端的mobilenet模型,我们用这个模型来对花卉进行分类。
一,下载mobilenet配置文件

wget https://raw.githubusercontent.com/PaddlePaddle/Mobile/develop/models/standard_network/mobilenet.py 

二,下载pre-trained 模型参数文件
在百度云上下载在imagenet上预训练的mobilenet模型参数 imagenet_pretrained_mobilenet.tar.gz
三,在imagenet模型上对flower102数据集进行微调(fine-tune)
拷贝以下代码,然后运行,会在每个epoch 后保存参数文件。可以点击此处 下载好我已经训练的模型参数。

import sys import gzip  from paddle.trainer_config_helpers import * import paddle.v2 as paddle from mobilenet import mobile_net  # batch 大小是40 BATCH = 40  def main():     datadim = 3 * 224 * 224     classdim = 102      #  采用gpu训练并使用***块卡     paddle.init(use_gpu=True, trainer_count=1, gpu_id=0)      momentum_optimizer = paddle.optimizer.Momentum(         momentum=0.9,         regularization=paddle.optimizer.L2Regularization(rate=0.0005 * BATCH),         learning_rate=0.001 / BATCH,         learning_rate_schedule='constant')      out = mobile_net(datadim, classdim, 1.0)      lbl = paddle.layer.data(         name="label", type=paddle.data_type.integer_value(classdim))     cost = paddle.layer.classification_cost(input=out, label=lbl)      # Create parameters     parameters = paddle.parameters.create(cost)     # 加载imagenet 预训练的模型参数     with gzip.open('imagenet_pretrained_mobilenet.tar.gz', 'r') as f:         fparameters = paddle.parameters.Parameters.from_tar(f)     for param_name in fparameters.names():         if param_name in parameters.names():             parameters.set(param_name, fparameters.get(param_name))      # End batch and end pass event handler     def event_handler(event):         if isinstance(event, paddle.event.EndIteration):             if event.batch_id % 50 == 0:                 print "\nPass %d, Batch %d, Cost %f, %s" % (                     event.pass_id, event.batch_id, event.cost, event.metrics)             else:                 sys.stdout.write('.')                 sys.stdout.flush()         if isinstance(event, paddle.event.EndPass):             # save parameters             with gzip.open('pruning_mobilenet_params_pass_%d.tar.gz' %                            event.pass_id, 'w') as f:                 parameters.to_tar(f)              result = trainer.test(                 reader=paddle.batch(                     paddle.dataset.flowers.test(), batch_size=10),                 feeding={'image': 0,                          'label': 1})             print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)      # Create trainer     trainer = paddle.trainer.SGD(         cost=cost, parameters=parameters, update_equation=momentum_optimizer)     trainer.train(         reader=paddle.batch(             paddle.reader.shuffle(                 paddle.dataset.flowers.train(), buf_size=50000),             batch_size=BATCH),         num_passes=100,         event_handler=event_handler,         feeding={'image': 0,                  'label': 1})   if __name__ == '__main__':     main() 

经过微调我们的分类精度可以达到98% 左右。 现在我们有了一个.py 文件,表示模型的配置文件, 还有一个.tar.gz文件,表示模型的参数文件, 这两个文件组成了***的一个模型。

Android 交叉编译PaddlePaddle

我们需要让PaddlePaddle运行在Android平台,需要在linux或者mac下编译出能在android或者ios平台下运行的PaddlePaddle库文件。这个过程为交叉编译。

Paddle repo下提供了关于如何在android平台下进行交叉编译PaddlePaddle:
在链接相关页面中提供了两种方式, 一种是通过docker的方式,一种基于自定义独立工具链编译方式, 这两种方式,我都进行了实验,个人比较倾向于自定义的方式,因为比较直接透明。具体的使用方式如下:

一, 下载 Android NDK

wget -q https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip unzip -q android-ndk-r14b-linux-x86_64.zip 

假设当前目录为 $CURRENT_DIR

二, 自定义工具链(--install-dir 表示安装路径,根据自己的需求设置,假设安装路径为$TOOLCHAIN_PATH )

$CURRENT_DIR/android-ndk-r14b-linux-x86_64/build/tools/make-standalone-toolchain.sh \         --arch=arm --platform=android-21 --install-dir=$TOOLCHAIN_PATH/v7_standalone_toolchain 

$TOOLCHAIN_PATH/v7_standalone_toolchain目录下的内容为我们刚刚生成的工具链。

三, 交叉编译PaddlePaddle

git clone https://github.com/PaddlePaddle/Paddle.git  cd Paddle #  建立docker 镜像 mkdir install  mkdir build  cd build  cmake -DCMAKE_SYSTEM_NAME=Android \       -DANDROID_STANDALONE_TOOLCHAIN=$TOOLCHAIN_PATH/v7_standalone_toolchain \       -DANDROID_ABI=armeabi-v7a \       -DANDROID_ARM_NEON=ON \       -DANDROID_ARM_MODE=ON \       -DUSE_EIGEN_FOR_BLAS=ON \       -DCMAKE_INSTALL_PREFIX=./install \       -DWITH_C_API=ON \       -DWITH_SWIG_PY=OFF \        -DANDROID_TOOLCHAIN=gcc  \       ..  make -j `nproc` make install  

编译结束后,会在 install/lib 目录下生成动态库libpaddle_capi_shared.so, 这个动态库提供了模型程序调用PaddlePaddle的所有入口。

Android shell 下运行分类模型

一, 下载预测程序
该程序功能是用来测试模型的运行速度,主要包括加载模型,随机化输入,多次进行模型前向运算并统计时间,然后输出模型的平均前向运行时间。

wget https://raw.githubusercontent.com/PaddlePaddle/Mobile/develop/benchmark/tool/C/inference.cc 

二, 将libpaddle_capi_shared.so copy至当前目录
三, 编译预测脚本

export PATH=$TOOLCHAIN_PATH/v7_standalone_toolchain/bin/:$PATH arm-linux-androideabi-g++ inference.cc -L./ -lpaddle_capi_shared -o inference -pie -fPIE 

我们可以看到,目录中多了一个inference 可运行的二进制文件。

四,将之前提到的模型配置文件.py 和模型参数文件.tar.gz融合成一个文件

from paddle.utils.merge_model import merge_v2_model  # import your network configuration from mobilenet import mobile_net  net = mobile_net(3*224*224, 102, 1.0) param_file = './mobilenet_flowers102.tar.gz' output_file = './mobilenet.paddle'  merge_v2_model(net, param_file, output_file) 

五,安装adb
linux 安装,查看教程
mac 安装,查看教程

adb 工具可以登陆android 手机的shell,让我们像使用linux shell一样来操作android。
adb安装之后,我们使用数据线将android手机和电脑链接。

六, Android shell下运行Paddle分类模型

adb push inference libpaddle_capi_shared.so mobilenet.paddle /sdcard/test_mobilenet adb shell cd /sdcard/test_mobilenet export LD_LIBRARY_PATH=./ ./inference --merged_model ./mobilenet.paddle --input_size 150528 

其中input_size 表示模型输入的大小,即3 * 224 * 224 等于 150528
如果看到以下的log,说明程序运行成功:

可以看到,paddle初始化的时间是1.78015ms, 加载模型的时间是113.749ms, 模型前向的时间是337.754ms.

 

责任编辑:张燕妮 来源: 简书
相关推荐

2018-03-26 20:49:08

图像分类

2018-03-26 20:14:32

深度学习

2018-01-21 14:11:22

人工智能PaddlePaddlTensorflow

2018-01-26 14:29:01

框架

2018-03-27 16:24:12

PaddlePaddl

2018-04-04 10:19:32

深度学习

2018-04-02 10:45:11

深度学习PaddlePaddl手写数字识别

2018-03-26 20:00:32

深度学习

2018-03-26 20:07:25

深度学习

2018-03-09 22:56:52

PaddlePaddl

2018-02-07 16:13:00

深度学习

2019-03-26 16:05:10

AI

2018-03-26 21:26:50

深度学习

2018-02-07 17:32:54

情感分析

2018-04-09 10:20:32

深度学习

2018-03-27 13:26:51

教程

2018-03-26 21:31:30

深度学习

2018-03-27 13:18:17

教程

2017-02-09 16:39:54

百度

2019-07-06 10:18:07

人工智能
点赞
收藏

51CTO技术栈公众号