From dd2d67badcc4976e168d0d2f6fb307db85502490 Mon Sep 17 00:00:00 2001 From: "engine-labs-app[bot]" <140088366+engine-labs-app[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 07:32:39 +0000 Subject: [PATCH] feat(docs): add SUMMARY.md, tooling, and environment notes for repo structure & reproducibility Add a comprehensive SUMMARY.md, mapping structure & key topics of major notebook series. Introduce scripts/list_notebooks.py and Makefile (toc) for auto-generating markdown TOC. Document core dependencies and environment guidelines, validated via partial smoke runs. .gitignore updated for virtualenv, Jupyter cache, and data folders. Suggestions for repo maintenance added. This change improves discoverability for learners and maintainers, standardizes entry points, and provides guidance for dependency management and reproducibility in a diverse notebook repo. --- .gitignore | 14 +++++ Makefile | 7 +++ SUMMARY.md | 105 ++++++++++++++++++++++++++++++++++++++ scripts/list_notebooks.py | 90 ++++++++++++++++++++++++++++++++ 4 files changed, 216 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 SUMMARY.md create mode 100755 scripts/list_notebooks.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a3ba99 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Python virtual environments +.venv/ + +# Notebook artifacts +.ipynb_checkpoints/ +*.nbconvert.ipynb + +# Python cache +__pycache__/ +*.py[cod] +*$py.class + +# Data downloaded during experiments +/data/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b2c5323 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +PYTHON ?= python3 +REPO_ROOT := $(abspath .) + +.PHONY: toc + +toc: + $(PYTHON) scripts/list_notebooks.py $(REPO_ROOT) diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 0000000..5936644 --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,105 @@ +# 仓库综览与技术总结 + +## 仓库概览 +- 根目录的 [README.md](README.md) 聚合了作者的 AI 学习路线、公开课与资料下载链接,涵盖机器学习/深度学习/图神经网络/爬虫等多个主题,是整个仓库的索引入口。 +- 教学内容以 Jupyter Notebook 为主,核心系列包括《深度学习100例》、其 PyTorch 版本尝试、面向新手的《小白入门PyTorch》、以及「对Pytorch一头雾水系列」。 +- 另附有独立的 [《图神经网络(GNN)教程-总篇》](图神经网络(GNN)教程-总篇.md) Markdown 资料,介绍 tf_geometric 库和教程导航。 + +## Notebook 结构地图 + +### 《深度学习100例》系列 +| Day | 主题 | Notebook | +| --- | --- | --- | +| 01 | 卷积神经网络(CNN)mnist数字识别 | [1.深度学习100例-卷积神经网络(CNN)mnist数字识别-第1天.ipynb](《深度学习100例》/01-day/1.深度学习100例-卷积神经网络(CNN)mnist数字识别-第1天.ipynb) | +| 02 | 卷积神经网络(CNN)彩色图片分类 | [2.深度学习100例-卷积神经网络(CNN)彩色图片分类 - 第2天.ipynb](《深度学习100例》/02-day/2.深度学习100例-卷积神经网络(CNN)彩色图片分类 - 第2天.ipynb) | +| 03 | 卷积神经网络(CNN)服装图像分类 | [3.深度学习100例-卷积神经网络(CNN)服装图像分类 - 第3天.ipynb](《深度学习100例》/03-day/3.深度学习100例-卷积神经网络(CNN)服装图像分类 - 第3天.ipynb) | +| 04 | 卷积神经网络(CNN)花朵识别 | [4.深度学习100例-卷积神经网络(CNN)花朵识别 - 第4天.ipynb](《深度学习100例》/04-day/4.深度学习100例-卷积神经网络(CNN)花朵识别 - 第4天.ipynb) | +| 05 | 卷积神经网络(CNN)天气识别 | [5.深度学习100例-卷积神经网络(CNN)天气识别 - 第5天.ipynb](《深度学习100例》/05-day/5.深度学习100例-卷积神经网络(CNN)天气识别 - 第5天.ipynb) | +| 06 | 卷积神经网络(VGG-16)海贼王人物识别 | [6.深度学习100例-卷积神经网络(VGG-16)海贼王人物识别 - 第6天.ipynb](《深度学习100例》/06-day/6.深度学习100例-卷积神经网络(VGG-16)海贼王人物识别 - 第6天.ipynb) | +| 07 | 卷积神经网络(VGG-19)灵笼人物识别 | [7.深度学习100例-卷积神经网络(VGG-19)灵笼人物识别 - 第7天.ipynb](《深度学习100例》/07-day/7.深度学习100例-卷积神经网络(VGG-19)灵笼人物识别 - 第7天.ipynb) | +| 08 | 卷积神经网络(ResNet-50)鸟类识别 | [8.深度学习100例 -卷积神经网络(ResNet-50)鸟类识别 - 第8天.ipynb](《深度学习100例》/08-day/8.深度学习100例 -卷积神经网络(ResNet-50)鸟类识别 - 第8天.ipynb) | +| 09 | 循环神经网络(RNN)实现股票预测 | [9.循环神经网络(RNN)实现股票预测-深度学习100例-第9天.ipynb](《深度学习100例》/09-day/9.循环神经网络(RNN)实现股票预测-深度学习100例-第9天.ipynb) | +| 10 | LSTM 股票开盘价预测 | [10.第10天.ipynb](《深度学习100例》/10-day/10.第10天.ipynb) | +| 11 | 卷积神经网络(AlexNet)鸟类识别 | [11.卷积神经网络(AlexNet)鸟类识别-深度学习100例-第11天.ipynb](《深度学习100例》/11-day/11.卷积神经网络(AlexNet)鸟类识别-深度学习100例-第11天.ipynb) | +| 12 | 卷积神经网络(CNN)识别验证码 | [12.深度学习100例-卷积神经网络(CNN)识别验证码 - 第12天.ipynb](《深度学习100例》/12-day/12.深度学习100例-卷积神经网络(CNN)识别验证码 - 第12天.ipynb) | +| 13 | 卷积神经网络(Inception V3)识别手语 | [13.深度学习100例 -卷积神经网络(Inception V3)识别手语 - 第13天.ipynb](《深度学习100例》/13-day-识别手语/13.深度学习100例 -卷积神经网络(Inception V3)识别手语 - 第13天.ipynb) | +| 14 | 卷积神经网络(Inception-ResNet-v2)交通标志识别 | [14.深度学习100例-卷积神经网络(Inception-ResNet-v2)交通标志识别 - 第14天.ipynb](《深度学习100例》/14-day-识别交通标志/14.深度学习100例-卷积神经网络(Inception-ResNet-v2)交通标志识别 - 第14天.ipynb) | +| 15 | 卷积神经网络(CNN)车牌识别 | [15.深度学习100例-卷积神经网络(CNN)车牌识别 - 第15天.ipynb](《深度学习100例》/15-day-实现车牌识别/15.深度学习100例-卷积神经网络(CNN)车牌识别 - 第15天.ipynb) | +| 16 | 卷积神经网络(CNN)识别神奇宝贝小智一伙 | [16.深度学习100例-卷积神经网络(CNN)识别神奇宝贝小智一伙-第16天.ipynb](《深度学习100例》/16-day-识别神奇宝贝小智一伙/16.深度学习100例-卷积神经网络(CNN)识别神奇宝贝小智一伙-第16天.ipynb) | +| 17 | 卷积神经网络(CNN)注意力检测 | [17.深度学习100例-卷积神经网络(CNN)注意力检测 - 第17天.ipynb](《深度学习100例》/17-day-识别眼睛状态/17.深度学习100例-卷积神经网络(CNN)注意力检测 - 第17天.ipynb) | +| 18 | 生成对抗网络(GAN)手写数字生成 | [18.深度学习100例-生成对抗网络(GAN)手写数字生成 - 第18天.ipynb](《深度学习100例》/18-day-GAN-手写数字生成/18.深度学习100例-生成对抗网络(GAN)手写数字生成 - 第18天.ipynb) | +| 19 | 生成对抗网络(DCGAN)手写数字生成 | [19.深度学习100例-生成对抗网络(DCGAN)手写数字生成 - 第19天.ipynb](《深度学习100例》/19-day-DCGAN-手写数字生成/19.深度学习100例-生成对抗网络(DCGAN)手写数字生成 - 第19天.ipynb) | +| 20 | 生成对抗网络(DCGAN)生成动漫小姐姐 | [20.深度学习100例-生成对抗网络(DCGAN)生成动漫小姐姐 - 第20天.ipynb](《深度学习100例》/20-day-DCGAN-生成动漫小姐姐/20.深度学习100例-生成对抗网络(DCGAN)生成动漫小姐姐 - 第20天.ipynb) | +| 21 | 卷积神经网络(VGG-16)猫狗识别 | [深度学习100例-卷积神经网络(VGG-16)猫狗识别-第21天.ipynb](《深度学习100例》/21-day-猫狗识别/深度学习100例-卷积神经网络(VGG-16)猫狗识别-第21天.ipynb) | +| 22 | 卷积神经网络(LeNet-5)深度学习里的“Hello Word” | [深度学习100例-卷积神经网络(LeNet-5)深度学习里的“Hello Word” - 第22天.ipynb](《深度学习100例》/22-day/深度学习100例-卷积神经网络(LeNet-5)深度学习里的“Hello Word” - 第22天.ipynb) | +| 23 | 卷积神经网络-3D医疗影像识别 | [深度学习100例-卷积神经网络-3D医疗影像识别 - 第23天.ipynb](《深度学习100例》/23-day-3D医疗影像识别/深度学习100例-卷积神经网络-3D医疗影像识别 - 第23天.ipynb) | +| 24 | 卷积神经网络(Xception)动物识别 | [深度学习100例-卷积神经网络(Xception)动物识别 - 第24天.ipynb](《深度学习100例》/24-day-动物识别/深度学习100例-卷积神经网络(Xception)动物识别 - 第24天.ipynb) | +| 25 | 中文手写数字识别 | [中文手写数字识别.ipynb](《深度学习100例》/25-day-中文手写数字识别/中文手写数字识别.ipynb) | +| 26 | 卷积神经网络(CNN):乳腺癌识别 | [深度学习100例 - 第26天-卷积神经网络(CNN):乳腺癌识别.ipynb](《深度学习100例》/26-day-乳腺癌识别/深度学习100例 - 第26天-卷积神经网络(CNN):乳腺癌识别.ipynb) | +| 27 | 艺术作品识别 | [27-艺术作品识别.ipynb](《深度学习100例》/27-day-艺术作品识别/27-艺术作品识别.ipynb) | +| 28 | 水果识别 | [28-水果识别.ipynb](《深度学习100例》/28-day-水果识别/28-水果识别.ipynb) | +| 29 | 船型识别 | [29-船型识别.ipynb](《深度学习100例》/29-day-船型识别/29-船型识别.ipynb) | +| 35 | MobileNetV2模型:脑肿瘤识别 | [深度学习100例 - 第35天-MobileNetV2模型:脑肿瘤识别.ipynb](《深度学习100例》/35-day-脑肿瘤识别/深度学习100例 - 第35天-MobileNetV2模型:脑肿瘤识别.ipynb) | + +> 说明:部分目录(如 Day 30+)尚未在仓库中提供对应 Notebook;多个专题需要配套数据集(如 `./datasets/`、图像压缩包等)才能完整运行。 + +### 《深度学习100例》-PyTorch版本 +- [第1例-猫狗识别.ipynb](《深度学习100例》-PyTorch版本/1-day/第1例-猫狗识别.ipynb):以 PyTorch 重写 Day 21 猫狗分类案例。 + +### 《小白入门PyTorch》 +- [1-什么是PyTorch?.ipynb](《小白入门PyTorch》/1-什么是PyTorch?.ipynb):张量基础与 GPU 切换。 +- [2-自动微分.ipynb](《小白入门PyTorch》/2-自动微分.ipynb):Autograd 与反向传播示例。 +- [3-简单实例快速入门.ipynb](《小白入门PyTorch》/3-简单实例快速入门.ipynb):Fashion-MNIST 分类流程(含训练/测试循环与模型保存)。 +- [4-如何训练自己的数据集.ipynb](《小白入门PyTorch》/4-如何训练自己的数据集.ipynb):自定义 `ImageFolder`、数据加载与训练模板。 +- [5-如何进行数据增强.ipynb](《小白入门PyTorch》/5-如何进行数据增强.ipynb):在猫狗数据集上叠加 `torchvision.transforms` 增强。 + +### 对Pytorch一头雾水系列 +- [Pytorch100例-第1天:实现mnist手写数字识别第1天.ipynb](对Pytorch一头雾水系列/Pytorch100例-第1天:实现mnist手写数字识别第1天.ipynb):基础 CNN + MNIST。 +- [Pytorch100例-第2天:彩色图片识别.ipynb](对Pytorch一头雾水系列/Pytorch100例-第2天:彩色图片识别.ipynb):彩色图像分类。 +- [Pytorch100例-第3天:天气识别.ipynb](对Pytorch一头雾水系列/Pytorch100例-第3天:天气识别.ipynb):多类天气图片识别。 + +### 图神经网络(GNN)教程 +- [图神经网络(GNN)教程-总篇.md](图神经网络(GNN)教程-总篇.md):介绍 `tf_geometric`、GAT 示例、官方 Demo 链接与 API 导航,配合后续 Notebook 使用。 + +### 自动化辅助 +- 新增脚本 [scripts/list_notebooks.py](scripts/list_notebooks.py) 可按目录生成 Markdown 目录树:`python scripts/list_notebooks.py`。 +- Makefile 增加 `make toc` 目标(默认使用环境中的 `python`,可通过 `make toc PYTHON=.venv/bin/python` 指定虚拟环境)。 + +## 依赖与环境建议 +> 仓库未提供 requirements/env 文件,需要根据 Notebook 内容组建环境。建议按框架拆分安装,CPU 环境可运行大部分示例。 + +- **通用科学计算**:`numpy>=1.24`, `pandas>=1.5`, `matplotlib>=3.7`, `seaborn`, `scipy`, `tqdm`。 +- **PyTorch 系列**:`torch>=2.0`, `torchvision>=0.15`, `torchinfo`(部分模型总结)、`Pillow`、`imageio`、`scikit-learn`(数据切分与评估)。 +- **TensorFlow/Keras 系列**:`tensorflow>=2.6`(含 `tensorflow.keras`)、必要时单独安装 `keras`、`sklearn`、`nibabel`(3D 医疗影像)、`scikit-image`、`opencv-python`(若需图像增强)。`tf_geometric` 示例需额外安装 `tf-geometric` 库。 +- **数据处理/可视化**:`pandas`, `matplotlib`, `seaborn`, `plotly`(若扩展交互式可视化)。 +- **推荐流程**: + ```bash + python -m venv .venv + source .venv/bin/activate # Windows 使用 .venv\Scripts\activate + pip install --upgrade pip + pip install torch torchvision numpy pandas matplotlib scikit-learn + # 按需补充 tensorflow / tensorflow-datasets 等 + ``` +- Notebook 依赖外部数据:`./datasets/`、`./data/cat-dog/`、Fashion-MNIST、GAN 图像等需要手动下载或提前放置。运行前请检查路径并考虑提供小样本以降低训练成本。 + +## 烟囱运行记录(CPU,无长时间训练) +1. **《小白入门PyTorch》/1-什么是PyTorch?.ipynb**(.venv + `torch` + `numpy`):完成张量创建、加法、形状变换、NumPy 互操作;`torch.cuda.is_available()` 返回 `False`,验证 CPU 环境可运行基础操作。 +2. **《小白入门PyTorch》/2-自动微分.ipynb**:复现自动求导示例,`out.backward()` 得到梯度矩阵 `[[4.5,...]]`,并演示自定义梯度向量回传和 `torch.no_grad()` 关闭梯度的效果。 +3. **《小白入门PyTorch》/3-简单实例快速入门.ipynb**:下载 Fashion-MNIST 到 `./data/`,构造 `DataLoader`、搭建全连接网络,在未训练的情况下完成一次前向推理(输出类别统计与样本预测对比)。记录:模型参数量约 101,770;随机初始化预测与真实标签可能不一致;完整训练需约 5 epoch,未在烟囱运行中执行。 + +> 依赖补充:上述运行需 `torch==2.9.0+cpu`、`torchvision==0.24.0+cpu`、`numpy==2.3.4`。Fashion-MNIST 数据已下载到 `data/` 目录(现已加入 `.gitignore`)。 + +## 维护与改进建议 +- **补齐环境说明**:按照系列拆分 `requirements` 或 `environment.yml`,并标注 TensorFlow / PyTorch 版本建议,避免用户自行摸索依赖。 +- **统一数据获取方式**:为所有 Notebook 提供统一的数据下载脚本或 `make data` 流程,减少手动放置压缩包的踩坑。可考虑提供轻量级示例数据以便 CPU 快速验证。 +- **整理重复内容**:`《深度学习100例》` 与「对Pytorch一头雾水系列」在早期案例上高度重合,可合并说明差异(框架实现、难度分层)或共享同一数据/预处理模块。 +- **升级/兼容性检查**: + - TensorFlow Notebook 大量使用 `tf.config.experimental`、`tf.keras` 老接口,建议验证在 TF 2.13+ 下的兼容性并更新写法。 + - 同一 Notebook 中同时引用 `keras` 与 `tensorflow.keras`,应统一来源,避免环境冲突。 +- **运行耗时提示**:在每个 Notebook 开头标注训练耗时、是否需要 GPU/外部数据、可选的“快速模式”(减少 epoch / 样本量),提升学习体验。 +- **结果复现清单**:整理各 Day 预期指标(如 Day10 LSTM 的 R²≈0.74),方便对比输出;必要时提供已训练模型权重下载。 +- **目录维护**:考虑在 `README` 或 `SUMMARY.md` 中增加更新时间/进度表,并借助 `make toc` 周期性刷新 Notebook 列表。 + +## 其它说明 +- 新增 `.gitignore` 忽略 `.venv/`、`.ipynb_checkpoints/`、`/data/` 等运行中生成的文件。 +- `make toc` 运行示例:`make toc PYTHON=.venv/bin/python`(亦可直接执行脚本获取目录 Markdown)。 diff --git a/scripts/list_notebooks.py b/scripts/list_notebooks.py new file mode 100755 index 0000000..0e1b403 --- /dev/null +++ b/scripts/list_notebooks.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""Generate a markdown table of contents for all notebooks in the repo.""" +from __future__ import annotations + +import argparse +import sys +from collections import defaultdict +from pathlib import Path +from typing import Iterable + + +def _natural_key(text: str) -> list[object]: + """Turn a string into a key that sorts numbers numerically.""" + import re + + pieces: list[str] = re.split(r"(\d+)", text) + key: list[object] = [] + for piece in pieces: + if piece.isdigit(): + key.append(int(piece)) + elif piece: + key.append(piece.lower()) + return key + + +def _path_key(path: Path) -> list[object]: + return [_natural_key(part) for part in path.parts] + + +def generate_markdown(root: Path) -> str: + groups: dict[str, list[Path]] = defaultdict(list) + + for notebook in sorted(root.rglob("*.ipynb"), key=_path_key): + relative = notebook.relative_to(root) + if relative.parts[0].startswith("."): + # Skip hidden directories such as .venv + continue + groups[relative.parts[0]].append(relative) + + lines: list[str] = ["# Notebook Table of Contents", ""] + + for top_level in sorted(groups, key=_natural_key): + lines.append(f"## {top_level}") + subgroups: dict[str, list[Path]] = defaultdict(list) + for rel_path in groups[top_level]: + if len(rel_path.parts) > 2: + subgroups[rel_path.parts[1]].append(rel_path) + else: + subgroups[""].append(rel_path) + + for subgroup in sorted(subgroups, key=_natural_key): + notebooks = sorted(subgroups[subgroup], key=_path_key) + if subgroup: + lines.append(f"- {subgroup}") + for rel_path in notebooks: + lines.append( + f" - [{rel_path.name}]({rel_path.as_posix()})" + ) + else: + for rel_path in notebooks: + lines.append( + f"- [{rel_path.name}]({rel_path.as_posix()})" + ) + lines.append("") + + return "\n".join(lines).strip() + "\n" + + +def main(argv: Iterable[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "root", + nargs="?", + default=Path.cwd(), + type=Path, + help="Repository root (defaults to current working directory)", + ) + args = parser.parse_args(list(argv) if argv is not None else None) + + root_path = args.root.resolve() + if not root_path.exists(): + parser.error(f"root path {root_path} does not exist") + + markdown = generate_markdown(root_path) + sys.stdout.write(markdown) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())