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();
nearest: knn.NearestEntry[][];
nearestK: number;
tSNEIteration: number = 0;
tSNEShouldStop = true;
dim = [0, 0];
hasTSNERun: boolean = false;
@ -199,6 +200,13 @@ export class DataSet implements scatterPlot.DataSet {
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
* 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};
this.tsne = new TSNE(opt);
this.tSNEShouldStop = false;
let iter = 0;
this.tSNEIteration = 0;
let step = () => {
if (this.tSNEShouldStop) {
stepCallback(null);
this.tsne = null;
return;
}
this.tsne.step();
@ -313,8 +322,8 @@ export class DataSet implements scatterPlot.DataSet {
dataPoint.projections['tsne-2'] = result[i * tsneDim + 2];
}
});
iter++;
stepCallback(iter);
this.tSNEIteration++;
stepCallback(this.tSNEIteration);
requestAnimationFrame(step);
};
@ -338,7 +347,6 @@ export class DataSet implements scatterPlot.DataSet {
runAsyncTask('Initializing T-SNE...', () => {
this.tsne.initDataDist(this.nearest);
}).then(step);
});
}
@ -429,6 +437,9 @@ export interface State {
/** The selected projection tab. */
selectedProjection?: Projection;
/** The t-SNE iteration of this projection. */
tSNEIteration?: number;
/** The projection component dimensions (for PCA) */
componentDimensions?: number[];

View File

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