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); }
private void BuildForwardComputation(BufferAllocator allocator, ConnectedLayerGroups connectedLayerGroups, ManagedNNInitParameters 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); } } }
private void Init(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer) { RunParallel = forwardCompute.RunParallel; ForwardCompute = forwardCompute; InitLowerErrorValueAccessItems(connectedLayer); ErrorBuffer = connectedLayer.ErrorBuffer; GradientBuffers = connectedLayer.GradientBuffers; GradientSumBuffers = connectedLayer.GradientSumBuffers; BiasGradientValueIndex = connectedLayer.BiasGradientValueIndex; BiasGradientSumValueIndex = connectedLayer.BiasGradientSumValueIndex; OutputErrorBuffer = connectedLayer.OutputErrorBuffer; }
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]; }
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; } }
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); } } }