Преобразовать выходные данные LibSVM в вектор чисел с плавающей точкой

Мне нужно сформировать HOGDescriptor::setSVMDetector() вход.

Я вычисляю дескрипторы с openCV, затем использую libSVM, чтобы получить файл модели.
Для формирования ввода я знаю, что мне нужно получить значения векторов поддержки и поэлементно смешать их с альфа-каналом (затем добавить -rho в конце), но я не понимаю, где взять эти альфы.

У меня есть список SV, как:

1 1:-0.0434783 2:0.153846 3:0.194444 4:-0.353712 5:-0.45054
1 1:-0.2173916 2:-0.38461 3:0.222262 4:-0.676686 5:-0.78062

а где взять альфы?

0

Решение

Но почему вы хотите классифицировать это «от руки»? OpenCV имеет процедуру классификации называется predict, который использует найденные SV ‘и альфы’

float response = SVM.predict(sampleMat);

Если вы действительно хотите сделать это самостоятельно, вам понадобятся не только SV и альфы, но и функция ядра, используемая для обучения и вычислений.

SUM alpha_i K( support_vector_i , data_point ) - rho

Я не уверен, возможно ли извлечь альфы «вручную», не расширяя класс SVM, как можно увидеть в источники — Альфы хранятся в CvSVMDecisionFunc состав:

struct CvSVMDecisionFunc
{
double rho;
int sv_count;
double* alpha;
int* sv_index;
};

в то время как единственная ссылка на эту структуру находится в protected раздел:

protected:

(...)

CvSVMDecisionFunc* decision_func;

Из исходного кода svm.cpp мы можем найти, что это только публично доступно через save рутина. Таким образом, «взломать» можно было бы сохранить модель и извлечь из нее альфы (она будет расположена в разделе «Функция принятия решения», написанном в удобочитаемом формате).

Самая простая техника извлечения, кажется, расширяет CvSVM класс и включить метод, как

public:

CvSVMDecisionFunc* get_decision_function() { return decision_func; }

после выяснения, что OP на самом деле пытается использовать внешне обученную модель в opencv — самый простой способ — преобразовать модель libsvm, созданную другим методом (libsvm, linearsvm и т. д.), в формат, совместимый с opencv, и загрузить его, используя read метод

void CvSVM::read( CvFileStorage* fs, CvFileNode* svm_node )

см. источник для более подробной информации.

0

Другие решения

Хорошо, кажется, теперь все ясно.
Альфы — первый столбец в моем случае.
Поскольку в моей тестовой модели все они были равны -1 или 1 (не знаю почему), я подумал, что это были ярлыки.

В любом случае, вот мой парсер (но вам нужно оставить только SV в файле):

std::ifstream ifs("cars_model.model");

const int nsv = 90;
const int nfeatures = 144;

float rho = 12.5459;

char ts[4000] = ""; // !

std::vector<float> res(nfeatures,0);

std::vector<float> alphas;

Mat_<float> temp(nsv, nfeatures);

int c = 0;

std::cout << "Loading model file...\n";

for (int i=0; i<nsv; i++) {

float al = 0;
ifs >> al;
alphas.push_back(al);

for (int j=0; j<nfeatures; j++) {

float ind, s;
char junk;

ifs >> ind >> junk >> s;

temp.at<float>(c, j) = s;

//std::cout << f << ' ' << s << '\n';

}

c++;

}

ifs.close();

std::cout << "Computing primal form...\n";

for (int i=0; i<nsv; i++) {

float alpha = alphas[i];

for (int j=0; j<nfeatures; j++) {
res[j] += (temp.at<float>(i,j) * alpha);
}

}

//res.push_back(-rho);

std::ofstream ofs("primal.txt");

for (int i=0; i<res.size(); i++)
ofs << res[i] << ' ';

ofs.close();

И вы знаете, это работает. Вы можете установить rho в качестве порога детектора.

0

По вопросам рекламы [email protected]