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;
	}
Exemple #3
0
	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];
					}
				}
			}
		}
	}
Exemple #4
0
	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);
	}