// Worker thread
void SearchSolution( )
{
bool reducedNetwork = ( ( classesCount == 2 ) && ( useOneNeuronForTwoClasses ) );
// prepare learning data
double[][] input = new double[samples][];
double[][] output = new double[samples][];
for ( int i = 0; i < samples; i++ )
{
input[i] = new double[variables];
output[i] = new double[neuronsCount];
// set input
for ( int j = 0; j < variables; j++ )
input[i][j] = data[i, j];
// set output
if ( reducedNetwork )
{
output[i][0] = classes[i];
}
else
{
output[i][classes[i]] = 1;
}
}
// create perceptron
ActivationNetwork network = new ActivationNetwork(
new SigmoidFunction( sigmoidAlphaValue ), variables, neuronsCount );
ActivationLayer layer = network[0];
// create teacher
DeltaRuleLearning teacher = new DeltaRuleLearning( network );
// set learning rate
teacher.LearningRate = learningRate;
// iterations
int iteration = 1;
// statistic files
StreamWriter errorsFile = null;
StreamWriter weightsFile = null;
try
{
// check if we need to save statistics to files
if ( saveStatisticsToFiles )
{
// open files
errorsFile = File.CreateText( "errors.csv" );
weightsFile = File.CreateText( "weights.csv" );
}
// erros list
ArrayList errorsList = new ArrayList( );
// loop
while ( !needToStop )
{
// save current weights
if ( weightsFile != null )
{
for ( int i = 0; i < neuronsCount; i++ )
{
weightsFile.Write( "neuron" + i + "," );
for ( int j = 0; j < variables; j++ )
weightsFile.Write( layer[i][j] + "," );
weightsFile.WriteLine( layer[i].Threshold );
}
}
// run epoch of learning procedure
double error = teacher.RunEpoch( input, output ) / samples;
errorsList.Add( error );
// save current error
if ( errorsFile != null )
{
errorsFile.WriteLine( error );
}
// show current iteration & error
SetText( currentIterationBox, iteration.ToString( ) );
SetText( currentErrorBox, error.ToString( ) );
iteration++;
// check if we need to stop
if ( ( useErrorLimit ) && ( error <= learningErrorLimit ) )
break;
if ( ( !useErrorLimit ) && ( iterationLimit != 0 ) && ( iteration > iterationLimit ) )
break;
}
// show perceptron's weights
ClearList( weightsList );
for ( int i = 0; i < neuronsCount; i++ )
{
string neuronName = string.Format( "Neuron {0}", i + 1 );
ListViewItem item = null;
// add all weights
for ( int j = 0; j < variables; j++ )
{
item = AddListItem( weightsList, neuronName );
AddListSubitem( item, string.Format( "Weight {0}", j + 1 ) );
AddListSubitem( item, layer[i][0].ToString( "F6" ) );
}
// threshold
item = AddListItem( weightsList, neuronName );
AddListSubitem( item, "Threshold");
AddListSubitem( item, layer[i].Threshold.ToString( "F6" ) );
}
// show error's dynamics
double[,] errors = new double[errorsList.Count, 2];
for ( int i = 0, n = errorsList.Count; i < n; i++ )
{
errors[i, 0] = i;
errors[i, 1] = (double) errorsList[i];
}
errorChart.RangeX = new DoubleRange( 0, errorsList.Count - 1 );
errorChart.UpdateDataSeries( "error", errors );
}
catch ( IOException )
{
MessageBox.Show( "Failed writing file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
finally
{
// close files
if ( errorsFile != null )
errorsFile.Close( );
if ( weightsFile != null )
weightsFile.Close( );
}
// enable settings controls
EnableControls( true );
}