{"action":"created","comment":{"url":"https://api.github.com/repos/mlpack/mlpack/pulls/comments/193182469","pull_request_review_id":126104969,"id":193182469,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5MzE4MjQ2OQ==","diff_hunk":"@@ -0,0 +1,459 @@\n+/**\n+ * @file lmnn_function_impl.cpp\n+ * @author Manish Kumar\n+ *\n+ * An implementation of the LMNNFunction class.\n+ *\n+ * mlpack is free software; you may redistribute it and/or modify it under the\n+ * terms of the 3-clause BSD license.  You should have received a copy of the\n+ * 3-clause BSD license along with mlpack.  If not, see\n+ * http://www.opensource.org/licenses/BSD-3-Clause for more information.\n+ */\n+#ifndef MLPACK_METHODS_LMNN_FUNCTION_IMPL_HPP\n+#define MLPACK_METHODS_LMNN_FUNCTION_IMPL_HPP\n+\n+#include \"lmnn_function.hpp\"\n+#include \"constraints.hpp\"\n+\n+#include <mlpack/core/math/make_alias.hpp>\n+#include <mlpack/core/optimizers/function.hpp>\n+\n+namespace mlpack {\n+namespace lmnn {\n+\n+template<typename MetricType>\n+LMNNFunction<MetricType>::LMNNFunction(const arma::mat& dataset,\n+                           const arma::Row<size_t>& labels,\n+                           size_t k,\n+                           double regularization,\n+                           MetricType metric) :\n+    dataset(math::MakeAlias(const_cast<arma::mat&>(dataset), false)),\n+    labels(math::MakeAlias(const_cast<arma::Row<size_t>&>(labels), false)),\n+    k(k),\n+    metric(metric),\n+    regularization(regularization)\n+{\n+  // Initialize the initial learning point.\n+  initialPoint.eye(dataset.n_rows, dataset.n_rows);\n+  // Initialize transformed dataset to base dataset.\n+  transformedDataset = dataset;\n+\n+  // Initialize target neighbors & impostors.\n+  Constraints constraint(dataset, labels, k);\n+  constraint.TargetNeighbors(targetNeighbors);\n+  constraint.Impostors(impostors);\n+}\n+\n+//! Shuffle the dataset.\n+template<typename MetricType>\n+void LMNNFunction<MetricType>::Shuffle()\n+{\n+  arma::mat newDataset;\n+  arma::Row<size_t> newLabels;\n+\n+  math::ShuffleData(dataset, labels, newDataset, newLabels);\n+\n+  math::ClearAlias(dataset);\n+  math::ClearAlias(labels);\n+\n+  dataset = std::move(newDataset);\n+  labels = std::move(newLabels);\n+\n+  // Re-calculate target neighbors as indices changed.\n+  Constraints constraint(dataset, labels, k);\n+  constraint.TargetNeighbors(targetNeighbors);\n+}\n+\n+inline void Projection(arma::mat& iterate)\n+{\n+  // Projection.\n+  arma::vec eigval;\n+  arma::mat eigvec;\n+\n+  arma::eig_sym(eigval, eigvec, iterate);\n+\n+  arma::uvec ind = arma::find(eigval > 0);\n+  arma::mat diagEigVal = arma::diagmat(eigval);\n+  iterate = eigvec.cols(ind) * diagEigVal.submat(ind, ind) *\n+      arma::trans(eigvec.cols(ind));\n+}\n+\n+//! Evaluate cost over whole dataset.\n+template<typename MetricType>\n+double LMNNFunction<MetricType>::Evaluate(const arma::mat& coordinates)\n+{\n+  // Hack\n+  arma::mat& iterate = const_cast<arma::mat&>(coordinates);\n+  // Apply projection.\n+  if (arma::accu(iterate == initialPoint) != initialPoint.n_elem)\n+    Projection(iterate);\n+\n+  double cost = 0;\n+\n+  // Apply metric over dataset.\n+  transformedDataset = coordinates * dataset;\n+\n+  // Re-calculate impostors on transformed dataset.\n+  Constraints constraint(transformedDataset, labels, k);\n+  constraint.Impostors(impostors);\n+\n+  for (size_t i = 0; i < dataset.n_cols; i++)\n+  {\n+    for (size_t j = 0; j < k ; j++)\n+    {\n+      // Calculate cost due to distance between target neighbors & data point.\n+      double eval = metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(targetNeighbors(j, i)));\n+      cost += (1 - regularization) * eval;\n+    }\n+\n+    for (int j = k - 1; j >= 0; j--)\n+    {\n+      // Bound constraints to avoid uneccesary computation.\n+      for (size_t l = 0, bp = k; l < bp ; l++)\n+      {\n+        // Calculate cost due to data point, target neighbors, impostors\n+        // triplets.\n+        double eval = metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(targetNeighbors(j, i))) -\n+                      metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(impostors(l, i)));\n+\n+        // Check bounding condition.\n+        if (eval < -1)\n+        {\n+          // update bound.\n+          bp = l;\n+          break;\n+        }\n+\n+        cost += regularization * (1 + eval);\n+      }\n+    }\n+  }\n+\n+  return cost;\n+};\n+\n+//! Calculate cost over batches.\n+template<typename MetricType>\n+double LMNNFunction<MetricType>::Evaluate(const arma::mat& coordinates,\n+                                          const size_t begin,\n+                                          const size_t batchSize)\n+{\n+  // Hack\n+  arma::mat& iterate = const_cast<arma::mat&>(coordinates);\n+  // Apply projection.\n+  if (arma::accu(iterate == initialPoint) != initialPoint.n_elem)\n+    Projection(iterate);\n+\n+  double cost = 0;\n+\n+  // Apply metric over dataset.\n+  transformedDataset = coordinates * dataset;\n+\n+  Constraints constraint(transformedDataset, labels, k);\n+  constraint.Impostors(impostors, begin, batchSize);\n+\n+  for (size_t i = begin; i < begin + batchSize; i++)\n+  {\n+    for (size_t j = 0; j < k ; j++)\n+    {\n+      // Calculate cost due to distance between target neighbors & data point.\n+      double eval = metric.Evaluate(transformedDataset.col(i),\n+                        transformedDataset.col(targetNeighbors(j, i)));\n+      cost += (1 - regularization) * eval;\n+    }\n+\n+    for (int j = k - 1; j >= 0; j--)\n+    {\n+      // Bound constraints to avoid uneccesary computation.\n+      for (size_t l = 0, bp = k; l < bp ; l++)\n+      {\n+        // Calculate cost due to data point, target neighbors, impostors\n+        // triplets.\n+        double eval = metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(targetNeighbors(j, i))) -\n+                      metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(impostors(l, i)));\n+\n+        // Check bounding condition.\n+        if (eval < -1)\n+        {\n+          // update bound.\n+          bp = l;\n+          break;\n+        }\n+\n+        cost += regularization * (1 + eval);\n+      }\n+    }\n+  }\n+\n+  return cost;\n+}\n+\n+//! Compute gradient over whole dataset.\n+template<typename MetricType>\n+template<typename GradType>\n+void LMNNFunction<MetricType>::Gradient(const arma::mat& /* coordinates */,\n+                                        GradType& gradient)\n+{\n+  gradient.zeros(dataset.n_rows, dataset.n_rows);\n+\n+  arma::mat cij = arma::zeros(dataset.n_rows, dataset.n_rows);\n+  arma::mat cil = arma::zeros(dataset.n_rows, dataset.n_rows);\n+\n+  for (size_t i = 0; i < dataset.n_cols; i++)\n+  {\n+    for (size_t j = 0; j < k ; j++)\n+    {\n+      // Calculate gradient due to target neighbors.\n+      arma::vec diff = dataset.col(i) - dataset.col(targetNeighbors(j, i));\n+      cij += diff * arma::trans(diff);\n+    }\n+\n+    for (int j = k - 1; j >= 0; j--)\n+    {\n+      // Bound constraints to avoid uneccesary computation.\n+      for (size_t l = 0, bp = k; l < bp ; l++)\n+      {\n+        // Calculate gradient due to triplets.\n+        double eval = metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(targetNeighbors(j, i))) -\n+                      metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(impostors(l, i)));\n+\n+        // Check bounding condition.\n+        if (eval < -1)\n+        {\n+          // update bound.\n+          bp = l;\n+          break;\n+        }\n+\n+        arma::vec diff = dataset.col(i) - dataset.col(targetNeighbors(j, i));\n+        cil += diff * arma::trans(diff);\n+\n+        diff = dataset.col(i) - dataset.col(impostors(l, i));\n+        cil -= diff * arma::trans(diff);\n+      }\n+    }\n+  }\n+\n+  gradient = (1 - regularization) * cij + regularization * cil;\n+}\n+\n+//! Compute gradient over a batch of data points.\n+template<typename MetricType>\n+template<typename GradType>\n+void LMNNFunction<MetricType>::Gradient(const arma::mat& /* coordinates */,\n+                                        const size_t begin,\n+                                        GradType& gradient,\n+                                        const size_t batchSize)\n+{\n+  gradient.zeros(dataset.n_rows, dataset.n_rows);\n+\n+  arma::mat cij = arma::zeros(dataset.n_rows, dataset.n_rows);\n+  arma::mat cil = arma::zeros(dataset.n_rows, dataset.n_rows);\n+\n+  for (size_t i = begin; i < begin + batchSize; i++)\n+  {\n+    for (size_t j = 0; j < k ; j++)\n+    {\n+      // Calculate gradient due to target neighbors.\n+      arma::vec diff = dataset.col(i) - dataset.col(targetNeighbors(j, i));\n+      cij += diff * arma::trans(diff);\n+    }\n+\n+    for (int j = k - 1; j >= 0; j--)\n+    {\n+      // Bound constraints to avoid uneccesary computation.\n+      for (size_t l = 0, bp = k; l < bp ; l++)\n+      {\n+        // Calculate gradient due to triplets.\n+        double eval = metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(targetNeighbors(j, i))) -\n+                      metric.Evaluate(transformedDataset.col(i),\n+                          transformedDataset.col(impostors(l, i)));\n+\n+        // Check bounding condition.\n+        if (eval < -1)\n+        {\n+          // update bound.\n+          bp = l;\n+          break;\n+        }\n+\n+        arma::vec diff = dataset.col(i) - dataset.col(targetNeighbors(j, i));\n+        cil += diff * arma::trans(diff);","path":"src/mlpack/methods/lmnn/lmnn_function_impl.hpp","position":211,"original_position":289,"commit_id":"824b0294ab9e7ccd205dc7f7000e0617d3e22a7e","original_commit_id":"8ae9745163e87d60627b92d7bbe8ecb174a04ef5","user":{"login":"rcurtin","id":1845039,"node_id":"MDQ6VXNlcjE4NDUwMzk=","avatar_url":"https://avatars0.githubusercontent.com/u/1845039?v=4","gravatar_id":"","url":"https://api.github.com/users/rcurtin","html_url":"https://github.com/rcurtin","followers_url":"https://api.github.com/users/rcurtin/followers","following_url":"https://api.github.com/users/rcurtin/following{/other_user}","gists_url":"https://api.github.com/users/rcurtin/gists{/gist_id}","starred_url":"https://api.github.com/users/rcurtin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rcurtin/subscriptions","organizations_url":"https://api.github.com/users/rcurtin/orgs","repos_url":"https://api.github.com/users/rcurtin/repos","events_url":"https://api.github.com/users/rcurtin/events{/privacy}","received_events_url":"https://api.github.com/users/rcurtin/received_events","type":"User","site_admin":false},"body":"I took a look and I added some numeric gradient checker tests like we do for the ANN layers, and everything seemed fine:\r\n\r\n```\r\ndiff --git a/src/mlpack/tests/lmnn_test.cpp b/src/mlpack/tests/lmnn_test.cpp\r\nindex 43020988a..f021a0595 100644\r\n--- a/src/mlpack/tests/lmnn_test.cpp\r\n+++ b/src/mlpack/tests/lmnn_test.cpp\r\n@@ -370,4 +370,113 @@ BOOST_AUTO_TEST_CASE(LMNNLBFGSSimpleDataset)\r\n   BOOST_REQUIRE_LT(finalObj, initObj);\r\n }\r\n \r\n+// Simple numerical gradient checker.\r\n+template<class FunctionType>\r\n+double CheckGradient(FunctionType& function,\r\n+                     arma::mat& coordinates,\r\n+                     const double eps = 1e-7)\r\n+{\r\n+  // Get gradients for the current parameters.\r\n+  arma::mat orgGradient, gradient, estGradient;\r\n+  function.Gradient(coordinates, orgGradient);\r\n+\r\n+  estGradient = arma::zeros(orgGradient.n_rows, orgGradient.n_cols);\r\n+\r\n+  // Compute numeric approximations to gradient.\r\n+  for (size_t i = 0; i < orgGradient.n_elem; ++i)\r\n+  {\r\n+    double tmp = coordinates(i);\r\n+\r\n+    // Perturb parameter with a positive constant and get costs.\r\n+    coordinates(i) += eps;\r\n+    double costPlus = function.Evaluate(coordinates);\r\n+\r\n+    // Perturb parameter with a negative constant and get costs.\r\n+    coordinates(i) -= (2 * eps);\r\n+    double costMinus = function.Evaluate(coordinates);\r\n+\r\n+    // Restore the parameter value.\r\n+    coordinates(i) = tmp;\r\n+\r\n+    // Compute numerical gradients using the costs calculated above.\r\n+    estGradient(i) = (costPlus - costMinus) / (2 * eps);\r\n+  }\r\n+\r\n+  // Estimate error of gradient.\r\n+  return arma::norm(orgGradient - estGradient) /\r\n+      arma::norm(orgGradient + estGradient);\r\n+}\r\n+\r\n+BOOST_AUTO_TEST_CASE(LMNNFunctionGradientTest)\r\n+{\r\n+  // Useful but simple dataset with six points and two classes.\r\n+  arma::mat dataset        = \"-0.1 -0.1 -0.1  0.1  0.1  0.1;\"\r\n+                             \" 1.0  0.0 -1.0  1.0  0.0 -1.0 \";\r\n+  arma::Row<size_t> labels = \" 0    0    0    1    1    1   \";\r\n+\r\n+  LMNNFunction<> lmnnfn(dataset, labels, 1, 0.6);\r\n+\r\n+  // 10 trials with random positions.\r\n+  for (size_t i = 0; i < 10; ++i)\r\n+  {\r\n+    arma::mat coordinates(2, 2, arma::fill::randu);\r\n+\r\n+    CheckGradient(lmnnfn, coordinates);\r\n+  }\r\n+}\r\n+\r\n+BOOST_AUTO_TEST_CASE(LMNNFunctionGradientTest2)\r\n+{\r\n+  // Useful but simple dataset with six points and two classes.\r\n+  arma::mat dataset        = \"-0.1 -0.1 -0.1  0.1  0.1  0.1;\"\r\n+                             \" 1.0  0.0 -1.0  1.0  0.0 -1.0 \";\r\n+  arma::Row<size_t> labels = \" 0    0    0    1    1    1   \";\r\n+\r\n+  LMNNFunction<> lmnnfn(dataset, labels, 1, 0.6);\r\n+\r\n+  // 10 trials with random positions.\r\n+  for (size_t i = 0; i < 10; ++i)\r\n+  {\r\n+    arma::mat coordinates(2, 2, arma::fill::randn);\r\n+\r\n+    CheckGradient(lmnnfn, coordinates);\r\n+  }\r\n+}\r\n+\r\n+BOOST_AUTO_TEST_CASE(LMNNFunctionGradientTest3)\r\n+{\r\n+  arma::mat dataset;\r\n+  arma::Row<size_t> labels;\r\n+  data::Load(\"iris.csv\", dataset);\r\n+  data::Load(\"iris_labels.txt\", labels);\r\n+\r\n+  LMNNFunction<> lmnnfn(dataset, labels, 1, 0.6);\r\n+\r\n+  // 10 trials with random positions.\r\n+  for (size_t i = 0; i < 10; ++i)\r\n+  {\r\n+    arma::mat coordinates(2, 2, arma::fill::randn);\r\n+\r\n+    CheckGradient(lmnnfn, coordinates);\r\n+  }\r\n+}\r\n+\r\n+BOOST_AUTO_TEST_CASE(LMNNFunctionGradientTest4)\r\n+{\r\n+  arma::mat dataset;\r\n+  arma::Row<size_t> labels;\r\n+  data::Load(\"iris.csv\", dataset);\r\n+  data::Load(\"iris_labels.txt\", labels);\r\n+\r\n+  LMNNFunction<> lmnnfn(dataset, labels, 1, 0.6);\r\n+\r\n+  // 10 trials with random positions.\r\n+  for (size_t i = 0; i < 10; ++i)\r\n+  {\r\n+    arma::mat coordinates(2, 2, arma::fill::randu);\r\n+\r\n+    CheckGradient(lmnnfn, coordinates);\r\n+  }\r\n+}\r\n+\r\n BOOST_AUTO_TEST_SUITE_END();\r\n```\r\n\r\n(You could add that if you like.)\r\n\r\nSo it seems that nothing is wrong.  For the observations:\r\n\r\n  1. This is expected, the step size for SGD has to be tuned.\r\n  2. This may happen depending on the loss surface.\r\n  3. This one concerns me a little bit more, but what is the dataset and parameters you are using?\r\n\r\nI tried using the `mlpack_lmnn` program and added some bits that would compute the accuracy before and afterwards.  It is much faster when compiled without debugging symbols; the iris dataset with k=3 and SGD with default parameters takes about half a second on my machine.  But the dataset is fairly small, so usually the accuracy increase is pretty marginal (i.e., 96 -> 96.7%, etc.).\r\n\r\nSo I think it may be worth finding some larger datasets to try on, and seeing how it does there.  But it seems to me that the implementation is correct, based on the tests and experiments I did.  Maybe with other datasets it behaves differently---I am not sure.","created_at":"2018-06-05T18:51:50Z","updated_at":"2018-06-05T18:51:51Z","html_url":"https://github.com/mlpack/mlpack/pull/1407#discussion_r193182469","pull_request_url":"https://api.github.com/repos/mlpack/mlpack/pulls/1407","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/comments/193182469"},"html":{"href":"https://github.com/mlpack/mlpack/pull/1407#discussion_r193182469"},"pull_request":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/1407"}},"in_reply_to_id":192758887},"pull_request":{"url":"https://api.github.com/repos/mlpack/mlpack/pulls/1407","id":189245318,"node_id":"MDExOlB1bGxSZXF1ZXN0MTg5MjQ1MzE4","html_url":"https://github.com/mlpack/mlpack/pull/1407","diff_url":"https://github.com/mlpack/mlpack/pull/1407.diff","patch_url":"https://github.com/mlpack/mlpack/pull/1407.patch","issue_url":"https://api.github.com/repos/mlpack/mlpack/issues/1407","number":1407,"state":"open","locked":false,"title":"[WIP] LMNN distance learning","user":{"login":"manish7294","id":17105412,"node_id":"MDQ6VXNlcjE3MTA1NDEy","avatar_url":"https://avatars0.githubusercontent.com/u/17105412?v=4","gravatar_id":"","url":"https://api.github.com/users/manish7294","html_url":"https://github.com/manish7294","followers_url":"https://api.github.com/users/manish7294/followers","following_url":"https://api.github.com/users/manish7294/following{/other_user}","gists_url":"https://api.github.com/users/manish7294/gists{/gist_id}","starred_url":"https://api.github.com/users/manish7294/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manish7294/subscriptions","organizations_url":"https://api.github.com/users/manish7294/orgs","repos_url":"https://api.github.com/users/manish7294/repos","events_url":"https://api.github.com/users/manish7294/events{/privacy}","received_events_url":"https://api.github.com/users/manish7294/received_events","type":"User","site_admin":false},"body":"Currently, I am pushing a rough implementation of LMNN. A lot of things will be updated within this PR including algorithms, tests, comments, etc.\r\n\r\n","created_at":"2018-05-20T18:12:17Z","updated_at":"2018-06-05T18:51:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"57548fceb803973c7b2a1e818dd96e07c95776bb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/mlpack/mlpack/pulls/1407/commits","review_comments_url":"https://api.github.com/repos/mlpack/mlpack/pulls/1407/comments","review_comment_url":"https://api.github.com/repos/mlpack/mlpack/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mlpack/mlpack/issues/1407/comments","statuses_url":"https://api.github.com/repos/mlpack/mlpack/statuses/824b0294ab9e7ccd205dc7f7000e0617d3e22a7e","head":{"label":"manish7294:lmnn","ref":"lmnn","sha":"824b0294ab9e7ccd205dc7f7000e0617d3e22a7e","user":{"login":"manish7294","id":17105412,"node_id":"MDQ6VXNlcjE3MTA1NDEy","avatar_url":"https://avatars0.githubusercontent.com/u/17105412?v=4","gravatar_id":"","url":"https://api.github.com/users/manish7294","html_url":"https://github.com/manish7294","followers_url":"https://api.github.com/users/manish7294/followers","following_url":"https://api.github.com/users/manish7294/following{/other_user}","gists_url":"https://api.github.com/users/manish7294/gists{/gist_id}","starred_url":"https://api.github.com/users/manish7294/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manish7294/subscriptions","organizations_url":"https://api.github.com/users/manish7294/orgs","repos_url":"https://api.github.com/users/manish7294/repos","events_url":"https://api.github.com/users/manish7294/events{/privacy}","received_events_url":"https://api.github.com/users/manish7294/received_events","type":"User","site_admin":false},"repo":{"id":117234183,"node_id":"MDEwOlJlcG9zaXRvcnkxMTcyMzQxODM=","name":"mlpack","full_name":"manish7294/mlpack","owner":{"login":"manish7294","id":17105412,"node_id":"MDQ6VXNlcjE3MTA1NDEy","avatar_url":"https://avatars0.githubusercontent.com/u/17105412?v=4","gravatar_id":"","url":"https://api.github.com/users/manish7294","html_url":"https://github.com/manish7294","followers_url":"https://api.github.com/users/manish7294/followers","following_url":"https://api.github.com/users/manish7294/following{/other_user}","gists_url":"https://api.github.com/users/manish7294/gists{/gist_id}","starred_url":"https://api.github.com/users/manish7294/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manish7294/subscriptions","organizations_url":"https://api.github.com/users/manish7294/orgs","repos_url":"https://api.github.com/users/manish7294/repos","events_url":"https://api.github.com/users/manish7294/events{/privacy}","received_events_url":"https://api.github.com/users/manish7294/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/manish7294/mlpack","description":"mlpack: a scalable C++ machine learning library -- ","fork":true,"url":"https://api.github.com/repos/manish7294/mlpack","forks_url":"https://api.github.com/repos/manish7294/mlpack/forks","keys_url":"https://api.github.com/repos/manish7294/mlpack/keys{/key_id}","collaborators_url":"https://api.github.com/repos/manish7294/mlpack/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/manish7294/mlpack/teams","hooks_url":"https://api.github.com/repos/manish7294/mlpack/hooks","issue_events_url":"https://api.github.com/repos/manish7294/mlpack/issues/events{/number}","events_url":"https://api.github.com/repos/manish7294/mlpack/events","assignees_url":"https://api.github.com/repos/manish7294/mlpack/assignees{/user}","branches_url":"https://api.github.com/repos/manish7294/mlpack/branches{/branch}","tags_url":"https://api.github.com/repos/manish7294/mlpack/tags","blobs_url":"https://api.github.com/repos/manish7294/mlpack/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/manish7294/mlpack/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/manish7294/mlpack/git/refs{/sha}","trees_url":"https://api.github.com/repos/manish7294/mlpack/git/trees{/sha}","statuses_url":"https://api.github.com/repos/manish7294/mlpack/statuses/{sha}","languages_url":"https://api.github.com/repos/manish7294/mlpack/languages","stargazers_url":"https://api.github.com/repos/manish7294/mlpack/stargazers","contributors_url":"https://api.github.com/repos/manish7294/mlpack/contributors","subscribers_url":"https://api.github.com/repos/manish7294/mlpack/subscribers","subscription_url":"https://api.github.com/repos/manish7294/mlpack/subscription","commits_url":"https://api.github.com/repos/manish7294/mlpack/commits{/sha}","git_commits_url":"https://api.github.com/repos/manish7294/mlpack/git/commits{/sha}","comments_url":"https://api.github.com/repos/manish7294/mlpack/comments{/number}","issue_comment_url":"https://api.github.com/repos/manish7294/mlpack/issues/comments{/number}","contents_url":"https://api.github.com/repos/manish7294/mlpack/contents/{+path}","compare_url":"https://api.github.com/repos/manish7294/mlpack/compare/{base}...{head}","merges_url":"https://api.github.com/repos/manish7294/mlpack/merges","archive_url":"https://api.github.com/repos/manish7294/mlpack/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/manish7294/mlpack/downloads","issues_url":"https://api.github.com/repos/manish7294/mlpack/issues{/number}","pulls_url":"https://api.github.com/repos/manish7294/mlpack/pulls{/number}","milestones_url":"https://api.github.com/repos/manish7294/mlpack/milestones{/number}","notifications_url":"https://api.github.com/repos/manish7294/mlpack/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/manish7294/mlpack/labels{/name}","releases_url":"https://api.github.com/repos/manish7294/mlpack/releases{/id}","deployments_url":"https://api.github.com/repos/manish7294/mlpack/deployments","created_at":"2018-01-12T11:38:29Z","updated_at":"2018-04-29T01:58:33Z","pushed_at":"2018-06-05T15:52:38Z","git_url":"git://github.com/manish7294/mlpack.git","ssh_url":"git@github.com:manish7294/mlpack.git","clone_url":"https://github.com/manish7294/mlpack.git","svn_url":"https://github.com/manish7294/mlpack","homepage":"http://www.mlpack.org/","size":243409,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mlpack:master","ref":"master","sha":"095f784a30742ff64f4616c362475d6c8ec8ea15","user":{"login":"mlpack","id":10216045,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMjE2MDQ1","avatar_url":"https://avatars0.githubusercontent.com/u/10216045?v=4","gravatar_id":"","url":"https://api.github.com/users/mlpack","html_url":"https://github.com/mlpack","followers_url":"https://api.github.com/users/mlpack/followers","following_url":"https://api.github.com/users/mlpack/following{/other_user}","gists_url":"https://api.github.com/users/mlpack/gists{/gist_id}","starred_url":"https://api.github.com/users/mlpack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlpack/subscriptions","organizations_url":"https://api.github.com/users/mlpack/orgs","repos_url":"https://api.github.com/users/mlpack/repos","events_url":"https://api.github.com/users/mlpack/events{/privacy}","received_events_url":"https://api.github.com/users/mlpack/received_events","type":"Organization","site_admin":false},"repo":{"id":28149409,"node_id":"MDEwOlJlcG9zaXRvcnkyODE0OTQwOQ==","name":"mlpack","full_name":"mlpack/mlpack","owner":{"login":"mlpack","id":10216045,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwMjE2MDQ1","avatar_url":"https://avatars0.githubusercontent.com/u/10216045?v=4","gravatar_id":"","url":"https://api.github.com/users/mlpack","html_url":"https://github.com/mlpack","followers_url":"https://api.github.com/users/mlpack/followers","following_url":"https://api.github.com/users/mlpack/following{/other_user}","gists_url":"https://api.github.com/users/mlpack/gists{/gist_id}","starred_url":"https://api.github.com/users/mlpack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlpack/subscriptions","organizations_url":"https://api.github.com/users/mlpack/orgs","repos_url":"https://api.github.com/users/mlpack/repos","events_url":"https://api.github.com/users/mlpack/events{/privacy}","received_events_url":"https://api.github.com/users/mlpack/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mlpack/mlpack","description":"mlpack: a scalable C++ machine learning library -- ","fork":false,"url":"https://api.github.com/repos/mlpack/mlpack","forks_url":"https://api.github.com/repos/mlpack/mlpack/forks","keys_url":"https://api.github.com/repos/mlpack/mlpack/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mlpack/mlpack/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mlpack/mlpack/teams","hooks_url":"https://api.github.com/repos/mlpack/mlpack/hooks","issue_events_url":"https://api.github.com/repos/mlpack/mlpack/issues/events{/number}","events_url":"https://api.github.com/repos/mlpack/mlpack/events","assignees_url":"https://api.github.com/repos/mlpack/mlpack/assignees{/user}","branches_url":"https://api.github.com/repos/mlpack/mlpack/branches{/branch}","tags_url":"https://api.github.com/repos/mlpack/mlpack/tags","blobs_url":"https://api.github.com/repos/mlpack/mlpack/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mlpack/mlpack/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mlpack/mlpack/git/refs{/sha}","trees_url":"https://api.github.com/repos/mlpack/mlpack/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mlpack/mlpack/statuses/{sha}","languages_url":"https://api.github.com/repos/mlpack/mlpack/languages","stargazers_url":"https://api.github.com/repos/mlpack/mlpack/stargazers","contributors_url":"https://api.github.com/repos/mlpack/mlpack/contributors","subscribers_url":"https://api.github.com/repos/mlpack/mlpack/subscribers","subscription_url":"https://api.github.com/repos/mlpack/mlpack/subscription","commits_url":"https://api.github.com/repos/mlpack/mlpack/commits{/sha}","git_commits_url":"https://api.github.com/repos/mlpack/mlpack/git/commits{/sha}","comments_url":"https://api.github.com/repos/mlpack/mlpack/comments{/number}","issue_comment_url":"https://api.github.com/repos/mlpack/mlpack/issues/comments{/number}","contents_url":"https://api.github.com/repos/mlpack/mlpack/contents/{+path}","compare_url":"https://api.github.com/repos/mlpack/mlpack/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mlpack/mlpack/merges","archive_url":"https://api.github.com/repos/mlpack/mlpack/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mlpack/mlpack/downloads","issues_url":"https://api.github.com/repos/mlpack/mlpack/issues{/number}","pulls_url":"https://api.github.com/repos/mlpack/mlpack/pulls{/number}","milestones_url":"https://api.github.com/repos/mlpack/mlpack/milestones{/number}","notifications_url":"https://api.github.com/repos/mlpack/mlpack/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mlpack/mlpack/labels{/name}","releases_url":"https://api.github.com/repos/mlpack/mlpack/releases{/id}","deployments_url":"https://api.github.com/repos/mlpack/mlpack/deployments","created_at":"2014-12-17T18:16:59Z","updated_at":"2018-06-05T07:11:57Z","pushed_at":"2018-06-05T15:52:39Z","git_url":"git://github.com/mlpack/mlpack.git","ssh_url":"git@github.com:mlpack/mlpack.git","clone_url":"https://github.com/mlpack/mlpack.git","svn_url":"https://github.com/mlpack/mlpack","homepage":"http://www.mlpack.org/","size":243556,"stargazers_count":2221,"watchers_count":2221,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":813,"mirror_url":null,"archived":false,"open_issues_count":113,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":813,"open_issues":113,"watchers":2221,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/1407"},"html":{"href":"https://github.com/mlpack/mlpack/pull/1407"},"issue":{"href":"https://api.github.com/repos/mlpack/mlpack/issues/1407"},"comments":{"href":"https://api.github.com/repos/mlpack/mlpack/issues/1407/comments"},"review_comments":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/1407/comments"},"review_comment":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mlpack/mlpack/pulls/1407/commits"},"statuses":{"href":"https://api.github.com/repos/mlpack/mlpack/statuses/824b0294ab9e7ccd205dc7f7000e0617d3e22a7e"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"rcurtin"}}