/// <summary>
        /// Reshape the bottom (input) and top (output) blobs.
        /// </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 Reshape(BlobCollection <T> colBottom, BlobCollection <T> colTop)
        {
            List <int> rgTopShape = PriorBoxParameter.Reshape(m_param.prior_box_param, colBottom[0].width, colBottom[0].height, m_nNumPriors);

            // Since all images in a batch have the same height and width, we only need to
            // generate one set of priors which can be shared across all images.
            m_log.CHECK_EQ(rgTopShape[0], 1, "The topshape(0) should be 1.");

            // 2 channels.
            // First channel stores the mean of each prior coordinate.
            // Second channel stores the variance of each prior coordiante.
            m_log.CHECK_EQ(rgTopShape[1], 2, "The topshape(1) should be 1.");
            m_log.CHECK_GT(rgTopShape[2], 0, "The top shape at index 2 must be greater than zero.");

            colTop[0].Reshape(rgTopShape);
        }
        /// <summary>
        /// Setup the layer.
        /// </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)
        {
            PriorBoxParameter p = m_param.prior_box_param;

            m_log.CHECK_GT(p.min_size.Count, 0, "Must provied at least one min_size!");

            for (int i = 0; i < p.min_size.Count; i++)
            {
                float fMin = p.min_size[i];
                m_log.CHECK_GT(fMin, 0, "min_size must be positive greater than zero.");
                m_rgfMinSizes.Add(fMin);
            }

            m_rgfAspectRatios = PriorBoxParameter.GetAspectRatios(p);
            m_bFlip           = p.flip;
            m_nNumPriors      = m_rgfAspectRatios.Count * m_rgfMinSizes.Count;

            if (p.max_size.Count > 0)
            {
                m_log.CHECK_EQ(p.min_size.Count, p.max_size.Count, "The max_size count must equal the min_size count!");
                for (int i = 0; i < p.max_size.Count; i++)
                {
                    float fMax = p.max_size[i];
                    m_log.CHECK_GT(fMax, m_rgfMinSizes[i], "The max_size must be greater than the min_size.");
                    m_rgfMaxSizes.Add(fMax);
                    m_nNumPriors++;
                }
            }

            m_bClip = p.clip;

            if (p.variance.Count > 1)
            {
                // Must and only provide 4 variance values.
                m_log.CHECK_EQ(p.variance.Count, 4, "Must only have 4 variance values.");

                for (int i = 0; i < p.variance.Count; i++)
                {
                    float fVar = p.variance[i];
                    m_log.CHECK_GT(fVar, 0, "The variance values must be greater than zero.");
                    m_rgfVariance.Add(fVar);
                }
            }
            else if (p.variance.Count == 1)
            {
                float fVar = p.variance[0];
                m_log.CHECK_GT(fVar, 0, "The variance value must be greater than zero.");
                m_rgfVariance.Add(fVar);
            }
            else
            {
                // Set default to 0.1.
                m_rgfVariance.Add(0.1f);
            }

            if (p.img_h.HasValue || p.img_w.HasValue)
            {
                m_log.CHECK(!p.img_size.HasValue, "Either img_size or img_h/img_w should be specified; but not both.");
                m_nImgH = (int)p.img_h.Value;
                m_log.CHECK_GT(m_nImgH, 0, "The img_h should be greater than 0.");
                m_nImgW = (int)p.img_w.Value;
                m_log.CHECK_GT(m_nImgW, 0, "The img_w should be greater than 0.");
            }
            else if (p.img_size.HasValue)
            {
                int nImgSize = (int)p.img_size.Value;
                m_log.CHECK_GT(nImgSize, 0, "The img_size should be greater than 0.");
                m_nImgH = nImgSize;
                m_nImgW = nImgSize;
            }
            else
            {
                m_nImgH = 0;
                m_nImgW = 0;
            }

            if (p.step_h.HasValue || p.step_w.HasValue)
            {
                m_log.CHECK(!p.step.HasValue, "Either step_size or step_h/step_w should be specified; but not both.");
                m_fStepH = p.step_h.Value;
                m_log.CHECK_GT(m_nImgH, 0, "The step_h should be greater than 0.");
                m_fStepW = p.step_w.Value;
                m_log.CHECK_GT(m_nImgW, 0, "The step_w should be greater than 0.");
            }
            else if (p.step.HasValue)
            {
                float fStep = p.step.Value;
                m_log.CHECK_GT(fStep, 0, "The step should be greater than 0.");
                m_fStepH = fStep;
                m_fStepW = fStep;
            }
            else
            {
                m_fStepH = 0;
                m_fStepW = 0;
            }

            m_fOffset = p.offset;
        }