Пример #1
0
        public override void DoConvolution(Volume <float> filters, int pad, int stride, Volume <float> result)
        {
            var batchSize = this.Shape.GetDimension(3);

            var inputWidth  = this.Shape.GetDimension(0);
            var inputHeight = this.Shape.GetDimension(1);

            var outputWidth  = result.Shape.GetDimension(0);
            var outputHeight = result.Shape.GetDimension(1);
            var outputDepth  = result.Shape.GetDimension(2);

            var filterWidth  = filters.Shape.GetDimension(0);
            var filterHeight = filters.Shape.GetDimension(1);
            var filterDepth  = filters.Shape.GetDimension(2);

            for (var n = 0; n < batchSize; n++)
            {
                for (var depth = 0; depth < outputDepth; depth++)
                {
                    var y = -pad;
                    for (var ay = 0; ay < outputHeight; y += stride, ay++)
                    {
                        var x = -pad;
                        for (var ax = 0; ax < outputWidth; x += stride, ax++)
                        {
                            // convolve centered at this particular location
                            var a = 0.0f;
                            for (var fy = 0; fy < filterHeight; fy++)
                            {
                                var oy = y + fy; // coordinates in the original input array coordinates
                                for (var fx = 0; fx < filterWidth; fx++)
                                {
                                    var ox = x + fx;
                                    if (oy >= 0 && oy < inputHeight && ox >= 0 && ox < inputWidth)
                                    {
                                        for (var fd = 0; fd < filterDepth; fd++)
                                        {
                                            a += filters.Storage.Get(fx, fy, fd, depth) *
                                                 this.Storage.Get(ox, oy, fd, n);
                                        }
                                    }
                                }
                            }

                            result.Storage.Set(ax, ay, depth, n, a);
                        }
                    }
                }
            }
        }
Пример #2
0
        protected override void DoConvolutionGradient(Volume <float> filters, Volume <float> outputGradients,
                                                      Volume <float> inputGradient, Volume <float> filterGradient, int pad,
                                                      int stride)
        {
            inputGradient.Clear(); // zero out gradient wrt bottom data, we're about to fill it

            var batchSize = this.Shape.GetDimension(3);

            var inputWidth  = this.Shape.GetDimension(0);
            var inputHeight = this.Shape.GetDimension(1);

            var outputWidth  = outputGradients.Shape.GetDimension(0);
            var outputHeight = outputGradients.Shape.GetDimension(1);
            var outputDepth  = outputGradients.Shape.GetDimension(2);

            var filterWidth  = filters.Shape.GetDimension(0);
            var filterHeight = filters.Shape.GetDimension(1);
            var filterDepth  = filters.Shape.GetDimension(2);

            for (var n = 0; n < batchSize; n++)
            {
                for (var depth = 0; depth < outputDepth; depth++)
                {
                    var y = -pad;
                    for (var ay = 0; ay < outputHeight; y += stride, ay++)
                    {
                        // xyStride
                        var x = -pad;
                        for (var ax = 0; ax < outputWidth; x += stride, ax++)
                        {
                            // xyStride

                            // convolve centered at this particular location
                            var chainGradient = outputGradients.Get(ax, ay, depth, n);

                            // gradient from above, from chain rule
                            for (var fy = 0; fy < filterHeight; fy++)
                            {
                                var oy = y + fy; // coordinates in the original input array coordinates
                                for (var fx = 0; fx < filterWidth; fx++)
                                {
                                    var ox = x + fx;
                                    if (oy >= 0 && oy < inputHeight && ox >= 0 && ox < inputWidth)
                                    {
                                        for (var fd = 0; fd < filterDepth; fd++)
                                        {
                                            filterGradient.Storage.Set(fx, fy, fd, depth,
                                                                       filterGradient.Get(fx, fy, fd, depth) +
                                                                       Get(ox, oy, fd, n) * chainGradient);
                                            inputGradient.Storage.Set(ox, oy, fd, n,
                                                                      inputGradient.Storage.Get(ox, oy, fd, n) +
                                                                      filters.Get(fx, fy, fd, depth) * chainGradient);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
 public override void DoSigmoid(Volume <float> volume)
 {
     this.Storage.Map(x => (float)(1.0 / (1.0 + Math.Exp(-x))), volume.Storage);
 }
Пример #4
0
 public override void DoTanhGradient(Volume <float> input, Volume <float> outputGradient, Volume <float> inputGradient)
 {
     this.Storage.Map((output, outGradient) => (1.0f - output * output) * outGradient, outputGradient.Storage, inputGradient.Storage);
 }
Пример #5
0
 public override void DoSoftMaxGradient(Volume <float> outputGradient, Volume <float> inputGradient)
 {
     this.Storage.Map((input, outputG) => (outputG - 1) * input + input, outputGradient.Storage,
                      inputGradient.Storage);
 }
Пример #6
0
 public override void DoTanh(Volume <float> volume)
 {
     this.Storage.Map(x => (float)Math.Tanh(x), volume.Storage);
 }
Пример #7
0
 public override void DoReluGradient(Volume <float> input, Volume <float> output, Volume <float> outputGradient)
 {
     this.Storage.Map((x, y) => x > 0 ? y : 0, output.Storage, outputGradient.Storage);
 }
Пример #8
0
 public override void DoRelu(Volume <float> volume)
 {
     this.Storage.Map(x => x <= 0 ? 0 : x, volume.Storage);
 }
Пример #9
0
 protected override void DoNegate(Volume <float> volume)
 {
     DoMultiply(volume, -1.0f);
 }
Пример #10
0
 protected override void DoMultiply(Volume <float> result, float factor)
 {
     this.Storage.Map(x => x * factor, result.Storage);
 }
Пример #11
0
 public override void DoAdd(Volume <float> other, Volume <float> result)
 {
     this.Storage.MapEx((x, y) => x + y, other.Storage, result.Storage);
 }