Commit 1246894606c8960d15496aa0dffb99afe5747d46
1 parent
29c8c3f5
LDA support for two class hyperplane classificiation
Showing
1 changed file
with
34 additions
and
1 deletions
openbr/plugins/eigen3.cpp
| ... | ... | @@ -302,11 +302,13 @@ class LDATransform : public Transform |
| 302 | 302 | Q_PROPERTY(int directLDA READ get_directLDA WRITE set_directLDA RESET reset_directLDA STORED false) |
| 303 | 303 | Q_PROPERTY(float directDrop READ get_directDrop WRITE set_directDrop RESET reset_directDrop STORED false) |
| 304 | 304 | Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false) |
| 305 | + Q_PROPERTY(bool isBinary READ get_isBinary WRITE set_isBinary RESET reset_isBinary STORED false) | |
| 305 | 306 | BR_PROPERTY(float, pcaKeep, 0.98) |
| 306 | 307 | BR_PROPERTY(bool, pcaWhiten, false) |
| 307 | 308 | BR_PROPERTY(int, directLDA, 0) |
| 308 | 309 | BR_PROPERTY(float, directDrop, 0.1) |
| 309 | 310 | BR_PROPERTY(QString, inputVariable, "Label") |
| 311 | + BR_PROPERTY(bool, isBinary, false) | |
| 310 | 312 | |
| 311 | 313 | int dimsOut; |
| 312 | 314 | Eigen::VectorXf mean; |
| ... | ... | @@ -316,7 +318,6 @@ class LDATransform : public Transform |
| 316 | 318 | { |
| 317 | 319 | // creates "Label" |
| 318 | 320 | TemplateList trainingSet = TemplateList::relabel(_trainingSet, inputVariable); |
| 319 | - | |
| 320 | 321 | int instances = trainingSet.size(); |
| 321 | 322 | |
| 322 | 323 | // Perform PCA dimensionality reduction |
| ... | ... | @@ -450,6 +451,34 @@ class LDATransform : public Transform |
| 450 | 451 | // Compute final projection matrix |
| 451 | 452 | projection = ((space2.eVecs.transpose() * space1.eVecs.transpose()) * pca.eVecs.transpose()).transpose(); |
| 452 | 453 | dimsOut = dim2; |
| 454 | + | |
| 455 | + if (isBinary) { | |
| 456 | + assert(dimsOut == 1); | |
| 457 | + TemplateList projected; | |
| 458 | + float posVal = 0; | |
| 459 | + float negVal = 0; | |
| 460 | + for (int i = 0; i < trainingSet.size(); i++) { | |
| 461 | + Template t; | |
| 462 | + project(trainingSet[i],t); | |
| 463 | + //Note: the positive class is assumed to be 0 b/c it will | |
| 464 | + // typically be the first gallery template in the TemplateList structure | |
| 465 | + if (classes[i] == 0) | |
| 466 | + posVal += t.m().at<float>(0,0); | |
| 467 | + else if (classes[i] == 1) | |
| 468 | + negVal += t.m().at<float>(0,0); | |
| 469 | + else | |
| 470 | + qFatal("Binary mode only supports two class problems."); | |
| 471 | + } | |
| 472 | + posVal /= classCounts[0]; | |
| 473 | + negVal /= classCounts[1]; | |
| 474 | + | |
| 475 | + if (posVal < negVal) { | |
| 476 | + //Ensure positive value is supposed to be > 0 after projection | |
| 477 | + Eigen::MatrixXf invert = Eigen::MatrixXf::Ones(dimsIn,1); | |
| 478 | + invert *= -1; | |
| 479 | + projection = invert.transpose() * projection; | |
| 480 | + } | |
| 481 | + } | |
| 453 | 482 | } |
| 454 | 483 | |
| 455 | 484 | void project(const Template &src, Template &dst) const |
| ... | ... | @@ -462,6 +491,10 @@ class LDATransform : public Transform |
| 462 | 491 | |
| 463 | 492 | // Do projection |
| 464 | 493 | outMap = projection.transpose() * (inMap - mean); |
| 494 | + | |
| 495 | + if (isBinary) { | |
| 496 | + dst.file.set("conf",dst.m().at<float>(0,0)); | |
| 497 | + } | |
| 465 | 498 | } |
| 466 | 499 | |
| 467 | 500 | void store(QDataStream &stream) const | ... | ... |