对 multiArray 输出求和的自定义 CoreML 输出层

如何解决对 multiArray 输出求和的自定义 CoreML 输出层

请多多包涵。我是 CoreML 和机器学习的新手。我有一个 CoreML 模型,我可以从使用 Caffe 的研究论文实现转换它。这是一个 CSRNet,目标是人群计数。经过多次争论,我能够使用 Coremltools 将 MLmodel 加载到 Python 中,使用 Pillow 预处理图像并预测输出。结果是一个 MultiArray(来自密度图),然后我对其进行了进一步处理以得出实际的数值预测。

如何将自定义层作为输出添加到采用当前输出并执行以下功能的模型?看了很多文章,还是一头雾水。 (本质上,它将 MultiArray 中所有值的值相加)我希望能够保存模型/层并将其导入 Xcode,以便 MLModel 结果是单个数值,而不是 MultiArray。>

这是我目前用于将模型的输出转换为数字的代码(在 Python 中):

# predict output

output = model.predict({'data': img})
summed_output = sum(output.values())
prediction = np.sum(summed_output)
print("prediction: ",prediction)

完整(缩写)代码:

import coremltools as ct
from PIL import Image
import numpy as np

# instantiate model (CSRNet)
model = ct.models.MLModel('shanghai_b.mlmodel')

# function to resize image
def load_image(path,resize_to=None):
    img = PIL.Image.open(path)
    if resize_to is not None:
        img = img.resize(resize_to,PIL.Image.ANTIALIAS)
    img_np = np.array(img).astype(np.float32)
    return img_np,img

# select image 
image = 'IMG_173.jpg'

#resize image
_,img = load_image(image,resize_to=(900,675)) 

# predict output
output = model.predict({'data': img})
summed_output = sum(output.values())
prediction = np.sum(summed_output)
print("prediction: ",prediction)

Xcode 将 MLModel 的输出显示为:“MultiArray (Double 1 x 168 x 225)”。当我使用 Coremltools 将它导入 python 时,它当前所代表的相同模型的规范描述如下:

<bound method MLModel.predict of input {
  name: "data"
  type {
    imageType {
      width: 224
      height: 224
      colorSpace: RGB
    }
  }
}
output {
  name: "estdmap"
  type {
    multiArrayType {
      dataType: DOUBLE
    }
  }
}
>

感谢您的帮助!如果有用,我很乐意在此过程中发布任何其他代码。

附言我还要添加我在 Xcode 项目中的代码作为参考。

private func detectImage(_ image: CIImage) {

        guard let model = try? VNCoreMLModel(for: HundredsPredictor().model) else {
            fatalError("Loading to CoreML failed") }
        
        let modelRequest = VNCoreMLRequest(model: model) { (request,error) in
            if error != nil {
                print(error?.localizedDescription ?? "Error")
            } else {
                guard let result = request.results as? [VNObservation] else {fatalError("Error")}
                
                if #available(iOS 14.0,*) {
                    print(result)
                    
                    // output: [<VNCoreMLFeatureValueObservation: 0x282069da0> 344A87BC-B13E-4195-922E-7381694C91FF requestRevision=1 confidence=1.000000 timeRange={{0/1 = 0.000},{0/1 = 0.000}} "density_map" - "MultiArray: Double 1 × 168 × 225 array" (1.000000)]
                    
                } else {
                    // Fallback on earlier versions
                }
                if let firstResult = result.first {
                    print(firstResult)

                    // output: [<VNCoreMLFeatureValueObservation: 0x282069da0> 344A87BC-B13E-4195-922E-7381694C91FF requestRevision=1 confidence=1.000000 timeRange={{0/1 = 0.000},{0/1 = 0.000}} "density_map" - "MultiArray : Double 1 × 168 × 225 array" (1.000000)]

                }
            }
        }

        let handler = VNImageRequestHandler(ciImage: image)
        do {
            try handler.perform([modelRequest])
            print(handler)
        }
        catch let error as NSError {
            print(error)
        }
    }

更新:解决方案

在蟒蛇中:

from helpers import get_nn
# helper file sourced from Matthijs Hollemans github
# url: https://github.com/hollance/coreml-survival-guide/blob/master/Scripts/helpers.py

# load original model
spec = ct.utils.load_spec("HundredsPredictor.mlmodel")

nn = get_nn(spec)

#construct new layer
new_layer = nn.layers.add()
new_layer.name = "summingLayer"

params = ct.proto.NeuralNetwork_pb2.ReduceLayerParams
new_layer.reduce.mode = params.SUM
new_layer.reduce.axis = params.CHW

# append new layer to model
new_layer.output.append(nn.layers[-2].output[0])
nn.layers[-2].output[0] = nn.layers[-2].name + "_output"
new_layer.input.append(nn.layers[-2].output[0])

spec.description.output[0].type.multiArrayType.shape[0] = 1

# save new model
ct.models.utils.save_spec(spec,"HundredPredictorSummed.mlmodel")

在 Swift 中,导入新的更新模型后:

private func detectImage(_ image: CIImage) {
        
        guard let model = try? VNCoreMLModel(for: HundredPredictorSummed().model) else {
            fatalError("Loading to CoreML failed") }
        
        let request = VNCoreMLRequest(model: model) { [weak self] request,error in
            guard let results = request.results as? [VNCoreMLFeatureValueObservation],let topResult = results.first else {
                fatalError("Unexpected result type from VNCoreMLRequest")}
            
            DispatchQueue.main.async {

                guard let data = topResult.featureValue.multiArrayValue else { return }

                let ptr = data.dataPointer.assumingMemoryBound(to: Double.self)
                let sum = ptr[0]
                print("SUM: ",sum)
                
                self?.detectLabel.text = "~\(String(Int(round(sum)))) ppl"

            }
            
        }
        
        let handler = VNImageRequestHandler(ciImage: image)
        
        DispatchQueue.global(qos: .userInteractive).async {
            do {
                try handler.perform([request])
            } catch {
                print(error)
        
            }
        }
        
    }

解决方法

您可以在模型的末尾添加一个 ReduceSumLayerParams。您需要在 Python 中手动执行此操作。如果将其 reduceAll 参数设置为 true,它将计算整个张量的总和。

但是,在我看来,使用模型同样容易,在您的 Swift 代码中获取指向 MLMultiArray 数据的指针并使用 vDSP.sum(a) 计算总和。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-