public PoolingNode(List <Unit> inputUnits, PoolingMethod poolingMethod) { value = 0; derivative = 0; this.poolingMethod = poolingMethod; this.inputUnits = inputUnits; }
/** @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; } }
/// <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); }