:MNIST 手寫數(shù)字二維降維可視化)
示例工程【免費下載鏈接】tfjs-examplesExamples built with TensorFlow.js項目地址https://gitcode.com/gh_mirrors/tf/tfjs-examples點擊查看免費下載本指南圍繞 tfjs-examples 倉庫中的tsne-mnist-canvas示例講解如何借助 TensorFlow.js 生態(tài)下的 tfjs-tsne 庫在瀏覽器中完成 MNIST 手寫數(shù)字數(shù)據(jù)集的 t-SNE 降維與實時可視化。讀完本文你將掌握 MNIST 數(shù)據(jù)的加載與張量預(yù)處理管線、tfjs-tsne 的 kNN 與迭代式嵌入 API、基于 d3 與 Canvas 2D 的坐標渲染方案以及 WebGL 2 環(huán)境要求與關(guān)鍵參數(shù)的調(diào)優(yōu)方向。示例概覽在瀏覽器里跑通完整的 t-SNE 流程正如 README.md 所描述的本示例演示了使用tfjs-tsne庫對 MNIST 數(shù)據(jù)集 做降維從測試集中取出10000 張手寫數(shù)字圖片將其縮放為10×10 像素再用t-SNE 算法把它們組織到二維平面上讓相同數(shù)字在空間上聚成簇、不同數(shù)字彼此分離從而直觀地檢驗高維圖像數(shù)據(jù)在低維空間中的結(jié)構(gòu)。演示頁面的標題正是“GPU Accelerated T-SNE in the Browser”整個計算過程依托 TensorFlow.js 與 WebGL 在 GPU 上完成這也是本示例區(qū)別于傳統(tǒng) CPU 版 t-SNE 工具的核心亮點。該示例的倉庫結(jié)構(gòu)十分精簡只有 6 個文件tsne-mnist-canvas/ ├── README.md # 示例說明與運行命令 ├── index.html # 頁面結(jié)構(gòu)、參數(shù)控件與樣式 ├── index.js # 主邏輯數(shù)據(jù)預(yù)處理、t-SNE 調(diào)用、渲染 ├── data.js # MnistData 類MNIST 數(shù)據(jù)加載與切分 ├── package.json # 依賴與構(gòu)建腳本 └── yarn.lock # 依賴鎖定文件運行環(huán)境前提必須支持 WebGL 2README 給出了一個重要但容易被忽略的環(huán)境限制tfjs-tsne requires WebGL 2 support and thus will not work on certain devices, mobile devices especially. Currently it best works on desktop devices.也就是說tfjs-tsne依賴WebGL 2支持因此移動設(shè)備上很可能無法運行尤其是部分只支持 WebGL 1 的手機瀏覽器桌面端瀏覽器體驗最佳建議在較新的 Chrome / Firefox / Edge 等支持 WebGL 2 的桌面瀏覽器中運行。從實現(xiàn)上可以推斷該限制源于 tfjs-tsne 將 kNN 近鄰圖構(gòu)建與 t-SNE 優(yōu)化等重計算全部放在 GPU 著色器shader中執(zhí)行以獲得實時的迭代可視化體驗而 WebGL 2 提供了所需的更靈活的浮點紋理與計算能力。因此如果運行頁面時出現(xiàn)空白或報錯請先確認瀏覽器支持 WebGL 2??焖龠\行兩條命令啟動README 給出的啟動方式只有兩條命令yarn yarn watchyarn安裝依賴依賴清單見 package.jsontensorflow/tfjs^1.3.2、tensorflow/tfjs-tsne0.2.0、d3^5.2.0yarn watch啟動開發(fā)服務(wù)器并在瀏覽器中自動打開頁面官方同時在 GCS 上托管了在線演示版本可直接訪問體驗。package.json中完整定義了三個腳本可滿足開發(fā)與構(gòu)建兩種場景scripts: { watch: NODE_ENVdevelopment parcel index.html --no-hmr --open, build: NODE_ENVproduction parcel build --no-scope-hoist index.html --public-url ./, link-local: yalc link }yarn watch基于Parcel的本地開發(fā)模式--no-hmr關(guān)閉熱模塊替換避免開發(fā)中頻繁整頁刷新--open自動打開瀏覽器yarn build產(chǎn)出生產(chǎn)構(gòu)建--public-url ./保證資源使用相對路徑方便部署到任意靜態(tài)目錄yarn link-local配合 devDependencies 中的yalc用于本地鏈接尚未發(fā)布的 tfjs-tsne 版本屬于庫作者聯(lián)調(diào)場景。數(shù)據(jù)準備從 MNIST 精靈圖加載訓練與測試集數(shù)據(jù)層由 data.js 中的MnistData類負責它直接從云存儲加載兩份 MNIST 原始資源一張把全部 65000 張圖片縱向拼接的精靈圖sprite以及一份 uint8 格式的標簽文件。關(guān)鍵常量見 data.jsconst IMAGE_SIZE 784; // 28×28 784 像素 const NUM_CLASSES 10; // 0~9 十個數(shù)字類別 const NUM_DATASET_ELEMENTS 65000; // 全量樣本數(shù) const NUM_TRAIN_ELEMENTS 55000; // 訓練集 const NUM_TEST_ELEMENTS 10000; // 測試集load()方法的核心加載流程值得注意用Image對象加載精靈圖并設(shè)置crossOrigin 以跨域讀取像素以chunkSize 5000為步長分塊繪制到臨時 canvas 上再通過getImageData取出像素——由于 MNIST 是灰度圖只需讀取紅色通道并除以 255 完成歸一化見 data.js并行fetch標簽文件解析為Uint8Array用tf.util.createShuffledIndices生成亂序索引并將圖像與標簽按 55000 / 10000 切分為trainImages、testImages、trainLabels、testLabels見 data.js。本示例只用到測試集因此在 index.js 中僅需一行async function loadData() { data new MnistData(); return data.load(); }預(yù)處理張量管線28×28 圖像降維到 10×10 特征這是整個示例中最有工程價值的一段在送入 t-SNE 之前把高維輸入壓縮到可控維度。start函數(shù)見 index.js在tf.tidy作用域內(nèi)完成全部張量操作const [reshaped, labels] tf.tidy(() { // 1. 標簽one-hot 轉(zhuǎn)成數(shù)字數(shù)組 const labelsTensor tf.tensor2d(data.testLabels, [NUM_IMAGES, NUM_CLASSES]); const labels labelsTensor.argMax(1).dataSync(); // 2. 圖像構(gòu)建 [10000, 28, 28, 1] 張量并截取前 numPoints 張 const images tf.tensor4d(data.testImages, [ NUM_IMAGES, IMG_HEIGHT, IMG_WIDTH, 1 ]).slice([0], [numPoints]); // 3. 縮放雙線性插值到 10×10 const resized images.resizeBilinear([NEW_HEIGHT, NEW_WIDTH]); // 4. 重塑攤平為 tfjs-tsne 期望的 rank-2 輸入 const reshaped resized.reshape([numPoints, NEW_HEIGHT * NEW_WIDTH]); return [reshaped, labels]; });各步驟的作用標簽轉(zhuǎn)換MNIST 標簽是 one-hot 編碼的[10000, 10]張量用argMax(1)取每行最大值下標得到[10000]的數(shù)字標簽數(shù)組供后續(xù)按類別著色切片slice([0], [numPoints])從測試集中取用戶指定的樣本數(shù)默認 10000雙線性縮放resizeBilinear([10, 10])把每張 28×28 圖像縮小到 10×10將特征維度從 784 降到100這既大幅降低了 t-SNE 的計算量又不至于損失過多的數(shù)字結(jié)構(gòu)信息重塑reshape([numPoints, 100])得到 tfjs-tsne 要求的 rank-2 輸入張量[樣本數(shù), 特征數(shù)]。最后tf.tidy自動回收中間張量函數(shù)末尾還顯式調(diào)用reshaped.dispose()釋放輸入張量避免 GPU 顯存泄漏——在動輒 10000 行樣本的降維任務(wù)里內(nèi)存管理是保持頁面流暢的必要細節(jié)。t-SNE 計算流程tfjs-tsne 的核心調(diào)用鏈doEmbedding函數(shù)見 index.js完整展示了 tfjs-tsne 的異步 API 用法整個流程分為兩階段async function doEmbedding( data, labels, numIterations, knnIter, perplexity, onIteration) { // 階段一創(chuàng)建 embedder 并預(yù)計算 kNN 近鄰圖 const embedder tsne.tsne(data); await embedder.iterateKnn(knnIter); // 階段二逐輪迭代優(yōu)化并在每輪之間渲染當前坐標 for (let i 0; i numIterations; i) { await embedder.iterate(1); const coordinates await embedder.coordsArray(); onIteration(coordinates, labels); await tf.nextFrame(); } }逐行拆解tsne.tsne(data)傳入[樣本數(shù), 100]的張量創(chuàng)建一個 GPU 加速的 t-SNE embedder 實例await embedder.iterateKnn(knnIter)正式優(yōu)化前先執(zhí)行若干輪 kNNk 近鄰迭代構(gòu)建樣本之間的近鄰關(guān)系圖這是 t-SNE 計算相似度矩陣的基礎(chǔ)await embedder.iterate(1)執(zhí)行一輪 t-SNE 梯度優(yōu)化迭代。示例刻意每輪只迭代 1 次代碼注釋明確說明“你也可以在兩次取坐標渲染之間多迭代幾次”——這樣可以在迭代尚未收斂時就展示中間狀態(tài)形成漸進式動畫await embedder.coordsArray()從 GPU 取回當前所有樣本的二維坐標數(shù)組交給渲染回調(diào)await tf.nextFrame()把控制權(quán)交還給瀏覽器渲染線程避免長循環(huán)阻塞頁面是瀏覽器端異步計算中保持 UI 流暢的關(guān)鍵一步。實時渲染d3 與 Canvas 2D 畫出手寫數(shù)字散點renderEmbedding見 index.js負責把坐標繪制到 800×800 的 canvas 上采用d3 縮放 Canvas 2D 逐點繪制的組合function renderEmbedding(coordinates, labels) { const x d3.scaleLinear().range([0, width]).domain([0, 1]); const y d3.scaleLinear().range([0, height]).domain([0, 1]); context.clearRect(0, 0, width, height); coordinates.forEach(function(d, i) { context.font 10px sans; context.fillStyle colors(parseInt(labels[i], 10)); context.fillText(labels[i], x(d[0]), y(d[1])); }); }渲染細節(jié)坐標映射d3.scaleLinear把坐標從[0, 1]區(qū)間線性映射到畫布像素范圍——從 domain 取值可以推斷coordsArray()返回的坐標被歸一化在[0, 1]內(nèi)逐點著色colors d3.scaleOrdinal(d3.schemeCategory10)見 index.js為 10 個數(shù)字類別各分配一種顏色直接繪制數(shù)字字符每個樣本用fillText繪制它自身的標簽數(shù)字0~9因此不依賴額外的點/圖片資源幾萬點也能在 10px 字號下保持清晰的散點分布逐幀重繪每輪 t-SNE 迭代都會clearRect后重新繪制全部坐標可視化出“點云逐步聚成 10 團”的動態(tài)過程。canvas 本身由initVisualization在#vis容器內(nèi)動態(tài)創(chuàng)建并獲取 2d context見 index.js樣式上通過 1px 黑色邊框與頁面布局區(qū)分可視化區(qū)域。交互控件與參數(shù)調(diào)優(yōu)index.html 提供了一組滑塊與單選按鈕initControls見 index.js在數(shù)據(jù)加載完成后將其啟用。點擊Start T-SNE按鈕后讀取全部參數(shù)并調(diào)用start(numPoints, tsneIter, knnIter, perplexity)按鈕文字隨之變?yōu)镽estart TSNE可反復調(diào)整參數(shù)重跑。全部可調(diào)參數(shù)及默認值如下控件含義取值范圍默認值Perplexityt-SNE 的核心超參數(shù)控制每個點周圍“有效近鄰”的數(shù)量用于平衡局部與全局結(jié)構(gòu)2 ~ 42步長 130KNN Iterations正式優(yōu)化前構(gòu)建 kNN 近鄰圖的迭代輪數(shù)決定相似度矩陣的質(zhì)量2 ~ 1500步長 1800T-SNE Iterations進入 t-SNE 優(yōu)化階段后的總迭代輪數(shù)決定嵌入結(jié)果的收斂程度1 ~ 1000步長 1500Number of Digits實際參與降維的樣本數(shù)對應(yīng)numPoints參數(shù)500 / 2000 / 10000單選10000調(diào)參方向可以這樣把握以下為 t-SNE 通用經(jīng)驗可作為調(diào)試參考Perplexity從算法原理看值越大越側(cè)重保留全局結(jié)構(gòu)值越小越側(cè)重局部結(jié)構(gòu)對 500 個樣本的小數(shù)據(jù)集過大的 perplexity 會引入偏差通常可相應(yīng)調(diào)低KNN Iterations迭代越多近鄰圖越準確但耗時線性增長。若聚類結(jié)果明顯雜亂可優(yōu)先增大該項T-SNE Iterations迭代越多收斂越好但每輪都要在 GPU 上更新并回讀坐標。本示例每輪只iterate(1)并立即渲染因此總迭代數(shù)也直接決定動畫時長樣本數(shù)10000 點最能展現(xiàn) MNIST 的完整結(jié)構(gòu)但計算與渲染開銷最大調(diào)試階段可用 500 或 2000 快速驗證參數(shù)效果。另外控件區(qū)域的所有input[typerange]滑塊都會在滑動時實時把當前值回顯到其前的span標簽中見 index.js方便觀察所選數(shù)值。小結(jié)一條完整的瀏覽器端降維鏈路tsne-mnist-canvas用約百行核心代碼串起了從數(shù)據(jù)加載、張量預(yù)處理、GPU 加速 t-SNE 到 Canvas 實時渲染的完整鏈路是理解 tfjs-tsne 用法的理想起點?;仡櫛疚囊c環(huán)境tfjs-tsne 依賴 WebGL 2移動端兼容性有限桌面瀏覽器體驗最佳數(shù)據(jù)data.js 展示了從精靈圖異步加載 MNIST 并進行 train/test 切分的完整寫法預(yù)處理index.js 通過slice → resizeBilinear → reshape把 28×28 圖像壓縮為 10×10100 維特征并借助tf.tidy管理 GPU 內(nèi)存計算tsne.tsne → iterateKnn → iterate(1) → coordsArray → tf.nextFrame兩階段調(diào)用鏈兼顧了收斂質(zhì)量與 UI 流暢度渲染d3 比例尺 Canvas 逐點fillText的方案支持數(shù)萬點的實時動畫。如需深入可繼續(xù)閱讀倉庫中 data.js、index.js 與 index.html 的完整實現(xiàn)并對照 package.json 了解依賴版本與構(gòu)建腳本即可在此基礎(chǔ)上替換為自己的數(shù)據(jù)集搭建瀏覽器端的通用高維數(shù)據(jù)探索工具。贊分享示例工程【免費下載鏈接】tfjs-examplesExamples built with TensorFlow.js項目地址https://gitcode.com/gh_mirrors/tf/tfjs-examples點擊查看免費下載相關(guān)推薦3步并行開發(fā)Prime Agent Subagent 子智能體實戰(zhàn)指南3步并行開發(fā)Prime Agent Subagent 子智能體實戰(zhàn)指南 認證模塊要改、測試要補、審查任務(wù)還堆著主智能體只能一件件串行干。Prime Agen人工智能AI Agent代碼智能體工具調(diào)用交互助手MCP ClientsAgent 記憶2024年最受歡迎的流媒體代理工具Threadfin核心功能全解析2024年最受歡迎的流媒體代理工具Threadfin核心功能全解析 Threadfin 是一款基于 xTeVe 開發(fā)的 M3U 代理工具專為 Kernel、后端音視頻Plotly 可視化 t-SNE 與 UMAP 降維投影從高維數(shù)據(jù)到 2D/3D 散點圖實戰(zhàn)基于 plotly.pyPlotly 可視化 t SNE 與 UMAP 降維投影從高維數(shù)據(jù)到 2D/3D 散點圖實戰(zhàn)基于 plotly.py 本篇技術(shù)指南以 doc/python數(shù)據(jù)可視化數(shù)據(jù)分析上一篇AlphaFold 3革命性蛋白質(zhì)結(jié)構(gòu)預(yù)測的7大關(guān)鍵技術(shù)突破與實戰(zhàn)指南下一篇gh_mirrors/de/developer組件設(shè)計構(gòu)建可復用UI創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考