Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ add_subdirectory(rnn)
add_subdirectory(rnn_tests)
add_subdirectory(rnn_examples)

# add_subdirectory(strategic)

# add_subdirectory(opencl)

add_subdirectory(weights)
Expand Down
2 changes: 1 addition & 1 deletion rnn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
add_library(examm_nn generate_nn.cxx rnn_genome.cxx rnn.cxx lstm_node.cxx ugrnn_node.cxx delta_node.cxx gru_node.cxx enarc_node.cxx enas_dag_node.cxx random_dag_node.cxx mgu_node.cxx dnas_node.cxx mse.cxx rnn_node.cxx rnn_edge.cxx rnn_recurrent_edge.cxx rnn_node_interface.cxx genome_property.cxx sin_node.cxx sum_node.cxx cos_node.cxx tanh_node.cxx sigmoid_node.cxx inverse_node.cxx multiply_node.cxx sin_node_gp.cxx cos_node_gp.cxx tanh_node_gp.cxx sigmoid_node_gp.cxx inverse_node_gp.cxx multiply_node_gp.cxx sum_node_gp.cxx)
add_library(examm_nn generate_nn.cxx rnn_genome.cxx rnn.cxx lstm_node.cxx ugrnn_node.cxx delta_node.cxx gru_node.cxx enarc_node.cxx enas_dag_node.cxx random_dag_node.cxx mgu_node.cxx dnas_node.cxx mse.cxx rnn_node.cxx rnn_edge.cxx rnn_recurrent_edge.cxx rnn_node_interface.cxx genome_property.cxx sin_node.cxx sum_node.cxx cos_node.cxx tanh_node.cxx sigmoid_node.cxx inverse_node.cxx multiply_node.cxx sin_node_gp.cxx cos_node_gp.cxx tanh_node_gp.cxx sigmoid_node_gp.cxx inverse_node_gp.cxx multiply_node_gp.cxx sum_node_gp.cxx stock_loss.cxx)
target_link_libraries(examm_nn exact_time_series exact_weights exact_common)
3 changes: 1 addition & 2 deletions rnn/generate_nn.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,10 @@ RNN_Genome* get_seed_genome(
get_argument(arguments, "--min_recurrent_depth", false, min_recurrent_depth);
int32_t max_recurrent_depth = 10;
get_argument(arguments, "--max_recurrent_depth", false, max_recurrent_depth);

Log::info("genome path is %s\n", genome_file_name.c_str());
bool epigenetic_weights = argument_exists(arguments, "--epigenetic_weights");
Log::info("Using epigeneratic weights is set to: %s \n", epigenetic_weights ? "True" : "False");
seed_genome = new RNN_Genome(genome_file_name);
seed_genome = new RNN_Genome(genome_file_name, arguments);
seed_genome->set_normalize_bounds(
time_series_sets->get_normalize_type(), time_series_sets->get_normalize_mins(),
time_series_sets->get_normalize_maxs(), time_series_sets->get_normalize_avgs(),
Expand Down
2 changes: 1 addition & 1 deletion rnn/mse.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ void get_mae(RNN* genome, const vector<vector<double> >& expected, double& mae_s
deltas[i][j] *= d_mae;
}
}
}
}
190 changes: 179 additions & 11 deletions rnn/rnn.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ using std::uniform_real_distribution;
#include <vector>
using std::vector;

# include <cmath>

#include "gru_node.hxx"
#include "lstm_node.hxx"
#include "rnn/rnn_genome.hxx"
Expand All @@ -39,6 +41,7 @@ using std::vector;
#include "random_dag_node.hxx"
#include "time_series/time_series.hxx"
// #include "word_series/word_series.hxx"
#include "stock_loss.hxx"

