16 #include "perceptron.h"
41 set(new_inputs_number);
53 set(new_inputs_number, new_parameters_value);
63 set(other_perceptron);
83 if(
this != &other_perceptron)
143 case Perceptron::Logistic:
149 case Perceptron::HyperbolicTangent:
155 case Perceptron::Threshold:
161 case Perceptron::SymmetricThreshold:
163 return(
"symmetric_threshold");
167 case Perceptron::Linear:
175 std::ostringstream buffer;
177 buffer <<
"OpenNN Exception: Perceptron class.\n"
178 <<
"std::string get_activation_function(void) const method.\n"
179 <<
"Unknown activation function.\n";
181 throw std::logic_error(buffer.str());
231 if(synaptic_weight_index >= inputs_number)
233 std::ostringstream buffer;
235 buffer <<
"OpenNN Exception: Perceptron class.\n"
236 <<
"double get_synaptic_weight(const size_t&) const method.\n"
237 <<
"Index of synaptic weight must be less than number of inputs.\n";
239 throw std::logic_error(buffer.str());
304 void Perceptron::set(
const size_t& new_inputs_number,
const double& new_parameters_value)
306 bias = new_parameters_value;
351 if(new_activation_function_name ==
"Logistic")
355 else if(new_activation_function_name ==
"HyperbolicTangent")
359 else if(new_activation_function_name ==
"Threshold")
363 else if(new_activation_function_name ==
"SymmetricThreshold")
367 else if(new_activation_function_name ==
"Linear")
373 std::ostringstream buffer;
375 buffer <<
"OpenNN Exception: Perceptron class.\n"
376 <<
"void set_activation_function(const std::string&) method.\n"
377 <<
"Unknown activation function: " << new_activation_function_name <<
".\n";
379 throw std::logic_error(buffer.str());
408 if(new_synaptic_weights.size() != inputs_number)
410 std::ostringstream buffer;
412 buffer <<
"OpenNN Exception: Perceptron class.\n"
413 <<
"void set_synaptic_weights(const Vector<double>&) method.\n"
414 <<
"Size of synaptic weights vector must be equal to number of inputs.\n";
416 throw std::logic_error(buffer.str());
441 if(synaptic_weight_index >= inputs_number)
443 std::ostringstream buffer;
445 buffer <<
"OpenNN Exception: Perceptron class.\n"
446 <<
"void set_synaptic_weight(const size_t&, const double&) method.\n"
447 <<
"Index of synaptic weight must be less than number of inputs.\n";
449 throw std::logic_error(buffer.str());
497 return(1 + inputs_number);
511 parameters[0] =
bias;
515 for(
size_t i = 0; i < inputs_number; i++)
537 const size_t size = new_parameters.size();
539 if(size != 1+inputs_number)
541 std::ostringstream buffer;
543 buffer <<
"OpenNN Exception: Perceptron class.\n"
544 <<
"void set_parameters(const Vector<double>&) method.\n"
545 <<
"Size must be equal to one plus number of inputs.\n";
547 throw std::logic_error(buffer.str());
552 bias = new_parameters[0];
554 for(
size_t i = 0; i < inputs_number; i++)
584 if(minimum > maximum)
586 std::ostringstream buffer;
588 buffer <<
"OpenNN Exception: Perceptron class.\n"
589 <<
"initialize_bias_uniform(const double&, const double&) method.\n"
590 <<
"Minimum value must be less than maximum value.\n";
592 throw std::logic_error(buffer.str());
597 bias = calculate_random_uniform(minimum, maximum);
636 if(standard_deviation < 0.0)
638 std::ostringstream buffer;
640 buffer <<
"OpenNN Exception: Perceptron class.\n"
641 <<
"initialize_bias_normal(const double&, const double&) method.\n"
642 <<
"Standard deviation must be equal or greater than zero.\n";
644 throw std::logic_error(buffer.str());
649 bias = calculate_random_normal(mean, standard_deviation);
691 if(inputs_number == 0)
693 std::ostringstream buffer;
695 buffer <<
"OpenNN Exception: Perceptron class.\n"
696 <<
"calculate_combination(const Vector<double>&) method.\n"
697 <<
"Number of inputs must be greater than zero.\n";
699 throw std::logic_error(buffer.str());
702 const size_t inputs_size = inputs.size();
704 if(inputs_size != inputs_number)
706 std::ostringstream buffer;
708 buffer <<
"OpenNN Exception: Perceptron class.\n"
709 <<
"double calculate_combination(const Vector<double>&) method.\n"
710 <<
"Size of inputs (" << inputs_size <<
") must be equal to number of inputs (" << inputs_number <<
").\n";
712 throw std::logic_error(buffer.str());
719 double combination =
bias;
721 for(
size_t i = 0; i < inputs_number; i++)
744 std::ostringstream buffer;
746 const size_t inputs_size = inputs.size();
748 if(inputs_size != inputs_number)
750 buffer <<
"OpenNN Exception: Perceptron class.\n"
751 <<
"double calculate_combination(const Vector<double>&, const Vector<double>&) const method.\n"
752 <<
"Size of inputs must be equal to number of inputs.\n";
754 throw std::logic_error(buffer.str());
757 const size_t parameters_size = parameters.size();
761 if(parameters_size != parameters_number)
763 buffer <<
"OpenNN Exception: Perceptron class.\n"
764 <<
"double calculate_combination(const Vector<double>&, const Vector<double>&) const method.\n"
765 <<
"Size of potential parameters (" << parameters_size <<
") must be equal to number of parameters (" << parameters_number <<
").\n";
767 throw std::logic_error(buffer.str());
774 double combination = parameters[0];
776 for(
size_t i = 0; i < inputs_number; i++)
778 combination += parameters[i+1]*inputs[i];
795 case Perceptron::Logistic:
797 return(1.0/(1.0 + exp(-combination)));
801 case Perceptron::HyperbolicTangent:
803 return(1.0-2.0/(exp(2.0*combination)+1.0));
807 case Perceptron::Threshold:
820 case Perceptron::SymmetricThreshold:
833 case Perceptron::Linear:
841 std::ostringstream buffer;
843 buffer <<
"OpenNN Exception: Perceptron class.\n"
844 <<
"double calculate_activation(const double&) const method.\n"
845 <<
"Unknown activation function.\n";
847 throw std::logic_error(buffer.str());
864 case Perceptron::Logistic:
866 const double exponent = exp(-combination);
868 return(exponent/((1.0+exponent)*(1.0+exponent)));
872 case Perceptron::HyperbolicTangent:
874 const double tanh_combination = tanh(combination);
876 return(1.0 - tanh_combination*tanh_combination);
880 case Perceptron::Threshold:
882 if(combination != 0.0)
888 std::ostringstream buffer;
890 buffer <<
"OpenNN Exception: Perceptron class.\n"
891 <<
"double calculate_activation_derivative(const double&) const method.\n"
892 <<
"Threshold activation function is not derivable.\n";
894 throw std::logic_error(buffer.str());
899 case Perceptron::SymmetricThreshold:
901 if(combination != 0.0)
907 std::ostringstream buffer;
909 buffer <<
"OpenNN Exception: Perceptron class.\n"
910 <<
"double calculate_activation_derivative(const double&) const method.\n"
911 <<
"Symmetric threshold activation function is not derivable.\n";
913 throw std::logic_error(buffer.str());
918 case Perceptron::Linear:
926 std::ostringstream buffer;
928 buffer <<
"OpenNN Exception: Perceptron class.\n"
929 <<
"double calculate_activation_derivative(const double&) const method.\n"
930 <<
"Unknown activation function.\n";
932 throw std::logic_error(buffer.str());
949 case Perceptron::Logistic:
951 const double exponent = exp(combination);
953 return(-exponent*(exponent-1.0)/((exponent+1.0)*(exponent+1.0)*(exponent+1.0)));
957 case Perceptron::HyperbolicTangent:
959 return(-2.0*tanh(combination)*(1.0 - pow(tanh(combination),2)));
963 case Perceptron::Threshold:
965 if(combination != 0.0)
971 std::ostringstream buffer;
973 buffer <<
"OpenNN Exception: Perceptron class.\n"
974 <<
"double calculate_activation_second_derivative(const double&) const method.\n"
975 <<
"Threshold activation function is not derivable.\n";
977 throw std::logic_error(buffer.str());
982 case Perceptron::SymmetricThreshold:
984 if(combination != 0.0)
990 std::ostringstream buffer;
992 buffer <<
"OpenNN Exception: Perceptron class.\n"
993 <<
"double calculate_activation_second_derivative(const double&) const method.\n"
994 <<
"Symmetric threshold activation function is not derivable.\n";
996 throw std::logic_error(buffer.str());
1001 case Perceptron::Linear:
1009 std::ostringstream buffer;
1011 buffer <<
"OpenNN Exception: Perceptron class.\n"
1012 <<
"double calculate_activation_second_derivative(const double&) const method.\n"
1013 <<
"Unknown activation function.\n";
1015 throw std::logic_error(buffer.str());
1034 const size_t size = inputs.size();
1037 if(size != inputs_number)
1039 std::ostringstream buffer;
1041 buffer <<
"OpenNN Exception: Perceptron class.\n"
1042 <<
"double calculate_output(const Vector<double>&) const method.\n"
1043 <<
"Size must be equal to number of inputs.\n";
1045 throw std::logic_error(buffer.str());
1069 const size_t inputs_size = inputs.size();
1072 if(inputs_size != inputs_number)
1074 std::ostringstream buffer;
1076 buffer <<
"OpenNN Exception: Perceptron class.\n"
1077 <<
"double calculate_output(const Vector<double>&, const Vector<double>&) const method.\n"
1078 <<
"Size of inputs must be equal to number of inputs.\n";
1080 throw std::logic_error(buffer.str());
1083 const size_t parameters_size = parameters.size();
1087 if(parameters_size != parameters_number)
1089 std::ostringstream buffer;
1091 buffer <<
"OpenNN Exception: Perceptron class.\n"
1092 <<
"double calculate_output(const Vector<double>&, const Vector<double>&) const method.\n"
1093 <<
"Size of potential parameters (" << parameters_size <<
") must be equal to number of parameters (" << parameters_number <<
").\n";
1095 throw std::logic_error(buffer.str());
1115 const size_t size = inputs.size();
1118 if(size != inputs_number)
1120 std::ostringstream buffer;
1122 buffer <<
"OpenNN Exception: Perceptron class.\n"
1123 <<
"Vector<double> calculate_gradient(const Vector<double>&) const method.\n"
1124 <<
"Size must be equal to number of inputs.\n";
1126 throw std::logic_error(buffer.str());
1156 const size_t size = inputs.size();
1158 if(size != inputs_number)
1160 std::ostringstream buffer;
1162 buffer <<
"OpenNN Exception: Perceptron class.\n"
1163 <<
"double calculate_gradient(const Vector<double>&, const Vector<double>&) const method.\n"
1164 <<
"Size must be equal to number of inputs.\n";
1166 throw std::logic_error(buffer.str());
1181 gradient[0] = activation_derivative;
1185 for(
size_t i = 1; i < 1+inputs_number; i++)
1187 gradient[i] = inputs[i-1]*activation_derivative;
1217 const size_t size = inputs.size();
1219 if(size != inputs_number)
1221 std::ostringstream buffer;
1223 buffer <<
"OpenNN Exception: Perceptron class.\n"
1224 <<
"double calculate_combination_gradient(const Vector<double>&, const Vector<double>&) const method.\n"
1225 <<
"Size must be equal to number of inputs.\n";
1227 throw std::logic_error(buffer.str());
1238 combination_gradient[0] = 1.0;
1242 for(
size_t i = 1; i < 1+inputs_number; i++)
1244 combination_gradient[i] = inputs[i-1];
1247 return(combination_gradient);
1263 const size_t inputs_size = inputs.size();
1265 if(inputs_size != inputs_number)
1267 std::ostringstream buffer;
1269 buffer <<
"OpenNN Exception: Perceptron class.\n"
1270 <<
"Matrix<double> calculate_Hessian(const Vector<double>&) const method.\n"
1271 <<
"Size of inputs must be equal to number of inputs.\n";
1273 throw std::logic_error(buffer.str());
1299 const size_t inputs_size = inputs.size();
1302 if(inputs_size != inputs_number)
1304 std::ostringstream buffer;
1306 buffer <<
"OpenNN Exception: Perceptron class.\n"
1307 <<
"Matrix<double> calculate_Hessian(const Vector<double>&, const Vector<double>&) const method.\n"
1308 <<
"Size of inputs must be equal to number of inputs.\n";
1310 throw std::logic_error(buffer.str());
1324 Hessian(0,0) = activation_second_derivative;
1328 for(
size_t i = 1; i < parameters_number; i++)
1330 Hessian(0,i) = activation_second_derivative*inputs[i-1];
1335 for(
size_t i = 1; i < parameters_number; i++)
1337 for(
size_t j = 1; j < parameters_number; j++)
1339 Hessian(i,j) = activation_second_derivative*inputs[i-1]*inputs[j-1];
1345 for(
size_t i = 0; i < parameters_number; i++)
1347 for(
size_t j = 0; j < i; j++)
1349 Hessian(i,j) = Hessian(j,i);
1365 const Matrix<double> combination_Hessian(inputs_number, inputs_number, 0.0);
1367 return(combination_Hessian);
1381 const Matrix<double> Hessian(parameters_number, parameters_number, 0.0);
1411 if(index >= inputs_number)
1413 std::ostringstream buffer;
1415 buffer <<
"OpenNN Exception: Perceptron class.\n"
1416 <<
"void prune_input(const size_t&) method.\n"
1417 <<
"Index of input is equal or greater than number of inputs.\n";
1419 throw std::logic_error(buffer.str());
1440 std::ostringstream buffer;
1442 buffer << output_name <<
"=" << activation_function_name <<
"("
1445 for(
size_t i = 0; i < inputs_number; i++)
1454 if(i != 0 && i%4 == 0 && i != inputs_number-1)
1462 return(buffer.str());
Vector< double > synaptic_weights
Synaptic weights vector.
void randomize_uniform(const double &=-1.0, const double &=1.0)
void set_display(const bool &)
void prune_input(const size_t &)
void initialize(const T &)
void initialize_bias_uniform(const double &, const double &)
void initialize_bias_normal(const double &, const double &)
double calculate_activation(const double &) const
void initialize_synaptic_weights(const double &)
void set(void)
Sets the size of a vector to zero.
const double & get_synaptic_weight(const size_t &) const
Matrix< double > calculate_Hessian(const Vector< double > &) const
size_t count_parameters_number(void) const
Returns the number of parameters (bias and synaptic weights) in the perceptron.
ActivationFunction
Enumeration of available activation functions for the perceptron neuron model.
void set_synaptic_weights(const Vector< double > &)
const ActivationFunction & get_activation_function(void) const
Returns the activation function of the neuron.
bool display
Display messages to screen.
void set_activation_function(const ActivationFunction &)
Perceptron & operator=(const Perceptron &)
std::string write_activation_function(void) const
Returns a string with the name of the activation function of the neuron.
Vector< double > arrange_parameters(void) const
Returns the parameters (bias and synaptic weights) of the perceptron.
void set_bias(const double &)
void set_inputs_number(const size_t &)
void initialize_synaptic_weights_uniform(const double &, const double &)
Matrix< T > direct(const Vector< T > &) const
double calculate_combination(const Vector< double > &) const
Vector< double > calculate_combination_gradient(const Vector< double > &) const
Returns the partial derivatives of the combination with respect to the inputs.
ActivationFunction activation_function
Activation function variable.
void set(void)
Sets the number of inputs to zero and the rest of members to their default values.
bool operator==(const Perceptron &) const
size_t get_inputs_number(void) const
Returns the number of inputs to the neuron.
double calculate_output(const Vector< double > &) const
void initialize_synaptic_weights_normal(const double &, const double &)
Matrix< double > calculate_combination_Hessian(const Vector< double > &) const
This method retuns the second derivatives of the combination with respect to the inputs.
virtual ~Perceptron(void)
std::string write_expression(const Vector< std::string > &, const std::string &) const
const bool & get_display(void) const
void randomize_normal(const double &=0.0, const double &=1.0)
void initialize_bias(const double &)
void initialize_parameters(const double &)
double calculate_activation_derivative(const double &) const
const Vector< double > & arrange_synaptic_weights(void) const
Returns the synaptic weight values of the neuron.
Vector< double > calculate_gradient(const Vector< double > &) const
const double & get_bias(void) const
Returns the bias value of the neuron.
double calculate_activation_second_derivative(const double &) const
void set_synaptic_weight(const size_t &, const double &)
void set_parameters(const Vector< double > &)