public void ComputeRMSEInThread(object input) { RMSEThreadInputDatum threadInputDatum = (RMSEThreadInputDatum) input; int outputSize = this.Sizes[this.LayerCount - 1]; foreach (double[] t in threadInputDatum.trainDatum) { // following assumes data has all x-values first, followed by y-values! Array.Copy(t, threadInputDatum.xValues, this.Sizes[0]); // extract inputs Array.Copy(t, this.Sizes[0], threadInputDatum.tValues, 0, outputSize); // extract targets double[] yValues = this.ComputeOutputs(threadInputDatum.xValues, threadInputDatum.field); for (int j = 0; j < outputSize; ++j) { double err = Math.Pow(yValues[j] - threadInputDatum.tValues[j], 2); threadInputDatum.sumSquaredErrors[0] += err * threadInputDatum.delim1; threadInputDatum.sumSquaredErrors[1] += err * threadInputDatum.delim2; } } }
public double[] RootMeanSquaredErrorMultiThread(double[][] trainData, double[] weights) { this.SetWeights(weights); // copy the weights to evaluate in TaskFactory taskFactory = new TaskFactory(); Task[] tasks = new Task[this.threadCount]; int lastLayerId = this.LayerCount - 1; int outputSize = this.Sizes[lastLayerId]; RMSEThreadInputDatum[] threadInputData = new RMSEThreadInputDatum[this.threadCount]; for (int i = 0; i < this.threadCount; i++) { threadInputData[i].field = new double[this.LayerCount][]; threadInputData[i].xValues = new double[this.Sizes[0]]; // inputs threadInputData[i].tValues = new double[outputSize]; // targets threadInputData[i].delim1 = 1.0 / trainData.Length; threadInputData[i].delim2 = 1.0 / trainData.Length / outputSize; threadInputData[i].sumSquaredErrors = new double[2]; for (int j = 0; j < this.LayerCount; j++) { threadInputData[i].field[j] = new double[this.Sizes[j]]; } } List<double[]> innerTrainData = new List<double[]>(trainData); List<double[]> innerTrainDataChunk = new List<double[]>(); int chunk_size = (int) (innerTrainData.Count * 0.8 / this.threadCount); while (innerTrainData.Count > 0) { int currentThread = -1; for (int i = 0; i < this.threadCount; i++) { // ReSharper disable once InvertIf if ((tasks[i] == null) || tasks[i].IsCompleted) { currentThread = i; break; } } if (currentThread == -1) { Thread.Sleep(20); continue; } innerTrainDataChunk.Clear(); while ((innerTrainDataChunk.Count < chunk_size) && (innerTrainData.Count > 0)) { innerTrainDataChunk.Add(innerTrainData[0]); innerTrainData.RemoveAt(0); } threadInputData[currentThread].trainDatum = innerTrainDataChunk.ToArray(); tasks[currentThread] = taskFactory.StartNew(this.ComputeRMSEInThread, threadInputData[currentThread]); } for (int i = 0; i < this.threadCount; i++) { if (tasks[i] != null) { tasks[i].Wait(); } } double sumSquaredErrorItem = 0; double sumSquaredError = 0; for (int i = 0; i < this.threadCount; i++) { sumSquaredError += threadInputData[i].sumSquaredErrors[0]; sumSquaredErrorItem += threadInputData[i].sumSquaredErrors[1]; } double[] d = {Math.Sqrt(sumSquaredErrorItem), Math.Sqrt(sumSquaredError)}; return d; }