跳到主要内容

reading-notes — python-shen-du-xue-xi-pytorch

通读记录(2026-08-27)。原文 19 文件全读:前言 + 16 章 + 附录 A/B。下面按原书章记要点、关键数字、可引段落(file:line 已按当前 text/ 核对)。

前言 (01-fm)

  • 作者吴茂贵,写作用环境 Python 3.6+ / PyTorch 1.0+ / TF 1.5+(:127);「近一年打磨」(:29)
  • 选 PyTorch 四条理由:动态图贴近 Python(:13)、要亲手定义网络层与参数更新(:16)、调试方便(:19)、热度增长(:22)
  • 全书 3 部分 16 章(:84);三大硬骨头:CNN、RNN、GAN(:44)
  • Cifar10 精度阶梯是全书暗线:68%→74%→90%→95%(:49)

ch1 NumPy (02, 803 行)

  • 为什么不用 list/array:list 存指针(:10),array 不支持多维(:12)
  • ndarray + ufunc 两大对象(:15)
  • 广播 4 规则(:746-764);例子 A(4,1)+B(3,)→(4,3),值为 [[0,1,2],[10,11,12],[20,21,22],[30,31,32]] (:787-801)
  • Mini-Batch 理由:整集资源瓶颈、单条吃不满 GPU 并行(:631-637)
  • 性能:np.sin 比 math.sin 快近 10 倍(:707);向量化点积 1.885ms vs 循环 798ms ≈ 400 倍(:737-742)

ch2 PyTorch 基础 (03, 988 行)

  • Facebook 2017-01 发布(:2);动态图 + tape-based autograd + 反向模式自动微分(:31-34)
  • 四包:torch/autograd/nn/optim(:51-60);0.4 合并 Variable 与 Tensor(:43);1.0 整合 Caffe2 + JIT(:44-47)
  • Tensor: add vs add_ 下划线就地(:246-251);torch.Tensor(1) 随机 vs torch.tensor(1) 固定(:294-311)
  • view 需 contiguous,reshape 自动 copy(:361-373)
  • autograd: requires_grad 叶子节点(:551);grad_fn;backward 后非叶子梯度清空;retain_graph;no_grad(:574)
  • 计算图 z=wx+b,DAG(:584-589);标量反向:x=2→w.grad=2, b.grad=1(:650-651)
  • 非标量:张量对张量不求导,传 gradient 参数 → 雅可比;y.backward([[1,1]]) 得 [6,9] (两行和);两步分算得 J=[[4,3],[2,6]] (:706-729)
  • 主走查素材:同一回归 y=3x²+2 三种实现:NumPy 手工梯度 800 轮 w=2.9586/b=2.1018(:816);autograd 800 轮 w=2.9645/b=2.1146(:887);TF 静态图 2000 轮 loss=0.0038, w=2.92/b=2.12(:976);PyTorch 参数更新在图外、TF 在图内(:936-937);动态图交互式(:979-985)

ch3 nn 工具箱 (04, 534 行)

  • 四组件:层/模型/损失函数/优化器(:24-30);循环:预测→损失→优化器更新(:37-41)
  • Module 自动管参数 vs functional 纯函数;含参用 nn.Xxx,不含参可用 F.xxx(:48-54, :362-378)
  • Dropout 的 train/eval 切换只有 nn.Xxx 有(:372-373)
  • MNIST 实例:28*28→300→100→10,batch 64/128,lr 0.01,momentum 0.5,20 epochs;train acc 0.9996 / test acc 0.9839(:104-109, :253-257);每 5 epoch lr*=0.1(:204-205)
  • 训练循环五步:train()→forward→zero_grad→backward→step(:398-423)
  • 新建 optimizer 会重置动量状态→收敛震荡,改 param_groups 更稳(:425-428)
  • 优化器对比实验:同网络 SGD/Momentum/RMSprop/Adam 跑 y=x²+噪声(:491-516)

ch4 数据工具箱 (05, 467 行)

  • Dataset 抽象类 getitem/len;DataLoader 批量+shuffle+多进程(:23-31, :121-129);pin_memory/drop_last
  • transforms:ToTensor HWC→CHW、[0,255]→[0,1] (:180-181);Normalize 减均值除标准差(:191);Compose 管道
  • ImageFolder 目录名→标签(:229-235)
  • tensorboardX:SummaryWriter/add_scalar(:299-326, :426)

