-1

I have trained a SVM in Python with scikit and used probabilities=true

model = svm.SVC(gamma=params["gamma"], C=params["C"], probability=True)
model.fit(X_train, y_train)
initial_type = [('float_input', FloatTensorType([None, X_train.shape[1]]))]
onnx_model = convert_sklearn(model, initial_types=initial_type,options={"zipmap": False},  target_opset=12)

And i have wrote a Android Class in kotlin for using it:

class Classifier(context: Context, modelFileName: String="") {

    private val session: OrtSession
    private val env: OrtEnvironment

    init {
        val modelBytes = context.resources.openRawResource(R.raw.svm_model2).readBytes()
        env = OrtEnvironment.getEnvironment()
        session = try {
            env.createSession(modelBytes)
        } catch (e: Exception) {
            Log.e("Classifier", "Error initializing model: ${e.message}")
            throw e
        }
    }

    suspend fun runInference(inputData: FloatArray): String {
        val inputName = session.inputNames?.iterator()?.next()
        val floatBufferInputs = FloatBuffer.wrap(inputData)
        val inputTensor = OnnxTensor.createTensor(env, floatBufferInputs, longArrayOf(1,inputData.size.toLong()))
        val result = session.run(mapOf(inputName to inputTensor))
        val re = result[0].value as Array<*>
        val outputArray = re.map { it.toString() }.toTypedArray()

        Log.v("classifier", outputArray.contentToString())

        return outputArray.contentToString()
    }
}

So when i use the kotlin Class, i get the correct label, but i want to get the probabilities as well, how can i do this?

1 Answers1

0

Since I believe that some might still have a similar issue, here's my response:

I would need to add the following to the Python code:

initial_type = [('float_input', FloatTensorType([None, X_train.shape[1]]))]
onnx_model = convert_sklearn(model, initial_types=initial_type,options={'zipmap': False, 'output_class_labels': False, 'raw_scores': False},  target_opset=12)
onnx.save_model(onnx_model, 'svm_model.onnx')

And I have rewritten my Kotlin class as follows:

class Classifier(context: Context, modelFileName: String="") {

    private val session: OrtSession
    private val env: OrtEnvironment

    init {
        val modelBytes = context.resources.openRawResource(R.raw.default_model).readBytes()
        env = OrtEnvironment.getEnvironment()
        session = try {
            env.createSession(modelBytes)
        } catch (e: Exception) {
            Log.e("Classifier", "Error initializing model: ${e.message}")
            throw e
        }
    }

    suspend fun runInference(inputData: HRVFeatures): Pair<String, Float> {
        val inputName = session.inputNames?.iterator()?.next()
        val floatBufferInputs = FloatBuffer.wrap(inputData.floatArray())
        val inputTensor = OnnxTensor.createTensor(env, floatBufferInputs, longArrayOf(1, inputData.floatArray().size.toLong()))

        val outputNames = session.outputNames?.toList()
        val results = session.run(mapOf(inputName to inputTensor),  outputNames?.toMutableSet() ?: mutableSetOf(), null)
        val labelOutput = results[0].value as? Array<*>
        val probabilityOutput = results[1] as? OnnxTensor

        val classifierLabel = labelOutput?.map { it.toString() }?.toTypedArray()?.get(0).toString()
        val classifierProbabilities = probabilityOutput?.floatBuffer?.array()

        return Pair(classifierLabel, classifierProbabilities?.maxOrNull() ?: 0.0f )
    }
}