public NeuralNetwork(int intendedTrainingCnt, double weightRescaleFactor, double learningRate, double momentum, bool showNNUI, params object[] layersData)
        {
            layers      = new List <Layer>();
            neurons     = new Dictionary <int, Neuron>();
            connections = new Dictionary <int, Connection>();

            args = new NeuralNetworkArgs();
            args.intendedTrainingCnt = intendedTrainingCnt;
            args.layersData          = layersData;
            args.learningRate        = learningRate;
            args.momentum            = momentum;
            this.learningRate        = learningRate;
            this.momentum            = momentum;
            learningRateT            = learningRate;
            momentumT = momentum;

            xAxisData = new Queue <double>();
            yAxisData = new Queue <double>();
            ui        = new NeuralNetworkUI(CallbackHandler);
            ui.AddToChart(ref xAxisData, ref yAxisData);
            UIThread = new Thread(ui.StartUI);
            if (showNNUI)
            {
                UIThread.Start();
            }
            ui.SetLearningRate(learningRate.ToString());
            ui.SetMomentum(momentum.ToString());

            Layer.ConstructLayers(layersData, ref layers, ref neurons, ref neuronCounter, ref connections, ref connectionCounter, learningRate, weightRescaleFactor);
            foreach (Layer layer in layers)
            {
                RegisterOutput("Count Neurons : " + layer.cntNeurons);
            }

            RegisterOutput("Neural Network Initialized");
        }
        public static NeuralNetwork Load(string filePath, bool showNNUI = false)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(filePath);
            }
            catch
            {
                throw new Exception("Invalid filepath given to NeuralNetwork.Load() !");
            }

            int               trainingCounter;
            int               layerCnt     = 0;
            double            learningRate = 0;
            NeuralNetworkArgs args         = new NeuralNetworkArgs();

            string basePath = "NeuralNetwork/";

            int.TryParse(XPathValue(basePath + "@TrainingDone", ref doc), out trainingCounter);
            int.TryParse(XPathValue(basePath + "@IndendedTrainingCnt", ref doc), out args.intendedTrainingCnt);
            double.TryParse(XPathValue(basePath + "@LearningRate", ref doc), out args.learningRate);
            double.TryParse(XPathValue(basePath + "@Momentum", ref doc), out args.momentum);
            basePath += "Layers/";

            int.TryParse(XPathValue(basePath + "@Count", ref doc), out layerCnt);
            args.layersData = new object[layerCnt];

            basePath += "Layer[@Index='{0}']/@{1}";
            XmlNodeList layerList = doc.SelectNodes("NeuralNetwork/Layers/Layer");

            for (int i = 0; i < layerCnt; i++)
            {
                XmlNode layerNode = layerList[i];
                switch (layerNode.Attributes["Type"].Value)
                {
                case "RELU":
                    LayerData.RELU reluLayer = new LayerData.RELU();
                    args.layersData[i] = reluLayer;
                    break;

                case "MAXPOOL":
                    LayerData.MaxPool maxpoolLayer = new LayerData.MaxPool();
                    int.TryParse(layerNode.Attributes["Size"].Value, out maxpoolLayer.size);
                    int.TryParse(layerNode.Attributes["Stride"].Value, out maxpoolLayer.stride);
                    args.layersData[i] = maxpoolLayer;
                    break;

                case "FULLYCONNECTED":
                    LayerData.FullyConnected fullyLayer = new LayerData.FullyConnected();
                    int.TryParse(layerNode.Attributes["Neurons"].Value, out fullyLayer.cntNeurons);
                    Enum.TryParse <TransferFuncType>(layerNode.Attributes["NeuronType"].Value, out fullyLayer.tFuncType);
                    args.layersData[i] = fullyLayer;
                    break;

                case "CONVOLUTIONAL":
                    LayerData.Convolutional convolutionalLayer = new LayerData.Convolutional();
                    int.TryParse(layerNode.Attributes["Stride"].Value, out convolutionalLayer.stride);
                    bool.TryParse(layerNode.Attributes["ZeroPadding"].Value, out convolutionalLayer.padding);
                    XmlDocument filterXml = new XmlDocument();
                    filterXml.LoadXml(layerNode.OuterXml);
                    XmlNodeList filterList = filterXml.SelectNodes("Layer/Filters/Filter");
                    convolutionalLayer.filters = new int[filterList.Count];
                    int j = 0;
                    foreach (XmlNode filterNode in filterList)
                    {
                        int.TryParse(filterNode.Attributes["Size"].Value, out convolutionalLayer.filters[j++]);
                    }
                    args.layersData[i] = convolutionalLayer;
                    break;

                default:
                    throw new Exception("Invalid Layer Type Entry Found!!!");
                }
            }

            NeuralNetwork nn = new NeuralNetwork(args.intendedTrainingCnt, 1, args.learningRate, args.momentum, showNNUI, args.layersData);

            int.TryParse(XPathValue("NeuralNetwork/@TrainingDone", ref doc), out nn.trainingCounter);

            nn.RegisterOutput("Loading Neurons");
            basePath = "NeuralNetwork/Neurons/Neuron[@Index='{0}']/@Bias";
            int neuronCnt;

            int.TryParse(XPathValue("NeuralNetwork/Neurons/@Count", ref doc), out neuronCnt);
            for (int i = 0; i < neuronCnt; i++)
            {
                double.TryParse(XPathValue(string.Format(basePath, i.ToString()), ref doc), out nn.neurons[i].bias);
            }
            nn.RegisterOutput("Loading Connections");
            basePath = "NeuralNetwork/Connections/Connection[@Index='{0}']/@{1}";

            XmlNodeList connectionList = doc.SelectNodes("NeuralNetwork/Connections/Connection");

            foreach (XmlNode connection in connectionList)
            {
                int idx, src, dest;
                int.TryParse(connection.Attributes["Index"].Value, out idx);
                int.TryParse(connection.Attributes["Source"].Value, out src);
                int.TryParse(connection.Attributes["Destination"].Value, out dest);
                double.TryParse(connection.Attributes["Weight"].Value, out nn.connections[idx].weight);
                double.TryParse(connection.Attributes["PreviousWeightDelta"].Value, out nn.connections[idx].previousWeightDelta);
                double.TryParse(connection.Attributes["LearningRate"].Value, out nn.connections[idx].learningRate);
                nn.connections[idx].srcDest[src] = dest;
            }
            nn.RegisterOutput("Neural Network : " + XPathValue("NeuralNetwork/@Name", ref doc) + "Loaded Successfully : )");
            doc = null;
            return(nn);
        }