Add features and labels view - #4352
Conversation
|
|
||
| CFeatures* CFeatures::view(const SGVector<index_t>& subset) | ||
| { | ||
| auto feats_view = this->duplicate(); |
There was a problem hiding this comment.
i would prefer a copy ctor here
There was a problem hiding this comment.
this is a virtual function that calls copy ctor of subclasses
There was a problem hiding this comment.
ah sorry I see now, totally justified!
| return feats_view; | ||
| } | ||
|
|
||
| CFeatures* CFeatures::view(const std::vector<index_t>& subset) |
There was a problem hiding this comment.
this doesnt belong into CFeatures imo, this is conversion code between std::vector and SGVector and therefore should sit in SGVector
features->view(SGVector<float64_t>(my_std_vector))
There was a problem hiding this comment.
or even done implicitly (if possible)
|
|
||
| CLabels* CBinaryLabels::duplicate() const | ||
| { | ||
| return new CBinaryLabels(*this); |
There was a problem hiding this comment.
why have this method why not just use the copy ctor?
| { | ||
| auto labels_view = this->duplicate(); | ||
|
|
||
| auto sg_subset = SGVector<index_t>(subset.size()); |
| // apply subset | ||
| if (m_subset_frac!=1.0) | ||
| apply_subset(feats,interf); | ||
| const auto result = get_subset(feats, interf); |
There was a problem hiding this comment.
why all these changes? shouldnt we focus on the view first?
There was a problem hiding this comment.
this is taken from michele's pr, we need small refactor on this to deploy views
There was a problem hiding this comment.
ok,
I technically would prefer first adding the view and then have a second Pr to deploy it.
But I think others see that differently, so ok leave it in :)
| CRegressionLabels* inter_f, CLabels* labs) | ||
| { | ||
| REQUIRE(m_labels,"training labels not set!\n") | ||
| SGVector<float64_t> labels=(dynamic_cast<CDenseLabels*>(m_labels))->get_labels(); |
There was a problem hiding this comment.
pls avoid such whitespace changes in PRs.
They should be in a sep PR. It just pollutes the diff (i.e. hard to review, takes longer)
| } | ||
|
|
||
| void CStochasticGBMachine::apply_subset(CDenseFeatures<float64_t>* f, CLabels* interf) | ||
| std::tuple<Some<CDenseFeatures<float64_t>>, Some<CRegressionLabels>, |
There was a problem hiding this comment.
can you explain the reasonaing here?
There was a problem hiding this comment.
since view create a new instance, using smart pointers prevent ref/unref
There was a problem hiding this comment.
doesnt this create the same problem with Some?
There was a problem hiding this comment.
actually no, this function is only used internally, so we know the static type of return value based on types of args
| lab[4]=0; | ||
|
|
||
| CDenseFeatures<float64_t>* feats=new CDenseFeatures<float64_t>(data); | ||
| auto feats = some<CDenseFeatures<float64_t>>(data); |
There was a problem hiding this comment.
again, I would prefer those changes to happen in a separate minimal PR
| return feats_view; | ||
| } | ||
|
|
||
| CFeatures* CFeatures::view(const std::vector<index_t>& subset) |
There was a problem hiding this comment.
can you explain ?
We need to use the base class interface in things like xvalidation ..
There was a problem hiding this comment.
ah sorry nevermind I didnt see the arugment was the std
| CFeatures* CFeatures::view(const SGVector<index_t>& subset) | ||
| { | ||
| auto feats_view = this->duplicate(); | ||
| feats_view->add_subset(subset.clone()); |
There was a problem hiding this comment.
i wonder, do we want to clone the subset?
I think actually we shouldnt
And also I think that add_subset should accept a const vector
There was a problem hiding this comment.
but maybe you have a different opinion?
There was a problem hiding this comment.
agree, we don't need clone here.
add_subset should accept a const vector, and we need to clone the vector in ctor of CSubset
| ASSERT_EQ(labels_subset->get_num_labels(), subset.vlen); | ||
| for (auto i : range(subset.vlen)) | ||
| { | ||
| EXPECT_EQ(labels_subset->get_int_label(i), labels_true[subset[i]]); |
There was a problem hiding this comment.
maybe we can actually systematically test all access methods of labels and features somehow?
I would also assert that the view's data pointer is the same as the original one (i.e. no copy happened)
There was a problem hiding this comment.
we don't have a way to test different features/labels types, and different access methods now.
and we can't check view's data pointer because that's a private member, calling get_labels will create a copy if subset is present
77a9f85 to
8711ea6
Compare
d1a175a to
ffb3fcc
Compare
a241ab1 to
dbfd69e
Compare
47a55bb to
83884f1
Compare
83884f1 to
f444cec
Compare
| static_assert( | ||
| std::is_base_of<CFeatures, T>::value || | ||
| std::is_base_of<CLabels, T>::value, | ||
| "Only CFeatures and CLabels are viewable."); |
There was a problem hiding this comment.
I am not a fan of error messages that contain things that might change in the future, i.e. a new class is made viewable.
I would just state: Class is not viewable. The compiler error will provide the T and also the static assert which will tell the caller what is viewable and what is not. Or?
| { | ||
|
|
||
| template <class T> | ||
| T* view(T* viewable, const SGVector<index_t>& subset) |
| { | ||
|
|
||
| template <class T> | ||
| T* view(T* viewable, const SGVector<index_t>& subset) |
There was a problem hiding this comment.
is this used anywhere?
How are we going to do this without multiple inheritance?
Maybe a mixin approach would be better, see IterativeMachine
There was a problem hiding this comment.
@karlnapf i'm not clear, could you explain the multiple inheritance problem?
currently we expect T to be either features or labels, but we can also use viewable mixin in features and labels
There was a problem hiding this comment.
@karlnapf you mean about the duplciate method or what exactly do you mean by multiple inheritance?
There was a problem hiding this comment.
I just realised that I had a mistake in my thinking. This is just a global templated function so all good, nevermind!
I like this idea of having the method with the static assert!
There was a problem hiding this comment.
k... note that needs extra love in case of SWIG interfaces... although it's a good question whether we actually wanna expose view mechanism for swig?
| REQUIRE(m_labels,"training labels not set!\n") | ||
| SGVector<float64_t> labels=(dynamic_cast<CDenseLabels*>(m_labels))->get_labels(); | ||
| SGVector<float64_t> labels = | ||
| (dynamic_cast<CDenseLabels*>(labs))->get_labels(); |
There was a problem hiding this comment.
since there's already a change here we could just port using as<CDenseLabels>
| SGVector<int32_t> subset(train_indices.data(),train_indices.size(),false); | ||
| data->add_subset(subset); | ||
| m_labels->add_subset(subset); | ||
| auto dense_labels = m_labels->as<CDenseLabels>(); |
There was a problem hiding this comment.
as agreed no need for this, drop it...
| { | ||
|
|
||
| template <class T> | ||
| T* view(T* viewable, const SGVector<index_t>& subset) |
There was a problem hiding this comment.
@karlnapf you mean about the duplciate method or what exactly do you mean by multiple inheritance?
| } | ||
|
|
||
| template <class T> | ||
| T* view(Some<T> viewable, const SGVector<index_t>& subset) |
There was a problem hiding this comment.
@karlnapf @vigsterkr maybe we can just return Some<T> here?
There was a problem hiding this comment.
Yes please! If you pass Some you should get Some
|
@vinx13 yep cool! this way the c++ code became much much cleaner! |
| * @return new viewable instance | ||
| */ | ||
| template <class T> | ||
| T* view(T* viewable, const SGVector<index_t>& subset) |
| * @return new viewable instance | ||
| */ | ||
| template <class T> | ||
| Some<T> view(Some<T> viewable, const SGVector<index_t>& subset) |
vigsterkr
left a comment
There was a problem hiding this comment.
rebase with latest develop and use override where necessary. this way the CIs wont fail :)
| */ | ||
| virtual ELabelType get_label_type() const; | ||
|
|
||
| virtual CLabels* duplicate() const; |
| * | ||
| * @return labels object | ||
| */ | ||
| virtual CLabels* duplicate() const |
c6ca257 to
9c75248
Compare
9c75248 to
ec57067
Compare
Continue #3970 , but features and labels view return raw pointer now instead of
Somebecause that will cause covariant type problem, andSomeis not available in SWIG