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

нейронная сеть

Recommended Posts

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

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

CvANN_MLP nnetwork;

nnetwork.create( число слоёв, CvANN_MLP::SIGMOID_SYM, какие то параметры, какие то параметры);

непонятное - число слоев. это должна быть cv::Mat, а если так, то как задать число скрытых слоев и размерность каждого по отдельности.

и какой длины ширины должен быть первый ( входной ) слой. как у одной картинки( если я собираюсь отличать одну картинку от другой ) или надо как для PCA формировать одну большую картинку.

число внутренних слоев и их размер, я так понимаю, выбирается эмпирически, а размеры выходного слоя - эти число возможных ответов сети.

если что - то неправильно, буду рад если поправите.

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


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

В примере opencv\samples\cpp\points_classifier.cpp

есть классификатор на основе нейронной сети.

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


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

а какая есть информация по выбору архитектуры нейронной сети?

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


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

Неплохой документ есть у neurosolutions:

http://www.neurosolutions.com/docs/NeuroSolutions.pdf

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


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

спасибо за ссылки). а с архитектурой пока решил так - ширина картинки * длину картинки это число входных нейронов. число внутренних слоев и число нейронов в них - загадка. выходной - пока думаю либо один либо почислу классов.

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

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


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

Выходы по числу классов, и посмотрите еще в сторону

http://en.wikipedia.org/wiki/Softmax_activation_function

тут еще статья соратника по курсу нейросетей coursera (с реализацией на шарпе):

http://habrahabr.ru/post/155235/

Ну и классики :) : http://yann.lecun.com/

здесь его работы: http://yann.lecun.com/exdb/publis/index.html#lecun-98

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


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

спасибо что отвечаете) пока делал так, применительно к задаче распознавания лиц

std::vector< std::vector < cv::Mat > > peoples - вектор людей, в котором хранятся векторы фоток каждого человека.

так же предполагается, что число фотографий каждого человека фиксированно

void NeuralNetwork::trainNeuralNetwork( std::vector< std::vector < cv::Mat > > peoples, Settings mysettings )  

{      

int widthFace = mysettings.faceWidth;

int heightFace = mysettings.faceHeight;

int countPeople = peoples.size();


cv::Mat layerSizes( 1, 3, CV_32SC1 );

layerSizes.at<int>(0,0)= widthFace * heightFace; 

layerSizes.at<int>(0,1)= 500;

layerSizes.at<int>(0,2)= countPeople; 


this->myMLP.create( layerSizes, CvANN_MLP::SIGMOID_SYM, 0.6, 1);


std::vector< cv::Mat > datafaces;


      for( unsigned int i = 0; i < peoples.size(); i++ ) {

          cv::Mat dataface( peoples[i].size(), widthFace * heightFace, CV_32FC1 );

          for( unsigned int j = 0; j < peoples[i].size(); j++ ) {

              cv::Mat trainSample = peoples[i][j].reshape( 1, 1 );

              cv::Mat row = dataface.row(j);

              trainSample.copyTo( row );

          }

          datafaces.push_back( dataface );

      }


      cv::Mat bigMat( datafaces[0].rows * datafaces.size(), widthFace*heightFace, CV_32FC1 );

      cv::Mat bigMatOutputs( datafaces[0].rows * datafaces.size(), countPeople, CV_32FC1, cv::Scalar(0) );

      int countPicture = 0;

      int counterBigMatRows = 0;


      while( countPicture < countPeople ) {

          for( int i = 0; i < datafaces[countPicture].rows; i++ ) {

              cv::Mat tempRow = datafaces[ countPicture ].row(i);

              cv::Mat tempBigMatRow = bigMat.row( counterBigMatRows );

              tempRow.copyTo( tempBigMatRow );

              counterBigMatRows++;

              bigMatOutputs.at<float>( counterBigMatRows, countPicture ) = 1;

          }

          countPicture++;

      } 

      cv::Mat weigth( 1, counterBigMatRows , CV_32FC1, cv::Scalar::all(0.3) );

      int train = this->myMLP.train( bigMat, bigMatOutputs, weigth );

      std::cout<< "Train - " << train << std::endl;

}  

