32template <
bool hist_shift_required >
33std::map< std::string, typename EpropArchivingNodeRecurrent< hist_shift_required >::surrogate_gradient_function >
38 {
"fast_sigmoid_derivative",
40 {
"arctan_derivative",
44template <
bool hist_shift_required >
47 , firing_rate_reg_( 0.0 )
53template <
bool hist_shift_required >
56 , firing_rate_reg_( n.firing_rate_reg_ )
58 , n_spikes_( n.n_spikes_ )
62template <
bool hist_shift_required >
65 const std::string& surrogate_gradient_function_name )
67 const auto found_entry_it = surrogate_gradient_funcs_.find( surrogate_gradient_function_name );
69 if ( found_entry_it != surrogate_gradient_funcs_.end() )
71 return found_entry_it->second;
74 std::string error_message =
"Surrogate gradient / pseudo-derivate function surrogate_gradient_function from [";
75 for (
const auto& surrogate_gradient_func : surrogate_gradient_funcs_ )
77 error_message +=
" \"" + surrogate_gradient_func.first +
"\",";
79 error_message.pop_back();
80 error_message +=
" ] required.";
82 throw BadProperty( error_message );
85template <
bool hist_shift_required >
98 return height * std::max( 0.0, 1.0 - std::abs( v_m - v_th ) / width );
101template <
bool hist_shift_required >
114 return height * std::exp( -std::abs( v_m - v_th ) / width );
117template <
bool hist_shift_required >
130 return height * std::pow( 1.0 + std::abs( v_m - v_th ) / width, -2.0 );
133template <
bool hist_shift_required >
146 return height / ( 1.0 + std::pow( ( v_m - v_th ) / width, 2.0 ) );
149template <
bool hist_shift_required >
153 if ( eprop_indegree_ == 0 )
158 eprop_history_.emplace_back( time_step, 0.0, 0.0, 0.0 );
161template <
bool hist_shift_required >
164 const double surrogate_gradient )
166 if ( eprop_indegree_ == 0 )
171 auto it_hist = get_eprop_history( time_step );
172 it_hist->surrogate_gradient_ = surrogate_gradient;
175template <
bool hist_shift_required >
178 const double learning_signal )
180 if ( eprop_indegree_ == 0 )
185 long shift = delay_rec_out_ + delay_out_rec_;
187 if constexpr ( hist_shift_required )
189 shift += delay_out_norm_;
192 auto it_hist = get_eprop_history( time_step - shift );
193 const auto it_hist_end = get_eprop_history( time_step - shift + delay_out_rec_ );
195 for ( ; it_hist != it_hist_end; ++it_hist )
197 it_hist->learning_signal_ += learning_signal;
201template <
bool hist_shift_required >
204 const double f_target,
207 if ( eprop_indegree_ == 0 )
216 const double f_av = n_spikes_ / update_interval;
217 const double f_target_ = f_target * dt;
218 const double firing_rate_reg = c_reg * ( f_av - f_target_ ) / update_interval;
220 firing_rate_reg_history_.emplace_back( t_current_update + shift, firing_rate_reg );
223template <
bool hist_shift_required >
227 const double f_target,
228 const double kappa_reg,
231 if ( eprop_indegree_ == 0 )
238 const double f_target_ = f_target * dt;
240 f_av_ = kappa_reg * f_av_ + ( 1.0 - kappa_reg ) * z / dt;
242 firing_rate_reg_ = c_reg * ( f_av_ - f_target_ );
244 auto it_hist = get_eprop_history( time_step );
245 it_hist->firing_rate_reg_ = firing_rate_reg_;
248template <
bool hist_shift_required >
252 const auto it_hist = std::lower_bound( firing_rate_reg_history_.begin(), firing_rate_reg_history_.end(), time_step );
253 assert( it_hist != firing_rate_reg_history_.end() );
255 return it_hist->firing_rate_reg_;
258template <
bool hist_shift_required >
262 long shift = delay_rec_out_ + delay_out_rec_;
264 if constexpr ( hist_shift_required )
266 shift += delay_out_norm_;
269 const auto it = get_eprop_history( time_step - shift );
270 if ( it == eprop_history_.end() )
275 return it->learning_signal_;
278template <
bool hist_shift_required >
282 auto it_update_hist = update_history_.begin();
283 auto it_reg_hist = firing_rate_reg_history_.begin();
285 while ( it_update_hist != update_history_.end() and it_reg_hist != firing_rate_reg_history_.end() )
287 if ( it_update_hist->access_counter_ == 0 )
289 it_reg_hist = firing_rate_reg_history_.erase( it_reg_hist );
Class implementing an intermediate archiving node model for recurrent node models supporting e-prop p...
Definition eprop_archiving_node_recurrent.h:43
void write_firing_rate_reg_to_history(const long t_current_update, const double f_target, const double c_reg)
Calculates the firing rate regularization for the current update and writes it to a new entry in the ...
Definition eprop_archiving_node_recurrent_impl.h:203
void write_learning_signal_to_history(const long time_step, const double learning_signal)
Writes the learning signal to the eprop history entry at the specifed time step.
Definition eprop_archiving_node_recurrent_impl.h:177
void append_new_eprop_history_entry(const long time_step)
Creates an entry for the specified time step at the end of the eprop history.
Definition eprop_archiving_node_recurrent_impl.h:151
EpropArchivingNodeRecurrent()
Constructs a new EpropArchivingNodeRecurrent object.
Definition eprop_archiving_node_recurrent_impl.h:45
surrogate_gradient_function find_surrogate_gradient(const std::string &surrogate_gradient_function_name)
Validates and finds surrogate gradient function based on the specified name.
Definition eprop_archiving_node_recurrent_impl.h:64
double compute_exponential_surrogate_gradient(const double r, const double v_m, const double v_th, const double height, const double width)
Computes an exponential function as the surrogate gradient.
Definition eprop_archiving_node_recurrent_impl.h:103
static std::map< std::string, surrogate_gradient_function > surrogate_gradient_funcs_
Maps provided names of surrogate gradients to corresponding pointers to member functions.
Definition eprop_archiving_node_recurrent.h:268
double compute_piecewise_linear_surrogate_gradient(const double r, const double v_m, const double v_th, const double height, const double width)
Computes a piecewise-linear function as the surrogate gradient.
Definition eprop_archiving_node_recurrent_impl.h:87
double compute_arctan_derivative_surrogate_gradient(const double r, const double v_m, const double v_th, const double height, const double width)
Computes the derivative of an arctan surrogate function as the surrogate gradient.
Definition eprop_archiving_node_recurrent_impl.h:135
void erase_used_firing_rate_reg_history()
Erases the history of the used firing rate regularization history.
Definition eprop_archiving_node_recurrent_impl.h:280
double get_learning_signal_from_history(const long time_step)
Retrieves the learning signal from the eprop history at the specified time step.
Definition eprop_archiving_node_recurrent_impl.h:260
void write_surrogate_gradient_to_history(const long time_step, const double surrogate_gradient)
Writes the surrogate gradient to the eprop history entry at the specified time step.
Definition eprop_archiving_node_recurrent_impl.h:163
double get_firing_rate_reg_history(const long time_step)
Retrieves the firing rate regularization at the specified time step from the firing rate regularizati...
Definition eprop_archiving_node_recurrent_impl.h:250
double compute_fast_sigmoid_derivative_surrogate_gradient(const double r, const double v_m, const double v_th, const double height, const double width)
Computes the derivative of a fast-sigmoid surrogate function as the surrogate gradient.
Definition eprop_archiving_node_recurrent_impl.h:119
Base class implementing archiving for node models supporting e-prop plasticity.
Definition eprop_archiving_node.h:53
Time get_eprop_update_interval() const
Definition simulation_manager.h:343
static Time get_resolution()
Definition nest_time.h:325
long get_steps() const
Definition nest_time.h:504
double get_ms() const
Definition nest_time.h:490
SimulationManager simulation_manager
Definition kernel_manager.h:237
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
KernelManager & kernel()
Definition kernel_manager.h:311