【HMS Core】使用機器學習服務和搜尋服務識別植物

華為開發者論壇發表於2023-02-09

1、介紹

總覽

機器學習服務(ML Kit)為開發者提供簡單易用、服務多樣、技術領先的機器學習能力,助力開發者更快更好地開發各類AI應用。同時,搜尋服務(Search Kit)透過端側SDK和雲側API方式,全面開放花瓣搜尋能力,使能生態合作伙伴快速構建更好的移動應用搜尋體驗。

 

您將建立什麼

在本次Codelab中,您將建立一個示例專案並整合ML Kit和Search Kit。在該專案中,您可以:

1、上傳您的植物圖片

2、透過ML Kit識別它是那種型別的植物

3、透過Search Kit向我們展示與此類植物相關的網站

 

您需要什麼

在本codelab中,你需要學習:

1、如何在AppGallery Connect中建立專案和應用程式

2、如何整合ML Kit和Search Kit

3、如何透過ML Kit建立自定義訓練模型

4、瞭解如何使用影像分類服務

5、如何透過Search Kit建立搜尋請求

 

2、您需要什麼

硬體需求

  • 一臺筆記本或臺式電腦。

  • 一部裝有EMUI 5.0或以上版本的華為手機,或一部裝有安卓4.4以上版本的非華為手機(部分能力僅華為手機支援)。

  • 手機用於執行和除錯demo

 

軟體需求

  • JDK版本:1.8.211或以上

  • Android Studio版本:3.X或以上

  • minSdkVersion:19或以上(必選)

  • targetSdkVersion:31(推薦)

  • compileSdkVersion:31(推薦)

  • Gradle版本:4.6或以上

 

必備知識

安卓應用開發基礎知識

 

3、能力接入準備

整合前,需要完成以下準備工作:

說明:

在進行準備前,請先註冊開發者帳號

  • 在AppGallery Connect中建立專案和應用。

  • 建立Android Studio專案。

  • 生成簽名證照。

  • 生成簽名證照指紋。

  • 在AppGallery Connect中將簽名指紋新增到應用中。

  • 新增必要配置。

  • 配置專案簽名。

  • 同步專案。

詳情請參見HUAWEI HMS Core整合準備

 

4、整合HMS Core SDK

新增您應用的AppGallery Connect配置檔案

  1. 登入AppGallery Connect,點選“我的專案”,在專案列表中找到並點選您的專案。

  2. 在“專案設定”頁面選擇“常規”頁籤。

  3. 在“專案”區域下點選“資料處理位置”後的“啟用”。

    cke_23502.png

  4. 點選“應用”區域的“agconnect-services.json”下載配置檔案。

    cke_30791.png

  5. 將配置檔案"agconnect-services.json"複製到應用級根目錄下。

    cke_57185.png

     

新增編譯依賴

  1. 開啟應用級的“build.gradle”檔案。

  2. 在dependencies中新增如下編譯依賴。

    dependencies { 
      // 匯入基礎ML Kit SDK
    Implementation 'com.huawei.hms:ml-computer-vision-classification:{version}' 
     // 匯入圖片分類模型包
     implementation
     'com.huawei.hms:ml-computer-vision-image-classification-model:{version}'
     //自定義模型公共SDK
    implementation 'com.huawei.hms:ml-computer-model-executor:{version}'
     //MindSpore Lite推理框架
    implementation 'mindspore:mindspore-lite:{version}'
    //Search Kit
     implementation 'com.huawei.hms:searchkit:{version}'
    
     }
    【HMS Core】使用機器學習服務和搜尋服務識別植物

    具體說明如下:

    1)將{version}替換為基礎ML Kit SDK的最新版本號,例如com.huawei.hms:ml-computer-vision-classification:3.7.0.301。有關最新版本號的詳細資訊,請參見文件

    2)將{version}替換為圖片分類模型包的最新版本號,例如com.huawei.hms:ml-computer-vision-image-classification-model:3.7.0.301。有關最新版本號的詳細資訊,請參見文件

     

    3)將{version}替換為自定義模型公共SDK的最新版本號,例如com.huawei.hms:ml-computer-model-executor:3.5.0.301。有關最新版本號的詳細資訊,請參見文件

    4)將{version}替換為Mindspore Lite的最新版本號,例如mindspore:mindspore-lite:5.0.5.300。有關最新版本號的詳細資訊,請參見文件

    5)將{version}替換為Search Kit的最新版本號,例如com.huawei.hms:searchkit:5.0.4.303。有關最新版本號的詳細資訊,請參見文件

  3. 在build.gradle檔案中,設定Java原始碼的相容性模式。

    compileOptions { 
    sourceCompatibility = 1.8 
    targetCompatibility = 1.8}   
    【HMS Core】使用機器學習服務和搜尋服務識別植物
  4. 在應用級build.gradle檔案中設定minSdkVersion。

    android {
     ... 
       defaultConfig {
          ... 
       minSdkVersion 26 
          ... 
      }
       ... 
    }
    【HMS Core】使用機器學習服務和搜尋服務識別植物
  5. 檢查是否已新增AppGallery Connect外掛。如沒有,在應用級build.gradle檔案中新增該外掛。

    apply plugin: 'com.huawei.agconnect'
    【HMS Core】使用機器學習服務和搜尋服務識別植物
  6. 自動更新機器學習模型。

    在AndroidManifest.xml檔案中新增以下程式碼。使用者從華為應用市場安裝應用後,機器學習模型會自動更新到使用者的裝置上。

    <manifest
        ...
        <meta-data
            android:name="com.huawei.hms.ml.DEPENDENCY"
            android:value= "label"/>
        ...
    </manifest>
    【HMS Core】使用機器學習服務和搜尋服務識別植物
  7. 配置網路許可權。

    為了實現targetSdkVersion 28或更高版本的裝置上支援允許HTTP網路請求,需在AndroidManifest.xml檔案中配置以下資訊:

    <application
        ...
        android:usesCleartextTraffic="true"
        >
        ...
    </application>
    【HMS Core】使用機器學習服務和搜尋服務識別植物

 

