Post not yet marked as solved
Post marked as unsolved with 0 replies, 526 views
Hi,
I try the activity classifier and want to show the results with an app on a IPhone SE.
I try the example analog https://apple.github.io/turicreate/docs/userguide/activity_classifier/export_coreml.html
When calling the prediction function:
...
func performModelPrediction () -> String? {
...
EXC_BAD_ACCESS (code=1, address=0x0) was thrown in line:
let modelPrediction = try! activityClassificationModel.prediction(
^^^^^^^^here was the Error shown
I can trak it down to the source of the mlmodel:
func prediction(input: MyActivityClassifier2Input, options: MLPredictionOptions) throws -> MyActivityClassifier2Output {
let outFeatures = try model.prediction(from: input, options:options)
return MyActivityClassifier2Output(features: outFeatures)
}
I created the model with ml creator, working with Xcode 13 beta.
What I am doing wrong ? Do you have any hints ? Is there a better example for activity classifier ?
Don't hesitate to ask for further details.
-Hans
here my code:
//
// ViewController.swift
// motionstor4yboard
//
// Created by Hans Regler on 19.07.21.
//
import Foundation
import UIKit
import CoreML
import CoreMotion
class ViewController: UIViewController
{
override func viewDidLoad() {
debugPrint("info: start viewDidLoad ... ")
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Connect data:
self.startDeviceMotion()
}
// Define some ML Model constants for the recurrent network
struct ModelConstants {
static let numOfFeatures = 6
// Must be the same value you used while training
static let predictionWindowSize = 100
static let sensorsUpdateInterval = 1.0 / 10.0
static let stateInLength = 400
}
// Initialize the model, layers, and sensor data arrays
let activityClassificationModel = MyActivityClassifier2()
var currentIndexInPredictionWindow = 0
let accelDataX = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
let accelDataY = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
let accelDataZ = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
let gyroDataX = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
let gyroDataY = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
let gyroDataZ = try! MLMultiArray(shape: [ModelConstants.predictionWindowSize] as [NSNumber], dataType: MLMultiArrayDataType.double)
var stateOutput = try! MLMultiArray(shape:[ModelConstants.stateInLength as NSNumber], dataType: MLMultiArrayDataType.double)
// Initialize CoreMotion Manager
let motionManager = CMMotionManager()
func startDeviceMotion() {
// guard motionManager.isDeviceMotionAvailable else {
guard motionManager.isAccelerometerAvailable, motionManager.isGyroAvailable else {
debugPrint("Core Motion Data Unavailable!")
return
}
motionManager.accelerometerUpdateInterval = TimeInterval(ModelConstants.sensorsUpdateInterval)
motionManager.gyroUpdateInterval = TimeInterval(ModelConstants.sensorsUpdateInterval)
motionManager.startAccelerometerUpdates(to: .main) { accelerometerData, error in
guard let accelerometerData = accelerometerData else {
print("Error: accelerometerData = accelerometerData")
return }
// Add the current data sample to the data array
self.addAccelSampleToDataArray(accelSample: accelerometerData)
}
}
func addAccelSampleToDataArray (accelSample: CMAccelerometerData) {
// Add the current accelerometer reading to the data array
accelDataX[[currentIndexInPredictionWindow] as [NSNumber]] = accelSample.acceleration.x as NSNumber
accelDataY[[currentIndexInPredictionWindow] as [NSNumber]] = accelSample.acceleration.y as NSNumber
accelDataZ[[currentIndexInPredictionWindow] as [NSNumber]] = accelSample.acceleration.z as NSNumber
// Update the index in the prediction window data array
currentIndexInPredictionWindow += 1
// If the data array is full, call the prediction method to get a new model prediction.
// We assume here for simplicity that the Gyro data was added to the data arrays as well.
if (currentIndexInPredictionWindow == ModelConstants.predictionWindowSize) {
if let predictedActivity = performModelPrediction() {
// Use the predicted activity here
// ...
// Start a new prediction window
currentIndexInPredictionWindow = 0
}
}
}
func performModelPrediction () -> String? {
// Perform model prediction
let modelPrediction = try! activityClassificationModel.prediction(
acceleration_x: accelDataX,
acceleration_y: accelDataY,
acceleration_z: accelDataZ,
rotation_x: gyroDataX,
rotation_y: gyroDataY,
rotation_z: gyroDataZ,
stateIn: stateOutput)
// Update the state vector
stateOutput = modelPrediction.stateOut
// Return the predicted activity - the activity with the highest probability
return modelPrediction.label
}