从简历项目到面试题挑战:我在深圳做计算机视觉实战的那些坑
上周五晚上十一点半,我瘫在工位上,盯着屏幕上不断报错的 OpenCV 日志,脑子里只有一句话:“早知道就不为了刷简历写 CV 项目了。”
没错,我是个安全工程师。日常工作就是跟各种漏洞、渗透测试、代码审计死磕。但最近想跳槽——不是对现公司不满(虽然产品经理上周又把需求改了七遍),而是发现很多大厂安全岗也开始要求“AI 安全”、“模型逆向”这些新方向。于是,某天深夜刷 Boss 直聘时,看到一条 JD 写着:“熟悉计算机视觉者优先”,我一拍大腿:得,卷起来!
但问题是,我一个天天看 SQL 注入和 XSS 的人,突然要去搞图像识别?行吧,反正深圳南山科技园里,腾讯、字节、Shopee 扎堆,AI 岗多如牛毛,不学点 CV 真怕简历石沉大海。
为什么安全工程师要碰计算机视觉?
先别急着喷“不务正业”。其实这几年,AI 安全已经成了热门交叉领域。比如:
- 对抗样本攻击(Adversarial Attacks):给一张猫的图片加点人眼看不见的噪声,模型就把它认成烤面包机;
- 模型窃取(Model Extraction):通过 API 查询反推内部模型结构;
- 数据投毒(Data Poisoning):在训练集里埋雷,让模型上线后行为异常。
这些攻击手段,底层都依赖对 CV 模型的理解。而如果你连 ResNet 和 YOLO 都分不清,怎么去审计一个智能安防系统的风险?
所以,我决定动手做一个端到端的实战项目:用开源数据集训练一个能识别工地安全帽佩戴情况的模型。选这个场景是因为——我们公司园区就有施工队!而且这项目既能练算法,又能包装进简历,面试时还能当“综合能力”的佐证。
选数据集:别信 Kaggle 的“干净”承诺
一开始我信心满满,直奔 Kaggle 下了个叫 “Hard Hat Dataset” 的数据集,号称 6000+ 张带标注的工地图片。结果解压一看:有些图模糊得像手机摔地上拍的,还有些标签标错了——一个人戴了帽子,label 却是 “no_helmet”。
当时真的想砸键盘。但转念一想:真实世界的 AI 项目,哪有干净数据? 我们做安全审计时,日志里也全是乱码、缺失字段、时间戳错乱。CV 也一样,数据脏才是常态。
于是我花了整整两天做数据清洗:
- 用 OpenCV 自动过滤分辨率低于 480p 的图片;
- 写脚本统计每个类别的 bbox 分布,发现 “helmet” 样本比 “no_helmet” 多三倍,立马做下采样;
- 手动复查了 200 张可疑标注(眼睛都快瞎了)。
📌 经验贴士:别迷信公开数据集的“开箱即用”。尤其 CV 项目,数据质量 > 模型复杂度。一个干净的小数据集,往往比一个混乱的大数据集效果好得多。
算法选型:YOLOv5 还是 EfficientDet?
接下来是重头戏:选模型。我列了个对比表,结合自己的“非 CV 背景”做了权衡:
| 模型 | 上手难度 | 推理速度 (RTX 3060) | mAP@0.5 | 是否支持 ONNX 导出 | 社区活跃度 |
|---|---|---|---|---|---|
| YOLOv5 | ⭐⭐ | 28 FPS | 0.89 | ✅ | 极高(GitHub 40k+ stars) |
| EfficientDet-D0 | ⭐⭐⭐⭐ | 12 FPS | 0.85 | ✅(需 hack) | 中等 |
| Faster R-CNN | ⭐⭐⭐⭐⭐ | 5 FPS | 0.87 | ❌(TF 模型难部署) | 高 |
作为安全工程师,我对 部署友好性 特别敏感——毕竟最后可能要集成到边缘设备(比如工地摄像头)。YOLOv5 不仅推理快,还原生支持导出 ONNX,后续用 ONNX Runtime 部署到 C++ 或 Python 服务都方便。再加上它的 GitHub Issues 区堪称“保姆级教程”,对我这种半路出家的太友好了。
于是,果断选 YOLOv5s(small 版本)。别笑,我知道它不是 SOTA,但工程落地不是打榜,稳定可维护更重要。
训练踩坑实录:从 NaN 到收敛的血泪史
环境搭好,数据准备好,python train.py 一敲,美滋滋等着看 loss 下降……结果第一轮就炸了:
WARNING: NaN detected in loss. Check your data and learning rate.
我:???
查了半天,发现是 数据增强 搞的鬼。YOLOv5 默认启用了 mosaic 和 mixup,但我的数据集里有些图片背景极暗(夜班施工),增强后像素值溢出,导致梯度爆炸。
解决办法很简单:关掉部分增强,或者调低 hsv_h, hsv_s, hsv_v 的扰动幅度。我在 data.yaml 里加了这几行:
# 关闭 mosaic,保留基本增强
augment:
hsv_h: 0.015 # 原来是 0.015,没问题
hsv_s: 0.7 # 降低饱和度扰动
hsv_v: 0.4 # 降低亮度扰动
degrees: 10.0
translate: 0.1
scale: 0.5
shear: 2.0
perspective: 0.0
flipud: 0.0
fliplr: 0.5
mosaic: 0.0 # 关键!关掉 mosaic
mixup: 0.0 # 也关掉
调完之后,loss 终于稳稳下降。训练 50 个 epoch 后,验证集 mAP@0.5 达到 0.91,肉眼测试效果也不错——连远处小工头上的黄色安全帽都能框出来。
💡 吐槽一句:很多教程只说“直接跑就行”,但真实训练过程全是细节魔鬼。调参不是玄学,是工程经验的积累。
面试题挑战:面试官问我“如何防止模型被对抗攻击”?
项目做完,我把它写进了简历。果然,最近几次面试都被问到了。最狠的一次,某大厂安全岗面试官直接问:
“假设你的安全帽检测模型部署在线上,攻击者上传一张经过扰动的图片,让系统误判为‘未戴安全帽’,从而触发错误告警。你怎么防?”
我当时心里一紧——这不就是对抗样本防御吗?幸好之前做过功课。
我答了三层防御思路:
- 输入预处理:对上传图片做 JPEG 压缩、随机裁剪、高斯模糊,破坏对抗噪声;
- 模型鲁棒性增强:在训练时加入 PGD(Projected Gradient Descent)对抗样本,做 adversarial training;
- 运行时监控:部署后加一层 anomaly detection,如果某张图的预测置信度突变(比如平时都是 0.95+,突然变成 0.6),就打日志告警。
面试官点点头:“不错,有安全思维。” ——那一刻,我觉得这几个月没白熬。
部署上线:从 PyTorch 到 ONNX 再到 Flask API
模型训好了,总不能只在 Jupyter Notebook 里 show off。我用 Flask 封装了一个 REST API,方便前端调用:
from flask import Flask, request, jsonify
import cv2
import numpy as np
import onnxruntime as ort
app = Flask(__name__)
ort_session = ort.InferenceSession("yolov5s_helmet.onnx")
def preprocess(img):
img = cv2.resize(img, (640, 640))
img = img.astype(np.float32) / 255.0
img = np.transpose(img, (2, 0, 1))
img = np.expand_dims(img, axis=0)
return img
@app.route('/detect', methods=['POST'])
def detect():
file = request.files['image']
img = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR)
input_img = preprocess(img)
outputs = ort_session.run(None, {'images': input_img})
# 解析输出,返回 bbox 和 label
results = parse_yolo_output(outputs)
return jsonify(results)
这里有个坑:ONNX 导出时要注意输入/输出节点名。YOLOv5 默认输出是个 list,但 ONNX 要求固定 shape。我用了 --dynamic 参数导出动态 batch,但部署时还是得固定输入尺寸。
另外,为了前端展示效果,我还用 Canvas + HTML5 写了个简单的可视化页面——毕竟我可是对前端动画有点执念的人。鼠标 hover 到 bbox 上,还能弹出“安全帽类型:黄色标准款”这种 tooltip,产品经理看了都说“这交互可以”。
效果与反思:不只是为了简历
最终,这个项目不仅帮我过了几轮技术面,还在公司内部 Hackathon 上拿了二等奖(奖金 3000,够买两台机械键盘了)。更重要的是,它让我理解了 CV 项目的完整链路:从数据、训练、调优到部署、安全防护。
现在回头看,当初熬夜调参的痛苦,换来的是面对“算法”、“综合能力”、“实战经验”这类面试题时的底气。
如果你也在刷简历、准备跳槽,我真心建议:别只堆砌“熟悉 TensorFlow/PyTorch”这种空话。花两周时间,从零做一个小而完整的 CV 项目,哪怕只是识别猫狗,也比十行 buzzword 有用。
最后一点真心话
在深圳这座“卷都”,每天都有人在焦虑:会不会被 AI 取代?要不要转大模型?但我想说,技术人的核心竞争力,从来不是会几个框架,而是解决问题的能力。
我是安全工程师,但我愿意跨界学 CV;你可能是前端,也可以试试搞搞算法。世界正在融合,岗位边界越来越模糊。与其恐慌,不如动手做一个项目——哪怕只是为了应付面试,至少你在这个过程中,真的学会了点东西。
对了,项目代码我放 GitHub 了(匿名仓库,别搜我名字),关键词:helmet-detection-yolov5-security。欢迎 star,更欢迎 issue 吐槽。
现在,我要去 review 一个新提的 PR 了——据说里面有个潜在的路径遍历漏洞。唉,CV 搞完了,老本行还得继续肝啊。
(完)

评论 0