Пример #1
0
        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);
        }
Пример #2
0
        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);
        }