2using System.Collections.Generic;
35 bool m_bGlobalPooling;
40 long m_hBottomDesc = 0;
42 long m_hPoolingDesc = 0;
77 m_blobRandIdx =
new Blob<T>(cuda, log);
79 m_blobMaxIdx =
new Blob<T>(cuda, log);
86 if (m_hPoolingDesc != 0)
88 m_cuda.FreePoolingDesc(m_hPoolingDesc);
94 m_cuda.FreeTensorDesc(m_hTopDesc);
98 if (m_hBottomDesc != 0)
100 m_cuda.FreeTensorDesc(m_hBottomDesc);
106 m_cuda.FreeCuDNN(m_hCudnn);
123 col.
Add(m_blobRandIdx);
124 col.
Add(m_blobMaxIdx);
173 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.");
181 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.");
188 if (m_bGlobalPooling)
190 m_nKernelH = colBottom[0].height;
191 m_nKernelW = colBottom[0].width;
207 m_log.
CHECK_GT(m_nKernelH, 0,
"Filter dimensions cannot be zero.");
208 m_log.
CHECK_GT(m_nKernelW, 0,
"Filter dimensions cannot be zero.");
215 m_nPadH = (int)p.
pad[0];
216 m_nPadW = (
int)p.
pad[0];
220 m_nPadH = (p.
pad_h.HasValue) ? (
int)p.
pad_h.Value : 0;
221 m_nPadW = (p.
pad_w.HasValue) ? (
int)p.
pad_w.Value : 0;
229 m_nStrideH = (int)p.
stride[0];
230 m_nStrideW = (
int)p.
stride[0];
238 if (m_bGlobalPooling)
239 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.");
241 if (m_nPadH != 0 || m_nPadW != 0)
245 m_log.
CHECK_LT(m_nPadH, m_nKernelH,
"The pad_h must be <= kernel_h.");
246 m_log.
CHECK_LT(m_nPadW, m_nKernelW,
"The pad_w must be <= kernel_w.");
267 m_hCudnn =
m_cuda.CreateCuDNN();
268 m_hBottomDesc =
m_cuda.CreateTensorDesc();
269 m_hTopDesc =
m_cuda.CreateTensorDesc();
270 m_hPoolingDesc =
m_cuda.CreatePoolingDesc();
271 m_cuda.SetPoolingDesc(m_hPoolingDesc, m_method, m_nKernelH, m_nKernelW, m_nPadH, m_nPadW, m_nStrideH, m_nStrideW);
281 m_log.
CHECK_EQ(4, colBottom[0].num_axes,
"Input must have 4 axes, corresponding to (num, channels, height, width)");
283 m_nChannels = colBottom[0].channels;
284 m_nHeight = colBottom[0].height;
285 m_nWidth = colBottom[0].width;
287 if (m_bGlobalPooling)
289 m_nKernelH = colBottom[0].height;
290 m_nKernelW = colBottom[0].width;
295 m_nPooledHeight = (int)Math.Floor((
double)((m_nHeight + 2 * m_nPadH - m_nKernelH) / (
double)m_nStrideH) + 1);
296 m_nPooledWidth = (int)Math.Floor((
double)((m_nWidth + 2 * m_nPadW - m_nKernelW) / (
double)m_nStrideW) + 1);
300 m_nPooledHeight = (int)Math.Ceiling((
double)((m_nHeight + 2 * m_nPadH - m_nKernelH) / (
double)m_nStrideH)) + 1;
301 m_nPooledWidth = (int)Math.Ceiling((
double)((m_nWidth + 2 * m_nPadW - m_nKernelW) / (
double)m_nStrideW)) + 1;
304 if (m_nPooledHeight <= 0)
310 if (m_nPooledWidth <= 0)
316 if (m_nPadH > 0 || m_nPadW > 0)
320 if ((m_nPooledHeight - 1) * m_nStrideH >= m_nHeight + m_nPadH)
323 if ((m_nPooledWidth - 1) * m_nStrideW >= m_nWidth + m_nPadW)
326 m_log.
CHECK_LT((m_nPooledHeight - 1) * m_nStrideH, m_nHeight + m_nPadH,
"The pooled height must fit in the image and not overlap onto the padding.");
327 m_log.
CHECK_LT((m_nPooledWidth - 1) * m_nStrideW, m_nWidth + m_nPadW,
"The pooled width must fit in the image and not overlap onto the padding.");
332 if (colTop.
Count > 1)
339 m_blobMaxIdx.
Reshape(colBottom[0].num, m_nChannels, m_nPooledHeight, m_nPooledWidth);
343 m_blobRandIdx.
Reshape(colBottom[0].num, m_nChannels, m_nPooledHeight, m_nPooledWidth);
352 m_cuda.SetTensorDesc(m_hBottomDesc, colBottom[0].num, m_nChannels, m_nHeight, m_nWidth,
m_bUseHalfSize);
353 m_cuda.SetTensorDesc(m_hTopDesc, colBottom[0].num, m_nChannels, m_nPooledHeight, m_nPooledWidth,
m_bUseHalfSize);
390 long hBottomData = colBottom[0].gpu_data;
391 long hTopData = colTop[0].mutable_gpu_data;
392 int nCount = colTop[0].count();
395 bool bUseTopMask = (colTop.
Count > 1) ?
true :
false;
403 hTopMask = colTop[1].mutable_gpu_data;
406 m_cuda.pooling_fwd(
POOLING_METHOD.MAX, nCount, hBottomData, colBottom[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hTopData, hMask, hTopMask);
410 m_cuda.pooling_fwd(
POOLING_METHOD.AVE, nCount, hBottomData, colBottom[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hTopData, 0, 0);
416 m_cuda.pooling_fwd(
POOLING_METHOD.STO_TRAIN, nCount, hBottomData, colBottom[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hTopData, m_blobRandIdx.
gpu_data, 0);
418 m_cuda.pooling_fwd(
POOLING_METHOD.STO_TEST, nCount, hBottomData, colBottom[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hTopData, m_blobRandIdx.
gpu_data, 0);
435 if (!rgbPropagateDown[0])
438 long hTopDiff = colTop[0].gpu_diff;
439 long hBottomDiff = colBottom[0].mutable_gpu_diff;
440 int nCount = colBottom[0].count();
443 bool bUseTopMask = (colTop.
Count > 1) ?
true :
false;
451 hTopMask = colTop[1].gpu_data;
455 m_cuda.pooling_bwd(
POOLING_METHOD.MAX, nCount, hTopDiff, colTop[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hBottomDiff, hMask, hTopMask);
459 m_cuda.pooling_bwd(
POOLING_METHOD.AVE, nCount, hTopDiff, colTop[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hBottomDiff, 0, 0);
463 m_cuda.pooling_bwd(
POOLING_METHOD.STO_TRAIN, nCount, hTopDiff, colTop[0].num, m_nChannels, m_nHeight, m_nWidth, m_nPooledHeight, m_nPooledWidth, m_nKernelH, m_nKernelW, m_nStrideH, m_nStrideW, m_nPadH, m_nPadW, hBottomDiff, m_blobRandIdx.
gpu_data, 0);
479 long hBottomData = colBottom[0].gpu_data;
480 long hTopData = colTop[0].mutable_gpu_data;
482 m_cuda.PoolingForward(m_hCudnn, m_hPoolingDesc,
m_tOne, m_hBottomDesc, hBottomData,
m_tZero, m_hTopDesc, hTopData);
493 long hTopDiff = colTop[0].gpu_diff;
494 long hTopData = colTop[0].gpu_data;
495 long hBottomData = colBottom[0].gpu_data;
496 long hBottomDiff = colBottom[0].mutable_gpu_diff;
498 m_cuda.PoolingBackward(m_hCudnn, m_hPoolingDesc,
m_tOne, m_hTopDesc, hTopData, m_hTopDesc, hTopDiff, m_hBottomDesc, hBottomData,
m_tZero, m_hBottomDesc, hBottomDiff);
The Log class provides general output in text form.
void CHECK(bool b, string str)
Test a flag for true.
void WriteLine(string str, bool bOverrideEnabled=false, bool bHeader=false, bool bError=false, bool bDisable=false)
Write a line of output.
void FAIL(string str)
Causes a failure which throws an exception with the desciptive text.
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
void CHECK_GT(double df1, double df2, string str)
Test whether one number is greater than another.
void CHECK_LT(double df1, double df2, string str)
Test whether one number is less than another.
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
int Count
Returns the number of items in the collection.
void ReshapeLike(BlobCollection< T > src)
Reshapes all blobs in the collection to the sizes of the source.
void Reshape(int[] rgShape)
Reshapes all blobs in the collection to the given shape.
The Blob is the main holder of data that moves through the Layers of the Net.
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
string Name
Get/set the name of the Blob.
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
An interface for the units of computation which can be composed into a Net.
Log m_log
Specifies the Log for output.
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
T m_tZero
Specifies a generic type equal to 0.0.
T m_tOne
Specifies a generic type equal to 1.0.
bool m_bUseHalfSize
Specifies that the half size of the top (if any) should be converted to the base size.
Phase m_phase
Specifies the Phase under which the Layer is run.
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
LayerParameter.LayerType m_type
Specifies the Layer type.
The PoolingLayer pools the input image by taking the max, average, etc. within regions....
override int? MinTopBlobs
Currentlym Engine.CUDNN does not support the extra top blob.
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer for use with both Engine.CAFFE and Engine.CUDNN modes.
override void dispose()
Releases all GPU and host resources used by the Layer.
override int? MaxTopBlobs
MAX Pool layers can output an extra top blob for the mask; others can only output the pooled inputs.
void forward_cudnn(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Run the Forward computation using the Engine.CUDNN mode as specified in the LayerParameter.
void backward_cuda(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Run the Backward computation using the Engine.CAFFE mode as specified in the LayerParameter.
override int? ExactNumTopBlobs
Returns the required number of top (output) Blobs: pool, mask (Engine.CAFFE only)
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Run the Forward computation using either the Engine.CAFFE or Engine.CUDNN mode as specified in the La...
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
PoolingLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The PoolingLayer constructor.
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Run the Backward computation using either the Engine.CAFFE or Engine.CUDNN mode as specified in the L...
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
void forward_cuda(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Run the Forward computation using the Engine.CAFFE mode as specified in the LayerParameter.
override int ExactNumBottomBlobs
Returns the required number of bottom (input) Blobs: input
void backward_cudnn(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Run the Backward computation using the Engine.CUDNN mode as specified in the LayerParameter.
Specifies whether to use the NVIDIA cuDnn version or Caffe version of a given forward/backward operat...
Engine engine
Specifies the Engine in use.
Engine
Defines the type of engine to use.
uint? stride_h
The stride height (2D only)
List< uint > kernel_size
Kernel size is given as a single value for equal dimensions in all spatial dimensions,...
uint? stride_w
The stride width (2D only)
uint? pad_h
The padding height (2D only)
uint? kernel_h
The kernel height (2D only)
List< uint > stride
Stride is given as a single value for equal dimensions in all spatial dimensions, or once per spatial...
uint? kernel_w
The kernel width (2D only)
uint? pad_w
The padding width (2D only)
List< uint > pad
Pad is given as a single value for equal dimensions in all spatial dimensions, or once per spatial di...
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
PoolingParameter pooling_param
Returns the parameter set when initialized with LayerType.POOLING
bool use_halfsize
Specifies whether or not to use half sized memory or not.
LayerType
Specifies the layer type.
Specifies the parameters for the PoolingLayer.
PoolingReshapeAlgorithm
Defines the pooling reshape algorithm to use.
PoolingMethod
Defines the pooling method.
bool useCudnn()
Queries whether or not to use NVIDIA's cuDnn.
PoolingMethod pool
Specifies the pooling method.
bool global_pooling
Specifies whether or not to enable global pooling.
PoolingReshapeAlgorithm reshape_algorithm
Specifies the reshape algorithm to use, either the original Caffe reshape (default = false) or the ne...
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Phase
Defines the Phase under which to run a Net.
The MyCaffe.common namespace contains common MyCaffe classes.
PoolingMethod
Specifies the pooling method used by the cuDnn function SetPoolingDesc.
POOLING_METHOD
Specifies the pooling method to use when using the Caffe pooling (instead of the pooling from NVIDIA'...
The MyCaffe.layers namespace contains all layers that have a solidified code base,...
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...