AZIP 0 Жалоба Опубликовано May 15, 2012 Привет всем. Делаю проект по распознаванию эмоций и наткнулся на проблему. Нужно решить систему уравнений: 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 (или что-то в этом роде). Подскажите, пожалуйста, что я сделал не так? Может дело в методе решения? Очень нужно ( Заранее спасибо всем. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 15, 2012 Матрица 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, который дает решение задачи методом наименьших квадратов. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AZIP 0 Жалоба Опубликовано May 15, 2012 Спасибо, может уже и не по теме..но есть и второй вариант решения)(соответственно тоже безуспешый, хотя в 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 Простите, что сколько вопросов) но может еще есть надежа?) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 15, 2012 Вариант не правильный, попытайтесь разобраться с методом (у Вас в задаче, 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 Хотя бы ссылки на литературу по которой Вы это делаете приведите. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AZIP 0 Жалоба Опубликовано May 15, 2012 Литературу не смогу... просто вот так вот сели и решили)) может поможет скрин с екселя.... http://dl.dropbox.com/u/66127184/screen.PNG а пока буду разбиратся( Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AZIP 0 Жалоба Опубликовано May 16, 2012 (изменено) Это опять я) нашел кое-кую багу: CvMat* ATA = cvCreateMat(2,2,CV_64FC1); cvMatMul(AT,_A,ATA); после этого умножения, в [АТА] ОЧЕНЬ болшие числа 3.9406234902248240e+133... может я не правильно создаю матрицы?(( В исходных матрицах числа порядка 0,01...1.0 Изменено May 16, 2012 пользователем AZIP Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 16, 2012 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 в систему с известными коэффициентами, полученными при обучении. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AZIP 0 Жалоба Опубликовано May 16, 2012 Спасибо Вам огромное) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 16, 2012 Тьюу, напутал a0+a1*x10+a2*x20+..+a9*x10=b0 ... a0+a1*x1n+a2*x2n+..+a9*x1n=bn вот A=inv(X'*X)*X'*b; ' - это транспонирование. только к Х надо добавить вначале строку единиц (коэффициенты перед a0 равны 1) чтобы размерности совпали. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AZIP 0 Жалоба Опубликовано May 16, 2012 Проблема решена!) Я как-то криво вводил данные в матрицу _А (слишком намудрил))): 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]; //!! Вот тут и была проблема } } Как говорится, нужно быть по-проще))Еще раз благодарю Вас) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах