private ComputationGraph(IComputationGraphNode root, IReadOnlyList <IComputationGraphNode> nodes, ProcessingNode output, IReadOnlyList <ProcessingNode> trainingOutputs) { Root = root is InputNode input ? input : throw new ArgumentException("The root node isn't valid"); Nodes = nodes; OutputNode = output; TrainingOutputNodes = trainingOutputs; ProcessingNodes = Nodes.Pick <IComputationGraphNode, ProcessingNode>().ToArray(); }
// Recursive forward function void Forward(IComputationGraphNode node) { switch (node) { case ProcessingNode processing: { processing.Layer.To <INetworkLayer, NetworkLayerBase>().Forward(aMap[processing.Parent], out Tensor z, out Tensor a); z.Free(); aMap[processing] = a; if (processing == Graph.OutputNode) { return; } break; } case DepthConcatenationNode concatenation: if (!TryExecuteMergeForward(aMap, concatenation, out Tensor m)) { return; } aMap[concatenation] = m; break; case SumNode sum: { if (!TryExecuteMergeForward(aMap, sum, out Tensor z, out Tensor a)) { return; } z.Free(); aMap[sum] = a; break; } case TrainingNode _: return; default: throw new ArgumentException("The node type is not supported", nameof(node)); } for (int i = 0; i < node.Children.Count; i++) { if (!aMap.ContainsKey(node.Children[i])) { Forward(node.Children[i]); } } }
public TrainingNode([NotNull] IComputationGraphNode root) : base(ComputationGraphNodeType.TrainingBranch) => Parent = root;
/// <inheritdoc/> public override bool Equals(IComputationGraphNode other) { return(base.Equals(other) && other is ProcessingNode processing && processing.Layer.Equals(Layer)); }
internal ProcessingNode([NotNull] INetworkLayer layer, [NotNull] IComputationGraphNode parent) : base(ComputationGraphNodeType.Processing) { Layer = layer; Parent = parent; }