public PatternGeneratorResult <T> Process(IEnumerable <T> source) { List <T> elements = source.ToList(); var hash = new Dictionary <T, PatternItem <T> >(); foreach (var i in elements) { hash.Add(i, new PatternItem <T>(i)); } foreach (var pattern in Patterns) { var avaiable = pattern.GetSelector().Select(new WhereSelector <T>(x => !hash[x].IsProcessed).Select(elements)); foreach (var range in avaiable) { var processed = pattern.Apply(range); hash.AddNewKeys(processed, x => new PatternItem <T>(x)); if (pattern.IsUnique) { foreach (var i in processed) { hash[i].IsProcessed = true; } } OnBatch?.Invoke(range, processed); int index = elements.IndexOf(range.First()); elements.RemoveRange(index, range.Count()); elements.InsertRange(index, processed); // TODO probably replace with linked list } } var result = new PatternGeneratorResult <T>(); result.Processed = elements.Except(source).ToList(); result.Unprocessed = source.Except(elements).ToList(); return(result); }
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); }