CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
机器学习入门/课时/TensorFlow 与 PyTorch
RawBlame
课时目录12 节

机器学习入门

  1. 01机器学习是什么
  2. 02数学基础
  3. 03Python 与数据栈
  4. 04数据预处理
  5. 05监督学习
  6. 06无监督学习
  7. 07模型评估
  8. 08Scikit-learn 工作流
  9. 09深度学习基础
  10. 10NLP 与 Transformer
  11. 11TensorFlow 与 PyTorch
  12. 12综合练习

TensorFlow 与 PyTorch

Keras、PyTorch 训练循环、RL 概览。

35 分钟

TensorFlow 与 PyTorch

这一课你将能做到

  1. 一张表说清 PyTorch / TensorFlow / JAX / XGBoost / scikit-learn 各守哪块阵地
  2. 用 FastAPI + pydantic 把上一课保存的 pipeline 部署成一个 HTTP 预测服务
  3. 用 uvicorn 启动服务并用命令行验证接口
  4. 说清训练/推理分离、版本管理、特征漂移监控、灰度发布这些上线工程题

为什么要学

「模型在 notebook 里准确率 0.9」和「模型在服务器上稳定服务 10 万用户」之间隔着一条工程鸿沟。面试官问深度学习框架,多半不是考 API,而是考你知不知道模型从实验到上线要经过什么。

本课先给框架地图定方位,再把上一课保存的 mastery_pipe.joblib 真正变成一个可调用的 HTTP 服务——这一步做完,你的项目才算闭环。

先建立图像

训练侧(离线,可以慢)              服务侧(在线,必须快而稳)
notebook / 脚本                    FastAPI 进程
   │ 交叉验证调参                      │ 启动时加载 joblib 工件
   ▼                                  │ 收到 JSON → DataFrame
joblib.dump(pipeline) ────工件───►    ▼
                                 pipeline.predict_proba → JSON 返回

跟着做

步骤 1:框架地图

框架定位什么场景选它
PyTorch研究与工业主流,动态图调试友好深度模型、论文复现、团队从零起步
TensorFlow / Keras部署生态完善(Serving / TFLite)移动端、嵌入式、存量 TF 团队
JAX函数式 + 编译加速前沿研究、TPU 大规模训练
XGBoost / LightGBM表格数据之王特征清晰的中小规模结构化数据
scikit-learn常规机器学习标准件基线模型、快速验证想法

结论:先跑通 sklearn/XGBoost 基线,再决定要不要上 PyTorch,顺序别反。

步骤 2:写预测服务(main.py)

# pip install fastapi uvicorn joblib pandas scikit-learn
import joblib
import pandas as pd
from fastapi import FastAPI
from pydantic import BaseModel, Field

class Answer(BaseModel):
    accuracy: float = Field(..., ge=0, le=1)   # pydantic 做入参校验
    attempts: float | None = None
    topic: str

app = FastAPI(title="掌握度预测服务")
pipe = joblib.load("mastery_pipe.joblib")      # 启动时加载一次

@app.post("/predict")
def predict(a: Answer):
    X = pd.DataFrame([a.model_dump()]).astype({"attempts": "float64"})
    proba = float(pipe.predict_proba(X)[0, 1])
    return {"mastery_probability": round(proba, 3),
            "mastery": proba >= 0.6}

两个细节:None 经 astype("float64") 转成 NaN 交给 Imputer 兜底;接口返回,阈值 0.6 留在业务层可随时改。

概率

步骤 3:启动并用 PowerShell 验证

uvicorn main:app --reload --port 8000

另开一个终端:

