public static (VectorND[] inputs, VectorND[] outputs) GetSquareSheets(double inputSize, double outputSize, int inputCountXY, int outputCountXY) { return ( inputs : Math2D.GetCells_WithinSquare(inputSize, inputCountXY). Select(o => new VectorND(o.center.X, o.center.Y, -1d)). ToArray(), outputs : Math2D.GetCells_WithinSquare(outputSize, outputCountXY). Select(o => new VectorND(o.center.X, o.center.Y, 1d)). ToArray() ); }
public TrackedItemHarness(double mapSize, double visionSize, double outputSize, int inputSizeXY, int outputSizeXY, double delayBetweenInstances) { MapSize = mapSize; VisionSize = visionSize; OutputSize = outputSize; InputSizeXY = inputSizeXY; InputCellCenters = Math2D.GetCells_WithinSquare(visionSize, InputSizeXY). Select(o => o.center). ToArray(); OutputSizeXY = outputSizeXY; OutputCellCenters = Math2D.GetCells_WithinSquare(outputSize, OutputSizeXY). Select(o => o.center). ToArray(); DelayBetweenInstances = delayBetweenInstances; }
// This is built from these two sources: //http://www.nashcoding.com/2010/10/29/tutorial-%E2%80%93-evolving-neural-networks-with-sharpneat-2-part-3/ //SharpNeat.Domains.BoxesVisualDiscrimination.BoxesVisualDiscriminationExperiment.CreateGenomeDecoder() //TODO: Instead of hardcoding input and output as 2D squares, the constructor should take enums for common shapes { Line, Square, Cube, CirclePerimiter, CircleArea, SphereShell, SphereFilled } public IGenomeDecoder <NeatGenome, IBlackBox> CreateGenomeDecoder(int inputSizeXY, int outputSizeXY) { int numInputs = inputSizeXY * inputSizeXY; int numOutputs = outputSizeXY * outputSizeXY; SubstrateNodeSet inputLayer = new SubstrateNodeSet(numInputs); SubstrateNodeSet outputLayer = new SubstrateNodeSet(numOutputs); // Each node in each layer needs a unique ID // Node IDs start at 1. (bias node is always zero) // The input nodes use ID range { 1, inputSize^2 } and // the output nodes are the next outputSize^2. uint inputId = 1; uint outputId = Convert.ToUInt32(numInputs + 1); var inputCells = Math2D.GetCells_WithinSquare(_inputSizeWorld, inputSizeXY); var outputCells = Math2D.GetCells_WithinSquare(_outputSizeWorld, outputSizeXY); for (int y = 0; y < inputSizeXY; y++) { for (int x = 0; x < inputSizeXY; x++) { inputId++; outputId++; Point inputPoint = inputCells[(y * inputSizeXY) + x].center; Point outputPoint = outputCells[(y * outputSizeXY) + x].center; inputLayer.NodeList.Add(new SubstrateNode(inputId, new double[] { inputPoint.X, inputPoint.Y, -1d })); outputLayer.NodeList.Add(new SubstrateNode(outputId, new double[] { outputPoint.X, outputPoint.Y, 1d })); } } List <SubstrateNodeSet> nodeSetList = new List <SubstrateNodeSet>(); nodeSetList.Add(inputLayer); nodeSetList.Add(outputLayer); //TODO: The two samples that I copied from have the same number of inputs and outputs. This mapping may be too simplistic when the counts are different // Define a connection mapping from the input layer to the output layer. List <NodeSetMapping> nodeSetMappingList = new List <NodeSetMapping>(); nodeSetMappingList.Add(NodeSetMapping.Create(0, 1, (double?)null)); // Construct the substrate using a steepened sigmoid as the phenome's // activation function. All weights under 0.2 will not generate // connections in the final phenome. Substrate substrate = new Substrate(nodeSetList, DefaultActivationFunctionLibrary.CreateLibraryCppn(), 0, 0.2, 5, nodeSetMappingList); // Create genome decoder. Decodes to a neural network packaged with // an activation scheme that defines a fixed number of activations per evaluation. IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder = new HyperNeatDecoder(substrate, _activationSchemeCppn, _activationScheme, false); return(genomeDecoder); }