@astermind/astermind-premium
Version:
Astermind Premium - Premium ML Toolkit
105 lines • 4 kB
JavaScript
// 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