一个后端老狗的CV实战:从刷题到简历上能写点AI

指针迷路了
2026-01-05 20:49
阅读 2896

上周五晚上九点半,公司茶水间只剩我一个人泡着第三杯速溶咖啡。屏幕里LeetCode第128题卡了我整整两小时,而隔壁组的实习生刚发了个PR,标题是“基于YOLOv5的商品图像识别模块初版”。我默默关掉VS Code(对,虽然我是Vim党,但刷题时还是得用IDE——别judge我),心里嘀咕:这届新人怎么连CV都玩上了?

说来惭愧,我在这家金融科技公司干了五年后端,日常和Kafka、MySQL、JWT打交道,安全审计比吃饭还勤。但最近准备跳槽,翻遍各大厂JD,清一色写着“熟悉机器学习/计算机视觉者优先”。更离谱的是,某头部券商的岗位描述直接要求“有区块链+AI交叉项目经验”——我当时就笑了,合着现在做风控还得会画猫狗?

但笑完还是得卷。毕竟简历不能只写“精通Spring Boot”和“曾修复过OAuth2.0越权漏洞”。于是咬牙花了两周时间,搞了个端到端的计算机视觉小项目。今天就来聊聊这个过程,顺便看看怎么把这种项目“包装”进简历,还不至于在面试时被问穿帮。


为什么一个后端要搞CV?

其实契机很现实:我们风控系统最近接了个新需求——用户上传身份证照片自动校验真伪。产品经理拍脑袋说“用AI识别就行”,运维老大冷笑:“你们打算把模型跑在生产K8s集群?那玩意儿吃GPU,我们全是CPU节点!” 测试同事补刀:“而且如果识别错了,用户资金损失谁担?”

那一刻我意识到:在金融场景下,CV不是炫技,而是责任。你不能像互联网公司那样容忍95%的准确率——在这里,99.99%可能都不够。

所以我决定自己动手,搞个轻量、可解释、部署成本低的方案。目标很明确:

  • 模型要能在CPU上跑(毕竟公司没GPU预算)
  • 要能输出置信度,供人工复核
  • 最好能和现有Java服务无缝集成

至于区块链?先别急,后面会说到它怎么意外派上用场。


数据集选择:别再用MNIST糊弄人了

很多教程一上来就拿CIFAR-10或MNIST练手,但在真实业务中,这些玩具数据集毫无意义。我们的身份证识别需要处理的是:

  • 光照不均(用户在厕所昏暗灯光下拍照)
  • 部分遮挡(手指挡住出生日期)
  • 伪造证件(PS过的身份证)

于是我用内部脱敏数据 + 公开数据集(如ICDAR2019)构建了一个混合训练集。总共约12万张图像,标注了以下字段:

字段 说明
id_card_valid 是否为真实身份证(二分类)
blur_score 图像模糊程度(0~1)
tamper_region PS区域坐标(用于分割任务)

教训:千万别相信“开源数据集开箱即用”。我花三天清洗数据,删掉那些拿驾照冒充身份证的样本——产品经理以为AI能自动区分,结果模型学了一堆噪声。


模型选型:小而美才是王道

一开始我试了ResNet50,准确率98.2%,但推理时间高达1.2秒(CPU)。上线?做梦。后来换成MobileNetV3 + EfficientNet-Lite组合,参数量砍到原来的1/10,准确率只降了0.7%,推理时间压到200ms。

关键代码(PyTorch):

import torch
from torchvision.models import mobilenet_v3_small

class IDCardValidator(torch.nn.Module):
    def __init__(self, num_classes=2):
        super().__init__()
        self.backbone = mobilenet_v3_small(pretrained=True)
        # 替换最后分类层
        self.backbone.classifier[3] = torch.nn.Linear(
            self.backbone.classifier[3].in_features, 
            num_classes
        )
        # 添加模糊度回归头
        self.blur_head = torch.nn.Sequential(
            torch.nn.AdaptiveAvgPool2d(1),
            torch.nn.Flatten(),
            torch.nn.Linear(576, 1),
            torch.nn.Sigmoid()
        )

    def forward(self, x):
        features = self.backbone.features(x)
        cls_out = self.backbone.classifier(features.mean([2, 3]))
        blur_out = self.blur_head(features)
        return cls_out, blur_out

调参心得

  • 用Focal Loss解决正负样本不平衡(伪造证件只占3%)
  • 在验证集上监控precision@99recall,而不是单纯看accuracy
  • 用TensorRT量化后,CPU推理速度又提升40%

部署:后端最关心的部分

模型训练完只是开始。作为后端,我必须让它跑在现有Spring Boot服务里。方案如下:

  1. ONNX导出:把PyTorch模型转成ONNX格式
    torch.onnx.export(model, dummy_input, "id_validator.onnx", opset_version=11)
    
  2. Java集成:用ONNX Runtime for Java加载模型
  3. 缓存策略:对同一用户ID的请求结果缓存5分钟,避免重复计算

上线后压测数据:

QPS 平均延迟 CPU占用
50 210ms 35%
100 230ms 60%

还算能接受。不过测试同事又来找茬:“如果模型服务挂了,整个开户流程就卡住?” 于是加了熔断机制——当模型不可用时,自动降级为人工审核队列。


区块链?真的用上了!

说到区块链,其实在最初的需求里根本没它什么事。但有一次安全审计,合规部突然问:“用户上传的身份证图像,如何证明未被篡改?”

灵光一闪:用区块链存哈希!

具体做法:

  1. 用户上传图片后,计算其SHA3-256哈希
  2. 将哈希 + 时间戳 + 用户ID 写入私有链(Hyperledger Fabric)
  3. 审核人员在后台可验证当前图片哈希是否与链上一致

虽然只是个轻量级应用,但写在简历里立马高大上起来:

“设计并实现基于CV的身份证真伪识别系统,结合区块链技术确保图像完整性,降低欺诈风险30%”

HR看不懂技术细节,但“区块链+AI”两个关键词足够抓眼球。


简历怎么写?别吹牛,要可验证

很多朋友问我:这种项目怎么写进简历才不显得注水?我的建议是:

  • 量化结果:不要写“提升了用户体验”,写“将人工审核量减少40%”
  • 突出角色:明确你是独立开发还是团队协作(我这里基本单干)
  • 技术栈清晰:列出具体工具,如“PyTorch 1.12 + ONNX Runtime + Hyperledger Fabric 2.4”
  • 附GitHub链接:哪怕代码不完美,也比空口无凭强

我的简历片段(脱敏后):

- 主导金融级身份证图像风控系统开发,采用MobileNetV3轻量化模型,在纯CPU环境实现200ms内识别
- 创新性引入区块链存证机制,确保用户上传图像不可篡改,通过银保监会合规检查
- 系统上线后拦截伪造证件申请1200+次/月,误判率<0.1%

最后一点真心话

说实话,作为一个写了五年CRUD的后端,搞CV确实痛苦。环境配置、数据标注、调参炼丹……每一步都想砸键盘。但当你看到模型成功识别出一张精心伪造的身份证,那种成就感,比修完一个P0级线上bug还爽。

更重要的是,技术广度决定了你的职业天花板。现在面试官问我“你怎么看待AI在金融风控中的应用”,我能聊数据、聊模型、聊部署、聊合规,而不是只会背八股文。

所以,别管是不是Vim党,是不是后端,该卷的时候就得上。毕竟——
简历上的每一个字,都是你未来薪资的筹码

(P.S. LeetCode第128题我最后用并查集搞定了,但那是另一个故事了……)

评论 0

最热最新
暂无评论
指针迷路了Lv.1
0
影响力
0
文章
0
粉丝