配置混淆指令碼

編譯APK前需要配置混淆指令碼,避免混淆HMS Core SDK。如果出現混淆,HMS Core SDK可能無法正常工作。

Android Studio開發環境裡的混淆指令碼是“proguard-rules.pro”。

加入排除HMS SDK的混淆配置。

-ignorewarnings 
-keepattributes *Annotation* 
-keepattributes Exceptions 
-keepattributes InnerClasses 
-keepattributes Signature 
-keepattributes SourceFile,LineNumberTable 
-keep class com.huawei.hianalytics.**{*;} 
-keep class com.huawei.updatesdk.**{*;} 
-keep class com.huawei.hms.**{*;}
【HMS Core】使用機器學習服務和搜尋服務識別植物

 

5、設計UI

cke_3547.png

6、整合機器學習服務&建立自定義模型

步驟一:檢視許可權

您的應用需要獲得以下許可權:

步驟二:同步專案。

在Android Studio視窗中,選擇“File > Sync Project with Gradle Files”,進行同步專案。

步驟三:使用MindSpore Lite建立自定義模型

機器學習服務推出的自定義模型端側推理框架便於整合開發執行到端側裝置,透過引入此推理框架,您能夠最小成本的定義自己的模型並實現模型推理。

現在,我們將使用HMS Toolkit的AI Create功能,建立我們自己的訓練自定義模型。

3.1環境準備

  1. 在Coding Assistant中,選擇“AI > AI Create”。遷移學習的能力,選擇“Image”、“Text”或“Object”,點選“Confirm”。

    cke_20885.png

    HMS Toolkit會自動下載資源,檢測到有更新會有如下彈窗。

    cke_29710.png

  2. 點選上圖中的“Confirm”,如果沒有配置Python環境,就會有如下彈窗提示下載Python。

    cke_38133.png

  3. 點選上圖中的連結下載並安裝Python 3.7.5。

  4. Python安裝完成後,請在path路徑下新增Python環境變數。

  5. 開啟命令列工具,輸入python命令。如果查詢結果為3.7.5版本,則說明設定成功。

  6. 重啟IDE,再次選擇“Image”、“Text”或“Object”,點選“Confirm”,會自動安裝MindSpore工具。若安裝失敗,會有如下彈窗提示使用者選擇是否手動安裝。點選“OK”,提示儲存MindSpore安裝檔案。然後開啟命令列工具,用pip install +”MindSpore安裝檔案” 進行手動安裝。

    cke_69158.png

3.2資源準備

使用影像分類遷移學習能力前,您需要按照要求準備用於訓練的影像資源。

cke_87404.png

影像資源具體要求如下:

  • 訓練影像需要按照影像進行分類,在每個分類的目錄下,放入合適的清晰影像。(影像儲存路徑和分類名稱只能包含:字母、數字、下劃線和中文,不能包括空格、特殊字元等符號。)

  • 影像分類數量約束:至少需要有2個以上的影像類別,上限為1000類。

  • 每一分類影像至少包含10張圖片。

  • 影像格式只能是:bmp、jpg、jpeg、png或gif。