void RNN::validate_parameters(
const vector<string>& input_parameter_names, const vector<string>& output_parameter_names
Expand Down Expand Up @@ -200,12 +203,16 @@ RNN::RNN(

RNN::RNN(
vector<RNN_Node_Interface*>& _nodes, vector<RNN_Edge*>& _edges, vector<RNN_Recurrent_Edge*>& _recurrent_edges,
const vector<string>& input_parameter_names, const vector<string>& output_parameter_names
const vector<string>& input_parameter_names, const vector<string>& output_parameter_names, const vector<string>& arguments
) {
nodes = _nodes;
edges = _edges;
recurrent_edges = _recurrent_edges;

this->arguments = arguments;

get_argument(arguments, "--loss", false, this->loss);

// sort nodes by depth
// sort edges by depth
Log::debug("creating rnn with %d nodes, %d edges\n", nodes.size(), edges.size());
Expand Down Expand Up @@ -569,6 +576,14 @@ double RNN::prediction_mae(
return calculate_error_mae(expected_outputs);
}

double RNN::prediction_stock_loss(
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool using_dropout,
bool training, double dropout_probability
) {
forward_pass(series_data, using_dropout, training, dropout_probability);
return calculate_error_stock_loss(series_data, expected_outputs);
}

vector<double> RNN::get_predictions(
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool using_dropout,
double dropout_probability
Expand Down Expand Up @@ -654,13 +669,27 @@ void RNN::get_analytic_gradient(
const vector<vector<double> >& outputs, double& mse, vector<double>& analytic_gradient, bool using_dropout,
bool training, double dropout_probability
) {

analytic_gradient.assign(test_parameters.size(), 0.0);

// get_argument(arguments, "--loss", false, this->loss);

set_weights(test_parameters);
forward_pass(inputs, using_dropout, training, dropout_probability);

mse = calculate_error_mse(outputs);
backward_pass(mse * (1.0 / outputs[0].size()) * 2.0, using_dropout, training, dropout_probability);
if (this->loss == "mse"){
mse = calculate_error_mse(outputs);
backward_pass(mse * (1.0 / outputs[0].size()) * 2.0, using_dropout, training, dropout_probability);
} else if (this->loss == "mae") {
mse = calculate_error_mae(outputs);
backward_pass(mse * (1.0 / outputs[0].size()) * 2.0, using_dropout, training, dropout_probability);
} else if (this->loss == "stock") {
mse = calculate_error_stock_loss(inputs, outputs);
backward_pass(mse, using_dropout, training, dropout_probability);
} else {
Log::fatal("ERROR: incorrect loss function provided\n");
exit(1);
}

vector<double> current_gradients;

Expand Down Expand Up @@ -693,7 +722,7 @@ void RNN::get_analytic_gradient(

void RNN::get_empirical_gradient(
const vector<double>& test_parameters, const vector<vector<double> >& inputs,
const vector<vector<double> >& outputs, double& mse, vector<double>& empirical_gradient, bool using_dropout,
const vector<vector<double> >& outputs, double& loss, vector<double>& empirical_gradient, bool using_dropout,
bool training, double dropout_probability
) {
empirical_gradient.assign(test_parameters.size(), 0.0);
Expand All @@ -702,11 +731,25 @@ void RNN::get_empirical_gradient(

set_weights(test_parameters);
forward_pass(inputs, using_dropout, training, dropout_probability);
double original_mse = calculate_error_mse(outputs);
double original_loss = 0.0;

if (this->loss == "mse"){
original_loss = calculate_error_mse(outputs);

} else if (this->loss == "mae") {
original_loss = calculate_error_mae(outputs);

} else if (this->loss == "stock") {
original_loss = calculate_error_stock_loss(inputs, outputs);

} else {
Log::fatal("ERROR: incorrect loss function provided\n");
exit(1);
}

double save;
double diff = 0.00001;
double mse1, mse2;
double loss1, loss2;

vector<double> parameters = test_parameters;
for (int32_t i = 0; i < (int32_t) parameters.size(); i++) {
Expand All @@ -715,20 +758,48 @@ void RNN::get_empirical_gradient(
parameters[i] = save - diff;
set_weights(parameters);
forward_pass(inputs, using_dropout, training, dropout_probability);
get_mse(this, outputs, mse1, deltas);
// get_mse(this, outputs, loss1, deltas);

if (this->loss == "mse"){
get_mse(this, outputs, loss1, deltas);

} else if (this->loss == "mae") {
get_mae(this, outputs, loss1, deltas);

} else if (this->loss == "stock") {
get_stock_loss(this, outputs, loss1, deltas, inputs, outputs);

} else {
Log::fatal("ERROR: incorrect loss function provided\n");
exit(1);
}

parameters[i] = save + diff;
set_weights(parameters);
forward_pass(inputs, using_dropout, training, dropout_probability);
get_mse(this, outputs, mse2, deltas);
// get_mse(this, outputs, loss2, deltas);

if (this->loss == "mse"){
get_mse(this, outputs, loss2, deltas);

} else if (this->loss == "mae") {
get_mae(this, outputs, loss2, deltas);

} else if (this->loss == "stock") {
get_stock_loss(this, outputs, loss2, deltas, inputs, outputs);

} else {
Log::fatal("ERROR: incorrect loss function provided\n");
exit(1);
}

empirical_gradient[i] = (mse2 - mse1) / (2.0 * diff);
empirical_gradient[i] *= original_mse;
empirical_gradient[i] = (loss2 - loss1) / (2.0 * diff);
empirical_gradient[i] *= original_loss;

parameters[i] = save;
}

mse = original_mse;
loss = original_loss;
}

void RNN::initialize_randomly() {
Expand Down Expand Up @@ -761,3 +832,100 @@ RNN* RNN::copy() {
return new RNN(node_copies, edge_copies, recurrent_edge_copies);
}
*/


template <typename T>
double signum(T x) {
if (x > 0) {
return 1.0;
} else if (x < 0) {
return -1.0;
} else {
return 0.0;
}
}

// double RNN::calculate_error_stock_loss (const vector<vector<double> >& expected_outputs,
// const vector<double> return_at_t,
// const vector<double> return_at_t_plus_1)
// {
// double loss_sum = 0.0;
// double sum_v_i = 0.0;

// for (int32_t i = 0; i < (int32_t) output_nodes.size(); i++) {
// for (int32_t j = 0; j < (int32_t) output_nodes[i]->output_values.size(); j++) {
// sum_v_i += fabs(output_nodes[i]->output_values[j]);
// }
// }

// for (int32_t i = 0; i < (int32_t) output_nodes.size(); i++) {

// double v_i = 0.0;

// for (int32_t j = 0; j < (int32_t) output_nodes[i]->output_values.size(); j++) {
// v_i = 1.0 * fabs(output_nodes[i]->output_values[j]) / sum_v_i;
// loss_sum += v_i * (return_at_t_plus_1[i] - return_at_t[i]) * signum(output_nodes[i]->output_values[j]);
// }
// }

// return loss_sum;
// }

double RNN::calculate_error_stock_loss(const vector<vector<double> >& return_at_t, const vector<vector<double> >& return_at_t_plus_1){

double loss_sum = 0.0;
double sum_v_i = 0.0;
double absolute_sum = 0.0;

for (int32_t i = 0; i < (int32_t) output_nodes.size(); i++) {
// output_nodes[i]->error_values.resize(expected_outputs[i].size());

// tanh convert input to -1 and 1

for (int32_t j = 0; j < (int32_t) return_at_t_plus_1[i].size(); j++) {
sum_v_i += fabs(output_nodes[i]->output_values[j]);
// absolute_sum += fabs(tanh(output_nodes[i]->output_values[j]));
}
}


for (int32_t i = 0; i < (int32_t) output_nodes.size(); i++) {
// output_nodes[i]->error_values.resize(expected_outputs[i].size());

double v_i = 0.0;
double gradient_at_k = 0.0;
double gradient_at_not_k = 0.0;

for (int32_t j = 0; j < (int32_t) return_at_t_plus_1[i].size(); j++) {

v_i = 1.0 * fabs(output_nodes[i]->output_values[j]) / sum_v_i;
loss_sum += v_i * (return_at_t_plus_1[i][j] - return_at_t[i][j]) * signum(output_nodes[i]->output_values[j]);

gradient_at_k += -1.0 * (return_at_t_plus_1[i][j] - return_at_t[i][j]) *
((sum_v_i - output_nodes[i]->output_values[j]) *
signum(output_nodes[i]->output_values[j])) / pow(sum_v_i, 2);

output_nodes[i]->error_values[j] += gradient_at_k;
}

for (int32_t j = 0; j < (int32_t) output_nodes.size(); j++) {
for (int32_t k = 0; j < (int32_t) return_at_t_plus_1[j].size(); k++) {
if (i == j){
continue;
}

gradient_at_not_k += -1.0 * (return_at_t_plus_1[i][j] - return_at_t[i][j]) *
signum(output_nodes[i]->output_values[k]) / pow(absolute_sum, 2);

}
output_nodes[i]->error_values[j] += gradient_at_not_k;
}

}

return loss_sum;
}

string RNN::get_loss() {
return this->loss;
}
21 changes: 19 additions & 2 deletions rnn/rnn.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ class RNN {
vector<RNN_Edge*> edges;
vector<RNN_Recurrent_Edge*> recurrent_edges;

vector<string> arguments;

string loss;

public:
RNN(vector<RNN_Node_Interface*>& _nodes, vector<RNN_Edge*>& _edges, const vector<string>& input_parameter_names,
const vector<string>& output_parameter_names);
RNN(vector<RNN_Node_Interface*>& _nodes, vector<RNN_Edge*>& _edges, vector<RNN_Recurrent_Edge*>& _recurrent_edges,
const vector<string>& input_parameter_names, const vector<string>& output_parameter_names);
const vector<string>& input_parameter_names, const vector<string>& output_parameter_names, const vector<string>& arguments);
~RNN();

void fix_parameter_orders(
Expand All @@ -51,6 +55,10 @@ class RNN {
double calculate_error_mse(const vector<vector<double> >& expected_outputs);
double calculate_error_mae(const vector<vector<double> >& expected_outputs);

// Stock Loss
double calculate_error_stock_loss(const vector<vector<double> >& return_at_t,
const vector<vector<double> >& return_at_t_plus_1);

double prediction_softmax(
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool using_dropout,
bool training, double dropout_probability
Expand All @@ -63,6 +71,10 @@ class RNN {
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool using_dropout,
bool training, double dropout_probability
);
double prediction_stock_loss(
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool using_dropout,
bool training, double dropout_probability
);

vector<double> get_predictions(
const vector<vector<double> >& series_data, const vector<vector<double> >& expected_outputs, bool usng_dropout,
Expand All @@ -82,7 +94,7 @@ class RNN {

int32_t get_number_weights();

void get_analytic_gradient(
void get_analytic_gradient( /// gradients
const vector<double>& test_parameters, const vector<vector<double> >& inputs,
const vector<vector<double> >& outputs, double& mse, vector<double>& analytic_gradient, bool using_dropout,
bool training, double dropout_probability
Expand All @@ -93,6 +105,8 @@ class RNN {
bool training, double dropout_probability
);

string get_loss();

// RNN* copy();

friend void get_mse(
Expand All @@ -101,6 +115,9 @@ class RNN {
friend void get_mae(
RNN* genome, const vector<vector<double> >& expected, double& mae, vector<vector<double> >& deltas
);
// Stock Loss
friend void get_stock_loss(RNN* genome, const vector<vector<double> >& expected, double& loss, vector<vector<double> >& deltas, const vector<double> return_at_t,
const vector<double> return_at_t_plus_1);
};

#endif
Loading