protected LayerBackwardCompute(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
            : base(forwardCompute, connectedLayer)
        {
            Contract.Requires(forwardCompute != null);
            Contract.Requires(connectedLayer != null);
            Contract.Requires((connectedLayer.StructuralElementFlags & NNStructuralElement.BackwardImplementation) != 0 &&
                (connectedLayer.StructuralElementFlags & NNStructuralElement.GradientInformation) != 0);

            RunParallel = forwardCompute.RunParallel;
        }
示例#2
0
 private void BuildForwardComputation(BufferAllocator allocator, ConnectedLayerGroups connectedLayerGroups, CPUNNInitParameters initPars)
 {
     forwardComputeGroups = new LayerForwardCompute[connectedLayerGroups.Groups.Count][];
     for (int groupIndex = 0; groupIndex < connectedLayerGroups.Groups.Count; groupIndex++)
     {
         var group = connectedLayerGroups.Groups[groupIndex];
         forwardComputeGroups[groupIndex] = new LayerForwardCompute[group.Count];
         for (int layerIndex = 0; layerIndex < group.Count; layerIndex++)
         {
             forwardComputeGroups[groupIndex][layerIndex] = CreateLayerForwardCompute(group[layerIndex], initPars);
         }
     }
 }
示例#3
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);
                }
            }
        }
示例#4
0
 private void FlipPBias(LayerForwardCompute comp)
 {
     var temp = comp.PBiasBuffers;
     comp.PBiasBuffers = comp.PrevPBiasBuffers;
     comp.PrevPBiasBuffers = temp;
 }
示例#5
0
 private void FlipPWeights(LayerForwardCompute comp)
 {
     var temp = comp.PWeightBuffers;
     comp.PWeightBuffers = comp.PrevPWeightBuffers;
     comp.PrevPWeightBuffers = temp;
 }
示例#6
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];
        }
示例#7
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;
     }
 }