用 Rerun 在 Jupyter Notebook 中实时训练并可视化 2D 神经场:notebook_neural_field_2d 实战指南
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
本篇指南以 Rerun 仓库中的 notebook_neural_field_2d 示例为核心,讲解如何在 Jupyter 环境中用rerun-sdk[notebook]直接嵌入 Rerun 查看器,并驱动一个多层感知机(MLP)神经场去拟合一张 2D 图片,同时把训练损失与网络解码出的图像实时流式可视化。读完本文,你将掌握 Rerun 的 Notebook 集成安装、蓝图(Blueprint)布局编排、按迭代时间轴记录标量与图像、以及神经场训练监控的完整实战链路。
概述:Rerun 与 Notebook 生态的无缝集成
Rerun 可以直接运行在 Jupyter Notebook 内部,且不止于 Jupyter——Google Colab、VSCode Notebook 等多种交互式环境均受支持。这意味着你可以把"训练循环"和"可视化调试"放进同一个文档流里:每跑一个 cell,训练进度就实时推送到内嵌的 Rerun 查看器中。
要使用这一能力,需要单独的支撑包rerun-notebook。通常通过 Rerun SDK 的notebookextra 一条命令完成安装:
pip install "rerun-sdk[notebook]"关于依赖关系,仓库中的 rerun_notebook/README.md 给出了更详细的解释:rerun-notebook是rerun-sdkNotebook 集成的实现包,内部封装了 Rerun Viewer 编译为 Wasm 的产物(约 31MiB)以及将其绑定为 Jupyter widget 的胶水代码(re_viewer_bg.wasm与widget.js)。单独拆分这个包,是为了避免让主 SDK 的体积翻倍,同时让rerun-sdk使用 Maturin、rerun-notebook使用 hatch 各自保持简单的构建后端。
示例背景:用神经场拟合一张 2D 图片
本 Notebook 演示的是一个经典且直观的神经场(Neural Field)问题:用一个简单的神经网络去拟合一张 2D 图片。
- 神经场本质上是一个多层感知机(MLP),可选地搭配位置编码(positional input encoding);
- 图片被均匀采样,网络的任务是根据给定的像素坐标 (u, v) 预测该位置的 RGB 颜色;
- 训练过程中,我们记录 loss,并周期性密集查询网络,把编码在网络权重中的"图像"重新解码出来,实时可视化训练效果。
利用 Notebook 的交互性,你可以就地尝试不同的学习率、不同的损失函数、不同的网络架构,直观地观察这些超参数对训练过程的影响——这正是本示例最有价值的实验场景。
快速开始:在 Jupyter 中运行
第一步:安装依赖
进入示例目录,安装 requirements 即可(其中已包含 Jupyter、Rerun SDK 与 Notebook 支撑包):
pip install -r requirements.txt对应的 requirements.txt 内容如下:
ipython<=8.12 # ipython 8.13 or greater doesn't work with python 3.8 jupyter rerun-sdk[notebook] torch # Lots of reported incompatibilities across recent versions for these 3 deps. # The following seems to be the most recent recommendations for a stable experience. # See e.g. https://github.com/jupyter/notebook/issues/6721 jupyter_client<8 pyzmq<25 tornado<=6.5.5其中有三条值得注意的版本约束:jupyter_client<8、pyzmq<25、tornado<=6.5.5。这是社区针对近期 Jupyter 生态依赖不兼容问题总结出的稳定组合(详见 requirements 中的注释),在复现本示例时建议保持这些上限约束,以免遇到 Jupyter 通信层(pyzmq/tornado)的已知问题。
第二步:启动 Notebook
jupyter notebook neural_field_2d.ipynb随后在浏览器中打开生成的 Notebook 页面,从上到下依次执行 cell 即可。整个 Notebook 只有 6 个 cell,流程分为四段:导入与初始化 → 定义神经场类 → 初始化并可视化神经场 → 训练神经场。
核心实现拆解
1. 神经场网络定义
Notebook 用 PyTorch 实现了一个极简的神经场类 NeuralField,它由"位置编码(可选)+ MLP + 激活函数"三部分构成:
class NeuralField(torch.nn.Module): """Simple neural field composed of positional encoding, MLP, and activation function.""" def __init__( self, num_layers: int, dim_hidden: int, dim_in: int = 2, dim_out: int = 3, activation: str = "sigmoid", pe_sigma: float | None = None, ) -> None: super().__init__() ... sizes = [dim_in] + [dim_hidden for _ in range(num_layers - 1)] + [dim_out] self.linears = torch.nn.ModuleList() for in_size, out_size in itertools.pairwise(sizes): self.linears.append(torch.nn.Linear(in_size, out_size)) if self.pe_sigma is not None: torch.nn.init.normal_(self.linears[0].weight, 0.0, self.pe_sigma)关键点在于pe_sigma(位置编码强度):
- 当
pe_sigma=None时,第一层使用relu激活; - 当
pe_sigma不为None时,第一层使用sin作为激活,并以pe_sigma为标准差做正态初始化——这实际上把第一层线性层变成了一个随机傅里叶特征映射(random Fourier features)。
pe_sigma直接决定了神经场"开箱即用"的空间变化频率:值越大,场能轻松表示的细节越丰富,但场在训练区域之外的 extrapolation(外推)行为也会越剧烈。这在可视化实验里会非常直观地体现出来。
2. 初始化与蓝图布局
Notebook 创建了 4 个参数各异(pe_sigma分别为 5 / 15 / 30 / 100,其余相同:num_layers=5, dim_hidden=128)的神经场,用于对比位置编码强度的影响。
随后通过rr.init("rerun_example_cube")初始化 Rerun 记录,并使用rerun.blueprint声明式地搭建查看器布局:
blueprint = rrb.Blueprint( rrb.Vertical( rrb.Grid( rrb.Spatial2DView(name="Target", origin="target"), *[rrb.Spatial2DView(name=str(field), origin=f"field_{i}") for i, field in enumerate(fields)], ), rrb.TimeSeriesView( name="Losses", origin="/", plot_legend=rrb.Corner2D.LeftTop, ), row_shares=[0.7, 0.3], ), collapse_panels=True, )这段布局对应仓库中 blueprint 模块的两个核心容器 containers.py(Vertical纵向容器、Grid网格容器)与两个核心视图 spatial2d_view.py、time_series_view.py:
- 上方
Grid(占 70% 高度)并排显示 1 个Target目标图 + 4 个神经场解码图; - 下方
TimeSeriesView(占 30% 高度)显示所有 loss 曲线,图例置于左上角(Corner2D.LeftTop); collapse_panels=True折叠左右面板,把屏幕空间全部留给可视化内容。
接着用rr.notebook_show(blueprint=blueprint, width=1050, height=600)把查看器内嵌到 Notebook 输出中。从 SDK 源码 recording_stream.py 可以看到,notebook_show会阻塞直到内嵌 Viewer 初始化完成并准备好接收数据,此后的所有rr.log调用都会把数据实时推送到查看器,因此把它放在数据开始流动之前非常关键。
3. 把神经场解码为图像
log_field_as_image是可视化的核心辅助函数:它在 (u, v) 坐标的[min_uv, max_uv]范围内生成稠密网格点,逐点查询网络输出,重整为 RGB 图像后通过rr.log(entity_path, rr.Image(...))记录:
@torch.no_grad() def log_field_as_image(entity_path, field, min_uv, max_uv, uv_resolution) -> None: u_values = torch.linspace(min_uv[0], max_uv[0], uv_resolution[0]) v_values = torch.linspace(min_uv[1], max_uv[1], uv_resolution[1]) uv_points = torch.cartesian_prod(u_values, v_values) + 0.5 / torch.tensor(uv_resolution) predictions = field(uv_points) image_prediction = torch.clamp(predictions.reshape(uv_resolution[0], uv_resolution[1], 3), 0, 1) image_prediction = image_prediction.permute(1, 0, 2) rr.log(entity_path, rr.Image(image_prediction.numpy(force=True)))注意两点细节:
- 采样范围是
(-0.1, -0.1)到(1.1, 1.1),即在 [0,1] 单位正方形之外留了 10% 的余量,用来观察神经场在训练区域之外的外推行为; - 坐标点加
0.5 / resolution的偏移,对应"像素中心"的语义,保证解码图像与真实采样一致。
初始时刻(rr.set_time("iteration", sequence=0))就记录一次各字段的初始图像,此时网络权重未训练,图像完全由位置编码决定。
4. 训练循环与实时日志
训练 cell 使用 Adam 优化器,默认参数为num_iterations=3000(README 与代码注释建议跑到10000以获得更好拟合)、batch_size=1000、learning_rate=1e-3、每 10 次迭代记录一次图像。目标图片通过requests从 Rerun 示例数据集下载(tiger.jpg,可切换为注释中的bird.jpg),归一化到 [0,1] 后作为target实体记录。
每个 iteration 的核心逻辑:
target_uvs = torch.rand(batch_size, 2) # 均匀采样像素坐标 target_jis = (target_uvs * torch.tensor([target_image.shape[1], target_image.shape[0]])).int() target_rgbs = target_image[target_jis[:, 1], target_jis[:, 0]] # 采样目标颜色 for field_id in field_ids: field = fields[field_id] total_iterations[field_id] += 1 predicted_rgbs = field(target_uvs) loss = torch.nn.functional.mse_loss(target_rgbs, predicted_rgbs) rr.set_time("iteration", sequence=total_iterations[field_id]) rr.log(f"loss/field_{field_id}", rr.Scalars(loss.item())) loss.backward() optimizer.step() if iteration % log_image_period == 0: for field_id in field_ids: log_field_as_image(f"field_{field_id}", fields[field_id], (-0.1, -0.1), (1.1, 1.1), (100, 100))这里体现了 Rerun 时序数据模型的正确用法:
rr.set_time("iteration", sequence=...)设置自定义时间轴(timeline),后续 log 都挂在该时间戳上;- loss 用
rr.Scalars记录到loss/field_i实体,配合初始化时rr.log(..., rr.SeriesLines(names=..., aggregation_policy=...), static=True)注册的序列样式(使用Average 聚合策略),多条 loss 曲线在同一张时序图中可读性极佳; - 图像按
log_image_period=10的周期更新,形成"每 10 步刷新一帧解码图"的训练动画; - 整个循环包裹在
try/except KeyboardInterrupt中,中途中断也能保留已记录的数据;重复运行该 cell 会从上次状态继续训练(total_iterations累加),想要重置则重新运行上一个 cell。
深入原理:Notebook 集成在底层是如何工作的
rr.notebook_show并不是简单地把图片贴进 Notebook。从 SDK 的 notebook 实现(如 recording_stream.py 与 _legacy_notebook.py)可以看到两条技术路径:
现代路径(默认):基于
anywidget机制的 Jupyter widget。查看器(Wasm 编译产物)作为 widget 资源注入单元格,Rerun SDK 通过 Jupyter comms 通道把日志数据持续推送给内嵌 viewer。notebook_show会阻塞到 viewer 就绪,之后所有 log 调用即时送达。Legacy 路径:
legacy_notebook_show/as_html将当前录制数据整体编码为 base64 的.rrd,嵌入一个 HTML 模板,再放进 iframe 加载https://app.rerun.io(默认地址,可用app_url覆盖;若调用过rr.start_web_viewer_server()则指向 localhost)。该方式对 anywidget 支持不完善的环境更友好,但每次展示都会做一次阻塞式 flush。
对于资产(Wasm/JS)的加载方式,rerun-notebook支持通过环境变量RERUN_NOTEBOOK_ASSET控制,需在import rerun_notebook之前设置:
RERUN_NOTEBOOK_ASSET=inline:将资产内联后通过 comms 直接传输,最可移植,但已知在 Google Colab 等环境存在内存泄漏与性能问题;RERUN_NOTEBOOK_ASSET=serve-local:在内核生命周期内于本地启动线程提供资产,Wasm 可流式编译,启动更快且可被浏览器缓存,适合本地 Jupyter;RERUN_NOTEBOOK_ASSET=https://your-hosted-asset-url.com/widget.js:从自托管 URL 加载,需同时提供相邻路径的re_viewer_bg.wasm,并配置好 CORS。
实验建议:把 Notebook 当作训练调参台
README 明确指出本示例的核心价值在于交互式实验。建议你按以下思路改造训练 cell,观察不同超参数对收敛行为的影响:
- 位置编码强度:对比
pe_sigma在 5、15、30、100 下的表现——过小则网络难以表达高频细节(图像模糊),过大则训练初期抖动剧烈、外推区域出现强烈的纹波; - 学习率:把
learning_rate从1e-3调大或调小一两个数量级,观察 loss 曲线的收敛速度与震荡; - 网络容量:修改
num_layers与dim_hidden,感受表达能力与拟合速度的权衡; - 训练轮数:
num_iterations从 3000 提到 10000,让图像细节持续逼近原图; - 损失函数:将
mse_loss换成其他损失,观察视觉质量差异。
得益于rr.Scalars+TimeSeriesView的实时联动,你无需等待训练结束即可判断当前配置是否有效;KeyboardInterrupt随时可以中断并保留已记录的所有中间帧。
小结
notebook_neural_field_2d 是一个把"训练 + 可视化 + 交互调参"压缩进单个 Notebook 的典型范例:它同时演示了 Rerun Notebook 集成的安装与运行、Blueprint 声明式布局、自定义时间轴上的标量/图像日志,以及神经场的原理与超参数影响。掌握这一模式后,你可以把它推广到任何"循环内可视化"的深度学习工作流——实时监控 loss、权重、梯度乃至任意中间表征,让调试回归直觉。
相关文件索引:
- 示例说明:README.md
- Notebook 本体:neural_field_2d.ipynb
- 依赖清单:requirements.txt
- Notebook 集成实现包说明:rerun_notebook/README.md
notebook_show源码:recording_stream.py- Legacy HTML 渲染实现:_legacy_notebook.py
- 蓝图容器与视图:containers.py、spatial2d_view.py、time_series_view.py
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考