Exemplo n.º 1
0
        /// <summary>
        /// Pass error from the last layer to the first layer
        /// </summary>
        /// <param name="pSequence"></param>
        /// <param name="seqFinalOutput"></param>
        /// <param name="isCRF"></param>
        /// <returns></returns>
        private void ComputeDeepErr(Sequence pSequence, SimpleLayer[] seqFinalOutput, out List <double[][]> fErrLayers, out List <double[][]> bErrLayers, bool isCRF = false)
        {
            int numStates = pSequence.States.Length;
            int numLayers = forwardHiddenLayers.Count;

            //Calculate output layer error
            for (int curState = 0; curState < numStates; curState++)
            {
                int         label = pSequence.States[curState].Label;
                SimpleLayer layer = seqFinalOutput[curState];

                if (isCRF == false)
                {
                    for (int c = 0; c < layer.LayerSize; c++)
                    {
                        layer.er[c] = -layer.cellOutput[c];
                    }
                    layer.er[label] = 1.0 - layer.cellOutput[label];
                }
                else
                {
                    double[] CRFOutputLayer = CRFSeqOutput[curState];
                    for (int c = 0; c < layer.LayerSize; c++)
                    {
                        layer.er[c] = -CRFOutputLayer[c];
                    }
                    layer.er[label] = 1 - CRFOutputLayer[label];
                }
            }

            //Now we already have err in output layer, let's pass them back to other layers
            fErrLayers = new List <double[][]>();
            bErrLayers = new List <double[][]>();
            for (int i = 0; i < numLayers; i++)
            {
                fErrLayers.Add(null);
                bErrLayers.Add(null);
            }

            //Pass error from i+1 to i layer
            SimpleLayer forwardLayer  = forwardHiddenLayers[numLayers - 1];
            SimpleLayer backwardLayer = backwardHiddenLayers[numLayers - 1];

            double[][] errLayer = new double[numStates][];
            Parallel.For(0, numStates, parallelOption, curState =>
            {
                errLayer[curState] = new double[forwardLayer.LayerSize];
                forwardLayer.ComputeLayerErr(seqFinalOutput[curState], errLayer[curState], seqFinalOutput[curState].er);
            });
            fErrLayers[numLayers - 1] = errLayer;
            bErrLayers[numLayers - 1] = errLayer;

            // Forward
            for (int i = numLayers - 2; i >= 0; i--)
            {
                forwardLayer = forwardHiddenLayers[i];
                errLayer     = new double[numStates][];
                double[][] srcErrLayer = fErrLayers[i + 1];
                Parallel.For(0, numStates, parallelOption, curState =>
                {
                    int curState2 = numStates - curState - 1;

                    errLayer[curState2] = new double[forwardLayer.LayerSize];
                    forwardLayer.ComputeLayerErr(forwardHiddenLayers[i + 1], errLayer[curState2], srcErrLayer[curState2]);
                });

                fErrLayers[i] = errLayer;
            }

            // Backward
            for (int i = numLayers - 2; i >= 0; i--)
            {
                backwardLayer = backwardHiddenLayers[i];
                errLayer      = new double[numStates][];
                double[][] srcErrLayer = bErrLayers[i + 1];
                Parallel.For(0, numStates, parallelOption, curState =>
                {
                    errLayer[curState] = new double[backwardLayer.LayerSize];
                    backwardLayer.ComputeLayerErr(backwardHiddenLayers[i + 1], errLayer[curState], srcErrLayer[curState]);
                });

                bErrLayers[i] = errLayer;
            }
        }