如何在MLMultiarray元素上应用Sigmoid?

时间:2020-10-13 10:32:36

标签: ios swift computer-vision coreml

对于python中的割炬张量,我可以使用
y = x[i].sigmoid()

如何在Swift中使用MLMultiArray复制此内容?
我可以通过VNCoreMLFeatureValueObservation.featureValue.multiArrayValue获得数组
现在我想在此应用乙状结肠

我正在使用的S型函数是:

func sigmoid(z: Double) -> Double {
        return 1.0 / (1.0 + exp(-z))
    }

2 个答案:

答案 0 :(得分: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担心它要简单得多。您可以通过在转换之前或之后向原始模型添加S型操作来实现此目的(有关如何执行此操作的说明,请参阅我的《 Core ML生存指南》一书)。

答案 1 :(得分:0)

我没有测试这个功能,但我认为它可以实现你想要的

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

}