Ejemplo n.º 1
0
 public PoolingNode(List <Unit> inputUnits, PoolingMethod poolingMethod)
 {
     value              = 0;
     derivative         = 0;
     this.poolingMethod = poolingMethod;
     this.inputUnits    = inputUnits;
 }
Ejemplo n.º 2
0
        /** @copydoc KernelParameter::Copy */
        public override void Copy(LayerParameterBase src)
        {
            base.Copy(src);

            if (src is PoolingParameter)
            {
                PoolingParameter p = (PoolingParameter)src;
                m_pool           = p.m_pool;
                m_bGlobalPooling = p.m_bGlobalPooling;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Setup the layer for use with both Engine.CAFFE and Engine.CUDNN modes.
        /// </summary>
        /// <param name="colBottom">Specifies the collection of bottom (input) Blobs.</param>
        /// <param name="colTop">Specifies the collection of top (output) Blobs.</param>
        public override void LayerSetUp(BlobCollection <T> colBottom, BlobCollection <T> colTop)
        {
            PoolingParameter p = m_param.pooling_param;

            if (p.global_pooling)
            {
                if (!(p.kernel_size.Count > 0 || p.kernel_h.HasValue || p.kernel_w.HasValue))
                {
                    m_log.WriteLine("WARNING: With global pooling = true, Filter size cannot be specified, the bottom hxw = '" + colBottom[0].height.ToString() + "x" + colBottom[0].width.ToString() + "' will be used instead for the kernel size.");
                }
            }
            else
            {
                m_log.CHECK(!(p.kernel_size.Count > 0) != !(p.kernel_h.HasValue && p.kernel_w.HasValue), "Filter size is kernel_size OR kernel_h and kernel_w; not both.");
                m_log.CHECK(p.kernel_size.Count > 0 || (p.kernel_h.HasValue && p.kernel_w.HasValue), "For non-square filters, both kernel_h and kernel_w are required.");
            }

            m_log.CHECK(((p.pad.Count == 0) && p.pad_h.HasValue && p.pad_w.HasValue) || (!p.pad_h.HasValue && !p.pad_w.HasValue), "Pad is pad or pad_h and pad_w are required.");
            m_log.CHECK(((p.stride.Count == 0) && p.stride_h.HasValue && p.stride_w.HasValue) || (!p.stride_h.HasValue && !p.stride_w.HasValue), "Stride is stride or stride_h and stride_w are required.");
            m_bGlobalPooling = p.global_pooling;


            //---- Kernel Size ----

            if (m_bGlobalPooling)
            {
                m_nKernelH = colBottom[0].height;
                m_nKernelW = colBottom[0].width;
            }
            else
            {
                if (p.kernel_size.Count > 0)
                {
                    m_nKernelH = (int)p.kernel_size[0];
                    m_nKernelW = (int)p.kernel_size[0];
                }
                else
                {
                    m_nKernelH = (int)p.kernel_h.Value;
                    m_nKernelW = (int)p.kernel_w.Value;
                }
            }

            m_log.CHECK_GT(m_nKernelH, 0, "Filter dimensions cannot be zero.");
            m_log.CHECK_GT(m_nKernelW, 0, "Filter dimensions cannot be zero.");


            //---- Pad ----

            if (p.pad.Count > 0)
            {
                m_nPadH = (int)p.pad[0];
                m_nPadW = (int)p.pad[0];
            }
            else
            {
                m_nPadH = (p.pad_h.HasValue) ? (int)p.pad_h.Value : 0;
                m_nPadW = (p.pad_w.HasValue) ? (int)p.pad_w.Value : 0;
            }


            //---- Stride ----

            if (p.stride.Count > 0)
            {
                m_nStrideH = (int)p.stride[0];
                m_nStrideW = (int)p.stride[0];
            }
            else
            {
                m_nStrideH = (p.stride_h.HasValue) ? (int)p.stride_h.Value : 1;
                m_nStrideW = (p.stride_w.HasValue) ? (int)p.stride_w.Value : 1;
            }

            if (m_bGlobalPooling)
            {
                m_log.CHECK(m_nPadH == 0 && m_nPadW == 0 && m_nStrideH == 1 && m_nStrideW == 1, "With global pooling = true, only pad = 0 and stride = 1 allowed.");
            }

            if (m_nPadH != 0 || m_nPadW != 0)
            {
                m_log.CHECK(m_param.pooling_param.pool == PoolingParameter.PoolingMethod.AVE ||
                            m_param.pooling_param.pool == PoolingParameter.PoolingMethod.MAX, "Padding implemented for AVE and MAX pooling only.");
                m_log.CHECK_LT(m_nPadH, m_nKernelH, "The pad_h must be <= kernel_h.");
                m_log.CHECK_LT(m_nPadW, m_nKernelW, "The pad_w must be <= kernel_w.");
            }

            if (!m_param.pooling_param.useCudnn())
            {
                return;
            }


            //---------------------------------------------
            //  cuDnn specific pooling.
            //
            //  Note only MAX and AVE pooling are supported.
            //---------------------------------------------

            // Setup the convert to half flags used by the Layer just before calling forward and backward.
            m_bUseHalfSize = m_param.use_halfsize;

            if (m_param.pooling_param.pool == PoolingParameter.PoolingMethod.MAX)
            {
                m_method = PoolingMethod.MAX;
            }
            else
            {
                m_method = PoolingMethod.AVE;
            }

            m_hCudnn       = m_cuda.CreateCuDNN();
            m_hBottomDesc  = m_cuda.CreateTensorDesc();
            m_hTopDesc     = m_cuda.CreateTensorDesc();
            m_hPoolingDesc = m_cuda.CreatePoolingDesc();
            m_cuda.SetPoolingDesc(m_hPoolingDesc, m_method, m_nKernelH, m_nKernelW, m_nPadH, m_nPadW, m_nStrideH, m_nStrideW);
        }
        public PoolingLayer(LayerConnection inputConnection, Filter mask, int stride, PoolingMethod method)
        {
            model     = new MatrixModel(inputConnection.length, stride);
            this.mask = mask;

            nodes = new DepthList <PoolingNode>(inputConnection.depth);

            int filterOutputsCount = model.filterOutputsCount(mask);
            int filterLineCount    = model.filterLineCount(mask);

            for (int d = 0; d < inputConnection.depth; d++)
            {
                for (int i = 0; i < filterOutputsCount; i++)
                {
                    List <Unit> inputUnits = new List <Unit>();

                    for (int x = 0; x < mask.count; x++)
                    {
                        int inner = x % mask.size + x / mask.size * model.size;
                        int outer = i % filterLineCount + i / filterLineCount * model.size;

                        inputUnits.Add(inputConnection[inner + outer, d]);
                    }

                    nodes.Add(new PoolingNode(inputUnits, method));
                }
            }

            input = new PoolingLayerConnection(nodes);
        }