ch5 机器学习基础 (06, 891 行)

  • 四任务:监督/无监督/半监督/强化(:26-29)
  • 流程:目标→收集→探索预处理(占大部分时间 :117)→模型/损失→评估(留出/K折 :152-162);没有免费的午餐(:132)
  • 过拟合:训练精度升测试精度降(:169-181)
  • 正则化主走查:房价 4 次多项式,损失加 10000θ3²+10000θ4²→系数压向 0,退回 2 次(:205-212);L2=weight_decay(:219-222)
  • Dropout(Srivastava 2014):随机屏蔽,复杂协同适应(:224-237);4 单元 16 子网络(:244-252);丢弃率 20%-50%,lr 扩 10-100 倍、冲量 0.9-0.99(:265-282);测试时按比例缩小输出(:259-261)
  • BN(Ioffe & Szegedy):微批次均值方差+γβ;作用在非线性映射前(:353);允许大学习率、可减 Dropout/L2(:360-368);简单网络效果不如 Dropout 明显(:398)
  • 初始化:影响收敛/局部最小(:402-410);xavier 配 sigmoid/tanh、kaiming 配 ReLU(:421-423)
  • 激活:sigmoid 导数 ≤1/4,深层梯度消失;ReLU 导数 1(:432-438)
  • 损失:回归 MSE、分类交叉熵;PyTorch CrossEntropyLoss = softmax + NLL,非严格交叉熵(:505-511);weight 治类别不均衡(:523)
  • 优化器:θ←θ-λg 敏感/鞍点/平坦区早停(:546-565);动量=惯性(:586);NAG 前瞻(:596-599);AdaGrad 适合稀疏但学习率衰减过早(:619-622);RMSProp 指数移动平均+ρ(:637-639);Adam=动量 RMSProp+偏置校正(:647-649);先 Adam 后 SGD,150 轮后 SGD 更好(:660-665)
  • GPU:众核几千流处理器,单核几十倍~上千倍(:671-675);to(device);DataParallel 把 batch128 拆成 64+64(:851);DistributedDataParallel 配置繁但更快(:862);注意事项:GPU 数取偶、数据少可能不如 CPU(:880-885)

ch6 视觉处理 (07, 1149 行)

  • 全连接参数爆炸:1000×1000 图 ×100 隐层 = 1000000×100 权重阵(:2-6)
  • 历史:1986 BP→1989 LeCun→1998 LeNet-5→低谷→2006 Hinton→2012 AlexNet→2014 VGG/DeepFace(LFW 99.75%)(:30-39)
  • 卷积走查:5×5 输入 3×3 核,左上 1×1+1×0+1×1+0×0+1×1+1×0+0×1+0×0+1×1=4(:143-147);步幅/填充 Same/Valid(:152-184);卷积核值全程共享=共享变量(:158-160)
  • 多通道:6×6×3,滤波器 3×3×3,逐通道卷积求和(:189-194);两组滤波器 7×7×3→3×3×2(:199)
  • 转置卷积:卷积=稀疏矩阵 C 乘 X,反向=C^T,即上采样,GAN 常用(:270-294)
  • 池化:最大/均值/全局(:304-316);GAP 一张特征图出一个值,替代 FC,无参数防过拟合(:374-396)
  • 谱系:LeNet(1998 卷积+池化+全连接定形,tanh,平均池化)→AlexNet(2012 胜第二名 10.9pp,ReLU/Dropout/数据增强/GPU)→VGG(16/19 层,两个 3×3 感受野=5×5 且参数更少,Top5 错误 7.3%)→GoogLeNet(Inception 并行+1×1 降维,AlexNet FC 占 90% 参数,GAP 替代,93.3%,比 VGG 快)→ResNet(2015 何恺明,残差=恒等梯度高速通道,22→152 层)→CapsNet(2017 Hinton,向量神经元+动态路由,省数据、保姿态,但 ImageNet/CIFAR-10 不行)(:433-604)
  • CIFAR-10:60000 张 32×32(:611);CNNNet 两层卷积 68%(cat 46%/bird 50% 最差)(:801-838);GAP 版参数 16022 vs 173742(10 倍多)但 63%、收敛慢(:871-877);层参数:Conv 1216/5220,Linear-5 166016 —— 参数全压在全连接(:951-978)
  • 集成:盲人摸象(:988);多样性比调参重要(:996-998);3 模型投票 74% vs 单模型最好 71%(:1078-1097)
  • VGG16(cfg 写法)→90%(:1112-1145);后文迁移+增强→95%

