I am trying to use Joachim's SVMstruct to learn a MRF using max-margin training. As I want to use graph cuts for inference, I want my energy function to be submodular. This should be easy to achieve by restricting non-diagonal pairwise terms to be positive.

SVMstruct has an option to include additional constraints such as this, it is even given as an example. Still, I was not able to really enforce these constraints - even with a cost factor for 1e10, my weights are all negative.

Does any one have any experience with this algorithm / software?

If someone has any hints on what I could be doing wrong, any help would be very much appreciated.

Btw, I am using the Python interface.

This question is marked "community wiki".

asked May 15 '12 at 13:15

Andreas%20Mueller's gravatar image

Andreas Mueller
2686185893

edited May 15 '12 at 13:16


2 Answers:

The newest release of the dlib library updates its structural SVM solver to support a non-negativity constraint. You don't have to define anything special yourself or set penalty factors, just tell it which terms you want to be non-negative and it will do the right thing. There is also an object specifically for doing max-margin training on a kind of MRF solvable with graph cuts.

As a disclaimer, I wrote this library. :)

This answer is marked "community wiki".

answered Jun 15 '12 at 19:54

Davis%20King's gravatar image

Davis King
19626

Thanks Davis, this sounds awesome! At the moment I'm working with my own simple implementation in Python. I haven't heard about your library but it looks great. I'll have a more detailed look if I find the time.

(Jun 16 '12 at 08:13) Andreas Mueller

You are not doing anything wrong, but the constraints are only enforced up to the current precision of the solver (denoted by epsilon). See the following code from the original svm_struct_api.c

/* add constraints so that all learned weights are
        positive. WARNING: Currently, they are positive only up to
        precision epsilon set by -e. */
c.lhs=my_malloc(sizeof(DOC *)*sizePsi);
c.rhs=my_malloc(sizeof(double)*sizePsi);
for(i=0; i<sizePsi; i++) {
  words[0].wnum=i+1;
  words[0].weight=1.0;
  words[1].wnum=0;
  /* the following slackid is a hack. we will run into problems,
     if we have move than 1000000 slack sets (ie examples) */
  c.lhs[i]=create_example(i,0,1000000+i,1,create_svector(words,"",1.0));
  c.rhs[i]=0.0;
}

The Python equivalent (without the slackid hack) is the following:

def init_constraints(sample,sm,sparm):
    slackid = len(sample)+1

    #set constraints that each weight should be positive
    constraints = []
    for i in range(sm.size_psi):
        coefficients = svmapi.Document(svmapi.Sparse([(i,1)]))
        coefficients.slackid = slackid+i
        constraints.append((coefficients,0))

    return constraints
This answer is marked "community wiki".

answered Sep 11 '12 at 03:53

CvW's gravatar image

CvW
11

Your answer
toggle preview

powered by OSQA

User submitted content is under Creative Commons: Attribution - Share Alike; Other things copyright (C) 2010, MetaOptimize LLC.