编辑:
发现问题了!我在预测中放入的样本没有达到 windowSize,并且由于某种原因,当我创建 MLMultiArrays 时,它直接用随机值填充了数组。所以解决方案是用这样的零填充它
for i in 0..<ModelConstants.predictionWindowSize {
centerOfMassXDifferenceArray[i] = 0
centerOfMassYDifferenceArray[i] = 0
heightDifferenceArray[i] = 0
numberOfPixelsDifferenceArray[i] = 0
widthDifferenceArray[i] = 0
xDifferenceArray[i] = 0
yDifferenceArray[i] = 0
}
for i in 0..<currentStateArray.count {
currentStateArray[i] = 0
}
最初的问题:
我已经在 CreateML 中训练了一个活动分类器,我在测试中获得了 100% 的正确性,但是当我进行设备推断时,它的猜测正确率约为 10%,甚至更少。任何想法为什么?
我唯一的错误修复线索是了解 LSTM 的 stateIn 变量,现在我将数组保留为 nil 值。每次添加样本时是否需要进行预测,以便获得新的状态变量?任何指针都会非常有帮助
在我的推理代码下方。
let classifier = ActivityModel()
struct ModelConstants {
static let predictionWindowSize = 49
}
guard let centerOfMassXDifferenceArray = try? MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let centerOfMassYDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let heightDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let numberOfPixelsDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let widthDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let xDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let yDifferenceArray = try? MLMultiArray( shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
guard let currentStateArray = try? MLMultiArray( shape: [400 as NSNumber], dataType: MLMultiArrayDataType.double) else { return nil }
// Populate
if inferenceData.count > ModelConstants.predictionWindowSize {
let range = inferenceData.index(inferenceData.endIndex, offsetBy: -ModelConstants.predictionWindowSize)..<inferenceData.endIndex
let arraySlice = inferenceData[range]
inferenceData = Array(arraySlice)
}
for i in 0..<inferenceData.count {
let blobMetric = inferenceData[i]
centerOfMassXDifferenceArray[i] = blobMetric.centerOfMassXDifference as NSNumber
centerOfMassYDifferenceArray[i] = blobMetric.centerOfMassYDifference as NSNumber
heightDifferenceArray[i] = blobMetric.heightDifference as NSNumber
numberOfPixelsDifferenceArray[i] = blobMetric.numberOfPixelsDifference as NSNumber
widthDifferenceArray[i] = blobMetric.widthDifference as NSNumber
xDifferenceArray[i] = blobMetric.xDifference as NSNumber
yDifferenceArray[i] = blobMetric.yDifference as NSNumber
}
// Perform prediction
let modelPrediction = try? classifier.prediction(
centerOfMassXDifference: centerOfMassXDifferenceArray,
centerOfMassYDifference: centerOfMassYDifferenceArray,
heightDifference: heightDifferenceArray,
numberOfPixelsDifference: numberOfPixelsDifferenceArray,
widthDifference: widthDifferenceArray,
xDifference: xDifferenceArray,
yDifference: yDifferenceArray,
stateIn: currentStateArray // Update the state vector
)
// Reset inferenceData
inferenceData = []
return modelPrediction?.label