Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNNLayer.h
Go to the documentation of this file.
1// @(#)root/tmva/tmva/dnn/rnn:$Id$
2// Author: Saurav Shekhar 19/07/17
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6 * Package: TMVA *
7 * Class : BasicRNNLayer *
8 * *
9 * Description: *
10 * NeuralNetwork *
11 * *
12 * Authors (alphabetical): *
13 * Saurav Shekhar <sauravshekhar01@gmail.com> - ETH Zurich, Switzerland *
14 * *
15 * Copyright (c) 2005-2015: *
16 * All rights reserved. *
17 * CERN, Switzerland *
18 * *
19 * For the licensing terms see $ROOTSYS/LICENSE. *
20 * For the list of contributors see $ROOTSYS/README/CREDITS. *
21 **********************************************************************************/
22
23//#pragma once
24
25//////////////////////////////////////////////////////////////////////
26// <Description> //
27//////////////////////////////////////////////////////////////////////
28
29#ifndef TMVA_DNN_RNN_LAYER
30#define TMVA_DNN_RNN_LAYER
31
32#include <cmath>
33#include <iostream>
34#include <vector>
35#include <string>
36
37#include "TMatrix.h"
39#include "TMVA/DNN/Functions.h"
41
42namespace TMVA
43{
44namespace DNN
45{
46
47namespace RNN {
48
49//______________________________________________________________________________
50//
51// Basic RNN Layer
52//______________________________________________________________________________
53
54/** \class BasicRNNLayer
55 Generic implementation
56*/
57template<typename Architecture_t>
58 class TBasicRNNLayer : public VGeneralLayer<Architecture_t>
59{
60
61public:
62
63 using Tensor_t = typename Architecture_t::Tensor_t;
64 using Matrix_t = typename Architecture_t::Matrix_t;
65 using Scalar_t = typename Architecture_t::Scalar_t;
66
67 using LayerDescriptor_t = typename Architecture_t::RecurrentDescriptor_t;
68 using WeightsDescriptor_t = typename Architecture_t::FilterDescriptor_t;
69 using TensorDescriptor_t = typename Architecture_t::TensorDescriptor_t;
70 using HelperDescriptor_t = typename Architecture_t::DropoutDescriptor_t;
71
72 using RNNWorkspace_t = typename Architecture_t::RNNWorkspace_t;
73 using RNNDescriptors_t = typename Architecture_t::RNNDescriptors_t;
74
75private:
76
77 size_t fTimeSteps; ///< Timesteps for RNN
78 size_t fStateSize; ///< Hidden state size of RNN
79 bool fRememberState; ///< Remember state in next pass
80 bool fReturnSequence = false; ///< Return in output full sequence or just last element in time
81
82 DNN::EActivationFunction fF; ///< Activation function of the hidden state
83
84 Matrix_t fState; ///< Hidden State
85 Matrix_t &fWeightsInput; ///< Input weights, fWeights[0]
86 Matrix_t &fWeightsState; ///< Prev state weights, fWeights[1]
87 Matrix_t &fBiases; ///< Biases
88
89 Tensor_t fDerivatives; ///< First fDerivatives of the activations
90 Matrix_t &fWeightInputGradients; ///< Gradients w.r.t. the input weights
91 Matrix_t &fWeightStateGradients; ///< Gradients w.r.t. the recurring weights
92 Matrix_t &fBiasGradients; ///< Gradients w.r.t. the bias values
93
96
97 typename Architecture_t::ActivationDescriptor_t fActivationDesc;
98
99 TDescriptors *fDescriptors = nullptr; ///< Keeps all the RNN descriptors
100 TWorkspace *fWorkspace = nullptr; // workspace needed for GPU computation (CudNN)
101
102 Matrix_t fCell; ///< Empty matrix for RNN
103
104 // tensors used internally for the forward and backward pass
105 Tensor_t fX; ///< cached input tensor as T x B x I
106 Tensor_t fY; ///< cached output tensor as T x B x S
107 Tensor_t fDx; ///< cached gradient on the input (output of backward) as T x B x I
108 Tensor_t fDy; ///< cached activation gradient (input of backward) as T x B x S
109
110
111public:
112
113 /** Constructor */
114 TBasicRNNLayer(size_t batchSize, size_t stateSize, size_t inputSize,
115 size_t timeSteps, bool rememberState = false, bool returnSequence = false,
118
119 /** Copy Constructor */
121
122 /*! Destructor. */
123 virtual ~TBasicRNNLayer();
124
125 /*! Initialize the weights according to the given initialization
126 ** method. */
127 void Initialize() override;
128
129 /*! Initialize the state
130 ** method. */
132
133 /*! Compute and return the next state with given input
134 * matrix */
135 void Forward(Tensor_t &input, bool isTraining = true) override;
136
137 /*! Forward for a single cell (time unit) */
138 void CellForward(const Matrix_t &input, Matrix_t & dF);
139
140 /*! Backpropagates the error. Must only be called directly at the corresponding
141 * call to Forward(...). */
143 const Tensor_t &activations_backward) override;
144
145 /* Updates weights and biases, given the learning rate */
146 void Update(const Scalar_t learningRate);
147
148 /*! Backward for a single time unit
149 * a the corresponding call to Forward(...). */
153
154 /** Prints the info about the layer */
155 void Print() const override;
156
157 /*! Writes the information and the weights about the layer in an XML node. */
158 void AddWeightsXMLTo(void *parent) override;
159
160 /*! Read the information and the weights about the layer from XML node. */
161 void ReadWeightsFromXML(void *parent) override;
162
163 void InitTensors();
164 // void InitializeDescriptors();
165 // void ReleaseDescriptors();
166 // void InitializeWorkspace();
167 // void FreeWorkspace();
168
169 /** Getters */
170 size_t GetTimeSteps() const { return fTimeSteps; }
171 size_t GetStateSize() const { return fStateSize; }
172 size_t GetInputSize() const { return this->GetInputWidth(); }
173 inline bool DoesRememberState() const {return fRememberState;}
174 inline bool DoesReturnSequence() const { return fReturnSequence; }
176 Matrix_t & GetState() {return fState;} // RNN Hidden state
177 const Matrix_t & GetState() const {return fState;}
178 Matrix_t &GetCell() { return fCell; } // this returns an empty matrixfor RNN
179 const Matrix_t &GetCell() const { return fCell; }
180
182 const Matrix_t & GetWeightsInput() const {return fWeightsInput;}
184 const Matrix_t & GetWeightsState() const {return fWeightsState;}
186 const Tensor_t & GetDerivatives() const {return fDerivatives;}
187 // Matrix_t &GetDerivativesAt(size_t i) { return fDerivatives[i]; }
188 // const Matrix_t &GetDerivativesAt(size_t i) const { return fDerivatives[i]; }
189
191 const Matrix_t & GetBiasesState() const {return fBiases;}
198
200 const Tensor_t &GetWeightsTensor() const { return fWeightsTensor; }
203
204 Tensor_t &GetX() { return fX; }
205 Tensor_t &GetY() { return fY; }
206 Tensor_t &GetDX() { return fDx; }
207 Tensor_t &GetDY() { return fDy; }
208};
209
210//______________________________________________________________________________
211//
212// BasicRNNLayer Implementation
213//______________________________________________________________________________
214template <typename Architecture_t>
215TBasicRNNLayer<Architecture_t>::TBasicRNNLayer(size_t batchSize, size_t stateSize, size_t inputSize, size_t timeSteps,
216 bool rememberState, bool returnSequence, DNN::EActivationFunction f, bool /*training*/,
218 // TODO inputDepth and outputDepth changed to batchSize??
219 : VGeneralLayer<Architecture_t>(batchSize, 1, timeSteps, inputSize, 1, (returnSequence) ? timeSteps : 1 ,
220 stateSize, 2, {stateSize, stateSize}, {inputSize, stateSize}, 1, {stateSize}, {1},
221 batchSize, (returnSequence) ? timeSteps : 1, stateSize, fA),
222 fTimeSteps(timeSteps), fStateSize(stateSize), fRememberState(rememberState), fReturnSequence(returnSequence), fF(f), fState(batchSize, stateSize),
223 fWeightsInput(this->GetWeightsAt(0)), fWeightsState(this->GetWeightsAt(1)),
224 fBiases(this->GetBiasesAt(0)), fDerivatives(timeSteps, batchSize, stateSize), // create tensor time x bs x S
225 fWeightInputGradients(this->GetWeightGradientsAt(0)), fWeightStateGradients(this->GetWeightGradientsAt(1)),
226 fBiasGradients(this->GetBiasGradientsAt(0)), fWeightsTensor({0}), fWeightGradientsTensor({0})
227{
228 InitTensors();
229}
230
231//______________________________________________________________________________
232template <typename Architecture_t>
234 : VGeneralLayer<Architecture_t>(layer), fTimeSteps(layer.fTimeSteps), fStateSize(layer.fStateSize),
235 fRememberState(layer.fRememberState), fReturnSequence(layer.fReturnSequence), fF(layer.GetActivationFunction()),
236 fState(layer.GetBatchSize(), layer.GetStateSize()),
237 fWeightsInput(this->GetWeightsAt(0)), fWeightsState(this->GetWeightsAt(1)), fBiases(this->GetBiasesAt(0)),
238 fDerivatives(layer.GetDerivatives().GetShape()), fWeightInputGradients(this->GetWeightGradientsAt(0)),
239 fWeightStateGradients(this->GetWeightGradientsAt(1)), fBiasGradients(this->GetBiasGradientsAt(0)),
240 fWeightsTensor({0}), fWeightGradientsTensor({0})
241{
242
243 Architecture_t::Copy(fDerivatives, layer.GetDerivatives() );
244
245 // Gradient matrices not copied
246 Architecture_t::Copy(fState, layer.GetState());
247 InitTensors();
248}
249
250template <typename Architecture_t>
252{
253 if (fDescriptors) {
254 Architecture_t::ReleaseRNNDescriptors(fDescriptors);
255 delete fDescriptors;
256 }
257
258 if (fWorkspace) {
259 Architecture_t::FreeRNNWorkspace(fWorkspace);
260 delete fWorkspace;
261 }
262}
263
264//______________________________________________________________________________
265template<typename Architecture_t>
267{
268 // auto m = this->GetInitialization();
269 // DNN::initialize<Architecture_t>(fWeightsInput, m);
270 // DNN::initialize<Architecture_t>(fWeightsState, m);
271 // DNN::initialize<Architecture_t>(fBiases, DNN::EInitialization::kZero);
272
274
275 Architecture_t::InitializeRNNDescriptors(fDescriptors, this);
276 Architecture_t::InitializeRNNWorkspace(fWorkspace, fDescriptors, this);
277}
278
279//______________________________________________________________________________
280template <typename Architecture_t>
282{
283 // fix output tensor for Cudnn must be a tensor of B x T x S of right layout
284 Architecture_t::InitializeRNNTensors(this);
285}
286//______________________________________________________________________________
287template <typename Architecture_t>
289{
290 DNN::initialize<Architecture_t>(this->GetState(), DNN::EInitialization::kZero);
291
292 Architecture_t::InitializeActivationDescriptor(fActivationDesc,this->GetActivationFunction());
293}
294
295//______________________________________________________________________________
296template<typename Architecture_t>
298-> void
299{
300 std::cout << " RECURRENT Layer: \t ";
301 std::cout << " (NInput = " << this->GetInputSize(); // input size
302 std::cout << ", NState = " << this->GetStateSize(); // hidden state size
303 std::cout << ", NTime = " << this->GetTimeSteps() << " )"; // time size
304 std::cout << "\tOutput = ( " << this->GetOutput().GetFirstSize() << " , " << this->GetOutput().GetHSize() << " , " << this->GetOutput().GetWSize() << " )\n";
305}
306
307template <typename Architecture_t>
308auto debugMatrix(const typename Architecture_t::Matrix_t &A, const std::string name = "matrix")
309-> void
310{
311 std::cout << name << "\n";
312 for (size_t i = 0; i < A.GetNrows(); ++i) {
313 for (size_t j = 0; j < A.GetNcols(); ++j) {
314 std::cout << A(i, j) << " ";
315 }
316 std::cout << "\n";
317 }
318 std::cout << "********\n";
319}
320
321
322//______________________________________________________________________________
323template <typename Architecture_t>
325{
326
327 //printf("doing RNNLayer forward\n");
328 // for Cudnn
329 if (Architecture_t::IsCudnn()) {
330
331 Tensor_t &x = this->fX;
332 Tensor_t &y = this->fY;
333
334 Architecture_t::Rearrange(x, input);
335
336 // why passing the first weight, better to pass all weight tensor (including bias)
337 // LM 05/24
338 //const auto &weights = this->GetWeightsAt(0);
339 const auto & weights = this->GetWeightsTensor();
340
341 // Tensor_t cx({1}); // not used for normal RNN
342 // Tensor_t cy({1}); // not used for normal RNN
343
344 // hx is fState - tensor are of right shape
345 auto &hx = this->GetState();
346 auto &cx = this->GetCell();
347 // use same for hy and cy
348 auto &hy = this->GetState();
349 auto &cy = this->GetCell();
350
351 auto & rnnDesc = static_cast<RNNDescriptors_t &>(*fDescriptors);
352 auto & rnnWork = static_cast<RNNWorkspace_t &>(*fWorkspace);
353
354 //printf("doing RNNLayer forward - calling cudnn forwsrd\n");
355
356 Architecture_t::RNNForward(x, hx, cx, weights, y, hy, cy, rnnDesc, rnnWork, isTraining);
357
358 if (fReturnSequence) {
359 Architecture_t::Rearrange(this->GetOutput(), y); // swap B and T from y to Output
360 }
361 else {
362 // tmp is a reference to y (full cudnn output)
363 Tensor_t tmp = (y.At(y.GetShape()[0] - 1)).Reshape({y.GetShape()[1], 1, y.GetShape()[2]});
364 Architecture_t::Copy(this->GetOutput(), tmp);
365 }
366 return;
367 }
368
369 // FORWARD for CPU architecture
370 // D : input size
371 // H : state size
372 // T : time size
373 // B : batch size
374
375 Tensor_t arrInput (fTimeSteps, this->GetBatchSize(), this->GetInputWidth() );
376 //for (size_t t = 0; t < fTimeSteps; ++t) arrInput.emplace_back(this->GetBatchSize(), this->GetInputWidth()); // T x B x D
377 Architecture_t::Rearrange(arrInput, input);
378 Tensor_t arrOutput ( fTimeSteps, this->GetBatchSize(), fStateSize);
379 //for (size_t t = 0; t < fTimeSteps;++t) arrOutput.emplace_back(this->GetBatchSize(), fStateSize); // T x B x H
380
381 if (!this->fRememberState) InitState(DNN::EInitialization::kZero);
382
383 for (size_t t = 0; t < fTimeSteps; ++t) {
384 Matrix_t arrInput_m = arrInput.At(t).GetMatrix();
385 Matrix_t df_m = fDerivatives.At(t).GetMatrix();
386 CellForward(arrInput_m, df_m );
387 Matrix_t arrOutput_m = arrOutput.At(t).GetMatrix();
388 Architecture_t::Copy(arrOutput_m, fState);
389 }
390
391 if (fReturnSequence)
392 Architecture_t::Rearrange(this->GetOutput(), arrOutput); // B x T x D
393 else {
394 // get T[end[]]
395
396 Tensor_t tmp = arrOutput.At(fTimeSteps - 1); // take last time step
397 // shape of tmp is for CPU (column wise) B x D , need to reshape to make a B x D x 1
398 // and transpose it to 1 x D x B (this is how output is expected in columnmajor format)
399 tmp = tmp.Reshape({tmp.GetShape()[0], tmp.GetShape()[1], 1});
400 assert(tmp.GetSize() == this->GetOutput().GetSize());
401 assert(tmp.GetShape()[0] == this->GetOutput().GetShape()[2]); // B is last dim in output and first in tmp
402 Architecture_t::Rearrange(this->GetOutput(), tmp);
403 // keep array output
404 fY = arrOutput;
405 }
406}
407
408//______________________________________________________________________________
409template <typename Architecture_t>
411-> void
412{
413 // State = act(W_input . input + W_state . state + bias)
414 const DNN::EActivationFunction fAF = this->GetActivationFunction();
415 Matrix_t tmpState(fState.GetNrows(), fState.GetNcols());
416 Architecture_t::MultiplyTranspose(tmpState, fState, fWeightsState);
417 Architecture_t::MultiplyTranspose(fState, input, fWeightsInput);
418 Architecture_t::ScaleAdd(fState, tmpState);
419 Architecture_t::AddRowWise(fState, fBiases);
421 Tensor_t tState(fState);
422
423 // DNN::evaluateDerivative<Architecture_t>(dFt, fAF, fState);
424 // DNN::evaluate<Architecture_t>(tState, fAF);
425
426 Architecture_t::Copy(inputActivFunc, tState);
427 Architecture_t::ActivationFunctionForward(tState, fAF, fActivationDesc);
428
429}
430
431//____________________________________________________________________________
432template <typename Architecture_t>
434 const Tensor_t &activations_backward) -> void // B x T x D
435 // std::vector<Matrix_t> & /*inp1*/, std::vector<Matrix_t> &
436 // /*inp2*/) -> void
437{
438 //BACKWARD for CUDNN
439 if (Architecture_t::IsCudnn() ) {
440
441 Tensor_t &x = this->fX;
442 Tensor_t &y = this->fY;
443 Tensor_t &dx = this->fDx;
444 Tensor_t &dy = this->fDy;
445
446 // input size is stride[1] of input tensor that is B x T x inputSize
447 assert(activations_backward.GetStrides()[1] == this->GetInputSize() );
448
449 Architecture_t::Rearrange(x, activations_backward);
450
451 if (!fReturnSequence) {
452
453 //Architecture_t::InitializeZero(dy);
454 Architecture_t::InitializeZero(dy);
455
456 //Tensor_t tmp1 = y.At(y.GetShape()[0] - 1).Reshape({y.GetShape()[1], 1, y.GetShape()[2]});
457 Tensor_t tmp2 = dy.At(dy.GetShape()[0] - 1).Reshape({dy.GetShape()[1], 1, dy.GetShape()[2]});
458
459 //Architecture_t::Copy(tmp1, this->GetOutput());
460 Architecture_t::Copy(tmp2, this->GetActivationGradients());
461 }
462 else {
463 Architecture_t::Rearrange(y, this->GetOutput());
464 Architecture_t::Rearrange(dy, this->GetActivationGradients());
465 }
466
467
468
469 // for cudnn Matrix_t and Tensor_t are same type
470 //const auto &weights = this->GetWeightsTensor();
471 auto &weights = this->GetWeightsTensor();
472 auto &weightGradients = this->GetWeightGradientsTensor();
473 // note that cudnnRNNBackwardWeights accumulate the weight gradients.
474 // We need then to initialize the tensor to zero every time
475 Architecture_t::InitializeZero(weightGradients);
476
477
478 // hx is fState
479 auto &hx = this->GetState();
480 auto &cx = this->GetCell();
481 // use same for hy and cy
482 auto &dhy = hx;
483 auto &dcy = cx;
484 auto &dhx = hx;
485 auto &dcx = cx;
486
487
488 auto & rnnDesc = static_cast<RNNDescriptors_t &>(*fDescriptors);
489 auto & rnnWork = static_cast<RNNWorkspace_t &>(*fWorkspace);
490
491 Architecture_t::RNNBackward(x, hx, cx, y, dy, dhy, dcy, weights, dx, dhx, dcx, weightGradients, rnnDesc, rnnWork);
492
493 if (gradients_backward.GetSize() != 0)
494 Architecture_t::Rearrange(gradients_backward, dx);
495
496 return;
497 }
498
499 // BACKWARD FOR CPU
500 // activations backward is input
501 // gradients_backward is activationGradients of layer before it, which is input layer
502 // currently gradient_backward is for input(x) and not for state
503 // TODO use this to change initial state??
504
505
506 bool dummy = false;
507 if (gradients_backward.GetSize() == 0) {
508 dummy = true;
509 }
510 Tensor_t arr_gradients_backward ( fTimeSteps, this->GetBatchSize(), this->GetInputSize());
511 //for (size_t t = 0; t < fTimeSteps; ++t) arr_gradients_backward.emplace_back(this->GetBatchSize(), this->GetInputSize()); // T x B x D
512
513 if (!dummy) {
514 // TODO gradients_backward will be written back on the matrix
515 //Architecture_t::Rearrange(arr_gradients_backward, gradients_backward);
516 }
517 Tensor_t arr_activations_backward ( fTimeSteps, this->GetBatchSize(), this->GetInputSize());
518 //for (size_t t = 0; t < fTimeSteps; ++t) arr_activations_backward.emplace_back(this->GetBatchSize(), this->GetInputSize()); // T x B x D
519 Architecture_t::Rearrange(arr_activations_backward, activations_backward);
520
521 Matrix_t state_gradients_backward(this->GetBatchSize(), fStateSize); // B x H
522 DNN::initialize<Architecture_t>(state_gradients_backward, DNN::EInitialization::kZero);
523
524 Matrix_t initState(this->GetBatchSize(), fStateSize); // B x H
525 DNN::initialize<Architecture_t>(initState, DNN::EInitialization::kZero);
526
527 Tensor_t arr_output ( fTimeSteps, this->GetBatchSize(), fStateSize);
528 Tensor_t arr_actgradients(fTimeSteps, this->GetBatchSize(), fStateSize);
529
530 if (fReturnSequence) {
531 Architecture_t::Rearrange(arr_output, this->GetOutput());
532 Architecture_t::Rearrange(arr_actgradients, this->GetActivationGradients());
533 } else {
534 //
535 arr_output = fY;
536
537 Architecture_t::InitializeZero(arr_actgradients);
538 // need to reshape to pad a time dimension = 1 (note here is columnmajor tensors)
539 Tensor_t tmp_grad = arr_actgradients.At(fTimeSteps - 1).Reshape({this->GetBatchSize(), fStateSize, 1});
540 assert(tmp_grad.GetSize() == this->GetActivationGradients().GetSize());
541 assert(tmp_grad.GetShape()[0] ==
542 this->GetActivationGradients().GetShape()[2]); // B in tmp is [0] and [2] in input act. gradients
543
544 Architecture_t::Rearrange(tmp_grad, this->GetActivationGradients());
545 }
546
547 // reinitialize weights and biases gradients to 0
548 fWeightInputGradients.Zero();
549 fWeightStateGradients.Zero();
550 fBiasGradients.Zero();
551
552 for (size_t t = fTimeSteps; t > 0; t--) {
553 //const Matrix_t & currStateActivations = arr_output[t - 1];
554 Matrix_t actgrad_m = arr_actgradients.At(t - 1).GetMatrix();
555 Architecture_t::ScaleAdd(state_gradients_backward, actgrad_m);
556
557 Matrix_t actbw_m = arr_activations_backward.At(t - 1).GetMatrix();
558 Matrix_t gradbw_m = arr_gradients_backward.At(t - 1).GetMatrix();
559
560 // compute derivatives of activations
561 Tensor_t df = fDerivatives.At(t-1);
563 //Tensor_t dy = arr_actgradients.At(t - 1);
564 Tensor_t y = arr_output.At(t-1);
565 Architecture_t::ActivationFunctionBackward(df, y,
566 dy, df, //do in place (should work)
567 this->GetActivationFunction(), fActivationDesc);
568
569 Matrix_t df_m = df.GetMatrix();
570
571 // Architecture_t::PrintTensor(df, "dy before");
572 if (t > 1) {
573 Matrix_t precStateActivations = arr_output.At(t - 2).GetMatrix();
575
576 } else {
579
580 }
581 }
582 if (!dummy) {
583 Architecture_t::Rearrange(gradients_backward, arr_gradients_backward );
584 }
585}
586
587//______________________________________________________________________________
588template <typename Architecture_t>
592-> Matrix_t &
593{
594 return Architecture_t::RecurrentLayerBackward(state_gradients_backward, fWeightInputGradients, fWeightStateGradients,
595 fBiasGradients, dF, precStateActivations, fWeightsInput,
596 fWeightsState, input, input_gradient);
597}
598
599//______________________________________________________________________________
600template <typename Architecture_t>
602{
603 auto layerxml = gTools().xmlengine().NewChild(parent, nullptr, "RNNLayer");
604
605 // write All other info like stateSize, inputSize, timeSteps,rememberState
606 gTools().xmlengine().NewAttr(layerxml, nullptr, "StateSize", gTools().StringFromInt(this->GetStateSize()));
607 gTools().xmlengine().NewAttr(layerxml, nullptr, "InputSize", gTools().StringFromInt(this->GetInputSize()));
608 gTools().xmlengine().NewAttr(layerxml, nullptr, "TimeSteps", gTools().StringFromInt(this->GetTimeSteps()));
609 gTools().xmlengine().NewAttr(layerxml, nullptr, "RememberState", gTools().StringFromInt(this->DoesRememberState()));
610 gTools().xmlengine().NewAttr(layerxml, nullptr, "ReturnSequence", gTools().StringFromInt(this->DoesReturnSequence()));
611
612 // write weights and bias matrices
613 this->WriteMatrixToXML(layerxml, "InputWeights", this -> GetWeightsAt(0));
614 this->WriteMatrixToXML(layerxml, "StateWeights", this -> GetWeightsAt(1));
615 this->WriteMatrixToXML(layerxml, "Biases", this -> GetBiasesAt(0));
616
617
618}
619
620//______________________________________________________________________________
621template <typename Architecture_t>
623{
624 // Read weights and biases
625 this->ReadMatrixXML(parent,"InputWeights", this -> GetWeightsAt(0));
626 this->ReadMatrixXML(parent,"StateWeights", this -> GetWeightsAt(1));
627 this->ReadMatrixXML(parent,"Biases", this -> GetBiasesAt(0));
628
629}
630
631} // namespace RNN
632} // namespace DNN
633} // namespace TMVA
634
635#endif
#define f(i)
Definition RSha256.hxx:104
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
char name[80]
Definition TGX11.cxx:142
Tensor_t fDy
cached activation gradient (input of backward) as T x B x S
Definition RNNLayer.h:108
typename Architecture_t::RNNDescriptors_t RNNDescriptors_t
Definition RNNLayer.h:73
DNN::EActivationFunction GetActivationFunction() const
Definition RNNLayer.h:175
void InitState(DNN::EInitialization m=DNN::EInitialization::kZero)
Initialize the state method.
Definition RNNLayer.h:288
const Matrix_t & GetWeightInputGradients() const
Definition RNNLayer.h:195
const Tensor_t & GetWeightGradientsTensor() const
Definition RNNLayer.h:202
typename Architecture_t::RecurrentDescriptor_t LayerDescriptor_t
Definition RNNLayer.h:67
Tensor_t fY
cached output tensor as T x B x S
Definition RNNLayer.h:106
void Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward) override
Backpropagates the error.
Definition RNNLayer.h:433
Tensor_t fDerivatives
First fDerivatives of the activations.
Definition RNNLayer.h:89
const Matrix_t & GetWeightStateGradients() const
Definition RNNLayer.h:197
Matrix_t & fWeightsInput
Input weights, fWeights[0].
Definition RNNLayer.h:85
Matrix_t & fWeightsState
Prev state weights, fWeights[1].
Definition RNNLayer.h:86
virtual ~TBasicRNNLayer()
Destructor.
Definition RNNLayer.h:251
void Print() const override
Prints the info about the layer.
Definition RNNLayer.h:297
TDescriptors * fDescriptors
Keeps all the RNN descriptors.
Definition RNNLayer.h:99
Tensor_t fX
cached input tensor as T x B x I
Definition RNNLayer.h:105
Matrix_t & fBiases
Biases.
Definition RNNLayer.h:87
Architecture_t::ActivationDescriptor_t fActivationDesc
Definition RNNLayer.h:97
typename Architecture_t::TensorDescriptor_t TensorDescriptor_t
Definition RNNLayer.h:69
bool fReturnSequence
Return in output full sequence or just last element in time.
Definition RNNLayer.h:80
const Tensor_t & GetWeightsTensor() const
Definition RNNLayer.h:200
Matrix_t & GetBiasStateGradients()
Definition RNNLayer.h:192
size_t fStateSize
Hidden state size of RNN.
Definition RNNLayer.h:78
const Matrix_t & GetState() const
Definition RNNLayer.h:177
const Matrix_t & GetCell() const
Definition RNNLayer.h:179
Matrix_t & CellBackward(Matrix_t &state_gradients_backward, const Matrix_t &precStateActivations, const Matrix_t &input, Matrix_t &input_gradient, Matrix_t &dF)
Backward for a single time unit a the corresponding call to Forward(...).
Definition RNNLayer.h:589
typename Architecture_t::Matrix_t Matrix_t
Definition RNNLayer.h:64
void ReadWeightsFromXML(void *parent) override
Read the information and the weights about the layer from XML node.
Definition RNNLayer.h:622
typename Architecture_t::DropoutDescriptor_t HelperDescriptor_t
Definition RNNLayer.h:70
typename Architecture_t::RNNWorkspace_t RNNWorkspace_t
Definition RNNLayer.h:72
Matrix_t fState
Hidden State.
Definition RNNLayer.h:84
Matrix_t & fWeightInputGradients
Gradients w.r.t. the input weights.
Definition RNNLayer.h:90
DNN::EActivationFunction fF
Activation function of the hidden state.
Definition RNNLayer.h:82
TBasicRNNLayer(size_t batchSize, size_t stateSize, size_t inputSize, size_t timeSteps, bool rememberState=false, bool returnSequence=false, DNN::EActivationFunction f=DNN::EActivationFunction::kTanh, bool training=true, DNN::EInitialization fA=DNN::EInitialization::kZero)
Constructor.
Definition RNNLayer.h:215
Tensor_t & GetWeightGradientsTensor()
Definition RNNLayer.h:201
size_t GetTimeSteps() const
Getters.
Definition RNNLayer.h:170
bool fRememberState
Remember state in next pass.
Definition RNNLayer.h:79
Matrix_t & fWeightStateGradients
Gradients w.r.t. the recurring weights.
Definition RNNLayer.h:91
Matrix_t & GetWeightInputGradients()
Definition RNNLayer.h:194
const Matrix_t & GetBiasesState() const
Definition RNNLayer.h:191
void Update(const Scalar_t learningRate)
typename Architecture_t::Scalar_t Scalar_t
Definition RNNLayer.h:65
size_t fTimeSteps
Timesteps for RNN.
Definition RNNLayer.h:77
void CellForward(const Matrix_t &input, Matrix_t &dF)
Forward for a single cell (time unit)
Definition RNNLayer.h:410
Tensor_t fDx
cached gradient on the input (output of backward) as T x B x I
Definition RNNLayer.h:107
typename Architecture_t::Tensor_t Tensor_t
Definition RNNLayer.h:63
void AddWeightsXMLTo(void *parent) override
Writes the information and the weights about the layer in an XML node.
Definition RNNLayer.h:601
const Matrix_t & GetBiasStateGradients() const
Definition RNNLayer.h:193
Matrix_t & GetWeightStateGradients()
Definition RNNLayer.h:196
Matrix_t & fBiasGradients
Gradients w.r.t. the bias values.
Definition RNNLayer.h:92
const Matrix_t & GetWeightsInput() const
Definition RNNLayer.h:182
Matrix_t fCell
Empty matrix for RNN.
Definition RNNLayer.h:102
void Initialize() override
Initialize the weights according to the given initialization method.
Definition RNNLayer.h:266
const Tensor_t & GetDerivatives() const
Definition RNNLayer.h:186
const Matrix_t & GetWeightsState() const
Definition RNNLayer.h:184
typename Architecture_t::FilterDescriptor_t WeightsDescriptor_t
Definition RNNLayer.h:68
void Forward(Tensor_t &input, bool isTraining=true) override
Compute and return the next state with given input matrix.
Definition RNNLayer.h:324
Generic General Layer class.
virtual void Initialize()
Initialize the weights and biases according to the given initialization method.
size_t GetInputWidth() const
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
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
auto debugMatrix(const typename Architecture_t::Matrix_t &A, const std::string name="matrix") -> void
Definition RNNLayer.h:308
EActivationFunction
Enum that represents layer activation functions.
Definition Functions.h:32
create variable transformations
Tools & gTools()
TMarker m
Definition textangle.C:8