在Android手机上使用MACE实现图像分类

article/2025/9/15 15:47:54

前言

在之前笔者有介绍过《在Android设备上使用PaddleMobile实现图像分类》,使用的框架是百度开源的PaddleMobile。在本章中,笔者将会介绍使用小米的开源手机深度学习框架MACE来实现在Android手机实现图像分类。

MACE的GitHub地址:https://github.com/XiaoMi/mace

编译MACE库和模型

编译MACE库和模型有两种方式,一种是在Ubuntu本地上编译,另一种是使用docker编译。下面就介绍使用这两种编译方式。

使用Ubuntu编译

使用Ubuntu编译源码比较麻烦的是就要自己配置环境,所以下面我们就来配置一下环境。以下是官方给出的环境依赖:

所需依赖

SoftwareInstallation commandTested version
Python2.7
Bazelbazel installation guide0.13.0
CMakeapt-get install cmake>= 3.11.3
Jinja2pip install -I jinja2==2.102.10
PyYamlpip install -I pyyaml==3.123.12.0
shpip install -I sh==1.12.141.12.14
Numpypip install -I numpy==1.14.0Required by model validation
sixpip install -I six==1.11.0Required for Python 2 and 3 compatibility (TODO)

可选依赖

SoftwareInstallation commandRemark
Android NDKNDK installation guideRequired by Android build, r15b, r15c, r16b, r17b
ADBapt-get install android-tools-adbRequired by Android run, >= 1.0.32
TensorFlowpip install -I tensorflow==1.6.0Required by TensorFlow model
Dockerdocker installation guideRequired by docker mode for Caffe model
Scipypip install -I scipy==1.0.0Required by model validation
FileLockpip install -I filelock==3.0.0Required by run on Android

安装依赖环境

  • 安装Bazel
export BAZEL_VERSION=0.13.1
mkdir /bazel && \cd /bazel && \wget https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \chmod +x bazel-*.sh && \./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \cd / && \rm -f /bazel/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh
  • 安装Android NDK
# Download NDK r15c
cd /opt/ && \wget -q https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip && \unzip -q android-ndk-r15c-linux-x86_64.zip && \rm -f android-ndk-r15c-linux-x86_64.zipexport ANDROID_NDK_VERSION=r15c
export ANDROID_NDK=/opt/android-ndk-${ANDROID_NDK_VERSION}
export ANDROID_NDK_HOME=${ANDROID_NDK}# add to PATH
export PATH=${PATH}:${ANDROID_NDK_HOME}
  • 安装其他工具
apt-get install -y --no-install-recommends \cmake \android-tools-adb
pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com setuptools
pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com \"numpy>=1.14.0" \scipy \jinja2 \pyyaml \sh==1.12.14 \pycodestyle==2.4.0 \filelock
  • 安装TensorFlow
pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com tensorflow==1.6.0

编译库和模型

  • 克隆MACE源码
git clone https://github.com/XiaoMi/mace.git
  • 进入到官方的Android Demo上
cd mace/mace/examples/android/
  • 修改当前目录下的build.sh,修成如下:
