2016-01-20 13 views
18

मैं एंड्रॉइड पर टेन्सफोर्लो मॉडल को प्रशिक्षण और तैनाती के लिए वर्कफ़्लो को समझने की कोशिश कर रहा हूं। मुझे स्टैक ओवरफ्लो पर इस तरह के अन्य प्रश्नों के बारे में पता है, लेकिन उनमें से कोई भी उन समस्याओं को हल करने के लिए प्रतीत नहीं होता है जिन्हें मैंने चलाया है।एंड्रॉइड पर एक टेंसफोर्लो मॉडल चलाना

  1. बिल्ड और अजगर में मॉडल Tensorflow प्रशिक्षित:

    Tensorflow रिपोजिटरी से एंड्रॉयड उदाहरण अध्ययन करने के बाद यह मैं क्या सोचता कार्यप्रवाह होना चाहिए।

  2. नया ग्राफ बनाएं, और इस नए ग्राफ में सभी प्रासंगिक नोड्स (यानी प्रशिक्षण के लिए ज़िम्मेदार नोड्स) को स्थानांतरित करें। प्रशिक्षित वज़न चर को स्थिरांक के रूप में आयात किया जाता है ताकि सी ++ एपीआई उन्हें पढ़ सके।
  3. जावा में एंड्रॉइड जीयूआई का विकास, देशी कीवर्ड का उपयोग करके टेंसफोर्लो मॉडल को कॉल करने के लिए।
  4. टेन्सफोर्लो मूल कॉल के लिए सी/सी ++ स्टब कोड उत्पन्न करने के लिए जावा चलाएं।
  5. प्रशिक्षित/क्रमबद्ध मॉडल को पढ़ने और एक्सेस करने के लिए टेन्सफोर्लो सी ++ एपीआई का उपयोग करके स्टब भरें।
  6. दोनों जावा ऐप, देशी टेन्सफोर्लो इंटरफ़ेस (एक .so फ़ाइल के रूप में) बनाने के लिए बेसल का उपयोग करें, और एपीके उत्पन्न करें।
  7. एपीके को तैनात करने के लिए एडीबी का उपयोग करें।

    चरण 6 समस्या है। बेज़ेल खुशी से देशी (ओएसएक्स) को संकलित करेगा। डिलीब जिसे मैं जावा से जेएनआई के माध्यम से कॉल कर सकता हूं। इसी तरह, एंड्रॉइड स्टूडियो एक्सएमएल कोड का एक पूरा समूह उत्पन्न करेगा जो जीयूआई चाहता है। हालांकि, बाजेल चाहता है कि सभी जावा ऐप कोड 'वर्कस्पेस' शीर्ष-स्तरीय निर्देशिका (टेन्सफोर्लो रेपो में) के अंदर हों, और एंड्रॉइड स्टूडियो तुरंत एसडीके से बाहरी पुस्तकालयों में जीयूआई बनाने के लिए लिंक करता है (मुझे पता है क्योंकि मेरा बैजल संकलन रन विफल रहता है जब यह इन संसाधनों को नहीं ढूंढ सकता)। एक .so फ़ाइल को पार करने के लिए बेसल को मजबूर करने के लिए मुझे एकमात्र तरीका मिल सकता है, यह इसे एंड्रॉइड नियम का आश्रित नियम बना रहा है। सीधे मूल निबंध को संकलित करना वह है जो मैं अपने एएस को पोर्ट करना पसंद करूंगा एक बेज़ेल परियोजना के लिए कोड।

    मैं इसे कैसे स्क्वायर करूं? बेज़ेल एंड्रॉइड कोड संकलित करेगा, लेकिन एंड्रॉइड स्टूडियो कोड उत्पन्न करता है जो बेज़ेल संकलित नहीं कर सकता है। Google के सभी उदाहरण आपको बिना किसी संकेत के किसी रेपो से कोड देते हैं कि यह कैसे उत्पन्न हुआ था। जहां तक ​​मुझे पता है, एक्सएमएल जो एंड्रॉइड स्टूडियो ऐप का हिस्सा है, उसे हाथ से नहीं बनाया जाना चाहिए। अगर इसे हाथ से बनाया जा सकता है, तो मैं उन सभी बाहरी पुस्तकालयों की आवश्यकता से कैसे बचूं?

    शायद मुझे वर्कफ़्लो गलत हो रहा है, या बैज़ल/एंड्रॉइड स्टूडियो का कुछ पहलू है जिसे मैं समझ नहीं पा रहा हूं। किसी भी मदद की सराहना की।