ch7 NLP/RNN (08, 1023 行)

  • 序列数据 CNN 不擅长(:2-6);RNN 自循环 W,U/W/V(:25-32);at=f(Uxt+Wat-1) 状态=记忆(:50)
  • 数值走查:a0=[0,0],x1=1→状态[0.537,0.462]→输出1.561;x2=2→[0.860,0.884]→2.727(:90-123, 附 Python 代码)
  • BPTT 按时间反传(:125-127);长期依赖:W^t 特征值分解,λ>1 爆炸 <1 消失(:136-146);RNN 同权重反复乘,比前馈更明显→短时记忆(:149-153)
  • LSTM(Hochreiter & Schmidhuber 1997):遗忘门/输入门/输出门+单元状态 c(:170-177);LSTM 参数=RNN 4 倍(wih [80,10] vs [20,10] 实测)(:346-362)
  • GRU:两门(更新 z/重置 r),状态合一,参数 3 倍,更省(:186-194, :423-424)
  • Bi-RNN(Schuster & Paliwal 1997):6 组权重,前向反向无信息流;百度语音(:202-209)
  • nn.RNN:输入 (seq,batch,feature) 默认,batch_first 可换;h0 (num_layers*directions,batch,hidden);实测 100×32×10→output(100,32,20)(:276-302)
  • 词向量:One-Hot=电报码,维数灾难+语义鸿沟(:535-552);分布式表示 Hinton 1986,「麦克」近「话筒」远「天气」(:556-560);Word2Vec=Google 2013,3 层浅网络,不算深度学习但成 NLP 地基(:564-568)
  • CBOW=上下文猜词,Skip-Gram=词猜上下文;例句「今天下午2点钟搜索引擎组开组会」;Hierarchical Softmax 治大词表 softmax 计算量(:573-602);quick brown fox window=1(:609-621)
  • 词性标注实例:2 句训练 9 词 3 词性;EMBEDDING 10/HIDDEN 3;NLLLoss+SGD 0.1;未训练预测 [2,2,1,1,1] 全错,400 轮后 [0,1,2,0,1]=DET NN V DET NN;测试句 They ate the fish→[1,2,0,1] (:656-818)
  • 股票:沪深300 2295 条,n=30 天最高价→当日价,标准化 (x-mean)/std,LSTM64→Linear(64,1),MSE+Adam(:819-986)
  • RNN 五种应用模式(1-1/1-N/N-1/N-N/同步 N-N)(:994-1005);RNN 图灵完备的说法(:1016)

ch8 生成式 VAE/GAN (09, 671 行)

  • 判别模型 x→y,生成模型 y→x(:2-5)
  • AE 不会生成新内容→VAE 给潜在空间加正态约束(:25-37);编码器输出 mu/log_var,ε~N(0,I),z=mu+exp(log_var/2)·ε(:49-58, :150-153)
  • 损失=BCE 重构 + KL 散度(:73-84);MNIST 784→400→20,30 epochs(:110-115)
  • GAN(Goodfellow 2014):验钞机 vs 假币机博弈(:216-224);伪造者/艺术商人(:231-237);D 损失=真+假两项(:271-283),G 损失=骗 D 认真(:285-292)
  • 训练不是最小化单一损失,是保持两股力量动态平衡→难训(:256-257)
  • VAE:空间连续有结构、可解释方向,但逐像素损失→模糊;GAN:更清晰、空间无结构、会坍塌,G 的梯度经 D 传递,D 太准则学不动→Wasserstein 距离(WGAN)(:413-436);结论:GAN 效果好、更难训(:437-441)
  • CGAN:z(100) 与标签嵌入(10) 拼成 110 进 G;D 输入 794(:471-501);generate_digit(G,8) 按需生成
  • DCGAN:Conv/ConvTranspose/BN(:573-577)
  • 训练技巧:批+BN;G 末层 tanh 归 [-1,1];LeakyReLU 防稀疏梯度;核大小被步幅整除防棋盘伪影(:644-653)

