public double Test(
            string filesPath,
            int dataCountInFile,
            int classCount,
            CancellationToken cancellation)
        {
            double accuracy = 0;

            for (int i = 0; i < dataCountInFile; ++i)
            {
                try
                {
                    var inputData   = BinaryFileProcessingHelper.GetInputData(filesPath, i).Result;
                    var input       = inputData.Item2;
                    var inputResult = PrepareInputResult(inputData.Item1, classCount);

                    accuracy += FeedForwardStep(0, input, inputResult).Item2;
                }
                catch (Exception ex)
                {
                    continue;
                }
            }

            return(accuracy);
        }
        public Tuple <List <double>, List <double> > SGDWholeFile(
            int epochs,
            double learningRate,
            int batchSize,
            double lossEps,
            string[] filesPath,
            int dataCountInFile,
            int classCount,
            CancellationToken cancellation)
        {
            Console.WriteLine("SGD CIFAR-10");

            var toReturn   = new List <double>();
            var toReturnAc = new List <double>();

            for (int i = 0; i < epochs; ++i)
            {
                for (int fileIndex = 0; fileIndex < filesPath.Length; ++fileIndex)
                {
                    var loss   = 0.0;
                    var losses = new List <double>();

                    var accuracy     = 0.0;
                    var accuracyList = new List <double>();

                    var inputResult = new double[classCount];

                    int idx = 0;
                    for (int k = 0; k < dataCountInFile; k++)
                    {
                        List <double[][]> input = new List <double[][]>();

                        try
                        {
                            var inputData = BinaryFileProcessingHelper.GetInputData(filesPath[fileIndex], k).Result;
                            input       = inputData.Item2;
                            inputResult = PrepareInputResult(inputData.Item1, classCount);
                        }
                        catch (Exception ex)
                        {
                            continue;
                        }

                        var stepResults = SGDStepCifar(learningRate, input, inputResult);

                        loss += stepResults;
                        idx++;

                        if (idx == 32)
                        {
                            loss /= 32;
                            Console.WriteLine($"Epoch - {i}, step - {k}, loss - {loss}, batch accuracy - {Accuracy.Sum()/32}");

                            toReturn.Add(Math.Abs(loss));
                            toReturnAc.Add(Math.Abs(Accuracy.Sum() / 32));
                            if (Math.Abs(loss) < lossEps)
                            {
                                break;
                            }

                            loss = 0;
                            idx  = 0;
                            Accuracy.Clear();
                        }

                        if (cancellation.IsCancellationRequested)
                        {
                            break;
                        }
                    }
                }
            }

            return(new Tuple <List <double>, List <double> >(toReturn, toReturnAc));
        }
        public async Task <Tuple <List <double>, List <double> > > MiniBatchSGDWholeFile(
            int epochs,
            double learningRate,
            int batchSize,
            double lossEps,
            string[] filesPath,
            int dataCountInFile,
            int classCount,
            CancellationToken cancellation)
        {
            Console.WriteLine("MINI-BATCH CIFAR-10");

            var toReturn   = new List <double>();
            var toReturnAc = new List <double>();

            for (int i = 0; i < epochs; ++i)
            {
                for (int fileIndex = 0; fileIndex < filesPath.Length; ++fileIndex)
                {
                    var batchCount = Convert.ToInt32(dataCountInFile / batchSize);

                    for (int j = 0; j < batchCount; j++)
                    {
                        var loss   = 0.0;
                        var losses = new List <double>();

                        var accuracy     = 0.0;
                        var accuracyList = new List <double>();

                        var outputLayerGradient = new double[Perceptron.OutputLayer.NeuronsCount];
                        var inputResult         = new double[classCount];

                        for (int k = 0; k < batchSize; k++)
                        {
                            List <double[][]> input = new List <double[][]>();

                            try
                            {
                                var inputData = await BinaryFileProcessingHelper.GetInputData(filesPath[fileIndex], k + j *batchSize);

                                input       = inputData.Item2;
                                inputResult = PrepareInputResult(inputData.Item1, classCount);
                            }
                            catch (Exception ex)
                            {
                                continue;
                            }

                            var stepResults = FeedForwardStep(learningRate, input, inputResult);
                            losses.Add(stepResults.Item1);
                            accuracyList.Add(stepResults.Item2);

                            outputLayerGradient.Add(Perceptron.GetOutputLayerGradient(inputResult));
                        }

                        outputLayerGradient.ForEach(item => item = item / batchSize);

                        BackwardStep(outputLayerGradient, learningRate, inputResult);

                        loss     = losses.Sum() / losses.Count;
                        accuracy = accuracyList.Sum() / accuracyList.Count;

                        Console.WriteLine($"Epoch - {i}, step - {j}, loss - {loss}, accuracy - {accuracy}");

                        toReturn.Add(Math.Abs(loss));
                        toReturnAc.Add(Math.Abs(accuracy));

                        if (Math.Abs(loss) < lossEps)
                        {
                            break;
                        }

                        if (cancellation.IsCancellationRequested)
                        {
                            break;
                        }
                    }
                }
            }

            return(new Tuple <List <double>, List <double> >(toReturn, toReturnAc));
        }