2using System.Collections.Generic;
35 bool m_bReshapedFirstTime;
47 List<BlobCollection<T>> m_rgPoolingBottomVec =
new List<BlobCollection<T>>();
51 List<PoolingLayer<T>> m_rgPoolingLayers =
new List<PoolingLayer<T>>();
55 List<BlobCollection<T>> m_rgPoolingTopVecs =
new List<BlobCollection<T>>();
63 List<FlattenLayer<T>> m_rgFlattenLayers =
new List<FlattenLayer<T>>();
67 List<BlobCollection<T>> m_rgFlattenLayerTopVecs =
new List<BlobCollection<T>>();
107 m_rgPoolingLayers.Clear();
109 if (m_colBlobSplitTopVec !=
null)
111 m_colBlobSplitTopVec.
Dispose();
112 m_colBlobSplitTopVec =
null;
115 if (m_split_layer !=
null)
118 m_split_layer =
null;
121 if (m_colBlobPoolingOutputs !=
null)
123 m_colBlobPoolingOutputs.
Dispose();
124 m_colBlobPoolingOutputs =
null;
127 if (m_colBlobFlattenOutputs !=
null)
129 m_colBlobFlattenOutputs.Dispose();
130 m_colBlobFlattenOutputs =
null;
138 m_rgFlattenLayers.Clear();
140 m_rgPoolingBottomVec.Clear();
141 m_rgPoolingTopVecs.Clear();
142 m_rgFlattenLayerTopVecs.Clear();
175 int nNumBins = (int)Math.Pow(2, nPyramidLevel);
179 int nKernelH = (int)Math.Ceiling(nBottomH / (
double)nNumBins);
180 int nKernelW = (int)Math.Ceiling(nBottomW / (
double)nNumBins);
183 int nRemainderH = nKernelH * nNumBins - nBottomH;
184 int nRemainderW = nKernelW * nNumBins - nBottomW;
187 int nPadH = (nRemainderH + 1) / 2;
188 int nPadW = (nRemainderW + 1) / 2;
208 m_nNum = colBottom[0].num;
209 m_nChannels = colBottom[0].channels;
210 m_nBottomH = colBottom[0].height;
211 m_nBottomW = colBottom[0].width;
212 m_bReshapedFirstTime =
false;
214 m_log.
CHECK_GT(m_nBottomH, 0,
"Input dimensions cannot be zero.");
215 m_log.
CHECK_GT(m_nBottomW, 0,
"Input dimensions cannot be zero.");
220 m_rgPoolingBottomVec =
new List<BlobCollection<T>>();
221 m_rgPoolingLayers =
new List<PoolingLayer<T>>();
222 m_rgPoolingTopVecs =
new List<BlobCollection<T>>();
224 m_rgFlattenLayers =
new List<FlattenLayer<T>>();
225 m_rgFlattenLayerTopVecs =
new List<BlobCollection<T>>();
229 if (m_nPyramidHeight == 1)
234 m_rgPoolingLayers[0].Setup(colBottom, colTop);
239 for (
int i = 0; i < m_nPyramidHeight; i++)
247 m_split_layer.
Setup(colBottom, m_colBlobSplitTopVec);
249 for (
int i = 0; i < m_nPyramidHeight; i++)
253 m_rgPoolingBottomVec[i].Add(m_colBlobSplitTopVec[i]);
258 m_rgPoolingTopVecs[i].Add(m_colBlobPoolingOutputs[i]);
263 m_rgPoolingLayers[i].Setup(m_rgPoolingBottomVec[i], m_rgPoolingTopVecs[i]);
268 m_rgFlattenLayerTopVecs[i].Add(m_colBlobFlattenOutputs[i]);
273 m_rgFlattenLayers[i].Setup(m_rgPoolingTopVecs[i], m_rgFlattenLayerTopVecs[i]);
276 m_colBlobConcatBottomVec.
Add(m_colBlobFlattenOutputs[i]);
282 m_concat_layer.
Setup(m_colBlobConcatBottomVec, colTop);
292 m_log.
CHECK_EQ(4, colBottom[0].num_axes,
"Input must have 4 axes, corresponding to (num, channels, height, width)");
295 if (m_nNum == colBottom[0].num &&
296 m_nChannels == colBottom[0].channels &&
297 m_nBottomH == colBottom[0].height &&
298 m_nBottomW == colBottom[0].width &&
299 m_bReshapedFirstTime)
302 m_nNum = colBottom[0].num;
303 m_nChannels = colBottom[0].channels;
304 m_nBottomH = colBottom[0].height;
305 m_nBottomW = colBottom[0].width;
306 m_bReshapedFirstTime =
true;
308 if (m_nPyramidHeight == 1)
312 if (m_rgPoolingLayers[0] !=
null)
313 m_rgPoolingLayers[0].Dispose();
316 m_rgPoolingLayers[0].Setup(colBottom, colTop);
317 m_rgPoolingLayers[0].Reshape(colBottom, colTop);
321 m_split_layer.
Reshape(colBottom, m_colBlobSplitTopVec);
323 for (
int i = 0; i < m_nPyramidHeight; i++)
327 if (m_rgPoolingLayers[i] !=
null)
328 m_rgPoolingLayers[i].Dispose();
331 m_rgPoolingLayers[i].Setup(m_rgPoolingBottomVec[i], m_rgPoolingTopVecs[i]);
332 m_rgPoolingLayers[i].Reshape(m_rgPoolingBottomVec[i], m_rgPoolingTopVecs[i]);
333 m_rgFlattenLayers[i].Reshape(m_rgPoolingTopVecs[i], m_rgFlattenLayerTopVecs[i]);
336 m_concat_layer.
Reshape(m_colBlobConcatBottomVec, colTop);
350 if (m_nPyramidHeight == 1)
352 m_rgPoolingLayers[0].Forward(colBottom, colTop);
356 m_split_layer.
Forward(colBottom, m_colBlobSplitTopVec);
358 for (
int i = 0; i < m_nPyramidHeight; i++)
360 m_rgPoolingLayers[i].Forward(m_rgPoolingBottomVec[i], m_rgPoolingTopVecs[i]);
361 m_rgFlattenLayers[i].Forward(m_rgPoolingTopVecs[i], m_rgFlattenLayerTopVecs[i]);
364 m_concat_layer.
Forward(m_colBlobConcatBottomVec, colTop);
377 if (!rgbPropagateDown[0])
380 if (m_nPyramidHeight == 1)
382 m_rgPoolingLayers[0].Backward(colTop, rgbPropagateDown, colBottom);
386 List<bool> rgbConcatPropagateDown =
Utility.
Create<
bool>(m_nPyramidHeight,
true);
387 m_concat_layer.
Backward(colTop, rgbConcatPropagateDown, m_colBlobConcatBottomVec);
389 for (
int i = 0; i < m_nPyramidHeight; i++)
391 m_rgFlattenLayers[i].Backward(m_rgFlattenLayerTopVecs[i], rgbPropagateDown, m_rgPoolingTopVecs[i]);
392 m_rgPoolingLayers[i].Backward(m_rgPoolingTopVecs[i], rgbPropagateDown, m_rgPoolingBottomVec[i]);
395 m_split_layer.
Backward(m_colBlobSplitTopVec, rgbPropagateDown, colBottom);
The Log class provides general output in text form.
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.
The Utility class provides general utility funtions.
static List< int > Create(int nCount, int nStart, int nInc)
Create a new List and fill it with values starting with start and incrementing by inc.
The BlobCollection contains a list of Blobs.
void Dispose()
Release all resource used by the collection and its Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
The Blob is the main holder of data that moves through the Layers of the Net.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
The ConcatLayer takes at least two Blobs and concatentates them along either the num or channel dimen...
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
The FlattenLayer reshapes the input Blob into flat vectors This layer is initialized with the MyCaffe...
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.
virtual void dispose()
Releases all GPU and host resources used by the Layer.
void Backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Given the top Blob error gradients, compute the bottom Blob error gradients.
double Forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Given the bottom (input) Blobs, this function computes the top (output) Blobs and the loss.
void Dispose()
Releases all GPU and host resources used by the Layer.
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
void Setup(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Implements common Layer setup functionality.
LayerParameter.LayerType m_type
Specifies the Layer type.
The PoolingLayer pools the input image by taking the max, average, etc. within regions....
The SPPLayer does spatial pyramid pooling on the input image by taking the max, average,...
SPPLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The SPPLayer constructor.
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Computes the forward calculation.
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: spp.
override void dispose()
Releases all GPU and host resources used by the Layer.
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: input.
virtual LayerParameter getPoolingParam(int nPyramidLevel, int nBottomH, int nBottomW, SPPParameter spp_param)
Calculates the kernel and stride dimensions for the pooling layer, returns a correctly configured Lay...
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t the inputs.
The SplitLayer creates a 'split' path in the network by copying the bottom blob into multiple top blo...
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
uint? stride_h
The stride height (2D only)
uint? stride_w
The stride width (2D only)
uint? pad_h
The padding height (2D only)
uint? kernel_h
The kernel height (2D only)
uint? kernel_w
The kernel width (2D only)
uint? pad_w
The padding width (2D only)
Specifies the base parameter for all layers.
LayerParameter()
Constructor for the parameter.
SPPParameter spp_param
Returns the parameter set when initialized with LayerType.SPP
PoolingParameter pooling_param
Returns the parameter set when initialized with LayerType.POOLING
LayerType
Specifies the layer type.
PoolingMethod pool
Specifies the pooling method.
The SPPParameter specifies the parameters for the SPPLayer.
uint pyramid_height
Specifies the pyramid height.
PoolingParameter.PoolingMethod pool
Specifies the pooling method to use.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
The MyCaffe.common namespace contains common MyCaffe classes.
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-...