Пример #1
0
void main()
{
  NET  Net;
  BOOL Stop;
  REAL MinTestError;

  InitializeRandoms();
  GenerateNetwork(&Net);
  RandomWeights(&Net);
  InitializeApplication(&Net);

  Stop = FALSE;
  MinTestError = MAX_REAL;
  do {
    TrainNet(&Net, 10);
    TestNet(&Net);
    if (TestError < MinTestError) {
      fprintf(f, " - saving Weights ...");
      MinTestError = TestError;
      SaveWeights(&Net);
    }
    else if (TestError > 1.2 * MinTestError) {
      fprintf(f, " - stopping Training and restoring Weights ...");
      Stop = TRUE;
      RestoreWeights(&Net);
    }
  } while (NOT Stop);

  TestNet(&Net);
  EvaluateNet(&Net);
   
  FinalizeApplication(&Net);
}
Пример #2
0
void MultiLayerPerceptron::Run(const char* fname, const int& maxiter)
{
  int    countTrain = 0;
  int    countLines = 0;
  bool   Stop = false;
  bool   firstIter = true;
  double dMinTestError = 0.0;
  InitializeRandoms();
  RandomWeights();
  do {
    countLines += Train(fname);
    Test(fname);
    countTrain++;
    if(firstIter)
      {
	dMinTestError = dAvgTestError;
	firstIter = false;
      }
    printf( "%i \t TestError: %f", countTrain, dAvgTestError);
    if ( dAvgTestError < dMinTestError) 
      {
	printf(" -> saving weights\n");
	dMinTestError = dAvgTestError;
	SaveWeights();
      }
    else if (dAvgTestError > 1.2 * dMinTestError) 
      {
	printf(" -> stopping training and restoring weights\n");
	Stop = true;
	RestoreWeights();
      }
    else
      {
	printf(" -> ok\n");
      }
  } while ( (!Stop) && (countTrain<maxiter) );
  printf("bye\n");
}
// Write C code for corresponding to the feed forward network into a given file.
void MultipleBackPropagation::GenerateCCode(OutputFile & f, VariablesData & trainVariables, BOOL inputLayerIsConnectedWithOutputLayer, BOOL spaceInputLayerIsConnectedWithOutputLayer) {
	CString s;

	CString MBPVersion;
	MBPVersion.LoadString(IDS_VERSION);

	f.WriteLine("/**");
	f.WriteLine(_TEXT(" Generated by ") + MBPVersion);
	f.WriteLine(" Multiple Back-Propagation can be freely obtained at http://dit.ipg.pt/MBP");
	f.WriteLine("*/\n");

	f.WriteLine("#include <math.h>");
	
	f.WriteLine("/**");
	s.Format(_TEXT(" inputs  - should be an array of %d element(s), containing the network input(s)."), inputs);

	bool hasMissingValues = false;
	for(int i = 0; i < inputs; i++) {
		if (trainVariables.HasMissingValues(i)) {
			s += " Inputs with NaN value are considered missing values.";
			hasMissingValues = true;
			break;
		}
	}

	f.WriteLine(s);
		
	s.Format(_TEXT(" outputs - should be an array of %d element(s), that will contain the network output(s)."), outputs);
	f.WriteLine(s);
	s = " Note : The array inputs will also be changed.";
	if (!hasMissingValues) s += "Its values will be rescaled between -1 and 1.";
	s += "\n*/";
	f.WriteLine(s);

	s = f.GetFileName();
	int p = s.Find('.');
	if (p != -1) s = s.Left(p);
	f.WriteLine(_TEXT("void ") +  s + _TEXT("(double * inputs, double * outputs) {"));

	f.WriteString("\tdouble mainWeights[] = {");
	SaveWeights(f, ", ");
	f.WriteLine("};");
	f.WriteLine("\tdouble * mw = mainWeights;");
	if (hasMissingValues) f.WriteLine("\tdouble b;");

	if (!spaceNetwork.IsNull()) {
		f.WriteString("\tdouble spaceWeights[] = {");
		spaceNetwork->SaveWeights(f, ", ");
		f.WriteLine("};");
		f.WriteLine("\tdouble * sw = spaceWeights;");
		s.Format(_TEXT("\tdouble mk[%d];"), spaceNetwork->Outputs());
		f.WriteLine(s);
		f.WriteLine("\tdouble *m = mk;");
		
		if (hasMissingValues) {
			s.Format(L"\tdouble spaceInputs[%d];", inputs);
			f.WriteLine(s);
		}
	}

	int numberLayers = layers.Lenght();

	for (int l = 1; l < numberLayers - 1; l++) {
		s.Format(L"\tdouble hiddenLayer%doutputs[%d];", l, layers.Element(l)->neurons.Lenght());
		f.WriteLine(s);
	}

	int numberSpaceLayers = (spaceNetwork.IsNull()) ? 0 : spaceNetwork->layers.Lenght();

	for (int l = 1; l < numberSpaceLayers - 1; l++) {
		s.Format(_TEXT("\tdouble spaceHiddenLayer%doutputs[%d];"), l, spaceNetwork->layers.Element(l)->neurons.Lenght());
		f.WriteLine(s);
	}

	f.WriteLine("\tint c;");

	f.WriteString("\n");

	// input variables will be rescaled between -1 and 1
	if (trainVariables.Number() == inputs + outputs) {
		for (int i = 0; i < inputs; i++) { 
			double min = trainVariables.Minimum(i);
			double max = trainVariables.Maximum(i);

			if (trainVariables.HasMissingValues(i)) {
				s.Format(L"\tif(inputs[%d] == inputs[%d]) { /* compiler must have support for NaN numbers */\n\t", i, i);
				f.WriteString(s);
			}

			if (min != max) {
				s.Format(L"\tinputs[%d] = -1.0 + (inputs[%d] - %1.15f) / %1.15f;", i, i, min, (max - min)/2);				
			} else {
				s.Format(L"\tinputs[%d] = inputs[%d] / %1.15f; /* WARNING: During the training this variable remain always constant */", i, i, max);
			}
			f.WriteLine(s);

			if (hasMissingValues && !spaceNetwork.IsNull()) {
				if (trainVariables.HasMissingValues(i)) f.WriteString("\t");
				s.Format(L"\tspaceInputs[%d] = inputs[%d];", i, i);
				f.WriteLine(s);
			}

			if (trainVariables.HasMissingValues(i)) {
				if (!spaceNetwork.IsNull()) {
					f.WriteLine("\t\tb = *sw++;");
					s.Format(L"\t\tspaceInputs[%d] = tanh(b + spaceInputs[%d] * *sw++);", i, i);
					f.WriteLine(s);
				}

				f.WriteLine("\t\tb = *mw++;");
				s.Format(L"\t\tinputs[%d] = tanh(b + inputs[%d] * *mw++);", i, i);
				f.WriteLine(s);
				f.WriteLine("\t} else {");
				s.Format(L"\t\tspaceInputs[%d] = inputs[%d] = 0.0;", i, i);
				f.WriteLine(s);
				f.WriteLine("\t}");
			}
		}
	}

	// space network
	for (int l = 1; l < numberSpaceLayers; l++) {
		List<Neuron> * neurons = &(spaceNetwork->layers.Element(l)->neurons);

		int nn = 0;
		for(NeuronWithInputConnections * n = dynamic_cast<NeuronWithInputConnections *>(neurons->First()); n != NULL; n = dynamic_cast<NeuronWithInputConnections *>(neurons->Next())) {
			CString aux;

			if (l == numberSpaceLayers -1) {
				aux.Format(_TEXT("mk[%d]"), nn);
			} else {
				aux.Format(_TEXT("spaceHiddenLayer%doutputs[%d]"), l, nn);
			}

			f.WriteString("\t");
			f.WriteString(aux);
			f.WriteLine(" = *sw++;");

			int numberInputsFromLastLayer = n->inputs.Lenght() - 1; // - bias
			if (spaceInputLayerIsConnectedWithOutputLayer  && l == numberSpaceLayers -1) numberInputsFromLastLayer -= inputs;

			s.Format(_TEXT("\tfor(c = 0; c < %d; c++) "), numberInputsFromLastLayer);
			f.WriteString(s);
			f.WriteString(aux);
			f.WriteString(" += *sw++ * ");

			if (l == 1) {
				s = (hasMissingValues) ? "spaceI" : "i";
				s+= "nputs[c];";
			} else {
				s.Format(_TEXT("spaceHiddenLayer%doutputs[c];"), l-1);
			}
			f.WriteLine(s);

			if (spaceInputLayerIsConnectedWithOutputLayer  && l == numberSpaceLayers -1) {
				s.Format(_TEXT("\tfor(c = 0; c < %d; c++) "), inputs);
				f.WriteString(s);
				f.WriteLine(aux + L" += *sw++ * " + ((hasMissingValues) ? "spaceI" : "i") + "nputs[c];");
			}

			WriteActivationFunctionCCode(f, n, CT2CA(aux));

			nn++;
		}
	}

	// main network

	for (int l = 1; l < numberLayers; l++) {
		List<Neuron> * neurons = &(layers.Element(l)->neurons);

		int nn = 0;
		for(NeuronWithInputConnections * n = dynamic_cast<NeuronWithInputConnections *>(neurons->First()); n != NULL; n = dynamic_cast<NeuronWithInputConnections *>(neurons->Next())) {
			CString aux;

			if (l == numberLayers -1) {
				aux.Format(_TEXT("outputs[%d]"), nn);
			} else {
				aux.Format(_TEXT("hiddenLayer%doutputs[%d]"), l, nn);
			}

			f.WriteString("\t");
			f.WriteString(aux);
			f.WriteLine(" = *mw++;");
			
			int numberInputsFromLastLayer = n->inputs.Lenght() - 1; // - bias
			if (inputLayerIsConnectedWithOutputLayer && l == numberLayers -1) numberInputsFromLastLayer -= inputs;

			s.Format(_TEXT("\tfor(c = 0; c < %d; c++) "), numberInputsFromLastLayer);
			f.WriteString(s);
			f.WriteString(aux);
			f.WriteString(" += *mw++ * ");

			if (l == 1) {
				s = "inputs[c];";
			} else {
				s.Format(_TEXT("hiddenLayer%doutputs[c];"), l-1);
			}

			f.WriteLine(s);

			if (inputLayerIsConnectedWithOutputLayer && l == numberLayers -1) {
				s.Format(_TEXT("\tfor(c = 0; c < %d; c++) "), inputs);
				f.WriteString(s);
				f.WriteLine(aux + _TEXT(" += *mw++ * inputs[c];"));
			}

			WriteActivationFunctionCCode(f, n, CT2CA(aux));

			if (!spaceNetwork.IsNull() && nn < neuronsWithSelectiveActivation[l]) {
				f.WriteString("\t");
				f.WriteString(aux);
				f.WriteLine(" *= *m++;");
			}

			nn++;
		}
	}

	// Rescale the outputs
	if (trainVariables.Number() == inputs + outputs) {
		for (int o = 0; o < outputs; o++) {
			int outVar = o + inputs;

			double min = trainVariables.Minimum(outVar);
			double max = trainVariables.Maximum(outVar);
			double nmin = trainVariables.newMinimum[outVar];

			s.Format(_TEXT("\toutputs[%d] = %1.15f + (outputs[%d] - %f) * %1.15f;"), o, min, o, nmin, (max - min) / (1.0 - nmin));
			f.WriteLine(s);
		}
	}

	f.WriteLine("}");
}