【问题标题】:Converting MLMultiArray to [Double] causes NaN将 MLMultiArray 转换为 [Double] 会导致 NaN
【发布时间】:2020-11-03 07:22:54
【问题描述】:

我正在将 CoreML (4 b1) 中 prediction() 的返回值从 MLMultiArray 转换为 [Double],结果是创建了 NaN,通常对我来说没有任何意义。可能会发生什么?

这是我正在使用的转换函数:

static func toDoubleArray(_ o: MLMultiArray) -> [Double] {
        let length = o.count
        let doublePtr =  o.dataPointer.bindMemory(to: Double.self, capacity: length)
        let doubleBuffer = UnsafeBufferPointer(start: doublePtr, count: length)
        let output = Array(doubleBuffer)
        return output
    }

这是一个示例输出,带有神秘的 NaN:

original:
zn: Float32 1 x 30 matrix
[1.082742,-0.6218173,0.4097924,0.7741141,0.3768867,0.1923163,-0.6453421,-1.51211,0.9758957,-0.01491163,0.3188823,0.6816303,-0.3234658,-0.1413545,-0.3082153,-0.3349644,0.6796142,0.0495025,1.436066,-1.348089,0.2413646,-0.931259,-0.1012118,0.849587,-0.1338869,-0.5497701,-0.5438929,1.653574,-0.6829579,-0.539122]

converted: [-0.0001189622124778386, 0.0006766730199516765, 9.747163042077938e-09, -0.13711044152516036, -1.7618037121610124e-17, 0.00023267642183680645, -9.748075633049926e-10, -8.196165002097733e-07, 1.901572700078848e-13, -0.05577234175498982, -0.003711220331500651, 0.0015560479289331661, -5.481938547240449e-05, 0.3071476808226601, -4.9620131810906736e-05, 3.793063e-317, 2.220121165e-314, 1.5e-323, -nan(0x3ffff89abcdef), 5.312137469e-314, 0.0, 0.0, 0.0, 4.4490612551694285e-308, 7.99e-321, 2.2200499266e-314, 5e-324, 5.417665788e-314, 0.0, 0.0]

似乎我只是从某个地方获取垃圾内存......但话又说回来,它不应该包含 NaN。很困惑。

更新:好的,正如 Matthijs 所指出的,底层内存是 Float32。如果我只想要一个包含 Doubles 作为 Swift 数组的 MLMultiArray,那么 toDoubleArray() 函数就可以了。但就我而言,我想要转换为 Double Swift Array。这个版本提供了这一点,并且似乎给出了预期的输出:

static func castToDoubleArray(_ o: MLMultiArray) -> [Double] {
        var result: [Double] = Array(repeating: 0.0, count: o.count)
        for i in 0 ..< o.count {
            result[i] = o[i].doubleValue
        }
        return result
    }

【问题讨论】:

    标签: swift coreml


    【解决方案1】:

    原来是一个 Float32 值的数组,所以你应该转换成一个 Float 数组,而不是 Double。

    【讨论】:

    • 好的,但至少应该可能将 Float32 转换为 Double 吗?我的代码库中的toDoubleArray() 的第一个版本来自您的 CoreMLHelpers...
    • 阅读更多bindMemory 看起来可能是内存布局问题。我创建了一个castToDoubleArray() 函数来处理它。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 2020-08-25
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2017-11-15
    相关资源
    最近更新 更多