图像识别拆开只有两步:算一个可比较的数,再定一个阈值。 Demo 用模板相关加阈值,12 条合成样本全判对(TP 6、FP 0、FN 0、TN 6), 但这个 1.000 不能当「模型好」的证据——样本是自己造的。
前五节把环境、数学、代码、特征、数据都过了一遍。 这一节把它们串起来,做一件最小但完整的事:看图分类。
一、两步:打分,切一刀
图像识别的全部流程可以压成两步:把图变成一个可比较的分数,再用一个阈值决定它属于哪一类。 Demo 造了两类 8×8 的小图:车辆(横条加两个轮子)和行人(头身腿)。 给每类加高斯噪声造 12 条样本,然后用「相关系数」当分数——它衡量两张图的形状有多像, 取值在 -1 到 1 之间。 结果:车辆样本与车辆模板的相关在 0.79 到 0.98 之间,与行人模板在 0.05 到 0.17 之间。 差距足够大,所以一刀就分开。 准确率 1.000、精度/召回/F1 都是 1.000、混淆矩阵 TP 6、FP 0、FN 0、TN 6。
二、为什么这个 1.000 不算数
因为样本是我造的、噪声是我加的、模板也是我从样本里平均出来的。三件事都由我控制,结果当然好。 换成真实照片,模板匹配很快就不行:光照一变,像素值整体偏移,相关系数立刻掉;角度一变,形状对不上; 有遮挡,相关系数掉一半。 所以这一节的结论不是「模板匹配能用」,而是流程是这样:图 → 分数 → 阈值 → 判定。 深度学习的区别只在第一步:分数不再是人设计的模板,而是模型自己学出来的特征。 后面第八章的卷积网络讲的就是这件事。
三、相关系数为什么能当分数
相关系数先把两张图各自减去自己的均值,再算「同向变化的程度」。 减去均值这一步很关键:它让整体亮度不再影响结果。 所以一张偏亮的车辆图和一张偏暗的车辆图,相关系数依然很高; 而一张车辆图和一张行人图,无论亮度如何,相关系数都低。 这就是「特征」的含义:把跟任务无关的变化(亮度)消掉,把跟任务有关的变化(形状)留下。 上一节的特征工程,本质是同一件事。
四、动手 Demo:模板相关加一刀,12 条全判对
用 numpy 造两类 8×8 图案(车辆、行人),各加高斯噪声造 12 条样本,从前 6 条样本平均出两个模板, 再用相关系数给每条打分、取大者作为判定,最后算准确率与混淆矩阵。
def corr(a, b):
a = a - a.mean(); b = b - b.mean()
return float((a * b).sum() / (np.sqrt((a * a).sum() * (b * b).sum()) + 1e-9))
pred = [0 if corr(im, tpl[0]) > corr(im, tpl[1]) else 1 for im, _ in samples]
实跑输出:
--------------------------------------------------------------------
图像识别 = 特征 + 一刀切下去
--------------------------------------------------------------------
样本 与车辆模板 与行人模板 判成 真值
-------------------------------------------
#01 0.945 0.021 车辆 车辆
#02 0.128 0.867 行人 行人
#03 0.952 0.041 车辆 车辆
#04 -0.058 0.891 行人 行人
#05 0.922 0.158 车辆 车辆
#06 0.136 0.931 行人 行人
#07 0.902 0.036 车辆 车辆
#08 0.064 0.829 行人 行人
#09 0.925 0.162 车辆 车辆
#10 0.155 0.798 行人 行人
#11 0.792 0.156 车辆 车辆
#12 0.167 0.844 行人 行人
准确率 1.000
精度 / 召回 / F1 1.000 / 1.000 / 1.000
混淆矩阵 TP 6、FP 0、FN 0、TN 6
这里的「特征」就是模板本身,「模型」就是一个相关系数加大于号。
模板是拿前 6 条样本平均出来的,不是真值;但合成图里两类差别够大,
12 条一条没判错。这个 1.000 不能当「模型好」的证据——样本是自己造的。
换成真实照片,模板匹配很快就撑不住:光照、角度、遮挡一变,相关系数就塌了。
深度学习的区别只在第一步:模板不再是人画的,是学出来的。
12 行打分里,车辆样本与车辆模板都在 0.79 以上,与行人模板都在 0.17 以下, 中间空得很宽——所以这一刀怎么切都对。 准确率 1.000、F1 1.000、混淆矩阵 TP 6 / FP 0 / FN 0 / TN 6。 数字漂亮,但我在正文和输出里都写了:样本是造的,不能当证据。 模板是拿前 6 条样本平均出来的,不是「真值模板」。 这一步很关键——真实系统里你也没有真值模板,只能从样本估。 这两个类别的形状差得很远(横条 对 竖条),所以相关系数能分开。 如果两类形状接近(比如轿车对卡车),这个办法立刻就吃力了。
30 秒实验
- 把噪声标准差从 0.30 加到 0.60,看准确率掉到多少。
- 把模板换成「只用 1 条样本」,看结果抖不抖。
- 想一想:为什么「减去均值」这一步能消掉亮度的影响?
常见误区
- 「准确率 1.0 说明方法好」——样本是自己造的,模板也是自己估的。
- 「模板匹配过时了」——小样本、形状固定的场景里它又快又稳。
- 「图像识别很神秘」——拆开就是打分加阈值。
自测三问(点开对答案)
1. 图像识别的两步是什么? —— 把图变成可比较的分数,再用阈值判定。 2. 为什么这个 Demo 的 1.000 不能当证据? —— 样本、噪声、模板全由自己造,没有真实数据检验。 3. 相关系数为什么要先减均值? —— 让整体亮度不再影响结果,只比较形状。基础能力六项讲完。下一节换个角度:这个岗位每天到底在干什么活。
- ☐ (本节完,下一节 2.2.1 AI训练师工作职责:赋予人工智能生命与智慧)