Generated reference › Update Metrics — Machine Learning/Incremental Learning
kind: generated#block#machine-learning-incremental-learning

Update Metrics — Machine Learning/Incremental Learning

metrics

Machine_Learning/Incremental_Learning/Update_Metrics · 3 input / 2 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++

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.

Update Metrics

Machine Learning / Incremental Learning

Tracks how well an incremental learner is doing, one observation per step: it scores the observation (x, y) with the model on the learner's bus and keeps two values of the chosen Metric – Cumulative, the mean loss over every observation since the model warmed up, and Window, the loss over the most recent Metrics Window Size of them. This is Simulink's Update Metrics block (Statistics and Machine Learning Toolbox), on MATLAB's own arithmetic:

  • Cumulative is the running mean: with n earlier observations, r = 1/n and Cumulative = (Cumulative + loss·r)/(1 + r).
  • Window is the mean of the last Metrics Window Size losses weighted by the model's prior of each one's true class at its step, as MATLAB weights a classifier's observations. It is recomputed each time that many new observations have arrived and held in between.

Today it reads the bus of an IncrementalClassificationNaiveBayes Fit block, scoring with that learner's posterior (as its Predict block does).

Ports

  • mdl (ICoreBus) – the learner's model, from an Incremental Classification Naive Bayes Fit block whose Class Names agree with this block's. The run is refused when the bus is not that shape.
  • x – the observation's P predictors, a row [1,P].
  • y – its class label, [1,1]. A label that is not one of Class Names is left out of both metrics.
  • IsWarm (bool) – the bus's IsWarm: whether the metrics are being tracked yet.
  • metrics – [Cumulative Window], [1,2]. Each reads −1 until it has a value: Cumulative from the first warm step, Window from the step that completes its first window.

Parameters

  • Class Names – the learner's class labels, in the Fit block's order: a row or a column of distinct numbers, at least two.
  • Metric – the loss of one observation, from the true class's score sy (its posterior probability):
    • classiferror (the default) – 1 when y is not the class with the largest score, else 0.
    • mincost – the minimal expected misclassification cost, 1 − the largest score.
    • binodeviance – log(1 + e−2sy).
    • exponential – e−sy.
    • hinge – max(0, 1 − sy).
    • logit – log(1 + e−sy).
    • quadratic – (1 − sy)².
  • Metrics Window Size – how many observations the Window covers, a whole number, 1 or more: MATLAB's MetricsWindowSize, default 200.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

When a run is refused

x that is not a row, y that is not a scalar, Class Names that are not distinct finite numbers, a window that is not a whole number of 1 or more, or a bus that is not the Naive Bayes learner's for those classes and predictors.

Code export

Six targets: Python, MATLAB, Java, Rust, C and C++, each keeping the running metric, the observation count and the window's buffer of losses and weights as persistent state, with the chosen Metric and the window size baked in. The hardware targets (VHDL, Verilog, SystemVerilog) and PLC Structured Text carry no bus, so an export to one stops and names the block.

Simulink bridge

None (Support::None). Simulink's block takes its learner as InitialLearner, the name of an incremental learner object in the MATLAB workspace, which has no public constructor a generated script could write, so the bridge reports this block rather than dropping it, and it has no parity testbench. Code export verification covers it in the six targets above.

Notes

  • Stateful and discrete: the running metric, its count and the window's buffer advance once per sample hit, and reset at the start of a run.
  • The model is scored as it is at the observation's own step, after the Fit block has fitted it, as Simulink's diagram does.
  • An observation whose label is not a class, or whose class has a zero prior, is left out of both metrics, as MATLAB leaves it out.
  • ⚠ Measured on R2026a: placing Simulink's Update Metrics beside a Fit block changes that Fit block's model (its deviations move off the population values), so the metrics Simulink then reports are of a different model. This block reads its inputs and changes nothing else; its numbers match the learner object's own updateMetrics. For mincost it reports what Simulink's block reports, the minimal expected cost; the object reports the 0/1 cost of the predicted class instead.
  • Only the Naive Bayes learner's bus is read today; the linear and kernel learners' buses join when their Fit blocks do. Simulink's weights and reset inputs and its Observations In option are not offered: one observation, in a row, per step.

Code facts#

FactValue
registered typeMachine_Learning/Incremental_Learning/Update_Metrics
familyMachine_Learning/Incremental_Learning
solver environment classICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Update_Metrics
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Incremental_Learning/Update_Metrics/ICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Update_Metrics.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Incremental_Learning/Update_Metrics/ICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Update_Metrics.h
default size on canvas150 × 90 px
ports at insert3 in, 2 out
code generators implementedPython, MATLAB, Java, Rust, C, C++

