Public
Edited
Mar 31, 2024
1 fork
Importers
18 stars
Insert cell
Insert cell
Insert cell
Insert cell
NUM_POINTS = 1000
Insert cell
Insert cell
Insert cell
Insert cell
import {worker} from "@fil/worker"
Insert cell
UMAP = "🌶" // fake symbol to allow Observable to read the fit function
Insert cell
fit = function* fit({ data, show_dynamic }) {
yield Array.from(data, _ => [10 * Math.random() - 5, 10 * Math.random() - 5]);

const umap = new UMAP({
nComponents: 2,
minDist: 0.1,
nNeighbors: 15
}),
nEpochs = umap.initializeFit(data);

yield umap.getEmbedding();
for (let i = 0; i < nEpochs; i++) {
umap.step();
if (show_dynamic) yield umap.getEmbedding();
}
yield umap.getEmbedding();
}
Insert cell
coordinates = Generators.observe(
worker(
fit,
{ data, show_dynamic, restart },
`
const window = {};
importScripts("https://cdn.jsdelivr.net/npm/umap-js@1.3.3");
const UMAP = window.UMAP;
`
)
)
Insert cell
// convert data back to a regular array (which UMAP-js consumes)
data = {
const x = tfdata;
// flatten array
let arr = x.dataSync();

//convert to multiple dimensional array
const b = x.shape.reverse().map(a => {
arr = arr.reduce(
(b, c) => {
const latest = b[b.length - 1];
latest.length < a ? latest.push(c) : b.push([c]);
return b;
},
[[]]
);
return arr;
});

return b[0];
}
Insert cell
Insert cell
tf = require("@tensorflow/tfjs-core@0.14")
Insert cell
Insert cell
sprites = new Promise((resolve, reject) => {
const image = new Image;
image.width = 33;
image.height = 33;
image.style.imageRendering = "pixelated";
image.crossOrigin = "anonymous";
image.src = "https://storage.googleapis.com/learnjs-data/model-builder/mnist_images.png";
image.onload = () => resolve(image);
image.onerror = reject;
})
Insert cell
Insert cell
Insert cell
Insert cell
function sprite(i) {
const context = DOM.context2d(SPRITE_SIZE, SPRITE_SIZE, 1);
for (let y = 0; y < SPRITE_SIZE; ++y) {
context.drawImage(sprites, y * SPRITE_SIZE, i, SPRITE_SIZE, 1, 0, y, SPRITE_SIZE, 1);
}
return context.canvas;
}
Insert cell
function inlineSprite(i) {
const canvas = sprite(i);
canvas.style.filter = "invert(1)";
canvas.style.width = "21px";
canvas.style.height = "21px";
return canvas;
}
Insert cell
Insert cell
Insert cell
datasetLabels = fetch("https://storage.googleapis.com/learnjs-data/model-builder/mnist_labels_uint8")
.then(response => response.arrayBuffer())
.then(buffer => new Uint8Array(buffer, 0, NUM_CLASSES * NUM_POINTS))
Insert cell
label = i => datasetLabels.subarray(i * NUM_CLASSES, (i + 1) * NUM_CLASSES)
Insert cell
classify = i => label(i).findIndex(value => value === 1)
Insert cell
Insert cell
Insert cell
labels = tidy(() => tf
.tensor2d(datasetLabels, [NUM_POINTS, NUM_CLASSES])
.argMax(1)
.dataSync())
Insert cell
tidy = f =>
Generators.disposable(tf.tidy(f), x => x && x.dispose && x.dispose())
Insert cell
Insert cell
Insert cell
datasetImages = {
const array = new Float32Array(NUM_POINTS * IMAGE_WIDTH);
const context = DOM.context2d(IMAGE_WIDTH, CHUNK_SIZE, 1);
for (let i = 0; i < NUM_POINTS; i += CHUNK_SIZE) {
context.drawImage(
sprites,
0, i, IMAGE_WIDTH, CHUNK_SIZE,
0, 0, IMAGE_WIDTH, CHUNK_SIZE
);
const {data} = context.getImageData(0, 0, IMAGE_WIDTH, CHUNK_SIZE);
const offset = i * IMAGE_WIDTH;
for (let j = 0; j < data.length; j += 4) {
array[offset + (j >> 2)] = data[j] / 255; // Grayscale, so just read the red channel.
}
}
return array;
}
Insert cell
Insert cell
Insert cell
tfdata = tidy(() =>
tf
.tensor4d(datasetImages, [NUM_POINTS, SPRITE_SIZE, SPRITE_SIZE, 1])
.resizeBilinear([NEW_SIZE, NEW_SIZE])
.reshape([NUM_POINTS, NEW_SIZE * NEW_SIZE])
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more