protected override double[] DoIteration(List <IGWGraph <NodeData, EdgeData, GraphData> > TrainingGraphs, double[] weightCurrent, int globalIteration) { var weights = weightCurrent.ToArray(); int u = TrainingGraphs.Count; var vit = new int[u][]; var mcmc = new int[u][]; double devges = 0.0; // Anzahl Knoten double mx = 0; var refLabel = new int[u][]; double devgesT = 0; // Summe aller Knoten aller Graphen double mu = 0; int[] countsMCMCMinusRef = new int[weightCurrent.Length]; int[] countsRefMinusMCMC = new int[weightCurrent.Length]; Log.Post("#Iteration: " + globalIteration); for (int g = 0; g < TrainingGraphs.Count; g++) { var graph = TrainingGraphs[g]; mx = graph.Nodes.Count(); mu += mx; // Labeling mit Viterbi (MAP) var request = new SolveInference(graph as IGWGraph <ICRFNodeData, ICRFEdgeData, ICRFGraphData>, Labels, BufferSizeInference); request.RequestInDefaultContext(); int[] labelingVit = request.Solution.Labeling; vit[g] = labelingVit; // Labeling mit MCMC basierend auf MAP var requestMCMC = new GiveProbableLabelings(graph as IGWGraph <ICRFNodeData, ICRFEdgeData, ICRFGraphData>) { StartingPoints = 1, PreRunLength = 100000, RunLength = 1 }; requestMCMC.RequestInDefaultContext(); var result = requestMCMC.Result; int[] labelingMCMC = new int[labelingVit.Length]; foreach (var item in result) { labelingMCMC[item.Key.GraphId] = (int)item.Value; } mcmc[g] = labelingMCMC; // reales labeling int[] labeling = graph.Data.ReferenceLabeling; refLabel[g] = labeling; // Berechnung des typischen/mittleren Fehlers devges += LossFunctionIteration(refLabel[g], mcmc[g]); devgesT += LossFunctionIteration(refLabel[g], vit[g]); // set scores according to weights SetWeightsCRF(weights, graph); if (debugOutputEnabled) { printLabelings(vit[g], mcmc[g], refLabel[g], g); } // calculate equation 6.13 and 6.14 int[] countsRef = CountPred(graph, refLabel[g]); int[] countsMCMC = CountPred(graph, mcmc[g]); for (int k = 0; k < countsRef.Length; k++) { countsMCMCMinusRef[k] += countsMCMC[k] - countsRef[k]; countsRefMinusMCMC[k] += countsRef[k] - countsMCMC[k]; } } // mittlerer (typischer) Fehler (Summen-Gibbs-Score) middev = devges / u; // realer Fehler fuer diese Runde (Summen-Trainings-Score) realdev = devgesT / u; var loss = (realdev - middev) * mu; // Scores berechnen?? Im Skript so, aber nicht notwendig double l2norm = (countsRefMinusMCMC.Sum(entry => entry * entry)); var deltaomegaFactor = 0.0; var deltaomega = new double[weights.Length]; var weightedScore = 0.0; for (int k = 0; k < weights.Length; k++) { if (l2norm > 0) { weightedScore += weights[k] * countsMCMCMinusRef[k]; deltaomegaFactor = (loss + weightedScore) / l2norm; deltaomega[k] = deltaomegaFactor * countsRefMinusMCMC[k]; } else { weightedScore += weights[k] * countsRefMinusMCMC[k]; deltaomegaFactor = (loss + weightedScore) / l2norm; deltaomega[k] = deltaomegaFactor * countsMCMCMinusRef[k]; } weights[k] += deltaomega[k]; } // debug output Log.Post("Loss: " + (int)loss + " Realdev: " + realdev + " Middev: " + middev); return(weights); }
protected override double[] DoIteration(List <IGWGraph <NodeData, EdgeData, GraphData> > TrainingGraphs, double[] weightCurrent, int globalIteration) { var weights = weightCurrent.ToArray(); int u = TrainingGraphs.Count; var vit = new int[u][]; var samplesMCMC = new int[NumberOfSamples][]; double devges = 0.0; // Anzahl Knoten double mx = 0; var refLabel = new int[u][]; double devgesT = 0; // Summe aller Knoten aller Graphen double mu = 0; MCMCDeviations = 0.0; refMCMCDeviations = 0.0; int[] countsRefMinusPred = new int[weightCurrent.Length]; Log.Post("#Iteration: " + globalIteration); for (int g = 0; g < TrainingGraphs.Count; g++) { var graph = TrainingGraphs[g]; mx = graph.Nodes.Count(); mu += mx; // Labeling mit Viterbi (MAP) var request = new SolveInference(graph as IGWGraph <ICRFNodeData, ICRFEdgeData, ICRFGraphData>, Labels, BufferSizeInference); request.RequestInDefaultContext(); int[] labelingVit = request.Solution.Labeling; vit[g] = labelingVit; // Labeling mit MCMC basierend auf MAP // TODO generate not 1 but k labelings for each graph for (int i = 0; i < NumberOfSamples; i++) { var requestMCMC = new GiveProbableLabelings(graph as IGWGraph <ICRFNodeData, ICRFEdgeData, ICRFGraphData>) { StartingPoints = 1, PreRunLength = 100000, RunLength = 1 }; requestMCMC.RequestInDefaultContext(); var result = requestMCMC.Result; int[] labelingMCMC = new int[labelingVit.Length]; foreach (var item in result) { labelingMCMC[item.Key.GraphId] = (int)item.Value; } samplesMCMC[i] = labelingMCMC; } // TODO function to sum the deviations in mcmc labelings CalculateMCMCDeviations(samplesMCMC); // reales labeling int[] labeling = graph.Data.ReferenceLabeling; refLabel[g] = labeling; // TODO function to sum deviations from reflabel to MCMC labelings CalculateRefMCMCDeviations(samplesMCMC, labeling); // Berechnung des realen Fehlers devgesT += LossFunctionIteration(refLabel[g], vit[g]); // set scores according to weights SetWeightsCRF(weights, graph); int[] countsRef = CountPred(graph, refLabel[g]); int[] countsPred = CountPred(graph, vit[g]); for (int k = 0; k < countsRef.Length; k++) { countsRefMinusPred[k] += countsRef[k] - countsPred[k]; } } // mittlerer (typischer) Fehler (Summen-Gibbs-Score) middev = devges / u; // realer Fehler fuer diese Runde (Summen-Trainings-Score) realdev = devgesT / u; MCMCDeviations /= u; refMCMCDeviations /= u; var loss = realdev * mu; // Scores berechnen?? Im Skript so, aber nicht notwendig double l2norm = (countsRefMinusPred.Sum(entry => entry * entry)); var deltaomega = new double[weights.Length]; var weightedScore = 0.0; for (int k = 0; k < weights.Length; k++) { weightedScore += weights[k] * countsRefMinusPred[k]; } var deltaomegaFactor = (loss - weightedScore) / l2norm; for (int k = 0; k < weights.Length; k++) { if (l2norm > 0) { deltaomega[k] = deltaomegaFactor * countsRefMinusPred[k]; } else { Log.Post("wiu wiu"); deltaomega[k] = 0; } weights[k] += deltaomega[k]; } // debug output Log.Post("Loss: " + (int)loss + " refMCMCDeviations: " + refMCMCDeviations + " MCMCDeviations: " + MCMCDeviations); return(weights); }