在xcode中使用mlmodel模型,之前说的最简单的方法是将模型拖进工程中即可,xcode会自动生成有关模型的前向预测接口,这种方式非常简单,但是更新模型就很不方便。

今天说下另外一种通过URL加载mlmodel的方式。具体可以查阅apple开发者官方文档 https://developer.apple.com/documentation/coreml/mlmodel

流程如下:

1.提供mlmodel的文件所在路径model_path

NSString *model_path = "path_to/.mlmodel"

2.将NSSting类型转换为NSURL,并根据路径对模型进行编译(编译出的为.mlmodelc 文件, 这是一个临时文件,如果需要,可以将其保存到一个固定位置:https://developer.apple.com/documentation/coreml/core_ml_api/downloading_and_compiling_a_model_on_the_user_s_device

NSURL *url = [NSURL fileURLWithPath:model_path isDirectory:FALSE];
NSURL *compile_url = [MLModel compileModelAtURL:url error:&error];

3.根据编译后模型所在路径,加载模型,类型为MLModel

MLModel *compiled_model = [MLModel modelWithContentsOfURL:compile_url configuration:model_config error:&error];

4.需要注意的是采用动态编译方式,coreml只是提供了一种代理方式MLFeatureProvider,类似于C++中的虚函数。因此需要自己重写模型输入和获取模型输出的类接口(该类继承自MLFeatureProvider)。如下自己封装的MLModelInput和MLModelOutput类。MLModelInput类可以根据模型的输入名称InputName,传递data给模型。而MLModelOutput可以根据不同的输出名称featureName获取预测结果。

这个是头文件:

#import <Foundation/Foundation.h>
#import <CoreML/CoreML.h> NS_ASSUME_NONNULL_BEGIN /// Model Prediction Input Type
API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0))
@interface MLModelInput : NSObject<MLFeatureProvider> //the input name,default is image
@property (nonatomic, strong) NSString *inputName; //data as color (kCVPixelFormatType_32BGRA) image buffer
@property (readwrite, nonatomic) CVPixelBufferRef data; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithData:(CVPixelBufferRef)data inputName:(NSString *)inputName; @end API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0))
@interface MLModelOutput : NSObject<MLFeatureProvider> //the output name, defalut is feature
@property (nonatomic, strong) NSString *outputName; // feature as multidimensional array of doubles
@property (readwrite, nonatomic) MLMultiArray *feature; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithFeature:(MLMultiArray *)feature;
@end NS_ASSUME_NONNULL_END

这个是类方法实现的文件:

@implementation MLModelInput

- (instancetype)initWithData:(CVPixelBufferRef)data inputName:(nonnull NSString *)inputName {
if (self) {
_data = data;
_inputName = inputName;
}
return self;
} - (NSSet<NSString *> *)featureNames {
return [NSSet setWithArray:@[self.inputName]];
} - (nullable MLFeatureValue *)featureValueForName:(nonnull NSString *)featureName {
if ([featureName isEqualToString:self.inputName]) {
return [MLFeatureValue featureValueWithPixelBuffer:_data];
}
return nil;
} @end @implementation MLModelOutput - (instancetype)initWithFeature:(MLMultiArray *)feature{
if (self) {
_feature = feature;
_outputName = DefalutOutputValueName;
}
return self;
} - (NSSet<NSString *> *)featureNames{
return [NSSet setWithArray:@[self.outputName]];
} - (nullable MLFeatureValue *)featureValueForName:(nonnull NSString *)featureName {
if ([featureName isEqualToString:self.outputName]) {
return [MLFeatureValue featureValueWithMultiArray:_feature];
}
return nil;
} @end

5. 模型预测,获取预测结果。上面这两个类接口写完后,就可以整理输入数据为CvPixelBuffer,然后通过获取模型描述MLModelDescription得到输入名称,根据输入名称创建MLModelInput,预测,然后再根据MLModelOutput中的featureNames获取对应的预测输出数据,类型为MLMultiArray:

MLModelDescription *model_description = compiled_model.modelDescription;
NSDictionary *dict = model_description.inputDescriptionsByName;
NSArray<NSString *> *feature_names = [dict allKeys];
NSString *input_feature_name = feature_names[];
NSError *error;
MLModelInput *model_input = [[MLModelInput alloc] initWithData:buffer inputName:input_feature_name];
id<MLFeatureProvider> model_output = [compiled_model predictionFromFeatures:model_input options:option error:&error];
NSSet<NSString *> *out_feature_names = [model_output featureNames];
NSArray<NSString *> *name_list = [out_feature_names allObjects];
NSUInteger size = [name_list count];
std::vector<MLMultiArray *> feature_list;
for (NSUInteger i = 0; i < size; i++) {
NSString *name = [name_list objectAtIndex:i];
MLMultiArray *feature = [model_output featureValueForName:name].multiArrayValue;
feature_list.push_back(feature);
}

6.读取MLMultiArray中的预测结果数据做后续处理..

