2

Edit:

Found the problem! The samples I was putting in the prediction did not reach the windowSize and for some reason when I was creating the MLMultiArrays, it directly filled the array with random values. So the solution was to fill it with zeroes like this

    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
    }

Initial Question:

I have trained an activity classifier in CreateML where I am getting 100% correctness on my tests, however when I do the device inference it guesses correctly around 10% of the times, or even less. Any ideas why?

The only bug fix lead I have is to understand the stateIn variable of LSTMs, right now I am keeping the array with nil values. Do I need to make a prediction every time I get add a sample so I can get the new state variable? Any pointers would be very helpful

Below my inference code.

    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
castillejoale
  • 519
  • 4
  • 13

0 Answers0