Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 * *
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 * (see tmva/doc/LICENSE) *
25 **********************************************************************************/
26
27#ifndef MAXPOOLLAYER_H_
28#define MAXPOOLLAYER_H_
29
30#include "TMatrix.h"
31
33#include "TMVA/DNN/Functions.h"
35
36#include <iostream>
37
38namespace TMVA {
39namespace DNN {
40namespace 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 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 */
58template <typename Architecture_t>
59class TMaxPoolLayer : public VGeneralLayer<Architecture_t> {
60
61public:
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
80protected:
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
96
97private:
98 Tensor_t fIndexTensor; ///< Matrix of indices for the backward pass.
99
101 void ReleaseDescriptors();
102 void InitializeWorkspace();
103 void FreeWorkspace();
104
105public:
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. */
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//______________________________________________________________________________
167template <typename Architecture_t>
168TMaxPoolLayer<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//______________________________________________________________________________
191template <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//______________________________________________________________________________
203template <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//______________________________________________________________________________
215template <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//______________________________________________________________________________
232template <typename Architecture_t>
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//______________________________________________________________________________
246template <typename Architecture_t>
247auto 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//______________________________________________________________________________
263template <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//______________________________________________________________________________
282template <typename Architecture_t>
284{
285 auto layerxml = gTools().xmlengine().NewChild(parent, nullptr, "MaxPoolLayer");
286
287 // write maxpool layer info
288 gTools().xmlengine().NewAttr(layerxml, nullptr, "FilterHeight", gTools().StringFromInt(this->GetFilterHeight()));
289 gTools().xmlengine().NewAttr(layerxml, nullptr, "FilterWidth", gTools().StringFromInt(this->GetFilterWidth()));
290 gTools().xmlengine().NewAttr(layerxml, nullptr, "StrideRows", gTools().StringFromInt(this->GetStrideRows()));
291 gTools().xmlengine().NewAttr(layerxml, nullptr, "StrideCols", gTools().StringFromInt(this->GetStrideCols()));
292
293}
294
295//______________________________________________________________________________
296template <typename Architecture_t>
298{
299 // all info is read before - nothing to do
300}
301
302//______________________________________________________________________________
303template <typename Architecture_t>
305 Architecture_t::InitializePoolDescriptors(fDescriptors, this);
306}
307
308template <typename Architecture_t>
310 Architecture_t::ReleasePoolDescriptors(fDescriptors);
311}
312
313//______________________________________________________________________________
314template <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
325template <typename Architecture_t>
327 //Architecture_t::FreePoolDropoutWorkspace(fWorkspace, this);
328}
329
330} // namespace CNN
331} // namespace DNN
332} // namespace TMVA
333
334#endif
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Generic Max Pooling Layer class.
typename Architecture_t::Tensor_t Tensor_t
const TWorkspace * GetWorkspace() const
TDescriptors * GetDescriptors()
typename Architecture_t::AlgorithmHelper_t AlgorithmHelper_t
Used for weight grad backward pass.
typename Architecture_t::Matrix_t Matrix_t
Scalar_t GetDropoutProbability() const
typename Architecture_t::EmptyDescriptor_t WeightsDescriptor_t
size_t fFilterHeight
The height of the filter.
typename Architecture_t::ReduceTensorDescriptor_t ReduceTensorDescriptor_t
void Forward(Tensor_t &input, bool applyDropout=true)
Computes activation of the layer for the given input.
TDescriptors * fDescriptors
Keeps the convolution, activations and filter descriptors.
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.
typename Architecture_t::AlgorithmForward_t AlgorithmForward_t
Forward layer operation.
Tensor_t fIndexTensor
Matrix of indices for the backward pass.
size_t fNLocalViewPixels
The number of pixels in one local image view.
typename Architecture_t::DropoutDescriptor_t HelperDescriptor_t
Scalar_t fDropoutProbability
Probability that an input is active.
virtual void ReadWeightsFromXML(void *parent)
Read the information and the weights about the layer from XML node.
size_t fStrideCols
The number of column pixels to slid the filter each step.
size_t fFilterWidth
The width of the filter.
typename Architecture_t::AlgorithmBackward_t AlgorithmBackward_t
Backward layer operation.
void Print() const
Prints the info about the layer.
size_t fNLocalViews
The number of local views in one image.
typename Architecture_t::Scalar_t Scalar_t
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...
const Tensor_t & GetIndexTensor() const
size_t fFilterDepth
The depth of the filter.
virtual void AddWeightsXMLTo(void *parent)
Writes the information and the weights about the layer in an XML node.
typename Architecture_t::PoolingDescriptor_t LayerDescriptor_t
typename Architecture_t::AlgorithmDataType_t AlgorithmDataType_t
const TDescriptors * GetDescriptors() const
virtual ~TMaxPoolLayer()
Destructor.
size_t fStrideRows
The number of row pixels to slid the filter each step.
size_t GetFilterDepth() const
Getters.
Generic General Layer class.
TXMLEngine & xmlengine()
Definition Tools.h:262
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
create new child element for parent node
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
create variable transformations
Tools & gTools()