Explicitly only skip the zeroth iteration of t-SNE update when sending new

points to the scatter plot. This fixes t-SNE bookmarks where the reprojection
would occur, but not be sent to the scatter plot for rendering.
Change: 137080345
This commit is contained in:
Charles Nicholson 2016-10-24 13:28:47 -08:00 committed by TensorFlower Gardener
parent 79a2a241c4
commit 4a465522c1
2 changed files with 19 additions and 8 deletions

View File

@ -115,6 +115,7 @@ export class DataSet implements scatterPlot.DataSet {
projections = d3.set(); projections = d3.set();
nearest: knn.NearestEntry[][]; nearest: knn.NearestEntry[][];
nearestK: number; nearestK: number;
tSNEIteration: number = 0;
tSNEShouldStop = true; tSNEShouldStop = true;
dim = [0, 0]; dim = [0, 0];
hasTSNERun: boolean = false; hasTSNERun: boolean = false;
@ -199,6 +200,13 @@ export class DataSet implements scatterPlot.DataSet {
return accessors; return accessors;
} }
hasMeaningfulVisualization(projection: Projection): boolean {
if (projection !== 'tsne') {
return true;
}
return this.tSNEIteration > 0;
}
/** /**
* Returns a new subset dataset by copying out data. We make a copy because * Returns a new subset dataset by copying out data. We make a copy because
* we have to modify the vectors by normalizing them. * we have to modify the vectors by normalizing them.
@ -295,11 +303,12 @@ export class DataSet implements scatterPlot.DataSet {
let opt = {epsilon: learningRate, perplexity: perplexity, dim: tsneDim}; let opt = {epsilon: learningRate, perplexity: perplexity, dim: tsneDim};
this.tsne = new TSNE(opt); this.tsne = new TSNE(opt);
this.tSNEShouldStop = false; this.tSNEShouldStop = false;
let iter = 0; this.tSNEIteration = 0;
let step = () => { let step = () => {
if (this.tSNEShouldStop) { if (this.tSNEShouldStop) {
stepCallback(null); stepCallback(null);
this.tsne = null;
return; return;
} }
this.tsne.step(); this.tsne.step();
@ -313,8 +322,8 @@ export class DataSet implements scatterPlot.DataSet {
dataPoint.projections['tsne-2'] = result[i * tsneDim + 2]; dataPoint.projections['tsne-2'] = result[i * tsneDim + 2];
} }
}); });
iter++; this.tSNEIteration++;
stepCallback(iter); stepCallback(this.tSNEIteration);
requestAnimationFrame(step); requestAnimationFrame(step);
}; };
@ -338,7 +347,6 @@ export class DataSet implements scatterPlot.DataSet {
runAsyncTask('Initializing T-SNE...', () => { runAsyncTask('Initializing T-SNE...', () => {
this.tsne.initDataDist(this.nearest); this.tsne.initDataDist(this.nearest);
}).then(step); }).then(step);
}); });
} }
@ -429,6 +437,9 @@ export interface State {
/** The selected projection tab. */ /** The selected projection tab. */
selectedProjection?: Projection; selectedProjection?: Projection;
/** The t-SNE iteration of this projection. */
tSNEIteration?: number;
/** The projection component dimensions (for PCA) */ /** The projection component dimensions (for PCA) */
componentDimensions?: number[]; componentDimensions?: number[];

View File

@ -414,11 +414,9 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
this.scatterPlot.showTickLabels(false); this.scatterPlot.showTickLabels(false);
this.scatterPlot.setPointAccessors(pointAccessors); this.scatterPlot.setPointAccessors(pointAccessors);
if (this.dataSet.hasMeaningfulVisualization(projection)) {
this.scatterPlot.update(); this.scatterPlot.update();
/* tsne needs to do an iteration for the points to look reasonable }
if (projection !== 'tsne') {
this.scatterPlot.update();
} */
this.scatterPlot.recreateScene(); this.scatterPlot.recreateScene();
this.scatterPlot.setCameraDefForNextCameraCreation(null); this.scatterPlot.setCameraDefForNextCameraCreation(null);
@ -442,6 +440,7 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
state.selectedProjection = this.selectedProjection; state.selectedProjection = this.selectedProjection;
state.is3d = this.projectionsPanel.is3d; state.is3d = this.projectionsPanel.is3d;
state.tSNEIteration = this.dataSet.tSNEIteration;
if (this.selectedProjection === 'pca') { if (this.selectedProjection === 'pca') {
state.componentDimensions = state.componentDimensions =
this.projectionsPanel.getPCAComponentUIValues(); this.projectionsPanel.getPCAComponentUIValues();
@ -466,6 +465,7 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
if (state.selectedProjection === 'tsne') { if (state.selectedProjection === 'tsne') {
this.dataSet.hasTSNERun = true; this.dataSet.hasTSNERun = true;
} }
this.dataSet.tSNEIteration = state.tSNEIteration;
this.projectionsPanel.disablePolymerChangesTriggerReprojection(); this.projectionsPanel.disablePolymerChangesTriggerReprojection();
this.projectionsPanel.is3d = state.is3d; this.projectionsPanel.is3d = state.is3d;