File indexing completed on 2025-01-18 10:10:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #ifndef TMVA_CNN_CONVLAYER
0028 #define TMVA_CNN_CONVLAYER
0029
0030 #include "TMatrix.h"
0031
0032 #include "TMVA/DNN/GeneralLayer.h"
0033 #include "TMVA/DNN/Functions.h"
0034 #include "TMVA/DNN/CNN/ContextHandles.h"
0035
0036 #include <vector>
0037 #include <iostream>
0038 #include <string>
0039
0040 namespace TMVA {
0041 namespace DNN {
0042 namespace CNN {
0043
0044 typedef struct TConvParams {
0045
0046 public:
0047 size_t batchSize;
0048
0049 size_t inputDepth;
0050 size_t inputHeight;
0051 size_t inputWidth;
0052
0053 size_t numberFilters;
0054 size_t filterHeight;
0055 size_t filterWidth;
0056
0057 size_t strideRows;
0058 size_t strideCols;
0059 size_t paddingHeight;
0060 size_t paddingWidth;
0061
0062 TConvParams(size_t _batchSize, size_t _inputDepth, size_t _inputHeight, size_t _inputWidth, size_t _numberFilters,
0063 size_t _filterHeight, size_t _filterWidth, size_t _strideRows, size_t _strideCols,
0064 size_t _paddingHeight, size_t _paddingWidth)
0065 : batchSize(_batchSize), inputDepth(_inputDepth), inputHeight(_inputHeight), inputWidth(_inputWidth),
0066 numberFilters(_numberFilters), filterHeight(_filterHeight), filterWidth(_filterWidth),
0067 strideRows(_strideRows), strideCols(_strideCols), paddingHeight(_paddingHeight),
0068 paddingWidth(_paddingWidth)
0069 {}
0070 } TConvParams;
0071
0072
0073
0074 template <typename Architecture_t>
0075 class TConvLayer : public VGeneralLayer<Architecture_t> {
0076 public:
0077 using Tensor_t = typename Architecture_t::Tensor_t;
0078 using Matrix_t = typename Architecture_t::Matrix_t;
0079 using Scalar_t = typename Architecture_t::Scalar_t;
0080
0081 using LayerDescriptor_t = typename Architecture_t::ConvolutionDescriptor_t;
0082 using WeightsDescriptor_t = typename Architecture_t::FilterDescriptor_t;
0083 using HelperDescriptor_t = typename Architecture_t::ActivationDescriptor_t;
0084
0085 using AlgorithmForward_t = typename Architecture_t::AlgorithmForward_t;
0086 using AlgorithmBackward_t = typename Architecture_t::AlgorithmBackward_t;
0087 using AlgorithmHelper_t = typename Architecture_t::AlgorithmHelper_t;
0088 using ReduceTensorDescriptor_t = typename Architecture_t::ReduceTensorDescriptor_t;
0089
0090
0091 using AlgorithmDataType_t = typename Architecture_t::AlgorithmDataType_t;
0092
0093
0094 static size_t calculateDimension(size_t imgDim, size_t fltDim, size_t padding, size_t stride);
0095
0096
0097 static size_t inline calculateNLocalViewPixels(size_t depth, size_t height, size_t width) { return depth * height * width; }
0098
0099
0100 static size_t calculateNLocalViews(size_t inputHeight, size_t filterHeight, size_t paddingHeight, size_t strideRows,
0101 size_t inputWidth, size_t filterWidth, size_t paddingWidth, size_t strideCols);
0102
0103 protected:
0104 size_t fFilterDepth;
0105 size_t fFilterHeight;
0106 size_t fFilterWidth;
0107
0108 size_t fStrideRows;
0109 size_t fStrideCols;
0110
0111 size_t fNLocalViewPixels;
0112 size_t fNLocalViews;
0113
0114 Scalar_t fDropoutProbability;
0115
0116 TDescriptors * fDescriptors = nullptr;
0117
0118 TWorkspace * fWorkspace = nullptr;
0119 private:
0120 size_t fPaddingHeight;
0121 size_t fPaddingWidth;
0122
0123 Tensor_t fInputActivation;
0124
0125 std::vector<int> fBackwardIndices;
0126
0127 EActivationFunction fF;
0128 ERegularization fReg;
0129 Scalar_t fWeightDecay;
0130
0131 Tensor_t fForwardTensor;
0132
0133 void InitializeDescriptors();
0134 void ReleaseDescriptors();
0135 void InitializeWorkspace();
0136 void FreeWorkspace();
0137
0138 public:
0139
0140 TConvLayer(size_t BatchSize, size_t InputDepth, size_t InputHeight, size_t InputWidth, size_t Depth, EInitialization Init,
0141 size_t FilterHeight, size_t FilterWidth, size_t StrideRows, size_t StrideCols, size_t PaddingHeight,
0142 size_t PaddingWidth, Scalar_t DropoutProbability, EActivationFunction f, ERegularization Reg,
0143 Scalar_t WeightDecay);
0144
0145
0146 TConvLayer(TConvLayer<Architecture_t> *layer);
0147
0148
0149 TConvLayer(const TConvLayer &);
0150
0151
0152 virtual ~TConvLayer();
0153
0154
0155
0156
0157
0158
0159
0160
0161 void Forward(Tensor_t &input, bool applyDropout = false);
0162
0163
0164
0165
0166
0167 void Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward);
0168
0169
0170
0171 void Print() const;
0172
0173
0174 virtual void AddWeightsXMLTo(void *parent);
0175
0176
0177 virtual void ReadWeightsFromXML(void *parent);
0178
0179
0180 size_t GetFilterDepth() const { return fFilterDepth; }
0181 size_t GetFilterHeight() const { return fFilterHeight; }
0182 size_t GetFilterWidth() const { return fFilterWidth; }
0183
0184 size_t GetStrideRows() const { return fStrideRows; }
0185 size_t GetStrideCols() const { return fStrideCols; }
0186
0187 size_t GetPaddingHeight() const { return fPaddingHeight; }
0188 size_t GetPaddingWidth() const { return fPaddingWidth; }
0189
0190 size_t GetNLocalViewPixels() const { return fNLocalViewPixels; }
0191 size_t GetNLocalViews() const { return fNLocalViews; }
0192
0193 Scalar_t GetDropoutProbability() const { return fDropoutProbability; }
0194
0195 const Tensor_t &GetInputActivation() const { return fInputActivation; }
0196 Tensor_t &GetInputActivation() { return fInputActivation; }
0197
0198 Matrix_t &GetInputActivationAt(size_t i) { return fInputActivation[i]; }
0199 const Matrix_t &GetInputActivationAt(size_t i) const { return fInputActivation[i]; }
0200
0201 const Tensor_t &GetForwardMatrices() const { return fForwardTensor; }
0202 Tensor_t &GetForwardMatrices() { return fForwardTensor; }
0203
0204 EActivationFunction GetActivationFunction() const { return fF; }
0205 ERegularization GetRegularization() const { return fReg; }
0206 Scalar_t GetWeightDecay() const { return fWeightDecay; }
0207
0208
0209 TDescriptors * GetDescriptors() {return fDescriptors;}
0210 const TDescriptors * GetDescriptors() const {return fDescriptors;}
0211
0212 TWorkspace * GetWorkspace() {return fWorkspace;}
0213 const TWorkspace * GetWorkspace() const {return fWorkspace;}
0214 };
0215
0216
0217
0218
0219
0220
0221 template <typename Architecture_t>
0222 TConvLayer<Architecture_t>::TConvLayer(size_t batchSize, size_t inputDepth, size_t inputHeight, size_t inputWidth,
0223 size_t depth, EInitialization init, size_t filterHeight, size_t filterWidth,
0224 size_t strideRows, size_t strideCols, size_t paddingHeight, size_t paddingWidth,
0225 Scalar_t dropoutProbability, EActivationFunction f, ERegularization reg,
0226 Scalar_t weightDecay)
0227 : VGeneralLayer<Architecture_t>(batchSize, inputDepth, inputHeight, inputWidth, depth,
0228 calculateDimension(inputHeight, filterHeight, paddingHeight, strideRows),
0229 calculateDimension(inputWidth, filterWidth, paddingWidth, strideCols),
0230 1, depth, calculateNLocalViewPixels(inputDepth, filterHeight, filterWidth),
0231 1, depth, 1, batchSize, depth,
0232 calculateNLocalViews(inputHeight, filterHeight, paddingHeight, strideRows,
0233 inputWidth, filterWidth, paddingWidth, strideCols),
0234 init),
0235 fFilterDepth(inputDepth), fFilterHeight(filterHeight), fFilterWidth(filterWidth), fStrideRows(strideRows),
0236 fStrideCols(strideCols), fNLocalViewPixels(calculateNLocalViewPixels(inputDepth, filterHeight, filterWidth)),
0237 fNLocalViews(calculateNLocalViews(inputHeight, filterHeight, paddingHeight, strideRows,
0238 inputWidth, filterWidth, paddingWidth, strideCols)),
0239 fDropoutProbability(dropoutProbability), fPaddingHeight(paddingHeight), fPaddingWidth(paddingWidth),
0240 fInputActivation(), fF(f), fReg(reg), fWeightDecay(weightDecay)
0241 {
0242
0243
0244
0245
0246
0247 fInputActivation = Tensor_t( batchSize, depth, fNLocalViews);
0248 fForwardTensor = Tensor_t ( batchSize, fNLocalViews, fNLocalViewPixels );
0249
0250
0251 InitializeDescriptors();
0252 InitializeWorkspace();
0253 }
0254
0255
0256 template <typename Architecture_t>
0257 TConvLayer<Architecture_t>::TConvLayer(TConvLayer<Architecture_t> *layer)
0258 : VGeneralLayer<Architecture_t>(layer), fFilterDepth(layer->GetFilterDepth()),
0259 fFilterHeight(layer->GetFilterHeight()), fFilterWidth(layer->GetFilterWidth()),
0260 fStrideRows(layer->GetStrideRows()), fStrideCols(layer->GetStrideCols()),
0261 fNLocalViewPixels(layer->GetNLocalViewPixels()), fNLocalViews(layer->GetNLocalViews()),
0262 fDropoutProbability(layer->GetDropoutProbability()), fPaddingHeight(layer->GetPaddingHeight()),
0263 fPaddingWidth(layer->GetPaddingWidth()),
0264 fInputActivation( layer->GetInputActivation().GetShape() ),
0265 fF(layer->GetActivationFunction()),
0266 fReg(layer->GetRegularization()), fWeightDecay(layer->GetWeightDecay()),
0267 fForwardTensor( layer->GetForwardMatrices().GetShape() )
0268 {
0269 InitializeDescriptors();
0270 InitializeWorkspace();
0271
0272 }
0273
0274
0275 template <typename Architecture_t>
0276 TConvLayer<Architecture_t>::TConvLayer(const TConvLayer &convLayer)
0277 : VGeneralLayer<Architecture_t>(convLayer), fFilterDepth(convLayer.fFilterDepth),
0278 fFilterHeight(convLayer.fFilterHeight), fFilterWidth(convLayer.fFilterWidth), fStrideRows(convLayer.fStrideRows),
0279 fStrideCols(convLayer.fStrideCols), fNLocalViewPixels(convLayer.fNLocalViewPixels),
0280 fNLocalViews(convLayer.fNLocalViews), fDropoutProbability(convLayer.fDropoutProbability),
0281 fPaddingHeight(convLayer.fPaddingHeight), fPaddingWidth(convLayer.fPaddingWidth),
0282 fInputActivation( convLayer.GetInputActivation().GetShape() ),
0283 fF(convLayer.fF),
0284 fReg(convLayer.fReg), fWeightDecay(convLayer.fWeightDecay),
0285 fForwardTensor( convLayer.GetForwardMatrices().GetShape() )
0286 {
0287 InitializeDescriptors();
0288 InitializeWorkspace();
0289 }
0290
0291
0292
0293 template <typename Architecture_t>
0294 TConvLayer<Architecture_t>::~TConvLayer()
0295 {
0296
0297 if (fDescriptors) {
0298 ReleaseDescriptors();
0299 delete fDescriptors;
0300 }
0301
0302 if (fWorkspace) {
0303 FreeWorkspace();
0304 delete fWorkspace;
0305 }
0306 }
0307
0308
0309
0310 template <typename Architecture_t>
0311 auto TConvLayer<Architecture_t>::Forward(Tensor_t &input, bool ) -> void
0312 {
0313 TConvParams params(this->GetBatchSize(), this->GetInputDepth(), this->GetInputHeight(), this->GetInputWidth(),
0314 this->GetDepth(), this->GetFilterHeight(), this->GetFilterWidth(),
0315 this->GetStrideRows(), this->GetStrideCols(), this->GetPaddingHeight(), this->GetPaddingWidth());
0316
0317
0318 Architecture_t::ConvLayerForward(this->GetOutput(), this->GetInputActivation(), input, this->GetWeightsAt(0),
0319 this->GetBiasesAt(0), params, this->GetActivationFunction(),
0320 this->GetForwardMatrices(), (TCNNDescriptors<TConvLayer<Architecture_t>> &) (*fDescriptors),
0321 (TCNNWorkspace<TConvLayer<Architecture_t>> &) (*fWorkspace));
0322 }
0323
0324
0325 template <typename Architecture_t>
0326 auto TConvLayer<Architecture_t>::Backward(Tensor_t &gradients_backward,
0327 const Tensor_t &activations_backward) -> void
0328
0329
0330 {
0331 Architecture_t::ConvLayerBackward(
0332 gradients_backward, this->GetWeightGradientsAt(0), this->GetBiasGradientsAt(0), this->GetInputActivation(),
0333 this->GetActivationGradients(), this->GetWeightsAt(0), activations_backward, this->GetOutput(),
0334 this->GetActivationFunction(),
0335 (TCNNDescriptors<TConvLayer<Architecture_t>> &) (*fDescriptors),
0336 (TCNNWorkspace<TConvLayer<Architecture_t>> &) (*fWorkspace),
0337 this->GetBatchSize(), this->GetInputHeight(), this->GetInputWidth(), this->GetDepth(),
0338 this->GetHeight(), this->GetWidth(), this->GetFilterDepth(), this->GetFilterHeight(),
0339 this->GetFilterWidth(), this->GetNLocalViews());
0340
0341 addRegularizationGradients<Architecture_t>(this->GetWeightGradientsAt(0), this->GetWeightsAt(0),
0342 this->GetWeightDecay(), this->GetRegularization());
0343 }
0344
0345
0346 template <typename Architecture_t>
0347 auto TConvLayer<Architecture_t>::Print() const -> void
0348 {
0349 std::cout << " CONV LAYER: \t";
0350 std::cout << "( W = " << this->GetWidth() << " , ";
0351 std::cout << " H = " << this->GetHeight() << " , ";
0352 std::cout << " D = " << this->GetDepth() << " ) ";
0353
0354 std::cout << "\t Filter ( W = " << this->GetFilterWidth() << " , ";
0355 std::cout << " H = " << this->GetFilterHeight() << " ) ";
0356
0357 if (this->GetOutput().GetSize() > 0) {
0358 std::cout << "\tOutput = ( " << this->GetOutput().GetFirstSize() << " , "
0359 << this->GetOutput().GetCSize() << " , " << this->GetOutput().GetHSize() << " , " << this->GetOutput().GetWSize()
0360 << " ) ";
0361 }
0362 std::vector<std::string> activationNames = { "Identity","Relu","Sigmoid","Tanh","SymmRelu","SoftSign","Gauss" };
0363 std::cout << "\t Activation Function = ";
0364 std::cout << activationNames[ static_cast<int>(fF) ] << std::endl;
0365 }
0366
0367
0368 template <typename Architecture_t>
0369 void TConvLayer<Architecture_t>::AddWeightsXMLTo(void *parent)
0370 {
0371 auto layerxml = gTools().xmlengine().NewChild(parent, nullptr, "ConvLayer");
0372
0373 gTools().xmlengine().NewAttr(layerxml, nullptr, "Depth", gTools().StringFromInt(this->GetDepth()));
0374 gTools().xmlengine().NewAttr(layerxml, nullptr, "FilterHeight", gTools().StringFromInt(this->GetFilterHeight()));
0375 gTools().xmlengine().NewAttr(layerxml, nullptr, "FilterWidth", gTools().StringFromInt(this->GetFilterWidth()));
0376 gTools().xmlengine().NewAttr(layerxml, nullptr, "StrideRows", gTools().StringFromInt(this->GetStrideRows()));
0377 gTools().xmlengine().NewAttr(layerxml, nullptr, "StrideCols", gTools().StringFromInt(this->GetStrideCols()));
0378 gTools().xmlengine().NewAttr(layerxml, nullptr, "PaddingHeight", gTools().StringFromInt(this->GetPaddingHeight()));
0379 gTools().xmlengine().NewAttr(layerxml, nullptr, "PaddingWidth", gTools().StringFromInt(this->GetPaddingWidth()));
0380
0381
0382 int activationFunction = static_cast<int>(this -> GetActivationFunction());
0383 gTools().xmlengine().NewAttr(layerxml, nullptr, "ActivationFunction",
0384 TString::Itoa(activationFunction, 10));
0385
0386
0387 this->WriteMatrixToXML(layerxml, "Weights", this -> GetWeightsAt(0));
0388 this->WriteMatrixToXML(layerxml, "Biases", this -> GetBiasesAt(0));
0389 }
0390
0391
0392 template <typename Architecture_t>
0393 void TConvLayer<Architecture_t>::ReadWeightsFromXML(void *parent)
0394 {
0395
0396
0397 this->ReadMatrixXML(parent,"Weights", this -> GetWeightsAt(0));
0398 this->ReadMatrixXML(parent,"Biases", this -> GetBiasesAt(0));
0399 }
0400
0401 template <typename Architecture_t>
0402 size_t TConvLayer<Architecture_t>::calculateDimension(size_t imgDim, size_t fltDim, size_t padding, size_t stride)
0403 {
0404 size_t temp = imgDim - fltDim + 2 * padding;
0405 if (temp % stride || temp + stride <= 0) {
0406 Fatal("calculateDimension", "Not compatible hyper parameters for layer - (imageDim, filterDim, padding, stride) "
0407 "%zu, %zu, %zu, %zu", imgDim, fltDim, padding, stride);
0408 }
0409 return temp / stride + 1;
0410 }
0411
0412 template <typename Architecture_t>
0413 size_t TConvLayer<Architecture_t>::calculateNLocalViews(size_t inputHeight, size_t filterHeight, size_t paddingHeight,
0414 size_t strideRows, size_t inputWidth, size_t filterWidth,
0415 size_t paddingWidth, size_t strideCols)
0416 {
0417 int height = calculateDimension(inputHeight, filterHeight, paddingHeight, strideRows);
0418 int width = calculateDimension(inputWidth, filterWidth, paddingWidth, strideCols);
0419
0420 return height * width;
0421 }
0422
0423
0424 template <typename Architecture_t>
0425 void TConvLayer<Architecture_t>::InitializeDescriptors() {
0426 Architecture_t::InitializeConvDescriptors(fDescriptors, this);
0427 }
0428
0429 template <typename Architecture_t>
0430 void TConvLayer<Architecture_t>::ReleaseDescriptors() {
0431 Architecture_t::ReleaseConvDescriptors(fDescriptors);
0432 }
0433
0434
0435 template <typename Architecture_t>
0436 void TConvLayer<Architecture_t>::InitializeWorkspace() {
0437 TConvParams params(this->GetBatchSize(), this->GetInputDepth(), this->GetInputHeight(), this->GetInputWidth(),
0438 this->GetDepth(), this->GetFilterHeight(), this->GetFilterWidth(),
0439 this->GetStrideRows(), this->GetStrideCols(), this->GetPaddingHeight(), this->GetPaddingWidth());
0440
0441 Architecture_t::InitializeConvWorkspace(fWorkspace, fDescriptors, params, this);
0442 }
0443
0444 template <typename Architecture_t>
0445 void TConvLayer<Architecture_t>::FreeWorkspace() {
0446 Architecture_t::FreeConvWorkspace(fWorkspace);
0447 }
0448
0449
0450
0451 }
0452 }
0453 }
0454
0455 #endif