public int[][] DecodeNBestCRF(Sequence seq, int N) { //ys contains the output of RNN for each word Matrix <float> ys; ProcessSequence(seq, RunningMode.Test, true, out ys); var n = seq.States.Length; var K = OutputLayer.LayerSize; var STP = CRFTagTransWeights; var vPath = new PAIR <int, int> [n, K, N]; var DUMP_LABEL = -1; var vPreAlpha = new float[K, N]; var vAlpha = new float[K, N]; var nStartTagIndex = 0; var nEndTagIndex = 0; var MIN_VALUE = float.MinValue; //viterbi algorithm for (var i = 0; i < K; i++) { for (var j = 0; j < N; j++) { vPreAlpha[i, j] = MIN_VALUE; vPath[0, i, j] = new PAIR <int, int>(DUMP_LABEL, 0); } } vPreAlpha[nStartTagIndex, 0] = ys[0][nStartTagIndex]; vPath[0, nStartTagIndex, 0].first = nStartTagIndex; var q = new PriorityQueue <float, PAIR <int, int> >(); for (var t = 1; t < n; t++) { for (var j = 0; j < K; j++) { while (q.Count() > 0) { q.Dequeue(); } var _stp = STP[j][0]; var _y = ys[t][j]; for (var k = 0; k < N; k++) { var score = vPreAlpha[0, k] + _stp + _y; q.Enqueue(score, new PAIR <int, int>(0, k)); } for (var i = 1; i < K; i++) { _stp = STP[j][i]; for (var k = 0; k < N; k++) { var score = vPreAlpha[i, k] + _stp + _y; if (score <= q.Peek().Key) { break; } q.Dequeue(); q.Enqueue(score, new PAIR <int, int>(i, k)); } } var idx = N - 1; while (q.Count() > 0) { vAlpha[j, idx] = q.Peek().Key; vPath[t, j, idx] = q.Peek().Value; idx--; q.Dequeue(); } } vPreAlpha = vAlpha; vAlpha = new float[K, N]; } //backtrace to get the n-best result path var vTagOutput = new int[N][]; for (var i = 0; i < N; i++) { vTagOutput[i] = new int[n]; } for (var k = 0; k < N; k++) { vTagOutput[k][n - 1] = nEndTagIndex; var decision = new PAIR <int, int>(nEndTagIndex, k); for (var t = n - 2; t >= 0; t--) { vTagOutput[k][t] = vPath[t + 1, decision.first, decision.second].first; decision = vPath[t + 1, decision.first, decision.second]; } } return(vTagOutput); }
public int[][] DecodeNBestCRF(Sequence seq, int N) { //ys contains the output of RNN for each word Matrix <double> ys = PredictSentence(seq, RunningMode.Test); int n = seq.States.Length; int K = L2; Matrix <double> STP = CRFTagTransWeights; PAIR <int, int>[, ,] vPath = new PAIR <int, int> [n, K, N]; int DUMP_LABEL = -1; double[,] vPreAlpha = new double[K, N]; double[,] vAlpha = new double[K, N]; int nStartTagIndex = 0; int nEndTagIndex = 0; double MIN_VALUE = double.MinValue; //viterbi algorithm for (int i = 0; i < K; i++) { for (int j = 0; j < N; j++) { vPreAlpha[i, j] = MIN_VALUE; vPath[0, i, j] = new PAIR <int, int>(DUMP_LABEL, 0); } } vPreAlpha[nStartTagIndex, 0] = ys[0][nStartTagIndex]; vPath[0, nStartTagIndex, 0].first = nStartTagIndex; AdvUtils.PriorityQueue <double, PAIR <int, int> > q = new AdvUtils.PriorityQueue <double, PAIR <int, int> >(); for (int t = 1; t < n; t++) { for (int j = 0; j < K; j++) { while (q.Count() > 0) { q.Dequeue(); } double _stp = STP[j][0]; double _y = ys[t][j]; for (int k = 0; k < N; k++) { double score = vPreAlpha[0, k] + _stp + _y; q.Enqueue(score, new PAIR <int, int>(0, k)); } for (int i = 1; i < K; i++) { _stp = STP[j][i]; for (int k = 0; k < N; k++) { double score = vPreAlpha[i, k] + _stp + _y; if (score <= q.Peek().Key) { break; } q.Dequeue(); q.Enqueue(score, new PAIR <int, int>(i, k)); } } int idx = N - 1; while (q.Count() > 0) { vAlpha[j, idx] = q.Peek().Key; vPath[t, j, idx] = q.Peek().Value; idx--; q.Dequeue(); } } vPreAlpha = vAlpha; vAlpha = new double[K, N]; } //backtrace to get the n-best result path int[][] vTagOutput = new int[N][]; for (int i = 0; i < N; i++) { vTagOutput[i] = new int[n]; } for (int k = 0; k < N; k++) { vTagOutput[k][n - 1] = nEndTagIndex; PAIR <int, int> decision = new PAIR <int, int>(nEndTagIndex, k); for (int t = n - 2; t >= 0; t--) { vTagOutput[k][t] = vPath[t + 1, decision.first, decision.second].first; decision = vPath[t + 1, decision.first, decision.second]; } } return(vTagOutput); }