aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dan Smilkov <smilkov@google.com>2016-12-12 15:28:04 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-12-12 15:45:25 -0800
commit12940319ebf08e2fb1bb92b82e309c20759e44a4 (patch)
tree807a98754fb6e68c907f0edb600915ed492d1b67
parente0587d1d504d60188938469cb662d2e809ec0206 (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.ts7
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;