Beispiel #1
0
        public static void SpatialMaxPoolingBackward(Tensor input, Tensor gradOutput, Tensor gradInput, Tensor indices, ConvolutionDesc2d cd, bool ceilMode)
        {
            int dimw = 3;
            int dimh = 2;
            int dimc = 1;

            long nbatch  = input.Sizes[0];
            long nslices = input.Sizes[dimc];
            long iheight = input.Sizes[dimh];
            long iwidth  = input.Sizes[dimw];
            long owidth  = gradOutput.Sizes[dimw];
            long oheight = gradOutput.Sizes[dimh];

            Ops.Fill(gradInput, 0);


            using Tensor gradOutputContig = Ops.AsContiguous(gradOutput);
            for (int i = 0; i < nbatch; ++i)
            {
                using Tensor gradInput_i  = gradInput.Select(0, i);
                using Tensor gradOutput_i = gradOutputContig.Select(0, i);
                using Tensor indices_i    = indices.Select(0, i);
                using (NativeWrapper.BuildTensorRefPtr(gradInput_i, out IntPtr gradInput_iPtr))
                    using (NativeWrapper.BuildTensorRefPtr(gradOutput_i, out IntPtr gradOutput_iPtr))
                        using (NativeWrapper.BuildTensorRefPtr(indices_i, out IntPtr indices_iPtr))
                        {
                            CpuOpsNative.TS_SpatialMaxPooling_updateGradInput_frame(gradInput_iPtr, gradOutput_iPtr, indices_iPtr,
                                                                                    nslices, iwidth, iheight,
                                                                                    owidth, oheight,
                                                                                    cd.dW, cd.dH);
                        }
            }
        }
