三级实操速查 — 3.1 Excel + 3.2 图片识别

共 35 分 | 5 套题随机抽 1 套 | 点击各节标题展开

15
3.1 Excel 分析
20
3.2 图片识别
35
合计

3.1 Excel 数据分析(15 分)— 通用考点

核心思路 5 套题结构一致:给你一份 xlsx 数据 → 按题面在答题卷指定单元格填写答案。不需要写公式,但需要会用 Excel 分析数据得出结论。
五套题数据对比
题号数据集列名分析维度
3.1.1智能音箱
1001行
用户ID, 时间戳, 功能调用类型, 响应时间功能频率 + 响应时间
3.1.2智能照明
1001行
时间戳, 用户ID, 光线亮度, 色温, 场景, 响应时间时段均值 + 场景频率 + 响应时间
3.1.3健康手环
两Sheet
Sheet1: 用户/日期/步数
Sheet2: 用户/时间戳/功能/延迟
时段步数 + 功能偏好 + 延迟
3.1.4健康监测
169行
时间戳, 收缩压, 舒张压, 血糖, 体脂, 响应时间时段趋势 + 指标偏好 + 响应时间
3.1.5家居环境
1001行
时间戳, 温度, 湿度, 光照, 响应时间, 能源消耗时段均值 + 响应时间 + 能源
必考操作 → Excel 操作路径
功能操作路径 / 公式注意事项
数据透视表
核心
选中数据区域 → 插入 → 数据透视表 → 拖字段到行/列/值区域 值字段默认"计数",需要求均值时要改为"平均值"
按时段分类
必考
透视表中拖"时间戳"到行区域 → 右键"组合" → 选择"小时"分组
或用公式:=HOUR(B2)提取小时后分类
时间列必须是日期格式,文本时间需要先转换
AVERAGEIF
常用
=AVERAGEIF(条件列, 条件, 求均值列) 条件用英文引号,如 "播放音乐"
COUNTIF
常用
=COUNTIF(范围, 条件) 统计频次,排序后可判断"最常使用/较少使用"
AVERAGE
基础
=AVERAGE(范围) 计算平均响应时间、平均温度等
排序
辅助
选中数据 → 数据 → 排序 → 选择列和升/降序 先全选再排序,避免只排一列导致数据错位
条件格式
可能考
开始 → 条件格式 → 色阶/数据条/突出显示 用于可视化高/低值
答题模板(5 套通用)
答题区域分析思路方法
用户使用习惯
(频率/偏好)
统计各功能/场景出现次数,排序COUNTIF 或透视表计数
时段均值
(温度/步数/亮度等)
按时间段分组求平均透视表组合 + 平均值
响应时间分析求整体平均;找最长/最短AVERAGE / MAX / MIN
优化方向 x3从数据中找问题 → 写对策见下方模板
优化方向万能模板 1. 响应时间优化:XX 功能响应时间过长 → 优化算法 / 增加缓存 / 负载均衡
2. 用户活跃度提升:XX 功能使用率低 → 优化交互设计 / 增加推荐引导
3. 数据质量改善:XX 指标波动大 → 增加采集频率 / 校准传感器
踩坑点不要修改答题卷格式,只在指定单元格填写答案
• 答题中出现的具体数值(如"平均响应时间 2.3 秒")要和 Excel 算出来的对得上
• 3.1.3 有两个 Sheet,注意看题目要求用哪个
• 3.1.4 收缩压/舒张压属血压功能,血糖属血糖功能,体脂属体脂功能 — 分类别统计
• 时间分组时注意时段划分(如 06:00-12:00 vs 6:00-12:00),严格按题目要求

3.1 快速操作步骤(考试照做)

  1. 打开 .docx 题目文件,通读题目要求,圈出需要填写的具体项
  2. 打开对应 .xlsx 数据文件,快速浏览表头和数据量
  3. 打开答题卷(同一个 xlsx 或单独文件),找到需要填答案的单元格位置
  4. 对时间列做分组:插入数据透视表 → 拖时间戳到行 → 右键组合 → 按小时/时段
  5. 统计频率:透视表中拖功能/场景列到行区域,拖同一列到值区域(计数)
  6. 求均值:值字段改为"平均值",得出各时段/各功能的平均数值
  7. 分析响应时间:用 AVERAGE / MAX / MIN 分别算整体平均、最长、最短
  8. 将计算结果填入答题卷对应单元格(文字+数值)
  9. 写 3 条优化方向:根据数据中"最长/最短/最高/最低"的指标写问题和对策
  10. 检查:数值是否合理、单位是否正确、是否填在正确位置

3.2 图片识别 — ONNX 推理通用流程(20 分)

标准流程四步走 加载模型 → 预处理图片 → 执行推理 → 后处理输出结果
五套题对比
题号模型图片预处理任务难度
3.2.1 resnet.onnx
~100MB
img_test.jpg
RGB 彩色
resize 256 → center crop 224 → 归一化
mean/std ImageNet
Top5 分类 中等
3.2.2 mnist.onnx
~26KB
img_test.png
灰度
resize 28x28 → 灰度
expand_dims x2
手写数字识别 简单
3.2.3 emotion-ferplus.onnx
~33MB
img_test.png
灰度
resize 64x64 → 灰度
expand_dims x2
情感分类 简单
3.2.4 flower-detection.onnx
~100MB
flower_test.png
RGB 彩色
同 3.2.1 的预处理函数 花卉分类 + 百分比 中等
3.2.5 version-RFB-320.onnx
~1.2MB
imgs/ 目录多图
RGB
resize 320x240 → 减均值/128
transpose + expand_dims
人脸检测 + 画框 较难
关键认知:考试题分两种形式填空版(.ipynb 中用 ______ 标记):需要补全代码
完成版:有正确答案可以参考,但也有故意留的错误(如 3.2.2 的拼写错误)
• 考试时拿到的一定是填空版,需要根据题目提示填入正确代码

3.2.1 ResNet 图片分类(Top5)

分值分布 模型加载 2 + 加载图片 2 + 预处理 2 + 推理 2 + softmax 2 + Top5 3 = 13 填空分
# ===== 3.2.1 ResNet 图片分类 — 完整代码模板 ===== import onnxruntime as ort import numpy as np import scipy.special from PIL import Image # 预处理函数(题目已提供,不用填) def preprocess_image(image, resize_size=256, crop_size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]): image = image.resize((resize_size, resize_size), Image.BILINEAR) w, h = image.size left = (w - crop_size) / 2 top = (h - crop_size) / 2 image = image.crop((left, top, left + crop_size, top + crop_size)) image = np.array(image).astype(np.float32) image = image / 255.0 image = (image - mean) / std image = np.transpose(image, (2, 0, 1)) image = image.reshape((1,) + image.shape) return image # ① 加载模型 (2分) session = ort.InferenceSession('resnet.onnx') # 加载标签 with open('labels.txt') as f: labels = [line.strip() for line in f.readlines()] input_name = session.get_inputs()[0].name output_name = session.get_outputs()[0].name # ② 加载图片 (2分) image = Image.open('img_test.jpg').convert('RGB') # ③ 预处理图片 (2分) processed_image = preprocess_image(image) processed_image = processed_image.astype(np.float32) # ④ 执行推理 (2分) output = session.run([output_name], {input_name: processed_image})[0] # ⑤ softmax (2分) probabilities = scipy.special.softmax(output, axis=-1) # ⑥ 取 Top5 (3分) top5_idx = np.argsort(probabilities[0])[-5:][::-1] top5_prob = probabilities[0][top5_idx] print("Top 5 predicted classes:") for i in range(5): print(f"{i+1}: {labels[top5_idx[i]]} - Probability: {top5_prob[i]}")
踩坑点session.run() 返回的是列表,要加 [0] 取第一个输出
• Top5 取法:np.argsort()[-5:][::-1] — 先取最后5个(最大),再反转成降序
top5_prob 不能写成 probabilities[top5_idx],要加 [0] 因为 probabilities 是三维的

3.2.2 MNIST 手写数字识别

分值分布 加载模型 2 + 加载图片 2 + resize 2 + np.array 2 + expand_dims x2 各 2 + get_inputs 2 + run 2 + argmax 2 = 18 填空分
# ===== 3.2.2 MNIST 手写数字 — 完整代码模板 ===== import onnxruntime import numpy as np from PIL import Image # ① 加载模型 (2分) ort_session = onnxruntime.InferenceSession('mnist.onnx') # ② 加载图片 + 转灰度 (2分) image = Image.open("img_test.png").convert('L') # ③ resize (2分) image = image.resize((28, 28)) # ④ 转 numpy (2分) image_array = np.array(image, dtype=np.float32) # ⑤ 添加 batch 维度 (2分) image_array = np.expand_dims(image_array, axis=0) # ⑥ 添加 channel 维度 (2分) image_array = np.expand_dims(image_array, axis=0) # ⑦ 获取输入名 (2分) ort_inputs = {ort_session.get_inputs()[0].name: image_array} # ⑧ 执行推理 (2分) ort_outs = ort_session.run(None, ort_inputs) # ⑨ 取最大概率的类别 (2分) predicted_class = np.argmax(ort_outs) print(f"Predicted class: {predicted_class}")
踩坑点(本题有大量拼写陷阱!)np.expend_dims 是错的!正确是 np.expand_dims
ort_seesion 是错的!正确是 ort_session
ort_session.get_input() 是错的!正确是 get_inputs()(有 s)
• expand_dims 两次:第一次 axis=0 加 batch 维,第二次 axis=0 加 channel 维(因为已经是 3D 了)
• 最终形状应该是 (1, 1, 28, 28)