Invoke-RestMethod -Uri http://127.0.0.1:8000/predict -Method Post `
  -ContentType "application/json" `
  -Body '{"accuracy":0.6,"attempts":null,"topic":"图论"}'

返回 mastery_probability 与 mastery 布尔值,服务闭环。浏览器打开 http://127.0.0.1:8000/docs 还有自动生成的交互文档。

步骤 4:上线之后要管四件事

  1. 版本登记:模型工件 + sklearn 版本 + 特征定义一起记录,出问题才能回滚到「上一个能用的组合」;
  2. 监控:预测分布突然偏移(特征漂移)往往先于业务指标恶化;
  3. 灰度:新旧模型并存,小流量验证后逐步放量,随时可切回;
  4. 再训练:线上积累了新数据,按周期触发重训与评估流程。

讲清楚要点

  • 训练与推理分离是铁律:notebook 里的实验代码(随机打印、临时变量、探索逻辑)不能进服务;服务只做「加载工件 + 前向计算」。
  • Pipeline 工件是接口契约:上游只需按训练时的原始列名传 JSON,所有预处理都在工件里——这就是上一课坚持存整条流水线的原因。
  • 校验要在入口做:pydantic 的类型与范围约束(ge/le)挡住脏数据,别让异常输入直接打到模型。
  • 概率比标签值钱:返回概率后,推难题、推复习、发勋章可以各用各的阈值,一次部署服务多个业务决策。

你可能会懵的地方

Q1:训练和推理为什么要分开部署? 资源特性相反:训练重吞吐、可离线、要 GPU;推理重延迟、常驻内存、多为 CPU。混在一起既慢又容易把实验代码的崩溃带给线上。

Q2:模型更新怎么做到不中断服务? 版本路由 + 滚动发布:新版本模型先起独立实例,健康检查通过后逐步切流量,旧实例待命以便秒级回滚——和后端服务的发布套路一致。

Q3:什么时候才需要 ONNX? 当你需要脱离 Python 运行时(C++ 服务、移动端、浏览器)或追求跨硬件加速时;纯 Python + FastAPI 的服务没必要多一层转换成本。

Q4:线上来了训练时没见过的类别怎么办? 短期靠 handle_unknown="ignore" 兜底不崩,中期靠监控发现新类别占比,长期触发重训把新类别纳入词表。

Q5:监控模型看什么指标? 三层:输入层看特征分布/漂移(如 PSI),模型层看预测分布与置信度,业务层看线上准确率与转化——离线 AUC 好不代表线上没问题。

错法对照

错法后果正确做法
训练代码直接当服务跑慢、脆、依赖混乱导出工件,服务只做前向
只存模型不记版本出事无法回滚工件 + 库版本 + 特征定义一起登记
接口返回硬编码 0/1改阈值要重新发版返回概率,阈值配置化
pydantic 不做约束脏数据打到模型Field(ge=0, le=1) + Optional 类型
上线后不看预测分布漂移发现不了监控输入/预测/业务三层指标

卡点急救

  1. pydantic v1 报 model_dump 不存在 → 旧版用 a.dict(),或升级 pydantic v2。
  2. Invoke-RestMethod 连不上 → 确认 uvicorn 窗口在运行、端口一致、URL 没写 https。
  3. joblib.load 报版本不兼容 → 训练端与服务端的 scikit-learn 大版本保持一致。

面试常问

Q1:说说模型从训练到上线的完整链路? 数据 → 训练评估 → 导出工件(含预处理) → 版本登记 → 服务封装(FastAPI/gRPC) → 灰度发布 → 监控与再训练,重点讲每步的失败模式。

Q2:特征漂移是什么,怎么发现? 线上输入分布随时间偏离训练分布(如新学期题目类型变化)。监控特征分布统计量(PSI/KL)与预测分布,超阈值告警并触发重训。

Q3:为什么推荐接口返回概率? 阈值是业务策略不是模型参数,返回概率可以让产品侧灵活调整判定线,还能支持排序类需求(只推 Top-K)。

自测三问

  1. handle_unknown="ignore" 遇到新类别的行为?(编码成全 0,服务不崩)
  2. 为什么接口返回概率而不是 0/1 标签?(阈值归业务层,一份概率服务多个决策)
  3. joblib 加载失败最常见原因?(训练与服务端 sklearn 版本不一致)

小结一句话

造模型是课程题,供模型是工程题——把工件、版本、监控、灰度补齐,模型才真正从 notebook 走进生产。

延伸

  • 官方文档:PyTorch API 文档 | scikit-learn 模型持久化
  • 下一课预告:最后一课综合演练——用 5000 条真实形态的做题记录,完整走一遍从特征构建到推题清单的端到端项目。
加载本节练习…
← 上一课NLP 与 Transformer下一课 →综合练习