diff --git a/src/mlpack/methods/ann/augmented/tasks/add.hpp b/src/mlpack/methods/ann/augmented/tasks/add.hpp index 2f1ac6c01f..f3f410b630 100644 --- a/src/mlpack/methods/ann/augmented/tasks/add.hpp +++ b/src/mlpack/methods/ann/augmented/tasks/add.hpp @@ -36,13 +36,15 @@ class AddTask * @param labels The variable to store output sequences. * @param batchSize The dataset size. */ - void Generate(arma::field& input, - arma::field& labels, + void Generate(arma::field& input, + arma::field& labels, const size_t batchSize); private: // Maximum binary length of numbers. size_t bitLen; + + arma::field Binarize(arma::field data); }; } // namespace tasks } // namespace augmented diff --git a/src/mlpack/methods/ann/augmented/tasks/add_impl.hpp b/src/mlpack/methods/ann/augmented/tasks/add_impl.hpp index 5c28cbf463..4ad0258c42 100644 --- a/src/mlpack/methods/ann/augmented/tasks/add_impl.hpp +++ b/src/mlpack/methods/ann/augmented/tasks/add_impl.hpp @@ -37,12 +37,12 @@ AddTask::AddTask(const size_t bitLen) : bitLen(bitLen) { assert(bitLen > 0); } -void AddTask::Generate(arma::field& input, - arma::field& labels, +void AddTask::Generate(arma::field& input, + arma::field& labels, const size_t batchSize) { - input = arma::field(batchSize); - labels = arma::field(batchSize); + arma::field vecInput = arma::field(batchSize); + arma::field vecLabels = arma::field(batchSize); for (size_t i = 0; i < batchSize; ++i) { // Random uniform length from [2..bitLen] size_t size_A = RandInt(2, bitLen + 1); @@ -50,18 +50,18 @@ void AddTask::Generate(arma::field& input, // Construct sequence of the form // (binary number with size_A bits) + '+' // + (binary number with size_B bits) - input(i) = arma::randi( + vecInput(i) = arma::randi( size_A + size_B + 1, arma::distr_param(0, 1)); - input(i).at(size_A) = 2; // special value for '+' delimiter + vecInput(i).at(size_A) = 2; // special value for '+' delimiter int val_A = 0; for (size_t k = 0; k < size_A; ++k) { val_A <<= 1; - val_A += input(i).at(k); + val_A += vecInput(i).at(k); } int val_B = 0; for (size_t k = size_A+1; k < size_A+1+size_B; ++k) { val_B <<= 1; - val_B += input(i).at(k); + val_B += vecInput(i).at(k); } int tot = val_A + val_B; vector binary_seq; @@ -70,13 +70,30 @@ void AddTask::Generate(arma::field& input, tot >>= 1; } size_t tot_len = binary_seq.size(); - labels(i) = arma::colvec(tot_len); + vecLabels(i) = arma::colvec(tot_len); for (size_t j = 0; j < tot_len; ++j) { - labels(i).at(j) = binary_seq[tot_len-j-1]; + vecLabels(i).at(j) = binary_seq[tot_len-j-1]; } } + input = Binarize(vecInput); + labels = Binarize(vecLabels); } +arma::field AddTask::Binarize(arma::field data) +{ + arma::field procData(data.n_elem); + for (size_t i = 0; i < data.n_elem; ++i) { + arma::mat temp = arma::zeros(3, data.at(i).n_elem); + for (size_t j = 0; j < data.at(i).n_elem; ++j) { + int val = data.at(i).at(j); + temp.at(val, j) = 1; + } + procData.at(i) = temp; + } + return procData; +} + + } // namespace tasks } // namespace augmented } // namespace ann diff --git a/src/mlpack/tests/augmented_rnns_tasks_test.cpp b/src/mlpack/tests/augmented_rnns_tasks_test.cpp index 953502b8fb..9b6d387616 100644 --- a/src/mlpack/tests/augmented_rnns_tasks_test.cpp +++ b/src/mlpack/tests/augmented_rnns_tasks_test.cpp @@ -60,7 +60,6 @@ class HardCodedCopyModel { } assert(oneCnt % zeroCnt == 0); nRepeats = oneCnt / zeroCnt; - std::cerr << "Repeats: " << nRepeats << "\n"; } void Predict( arma::mat& predictors, @@ -72,8 +71,6 @@ class HardCodedCopyModel { for (size_t i = 0; i < outputLen; ++i) { labels.at(seqLen+i) = predictors.at(2 * (i % seqLen)); } - std::cerr << "Predictors:\n" << predictors.t(); - std::cerr << "Labels:\n" << labels.t(); } void Predict( arma::field& predictors, @@ -134,19 +131,20 @@ class HardCodedSortModel { class HardCodedAddModel { public: HardCodedAddModel() {} - void Train(arma::field& predictors, - arma::field& labels) + void Train(arma::field& predictors, + arma::field& labels) { return; } - void Predict(arma::colvec& predictors, - arma::colvec& labels) + void Predict(arma::mat& predictors, + arma::mat& labels) { + assert(predictors.n_rows == 3); int num_A = 0, num_B = 0; bool num = false; // true iff we have already seen the separating symbol - auto len = predictors.n_elem; + size_t len = predictors.n_cols; for (size_t i = 0; i < len; ++i) { - auto digit = predictors.at(i); + auto digit = arma::as_scalar(arma::find(1 == predictors.col(i), 1)); if (digit != 0 && digit != 1) { // We should not see two separators @@ -175,16 +173,16 @@ class HardCodedAddModel { total >>= 1; } auto tot_len = binary_seq.size(); - labels = arma::colvec(tot_len); + labels = arma::zeros(3, tot_len); for (size_t j = 0; j < tot_len; ++j) { - labels.at(j) = binary_seq[tot_len-j-1]; + labels.at(binary_seq[tot_len-j-1], j) = 1; } } void Predict( - arma::field& predictors, - arma::field& labels) { + arma::field& predictors, + arma::field& labels) { auto sz = predictors.n_elem; - labels = arma::field(sz); + labels = arma::field(sz); for (size_t i = 0; i < sz; ++i) { Predict(predictors.at(i), labels.at(i)); } @@ -251,16 +249,16 @@ BOOST_AUTO_TEST_CASE(AddTaskTest) { bool ok = true; for (size_t bitLen = 2; bitLen <= 16; ++bitLen) { AddTask task(bitLen); - arma::field trainPredictor, trainResponse; + arma::field trainPredictor, trainResponse; task.Generate(trainPredictor, trainResponse, 8); - arma::field testPredictor, testResponse; + arma::field testPredictor, testResponse; task.Generate(testPredictor, testResponse, 8); HardCodedAddModel model; model.Train(trainPredictor, trainResponse); - arma::field predResponse; + arma::field predResponse; model.Predict(testPredictor, predResponse); // A single failure is a failure. - if (SequencePrecision(testResponse, predResponse) < 0.99) { + if (SequencePrecision(testResponse, predResponse) < 0.99) { ok = false; break; }