Beispiel #2
0
        private static void Conv2BackwardInputFrame(Tensor gradOutput, Tensor gradInput, Tensor weight, Tensor fgradInput, ConvolutionDesc2d cd)
        {
            using (Tensor gradOutput2d = gradOutput.View(gradOutput.Sizes[0], gradOutput.Sizes[1] * gradOutput.Sizes[2]))
            {
                Ops.Addmm(fgradInput, 0, fgradInput, 1, weight, gradOutput2d);
            }

            Ops.Fill(gradInput, 0);

            using (NativeWrapper.BuildTensorRefPtr(fgradInput, out IntPtr fgradInputPtr))
                using (NativeWrapper.BuildTensorRefPtr(gradInput, out IntPtr gradInputPtr))
                {
                    CpuOpsNative.TS_Unfolded_Acc(fgradInputPtr, gradInputPtr, cd.kW, cd.kH, cd.dW, cd.dH, cd.padW, cd.padH,
                                                 (int)gradInput.Sizes[0], (int)gradInput.Sizes[2], (int)gradInput.Sizes[1],
                                                 (int)gradOutput.Sizes[2], (int)gradOutput.Sizes[1]);
                }
        }
        /// <summary>
        /// Spatials the maximum pooling backward.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="gradOutput">The grad output.</param>
        /// <param name="gradInput">The grad input.</param>
        /// <param name="indices">The indices.</param>
        /// <param name="cd">The cd.</param>
        /// <param name="ceilMode">if set to <c>true</c> [ceil mode].</param>
        public static void SpatialMaxPoolingBackward(NDArray input, NDArray gradOutput, NDArray gradInput, NDArray indices, ConvolutionDesc2d cd, bool ceilMode)
        {
            var dimw = 3;
            var dimh = 2;
            var dimc = 1;

            var nbatch  = input.Shape[0];
            var nslices = input.Shape[dimc];
            var iheight = input.Shape[dimh];
            var iwidth  = input.Shape[dimw];
            var owidth  = gradOutput.Shape[dimw];
            var oheight = gradOutput.Shape[dimh];

            Ops.Fill(gradInput, 0);


            using (var gradOutputContig = Ops.AsContiguous(gradOutput))
            {
                for (int i = 0; i < nbatch; ++i)
                {
                    using (var gradInput_i = gradInput.Select(0, i))
                        using (var gradOutput_i = gradOutputContig.Select(0, i))
                            using (var indices_i = indices.Select(0, i))
                            {
                                IntPtr gradInput_iPtr, gradOutput_iPtr, indices_iPtr;
                                using (NativeWrapper.BuildTensorRefPtr(gradInput_i, out gradInput_iPtr))
                                    using (NativeWrapper.BuildTensorRefPtr(gradOutput_i, out gradOutput_iPtr))
                                        using (NativeWrapper.BuildTensorRefPtr(indices_i, out indices_iPtr))
                                        {
                                            CpuOpsNative.TS_SpatialMaxPooling_updateGradInput_frame(gradInput_iPtr, gradOutput_iPtr, indices_iPtr,
                                                                                                    nslices, iwidth, iheight,
                                                                                                    owidth, oheight,
                                                                                                    cd.dW, cd.dH);
                                        }
                            }
                }
            }
        }
        public static void SpatialMaxPoolingForward(Tensor input, Tensor output, Tensor indices, ConvolutionDesc2d cd, bool ceilMode)
        {
            if (input.DimensionCount != 4)
            {
                throw new ArgumentException("input must be a 4D tensor");
            }

            var dimw = 3;
            var dimh = 2;
            var dimc = 1;

            if (input.Sizes[dimw] < cd.kW - cd.padW || input.Sizes[dimh] < cd.kH - cd.padH)
            {
                throw new InvalidOperationException("input image is smaller than kernel size");
            }

            if (cd.padW > cd.kW / 2 || cd.padH > cd.kH / 2)
            {
                throw new InvalidOperationException("pad should be smaller than half of the kernel size");
            }

            var nbatch  = input.Sizes[0];
            var nslices = input.Sizes[dimc];
            var iheight = input.Sizes[dimh];
            var iwidth  = input.Sizes[dimw];

            long owidth;
            long oheight;

            if (ceilMode)
            {
                // ReSharper disable once ArrangeRedundantParentheses
                oheight = (long)(Math.Ceiling((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                // ReSharper disable once ArrangeRedundantParentheses
                owidth = (long)(Math.Ceiling((float)(iwidth - cd.kW + 2 * cd.padW) / cd.dW)) + 1;
            }
            else
            {
                // ReSharper disable once ArrangeRedundantParentheses
                oheight = (long)(Math.Floor((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                // ReSharper disable once ArrangeRedundantParentheses
                owidth = (long)(Math.Floor((float)(iwidth - cd.kW + 2 * cd.padW) / cd.dW)) + 1;
            }

            if (cd.padW != 0 || cd.padH != 0)
            {
                // ensure that the last pooling starts inside the image
                if ((oheight - 1) * cd.dH >= iheight + cd.padH)
                {
                    --oheight;
                }

                if ((owidth - 1) * cd.dW >= iwidth + cd.padW)
                {
                    --owidth;
                }
            }

            using var inputContig = Ops.AsContiguous(input);
            for (var i = 0; i < nbatch; ++i)
            {
                using var input_i   = inputContig.Select(0, i);
                using var output_i  = output.Select(0, i);
                using var indices_i = indices.Select(0, i);
                using (NativeWrapper.BuildTensorRefPtr(input_i, out var input_iPtr))
                {
                    using (NativeWrapper.BuildTensorRefPtr(output_i, out var output_iPtr))
                    {
                        using (NativeWrapper.BuildTensorRefPtr(indices_i, out var indices_iPtr))
                        {
                            CpuOpsNative.TS_SpatialMaxPooling_updateOutput_frame(input_iPtr, output_iPtr, indices_iPtr,
                                                                                 nslices, iwidth, iheight,
                                                                                 owidth, oheight,
                                                                                 cd.kW, cd.kH, cd.dW, cd.dH, cd.padW, cd.padH);
                        }
                    }
                }
            }
        }