示例#1
0
            public IMatrix Execute(IMatrix error, ITrainingContext context, bool calculateOutput, INeuralNetworkUpdateAccumulator updateAccumulator)
            {
                var matrixList = error.AsIndexable().Columns.Select(v => v.ToArray()).ToList();

                var newMatrixList = new List <IMatrix>();
                Tuple <int, int> newIndex;

                for (var i = 0; i < matrixList.Count; i++)
                {
                    var matrix = matrixList[i];
                    var table  = _indexPosList[i];

                    newMatrixList.Add(_lap.Create(_rows, _columns, (x, y) => {
                        if (table.TryGetValue(Tuple.Create(x, y), out newIndex))
                        {
                            var newIndex2 = newIndex.Item1 * _newRows + newIndex.Item2;
                            return(matrix[newIndex2]);
                        }
                        return(0f);
                    }));
                }
                using (var tensor = _lap.CreateTensor(newMatrixList)) {
                    var ret = tensor.ConvertToMatrix();
                    foreach (var item in newMatrixList)
                    {
                        item.Dispose();
                    }
                    return(ret);
                }
            }
示例#2
0
 float _DifferenceCost(IMatrix m1, IMatrix m2)
 {
     return(m1.AsIndexable().Rows
            .Zip(m2.AsIndexable().Rows, (r1, r2) => _costFunction.Compute(r1, r2))
            .Average()
            );
 }
示例#3
0
        public IReadOnlyList <IFeedForwardOutput> Execute(ITrainingDataProvider data)
        {
            IMatrix curr = null;
            var     ret  = new List <IFeedForwardOutput>();

            foreach (var miniBatch in _GetMiniBatches(data, false, DEFAULT_BATCH_SIZE))
            {
                var garbage = new List <IMatrix>();
                garbage.Add(curr = miniBatch.Input);
                garbage.Add(miniBatch.ExpectedOutput);

                // feed forward
                foreach (var layer in _layer)
                {
                    garbage.Add(curr = layer.FeedForward(curr, false));
                }

                // break the output into rows
                ret.AddRange(curr.AsIndexable().Rows.Zip(miniBatch.ExpectedOutput.AsIndexable().Rows, (a, e) => new FeedForwardOutput(a, e)));

                // clear memory
                garbage.ForEach(m => m.Dispose());
            }
            return(ret);
        }
示例#4
0
        public IEnumerable <IIndexableVector[]> ExecuteToLayer(ITrainingDataProvider data, int layerDepth)
        {
            IMatrix curr = null;

            foreach (var miniBatch in _GetMiniBatches(data, false, DEFAULT_BATCH_SIZE))
            {
                var garbage = new List <IMatrix>();
                garbage.Add(curr = miniBatch.Input);
                garbage.Add(miniBatch.ExpectedOutput);

                // feed forward
                for (var i = 0; i < layerDepth; i++)
                {
                    var layer = _layer[i];
                    garbage.Add(curr = layer.FeedForward(curr, false));
                }

                var ret = curr.AsIndexable().Rows.ToList();

                // clear memory
                garbage.ForEach(m => m.Dispose());

                yield return(ret.ToArray());
            }
        }
