如何使用在 Swift 中返回 MultiArray(Double) 的模型进行预测
Posted
技术标签:
【中文标题】如何使用在 Swift 中返回 MultiArray(Double) 的模型进行预测【英文标题】:How to make a prediction with model that returns MultiArray(Double) in Swift 【发布时间】:2020-04-19 13:21:15 【问题描述】:我使用 Keras 训练了一个模型,并使用 CoreMLTools 将其转换为 CoreML。您可以在此处查看有关模型的详细信息:
如何使用此模型进行预测?当我尝试时出现此错误:
2019-12-30 13:07:01.564792-0800 agricultural-helper[16042:6014777] [espresso] [Espresso::handle_ex_plan] exception=Espresso exception: "Invalid argument": generic_reshape_kernel: Invalid bottom shape (512 28 -3 1 1) for reshape to (512 -1 1 1 1) status=-6
2019-12-30 13:07:01.565447-0800 agricultural-helper[16042:6014777] [coreml] Error computing NN outputs -6
Error Domain=com.apple.CoreML Code=0 "Error computing NN outputs." UserInfo=NSLocalizedDescription=Error computing NN outputs.
这是我的代码:
override init()
super.init()
let options = MLPredictionOptions()
options.usesCPUOnly = true
let model = CropDisease()
let uiImage = UIImage(named: "test.png")!
let pixelBuffer = buffer(from: uiImage)!
let modelInput = CropDiseaseInput(conv2d_input: pixelBuffer)
do
let output = try model.prediction(input: modelInput, options: options)
print(output)
catch
print(error)
func buffer(from image: UIImage) -> CVPixelBuffer?
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBuffer : CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
guard (status == kCVReturnSuccess) else
return nil
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: pixelData, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)
context?.translateBy(x: 0, y: image.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
UIGraphicsPushContext(context!)
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
UIGraphicsPopContext()
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
return pixelBuffer
任何帮助。谢谢!
【问题讨论】:
【参考方案1】:您的 Core ML 模型似乎存在内部问题。尝试使用 coremltools 从 Python 进行预测。我猜你会得到同样的错误信息。
如果情况确实如此,那么解决方案是找出问题在模型中的确切位置。错误信息已经给出了相当大的提示:
generic_reshape_kernel: Invalid bottom shape (512 28 -3 1 1)
for reshape to (512 -1 1 1 1)
某处的某个层正在获得一个形状为 (512, 28, -3, 1, 1) 但预期为 (512, -1, 1, 1, 1) 的张量。请注意,-1 不一定是问题(通常这意味着“自动计算此维度的大小”),但 -3 看起来有问题...
【讨论】:
感谢您的建议。现在就试试吧! 很遗憾,找不到太多。灰度图像与彩色图像是否存在问题? 如果你传入了错误的图像(像素不够等),那么 Core ML 会给出不同的错误,所以我怀疑是这样。你用什么框架来训练这个模型,也许是 TF 2.0? 我明白了。是的,我用过 TF2.0 对 TF 2.0 的支持是最近才添加到 coremltools 中的,所以毫无疑问它仍然存在错误。您可能会在这里遇到其中之一。没有看到实际的 mlmodel 文件就很难说。以上是关于如何使用在 Swift 中返回 MultiArray(Double) 的模型进行预测的主要内容,如果未能解决你的问题,请参考以下文章
Swift:如何在异步 urlsession 函数中返回一个值?
Swift:如何在异步 urlsession 函数中返回一个值?
Alamofire 4 请求返回 NSArray,无法弄清楚如何在 Swift 3 中使用 SwiftyJSON 进行解析