How can I change the output dimensions of a CoreML model in Xcode when the outputs come from a NonMaximumSuppression layer?

After exerting a custom model with nms=True. In Xcode, the outputs show as:

confidence: MultiArray (0 × 5) coordinates: MultiArray (0 × 4)

I want to set fixed shapes (e.g., 100 × 5, 100 × 4), but Xcode does not allow editing—the shape fields are locked. The model graph shows both outputs come directly from a NonMaximumSuppression layer.

Is it possible to set fixed output dimensions for NMS outputs in CoreML?

In CoreML, setting fixed output dimensions for layers like NonMaximumSuppression (NMS) directly isn't straightforward because these layers typically produce outputs based on the input data, which can vary in size. The NMS layer reduces the number of detected objects based on overlap and confidence scores, so the number of outputs is inherently dynamic.

However, you can work around this limitation by using a few strategies:

Padding Outputs: You can modify your model to ensure that the maximum possible number of detections is produced, and then pad the results to a fixed size. This involves editing your model's architecture in a framework like TensorFlow or PyTorch before converting it to CoreML. For example, you can add a layer that pads the detection outputs to a fixed size like 100. Post-Processing in Swift: After obtaining the outputs from CoreML, you can perform post-processing in Swift to pad the results to the desired dimensions. This approach is flexible and doesn't require modifying the CoreML model itself.

Here's an example of how you might handle this in Swift:

import CoreML

func processDetections(confidence: MLMultiArray, coordinates: MLMultiArray) -> (confidence: [Float], coordinates: [[Float]]) { // Assuming confidence and coordinates are 1D arrays let maxDetections = 100 var paddedConfidence = confidence.floatData var paddedCoordinates = coordinates.floatData

// Pad confidence
while paddedConfidence.count < maxDetections * 5 {
    paddedConfidence.append(0.0)
}

// Pad coordinates
while paddedCoordinates.count < maxDetections * 4 {
    paddedCoordinates.append(0.0)
}

// Convert back to 2D arrays for confidence and coordinates
let confidenceArray = stride(from: 0, to: paddedConfidence.count, by: 5).map {
    Array(paddedConfidence[$0..<min($0 + 5, paddedConfidence.count)])
}

let coordinatesArray = stride(from: 0, to: paddedCoordinates.count, by: 4).map {
    Array(paddedCoordinates[$0..<min($0 + 4, paddedCoordinates.count)])
}

return (confidenceArray, coordinatesArray)

}

Custom Layer Implementation: If you have control over the model training process, you could implement a custom layer in TensorFlow or PyTorch that mimics the behavior of NMS but outputs fixed-size results. This custom layer can then be included in the model before conversion to CoreML.

By using one of these strategies, you can ensure that your CoreML model outputs have fixed dimensions, even if the NMS layer itself produces variable-sized outputs.

How can I change the output dimensions of a CoreML model in Xcode when the outputs come from a NonMaximumSuppression layer?
 
 
Q