Модераторы: Rickert
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обучение нейронной сети opencv, повышение точности 
:(
    Опции темы
RobinHoodPHD
Дата 3.1.2012, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 12.8.2007
Где: Русь

Репутация: нет
Всего: 2



Доброго времени суток, Господа.

Меня заинтересовала тема нейронных сетей и я решил почитать литературу по этой теме и поэкспериментировать. Для экспериментов выбрал библиотеку opencv и нашел тестовый пример, в котором на вход сети подается два числа (a,b) в диапазоне [0..100] а на выходе получаем середину отрезка (a+b)/2

Итак, диспозиция:
opencv 2.3.1 
IDE - Visual Studio 2010
тип нейронной сети - многослойный перцептрон, два нейрона во входном слое, два скрытых слоя и один нейрон на выходном слое.
метод обучения - метод обратного распространения ошибки

Я написал небольшое консольное приложение (код в конце поста), генерирующее обучающую выборку заданного размера (функция generateTrainData) и далее заданное количество итераций (эпох) обучающее нейронную сеть на этой выборке. После каждого обучения (эпохи) я считаю суммарную ошибку сети - как сумму ошибок в 10 точках (массив quality_array), деленную на количество этих точек. Если Вы посмотрите на лог-файл, который генерирует программа, то увидите, что точность после каждой эпохи может улучшится, а может и ухудшится (строки Train quality ). Например первые две эпохи точность вроде бы улучшалась: была 0.509696, потом стала 0.467227, а потом снова ухудшилась 0.643969.

Вопрос: в чем причина того, что ошибка не уменьшается монотонно, как я предполагал? 

Для увеличения точности, я варьировал параметрами самой сети и обучения - увеличил число нейронов в скрытом слое ажно до 100 !!! Увеличивал точность и число итераций при обучении (константы Epsilon и MaxIter). Увеличивал число эпох обучения и размер выборки - но все тщетно: точность не увеличивалась от эпохи к эпохе и ошибка не достигала 3 знака после запятой.

Вопрос: что можно предпринять для увеличения точности? 

Лог-файл:
Код

Train quality 0.509696
Train quality 0.467227
Train quality 0.643969
Train quality 0.986835
Train quality 0.718875
Train quality 0.781358
Train quality 0.826931
Train quality 0.855752
Train quality 0.617246
Train quality 0.778907

Predict input    1.000000            8.000000            Result    4.738886            Error            0.238886
Predict input    2.000000            14.000000    Result    8.184313            Error            0.184313
Predict input    30.000000    40.000000    Result    35.144043    Error    0.144043
Predict input    50.000000    54.000000    Result    51.961819    Error    0.038181

Time elapsed 119 sec
 
Код программы
Код

#include "stdafx.h"
#include "cv.h"
#include "ml.h"
#include <cstdlib> 
#include <iostream> 
#include <stdlib.h>
#include <math.h>

// The neural network
CvANN_MLP machineBrain;
using namespace std;

float td[100000][3];

#define train_sample_count 2000
#define MaxIter 1000000
#define Epsilon 0.0000001
#define Param1 0.1
#define Param2 0.5
#define Epoch 10
#define Range 100

#define quality_test 10
float quality_array[quality_test][2] = {{1,8},    {12,20}, {18,28}, {30,36}, {42,49}
    ,    {50,54},{54,60}, {1,80}, {90,30}, {80,90}};

float round_2 (float val) {
     return floorf(val * 100) / 100;
}

void generateTrainData (float parts, float over, FILE * ftrain) {
    int j = 0;
    for (float p = 0; p < 1.0; p+=parts) {
        for (int i=0;i<train_sample_count*parts;i++,j++)
        {
            td[j][0] = int((rand()/float(RAND_MAX))*(((int)(Range*(parts+over))) + 0.001) + Range*p + 1); //(rand()%((int)(Range*(parts+over)))) + Range*p + 1;
            td[j][1] = int((rand()/float(RAND_MAX))*(((int)(Range*(parts+over))) + 0.001) + Range*p + 1); //(rand()%((int)(Range*(parts+over)))) + Range*p + 1;
            td[j][2] = round_2((td[j][0] + td[j][1]) / 2.0);
            fprintf(ftrain,"%f\t%f\t%f\n",td[j][0],td[j][1],td[j][2]);
        }        
    }
}

void trainMachine(FILE * flog)
{
   int i;

   printf("Found training file with %d samples...\n", train_sample_count);
  
   //Input data samples. Matrix of order (train_sample_count x 2)
   CvMat* trainData = cvCreateMat(train_sample_count, 2, CV_32FC1);

   //Output data samples. Matrix of order (train_sample_count x 1)
   CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1);

   //The weight of each training data sample. We'll later set all to equal weights.
   CvMat* sampleWts = cvCreateMat(train_sample_count, 1, CV_32FC1);

   CvMat trainData1, trainClasses1, sampleWts1;

   cvGetRows(trainData, &trainData1, 0, train_sample_count);
   cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count);
   cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count);
   cvGetRows(sampleWts, &sampleWts1, 0, train_sample_count);

   //Assemble the ML training data.
   for (i=0; i<train_sample_count; i++)
   {
       //Input 1
       cvSetReal2D(&trainData1, i, 0, td[i][0]);
       //Input 2
       cvSetReal2D(&trainData1, i, 1, td[i][1]);
       //Output
       cvSet1D(&trainClasses1, i, cvScalar(td[i][2]));
       //Weight (setting everything to 1)
       cvSet1D(&sampleWts1, i, cvScalar(1));
   }
   
   //Train it with our data.
   //See the Machine learning reference at http://www.seas.upenn.edu/~bensapp/opencvdocs/ref/opencvref_ml.htm#ch_ann
   machineBrain.train(
       trainData,
       trainClasses,
       sampleWts,
       0,
       CvANN_MLP_TrainParams(
           cvTermCriteria(
               CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
               MaxIter,
               //! 1.0
               Epsilon
               ),
           CvANN_MLP_TrainParams::BACKPROP,
           //!0.01,
           Param1,
           //!0.05
           Param2
           )
       );

   fprintf(flog,"Settings:\ntrain_sample_count %d MaxIter %d Epsilon %f Param1 %f Param2 %f\n",train_sample_count,MaxIter,Epsilon,Param1,Param2);

}

