Zum Hauptinhalt springen

Machine Learning in Cursor: TensorFlow.js, ONNX und KI-gestützte ML-Pipelines

Machine Learning in Cursor

Machine Learning bringt prädiktive Intelligenz in Anwendungen, von Bildklassifizierung über Natural Language Processing bis hin zu Empfehlungssystemen. Cursor, ein KI-gestützter IDE-Editor, beschleunigt jede Phase des ML-Workflows: Datenpräverarbeitung, Modelldesign, Trainingsschleifen, Evaluierungsmetriken und Deployment. Dieser Leitfaden behandelt TensorFlow.js für browserbasierte Inferenz und Training, ONNX Runtime für plattformübergreifende Modellausführung, Datenpräverarbeitungs-Pipelines, Modellevaluierungs-Strategien und KI-gestützte ML-Pipeline-Generierung, die Naturalsprachbeschreibungen in funktionierende Trainingsskripte umwandelt.

Voraussetzungen​

Stellen Sie vor dem Start sicher, dass Sie Folgendes haben:

  • Cursor (aktuellste Version empfohlen) als IDE-Editor
  • Node.js 18 oder höher
  • Grundlegende Vertrautheit mit JavaScript, TypeScript und Python
  • Konzeptionelles Verständnis von neuronalen Netzen, Verlustfunktionen und Gradientenabstieg
tipp

Wenn Sie neu im Machine Learning sind, bitten Sie Cursor, den Unterschied zwischen überwachtem, unüberwachtem und bestärkendem Lernen zu erklären, bevor Sie Code schreiben. Zu verstehen, in welches Paradigma Ihr Problem fällt, bestimmt Ihren gesamten Ansatz: Daten-Labeling, Modellarchitektur und Evaluierungsmetriken.

Den ML-Workflow in Cursor verstehen​

Ein typisches Machine-Learning-Projekt folgt einer vorhersehbaren Pipeline. Cursor hilft Ihnen, jede Phase zu implementieren und zu verbinden:

  1. Datensammlung und -präverarbeitung: Rohdaten bereinigen, fehlende Werte behandeln, Merkmale normalisieren und in Train/Validation/Test-Splits aufteilen.
  2. Modelldesign: Eine Architektur wählen (Dense Network, CNN, RNN, Transformer) und Schichten definieren.
  3. Training: Die Trainingsschleife mit einem gewählten Optimierer und einer Verlustfunktion ausführen, Metriken überwachen und Early Stopping anwenden.
  4. Evaluierung: Leistung mit Precision, Recall, F1-Score, Confusion Matrices und weiteren Metriken messen.
  5. Deployment: Das Modell exportieren, bei Bedarf zu ONNX konvertieren und Inferenz im Browser oder auf einem Server ausführen.

Projekt-Scaffolding​

Bitten Sie Cursor, ein TensorFlow.js-Projekt zu scaffolden:

Create a TypeScript project for machine learning with TensorFlow.js.
Set up Vite for the frontend, install @tensorflow/tfjs and
@tensorflow/tfjs-node, and create a folder structure for data,
models, training scripts, and evaluation utilities.

Cursor generiert:

my-ml-project/
data/
raw/
processed/
models/
src/
train.ts
evaluate.ts
predict.ts
src-tauri/ (optional, for desktop deployment)
package.json
tsconfig.json
warnung

Verwenden Sie immer @tensorflow/tfjs-node (das an die native C++ TensorFlow-Bibliothek bindet) für das Training, nicht reinen @tensorflow/tfjs (der auf WebGL/WASM im Browser läuft). Training auf Node.js ist 10x bis 50x schneller als browserbasiertes Training, da es SIMD-Instruktionen und natives Speichermanagement nutzt. Browser-TF.js ist für Inferenz, nicht für schweres Training.

Datenpräverarbeitung​

Datenpräverarbeitung verbraucht den Großteil der ML-Entwicklungszeit. Cursor kann vollständige Präverarbeitungs-Pipelines generieren, die Bereinigung, Normalisierung, Encoding und Splitting handhaben.

Präverarbeitungs-Pipeline​

// src/preprocessing.ts
import * as tf from '@tensorflow/tfjs-node';

export interface DatasetStats {
mean: number[];
std: number[];
min: number[];
max: number[];
}

export class DataPreprocessor {
private stats: DatasetStats | null = null;

/**
* Compute normalization statistics from training data.
* Must be called before normalize() and applied identically
* to training, validation, and test sets.
*/
computeStats(data: number[][]): void {
const tensor = tf.tensor2d(data);
const mean = tensor.mean(0).dataSync();
const std = tensor.sub(tensor.mean(0)).square().mean(0).sqrt().dataSync();
const min = tensor.min(0).dataSync();
const max = tensor.max(0).dataSync();

this.stats = {
mean: Array.from(mean),
std: Array.from(std).map((s, i) => (s < 1e-8 ? 1 : s)), // Avoid division by zero
min: Array.from(min),
max: Array.from(max),
};

tensor.dispose();
}

/**
* Apply Z-score normalization: (x - mean) / std
*/
normalize(data: number[][]): number[][] {
if (!this.stats) throw new Error('Call computeStats() first');
return data.map((row) =>
row.map((val, i) => (val - this.stats!.mean[i]) / this.stats!.std[i])
);
}

/**
* One-hot encode categorical labels
*/
encodeLabels(labels: number[], numClasses: number): number[][] {
return labels.map((label) => {
const encoded = new Array(numClasses).fill(0);
encoded[label] = 1;
return encoded;
});
}

/**
* Split data into train, validation, and test sets
*/
split(
data: number[][],
labels: number[][],
trainRatio = 0.7,
valRatio = 0.15
): { trainX: number[][]; trainY: number[]; valX: number[][]; valY: number[]; testX: number[][]; testY: number[] } {
const n = data.length;
const indices = Array.from({ length: n }, (_, i) => i);
// Fisher-Yates shuffle
for (let i = n - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[indices[i], indices[j]] = [indices[j], indices[i]];
}
const trainEnd = Math.floor(n * trainRatio);
const valEnd = trainEnd + Math.floor(n * valRatio);
const pick = (idx: number[]) => ({ x: idx.map((i) => data[i]), y: idx.map((i) => labels[i]) });
const train = pick(indices.slice(0, trainEnd));
const val = pick(indices.slice(trainEnd, valEnd));
const test = pick(indices.slice(valEnd));
return { trainX: train.x, trainY: train.y, valX: val.x, valY: val.y, testX: test.x, testY: test.y };
}

/**
* Handle missing values by imputing the column mean
*/
imputeMissing(data: (number | null)[][]): number[][] {
const numCols = data[0].length;
const colSums = new Array(numCols).fill(0);
const colCounts = new Array(numCols).fill(0);

data.forEach((row) => {
row.forEach((val, col) => {
if (val !== null && !isNaN(val)) { colSums[col] += val; colCounts[col]++; }
});
});

const colMeans = colSums.map((sum, i) => (colCounts[i] > 0 ? sum / colCounts[i] : 0));

return data.map((row) => row.map((val, col) => (val === null || isNaN(val) ? colMeans[col] : val)));
}

getStats(): DatasetStats | null {
return this.stats;
}
}
tipp

Bitten Sie Cursor, synthetische Datensätze zum Testen Ihrer Präverarbeitungs-Pipeline zu generieren. Ein Prompt wie „Generiere eine synthetische CSV mit 1000 Zeilen, 8 numerischen Merkmalen, 2 kategorialen Spalten und 5 % fehlenden Werten" gibt Ihnen realistische Testdaten, ohne zuerst einen echten Datensatz finden und herunterladen zu müssen.

Modelldesign und Training​

TensorFlow.js verwendet eine geschichtete API zum Aufbau neuronaler Netze. Cursor generiert vollständige Modellarchitekturen basierend auf Ihrer Problembeschreibung.

Ein Klassifikationsmodell bauen​

// src/models/classifier.ts
import * as tf from '@tensorflow/tfjs-node';

export interface ModelConfig {
inputSize: number;
numClasses: number;
hiddenLayers: number[];
learningRate: number;
dropoutRate: number;
}

export function buildClassifier(config: ModelConfig): tf.LayersModel {
const model = tf.sequential();

// Input layer
model.add(
tf.layers.dense({
inputShape: [config.inputSize],
units: config.hiddenLayers[0],
activation: 'relu',
kernelInitializer: 'heNormal',
})
);

model.add(tf.layers.batchNormalization());
model.add(tf.layers.dropout({ rate: config.dropoutRate }));

// Hidden layers
for (let i = 1; i < config.hiddenLayers.length; i++) {
model.add(
tf.layers.dense({
units: config.hiddenLayers[i],
activation: 'relu',
kernelInitializer: 'heNormal',
})
);
model.add(tf.layers.batchNormalization());
model.add(tf.layers.dropout({ rate: config.dropoutRate }));
}

// Output layer
model.add(
tf.layers.dense({
units: config.numClasses,
activation: 'softmax',
})
);

model.compile({
optimizer: tf.train.adam(config.learningRate),
loss: 'categoricalCrossentropy',
metrics: ['accuracy'],
});

return model;
}

Trainingsschleife mit Callbacks​

// src/train.ts
import * as tf from '@tensorflow/tfjs-node';
import { buildClassifier, ModelConfig } from './models/classifier';
import { DataPreprocessor } from './preprocessing';
import * as fs from 'fs/promises';
import * as path from 'path';

interface TrainingResult {
finalAccuracy: number;
finalLoss: number;
epochsRun: number;
modelPath: string;
}

export async function trainModel(
dataPath: string,
config: ModelConfig,
outputDir: string
): Promise<TrainingResult> {
// Load and preprocess data
const rawData = await loadCSV(dataPath);
const features = rawData.map((row) => row.slice(0, config.inputSize));
const labels = rawData.map((row) => row[config.inputSize]);

const preprocessor = new DataPreprocessor();
preprocessor.computeStats(features);
const normalizedFeatures = preprocessor.normalize(features);

const encodedLabels = preprocessor.encodeLabels(labels, config.numClasses);

const split = preprocessor.split(normalizedFeatures, labels);

const trainXTensor = tf.tensor2d(split.trainX);
const trainYTensor = tf.tensor2d(
preprocessor.encodeLabels(split.trainY, config.numClasses)
);
const valXTensor = tf.tensor2d(split.valX);
const valYTensor = tf.tensor2d(
preprocessor.encodeLabels(split.valY, config.numClasses)
);

// Build model
const model = buildClassifier(config);

// Train with callbacks
const history = await model.fit(trainXTensor, trainYTensor, {
epochs: 100,
batchSize: 32,
validationData: [valXTensor, valYTensor],
shuffle: true,
callbacks: [
tf.callbacks.earlyStopping({ monitor: 'val_loss', patience: 10, minDelta: 0.001, restoreBestWeight: true }),
{
onEpochEnd: async (epoch, logs) => {
if (epoch > 0 && epoch % 20 === 0) {
console.log(`Epoch ${epoch}: Consider reducing learning rate`);
}
console.log(`Epoch ${epoch + 1}: loss=${logs?.loss?.toFixed(4)}, acc=${logs?.acc?.toFixed(4)}, val_loss=${logs?.val_loss?.toFixed(4)}, val_acc=${logs?.val_acc?.toFixed(4)}`);
},
},
],
});

// Save model and preprocessor stats
const modelPath = path.join(outputDir, 'model');
await model.save(`file://${modelPath}`);
await fs.writeFile(path.join(outputDir, 'preprocessor-stats.json'), JSON.stringify(preprocessor.getStats(), null, 2));

// Cleanup tensors
[trainXTensor, trainYTensor, valXTensor, valYTensor].forEach((t) => t.dispose());

const lastEpoch = history.epoch.length;
const finalAccuracy = history.history.val_acc?.[lastEpoch - 1] ?? 0;
const finalLoss = history.history.val_loss?.[lastEpoch - 1] ?? 0;

console.log(`\nTraining complete after ${lastEpoch} epochs`);
console.log(`Best validation accuracy: ${finalAccuracy.toFixed(4)}`);
console.log(`Model saved to: ${modelPath}`);

return { finalAccuracy, finalLoss, epochsRun: lastEpoch, modelPath };
}

async function loadCSV(filePath: string): Promise<number[][]> {
const lines = (await fs.readFile(filePath, 'utf-8')).trim().split('\n');
const header = lines[0].split(',').length;
return lines.slice(1)
.map((line) => line.split(',').map((v) => parseFloat(v.trim())))
.filter((row) => row.length === header && row.every((v) => !isNaN(v)));
}
tipp

Wenn das Training zu lange dauert, bitten Sie Cursor, den Engpass zu profilieren. Ein Prompt wie „Analysiere mein Trainingsskript auf Performance-Probleme. Prüfe auf Tensor-Speicherlecks, unnötige synchrone Operationen und Daten-Lade-Engpässe" identifiziert Probleme wie nicht freigegebene Tensoren, die Speicherdruck und Verlangsamung verursachen.

warnung

TensorFlow.js-Tensoren werden nicht Garbage Collected. Jeder Tensor, den Sie erstellen, bleibt im Speicher, bis Sie .dispose() aufrufen oder ihn in tf.tidy() wrappen. In einer Trainingsschleife verursacht das Erstellen von Tensoren ohne Freigabe ein Anwachsen des Speichers bis zum Absturz des Prozesses. Geben Sie Tensoren nach der Verwendung immer frei und verwenden Sie tf.tidy() für kurzlebige Berechnungen.

Modellevaluierung​

Evaluierung geht über Genauigkeit hinaus. Cursor generiert umfassenden Evaluierungs-Code, der mehrere Metriken berechnet und Ergebnisse visualisiert.

Evaluierungsmetriken​

// src/evaluate.ts
import * as tf from '@tensorflow/tfjs-node';
import { DataPreprocessor } from './preprocessing';

export interface EvaluationResult {
accuracy: number;
precision: number;
recall: number;
f1Score: number;
confusionMatrix: number[][];
perClassMetrics: Array<{
class: number;
precision: number;
recall: number;
f1: number;
support: number;
}>;
}

export async function evaluateModel(
model: tf.LayersModel,
testX: number[][],
testY: number[],
numClasses: number,
preprocessor: DataPreprocessor
): Promise<EvaluationResult> {
const inputTensor = tf.tensor2d(preprocessor.normalize(testX));
const predictions = model.predict(inputTensor) as tf.Tensor;
const predicted = predictions.argMax(1).dataSync();
const actual = tf.tensor1d(testY).dataSync();

// Build confusion matrix
const confusionMatrix: number[][] = Array.from({ length: numClasses }, () => new Array(numClasses).fill(0));
for (let i = 0; i < predicted.length; i++) confusionMatrix[actual[i]][predicted[i]]++;

// Per-class metrics
const perClassMetrics: EvaluationResult['perClassMetrics'] = [];
let totalCorrect = 0;
let totalSamples = 0;

for (let c = 0; c < numClasses; c++) {
const tp = confusionMatrix[c][c];
const fp = confusionMatrix.reduce((sum, row, idx) => sum + (idx !== c ? row[c] : 0), 0);
const fn = confusionMatrix[c].reduce((sum, val, idx) => sum + (idx !== c ? val : 0), 0);
const support = confusionMatrix[c].reduce((a, b) => a + b, 0);

const precision = tp + fp > 0 ? tp / (tp + fp) : 0;
const recall = tp + fn > 0 ? tp / (tp + fn) : 0;
const f1 = precision + recall > 0 ? (2 * precision * recall) / (precision + recall) : 0;

perClassMetrics.push({ class: c, precision, recall, f1, support });
totalCorrect += tp;
totalSamples += support;
}

// Macro-averaged metrics
const macroPrecision = perClassMetrics.reduce((sum, m) => sum + m.precision, 0) / numClasses;
const macroRecall = perClassMetrics.reduce((sum, m) => sum + m.recall, 0) / numClasses;
const macroF1 = perClassMetrics.reduce((sum, m) => sum + m.f1, 0) / numClasses;

inputTensor.dispose();
predictions.dispose();

return {
accuracy: totalCorrect / totalSamples,
precision: macroPrecision,
recall: macroRecall,
f1Score: macroF1,
confusionMatrix,
perClassMetrics,
};
}

export function printEvaluation(result: EvaluationResult): void {
console.log('\n=== Model Evaluation ===\n');
console.log(`Accuracy: ${(result.accuracy * 100).toFixed(2)}%`);
console.log(`Precision: ${(result.precision * 100).toFixed(2)}%`);
console.log(`Recall: ${(result.recall * 100).toFixed(2)}%`);
console.log(`F1-Score: ${(result.f1Score * 100).toFixed(2)}%`);

console.log('\nPer-Class Metrics:');
console.log('Class | Precision | Recall | F1 | Support');
result.perClassMetrics.forEach((m) => {
console.log(` ${m.class} | ${(m.precision * 100).toFixed(1)}% | ${(m.recall * 100).toFixed(1)}% | ${(m.f1 * 100).toFixed(1)}% | ${m.support}`);
});

console.log('\nConfusion Matrix:');
result.confusionMatrix.forEach((row, i) => {
console.log(` ${i}: ` + row.join(' '));
});
}
tipp

Bitten Sie Cursor, einen textbasierten Confusion-Matrix-Visualisierer und einen HTML-Bericht zu generieren. Ein Prompt wie „Erstelle ein HTML-Template, das die Evaluierungsergebnisse als gestylten Bericht mit einer Confusion-Matrix-Heatmap, Balken für Metriken pro Klasse und einer Zusammenfassungstabelle rendert" gibt Ihnen teilbare Evaluierungsberichte für Stakeholder.

ONNX Runtime für plattformübergreifende Inferenz​

ONNX (Open Neural Network Exchange) ist ein Standardformat zur Darstellung von ML-Modellen, das auf vielen Plattformen läuft. Konvertieren Sie Ihr TensorFlow.js-Modell zu ONNX und führen Sie Inferenz im Browser, auf Mobilgeräten oder auf Edge-Geräten aus.

Konvertierung zu ONNX​

# scripts/convert_to_onnx.py
# Run this script to convert a saved TF model to ONNX format
import tensorflow as tf
import tf2onnx
import onnxruntime as ort
import numpy as np

# Load the saved TensorFlow model
model = tf.keras.models.load_model('models/saved_model')

# Convert to ONNX
spec = (tf.TensorSpec((None, 8), tf.float32, name='input'),)
onnx_model, _ = tf2onnx.convert.from_keras(model, input_signature=spec, opset=15)

# Save the ONNX model
with open('models/model.onnx', 'wb') as f:
f.write(onnx_model.SerializeToString())

# Verify with ONNX Runtime
session = ort.InferenceSession('models/model.onnx')
print(f"ONNX model inputs: {session.get_inputs()[0].name}")
print(f"ONNX model outputs: {[o.name for o in session.get_outputs()]}")

# Quick sanity check with dummy data
dummy_input = np.random.randn(1, 8).astype(np.float32)
result = session.run(None, {'input': dummy_input})
print(f"Test inference output shape: {result[0].shape}")

ONNX-Inferenz im Browser ausführen​

// src/predict.ts
import * as ort from 'onnxruntime-web';

export interface PredictionResult {
predictedClass: number;
confidence: number;
probabilities: number[];
}

export class OnnxPredictor {
private session: ort.InferenceSession | null = null;
private inputName: string = '';
private outputName: string = '';

async loadModel(modelPath: string): Promise<void> {
this.session = await ort.InferenceSession.create(modelPath, {
executionProviders: ['wasm'],
graphOptimizationLevel: 'all',
});

this.inputName = this.session.inputNames[0];
this.outputName = this.session.outputNames[0];
}

async predict(features: number[], mean: number[], std: number[]): Promise<PredictionResult> {
if (!this.session) throw new Error('Model not loaded. Call loadModel() first.');

// Normalize input
const normalized = features.map((val, i) => (val - mean[i]) / std[i]);

// Create ONNX tensor
const input = new ort.Tensor('float32', Float32Array.from(normalized), [1, normalized.length]);

// Run inference
const outputs = await this.session.run({ [this.inputName]: input });
const output = outputs[this.outputName];

// Convert to probabilities
const probabilities = Array.from(output.data as Float32Array);
const maxIndex = probabilities.indexOf(Math.max(...probabilities));

return {
predictedClass: maxIndex,
confidence: probabilities[maxIndex],
probabilities,
};
}
}
tipp

Verwenden Sie beim Laden von ONNX-Modellen im Browser onnxruntime-web mit dem wasm-Execution-Provider. Der webgl-Provider ist schneller, hat jedoch Kompatibilitätsprobleme mit einigen Modellarchitekturen. Bitten Sie Cursor, beide Provider auf Ihrem spezifischen Modell zu benchmarken und den besten zu empfehlen.

warnung

ONNX-Modelldateien können groß sein (10 MB bis 500 MB). Das Laden im Browser blockiert den UI-Thread. Verwenden Sie immer einen Web Worker für ONNX-Inferenz, um Ihre Anwendung ansprechend zu halten. Bitten Sie Cursor, den Prädiktor in einen Worker mit Message-Passing-API zu wrappen.

KI-gestützte ML-Pipeline-Generierung​

Die mächtigste ML-Funktion von Cursor ist die Generierung ganzer Training-Pipelines aus einer Naturalsprachbeschreibung. Beschreiben Sie Ihr Problem, und Cursor produziert den vollständigen Code-Stack.

Eine vollständige Pipeline generieren​

Create a complete machine learning pipeline for customer churn prediction:
1. Load a CSV with columns: tenure, monthlyCharges, totalCharges, contractType, internetService, churn
2. Handle missing values in totalCharges (impute median)
3. One-hot encode contractType and internetService
4. Normalize all numeric features with Z-score
5. Split 70/15/15 train/val/test
6. Build a dense neural network with 3 hidden layers (64, 32, 16) and dropout
7. Train with Adam optimizer, binary crossentropy loss, early stopping
8. Evaluate with accuracy, precision, recall, F1, and confusion matrix
9. Save the model and preprocessor stats
10. Export to ONNX format

Write all code in TypeScript using @tensorflow/tfjs-node.

Cursor generiert die vollständige Pipeline in mehreren Dateien, verbunden und einsatzbereit. Dies entspricht dem manuellen Schreiben von 500+ Zeilen Boilerplate-Code.

tipp

Iterieren Sie Ihre Pipeline, indem Sie Cursor bitten, spezifische Teile zu modifizieren. Zum Beispiel: „Ändere die Modellarchitektur, um BatchNorm vor jeder Dense-Schicht zu verwenden" oder „Füge Klassengewichtsausgleich hinzu, da die Churn-Klasse nur 20 % der Daten ausmacht." Dieser inkrementelle Ansatz lässt Sie schnell experimentieren, ohne die gesamte Pipeline neu zu schreiben.

Modell-Deployment-Muster​

ONNX-Modelldateien können groß sein (10 MB bis 500 MB). Das Laden im Browser blockiert den UI-Thread. Verwenden Sie immer einen Web Worker für Inferenz, um die Anwendung ansprechend zu halten.

Browser-Inferenz mit einem Web Worker​

// src/worker/inference-worker.ts
import { OnnxPredictor } from '../lib/predict';

let predictor: OnnxPredictor | null = null;

self.onmessage = async (event: MessageEvent) => {
const { type, modelPath, features, stats } = event.data;
if (type === 'load' && modelPath) {
predictor = new OnnxPredictor();
await predictor.loadModel(modelPath);
self.postMessage({ type: 'loaded' });
} else if (type === 'predict' && features && stats && predictor) {
const result = await predictor.predict(features, stats.mean, stats.std);
self.postMessage({ type: 'result', result });
}
};

Den Worker im Main Thread verwenden​

// src/lib/inference-client.ts
import { PredictionResult } from './predict';

export class InferenceClient {
private worker = new Worker(new URL('../worker/inference-worker.ts', import.meta.url));

async loadModel(modelPath: string): Promise<void> {
return new Promise((resolve) => {
const handler = () => { this.worker.removeEventListener('message', handler); resolve(); };
this.worker.addEventListener('message', handler);
this.worker.postMessage({ type: 'load', modelPath });
});
}

async predict(features: number[], stats: { mean: number[]; std: number[] }): Promise<PredictionResult> {
return new Promise((resolve) => {
const handler = (event: MessageEvent) => {
if (event.data.type === 'result') {
this.worker.removeEventListener('message', handler);
resolve(event.data.result);
}
};
this.worker.addEventListener('message', handler);
this.worker.postMessage({ type: 'predict', features, stats });
});
}
}
tipp

Bitten Sie Cursor, eine vollständige React-Komponente zu generieren, die das ONNX-Modell in einem Worker lädt, Benutzereingaben über ein Formular akzeptiert, Inferenz ausführt und die Vorhersage mit einem Konfidenzbalken anzeigt. Dieses End-to-End-Muster demonstriert den vollständigen Deployment-Workflow von Modelldatei zu benutzersichtbarer UI.

Zusammenfassung​

Machine Learning in Cursor bringt den vollständigen ML-Lebenszyklus in einen einzigen KI-gestützten IDE-Editor. Mit den Mustern dieses Leitfadens — strukturierte Datenpräverarbeitung, gut architeturierte TensorFlow.js-Modelle, umfassende Evaluierungsmetriken, plattformübergreifendes ONNX-Deployment und KI-gestützte Pipeline-Generierung — können Sie ein Machine-Learning-Projekt schneller als je zuvor von der Konzeption zur Produktion bringen. Denken Sie daran, den Tensor-Speicher sorgfältig zu verwalten, immer mit mehreren Metriken jenseits der Genauigkeit zu evaluieren, und lassen Sie Cursor Ihr Boilerplate generieren, damit Sie sich auf Modellarchitektur und Datenqualität konzentrieren können.