void log_gradient_and_output(size_t variable_idx, const Eigen::VectorXd& inputs, const Eigen::VectorXd& parameters, Eigen::VectorXd& outputs, Eigen::VectorXd& gradient_vector) { // TODO: Check concept for InputIterator //double N = std::distance(first_input, last_input); //double scaling_factor = 1. / view.size(); gradient_vector.setZero(); // DEBUG //std::cout << gradient_ << std::endl; //for (unsigned int i = 0; i < view.size(); i++) { forward_propagation(parameters, inputs, outputs, true); // DEBUG: Look for NaN /*for (size_t idx = 0; idx < static_cast<size_t>(outputs.size()); idx++) { if (std::isnan(outputs[idx])) std::cout << "NaN: Output[" << idx << "] from forward propagation" << std::endl; }*/ // TODO: Check that outputs isn't overwritten by back propagation! // back_propagation_output(size_t variable_idx, const Eigen::VectorXd& parameters, const Eigen::MatrixBase<T>& inputs, Eigen::VectorXd& outputs, Eigen::VectorXd& gradient, double scaling_factor) back_propagation_log_output(variable_idx, parameters, inputs, inputs_to_output_activation_, gradient_vector, 1.); //} // DEBUG //std::cout << gradient_ << std::endl; }
double objective(View& view, const Eigen::VectorXd& parameters) { double total_error = 0, scaling_factor = 1. / view.size(); // TODO: Let data object be used in range based for for (unsigned int i = 0; i < view.size(); i++) { forward_propagation(parameters, view.first(i), outputs()); total_error += error_policy.error(outputs(), view.second(i), scaling_factor); } return total_error; }
SPROUT_CXX14_CONSTEXPR void train( ForwardIterator1 in_first, ForwardIterator1 in_last, ForwardIterator2 t_first, ForwardIterator2 t_last, std::size_t repeat = 1000, value_type eta = value_type(0.1) ) { SPROUT_ASSERT(sprout::distance(in_first, in_last) % In == 0); SPROUT_ASSERT(sprout::distance(in_first, in_last) / In == sprout::distance(t_first, t_last)); worker work{}; for (std::size_t times = 0; times != repeat; ++times) { ForwardIterator1 in_it = in_first; ForwardIterator2 t_it = t_first; for (; in_it != in_last; sprout::advance(in_it, In), ++t_it) { // forward propagation forward_propagation(in_it, sprout::next(in_it, In), work); // error calculation of output layer for (std::size_t i = 0; i != Out; ++i) { d3[i] = *t_it == i ? work.o3[i] - 1 : work.o3[i] ; } // weight update of output layer for (std::size_t i = 0; i != Hid + 1; ++i) { for (std::size_t j = 0; j != Out; ++j) { w2[i * Out + j] -= eta * d3[j] * work.o2[i]; } } // error calculation of hidden layer for (std::size_t i = 0; i != Hid + 1; ++i) { d2[i] = 0; for (std::size_t j = 0; j != Out; ++j) { d2[i] += w2[i * Out + j] * d3[j]; } d2[i] *= sprout::math::d_sigmoid(work.xi2[i]); } // weight update of hidden layer for (std::size_t i = 0; i != In + 1; ++i) { for (std::size_t j = 0; j != Hid; ++j) { w1[i * Hid + j] -= eta * d2[j] * work.o1[i]; } } } } }
SPROUT_CXX14_CONSTEXPR std::size_t predict(ForwardIterator in_first, ForwardIterator in_last) const { SPROUT_ASSERT(sprout::distance(in_first, in_last) == In); worker work{}; // prediction by forward propagation forward_propagation(in_first, in_last, work); // determining a class which output is maximum return sprout::distance( sprout::begin(work.o3), sprout::max_element(sprout::begin(work.o3), sprout::end(work.o3)) ); }
void gradient(View& view, const Eigen::VectorXd& parameters, Eigen::VectorXd& gradient_vector) { // TODO: Check concept for InputIterator //double N = std::distance(first_input, last_input); double scaling_factor = 1. / view.size(); gradient_vector.setZero(); // DEBUG //std::cout << gradient_ << std::endl; for (unsigned int i = 0; i < view.size(); i++) { forward_propagation(parameters, view.first(i), outputs()); back_propagation_error(parameters, view.first(i), outputs(), view.second(i), gradient_vector, scaling_factor); } // DEBUG //std::cout << gradient_ << std::endl; }
// TODO: Change this function depending on model implied by activation functions double predict(const Eigen::VectorXd& parameters, const Eigen::VectorXd& inputs) { forward_propagation(parameters, inputs, outputs()); return get_maximum(outputs()); }
void log_output(const Eigen::VectorXd& parameters, const Eigen::VectorXd& inputs, Eigen::VectorXd& outputs) { forward_propagation(parameters, inputs, outputs, true); }