如何在 MLMultiarray 元素上应用 Sigmoid?
Posted
技术标签:
【中文标题】如何在 MLMultiarray 元素上应用 Sigmoid?【英文标题】:How to apply Sigmoid on MLMultiarray elements? 【发布时间】:2021-01-27 16:34:59 【问题描述】:对于 python 中的火炬张量,我可以使用 y = x[i].sigmoid()
如何在 Swift 中使用 MLMultiArray 复制它?
我可以通过VNCoreMLFeatureValueObservation.featureValue.multiArrayValue
获取数组
现在我想在这个上应用 sigmoid
我使用的 sigmoid 函数是:
func sigmoid(z: Double) -> Double
return 1.0 / (1.0 + exp(-z))
【问题讨论】:
【参考方案1】:这是从内存中输入的,所以可能会有错误,但基本上你抓住一个指向内存的指针然后循环遍历它:
let ptr = multiArray.dataPointer.assumingMemoryBound(to: Double.self)
for i in 0..<multiArray.count
ptr[i] = sigmoid(ptr[i])
但是,将 sigmoid 操作添加到 Core ML 模型本身并让 Core ML 担心要简单得多。您可以通过在转换之前或之后将 sigmoid 操作添加到原始模型来做到这一点(有关如何执行此操作的说明,请参阅我的书 Core ML Survival Guide)。
【讨论】:
这行得通,但我在操作 MLMultiArrays 时遇到了困难。我试图从输出 3 个 multiArrays 的 yolov5 coreml 模型中推断。我已经确定我需要从 python 转换为 swift,就像提到的 here 一样,但我似乎无法理解它。你能以任何方式帮助我吗? 这是人们付钱让我做的事情。 ;-) 但是如果你读了我的书,你应该已经在路上了。 啊,我明白了。尽管我对此感到沮丧,但我现在真的很想自己破解这个。感谢您的帮助和本书! 如果您还没有看到,this repo 展示了如何解码来自 YOLOv2 的预测。 YOLOv5 的方法是类似的,除了你有多个输出网格而不是只有一个,而且数学略有不同。【参考方案2】:我没有测试这个功能,但我认为它可以达到你想要的效果
public func sigmoid_multiarray(inputs: [MLMultiArray], outputs: [MLMultiArray])
for i in 0..<inputs.count
let input=inputs[i]
let output=outputs[i]
let count = input.count
let iptr = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let optr = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
// output = -input
vDSP_vneg(iptr, 1, optr, 1, vDSP_Length(count))
// output = exp(-input)
var countAsInt32 = Int32(count)
vvexpf(optr, optr, &countAsInt32)
// output = 1 + exp(-input)
var one: Float = 1
vDSP_vsadd(optr, 1, &one, optr, 1, vDSP_Length(count))
// output = 1 / 1 + exp(-input)
var one_ar = [Float] (repeating: 1, count: input.count)
vvdivf(optr, &one_ar, optr, &countAsInt32)
【讨论】:
以上是关于如何在 MLMultiarray 元素上应用 Sigmoid?的主要内容,如果未能解决你的问题,请参考以下文章
如何调整 MLMultiArray 的大小以适合我的相机纹理大小?
快速从 .npy 转换为 MLMultiArray 以进行 CoreML 预测
VNImageRequestHandler 可以接受 MLMultiArray 作为输入吗? (无需转换为 UIImage)