Перейти к содержимому
Compvision.ru
AZIP

Проблемы с cvSolve()

Recommended Posts

Привет всем.

Делаю проект по распознаванию эмоций и наткнулся на проблему.

Нужно решить систему уравнений:

CvMat *_A, *_B, *_X;

_A= cvCreateMat(10,2,CV_64FC1);

_B = cvCreateMat(10,1,CV_64FC1);

_X = cvCreateMat(10,1,CV_64FC1);

Данные ввожу таким вот путем:

double *data = _B->data.db;

(data)[0] = EyeWidth()/b;

(data)[1] = EyeHeight()/b;

...

Функции EyeWidth() и т.д. возвращают нормальные double значения.

Матрица _А, в первой колонке коефициенты для одно емоции, в второй - другой (тоесть, они не могут быть одинаковыми):

int step = _A->step/sizeof(double);

double *data = _A->data.db;

double *dataA = _B->data.db;

for (int i=0;i<10;i++)

{

(data+step*i)[col]=(dataA+step*i)[0];

}

Собственно решение:

CvMat* RES = cvCreateMat(2,1,CV_64FC1);

cvSolve(_A,_B,RES,CV_LU);

double *data = RES->data.db;

_happy=(data)[0];

_sad=(data)[1];

_happy і _sad возвращают одинаковые значение -1.4216995963440653e-068 (или что-то в этом роде).

Подскажите, пожалуйста, что я сделал не так? Может дело в методе решения? Очень нужно (

Заранее спасибо всем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Матрица A должна быть квадратной. Запишите систему уравнений на бумаге и все станет ясно.

Неквадратные матрицы может решать SVD метод, но это тоже не ваш случай (возможно это Вы и хотите сделать), т.к. если бы было по 10 примеров 2-х эмоций то A была бы 10х2 (или 2х10 с транспонированием сами разбирайтесь :) ) остальные матрицы были бы 2х1.

Если признаков эмоций 10, то количество уравнений должно быть >=10. Если их 10, то матрица A будет квадратной 10х10 матрицей, а X и B векторами 1х10. Если уравнений больше 10, то матрица A будет прямоугольной, размером Nx10, а X и B все равно векторами 1х10 и решаться это все будет методом SVD, который дает решение задачи методом наименьших квадратов.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо, может уже и не по теме..но есть и второй вариант решения)(соответственно тоже безуспешый, хотя в Excell даная модель работала...)

//Transpose [A] matrix

CvMat* AT = cvCreateMat(2,10,CV_64FC1);

cvTranspose(_A,AT);

////Multiply [At] x [A]

CvMat* ATA = cvCreateMat(2,2,CV_64FC1);

cvMatMul(AT,_A,ATA);

//Multiply [At] x

CvMat* ATB = cvCreateMat(2,1,CV_64FC1);

cvMatMul(AT,_B,ATB);

//Invert [AtxA] matrix

CvMat* ATAi = cvCreateMat(2,2,CV_64FC1);

cvInvert(ATA,ATAi);

//Finally, [AtxA]^-1 x [AtxB]

CvMat* RES = cvCreateMat(2,1,CV_64FC1);

cvMatMul(ATAi,ATB,RES);

В результате 0.00 и 0.00

Простите, что сколько вопросов) но может еще есть надежа?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вариант не правильный, попытайтесь разобраться с методом (у Вас в задаче, 10 измеряемых признаков 2 известных эмоции).

У Вас, в том виде в котором это приведено, метод может работать в таких конфигурациях матриц, но это будет как если бы Вы имели дело с двумя признаками и десятью известными эмоциями (можно чтобы эмоции повторялись для разных признаков).

Метод, с которым Вы имеете дело, называется линейной регрессией.

http://www.machinelearning.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%BD%D0%B0%D0%B8%D0%BC%D0%B5%D0%BD%D1%8C%D1%88%D0%B8%D1%85_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BE%D0%B2

Хотя бы ссылки на литературу по которой Вы это делаете приведите.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Литературу не смогу... просто вот так вот сели и решили)) может поможет скрин с екселя....

http://dl.dropbox.com/u/66127184/screen.PNG

а пока буду разбиратся(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это опять я) нашел кое-кую багу:

CvMat* ATA = cvCreateMat(2,2,CV_64FC1);

cvMatMul(AT,_A,ATA);

после этого умножения, в [АТА] ОЧЕНЬ болшие числа 3.9406234902248240e+133... может я не правильно создаю матрицы?((

В исходных матрицах числа порядка 0,01...1.0

Изменено пользователем AZIP

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

http://opencv.willowgarage.com/wiki/Matrix_operations

А что у Вас означает вектор b?

Обычно так:

a01+a11*x1+a21*x2+..+a91*x10=b0

...

a0n+a1n*x1+a2n*x2+..+a9n*x10=bn

A - это матрица коэффициентов a, в которых, собственно и содержится информация о том, как трактовать измеренные параметры.

X - это вектор значений измеряемых параметров x

B - вектор меток класса (радость/печаль)

При обучении, мы методом наименьших квадратов, находим коэффициенты матрицы A, при заданных значениях векторов X и b.

Чтобы получить коэффициенты правильно, нужно 10 или больше уравнений, иначе система недоопределена.

В вашем экселевском расчете ошибки наложились друг на друга, в результате, все равно получается ерунда, хотя и считает что-то (псевдоинверсией (A^T*A)^(-1)*A^T надо пользоваться осторожно, т.к. она выдает какой-то результат почти всегда).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тьюу, напутал :)

a0+a1*x10+a2*x20+..+a9*x10=b0

...

a0+a1*x1n+a2*x2n+..+a9*x1n=bn

вот

A=inv(X'*X)*X'*b;

' - это транспонирование.

только к Х надо добавить вначале строку единиц (коэффициенты перед a0 равны 1) чтобы размерности совпали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Проблема решена!) Я как-то криво вводил данные в матрицу _А (слишком намудрил))):

void Analiser::SetFeatures(int col)

{

int step = _A->step/sizeof(double);

double *data = _A->data.db;

double *dataA = _B->data.db;

for (int i=0;i<10;i++)

{

cvmSet(_A,i,col,cvmGet(_B,i,0));

//(data+step*i)[col]=(dataA+step*i)[0]; //!! Вот тут и была проблема ;)

}

}

Как говорится, нужно быть по-проще))Еще раз благодарю Вас)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×