private static JobResult RunJob(JobDescription job) { Matrix <double> weights = GenerateRandomWeights(job.k, -1, 1); Matrix <double> radial = new Matrix <double>(1, job.k); Random rng = new Random(); // kohonen learning phase for (int t = 0; t < job.iters_kohonen; t++) { int ostIndex = rng.Next(job.ost.Rows); RadialNumerators(radial, job.ost, weights, ostIndex); int j_0 = radial.IndexOfMax(); weights[j_0, 0] += job.eta_kohonen * (job.ost[ostIndex, 0] - weights[j_0, 0]); weights[j_0, 1] += job.eta_kohonen * (job.ost[ostIndex, 1] - weights[j_0, 1]); } Lab1.NeuralNetwork nn = new Lab1.NeuralNetwork(job.beta, new int[] { job.k, 1 }); nn.RandomizeBiases(-1, 1); nn.RandomizeWeights(-1, 1); Matrix <double>[] ostRadials = new Matrix <double> [job.ost.Rows]; for (int i = 0; i < job.ost.Rows; i++) { RadialNumerators(ostRadials[i] = new Matrix <double>(1, job.k), job.ost, weights, i); Radial(ostRadials[i]); } var radialIndices = Enumerable.Range(0, job.ost.Rows).ToList(); radialIndices.Shuffle(); Matrix <double>[] trainingRadials = new Matrix <double> [(int)Math.Round(job.ost.Rows * 0.7)]; int[][] trainingClasses = new int[trainingRadials.Length][]; for (int i = 0; i < trainingRadials.Length; i++) { trainingRadials[i] = ostRadials[radialIndices[i]]; trainingClasses[i] = job.ostClasses[radialIndices[i]]; } Matrix <double>[] validationRadials = new Matrix <double> [job.ost.Rows - trainingRadials.Length]; int[][] validationClasses = new int[validationRadials.Length][]; for (int i = 0; i < validationRadials.Length; i++) { validationRadials[i] = ostRadials[radialIndices[trainingRadials.Length + i]]; validationClasses[i] = job.ostClasses[radialIndices[trainingRadials.Length + i]]; } // perceptron learning phase for (int t = 0; t < job.iters_perceptron; t++) { int ostIndex = rng.Next(trainingRadials.Length); nn.Train(trainingRadials[ostIndex], trainingClasses[ostIndex], job.eta_perceptron); } double trainingErrorRate = Lab1.Task4a.ErrorRate(trainingRadials, trainingClasses, nn); double validationErrorRate = Lab1.Task4a.ErrorRate(validationRadials, validationClasses, nn); var result = new JobResult { k = job.k, weights = weights, nn = nn, radial = radial, traniningErrorRate = trainingErrorRate, validationErrorRate = validationErrorRate }; Interlocked.Increment(ref JobsCompleted); return(result); }
private static void BoundaryDump(string fileStr, Matrix <double> ost, Matrix <double> weights, Matrix <double> radial, Lab1.NeuralNetwork nn) { //double x_min = weights.Col(0).Min(), x_max = weights.Col(0).Max(); //double y_min = weights.Col(1).Min(), y_max = weights.Col(1).Max(); double x_min = ost.Col(0).Min(), x_max = ost.Col(0).Max(); double y_min = ost.Col(1).Min(), y_max = ost.Col(1).Max(); double x_stepSize = (x_max - x_min) / 999; double classification_precision = 1E-6; Matrix <double> zeroOst = new Matrix <double>(1, 2); List <Tuple <double, double> > boundary = new List <Tuple <double, double> >(1000); for (double x = x_min; x <= x_max; x += x_stepSize) { zeroOst[0, 0] = x; zeroOst[0, 1] = y_max; RadialNumerators(radial, zeroOst, weights, 0); Radial(radial); nn.FeedPattern(radial); double max_classification = nn.Output[0, 0]; zeroOst[0, 1] = y_min; RadialNumerators(radial, zeroOst, weights, 0); Radial(radial); nn.FeedPattern(radial); double min_classificiaton = nn.Output[0, 0]; if (max_classification * min_classificiaton > 0) { continue; } double classification = max_classification; double range_max = y_max, range_min = y_min; while (Math.Abs(classification) > classification_precision) { zeroOst[0, 1] = (range_max - range_min) / 2 + range_min; RadialNumerators(radial, zeroOst, weights, 0); Radial(radial); nn.FeedPattern(radial); classification = nn.Output[0, 0]; if (classification * max_classification > 0) { range_max = zeroOst[0, 1]; } else { range_min = zeroOst[0, 1]; } } boundary.Add(Tuple.Create(zeroOst[0, 0], zeroOst[0, 1])); } string filename = "lab2task3_boundary_" + fileStr + ".txt"; Console.WriteLine("Writing to " + filename + "..."); using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.CreateNew))) { foreach (var xy in boundary) { sw.WriteLine(xy.Item1.ToString(CultureInfo.InvariantCulture) + "," + xy.Item2.ToString(CultureInfo.InvariantCulture)); } } }