init in {'gauss', 'identity', 'random'}
(X_train, ncodebooks, codebook_bits=8, niters=20,
initial_kmeans_iters=1, init='gauss', debug=False)
| 270 | # https://github.com/arbabenko/Quantizations/blob/master/opqCoding.py |
| 271 | @_memory.cache |
| 272 | def learn_opq(X_train, ncodebooks, codebook_bits=8, niters=20, |
| 273 | initial_kmeans_iters=1, init='gauss', debug=False): |
| 274 | """init in {'gauss', 'identity', 'random'}""" |
| 275 | |
| 276 | print "OPQ: Using init '{}'".format(init) |
| 277 | |
| 278 | t0 = time.time() |
| 279 | |
| 280 | X = X_train.astype(np.float32) |
| 281 | N, D = X.shape |
| 282 | ncentroids = int(2**codebook_bits) |
| 283 | subvect_len = D // ncodebooks |
| 284 | |
| 285 | assert D % subvect_len == 0 # equal number of dims for each codebook |
| 286 | |
| 287 | X_rotated, R = opq_initialize(X_train, ncodebooks=ncodebooks, init=init) |
| 288 | |
| 289 | # initialize codebooks by running kmeans on each rotated dim; this way, |
| 290 | # setting niters=0 corresponds to normal PQ |
| 291 | codebooks, assignments = learn_pq(X_rotated, ncentroids=ncentroids, |
| 292 | nsubvects=ncodebooks, |
| 293 | subvect_len=subvect_len, |
| 294 | max_kmeans_iters=1) |
| 295 | |
| 296 | for it in np.arange(niters): |
| 297 | # compute reconstruction errors |
| 298 | X_hat = reconstruct_X_pq(assignments, codebooks) |
| 299 | # err = compute_reconstruction_error(X_rotated, X_hat, subvect_len=subvect_len) |
| 300 | err = compute_reconstruction_error(X_rotated, X_hat) |
| 301 | print "---- OPQ {}x{}b iter {}: mse / variance = {:.5f}".format( |
| 302 | ncodebooks, codebook_bits, it, err) |
| 303 | |
| 304 | # update rotation matrix based on reconstruction errors |
| 305 | U, s, V = np.linalg.svd(np.dot(X_hat.T, X), full_matrices=False) |
| 306 | R = np.dot(U, V) |
| 307 | |
| 308 | # update centroids using new rotation matrix |
| 309 | X_rotated = opq_rotate(X, R) |
| 310 | assignments = _encode_X_pq(X_rotated, codebooks) |
| 311 | codebooks = _update_centroids_opq(X_rotated, assignments, ncentroids) |
| 312 | |
| 313 | X_hat = reconstruct_X_pq(assignments, codebooks) |
| 314 | err = compute_reconstruction_error(X_rotated, X_hat) |
| 315 | t = time.time() - t0 |
| 316 | print "---- OPQ {}x{}b final mse / variance = {:.5f} ({:.3f}s)".format( |
| 317 | ncodebooks, codebook_bits, err, t) |
| 318 | |
| 319 | return codebooks, assignments, R |
| 320 | |
| 321 | |
| 322 | # ================================================================ Block OPQ |
nothing calls this directly
no test coverage detected