Ejemplo n.º 1
0
        /// <summary>
        /// Outputs the size.
        /// </summary>
        /// <param name="inputSizes">The input sizes.</param>
        /// <param name="weightSizes">The weight sizes.</param>
        /// <param name="cd">The cd.</param>
        /// <returns>System.Int64[].</returns>
        public static long[] OutputSize(long[] inputSizes, long[] weightSizes, ConvolutionDesc2d cd)
        {
            int dimf = 1;
            int dimw = 3;
            int dimh = 2;

            var n            = inputSizes[0];
            var nInputPlane  = inputSizes[dimf];
            var inputWidth   = inputSizes[dimw];
            var inputHeight  = inputSizes[dimh];
            var nOutputPlane = weightSizes[0];

            var outputWidth  = (inputWidth + 2 * cd.padW - cd.kW) / cd.dW + 1;
            var outputHeight = (inputHeight + 2 * cd.padH - cd.kH) / cd.dH + 1;

            return(new long[] { n, nOutputPlane, outputHeight, outputWidth });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Outputs the size.
        /// </summary>
        /// <param name="inputSizes">The input sizes.</param>
        /// <param name="ceilMode">if set to <c>true</c> [ceil mode].</param>
        /// <param name="cd">The cd.</param>
        /// <returns>System.Int64[].</returns>
        public static long[] OutputSize(long[] inputSizes, bool ceilMode, ConvolutionDesc2d cd)
        {
            int dimw = 3;
            int dimh = 2;

            var iwidth  = inputSizes[dimw];
            var iheight = inputSizes[dimh];

            long oheight, owidth;

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

            return(new long[] { inputSizes[0], inputSizes[1], oheight, owidth });
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Spatials the maximum pooling forward.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="output">The output.</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>
        /// <exception cref="ArgumentException">input must be a 4D tensor</exception>
        /// <exception cref="InvalidOperationException">
        /// input image is smaller than kernel size
        /// or
        /// pad should be smaller than half of the kernel size
        /// </exception>
        public static void SpatialMaxPoolingForward(NDArray input, NDArray output, NDArray 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.Shape[dimw] < cd.kW - cd.padW || input.Shape[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.Shape[0];
            var nslices = input.Shape[dimc];
            var iheight = input.Shape[dimh];
            var iwidth  = input.Shape[dimw];

            long owidth;
            long oheight;

            if (ceilMode)
            {
                oheight = (long)(Math.Ceiling((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                owidth  = (long)(Math.Ceiling((float)(iwidth - cd.kW + 2 * cd.padW) / cd.dW)) + 1;
            }
            else
            {
                oheight = (long)(Math.Floor((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                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 (int 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))
                            {
                                IntPtr input_iPtr, output_iPtr, indices_iPtr;
                                using (NativeWrapper.BuildTensorRefPtr(input_i, out input_iPtr))
                                    using (NativeWrapper.BuildTensorRefPtr(output_i, out output_iPtr))
                                        using (NativeWrapper.BuildTensorRefPtr(indices_i, out 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);
                                        }
                            }
                }
            }
        }
Ejemplo n.º 4
0
        /// <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);
                                        }
                            }
                }
            }
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Conv2s the backward filter frame.
 /// </summary>
 /// <param name="gradOutput">The grad output.</param>
 /// <param name="gradWeight">The grad weight.</param>
 /// <param name="gradBias">The grad bias.</param>
 /// <param name="finput">The finput.</param>
 /// <param name="cd">The cd.</param>
 private static void Conv2BackwardFilterFrame(NDArray gradOutput, NDArray gradWeight, NDArray gradBias, NDArray finput, ConvolutionDesc2d cd)
 {
     using (var gradOutput2d = gradOutput.View(gradOutput.Shape[0], gradOutput.Shape[1] * gradOutput.Shape[2]))
         using (var finputT = finput.Transpose())
         {
             Ops.Addmm(gradWeight, 1, gradWeight, 1, gradOutput2d, finputT);
             Ops.Sum(gradBias, gradOutput2d, 1);
         }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Conv2s the backward filter.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="gradOutput">The grad output.</param>
        /// <param name="gradWeight">The grad weight.</param>
        /// <param name="gradBias">The grad bias.</param>
        /// <param name="finput">The finput.</param>
        /// <param name="fgradInput">The fgrad input.</param>
        /// <param name="cd">The cd.</param>
        /// <exception cref="InvalidOperationException">
        /// Number of output features must equal nOutputPlane
        /// or
        /// Kernel size should be greater than zero
        /// or
        /// stride should be greater than zero
        /// </exception>
        public static void Conv2BackwardFilter(NDArray input, NDArray gradOutput, NDArray gradWeight, NDArray gradBias, NDArray finput, NDArray fgradInput, ConvolutionDesc2d cd)
        {
            var nOutputPlane = gradWeight.Shape[0];
            var n            = input.Shape[0];

            if (gradOutput.Shape[1] != nOutputPlane)
            {
                throw new InvalidOperationException("Number of output features must equal nOutputPlane");
            }

            if (cd.kW <= 0 && cd.kH <= 0)
            {
                throw new InvalidOperationException("Kernel size should be greater than zero");
            }

            if (cd.dW <= 0 && cd.dH <= 0)
            {
                throw new InvalidOperationException("stride should be greater than zero");
            }

            for (int i = 0; i < n; ++i)
            {
                using (var gradOutput_i = gradOutput.Select(0, i))
                    using (var finput_i = finput.Select(0, i))
                    {
                        Conv2BackwardFilterFrame(gradOutput_i, gradWeight, gradBias, finput_i, cd);
                    }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Conv2s the backward input frame.
        /// </summary>
        /// <param name="gradOutput">The grad output.</param>
        /// <param name="gradInput">The grad input.</param>
        /// <param name="weight">The weight.</param>
        /// <param name="fgradInput">The fgrad input.</param>
        /// <param name="cd">The cd.</param>
        private static void Conv2BackwardInputFrame(NDArray gradOutput, NDArray gradInput, NDArray weight, NDArray fgradInput, ConvolutionDesc2d cd)
        {
            using (var gradOutput2d = gradOutput.View(gradOutput.Shape[0], gradOutput.Shape[1] * gradOutput.Shape[2]))
            {
                Ops.Addmm(fgradInput, 0, fgradInput, 1, weight, gradOutput2d);
            }

            Ops.Fill(gradInput, 0);

            IntPtr fgradInputPtr, gradInputPtr;

            using (NativeWrapper.BuildTensorRefPtr(fgradInput, out fgradInputPtr))
                using (NativeWrapper.BuildTensorRefPtr(gradInput, out gradInputPtr))
                {
                    CpuOpsNative.TS_Unfolded_Acc(fgradInputPtr, gradInputPtr, cd.kW, cd.kH, cd.dW, cd.dH, cd.padW, cd.padH,
                                                 (int)gradInput.Shape[0], (int)gradInput.Shape[2], (int)gradInput.Shape[1],
                                                 (int)gradOutput.Shape[2], (int)gradOutput.Shape[1]);
                }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Conv2s the forward.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="output">The output.</param>
        /// <param name="weight">The weight.</param>
        /// <param name="bias">The bias.</param>
        /// <param name="finput">The finput.</param>
        /// <param name="cd">The cd.</param>
        /// <exception cref="InvalidOperationException">
        /// bias has incorrect size. Expected 1D tensor of size " + nOutputPlane
        /// or
        /// or
        /// or
        /// 4D input expected (NCHW order)
        /// or
        /// finput is incorrect size
        /// or
        /// output is incorrect size
        /// </exception>
        public static void Conv2Forward(NDArray input, NDArray output, NDArray weight, NDArray bias, NDArray finput, ConvolutionDesc2d cd)
        {
            int dimf = 1;
            int dimw = 3;
            int dimh = 2;

            var n            = input.Shape[0];
            var nInputPlane  = input.Shape[dimf];
            var inputWidth   = input.Shape[dimw];
            var inputHeight  = input.Shape[dimh];
            var nOutputPlane = weight.Shape[0];

            var outputWidth  = (inputWidth + 2 * cd.padW - cd.kW) / cd.dW + 1;
            var outputHeight = (inputHeight + 2 * cd.padH - cd.kH) / cd.dH + 1;

            if (bias != null && (bias.Shape[0] != nOutputPlane))
            {
                throw new InvalidOperationException("bias has incorrect size. Expected 1D tensor of size " + nOutputPlane);
            }

            if (outputWidth < 1 || outputHeight < 1)
            {
                throw new InvalidOperationException(string.Format(
                                                        "Output size too small; calculated output size = ({0}x{1}x{2}", nOutputPlane, outputHeight, outputWidth));
            }

            if (nInputPlane * cd.kW * cd.kH != weight.Shape[1])
            {
                throw new InvalidOperationException(
                          string.Format("Input has incorrect number of channels. Got {0}, expected {1}", nInputPlane, weight.Shape[1] / ((float)(cd.kW * cd.kH))));
            }

            if (input.DimensionCount != 4)
            {
                throw new InvalidOperationException("4D input expected (NCHW order)");
            }


            if (finput.Shape[0] != n || finput.Shape[1] != cd.kW * cd.kH * nInputPlane || finput.Shape[2] != outputHeight * outputWidth)
            {
                throw new InvalidOperationException("finput is incorrect size");
            }

            if (output.Shape[0] != n || output.Shape[1] != nOutputPlane || output.Shape[2] != outputHeight || output.Shape[3] != outputWidth)
            {
                throw new InvalidOperationException("output is incorrect size");
            }

            for (int i = 0; i < n; ++i)
            {
                using (var input_i = input.Select(0, i))
                    using (var output_i = output.Select(0, i))
                        using (var finput_i = finput.Select(0, i))
                        {
                            Conv2ForwardFrame(input_i, output_i, weight, bias, finput_i,
                                              cd.kW, cd.kH, cd.dW, cd.dW, cd.padW, cd.padH,
                                              nInputPlane, inputWidth, inputHeight,
                                              nOutputPlane, outputWidth, outputHeight);
                        }
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// fs the size of the input.
 /// </summary>
 /// <param name="inputSizes">The input sizes.</param>
 /// <param name="outputSizes">The output sizes.</param>
 /// <param name="cd">The cd.</param>
 /// <returns>System.Int64[].</returns>
 public static long[] FInputSize(long[] inputSizes, long[] outputSizes, ConvolutionDesc2d cd)
 {
     return(new long[] { inputSizes[0], cd.kW *cd.kH *inputSizes[1], outputSizes[2] * outputSizes[3] });
 }