LCOV - code coverage report
Current view: top level - ml - Layer.h (source / functions) Hit Total Coverage
Test: test_coverage.info.cleaned Lines: 1 1 100.0 %
Date: 2022-07-06 02:47:47 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <string>
       4             : #include <vector>
       5             : #include <memory>
       6             : #include <ostream>
       7             : #include <iomanip>
       8             : 
       9             : #include "elsaDefines.h"
      10             : #include "VolumeDescriptor.h"
      11             : #include "Common.h"
      12             : #include "State.h"
      13             : #include "DataContainer.h"
      14             : 
      15             : namespace elsa::ml
      16             : {
      17             :     /// Base class for all layers in a network
      18             :     ///
      19             :     /// @author David Tellenbach
      20             :     template <typename data_t = real_t>
      21             :     class Layer
      22             :     {
      23             :     public:
      24             :         Layer() = default;
      25             : 
      26             :         /**
      27             :          *  Construct a layer
      28             :          *
      29             :          * @param layerType the type of the layer
      30             :          * @param requiredNumberOfDimensions the required number of
      31             :          *            dimensions any input to this layer has. This can be set
      32             :          *            to Layer::AnyNumberOfInputDimensions to indicate that the
      33             :          *            number of input dimensions is not restricted.
      34             :          *  @param allowedNumberOfInputs the allowed number of inputs to
      35             :          *             this layer. This can be set to Layer::AnyNumberOfInputs
      36             :          *             to indicate that the layer accepts an arbitrary number of
      37             :          *             inputs.
      38             :          */
      39             :         Layer(LayerType layerType, const std::string& name,
      40             :               int requiredNumberOfDimensions = Layer::AnyNumberOfInputDimensions,
      41             :               int allowedNumberOfInputs = Layer::AnyNumberOfInputs, bool isTrainable = false);
      42             : 
      43             :         /// Copy constructor
      44             :         Layer(const Layer&);
      45             : 
      46             :         /// Move constructor
      47             :         Layer(Layer&&) = default;
      48             : 
      49             :         /// Copy-assignment operator
      50             :         Layer& operator=(const Layer&);
      51             : 
      52             :         /// Move assignment operator
      53             :         Layer& operator=(Layer&&) = default;
      54             : 
      55             :         /// Destructor
      56           9 :         virtual ~Layer() = default;
      57             : 
      58             :         /// @returns this layer's layer-type
      59             :         LayerType getLayerType() const;
      60             : 
      61             :         /// @returns this layer's name
      62             :         std::string getName() const;
      63             : 
      64             :         /// set the layer's input descriptor at a given index
      65             :         void setInputDescriptor(const VolumeDescriptor&);
      66             : 
      67             :         /// @returns this layer's input descriptor at a given index
      68             :         VolumeDescriptor getInputDescriptor(index_t index = 0) const;
      69             : 
      70             :         /// @returns the number of inputs of this layer
      71             :         index_t getNumberOfInputs() const;
      72             : 
      73             :         /// @returns the layer's output descriptor
      74             :         VolumeDescriptor getOutputDescriptor() const;
      75             : 
      76             :         /// @returns the layer's unique global index
      77             :         index_t getGlobalIndex() const;
      78             : 
      79             :         /// Set this layer's input.
      80             :         void setInput(Layer* layer);
      81             : 
      82             :         /// Set his layer's input.
      83             :         void setInput(std::initializer_list<Layer*>);
      84             : 
      85             :         /// Compute this layer's output descriptor.
      86             :         virtual void computeOutputDescriptor();
      87             : 
      88             :         /// @returns true of a layer is trainable and false otherwise
      89             :         bool isTrainable() const;
      90             : 
      91             :         /// @returns true of a layer can merge multiple inputs and false otherwise
      92             :         virtual bool canMerge() const;
      93             : 
      94             :         /// @returns the number of trainable parameters
      95             :         index_t getNumberOfTrainableParameters() const;
      96             : 
      97             :         template <typename T>
      98             :         friend std::ostream& operator<<(std::ostream& os, const Layer<T>& layer);
      99             : 
     100             :     protected:
     101             :         /// check if the number of dimensions of the layer's input descriptor matches the
     102             :         /// required number of dimensions
     103             :         void checkNumberOfInputDimensions(const VolumeDescriptor&) const;
     104             : 
     105             :         static constexpr int AnyNumberOfInputDimensions = -1;
     106             :         static constexpr int AnyNumberOfInputs = -1;
     107             : 
     108             :         int requiredNumberOfDimensions_;
     109             :         int allowedNumberOfInputs_;
     110             : 
     111             :         index_t globalIndex_;
     112             :         LayerType layerType_;
     113             : 
     114             :         std::string name_;
     115             : 
     116             :         index_t numberOfTrainableParameters_;
     117             : 
     118             :         // A layer can have more than one input (e.g. any merging layer) but has
     119             :         // always a single well-defined output descriptor that in general depend
     120             :         // on the input descriptors
     121             :         std::vector<std::unique_ptr<DataDescriptor>> inputDescriptors_;
     122             :         std::unique_ptr<DataDescriptor> outputDescriptor_;
     123             : 
     124             :         bool isTrainable_;
     125             : 
     126             :     private:
     127             :         static index_t staticGlobalIndex_;
     128             :     };
     129             : 
     130             :     template <typename data_t>
     131             :     index_t Layer<data_t>::staticGlobalIndex_{0};
     132             : 
     133             :     template <typename T>
     134             :     std::ostream& operator<<(std::ostream& os, const Layer<T>& layer)
     135             :     {
     136             :         std::stringstream ss;
     137             : 
     138             :         // Name and layer-type
     139             :         std::string description =
     140             :             layer.getName() + " (" + detail::getEnumMemberAsString(layer.getLayerType()) + ")";
     141             :         os << std::left << std::setw(35) << description;
     142             : 
     143             :         // output-shape
     144             :         Eigen::IOFormat fmt(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "(", ")");
     145             :         ss << layer.getOutputDescriptor().getNumberOfCoefficientsPerDimension().format(fmt);
     146             :         std::string outputShape = ss.str();
     147             :         os << std::left << std::setw(20) << outputShape;
     148             : 
     149             :         // number of parameters
     150             :         os << std::left << std::setw(10) << layer.getNumberOfTrainableParameters();
     151             : 
     152             :         return os;
     153             :     }
     154             : 
     155             : } // namespace elsa::ml

Generated by: LCOV version 1.15