3.3模型訓練

  1. 在Coding Assistant中,選擇“AI > AI Create > Image”。

  2. 設定影像訓練模型的操作型別和模型部署位置,然後點選“Confirm”。

    cke_156532.png

  3. 將分類好的影像資料夾拖入或新增到“Please select train image folder”,並設定生成的模型的儲存路徑(Output model file path)和訓練引數(Train parameter)。

    cke_166451.png

  4. 點選“Create Model”開始進行訓練,生成影像分類識別模型。

  5. 等待模型生成後,可以檢視模型學習的結果(訓練精度和驗證精度)、對應的學習引數和訓練資料等資訊。

    cke_176543.png

  6. 模型訓練完成後,您還可以對模型進行驗證,您只需要在“Add test image”的“Please select test image folder”區域加入需要測試的影像資料夾即可。工具會自動利用訓練好的模型進行測試,並顯示測試結果。

    cke_187228.png

  7. 現在,我們將在專案中使用的自定義訓練模型已經就緒。現在,我們將學習如何將此“.ms”檔案新增到我們的專案中。

步驟四:為自定義模型建立本地整合資料夾

1、將模型儲存在assets目錄中。

      cke_267402.png

2、模型檔案是不可以被壓縮的,在工程的build.gradle新增如下配置來保證Gradle在構建應用時不會壓縮演算法模型:

android {
    // ...
    aaptOptions {
        noCompress "ms"  // Your model's file extension: "ms".
    }
}
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟五:將自定義模型整合到專案中

首先載入我們的自定義模型

var modelExecutor: MLModelExecutor? = null
 private val mModelName = "flowers"
private val mModelFullName = "train.ms"

private fun isLoadOk(): Boolean {
     return loadOk
}

fun loadModelFromAssets() {
     val localModel: MLCustomLocalModel =
         MLCustomLocalModel.Factory(mModelName).setAssetPathFile(mModelFullName).create()
     val settings: MLModelExecutorSettings = MLModelExecutorSettings.Factory(localModel).create()
     try {
         modelExecutor = MLModelExecutor.getInstance(settings)
         loadOk = true
     } catch (error: MLException) {
         error.printStackTrace()
         Log.i(TAG, "executor cannot be performed" + error.toString())
     } }
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟六:使用圖片分類服務

讓我們建立預置圖片分類模型的函式。

fun predict(
     bitmap: Bitmap?,
     successCallback: OnSuccessListener<MLModelOutputs?>?,
     failureCallback: OnFailureListener?
 ) {
     if (!isLoadOk()) {
         Toast.makeText(mContext, "the model does not init", Toast.LENGTH_LONG).show()
         return
     }
     if (bitmap == null) {
         Toast.makeText(mContext, "please select an image to process!", Toast.LENGTH_LONG).show()
         return
     }
     val inputBitmap: Bitmap = resizeBitMap(bitmap)
     val input = preprocess(inputBitmap)
     Log.d(TAG, "interpret pre process")
     var inputs: MLModelInputs? = null
     try {
         inputs = MLModelInputs.Factory().add(input).create()
     } catch (e: MLException) {
         Log.e(TAG, "add inputs failed! " + e.message)
     }
     var inOutSettings: MLModelInputOutputSettings? = null
     try {
         val settingsFactory: MLModelInputOutputSettings.Factory =
             MLModelInputOutputSettings.Factory()
         settingsFactory.setInputFormat(
             0,
             MLModelDataType.FLOAT32,
             intArrayOf(1, BITMAP_SIZE, BITMAP_SIZE, 3)
         )
         val outputSettingsList = ArrayList<IntArray>()
         val outputShape = intArrayOf(1, labelList!!.size)
         outputSettingsList.add(outputShape)
         for (i in outputSettingsList.indices) {
             settingsFactory.setOutputFormat(i, MLModelDataType.FLOAT32, outputSettingsList[i])
         }
         inOutSettings = settingsFactory.create()
     } catch (e: MLException) {
         Log.e(TAG, "set input output format failed! " + e.message)
     }
     Log.d(TAG, "interpret start")
     modelExecutor?.exec(inputs, inOutSettings)?.addOnSuccessListener(successCallback)
         ?.addOnFailureListener(failureCallback)
 }
【HMS Core】使用機器學習服務和搜尋服務識別植物

根據圖片初始化輸入資料。

private fun preprocess(inputBitmap: Bitmap): Any {
     val input = Array(1) { Array(BITMAP_SIZE) { Array(BITMAP_SIZE) { FloatArray(3) } } }
     for (h in 0 until BITMAP_SIZE) {
         for (w in 0 until BITMAP_SIZE) {
             val pixel: Int = inputBitmap.getPixel(w, h)
             input[0][h][w][0] = (Color.red(pixel) - IMAGE_MEAN[0]) / IMAGE_STD[0]
             input[0][h][w][1] = (Color.green(pixel) - IMAGE_MEAN[1]) / IMAGE_STD[1]
             input[0][h][w][2] = (Color.blue(pixel) - IMAGE_MEAN[2]) / IMAGE_STD[2]
         }
     }
     return input
 }
【HMS Core】使用機器學習服務和搜尋服務識別植物

在我們的activity中呼叫的預置方法。

private fun runOnClick() {
     detector!!.predict(bitmap,
         { mlModelOutputs ->
             Log.i(TAG, "interpret get result")
             val result = detector!!.resultPostProcess(mlModelOutputs!!)
             showResult(result)
         }) { e ->
         e.printStackTrace()
         Log.e(TAG, "interpret failed, because " + e.message)
         Toast.makeText(
             this@MainActivity,
             "interpret failed, because" + e.message,
             Toast.LENGTH_SHORT
         ).show()
     }
【HMS Core】使用機器學習服務和搜尋服務識別植物

 

7、整合搜尋服務

步驟一:初始化Search Kit

在Activity中呼叫SearchKitInstance.init(),請參閱文件

// Initialize Search Kit.
 // appID is obtained after your app is created in AppGallery Connect. Its value is of the String type.
 SearchKitInstance.init(this, appID);
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟二:建立網頁搜尋

進行網頁搜尋前先使用WebSearchRequest構建請求物件,請參閱文件

val webSearchRequest = WebSearchRequest()
// Set the search keyword. (The following uses test as an example. You can set other keywords as required.)
webSearchRequest.setQ(word)
// Set the language for search.
webSearchRequest.setLang(Language.ENGLISH)
// Set the region for search.
webSearchRequest.setSregion(Region.UNITEDKINGDOM)
// Set the number of search results returned on a page.
webSearchRequest.setPs(10)
// Set the page number.
 webSearchRequest.setPn(1)
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟三:設定token

Search Kit提供setInstanceCredential和setCredential兩種方式(請選擇一種來使用)設定token。

SearchKitInstance.getInstance().setInstanceCredential(token)
【HMS Core】使用機器學習服務和搜尋服務識別植物

建立POST請求以接收token,請參閱文件

fun postVolley() {
     val queue = Volley.newRequestQueue(this)
     val url = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"

     val stringReq: StringRequest =
         object : StringRequest(Method.POST, url,
             Response.Listener { response ->
                 // response
                 var strResp = response.toString()

                 val gson = Gson()
                 val mapType = object : TypeToken<Map<String, Any>>() {}.type

                 var tutorialMap: Map<String, Any> =
                     gson.fromJson(strResp, object : TypeToken<Map<String, Any>>() {}.type)
                 tutorialMap.forEach { println(it) }
                 var access_token = tutorialMap.getValue("access_token").toString()
                 token = access_token
                 Log.d("API1", access_token)
                 Log.d("API1", strResp)

             },
             Response.ErrorListener { error ->
                 Log.d("API", "error => $error")
             }
         ) {
             override fun getParams(): MutableMap<String, String> {
                 var params: MutableMap<String, String> = HashMap<String, String>()
                 params.put("grant_type", "client_credentials")
                 params.put("client_id", "YOUR_CLIENT_ID")
                 params.put(
                     "client_secret",
                     "YOUR_CLIENT_SECRET"
                 )
                 return params
             }
         }
     queue.add(stringReq)
 }
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟四:開始網頁搜尋

將之前構造的webSearchRequest作為引數傳遞給search方法。

val webSearchResponse =
     SearchKitInstance.getInstance().webSearcher.search(webSearchRequest)
【HMS Core】使用機器學習服務和搜尋服務識別植物

步驟五:檢視Web搜尋後返回的結果

for (i in webSearchResponse.getData()) {
     Log.i(
         TAG, "site_name : " + i.site_name + "\n"
                 + "getSnippet : " + i.getSnippet() + "\n"
                 + "siteName : " + i.siteName + "\n"
                 + "title : " + i.title + "\n"
                 + "clickUrl : " + i.clickUrl + "\n"
                 + "click_url : " + i.click_url + "\n"
                 + "getTitle : " + i.getTitle()
     )

 }
【HMS Core】使用機器學習服務和搜尋服務識別植物

 

8、恭喜您

祝賀您,您已經成功完成本Codelab並學到了:

如何整合機器學習服務和搜尋服務

如何建立自定義模型

 

9、參考檔案

點選如下連結下載原始碼:原始碼下載

​欲瞭解更多更全技術文章,歡迎訪問https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh

相關文章