protected override NetworkDefinition<NeuralNode, NeuralConnection> CreateDefinition() { var networkDef = new NetworkDefinition<NeuralNode, NeuralConnection>(); int nodeBeginIndex = InputInterfaceLength; int nodeEndIndex = nodeBeginIndex + NodeCount - 1; int maxConnectionIndex = InputInterfaceLength + NodeCount + OutputInterfaceLength - 1; // Nodes: for (int idx = nodeBeginIndex; idx <= nodeEndIndex; idx++) { networkDef.AddNode(idx, NodeFactory.Create()); } // Input: for (int iidx = 0; iidx < nodeBeginIndex; iidx++) { for (int nidx = nodeBeginIndex; nidx <= nodeEndIndex; nidx++) { networkDef.AddConnection(new ConnectionIndex(iidx, nidx), ConnectionFactory.Create()); } } // Hidden: for (int nidx = nodeBeginIndex; nidx <= nodeEndIndex; nidx++) { for (int oidx = nidx + 1; oidx <= maxConnectionIndex; oidx++) { networkDef.AddConnection(new ConnectionIndex(nidx, oidx), ConnectionFactory.Create()); if (Recurrent) networkDef.AddConnection(new ConnectionIndex(oidx, nidx), ConnectionFactory.Create()); } } // Output: for (int idx = nodeEndIndex + 1; idx <= maxConnectionIndex; idx++) { networkDef.AddNode(idx, CollectorNodeFactory.Create()); networkDef.AddConnection(new ConnectionIndex(idx, idx + OutputInterfaceLength), new NeuralConnection()); } Debug.Assert(networkDef.MaxNodeIndex == maxConnectionIndex + OutputInterfaceLength); return networkDef; }
private NetworkDefinition<NeuralNode, NeuralConnection> Build() { var networkDef = new NetworkDefinition<NeuralNode, NeuralConnection>(); int currentNodeIndex = InputInterfaceLength; var nodeLayerInfos = new Dictionary<int, IntRange>(); nodeLayerInfos.Add(0, IntRange.CreateExclusive(0, InputInterfaceLength)); int entryCount = Definition.NodeCount; int entryIdx = 0; foreach (var nodeEntry in Definition.NodeEntries) { // Info var currentInfo = IntRange.CreateExclusive(currentNodeIndex, currentNodeIndex + nodeEntry.Node.NodeCount); nodeLayerInfos.Add(nodeEntry.Index, currentInfo); currentNodeIndex += nodeEntry.Node.NodeCount; // Upper foreach (var conn in Definition.GetUpperConnections(nodeEntry.Index)) { IntRange prevInfo; if (!nodeLayerInfos.TryGetValue(conn.Index.UpperNodeIndex, out prevInfo)) { throw GetArchitectureBuildingErrorEx("Node layer definition at '" + conn.Index.UpperNodeIndex + "' doesn't exists."); } for (int uidx = prevInfo.MinValue; uidx <= prevInfo.MaxValue; uidx++) { for (int lidx = currentInfo.MinValue; lidx <= currentInfo.MaxValue; lidx++) { networkDef.AddConnection(new ConnectionIndex(uidx, lidx), conn.Connection.ConnectionFactory.Create()); } } } // Nodes for (int idx = currentInfo.MinValue; idx <= currentInfo.MaxValue; idx++) { networkDef.AddNode(idx, nodeEntry.Node.NodeFactory.Create()); } var selfConnDef = nodeEntry.Node.SelfConnectionDefinition; if (selfConnDef != null) { for (int uidx = currentInfo.MinValue; uidx < currentInfo.MaxValue; uidx++) { for (int lidx = uidx + 1; lidx <= currentInfo.MaxValue; lidx++) { networkDef.AddConnection(new ConnectionIndex(uidx, lidx), selfConnDef.ConnectionFactory.Create()); } } } // Output: if (entryIdx == entryCount - 1) { if (currentInfo.Size != OutputInterfaceLength) { throw GetArchitectureBuildingErrorEx("Last node layer output size must be same as OutputInterfaceLength."); } for (int uidx = currentInfo.MinValue; uidx <= currentInfo.MaxValue; uidx++) { int lidx = uidx + OutputInterfaceLength; networkDef.AddConnection(new ConnectionIndex(uidx, lidx), new NeuralConnection()); } } entryIdx++; } return networkDef; }