【HMS Core】使用机器学习服务和搜索服务识别植物

2023-06-25,,

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配置文件

    登录AppGallery Connect,点击“我的项目”,在项目列表中找到并点击您的项目。

    在“项目设置”页面选择“常规”页签。

    在“项目”区域下点击“数据处理位置”后的“启用”。

    点击“应用”区域的“agconnect-services.json”下载配置文件。

    将配置文件"agconnect-services.json"复制到应用级根目录下。

添加编译依赖

    打开应用级的“build.gradle”文件。

    在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}' }

    具体说明如下:

    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。有关最新版本号的详细信息,请参见文档。

    在build.gradle文件中,设置Java源代码的兼容性模式。

    compileOptions {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8}

    在应用级build.gradle文件中设置minSdkVersion。

    android {
    ...
    defaultConfig {
    ...
    minSdkVersion 26
    ...
    }
    ...
    }

    检查是否已添加AppGallery Connect插件。如没有,在应用级build.gradle文件中添加该插件。

    apply plugin: 'com.huawei.agconnect'

    自动更新机器学习模型。

    在AndroidManifest.xml文件中添加以下代码。用户从华为应用市场安装应用后,机器学习模型会自动更新到用户的设备上。

    <manifest
    ...
    <meta-data
    android:name="com.huawei.hms.ml.DEPENDENCY"
    android:value= "label"/>
    ...
    </manifest>

    配置网络权限。

    为了实现targetSdkVersion 28或更高版本的设备上支持允许HTTP网络请求,需在AndroidManifest.xml文件中配置以下信息:

    <application
    ...
    android:usesCleartextTraffic="true"
    >
    ...
    </application>

配置混淆脚本

编译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.**{*;}

5、设计UI

6、集成机器学习服务&创建自定义模型

步骤一:查看权限

您的应用需要获得以下权限:

步骤二:同步项目。

在Android Studio窗口中,选择“File > Sync Project with Gradle Files”,进行同步项目。

步骤三:使用MindSpore Lite创建自定义模型

机器学习服务推出的自定义模型端侧推理框架便于集成开发运行到端侧设备,通过引入此推理框架,您能够最小成本的定义自己的模型并实现模型推理。

现在,我们将使用HMS Toolkit的AI Create功能,创建我们自己的训练自定义模型。

3.1环境准备

    在Coding Assistant中,选择“AI > AI Create”。迁移学习的能力,选择“Image”、“Text”或“Object”,点击“Confirm”。

    HMS Toolkit会自动下载资源,检测到有更新会有如下弹窗。

    点击上图中的“Confirm”,如果没有配置Python环境,就会有如下弹窗提示下载Python。

    点击上图中的链接下载并安装Python 3.7.5。

    Python安装完成后,请在path路径下添加Python环境变量。

    打开命令行工具,输入python命令。如果查询结果为3.7.5版本,则说明设置成功。

    重启IDE,再次选择“Image”、“Text”或“Object”,点击“Confirm”,会自动安装MindSpore工具。若安装失败,会有如下弹窗提示用户选择是否手动安装。点击“OK”,提示保存MindSpore安装文件。然后打开命令行工具,用pip install +”MindSpore安装文件” 进行手动安装。

3.2资源准备

使用图像分类迁移学习能力前,您需要按照要求准备用于训练的图像资源。

图像资源具体要求如下:

训练图像需要按照图像进行分类,在每个分类的目录下,放入合适的清晰图像。(图像存储路径和分类名称只能包含:字母、数字、下划线和中文,不能包括空格、特殊字符等符号。)

图像分类数量约束:至少需要有2个以上的图像类别,上限为1000类。

每一分类图像至少包含10张图片。

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

3.3模型训练

    在Coding Assistant中,选择“AI > AI Create > Image”。

    设置图像训练模型的操作类型和模型部署位置,然后点击“Confirm”。

    将分类好的图像文件夹拖入或添加到“Please select train image folder”,并设置生成的模型的存储路径(Output model file path)和训练参数(Train parameter)。

    点击“Create Model”开始进行训练,生成图像分类识别模型。

    等待模型生成后,可以查看模型学习的结果(训练精度和验证精度)、对应的学习参数和训练数据等信息。

    模型训练完成后,您还可以对模型进行验证,您只需要在“Add test image”的“Please select test image folder”区域加入需要测试的图像文件夹即可。工具会自动利用训练好的模型进行测试,并显示测试结果。

    现在,我们将在项目中使用的自定义训练模型已经就绪。现在,我们将学习如何将此“.ms”文件添加到我们的项目中。

步骤四:为自定义模型创建本地集成文件夹

1、将模型保存在assets目录中。

2、模型文件是不可以被压缩的,在工程的build.gradle添加如下配置来保证Gradle在构建应用时不会压缩算法模型:

android {
// ...
aaptOptions {
noCompress "ms" // Your model's file extension: "ms".
}
}

步骤五:将自定义模型集成到项目中

首先加载我们的自定义模型。

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())
} }

步骤六:使用图片分类服务

让我们创建预置图片分类模型的函数。

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)
}

根据图片初始化输入数据。

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
}

在我们的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()
}

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);

步骤二:创建网页搜索

进行网页搜索前先使用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)

步骤三:设置token

Search Kit提供setInstanceCredential和setCredential两种方式(请选择一种来使用)设置token。

SearchKitInstance.getInstance().setInstanceCredential(token)

创建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)
}

步骤四:开始网页搜索

将之前构造的webSearchRequest作为参数传递给search方法。

val webSearchResponse =
SearchKitInstance.getInstance().webSearcher.search(webSearchRequest)

步骤五:查看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()
) }

8、恭喜您

祝贺您,您已经成功完成本Codelab并学到了:

如何集成机器学习服务和搜索服务

如何创建自定义模型

9、参考文件

ML Kit Permissions

MindSpore Lite

AI Create

Model Inference

Image Classification

Search Kit

点击如下链接下载源码:源码下载

​欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh

【HMS Core】使用机器学习服务和搜索服务识别植物的相关教程结束。

《【HMS Core】使用机器学习服务和搜索服务识别植物.doc》

下载本文的Word格式文档,以方便收藏与打印。