编辑:
发现了问题!我放入预测中的样本未达到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