Ios 向数据对象强制转换多维数组以进行TF推断

Ios 向数据对象强制转换多维数组以进行TF推断,ios,swift,tensorflow,Ios,Swift,Tensorflow,我目前正在iOS应用程序中使用Tensorflow的Swift版本。 我的模型工作得很好,但是我很难将数据复制到第一张量中,这样我就可以使用神经网络来检测东西了 我进行了咨询,他们的代码如下: 他们正在使用一些扩展: extension Array { /// Creates a new array from the bytes of the given unsafe data. /// /// - Note: Returns `nil` if `unsafeData.c

我目前正在iOS应用程序中使用Tensorflow的Swift版本。 我的模型工作得很好,但是我很难将数据复制到第一张量中,这样我就可以使用神经网络来检测东西了

我进行了咨询,他们的代码如下:

他们正在使用一些扩展:

extension Array {
    /// Creates a new array from the bytes of the given unsafe data.
    ///
    /// - Note: Returns `nil` if `unsafeData.count` is not a multiple of
    ///     `MemoryLayout<Element>.stride`.
    /// - Parameter unsafeData: The data containing the bytes to turn into an array.
    init?(unsafeData: Data) {
        guard unsafeData.count % MemoryLayout<Element>.stride == 0 else { return nil }
        let elements = unsafeData.withUnsafeBytes {
            UnsafeBufferPointer<Element>(
                start: $0,
                count: unsafeData.count / MemoryLayout<Element>.stride
            )
        }
        self.init(elements)
    }
}

extension Data {
    /// Creates a new buffer by copying the buffer pointer of the given array.
    ///
    /// - Warning: The given array's element type `T` must be trivial in that it can be copied bit
    ///     for bit with no indirection or reference-counting operations; otherwise, reinterpreting
    ///     data from the resulting buffer has undefined behavior.
    /// - Parameter array: An array with elements of type `T`.
    init<T>(copyingBufferOf array: [T]) {
        self = array.withUnsafeBufferPointer(Data.init)
    }
}
然后,他们将
输入数据
复制到神经网络中

我试图修改他们的代码,将图像加载到[1,28,28,1]张量中。 图像看起来像这样:

[[[[Float32(254.0)],
               [Float32(255.0)],
               [Float32(254.0)],
               [Float32(250.0)],
               [Float32(252.0)],
               [Float32(255.0)],
               [Float32(255.0)],
               [Float32(255.0)],
               [Float32(255.0)],
               [Float32(254.0)],
               [Float32(214.0)],
               [Float32(160.0)],
               [Float32(130.0)],
               [Float32(124.0)],
               [Float32(129.0)],
...
你明白了

但如果我尝试用图像数据将其转换为Data/init Data,我只得到8个字节:

private func createTestData()  -> Data {
        return Data(copyingBufferOf:
            [[[[Float32(254.0)],
               [Float32(255.0)],
               [Float32(254.0)],
...

测试中的代码也是如此,但对于它们来说,这很好(2*Float32=8字节)。 对我来说,这太小了(应该是28*28*4=3136字节)

  • 我有没有遗漏什么(我是否忽略了什么)
  • 要将图像放入正确的阵列/数据类型,我需要做什么

  • Swift
    数组是一个固定大小的结构,带有指向实际元素存储的(不透明)指针。
    withUnsafeBufferPointer()
    方法使用指向该元素存储的缓冲区指针调用给定的闭包。对于
    [Float]
    数组,它是指向浮点值的内存地址的指针。这就是为什么

    array.withUnsafeBufferPointer(Data.init)
    
    用于获取表示浮点数的
    数据

    如果将嵌套数组(例如
    [[Float]]
    类型)传递给
    withUnsafeBufferPointer()
    方法,则使用指向内部数组的
    数组结构的指针调用闭包。因此,元素类型现在不是
    Float
    ,而是
    [Float]
    ——而不是警告意义上的“普通类型”

    /// - Warning: The given array's element type `T` must be trivial in that it can be copied bit
    ///     for bit with no indirection or reference-counting operations; otherwise, reinterpreting
    ///     data from the resulting buffer has undefined behavior.
    

    您需要做的是将嵌套数组展平为一个简单数组,然后从简单数组创建一个
    Data
    值。

    我没有Tensorflow的经验,但是
    Data(copyingBufferOf:)
    方法需要一个浮动的平面数组。对于嵌套数组,您可能需要首先将其展平为一个简单数组。@MartinR您完全正确。我不是Swift开发人员,这只是一个简单的应用程序,用于向大学展示一些东西,所以我不知道数组和东西在TF Swift中是如何工作的。在我做了大量的挖掘和实验后,我得出了相同的结论。半小时后,我读到了你的回复:D。如果你想,你可以把它作为一个答案发布(毕竟它是正确的),这样你就可以得到那些甜点。如果你不想那样做,我会自己发布一个答案。
    /// - Warning: The given array's element type `T` must be trivial in that it can be copied bit
    ///     for bit with no indirection or reference-counting operations; otherwise, reinterpreting
    ///     data from the resulting buffer has undefined behavior.