diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/README.md b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5e62bf6fc2c440610d3e1f085f11b33ce1b91e50 100644 --- a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/README.md +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/README.md @@ -0,0 +1,264 @@ +# Mobilenet_v3 在 ARM CPU 上部署示例 + +# 目录 + +- [1 获取 inference model]() +- [2 准备模型转换工具并生成 Paddle Lite 的部署模型]() +- [3 以 arm v8 、Android 系统为例进行部署]() +- [4 推理结果正确性验证]() + + +### 1 获取 inference model + +提供以下两种方式获取 inference model + +- 直接下载(推荐):[inference model](https://paddle-model-ecology.bj.bcebos.com/model/mobilenetv3_reprod/mobilenet_v3_small_infer.tar) + +- 通过预训练模型获取 + +首先获取[预训练模型](https://paddle-model-ecology.bj.bcebos.com/model/mobilenetv3_reprod/mobilenet_v3_small_pretrained.pdparams),在 ```models/tutorials/mobilenetv3_prod/Step6/tools``` 文件夹下提供了工具 export_model.py ,可以将预训练模型输出 为inference model ,运行如下命令即可获取 inference model。 +``` +# 假设当前在 models/tutorials/mobilenetv3_prod/Step6 目录下 +python ./tools/export_model.py --pretrained=./mobilenet_v3_small_pretrained.pdparams --save-inference-dir=./mobilenet_v3_small_infer +``` +在 mobilenet_v3_small_infer 文件夹下有 inference.pdmodel、inference.pdiparams 和 inference.pdiparams.info 文件。 + +### 2 准备模型转换工具并生成 Paddle Lite 的部署模型 + +- python 脚本方式 + +适用于 ``` python == 3.5\3.6\3.7 ``` +首先 pip 安装 Paddle Lite: + +``` +pip3 install paddlelite==2.10 +``` + +在```mobilenet_v3```文件夹下允许如下命令: + +``` +python export_lite_model.py --model-file=./mobilenet_v3_small_infer/inference.pdmodel --param-file=./mobilenet_v3_small_infer/inference.pdiparams --optimize-out=./mobilenet_v3_small +``` +在当前文件夹下会生成mobilenet_v3_small.nb文件。 + +- 终端命令方式 + +模型转换工具[opt_linux](https://github.com/PaddlePaddle/Paddle-Lite/releases/download/v2.10/opt_linux)、[opt_mac](https://github.com/PaddlePaddle/Paddle-Lite/releases/download/v2.10/opt_mac)。或者参考[文档](https://paddle-lite.readthedocs.io/zh/develop/user_guides/model_optimize_tool.html)编译您的模型转换工具,使用如下命令转换可以转换 inference model 到 Paddle Lite 的 nb 模型: + +``` +./opt --model_file=./mobilenet_v3_small_infer/inference.pdmodel --param_file=./mobilenet_v3_small_infer/inference.pdiparams --optimize_out=./mobilenet_v3_small +``` +在当前文件夹下会生成mobilenet_v3_small.nb文件。 + +注:在 mac 上运行 opt_mac 可能会有如下错误: + +
+ +
+需要搜索安全性与隐私,点击通用,点击仍然允许,即可。 +
+ +
+ +### 3 以 arm v8 、Android 系统为例进行部署 + +- 准备编译环境 + +``` +gcc、g++(推荐版本为 8.2.0) +git、make、wget、python、adb +Java Environment +CMake(请使用 3.10 版本,其他版本的 Cmake 可能有兼容性问题,导致编译不通过) +Android NDK(支持 ndk-r17c 及之后的所有 NDK 版本, 注意从 ndk-r18 开始,NDK 交叉编译工具仅支持 Clang, 不支持 GCC) +``` + +- 环境安装命令 + +以 Ubuntu 为例介绍安装命令。注意需要 root 用户权限执行如下命令。mac 环境下编译 Android 库参考[Android 源码编译](https://paddle-lite.readthedocs.io/zh/develop/source_compile/macos_compile_android.html),Windows 下暂不支持编译 Android 版本库。 + +``` + # 1. 安装 gcc g++ git make wget python unzip adb curl 等基础软件 + apt update + apt-get install -y --no-install-recommends \ + gcc g++ git make wget python unzip adb curl + + # 2. 安装 jdk + apt-get install -y default-jdk + + # 3. 安装 CMake,以下命令以 3.10.3 版本为例(其他版本的 Cmake 可能有兼容性问题,导致编译不通过,建议用这个版本) + wget -c https://mms-res.cdn.bcebos.com/cmake-3.10.3-Linux-x86_64.tar.gz && \ + tar xzf cmake-3.10.3-Linux-x86_64.tar.gz && \ + mv cmake-3.10.3-Linux-x86_64 /opt/cmake-3.10 && + ln -s /opt/cmake-3.10/bin/cmake /usr/bin/cmake && \ + ln -s /opt/cmake-3.10/bin/ccmake /usr/bin/ccmake + + # 4. 下载 linux-x86_64 版本的 Android NDK,以下命令以 r17c 版本为例,其他版本步骤类似。 + cd /tmp && curl -O https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip + cd /opt && unzip /tmp/android-ndk-r17c-linux-x86_64.zip + + # 5. 添加环境变量 NDK_ROOT 指向 Android NDK 的安装路径 + echo "export NDK_ROOT=/opt/android-ndk-r17c" >> ~/.bashrc + source ~/.bashrc +``` + +- 获取预测库 + +可以使用下面两种方式获得预测库。 + +(1) 使用预编译包 + + 推荐使用 Paddle Lite 仓库提供的 [release库](https://github.com/PaddlePaddle/Paddle-Lite/releases/tag/v2.10),在网页最下边选取要使用的库(注意本教程需要用 static 的库),例如这个[预编译库](https://github.com/PaddlePaddle/Paddle-Lite/releases/download/v2.10/inference_lite_lib.android.armv8.clang.c++_static.tar.gz)。 + +``` +mv inference_lite_lib.android.armv8.clang.c++_static.tar.gz inference_lite_lib.android.armv8.tar.gz +tar -xvzf inference_lite_lib.android.armv8.tar.gz +``` +即可获取编译好的库。注意,即使获取编译好的库依然要进行上述**环境安装**的步骤,因为下面编译 demo 时候会用到。 + +(2) 编译预测库 + + 运行编译脚本之前,请先检查系统环境变量 ``NDK_ROOT`` 指向正确的 Android NDK 安装路径。 +之后可以下载并构建 Paddle Lite 编译包。 + +``` + # 1. 检查环境变量 `NDK_ROOT` 指向正确的 Android NDK 安装路径 + echo $NDK_ROOT + + # 2. 下载 Paddle Lite 源码并切换到发布分支,如 release/v2.10 + git clone https://github.com/PaddlePaddle/Paddle-Lite.git + cd Paddle-Lite && git checkout release/v2.10 + + # (可选) 删除 third-party 目录,编译脚本会自动从国内 CDN 下载第三方库文件 + # rm -rf third-party + + # 3. 编译 Paddle Lite Android 预测库 + ./lite/tools/build_android.sh +``` + +如果按 ``./lite/tools/build_android.sh`` 中的默认参数执行,成功后会在 ``Paddle-Lite/build.lite.android.armv8.gcc/inference_lite_lib.android.armv8`` 生成 Paddle Lite 编译包,文件目录如下。 + +``` + inference_lite_lib.android.armv8/ + ├── cxx C++ 预测库和头文件 + │ ├── include C++ 头文件 + │ │ ├── paddle_api.h + │ │ ├── paddle_image_preprocess.h + │ │ ├── paddle_lite_factory_helper.h + │ │ ├── paddle_place.h + │ │ ├── paddle_use_kernels.h + │ │ ├── paddle_use_ops.h + │ │ └── paddle_use_passes.h + │ └── lib C++ 预测库 + │ ├── libpaddle_api_light_bundled.a C++ 静态库 + │ └── libpaddle_light_api_shared.so C++ 动态库 + │ + ├── java Java 预测库 + │ ├── jar + │ │ └── PaddlePredictor.jar Java JAR 包 + │ ├── so + │ │ └── libpaddle_lite_jni.so Java JNI 动态链接库 + │ └── src + │ + └── demo C++ 和 Java 示例代码 + ├── cxx C++ 预测库示例 + └── java Java 预测库示例 +``` + +- 编译运行示例 + +将编译好的预测库放在当前目录下 mobilenet_v3 文件夹下,并准备好用于测试的[图片](../../images/demo.jpg),和 [label](./mobilenet_v3/imagenet1k_label_list.txt) 、[config](./mobilenet_v3/config.txt) 。最后文件夹如下所示: + +``` + mobilenet_v3/ 示例文件夹 + ├── inference_lite_lib.android.armv8/ Paddle Lite C++ 预测库和头文件 + │ + ├── Makefile 编译相关 + │ + ├── mobilenet_v3_small.nb 优化后的模型 + │ + ├── mobilenet_v3.cc C++ 示例代码 + │ + ├── demo.jpg 示例图片 + │ + ├── imagenet1k_label_list.txt 示例label(用于后处理) + │ + └── config.txt 示例config(用于前处理) +``` +在 mobilenet_v3 文件夹下运行 + +```bash +make +``` +会进行编译过程,注意编译过程会下载 opencv 第三方库,需要连接网络。编译完成后会生成 mobilenet_v3可执行文件。 +注意 Makefile 中第4行: + +``` +LITE_ROOT=./inference_lite_lib.android.armv8 +``` +中的 ```LITE_ROOT```需要改成您的预测库的文件夹名。 + +- 在 Android 手机上部署 +连接一台开启了**USB调试功能**的手机,运行 +``` +adb devices +``` +可以看到有输出 +``` +List of devices attached +1ddcf602 device +``` + +- 在手机上运行 mobilenet_v3 demo。 + +```bash +################################# +# 假设当前位于 mobilenet_v3 目录下 # +################################# + +# prepare enviroment on phone +adb shell mkdir -p /data/local/tmp/arm_cpu/ + + +# push executable binary, library to device +adb push mobilenet_v3 /data/local/tmp/arm_cpu/ +adb shell chmod +x /data/local/tmp/arm_cpu/mobilenet_v3 +adb push inference_lite_lib.android.armv8/cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/arm_cpu/ + +# push model with optimized(opt) to device +adb push ./mobilenet_v3_small.nb /data/local/tmp/arm_cpu/ + +# push config and label and pictures to device +adb push ./config.txt /data/local/tmp/arm_cpu/ +adb push ./imagenet1k_label_list.txt /data/local/tmp/arm_cpu/ +adb push ./demo.jpg /data/local/tmp/arm_cpu/ + +# run demo on device +adb shell "export LD_LIBRARY_PATH=/data/local/tmp/arm_cpu/; \ + /data/local/tmp/arm_cpu/mobilenet_v3 \ + /data/local/tmp/arm_cpu/config.txt \ + /data/local/tmp/arm_cpu/demo.jpg" +``` + +得到以下输出: + +``` +===clas result for image: /data/local/tmp/arm_cpu/demo.jpg=== + Top-1, class_id: 8, class_name: hen, score: 0.901639 + Top-2, class_id: 7, class_name: cock, score: 0.0970001 + Top-3, class_id: 86, class_name: partridge, score: 0.000225853 + Top-4, class_id: 80, class_name: black grouse, score: 0.0001647 + Top-5, class_id: 21, class_name: kite, score: 0.000128394 +``` + +代表在 Android 手机上推理部署完成。 + +### 4 验证推理结果正确性 + +在`models/tutorials/mobilenetv3_prod/Step6`目录下运行如下命令: + +``` +python tools/predict.py --pretrained=./mobilenet_v3_small_paddle_pretrained.pdparams --img-path=images/demo.jpg +``` +最终输出结果为 ```class_id: 8, prob: 0.9091238975524902``` ,表示预测的类别ID是```8```,置信度为```0.909```。 + +与Paddle Lite预测结果一致。输出结果微小差距的原因是 Paddle Lite 所用 ```opencv``` 和 训练所用 ```PIL```库前处理方式有微小差别。 diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/Makefile b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c8769e1b178112b2a2c839c6f3b9dfb33c0ec55c --- /dev/null +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/Makefile @@ -0,0 +1,61 @@ +ARM_ABI = arm8 +export ARM_ABI + +LITE_ROOT=./inference_lite_lib.android.armv8 + +include ${LITE_ROOT}/demo/cxx/Makefile.def + +THIRD_PARTY_DIR=${LITE_ROOT}/third_party + +OPENCV_VERSION=opencv4.1.0 + +OPENCV_LIBS = ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/libs/libopencv_imgcodecs.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/libs/libopencv_imgproc.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/libs/libopencv_core.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/libtegra_hal.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/liblibjpeg-turbo.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/liblibwebp.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/liblibpng.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/liblibjasper.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/liblibtiff.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/libIlmImf.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/libtbb.a \ + ${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/3rdparty/libs/libcpufeatures.a + +OPENCV_INCLUDE = -I${THIRD_PARTY_DIR}/${OPENCV_VERSION}/arm64-v8a/include + +CXX_INCLUDES = $(INCLUDES) ${OPENCV_INCLUDE} -I$(LITE_ROOT)/cxx/include + +CXX_LIBS = ${OPENCV_LIBS} -L$(LITE_ROOT)/cxx/lib/ -lpaddle_light_api_shared $(SYSTEM_LIBS) + +############################################################### +# How to use one of static libaray: # +# `libpaddle_api_full_bundled.a` # +# `libpaddle_api_light_bundled.a` # +############################################################### +# Note: default use lite's shared library. # +############################################################### +# 1. Comment above line using `libpaddle_light_api_shared.so` +# 2. Undo comment below line using `libpaddle_api_light_bundled.a` + +#CXX_LIBS = $(LITE_ROOT)/cxx/lib/libpaddle_api_light_bundled.a $(SYSTEM_LIBS) + +mobilenet_v3: fetch_opencv mobilenet_v3.o + $(CC) $(SYSROOT_LINK) $(CXXFLAGS_LINK) mobilenet_v3.o -o mobilenet_v3 $(CXX_LIBS) $(LDFLAGS) + +mobilenet_v3.o: mobilenet_v3.cc + $(CC) $(SYSROOT_COMPLILE) $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o mobilenet_v3.o -c mobilenet_v3.cc + +fetch_opencv: + @ test -d ${THIRD_PARTY_DIR} || mkdir ${THIRD_PARTY_DIR} + @ test -e ${THIRD_PARTY_DIR}/${OPENCV_VERSION}.tar.gz || \ + (echo "fetch opencv libs" && \ + wget -P ${THIRD_PARTY_DIR} https://paddle-inference-dist.bj.bcebos.com/${OPENCV_VERSION}.tar.gz) + @ test -d ${THIRD_PARTY_DIR}/${OPENCV_VERSION} || \ + tar -zxvf ${THIRD_PARTY_DIR}/${OPENCV_VERSION}.tar.gz -C ${THIRD_PARTY_DIR} + + +.PHONY: clean +clean: + rm -f mobilenet_v3.o + rm -f mobilenet_v3 diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/config.txt b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/config.txt new file mode 100644 index 0000000000000000000000000000000000000000..be60a990b146262b2c1a3f638d25686a5acd7eea --- /dev/null +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/config.txt @@ -0,0 +1,6 @@ +clas_model_file /data/local/tmp/arm_cpu/mobilenet_v3_small.nb +label_path /data/local/tmp/arm_cpu/imagenet1k_label_list.txt +resize_short_size 256 +crop_size 224 +visualize 0 +enable_benchmark 0 diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/export_lite_model.py b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/export_lite_model.py new file mode 100644 index 0000000000000000000000000000000000000000..d409dd319f373a9fefa2bd8ed993116fbb4b52a6 --- /dev/null +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/export_lite_model.py @@ -0,0 +1,32 @@ +from paddlelite.lite import * + +def get_args(add_help=True): + import argparse + parser = argparse.ArgumentParser( + description='Paddle Lite Optimize model', add_help=add_help) + + parser.add_argument('--model-dir', default='mobilenet_v3_small', help='model dir') + parser.add_argument('--model-file', default='', help='model file') + parser.add_argument('--param-file', default='', help='param file') + parser.add_argument('--target', default='arm', help='arm or opencl or X86') + parser.add_argument('--model-type', default='naive_buffer', help='save model type') + parser.add_argument('--optimize-out', default='mobilenet_v3_small', help='save model type') + + args = parser.parse_args() + return args + +def export(args): + opt=Opt() + opt.set_model_file(args.model_file) + opt.set_param_file(args.param_file) + opt.set_valid_places(args.target) + opt.set_model_type(args.model_type) + opt.set_optimize_out(args.optimize_out) + opt.run() + +if __name__ == "__main__": + args = get_args() + export(args) + + + diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/imagenet1k_label_list.txt b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/imagenet1k_label_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..376e18021d543bc45e33df771b5dc7acdd5f2e4f --- /dev/null +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/imagenet1k_label_list.txt @@ -0,0 +1,1000 @@ +0 tench, Tinca tinca +1 goldfish, Carassius auratus +2 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias +3 tiger shark, Galeocerdo cuvieri +4 hammerhead, hammerhead shark +5 electric ray, crampfish, numbfish, torpedo +6 stingray +7 cock +8 hen +9 ostrich, Struthio camelus +10 brambling, Fringilla montifringilla +11 goldfinch, Carduelis carduelis +12 house finch, linnet, Carpodacus mexicanus +13 junco, snowbird +14 indigo bunting, indigo finch, indigo bird, Passerina cyanea +15 robin, American robin, Turdus migratorius +16 bulbul +17 jay +18 magpie +19 chickadee +20 water ouzel, dipper +21 kite +22 bald eagle, American eagle, Haliaeetus leucocephalus +23 vulture +24 great grey owl, great gray owl, Strix nebulosa +25 European fire salamander, Salamandra salamandra +26 common newt, Triturus vulgaris +27 eft +28 spotted salamander, Ambystoma maculatum +29 axolotl, mud puppy, Ambystoma mexicanum +30 bullfrog, Rana catesbeiana +31 tree frog, tree-frog +32 tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui +33 loggerhead, loggerhead turtle, Caretta caretta +34 leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea +35 mud turtle +36 terrapin +37 box turtle, box tortoise +38 banded gecko +39 common iguana, iguana, Iguana iguana +40 American chameleon, anole, Anolis carolinensis +41 whiptail, whiptail lizard +42 agama +43 frilled lizard, Chlamydosaurus kingi +44 alligator lizard +45 Gila monster, Heloderma suspectum +46 green lizard, Lacerta viridis +47 African chameleon, Chamaeleo chamaeleon +48 Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis +49 African crocodile, Nile crocodile, Crocodylus niloticus +50 American alligator, Alligator mississipiensis +51 triceratops +52 thunder snake, worm snake, Carphophis amoenus +53 ringneck snake, ring-necked snake, ring snake +54 hognose snake, puff adder, sand viper +55 green snake, grass snake +56 king snake, kingsnake +57 garter snake, grass snake +58 water snake +59 vine snake +60 night snake, Hypsiglena torquata +61 boa constrictor, Constrictor constrictor +62 rock python, rock snake, Python sebae +63 Indian cobra, Naja naja +64 green mamba +65 sea snake +66 horned viper, cerastes, sand viper, horned asp, Cerastes cornutus +67 diamondback, diamondback rattlesnake, Crotalus adamanteus +68 sidewinder, horned rattlesnake, Crotalus cerastes +69 trilobite +70 harvestman, daddy longlegs, Phalangium opilio +71 scorpion +72 black and gold garden spider, Argiope aurantia +73 barn spider, Araneus cavaticus +74 garden spider, Aranea diademata +75 black widow, Latrodectus mactans +76 tarantula +77 wolf spider, hunting spider +78 tick +79 centipede +80 black grouse +81 ptarmigan +82 ruffed grouse, partridge, Bonasa umbellus +83 prairie chicken, prairie grouse, prairie fowl +84 peacock +85 quail +86 partridge +87 African grey, African gray, Psittacus erithacus +88 macaw +89 sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita +90 lorikeet +91 coucal +92 bee eater +93 hornbill +94 hummingbird +95 jacamar +96 toucan +97 drake +98 red-breasted merganser, Mergus serrator +99 goose +100 black swan, Cygnus atratus +101 tusker +102 echidna, spiny anteater, anteater +103 platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus +104 wallaby, brush kangaroo +105 koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus +106 wombat +107 jellyfish +108 sea anemone, anemone +109 brain coral +110 flatworm, platyhelminth +111 nematode, nematode worm, roundworm +112 conch +113 snail +114 slug +115 sea slug, nudibranch +116 chiton, coat-of-mail shell, sea cradle, polyplacophore +117 chambered nautilus, pearly nautilus, nautilus +118 Dungeness crab, Cancer magister +119 rock crab, Cancer irroratus +120 fiddler crab +121 king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica +122 American lobster, Northern lobster, Maine lobster, Homarus americanus +123 spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish +124 crayfish, crawfish, crawdad, crawdaddy +125 hermit crab +126 isopod +127 white stork, Ciconia ciconia +128 black stork, Ciconia nigra +129 spoonbill +130 flamingo +131 little blue heron, Egretta caerulea +132 American egret, great white heron, Egretta albus +133 bittern +134 crane +135 limpkin, Aramus pictus +136 European gallinule, Porphyrio porphyrio +137 American coot, marsh hen, mud hen, water hen, Fulica americana +138 bustard +139 ruddy turnstone, Arenaria interpres +140 red-backed sandpiper, dunlin, Erolia alpina +141 redshank, Tringa totanus +142 dowitcher +143 oystercatcher, oyster catcher +144 pelican +145 king penguin, Aptenodytes patagonica +146 albatross, mollymawk +147 grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus +148 killer whale, killer, orca, grampus, sea wolf, Orcinus orca +149 dugong, Dugong dugon +150 sea lion +151 Chihuahua +152 Japanese spaniel +153 Maltese dog, Maltese terrier, Maltese +154 Pekinese, Pekingese, Peke +155 Shih-Tzu +156 Blenheim spaniel +157 papillon +158 toy terrier +159 Rhodesian ridgeback +160 Afghan hound, Afghan +161 basset, basset hound +162 beagle +163 bloodhound, sleuthhound +164 bluetick +165 black-and-tan coonhound +166 Walker hound, Walker foxhound +167 English foxhound +168 redbone +169 borzoi, Russian wolfhound +170 Irish wolfhound +171 Italian greyhound +172 whippet +173 Ibizan hound, Ibizan Podenco +174 Norwegian elkhound, elkhound +175 otterhound, otter hound +176 Saluki, gazelle hound +177 Scottish deerhound, deerhound +178 Weimaraner +179 Staffordshire bullterrier, Staffordshire bull terrier +180 American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier +181 Bedlington terrier +182 Border terrier +183 Kerry blue terrier +184 Irish terrier +185 Norfolk terrier +186 Norwich terrier +187 Yorkshire terrier +188 wire-haired fox terrier +189 Lakeland terrier +190 Sealyham terrier, Sealyham +191 Airedale, Airedale terrier +192 cairn, cairn terrier +193 Australian terrier +194 Dandie Dinmont, Dandie Dinmont terrier +195 Boston bull, Boston terrier +196 miniature schnauzer +197 giant schnauzer +198 standard schnauzer +199 Scotch terrier, Scottish terrier, Scottie +200 Tibetan terrier, chrysanthemum dog +201 silky terrier, Sydney silky +202 soft-coated wheaten terrier +203 West Highland white terrier +204 Lhasa, Lhasa apso +205 flat-coated retriever +206 curly-coated retriever +207 golden retriever +208 Labrador retriever +209 Chesapeake Bay retriever +210 German short-haired pointer +211 vizsla, Hungarian pointer +212 English setter +213 Irish setter, red setter +214 Gordon setter +215 Brittany spaniel +216 clumber, clumber spaniel +217 English springer, English springer spaniel +218 Welsh springer spaniel +219 cocker spaniel, English cocker spaniel, cocker +220 Sussex spaniel +221 Irish water spaniel +222 kuvasz +223 schipperke +224 groenendael +225 malinois +226 briard +227 kelpie +228 komondor +229 Old English sheepdog, bobtail +230 Shetland sheepdog, Shetland sheep dog, Shetland +231 collie +232 Border collie +233 Bouvier des Flandres, Bouviers des Flandres +234 Rottweiler +235 German shepherd, German shepherd dog, German police dog, alsatian +236 Doberman, Doberman pinscher +237 miniature pinscher +238 Greater Swiss Mountain dog +239 Bernese mountain dog +240 Appenzeller +241 EntleBucher +242 boxer +243 bull mastiff +244 Tibetan mastiff +245 French bulldog +246 Great Dane +247 Saint Bernard, St Bernard +248 Eskimo dog, husky +249 malamute, malemute, Alaskan malamute +250 Siberian husky +251 dalmatian, coach dog, carriage dog +252 affenpinscher, monkey pinscher, monkey dog +253 basenji +254 pug, pug-dog +255 Leonberg +256 Newfoundland, Newfoundland dog +257 Great Pyrenees +258 Samoyed, Samoyede +259 Pomeranian +260 chow, chow chow +261 keeshond +262 Brabancon griffon +263 Pembroke, Pembroke Welsh corgi +264 Cardigan, Cardigan Welsh corgi +265 toy poodle +266 miniature poodle +267 standard poodle +268 Mexican hairless +269 timber wolf, grey wolf, gray wolf, Canis lupus +270 white wolf, Arctic wolf, Canis lupus tundrarum +271 red wolf, maned wolf, Canis rufus, Canis niger +272 coyote, prairie wolf, brush wolf, Canis latrans +273 dingo, warrigal, warragal, Canis dingo +274 dhole, Cuon alpinus +275 African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus +276 hyena, hyaena +277 red fox, Vulpes vulpes +278 kit fox, Vulpes macrotis +279 Arctic fox, white fox, Alopex lagopus +280 grey fox, gray fox, Urocyon cinereoargenteus +281 tabby, tabby cat +282 tiger cat +283 Persian cat +284 Siamese cat, Siamese +285 Egyptian cat +286 cougar, puma, catamount, mountain lion, painter, panther, Felis concolor +287 lynx, catamount +288 leopard, Panthera pardus +289 snow leopard, ounce, Panthera uncia +290 jaguar, panther, Panthera onca, Felis onca +291 lion, king of beasts, Panthera leo +292 tiger, Panthera tigris +293 cheetah, chetah, Acinonyx jubatus +294 brown bear, bruin, Ursus arctos +295 American black bear, black bear, Ursus americanus, Euarctos americanus +296 ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus +297 sloth bear, Melursus ursinus, Ursus ursinus +298 mongoose +299 meerkat, mierkat +300 tiger beetle +301 ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle +302 ground beetle, carabid beetle +303 long-horned beetle, longicorn, longicorn beetle +304 leaf beetle, chrysomelid +305 dung beetle +306 rhinoceros beetle +307 weevil +308 fly +309 bee +310 ant, emmet, pismire +311 grasshopper, hopper +312 cricket +313 walking stick, walkingstick, stick insect +314 cockroach, roach +315 mantis, mantid +316 cicada, cicala +317 leafhopper +318 lacewing, lacewing fly +319 dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk +320 damselfly +321 admiral +322 ringlet, ringlet butterfly +323 monarch, monarch butterfly, milkweed butterfly, Danaus plexippus +324 cabbage butterfly +325 sulphur butterfly, sulfur butterfly +326 lycaenid, lycaenid butterfly +327 starfish, sea star +328 sea urchin +329 sea cucumber, holothurian +330 wood rabbit, cottontail, cottontail rabbit +331 hare +332 Angora, Angora rabbit +333 hamster +334 porcupine, hedgehog +335 fox squirrel, eastern fox squirrel, Sciurus niger +336 marmot +337 beaver +338 guinea pig, Cavia cobaya +339 sorrel +340 zebra +341 hog, pig, grunter, squealer, Sus scrofa +342 wild boar, boar, Sus scrofa +343 warthog +344 hippopotamus, hippo, river horse, Hippopotamus amphibius +345 ox +346 water buffalo, water ox, Asiatic buffalo, Bubalus bubalis +347 bison +348 ram, tup +349 bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis +350 ibex, Capra ibex +351 hartebeest +352 impala, Aepyceros melampus +353 gazelle +354 Arabian camel, dromedary, Camelus dromedarius +355 llama +356 weasel +357 mink +358 polecat, fitch, foulmart, foumart, Mustela putorius +359 black-footed ferret, ferret, Mustela nigripes +360 otter +361 skunk, polecat, wood pussy +362 badger +363 armadillo +364 three-toed sloth, ai, Bradypus tridactylus +365 orangutan, orang, orangutang, Pongo pygmaeus +366 gorilla, Gorilla gorilla +367 chimpanzee, chimp, Pan troglodytes +368 gibbon, Hylobates lar +369 siamang, Hylobates syndactylus, Symphalangus syndactylus +370 guenon, guenon monkey +371 patas, hussar monkey, Erythrocebus patas +372 baboon +373 macaque +374 langur +375 colobus, colobus monkey +376 proboscis monkey, Nasalis larvatus +377 marmoset +378 capuchin, ringtail, Cebus capucinus +379 howler monkey, howler +380 titi, titi monkey +381 spider monkey, Ateles geoffroyi +382 squirrel monkey, Saimiri sciureus +383 Madagascar cat, ring-tailed lemur, Lemur catta +384 indri, indris, Indri indri, Indri brevicaudatus +385 Indian elephant, Elephas maximus +386 African elephant, Loxodonta africana +387 lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens +388 giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca +389 barracouta, snoek +390 eel +391 coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch +392 rock beauty, Holocanthus tricolor +393 anemone fish +394 sturgeon +395 gar, garfish, garpike, billfish, Lepisosteus osseus +396 lionfish +397 puffer, pufferfish, blowfish, globefish +398 abacus +399 abaya +400 academic gown, academic robe, judge's robe +401 accordion, piano accordion, squeeze box +402 acoustic guitar +403 aircraft carrier, carrier, flattop, attack aircraft carrier +404 airliner +405 airship, dirigible +406 altar +407 ambulance +408 amphibian, amphibious vehicle +409 analog clock +410 apiary, bee house +411 apron +412 ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin +413 assault rifle, assault gun +414 backpack, back pack, knapsack, packsack, rucksack, haversack +415 bakery, bakeshop, bakehouse +416 balance beam, beam +417 balloon +418 ballpoint, ballpoint pen, ballpen, Biro +419 Band Aid +420 banjo +421 bannister, banister, balustrade, balusters, handrail +422 barbell +423 barber chair +424 barbershop +425 barn +426 barometer +427 barrel, cask +428 barrow, garden cart, lawn cart, wheelbarrow +429 baseball +430 basketball +431 bassinet +432 bassoon +433 bathing cap, swimming cap +434 bath towel +435 bathtub, bathing tub, bath, tub +436 beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon +437 beacon, lighthouse, beacon light, pharos +438 beaker +439 bearskin, busby, shako +440 beer bottle +441 beer glass +442 bell cote, bell cot +443 bib +444 bicycle-built-for-two, tandem bicycle, tandem +445 bikini, two-piece +446 binder, ring-binder +447 binoculars, field glasses, opera glasses +448 birdhouse +449 boathouse +450 bobsled, bobsleigh, bob +451 bolo tie, bolo, bola tie, bola +452 bonnet, poke bonnet +453 bookcase +454 bookshop, bookstore, bookstall +455 bottlecap +456 bow +457 bow tie, bow-tie, bowtie +458 brass, memorial tablet, plaque +459 brassiere, bra, bandeau +460 breakwater, groin, groyne, mole, bulwark, seawall, jetty +461 breastplate, aegis, egis +462 broom +463 bucket, pail +464 buckle +465 bulletproof vest +466 bullet train, bullet +467 butcher shop, meat market +468 cab, hack, taxi, taxicab +469 caldron, cauldron +470 candle, taper, wax light +471 cannon +472 canoe +473 can opener, tin opener +474 cardigan +475 car mirror +476 carousel, carrousel, merry-go-round, roundabout, whirligig +477 carpenter's kit, tool kit +478 carton +479 car wheel +480 cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM +481 cassette +482 cassette player +483 castle +484 catamaran +485 CD player +486 cello, violoncello +487 cellular telephone, cellular phone, cellphone, cell, mobile phone +488 chain +489 chainlink fence +490 chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour +491 chain saw, chainsaw +492 chest +493 chiffonier, commode +494 chime, bell, gong +495 china cabinet, china closet +496 Christmas stocking +497 church, church building +498 cinema, movie theater, movie theatre, movie house, picture palace +499 cleaver, meat cleaver, chopper +500 cliff dwelling +501 cloak +502 clog, geta, patten, sabot +503 cocktail shaker +504 coffee mug +505 coffeepot +506 coil, spiral, volute, whorl, helix +507 combination lock +508 computer keyboard, keypad +509 confectionery, confectionary, candy store +510 container ship, containership, container vessel +511 convertible +512 corkscrew, bottle screw +513 cornet, horn, trumpet, trump +514 cowboy boot +515 cowboy hat, ten-gallon hat +516 cradle +517 crane +518 crash helmet +519 crate +520 crib, cot +521 Crock Pot +522 croquet ball +523 crutch +524 cuirass +525 dam, dike, dyke +526 desk +527 desktop computer +528 dial telephone, dial phone +529 diaper, nappy, napkin +530 digital clock +531 digital watch +532 dining table, board +533 dishrag, dishcloth +534 dishwasher, dish washer, dishwashing machine +535 disk brake, disc brake +536 dock, dockage, docking facility +537 dogsled, dog sled, dog sleigh +538 dome +539 doormat, welcome mat +540 drilling platform, offshore rig +541 drum, membranophone, tympan +542 drumstick +543 dumbbell +544 Dutch oven +545 electric fan, blower +546 electric guitar +547 electric locomotive +548 entertainment center +549 envelope +550 espresso maker +551 face powder +552 feather boa, boa +553 file, file cabinet, filing cabinet +554 fireboat +555 fire engine, fire truck +556 fire screen, fireguard +557 flagpole, flagstaff +558 flute, transverse flute +559 folding chair +560 football helmet +561 forklift +562 fountain +563 fountain pen +564 four-poster +565 freight car +566 French horn, horn +567 frying pan, frypan, skillet +568 fur coat +569 garbage truck, dustcart +570 gasmask, respirator, gas helmet +571 gas pump, gasoline pump, petrol pump, island dispenser +572 goblet +573 go-kart +574 golf ball +575 golfcart, golf cart +576 gondola +577 gong, tam-tam +578 gown +579 grand piano, grand +580 greenhouse, nursery, glasshouse +581 grille, radiator grille +582 grocery store, grocery, food market, market +583 guillotine +584 hair slide +585 hair spray +586 half track +587 hammer +588 hamper +589 hand blower, blow dryer, blow drier, hair dryer, hair drier +590 hand-held computer, hand-held microcomputer +591 handkerchief, hankie, hanky, hankey +592 hard disc, hard disk, fixed disk +593 harmonica, mouth organ, harp, mouth harp +594 harp +595 harvester, reaper +596 hatchet +597 holster +598 home theater, home theatre +599 honeycomb +600 hook, claw +601 hoopskirt, crinoline +602 horizontal bar, high bar +603 horse cart, horse-cart +604 hourglass +605 iPod +606 iron, smoothing iron +607 jack-o'-lantern +608 jean, blue jean, denim +609 jeep, landrover +610 jersey, T-shirt, tee shirt +611 jigsaw puzzle +612 jinrikisha, ricksha, rickshaw +613 joystick +614 kimono +615 knee pad +616 knot +617 lab coat, laboratory coat +618 ladle +619 lampshade, lamp shade +620 laptop, laptop computer +621 lawn mower, mower +622 lens cap, lens cover +623 letter opener, paper knife, paperknife +624 library +625 lifeboat +626 lighter, light, igniter, ignitor +627 limousine, limo +628 liner, ocean liner +629 lipstick, lip rouge +630 Loafer +631 lotion +632 loudspeaker, speaker, speaker unit, loudspeaker system, speaker system +633 loupe, jeweler's loupe +634 lumbermill, sawmill +635 magnetic compass +636 mailbag, postbag +637 mailbox, letter box +638 maillot +639 maillot, tank suit +640 manhole cover +641 maraca +642 marimba, xylophone +643 mask +644 matchstick +645 maypole +646 maze, labyrinth +647 measuring cup +648 medicine chest, medicine cabinet +649 megalith, megalithic structure +650 microphone, mike +651 microwave, microwave oven +652 military uniform +653 milk can +654 minibus +655 miniskirt, mini +656 minivan +657 missile +658 mitten +659 mixing bowl +660 mobile home, manufactured home +661 Model T +662 modem +663 monastery +664 monitor +665 moped +666 mortar +667 mortarboard +668 mosque +669 mosquito net +670 motor scooter, scooter +671 mountain bike, all-terrain bike, off-roader +672 mountain tent +673 mouse, computer mouse +674 mousetrap +675 moving van +676 muzzle +677 nail +678 neck brace +679 necklace +680 nipple +681 notebook, notebook computer +682 obelisk +683 oboe, hautboy, hautbois +684 ocarina, sweet potato +685 odometer, hodometer, mileometer, milometer +686 oil filter +687 organ, pipe organ +688 oscilloscope, scope, cathode-ray oscilloscope, CRO +689 overskirt +690 oxcart +691 oxygen mask +692 packet +693 paddle, boat paddle +694 paddlewheel, paddle wheel +695 padlock +696 paintbrush +697 pajama, pyjama, pj's, jammies +698 palace +699 panpipe, pandean pipe, syrinx +700 paper towel +701 parachute, chute +702 parallel bars, bars +703 park bench +704 parking meter +705 passenger car, coach, carriage +706 patio, terrace +707 pay-phone, pay-station +708 pedestal, plinth, footstall +709 pencil box, pencil case +710 pencil sharpener +711 perfume, essence +712 Petri dish +713 photocopier +714 pick, plectrum, plectron +715 pickelhaube +716 picket fence, paling +717 pickup, pickup truck +718 pier +719 piggy bank, penny bank +720 pill bottle +721 pillow +722 ping-pong ball +723 pinwheel +724 pirate, pirate ship +725 pitcher, ewer +726 plane, carpenter's plane, woodworking plane +727 planetarium +728 plastic bag +729 plate rack +730 plow, plough +731 plunger, plumber's helper +732 Polaroid camera, Polaroid Land camera +733 pole +734 police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria +735 poncho +736 pool table, billiard table, snooker table +737 pop bottle, soda bottle +738 pot, flowerpot +739 potter's wheel +740 power drill +741 prayer rug, prayer mat +742 printer +743 prison, prison house +744 projectile, missile +745 projector +746 puck, hockey puck +747 punching bag, punch bag, punching ball, punchball +748 purse +749 quill, quill pen +750 quilt, comforter, comfort, puff +751 racer, race car, racing car +752 racket, racquet +753 radiator +754 radio, wireless +755 radio telescope, radio reflector +756 rain barrel +757 recreational vehicle, RV, R.V. +758 reel +759 reflex camera +760 refrigerator, icebox +761 remote control, remote +762 restaurant, eating house, eating place, eatery +763 revolver, six-gun, six-shooter +764 rifle +765 rocking chair, rocker +766 rotisserie +767 rubber eraser, rubber, pencil eraser +768 rugby ball +769 rule, ruler +770 running shoe +771 safe +772 safety pin +773 saltshaker, salt shaker +774 sandal +775 sarong +776 sax, saxophone +777 scabbard +778 scale, weighing machine +779 school bus +780 schooner +781 scoreboard +782 screen, CRT screen +783 screw +784 screwdriver +785 seat belt, seatbelt +786 sewing machine +787 shield, buckler +788 shoe shop, shoe-shop, shoe store +789 shoji +790 shopping basket +791 shopping cart +792 shovel +793 shower cap +794 shower curtain +795 ski +796 ski mask +797 sleeping bag +798 slide rule, slipstick +799 sliding door +800 slot, one-armed bandit +801 snorkel +802 snowmobile +803 snowplow, snowplough +804 soap dispenser +805 soccer ball +806 sock +807 solar dish, solar collector, solar furnace +808 sombrero +809 soup bowl +810 space bar +811 space heater +812 space shuttle +813 spatula +814 speedboat +815 spider web, spider's web +816 spindle +817 sports car, sport car +818 spotlight, spot +819 stage +820 steam locomotive +821 steel arch bridge +822 steel drum +823 stethoscope +824 stole +825 stone wall +826 stopwatch, stop watch +827 stove +828 strainer +829 streetcar, tram, tramcar, trolley, trolley car +830 stretcher +831 studio couch, day bed +832 stupa, tope +833 submarine, pigboat, sub, U-boat +834 suit, suit of clothes +835 sundial +836 sunglass +837 sunglasses, dark glasses, shades +838 sunscreen, sunblock, sun blocker +839 suspension bridge +840 swab, swob, mop +841 sweatshirt +842 swimming trunks, bathing trunks +843 swing +844 switch, electric switch, electrical switch +845 syringe +846 table lamp +847 tank, army tank, armored combat vehicle, armoured combat vehicle +848 tape player +849 teapot +850 teddy, teddy bear +851 television, television system +852 tennis ball +853 thatch, thatched roof +854 theater curtain, theatre curtain +855 thimble +856 thresher, thrasher, threshing machine +857 throne +858 tile roof +859 toaster +860 tobacco shop, tobacconist shop, tobacconist +861 toilet seat +862 torch +863 totem pole +864 tow truck, tow car, wrecker +865 toyshop +866 tractor +867 trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi +868 tray +869 trench coat +870 tricycle, trike, velocipede +871 trimaran +872 tripod +873 triumphal arch +874 trolleybus, trolley coach, trackless trolley +875 trombone +876 tub, vat +877 turnstile +878 typewriter keyboard +879 umbrella +880 unicycle, monocycle +881 upright, upright piano +882 vacuum, vacuum cleaner +883 vase +884 vault +885 velvet +886 vending machine +887 vestment +888 viaduct +889 violin, fiddle +890 volleyball +891 waffle iron +892 wall clock +893 wallet, billfold, notecase, pocketbook +894 wardrobe, closet, press +895 warplane, military plane +896 washbasin, handbasin, washbowl, lavabo, wash-hand basin +897 washer, automatic washer, washing machine +898 water bottle +899 water jug +900 water tower +901 whiskey jug +902 whistle +903 wig +904 window screen +905 window shade +906 Windsor tie +907 wine bottle +908 wing +909 wok +910 wooden spoon +911 wool, woolen, woollen +912 worm fence, snake fence, snake-rail fence, Virginia fence +913 wreck +914 yawl +915 yurt +916 web site, website, internet site, site +917 comic book +918 crossword puzzle, crossword +919 street sign +920 traffic light, traffic signal, stoplight +921 book jacket, dust cover, dust jacket, dust wrapper +922 menu +923 plate +924 guacamole +925 consomme +926 hot pot, hotpot +927 trifle +928 ice cream, icecream +929 ice lolly, lolly, lollipop, popsicle +930 French loaf +931 bagel, beigel +932 pretzel +933 cheeseburger +934 hotdog, hot dog, red hot +935 mashed potato +936 head cabbage +937 broccoli +938 cauliflower +939 zucchini, courgette +940 spaghetti squash +941 acorn squash +942 butternut squash +943 cucumber, cuke +944 artichoke, globe artichoke +945 bell pepper +946 cardoon +947 mushroom +948 Granny Smith +949 strawberry +950 orange +951 lemon +952 fig +953 pineapple, ananas +954 banana +955 jackfruit, jak, jack +956 custard apple +957 pomegranate +958 hay +959 carbonara +960 chocolate sauce, chocolate syrup +961 dough +962 meat loaf, meatloaf +963 pizza, pizza pie +964 potpie +965 burrito +966 red wine +967 espresso +968 cup +969 eggnog +970 alp +971 bubble +972 cliff, drop, drop-off +973 coral reef +974 geyser +975 lakeside, lakeshore +976 promontory, headland, head, foreland +977 sandbar, sand bar +978 seashore, coast, seacoast, sea-coast +979 valley, vale +980 volcano +981 ballplayer, baseball player +982 groom, bridegroom +983 scuba diver +984 rapeseed +985 daisy +986 yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum +987 corn +988 acorn +989 hip, rose hip, rosehip +990 buckeye, horse chestnut, conker +991 coral fungus +992 agaric +993 gyromitra +994 stinkhorn, carrion fungus +995 earthstar +996 hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa +997 bolete +998 ear, spike, capitulum +999 toilet tissue, toilet paper, bathroom tissue diff --git a/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/mobilenet_v3.cc b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/mobilenet_v3.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c34febe26ebbd7423b565a1fb5e8f0dfff4c0a8 --- /dev/null +++ b/tutorials/mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/mobilenet_v3.cc @@ -0,0 +1,346 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "paddle_api.h" // NOLINT +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace paddle::lite_api; // NOLINT +using namespace std; + +struct RESULT { + std::string class_name; + int class_id; + float score; +}; + +std::vector PostProcess(const float *output_data, int output_size, + const std::vector &word_labels, + cv::Mat &output_image) { + const int TOPK = 5; + int max_indices[TOPK]; + double max_scores[TOPK]; + for (int i = 0; i < TOPK; i++) { + max_indices[i] = 0; + max_scores[i] = 0; + } + for (int i = 0; i < output_size; i++) { + float score = output_data[i]; + int index = i; + for (int j = 0; j < TOPK; j++) { + if (score > max_scores[j]) { + index += max_indices[j]; + max_indices[j] = index - max_indices[j]; + index -= max_indices[j]; + score += max_scores[j]; + max_scores[j] = score - max_scores[j]; + score -= max_scores[j]; + } + } + } + + std::vector results(TOPK); + for (int i = 0; i < results.size(); i++) { + results[i].class_name = "Unknown"; + if (max_indices[i] >= 0 && max_indices[i] < word_labels.size()) { + results[i].class_name = word_labels[max_indices[i]]; + } + results[i].score = max_scores[i]; + results[i].class_id = max_indices[i]; + cv::putText(output_image, + "Top" + std::to_string(i + 1) + "." + results[i].class_name + + ":" + std::to_string(results[i].score), + cv::Point2d(5, i * 18 + 20), cv::FONT_HERSHEY_PLAIN, 1, + cv::Scalar(51, 255, 255)); + } + return results; +} + +// fill tensor with mean and scale and trans layout: nhwc -> nchw, neon speed up +void NeonMeanScale(const float *din, float *dout, int size, + const std::vector mean, + const std::vector scale) { + if (mean.size() != 3 || scale.size() != 3) { + std::cerr << "[ERROR] mean or scale size must equal to 3\n"; + exit(1); + } + float32x4_t vmean0 = vdupq_n_f32(mean[0]); + float32x4_t vmean1 = vdupq_n_f32(mean[1]); + float32x4_t vmean2 = vdupq_n_f32(mean[2]); + float32x4_t vscale0 = vdupq_n_f32(scale[0]); + float32x4_t vscale1 = vdupq_n_f32(scale[1]); + float32x4_t vscale2 = vdupq_n_f32(scale[2]); + + float *dout_c0 = dout; + float *dout_c1 = dout + size; + float *dout_c2 = dout + size * 2; + + int i = 0; + for (; i < size - 3; i += 4) { + float32x4x3_t vin3 = vld3q_f32(din); + float32x4_t vsub0 = vsubq_f32(vin3.val[0], vmean0); + float32x4_t vsub1 = vsubq_f32(vin3.val[1], vmean1); + float32x4_t vsub2 = vsubq_f32(vin3.val[2], vmean2); + float32x4_t vs0 = vmulq_f32(vsub0, vscale0); + float32x4_t vs1 = vmulq_f32(vsub1, vscale1); + float32x4_t vs2 = vmulq_f32(vsub2, vscale2); + vst1q_f32(dout_c0, vs0); + vst1q_f32(dout_c1, vs1); + vst1q_f32(dout_c2, vs2); + + din += 12; + dout_c0 += 4; + dout_c1 += 4; + dout_c2 += 4; + } + for (; i < size; i++) { + *(dout_c0++) = (*(din++) - mean[0]) * scale[0]; + *(dout_c1++) = (*(din++) - mean[1]) * scale[1]; + *(dout_c2++) = (*(din++) - mean[2]) * scale[2]; + } +} + +cv::Mat ResizeImage(const cv::Mat &img, const int &resize_short_size) { + int w = img.cols; + int h = img.rows; + + cv::Mat resize_img; + + float ratio = 1.f; + if (h < w) { + ratio = float(resize_short_size) / float(h); + } else { + ratio = float(resize_short_size) / float(w); + } + int resize_h = round(float(h) * ratio); + int resize_w = round(float(w) * ratio); + + cv::resize(img, resize_img, cv::Size(resize_w, resize_h)); + return resize_img; +} + +cv::Mat CenterCropImg(const cv::Mat &img, const int &crop_size) { + int resize_w = img.cols; + int resize_h = img.rows; + int w_start = int((resize_w - crop_size) / 2); + int h_start = int((resize_h - crop_size) / 2); + int w_end = w_start + crop_size; + int h_end = h_start + crop_size; + cv::Rect rect(w_start, h_start, w_end, h_end); + cv::Mat crop_img = img(rect); + return crop_img; +} + +std::vector +RunClasModel(std::shared_ptr predictor, const cv::Mat &img, + const std::map &config, + const std::vector &word_labels, double &cost_time) { + // Read img + int resize_short_size = stoi(config.at("resize_short_size")); + int crop_size = stoi(config.at("crop_size")); + int visualize = stoi(config.at("visualize")); + + cv::Mat resize_image = ResizeImage(img, resize_short_size); + + cv::Mat crop_image = CenterCropImg(resize_image, crop_size); + + cv::Mat img_fp; + double e = 1.0 / 255.0; + crop_image.convertTo(img_fp, CV_32FC3, e); + + // Prepare input data from image + std::unique_ptr input_tensor(std::move(predictor->GetInput(0))); + input_tensor->Resize({1, 3, img_fp.rows, img_fp.cols}); + auto *data0 = input_tensor->mutable_data(); + + std::vector mean = {0.485f, 0.456f, 0.406f}; + std::vector scale = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f}; + const float *dimg = reinterpret_cast(img_fp.data); + NeonMeanScale(dimg, data0, img_fp.rows * img_fp.cols, mean, scale); + + auto start = std::chrono::system_clock::now(); + // Run predictor + predictor->Run(); + + // Get output and post process + std::unique_ptr output_tensor( + std::move(predictor->GetOutput(0))); + auto *output_data = output_tensor->data(); + auto end = std::chrono::system_clock::now(); + auto duration = + std::chrono::duration_cast(end - start); + cost_time = double(duration.count()) * + std::chrono::microseconds::period::num / + std::chrono::microseconds::period::den; + + int output_size = 1; + for (auto dim : output_tensor->shape()) { + output_size *= dim; + } + + cv::Mat output_image; + auto results = + PostProcess(output_data, output_size, word_labels, output_image); + + if (visualize) { + std::string output_image_path = "./clas_result.png"; + cv::imwrite(output_image_path, output_image); + std::cout << "save output image into " << output_image_path << std::endl; + } + + return results; +} + +std::shared_ptr LoadModel(std::string model_file) { + MobileConfig config; + config.set_model_from_file(model_file); + + std::shared_ptr predictor = + CreatePaddlePredictor(config); + return predictor; +} + +std::vector split(const std::string &str, + const std::string &delim) { + std::vector res; + if ("" == str) + return res; + char *strs = new char[str.length() + 1]; + std::strcpy(strs, str.c_str()); + + char *d = new char[delim.length() + 1]; + std::strcpy(d, delim.c_str()); + + char *p = std::strtok(strs, d); + while (p) { + string s = p; + res.push_back(s); + p = std::strtok(NULL, d); + } + + return res; +} + +std::vector ReadDict(std::string path) { + std::ifstream in(path); + std::string filename; + std::string line; + std::vector m_vec; + if (in) { + while (getline(in, line)) { + m_vec.push_back(line); + } + } else { + std::cout << "no such file" << std::endl; + } + return m_vec; +} + +std::map LoadConfigTxt(std::string config_path) { + auto config = ReadDict(config_path); + + std::map dict; + for (int i = 0; i < config.size(); i++) { + std::vector res = split(config[i], " "); + dict[res[0]] = res[1]; + } + return dict; +} + +void PrintConfig(const std::map &config) { + std::cout << "=======PaddleClas lite demo config======" << std::endl; + for (auto iter = config.begin(); iter != config.end(); iter++) { + std::cout << iter->first << " : " << iter->second << std::endl; + } + std::cout << "=======End of PaddleClas lite demo config======" << std::endl; +} + +std::vector LoadLabels(const std::string &path) { + std::ifstream file; + std::vector labels; + file.open(path); + while (file) { + std::string line; + std::getline(file, line); + std::string::size_type pos = line.find(" "); + if (pos != std::string::npos) { + line = line.substr(pos); + } + labels.push_back(line); + } + file.clear(); + file.close(); + return labels; +} + +int main(int argc, char **argv) { + if (argc < 3) { + std::cerr << "[ERROR] usage: " << argv[0] << " config_path img_path\n"; + exit(1); + } + + std::string config_path = argv[1]; + std::string img_path = argv[2]; + + // load config + auto config = LoadConfigTxt(config_path); + PrintConfig(config); + + double elapsed_time = 0.0; + int warmup_iter = 10; + + bool enable_benchmark = bool(stoi(config.at("enable_benchmark"))); + int total_cnt = enable_benchmark ? 1000 : 1; + + std::string clas_model_file = config.at("clas_model_file"); + std::string label_path = config.at("label_path"); + + // Load Labels + std::vector word_labels = LoadLabels(label_path); + + auto clas_predictor = LoadModel(clas_model_file); + for (int j = 0; j < total_cnt; ++j) { + cv::Mat srcimg = cv::imread(img_path, cv::IMREAD_COLOR); + cv::cvtColor(srcimg, srcimg, cv::COLOR_BGR2RGB); + + double run_time = 0; + std::vector results = + RunClasModel(clas_predictor, srcimg, config, word_labels, run_time); + + std::cout << "===clas result for image: " << img_path << "===" << std::endl; + for (int i = 0; i < results.size(); i++) { + std::cout << "\t" + << "Top-" << i + 1 << ", class_id: " << results[i].class_id + << ", class_name: " << results[i].class_name + << ", score: " << results[i].score << std::endl; + } + if (j >= warmup_iter) { + elapsed_time += run_time; + std::cout << "Current image path: " << img_path << std::endl; + std::cout << "Current time cost: " << run_time << " s, " + << "average time cost in all: " + << elapsed_time / (j + 1 - warmup_iter) << " s." << std::endl; + } else { + std::cout << "Current time cost: " << run_time << " s." << std::endl; + } + } + + return 0; +} diff --git a/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic1.png b/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f880422a8c64721335780ae26a5bbf2b4308429 Binary files /dev/null and b/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic1.png differ diff --git a/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic2.png b/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic2.png new file mode 100644 index 0000000000000000000000000000000000000000..41ce128694ddddac2af401a83a8dc1cb1e9b80d3 Binary files /dev/null and b/tutorials/mobilenetv3_prod/Step6/images/Paddle-Lite/pic2.png differ diff --git a/tutorials/tipc/images/paddleliteworkflow.png b/tutorials/tipc/images/paddleliteworkflow.png new file mode 100644 index 0000000000000000000000000000000000000000..50aeb35933137ba57d2029f8969430a2be5ed0bd Binary files /dev/null and b/tutorials/tipc/images/paddleliteworkflow.png differ diff --git a/tutorials/tipc/lite_infer_cpp_arm_cpu/lite_infer_cpp_arm_cpu.md b/tutorials/tipc/lite_infer_cpp_arm_cpu/lite_infer_cpp_arm_cpu.md index 28552922e174ab4b4b22d36bd9d87acc4329ebbf..20350f6817919bcdfded8df525a597fecb2ef0e3 100644 --- a/tutorials/tipc/lite_infer_cpp_arm_cpu/lite_infer_cpp_arm_cpu.md +++ b/tutorials/tipc/lite_infer_cpp_arm_cpu/lite_infer_cpp_arm_cpu.md @@ -1,8 +1,155 @@ -# Lite ARM CPU 推理开发文档 +# Paddle Lite arm cpu 推理开发文档 # 目录 -- [1. 简介](#1---) -- [2. Lite ARM CPU 基础推理开发文档](#2---) -- [3. Lite ARM CPU 高级推理开发文档](#3---) -- [4. FAQ](#4---) +- [1. 简介](#1) +- [2. 使用 Paddle Lite 在 ARM CPU 上的部署流程](#2) + - [2.1 准备推理数据与环境 ](#2.1) + - [2.2 准备推理模型 ](#2.1) + - [2.3 准备推理所需代码](#2.2) + - [2.4 开发数据预处理程序](#2.3) + - [2.5 开发推理程序](#2.4) + - [2.6 开发推理结果后处理程序](#2.5) + - [2.7 验证推理结果正确性](#2.6) +- [3. FAQ](#3) + - [3.1 通用问题](#3.1) + +## 1. 简介 + +在 ARM CPU 上部署需要使用 [Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite) 进行部署,Paddle Lite 是一个轻量级、灵活性强、易于扩展的高性能的深度学习预测框架,它可以支持诸如 ARM、OpenCL 、NPU 等等多种终端,同时拥有强大的图优化及预测加速能力。如果您希望将 Paddle Lite 框架集成到自己的项目中,那么只需要如下几步简单操作即可。 + +
+ +
+ +图中的2、7是核验点,需要核验结果正确性。 + +## 2.使用 Paddle Lite 在 ARM CPU 上的部署流程 + +### 2.1 准备推理数据与环境 + +- 推理环境 + +开发机器:一台开发机,可以是 x86 linux 或者 Mac 设备。开发机器上需要安装开发环境。 + +推理设备:一台 ARM CPU 设备,可以连接到开发机上。开发板的系统可以是 Android 或 Armlinux。 + +开发机上安装开发环境以及对推理设备的配置参考[mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu)中的**准备开发环境**和**在 Android 手机上部署**章节。 + +- 推理数据 + +一张可用于推理的[图片](../../mobilenetv3_prod/Step6/images/demo.jpg)和用于前处理的[配置文件](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/config.txt)(可选,和前处理有关)以及用于推理结果后处理相关的 [label](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3/imagenet1k_label_list.txt) 文件(可选,跟后处理有关)。 + +### 2.2 准备推理模型 + +- 准备 inference model + +Paddle Lite 框架直接支持[ PaddlePaddle ](https://www.paddlepaddle.org.cn/)深度学习框架产出的模型。在 PaddlePaddle 静态图模式下,使用`save_inference_model`这个 API 保存预测模型,Paddle Lite 对此类预测模型已经做了充分支持;在 PaddlePaddle 动态图模式下,使用`paddle.jit.save`这个 API 保存预测模型,Paddle Lite 可以支持绝大部分此类预测模型了。 + +- 使用 opt 工具优化模型 + +Paddle Lite 框架拥有优秀的加速、优化策略及实现,包含量化、子图融合、Kernel 优选等优化手段。优化后的模型更轻量级,耗费资源更少,并且执行速度也更快。 +这些优化通过 Paddle Lite 提供的 opt 工具实现。opt 工具还可以统计并打印出模型中的算子信息,并判断不同硬件平台下 Paddle Lite 的支持情况。 + +导出 inference model 和使用 opt 工具优化参考[mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu)中的**获取 inference model**和**生成 Paddle Lite 部署模型**章节,注意本步骤需要核验是否有```xxx.nb```模型生成。 + +### 2.3 准备推理所需代码 + +- Paddle Lite 预测库 + +Paddle Lite 提供了 `Android/IOS/ArmLinux/Windows/MacOS/Ubuntu` 平台的官方 Release 预测库下载,我们优先推荐您直接下载 [Paddle Lite 预编译库](https://github.com/PaddlePaddle/Paddle-Lite/releases/tag/v2.10)。您也可以根据目标平台选择对应的 [源码编译方法](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html)。Paddle Lite 提供了源码编译脚本,位于 `lite/tools/` 文件夹下,只需要进行必要的环境准备之后即可运行。 + +- 用户的推理应用程序,例如mobilenet_v3.cc + +- Makefile用于编译应用程序 + +至此已经准备好部署所需的全部文件。以[mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu)中的 mobilenet_v3 文件夹为例展示: + +``` + mobilenet_v3/ 示例文件夹 + ├── inference_lite_lib.android.armv8/ Paddle Lite C++ 预测库和头文件 + │ + ├── Makefile 编译相关 + │ + ├── Makefile.def 编译相关 + │ + ├── mobilenet_v3_small.nb 优化后的模型 + │ + ├── mobilenet_v3.cc C++ 示例代码 + │ + ├── demo.jpg 示例图片 + │ + ├── imagenet1k_label_list.txt 示例label(用于后处理) + │ + └── config.txt 示例config(用于前处理) +``` + +### 2.4 开发数据预处理程序 + +Paddle Lite 推理框架的输入不能直接是图片,所以需要对图片进行预处理,预处理过程一般包括 `opencv 读取`、`resize`、 `crop`、`归一化`等操作,之后才能变成最后输入给推理框架的数据。预处理参考 [mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3) 中的mobilenet_v3.cc 文件。 + + + +### 2.5 开发推理程序 + +使用 Paddle Lite 的 `API` 只需简单五步即可完成预测: + +1. 声明 `MobileConfig` ,设置第二步优化后的模型文件路径,或选择从内存中加载模型 +2. 创建 `Predictor` ,调用 `CreatePaddlePredictor` 接口,一行代码即可完成引擎初始化 +3. 准备输入,通过 `predictor->GetInput(i)` 获取输入变量,并为其指定输入大小和输入值 +4. 执行预测,只需要运行 `predictor->Run()` 一行代码,即可使用 Paddle Lite 框架完成预测执行 +5. 获得输出,使用 `predictor->GetOutput(i)` 获取输出变量,并通过 `data` 取得输出值 + +在此提供简单示例: + +```c++ +#include +// 引入 C++ API +#include "paddle_lite/paddle_api.h" +#include "paddle_lite/paddle_use_ops.h" +#include "paddle_lite/paddle_use_kernels.h" + +// 1. 设置 MobileConfig +MobileConfig config; +config.set_model_from_file(); // 设置 NaiveBuffer 格式模型路径 +config.set_power_mode(LITE_POWER_NO_BIND); // 设置 CPU 运行模式 +config.set_threads(4); // 设置工作线程数 + +// 2. 创建 PaddlePredictor +std::shared_ptr predictor = CreatePaddlePredictor(config); + +// 3. 设置输入数据,可以在这里进行您的前处理,比如用opencv读取图片等。这里为全一输入。 +std::unique_ptr input_tensor(std::move(predictor->GetInput(0))); +input_tensor->Resize({1, 3, 224, 224}); +auto* data = input_tensor->mutable_data(); +for (int i = 0; i < ShapeProduction(input_tensor->shape()); ++i) { + data[i] = 1; +} + +//其他前处理 + +// 4. 执行预测 +predictor->run(); + +// 5. 获取输出数据 +std::unique_ptr output_tensor(std::move(predictor->GetOutput(0))); +std::cout << "Output shape " << output_tensor->shape()[1] << std::endl; +for (int i = 0; i < ShapeProduction(output_tensor->shape()); i += 100) { + std::cout << "Output[" << i << "]: " << output_tensor->data()[i] + << std::endl; +} +//后处理 +``` + +### 2.6 开发推理结果后处理程序 + +后处理主要处理的是Paddle Lite 推理框架的输出 `tensor`, 包括选取哪个 `tensor` 以及根据 `label` 文件进行获得预测的类别,后处理参考 [mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu/mobilenet_v3) 中的mobilenet_v3.cc 文件。 + +### 2.7 验证推理结果正确性 + +Paddle Lite 的推理结果,需要和训练框架的预测结果对比是否一致。注意此过程中需要首先保证前处理和后处理与训练代码是一致的。具体可以参考 [mobilenet_v3开发实战](../../mobilenetv3_prod/Step6/deploy/lite_infer_cpp_arm_cpu)。 + +## 3. FAQ + +### 3.1 通用问题 +如果您在使用过程中遇到任何问题,可以参考 [Paddle Lite 文档](https://paddle-lite.readthedocs.io/zh/latest/index.html) ,还可以在[这里](https://github.com/PaddlePaddle/Paddle-Lite/issues)提 issue 给我们,我们会高优跟进。