coreml之通过URL加载模型的更多相关文章

  1. tensorflowjs下载源文件到本地不能加载模型解决方案

    大多数情况(非源文件错误)下载源文件到本地不能加载模型,那么你可能需要搭建一个本地WEB服务器. 1.安装apache或ngnix,可以参照这个博客 2.强烈推荐一个Chrome插件Web Serve ...

  2. C#开发BIMFACE系列37 网页集成开发1:审图系统中加载模型或图纸

    系列目录     [已更新最新开发文章,点击查看详细] 在之前的<C#开发BIMFACE系列>中主要介绍了BIMFACE平台提供的服务端API接口的封装开发与测试过程. 服务端API测试通 ...

  3. C#开发BIMFACE系列50 Web网页中使用jQuery加载模型与图纸

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列49 Web网页集成BIMFACE应用的技术方案>中介绍了目前市场主流 ...

  4. C#开发BIMFACE系列53 WinForm程序中使用CefSharp加载模型图纸1 简单应用

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] 在我的博客<C#开发BIMFACE系列52 CS客户端集成BIMFACE应用的技术方案>中介绍了多种集成BIM ...

  5. NeHe OpenGL教程 第三十一课:加载模型

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. URL加载系统----iOS工程师必须熟练掌握

    URL加载系统----iOS工程师必须熟练掌握     iOS根本离不开网络——不论是从服务端读写数据.向系统分发计算任务,还是从云端加载图片.音频.视频等.   当应用程序面临处理问题的抉择时,通常 ...

  7. tensorflow学习笔记2:c++程序静态链接tensorflow库加载模型文件

    首先需要搞定tensorflow c++库,搜了一遍没有找到现成的包,于是下载tensorflow的源码开始编译: tensorflow的contrib中有一个makefile项目,极大的简化的接下来 ...

  8. 深度学习原理与框架-猫狗图像识别-卷积神经网络(代码) 1.cv2.resize(图片压缩) 2..get_shape()[1:4].num_elements(获得最后三维度之和) 3.saver.save(训练参数的保存) 4.tf.train.import_meta_graph(加载模型结构) 5.saver.restore(训练参数载入)

    1.cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR) 参数说明:image表示输入图片,image_size表示变 ...

  9. PyTorch保存模型与加载模型+Finetune预训练模型使用

    Pytorch 保存模型与加载模型 PyTorch之保存加载模型 参数初始化参 数的初始化其实就是对参数赋值.而我们需要学习的参数其实都是Variable,它其实是对Tensor的封装,同时提供了da ...

随机推荐

  1. 在Azure DevOps Server (TFS)的流水线中编译和测试Xcode移动应用(iPhone)

    概述 Xcode是开发基于苹果macOS系统的桌面应用和移动应用的主要IDE工具.使用Azure DevOps Server (原名TFS)系统中的pipelines流水线功能,可以方便的集成Xcod ...

  2. 正式开放 | 阿里云 10 亿级镜像服务正式支持 Helm Charts,云原生交付再加速!

    作者 | 阿里巴巴高级开发工程师 谢于宁(予栖) 2018 年 6 月,Helm 正式加入了 CNCF 孵化项目: 2018 年 8 月,据 CNCF 的调研表明,有百分之六十八的开发者选择了 Hel ...

  3. 搭建rsyslog日志服务器

    环境配置 centos7系统 client1:192.168.91.17 centos7系统 master:192.168.91.18 rsyslog客户端配置 1.rsyslog安装 yum ins ...

  4. 使用 Logstash 和 JDBC 确保 Elasticsearch 与关系型数据库保持同步

    为了充分利用 Elasticsearch 提供的强大搜索功能,很多公司都会在既有关系型数据库的基础上再部署Elasticsearch.在这种情况下,很可能需要确保 Elasticsearch 与所关联 ...

  5. 使用NumPy、Numba的简单使用(二)

    本来要写NLP第三课动态规划的,日了,写到一半发现自己也不会了,理论很简单,动态规划咋回事也知道,但是实现在源码上还是有点难度,现在简单给予题目描述,小伙伴也可以来思考一下,例题一,我们现在有1元硬币 ...

  6. 微信测试号:config:invalid url domain

    今天调试微信分享的时候,配置参数时一直提示config:invalid url domain,网上找了一下,都说是appId和域名没有绑定.仔细看了下,有绑定没错.又猜测是不是二级域名的问题,因为是测 ...

  7. Java生鲜电商平台-高并发的设计与架构

    Java生鲜电商平台-高并发的设计与架构 说明:源码下载Java开源生鲜电商平台以及高并发的设计与架构文档 对于高并发的场景来说,比如电商类,o2o,门户,等等互联网类的项目,缓存技术是Java项目中 ...

  8. JVM 学习总结

    目录 Java内存区域 运行时数据区 & Java 内存结构 & Java 内存区域 1. 程序计数器 2. Java 虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区 6. 运行时 ...

  9. 百度地图分布图(百度地图api司机位置实时定位分布图)

    就类似于我们使用共享单车app的时候,可以看到我们周围的空闲单车分布.e代驾在后台管理系统需求里也有此功能,目的是为了实时看到目标城市下的所有司机状态. 一.controller //controll ...

  10. 高效并发一 Java内存模型与Java线程(绝对干货)

    高效并发一 Java内存模型与Java线程 本篇文章,首先了解虚拟机Java 内存模型的结构及操作,然后讲解原子性,可见性,有序性在 Java 内存模型中的体现,最后介绍先行发生原则的规则和使用. 在 ...