00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "neuralnet.h"
00021 #include "learningalgorithm.h"
00022 #include "factory.h"
00023
00024 namespace farsa {
00025
00026 void Pattern::setInputsOf( Cluster* cl, const DoubleVector& ins ) {
00027 pinfo[cl].inputs.resize( cl->numNeurons() );
00028 pinfo[cl].inputs.copyValues( ins );
00029 };
00030
00031 void Pattern::setOutputsOf( Cluster* cl, const DoubleVector& ous ) {
00032 pinfo[cl].outputs.resize( cl->numNeurons() );
00033 pinfo[cl].outputs.copyValues( ous );
00034 };
00035
00036 void Pattern::setInputsOutputsOf( Cluster* cl, const DoubleVector& ins, const DoubleVector& ous ) {
00037 pinfo[cl].inputs.resize( cl->numNeurons() );
00038 pinfo[cl].inputs.copyValues( ins );
00039 pinfo[cl].outputs.resize( cl->numNeurons() );
00040 pinfo[cl].outputs.copyValues( ous );
00041 };
00042
00043 DoubleVector Pattern::inputsOf( Cluster* cl ) const {
00044 if ( pinfo.count(cl) != 0 ) {
00045 return pinfo[cl].inputs;
00046 } else {
00047 return DoubleVector();
00048 }
00049 };
00050
00051 DoubleVector Pattern::outputsOf( Cluster* cl ) const {
00052 if ( pinfo.count(cl) != 0 ) {
00053 return pinfo[cl].outputs;
00054 } else {
00055 return DoubleVector();
00056 }
00057 };
00058
00059 Pattern::PatternInfo& Pattern::operator[]( Cluster* cl ) {
00060 return pinfo[cl];
00061 };
00062
00063 void Pattern::configure(ConfigurationParameters& params, QString prefix) {
00064
00065 QStringList clusterList = params.getParametersWithPrefixList( prefix, "cluster:" );
00066 foreach( QString cluster, clusterList ) {
00067 QString id = cluster.split(':')[1];
00068 if ( id.isEmpty() ) continue;
00069
00070 QString str = params.getValue( prefix + "inputs:" + id );
00071 DoubleVector inputs;
00072 if (!str.isEmpty()) {
00073 QStringList list = str.split(QRegExp("\\s+"), QString::SkipEmptyParts);
00074 for( int i=0; i<list.size(); i++) {
00075 inputs.append( list[i].toDouble() );
00076 }
00077 }
00078 str = params.getValue( prefix + "outputs:" + id );
00079 DoubleVector outputs;
00080 if (!str.isEmpty()) {
00081 QStringList list = str.split(QRegExp("\\s+"), QString::SkipEmptyParts);
00082 for( int i=0; i<list.size(); i++) {
00083 outputs.append( list[i].toDouble() );
00084 }
00085 }
00086 if ( inputs.size() == 0 && outputs.size() == 0 ) continue;
00087 Cluster* cl = params.getObjectFromParameter<Cluster>( prefix+cluster, false, true );
00088 if ( inputs.size() > 0 ) {
00089 setInputsOf( cl, inputs );
00090 }
00091 if ( outputs.size() > 0 ) {
00092 setOutputsOf( cl, outputs );
00093 }
00094 }
00095 }
00096
00097 void Pattern::save(ConfigurationParameters& params, QString prefix) {
00098 params.startObjectParameters(prefix, "Pattern", this);
00099 QString tmpl = "%1:%2";
00100 QList<Cluster*> cls = pinfo.keys();
00101 for( int i=0; i<cls.size(); i++ ) {
00102 PatternInfo& info = pinfo[ cls[i] ];
00103 params.createParameter(prefix, tmpl.arg("cluster").arg(i), cls[i]);
00104 if ( info.inputs.size() > 0 ) {
00105 QStringList list;
00106 for( unsigned int j=0; j<info.inputs.size(); j++ ) {
00107 list.push_back(QString::number(info.inputs[j]));
00108 }
00109 params.createParameter(prefix, tmpl.arg("inputs").arg(i), list.join(" "));
00110 }
00111 if ( info.outputs.size() > 0 ) {
00112 QStringList list;
00113 for( unsigned int j=0; j<info.outputs.size(); j++ ) {
00114 list.push_back(QString::number(info.outputs[j]));
00115 }
00116 params.createParameter(prefix, tmpl.arg("outputs").arg(i), list.join(" "));
00117 }
00118 }
00119 }
00120
00121 void Pattern::describe( QString type ) {
00122 Descriptor d = addTypeDescription( type, "Represent a pattern of inputs/outputs for Clusters", "A Pattern is specified by groups of three parameters: cluster, inputs and outputs. The inputs and outputs parameters specify the values to set on the neurons of the cluster specified by the corresponding cluster parameter. The inputs and outputs parameter are not mandatory but specify a cluster without setting inputs or outputs has no effect" );
00123 d.describeObject( "cluster" ).type( "Cluster" ).props( IsMandatory | AllowMultiple ).help( "The Cluster on which the inputs and outputs parameters referes" );
00124 d.describeReal( "inputs" ).props( IsList | AllowMultiple ).help( "The values to set on the cluster's input neurons" );
00125 d.describeReal( "outputs" ).props( IsList | AllowMultiple ).help( "The values to set on the cluster's output neurons" );
00126 }
00127
00128 LearningAlgorithm::LearningAlgorithm( NeuralNet* net )
00129 : ParameterSettableWithConfigureFunction() {
00130 this->netp = net;
00131 }
00132
00133 LearningAlgorithm::LearningAlgorithm()
00134 : ParameterSettableWithConfigureFunction() {
00135 this->netp = NULL;
00136 }
00137
00138 LearningAlgorithm::~LearningAlgorithm() {
00139 }
00140
00141 PatternSet LearningAlgorithm::loadPatternSet( ConfigurationParameters& params, QString path, QString prefix ) {
00142 params.startRememberingGroupObjectAssociations();
00143
00144 PatternSet patternSet;
00145 foreach( QString group, params.getGroupsWithPrefixList(path, prefix) ) {
00146 patternSet << *(params.getObjectFromGroup<Pattern>( path + "/" + group ));
00147 }
00148 #ifdef __GNUC__
00149 #warning Se patternSet copia il Pattern creato all interno, allora quelli creati qui creano un leak perche non vengono mai distrutti !!
00150 #endif
00151 params.stopRememberingGroupObjectAssociations();
00152 return patternSet;
00153 }
00154
00155 void LearningAlgorithm::savePatternSet( PatternSet& set, ConfigurationParameters& params, QString prefix ) {
00156 QString tmpl = prefix+":%1";
00157 for( int i=0; i<set.size(); i++ ) {
00158 QString group = tmpl.arg(i);
00159 params.createGroup( group );
00160 set[i].save( params, group );
00161 }
00162 }
00163
00164 }