diff --git a/src/IrisDatasetTest.cpp b/src/IrisDatasetTest.cpp index 3fcaa42..af6ef35 100644 --- a/src/IrisDatasetTest.cpp +++ b/src/IrisDatasetTest.cpp @@ -21,14 +21,22 @@ INITIALIZE_EASYLOGGINGPP // Disclaimer: This is NOT an example of good machine learning practices // regarding training/testing dataset partitioning. +const int input_size = 4; +const int number_classes = 3; +#if defined(_WIN32) const char *iris_dataset = "../../data/iris.data"; -const std::array class_names = +const std::string iris_mlp_weights = "../../data/iris.mlp"; +#else +const char *iris_dataset = "./data/iris.data"; +const std::string iris_mlp_weights = "./data/iris.mlp"; +#endif +const std::array class_names = { "Iris-setosa", "Iris-versicolor", "Iris-virginica" }; bool load_data(int *samples, - std::vector *input, - std::vector *iris_class) { + std::vector *input, + std::vector *iris_class) { // Load the iris data-set. FILE *in = fopen(iris_dataset, "r"); if (!in) { @@ -46,32 +54,41 @@ bool load_data(int *samples, LOG(INFO) << "Loading " << (*samples) << " data points from " << iris_dataset << "."; // Allocate memory for input and output data. - input->resize((*samples) * 4); - iris_class->resize((*samples) * 3); + input->resize((*samples) * input_size); + iris_class->resize((*samples) * number_classes); // Read the file into our arrays. int i, j; for (i = 0; i < (*samples); ++i) { - double *p = &((*input)[0]) + i * 4; - double *c = &((*iris_class)[0]) + i * 3; - c[0] = c[1] = c[2] = 0.0; + double *p = &((*input)[0]) + i * input_size; + double *c = &((*iris_class)[0]) + i * number_classes; + for (int k = 0; k < number_classes; k++) { + c[i] = 0.0; + } fgets(line, 1024, in); char *split = strtok(line, ","); for (j = 0; j < 4; ++j) { p[j] = atof(split); - split = strtok(0, ","); + split = strtok(NULL, ","); } - split[strlen(split) - 1] = 0; + if (strlen(split) >= 1 && split[strlen(split) - 1] == '\n') + split[strlen(split) - 1] = '\0'; + if (strlen(split) >= 2 && split[strlen(split) - 2] == '\r') + split[strlen(split) - 2] = '\0'; + if (strcmp(split, class_names[0].c_str()) == 0) { c[0] = 1.0; - } else if (strcmp(split, class_names[1].c_str()) == 0) { + } + else if (strcmp(split, class_names[1].c_str()) == 0) { c[1] = 1.0; - } else if (strcmp(split, class_names[2].c_str()) == 0) { + } + else if (strcmp(split, class_names[2].c_str()) == 0) { c[2] = 1.0; - } else { + } + else { LOG(ERROR) << "Unknown iris_class " << split << "."; return false; @@ -106,7 +123,7 @@ int main(int argc, char *argv[]) { for (int i = 0; i < 3; i++) training_set_output.push_back(*(&(iris_class[0]) + j * 3 + i)); training_set.emplace_back(std::move(training_set_input), - std::move(training_set_output)); + std::move(training_set_output)); } std::vector training_sample_set_with_bias(std::move(training_set)); //set up bias @@ -126,11 +143,11 @@ int main(int argc, char *argv[]) { LOG(INFO) << "Training for " << loops << " loops over data."; my_mlp.Train(training_sample_set_with_bias, .01, loops, 0.10, false); - my_mlp.SaveMLPNetwork(std::string("../../data/iris.mlp")); + my_mlp.SaveMLPNetwork(iris_mlp_weights); } //Destruction/Construction of a MLP object to show off saving and loading a trained model { - MLP my_mlp(std::string("../../data/iris.mlp")); + MLP my_mlp(iris_mlp_weights); int correct = 0; for (int j = 0; j < samples; ++j) { @@ -141,9 +158,11 @@ int main(int argc, char *argv[]) { if (iris_class[j * 3 + 0] == 1.0 && class_id == 0) { ++correct; - } else if (iris_class[j * 3 + 1] == 1.0 && class_id == 1) { + } + else if (iris_class[j * 3 + 1] == 1.0 && class_id == 1) { ++correct; - } else if (iris_class[j * 3 + 2] == 1.0 && class_id == 2) { + } + else if (iris_class[j * 3 + 2] == 1.0 && class_id == 2) { ++correct; } } diff --git a/src/MLP.cpp b/src/MLP.cpp index 558ca44..cd76f15 100644 --- a/src/MLP.cpp +++ b/src/MLP.cpp @@ -28,7 +28,7 @@ MLP::MLP(const std::vector & layers_nodes, constant_weight_init); }; -MLP::MLP(std::string & filename) { +MLP::MLP(const std::string & filename) { LoadMLPNetwork(filename); } @@ -58,7 +58,7 @@ void MLP::CreateMLP(const std::vector & layers_nodes, } }; -void MLP::SaveMLPNetwork(std::string & filename)const { +void MLP::SaveMLPNetwork(const std::string & filename)const { FILE * file; file = fopen(filename.c_str(), "wb"); fwrite(&m_num_inputs, sizeof(m_num_inputs), 1, file); @@ -71,7 +71,7 @@ void MLP::SaveMLPNetwork(std::string & filename)const { } fclose(file); }; -void MLP::LoadMLPNetwork(std::string & filename) { +void MLP::LoadMLPNetwork(const std::string & filename) { m_layers_nodes.clear(); m_layers.clear(); diff --git a/src/MLP.h b/src/MLP.h index 783cc05..d4ecbea 100644 --- a/src/MLP.h +++ b/src/MLP.h @@ -24,11 +24,11 @@ public: const std::vector & layers_activfuncs, bool use_constant_weight_init = false, double constant_weight_init = 0.5); - MLP(std::string & filename); + MLP(const std::string & filename); ~MLP(); - void SaveMLPNetwork(std::string & filename)const; - void LoadMLPNetwork(std::string & filename); + void SaveMLPNetwork(const std::string & filename)const; + void LoadMLPNetwork(const std::string & filename); void GetOutput(const std::vector &input, std::vector * output,