И сразу вопрос возникает надо ли исходные картинки преобразовывать во float вручную? то есть брать значение каждого пикселя каждой картинки, делить на 255 и пихать обратно? а то приходят они в функцию как unsigned char.

а так же какая примерно стуктура подойдет(скрытые слои и нейроны в них), если я собираюсь сравнивать лица.

хотя бы порядок чисел)

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


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

И как результат?

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


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

с такими параметрами херово) как что нибудь дельное получется напишу)

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


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

можете попробовать протестировать на MNIST (я могу попозже выложить результаты для нейросети на матлабе)

www.compvision.ru/forum/index.php?showtopic=852 (тут как считать и про кластеризацию заодно PCA и kmeans)

+ еще цифры можно исказить рэндомно например аффинными или перспективными преобразованиями и получить в несколько раз большую тестовую выборку.

И сразу вопрос возникает надо ли исходные картинки преобразовывать во float вручную? то есть брать значение каждого пикселя каждой картинки, делить на 255 и пихать обратно? а то приходят они в функцию как unsigned char.

можно через convert.

A base rule is to start small, and observe the behavior of the learning curve. If the final training error is small, the number of PEs is probably appropriate. If the final error is large, either the learning was caught in a local minima (See Network Training) or the network does not have enough degrees of freedom to solve the problem, so you should increase the number of PEs.

Neural network researchers have shown that an excessive number of weights is the culprit for poor generalization. If the network performance drops dramatically from the training set to the test set one of two things has happened: either your training set is not representative of the problem domain, or you have configured your network with too many weights. You can still train a large network appropriately, but you will need a lot of training patterns. A good rule of thumb is that the number of weights should be equal to the number of training patterns multiplied by the precision required for the classification (in percentage), i.e.

where N is the number of patterns, W the number of weights and ε the classification error that you desire. For instance for a 5% classification error a network with 1000 weights requires 20,000 patterns.

и еще

This illustrates an inherent problem with the MLP. The network needs a lot of PEs to classify complex patterns, but these PEs will have many weights that require lots of training data to generalize. The way out is to use data reduction techniques or special topologies (such as principal component analysis, or self-organizing maps). This reduces the number of inputs to the network (normally the largest layer). Another method is to use alternative topologies to the multilayer perceptron that use less weights per PE (such as the radial basis function networks), or to use modular MLP designs that decrease the number of weights per PE because their topologies are not fully connected.

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


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

похоже еще читать и читать) Кстати, я так понимаю возможности применения этой нейронной сети ограничиваются задачей классификации из закрытой базы?

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

то есть если будем иметь нейронку с двумя выходами ( квадрат и круг ), хорошо ей натренируем, а потом подадим неизвестную нейронке фигуру. По идее будет ошибка.

И что бы ее небыло надо добавить еще один выход - "остальные фигуры" и натренировать всевозможными и невозможными изображениями произвольных фигур? а возможных фигур бесконечное множетсво, а невозможных фигур - еще больше... Я надеюсь все правильно понимаю)

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


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

не знаю будет ли работать.

но по идее можно сделать 2 бинарных классификатора круг-не круг и квадрат-не квадрат и применять их последовательно.

возможных фигур бесконечное множетсво, а невозможных фигур - еще больше

интересно что вы под этим подразумеваете.

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


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

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

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


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

mrgloom >еще цифры можно исказить рэндомно

И нейросеть тоже можно исказить рэндомно ;) См. препринт "Improving neural networks by preventing co-adaptation of feature detectors " Джеффри Хинтона сотоварищи.

Правда, не знаю - насколько сильные ручные переделки библиотечного (OpenCV) нейросетевого кода для этого могут потребоваться.

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×