ch9 人脸 (10, 506 行)

  • 流程:采集→检测→预处理→特征提取→识别(:23-38)
  • 目标检测谱系:Viola Jones/HOG→OverFeat(2013)→R-CNN(50% 提升)→Fast R-CNN(ROI 池化,端到端可导,仍依赖选择性搜索)→Faster R-CNN(RPN)(:51-106)
  • 对齐:关键点+相似变换(旋转缩放平移)→标准人脸(:122-126)
  • MTCNN(深圳先进院乔宇组,IEEE SPL 2016):P-Net(金字塔候选窗+bbox 回归+NMS)→R-Net(拒假窗)→O-Net(最终框+5 关键点);网络渐深渐准渐慢,层层过滤省时间(:134-162)
  • softmax 损失问题:类内距离可大于类间,MNIST 2 维可视化(:185-193);softmax 收敛快但卡 0.9(:199-201);Triplet Loss 属度量学习,样本挑选靠技巧、要大数据(:205-216);Center Loss 每类存中心,L=Ls+λLc,类多(>10000)吃内存(:218-238);ArcFace:W 与特征都归一化→cosθ,角度加 m、乘 s,超球面分类;MegaFace 91%→98%(洞见/InsightFace)(:241-254);代码 s=30.0, m=0.50(:289)
  • 实战:MTCNN 检 5749 张 35 分钟(2.69it/s);删 <4 张的类;resnet_face18 预训练,LFW 测试「准确率: 100%,阀值: 0.11820279」(:414, :430, :502)

ch10 迁移学习 (11, 524 行)

  • 任务 A 模型当任务 B 起点(:27-29);两场景:特征提取(冻结除最后 FC)、微调(小学习率训全/部分网络)(:42-46)
  • 预训练模型统一吃 ImageNet 标准化:mean=[0.485,0.456,0.406],std=[0.229,0.224,0.225],3×H×W<224(:104-107)
  • 冻结:requires_grad=False(:111-116);resnet18 总参 11,181,642 → 可训 5,130(:203-205)
  • 特征提取:换 fc=Linear(512,10),只训 fc→75%(3:22/epoch)(:222-233);微调+增强(Rotation15/ColorJitter/RandomResizedCrop)→95%(9:15/epoch)(:406-415)
  • 数据增强注意:别用会变类的变换,旋转 90° 把 9 变 6(:251-253)
  • 微调优于特征提取:能继续优化参数适配新任务(:340-347)
  • 去雾小网:5 层卷积带拼接,clean_image=relu(x5*x - x5 + 1),载 dehazer.pth(:450-475)
  • 「站在巨人的肩膀上」收尾(:521)

ch11 注意力翻译 (12, 720 行)

  • NMT=Encoder-Decoder=Seq2Seq;C=f(x1..xm),yi=g(C,y1..yi-1)(:19-47)
  • 缺陷:所有输出词共用同一个 C→长句崩,「分心模型」(:60-64)
  • Tom chase Jerry→汤姆/追逐/杰瑞:翻译「杰瑞」时理想分布 (Tom,0.3)(Chase,0.2)(Jerry,0.5)(:84-98);Ci=Σ αij·f2(xj),如 C汤姆=g(0.6·Tom,0.2·Chase,0.2·Jerry)(:120-129);对齐函数 F(hj,Hi-1)+softmax 归一化(:157-163);AM=词对齐模型=影响力模型(:172-179)
  • 变体:Soft/Hard/Global/Local/Self(:181-183)
  • Bahdanau 解码器 4 层:嵌入/注意力能量/RNN/输出(:247-249)
  • 实战:eng-cmn.txt 21007 对过滤成 640 对,中文词表 1063、英文 808;SOS=0/EOS=1;jieba 分词(:317-481)
  • 训练:hidden 256,SGD lr=0.01,75000 轮 47 分钟,loss 2.6447→0.0094(:630-644);翻译样例三连全对(:668-682);注意力矩阵 matshow 可视化「我们在严肃地谈论你的未来」(:691-714)

ch12 生成式实战 (13, 870 行)

  • DeepDream:梯度上升,冻结权重、更新输入像素;最大化特征 L2 范数,loss=out.norm();云像狗 [0.6,0.4] 越放大越像狗(:25-38);八度(octave):缩小 2 倍递归+高斯模糊+blend 0.6(:44-59, :119-140);VGG19 第 4/8/32 层,越顶层图案越抽象(:152-172)
  • 风格迁移(Gatys 2015):loss=风格距离+内容距离(:187-195);内容层取 conv_4(浅了太具体深了丢细节),风格层 conv_1..5 都要(:210-214, :299);风格=Gram 矩阵(通道两两内积 [ch,hw]×[hw,ch]→[ch,ch],纹理统计)(:254-261);权重 style_weight=1000000 vs content_weight=1;优化器 LBFGS,300 步(:387-390, :455);梵高星空×上海外滩
  • 修复 Context Encoder:编码器(AlexNet 式,6×6×256 瓶颈)+Channel-Wise FC+解码器 5 层反卷积;损失=重构+对抗(只重构会模糊)(:510-539)
  • DiscoGAN:两域互转 A→B→A 重构,双射约束,无需配对标签;包↔鞋;edges2shoes 4800/9000 轮 Loss_D 2.5586 Loss_G 2.3439,2.43s/it(:636-712, :835-843)

