1、编译tensorflow模型到手机
<h3>1、准备数据</h3>
<p>参考:<a href="https://blog.csdn.net/h_o_w_e/article/details/79271885">https://blog.csdn.net/h_o_w_e/article/details/79271885</a>
1、<a href="https://github.com/tensorflow/tensorflow/tree/r1.5">https://github.com/tensorflow/tensorflow/tree/r1.5</a> 下载1.5版本
Android的示例代码在tensorflow-r1.5\tensorflow\examples\android目录下。</p>
<h4>2、修改build.gradle和download-models.gradle两个文件:</h4>
<p>2.1 修改build.gradle , 把nativeBuildSystem的值改为none
def nativeBuildSystem = 'none'
2.2 修改build.gradle和download-models.gradle,把
jcenter()替换为 jcenter { url "<a href="http://jcenter.bintray.com">http://jcenter.bintray.com</a>" }
//jcenter()
jcenter { url "<a href="http://jcenter.bintray.com">http://jcenter.bintray.com</a>" }</p>
<h4>3、下载tensorflow动态库(是的,懒的编译了)</h4>
<p><a href="http://ci.tensorflow.org/view/Nightly/job/nightly-android/lastSuccessfulBuild/artifact/out/native/libtensorflow_demo.so/">http://ci.tensorflow.org/view/Nightly/job/nightly-android/lastSuccessfulBuild/artifact/out/native/libtensorflow_demo.so/</a>
点击(打包下载全部文件),
然后在android的目录下增加libs文件夹,解压缩后把arm64-v8a,armeabi-v7a,x86,x86_64这些子目录及文件都放进libs。</p>
<h4>4、下载tensorflow的训练好的模型</h4>
<p>特别说明,有些同学直接下载https://storage.googleapis.com/download.tensorflow.org/models这是不对的。应该是下载下面4个文件(通过浏览器直接下载就行)</p>
<p><a href="https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip">https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip</a>
<a href="https://storage.googleapis.com/download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_android_export.zip">https://storage.googleapis.com/download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_android_export.zip</a>
<a href="https://storage.googleapis.com/download.tensorflow.org/models/stylize_v1.zip">https://storage.googleapis.com/download.tensorflow.org/models/stylize_v1.zip</a>
<a href="https://storage.googleapis.com/download.tensorflow.org/models/speech_commands_conv_actions.zip">https://storage.googleapis.com/download.tensorflow.org/models/speech_commands_conv_actions.zip</a>
下载完毕之后,把4个zip文件放到android\gradleBuild\downloads目录下。</p>
<p>5、github上tensorflow1.5版、android/libs/libtensorflow_inference.so、libtensorflow_demo.so
把4个zip文件放到android\gradleBuild\downloads目录下,没有目录的新建目录</p>
<p>build.gradle 实例</p>
<pre><code>// This file provides basic support for building the TensorFlow demo
// in Android Studio with Gradle.
//
// Note that Bazel is still used by default to compile the native libs,
// and should be installed at the location noted below. This build file
// automates the process of calling out to it and copying the compiled
// libraries back into the appropriate directory.
//
// Alternatively, experimental support for Makefile builds is provided by
// setting nativeBuildSystem below to 'makefile'. This will allow building the demo
// on Windows machines, but note that full equivalence with the Bazel
// build is not yet guaranteed. See comments below for caveats and tips
// for speeding up the build, such as enabling ccache.
// NOTE: Running a make build will cause subsequent Bazel builds to *fail*
// unless the contrib/makefile/downloads/ and gen/ dirs are deleted afterwards.
// cmake仅生成libtensorflow_demo.so、
// libtensorflow_inference.so需要tensorflow.aar的依赖
// The cmake build only creates libtensorflow_demo.so. In this situation,
// libtensorflow_inference.so will be acquired via the tensorflow.aar dependency.
// It is necessary to customize Gradle's build directory, as otherwise
// it will conflict with the BUILD file used by Bazel on case-insensitive OSs.
project.buildDir = 'gradleBuild'
getProject().setBuildDir('gradleBuild')
buildscript {
repositories {
jcenter { url "http://jcenter.bintray.com" }
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'org.apache.httpcomponents:httpclient:4.5.4'
}
}
allprojects {
repositories {
jcenter { url "http://jcenter.bintray.com" }
google()
}
}
// set to 'bazel', 'cmake', 'makefile', 'none'
def nativeBuildSystem = 'none'
//def nativeBuildSystem = 'bazel'
// Controls output directory in APK and CPU type for Bazel builds.
// NOTE: Does not affect the Makefile build target API (yet), which currently
// assumes armeabi-v7a. If building with make, changing this will require
// editing the Makefile as well.
// The CMake build has only been tested with armeabi-v7a; others may not work.
def cpuType = 'armeabi-v7a'
// Output directory in the local directory for packaging into the APK.
def nativeOutDir = 'libs/' + cpuType
// Default to building with Bazel and override with make if requested.
def nativeBuildRule = 'buildNativeBazel'
def demoLibPath = '../../../bazel-bin/tensorflow/examples/android/libtensorflow_demo.so'
def inferenceLibPath = '../../../bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so'
if (nativeBuildSystem == 'makefile') {
nativeBuildRule = 'buildNativeMake'
demoLibPath = '../../../tensorflow/contrib/makefile/gen/lib/libtensorflow_demo.so'
inferenceLibPath = '../../../tensorflow/contrib/makefile/gen/lib/libtensorflow_inference.so'
}
// If building with Bazel, this is the location of the bazel binary.
// NOTE: Bazel does not yet support building for Android on Windows,
// so in this case the Makefile build must be used as described above.
def bazelLocation = '/usr/local/bin/bazel'
// 导入下载模型的任务
// import DownloadModels task
project.ext.ASSET_DIR = projectDir.toString() + '/assets'
project.ext.TMP_DIR = project.buildDir.toString() + '/downloads'
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '26.0.2'
if (nativeBuildSystem == 'cmake') {
defaultConfig {
applicationId = 'org.tensorflow.demo'
minSdkVersion 21
targetSdkVersion 23
ndk {
abiFilters "${cpuType}"
}
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=gcc', '-DANDROID_STL=gnustl_static'
}
}
}
externalNativeBuild {
cmake {
path './jni/CMakeLists.txt'
}
}
}
lintOptions {
abortOnError false
}
sourceSets {
main {
if (nativeBuildSystem == 'bazel' || nativeBuildSystem == 'makefile') {
// TensorFlow Java API sources.
java {
srcDir '../../java/src/main/java'
exclude '**/examples/**'
}
// Android TensorFlow wrappers, etc.
java {
srcDir '../../contrib/android/java'
}
}
// Android demo app sources.
java {
srcDir 'src'
}
manifest.srcFile 'AndroidManifest.xml'
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = [project.ext.ASSET_DIR]
jniLibs.srcDirs = ['libs']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}
task buildNativeBazel(type: Exec) {
workingDir '../../..'
commandLine bazelLocation, 'build', '-c', 'opt', \
'tensorflow/examples/android:tensorflow_native_libs', \
'--crosstool_top=//external:android/crosstool', \
'--cpu=' + cpuType, \
'--host_crosstool_top=@bazel_tools//tools/cpp:toolchain'
}
task buildNativeMake(type: Exec) {
environment "NDK_ROOT", android.ndkDirectory
// Tip: install ccache and uncomment the following to speed up
// builds significantly.
// environment "CC_PREFIX", 'ccache'
workingDir '../../..'
commandLine 'tensorflow/contrib/makefile/build_all_android.sh', \
'-s', \
'tensorflow/contrib/makefile/sub_makefiles/android/Makefile.in', \
'-t', \
'libtensorflow_inference.so libtensorflow_demo.so' \
//, '-T' // Uncomment to skip protobuf and speed up subsequent builds.
}
task copyNativeLibs(type: Copy) {
from demoLibPath
from inferenceLibPath
into nativeOutDir
duplicatesStrategy = 'include'
dependsOn nativeBuildRule
fileMode 0644
}
tasks.whenTaskAdded { task ->
if (nativeBuildSystem == 'bazel' || nativeBuildSystem == 'makefile') {
if (task.name == 'assembleDebug') {
task.dependsOn 'copyNativeLibs'
}
if (task.name == 'assembleRelease') {
task.dependsOn 'copyNativeLibs'
}
}
}
// Download default models; if you wish to use your own models then
// place them in the "assets" directory and comment out this line.
// 注释下面语句将不执行下载任务
// apply from: "download-models.gradle"
dependencies {
if (nativeBuildSystem == 'cmake' || nativeBuildSystem == 'none') {
compile 'org.tensorflow:tensorflow-android:+'
}
}
</code></pre>
<p>download-models.gradle 实例</p>
<pre><code>/*
* download-models.gradle
* Downloads model files from ${MODEL_URL} into application's asset folder
* Input:
* project.ext.TMP_DIR: absolute path to hold downloaded zip files
* project.ext.ASSET_DIR: absolute path to save unzipped model files
* Output:
* 3 model files will be downloaded into given folder of ext.ASSET_DIR
*/
// hard coded model files
// LINT.IfChange
def models = ['inception5h.zip',
'object_detection/ssd_mobilenet_v1_android_export.zip',
'stylize_v1.zip',
'speech_commands_conv_actions.zip']
// LINT.ThenChange(//tensorflow/examples/android/BUILD)
// Root URL for model archives
def MODEL_URL = 'https://storage.googleapis.com/download.tensorflow.org/models'
buildscript {
repositories {
jcenter { url "http://jcenter.bintray.com" }
}
dependencies {
classpath 'de.undercouch:gradle-download-task:3.2.0'
}
}
import de.undercouch.gradle.tasks.download.Download
task downloadFile(type: Download){
for (f in models) {
src "${MODEL_URL}/" + f
}
dest new File(project.ext.TMP_DIR)
overwrite true
}
task extractModels(type: Copy) {
for (f in models) {
def localFile = f.split("/")[-1]
from zipTree(project.ext.TMP_DIR + '/' + localFile)
}
into file(project.ext.ASSET_DIR)
fileMode 0644
exclude '**/LICENSE'
def needDownload = false
for (f in models) {
def localFile = f.split("/")[-1]
if (!(new File(project.ext.TMP_DIR + '/' + localFile)).exists()) {
needDownload = true
}
}
if (needDownload) {
dependsOn downloadFile
}
}
tasks.whenTaskAdded { task ->
if (task.name == 'assembleDebug') {
task.dependsOn 'extractModels'
}
if (task.name == 'assembleRelease') {
task.dependsOn 'extractModels'
}
}
</code></pre>