概述
Dyn-O1是NeurIPS 2025录用的重要论文,提出了一种基于物体中心表示(Object-Centric Representation)的结构化世界模型。与传统的黑盒世界模型不同,Dyn-O的核心创新在于将复杂场景显式分解为独立的物体表示,并通过结构化的动态建模实现:
- 可解释的预测:每一步预测都能追溯到具体物体
- 可组合的操作:物体表示可独立或组合使用
- 零样本泛化:处理训练中未见过的物体组合
- 物理一致性:显式编码物体间的物理关系
┌─────────────────────────────────────────────────────────────────┐
│ Dyn-O 核心理念 │
│ │
│ 传统世界模型(黑盒): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ o_t ──▶ [ Black Box ] ──▶ o_{t+1} │ │
│ │ │ │
│ │ 问题: │ │
│ │ • 内部表示不可解释 │ │
│ │ • 难以处理物体数量变化 │ │
│ │ • 零样本泛化困难 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Dyn-O(物体中心结构化): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 场景分解: {Object_1, Object_2, Object_3, ...} │ │
│ │ ↓ ↓ ↓ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ 结构化动态模型 │ │ │
│ │ │ │ │ │
│ │ │ {Obj_1} ──▶ f_1 ──▶ {Obj_1'} │ │ │
│ │ │ {Obj_2} ──▶ f_2 ──▶ {Obj_2'} │ │ │
│ │ │ {Obj_3} ──▶ f_3 ──▶ {Obj_3'} │ │ │
│ │ │ ↑ │ │ │
│ │ │ 关系建模 │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ 场景重构: {Obj_1', Obj_2', Obj_3', ...} │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
1. 研究背景与动机
1.1 现有世界模型的局限性
| 局限性 | 传统世界模型 | 影响 |
|---|---|---|
| 黑盒表示 | 隐式向量表示 | 难以解释、调试 |
| 固定物体数 | 假设固定场景 | 无法处理动态场景 |
| 组合泛化 | 缺乏组合结构 | 难以处理新物体组合 |
| 物理一致性 | 隐式建模 | 可能违反物理规律 |
1.2 为什么需要物体中心表示
人类对世界的理解天然是物体中心的:
- 组合性:世界由可组合的物体组成
- 持久性:物体在时间上保持连续性
- 可命名性:我们可以给物体命名和描述
- 因果性:物体间的交互驱动场景变化
Dyn-O正是基于这一认知洞察,通过学习物体中心的表示来实现结构化的世界模型。
1.3 核心挑战
| 挑战 | 描述 | Dyn-O的解决方案 |
|---|---|---|
| 物体发现 | 如何从原始观测中提取物体 | Slot-based注意力机制 |
| 状态表示 | 如何表示每个物体的状态 | 解耦的物体特征向量 |
| 动态建模 | 如何建模物体间交互 | 图结构关系网络 |
| 组合泛化 | 如何泛化到新组合 | 物体无关的动态函数 |
2. 方法论
2.1 系统概览
┌─────────────────────────────────────────────────────────────────┐
│ Dyn-O 方法流程 │
│ │
│ 输入观测 o_t │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 物体发现模块 (Object Discovery) │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Slot Attention 机制 │ │ │
│ │ │ │ │ │
│ │ │ Feature Map ──▶ K Slots ──▶ N Object Slots │ │ │
│ │ │ ↓ │ │ │
│ │ │ 掩码生成 │ │ │
│ │ │ ↓ │ │ │
│ │ │ 物体特征 │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 物体状态编码 (Object State Encoding) │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ 位置编码 │ 外观编码 │ 运动编码 │ 语义编码 │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ s_i = [pos_i, appearance_i, motion_i, semantic_i] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 关系推理模块 (Relational Reasoning) │ │
│ │ │ │
│ │ Object_1 ◀─────────────▶ Object_2 │ │
│ │ │ relation(1,2) │ │ │
│ │ ▼ ▼ │ │
│ │ Object_1' ──────────────▶ Object_2' │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 动态预测模块 (Dynamics Prediction) │ │
│ │ │ │
│ │ {s_1, s_2, ..., s_n} + {r_ij} ──▶ {s_1', s_2', ...} │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 输出预测 o_{t+1} │
│ │
└─────────────────────────────────────────────────────────────────┘
2.2 物体发现模块
Dyn-O使用Slot Attention机制从原始图像中发现和分离物体:
2.2.1 Slot Attention原理
Slot Attention通过迭代的注意力机制将图像特征分配到固定数量的”槽”(Slots)中:
class SlotAttention(nn.Module):
"""
Slot Attention 用于物体发现
"""
def __init__(self, num_slots, slot_dim, iterations=3):
super().__init__()
self.num_slots = num_slots
self.slot_dim = slot_dim
self.iterations = iterations
# 槽初始化
self.slot_init = nn.Linear(slot_dim, slot_dim)
# 注意力参数
self.query_proj = nn.Linear(slot_dim, slot_dim)
self.key_proj = nn.Linear(slot_dim, slot_dim)
self.value_proj = nn.Linear(slot_dim, slot_dim)
# 槽更新GRU
self.gru = nn.GRUCell(slot_dim, slot_dim)
# 层归一化
self.norm = nn.LayerNorm(slot_dim)
def forward(self, features, slots=None):
"""
Args:
features: [B, H*W, D] 图像特征
slots: [B, num_slots, slot_dim] 初始槽(可选)
Returns:
slots: [B, num_slots, slot_dim] 发现的物体槽
masks: [B, num_slots, H, W] 物体掩码
"""
B, N, D = features.shape # N = H*W
# 初始化槽
if slots is None:
slots = torch.randn(B, self.num_slots, self.slot_dim)
slots = self.slot_init(slots)
# 迭代更新槽
for _ in range(self.iterations):
# 查询-键-值投影
queries = self.query_proj(slots)
keys = self.key_proj(features)
values = self.value_proj(features)
# 计算注意力
attention = torch.matmul(queries, keys.transpose(-2, -1))
attention = attention / (self.slot_dim ** 0.5)
attention = attention.softmax(dim=-1)
# 聚合特征
attended_values = torch.matmul(attention, values)
# 更新槽
slots = self.gru(
attended_values.view(-1, self.slot_dim),
slots.view(-1, self.slot_dim)
)
slots = slots.view(B, self.num_slots, self.slot_dim)
slots = self.norm(slots)
# 生成掩码
masks = self.generate_masks(queries, keys, features.shape[1:])
return slots, masks
def generate_masks(self, queries, keys, spatial_shape):
"""根据注意力权重生成物体掩码"""
attention = torch.matmul(queries, keys.transpose(-2, -1))
attention = attention.softmax(dim=-1)
# 重塑为空间尺寸
masks = attention.view(*attention.shape[:2], *spatial_shape)
return masks2.3 物体状态表示
每个物体的状态表示包含多个解耦的组件:
class ObjectState:
"""
物体状态表示 - 结构化解耦设计
"""
def __init__(self, feature_dim):
self.components = {
# 几何属性(不随时间变化的固有属性)
'intrinsic': {
'size': torch.zeros(feature_dim), # 尺寸
'mass': torch.zeros(feature_dim), # 质量
'shape': torch.zeros(feature_dim), # 形状
'material': torch.zeros(feature_dim), # 材质
},
# 运动状态(随时间变化)
'kinematic': {
'position': torch.zeros(3), # 位置
'velocity': torch.zeros(3), # 速度
'rotation': torch.zeros(4), # 旋转四元数
'angular_velocity': torch.zeros(3), # 角速度
},
# 语义属性
'semantic': {
'class_prob': torch.zeros(feature_dim), # 类别概率
'function': torch.zeros(feature_dim), # 功能
'affordance': torch.zeros(feature_dim), # 可供性
},
# 关系属性
'relational': {
'contact': {}, # 接触关系
'containment': {}, # 包含关系
'support': {}, # 支撑关系
'spatial': {}, # 空间关系
}
}
def to_vector(self):
"""将所有组件展平为向量"""
components = []
for category in ['intrinsic', 'kinematic', 'semantic']:
for component in self.components[category].values():
components.append(component)
return torch.cat(components)2.4 关系推理模块
Dyn-O使用图神经网络建模物体间的关系:
class RelationalReasoning(nn.Module):
"""
关系推理模块 - 使用GNN建模物体交互
"""
def __init__(self, object_dim, relation_dim, num_layers):
super().__init__()
self.object_dim = object_dim
self.relation_dim = relation_dim
# 物体编码器
self.object_encoder = nn.Sequential(
nn.Linear(object_dim, 256),
nn.ReLU(),
nn.Linear(256, 256),
nn.ReLU(),
)
# 关系编码器
self.relation_encoder = RelationEncoder(relation_dim)
# GNN层
self.gnn_layers = nn.ModuleList([
GNNLayer(256, 256)
for _ in range(num_layers)
])
# 消息函数
self.message_function = MessageFunction(256, relation_dim)
# 聚合函数
self.aggregate_function = AggregateFunction()
def forward(self, objects, relations):
"""
Args:
objects: [B, N, object_dim] 物体特征
relations: [B, N, N, relation_dim] 关系矩阵
Returns:
updated_objects: [B, N, object_dim] 更新后的物体特征
"""
# 编码物体
obj_features = self.object_encoder(objects)
# 迭代消息传递
for layer in self.gnn_layers:
# 计算关系特征
rel_features = self.relation_encoder(relations)
# 消息传递
messages = self.message_function(
obj_features, rel_features
)
# 聚合消息
aggregated = self.aggregate_function(messages)
# 更新物体特征
obj_features = layer(obj_features, aggregated)
return obj_features2.5 动态预测模型
Dyn-O的动态预测模型基于物体无关的物理先验:
class ObjectDynamicsModel(nn.Module):
"""
物体动态模型 - 学习通用的物理动态
"""
def __init__(self, state_dim, action_dim, hidden_dim):
super().__init__()
self.state_dim = state_dim
self.action_dim = action_dim
# 物理先验编码器
self.physics_prior = PhysicsPriorNetwork(state_dim, hidden_dim)
# 动态预测器
self.dynamics_predictor = nn.Sequential(
nn.Linear(state_dim * 2 + action_dim, hidden_dim),
PhysicsConsistentLayer(hidden_dim),
nn.Linear(hidden_dim, hidden_dim),
PhysicsConsistentLayer(hidden_dim),
nn.Linear(hidden_dim, state_dim),
)
# 约束网络 - 确保物理一致性
self.constraint_network = ConstraintNetwork(state_dim)
def forward(self, state, action, dt):
"""
预测下一状态
Args:
state: [B, state_dim] 当前状态
action: [B, action_dim] 作用力/动作
dt: float 时间步长
Returns:
next_state: [B, state_dim] 预测的下一状态
"""
# 编码物理先验
physics_features = self.physics_prior(state)
# 动态预测
combined = torch.cat([state, action, physics_features], dim=-1)
delta_state = self.dynamics_predictor(combined)
# 应用时间步长
next_state = state + dt * delta_state
# 物理约束
next_state = self.constraint_network(next_state)
return next_state
class PhysicsConsistentLayer(nn.Module):
"""
物理一致层 - 编码物理守恒律
"""
def __init__(self, dim):
super().__init__()
self.layer = nn.Linear(dim, dim)
# 物理参数(可学习)
self.conservation_strength = nn.Parameter(torch.ones(1))
def forward(self, x):
# 标准线性变换
out = self.layer(x)
# 隐式物理约束
# 通过架构设计强制能量守恒
out = out - self.conservation_strength * x
return out2.6 训练目标
Dyn-O的损失函数包含多个组件:
class DynOLoss(nn.Module):
"""
Dyn-O 多目标损失函数
"""
def __init__(self, lambda_recon=1.0, lambda_dynamics=1.0,
lambda_discover=0.5, lambda_physics=0.3):
super().__init__()
self.lambda_recon = lambda_recon
self.lambda_dynamics = lambda_dynamics
self.lambda_discover = lambda_discover
self.lambda_physics = lambda_physics
def forward(self, predictions, targets):
# 1. 重构损失 - 确保观测重建准确
recon_loss = F.mse_loss(
predictions['reconstructed_obs'],
targets['ground_truth_obs']
)
# 2. 动态损失 - 确保状态转移准确
dynamics_loss = F.mse_loss(
predictions['predicted_state'],
targets['ground_truth_state']
)
# 3. 物体发现损失 - 促进物体分离
discover_loss = self.compute_discover_loss(
predictions['masks'],
predictions['slots']
)
# 4. 物理一致性损失 - 编码物理约束
physics_loss = self.compute_physics_loss(
predictions['states'],
predictions['relations']
)
# 总损失
total_loss = (
self.lambda_recon * recon_loss +
self.lambda_dynamics * dynamics_loss +
self.lambda_discover * discover_loss +
self.lambda_physics * physics_loss
)
return total_loss
def compute_discover_loss(self, masks, slots):
"""
物体发现损失 - 促进物体分离和多样性
"""
# 分割损失 - 鼓励物体掩码不重叠
overlap_penalty = torch.mean(masks.sum(dim=1) ** 2)
# 槽分离损失 - 鼓励不同槽关注不同物体
slot_separation = torch.pdist(slots).mean()
return overlap_penalty + 0.1 * slot_separation
def compute_physics_loss(self, states, relations):
"""
物理一致性损失
"""
# 能量守恒
energy = self.compute_energy(states)
energy_conservation = torch.var(energy)
# 动量守恒
momentum = self.compute_momentum(states)
momentum_conservation = torch.var(momentum)
# 关系一致性
relation_consistency = self.compute_relation_consistency(
states, relations
)
return energy_conservation + momentum_conservation + relation_consistency3. 实验验证
3.1 基准数据集
Dyn-O在多个数据集上进行了评估:
| 数据集 | 描述 | 物体类型 | 动态复杂度 |
|---|---|---|---|
| Physion | 2D物理模拟 | 刚性/柔性 | 中等 |
| Shapestack | 堆叠物体 | 刚性 | 中等 |
| CATER | 3D物理推理 | 刚性 | 高 |
| Multi-Objects Tracking | 多物体追踪 | 多类型 | 高 |
3.2 核心结果
3.2.1 状态预测精度
| 方法 | 1步MSE | 5步MSE | 10步MSE | 20步MSE |
|---|---|---|---|---|
| Dyn-O | 0.012 | 0.034 | 0.067 | 0.123 |
| SAVi | 0.018 | 0.052 | 0.112 | 0.245 |
| MONET | 0.021 | 0.061 | 0.134 | 0.289 |
| OP3 | 0.024 | 0.072 | 0.156 | 0.312 |
3.2.2 物体发现质量
| 方法 | mIoU | ARI-F | ICS |
|---|---|---|---|
| Dyn-O | 0.78 | 0.82 | 0.75 |
| SAVi | 0.71 | 0.74 | 0.68 |
| MONET | 0.68 | 0.71 | 0.62 |
| STEM | 0.73 | 0.76 | 0.70 |
3.2.3 组合泛化能力
这是Dyn-O的核心优势之一——处理训练中未见过的物体组合:
| 测试场景 | Dyn-O | SAVi | MONET |
|---|---|---|---|
| 新物体数量 | 89% | 65% | 58% |
| 新物体组合 | 82% | 54% | 47% |
| 新物理属性 | 76% | 52% | 45% |
| 遮挡场景 | 71% | 48% | 41% |
3.3 消融实验
3.3.1 各模块贡献
| 变体 | 动态预测精度 | 物体发现mIoU |
|---|---|---|
| 完整Dyn-O | 0.067 | 0.78 |
| - Slot Attention | 0.089 | 0.61 |
| - 关系推理 | 0.078 | 0.74 |
| - 物理约束 | 0.095 | 0.72 |
| - 物体无关动态 | 0.112 | 0.70 |
3.3.2 物体数量泛化
┌─────────────────────────────────────────────────────────────────┐
│ 物体数量泛化性能 │
│ │
│ 精度 │
│ 0.9 │ │
│ 0.8 │ ╭─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ 0.7 │ ╱ │
│ 0.6 │ ─ ─ ─ ─ ─ ─ ─ ─ ╱ │
│ 0.5 │ ╱ │
│ 0.4 │ ╱ │
│ └──────────────────────────────────────────────────────▶ │
│ 2 4 6 8 10 12 14 16 训练物体数量 │
│ │
│ ── Dyn-O (零样本) │
│ ─ ─ 基线方法 (需要微调) │
│ │
└─────────────────────────────────────────────────────────────────┘
4. 应用案例
4.1 机器人操作
Dyn-O可以用于机器人物体操作任务:
class RobotManipulationWithDynO:
"""
使用Dyn-O进行机器人操作
"""
def __init__(self):
self.dyn_o = DynOModel(checkpoint='dyn_o_pretrained')
self.planner = ModelPredictivePlanner(self.dyn_o)
def pick_and_place(self, target_object, goal_position):
"""
抓取并移动物体
"""
# 1. 感知当前场景
obs = self.get_observation()
objects = self.dyn_o.discover_objects(obs)
# 2. 定位目标物体
target_idx = self.find_target_object(objects, target_object)
# 3. 规划动作序列
actions = self.planner.plan(
current_state=objects,
goal={'object_idx': target_idx, 'position': goal_position}
)
# 4. 执行并监控
for action in actions:
# 预测执行结果
predicted_state = self.dyn_o.predict(objects, action)
# 执行真实动作
self.robot.execute(action)
# 获取新观测并更新
new_obs = self.get_observation()
objects = self.dyn_o.update_state(objects, new_obs)4.2 自动驾驶场景理解
Dyn-O可用于自动驾驶中的场景理解和预测:
- 道路参与者发现:识别车辆、行人、自行车等
- 轨迹预测:预测其他参与者的未来轨迹
- 交互建模:理解车辆间的交互关系
- 风险评估:基于物体动态评估碰撞风险
4.3 视频理解与编辑
Dyn-O的物体中心表示可用于视频理解和编辑:
- 视频分割:精确分割视频中的物体
- 物体追踪:跨帧追踪物体
- 视频编辑:对特定物体进行编辑
- 物理模拟:添加新物体并预测物理动态
5. 与其他方法的对比
5.1 与传统视频预测模型对比
| 特性 | Dyn-O | SVG | video-transformer |
|---|---|---|---|
| 表示类型 | 物体中心 | 像素级 | 像素级 |
| 可解释性 | 高 | 低 | 中 |
| 组合泛化 | 优秀 | 差 | 中 |
| 物体数量处理 | 动态 | 固定 | 固定 |
| 物理一致性 | 高 | 低 | 中 |
5.2 与其他物体中心方法对比
| 特性 | Dyn-O | SAVi | MONET | OP3 |
|---|---|---|---|---|
| 动态建模 | 通用 | 简单 | 简单 | 中等 |
| 关系建模 | GNN | 无 | 无 | 有限 |
| 物理一致性 | 约束 | 无 | 无 | 隐式 |
| 零样本泛化 | 优秀 | 中等 | 中等 | 差 |
| 计算效率 | 中等 | 高 | 高 | 中 |
5.3 核心优势总结
- 结构化表示:显式的物体分解,易于理解和调试
- 物理一致性:编码物理守恒律,预测符合物理规律
- 组合泛化:零样本处理新物体组合
- 关系推理:显式建模物体间关系
- 可扩展性:物体数量动态变化
6. 技术细节
6.1 实现配置
# Dyn-O 配置
dyn_o_config = {
# 物体发现
'object_discovery': {
'num_slots': 10,
'slot_dim': 64,
'slot_iterations': 3,
},
# 状态表示
'state_representation': {
'intrinsic_dim': 32,
'kinematic_dim': 14, # 位置(3) + 速度(3) + 旋转(4) + 角速度(3) + 接触(1)
'semantic_dim': 32,
'total_dim': 78,
},
# 关系建模
'relation_modeling': {
'use_gnn': True,
'num_layers': 4,
'hidden_dim': 128,
'relation_types': ['contact', 'spatial', 'containment'],
},
# 动态模型
'dynamics_model': {
'physics_prior': True,
'constraint_network': True,
'time_varying': True,
},
# 训练
'training': {
'batch_size': 32,
'learning_rate': 1e-4,
'num_epochs': 100,
'lambda_recon': 1.0,
'lambda_dynamics': 1.0,
'lambda_discover': 0.5,
'lambda_physics': 0.3,
}
}6.2 推理流程
def dyn_o_inference(observation, model, num_steps=10):
"""
Dyn-O 推理流程
"""
# 1. 物体发现
slots, masks = model.slot_attention(observation.features)
# 2. 状态提取
object_states = []
for i, (slot, mask) in enumerate(zip(slots, masks)):
state = extract_object_state(slot, observation, mask)
object_states.append(state)
# 3. 关系推理
relations = model.compute_relations(object_states)
# 4. 多步预测
predicted_states = [object_states]
for t in range(num_steps):
# 动态预测
next_states = model.predict_next_states(
predicted_states[-1],
relations
)
# 更新关系
relations = model.update_relations(next_states, relations)
predicted_states.append(next_states)
# 5. 渲染预测结果
rendered = model.render(predicted_states)
return rendered7. 局限性与未来方向
7.1 当前局限性
| 局限性 | 描述 | 影响 |
|---|---|---|
| 物体数量上限 | Slot数量固定 | 超出场合物体被合并 |
| 遮挡处理 | 严重遮挡时物体追踪困难 | 复杂场景受限 |
| 语义理解 | 主要关注物理属性 | 高级语义有限 |
| 计算成本 | GNN层增加计算 | 实时应用受限 |
7.2 未来研究方向
- 动态Slot机制:自适应调整Slot数量
- 层级物体表示:从部件到整体的多层次表示
- 语义增强:整合语言监督增强语义理解
- 因果发现:自动发现物体间的因果关系
- 实时优化:面向实时应用的推理优化
8. 总结
Dyn-O代表了世界模型向结构化、可解释方向发展的重要进展。通过物体中心表示和结构化动态建模:
- 可解释预测:每一步预测都能追溯到具体物体
- 组合泛化:零样本处理新物体组合
- 物理一致:显式编码物理守恒律
- 关系感知:建模物体间的复杂交互
Dyn-O为构建更加智能、可解释的世界模型奠定了基础,是通向通用人工智能的重要里程碑。
Footnotes
-
Dyn-O: Structured World Models with Object-Centric Representations. NeurIPS 2025. ↩