public override void _Backward(INode fromNode, IGraphData errorSignal, IContext context, IReadOnlyList <INode> parents) { Debug.Assert(_source._children.Contains(fromNode)); _signalTable[fromNode] = errorSignal; if (_signalTable.All(s => s.Value != null) && parents?.Any() == true) { var firstSignal = _signalTable[_source._children.First()]; var otherSignals = _signalTable.Where(s => s.Value != firstSignal && s.Value.Columns == firstSignal.Columns && s.Value.Rows == firstSignal.Rows).ToList(); if (otherSignals.Any()) { var matrix = firstSignal.GetMatrix(); foreach (var item in otherSignals) { matrix.AddInPlace(item.Value.GetMatrix()); } firstSignal = firstSignal.ReplaceWith(matrix); } foreach (var parent in parents) { context.AddBackward(firstSignal, parent, _source); } _source._onBackpropagation?.Invoke(_signalTable); } }
public override void _Backward(INode fromNode, IGraphData errorSignal, IContext context, IReadOnlyList <INode> parents) { var matrix = errorSignal.GetMatrix(); (IMatrix left, IMatrix right) = matrix.SplitAtColumn(matrix.ColumnCount - _reverseSize); context.AddBackward(errorSignal.ReplaceWith(left), parents[0], _source); var batch = context.BatchSequence.MiniBatch; var sequenceIndex = context.BatchSequence.SequenceIndex; var reversedSequenceIndex = batch.SequenceCount - sequenceIndex - 1; _source._reverseBackpropagation.Add(reversedSequenceIndex, (parents[1], errorSignal.ReplaceWith(right))); _source._contextTable.Add(sequenceIndex, context); if (sequenceIndex == 0) { // process in order as we are pushing onto a stack (so will be read in reverse order) for (var i = 0; i < batch.SequenceCount; i++) { var data = _source._reverseBackpropagation[i]; var reverseContext = _source._contextTable[i]; reverseContext.AddBackward(data.Item2, data.Item1, _source); } _source._reverseBackpropagation.Clear(); _source._contextTable.Clear(); } }
/// <summary> /// Sends a backpropagation signal further up the graph /// </summary> /// <param name="errorSignal">The backpropagating error</param> /// <param name="context">Graph context</param> /// <param name="parents">Parents of the current node</param> protected void _SendErrorTo(IGraphData errorSignal, IContext context, IReadOnlyList <INode> parents) { if (parents?.Any() == true) { foreach (var parent in parents) { context.AddBackward(errorSignal, parent, _source); } } }
/// <summary> /// Called when backpropagating /// </summary> /// <param name="fromNode">The node that sent the backpropagation signal</param> /// <param name="errorSignal">The backpropagating error</param> /// <param name="context">Graph context</param> /// <param name="parents">Parents of the current node</param> public void Backward(INode fromNode, IGraphData errorSignal, IContext context, IReadOnlyList <INode> parents) { if (errorSignal == null) { if (parents?.Any() == true) { foreach (var parent in parents) { context.AddBackward(errorSignal, parent, _source); } } } else { _Backward(fromNode, errorSignal, context, parents); } }
public void AddBackward(IGraphData errorSignal, INode target, INode source) { _context.AddBackward(errorSignal, target, source); }