diff options
author | 2016-12-12 15:28:04 -0800 | |
---|---|---|
committer | 2016-12-12 15:45:25 -0800 | |
commit | 12940319ebf08e2fb1bb92b82e309c20759e44a4 (patch) | |
tree | 807a98754fb6e68c907f0edb600915ed492d1b67 | |
parent | e0587d1d504d60188938469cb662d2e809ec0206 (diff) |
Fix t-sne bug (division by 0) when there are duplicate points.
Change: 141818266
-rw-r--r-- | tensorflow/tensorboard/components/vz_projector/bh_tsne.ts | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/tensorflow/tensorboard/components/vz_projector/bh_tsne.ts b/tensorflow/tensorboard/components/vz_projector/bh_tsne.ts index 1d57dc720a..9d2df65f56 100644 --- a/tensorflow/tensorboard/components/vz_projector/bh_tsne.ts +++ b/tensorflow/tensorboard/components/vz_projector/bh_tsne.ts @@ -51,6 +51,9 @@ type AugmSPNode = SPNode&{numCells: number, yCell: number[], rCell: number}; * results. Recommended value mentioned in the paper is 0.8. */ const THETA = 0.8; + +const MIN_POSSIBLE_PROB = 1E-9; + // Variables used for memorizing the second random number since running // gaussRandom() generates two random numbers at the cost of 1 atomic // computation. This optimization results in 2X speed-up of the generator. @@ -159,6 +162,7 @@ function nearest2P( for (let k = 0; k < neighbors.length; ++k) { let neighbor = neighbors[k]; let pij = (i === neighbor.index) ? 0 : Math.exp(-neighbor.dist * beta); + pij = Math.max(pij, MIN_POSSIBLE_PROB); pRow[k] = pij; psum += pij; } @@ -433,7 +437,8 @@ export class TSNE { let squaredDistToCell = this.dist2(pointI, node.yCell); // Squared distance from point i to cell. if (node.children == null || - (node.rCell / Math.sqrt(squaredDistToCell) < THETA)) { + (squaredDistToCell > 0 && + node.rCell / Math.sqrt(squaredDistToCell) < THETA)) { let qijZ = 1 / (1 + squaredDistToCell); let dZ = node.numCells * qijZ; Z += dZ; |