Skip to content

Instantly share code, notes, and snippets.

@liuliu
Last active September 26, 2016 06:05
Show Gist options
  • Save liuliu/9117a0011a682ab231d3 to your computer and use it in GitHub Desktop.
Save liuliu/9117a0011a682ab231d3 to your computer and use it in GitHub Desktop.
k-mean for layer
gsl_rng_env_setup();
gsl_rng* rng = gsl_rng_alloc(gsl_rng_default);
sqlite3* db = 0;
int h[0x10000];
int kc[0x100];
float kmean[0x100];
uint16_t tbl[0x10000];
int i;
for (i = 0; i < 0x10000; i++)
tbl[i] = i;
float lut[0x10000];
int a[0x10000];
ccv_half_precision_to_float(tbl, lut, 0x10000);
if (SQLITE_OK == sqlite3_open(argv[1], &db))
{
sqlite3_stmt* layer_data_stmt = 0;
const char layer_data_qs[] =
"SELECT layer, weight, bias, half_precision FROM layer_data;";
if (SQLITE_OK == sqlite3_prepare_v2(db, layer_data_qs, sizeof(layer_data_qs), &layer_data_stmt, 0))
{
while (sqlite3_step(layer_data_stmt) == SQLITE_ROW)
{
printf("layer %d\n", sqlite3_column_int(layer_data_stmt, 0));
if (sqlite3_column_int(layer_data_stmt, 0) < 10)
continue;
int half_precision = sqlite3_column_int(layer_data_stmt, 3);
memset(h, 0, sizeof(h));
int wnum = sqlite3_column_bytes(layer_data_stmt, 1) / (half_precision ? sizeof(uint16_t) : sizeof(float));
int bnum = sqlite3_column_bytes(layer_data_stmt, 2) / (half_precision ? sizeof(uint16_t) : sizeof(float));
const uint16_t* w = sqlite3_column_blob(layer_data_stmt, 1);
const uint16_t* bias = sqlite3_column_blob(layer_data_stmt, 2);
int i;
for (i = 0; i < wnum; i++)
++h[w[i]];
for (i = 0; i < bnum; i++)
++h[bias[i]];
for (i = 0; i < 0x10000; i++)
if (h[i] > 0)
a[i] = gsl_rng_uniform_int(rng, 0x100);
else
a[i] = 0;
int t, k;
for (t = 0; t < 10000; t++)
{
memset(kc, 0, sizeof(kc));
memset(kmean, 0, sizeof(kmean));
for (i = 0; i < 0x10000; i++)
if (h[i] > 0)
{
kmean[a[i]] += lut[i] * h[i];
kc[a[i]] += h[i];
}
for (i = 0; i < 0x100; i++)
kmean[i] = kmean[i] / kc[i];
int change = 0;
for (i = 0; i < 0x10000; i++)
if (h[i] > 0)
{
int j = 0;
for (k = 1; k < 0x100; k++)
if (fabs(lut[i] - kmean[k]) < fabs(lut[i] - kmean[j]))
j = k;
if (a[i] != j)
change = 1;
a[i] = j;
}
if (!change)
break;
}
union {
float f;
int i;
} v;
for (i = 0; i < 0x100; i++)
{
v.f = kmean[i];
printf("%d %d\n", i, v.i);
}
}
}
}
gsl_rng_free(rng);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment