ceras
yet another deep learning engine
variable.hpp
Go to the documentation of this file.
1 #ifndef QVETFVLYKDJJLDBPAMVBUWUGPWXIAIGMXUDVOFGQIHUHVOTBAWEMPJQEWJQIGGSTUCNDHLUYL
2 #define QVETFVLYKDJJLDBPAMVBUWUGPWXIAIGMXUDVOFGQIHUHVOTBAWEMPJQEWJQIGGSTUCNDHLUYL
3 
4 #include "./includes.hpp"
5 #include "./tensor.hpp"
6 #include "./utils/id.hpp"
7 #include "./utils/debug.hpp"
8 #include "./config.hpp"
9 #include "./utils/enable_shared.hpp"
10 #include "./utils/state.hpp"
11 
12 namespace ceras
13 {
14 
15  namespace ceras_private
16  {
17  template< Tensor Tsor >
18  struct session;
19  }
20 
21  template< Tensor Tsor >
22  ceras_private::session<Tsor>& get_default_session();
23 
24  template< Tensor Tsor >
26  {
27  Tsor data_;
28  Tsor gradient_;
29  std::vector<Tsor> contexts_;
30  };
31 
32  template< typename Float > requires std::floating_point<Float>
33  struct regularizer
34  {
35  typedef Float value_type;
39 
40  constexpr regularizer( value_type l1, value_type l2, bool synchronized ) noexcept : l1_{l1}, l2_{l2}, synchronized_{synchronized} {}
41  };
42 
43  template< Tensor Tsor >
44  struct variable : enable_id<variable<Tsor>, "Variable">
45  {
46  typedef Tsor tensor_type;
47  typedef typename tensor_type::value_type value_type;
48 
49  std::shared_ptr<variable_state<tensor_type>> state_;
51  bool trainable_;
52 
53  variable( tensor_type const& data, value_type l1=value_type{0}, value_type l2=value_type{0}, bool trainable=true ) : enable_id<variable<tensor_type>, "Variable">{}, regularizer_{l1, l2, true}, trainable_{trainable}
54  {
55  (*this).state_ = std::make_shared<variable_state<tensor_type>>();
56  (*((*this).state_)).data_ = data;
57  (*((*this).state_)).gradient_ = tensor_type{ data.shape() };
58 
59  auto& ss = get_default_session<tensor_type>();
60  ss.remember( *this );
61  }
62 
63  variable() = delete;
64  variable( variable const& other ) = default;
65  variable( variable && ) = default;
66  variable& operator=( variable&&) = default;
67  variable& operator=( variable const& other) = default;
68 
69  tensor_type const forward() noexcept// const
70  {
71  auto& state = *((*this).state_);
72 
73  if ( learning_phase == 1 )
74  {
75  typedef typename tensor_type::value_type value_type;
76  state.gradient_.reset( value_type{0} );
77  regularizer_.synchronized_ = false; // mark changes
78  }
79  return state.data_;
80  }
81 
82  void backward( auto const& grad ) noexcept
83  {
84  if (!trainable_) return;
85 
86  auto& state = *((*this).state_);
87  {
88  if (state.gradient_.shape() != state.data_.shape())
89  state.gradient_.resize( state.data_.shape() );
90  }
91  state.gradient_ += grad; // collecting all the gradients from its children nodes, will be called mulitple times in a single backward pass
92 
93  // apply regularizers
94  if (!(regularizer_.synchronized_)) // in case of multiple invoke of this method in a same backward pass
95  {
96  if ( regularizer_.l1_ >= eps ) // l1 regularizer
97  {
98  value_type const factor = regularizer_.l1_;
99  for_each( state.data_.begin(), state.data_.end(), state.gradient_.begin(), [factor]( value_type d, value_type& g ){ g += (d >= value_type{0}) ? factor : -factor; } );
100  }
101  if ( regularizer_.l2_ >= eps ) // l2 regularizer
102  {
103  value_type const factor = regularizer_.l2_;
104  for_each( state.data_.begin(), state.data_.end(), state.gradient_.begin(), [factor]( value_type d, value_type& g ){ g += value_type{2} * d * factor; } );
105  }
106 
108  }
109  }
110 
111  std::vector<std::size_t> shape() const noexcept
112  {
113  auto& state = *((*this).state_);
114  return state.data_.shape();
115  }
116 
117  std::vector<tensor_type>& contexts()
118  {
119  auto& state = *((*this).state_);
120  return state.contexts_;
121  }
122 
123  std::vector<tensor_type> contexts() const
124  {
125  auto& state = *((*this).state_);
126  return state.contexts_;
127  }
128 
130  {
131  auto& state = *((*this).state_);
132  return state.data_;
133  }
134 
136  {
137  auto& state = *((*this).state_);
138  return state.data_;
139  }
140 
142  {
143  auto& state = *((*this).state_);
144  return state.gradient_;
145  }
146 
148  {
149  auto& state = *((*this).state_);
150  return state.gradient_;
151  }
152 
153  void reset()
154  {
155  data().reset();
156  gradient().reset();
157  }
158 
159  /*
160  void reset_states()
161  {
162  if ( stateful_ )
163  reset();
164  }
165  */
166 
167  bool trainable() const noexcept { return trainable_; }
168  void trainable( bool t ) { trainable_ = t; }
169  /*
170  bool stateful() const noexcept { return stateful_; }
171  void stateful( bool s ){ stateful_ = s; }
172  */
173 
174  };//struct variable
175 
176  template< typename T >
177  struct is_variable : std::false_type {};
178 
179  template< Tensor Tsor >
180  struct is_variable< variable<Tsor> > : std::true_type {};
181 
182  template< class T >
183  inline constexpr bool is_variable_v = is_variable<T>::value;
184 
185  template< typename T >
186  concept Variable = is_variable_v<T>;
187 
188  template< Variable Var >
189  bool operator == ( Var const& lhs, Var const& rhs ) noexcept
190  {
191  return lhs.id_ == rhs.id_;
192  }
193 
194 }//namespace ceras
195 
196 #endif//QVETFVLYKDJJLDBPAMVBUWUGPWXIAIGMXUDVOFGQIHUHVOTBAWEMPJQEWJQIGGSTUCNDHLUYL
197 
Definition: activation.hpp:12
ceras_private::session< Tsor > & get_default_session()
Definition: session.hpp:184
constexpr bool is_variable_v
Definition: variable.hpp:183
bool operator==(Var const &lhs, Var const &rhs) noexcept
Definition: variable.hpp:189
concept Variable
Definition: variable.hpp:186
Definition: variable.hpp:177
Definition: variable.hpp:34
constexpr regularizer(value_type l1, value_type l2, bool synchronized) noexcept
Definition: variable.hpp:40
value_type l2_
Definition: variable.hpp:37
bool synchronized_
Definition: variable.hpp:38
value_type l1_
Definition: variable.hpp:36
Float value_type
Definition: variable.hpp:35
Definition: variable.hpp:26
std::vector< Tsor > contexts_
Definition: variable.hpp:29
Tsor gradient_
Definition: variable.hpp:28
Tsor data_
Definition: variable.hpp:27
Definition: variable.hpp:45
variable()=delete
variable & operator=(variable const &other)=default
tensor_type data() const
Definition: variable.hpp:135
variable & operator=(variable &&)=default
std::vector< tensor_type > & contexts()
Definition: variable.hpp:117
std::shared_ptr< variable_state< tensor_type > > state_
Definition: variable.hpp:49
tensor_type & data()
Definition: variable.hpp:129
regularizer< value_type > regularizer_
Definition: variable.hpp:50
void trainable(bool t)
Definition: variable.hpp:168
tensor_type gradient() const
Definition: variable.hpp:147
std::vector< tensor_type > contexts() const
Definition: variable.hpp:123
tensor_type::value_type value_type
Definition: variable.hpp:47
Tsor tensor_type
Definition: variable.hpp:46
void reset()
Definition: variable.hpp:153
void backward(auto const &grad) noexcept
Definition: variable.hpp:82
bool trainable() const noexcept
Definition: variable.hpp:167
variable(variable &&)=default
bool trainable_
Definition: variable.hpp:51
variable(variable const &other)=default
tensor_type & gradient()
Definition: variable.hpp:141
std::vector< std::size_t > shape() const noexcept
Definition: variable.hpp:111
variable(tensor_type const &data, value_type l1=value_type{0}, value_type l2=value_type{0}, bool trainable=true)
Definition: variable.hpp:53
tensor_type const forward() noexcept
Definition: variable.hpp:69