ER-NeRF模块解析-network

ER-NeRF中在模型文件中包含两个和model相关的文件,一个是network.py,另一个是renderer.py,这里分析这两个文件各自的作用。

功能差异

这两个文件是同一个渲染体系里“通用渲染框架 (renderer)”与“具体网络结构 (network)”的分层实现:

  • renderer.py 定义了 NeRF 推理/训练时的“光线行进 + 体渲染组合逻辑”的通用骨架(NeRFRenderer 基类)。
  • network.py 在这个骨架之上定义了具体模型(NeRFNetwork)——包括音频特征、哈希/频率编码、密度/颜色/不确定性/注意力等神经网络结构,并覆写/调用基类期望的接口。
文件主要类职责定位不放在一起原因
renderer.pyNeRFRenderer光线采样、ray marching、密度栅格(加速结构)维护、组合积分(composite)、torso/head 混合、密度网格更新纯渲染管线逻辑相对稳定,可复用给不同网络结构或改写模型部分时保持不动
network.pyNeRFNetwork (+ AudioNet, AudioAttNet, MLP)具体的可学习模型:音频编码、三平面 (triplane/hashgrid) 特征编码、sigma/color/uncertainty/注意力/torso 等实际预测模型结构试验频繁,独立文件便于迭代;避免 renderer 变得巨无霸

简单说:renderer.py 处理 “给我一堆光线,我负责决定沿光线路径取多少采样点、取完后怎么合成”,network.py 负责 “给我坐标/方向/音频条件,我算出密度、颜色、注意力等数值”。

具体关系

调用流程(训练或推理一次)

  1. 上层(例如 utils.py 的 train_step / test_step)准备:rays_o, rays_d, auds, poses, bg_coords, eye, index。
  2. 调用 NeRFNetwork.render(…)(注意这其实继承自 NeRFRenderer.render,它内部直接 _run = self.run_cuda)。
  3. run_cuda 做的事(来自 renderer.py):
    • 展平/整理光线张量
    • 计算与 aabb 的 near / far
    • 通过 self.encode_audio(auds)(这个方法来自 NeRFNetwork 定义)拿条件向量 enc_a
    • 训练模式:调用 raymarching.march_rays_train 得到所有 sample points(xyzs, dirs 等)
    • 调用 self(xyzs, dirs, enc_a, ind_code, eye) —— 这里的 self.call 就是 NeRFNetwork.forward(来自 network.py)
    • 得到每个采样点的 sigma, color, amb_aud, amb_eye, uncertainty
    • 用 raymarching.composite_* 把这些沿光线积分成最终像素颜色和深度
    • Torso 逻辑 run_torso(仍在 renderer.py)把背景/躯干合成
    • 返回 results(包含 image, depth, ambient_* 等)
  4. renderer.py 从不关心“网络长什么样”,只假设 self(…) 能返回“密度 + 颜色 + 附加通道”。

继承优势

继承带来几个优势:

  • 直接复用光线加速(bitfield、density grid、更新函数、torso 混合)
  • 可以只关注“如何根据输入点求 (sigma, color, 辅助特征)”
  • 如果未来换另一种表达(例如不同的 hashgrid 参数、增加情绪编码),不需要重写渲染循环

关键接口契约

在 renderer.py 的 run_cuda 里,它期望网络(子类)提供:

  • encode_audio(auds)(network.py 内实现,音频 → 嵌入 enc_a)
  • __call__(xyzs, dirs, enc_a, ind_code, eye)(network.py 的 forward)
    返回值顺序固定:sigma, color, ambient_aud, ambient_eye, uncertainty
  • density(…):用于加速结构更新时仅查询密度(network.py 里重新实现的 density,和 forward 共用前半部编码)
  • Optional:forward_torso(渲染 torso 时使用)

而 network.py 又依赖基类里的一些属性:

  • self.bound, self.cuda_ray, self.density_bitfield(加速结构)
  • self.individual_codes / camera 偏移参数(个体化学习)
  • self.run_torso() 在基类中被调用
          +------------------+
          |  NeRFRenderer    |  (renderer.py)
          |------------------|
   calls  | run_cuda()       |--> raymarching.* (C++/CUDA)
          | render()         |
          | run_torso()      |
          +---------^--------+
                    |
             inherits
                    |
          +------------------+
          |  NeRFNetwork     |  (network.py)
          |------------------|
          | encode_audio()   |
          | forward()        |--> uses AudioNet / Hash Encoders / MLP
          | density()        |
          +------------------+

常见修改路线举例

场景:你想让渲染结果根据情绪(emotion embedding)变化:

  1. 在 network.py 添加 emotion embedding 输入并拼到 enc_a 或额外通道。
  2. 修改 density / forward 拼接方式。
  3. 不需要改 renderer.py,除非 emotion 也要写进 composite 的统计结果(再扩展 raymarching 的 ambient 通道)。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注