-
Notifications
You must be signed in to change notification settings - Fork 228
[WIP] Add verbose to NCA and MLKR #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Add verbose to NCA and MLKR #105
Conversation
…cation for classification and regression for regression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments, but overall I'm happy with this.
metric_learn/mlkr.py
Outdated
def _loss(self, flatA, X, y, dX): | ||
|
||
if self.n_iter_ == 0: | ||
if self.verbose: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd combine these into a single condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, done
metric_learn/mlkr.py
Outdated
cls_name = self.__class__.__name__ | ||
print('[{}]'.format(cls_name)) | ||
print('[{}] {}\n[{}] {}'.format(cls_name, header, cls_name, | ||
'-' * len(header))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Named format slots might make this easier to read. That is, like the "by name" examples here: https://docs.python.org/2/library/string.html#format-examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, done (except for the header field because there I thought keyword arguments would be more redundant than really helping reading , but tell me if you don't think so)
metric_learn/mlkr.py
Outdated
print('[{}] {}\n[{}] {}'.format(cls_name, header, cls_name, | ||
'-' * len(header))) | ||
|
||
t_funcall = time.time() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of the t_
prefix for times. How about start_time
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, done
I just noticed that the Conjugate Gradient method (used in I was thinking I could maybe instead print the cost function for each function evaluation instead of each iteration, for Or we could use Note: here is a thread that compares the two methods: https://scicomp.stackexchange.com/questions/507/bfgs-vs-conjugate-gradient-method |
The MLKR paper says this about the optimization problem, after briefly describing a gradient descent algorithm:
The initial MLKR implementation by @dsquareindia used a hand-rolled gradient descent, and I later converted this to use So in summary: if you think L_BFGS-B will work better, feel free to try it out! 👍 |
L-BFGS-B should also work well (maybe slightly better) at the cost of slightly higher memory. Maybe you can indeed give it a try, this would make it more consistent with NCA |
Allright, we can go for L-BFGS-B for now (it can easily be changed in the future) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. This slightly changes the interface to MLKR (remove epsilon
and change alpha
to tol
). If we want to ensure compatibility with existing code we could keep the name alpha
and show some deprecation warning for epsilon
. But maybe this is not so important. @perimosocordiae ?
Changing the underlying optimizer is a bit of a compatibility break, too, so I'm fine with making it explicit by changing the keyword arguments. |
# Conflicts: # metric_learn/mlkr.py # test/metric_learn_test.py
# Conflicts: # metric_learn/mlkr.py # metric_learn/nca.py
I just realized in fact |
From my understanding, |
Oh yes that's right |
I just realized that |
Makes sense indeed :-) But need to fix the travis failure |
Done |
Fixes #67.
This PR adds a verbose argument for
NCA
andMLKR
. Here is an example on a snippet.Returns: UPDATE: Edited after commit 8ca38b7 that correct the training time
The code mostly comes from scikit-learn's NCA PR (scikit-learn/scikit-learn#10058), and this verbose code in particular was taken mostly from scikit-learn's LMNN PR (scikit-learn/scikit-learn#8602)
TODO:
MLKR
(related to MLKR optimization algorithm does not work as expected regarding iterations #104)