Ports#

#DirectionSignal typeDescription label
1inICoreBusmdl
2inICoreDoublex
3inICoreDoubley
4outICoreBoolIsWarm
5outICoreDoublemetrics

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 variableDefaultSimulink parameter
Class Names[1 2 3]—
Metricmincost%~%classiferror%~%binodeviance%~%exponential%~%hin…—
Metrics Window Size200—

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.

supportSupport::None
Simulink path—
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): Simulink's Update Metrics takes its learner as InitialLearner, the name of an incremental learner object in the MATLAB workspace, which has no public constructor a generated script could write; the block is reported rather than dropped

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:

  • B0 every 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).

Update Metrics -- the running performance of an incremental learner, from its model bus statsIncremental/Update Metrics, MEASURED on R2026a 2026-10-03 (BLOCKS_TO_ADD_TOOLBOXES.md statsIncremental, on FEATURES_TO_ADD.md BF1): three inputs (the learner's bus, x, y), two outputs (IsWarm, and metrics = [Cumulative Window]); one popup, Metric. Simulink's block takes its learner as InitialLearner, from which it reads the class names and MetricsWindowSize; here those are configs. TODAY IT READS THE IncrementalClassificationNaiveBayes BUS -- the one learner bus in the tree -- and refuses any other by name; the linear and kernel learners' buses join when their Fit blocks land.

WHAT EACH STEP DOES, transcribed from R2026a's own implementation (toolbox/stats/incremental/+incremental/+coder/Learner.m: updateCumulativeMetrics and updateWindowMetrics; +classif/ClassificationModel.m: adjustWeights) and checked over a 30-step run in all seven metrics against the learner object's fit() and updateMetrics() (the paragraph at the end says why not against the block's diagram):

  • Nothing is measured until the bus says IsWarm; both metrics read -1 until then, and the

IsWarm output is the bus's.

  • The observation is scored by the bus's model as it is AT THIS STEP -- the Fit block has

already fitted it -- with the Predict block's posterior, and its loss is the chosen metric of the true class's score s_y: classiferror (y is not the first largest score), mincost (1 - the largest score, the minimal expected cost under MATLAB's default cost), binodeviance log(1 + e^(-2 s_y)), exponential e^(-s_y), hinge max(0, 1 - s_y), logit log(1 + e^(-s_y)), quadratic (1 - s_y)^2.

  • Cumulative is the running mean, kept as MATLAB keeps it: with n earlier observations,

r = 1/n and Cumulative = (Cumulative + loss*r) / (1 + r).

  • Window is a WEIGHTED mean of the last Metrics Window Size losses, the weight of each being

the model's Prior of its true class at its step (adjustWeights: one observation of class y gets prior(y)/1). It is recomputed only when that many new observations have arrived, and HELD in between -- so with a window of 5 it moves on the 5th, 10th, ... warm observation. With weights all equal it would be the plain mean; with this learner's moving prior it is not (0.39981 where two errors in five would read 0.4).

  • An observation whose label is not a class, whose scores are all NaN, or whose class has a

zero prior is left out of both, as R2026a leaves it out.

⚠ MEASURED AND NOT COPIED: IN R2026a, PLACING THIS BLOCK BESIDE A FIT BLOCK CORRUPTS THE FIT BLOCK'S BUS. The same IncrementalClassificationNaiveBayes Fit block, on the same 30 observations, reports class 3's deviations as [0.4554 0.5533] -- the population values -- alone, and as [0.5533 0.6726] with an Update Metrics block in the diagram; the two masks' Data Store Memories evidently collide. Every metric R2026a's diagram then reports is a metric of a wrong model. This block reads its inputs and writes its outputs and touches nothing else, and its reference is the learner object's own fit() and updateMetrics() (suite incremental_naive_bayes). The one place

Sample results#

No stimulus produced a sampled output in this rig — Incorrect bus shape reaching port: ICore Blocks/Home/Update Metrics/ICoreBus-In-0 requires { DistrMean: ICoreDouble [3x1], DistrStd: ICoreDouble [3x1], Prior: ICoreDouble [3x1], CanPredict: ICoreBool [1x1], IsWarm: ICoreBool [1x1], MajorityClass: ICoreUInt16 [1x1] }, ICore Blocks/Home/Bus Creator/ICoreBus-Out-0 carries { a: ICoreDouble [1x1], b: ICoreDouble [1x1] }. 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 09c5f64bf · produced by docsSample --out <folder> --blocks Update_Metrics --steps 60

Sample data: docs/generated/samples/Machine_Learning__Incremental_Learning__Update_Metrics.json