我们可以在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.
作者:X_Dragon
链接:https://www.jianshu.com/p/91053654da98
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
案例很不错