Опубликован: 20.08.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Новосибирский Государственный Университет
Самостоятельная работа 3:

Машинное обучение

Приведем пример использования класса CvDTree для решения задачи бинарной классификации аналогичной, решаемой в примере для CvSVM.

#include <stdlib.h> 
#include <stdio.h> 
#include <opencv2/core/core.hpp> 
#include <opencv2/ml/ml.hpp> 
 
using namespace cv; 
 
// размерность пространства признаков 
const int d = 2; 
 
// функция истинной зависимости целевого признака 
// от остальных 
int f(Mat sample) 
{ 
  return (int)((sample.at<float>(0) < 0.5f && 
      sample.at<float>(1) < 0.5f) || 
      (sample.at<float>(0) > 0.5f && 
      sample.at<float>(1) > 0.5f)); 
} 
 
int main(int argc, char* argv[]) 
{ 
  // объем генерируемой выборки 
  int n = 2000; 
  // объем обучающей части выборки 
  int n1 = 1000; 
 
  // матрица признаковых описаний объектов 
  Mat samples(n, d, CV_32F); 
  // номера классов (матрица значений целевой переменной) 
  Mat labels(n, 1, CV_32S); 
  // генерируем случайным образом точки 
  // в пространстве признаков 
  randu(samples, 0.0f, 1.0f); 
 
  // вычисляем истинные значения целевой переменной 
  for (int i = 0; i < n; ++i) 
  { 
    labels.at<int>(i) = f(samples.row(i)); 
  } 
 
  // создаем маску прецедентов, которые будут 
  // использоваться для обучения: используем n1 
  // первых прецедентов 
  Mat trainSampleMask(1, n1, CV_32S); 
  for (int i = 0; i < n1; ++i) 
  { 
    trainSampleMask.at<int>(i) = i; 
  } 
 
  // будем обучать дерево решений высоты не больше 10, 
  // после построения которого выполним отсечения 
  // с помощью пятикратного перекресного контроля 
  CvDTreeParams params; 
  params.max_depth = 10; 
  params.min_sample_count = 1; 
  params.cv_folds = 5; 
 
  CvDTree dtree; 
  Mat varIdx(1, d, CV_8U, Scalar(1)); 
  Mat varTypes(1, d + 1, CV_8U, Scalar(CV_VAR_ORDERED)); 
  varTypes.at<uchar>(d) = CV_VAR_CATEGORICAL; 
  dtree.train(samples, CV_ROW_SAMPLE, 
      labels, varIdx, 
      trainSampleMask, varTypes, 
      Mat(), params); 
  dtree.save("model-dtree.yml", "simpleDTreeModel"); 
 
  // вычисляем ошибку на обучающей выборке 
  float trainError = 0.0f; 
  for (int i = 0; i < n1; ++i) 
  { 
    int prediction = 
      (int)(dtree.predict(samples.row(i))->value); 
    trainError += (labels.at<int>(i) != prediction); 
  } 
  trainError /= float(n1); 
 
  // вычисляем ошибку на тестовой выборке 
  float testError = 0.0f; 
  for (int i = 0; i < n - n1; ++i) 
  { 
    int prediction = 
      (int)(dtree.predict(samples.row(n1 + i))->value); 
    testError += 
      (labels.at<int>(n1 + i) != prediction); 
  } 
  testError /= float(n - n1); 
 
  printf("train error = %.4f\ntest error = %.4f\n", 
    trainError, testError); 
 
  return 0; 
}   
    

Иллюстрацией разбиения пространства признаков обученным с помощью данного кода деревом решений служит рис. 8.2.

Точки обучающей выборки и разбиение пространства признаков деревом решений

Рис. 8.2. Точки обучающей выборки и разбиение пространства признаков деревом решений
Александра Максимова
Александра Максимова

При прохождении теста 1 в нем оказались вопросы, который во-первых в 1 лекции не рассматривались, во-вторых, оказалось, что вопрос был рассмаотрен в самостоятельно работе №2. Это значит, что их нужно выполнить перед прохождением теста? или это ошибка?
 

Алена Борисова
Алена Борисова

В лекции по обработке полутоновых изображений (http://www.intuit.ru/studies/courses/10621/1105/lecture/17979?page=2) увидела следующий фильтр:


    \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 2 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array} - \frac{1}{9} \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 1 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array}

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

Что вижу я в конструкции фильтра (скорее всего ошибочно): F(x, y) = 2 * I(x, y) - 1/9 I(x, y) = 17/9 * I(x, y), где F(x, y) - яркость отфильтрованного пикселя, а I(x, y) - яркость исходного пикселя с координатами (x, y). Что означает обычное повышение яркости изображения, при этом без учета соседних пикселей (так как их множители равны 0).

Объясните, пожалуйста, как данный фильтр может повышать четкость изображения?

Сергей Кротов
Сергей Кротов
Россия
Дмитрий Донсков
Дмитрий Донсков
Россия, Москва, Московский Авиационный Институт