马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
场景阐明
开辟者可以使用[@ohos.ai.mindSporeLite],在UI代码中集成MindSpore Lite本领,快速摆设AI算法,举行AI模子推理,实现图像分类的应用。
图像分类可实现对图像中物体的辨认,在医学影像分析、自动驾驶、电子商务、人脸辨认等有广泛的应用。
根本概念
在举行开辟前,请先相识以下概念。
张量:它与数组和矩阵非常相似,是MindSpore Lite网络运算中的根本数据结构。
Float16推理模式: Float16又称半精度,它使用16比特表现一个数。Float16推理模式表现推理的时间用半精度举行推理。
接口阐明
这里给出MindSpore Lite推理的通用开辟流程中涉及的一些接口,具体请见下列表格。
接口名形貌loadModelFromFile(model: string, context?: Context): Promise从路径加载模子。getInputs(): MSTensor[]获取模子的输入。predict(inputs: MSTensor[]): Promise<MSTensor[]>推理模子。getData(): ArrayBuffer获取张量的数据。setData(inputArray: ArrayBuffer): void设置张量的数据。开辟流程
- 选择图像分类模子。
- 在端侧使用MindSpore Lite推理模子,实现对选择的图片举行分类。
环境准备
安装DevEco Studio,要求版本 >= 4.1,并更新SDK到API 11或以上。
开辟步调
本文以对相册的一张图片举行推理为例,提供使用MindSpore Lite实现图像分类的开辟引导。
选择模子
本示例步调中使用的图像分类模子文件为[mobilenetv2.ms],放置在entry/src/main/resources/rawfile工程目次下。
假如开辟者有其他图像分类的预练习模子,请参考[MindSpore Lite 模子转换]先容,将原始模子转换成.ms格式。
编写代码
图像输入和预处置惩罚
- 此处以获取相册图片为例,调用[@ohos.file.picker] 实现相册图片文件的选择。
- import { photoAccessHelper } from '@kit.MediaLibraryKit';
- import { BusinessError } from '@kit.BasicServicesKit';
- let uris: Array<string> = [];
- // 创建图片文件选择实例
- let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
- // 设置选择媒体文件类型为IMAGE,设置选择媒体文件的最大数目
- photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
- photoSelectOptions.maxSelectNumber = 1;
- // 创建图库选择器实例,调用select()接口拉起图库界面进行文件选择。文件选择成功后,返回photoSelectResult结果集。
- let photoPicker = new photoAccessHelper.PhotoViewPicker();
- photoPicker.select(photoSelectOptions, async (
- err: BusinessError, photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
- if (err) {
- console.error('MS_LITE_ERR: PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
- return;
- }
- console.info('MS_LITE_LOG: PhotoViewPicker.select successfully, ' +
- 'photoSelectResult uri: ' + JSON.stringify(photoSelectResult));
- uris = photoSelectResult.photoUris;
- console.info('MS_LITE_LOG: uri: ' + uris);
- })
- ts
复制代码 - 根据模子的输入尺寸,调用[@ohos.multimedia.image] (实现图片处置惩罚)、[@ohos.file.fs] (实现底子文件使用) API对选择图片举行裁剪、获取图片buffer数据,并举行标准化处置惩罚。
- import { image } from '@kit.ImageKit';
- import { fileIo } from '@kit.CoreFileKit';
- let modelInputHeight: number = 224;
- let modelInputWidth: number = 224;
- // 使用fileIo.openSync接口,通过uri打开这个文件得到fd
- let file = fileIo.openSync(this.uris[0], fileIo.OpenMode.READ_ONLY);
- console.info('MS_LITE_LOG: file fd: ' + file.fd);
- // 通过fd使用fileIo.readSync接口读取这个文件内的数据
- let inputBuffer = new ArrayBuffer(4096000);
- let readLen = fileIo.readSync(file.fd, inputBuffer);
- console.info('MS_LITE_LOG: readSync data to file succeed and inputBuffer size is:' + readLen);
- // 通过PixelMap预处理
- let imageSource = image.createImageSource(file.fd);
- imageSource.createPixelMap().then((pixelMap) => {
- pixelMap.getImageInfo().then((info) => {
- console.info('MS_LITE_LOG: info.width = ' + info.size.width);
- console.info('MS_LITE_LOG: info.height = ' + info.size.height);
- // 根据模型输入的尺寸,将图片裁剪为对应的size,获取图片buffer数据readBuffer
- pixelMap.scale(256.0 / info.size.width, 256.0 / info.size.height).then(() => {
- pixelMap.crop(
- { x: 16, y: 16, size: { height: modelInputHeight, width: modelInputWidth } }
- ).then(async () => {
- let info = await pixelMap.getImageInfo();
- console.info('MS_LITE_LOG: crop info.width = ' + info.size.width);
- console.info('MS_LITE_LOG: crop info.height = ' + info.size.height);
- // 需要创建的像素buffer大小
- let readBuffer = new ArrayBuffer(modelInputHeight * modelInputWidth * 4);
- await pixelMap.readPixelsToBuffer(readBuffer);
- console.info('MS_LITE_LOG: Succeeded in reading image pixel data, buffer: ' +
- readBuffer.byteLength);
- // 处理readBuffer,转换成float32格式,并进行标准化处理
- const imageArr = new Uint8Array(
- readBuffer.slice(0, modelInputHeight * modelInputWidth * 4));
- console.info('MS_LITE_LOG: imageArr length: ' + imageArr.length);
- let means = [0.485, 0.456, 0.406];
- let stds = [0.229, 0.224, 0.225];
- let float32View = new Float32Array(modelInputHeight * modelInputWidth * 3);
- let index = 0;
- for (let i = 0; i < imageArr.length; i++) {
- if ((i + 1) % 4 == 0) {
- float32View[index] = (imageArr[i - 3] / 255.0 - means[0]) / stds[0]; // B
- float32View[index+1] = (imageArr[i - 2] / 255.0 - means[1]) / stds[1]; // G
- float32View[index+2] = (imageArr[i - 1] / 255.0 - means[2]) / stds[2]; // R
- index += 3;
- }
- }
- console.info('MS_LITE_LOG: float32View length: ' + float32View.length);
- let printStr = 'float32View data:';
- for (let i = 0; i < 20; i++) {
- printStr += ' ' + float32View[i];
- }
- console.info('MS_LITE_LOG: float32View data: ' + printStr);
- })
- })
- });
- });
- ts
复制代码 编写推理代码
- 工程默认装备界说的本领集大概不包罗MindSporeLite。需在DevEco Studio工程的entry/src/main目次下,手动创建syscap.json文件,内容如下:
- {
- "devices": {
- "general": [
- // 需跟module.json5中deviceTypes保持一致。
- "default"
- ]
- },
- "development": {
- "addedSysCaps": [
- "SystemCapability.AI.MindSporeLite"
- ]
- }
- }
- json
复制代码 - 调用[@ohos.ai.mindSporeLite]实现端侧推理。具体开辟过程及细节如下:
- 创建上下文,设置线程数、装备范例等参数。
- 加载模子。本文从内存加载模子。
- 加载数据。模子实行之前必要先获取输入,再向输入的张量中添补数据。
- 实行推理。使用predict接口举行模子推理。
- // model.ets
- import { mindSporeLite } from '@kit.MindSporeLiteKit'
- export default async function modelPredict(
- modelBuffer: ArrayBuffer, inputsBuffer: ArrayBuffer[]): Promise<mindSporeLite.MSTensor[]> {
- // 1.创建上下文,设置线程数、设备类型等参数。
- let context: mindSporeLite.Context = {};
- context.target = ['cpu'];
- context.cpu = {}
- context.cpu.threadNum = 2;
- context.cpu.threadAffinityMode = 1;
- context.cpu.precisionMode = 'enforce_fp32';
- // 2.从内存加载模型。
- let msLiteModel: mindSporeLite.Model = await mindSporeLite.loadModelFromBuffer(modelBuffer, context);
- // 3.设置输入数据。
- let modelInputs: mindSporeLite.MSTensor[] = msLiteModel.getInputs();
- for (let i = 0; i < inputsBuffer.length; i++) {
- let inputBuffer = inputsBuffer[i];
- if (inputBuffer != null) {
- modelInputs[i].setData(inputBuffer as ArrayBuffer);
- }
- }
- // 4.执行推理。
- console.info('=========MS_LITE_LOG: MS_LITE predict start=====');
- let modelOutputs: mindSporeLite.MSTensor[] = await msLiteModel.predict(modelInputs);
- return modelOutputs;
- }
- ts
复制代码 举行推理并输出效果
加载模子文件,调用推理函数,对相册选择的图片举行推理,并对推理效果举行处置惩罚。- import modelPredict from './model';
- import { resourceManager } from '@kit.LocalizationKit'
- let modelName: string = 'mobilenetv2.ms';
- let max: number = 0;
- let maxIndex: number = 0;
- let maxArray: Array<number> = [];
- let maxIndexArray: Array<number> = [];
- // 完成图像输入和预处理后的buffer数据保存在float32View,具体可见上文图像输入和预处理中float32View的定义和处理。
- let inputs: ArrayBuffer[] = [float32View.buffer];
- let resMgr: resourceManager.ResourceManager = getContext().getApplicationContext().resourceManager;
- resMgr.getRawFileContent(modelName).then(modelBuffer => {
- // predict
- modelPredict(modelBuffer.buffer.slice(0), inputs).then(outputs => {
- console.info('=========MS_LITE_LOG: MS_LITE predict success=====');
- // 结果打印
- for (let i = 0; i < outputs.length; i++) {
- let out = new Float32Array(outputs[i].getData());
- let printStr = outputs[i].name + ':';
- for (let j = 0; j < out.length; j++) {
- printStr += out[j].toString() + ',';
- }
- console.info('MS_LITE_LOG: ' + printStr);
- // 取分类占比的最大值
- this.max = 0;
- this.maxIndex = 0;
- this.maxArray = [];
- this.maxIndexArray = [];
- let newArray = out.filter(value => value !== max)
- for (let n = 0; n < 5; n++) {
- max = out[0];
- maxIndex = 0;
- for (let m = 0; m < newArray.length; m++) {
- if (newArray[m] > max) {
- max = newArray[m];
- maxIndex = m;
- }
- }
- maxArray.push(Math.round(max * 10000))
- maxIndexArray.push(maxIndex)
- // filter函数,数组过滤函数
- newArray = newArray.filter(value => value !== max)
- }
- console.info('MS_LITE_LOG: max:' + maxArray);
- console.info('MS_LITE_LOG: maxIndex:' + maxIndexArray);
- }
- console.info('=========MS_LITE_LOG END=========');
- })
- })
- ts
复制代码 调考试证
- 在DevEco Studio中毗连装备,点击Run entry,编译Hap,有如下表现:
- Launching com.samples.mindsporelitearktsdemo
- $ hdc shell aa force-stop com.samples.mindsporelitearktsdemo
- $ hdc shell mkdir data/local/tmp/xxx
- $ hdc file send C:\Users\xxx\MindSporeLiteArkTSDemo\entry\build\default\outputs\default\entry-default-signed.hap "data/local/tmp/xxx"
- $ hdc shell bm install -p data/local/tmp/xxx
- $ hdc shell rm -rf data/local/tmp/xxx
- $ hdc shell aa start -a EntryAbility -b com.samples.mindsporelitearktsdemo
- shell
复制代码 - 在装备屏幕点击photo按钮,选择图片,点击确定。装备屏幕表现所选图片的分类效果,在日志
打印效果中,过滤关键字”MS_LITE“,可得到如下效果:- 08-06 03:24:33.743 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: PhotoViewPicker.select successfully, photoSelectResult uri: {"photoUris":["file://media/Photo/13/IMG_1501955351_012/plant.jpg"]}
- 08-06 03:24:33.795 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: readSync data to file succeed and inputBuffer size is:32824
- 08-06 03:24:34.147 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: crop info.width = 224
- 08-06 03:24:34.147 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: crop info.height = 224
- 08-06 03:24:34.160 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: Succeeded in reading image pixel data, buffer: 200704
- 08-06 03:24:34.970 22547-22547 A03d00/JSAPP com.sampl...liteark+ I =========MS_LITE_LOG: MS_LITE predict start=====
- 08-06 03:24:35.432 22547-22547 A03d00/JSAPP com.sampl...liteark+ I =========MS_LITE_LOG: MS_LITE predict success=====
- 08-06 03:24:35.447 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: Default/head-MobileNetV2Head/Sigmoid-op466:0.0000034338463592575863,0.000014028532859811094,9.119685273617506e-7,0.000049100715841632336,9.502661555416125e-7,3.945370394831116e-7,0.04346757382154465,0.00003971960904891603...
- 08-06 03:24:35.499 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: max:9497,7756,1970,435,46
- 08-06 03:24:35.499 22547-22547 A03d00/JSAPP com.sampl...liteark+ I MS_LITE_LOG: maxIndex:323,46,13,6,349
- 08-06 03:24:35.499 22547-22547 A03d00/JSAPP com.sampl...liteark+ I =========MS_LITE_LOG END=========
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|