fix(kmeans): correct spherical centroid normalization (#654)
This commit is contained in:
parent
9ff5db33db
commit
d7a95d02be
|
|
@ -492,16 +492,15 @@ class NumericalKmeansContext {
|
|||
MatrixHelper::ReverseTranspose<uint32_t, BatchCount>(src, dim >> 2, dst);
|
||||
}
|
||||
|
||||
//! Compute Norm2
|
||||
template <typename ValueType, typename = typename std::enable_if<
|
||||
IsFloatingPoint<ValueType>::value>::type>
|
||||
//! Normalize with L2 norm for floating-point values, otherwise do nothing
|
||||
static void Norm2(ValueType *data, size_t dim, float *norm) {
|
||||
Normalizer<ValueType>::L2(data, dim, norm);
|
||||
}
|
||||
|
||||
//! Compute Norm2, for non-float do nothing
|
||||
static void Norm2(ValueType * /*data*/, size_t /*dim*/, float *norm) {
|
||||
*norm = 0.0f;
|
||||
if constexpr (IsFloatingPoint<ValueType>::value) {
|
||||
Normalizer<ValueType>::L2(data, dim, norm);
|
||||
} else {
|
||||
(void)data;
|
||||
(void)dim;
|
||||
*norm = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -843,16 +842,15 @@ class NumericalInnerProductKmeansContext {
|
|||
MatrixHelper::ReverseTranspose<uint32_t, BatchCount>(src, dim >> 2, dst);
|
||||
}
|
||||
|
||||
//! Compute Norm2
|
||||
template <typename ValueType, typename = typename std::enable_if<
|
||||
IsFloatingPoint<ValueType>::value>::type>
|
||||
//! Normalize with L2 norm for floating-point values, otherwise do nothing
|
||||
static void Norm2(ValueType *data, size_t dim, float *norm) {
|
||||
Normalizer<ValueType>::L2(data, dim, norm);
|
||||
}
|
||||
|
||||
//! Compute Norm2, for non-float do nothing
|
||||
static void Norm2(ValueType * /*data*/, size_t /*dim*/, float *norm) {
|
||||
*norm = 0.0f;
|
||||
if constexpr (IsFloatingPoint<ValueType>::value) {
|
||||
Normalizer<ValueType>::L2(data, dim, norm);
|
||||
} else {
|
||||
(void)data;
|
||||
(void)dim;
|
||||
*norm = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class LloydCluster {
|
|||
|
||||
if (spherical_) {
|
||||
for (size_t i = 0, n = centroids_.count(); i != n; ++i) {
|
||||
float norm;
|
||||
float norm = 0.0f;
|
||||
ContextType::Norm2(centroids_[i], centroids_.dimension(), &norm);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,6 +239,39 @@ TEST(NumericalKmeans, FP32_General_InnerProduct) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(NumericalInnerProductKmeansContext, NormalizeFloatingPointCentroid) {
|
||||
float centroid[] = {3.0f, 4.0f};
|
||||
float norm = 0.0f;
|
||||
|
||||
ailego::NumericalInnerProductKmeansContext<float>::Norm2(centroid, 2, &norm);
|
||||
|
||||
EXPECT_FLOAT_EQ(norm, 5.0f);
|
||||
EXPECT_FLOAT_EQ(centroid[0], 0.6f);
|
||||
EXPECT_FLOAT_EQ(centroid[1], 0.8f);
|
||||
}
|
||||
|
||||
TEST(NumericalKmeansContext, NormalizeFloatingPointCentroid) {
|
||||
float centroid[] = {3.0f, 4.0f};
|
||||
float norm = 0.0f;
|
||||
|
||||
ailego::NumericalKmeansContext<float>::Norm2(centroid, 2, &norm);
|
||||
|
||||
EXPECT_FLOAT_EQ(norm, 5.0f);
|
||||
EXPECT_FLOAT_EQ(centroid[0], 0.6f);
|
||||
EXPECT_FLOAT_EQ(centroid[1], 0.8f);
|
||||
}
|
||||
|
||||
TEST(NumericalKmeansContext, KeepIntegerCentroidUnchanged) {
|
||||
int8_t centroid[] = {3, 4};
|
||||
float norm = 1.0f;
|
||||
|
||||
ailego::NumericalKmeansContext<int8_t>::Norm2(centroid, 2, &norm);
|
||||
|
||||
EXPECT_FLOAT_EQ(norm, 0.0f);
|
||||
EXPECT_EQ(centroid[0], 3);
|
||||
EXPECT_EQ(centroid[1], 4);
|
||||
}
|
||||
|
||||
TEST(NumericalKmeans, FP16_General_InnerProduct) {
|
||||
const size_t DIMENSION = 20;
|
||||
const size_t K_VALUE = 20;
|
||||
|
|
|
|||
Loading…
Reference in New Issue