下面进行华为2026年6月12日AI岗机考题的复盘和关键知识点(重点)深度剖析,笔者7月9-10日刷完选择题和2道算法题。选择题考到图像匹配、线性代数、PCA主成分分析法、MLE估计、梯度计算、CNN卷积、训练优化器、嵌入层与注意力机制、MHA与GQA/MQA和训推优化、优化理论(凸函数)、大模并行训练等知识点。编程题有机器学习和传统的数据结构与算法的考点,一个是K-Means无监督聚类算法(机器学习,自动驾驶点云聚类-物体识别场景)的题目(评级中等),一个是大模型MoE混合专家架构(Transformer Block内部的MLP,拥有更多的数量和更低的维度)相关的优化算法Expert Choice Routing(ECR)的模拟考点的题目(评级困难)。
说明:文章内选择题证明和论述部分的绿色字体是AI生成内容,红色字体是人工增添或重要修改内容。
目录
[代码题1 (中等)](#代码题1 (中等))
总答题用时:1小时30分钟
选择题
用时24分钟
第一题
图像匹配,正确答案A。

需要先说明哈,这里说余弦相似度"适合度量亮度差异较大的两张图片的内容的相似度"针对的是乘性亮度变化,对于加入一个常量的加性亮度变化一般使用NCC(归一化互相关系数或者Pearson系数),可以规避余弦相似度或者归一化后计算欧氏距离的短板(单调负相关),其实就是零均值化预处理加强版的余弦相似度计算。
学术界和产业界主要有五种图像匹配的方法,按鲁棒性(抗干扰能力)从低到高排序如下:
- 像素级数值度量(对亮度、噪声极其敏感)
这类指标直接计算像素值的绝对误差,不适合你题目中的亮度差异场景。
- MSE(均方误差):计算对应像素点差的平方。亮度整体提升50,MSE会瞬间暴增,导致误判为"完全不像";
- PSNR(峰值信噪比):PSNR=10⋅log10(
) - 曼哈顿距离 / 欧氏距离:同样受数值绝对值影响极大,通常只用于图像压缩或去噪算法的质量评估,而非内容相似度。
- 相关性/线性不变度量
这类指标通过归一化或角度计算,能自动屏蔽亮度和对比度的线性变化。
- 余弦相似度:如上所述,屏蔽整体亮度缩放。在实际图像检索(CBIR)系统中,如果遇到亮度差异大的情况,常规做法是先对图像做直方图均衡化(Histogram Equalization)或归一化处理,然后再提取特征计算余弦相似度。
- 关于直方图均衡化的数字图像处理(DIP)方法,大家可以类比参考随机过程里面非固定λ参数(非齐次)泊松过程和齐次泊松过程的积分转化原则。两个累积分布函数之间形成一对一的单调正相关映射。从而实现颜色亮度分布的重塑。对于彩色图像,RGB三个通道可以设置相同的直方图均衡CDF函数,也可以设置不同的CDF函数。
- NCC(归一化互相关,Normalized Cross-Correlation):这是模板匹配中的经典算法。它不仅去除了均值(加性,亮度偏移),还去除了方差(乘性,对比度拉伸),比余弦相似度更强大,是工业界解决"光照不均"问题的常用手段。
- 结构感知度量(模仿人眼视觉)
这类指标认为像素是有关联的,更看重纹理和结构。
- SSIM(结构相似性指数):它将相似度分解为亮度(L)、对比度(C)和结构(S)三个分量进行比对。虽然它也能处理一定的亮度变化,但它是非线性函数,如果亮度差异极大,SSIM依然会下降,本题语境下不如余弦相似度纯粹。
- 局部特征点匹配(应对旋转、裁剪、遮挡)
当图片发生了旋转、缩放或部分遮挡时,上面的全局指标全部失效。
- SIFT / SURF / ORB:这些算法提取图像中的关键点(如角点、边缘),生成局部特征描述子,然后进行特征点配对。它们对亮度、旋转、尺度都具有极强的鲁棒性,常用于全景拼接、物体空间运动轨迹估计和3D重建(比如Structure From Motion)、图像匹配和检索等领域。
- 深度学习语义度量(应对"内容相同、表象迥异")
这是目前最前沿的方法,适合判断两张图是否属于同一类物体或场景。
- LPIPS(学习感知图像块相似度):利用预训练的深度神经网络(如VGG)提取高层语义特征,在特征空间计算距离。它更关注"猫长什么样"而非"像素颜色",对亮度、纹理变化的容忍度极高。
- DreamSim / CLIP:这类多模态模型甚至能判断"一只狗在草地上的照片"和"一只狗在雪地里的简笔画"是相似的,达到了语义级别的理解。
第十九题
二分类问题(正类和负类)混淆矩阵相关衡量指标,正确答案ABC
一般情况下,召回率和TPR(真阳性率)是一个指标。所以B和C都正确。准确率把正负类样本同时纳入计算,正确答案约为0.94。
关于相关指标,主要有准确率(Accuracy)、精确率(Precision/P)、召回率(Recall/R)、真阳性率(TPR)、假阳性率(FPR)、特异性性比率(阴性检测率,TNR)、F1-Score或Dice系数(
)、适用于多类别分类的宏平均召回率(Macro-Recall)和微平均召回率(Micro-Recall)等。
- TPR(召回率) =
(分母是所有真实正样本) - FPR(假阳性率) =
(分母是所有真实负样本) - FPR=1−特异性比率(TNR)
宏平均召回率和微平均召回率都和各类别(本类别和非本类别,按照二分类处理)的TPR相关。微平均召回率的计算容易受到数据分布中大样本数量的类别的TPR的影响,而宏平均召回率在多个类别中算术平均,和类别信息丰富度无关。具体说明如下:
假设有 A、B、C 三类样本,模型预测结果如下(三分类混淆矩阵):
| 真实 \ 预测 | A类 | B类 | C类 |
|---|---|---|---|
| A类 (100个) | 90 (TP) | 5 | 5 (FN=10) |
| B类 (10个) | 0 | 1 (TP) | 9 (FN=9) |
| C类 (20个) | 0 | 0 | 20 (TP, FN=0) |
首先,分别计算每个类别的 TPR(召回率):
- A类的 TPR = 90 / (90+10) = 0.90
- B类的 TPR = 1 / (1+9) = 0.10
- C类的 TPR = 20 / (20+0) = 1.00
- Micro-Recall(微平均召回率)------ 看"总数"
它先把所有类别的 TP 加起来,所有类别的 FN 加起来,最后只算一次除法。
公式:

- 总 TP = 90 + 1 + 20 = 111
- 总真实样本 = 100 + 10 + 20 = 130
- Micro-Recall = 111 / 130 ≈ 0.85
- Macro-Recall(宏平均召回率)------ 看"平均"
它先把每个类别的 TPR 单独算出来,最后对所有类别的 TPR 取算术平均值。
公式:

- Macro-Recall = (0.90 + 0.10 + 1.00) / 3 ≈ 0.67
代码题1 (中等)
用时23分钟,单考点:K-means聚类(自动驾驶场景),全部AC

python
def code():
import copy
N, K = map(int, input().split())
data = []
for i in range(N):
data.append(list(map(float, input().split())))
initial_centers = list(range(K))
centers = [data[ic][:] for ic in initial_centers]
clusters = {i: [] for i in range(K)}
for e in range(100):
clusters = {i: [] for i in range(K)}
last_centers = copy.deepcopy(centers)
for n in range(N):
dists = []
min_id = 0
for c in centers:
dists.append(sum([(c[k] - data[n][k]) ** 2 for k in range(3)]) ** 0.5)
if dists[-1] < dists[min_id]:
min_id = len(dists) - 1
clusters[min_id].append(n)
for k, v in clusters.items():
if len(v) > 0:
for t in range(3):
centers[k][t] = sum(data[ve][t] for ve in v) / len(v)
flag = True
for k in range(K):
if max([abs(last_centers[k][t] - centers[k][t]) for t in range(3)]) > 1e-6:
flag = False
break
if flag:
break
results = {}
for k, v in clusters.items():
for ve in v:
results[ve] = k
for n in range(N):
print(results[n])
代码题2(困难)
用时43分钟,单考点:模拟,全部AC

python
def code2():
try:
N, d, E, S = map(int, input().split())
except:
print(0)
else:
if min([N, d, E, S]) <= 0 or S > N:
print(0)
else:
import math
tokens = []
Wg = []
We = []
for n in range(N):
tokens.append(list(map(float, input().split())))
for di in range(d):
Wg.append(list(map(float, input().split())))
for e in range(E):
Wei = []
for di in range(d):
Wei.append(list(map(float, input().split())))
We.append(Wei)
# token对专家注意力分配处理
scores = []
for t in tokens:
att_score = []
for e in range(E):
att_score.append(sum([t[di] * Wg[di][e] for di in range(d)]))
att_score = [math.exp(ats) for ats in att_score]
total = sum(att_score)
att_score = [ats / total for ats in att_score]
scores.append(att_score)
# top-s选择
scores2 = [[0 for i in range(N)] for j in range(E)]
for i in range(N):
for j in range(E):
scores2[j][i] = scores[i][j]
expert_tops = []
for e in range(E):
# 确保序号小的排前面
inds = list(range(N - 1, -1, -1))
inds.sort(key=lambda x: scores2[e][x], reverse=True)
tops = []
for f in range(N):
if f in inds[:S]:
tops.append(1)
else:
tops.append(0)
expert_tops.append(tops)
# print(expert_tops)
# MoE计算
res = []
for n in range(N):
s = [0 for i in range(d)]
for e in range(E):
for t in range(d):
s[t] += expert_tops[e][n] * scores[n][e] * sum(
[tokens[n][di] * We[e][di][t] for di in range(d)])
res.append(s)
# 输出处理
res = [["{:.2f}".format(si) for si in s] for s in res]
for s in res:
print(" ".join(s))