-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #105 from czgdp1807/lnn
Port ``integration_tests/lnn`` from LPython
- Loading branch information
Showing
11 changed files
with
587 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#include <vector> | ||
#include <iostream> | ||
|
||
struct Perceptron { | ||
int32_t no_of_inputs; | ||
std::vector<double> weights; | ||
double learn_rate; | ||
int32_t iterations_limit; | ||
double des_accuracy; | ||
double cur_accuracy; | ||
int32_t epochs_cnt; | ||
}; | ||
|
||
int32_t predict_perceptron(const struct Perceptron& p, const std::vector<double>& input_vector); | ||
int32_t activation_function(double value); | ||
double test_perceptron(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<int32_t>& outputs); | ||
|
||
std::vector<double> get_inp_vec_with_bias(std::vector<double>& a) { | ||
std::vector<double> b = {}; | ||
size_t i; | ||
for( i = 0; i < a.size(); i++ ) { | ||
b.push_back(a[i]); | ||
} | ||
b.push_back(1.0); | ||
return b; | ||
} | ||
|
||
std::vector<double> init_weights(int32_t size) { | ||
std::vector<double> weights = {}; | ||
int32_t i; | ||
for( i = 0; i < size; i++ ) { | ||
weights.push_back(0.0); | ||
} | ||
weights.push_back(0.0); | ||
return weights; | ||
} | ||
|
||
void init_perceptron(struct Perceptron& p, int32_t n, double rate, | ||
int32_t iterations_limit, double des_accuracy) { | ||
if (n < 1 or n > 1000) { | ||
std::cout << "no_of_inputs must be between [1, 1000]" << std::endl; | ||
exit(2); | ||
} | ||
p.no_of_inputs = n; | ||
p.weights = init_weights(n); | ||
p.learn_rate = rate; | ||
p.iterations_limit = iterations_limit; | ||
p.des_accuracy = des_accuracy; | ||
p.cur_accuracy = 0.0; | ||
p.epochs_cnt = 0; | ||
} | ||
|
||
void train_perceptron(struct Perceptron& p, const std::vector<double>& input_vector, int32_t actual_output) { | ||
int32_t predicted_output = predict_perceptron(p, input_vector); | ||
int32_t error = actual_output - predicted_output; | ||
size_t i; | ||
for( i = 0; i < input_vector.size(); i++ ) { | ||
p.weights[i] += p.learn_rate * double(error) * double(input_vector[i]); | ||
} | ||
} | ||
|
||
int32_t predict_perceptron(const struct Perceptron& p, const std::vector<double>& input_vector) { | ||
double weighted_sum = 0.0; | ||
size_t i = 0; | ||
for( i = 0; i < input_vector.size(); i++ ) { | ||
weighted_sum = weighted_sum + p.weights[i] * double(input_vector[i]); | ||
} | ||
return activation_function(weighted_sum); | ||
} | ||
|
||
int32_t activation_function(double value) { | ||
if ( value >= 0.0 ) { | ||
return 1; | ||
} | ||
return -1; | ||
} | ||
|
||
void train_epoch(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<int32_t>& outputs) { | ||
size_t i; | ||
for( i = 0; i < input_vectors.size(); i++ ) { | ||
std::vector<double> input_vector = get_inp_vec_with_bias(input_vectors[i]); | ||
if( predict_perceptron(p, input_vector) != outputs[i] ) { | ||
train_perceptron(p, input_vector, outputs[i]); | ||
} | ||
} | ||
} | ||
|
||
void train_dataset(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<int32_t>& outputs) { | ||
p.cur_accuracy = 0.0; | ||
p.epochs_cnt = 0; | ||
while( p.cur_accuracy < p.des_accuracy and p.epochs_cnt < p.iterations_limit ) { | ||
p.epochs_cnt += 1; | ||
train_epoch(p, input_vectors, outputs); | ||
p.cur_accuracy = test_perceptron(p, input_vectors, outputs); | ||
} | ||
} | ||
|
||
double test_perceptron(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<int32_t>& outputs) { | ||
int32_t correctly_classified_cnt = 0; | ||
size_t i; | ||
for( i = 0; i < input_vectors.size(); i++ ) { | ||
std::vector<double> input_vector = get_inp_vec_with_bias(input_vectors[i]); | ||
if( predict_perceptron(p, input_vector) == outputs[i] ) { | ||
correctly_classified_cnt += 1; | ||
} | ||
} | ||
return (correctly_classified_cnt / input_vectors.size()) * 100.0; | ||
} | ||
|
||
void print_perceptron(struct Perceptron& p) { | ||
std::cout<<"weights = ["; | ||
int32_t i; | ||
for( i = 0; i < p.no_of_inputs; i++ ) { | ||
std::cout<<p.weights[i]<<", "; | ||
} | ||
std::cout<<p.weights[p.no_of_inputs]<<"(bias)]\n"; | ||
std::cout<<"learn_rate = "; | ||
std::cout<<p.learn_rate<<"\n"; | ||
std::cout<<"accuracy = "; | ||
std::cout<<p.cur_accuracy<<"\n"; | ||
std::cout<<"epochs_cnt = "; | ||
std::cout<<p.epochs_cnt<<"\n"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include <iostream> | ||
|
||
struct Perceptron { | ||
int32_t no_of_inputs; | ||
std::vector<double> weights; | ||
double learn_rate; | ||
int32_t iterations_limit; | ||
double err_limit; | ||
double err; | ||
int32_t epochs_cnt; | ||
}; | ||
|
||
double predict_perceptron(struct Perceptron& p, std::vector<double>& input_vector); | ||
double activation_function(double value); | ||
double test_perceptron(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<double>& outputs); | ||
|
||
std::vector<double> get_inp_vec_with_bias(std::vector<double>& a) { | ||
std::vector<double> b = {}; | ||
size_t i; | ||
for( i = 0; i < a.size(); i++ ) { | ||
b.push_back(a[i]); | ||
} | ||
b.push_back(1.0); | ||
return b; | ||
} | ||
|
||
std::vector<double> init_weights(int32_t size) { | ||
std::vector<double> weights = {}; | ||
int32_t i; | ||
for( i = 0; i < size; i++ ) { | ||
weights.push_back(0.0); | ||
} | ||
weights.push_back(0.0); | ||
return weights; | ||
} | ||
|
||
void init_perceptron(struct Perceptron& p, int32_t n, double rate, int32_t iterations_limit, double err_limit) { | ||
p.no_of_inputs = n; | ||
p.weights = init_weights(n); | ||
p.learn_rate = rate; | ||
p.iterations_limit = iterations_limit; | ||
p.err_limit = err_limit; | ||
p.err = 1.0; | ||
p.epochs_cnt = 0; | ||
} | ||
|
||
void train_perceptron(struct Perceptron& p, std::vector<double>& input_vector, double actual_output) { | ||
double predicted_output = predict_perceptron(p, input_vector); | ||
double error = actual_output - predicted_output; | ||
int32_t i; | ||
for( i = 0; i < input_vector.size(); i++ ) { | ||
p.weights[i] += p.learn_rate * error * input_vector[i]; | ||
} | ||
} | ||
|
||
double predict_perceptron(struct Perceptron& p, std::vector<double>& input_vector) { | ||
double weighted_sum = 0.0; | ||
int32_t i = 0; | ||
for( i = 0; i < input_vector.size(); i++ ) { | ||
weighted_sum = weighted_sum + p.weights[i] * input_vector[i]; | ||
} | ||
return activation_function(weighted_sum); | ||
} | ||
|
||
double activation_function(double value) { | ||
return value; | ||
} | ||
|
||
void train_epoch(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<double>& outputs) { | ||
int32_t i; | ||
for( i = 0; i < input_vectors.size(); i++ ) { | ||
std::vector<double> input_vector = get_inp_vec_with_bias(input_vectors[i]); | ||
if ( predict_perceptron(p, input_vector) != outputs[i] ) { | ||
train_perceptron(p, input_vector, outputs[i]); | ||
} | ||
} | ||
} | ||
|
||
void train_dataset(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<double>& outputs) { | ||
double prev_err = 0.0; | ||
p.err = 1.0; | ||
p.epochs_cnt = 0; | ||
while( abs(p.err - prev_err) >= p.err_limit and p.epochs_cnt < p.iterations_limit ) { | ||
p.epochs_cnt += 1; | ||
train_epoch(p, input_vectors, outputs); | ||
prev_err = p.err; | ||
p.err = test_perceptron(p, input_vectors, outputs); | ||
} | ||
} | ||
|
||
double test_perceptron(struct Perceptron& p, std::vector<std::vector<double>>& input_vectors, std::vector<double>& outputs) { | ||
double err = 0.0; | ||
int32_t i; | ||
for( i = 0; i < input_vectors.size(); i++ ) { | ||
std::vector<double> input_vector = get_inp_vec_with_bias(input_vectors[i]); | ||
err = err + pow((outputs[i] - predict_perceptron(p, input_vector)), 2.0); | ||
} | ||
return err; | ||
} | ||
|
||
void print_perceptron(struct Perceptron& p) { | ||
std::cout << "weights = ["; | ||
int32_t i; | ||
for( i = 0; i < p.no_of_inputs; i++ ) { | ||
std::cout << p.weights[i] << ", "; | ||
} | ||
std::cout << p.weights[p.no_of_inputs] << "\n"; | ||
std::cout << "learn_rate = "; | ||
std::cout << p.learn_rate << "\n"; | ||
std::cout << "error = "; | ||
std::cout << p.err << "\n"; | ||
std::cout << "epochs_cnt = "; | ||
std::cout << p.epochs_cnt << "\n"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <vector> | ||
|
||
double normalize(double value, double leftMin, double leftMax, double rightMin, double rightMax) { | ||
// Figure out how 'wide' each range is | ||
double leftSpan = leftMax - leftMin; | ||
double rightSpan = rightMax - rightMin; | ||
|
||
// Convert the left range into a 0-1 range (float) | ||
double valueScaled = (value - leftMin) / leftSpan; | ||
|
||
// Convert the 0-1 range into a value in the right range. | ||
return rightMin + (valueScaled * rightSpan); | ||
} | ||
|
||
void normalize_input_vectors(std::vector<std::vector<double>>& input_vectors) { | ||
int32_t rows = input_vectors.size(); | ||
int32_t cols = input_vectors[0].size(); | ||
|
||
int32_t j; | ||
for( j = 0; j < cols; j++ ) { | ||
double colMinVal = input_vectors[0][j]; | ||
double colMaxVal = input_vectors[0][j]; | ||
int32_t i; | ||
for( i = 0; i < rows; i++ ) { | ||
if( input_vectors[i][j] > colMaxVal ) { | ||
colMaxVal = input_vectors[i][j]; | ||
} | ||
if( input_vectors[i][j] < colMinVal ) { | ||
colMinVal = input_vectors[i][j]; | ||
} | ||
} | ||
|
||
for( i = 0; i < rows; i++ ) { | ||
input_vectors[i][j] = normalize(input_vectors[i][j], colMinVal, colMaxVal, -1.0, 1.0); | ||
} | ||
} | ||
} | ||
|
||
void normalize_output_vector(std::vector<double>& output_vector) { | ||
int32_t rows = output_vector.size(); | ||
double colMinVal = output_vector[0]; | ||
double colMaxVal = output_vector[0]; | ||
int32_t i; | ||
for( i = 0; i < rows; i++ ) { | ||
if( output_vector[i] > colMaxVal ) { | ||
colMaxVal = output_vector[i]; | ||
} | ||
if( output_vector[i] < colMinVal ) { | ||
colMinVal = output_vector[i]; | ||
} | ||
} | ||
|
||
for( i = 0; i < rows; i++ ) { | ||
output_vector[i] = normalize(output_vector[i], colMinVal, colMaxVal, -1.0, 1.0); | ||
} | ||
} |
Oops, something went wrong.