示例#5
0
        public void Train(ITrainingDataProvider trainingData, int numEpochs, ITrainingContext context)
        {
            IMatrix curr = null;
            var     additionalBackpropagation = trainingData as ICanBackpropagate;

            for (int i = 0; i < numEpochs && context.ShouldContinue; i++)
            {
                context.StartEpoch(trainingData.Count);
                trainingData.StartEpoch();
                var batchErrorList = new List <double>();

                // iterate over each mini batch
                foreach (var miniBatch in _GetMiniBatches(trainingData, _stochastic, context.MiniBatchSize))
                {
                    var garbage = new List <IMatrix>();
                    garbage.Add(curr = miniBatch.Input);
                    _lap.PushLayer();

                    // set up the layer stack
                    var layerStack = new Stack <ICanBackpropagate>();
                    if (additionalBackpropagation != null)
                    {
                        layerStack.Push(additionalBackpropagation);
                    }

                    // feed forward
                    foreach (var layer in _layer)
                    {
                        garbage.Add(curr = layer.FeedForward(curr, true));
                        layerStack.Push(layer);
                    }

                    // calculate the error against the training examples
                    using (var expectedOutput = miniBatch.ExpectedOutput) {
                        garbage.Add(curr = context.ErrorMetric.CalculateDelta(curr, expectedOutput));

                        // calculate the training error for this mini batch
                        if (_calculateTrainingError)
                        {
                            batchErrorList.Add(curr.AsIndexable().Values.Select(v => Math.Pow(v, 2)).Average() / 2);
                        }

                        // backpropagate the error
                        while (layerStack.Any())
                        {
                            var currentLayer = layerStack.Pop();
                            garbage.Add(curr = currentLayer.Backpropagate(curr, context, layerStack.Any()));
                        }
                    }

                    // clear memory
                    context.EndBatch();
                    garbage.ForEach(m => m?.Dispose());
                    _lap.PopLayer();
                }
                context.EndEpoch(_calculateTrainingError ? batchErrorList.Average() : 0f);
            }
        }
示例#6
0
        double _VerifyDerivatives(IMatrix activationDerivative)
        {
            const float epsilon    = 0.0001f;
            var         activation = _layerUpdater.Layer.Activation;

            return(_layerOutput.AsIndexable().Values.Zip(activationDerivative.AsIndexable().Values, (val, valD) => {
                var approximatedDerivative = (activation.Calculate(val + epsilon) - activation.Calculate(val - epsilon)) / (2 * epsilon);
                return Math.Abs(valD - approximatedDerivative);
            }).Average());
        }
示例#7
0
        void _TestNode(INode node, IMatrix forwardInput, IMatrix expectedForwardOutput, IMatrix backwardInput, IMatrix expectedBackwardOutput)
        {
            var context = new TestingContext(_cpu);
            var matrix  = forwardInput.AsIndexable();

            context.Data = matrix.AsGraphData();
            node.ExecuteForward(context, 0);

            var output       = context.Forward.First();
            var outputMatrix = output.Item1.Data.GetMatrix();

            FloatingPointHelper.AssertEqual(outputMatrix.AsIndexable(), expectedForwardOutput.AsIndexable());

            output.Item2.Backward(null, backwardInput.Clone().AsGraphData(), context, new[] { node });
            var bpOutput = context.Backward.First().Item1.GetMatrix();

            FloatingPointHelper.AssertEqual(bpOutput.AsIndexable(), expectedBackwardOutput.AsIndexable());
        }
示例#8
0
        public IReadOnlyList <IReadOnlyList <IIndexableVector> > Cluster(int numIterations, Action <float> callback, float errorThreshold = 0.001f)
        {
            for (int i = 0; i < numIterations; i++)
            {
                using (var wh = _weights.Multiply(_features)) {
                    var cost = _DifferenceCost(_dataMatrix, wh);
                    callback(cost);
                    if (cost <= errorThreshold)
                    {
                        break;
                    }

                    using (var wT = _weights.Transpose())
                        using (var hn = wT.Multiply(_dataMatrix))
                            using (var wTw = wT.Multiply(_weights))
                                using (var hd = wTw.Multiply(_features))
                                    using (var fhn = _features.PointwiseMultiply(hn)) {
                                        _features.Dispose();
                                        _features = fhn.PointwiseDivide(hd);
                                    }

                    using (var fT = _features.Transpose())
                        using (var wn = _dataMatrix.Multiply(fT))
                            using (var wf = _weights.Multiply(_features))
                                using (var wd = wf.Multiply(fT))
                                    using (var wwn = _weights.PointwiseMultiply(wn)) {
                                        _weights.Dispose();
                                        _weights = wwn.PointwiseDivide(wd);
                                    }
                }
            }

            // weights gives cluster membership
            return(_weights.AsIndexable().Rows
                   .Select((c, i) => Tuple.Create(i, c.MaximumIndex()))
                   .GroupBy(d => d.Item2)
                   .Select(g => g.Select(d => _data[d.Item1]).ToArray())
                   .ToList()
                   );
        }