Я использую OpenCV 3.1.0, чтобы подогнать модель гауссовой смеси к данным двух классов с использованием EM. Выборки помечены, поэтому я предоставляю средние значения класса и ковариации во время обучения с помощью EM::trainE. Когда я проверяю предсказанные метки, они кажутся хорошо соответствующими данным, но противоположными (выборки из класса 1 почти всегда прогнозируются как находящиеся в классе 0 и наоборот). Вот как обучается модель:
// Run EM
Mat predicted_labels(samples.rows, 1, CV_64F);
Mat means0(EM_CLASS_COUNT, SAMPLE_DIMENSIONS, CV_64F);
const int sizes[]{ EM_CLASS_COUNT, SAMPLE_DIMENSIONS, SAMPLE_DIMENSIONS };
Mat covar0(3, sizes, CV_64F);
for (int i = 0; i < EM_CLASS_COUNT; ++i) {
calcCovarMatrix(class_samples[i], Mat(SAMPLE_DIMENSIONS, SAMPLE_DIMENSIONS, samples.type(), covar0.row(i).data), means0.row(i), COVAR_NORMAL | COVAR_ROWS);
}
Ptr model = EM::create();
model->setClustersNumber(EM_CLASS_COUNT);
model->trainE(samples, means0, covar0, noArray(), noArray(), predicted_labels);
// Print results
for (int i = 0; i < csv_data.size(); ++i) {
printf("(%f, %f, %f): %d -> %d\n", samples.at(i, 0), samples.at(i, 1), samples.at(i, 2), sample_labels.at(i), predicted_labels.at(i));
}
Mat error = (sample_labels != predicted_labels) / 255;
printf("Error rate: %f\n", norm(error, NORM_L1) / error.rows);
Mat means = model->getMeans();
printf("Sample means: 0:(%f, %f, %f), 1:(%f, %f, %f)\n", means0.at(0, 0), means0.at(0, 1), means0.at(0, 2), means0.at(1, 0), means0.at(1, 1), means0.at(1, 2));
printf("Calculated means: 0:(%f, %f, %f), 1:(%f, %f, %f)\n", means.at(0, 0), means.at(0, 1), means.at(0, 2), means.at(1, 0), means.at(1, 1), means.at(1, 2));
Проверив данные, выведенные на консоль, вычисленное среднее значение для каждого класса наиболее близко к выборочному среднему противоположного класса.
Вот визуализация выборочных данных и обученной модели, показывающая замененную классификацию. Красный — класс 0, синий — класс 1, а получение ковариации содержит ошибки, поэтому контуры представляют собой круги, а не эллипсы:
Есть ли способ гарантировать, что каждый гауссиан в конечном итоге оптимизируется на тех образцах, которыми он был создано, или существует ли другой стандартный метод для определения того, какая метка класса принадлежит каждому гауссову?
Я использую OpenCV 3.1.0, чтобы подогнать модель гауссовой смеси к данным двух классов с использованием EM. Выборки помечены, поэтому я предоставляю средние значения класса и ковариации во время обучения с помощью EM::trainE. Когда я проверяю предсказанные метки, они кажутся хорошо соответствующими данным, но противоположными (выборки из класса 1 почти всегда прогнозируются как находящиеся в классе 0 и наоборот). Вот как обучается модель:
[code]// Run EM Mat predicted_labels(samples.rows, 1, CV_64F); Mat means0(EM_CLASS_COUNT, SAMPLE_DIMENSIONS, CV_64F); const int sizes[]{ EM_CLASS_COUNT, SAMPLE_DIMENSIONS, SAMPLE_DIMENSIONS }; Mat covar0(3, sizes, CV_64F); for (int i = 0; i < EM_CLASS_COUNT; ++i) { calcCovarMatrix(class_samples[i], Mat(SAMPLE_DIMENSIONS, SAMPLE_DIMENSIONS, samples.type(), covar0.row(i).data), means0.row(i), COVAR_NORMAL | COVAR_ROWS); } Ptr model = EM::create(); model->setClustersNumber(EM_CLASS_COUNT); model->trainE(samples, means0, covar0, noArray(), noArray(), predicted_labels);
Проверив данные, выведенные на консоль, вычисленное среднее значение для каждого класса наиболее близко к выборочному среднему противоположного класса.
Вот визуализация выборочных данных и обученной модели, показывающая замененную классификацию. Красный — класс 0, синий — класс 1, а получение ковариации содержит ошибки, поэтому контуры представляют собой круги, а не эллипсы:
[img]https://i.sstatic.net/wfHeQ.png[/img]
Есть ли способ гарантировать, что каждый гауссиан в конечном итоге оптимизируется на тех образцах, которыми он был создано, или существует ли другой стандартный метод для определения того, какая метка класса принадлежит каждому гауссову?