ch13 Caffe2 迁移 (14, 217 行)

  • PyTorch1.0 与 Caffe2 合并(:2-6);Caffe 层→Caffe2 计算图 Operator/blob,400+ 算子(:34-54)
  • ONNX:框架间互操作的开源格式;PyTorch 走一遍模型记录轨迹导出(:107-175);Caffe2 后端跑并 assert_almost_equal 对数(:199)
  • 排坑:protobuffer 版本、import caffe 在 import torch 后段错误(:85-99, :204-216)

ch14 对抗攻击 (15, 329 行)

  • 对抗样本:人眼难察觉的噪声让模型误判;雪山+噪声→狗(:21-27)
  • 白盒(知算法与参数)/黑盒(只看输入输出);无目标/有目标(:41-70)
  • 神经网络单元格过度线性化→对细微扰动敏感;停车标志攻击无人车(:51-57)
  • FGSM:x*=x+ε·sign(∇xJ),L∞ 约束;熊猫 57.7%→长臂猿 99.3%,ε=0.07(:75-88);FGM(L2)、IFGSM 多步 α/T,白盒下更好(:91-100)
  • PyTorch:Inception_v3,eps=0.025,steps=40,step_alpha=0.01;无目标=沿 sign(grad) 上升;有目标=减号(向目标类下降);每步 clamp 到 [-eps,eps] 和 [0,1] (:118-124, :177-251)
  • 防御四类:对抗训练/梯度掩码/随机化/去噪(:296-317);2017 NIPS 增设对抗攻防竞赛(:328-330)

ch15 强化学习 (16, 326 行)

  • 没标签没模板,只有试错反馈;爱迪生电灯(:7-13)
  • 五元素:环境/主体/状态/动作/奖励;网格 25 格 4 动作,五角星 +100、小树 -100(:53-70);输出=Policy s→a(:84-97)
  • Q-Learning:Q 表;new_q = r + γ·max(Q(s'));Q[s][a] += lr·(new_q-cur)(:111-135, :143-144);ε-greedy(ε=0.1) 平衡经验与探索(:156-164);lr=0.01, γ=0.9(:193-195);200 episodes(:236)
  • SARSA:用实际选的 next_action,Q(s',a'),不是 max → 更「胆小」,躲着陷阱走、难到宝藏(:253-284, :316-323)

ch16 深度强化学习 (17, 295 行)

  • Q 表局限:状态高维连续→表格放不下→函数逼近 Q(s,a;θ)≈Q(s,a)(:2-5, :33-39)
  • DL+RL 四矛盾:无标签只有 reward/样本前后相关/分布漂移/非线性网络不稳(:46-53)
  • DQN(Mnih 2013,Nature 2015):reward 造标签;经验回放(存 (φ,a,r,φ') 四元组,均匀随机采样打破相关性)(:57-67, :163-167);双网络 policy/target,每 C 步同步(:66-67, :99-101);L(θ)=E[(TargetQ-Q)²],TargetQ=r+γmax Q(s',a';θ-)(:76-80)
  • 实现:3 层 conv+BN,输入=相邻两帧画面差;Huber(smooth L1)损失;CartPole 50 episodes,TARGET_UPDATE 同步(:201-279)

附录 A(18)PyTorch 0.4 变更

  • Variable 并入 Tensor;type() 换 x.type()/isinstance;.data 不安全→detach();loss.data[0]→loss.item();Volatile→no_grad;dtype/device/layout(:5-70, :171-189)
  • 价值:整本书代码都是 0.4+/1.0 时代的习语,今天部分已再变(见②类锚)

附录 B(19)行业应用

  • 2019 年前新闻汇编:鲁班、车险理赔 3 天→30 分钟、摩根大通 36 万小时→秒级、青岛交通 +9.71% 等;仅当时代坐标用,不逐条引用