MCPcopy Create free account
hub / github.com/dblalock/bolt / OPQEncoder

Class OPQEncoder

experiments/python/main.py:187–312  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

185
186
187class OPQEncoder(PQEncoder):
188
189 def __init__(self, dataset, code_bits=-1, bits_per_subvect=-1,
190 nsubvects=-1, elemwise_dist_func=dists_elemwise_sq,
191 opq_iters=20, quantize_lut=False, algo='OPQ', **opq_kwargs):
192 X = dataset.X_train
193 self.elemwise_dist_func = elemwise_dist_func
194 self.quantize_lut = quantize_lut
195 self.opq_iters = opq_iters
196 self.algo = algo
197
198 tmp = _parse_codebook_params(X.shape[1], code_bits=code_bits,
199 bits_per_subvect=bits_per_subvect,
200 nsubvects=nsubvects)
201 self.nsubvects, self.ncentroids, self.subvect_len = tmp
202 self.code_bits = int(np.log2(self.ncentroids))
203
204 # for fast lookups via indexing into flattened array
205 self.offsets = np.arange(self.nsubvects, dtype=np.int) * self.ncentroids
206
207 if self.algo == 'Bolt':
208 # Note: we always pass in 0 iters in the reported experiments,
209 # so it never rotates anything
210 self.centroids, _, self.rotations = pq.learn_bopq(
211 X, ncodebooks=nsubvects, codebook_bits=bits_per_subvect,
212 niters=opq_iters, **opq_kwargs)
213 elif self.algo == 'OPQ':
214 self.centroids, _, self.R = pq.learn_opq(
215 X, ncodebooks=nsubvects, codebook_bits=bits_per_subvect,
216 niters=opq_iters, **opq_kwargs)
217 else:
218 raise ValueError("argument algo must be one of {OPQ, Bolt}")
219
220 # learn appropriate offsets and shared scale factor for quantization
221 self.lut_offsets = np.zeros(self.nsubvects)
222 self.order_idxs = np.arange(self.nsubvects, dtype=np.int)
223
224 if self.quantize_lut: # TODO put this logic in separate function
225 print "learning quantization..."
226
227 num_rows = min(10*1000, len(X) / 2)
228 _, queries = datasets.extract_random_rows(
229 X[num_rows:], how_many=1000, remove_from_X=False)
230 X = X[:num_rows] # limit to first 10k rows of X
231
232 # compute luts for all the queries
233 luts = [self._fit_query(q, quantize=False) for q in queries]
234 luts = np.vstack(luts)
235 assert luts.shape == (self.ncentroids * len(queries), self.nsubvects)
236
237 self.lut_offsets, self.scale_by, _ = _learn_best_quantization(luts)
238
239 def name(self):
240 return "{}_{}x{}b_iters={}_quantize={}".format(
241 self.algo, self.nsubvects, self.code_bits, self.opq_iters,
242 int(self.quantize_lut))
243
244 def params(self):

Callers 1

_experiment_one_datasetFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected