UNPKG

@astermind/astermind-premium

Version:

Astermind Premium - Premium ML Toolkit

105 lines 4 kB
// elm-kelm-cascade.ts — ELM-KELM Cascade // ELM feature extraction → KELM classification import { ELM, KernelELM } from '@astermind/astermind-elm'; import { requireLicense } from '../core/license.js'; /** * ELM-KELM Cascade * Features: * - ELM for feature extraction * - KELM for classification * - Hierarchical learning * - Efficiency + accuracy */ export class ELMKELMCascade { constructor(options) { this.trained = false; requireLicense(); // Premium feature - requires valid license this.categories = options.categories; this.options = { categories: options.categories, elmHiddenUnits: options.elmHiddenUnits ?? 256, kelmKernel: options.kelmKernel ?? 'rbf', kelmGamma: options.kelmGamma ?? 1.0, kelmDegree: options.kelmDegree ?? 2, kelmCoef0: options.kelmCoef0 ?? 0, activation: options.activation ?? 'relu', maxLen: options.maxLen ?? 100, useTokenizer: options.useTokenizer ?? true, }; // Initialize ELM for feature extraction this.elm = new ELM({ useTokenizer: this.options.useTokenizer ? true : undefined, hiddenUnits: this.options.elmHiddenUnits, categories: [], // No categories for feature extraction maxLen: this.options.maxLen, activation: this.options.activation, }); // Initialize KELM for classification this.kelm = new KernelELM({ useTokenizer: false, // Already tokenized by ELM categories: this.options.categories, maxLen: undefined, kernel: this.options.kelmKernel, gamma: this.options.kelmGamma, degree: this.options.kelmDegree, coef0: this.options.kelmCoef0, }); } /** * Train cascade */ train(X, y) { // Prepare labels const labelIndices = y.map(label => typeof label === 'number' ? label : this.options.categories.indexOf(label)); // Step 1: Train ELM for feature extraction (autoencoder-style) this.elm.trainFromData?.(X, X.map((_, i) => i)); // Self-supervised // Step 2: Extract features using ELM const extractedFeatures = this._extractFeatures(X); // Step 3: Train KELM on extracted features this.kelm.setCategories?.(this.options.categories); this.kelm.trainFromData?.(extractedFeatures, labelIndices); this.trained = true; } /** * Extract features using ELM */ _extractFeatures(X) { const features = []; for (const x of X) { // Get hidden layer activations as features const logits = this.elm.predictLogitsFromVector?.(x) || []; features.push(logits.length > 0 ? logits : x); // Fallback to input if no logits } return features; } /** * Predict with cascade */ predict(X, topK = 3, returnFeatures = false) { if (!this.trained) { throw new Error('Model must be trained before prediction'); } const XArray = Array.isArray(X[0]) ? X : [X]; const results = []; for (const x of XArray) { // Step 1: Extract features const extractedFeatures = this._extractFeatures([x])[0]; // Step 2: Classify with KELM const preds = this.kelm.predictFromVector?.([extractedFeatures], topK) || []; for (const pred of preds.slice(0, topK)) { const result = { label: pred.label || this.options.categories[pred.index || 0], prob: pred.prob || 0, }; if (returnFeatures) { result.extractedFeatures = [...extractedFeatures]; } results.push(result); } } return results; } } //# sourceMappingURL=elm-kelm-cascade.js.map