更换 AI 之前,先检查它测到了什么
系统报告房间比平时更热。负责人发现警报增多,想重新训练模型。但变化可能来自房间、传感器,或转换读数的软件。如何在把时间花到错误问题之前分辨原因?我们将通过完整数值算例,理解什么时候应先检查传感器,再考虑更新 AI,以及决策需要哪些信息。
案例完全合成:温度和参考值都是作者选择的数字,不是仪器读数。未测试微控制器、传感器、AI 模型或报警系统。实际执行的代码估计参考值与读数间的简单关系,求逆,并检查另外四个值。它不是认证程序,也不证明设备性能。所有结果都会保留计算与测量的区别。
单次读数不能独自说明原因
假设读数为 22 °C。在世界 A,真实温度是 20 °C,仪器加上恒定的 2 °C 误差。在世界 B,真实温度确为 22 °C,仪器没有额外偏差。观测数字完全相同。只收到这个数字的算法,在没有其他假设或信息时无法区分两个世界。这不是训练缺陷,而是信息不足,即原因不可识别。
独立参考可以打破歧义,但必须在相关条件一致时测量同一量。不同位置的探头可能读到不同温度,却都没有故障。同步、位置和稳定时间都是比较的一部分。独立不等于绝对正确;参考也有不确定性,可能与仪器共享误差。理想算例假定参考值已知,是为了隔离机制,并非声称现场存在这种完美条件。
两种不同的偏差方式
传感器可能总是增加同一偏移,也可能放大变化。为区分二者,采用具有截距 a 和斜率 b 的直线。若参考值和读数均以摄氏度表示,a 的单位为 °C,b 无单位。误差 e 是直线未解释的部分。NIST 将这类模型列为校准模型之一;我们选择仿射情况只是教学假设,并非所有传感器的规律。
代入数值:a=2 °C、b=1.1,在加上小误差 e 之前把 20 °C 变成 24 °C;40 °C 则读为 46 °C。只减两度可修正截距,却留下比例误差:40 度时仍得到 44。只在一个温度点比较,不能充分区分斜率与截距。需要多个水平,并检查该关系在使用范围内是否成立。
构造数据并估计修正
采用五个合成参考值:0、10、20、30、40 °C。每个值按 2+1.1x 生成两次读数,分别加 −0.2 和 +0.2 °C。十个确定性点具有刻意构造的对称性,不是随机样本,也不是重复性试验。代码保留全部点,不删除不方便的观测。这种对称性使参数恢复容易理解,但远比真实校准简单。
选择直线前,先定义“拟合这些点”的含义。最小化竖直偏差平方和,会更强地惩罚大偏差。J 写成 [yᵢ−a−bxᵢ]² 的总和。该准则把 x 当成已知;若参考的不确定性不可忽略,这种选择可能不适当。方法简单,不等于可以忽略实验条件。
后两个表达式来自令 J 对 a、b 的导数为零:一个要求平均残差为零,另一个要求残差与中心化 x 不相关。分母衡量参考值的分散;若参考全相同,分母为零,斜率不可识别。本例均值为 20、24 °C,分子为 2200 °C²,分母为 2000 °C²,得到 b=1.1、a=2 °C,并由程序检查。
从读数到修正值:把问题反过来
此前根据参考值预测仪器读数;实际使用时问的恰好相反:收到的读数对应什么值?对 x 解方程,先减截距,再除斜率。x̂ 表示估计,不是真实值。求逆要求 b 非零。如果 b 很小,除法会放大微小读数误差;漂亮公式不会消除这个问题。
另用未参与估计的 5、15、25、35 °C 四个参考检查计算。按同一关系生成读数,交替加 +0.11、−0.11 °C。首个读数为 7.61,修正为 5.1,仍有 +0.1 °C 误差。四点都在参考范围内,因此不是外推测试。它们与拟合点分开,但不是独立仪器验证。
| 参考 °C | 读数 °C | 修正 °C | 原始误差 °C | 修正误差 °C |
|---|---|---|---|---|
| 5 | 7.61 | 5.1 | 2.61 | 0.1 |
| 15 | 18.39 | 14.9 | 3.39 | -0.1 |
| 25 | 29.61 | 25.1 | 4.61 | 0.1 |
| 35 | 40.39 | 34.9 | 5.39 | -0.1 |
表中各列单位均为 °C;误差定义为估计减参考。另报告平均绝对误差 MAE:绝对值相加后除以四,同时保留单独的带符号误差。原读数 MAE 为 4 °C,修正后为 0.1 °C,代码实际计算了二者。数据构造有利于改进,不能预测真实传感器改进幅度或 AI 模型准确率。

左图每点为读数减参考;偏差随温度增加,与构造的比例误差一致。右图四个检查误差从正的数度变为 ±0.1。两图纵轴尺度相同,便于比较幅度;这不会把四点变成统计分布。若只画读数,看起来几乎完全线性,反而掩盖偏差对决策的重要性。
修正偏差不等于让噪声仪器变精密
偏差是系统性偏离;精密度描述规定条件下重复测量的分散,二者不同。NIST 对校准失败的讨论指出,修正不能解决精密度不足或随时间失控的变化。本例波动由作者设定,小且对称;没有估计日漂移、滞后或湿度依赖。若拟合后物理关系变化,固定修正也会变错。
不应自动删除大偏差。异常读数可能揭示间歇连接、真实变化或参考尚未稳定。排除必须有理由并可追溯。直线本身也需质疑:弯曲残差可能提示非仿射关系。增加参数可更贴合已有点,却不保证新测量可靠。关键比较应使用未参与选择修正的条件和点。
明天偏移变了,旧修正就可能失效
直接检验稳定性假设:给四个检查读数都加 0.55 °C,不重新估计系数。旧修正会把变化也除以 1.1,因此每个估计增加 0.5 °C。误差变为 +0.6、+0.4、+0.6、+0.4 °C,MAE 升到 0.5 °C。这也是构造数据的计算,不是观测漂移。保留修正系数并不代表可以忘记参考比较。
求逆还揭示局部敏感度:固定系数时,读数偏离 0.2 °C,除以 1.1 后估计约偏离 0.1818 °C。这不是测量总不确定性,不包含系数、参考、探头位置或直线有效性的不确定性。把敏感度当成准确度区间,会声称本例没有测到的质量。比较板卡与算法时也应保留这个区别。
运行决策还需要由任务理由支持的容差。描述房间趋势时可接受的偏差,对其他工艺未必适用;这里不设通用阈值。接近决策边界时,应问数值还剩多少不确定性,而非软件打印几位小数。计算可以有很多小数,但物理数据不会因此同样精确。因此结果保留单位与假设,不承诺可直接部署的校准。
嵌入式设备上的决策如何变化
嵌入式表示软件运行在专用设备中,常有内存、能源和时间限制。仿射修正每样本需要一次减法和一次除法,无需重训网络。这描述运算次数,不是实测延迟;硬件上数值表示、库和采集都重要。两个系数不等于系统全部 RAM 需求。没有测量,因此不报告毫秒、瓦或焦耳。
改变修正应用位置,也会改变模型输入的意义。历史数据若已修正,再修正一次会增加错误。模型若在原读数上训练,改变输入尺度会改变决策;应以独立标签重新评价整条链。记录应附带系数版本、单位、有效范围及模型版本。替换两个数后警报减少,并不足以证明有效。
还应比较不用 AI 的方案:对正确测量物理量设置规则,可能足以满足简单需求。反之,校准不能修复温度与工艺结果关系的真实变化。如果传感器与独立参考一致,但新标注案例的预测变差,重训、增加变量或维护工艺才重新成为合理假设。没有普遍答案,证据必须区分测量故障与任务变化。
证明了什么,还缺什么
反例证明单次读数不能识别原因,随后数值检查了对独立合成值的仿射修正。没有证明真实传感器漂移,也没有证明模型需要重训。实际决策是在盲目干预前先获得独立比较。测量改善与最终任务改善是两项不同验证;改变运行链时应分别记录。
真实试验仍需覆盖实际范围、带明确不确定性的参考、跨时间重复及相关环境条件。硬件还应验证转换、数值精度、超范围处理及配置回退。本例不涉及临床决策或安全设备。EL-AI 并非在此被描述为传感器制造商或试验执行方;编辑层面对嵌入式的兴趣,不证明已有产品或安装。
附带代码用 Decimal 精确保留所选十进制输入,创建十对数据,计算均值与总和,估计两个参数,再检查四点和反例。复杂度随数据对数线性增长,保存列表也一样。它不是微控制器库,也不测量设备内存。断言只记录预期算术已经执行,不能替代计量、统计或集成试验。
NIST/SEMATECH e-Handbook — Models for instrument calibration, section 2.3.6.1.
NIST/SEMATECH e-Handbook — Data collection, section 2.3.6.2.
NIST/SEMATECH e-Handbook — What can go wrong with calibration, section 2.3.6.4.
NIST/SEMATECH e-Handbook — Data analysis and model validation, section 2.3.6.5.
NIST/SEMATECH e-Handbook — Linear Least Squares Regression, section 4.1.4.1.
from decimal import Decimal as D
from pathlib import Path
import json,sys
# Entirely synthetic temperatures and reference values, not hardware measurements.
train=[(D(x),D('1.1')*D(x)+D(2)+e) for x in [0,10,20,30,40] for e in [D('-.2'),D('.2')]]
xbar=sum(x for x,y in train)/len(train);ybar=sum(y for x,y in train)/len(train)
b=sum((x-xbar)*(y-ybar) for x,y in train)/sum((x-xbar)**2 for x,y in train)
a=ybar-b*xbar
assert a==2 and b==D('1.1')
test=[]
for x,e in zip([5,15,25,35],[D('.11'),D('-.11'),D('.11'),D('-.11')]):
x=D(x);y=D('1.1')*x+2+e;corrected=(y-a)/b
test.append(dict(referenceC=str(x),readingC=str(y),correctedC=str(corrected),rawErrorC=str(y-x),correctedErrorC=str(corrected-x)))
raw=sum(abs(D(t['rawErrorC'])) for t in test)/len(test)
corrected=sum(abs(D(t['correctedErrorC'])) for t in test)/len(test)
assert raw==4 and corrected==D('.1')
# One reading admits distinct physical explanations without an independent reference.
assert D(20)+2==D(22)+0
shifted=[(D(t['readingC'])+D('.55')-a)/b-D(t['referenceC']) for t in test]
shiftedMAE=sum(abs(e) for e in shifted)/len(shifted)
assert shifted==[D('.6'),D('.4'),D('.6'),D('.4')] and shiftedMAE==D('.5')
assert sum((x-xbar)**2 for x,y in train)==2000
assert sum((x-xbar)*(y-ybar) for x,y in train)==2200
r=dict(shiftedErrorsC=[str(e) for e in shifted],shiftedMAEC=str(shiftedMAE),readingSensitivityForPointTwo=str(D('.2')/b),python=sys.version.split()[0],seed=None,scope='Synthetic affine calibration arithmetic, no hardware, no AI training, no certification or model accuracy benchmark',training=[dict(referenceC=str(x),readingC=str(y)) for x,y in train],interceptC=str(a),slope=str(b),test=test,rawMAEC=str(raw),correctedMAEC=str(corrected),identifiabilityCounterexample=dict(observedC='22',worldA=dict(trueC='20',offsetC='2'),worldB=dict(trueC='22',offsetC='0')))
Path(__file__).with_name('results.json').write_text(json.dumps(r,indent=2),encoding='utf8')
print(json.dumps(r))
代码、数据与说明 · JSON. 教学计算使用 Python 3.14.0,图使用 Matplotlib 3.11.2。分析由 AI 辅助,不声称经过同行评审或人工审核。原创 ImageGen 封面仅作示意,不记录 EL-AI 人员、场所或实际安装。来源查阅于 2026 年 10 月 30 日。