#!/usr/bin/env bashset -e -u -o pipefailpushd ../../../TARGET_ABI=armeabi-v7a
LIBRARY_DIR=mace/examples/android/macelibrary/src/main/cpp/
INCLUDE_DIR=$LIBRARY_DIR/include/mace/public/
LIBMACE_DIR=$LIBRARY_DIR/lib/$TARGET_ABI/rm -rf $LIBRARY_DIR/include/
mkdir -p $INCLUDE_DIRrm -rf $LIBRARY_DIR/lib/
mkdir -p $LIBMACE_DIRrm -rf $LIBRARY_DIR/model/python tools/converter.py convert --config=mace/examples/android/mobilenet.yml --target_abis=$TARGET_ABI
cp -rf builds/mobilenet/include/mace/public/*.h $INCLUDE_DIR
cp -rf builds/mobilenet/model $LIBRARY_DIRbazel build --config android --config optimization mace/libmace:libmace_static --define neon=true --define openmp=true --define opencl=true --cpu=$TARGET_ABI
cp -rf mace/public/*.h $INCLUDE_DIR
cp -rf bazel-genfiles/mace/libmace/libmace.a $LIBMACE_DIRpopd
  • 修改模型的配置文件mobilenet.yml,修改成如下,这些属性的文件可以查看官方的文档,各个模型的配置可以参考Mobile Model Zoo下的各个模型,以下是以为MobileNet V2为例。
library_name: mobilenet
target_abis: [armeabi-v7a]
model_graph_format: code
model_data_format: code
models:mobilenet_v2:platform: tensorflowmodel_file_path: https://cnbj1.fds.api.xiaomi.com/mace/miai-models/mobilenet-v2/mobilenet-v2-1.0.pbmodel_sha256_checksum: 369f9a5f38f3c15b4311c1c84c032ce868da9f371b5f78c13d3ea3c537389bb4subgraphs:- input_tensors:- inputinput_shapes:- 1,224,224,3output_tensors:- MobilenetV2/Predictions/Reshape_1output_shapes:- 1,1001runtime: cpu+gpulimit_opencl_kernel_time: 0nnlib_graph_mode: 0obfuscate: 0winograd: 0
  • 开始编译
./build.sh
  • 编译完成之后,可以在mace/mace/examples/android/macelibrary/src/main/cpp/看到多了3个文件:
  1. include是存放调用mace接口和模型配置的头文件
  2. lib是存放编译好的mace库
  3. model是存放模型的文件夹,比如我们编译的MobileNet V2模型

使用Docker编译

  • 首先安装docker,命令如下:
apt-get install docker.io
  • 拉取mace镜像:
docker pull registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev
  • 获取MACE源码,并按照上一步修改mace/mace/examples/android/目录下的build.shmobilenet.yml这个两个文件。
git clone https://github.com/XiaoMi/mace.git
  • 进入到MACE的根目录,执行以下命令:
docker run -it -v $PWD:/mace registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev
  • 接着执行以下命令:
cd mace/mace/examples/android/
./build.sh

执行之后便可得到跟上一步获取的一样的文件。使用docker就简单很多,少了很多安装依赖环境的步骤。

开发Android项目

  • 创建Android项目

在创建项目是要选择C++支持。
这里写图片描述

因为MACE最低支持版本是Android5.0,所以这里要选择Android5.0。
这里写图片描述

MACE使用的是C++11。
这里写图片描述

  • 复制C++文件。删除cpp目录下自动生产的C++文件,并复制上一步编译得到的3个目录和本来就有的两C++文件到Android项目的cpp目录下。如下图:
    这里写图片描述

  • 修改CMakeLists.txt编译文件,修改如下,编译对应的是我们上一步复制的C++文件:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../app/libs/${ANDROID_ABI})include_directories(${CMAKE_SOURCE_DIR}/)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
set(mace_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/lib/armeabi-v7a/libmace.a)
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/armeabi-v7a/mobilenet.a)
add_library (mace_lib STATIC IMPORTED)
set_target_properties(mace_lib PROPERTIES IMPORTED_LOCATION ${mace_lib})
add_library (mobilenet_lib STATIC IMPORTED)
set_target_properties(mobilenet_lib PROPERTIES IMPORTED_LOCATION ${mobilenet_lib})add_library( # Sets the name of the library.mace_mobile_jni# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).src/main/cpp/image_classify.cc )# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log )# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.mace_mobile_jnimace_libmobilenet_lib# Links the target library to the log library# included in the NDK.${log-lib} )
  • 修改app目录下的build.gradle,修改如下:

把原来的

externalNativeBuild {cmake {cppFlags "-std=c++11"}}

修改成,因为我们只编译了armeabi-v7a支持:

externalNativeBuild {cmake {cppFlags "-std=c++11 -fopenmp"abiFilters "armeabi-v7a"}}

android下加上:

    sourceSets {main {jniLibs.srcDirs = ["src/main/jniLibs"]jni.srcDirs = ['src/cpp']}}
  • 修改Android项目使用的NDK版本,我们编译的时候是使用r15c,所以我们在Android项目上也要使用r15c,如下:
    这里写图片描述

  • 创建一个com.xiaomi.mace包,并复制官方demo中的java类JniMaceUtils.java到该包中,代码如下,这个就是使用mace的JNI接口:

package com.xiaomi.mace;public class JniMaceUtils {static {System.loadLibrary("mace_mobile_jni");}// 设置模型属性public static native int maceMobilenetSetAttrs(int ompNumThreads, int cpuAffinityPolicy, int gpuPerfHint, int gpuPriorityHint, String kernelPath);// 加载模型和选择使用GPU或CPUpublic static native int maceMobilenetCreateEngine(String model, String device);// 预测图片public static native float[] maceMobilenetClassify(float[] input);
}
  • 在项目的包下创建一个InitData.java类,这个是配置mace的信息类,比如使用CPU还是GPU来预测,加载的是那个模型等等:
package com.example.myapplication;import android.os.Environment;import java.io.File;public class InitData {public static final String[] DEVICES = new String[]{"CPU", "GPU"};public static final String[] MODELS = new String[]{"mobilenet_v1", "mobilenet_v2"};private String model;private String device = "";private int ompNumThreads;private int cpuAffinityPolicy;private int gpuPerfHint;private int gpuPriorityHint;private String kernelPath = "";public InitData() {model = MODELS[1];ompNumThreads = 4;cpuAffinityPolicy = 0;gpuPerfHint = 3;gpuPriorityHint = 3;device = DEVICES[0];kernelPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "mace";File file = new File(kernelPath);if (!file.exists()) {file.mkdir();}}public String getModel() {return model;}public void setModel(String model) {this.model = model;}public String getDevice() {return device;}public void setDevice(String device) {this.device = device;}public int getOmpNumThreads() {return ompNumThreads;}public void setOmpNumThreads(int ompNumThreads) {this.ompNumThreads = ompNumThreads;}public int getCpuAffinityPolicy() {return cpuAffinityPolicy;}public void setCpuAffinityPolicy(int cpuAffinityPolicy) {this.cpuAffinityPolicy = cpuAffinityPolicy;}public int getGpuPerfHint() {return gpuPerfHint;}public void setGpuPerfHint(int gpuPerfHint) {this.gpuPerfHint = gpuPerfHint;}public int getGpuPriorityHint() {return gpuPriorityHint;}public void setGpuPriorityHint(int gpuPriorityHint) {this.gpuPriorityHint = gpuPriorityHint;}public String getKernelPath() {return kernelPath;}public void setKernelPath(String kernelPath) {this.kernelPath = kernelPath;}
}
  • 同样是在项目的包下创建PhotoUtil.java类,这是一个工具类,包括启动相机获拍摄图片并返回该图片的绝对路径,还有一个是把图片转换成预测的数据,mace读取的预测数据是一个float数组。
package com.example.myapplication;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;public class PhotoUtil {// start camerapublic static Uri start_camera(Activity activity, int requestCode) {Uri imageUri;// save image in cache pathFile outputImage = new File(activity.getExternalCacheDir(), "out_image.jpg");try {if (outputImage.exists()) {outputImage.delete();}outputImage.createNewFile();} catch (IOException e) {e.printStackTrace();}if (Build.VERSION.SDK_INT >= 24) {// compatible with Android 7.0 or overimageUri = FileProvider.getUriForFile(activity,"com.example.myapplication", outputImage);} else {imageUri = Uri.fromFile(outputImage);}// set system camera ActionIntent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// set save photo pathintent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);// set photo quality, min is 0, max is 1intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);activity.startActivityForResult(intent, requestCode);return imageUri;}// get picture in photopublic static void use_photo(Activity activity, int requestCode){Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/*");activity.startActivityForResult(intent, requestCode);}// get photo from Uripublic static String get_path_from_URI(Context context, Uri uri) {String result;Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);if (cursor == null) {result = uri.getPath();} else {cursor.moveToFirst();int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);result = cursor.getString(idx);cursor.close();}return result;}// Compress the image to the size of the training imagepublic static float[] getScaledMatrix(Bitmap bitmap, int desWidth,int desHeight) {// create data bufferfloat[] floatValues = new float[desWidth * desHeight * 3];FloatBuffer floatBuffer = FloatBuffer.wrap(floatValues, 0, desWidth * desHeight * 3);floatBuffer.rewind();// get image pixelint[] pixels = new int[desWidth * desHeight];Bitmap bm = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, false);bm.getPixels(pixels, 0, bm  .getWidth(), 0, 0, desWidth, desHeight);// pixel to datafor (int clr : pixels) {floatBuffer.put((((clr >> 16) & 0xFF) - 128f) / 128f);floatBuffer.put((((clr >> 8) & 0xFF) - 128f) / 128f);floatBuffer.put(((clr & 0xFF) - 128f) / 128f);}if (bm.isRecycled()) {bm.recycle();}return floatBuffer.array();}// compress picturepublic static Bitmap getScaleBitmap(String filePath) {BitmapFactory.Options opt = new BitmapFactory.Options();opt.inJustDecodeBounds = true;BitmapFactory.decodeFile(filePath, opt);int bmpWidth = opt.outWidth;int bmpHeight = opt.outHeight;int maxSize = 500;// compress picture with inSampleSizeopt.inSampleSize = 1;while (true) {if (bmpWidth / opt.inSampleSize < maxSize || bmpHeight / opt.inSampleSize < maxSize) {break;}opt.inSampleSize *= 2;}opt.inJustDecodeBounds = false;return BitmapFactory.decodeFile(filePath, opt);}
}
  • 修改MainActivity.java,修改如下,主要是有两个功能,第一个是打开相册选择图片进行预测,另一个是启动相机拍摄图片进行预测。在进入应用是就调用init_model()方法来设置mace的配置信息和加载模型,其中可以通过调用load_model(String model)该更换模型。通过调用predict_image(String image_path)方法预测图片并显示结果:
package com.example.myapplication;import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.xiaomi.mace.JniMaceUtils;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class MainActivity extends AppCompatActivity {private static final String TAG = MainActivity.class.getName();private static final int USE_PHOTO = 1001;private static final int START_CAMERA = 1002;private Uri camera_image_path;private ImageView show_image;private TextView result_text;private boolean load_result = false;private int[] ddims = {1, 3, 224, 224};private int model_index = 1;private InitData initData = new InitData();private List<String> resultLabel = new ArrayList<>();private static final String[] PADDLE_MODEL = {"mobilenet_v1","mobilenet_v2"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init_view();init_model();readCacheLabelFromLocalFile();}// initialize viewprivate void init_view() {request_permissions();show_image = (ImageView) findViewById(R.id.show_image);result_text = (TextView) findViewById(R.id.result_text);result_text.setMovementMethod(ScrollingMovementMethod.getInstance());Button use_photo = (Button) findViewById(R.id.use_photo);Button start_photo = (Button) findViewById(R.id.start_camera);// use photo clickuse_photo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (!load_result) {Toast.makeText(MainActivity.this, "never load model", Toast.LENGTH_SHORT).show();return;}PhotoUtil.use_photo(MainActivity.this, USE_PHOTO);}});// start camera clickstart_photo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (!load_result) {Toast.makeText(MainActivity.this, "never load model", Toast.LENGTH_SHORT).show();return;}camera_image_path = PhotoUtil.start_camera(MainActivity.this, START_CAMERA);}});}// init mace environmentprivate void init_model() {int result = JniMaceUtils.maceMobilenetSetAttrs(initData.getOmpNumThreads(), initData.getCpuAffinityPolicy(),initData.getGpuPerfHint(), initData.getGpuPriorityHint(),initData.getKernelPath());Log.i(TAG, "maceMobilenetSetAttrs result = " + result);load_model(PADDLE_MODEL[model_index]);}// load infer modelprivate void load_model(String model) {// set will load model nameinitData.setModel(model);// load modelint result = JniMaceUtils.maceMobilenetCreateEngine(initData.getModel(), initData.getDevice());Log.i(TAG, "maceMobilenetCreateEngine result = " + result);// set load model resultload_result = result == 0;if (load_result) {Toast.makeText(MainActivity.this, model + " model load success", Toast.LENGTH_SHORT).show();Log.d(TAG, model + " model load success");} else {Toast.makeText(MainActivity.this, model + " model load fail", Toast.LENGTH_SHORT).show();Log.d(TAG, model + " model load fail");}}private void readCacheLabelFromLocalFile() {try {AssetManager assetManager = getApplicationContext().getAssets();BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open("cacheLabel.txt")));String readLine = null;while ((readLine = reader.readLine()) != null) {resultLabel.add(readLine);}reader.close();} catch (Exception e) {Log.e("labelCache", "error " + e);}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {String image_path;RequestOptions options = new RequestOptions().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE);if (resultCode == Activity.RESULT_OK) {switch (requestCode) {case USE_PHOTO:if (data == null) {Log.w(TAG, "user photo data is null");return;}Uri image_uri = data.getData();Glide.with(MainActivity.this).load(image_uri).apply(options).into(show_image);// get image path from uriimage_path = PhotoUtil.get_path_from_URI(MainActivity.this, image_uri);// predict imagepredict_image(image_path);break;case START_CAMERA:// show photoGlide.with(MainActivity.this).load(camera_image_path).apply(options).into(show_image);image_path = PhotoUtil.get_path_from_URI(MainActivity.this, camera_image_path);// predict imagepredict_image(image_path);break;}}}//  predict imageprivate void predict_image(String image_path) {// picture to float arrayBitmap bmp = PhotoUtil.getScaleBitmap(image_path);float[] inputData = PhotoUtil.getScaledMatrix(bmp, ddims[2], ddims[3]);try {// Data format conversion takes too long// Log.d("inputData", Arrays.toString(inputData));long start = System.currentTimeMillis();// get predict resultfloat[] result = JniMaceUtils.maceMobilenetClassify(inputData);long end = System.currentTimeMillis();Log.d(TAG, "origin predict result:" + Arrays.toString(result));long time = end - start;Log.d("result length", String.valueOf(result.length));// show predict result and timeint r = get_max_result(result);String show_text = "result:" + r + "\nname:" + resultLabel.get(r) + "\nprobability:" + result[r] + "\ntime:" + time + "ms";result_text.setText(show_text);} catch (Exception e) {e.printStackTrace();}}// get max probability labelprivate int get_max_result(float[] result) {float probability = result[0];int r = 0;for (int i = 0; i < result.length; i++) {if (probability < result[i]) {probability = result[i];r = i;}}return r;}// request permissionsprivate void request_permissions() {List<String> permissionList = new ArrayList<>();if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.CAMERA);}if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);}if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);}// if list is not empty will request permissionsif (!permissionList.isEmpty()) {ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode) {case 1:if (grantResults.length > 0) {for (int i = 0; i < grantResults.length; i++) {int grantResult = grantResults[i];if (grantResult == PackageManager.PERMISSION_DENIED) {String s = permissions[i];Toast.makeText(this, s + " permission was denied", Toast.LENGTH_SHORT).show();}}}break;}}
}
  • main下创建一个asset目录并加入这个文件

  • 最后别忘了在配置文件AndroidManifest.xml上加上权限

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

最后运行得到的结果如下图:
在这里插入图片描述

注意:该项目对Android7.0相机兼容不是很好。
源码下载: 上面已经是全部代码了,如果读者想更方便使用,可以直接下载该项目

参考资料

  1. https://github.com/XiaoMi/mace
  2. https://mace.readthedocs.io/en/latest/

http://chatgpt.dhexx.cn/article/0ofjjYNd.shtml

相关文章

Ubuntu 16.04 下编译小米mace源码依赖库,跑在android板子上

https://blog.csdn.net/qq_27063119/article/details/81015227 以上链接是编译mace源码的基础步骤&#xff0c;下面我叙述一下本人编译所踩过的坑 1、编译过程中所需要的依赖必须全部安装&#xff0c;就算你一开始并没有用到的依赖&#xff0c;到后面还是会用到&#xff0c;还…

比拼三大移动端深度学习框架,小米MACE有哪些优势?

采访嘉宾 | 何亮亮 AI前线导读&#xff1a; 随着深度学习领域的快速发展&#xff0c;以及移动端芯片计算能力的逐步提升&#xff0c;设备端上的深度学习推理正在变成一个巨大的需求和趋势&#xff0c;一个好用的深度学习框架成为深度学习应用落地的关键。小米团队打造的MACE (…

小米开源框架mace android案例调试

小米开源框架mace android案例调试 1. 准备工作 编译环境准备&#xff1a;请参照小米官方的文档&#xff1a; https://mace.readthedocs.io/en/latest/installation/env_requirement.html Required dependencies SoftwareInstallation commandTested versionPython 2.7Bazelba…

MACE的环境搭建——conda实现

1. MACE 主页 MACE 的github地址&#xff1a;https://github.com/XiaoMi/mace 小米官方的相关文档&#xff1a;https://mace.readthedocs.io/en/latest/ 对开发环境的要求&#xff0c;可以按照以下指令安装相关的包&#xff1a; 2. 创建虚拟环境并安装常见的包 (1) 创建虚拟环境…

小米开源自研移动端深度学习框架MACE

小米人工智能与云平台副总裁崔宝秋博士在开源中国开源世界高峰论坛上发表《小米 AI 时代的开源》演讲&#xff0c;并在会上宣布&#xff0c;开源小米自研的移动端深度学习框架 Mobile AI Compute Engine (MACE)。 6 月 28 日&#xff0c;小米人工智能与云平台副总裁崔宝秋博士在…

小米开源框架MACE 源码阅读笔记

转载自 https://www.jianshu.com/p/7061fd67d419 前扯 在前不久的某高峰论坛上&#xff0c;小米开源了其移动端的深度学习框架Mobile AI Compute Engine&#xff08;MACE&#xff09;。这对于很多致力于嵌入式端优化的人来说&#xff0c;无疑是巨大的惊喜&#xff08;新坑出现&…

Mace-micro引擎编译与测试

官方简介 Mobile AI Compute Engine (MACE) 是一个专为移动端异构计算平台(支持Android, iOS, Linux, Windows)优化的神经网络计算框架。 主要从以下的角度做了专门的优化&#xff1a; 性能 代码经过NEON指令&#xff0c;OpenCL以及Hexagon HVX专门优化&#xff0c;并且采用W…

小米MACE开源框架搭建

一、环境配置 请参照小米官方的文档&#xff1a; https://mace.readthedocs.io/en/latest/installation/env_requirement.html For Android build, ANDROID_NDK_HOME must be confifigured by using export ANDROID_NDK_HOME/path/to/ndk It will link libc instead of gnustl …

小米AI平台MACE的构建和部署

1.准备部署文件 需要准备的部署文件包括头文件(.h), mace库文件(.)&#xff0c;转化后的模型(.a)&#xff0c;这里以resnet18v1-opt.onnx模型为例 1.1. 优化onnx模型 # Optimize your model $python MACE_ROOT/tools/onnx_optimizer.py resnet18v1.onnx resnet18v1-opt.onnx…

小米开源框架MACE - 源码阅读笔记一

首先先一目了然看一下其目录结构&#xff08;这些个源码可以在github上下载到&#xff0c;只要在GitHub搜索mace即可&#xff09;&#xff1a; 介绍 MACE&#xff08;Mobile AI Compute Engine&#xff09;是一个针对移动异构计算平台优化的深度学习推理框架。MACE提供工具和文…

MACE的环境搭建和工程构建

1. MACE 主页 MACE 的github地址&#xff1a;https://github.com/XiaoMi/mace 小米官方的相关文档&#xff1a;https://mace.readthedocs.io/en/latest/ 对开发环境的要求&#xff0c;可以按照以下指令安装相关的包&#xff1a; 2. 安装docker 参照教程&#xff1a;https:/…

meterpreter之timestomp命令修改文件MACE时间

文章目录 前言一、timestomp的使用前提二、MACE时间1、文件系统简述2、linux操作系统3、windows操作系统 三、timestomp使用详解1.查看帮助文档2.使用-v选项查看文件信息3.使用-f选项拷贝文件MACE时间4.使用-m/-a/-c/-e修改文件MACE时间5.使用-b/-r使MACE时间显示清空 总结 前言…

小米开源AI框架mace编译构建

目录 简介 环境要求 1 安装 Bazel 2 安装Android NDK 3 在Ubuntu16.04下安装Docker&#xff08;17.09&#xff09; 构建并运行示例模型 1 拉取MACE项目 2 拉取MACE Model Zoo项目 3 构建通用MACE库 4 将预先训练的mobilenet-v2模型转换为MACE格式模型 编译运行DEMO…

使用MACE加速---使用篇

最近开始研究如何对手机应用中的识别算法进行加速&#xff0c;搜索后发现了小米的MACE。 Mobile AI Compute Engine (MACE) 是一个专为移动端异构计算设备优化的深度学习前向预测框架。 覆盖了常见的移动端计算设备&#xff08;CPU&#xff0c;GPU和DSP&#xff09;。支持的硬…

小米AI推理框架MACE介绍

MACE 是小米公司自研的移动端深度学习框架 Mobile AI Compute Engine&#xff0c;2017年12月15日于公司内部正式发布。2018年6月28日&#xff0c;在“2018&#xff08;第十三届&#xff09;开源中国开源世界高峰论坛”上&#xff0c;小米公司人工智能与云平台副总裁崔宝秋博士宣…

MACE 使用笔记

环境安装 tensorflow 安装&#xff0c;一直不太想用mace的部分原因是不支持tensorflow2.模型&#xff0c; 但为了GPU(OpenCL)还是要用啊。 Shell set -e 学习笔记&#xff1a; shell 中的 set -e &#xff0c; set e 用法_滴水成川-CSDN博客_linux set-eset -eset命令的-e参…

小米开源框架MACE 简介

转载自 https://www.jianshu.com/p/2ab68779d05b 前言 MACE 是小米公司自研的移动端深度学习框架 Mobile AI Compute Engine&#xff0c;2017年12月15日于公司内部正式发布。2018年6月28日&#xff0c;在“2018&#xff08;第十三届&#xff09;开源中国开源世界高峰论坛”上…

MACE(1)-----环境搭建

学习MACE也有一个月了&#xff0c;将其划分三步来学习。本文是MACE学习的第一步即MACE环境的搭建。之后还有两步mace的编译和mace工程化。 MACE(2)-----模型编译&#xff1a;https://www.cnblogs.com/missidiot/p/9509831.html MACE(3)-----工程化&#xff1a;https://www.cnbl…

JDK , Tomcat , Eclipse 版本对应关系

1. JDK , Tomcat 版本对应关系 参考网址 : https://tomcat.apache.org/whichversion.html 2. JDK , Eclipse 版本对应关系 参考网址 : https://wiki.eclipse.org/Eclipse/Installation 作者 Github : tojohnonly , 博客 : EnskDeCode

如何查看eclipse的版本

阅读数&#xff1a;20254 转载文章&#xff0c;原文地址&#xff1a;https://blog.csdn.net/duqian94/article/details/52386076 由于作者已经写的很清楚了&#xff0c;就没有做修改直接转载过来了。 本篇文章主要讲解的是三种查看eclipse版本的方法&#xff08;超详细&#xf…