private void btnRunTraining_Click(object sender, EventArgs e)
{
if (dgvTrainingSource.Rows.Count == 0)
{
MessageBox.Show("Please load the training data before clicking this button");
return;
}
lbStatus.Text = "Gathering data. This may take a while...";
Application.DoEvents();
// Extract inputs and outputs
int rows = dgvTrainingSource.Rows.Count;
double[][] input = new double[rows][];
int[] output = new int[rows];
for (int i = 0; i < rows; i++)
{
input[i] = (double[])dgvTrainingSource.Rows[i].Cells["colTrainingFeatures"].Value;
output[i] = (int)dgvTrainingSource.Rows[i].Cells["colTrainingLabel"].Value;
}
// Create the chosen kernel function
// using the user interface parameters
//
IKernel kernel = createKernel();
// Extract training parameters from the interface
double complexity = (double)numComplexity.Value;
double tolerance = (double)numTolerance.Value;
int cacheSize = (int)numCache.Value;
SelectionStrategy strategy = (SelectionStrategy)cbStrategy.SelectedItem;
// Create the learning algorithm using the machine and the training data
var ml = new MulticlassSupportVectorLearning<IKernel>()
{
// Configure the learning algorithm
Learner = (param) => new SequentialMinimalOptimization<IKernel>()
{
Complexity = complexity,
Tolerance = tolerance,
CacheSize = cacheSize,
Strategy = strategy,
Kernel = kernel
}
};
lbStatus.Text = "Training the classifiers. This may take a (very) significant amount of time...";
Application.DoEvents();
Stopwatch sw = Stopwatch.StartNew();
// Train the machines. It should take a while.
ksvm = ml.Learn(input, output);
// If we created a linear machine, compress the support vectors
// into one single parameter vector for increased performance:
if (ksvm.Kernel is Linear)
{
ksvm.Compress();
}
sw.Stop();
double error = new ZeroOneLoss(output)
{
Mean = true
}.Loss(ksvm.Decide(input));
lbStatus.Text = String.Format(
"Training complete ({0}ms, {1}er). Click Classify to test the classifiers.",
sw.ElapsedMilliseconds, error);
// Update the interface status
btnClassifyVoting.Enabled = true;
btnClassifyElimination.Enabled = true;
btnCalibration.Enabled = true;
// Populate the information tab with the machines
dgvMachines.Rows.Clear();
int k = 1;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < i; j++, k++)
{
var machine = ksvm[i, j];
int sv = machine.SupportVectors == null ? 0 : machine.SupportVectors.Length;
int c = dgvMachines.Rows.Add(k, i + "-vs-" + j, sv, machine.Threshold);
dgvMachines.Rows[c].Tag = machine;
}
}
// approximate size in bytes =
// number of support vectors * number of doubles in a support vector * size of double
int bytes = ksvm.SupportVectorUniqueCount * 1024 * sizeof(double);
float megabytes = bytes / (1024 * 1024);
lbSize.Text = String.Format("{0} ({1} MB)", ksvm.SupportVectorUniqueCount, megabytes);
}