Ask Your Question
0

Load an SVM from a string in Python?

asked 2020-05-28 21:40:05 -0600

Is there a way to load a pre-trained SVM model from an XML string in Python? I am looking to use it on a platform that does not support an external file system, so the model must be saved as a string in the .py file itself.

These examples (1, 2) seem possible in C++; however, it doesn't appear that svm->read is exposed in Python.

Is there a workaround that would accomplish something similar in Python?

//1
string yml; // the whole schlepp in a string
FileStorage fs;
fs.open(yml,FileStorage::READ|FileStorage::MEMORY);
facereco->load(fs);
fs.release();

//2
string data_string; //containing xml/yml data
FileStorage fs( data_string, FileStorage::READ | FileStorage::MEMORY);
svm.read(fs.getFirstTopLevelNode()); // or the node with your trainset
edit retag flag offensive close merge delete

Comments

opencv version ?

this should be possible, cv2.ml.SVM has a read() method

berak gravatar imageberak ( 2020-05-29 00:58:45 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-05-29 02:25:57 -0600

berak gravatar image

updated 2020-05-29 02:26:31 -0600

you probably did not try hard enough, it's possible with opencv >= 3 ;)

given a pretrained xml (5 features, 5 data points):

>>> xml = """
<?xml version="1.0"?>
<opencv_storage>
<opencv_ml_svm>
  <format>3</format>
  <svmType>C_SVC</svmType>
  <kernel>
    <type>RBF</type>
    <gamma>1.</gamma></kernel>
  <C>1.</C>
  <term_criteria><epsilon>1.1920928955078125e-07</epsilon>
    <iterations>1000</iterations></term_criteria>
  <var_count>5</var_count>
  <class_count>5</class_count>
  <class_labels type_id="opencv-matrix">
    <rows>5</rows>
    <cols>1</cols>
    <dt>i</dt>
    <data>
      1 2 3 4 5</data></class_labels>
  <sv_total>5</sv_total>
  <support_vectors>
    <_>
      1. 1. 1. 1. 1.</_>
    <_>
      1. 1. 1. 1. 1.</_>
    <_>
      1. 1. 1. 1. 1.</_>
    <_>
      1. 1. 1. 1. 1.</_>
    <_>
      1. 1. 1. 1. 1.</_></support_vectors>
  <decision_functions>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        0 1</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        0 2</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        0 3</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        0 4</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        1 2</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        1 3</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        1 4</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        2 3</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        2 4</index></_>
    <_>
      <sv_count>2</sv_count>
      <rho>0.</rho>
      <alpha>
        1. -1.</alpha>
      <index>
        3 4</index></_></decision_functions></opencv_ml_svm>
</opencv_storage>
"""
>>> fs = cv2.FileStorage(xml, cv2.FileStorage_READ | cv2.FileStorage_MEMORY)
>>> n = fs.getFirstTopLevelNode()
>>> n.name()
'opencv_ml_svm'
>>> svm2 = cv2.ml.SVM_create()
>>> svm2.read(n)
>>> svm2.isTrained()
True
edit flag offensive delete link more

Comments

Thanks for the quick response! Yes this works, I guess I was looking in the wrong place (for something like cv2.ml.SVM_read())

jmcgrat3 gravatar imagejmcgrat3 ( 2020-05-29 07:52:57 -0600 )edit

>>> help(cv2.ml.SVM_create())

berak gravatar imageberak ( 2020-05-29 10:22:28 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-05-28 21:40:05 -0600

Seen: 605 times

Last updated: May 29 '20