Ios 向数据对象强制转换多维数组以进行TF推断
我目前正在iOS应用程序中使用Tensorflow的Swift版本。 我的模型工作得很好,但是我很难将数据复制到第一张量中,这样我就可以使用神经网络来检测东西了 我进行了咨询,他们的代码如下: 他们正在使用一些扩展: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
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.