3.2.3 人脸情感识别

分值分布 情感映射表 3 + 加载模型 3 + 预处理调用 3 + 推理 3 + argmax 3 + 查表 3 = 18 填空分
# ===== 3.2.3 情感识别 — 完整代码模板 ===== import numpy as np from PIL import Image import onnxruntime as ort # 预处理函数(题目已提供) def preprocess(image_path): input_shape = (1, 1, 64, 64) img = Image.open(image_path).convert('L') img = img.resize((64, 64), Image.ANTIALIAS) img_data = np.array(img, dtype=np.float32) img_data = np.expand_dims(img_data, axis=0) img_data = np.expand_dims(img_data, axis=1) assert img_data.shape == input_shape return img_data # ① 情感映射表 (3分) — 8 类情感 emotion_table = {0: 'Neutral', 1: 'Happy', 2: 'Sad', 3: 'Surprise', 4: 'Fear', 5: 'Disgust', 6: 'Anger', 7: 'Contempt'} # ② 加载模型 (3分) ort_session = ort.InferenceSession('emotion-ferplus.onnx') # ③ 预处理图片 (3分) input_data = preprocess('img_test.png') ort_inputs = {ort_session.get_inputs()[0].name: input_data} # ④ 执行推理 (3分) ort_outs = ort_session.run(None, ort_inputs) # ⑤ 取预测类别 (3分) predicted_label = np.argmax(ort_outs[0]) # ⑥ 查情感名 (3分) predicted_emotion = emotion_table[predicted_label] print(f"Predicted emotion: {predicted_emotion}")
踩坑点 • 情感映射表要自己写全 8 类(0-7),别漏
preprocess() 函数已提供,直接调用传图片路径即可
ort_outs[0] 取第一个输出再 argmax,别对整个列表 argmax

3.2.4 花卉分类 + 百分比输出

分值分布 加载模型 2 + 加载标签 2 + 加载图片 2 + 预处理 2 + 推理 2 + softmax 2 + 取idx/prob/label 各算 = 共 20 分
# ===== 3.2.4 花卉分类 — 完整代码模板 ===== import onnxruntime as ort import numpy as np import scipy.special from PIL import Image # 预处理函数(同 3.2.1) def preprocess_image(image, resize_size=256, crop_size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]): image = image.resize((resize_size, resize_size), Image.BILINEAR) w, h = image.size left = (w - crop_size) / 2 top = (h - crop_size) / 2 image = image.crop((left, top, left + crop_size, top + crop_size)) image = np.array(image).astype(np.float32) image = image / 255.0 image = (image - mean) / std image = np.transpose(image, (2, 0, 1)) image = image.reshape((1,) + image.shape) return image # ① 加载模型 (2分) session = ort.InferenceSession('flower-detection.onnx') # ② 加载标签 (2分) with open('labels.txt') as f: labels = [line.strip() for line in f.readlines()] input_name = session.get_inputs()[0].name output_name = session.get_outputs()[0].name # ③ 加载图片 (2分) image = Image.open('flower_test.png').convert('RGB') # ④ 预处理 (2分) processed_image = preprocess_image(image) processed_image = processed_image.astype(np.float32) # ⑤ 推理 (2分) output = session.run([output_name], {input_name: processed_image})[0] # ⑥ softmax (2分) accuracy = scipy.special.softmax(output, axis=-1) # ⑦ 取预测索引 predicted_idx = np.argmax(accuracy) # ⑧ 转百分比 prob_percentage = accuracy[0][predicted_idx] * 100 # ⑨ 取标签名 predicted_label = labels[predicted_idx] print(f"Predicted class: {predicted_label}, Accuracy: {prob_percentage:.2f}%")
踩坑点 • 标签文件路径要填对:'labels.txt' 不是空字符串
accuracy[0][predicted_idx] — 注意 accuracy 是三维的 (1, 1, N),要先 [0]
• 乘 100 转百分比,.2f 保留两位小数
• 和 3.2.1 的区别:只要 Top1,不是 Top5

3.2.5 人脸检测(目标检测 + 画框)

分值分布 标签加载 2 + 加载模型 2 + 获取输入名 2 + 创建目录 2 + 读图 2 + resize 2 + 均值 2 + expand_dims 1 + run 2 = 17 填空分
# ===== 3.2.5 人脸检测 — 填空关键行 ===== # 已有导入和 predict 函数(不用填) # ① 加载标签 (2分) class_names = [name.strip() for name in open('voc-model-labels.txt').readlines()] # ② 加载模型 (2分) ort_session = ort.InferenceSession('version-RFB-320.onnx') # ③ 获取输入名 (2分) input_name = ort_session.get_inputs()[0].name result_path = "./detect_imgs_results_onnx" threshold = 0.7 path = "imgs" sum = 0 # ④ 创建目录 (2分) if not os.path.exists(result_path): os.makedirs(result_path) listdir = os.listdir(path) for file_path in listdir: img_path = os.path.join(path, file_path) # ⑤ 读取图片 (2分) orig_image = cv2.imread(img_path) image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) # ⑥ resize (2分) image = cv2.resize(image, (320, 240)) # ⑦ 均值 (2分) image_mean = np.array([127, 127, 127]) image = (image - image_mean) / 128 image = np.transpose(image, [2, 0, 1]) # ⑧ expand_dims (1分) image = np.expand_dims(image, axis=0) image = image.astype(np.float32) time_time = time.time() # ⑨ 推理 (2分) confidences, boxes = ort_session.run(None, {input_name: image}) print("cost time:{}".format(time.time() - time_time)) boxes, labels, probs = predict(orig_image.shape[1], orig_image.shape[0], confidences, boxes, threshold) for i in range(boxes.shape[0]): box = boxes[i, :] label = f"{class_names[labels[i]]}: {probs[i]:.2f}" cv2.rectangle(orig_image, (box[0], box[1]), (box[2], box[3]), (255, 255, 0), 4) cv2.imwrite(os.path.join(result_path, file_path), orig_image) sum += boxes.shape[0] print("sum:{}".format(sum))
踩坑点 • 标签解析:name.strip() 不是 line.strip(),for 循环变量是 name
• 创建目录用 os.makedirs 不是 os.mkdir(虽然单层目录都可以)
cv2.imread() 返回 BGR,要 cv2.cvtColor 转 RGB
• resize 参数是 (宽, 高)(320, 240),不是 (240, 320)
np.array([127,127,127]) — 别忘了 np.array
• 这题用 ort_session 不是 session,变量名要和前面一致
• 结果图片保存在 detect_imgs_results_onnx/ 目录

3.2 通用填空速查表

高频填空答案一览
填空位置答案出现频率
加载 ONNX 模型ort.InferenceSession('模型名.onnx')5/5
打开图片Image.open('图片名').convert('RGB')'L'5/5
执行推理session.run(None, {input_name: data})5/5
获取输入名session.get_inputs()[0].name4/5
取预测类别np.argmax(output)3/5
添加维度np.expand_dims(arr, axis=0)4/5
softmaxscipy.special.softmax(output, axis=-1)2/5
读标签文件with open('labels.txt') as f:2/5
创建目录os.makedirs(path)1/5
3.2 通用操作步骤
  1. 打开 Jupyter Notebook,确认素材文件(.onnx 模型 + 图片 + labels.txt)都在同目录
  2. 先运行已有的 import 单元格,确认库都能正常导入
  3. 如果预处理函数已提供,先运行它(不需要修改)
  4. 依次填写:加载模型 → 加载标签/映射表 → 加载图片 → 调预处理 → 推理 → 后处理
  5. 注意检查变量名拼写,特别是 ort_session vs session
  6. 运行整个 Notebook,看输出是否正常(有预测结果,无报错)
  7. 保存 Notebook
全局踩坑点Image.ANTIALIAS 在新版 Pillow 中已弃用,新版用 Image.Resampling.LANCZOS,但考试环境可能是旧版
ort.run(None, inputs) 第一个参数 None 表示返回所有输出
• 图片颜色模式:彩色用 .convert('RGB'),灰度用 .convert('L'),看题目要求
• numpy 数组形状一定要和模型输入匹配,不确定时用 print(arr.shape) 检查
np.argmax() 返回的是索引号,不是概率值
拿满 20 分的检查清单 ✓ 模型文件名拼写正确
✓ 图片文件名拼写正确
✓ 变量名前后一致
✓ 输出结果合理(概率在 0-1 之间,类别名不是乱码)
✓ Notebook 已保存

考前 5 分钟速记

3.1 Excel 一句话口诀
透视表拉频率,AVERAGE 算均值,三大优化写上去
优化方向万能三条:①响应慢的加速 ②用得少的推广 ③数据波动的改善
3.2 ONNX 一句话口诀
InferenceSession 加模型,Image.open 读图片,run 做推理,argmax 取结果
检查三件事:文件名对不对、变量名一不一致、shape 匹不匹配
易错 API 速查
易错写法正确写法
np.expend_dimsnp.expand_dims
ort_seesionort_session
get_input()get_inputs()
Image.open().convert('gray').convert('L')
cv2.resize(img, (高, 宽))cv2.resize(img, (宽, 高))
onnxruntime.InferenceSessionort.InferenceSession(别名也可)