Skip to content

Commit b72d751

Browse files
authored
Embedding Projector: fix projector knn computation (#6269)
## Motivation for features / changes Fix a bug with knn computation in projector ## Technical description of changes If we have 1000 points, and we sample 100 points, we cannot reuse the old knn computation because it could contain points that are not part of the sample. ## Screenshots of UI changes N/A ## Detailed steps to verify changes work correctly (as executed by you) 1. Build and launch [projector](https://github.com/tensorflow/tensorboard/blob/bbc9e4f29a55d48478c3f23a7d80221b5b1b1e3c/tensorboard/plugins/projector/README.md) 2. Use default demo tensor (Word2Vec 10K) 3. Change projection type from PCA to T-SNE. This should compute 10k sample points with 90 neighbors for knn. 4. Change projection type from T-SNE to UMAP. You'll see a "Initializing UMAP..." screen loading indefinitely. UMAP uses 5k sample points and 15 neighbors for knn by default Verify the above step results in successful UMAP rendering after the changes are applied ## Alternate designs / implementations considered
1 parent c0e7447 commit b72d751

File tree

1 file changed

+3
-9
lines changed
  • tensorboard/plugins/projector/vz_projector

1 file changed

+3
-9
lines changed

tensorboard/plugins/projector/vz_projector/data.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export interface DataPoint {
8787
};
8888
}
8989
const IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0;
90-
/** Controls whether nearest neighbors computation is done on the GPU or CPU. */
90+
/** Maximum sample size for each projection type. */
9191
export const TSNE_SAMPLE_SIZE = 10000;
9292
export const UMAP_SAMPLE_SIZE = 5000;
9393
export const PCA_SAMPLE_SIZE = 50000;
@@ -459,20 +459,14 @@ export class DataSet {
459459
this.nearest && this.nearest.length ? this.nearest[0].length : 0;
460460
if (
461461
this.nearest != null &&
462-
this.nearest.length >= data.length &&
462+
this.nearest.length === data.length &&
463463
previouslyComputedNNeighbors >= nNeighbors
464464
) {
465465
return Promise.resolve(
466466
this.nearest
467-
// `this.points` is only set and constructor and `data` is subset of
468-
// it. If `nearest` is calculated with N = 1000 sampled points before
469-
// and we are asked to calculate KNN ofN = 50, pretend like we
470-
// recalculated the KNN for N = 50 by taking first 50 of result from
471-
// N = 1000.
472-
.slice(0, data.length)
473467
// NearestEntry has list of K-nearest vector indices at given index.
474468
// Hence, if we already precomputed K = 100 before and later seek
475-
// K-10, we just have ot take the first ten.
469+
// K = 10, we just have ot take the first ten.
476470
.map((neighbors) => neighbors.slice(0, nNeighbors))
477471
);
478472
} else {

0 commit comments

Comments
 (0)