धन्यवाद!

संपादित करें:

  1. मैं नवीनतम Bazel करने के लिए उन्नत:

    वहाँ कई चीजें हैं जो मुझे लगता है कि कर समाप्त हो गया सफलतापूर्वक पुस्तकालय भवन में योगदान दिया है हो सकता है थे।

  2. मैंने स्रोत से टेंसरफ्लो का पुनर्निर्माण किया।
  3. मैं सिफारिश Bazel नीचे फ़ाइल का निर्माण लागू किया कि कुछ अतिरिक्त सुविधा (एंड्रॉयड उदाहरण से लिया गया) के साथ:

    cc_binary(
    name = "libName.so", 
    srcs = ["org_tensorflowtest_MyActivity.cc", 
         "org_tensorflowtest_MyActivity.h", 
         "jni.h", 
         "jni_md.h", 
         ":libpthread.so"], 
    deps = ["//tensorflow/core:android_tensorflow_lib", 
         ], 
    copts = [ 
        "-std=c++11", 
        "-mfpu=neon", 
        "-O2", 
    ], 
    linkopts = ["-llog -landroid -lm"], 
    linkstatic = 1, 
    linkshared = 1, 
    ) 
    
    cc_binary(
        name = "libpthread.so", 
        srcs = [], 
        linkopts = ["-shared"], 
        tags = [ 
         "manual", 
         "notap", 
        ], 
    ) 
    

मैं सत्यापित नहीं किया है कि इस पुस्तकालय लोड और Android में इस्तेमाल किया जा सकता अभी तक; एंड्रॉइड स्टूडियो 1.5 देशी libs की उपस्थिति को स्वीकार करने के बारे में बहुत मुश्किल लगता है।

+0

एक .dylib बनाना बिल्कुल मदद नहीं करेगा, क्योंकि एंड्रॉइड ओएसएक्स-डाइलिब ओएसएक्स केवल प्रारूप नहीं है। यह लिनक्स है, आपको एक एसएसओ बनाने की जरूरत है (जो कि वही चीज़ फीचर वार है, लेकिन एक अलग फ़ाइल प्रारूप है)। इसके अलावा, एंड्रॉइड में एक्सएमएल हाथ से उत्पन्न नहीं है। किसी भी Google उदाहरण में बहुत कुछ भी उत्पन्न नहीं होता है। तथ्य यह है कि आप इसे होने की उम्मीद कर रहे हैं शायद आपकी समस्या का हिस्सा है। –

+0

इसके अलावा, जब तक कि आपके टेन्स्फोर्लो सॉफ़्टवेयर को बैज़ेल का उपयोग करने की आवश्यकता न हो, मैंने कभी एंड्रॉइड काम के लिए इसका उपयोग नहीं किया है। ग्रैडल नया मानक है, और चींटी विरासत मानक है। यदि आप बाजेल का उपयोग कर रहे हैं तो आप या तो खून बह रहा है या पूरी तरह से अपनी खुद की चीज कर रहे हैं। –

+0

@amm क्या आप इसे एंड्रॉइड पर चलाने में सक्षम थे क्या आपने बनाया ऐप का आकार क्या है? – sau

उत्तर

10

अपने कार्यक्षेत्र फ़ाइल में एक एंड्रॉयड NDK स्थापित करने के बाद, Bazel Android के लिए एक .so पार संकलन कर सकते हैं, इस तरह:

cc_binary(
    name = "libfoo.so", 
    srcs = ["foo.cc"], 
    deps = [":bar"], 
    linkstatic = 1, 
    linkshared = 1, 
) 

$ bazel build foo:libfoo.so \ 
    --crosstool_top=//external:android/crosstool --cpu=armeabi-v7a \ 
    [email protected]_tools//tools/cpp:toolchain 
$ file bazel-bin/foo/libfoo.so 
bazel-bin/foo/libfoo.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped 

Bazel wants all of the java app code to be inside the 'WORKSPACE' top-level directory (in the Tensorflow repo)

जब 0.1.4 जारी किया गया है (यह अभी धक्का) और हम TensorFlow और Protobuf करने के लिए कुछ सुधारों को धक्का दिया है, तो आप एक दूरस्थ भंडार के रूप में TensorFlow रेपो का उपयोग शुरू कर सकते हैं। अपने कार्यक्षेत्र फ़ाइल में स्थापित करने के बाद, आप तो @tensorflow//foo/bar लेबल का उपयोग TensorFlow नियमों का उल्लेख कर सकते।

+0

चूंकि आप सबसे अधिक संभावना [Bazel समूह] के सदस्य हैं (https://github.com/ulfjack/bazel/graphs/contributors) क्या आप इसे अपने [SO प्रोफ़ाइल] में देख सकते हैं (http://stackoverflow.com/users/4731056/Ulf-एडम्स)। अगर मैं जानता हूं कि उत्तर देने वाला व्यक्ति विकास टीम का सदस्य है तो मैं एक उत्तर देने के लिए अधिक उपयुक्त हूं। –

+0

टिप्पणी से मेरा क्या मतलब है: मैं अपने ऐप कोड को टेंसफोर्लो रूट से अलग निर्देशिका संरचना में नहीं रख सकता। – amm

+0

यह समाधान मेरे लिए काम नहीं करता है। त्रुटि संदेश: "त्रुटि: सीपीयू 'डार्विन' के लिए कोई टूलचैन नहीं मिला।" मेरे पास android_sdk_repository() और android_ndk_repository() को मेरी वर्कस्पेस फ़ाइल में परिभाषित किया गया है। – amm

1
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git 

नोट: - रीकोडर्स खींचने के लिए रिक्रेस-सबोड्यूल्यूल महत्वपूर्ण है।

यहां से Bazel स्थापित करें। बेज़ेल टेंसरफ्लो के लिए प्राथमिक निर्माण प्रणाली है। अब, कार्यस्थान संपादित करते हैं, हम TensorFlow कि हम पहले क्लोन है की रूट निर्देशिका में कार्यस्थान फ़ाइल पा सकते हैं।

# Uncomment and update the paths in these entries to build the Android demo. 
#android_sdk_repository(
# name = "androidsdk", 
# api_level = 23, 
# build_tools_version = "25.0.1", 
# # Replace with path to Android SDK on your system 
# path = "<PATH_TO_SDK>", 
#) 
# 
#android_ndk_repository(
# name="androidndk", 
# path="<PATH_TO_NDK>", 
# api_level=14) 
हमारी एसडीके और NDK पथ के साथ नीचे की तरह

:

android_sdk_repository(
    name = "androidsdk", 
    api_level = 23, 
    build_tools_version = "25.0.1", 
    # Replace with path to Android SDK on your system 
    path = "/Users/amitshekhar/Library/Android/sdk/", 
) 
android_ndk_repository(
    name="androidndk", 
    path="/Users/amitshekhar/Downloads/android-ndk-r13/", 
    api_level=14) 

फिर .so फ़ाइल का निर्माण।

bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so \ 
    --crosstool_top=//external:android/crosstool \ 
    [email protected]_tools//tools/cpp:toolchain \ 
    --cpu=armeabi-v7a 

हमारे वांछित लक्ष्य आर्किटेक्चर के साथ armeabi-v7a को प्रतिस्थापित करना। पुस्तकालय में स्थान दिया जाएगा:

bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so 

जावा समकक्ष बनाने के लिए:

bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar 

अब हम दोनों जार है और:

bazel build //tensorflow/contrib/android:android_tensorflow_inference_java 

हम पर JAR फ़ाइल पा सकते हैं। तो फाइल। मैंने पहले से ही .so फ़ाइल और जार बनाया है, आप सीधे project से उपयोग कर सकते हैं। libs में

रखें libandroid_tensorflow_inference_java.jar फ़ोल्डर और दाएँ क्लिक और पुस्तकालय के रूप में जोड़ें।

compile files('libs/libandroid_tensorflow_inference_java.jar') 

मुख्य निर्देशिका में jniLibs फ़ोल्डर बनाएँ और/armeabi-v7a/फ़ोल्डर jniLibs में libtensorflow_inference.so डाल दिया।

अब, हम TensorFlow जावा एपीआई कॉल करने के लिए सक्षम हो जाएगा।

TensorFlow जावा एपीआई एक वर्ग TensorFlowInferenceInterface के माध्यम से सभी आवश्यक तरीकों से अवगत कराया गया है।

अब, हम मॉडल पथ के साथ TensorFlow जावा एपीआई कॉल और इसे लोड करने के लिए है।

मैंने एक पूरा ब्लॉग here लिखा है।

संबंधित मुद्दे