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 SGVector instead of plain pointer in GMM #3859
Conversation
@MikeLing if you wanna insist on these changes then let's switch as well all the CMath methods and other SGVector/SGMatrix methods to linalg plz! :) lemme know if you need help there which one and how! |
Hi @vigsterkr , sure, please tell me more about that! But I'm not sure I could start to work on it right away, let me finish these issues on my hand first :) BTW, I just update this pr due to I found I forget to remove some debug statement in the pr :P |
@MikeLing i dont see the point of doing halfway things in this case. if you started this then plz do it properly if not then close this PR. the change of Malloc to SGVector is really not enough here... that can be done with a regex script automatically... |
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.
here are some examples where one could use linalg... but there's plenty more...
src/shogun/clustering/GMM.cpp
Outdated
SGVector<float64_t>::add(mean_sum, alpha.matrix[j*alpha.num_cols+i], v.vector, 1, mean_sum, v.vlen); | ||
SGVector<float64_t>::add( | ||
mean_sum.vector, alpha.matrix[j * alpha.num_cols + i], v.vector, | ||
1, mean_sum.vector, v.vlen); | ||
} | ||
|
||
for (int32_t j=0; j<num_dim; j++) | ||
mean_sum[j]/=alpha_sum; |
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.
this is bascially linalg::scale(mean, mean, 1/alpha_sum)
src/shogun/clustering/GMM.cpp
Outdated
cov_sum=SG_MALLOC(float64_t, 1); | ||
cov_sum[0]=0; | ||
cov_sum = SGMatrix<float64_t>(1, 1); | ||
cov_sum.zero(); |
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.
linalg::zero(cov_sum)
src/shogun/clustering/GMM.cpp
Outdated
} | ||
|
||
for (int32_t j=0; j<alpha.num_rows; j++) | ||
{ | ||
SGVector<float64_t> v=dotdata->get_computed_dot_feature_vector(j); | ||
SGVector<float64_t>::add(v.vector, 1, v.vector, -1, mean_sum, v.vlen); | ||
|
||
SGVector<float64_t>::add( |
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.
linalg::add
src/shogun/clustering/GMM.cpp
Outdated
case SPHERICAL: | ||
float64_t temp = 0; | ||
|
||
for (int32_t k = 0; k < num_dim; k++) |
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.
this is basically linalg::dot(v,v)
Once this is done (very nice initiative), let's re-design the Gaussians and mixture models a bit. I can help with that, let me know once you are ready with this stuff |
src/shogun/clustering/GMM.cpp
Outdated
} | ||
|
||
for (int32_t j=0; j<num_dim; j++) | ||
mean_sum[j]/=alpha_sum; | ||
linalg::scale(mean_sum, mean_sum, 1 / alpha_sum); |
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.
1.0/alpha_sum
src/shogun/clustering/GMM.cpp
Outdated
} | ||
|
||
for (int32_t j=0; j<alpha.num_rows; j++) | ||
{ | ||
SGVector<float64_t> v=dotdata->get_computed_dot_feature_vector(j); | ||
SGVector<float64_t>::add(v.vector, 1, v.vector, -1, mean_sum, v.vlen); | ||
mean_sum.display_vector(); |
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.
debug ;)
src/shogun/clustering/GMM.cpp
Outdated
|
||
linalg::add(v, mean_sum, v, float64_t(1), float64_t(-1)); | ||
mean_sum.display_vector(); |
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.
debug ;)
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 @vigsterkr, I misapprehend your comment. I thought you are saying we need to add more mathematic function in SGVector and SGMatrix :P Had update the pr, plz tell me if there are anything else to do in this pr. Thank you |
src/shogun/clustering/GMM.cpp
Outdated
cov_sum(0, k) += v.vector[k] * v.vector[k] * | ||
alpha.matrix[j * alpha.num_cols + i]; | ||
|
||
cov_sum.display_matrix(); |
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.
debug
src/shogun/clustering/GMM.cpp
Outdated
|
||
cov_sum(0, 0) += | ||
temp * alpha.matrix[j * alpha.num_cols + i]; | ||
cov_sum.display_matrix(); |
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.
debug
src/shogun/clustering/GMM.cpp
Outdated
} | ||
|
||
m_coefficients.vector[i]=alpha_sum; | ||
alpha_sum_sum+=alpha_sum; | ||
} | ||
|
||
for (int32_t i=0; i<alpha.num_cols; i++) | ||
m_coefficients.vector[i]/=alpha_sum_sum; | ||
linalg::scale(m_coefficients, m_coefficients, 1 / alpha_sum_sum); |
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.
1.0/alpha_sum_sum
src/shogun/clustering/GMM.cpp
Outdated
CblasRowMajor, num_dim, num_dim, | ||
alpha.matrix[j * alpha.num_cols + i], v.vector, 1, | ||
v.vector, 1, (double*)cov_sum.matrix, num_dim); | ||
cov_sum.display_matrix(); |
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.
debug
|
||
cov_sum[0]+=temp*alpha.matrix[j*alpha.num_cols+i]; | ||
break; | ||
cblas_dger( |
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.
is this the one and only function we use in GMM from LAPACK?
and this is the reason why we require LAPACK?
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.
no, this compute_eigenvectors https://github.com/shogun-toolbox/shogun/blob/develop/src/shogun/clustering/GMM.cpp#L600 also require LAPACK
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.
oooh
old linalg can take care of it: https://github.com/shogun-toolbox/shogun/blob/develop/src/shogun/mathematics/linalg/eigsolver/DirectEigenSolver.h
but ok it should be done if we have some time later.... not part of this pr
@MikeLing my only concern is that GMM is tested nowhere automatically only in a notebook :S |
mmm, do i need to add some unit test for it? Or we could test and merge it after micmn add unit test for GMM? |
@MikeLing i'm not aware of anybody planning to add unit test for GMM ;) |
@vigsterkr oh, I see what you mean. We do have meta test for GMM( integration_meta_cpp-clustering-gmm ) actually, but I'm not sure if that's good enough to test it. Let me test gmm on notebook anyway :) |
@MikeLing oh yeah that's should at least as well assure that we are still having the same output :))) |
@MikeLing ok lemme know when you've done with the notebook test as this seems to be ok so i'm gonna merge once you are done with double-checking.thnx |
@vigsterkr Hi, sorry for the late reply. So, first of all, I would say "yes, we are still having the same output for GMM." But, however, the GMM notebook may broken already. I send you some screenshots on irc already. (here is the output of develop branch |
@@ -267,7 +267,7 @@ float64_t CGaussian::compute_log_PDF(SGVector<float64_t> point) | |||
return -0.5 * answer; | |||
} | |||
|
|||
SGVector<float64_t> CGaussian::get_mean() | |||
SGVector<float64_t>& CGaussian::get_mean() |
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.
Why returning a reference?
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.
we need use linalg add function in https://github.com/shogun-toolbox/shogun/pull/3859/files#diff-b59cfc6c549dd52160d0ce73b6356b04R377
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.
How is it related? :)
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's not... there shouldn't be a need for doing this.
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.
mmm, but I got error message like
error: no matching function for call to 'add' if I don't return reference. More error message in here https://pastebin.mozilla.org/9025837
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 @vigsterkr and @lisitsyn , the linalg add need a reference rather than a value like add (SGVector< T > &a, SGVector< T > &b, SGVector< T > &result, T alpha=1, T beta=1)
, I just don't know how to make this
linalg::add( components[1]->get_mean(), components[2]->get_mean(), components[1]->get_mean(), alpha1, alpha2);
works if I don't return a reference in here. Maybe I'm asking a dumb question, but I just don't know what should I do to make it works :(
Thank 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.
What happens if you put the get_mean()
output into a local variable first? It is a bit nicer to read anyways
|
Hi @MikeLing |
0ab8441
to
9df2c13
Compare
Codecov Report
@@ Coverage Diff @@
## develop #3859 +/- ##
===========================================
+ Coverage 55.79% 55.82% +0.03%
===========================================
Files 1356 1356
Lines 94000 93987 -13
===========================================
+ Hits 52445 52466 +21
+ Misses 41555 41521 -34
Continue to review full report at Codecov.
|
@karlnapf ask review for this pr :) Thank you |
037a675
to
aa8b60d
Compare
Mmmh the unit test thing is quite concerning .... notebook checks:
|
@@ -275,8 +272,11 @@ float64_t CGMM::train_smem(int32_t max_iter, int32_t max_cand, float64_t min_cov | |||
counter++; | |||
} | |||
} | |||
CMath::qsort_backward_index(split_crit, split_ind, int32_t(m_components.size())); | |||
CMath::qsort_backward_index(merge_crit, merge_ind, int32_t(m_components.size()*(m_components.size()-1)/2)); | |||
CMath::qsort_backward_index( |
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.
can you please refactor these two methods as well?
src/shogun/clustering/GMM.cpp
Outdated
@@ -385,8 +374,10 @@ void CGMM::partial_em(int32_t comp1, int32_t comp2, int32_t comp3, float64_t min | |||
float64_t noise_mag=SGVector<float64_t>::twonorm(components[0]->get_mean().vector, dim_n)*0.1/ | |||
CMath::sqrt((float64_t)dim_n); | |||
|
|||
SGVector<float64_t>::add(components[1]->get_mean().vector, alpha1, components[1]->get_mean().vector, alpha2, | |||
components[2]->get_mean().vector, dim_n); | |||
SGVector<float64_t> temp_mean = components[2]->get_mean(); |
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.
auto please
src/shogun/clustering/GMM.cpp
Outdated
components[2]->get_mean().vector, dim_n); | ||
SGVector<float64_t> temp_mean = components[2]->get_mean(); | ||
SGVector<float64_t> temp_mean_result = components[1]->get_mean(); | ||
linalg::add(temp_mean_result, temp_mean, temp_mean_result, alpha1, alpha2); |
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.
doesnt linalg have an in-place add? That would be cleaner here
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.
mmm, what's the in-place add of linalg you mean?
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.
nevermind for now.
Let's move on with this. What is missing?
|
||
for (int32_t j=0; j<alpha.num_rows; j++) | ||
{ | ||
alpha_sum+=alpha.matrix[j*alpha.num_cols+i]; | ||
SGVector<float64_t> v=dotdata->get_computed_dot_feature_vector(j); | ||
SGVector<float64_t>::add(mean_sum, alpha.matrix[j*alpha.num_cols+i], v.vector, 1, mean_sum, v.vlen); | ||
linalg::add( |
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.
this seems to be a matrix product, and it would be better to use no loop here
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.
mmmm, I'm not sure why this doesn't work:
alpha_sum = alpha_sum_v[i];
SGMatrix<float64_t> v=dotdata->get_computed_dot_feature_matrix();
auto column_vector = SGVector<float64_t>(alpha.get_column_vector(i), alpha.num_rows, false);
linalg::matrix_prod(v, column_vector, mean_sum);
Maybe it's not about matrix product ? Or I misunderstand something here?
src/shogun/clustering/GMM.cpp
Outdated
|
||
break; | ||
case DIAG: | ||
for (int32_t k = 0; k < num_dim; k++) |
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.
matrix multiplication!
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.
alpha.matrix[j * alpha.num_cols + i]
is a element rather than a vector or matrix. So I think it's something like vector^{2}*R(R is a real number) rather than matrix multiplication. Does it make sense to u? :)
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 am generally OK here.
But we cannot merge this before we have at least a working integration test (with new random) that remains unchanged for the refactoring (we dont change any computation)
@karlnapf this has nothing to do with the new random. |
Ah ok. |
travis seems ok. |
@MikeLing can we please finish up this one by friday? what is missing is couple of matrix multiplications instead of using for loops... ping me if you need help, plz! just let's have this finally merged! |
d015011
to
eedc791
Compare
During I'm working on the global random removing, I found we have a lot of plain pointer in GMM. I thought maybe we want this pr, please feel free to close it if it's not. :)
Thank you