-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Use iterative machine mixin in AveragedPerceptron #4551
Conversation
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.
Hi
Thanks a lot for the PR! Much appreciated!
I made some initial comments. It probably needs a few more iterations or minor changes, @shubham808 will probably have more comments.
The tests fail because the class is not recognised by class list anymore. Check the formatting of the class definition of perceptron and make it like this here, then the error should go away (there is some python code that scans the codebase for all classes and it expects a certain formatting iirc
max_iter = 1000; | ||
learn_rate = 0.1; | ||
SG_ADD(&max_iter, "max_iter", "Maximum number of iterations.", ParameterProperties::HYPER); | ||
set_max_iter(1000); |
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.
yes this is better
good first pr :) |
@shubham808 consistency_training_tests has that test that makes sure that two models: one with max_iterations = 1 and the other stopped after an iteration, yield the same results. This isn't true here, since the one with max_iterations=1 has different weights because end_training() method is called after training is finished, which changes the weights to the final form (performs averaging). |
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.
See comments
int32_t max_iter; | ||
|
||
private: | ||
float64_t tmp_bias; |
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.
Could we maybe name those two a bit better?
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.
Current name is cached_bias
and cached_w
, which is still bad I think. I will think of something better.
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.
what about just saying what it is? w_averaged etc?
We had this issue before. I dont remember how we exactly solved it. A running average seems to work here and seems like a very good idea. Make sure to pick a numerically stable one (might require some googling). Could you add a way to update a mean vector/scalar in |
cached_w = SGVector<float64_t>(num_feat); | ||
// start with uniform w, bias=0, tmp_bias=0 | ||
bias = 0; | ||
cached_bias = 0; |
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.
actually this name is fine imo
} | ||
iter++; | ||
pb.print_progress(); | ||
linalg::update_mean(w, cached_w, num_prev_weights); |
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.
sweet, much nicer to read!
return std::string(XSTRING__(ptype)); \ | ||
} | ||
|
||
SG_PRIMITIVE_TYPE(bool, PT_BOOL); |
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.
@gf712 do we have a central map for these?
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.
all the supported types should go here
shogun/src/shogun/lib/sg_types.h
Line 41 in 801bdba
using sg_feature_types = Types< |
and all the any supported types are here
shogun/src/shogun/lib/type_case.h
Line 118 in 801bdba
SG_ADD_PRIMITIVE_TYPE(bool, TYPE::T_BOOL) |
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.
@gf712 DataType.h
seems to be obsolete, but I can't use sg_types
and type_case
yet since the class_list
script (which has the create
function) uses the old code.
Btw, the implementation of these two files is very interesting!
@@ -0,0 +1,164 @@ | |||
#ifndef __SG_OBJECT_ITERATOR_H__ |
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.
good idea moving this into a new file!
|
||
using namespace shogun; | ||
|
||
std::set<std::string> sg_linear_machines = {"Perceptron", "AveragedPerceptron", |
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.
ok! This is definitely better than before. I have a question: If a test fails, is it easy to see which class is the offender?
Filtering the tests obviously is not possible via this though. Compile time is an advantage to the typed version of this we had before (we define a bunch of types and then essentially template the test). This then allows for filtering. Maybe in a follow up PR, we can do something about that. I think the current blocker was that it is hard to find all subclasses automatically. However, if we simply define a type list (as you have done here with strings), that is also acceptable for now.
@gf712 might also be interesting for you
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.
It should be easy using SCOPED_TRACE
.
Hard coding the linear machines may not be so scaleable. Can't the class_list
script be extended to detect hierarchies?
Sorry I don't get your point about filtering, and why templated tests can be better.
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.
Cool add the scoping!
Yes we can do this extension, but for now the explicit list is fine.
Compiled types can be helpful but for now this is good!
machine_stop->train(features); | ||
|
||
machine_iters->set_labels(labels); | ||
machine_iters->put<int32_t>("max_iterations", max_iters); |
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.
there should be yet a typed setter for this or?
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.
since this helps to make the tests for reliable (no runtime error when setting things as here), we can keep the setter (even though it will be hidden from users 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.
I like this update! :) Thanks!
So two things.
- Can we somehow set the continue features in
IterativeMachine
? - a compiled test for every IterativeMachine might be easier to handle debugging wise. Something to look into? We can keep the runtime version for now
- See some minor inline comments
@theartful Nice clean up for the tests, CI error seems unrelated |
Unrelated, but for some reason the LibLinearRegression test on MacOS passed :"D |
Cool ci passed so this is almost good to go. I’ll do one more detailed read through later and then we can merge |
@theartful lets check for memory leaks of the new test and then this is good to go from my side 👍 |
#include <string> | ||
#include <shogun/base/class_list.h> | ||
|
||
using namespace shogun; |
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.
@theartful plz never do this in a header file...
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.
my bad didn't see it
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.
ouch! sorry for that
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.
namespace |
shouldn't it be namespace shogun?
* Add function to set features in iterative machine * Use iterative machine mixin in AveragedPerceptron * Add generic iterative machine test * Move m_continue_features assignment to IterativeMachine
@shubham808 This PR addresses the project 'inside the black box II' and issue #4488.
I still need to write some unit tests, but I would like to get confirmation that this is the right way, since I'm still new to this project.