/// <summary> /// Create a sandwich substrate. A sandwich has an input layer connected /// directly to an output layer, both are square. /// </summary> /// <param name="inputEdgeSize">The input edge size.</param> /// <param name="outputEdgeSize">The output edge size.</param> /// <returns>The substrate.</returns> public static Substrate factorSandwichSubstrate(int inputEdgeSize, int outputEdgeSize) { Substrate result = new Substrate(3); double inputTick = 2.0 / inputEdgeSize; double outputTick = 2.0 / inputEdgeSize; double inputOrig = -1.0 + (inputTick / 2.0); double outputOrig = -1.0 + (inputTick / 2.0); // create the input layer for (int row = 0; row < inputEdgeSize; row++) { for (int col = 0; col < inputEdgeSize; col++) { SubstrateNode inputNode = result.CreateInputNode(); inputNode.Location[0] = -1; inputNode.Location[1] = inputOrig + (row * inputTick); inputNode.Location[2] = inputOrig + (col * inputTick); } } // create the output layer (and connect to input layer) for (int orow = 0; orow < outputEdgeSize; orow++) { for (int ocol = 0; ocol < outputEdgeSize; ocol++) { SubstrateNode outputNode = result.CreateOutputNode(); outputNode.Location[0] = 1; outputNode.Location[1] = outputOrig + (orow * outputTick); outputNode.Location[2] = outputOrig + (ocol * outputTick); // link this output node to every input node foreach (SubstrateNode inputNode in result.InputNodes) { result.CreateLink(inputNode, outputNode); } } } return(result); }
/// <inheritdoc/> public IMLMethod Decode(NEATPopulation pop, Substrate.Substrate substrate, IGenome genome) { // obtain the CPPN NEATCODEC neatCodec = new NEATCODEC(); NEATNetwork cppn = (NEATNetwork)neatCodec.Decode(genome); List <NEATLink> linkList = new List <NEATLink>(); IActivationFunction[] afs = new IActivationFunction[substrate.NodeCount]; IActivationFunction af = new ActivationSteepenedSigmoid(); // all activation functions are the same for (int i = 0; i < afs.Length; i++) { afs[i] = af; } double c = this.MaxWeight / (1.0 - this.MinWeight); BasicMLData input = new BasicMLData(cppn.InputCount); // First create all of the non-bias links. foreach (SubstrateLink link in substrate.Links) { SubstrateNode source = link.Source; SubstrateNode target = link.Target; int index = 0; foreach (double d in source.Location) { input.Data[index++] = d; } foreach (double d in target.Location) { input.Data[index++] = d; } IMLData output = cppn.Compute(input); double weight = output[0]; if (Math.Abs(weight) > this.MinWeight) { weight = (Math.Abs(weight) - this.MinWeight) * c * Math.Sign(weight); linkList.Add(new NEATLink(source.ID, target.ID, weight)); } } // now create biased links input.Clear(); int d2 = substrate.Dimensions; IList <SubstrateNode> biasedNodes = substrate.GetBiasedNodes(); foreach (SubstrateNode target in biasedNodes) { for (int i = 0; i < d2; i++) { input.Data[d2 + i] = target.Location[i]; } IMLData output = cppn.Compute(input); double biasWeight = output[1]; if (Math.Abs(biasWeight) > this.MinWeight) { biasWeight = (Math.Abs(biasWeight) - this.MinWeight) * c * Math.Sign(biasWeight); linkList.Add(new NEATLink(0, target.ID, biasWeight)); } } // check for invalid neural network if (linkList.Count == 0) { return(null); } linkList.Sort(); NEATNetwork network = new NEATNetwork(substrate.InputCount, substrate.OutputCount, linkList, afs); network.ActivationCycles = substrate.ActivationCycles; return(network); }
/// <summary> /// Constructs with the specified source and target substrate nodes. /// </summary> public SubstrateConnection(SubstrateNode srcNode, SubstrateNode tgtNode) { _srcNode = srcNode; _tgtNode = tgtNode; }
/// <summary> /// /// </summary> /// <param name="substrateXml"></param> /// <param name="substrateSettingsXml"></param> /// <param name="multispatial"></param> /// <returns></returns> public static ISubstrate ReadSubstrateFromXml(XmlElement substrateXml, XmlElement substrateSettingsXml) { var activationFunction = CreateActivationFunctionFromString(XmlUtils.GetValueAsString(substrateSettingsXml, "Function")); var weightThreshold = XmlUtils.TryGetValueAsDouble(substrateSettingsXml, "WeightThreshold") ?? 0.2; var maxWeight = XmlUtils.TryGetValueAsDouble(substrateSettingsXml, "MaxWeight") ?? 5.0; bool multispatial = XmlUtils.TryGetValueAsBool(substrateSettingsXml, "Multispatial") ?? false; bool leo = XmlUtils.TryGetValueAsBool(substrateSettingsXml, "Leo") ?? false; var layerlist = new List <SubstrateNodeSet>(); var nodes = new Dictionary <uint, SubstrateNode>(); uint nodeid = 1; foreach (XmlElement layer in substrateXml.GetElementsByTagName("Layer")) { SubstrateNodeSet.LayerType type; if (!Enum.TryParse(layer.GetAttribute("type"), out type)) { throw new Exception("Layer type must be defined as Input/Output/Hidden"); } var tmp = new SubstrateNodeSet(layer.ChildNodes.Count, type); foreach (XmlNode n in layer.ChildNodes) { if (n is XmlComment) { continue; } var node = (XmlElement)n; var tmpNode = new SubstrateNode(nodeid, Array.ConvertAll(node.InnerText.Split(','), double.Parse)); tmp.NodeList.Add(tmpNode); nodes.Add(nodeid, tmpNode); nodeid++; } layerlist.Add(tmp); } XmlNodeList mappings = substrateXml.GetElementsByTagName("Mapping"); XmlNodeList connections = substrateXml.GetElementsByTagName("Connection"); ISubstrate retval; if (connections.Count > 0) { var connectionList = new List <SubstrateConnection>(); foreach (XmlElement connection in connections) { var ids = Array.ConvertAll(connection.InnerText.Split(','), uint.Parse); connectionList.Add(new SubstrateConnection(nodes[ids[0]], nodes[ids[1]])); } retval = multispatial ? (ISubstrate) new MultiSpatialSubstrate(layerlist, activationFunction, 0, weightThreshold, maxWeight, connectionList) : new Substrate(layerlist, activationFunction, 0, weightThreshold, maxWeight, connectionList); } else if (mappings.Count > 0) { var mappingList = new List <NodeSetMapping>(); foreach (XmlElement mapping in mappings) { var ids = Array.ConvertAll(mapping.InnerText.Split(','), int.Parse); double maxDist; double?maxDistN = null; if (double.TryParse(mapping.GetAttribute("maxDist"), out maxDist)) { maxDistN = maxDist; } mappingList.Add(NodeSetMapping.Create(ids[0], ids[1], maxDistN)); } retval = multispatial ? (ISubstrate) new MultiSpatialSubstrate(layerlist, activationFunction, 0, weightThreshold, maxWeight, mappingList) : new Substrate(layerlist, activationFunction, 0, weightThreshold, maxWeight, mappingList); } else { throw new XmlException("Faulty substrate definition, at least one Mapping or Connection element must be defined."); } retval.Leo = leo; return(retval); }