Как применить сигмоид к элементам MLMultiarray?

#ios #swift #computer-vision #coreml

#iOS #swift #компьютерное зрение #coreml

Вопрос:

для тензора факела в python я могу использовать
y = x[i].sigmoid()

как мне воспроизвести это с помощью MLMultiArray в Swift?
Я могу получить массив с помощью VNCoreMLFeatureValueObservation.featureValue.multiArrayValue
теперь я хочу применить сигмоид к этому

функция 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).

Комментарии:

1. это сработало, но мне сложно манипулировать MLMultiArrays. Я пытаюсь сделать вывод из модели yolov5 coreml, которая выводит 3 многомаршрута. Я определил, что мне нужно перевести с python на swift, как упоминалось здесь , но, похоже, я не могу понять это. Можете ли вы мне здесь как-нибудь помочь?

2. Это то, за что мне платят. 😉 Но если вы читали мою книгу, вы уже должны быть на правильном пути.

3. А, понятно. Как бы я ни был разочарован этим, я действительно хочу сам взломать это сейчас. Спасибо за вашу помощь и книгу!

4. В случае, если вы еще этого не видели, в этом репозитории показано, как декодировать прогнозы из 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, amp;countAsInt32)

    // output = 1   exp(-input)
    var one: Float = 1
    vDSP_vsadd(optr, 1, amp;one, optr, 1, vDSP_Length(count))
    
    // output = 1 / 1   exp(-input)
    var one_ar = [Float] (repeating: 1, count: input.count)
    vvdivf(optr, amp;one_ar, optr, amp;countAsInt32)
}
  

}