Пример #1
0
        public void Train(Dataset dataset, ILoss loss, IOptimizer optimizer, int batchSize, int nEpoches, double minError, Dataset valDataset, IMetric metric, bool shuffle = true)
        {
            if (dataset.InputShape != InputShape)
            {
                throw new ShapeMismatchException($"{nameof(dataset)} {nameof(dataset.InputShape)}");
            }

            if (dataset.TargetShape != OutputShape)
            {
                throw new ShapeMismatchException($"{nameof(dataset)} {nameof(dataset.TargetShape)}");
            }

            if (valDataset.InputShape != InputShape)
            {
                throw new ShapeMismatchException($"{nameof(valDataset)} {nameof(dataset.InputShape)}");
            }

            if (valDataset.TargetShape != OutputShape)
            {
                throw new ShapeMismatchException($"{nameof(valDataset)} {nameof(dataset.TargetShape)}");
            }

            ClearCache();

            double valError = Validate(valDataset, metric);
            int    epoch;

            OnStart?.Invoke(valError);

            for (epoch = 0; epoch < nEpoches; epoch++)
            {
                if (valError <= minError)
                {
                    break;
                }

                if (shuffle)
                {
                    dataset.Shuffle();
                }

                dataset.ForEach((D, index) =>
                {
                    Forward(D.Inputs, true);
                    CalcGrads(loss, D.Targets);
                    optimizer.UpdateEpoch(epoch);
                    Optimize(optimizer);

                    if (index % batchSize == 0)
                    {
                        Update();

                        OnBatch?.Invoke(index / batchSize);
                    }
                });

                valError = Validate(valDataset, metric);

                OnEpoch?.Invoke(epoch, valError);
            }

            OnFinish?.Invoke(epoch, valError);
        }