/// <summary> /// Create a template of a PhenotypeNetwork, to use on sensing adjacent creatures. /// </summary> /// <param name="phenoNetEditor">Wrapper for PhenotypeNetwork.</param> /// <param name="layer">Layer in which network exists (probably 0).</param> /// <param name="name">Name of network.</param> /// <param name="hiddenNodesPerLayer">Nodes per hidden layer.</param> /// <param name="layersHiddenNodes">Number of hidden layers in the network.</param> /// <param name="outputActionNames">Names of output actions, whose output networks will be connected to this network.</param> /// <param name="hiddenNodeActiv">The type of activation function used by the hidden nodes.</param> /// <param name="outputNodeActiv">The type of activation function used by the output nodes. Note: the output of this function should be in the range [0,1].</param> public static void createPhenotypeNet(PhenotypeNetworkEditor phenoNetEditor, int layer, string name, int hiddenNodesPerLayer, int layersHiddenNodes, List <string> outputActionNames, ActivationBehaviorTypes hiddenNodeActiv, ActivationBehaviorTypes outputNodeActiv) { phenoNetEditor.setInLayer(layer); // called by default with index of layer user clicked phenoNetEditor.setName(name); phenoNetEditor.createInputNodes(); // set index of output layer based on hidden nodes int outputLayer = layersHiddenNodes + 1; // for every hidden layer for (int i = 0; i < layersHiddenNodes; i++) { phenoNetEditor.insertNewLayer(i + 1); // add every node in that layer for (int j = 0; j < hiddenNodesPerLayer; j++) { makeHiddenNode(phenoNetEditor, hiddenNodeActiv, i + 1); } } for (int i = 0; i < outputActionNames.Count; i++) { makeOutputNode(phenoNetEditor, outputNodeActiv, outputActionNames[i], outputLayer); } }
public void setActivationFunction(ActivationBehaviorTypes activType) { switch (activType) { case ActivationBehaviorTypes.LogisticAB: hiddenNode.setActivBehavior(new LogisticActivBehavior()); break; case ActivationBehaviorTypes.EmptyAB: hiddenNode.setActivBehavior(new EmptyActivBehavior()); break; case ActivationBehaviorTypes.LogWithNeg: hiddenNode.setActivBehavior(new LogisticWithNegActivBehav()); break; case ActivationBehaviorTypes.Tanh: hiddenNode.setActivBehavior(new TanhActivBehav()); break; default: Debug.LogError("Activation function type not found."); break; } }
/// <summary> /// Add a hidden node to a particular network. /// </summary> /// <param name="netCreator">Wrapper for Network.</param> /// <param name="activationType">Activation type for hidden node.</param> /// <param name="layer">Layer in which hidden node is to be added.</param> public static void makeHiddenNode(NetworkEditor netCreator, ActivationBehaviorTypes activationType, int layer) { // user adds node to second layer NodeEditor nodeCreator = netCreator.addNode(layer); nodeCreator.setCreator(NodeCreatorType.hiddenNode); HiddenNodeEditor hne = (HiddenNodeEditor)nodeCreator.getNodeCreator(); hne.setActivationFunction(activationType); netCreator.saveNode(); // user clicks save on network creator }
/// <summary> /// Create a series of output network for different actions, but otherwise identical. /// </summary> /// <param name="ce">Creature wrapper object.</param> /// <param name="netLayer">Layer in which the output networks belong (probably last layer).</param> /// <param name="names">Names of output networks to be made (could be any name) and their associated actions (must use exact action names).</param> /// <param name="hiddenLayerNum">Number of hidden layers in the network.</param> /// <param name="nodesPerLayer">Nodes per hidden layer.</param> /// <param name="hiddenActiv">The type of activation function used by the hidden nodes.</param> /// <param name="outputActiv">The type of activation function used by the output nodes. Note: the output of this function should be in the range [0,1].</param> public static void createOutputNetworks(CreatureEditor ce, int netLayer, Dictionary <string, string> names, int hiddenLayerNum, int nodesPerLayer, ActivationBehaviorTypes hiddenActiv, ActivationBehaviorTypes outputActiv) { OutputNetworkEditor outNetCreator; foreach (string netName in names.Keys) { outNetCreator = (OutputNetworkEditor)ce.addNetwork(NetworkType.output); createOutputNetwork(outNetCreator, names[netName], netLayer, netName, ce.creature.actionPool[names[netName]], hiddenLayerNum, nodesPerLayer, hiddenActiv, outputActiv, ce.creature.networks); // user clicks save on creature creator ce.saveNetwork(); } }
/// <summary> /// Create an output network (a network that decides on wether or not to take an action. /// </summary> /// <param name="outNetEditor">OutputNetwork wrapper.</param> /// <param name="outputAction">Name of the action associated with this network.</param> /// <param name="layer">The layer of this network's Dictionary in the List of Dictionaries of networks.</param> /// <param name="name">The name of the network.</param> /// <param name="action">Action that is associated with this output network.</param> /// <param name="hiddenLayerNum">Number of hidden layers in the network.</param> /// <param name="nodesPerLayer">Nodes per hidden layer.</param> /// <param name="hiddenActiv">The type of activation function used by the hidden nodes.</param> /// <param name="outputActiv">The type of activation function used by the output nodes. Note: the output of this function should be in the range [0,1].</param> /// <param name="networks">The networks of which this network is a part.</param> public static void createOutputNetwork(OutputNetworkEditor outNetEditor, string outputAction, int layer, string name, Action action, int hiddenLayerNum, int nodesPerLayer, ActivationBehaviorTypes hiddenActiv, ActivationBehaviorTypes outputActiv, List <Dictionary <string, Network> > networks) { // network added to second layer of networks outNetEditor.setInLayer(layer); // called by default with index of layer user clicked outNetEditor.setName(name); outNetEditor.setOutputAction(action); // for every network in previous layer foreach (string key in networks[layer - 1].Keys) { List <List <Node> > net = networks[layer - 1][key].net; int lastLayer = net.Count - 1; // for every node in the final layer of that network for (int i = 0; i < net[lastLayer].Count; i++) { OutputNode node = (OutputNode)net[lastLayer][i]; // if the node's action is the same as output action: if (node.action.name.Equals(outputAction)) { // create inner input node to that node makeInnerInputNode(outNetEditor, 0, key, layer - 1, i); // TODO: automate this linking processes } } } int outputLayer = hiddenLayerNum + 1; // for every hidden layer for (int i = 0; i < hiddenLayerNum; i++) { outNetEditor.insertNewLayer(i + 1); // add every node in that layer for (int j = 0; j < nodesPerLayer; j++) { makeHiddenNode(outNetEditor, hiddenActiv, i + 1); } } /* Node outNet 1,0 */ makeOutputNode(outNetEditor, outputActiv, outputAction, outputLayer); }
/// <summary> /// Create a node that connects the networks to actions. These nodes belong in the last layer of the last networks. /// </summary> /// <param name="netCreator">Network wrapper.</param> /// <param name="activationType">Activation type: should have an output in the range: [0,1] to be associated with a probability.</param> /// <param name="action">Action that the node is associated with.</param> /// <param name="layer">Layer in which to place node (final layer).</param> public static void makeOutputNode(NetworkEditor netCreator, ActivationBehaviorTypes activationType, string action, int layer) { // user adds node to second layer NodeEditor nodeCreator = netCreator.addNode(layer); nodeCreator.setCreator(NodeCreatorType.outputNodeCreator); OutputNodeEditor onc = (OutputNodeEditor)nodeCreator.getNodeCreator(); if (!netCreator.parentCreatureCreator.creature.actionPool.ContainsKey(action)) { Debug.LogError("invalid action key for output node"); } else { Action a = netCreator.parentCreatureCreator.creature.actionPool[action]; onc.setAction(a); onc.setActivationFunction(activationType); netCreator.saveNode(); } // user clicks save on network creator }
/// <summary> /// Create a network that senses some or all of the creature's internal resource levels. /// </summary> /// <param name="netCreator">Network wrapper.</param> /// <param name="layer">Layer of network (probably 0).</param> /// <param name="name">Name of network.</param> /// <param name="resourcesToSense">A list of the internal resources that the network should sense.</param> /// <param name="outputActions">A list of the output actions that should be associated with this network (through output nodes connected to output networks).</param> /// <param name="hiddenLayerNum">Number of hidden layers.</param> /// <param name="nodesPerLayer">Number of nodes per hidden layer.</param> /// <param name="hiddenActiv">Activation function for hidden nodes.</param> /// <param name="outputActiv">Activation function for output nodes.</param> public static void makeInternalInputNetwork(NetworkEditor netCreator, int layer, string name, List <string> resourcesToSense, List <string> outputActions, int hiddenLayerNum, int nodesPerLayer, ActivationBehaviorTypes hiddenActiv, ActivationBehaviorTypes outputActiv) { netCreator.setInLayer(layer); // called by default with index of layer user clicked netCreator.setName(name); // for every resource for (int i = 0; i < resourcesToSense.Count; i++) { makeInternalResourceInputNode(netCreator, resourcesToSense[i]); } int outputLayer = hiddenLayerNum + 1; // for every hidden layer for (int i = 0; i < hiddenLayerNum; i++) { netCreator.insertNewLayer(i + 1); // add every node in that layer for (int j = 0; j < nodesPerLayer; j++) { makeHiddenNode(netCreator, hiddenActiv, i + 1); } } for (int i = 0; i < outputActions.Count; i++) { makeOutputNode(netCreator, outputActiv, outputActions[i], outputLayer); } }