Logo ROOT   master
Reference Guide
MaxPoolLayer.h
Go to the documentation of this file.
1 // @(#)root/tmva/tmva/dnn:$Id$
2 // Author: Vladimir Ilievski
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : TMaxPoolLayer *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Max Pool Deep Neural Network Layer *
12  * *
13  * Authors (alphabetical): *
14  * Vladimir Ilievski <ilievski.vladimir@live.com> - CERN, Switzerland *
15  * *
16  * Copyright (c) 2005-2015: *
17  * CERN, Switzerland *
18  * U. of Victoria, Canada *
19  * MPI-K Heidelberg, Germany *
20  * U. of Bonn, Germany *
21  * *
22  * Redistribution and use in source and binary forms, with or without *
23  * modification, are permitted according to the terms listed in LICENSE *
24  * (http://tmva.sourceforge.net/LICENSE) *
25  **********************************************************************************/
26 
27 #ifndef MAXPOOLLAYER_H_
28 #define MAXPOOLLAYER_H_
29 
30 #include "TMatrix.h"
31 
32 #include "TMVA/DNN/CNN/ConvLayer.h"
33 #include "TMVA/DNN/Functions.h"
35 
36 #include <iostream>
37 
38 namespace TMVA {
39 namespace DNN {
40 namespace CNN {
41 
42 
43 /** \class TMaxPoolLayer
44 
45  Generic Max Pooling Layer class.
46 
47  This generic Max Pooling Layer Class represents a pooling layer of
48  a CNN. It inherits all of the properties of the convolutional layer
49  TConvLayer, but it overrides the propagation methods. In a sense, max pooling
50  can be seen as non-linear convolution: a filter slides over the input and produces
51  one element as a function of the the elements within the receptive field.
52  In addition to that, it contains a matrix of winning units.
53 
54  The height and width of the weights and biases is set to 0, since this
55  layer does not contain any weights.
56 
57  */
58 template <typename Architecture_t>
59 class TMaxPoolLayer : public VGeneralLayer<Architecture_t> {
60 
61 public:
62  using Tensor_t = typename Architecture_t::Tensor_t;
63  using Matrix_t = typename Architecture_t::Matrix_t;
64  using Scalar_t = typename Architecture_t::Scalar_t;
65 
66  using LayerDescriptor_t = typename Architecture_t::PoolingDescriptor_t;
67  using WeightsDescriptor_t = typename Architecture_t::EmptyDescriptor_t;
68  using HelperDescriptor_t = typename Architecture_t::DropoutDescriptor_t;
69 
70  // do we need thse ???
71  using AlgorithmForward_t = typename Architecture_t::AlgorithmForward_t; // Forward layer operation
72  using AlgorithmBackward_t = typename Architecture_t::AlgorithmBackward_t; // Backward layer operation
73  using AlgorithmHelper_t = typename Architecture_t::AlgorithmHelper_t; // Used for weight grad backward pass
74 
75  // FIXME: Add other cudnn types (algorithm preference etc.)
76  using AlgorithmDataType_t = typename Architecture_t::AlgorithmDataType_t;
77 
78  using ReduceTensorDescriptor_t = typename Architecture_t::ReduceTensorDescriptor_t; // used for reduction of tensor(bias grad)
79 
80 protected:
81  size_t fFilterDepth; ///< The depth of the filter.
82  size_t fFilterHeight; ///< The height of the filter.
83  size_t fFilterWidth; ///< The width of the filter.
84 
85  size_t fStrideRows; ///< The number of row pixels to slid the filter each step.
86  size_t fStrideCols; ///< The number of column pixels to slid the filter each step.
87 
88  size_t fNLocalViewPixels; ///< The number of pixels in one local image view.
89  size_t fNLocalViews; ///< The number of local views in one image.
90 
91  Scalar_t fDropoutProbability; ///< Probability that an input is active.
92 
93  TDescriptors *fDescriptors = nullptr; ///< Keeps the convolution, activations and filter descriptors
94 
95  TWorkspace *fWorkspace = nullptr;
96 
97 private:
98  Tensor_t fIndexTensor; ///< Matrix of indices for the backward pass.
99 
100  void InitializeDescriptors();
101  void ReleaseDescriptors();
102  void InitializeWorkspace();
103  void FreeWorkspace();
104 
105 public:
106  /*! Constructor. */
107  TMaxPoolLayer(size_t BatchSize, size_t InputDepth, size_t InputHeight, size_t InputWidth, size_t FilterHeight,
108  size_t FilterWidth, size_t StrideRows, size_t StrideCols, Scalar_t DropoutProbability);
109 
110  /*! Copy the max pooling layer provided as a pointer */
112 
113  /*! Copy constructor. */
114  TMaxPoolLayer(const TMaxPoolLayer &);
115 
116  /*! Destructor. */
117  virtual ~TMaxPoolLayer();
118 
119  // virtual void Initialize();
120 
121  /*! Computes activation of the layer for the given input. The input
122  * must be in 3D tensor form with the different matrices corresponding to
123  * different events in the batch. It spatially downsamples the input
124  * matrices. */
125  void Forward(Tensor_t &input, bool applyDropout = true);
126 
127  /*! Depending on the winning units determined during the Forward pass,
128  * it only forwards the derivatives to the right units in the previous
129  * layer. Must only be called directly at the corresponding call
130  * to Forward(...). */
131  void Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward);
132  // Tensor_t &inp1, Tensor_t &inp2);
133 
134  /*! Writes the information and the weights about the layer in an XML node. */
135  virtual void AddWeightsXMLTo(void *parent);
136 
137  /*! Read the information and the weights about the layer from XML node. */
138  virtual void ReadWeightsFromXML(void *parent);
139 
140  /*! Prints the info about the layer. */
141  void Print() const;
142 
143  /*! Getters */
144  size_t GetFilterDepth() const { return fFilterDepth; }
145  size_t GetFilterHeight() const { return fFilterHeight; }
146  size_t GetFilterWidth() const { return fFilterWidth; }
147 
148  size_t GetStrideRows() const { return fStrideRows; }
149  size_t GetStrideCols() const { return fStrideCols; }
150 
151  size_t GetNLocalViews() const { return fNLocalViews; }
152 
154 
155  const Tensor_t & GetIndexTensor() const { return fIndexTensor; }
157 
158  // The following getters are used for testing
160  const TDescriptors *GetDescriptors() const { return fDescriptors; }
161 
163  const TWorkspace *GetWorkspace() const { return fWorkspace; }
164 };
165 
166 //______________________________________________________________________________
167 template <typename Architecture_t>
168 TMaxPoolLayer<Architecture_t>::TMaxPoolLayer(size_t batchSize, size_t inputDepth, size_t inputHeight, size_t inputWidth,
169  size_t filterHeight, size_t filterWidth, size_t strideRows,
170  size_t strideCols, Scalar_t dropoutProbability)
171  : VGeneralLayer<Architecture_t>(
172  batchSize, inputDepth, inputHeight, inputWidth, inputDepth,
173  TConvLayer<Architecture_t>::calculateDimension(inputHeight, filterHeight, 0, strideRows),
174  TConvLayer<Architecture_t>::calculateDimension(inputWidth, filterWidth, 0, strideCols), 0, 0, 0, 0, 0,
175  0, // weights dimensions
176  batchSize, inputDepth,
177  TConvLayer<Architecture_t>::calculateNLocalViews(inputHeight, filterHeight, 0, strideRows, inputWidth,
178  filterWidth, 0, strideCols),
180  fFilterDepth(inputDepth), fFilterHeight(filterHeight), fFilterWidth(filterWidth), fStrideRows(strideRows),
181  fStrideCols(strideCols),
182  fNLocalViews(TConvLayer<Architecture_t>::calculateNLocalViews(inputHeight, filterHeight, 0, strideRows,
183  inputWidth, filterWidth, 0, strideCols)),
184  fDropoutProbability(dropoutProbability), fIndexTensor(batchSize, inputDepth, fNLocalViews)
185 {
188 }
189 
190 //______________________________________________________________________________
191 template <typename Architecture_t>
193  : VGeneralLayer<Architecture_t>(layer), fFilterDepth(layer->GetFilterDepth()),
194  fFilterHeight(layer->GetFilterHeight()), fFilterWidth(layer->GetFilterWidth()),
195  fStrideRows(layer->GetStrideRows()), fStrideCols(layer->GetStrideCols()), fNLocalViews(layer->GetNLocalViews()),
196  fDropoutProbability(layer->GetDropoutProbability()), fIndexTensor(layer->GetIndexTensor().GetShape())
197 {
200 }
201 
202 //______________________________________________________________________________
203 template <typename Architecture_t>
205  : VGeneralLayer<Architecture_t>(layer), fFilterDepth(layer.fFilterDepth), fFilterHeight(layer.fFilterHeight),
206  fFilterWidth(layer.fFilterWidth), fStrideRows(layer.fStrideRows), fStrideCols(layer.fStrideCols),
207  fNLocalViews(layer.fNLocalViews), fDropoutProbability(layer.fDropoutProbability),
208  fIndexTensor(layer.GetIndexTensor().GetShape())
209 {
212 }
213 
214 //______________________________________________________________________________
215 template <typename Architecture_t>
217 {
218  if (fDescriptors) {
219  ReleaseDescriptors();
220  delete fDescriptors;
221  fDescriptors = nullptr;
222  }
223 
224  if (fWorkspace) {
225  FreeWorkspace();
226  delete fWorkspace;
227  fWorkspace = nullptr;
228  }
229 }
230 
231 //______________________________________________________________________________
232 template <typename Architecture_t>
233 auto TMaxPoolLayer<Architecture_t>::Forward(Tensor_t &input, bool applyDropout) -> void
234 {
235  if (applyDropout && (this->GetDropoutProbability() != 1.0)) {
236  Architecture_t::DropoutForward(input, fDescriptors, fWorkspace, this->GetDropoutProbability());
237  }
238 
239  Architecture_t::Downsample(
240  this->GetOutput(), fIndexTensor, input, (TCNNDescriptors<TMaxPoolLayer<Architecture_t>> &)*fDescriptors,
241  (TCNNWorkspace<TMaxPoolLayer<Architecture_t>> &)*fWorkspace, this->GetInputHeight(), this->GetInputWidth(),
242  this->GetFilterHeight(), this->GetFilterWidth(), this->GetStrideRows(), this->GetStrideCols());
243 }
244 
245 //______________________________________________________________________________
246 template <typename Architecture_t>
247 auto TMaxPoolLayer<Architecture_t>::Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward) -> void
248 // Tensor_t & /*inp1*/, Tensor_t &
249 {
250 
251  if (this->GetDropoutProbability() != 1.0) {
252  Architecture_t::DropoutBackward(this->GetActivationGradients(), fDescriptors, fWorkspace);
253  }
254  Architecture_t::MaxPoolLayerBackward(
255  gradients_backward, this->GetActivationGradients(), fIndexTensor, activations_backward, this->GetOutput(),
257  (TCNNWorkspace<TMaxPoolLayer<Architecture_t>> &)(*fWorkspace), this->GetInputHeight(), this->GetInputWidth(),
258  this->GetFilterHeight(), this->GetFilterWidth(), this->GetStrideRows(), this->GetStrideCols(),
259  this->GetNLocalViews());
260 }
261 
262 //______________________________________________________________________________
263 template <typename Architecture_t>
265 {
266  std::cout << " POOL Layer: \t";
267  std::cout << "( W = " << this->GetWidth() << " , ";
268  std::cout << " H = " << this->GetHeight() << " , ";
269  std::cout << " D = " << this->GetDepth() << " ) ";
270 
271  std::cout << "\t Filter ( W = " << this->GetFilterWidth() << " , ";
272  std::cout << " H = " << this->GetFilterHeight() << " ) ";
273 
274  if (this->GetOutput().GetSize() > 0) {
275  std::cout << "\tOutput = ( " << this->GetOutput().GetFirstSize() << " , " << this->GetOutput().GetCSize()
276  << " , " << this->GetOutput().GetHSize() << " , " << this->GetOutput().GetWSize() << " ) ";
277  }
278  std::cout << std::endl;
279 }
280 
281 //______________________________________________________________________________
282 template <typename Architecture_t>
284 {
285  auto layerxml = gTools().xmlengine().NewChild(parent, 0, "MaxPoolLayer");
286 
287  // write maxpool layer info
288  gTools().xmlengine().NewAttr(layerxml, 0, "FilterHeight", gTools().StringFromInt(this->GetFilterHeight()));
289  gTools().xmlengine().NewAttr(layerxml, 0, "FilterWidth", gTools().StringFromInt(this->GetFilterWidth()));
290  gTools().xmlengine().NewAttr(layerxml, 0, "StrideRows", gTools().StringFromInt(this->GetStrideRows()));
291  gTools().xmlengine().NewAttr(layerxml, 0, "StrideCols", gTools().StringFromInt(this->GetStrideCols()));
292 
293 }
294 
295 //______________________________________________________________________________
296 template <typename Architecture_t>
298 {
299  // all info is read before - nothing to do
300 }
301 
302 //______________________________________________________________________________
303 template <typename Architecture_t>
305  Architecture_t::InitializePoolDescriptors(fDescriptors, this);
306 }
307 
308 template <typename Architecture_t>
310  Architecture_t::ReleasePoolDescriptors(fDescriptors);
311 }
312 
313 //______________________________________________________________________________
314 template <typename Architecture_t>
316 // #if 0 // this is for dropout and needs to be fixed
317 // TConvParams params(this->GetBatchSize(), this->GetInputDepth(), this->GetInputHeight(), this->GetInputWidth(),
318 // this->GetDepth(), this->GetFilterHeight(), this->GetFilterWidth(),
319 // this->GetStrideRows(), this->GetStrideCols(), this->GetPaddingHeight(), this->GetPaddingWidth());
320 
321 // Architecture_t::InitializePoolDropoutWorkspace(fWorkspace, fDescriptors, params, this);
322 // #endif
323 }
324 
325 template <typename Architecture_t>
327  //Architecture_t::FreePoolDropoutWorkspace(fWorkspace, this);
328 }
329 
330 } // namespace CNN
331 } // namespace DNN
332 } // namespace TMVA
333 
334 #endif
size_t fFilterHeight
The height of the filter.
Definition: MaxPoolLayer.h:82
Generic General Layer class.
Definition: GeneralLayer.h:49
TXMLEngine & xmlengine()
Definition: Tools.h:268
typename Architecture_t::ReduceTensorDescriptor_t ReduceTensorDescriptor_t
Definition: MaxPoolLayer.h:78
virtual ~TMaxPoolLayer()
Destructor.
Definition: MaxPoolLayer.h:216
size_t fStrideRows
The number of row pixels to slid the filter each step.
Definition: MaxPoolLayer.h:85
size_t fFilterDepth
The depth of the filter.
Definition: MaxPoolLayer.h:81
Generic Max Pooling Layer class.
Definition: MaxPoolLayer.h:59
void Forward(Tensor_t &input, bool applyDropout=true)
Computes activation of the layer for the given input.
Definition: MaxPoolLayer.h:233
size_t fNLocalViews
The number of local views in one image.
Definition: MaxPoolLayer.h:89
typename Architecture_t::PoolingDescriptor_t LayerDescriptor_t
Definition: MaxPoolLayer.h:66
size_t fStrideCols
The number of column pixels to slid the filter each step.
Definition: MaxPoolLayer.h:86
typename Architecture_t::DropoutDescriptor_t HelperDescriptor_t
Definition: MaxPoolLayer.h:68
typename Architecture_t::AlgorithmHelper_t AlgorithmHelper_t
Definition: MaxPoolLayer.h:73
typename Architecture_t::AlgorithmDataType_t AlgorithmDataType_t
Definition: MaxPoolLayer.h:76
EInitialization
Definition: Functions.h:72
typename Architecture_t::Tensor_t Tensor_t
Definition: MaxPoolLayer.h:62
TDescriptors * fDescriptors
Keeps the convolution, activations and filter descriptors.
Definition: MaxPoolLayer.h:93
virtual void ReadWeightsFromXML(void *parent)
Read the information and the weights about the layer from XML node.
Definition: MaxPoolLayer.h:297
void Print() const
Prints the info about the layer.
Definition: MaxPoolLayer.h:264
typename Architecture_t::Scalar_t Scalar_t
Definition: MaxPoolLayer.h:64
size_t GetFilterDepth() const
Getters.
Definition: MaxPoolLayer.h:144
virtual void AddWeightsXMLTo(void *parent)
Writes the information and the weights about the layer in an XML node.
Definition: MaxPoolLayer.h:283
typename Architecture_t::AlgorithmBackward_t AlgorithmBackward_t
Definition: MaxPoolLayer.h:72
Scalar_t fDropoutProbability
Probability that an input is active.
Definition: MaxPoolLayer.h:91
typename Architecture_t::EmptyDescriptor_t WeightsDescriptor_t
Definition: MaxPoolLayer.h:67
Tools & gTools()
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
create new child element for parent node
Definition: TXMLEngine.cxx:710
size_t fNLocalViewPixels
The number of pixels in one local image view.
Definition: MaxPoolLayer.h:88
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:581
void Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward)
Depending on the winning units determined during the Forward pass, it only forwards the derivatives t...
Definition: MaxPoolLayer.h:247
Tensor_t fIndexTensor
Matrix of indices for the backward pass.
Definition: MaxPoolLayer.h:98
typename Architecture_t::Matrix_t Matrix_t
Definition: MaxPoolLayer.h:63
const Tensor_t & GetIndexTensor() const
Definition: MaxPoolLayer.h:155
TDescriptors * GetDescriptors()
Definition: MaxPoolLayer.h:159
create variable transformations
TMaxPoolLayer(size_t BatchSize, size_t InputDepth, size_t InputHeight, size_t InputWidth, size_t FilterHeight, size_t FilterWidth, size_t StrideRows, size_t StrideCols, Scalar_t DropoutProbability)
Constructor.
Definition: MaxPoolLayer.h:168
const TDescriptors * GetDescriptors() const
Definition: MaxPoolLayer.h:160
size_t fFilterWidth
The width of the filter.
Definition: MaxPoolLayer.h:83
const TWorkspace * GetWorkspace() const
Definition: MaxPoolLayer.h:163
typename Architecture_t::AlgorithmForward_t AlgorithmForward_t
Definition: MaxPoolLayer.h:71
Scalar_t GetDropoutProbability() const
Definition: MaxPoolLayer.h:153