/// <summary> /// Create a feedforward freeform neural network. /// </summary> /// <param name="input">The input count.</param> /// <param name="hidden1">The first hidden layer count, zero if none.</param> /// <param name="hidden2">The second hidden layer count, zero if none.</param> /// <param name="output">The output count.</param> /// <param name="af">The activation function.</param> /// <returns>The newly crated network.</returns> public static FreeformNetwork CreateFeedforward(int input, int hidden1, int hidden2, int output, IActivationFunction af) { var network = new FreeformNetwork(); IFreeformLayer lastLayer = network.CreateInputLayer(input); IFreeformLayer currentLayer; if (hidden1 > 0) { currentLayer = network.CreateLayer(hidden1); network.ConnectLayers(lastLayer, currentLayer, af, 1.0, false); lastLayer = currentLayer; } if (hidden2 > 0) { currentLayer = network.CreateLayer(hidden2); network.ConnectLayers(lastLayer, currentLayer, af, 1.0, false); lastLayer = currentLayer; } currentLayer = network.CreateOutputLayer(output); network.ConnectLayers(lastLayer, currentLayer, af, 1.0, false); network.Reset(); return(network); }
/// <summary> /// Connect layers from a BasicNetwork. Used internally only. /// </summary> /// <param name="network">The BasicNetwork.</param> /// <param name="fromLayerIdx">The from layer index.</param> /// <param name="source">The from layer.</param> /// <param name="target">The target.</param> private void ConnectLayersFromBasic(BasicNetwork network, int fromLayerIdx, IFreeformLayer source, IFreeformLayer target) { for (int targetNeuronIdx = 0; targetNeuronIdx < target.Count; targetNeuronIdx++) { for (int sourceNeuronIdx = 0; sourceNeuronIdx < source.Count; sourceNeuronIdx++) { IFreeformNeuron sourceNeuron = source.Neurons[sourceNeuronIdx]; IFreeformNeuron targetNeuron = target.Neurons[targetNeuronIdx]; // neurons with no input (i.e. bias neurons) if (targetNeuron.InputSummation == null) { continue; } IFreeformConnection connection = _connectionFactory .Factor(sourceNeuron, targetNeuron); sourceNeuron.AddOutput(connection); targetNeuron.AddInput(connection); double weight = network.GetWeight(fromLayerIdx, sourceNeuronIdx, targetNeuronIdx); connection.Weight = weight; } } }
/// <summary> /// Create the output layer. /// </summary> /// <param name="neuronCount">The neuron count.</param> /// <returns>The newly created output layer.</returns> public IFreeformLayer CreateOutputLayer(int neuronCount) { if (neuronCount < 1) { throw new FreeformNetworkError( "Output layer must have at least one neuron."); } _outputLayer = CreateLayer(neuronCount); return(_outputLayer); }
/// <summary> /// Construct an Elmann recurrent neural network. /// </summary> /// <param name="input">The input count.</param> /// <param name="hidden1">The hidden count.</param> /// <param name="output">The output count.</param> /// <param name="af">The activation function.</param> /// <returns>The newly created network.</returns> public static FreeformNetwork CreateElman(int input, int hidden1, int output, IActivationFunction af) { var network = new FreeformNetwork(); IFreeformLayer inputLayer = network.CreateInputLayer(input); IFreeformLayer hiddenLayer1 = network.CreateLayer(hidden1); IFreeformLayer outputLayer = network.CreateOutputLayer(output); network.ConnectLayers(inputLayer, hiddenLayer1, af, 1.0, false); network.ConnectLayers(hiddenLayer1, outputLayer, af, 1.0, false); network.CreateContext(hiddenLayer1, hiddenLayer1); network.Reset(); return(network); }
/// <summary> /// Create a hidden layer. /// </summary> /// <param name="neuronCount">The neuron count.</param> /// <returns>The newly created layer.</returns> public IFreeformLayer CreateLayer(int neuronCount) { if (neuronCount < 1) { throw new FreeformNetworkError( "Layer must have at least one neuron."); } IFreeformLayer result = _layerFactory.Factor(); // Add the neurons for this layer for (int i = 0; i < neuronCount; i++) { result.Add(_neuronFactory.FactorRegular(null)); } return(result); }
/// <summary> /// Connect two layers. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <param name="theActivationFunction">The activation function to use.</param> /// <param name="biasActivation">The bias activation to use.</param> /// <param name="isRecurrent">True, if this is a recurrent connection.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target, IActivationFunction theActivationFunction, double biasActivation, bool isRecurrent) { // create bias, if requested if (biasActivation > EncogFramework.DefaultDoubleEqual) { // does the source already have a bias? if (source.HasBias) { throw new FreeformNetworkError( "The source layer already has a bias neuron, you cannot create a second."); } IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.Activation = biasActivation; biasNeuron.IsBias = true; source.Add(biasNeuron); } // create connections foreach (IFreeformNeuron targetNeuron in target.Neurons) { // create the summation for the target IInputSummation summation = targetNeuron.InputSummation; // do not create a second input summation if (summation == null) { summation = _summationFactory.Factor(theActivationFunction); targetNeuron.InputSummation = summation; } // connect the source neurons to the target neuron foreach (IFreeformNeuron sourceNeuron in source.Neurons) { IFreeformConnection connection = _connectionFactory .Factor(sourceNeuron, targetNeuron); sourceNeuron.AddOutput(connection); targetNeuron.AddInput(connection); } } }
/// <summary> /// Create a context connection, such as those used by Jordan/Elmann. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <returns>The newly created context layer.</returns> public IFreeformLayer CreateContext(IFreeformLayer source, IFreeformLayer target) { const double biasActivation = 0.0; if (source.Neurons[0].Outputs.Count < 1) { throw new FreeformNetworkError( "A layer cannot have a context layer connected if there are no other outbound connections from the source layer. Please connect the source layer somewhere else first."); } IActivationFunction activatonFunction = source.Neurons[0].InputSummation .ActivationFunction; // first create the context layer IFreeformLayer result = _layerFactory.Factor(); for (int i = 0; i < source.Count; i++) { IFreeformNeuron neuron = source.Neurons[i]; if (neuron.IsBias) { IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.IsBias = true; biasNeuron.Activation = neuron.Activation; result.Add(biasNeuron); } else { IFreeformNeuron contextNeuron = _neuronFactory .FactorContext(neuron); result.Add(contextNeuron); } } // now connect the context layer to the target layer ConnectLayers(result, target, activatonFunction, biasActivation, false); return(result); }
public void Execute(IExampleInterface app) { // create a neural network, without using a factory var network = new FreeformNetwork(); IFreeformLayer inputLayer = network.CreateInputLayer(2); IFreeformLayer hiddenLayer1 = network.CreateLayer(3); IFreeformLayer outputLayer = network.CreateOutputLayer(1); network.ConnectLayers(inputLayer, hiddenLayer1, new ActivationSigmoid(), 1.0, false); network.ConnectLayers(hiddenLayer1, outputLayer, new ActivationSigmoid(), 1.0, false); network.Reset(); // create training data IMLDataSet trainingSet = new BasicMLDataSet(XORInput, XORIdeal); EncogUtility.TrainToError(network, trainingSet, 0.01); EncogUtility.Evaluate(network, trainingSet); EncogFramework.Instance.Shutdown(); }
/// <summary> /// Connect layers from a BasicNetwork. Used internally only. /// </summary> /// <param name="network">The BasicNetwork.</param> /// <param name="fromLayerIdx">The from layer index.</param> /// <param name="source">The from layer.</param> /// <param name="target">The target.</param> private void ConnectLayersFromBasic(BasicNetwork network, int fromLayerIdx, IFreeformLayer source, IFreeformLayer target) { for (int targetNeuronIdx = 0; targetNeuronIdx < target.Count; targetNeuronIdx++) { for (int sourceNeuronIdx = 0; sourceNeuronIdx < source.Count; sourceNeuronIdx++) { IFreeformNeuron sourceNeuron = source.Neurons[sourceNeuronIdx]; IFreeformNeuron targetNeuron = target.Neurons[targetNeuronIdx]; // neurons with no input (i.e. bias neurons) if (targetNeuron.InputSummation == null) { continue; } IFreeformConnection connection = _connectionFactory .Factor(sourceNeuron, targetNeuron); sourceNeuron.AddOutput(connection); targetNeuron.AddInput(connection); double weight = network.GetWeight(fromLayerIdx, sourceNeuronIdx, targetNeuronIdx); connection.Weight = weight; } } }
/// <summary> /// Create a context connection, such as those used by Jordan/Elmann. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <returns>The newly created context layer.</returns> public IFreeformLayer CreateContext(IFreeformLayer source, IFreeformLayer target) { const double biasActivation = 0.0; if (source.Neurons[0].Outputs.Count < 1) { throw new FreeformNetworkError( "A layer cannot have a context layer connected if there are no other outbound connections from the source layer. Please connect the source layer somewhere else first."); } IActivationFunction activatonFunction = source.Neurons[0].InputSummation .ActivationFunction; // first create the context layer IFreeformLayer result = _layerFactory.Factor(); for (int i = 0; i < source.Count; i++) { IFreeformNeuron neuron = source.Neurons[i]; if (neuron.IsBias) { IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.IsBias = true; biasNeuron.Activation = neuron.Activation; result.Add(biasNeuron); } else { IFreeformNeuron contextNeuron = _neuronFactory .FactorContext(neuron); result.Add(contextNeuron); } } // now connect the context layer to the target layer ConnectLayers(result, target, activatonFunction, biasActivation, false); return result; }
/// <summary> /// Create the output layer. /// </summary> /// <param name="neuronCount">The neuron count.</param> /// <returns>The newly created output layer.</returns> public IFreeformLayer CreateOutputLayer(int neuronCount) { if (neuronCount < 1) { throw new FreeformNetworkError( "Output layer must have at least one neuron."); } _outputLayer = CreateLayer(neuronCount); return _outputLayer; }
/// <summary> /// Connect two layers. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <param name="theActivationFunction">The activation function to use.</param> /// <param name="biasActivation">The bias activation to use.</param> /// <param name="isRecurrent">True, if this is a recurrent connection.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target, IActivationFunction theActivationFunction, double biasActivation, bool isRecurrent) { // create bias, if requested if (biasActivation > EncogFramework.DefaultDoubleEqual) { // does the source already have a bias? if (source.HasBias) { throw new FreeformNetworkError( "The source layer already has a bias neuron, you cannot create a second."); } IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.Activation = biasActivation; biasNeuron.IsBias = true; source.Add(biasNeuron); } // create connections foreach (IFreeformNeuron targetNeuron in target.Neurons) { // create the summation for the target IInputSummation summation = targetNeuron.InputSummation; // do not create a second input summation if (summation == null) { summation = _summationFactory.Factor(theActivationFunction); targetNeuron.InputSummation = summation; } // connect the source neurons to the target neuron foreach (IFreeformNeuron sourceNeuron in source.Neurons) { IFreeformConnection connection = _connectionFactory .Factor(sourceNeuron, targetNeuron); sourceNeuron.AddOutput(connection); targetNeuron.AddInput(connection); } } }
/// <summary> /// Connect two layers, assume bias activation of 1.0 and non-recurrent /// connection. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <param name="theActivationFunction">The activation function.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target, IActivationFunction theActivationFunction) { ConnectLayers(source, target, theActivationFunction, 1.0, false); }
/// <summary> /// Connect two layers. These layers will be connected with a TANH activation /// function in a non-recurrent way. A bias activation of 1.0 will be used, /// if needed. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target) { ConnectLayers(source, target, new ActivationTANH(), 1.0, false); }
/// <summary> /// Craete a freeform network from a basic network. /// </summary> /// <param name="network">The basic network to use.</param> public FreeformNetwork(BasicNetwork network) { if (network.LayerCount < 2) { throw new FreeformNetworkError( "The BasicNetwork must have at least two layers to be converted."); } // handle each layer IFreeformLayer previousLayer = null; for (int currentLayerIndex = 0; currentLayerIndex < network .LayerCount; currentLayerIndex++) { // create the layer IFreeformLayer currentLayer = _layerFactory.Factor(); // Is this the input layer? if (_inputLayer == null) { _inputLayer = currentLayer; } // Add the neurons for this layer for (int i = 0; i < network.GetLayerNeuronCount(currentLayerIndex); i++) { // obtain the summation object. IInputSummation summation = null; if (previousLayer != null) { summation = _summationFactory.Factor(network .GetActivation(currentLayerIndex)); } // add the new neuron currentLayer.Add(_neuronFactory.FactorRegular(summation)); } // Fully connect this layer to previous if (previousLayer != null) { ConnectLayersFromBasic(network, currentLayerIndex - 1, previousLayer, currentLayer); } // Add the bias neuron // The bias is added after connections so it has no inputs if (network.IsLayerBiased(currentLayerIndex)) { IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.IsBias = true; biasNeuron.Activation = network .GetLayerBiasActivation(currentLayerIndex); currentLayer.Add(biasNeuron); } // update previous layer previousLayer = currentLayer; } // finally, set the output layer. _outputLayer = previousLayer; }
/// <summary> /// Connect two layers. These layers will be connected with a TANH activation /// function in a non-recurrent way. A bias activation of 1.0 will be used, /// if needed. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target) { ConnectLayers(source, target, new ActivationTANH(), 1.0, false); }
/// <summary> /// Craete a freeform network from a basic network. /// </summary> /// <param name="network">The basic network to use.</param> public FreeformNetwork(BasicNetwork network) { if (network.LayerCount < 2) { throw new FreeformNetworkError( "The BasicNetwork must have at least two layers to be converted."); } // handle each layer IFreeformLayer previousLayer = null; for (int currentLayerIndex = 0; currentLayerIndex < network .LayerCount; currentLayerIndex++) { // create the layer IFreeformLayer currentLayer = _layerFactory.Factor(); // Is this the input layer? if (_inputLayer == null) { _inputLayer = currentLayer; } // Add the neurons for this layer for (int i = 0; i < network.GetLayerNeuronCount(currentLayerIndex); i++) { // obtain the summation object. IInputSummation summation = null; if (previousLayer != null) { summation = _summationFactory.Factor(network .GetActivation(currentLayerIndex)); } // add the new neuron currentLayer.Add(_neuronFactory.FactorRegular(summation)); } // Fully connect this layer to previous if (previousLayer != null) { ConnectLayersFromBasic(network, currentLayerIndex - 1, previousLayer, currentLayer); } // Add the bias neuron // The bias is added after connections so it has no inputs if (network.IsLayerBiased(currentLayerIndex)) { IFreeformNeuron biasNeuron = _neuronFactory .FactorRegular(null); biasNeuron.IsBias = true; biasNeuron.Activation = network .GetLayerBiasActivation(currentLayerIndex); currentLayer.Add(biasNeuron); } // update previous layer previousLayer = currentLayer; } // finally, set the output layer. _outputLayer = previousLayer; }
/// <summary> /// Connect two layers, assume bias activation of 1.0 and non-recurrent /// connection. /// </summary> /// <param name="source">The source layer.</param> /// <param name="target">The target layer.</param> /// <param name="theActivationFunction">The activation function.</param> public void ConnectLayers(IFreeformLayer source, IFreeformLayer target, IActivationFunction theActivationFunction) { ConnectLayers(source, target, theActivationFunction, 1.0, false); }