29#ifndef TMVA_DNN_RNN_LAYER
30#define TMVA_DNN_RNN_LAYER
57template<
typename Architecture_t>
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;
155 void Print()
const override;
214template <
typename Architecture_t>
223 fWeightsInput(
this->GetWeightsAt(0)), fWeightsState(
this->GetWeightsAt(1)),
225 fWeightInputGradients(
this->GetWeightGradientsAt(0)), fWeightStateGradients(
this->GetWeightGradientsAt(1)),
226 fBiasGradients(
this->GetBiasGradientsAt(0)), fWeightsTensor({0}), fWeightGradientsTensor({0})
232template <
typename Architecture_t>
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})
243 Architecture_t::Copy(fDerivatives,
layer.GetDerivatives() );
246 Architecture_t::Copy(fState,
layer.GetState());
250template <
typename Architecture_t>
254 Architecture_t::ReleaseRNNDescriptors(fDescriptors);
259 Architecture_t::FreeRNNWorkspace(fWorkspace);
265template<
typename Architecture_t>
275 Architecture_t::InitializeRNNDescriptors(fDescriptors,
this);
276 Architecture_t::InitializeRNNWorkspace(fWorkspace, fDescriptors,
this);
280template <
typename Architecture_t>
284 Architecture_t::InitializeRNNTensors(
this);
287template <
typename Architecture_t>
292 Architecture_t::InitializeActivationDescriptor(fActivationDesc,this->GetActivationFunction());
296template<
typename Architecture_t>
300 std::cout <<
" RECURRENT Layer: \t ";
301 std::cout <<
" (NInput = " << this->GetInputSize();
302 std::cout <<
", NState = " << this->GetStateSize();
303 std::cout <<
", NTime = " << this->GetTimeSteps() <<
" )";
304 std::cout <<
"\tOutput = ( " << this->GetOutput().GetFirstSize() <<
" , " << this->GetOutput().GetHSize() <<
" , " << this->GetOutput().GetWSize() <<
" )\n";
307template <
typename Architecture_t>
308auto debugMatrix(
const typename Architecture_t::Matrix_t &A,
const std::string
name =
"matrix")
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) <<
" ";
318 std::cout <<
"********\n";
323template <
typename Architecture_t>
329 if (Architecture_t::IsCudnn()) {
334 Architecture_t::Rearrange(
x,
input);
339 const auto & weights = this->GetWeightsTensor();
345 auto &
hx = this->GetState();
346 auto &
cx = this->GetCell();
348 auto &
hy = this->GetState();
349 auto &
cy = this->GetCell();
358 if (fReturnSequence) {
359 Architecture_t::Rearrange(this->GetOutput(),
y);
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);
375 Tensor_t arrInput (fTimeSteps, this->GetBatchSize(), this->GetInputWidth() );
383 for (
size_t t = 0; t < fTimeSteps; ++t) {
392 Architecture_t::Rearrange(this->GetOutput(),
arrOutput);
399 tmp =
tmp.Reshape({
tmp.GetShape()[0],
tmp.GetShape()[1], 1});
401 assert(
tmp.GetShape()[0] ==
this->GetOutput().GetShape()[2]);
402 Architecture_t::Rearrange(this->GetOutput(),
tmp);
409template <
typename Architecture_t>
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);
427 Architecture_t::ActivationFunctionForward(
tState,
fAF, fActivationDesc);
432template <
typename Architecture_t>
439 if (Architecture_t::IsCudnn() ) {
451 if (!fReturnSequence) {
454 Architecture_t::InitializeZero(
dy);
460 Architecture_t::Copy(
tmp2, this->GetActivationGradients());
463 Architecture_t::Rearrange(
y, this->GetOutput());
464 Architecture_t::Rearrange(
dy, this->GetActivationGradients());
471 auto &weights = this->GetWeightsTensor();
479 auto &
hx = this->GetState();
480 auto &
cx = this->GetCell();
491 Architecture_t::RNNBackward(
x,
hx,
cx,
y,
dy,
dhy,
dcy, weights,
dx,
dhx,
dcx,
weightGradients,
rnnDesc,
rnnWork);
530 if (fReturnSequence) {
531 Architecture_t::Rearrange(
arr_output, this->GetOutput());
532 Architecture_t::Rearrange(
arr_actgradients, this->GetActivationGradients());
542 this->GetActivationGradients().GetShape()[2]);
544 Architecture_t::Rearrange(
tmp_grad, this->GetActivationGradients());
548 fWeightInputGradients.Zero();
549 fWeightStateGradients.Zero();
550 fBiasGradients.Zero();
552 for (
size_t t = fTimeSteps; t > 0; t--) {
565 Architecture_t::ActivationFunctionBackward(df,
y,
567 this->GetActivationFunction(), fActivationDesc);
588template <
typename Architecture_t>
594 return Architecture_t::RecurrentLayerBackward(
state_gradients_backward, fWeightInputGradients, fWeightStateGradients,
600template <
typename Architecture_t>
613 this->WriteMatrixToXML(
layerxml,
"InputWeights",
this -> GetWeightsAt(0));
614 this->WriteMatrixToXML(
layerxml,
"StateWeights",
this -> GetWeightsAt(1));
615 this->WriteMatrixToXML(
layerxml,
"Biases",
this -> GetBiasesAt(0));
621template <
typename Architecture_t>
625 this->ReadMatrixXML(parent,
"InputWeights",
this -> GetWeightsAt(0));
626 this->ReadMatrixXML(parent,
"StateWeights",
this -> GetWeightsAt(1));
627 this->ReadMatrixXML(parent,
"Biases",
this -> GetBiasesAt(0));
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
Tensor_t fDy
cached activation gradient (input of backward) as T x B x S
size_t GetStateSize() const
typename Architecture_t::RNNDescriptors_t RNNDescriptors_t
DNN::EActivationFunction GetActivationFunction() const
void InitState(DNN::EInitialization m=DNN::EInitialization::kZero)
Initialize the state method.
const Matrix_t & GetWeightInputGradients() const
const Tensor_t & GetWeightGradientsTensor() const
typename Architecture_t::RecurrentDescriptor_t LayerDescriptor_t
Tensor_t fY
cached output tensor as T x B x S
void Backward(Tensor_t &gradients_backward, const Tensor_t &activations_backward) override
Backpropagates the error.
Tensor_t fDerivatives
First fDerivatives of the activations.
const Matrix_t & GetWeightStateGradients() const
Matrix_t & fWeightsInput
Input weights, fWeights[0].
Matrix_t & fWeightsState
Prev state weights, fWeights[1].
virtual ~TBasicRNNLayer()
Destructor.
void Print() const override
Prints the info about the layer.
TDescriptors * fDescriptors
Keeps all the RNN descriptors.
Tensor_t fX
cached input tensor as T x B x I
Matrix_t & fBiases
Biases.
Architecture_t::ActivationDescriptor_t fActivationDesc
typename Architecture_t::TensorDescriptor_t TensorDescriptor_t
bool fReturnSequence
Return in output full sequence or just last element in time.
const Tensor_t & GetWeightsTensor() const
Matrix_t & GetBiasStateGradients()
Tensor_t fWeightGradientsTensor
size_t fStateSize
Hidden state size of RNN.
Matrix_t & GetWeightsState()
const Matrix_t & GetState() const
Tensor_t & GetDerivatives()
const Matrix_t & GetCell() const
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(...).
typename Architecture_t::Matrix_t Matrix_t
void ReadWeightsFromXML(void *parent) override
Read the information and the weights about the layer from XML node.
typename Architecture_t::DropoutDescriptor_t HelperDescriptor_t
typename Architecture_t::RNNWorkspace_t RNNWorkspace_t
Matrix_t fState
Hidden State.
Matrix_t & fWeightInputGradients
Gradients w.r.t. the input weights.
DNN::EActivationFunction fF
Activation function of the hidden state.
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.
Tensor_t & GetWeightGradientsTensor()
Matrix_t & GetWeightsInput()
size_t GetTimeSteps() const
Getters.
bool fRememberState
Remember state in next pass.
Tensor_t & GetWeightsTensor()
Matrix_t & fWeightStateGradients
Gradients w.r.t. the recurring weights.
Matrix_t & GetWeightInputGradients()
const Matrix_t & GetBiasesState() const
void Update(const Scalar_t learningRate)
typename Architecture_t::Scalar_t Scalar_t
size_t fTimeSteps
Timesteps for RNN.
bool DoesRememberState() const
void CellForward(const Matrix_t &input, Matrix_t &dF)
Forward for a single cell (time unit)
Tensor_t fDx
cached gradient on the input (output of backward) as T x B x I
typename Architecture_t::Tensor_t Tensor_t
void AddWeightsXMLTo(void *parent) override
Writes the information and the weights about the layer in an XML node.
const Matrix_t & GetBiasStateGradients() const
size_t GetInputSize() const
Matrix_t & GetWeightStateGradients()
bool DoesReturnSequence() const
Matrix_t & fBiasGradients
Gradients w.r.t. the bias values.
const Matrix_t & GetWeightsInput() const
Matrix_t fCell
Empty matrix for RNN.
void Initialize() override
Initialize the weights according to the given initialization method.
const Tensor_t & GetDerivatives() const
Matrix_t & GetBiasesState()
const Matrix_t & GetWeightsState() const
typename Architecture_t::FilterDescriptor_t WeightsDescriptor_t
void Forward(Tensor_t &input, bool isTraining=true) override
Compute and return the next state with given input matrix.
Generic General Layer class.
virtual void Initialize()
Initialize the weights and biases according to the given initialization method.
size_t GetInputWidth() const
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
auto debugMatrix(const typename Architecture_t::Matrix_t &A, const std::string name="matrix") -> void
EActivationFunction
Enum that represents layer activation functions.
create variable transformations