|
From: Herton R. K. <he...@us...> - 2005-07-03 00:31:53
|
Update of /cvsroot/kimageprocess/kimageprocess/src/plugins/fann In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17042/fann Modified Files: fann.cpp fann.h Log Message: - Adapted fann plugin to the new plugin structure. Also added more variables to plugin class that handle more parameters of the fann network. - Misc cosmetics and cleanups at snns and fann plugins. Index: fann.h =================================================================== RCS file: /cvsroot/kimageprocess/kimageprocess/src/plugins/fann/fann.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- fann.h 23 Jun 2005 18:30:06 -0000 1.4 +++ fann.h 3 Jul 2005 00:31:40 -0000 1.5 @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2004-2005 by * + * Copyright (C) 2004-2005 by * * Gustavo Pichorim Boiko <gus...@kd...> * * Herton Ronaldo Krzesinski <he...@my...> * * * @@ -27,20 +27,9 @@ #include <qvaluelist.h> -#include <kurl.h> - -class KAction; -class KTImage; -class QImage; - -typedef struct -{ - float *inputs; - int sampleClass; -} pattern; - /** A Fast Artificial Neural Network plugin + @author Gustavo Pichorim Boiko */ class KTFANNPlugin : public KTClassifBackend @@ -53,47 +42,23 @@ void setupPlugin(); - int iterations() { return m_iterations; } - void setIterations(int value) { m_iterations = value; } - - int hiddenLayers() { return m_hiddenLayers; } - void setHiddenLayers(int value) { m_hiddenLayers = value; } - // Reimplemented from KTClassifBackends - void parseResults(const QValueList<float> &results); - - void parseSampleResults(const QValueList<float> &results, int sampleClass); + void doTraining(const QValueList<dataEntry>& data, int inputs, int outputs); + void doClassify(const QValueList<dataEntry>& data, int inputs, int outputs); private: - KAction *m_trainNetwork; - KAction *m_classifyImage; - struct fann *m_network; - int m_input; - int m_output; + int m_hiddenLayers; float m_connectionRate; float m_learningRate; - - QImage *m_img; - int m_width; - int m_height; - int m_colorStep; - - int m_x; - int m_y; - + int m_activationFunctionHidden; + int m_activationFunctionOutput; + float m_steepnessHidden; + float m_steepnessOutput; int m_iterations; - int m_hiddenLayers; - - double m_error; - - QValueList<pattern> m_patterns; - -private slots: - void slotTrainNetwork(); - // for now assume we are using one test image for each project. - // TODO: Fix that (will require API change) - void slotClassifyImage(); + float m_desiredError; }; #endif + +// vim:et Index: fann.cpp =================================================================== RCS file: /cvsroot/kimageprocess/kimageprocess/src/plugins/fann/fann.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- fann.cpp 23 Jun 2005 18:30:06 -0000 1.5 +++ fann.cpp 3 Jul 2005 00:31:40 -0000 1.6 @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2004-2005 by * + * Copyright (C) 2004-2005 by * * Gustavo Pichorim Boiko <gus...@kd...> * * Herton Ronaldo Krzesinski <he...@my...> * * * @@ -21,17 +21,12 @@ #include "fann.h" #include <kgenericfactory.h> -#include <kaction.h> -#include <kdebug.h> #include <kio/netaccess.h> #include <kfiledialog.h> #include <ktempfile.h> -#include <qfile.h> - #include <ktimage.h> #include <ktpluginmanager.h> -#include <ktpatternmanager.h> K_EXPORT_COMPONENT_FACTORY( kimageprocess_fann, KGenericFactory<KTFANNPlugin>( "kimageprocess_fann" ) ) @@ -39,24 +34,17 @@ KTFANNPlugin::KTFANNPlugin(QObject *parent, const char* name, const QStringList&) : KTClassifBackend(parent, name) { - m_trainNetwork = new KAction(i18n("Train &Network"), 0, - this, SLOT(slotTrainNetwork()), - actionCollection(), "fann_train_network"); - - m_classifyImage = new KAction(i18n("Classify &Image"), 0, - this, SLOT(slotClassifyImage()), - actionCollection(), "fann_classify_image"); - - setInstance(KGenericFactory<KTFANNPlugin>::instance()); - setXMLFile("kimageprocess_fann.rc"); - m_network = 0; m_img = 0; - m_iterations = 100000; + m_iterations = 300000; m_hiddenLayers = 1; - m_connectionRate = 1.0; m_learningRate = 0.7; + m_activationFunctionHidden = FANN_SIGMOID_SYMMETRIC; + m_activationFunctionOutput = FANN_SIGMOID_SYMMETRIC; + m_steepnessHidden = 1.0; + m_steepnessOutput = 1.0; + m_desiredError = 0.001; } KTFANNPlugin::~KTFANNPlugin() @@ -65,114 +53,103 @@ fann_destroy(m_network); } -void KTFANNPlugin::slotTrainNetwork() +void KTFANNPlugin::doTraining(const QValueList<dataEntry>& data, int inputs, int outputs) { if (m_network) fann_destroy(m_network); - m_input = KTImageManager::self()->activeFeaturesCount(); - m_output = KTImageManager::self()->sampleCount(); - //create the network - m_network = fann_create(m_connectionRate, m_learningRate, 3, m_input, m_input, m_output); - fann_set_activation_steepness_hidden(m_network, 1.0); - fann_set_activation_steepness_output(m_network, 1.0); - fann_set_activation_function_hidden(m_network, FANN_SIGMOID_SYMMETRIC_STEPWISE); - fann_set_activation_function_output(m_network, FANN_SIGMOID_SYMMETRIC_STEPWISE); - m_error = 0.0; - - //start training - KTImageManager::self()->calculateSampleData(0, this); + unsigned int neurons[m_hiddenLayers + 2]; + neurons[0] = inputs + for ( int i=1; i < m_hiddenLayers; ++i ) { + neurons[i] = inputs; + } + neurons[m_hiddenLayers + 1] = outputs; + m_network = fann_create_array(m_connectionRate, m_learningRate, m_hiddenLayers + 2, neurons); + fann_set_activation_steepness_hidden(m_network, m_steepnessHidden); + fann_set_activation_steepness_output(m_network, m_steepnessOutput); + fann_set_activation_function_hidden(m_network, m_activationFunctionHidden); + fann_set_activation_function_output(m_network, m_activationFunctionOutput); - struct fann_train_data tfanndata; - float *tempf_outputs; - int i, j; - QValueList<pattern>::size_type c_patcount; + struct fann_train_data fanndata; + float *out; + float error = 0.0; - c_patcount = m_patterns.count(); - tempf_outputs = new float[c_patcount * m_output]; - tfanndata.num_data = c_patcount; - tfanndata.num_input = m_input; - tfanndata.num_output = m_output; - tfanndata.input = new float*[c_patcount]; - tfanndata.output = new float*[c_patcount]; - for (i = 0; i < c_patcount; i++) + out = new float[data.count() * outputs]; + fanndata.num_data = data.count(); + fanndata.num_input = inputs; + fanndata.num_output = outputs; + fanndata.input = new float*[data.count()]; + fanndata.output = new float*[data.count()]; + for ( int i=0; i < data.count(); ++i ) { - tfanndata.output[i] = tempf_outputs + i * m_output; - for (j = 0; j < m_output; j++) + fanndata.output[i] = out + i * outputs; + for ( int j=0; j < m_output; ++j ) { - tfanndata.output[i][j] = 0; + fanndata.output[i][j] = 0; } } - j = 0; - QValueList<pattern>::iterator end = m_patterns.end(); - for (QValueList<pattern>::iterator it = m_patterns.begin(); it != end; ++it) - { - tfanndata.output[j][(*it).sampleClass-1] = 1; - tfanndata.input[j] = (*it).inputs; - j++; - } - fann_init_weights(m_network, &tfanndata); - fann_train_on_data(m_network, &tfanndata, m_iterations, m_iterations / 100, 0.001); - m_error = fann_get_MSE(m_network); - /*int print_debug = 0; - QValueList<pattern>::iterator end = m_patterns.end(); - for (i = 0; i < m_iterations; ++i) + QValueList<dataEntry>::ConstIterator end = data.constEnd(); + + for ( QValueList<dataEntry>::ConstIterator it = data.constBegin(), int c=0; it != end; ++it, ++c ) { - for (QValueList<pattern>::iterator it = m_patterns.begin(); it != end; ++it) - { - outputs[(*it).sampleClass-1] = 1; - fann_train(m_network, (*it).inputs, outputs); - outputs[(*it).sampleClass-1] = 0; - } - print_debug++; - if (print_debug == 1000) - { - m_error = fann_get_MSE(m_network); - kdDebug() << "Network output average error:" << m_error << endl; - print_debug = 0; - } - }*/ + fanndata.inputs[c] = (*it).inputs; + fanndata.output[c][(*it).sampleClass-1] = 1; + } + fann_init_weights(m_network, &fanndata); + fann_train_on_data(m_network, &fanndata, m_iterations, m_iterations / 100, m_desiredError); //clear data - end = m_patterns.end(); - for (QValueList<pattern>::iterator it = m_patterns.begin(); it != end; ++it) - delete (*it).inputs; - delete tfanndata.input; - delete tempf_outputs; - delete tfanndata.output; - m_patterns.clear(); + delete out; + delete fanndata.input; + delete fanndata.output; } -void KTFANNPlugin::slotClassifyImage() +void KTFANNPlugin::doClassify(const QValueList<dataEntry>& data, int inputs, int outputs) { if (!m_network) return; - KTImage *img = KTImageManager::self()->testingImage(); - - m_width = img->width(); - m_height = img->height(); - m_x = m_y = 0; + KTImage *c_img = KTImageManager::self()->testingImage(); + QImage *img = new QImage(c_img->width(), c_img->height(), 32); + float *outputs; + QValueList<dataEntry>::ConstIterator end = data.constEnd(); + int x = 0, y = 0; + int colorStep = 255 / (outputs - 1); + int level; - if (m_img) - delete m_img; - m_img = new QImage(m_width,m_height,32); - m_colorStep = 255/(m_output-1); - kdDebug() << "Color step is: " << m_colorStep << endl; - m_patterns.clear(); - KTImageManager::self()->calculateTestData(0, this); + for ( QValueList<dataEntry>::ConstIterator it = data.constBegin(), int i=0; it != end; ++it, ++i ) + { + outputs = fann_run(m_network, (*it).inputs); + int maxclass = 0; + int maxvalue = outputs[0]; + for ( int j=1; j < outputs; ++j ) + { + if (outputs[j] > maxvalue) + { + maxclass = j; + maxvalue = outputs[j]; + } + } + level = maxclass * colorStep; + img->setPixel(x++, y, qRgb(level, level, level)); + if (x >= c_img->width()) + { + x = 0; + y++; + } + } //save the image KURL dest = KFileDialog::getSaveURL(QString::null,i18n("*.pgm|PGM File"),0,i18n("Save classified image")); if (!dest.isEmpty()) { - KTempFile tmpImg(QString::null,".pgm"); + KTempFile tmpImg(QString::null, ".pgm"); tmpImg.close(); - m_img->save(tmpImg.name(),"PGM"); - KIO::NetAccess::upload(tmpImg.name(),dest,0); + m_img->save(tmpImg.name(), "PGM"); + KIO::NetAccess::upload(tmpImg.name(), dest, 0); KIO::NetAccess::removeTempFile(tmpImg.name()); } } @@ -182,61 +159,6 @@ //connect signals/slots here } -void KTFANNPlugin::parseResults(const QValueList<float> &results) -{ - float *inputs = new float[m_input]; - float *outputs; - - QValueList<float>::const_iterator it; - int i = 0; - kdDebug() << "------------------------" << endl; - //prepare the input - for ( it = results.begin(); it != results.end(); ++it) - { - kdDebug() << "inputs[" << i << "] = " << (*it) << endl; - inputs[i++] = (*it); - } - - outputs = fann_run(m_network, inputs); - - int maxclass = 0; - float maxvalue = 0; - for (i = 0; i < m_output; i++) - { - kdDebug() << "outputs[" << i << "] = " << outputs[i] << endl; - if (outputs[i] > maxvalue) - { - maxclass = i; - maxvalue = outputs[i]; - } - } - int level = maxclass * m_colorStep; - //kdDebug() << "Pixel x=" << m_x << " y=" << m_y << " is of class " << maxclass << " with value = " << maxvalue << endl; - m_img->setPixel(m_x++,m_y,qRgb(level,level,level)); - - if (m_x >= m_width) - { - m_x = 0; - m_y++; - } - -} - -void KTFANNPlugin::parseSampleResults(const QValueList<float> &results, int sampleClass) -{ - float *inputs = new float[m_input]; - - QValueList<float>::const_iterator it; - int i = 0; - - //prepare the input - for ( it = results.begin(); it != results.end(); ++it) - inputs[i++] = (*it); - - pattern pat; - pat.inputs = inputs; - pat.sampleClass = sampleClass; - m_patterns.append(pat); -} - #include "fann.moc" + +// vim:et |