Пример #1
0
        protected LayerBackwardCompute(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
        {
            Contract.Requires(forwardCompute != null);
            Contract.Requires(connectedLayer != null);
            Contract.Requires((connectedLayer.StructuralElementFlags & NNStructuralElement.BackwardImplementation) != 0 &&
                (connectedLayer.StructuralElementFlags & NNStructuralElement.GradientInformation) != 0);

            Init(forwardCompute, connectedLayer);
        }
Пример #2
0
        private void Init(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
        {
            ForwardCompute = forwardCompute;

            InitLowerErrorValueAccessItems(connectedLayer);
            ErrorBuffer = connectedLayer.ErrorBuffer;
            GradientBuffers = connectedLayer.GradientBuffers;
            GradientSumBuffers = connectedLayer.GradientSumBuffers;
            BiasGradientValueIndex = connectedLayer.BiasGradientValueIndex;
            BiasGradientSumValueIndex = connectedLayer.BiasGradientSumValueIndex;
            OutputErrorBuffer = connectedLayer.OutputErrorBuffer;
        }
Пример #3
0
 private unsafe void SetGradientValue(float* valueBuffer, LayerForwardCompute comp, int iValueIndex, int jLayerIndex, int jValueIndex, float gradient)
 {
     if (jLayerIndex == -1)
     {
         // Bias
         Debug.Assert(jValueIndex == -1);
         Debug.Assert(comp.BiasGradientValueIndex != null);
         valueBuffer[comp.BiasGradientValueIndex.Value] = gradient;
         valueBuffer[comp.BiasGradientSumValueIndex.Value] += gradient;
     }
     else
     {
         int wvIndex = WeightAccessor.GetWeightValueIndex(jValueIndex, iValueIndex, comp.OutputBuffer.Size);
         valueBuffer[comp.GradientBuffers[jLayerIndex].MinValue + wvIndex] = gradient;
         valueBuffer[comp.GradientSumBuffers[jLayerIndex].MinValue + wvIndex] += gradient;
     }
 }
Пример #4
0
        private unsafe float GetInputValue(float* valueBuffer, LayerForwardCompute comp, int jLayerIndex, int jValueIndex)
        {
            if (jLayerIndex == -1)
            {
                // Bias
                Debug.Assert(jValueIndex == -1);
                Debug.Assert(comp.BiasValueIndex != null);
                return valueBuffer[comp.BiasValueIndex.Value];
            }

            var accessItem = comp.InputValueAccessItems[jLayerIndex];
            var valueIndex = accessItem.InputBufferBeginIndex + jValueIndex;
            Debug.Assert(valueIndex <= accessItem.InputBufferBeginIndex + accessItem.InputSize);
            return valueBuffer[valueIndex];
        }
Пример #5
0
        unsafe private void ComputePValues(float* valueBuffer, LayerForwardCompute comp, IntRange[] valueRelatedPBuffs, IntRange[] valueRelatedPrevPBuffs, int iLayerIndex, int iValueIndex, int jLayerIndex, int jValueIndex, float* eVector)
        {
            int outputLayerIndex = valueRelatedPBuffs.Length - 1;
            Debug.Assert(outputLayerIndex == ForwardComputes.Length - 1);
            Debug.Assert(outputLayerIndex == ForwardComputes[ForwardComputes.Length - 1].ConnectedLayerIndex);
            for (int kLayerIndex = 0; kLayerIndex < valueRelatedPBuffs.Length; kLayerIndex++)
            {
                float gradient = 0.0f;
                bool computeGradient = kLayerIndex == outputLayerIndex && eVector != null;

                var currentPBuffValueRange = valueRelatedPBuffs[kLayerIndex];
                var currentPrevPBuffValueRange = valueRelatedPrevPBuffs[kLayerIndex];
                int currentPBuffValueRangeSize = currentPBuffValueRange.Size;
                for (int kValueIndex = 0; kValueIndex < currentPBuffValueRangeSize; kValueIndex++)
                {
                    // i: iLayerIndex, iValueIndex
                    // j: jLayerIndex, jValueIndex
                    // k: kLayerIndex, kValueIndex

                    float netDeriv_k = GetNetDerivValue(valueBuffer, kLayerIndex, kValueIndex);
                    float sum = 0.0f;

                    var comp_k = ForwardComputes[kLayerIndex];
                    foreach (var upperNonInputLayerInfo in comp_k.UpperNonInputLayerInfos)
                    {
                        int lLayerIndex = upperNonInputLayerInfo.LayerIndex;
                        var accessItem = comp_k.InputValueAccessItems[upperNonInputLayerInfo.WeightedErrorBufferIndex];
                        for (int lValueIndex = 0; lValueIndex < accessItem.InputSize; lValueIndex++)
                        {
                            // i: iLayerIndex, iValueIndex
                            // j: jLayerIndex, jValueIndex
                            // k: kLayerIndex, kValueIndex
                            // l: lLayerIndex, lValueIndex

                            float weight_k_l = valueBuffer[accessItem.WeightBufferBeginIndex + WeightAccessor.GetWeightValueIndex(lValueIndex, kValueIndex, currentPBuffValueRangeSize)];
                            float p_i_j_l = valueBuffer[valueRelatedPrevPBuffs[lLayerIndex].MinValue + lValueIndex];

                            sum += weight_k_l * p_i_j_l;
                        }
                    }

                    if (iLayerIndex == kLayerIndex && iValueIndex == kValueIndex)
                    {
                        sum += GetInputValue(valueBuffer, comp, jLayerIndex, jValueIndex);
                    }

                    if (computeGradient)
                    {
                        gradient += eVector[kValueIndex] * (valueBuffer[valueRelatedPBuffs[kLayerIndex].MinValue + kValueIndex] = netDeriv_k * sum);
                    }
                    else
                    {
                        valueBuffer[valueRelatedPBuffs[kLayerIndex].MinValue + kValueIndex] = netDeriv_k * sum;
                    }
                }

                if (computeGradient)
                {
                    //Console.WriteLine(gradient);
                    SetGradientValue(valueBuffer, comp, iValueIndex, jLayerIndex, jValueIndex, gradient);
                }
            }
        }