void createMachine() {
    //The matrix representation of our ANN. We'll have four layers.
    CvMat* neuralLayers = cvCreateMat(4, 1, CV_32SC1);

    CvMat neuralLayers1;
    cvGetRows(neuralLayers, &neuralLayers1, 0, 4);

    cvSet1D(&neuralLayers1, 0, cvScalar(2));
    cvSet1D(&neuralLayers1, 1, cvScalar(100));
    cvSet1D(&neuralLayers1, 2, cvScalar(100));
    cvSet1D(&neuralLayers1, 3, cvScalar(1));
    //Create our ANN.
    machineBrain.create(neuralLayers);

}

// Predict the output with the trained ANN given the two inputs.
float Predict(float data1, float data2,FILE * flog)
{
   float _sample[2];
   CvMat sample = cvMat(1, 2, CV_32FC1, _sample);
   float _predout[1];
   CvMat predout = cvMat(1, 1, CV_32FC1, _predout);
   sample.data.fl[0] = data1;
   sample.data.fl[1] = data2;

   machineBrain.predict(&sample, &predout);

   if (flog != NULL) {
        fprintf(flog,"Predict input\t%f\t%f\tResult\t%f\tError\t%f\n",data1,data2,predout.data.fl[0],abs(abs((data2+data1)/2.0)-abs(predout.data.fl[0])));
   }
   return predout.data.fl[0];
}

float train_quality (FILE * flog) {
    float a,b,summary_error;
    summary_error=0;
    for (int i = 0 ; i < quality_test; i++) {
            a = quality_array[i][0];//int((rand()/float(RAND_MAX))*((int)(Range + 0.001))) + 1; //(rand()%((int)(Range*(parts+over)))) + Range*p + 1;
            b = quality_array[i][1];//int((rand()/float(RAND_MAX))*((int)(Range + 0.001))) + 1; //(rand()%((int)(Range*(parts+over)))) + Range*p + 1;
            summary_error += abs(abs((a + b) / 2.0)-abs(Predict(a,b,NULL)));
    }
    fprintf(flog,"%f\t%f\t%f\tPredict (a,b) %f\tTrain quality %f\n",a,b,summary_error,Predict(a,b,NULL),summary_error/quality_test );
    return summary_error/quality_test;
}

int _tmain(int argc, _TCHAR* argv[])
{
      time_t seconds;

  seconds = time (NULL);
FILE * flog;
FILE * ftrain;
   ftrain= fopen("C:\\train_data.txt", "a+");
   fprintf(ftrain,"\nNext training set:\n");

   flog = fopen("C:\\train_log.txt", "a+");

  time_t rawtime;
  struct tm * timeinfo;
  float quality=10000;
  time ( &rawtime );
  timeinfo = localtime ( &rawtime );

   fprintf(flog,"\nPredict transaction, date %s \n",asctime (timeinfo) );

    srand((unsigned)time(0));
   int wait;


   createMachine();
   generateTrainData (0.1,0.05,ftrain);
   // Train the neural network  with the samples
   for (int i = 0; i < Epoch; i++) {
        trainMachine(flog);
        quality = train_quality(flog);
   }
   
   machineBrain.save("C:\\savednet.txt");
   //machineBrain.load("C:\\savednet.txt");

   Predict(1.0,8.0,flog);
   Predict(2.0,14.0,flog);
   Predict(30.0,40.0,flog);
   Predict(50.0,54.0,flog);
   Predict(50.0,54.0,flog);

   seconds = time (NULL) - seconds;

   fprintf(flog,"\nTime elapsed %ld sec",seconds );
   fflush(flog);
   fclose(flog);
   //I'll wait for an integer. :)
   scanf("%d",&wait);
   fclose(ftrain);
   return 0;
}



Заранее благодарен за Ваши ответы!
PM MAIL   Вверх
Mirkes
Дата 24.1.2012, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: нет
Всего: 17



С писанным Вами пакетом не знаком.
Вероятно используется метод позадачного обучения, а не пакетный метод.
Для позадачного обучения характерно не монотонное поведение ошибки.
Этот эффект хорошо известен.

Почему не учится сеть в Вашем случае - скорее всего Вы перебрали с числом нейронов и числом скрытых слоев.
Если вы сделаете один (а лучше ноль) скрытый слой и оставите в нем 1-2 нейрона, то дело должно стать получше.

Мои рекомендации основаны не на теоремах, а на большом опыте обучения нейронных сетей решению различных задач. 
Попробуйте.



--------------------
Mirkes
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.1102 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.