1

Input shape of my tflite model - (18, 63) or 1134 numbers.

I get the data itself in objective-c code, and then I send it to swift code and an error already occurs there. In detail I do the following

  1. Receive the data in NSMutableArray. The length of the array is 1134 NSNumber
  2. Converting NSMutableArray to NSData
   NSData *d = [NSKeyedArchiver archivedDataWithRootObject:_data];
   NSLog(@"output: %@", d);
   // output: {length = 18181, bytes = 0x62706c69 73743030 d4000100 02000300 ... 00000000 000034fd }
  1. I send data to the swift code.
    Swift code:
@objc public func predict(_ data: NSData) {
        guard
          let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite")
        else {
            return
        }

        do {
          let interpreter = try Interpreter(modelPath: modelPath)
          try interpreter.allocateTensors()

          let inputData: Data = data as Data

          try interpreter.copy(inputData, toInputAt: 0) // <-- an error occurs in this line

          try interpreter.invoke()
          let outputTensor = try interpreter.output(at: 0)
        } catch {
          print(error)
        }
}
  1. I get an error in the above line of code. Error:
    Provided data count 18181 must match the required count 4536.

H

  • Why does the unarchived data have a length of 18,181, when you should have 4536? – NRitH Jan 05 '21 at 16:53
  • I don't know why, it's just a bug that I don't know how to fix – capybar133213 Jan 05 '21 at 17:17
  • 1
    I see you convert the ```NSMutableArray``` to ```NSData```. The length of the converted *data* is 18181 *bytes* (this represents the 1134 *numbers* stored in the array). Somewhere on the swift side you need to convert the data back to an array, you have to *unarchive* the data to get the array back *before* you pass it to the model. – skaak Jan 05 '21 at 17:46
  • The model accepts NSData / Data format data – capybar133213 Jan 06 '21 at 04:48
  • Ok, I don't have tflite docs and don't use it, but then maybe you need to convert it to data differently e.g. use a property list encoding? The docs should give some working example of how to convert to the ```NSData``` it expects? – skaak Jan 06 '21 at 07:39
  • I used this tutorial https://www.tensorflow.org/lite/guide/inference#load_and_run_a_model_in_swift . I haven't seen any other examples, as a rule, the cnn model is used everywhere and everything is done a little differently there. In my case, I just want to use a regular full-connected network – capybar133213 Jan 06 '21 at 09:08
  • I checked that quickly - looks like that is using image data and you are using numbers. But do you have API docs somewhere. – skaak Jan 06 '21 at 09:57
  • I haven't come across an available tflite api for swift – capybar133213 Jan 06 '21 at 11:16

2 Answers2

0

It looks like you're converting to NSData wrong. The code doesn't show how you are constructing _data, but from the size logged it looks like this is the issue. See this question on how to extract value from the NSNumber object and do this before passing it to the swift function.

Karim Nosseir
  • 540
  • 2
  • 8
0

I had the same issue and that's what I used. I start with an array of type Double.

Then I convert it in float32:

guard let inputDataFloat32 = yourArray.compactMap({ d in
    Float32(d)
}) else { return }

And then in Data():

let inputData = inputDataFloat32.withUnsafeBytes { f in
    Data(f)
}

And you can get the output like so:

guard let data = outputTensor?.data else {
    return
}
    
var output = Array<Float32>(repeating: 0, count: data.count/MemoryLayout<Float32>.stride)
_ = output.withUnsafeMutableBytes { i in
    data.copyBytes(to: i)
}
print("Output: \(output)")
MrPOHB
  • 31
  • 4