Kernel Classifier Predictor — Machine Learning/Classical Models
Machine_Learning/Classical_Models/Kernel_Classifier_Predictor · 1 input / 2 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Kernel Classifier Predictor
Machine Learning / Classical Models
Evaluates a fitted binary kernel classifier at inference – what MATLAB's
[label, score] = predict(Mdl, x) returns for a
ClassificationKernel model (trained with fitckernel) and one
observation. Such a model is a linear classifier on a random feature expansion
of x that approximates a Gaussian kernel:
xs = (x − Mu) ./ Sigma (only for a model trained with
'Standardize', true), f = Σc
Betac·zc(xs) + Bias, score = [ T(−f) ;
T(f) ], label = ClassNames(2) when score(2) > score(1),
ClassNames(1) otherwise – where T is the model's score transform and z is
MATLAB's Fastfood expansion: for each Hadamard block i, Ti =
H(H(xs·Si)·Gi permuted by Pi)·Bi·√2/(KernelScale·√o),
with H the Walsh–Hadamard transform of order o = 2⌈log2 D⌉ (x
zero-padded to o entries), and the columns [cos T1, sin T1,
cos T2, sin T2, …] cut to the first n = numel(Beta) and
each scaled by 1/√(o·b). This is not the kernel SVM of
SVM Predictor: there are no support vectors, only the explicit expansion.
The model is baked in as configuration. MATLAB keeps most of its numbers out of the
model's public properties, and publishes them through
saveLearnerForCoder(Mdl, 'kmdl'); then s =
load('kmdl.mat').compactStruct holds every one below.
Ports
- x – one observation, a column [D,1] with one predictor per row, in the order the model was trained on. D decides the Hadamard order o, which must match the feature maps' width; at most 8 predictors.
- label – the predicted class, a scalar [1,1]: one of the two Class Names, as a number.
- score – the two class scores, a column [2,1] in Class Names order: row 1 is T(−f), the first class's score, and row 2 is T(f), the second class's. MATLAB returns the same pair as a row.
Parameters
- Feature Map S – the Fastfood scaling matrix, [b,o], one row per
Hadamard block:
s.FeatureMapper.S. - Feature Map G – the Gaussian scaling matrix, [b,o]:
s.FeatureMapper.G. - Feature Map B – the random signs, [b,o]:
s.FeatureMapper.B. - Feature Map P – the permutations, [b,o], each row a permutation of
1…o (one-based, as MATLAB saves it):
double(s.FeatureMapper.P). - Kernel Scale – the model's
KernelScale, a positive number (the resolved value when the model was fitted with'auto'). - Beta – the linear coefficients, one per expanded feature, [n,1]:
s.Impl.Beta. n is the model'sNumExpansionDimensions, at most 256, and it must need exactly b = ⌈n/(2o)⌉ Hadamard blocks – the four feature maps and Beta come from the same model. - Bias – the intercept, a scalar:
s.Impl.Bias. Added after the sum. - Mu – the predictor means, [1,D]:
Mdl.Mu. [] (the default) for a model trained without'Standardize', whose Mu is empty. - Sigma – the predictor standard deviations, [1,D]:
Mdl.Sigma, or [] with Mu. As in MATLAB, a predictor whose Sigma is 0 is centred and not divided. - Class Names – the two class labels as numbers, in the model's own
order:
Mdl.ClassNames, copied as it is. The second is the class whose score is T(f), whatever order the names are in. The two must differ. Text or categorical labels are not numbers: use their positions, [1 2], and map them downstream. - Score Transform – T, the model's
ScoreTransform, spelled as MATLAB spells it.fitckernelsets logit for a logistic learner and none for an SVM learner. All eight act on the pair [−f, f]:- none – T(z) = z. The default.
- logit – 1/(1 + e−z), a probability.
- doublelogit – 1/(1 + e−2z); on a two-class pair also exactly what softmax gives.
- symmetric – 2z − 1.
- symmetriclogit – 2/(1 + e−z) − 1.
- sign – −1, 0 or +1 by the sign of z.
- ismax – 1 for the larger of the pair and 0 for the other; on a tie the first gets the 1.
- symmetricismax – as ismax, with −1 in place of 0.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The whole model is baked into the body at export time; there is no tunable parameter, so a refitted model means a re-export. The feature map is linear in x up to the cosine, so it is folded at export into one dense [D,o·b] matrix and every target writes the sum out term by term – D multiply-adds, one cosine and one sine per column pair. That is why D and n are capped: the limits bound the size of the generated code, not the math.
On the three HDL targets f is simulation-only real arithmetic: a
cosine has no Q16.16 form to call. f is quantized to Q16.16 once; after that
none, symmetric, sign, ismax and symmetricismax stay
in fixed point, and logit, doublelogit and symmetriclogit are
real again, quantized at the output port.
Simulink bridge
None. Simulink's ClassificationKernel Predict block (Statistics and
Machine Learning Toolbox) exists, but its only model parameter,
TrainedLearner, is the name of a fitted model object in the MATLAB
workspace. That object cannot be built from these numbers –
ClassificationKernel has no public constructor – and a parameter
mapping carries one value to one parameter, so neither direction can cross. The
bridge reports the block rather than dropping it silently, and it has no parity
testbench, which is the documented consequence of that. The arithmetic is checked
against MATLAB's own predict instead, and code export verification covers
all ten languages in every transform. The Simulink block also has no
SampleTime parameter.
Notes
- Algebraic and stateless: the outputs depend only on the current input. Nonlinear, and deliberately carries no state space: the label is a discontinuous function of x.
- The label compares the TRANSFORMED scores, as MATLAB does: at f = 0 exactly every transform ties and the first class wins, and under logit an f within about 10−16 of zero rounds both entries to 0.5 and also gives the first class.
- The label is discontinuous at the boundary, so the three HDL targets, which quantize x to Q16.16, can disagree with the simulation on a sample whose x lies within about one quantum (1.5×10−5) of the decision boundary: the label then differs by the whole distance between the two class names. That is inherent to reducing a continuous quantity to a decision in fixed point, not an export fault; threshold the score output downstream in floating point if an application cannot tolerate it.
- Fastfood only. Every model
fitckernelbuilds uses it – the function has no option to choose another expansion. A model built with the undocumented Kitchen Sinks expansion keeps a matrix W instead of S, G, B and P, and is not carried. - Prior and Cost do not enter the label (MATLAB labels by the first maximum score). MATLAB uses the prior only for an observation holding a NaN, which it labels with the most probable class; here a NaN makes both scores NaN and the label ClassNames(1).
- Binary only.
fitckernelrefuses more than two classes; several classes are an ECOC model of several of these. - Agreement with predict is to rounding, not bit for bit: MATLAB applies the butterflies to each observation, this block applies their product, folded once. The two differ by about 10−15 in f.
Code facts#
| Fact | Value |
|---|---|
| registered type | Machine_Learning/Classical_Models/Kernel_Classifier_Predictor |
| family | Machine_Learning/Classical_Models |
| solver environment class | ICoreBlock_0_Machine_Learning_1_Classical_Models_2_Kernel_Classifier_Predictor |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Classical_Models/Kernel_Classifier_Predictor/ICoreBlock_0_Machine_Learning_1_Classical_Models_2_Kernel_Classifier_Predictor.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Classical_Models/Kernel_Classifier_Predictor/ICoreBlock_0_Machine_Learning_1_Classical_Models_2_Kernel_Classifier_Predictor.h |
| default size on canvas | 140 × 90 px |
| ports at insert | 1 in, 2 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | x |
| 2 | out | ICoreDouble | label |
| 3 | out | ICoreDouble | score |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Feature Map S | [1.4757635231040345 1.6883042579174161;1.385864207018217 … | — |
Feature Map G | [-1.0737486266556295 0.18529993573268261;0.13380297726795… | — |
Feature Map B | [-1 1;1 1] | — |
Feature Map P | [1 2;1 2] | — |
Kernel Scale | 1 | — |
Beta | [1.4045311597837895;1.5606718928879124;-0.301811747498746… | — |
Bias | -5.9357843354941267 | — |
Mu | [] | — |
Sigma | [] | — |
Class Names | [-1 1] | — |
Score Transform | none%~%logit%~%doublelogit%~%symmetric%~%symmetriclogit%~… | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no bridge: Simulink's ClassificationKernel Predict block (statsLibrary) takes its model as TrainedLearner, the NAME of a fitted ClassificationKernel object in the MATLAB workspace, and ClassificationKernel has no public constructor -- no parameter mapping can build that object from the feature maps, Beta, Bias, the class names and the score transform, or read them back out of a variable name
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0every stimulus in the sample errored — cross-checks skipped
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Kernel Classifier Predictor — a fitted binary MATLAB ClassificationKernel model at inference xs = (x - Mu) ./ Sigma only for a model trained with Standardize f = SUM_c Beta_c * z_c(xs) + Bias z = MATLAB's Fastfood feature expansion score = [ T(-f) ; T(f) ] T = ScoreTransform, applied element by element label = ClassNames(2) if score(2) > score(1), else ClassNames(1)
f -- reading the model, the dense form of the feature map, the reference sum and its ten emitted forms -- comes from ICoreRandomFeatureSupport, shared with Kernel_Regression_Predictor. Everything after f is a linear classifier's, and was read out of R2026a's ClassificationKernel.m and then measured:
- scoreWithoutDataChecks maps x, takes LinearImpl.score (Xm*Beta + Bias), and
expandLinearMdlScoreForEachClass fills every class column with -f and overwrites the column of the SECOND class -- ClassNames(2) in the model's own order -- with f. Measured: with 'ClassNames', [5 2] the column carrying f is 2's.
- LabelPredictor is ClassificationModel.maxScore (makeNoFit sets it), and fitckernel with a
Cost matrix still labels by the first maximum of the transformed pair: 0 differences. Under all eight transforms the label equals the first maximum of predict's own scores.
- The logistic learner sets ScoreTransform 'logit'; the svm learner leaves 'none'.
The transform table and its ten spellings are Linear_Classifier_Predictor's (whose measurements of the tie and the 1.1e-16 logit case apply unchanged: the pair after f is the same function), copied rather than shared because that block keeps them private and a change to a helper other blocks use widens its blast radius to every one of them.
Sample results#
No stimulus produced a sampled output in this rig — Invalid model at: ICore Blocks/Home/Kernel Classifier Predictor. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.
Category unsampled · sample time 0.1 · 60 steps · commit 23d8841c6561ca4bb64cd9b5b64da9638de12629 · produced by docsSample --out <folder> --blocks Fixed_Wing_Point_Mass Kernel_Classifier_Predictor Kernel_Regression_Predictor Rotor Rotor_With_Flap_Effects Multirotor Multirotor_With_Flap_Effects Dynamic_Inflow_3_State Kurtogram Empirical_Mode_Decomposition Modal_FRF Order_Spectrum --steps 60
Sample data: docs/generated/samples/Machine_Learning__Classical_Models__Kernel_Classifier_Predictor.json