简介这是一份面向深度学习初学者与进阶学员的Python课件PPT系统梳理从编程基础到主流模型再到行业落地的完整知识链路帮助读者建立理论认知并衔接工程实践。内容覆盖Python语法与流程控制、数据清洗与标准化、线性回归、神经网络结构与激活函数、卷积与循环神经网络并延伸至自然语言处理、语音识别、图像分类、目标检测、生成对抗网络与强化学习等方向同时介绍TensorFlow与Keras框架、正则化与dropout等优化技巧及数据可视化方法。资源包共1个PPT文件约19.12MB以幻灯片形式组织章节便于课堂讲授与自学翻阅。目前已有289人学习适合希望系统入门深度学习、快速把握知识框架与典型应用场景的读者参考。1. 用 Python 把深度学习课件做成可复现的 PPT一份能直接抄的工程化路径带过几期深度学习内训之后我最怕听到的一句话是「课件发我一份」。因为发出去的 PPT 里模型结构图是截图训练曲线是截图连损失函数的公式都是截图——学员拿回去想改个学习率、换层数发现根本无从下手。更尴尬的是半年后我自己回头看那份课件也说不清当时那个 0.87 的准确率到底是怎么跑出来的。所以后来我给自己定了个规矩凡是深度学习相关的课件能用 Python 生成的图绝不截图能跑出结果的代码绝不只贴结论。这份《基于 Python 的深度学习课件 PPT》要解决的就是「课件里的每个数字、每张图都能追溯到一段可执行代码」这件事。它适合三类人要给团队做内训的算法工程师、要交课程设计的学生、以及想把实验记录整理成汇报材料的开发者。核心思路不复杂——用 python-pptx 做骨架用 matplotlib 出图用真实训练脚本喂数据最后把三者串成一条可重复执行的流水线。2. 为什么不用手工排版课件可复现的底层逻辑与工具选型手工做 PPT 的问题不在于慢而在于「不可复现」。你今天用鼠标拖了一个折线图进去明天数据更新了你得重新截图、重新对齐、重新调字号。一旦课件超过 30 页维护成本会指数级上升。工程化的做法是把 PPT 当成一份「编译产物」数据是源文件绘图脚本是编译器pptx 是输出。这样每次实验更新只需要重跑一遍脚本整份课件自动刷新。2.1 三条技术路线的取舍python-pptx、Jupyter 导出与模板填充常见做法有三条路我逐一试过说下各自的边界。第一条是 python-pptx 直接编程生成。它是纯 Python 库不依赖 Office 环境能在 Linux 服务器上跑。优点是控制粒度细每个文本框、每张图片的位置都能用坐标精确指定缺点是排版全靠代码写起来啰嗦一个标题加正文的版式要写七八行。第二条是 Jupyter Notebook 导出。用 nbconvert 可以把 notebook 转成幻灯片格式代码、输出、图表天然在一起。优点是「所写即所得」适合做代码演示型课件缺点是版式控制弱导出的 HTML 或 PDF 很难再精修而且对非技术听众不友好——满屏代码会劝退业务方。第三条是模板填充即先手工做一个 pptx 模板用占位符标记位置再用脚本替换文字和图片。这条路在工程上最实用因为它把「设计」和「内容」分离了设计交给会排版的人内容交给脚本。python-pptx 完全支持读取模板并操作占位符。我一般的组合是模板填充为主python-pptx 动态生成图表页为辅。纯代码生成适合页数少、结构固定的场景模板填充适合页数多、版式讲究的场景。2.2 环境准备与最小可运行示例先把依赖装好。这里锁一下大版本避免 API 变动导致脚本跑不通。# 建议在虚拟环境里操作避免污染全局 python -m venv ppt_env source ppt_env/bin/activate # Windows 用 ppt_env\Scripts\activate # 核心依赖pptx 负责生成matplotlib 负责出图pillow 处理图片尺寸 pip install python-pptx0.6.21 matplotlib3.7.1 pillow9.5.0 numpy1.24.3装完之后先跑一个最小示例确认环境没问题。下面这段代码生成一张带标题和正文的幻灯片是后面所有复杂操作的基础。from pptx import Presentation from pptx.util import Inches, Pt # 新建一个空白演示文稿 prs Presentation() # 使用第 5 号版式Title Only索引从 0 开始 slide_layout prs.slide_layouts[5] slide prs.slides.add_slide(slide_layout) # 设置标题文字与字号 title slide.shapes.title title.text 深度学习训练流程概览 title.text_frame.paragraphs[0].font.size Pt(32) # 在指定坐标插入一个文本框坐标单位是英寸 left Inches(1.0) top Inches(2.0) width Inches(8.0) height Inches(3.0) txBox slide.shapes.add_textbox(left, top, width, height) tf txBox.text_frame tf.text 数据加载 - 前向传播 - 损失计算 - 反向传播 - 参数更新 # 保存文件 prs.save(demo_minimal.pptx) print(已生成 demo_minimal.pptx)逻辑说明Presentation()不带参数时用的是内置默认模板版式索引 5 对应「仅标题」页。Inches()是长度单位转换函数python-pptx 内部用 EMUEnglish Metric Unit计量1 英寸等于 914400 EMU直接用 Inches 更直观。add_textbox返回的 shape 里text_frame才是真正管文字的对象tf.text赋值会覆盖原有内容。参数说明slide_layouts的索引在不同模板里含义不同内置模板共 11 种版式0 是标题页1 是标题加内容5 是仅标题6 是空白。如果你用自定义模板索引要对着模板实际顺序数。字号用Pt()指定正文一般 18 到 24标题 28 到 36。提示python-pptx 保存的文件在 WPS 和 Office 里都能打开但如果你用了自定义字体对方机器没装会回退成默认字体跨机器演示前先在目标机器上过一遍。3. 把训练结果变成图表matplotlib 出图与 pptx 嵌入的完整链路课件里最有说服力的不是文字是曲线。但曲线不能是随手截的得是脚本按固定数据源画出来的。这一章讲怎么把训练日志变成规范图表再嵌进 PPT。3.1 从训练日志到规范图表绘图脚本的四个关键参数假设训练脚本每轮往 CSV 里写一行字段是 epoch、train_loss、val_loss、val_acc。下面这段代码读 CSV 并画出双轴曲线。import csv import matplotlib matplotlib.use(Agg) # 无界面环境必须指定否则服务器上会报错 import matplotlib.pyplot as plt # 读取训练日志 epochs, train_loss, val_loss, val_acc [], [], [], [] with open(train_log.csv, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: epochs.append(int(row[epoch])) train_loss.append(float(row[train_loss])) val_loss.append(float(row[val_loss])) val_acc.append(float(row[val_acc])) # 创建画布尺寸按 16:9 设置方便铺满幻灯片 fig, ax1 plt.subplots(figsize(10, 5.6), dpi150) # 左轴画损失 ax1.plot(epochs, train_loss, color#2b6cb0, linewidth2, labelTrain Loss) ax1.plot(epochs, val_loss, color#c53030, linewidth2, linestyle--, labelVal Loss) ax1.set_xlabel(Epoch, fontsize12) ax1.set_ylabel(Loss, fontsize12) ax1.grid(alpha0.3) # 右轴画准确率共享 x 轴 ax2 ax1.twinx() ax2.plot(epochs, val_acc, color#2f855a, linewidth2, labelVal Acc) ax2.set_ylabel(Accuracy, fontsize12) # 合并两个轴的图例 lines1, labels1 ax1.get_legend_handles_labels() lines2, labels2 ax2.get_legend_handles_labels() ax1.legend(lines1 lines2, labels1 labels2, loccenter right, fontsize10) plt.tight_layout() plt.savefig(training_curve.png, bbox_inchestight) print(图表已保存)逻辑说明matplotlib.use(Agg)是关键服务器没有图形界面时默认后端会尝试连接显示器然后失败Agg 是纯文件渲染后端。twinx()创建共享 x 轴的第二个 y 轴适合量纲不同的两条曲线放一起。bbox_inchestight会裁掉多余白边嵌进 PPT 时不会留一圈空白。参数说明figsize按英寸给16:9 的幻灯片用 10×5.6 比较合适比例接近 1.78。dpi建议 150 以上投影仪上不糊如果要打印提到 300。线宽 2 在投影距离下看得清太细会虚。颜色用十六进制而不是r、b这种单字母方便统一色板。3.2 图片嵌入的尺寸换算与占位符替换图有了接下来嵌进 PPT。这里有个容易翻车的点图片原始像素和幻灯片英寸之间没有自动换算你得自己算否则图要么被拉伸变形要么只占一个小角。from pptx import Presentation from pptx.util import Inches prs Presentation(template.pptx) # 用事先做好的模板 slide prs.slides.add_slide(prs.slide_layouts[6]) # 空白版式 # 幻灯片默认尺寸是 10 x 7.5 英寸4:3宽屏模板是 13.33 x 7.5 slide_width prs.slide_width slide_height prs.slide_height # 图片按原始宽高比缩放留出左右各 0.5 英寸边距 img_path training_curve.png from PIL import Image with Image.open(img_path) as im: img_w, img_h im.size aspect img_h / img_w display_width slide_width - Inches(1.0) display_height int(display_width * aspect) left Inches(0.5) top int((slide_height - display_height) / 2) # 垂直居中 slide.shapes.add_picture(img_path, left, top, widthdisplay_width, heightdisplay_height) prs.save(with_chart.pptx) print(图表页已生成)逻辑说明add_picture的 width 和 height 如果只给一个另一个会按原始比例自动算两个都给就必须自己保证比例一致否则图片会被拉伸。这里用 PIL 读出原始尺寸算出宽高比再按幻灯片可用宽度反推高度保证不变形。垂直居中用(slide_height - display_height) / 2注意单位统一成 EMU 再运算。参数说明slide_width和slide_height是 EMU 整数直接参与算术没问题。边距 0.5 英寸是经验值投影时边缘不会被裁。如果模板是宽屏slide_width会是 12192000 EMU13.33 英寸脚本不用改自适应。注意不要用add_picture之后再手动设shape.width那样容易把比例改坏。一次性在调用时传对参数最稳。3.3 批量生成多页图表循环里的命名与去重一份课件往往有十几张图逐张写代码不现实。用循环批量处理但要注意文件名冲突和页序。import os from pptx import Presentation from pptx.util import Inches prs Presentation(template.pptx) chart_dir charts chart_files sorted(os.listdir(chart_dir)) # 排序保证页序稳定 for idx, fname in enumerate(chart_files): if not fname.lower().endswith(.png): continue slide prs.slides.add_slide(prs.slide_layouts[6]) img_path os.path.join(chart_dir, fname) slide.shapes.add_picture( img_path, Inches(0.5), Inches(0.5), widthprs.slide_width - Inches(1.0) ) # 在页脚加一个页码方便讲的时候定位 from pptx.util import Pt tb slide.shapes.add_textbox(Inches(0.5), prs.slide_height - Inches(0.6), Inches(2.0), Inches(0.4)) tb.text_frame.text f图 {idx 1} tb.text_frame.paragraphs[0].font.size Pt(12) prs.save(batch_charts.pptx) print(f共生成 {len(chart_files)} 页图表)逻辑说明sorted()保证文件按名字排序页序可预测不会因为文件系统返回顺序不同而每次生成结果不一样。页码用文本框单独加不依赖模板的页脚功能跨模板通用。参数说明chart_dir里的图片建议用01_loss.png、02_acc.png这种带序号前缀的命名排序结果就是讲解顺序。如果图片数量超过 50 张考虑分文件生成再合并单文件太大打开会卡。4. 避坑与排查课件生成脚本最容易翻车的五个地方这一章是我踩过的坑合集每条都按「现象 → 原因 → 解决」写照着排查能省不少时间。4.1 中文显示成方框现象图表里的中文标题、坐标轴标签全变成小方块英文正常。原因matplotlib 默认字体不含中文字形找不到就画方框。解决显式指定中文字体。Linux 上常用文泉驿或思源Windows 上用微软雅黑macOS 上用苹方。代码里加两行plt.rcParams[font.sans-serif] [SimHei, WenQuanYi Zen Hei, PingFang SC] plt.rcParams[axes.unicode_minus] False # 负号也会变方框一起关掉字体列表按优先级排系统里第一个存在的会被用上。如果服务器上没装中文字体先fc-list :langzh查一下没有就装一个。4.2 图片嵌入后模糊现象脚本里生成的图看着清晰嵌进 PPT 投影后发虚。原因matplotlib 默认 dpi 是 10010 英寸宽的图只有 1000 像素投影放大后不够。解决savefig时把 dpi 提到 200 到 300同时 PPT 里嵌入时不要放大超过原始尺寸。如果原始图 2000 像素宽幻灯片上显示宽度不超过 10 英寸约 2000 像素 200dpi就不会糊。4.3 模板占位符找不到现象脚本报KeyError或占位符文字没被替换。原因模板里的占位符索引和脚本里写的不一致或者占位符被手工删过。解决遍历slide.placeholders打印索引和名称对着实际值写代码别凭记忆。for shape in slide.placeholders: print(shape.placeholder_format.idx, shape.name)4.4 文件被占用导致保存失败现象脚本报PermissionError提示文件被另一个程序占用。原因上一次生成的 pptx 还在 PowerPoint 或 WPS 里开着Windows 下文件锁没释放。解决保存前换个文件名或者先检测并关闭。工程上更稳的做法是每次输出带时间戳的文件名避免覆盖正在打开的文件。4.5 页数多了之后生成变慢现象超过 100 页后脚本跑一次要几分钟。原因python-pptx 每次add_slide都会操作整个 XML 树页数多时开销累积。解决分块生成每 50 页存一个文件最后用python-pptx的合并逻辑或者手工拼接。另一个办法是减少每页的 shape 数量能合并的文本框合并。5. 进阶技巧让课件自带可验证的实验记录课件做到能自动生成只是第一步真正拉开差距的是「可验证」。我后来养成一个习惯每张图表页的备注栏里写清楚这张图对应的代码 commit、数据版本和关键超参。这样任何人拿到课件都能顺着备注复现出同样的图。5.1 用备注栏承载实验元数据python-pptx 支持给幻灯片加备注备注在演示时观众看不到但导出讲义或交接时非常有用。from pptx import Presentation prs Presentation(with_chart.pptx) slide prs.slides[1] # 第二页即图表页 notes_slide slide.notes_slide tf notes_slide.notes_text_frame tf.text ( 数据版本: train_log_v3.csv\n 脚本: plot_curve.py commit a1b2c3d\n 超参: lr0.001, batch64, epochs50\n 生成时间: 2024-06-01 10:30 ) prs.save(with_notes.pptx) print(备注已写入)逻辑说明notes_slide是懒加载的第一次访问时才创建备注页。notes_text_frame和普通文本框一样操作。把元数据写进备注等于给每页课件挂了一个「黑匣子」出问题能回溯。参数说明commit 号、数据文件名、超参这三样是必须的生成时间可选。如果团队用实验管理工具把 run id 也写进去。5.2 生成前做一次自检三个断言脚本跑完不代表课件没问题。我一般会在保存前加几个断言把低级错误挡在交付之前。检查项断言写法触发后的处理页数是否为零assert len(prs.slides) 0检查数据源和循环条件图片文件是否存在assert os.path.exists(img_path)检查绘图脚本是否先执行关键文字是否为空assert slide.shapes.title.text.strip()检查占位符索引这三条覆盖了最常见的「生成了但内容是空的」情况。断言失败时脚本直接退出不会产出一个看似正常实则残缺的文件。5.3 一个具体技巧把超参表做成可点击的目录页课件页数一多讲的时候翻页很痛苦。我的做法是在第二页放一个目录每一项用文本框加超链接点击直接跳到对应页。python-pptx 支持给 shape 加超链接。from pptx.util import Inches, Pt # 假设 prs 已经有多页在第 1 页加目录 toc_slide prs.slides[0] items [(数据概览, 2), (模型结构, 5), (训练曲线, 8), (消融实验, 12)] top Inches(2.0) for text, target_idx in items: tb toc_slide.shapes.add_textbox(Inches(1.0), top, Inches(6.0), Inches(0.5)) tb.text_frame.text text tb.text_frame.paragraphs[0].font.size Pt(20) # 加超链接点击跳到目标页 tb.click_action.target_slide prs.slides[target_idx] top Inches(0.7) prs.save(with_toc.pptx) print(目录页已生成)逻辑说明click_action.target_slide直接指定目标幻灯片对象不需要手写页号。目标页索引从 0 开始所以「数据概览」对应第 3 页时写 2。参数说明目录项间距 0.7 英寸字号 20一页放 6 到 8 项比较舒服。超过 8 项就分两列或者拆成两个目录页。这套流程我用了两年多最大的体会是课件的价值不在于做得漂亮而在于半年后你还能把它跑起来。我现在的习惯是任何一份深度学习课件先写生成脚本再考虑排版脚本跑不通说明实验本身就没整理清楚。希望帮到你。本文还有配套的精品资源点击获取