模仿学习aloha中ACT算法理解

时间:2024-11-11 19:41:29

1 具身智能-模仿学习

1.1 aloha系列(ACT)

  1. aloha github地址
  2. act act-plus-plus
  3. mobile-alohagithub地址
  4. humanplus github地址
  5. aloha-unleashed 暂时代码未开源
  • aloha提出了ACT和CNNMLP两种策略方式。
  • moblie aloha增加了移动功能;除了ACT与CNNMLP policy还有diffusion, VINN policy,但可能每个场景的数据量比较少,ACT的表现比较好。
  • ALOHA Unleashed 论文中介绍使用的diffusion policy+大规模数据集(5个任务,26000次演示), 在真实的系鞋带,叠衣服等复杂精细任务,效果能达到百分70以上。期待deepmind团队开源, 从deepmind团队RT系列的项目来看, 开源速度比较慢????
  • humanplus, 通过从RGB相机上获取到人类动作,并做姿态估计且重定向之后,以作为机器人的目标动作去模仿学习, 模仿学习还是用的ACT和HIT policy, 但是源码里面HIT还是用的ACT(没有细看区别)。本人目前工作也在做open Televison遥操作的复现, 后期可能会用HIT做模仿学习复现。

  • 少量数据+简单任务用ACT
  • 大量数据+复杂精细任务用diffusion

1.2 diffusion

diffusion-policy github仓库地址
3D-Diffusion-Policy,github地址
3d_diffuser_actorgithub地址
UMI github地址
Improved-3D-Diffusion-Policy
diffusion policy代码还没深入研究, 只看了一下扩散模型的理论, 后面看明白了再记录。
UMI解决数据收集问题

1.3 RL

DPPO github地址

  • ppo+diffusion做机械臂的动作。
    panda-gym

1.4 大模型

团队钞能力有限,要数据没数据,要算力没算力,要人没人,就不去卷这个方向了,但未来一定是这个方向。

  1. 非端到端的 LLM/VLM-based policy
    大模型通用理解能力和上下文能力,执行任务拆解,以执行特定任务。
    Voxposer github地址
  2. 端到端VLA
    RT系列,从网络和机器人数据中学习,并将这些知识直接转换为机器人控制指令。
    RT-1 github地址
    RT-2
    RT-X # Open X-Embodiment-github地址
    RT-Trajectory
    OpenVLA github地址 tensorrt-openVLA-github地址
    octo-github地址
    RDT

openvla有比较完整的readme,训练、微调、预训练模型、数据集、 评估, 大家可以试试。


  • 初学者建议路线: A C T − > D i f f u s i o n − > R L ( p p o ) ACT -> Diffusion -> RL(ppo) ACT>Diffusion>RL(ppo)
  • 大模型可以看看OpenVLA
  • RDT清华大学最新开源的,支持微调,基于diffusion,也可以试试

2 ACT源码细节

act(Action Chunking with Transformers)基于Transfermer的动作分块模型,网络架构如下:
请添加图片描述

2.1 训练部分

  1. 当前的joint-state和actions作用输入+位置编码,通过一个VAE模型(只有编码层),预测一个隐变量z, 代码如下
# 1 组合位置编码, qpos、action
encoder_input = torch.cat([cls_embed, qpos_embed, action_embed], axis=1)
# ...
# 2 编码器
encoder_output = self.encoder(encoder_input, pos=pos_embed, src_key_padding_mask=is_pad)
# ...
# 3 改变维度
latent_info = self.latent_proj(encoder_output)
# 4 预测μ和σ
mu = latent_info[:, :self.latent_dim]
logvar = latent_info[:, self.latent_dim:]
# 5 重参数化
latent_sample = reparametrize(mu, logvar)
  1. 四个图像输入通过ResNet18特征提取,得到图形特征image-feature
  2. 隐变量z和图像特征image-feature组合,然后丢给transformer层,预测actions作为输出。
    细节部分:
  3. 输入的各位数据的维度对不上,就先通过一个线性层改变输入的维度
# 直接线性层改变维度
self.encoder_joint_proj = nn.Linear(state_dim, hidden_dim)
  1. 每个输入都带了位置编码,搞过transformer应该都理解,这里不再叙述。
  2. 隐变量z怎么产生,就是重参数化,简单讲就是模型预测2个值(一个均值μ,一个方差σ), 然后通过 x ∼ N ( 0 , 1 ) x \sim \mathcal{N}(0, 1) xN(0,1)分布产生高斯分布 x ∼ N ( μ , σ 2 ) x \sim \mathcal{N}(\mu, \sigma^2) xN(μ,σ2), 具体细节看数学公式:
    z = μ + σ ⊙ ϵ z = \mu + \sigma \odot \epsilon z=μ+σϵ
    ϵ \epsilon ϵ服从0-1分布, 代码中是给的随机值(正太分布采样), 通过上面公式计算的z就服从高斯分布了, z ∼ N ( μ , σ 2 ) z \sim \mathcal{N}(\mu, \sigma^2) zN(μ,σ2),原理:概率论基础知识,简单讲 ϵ \epsilon ϵ均值为0, 每个样本 + μ +μ +μ了均值就变成了 0 + μ 0+μ 0+μ, 方差是乘,最后变成了 1 × σ 1 × \sigma 1×σ, 代码如下:
# 1 接收模型预测的μ和σ
def reparametrize(mu, logvar):
	# 2 取指数形式 
	std = logvar.div(2).exp()
	# 3 随机一个0-1分布的ε
	eps = Variable(std.data.new(std.size()).normal_())
	# 4 产生隐变量
	return mu + std * eps

2.2 推理部分

  1. z怎么产生?
    直接取的0, 本人理解:既然是高斯分布采样得到,如下图在0处,概率密度函数值最大. 就取0位置。代码如下
latent_sample = torch.zeros([bs, self.latent_dim], dtype=torch.float32).to(qpos.device)

请添加图片描述

  1. 模型输出处理:
    输出是actions, 怎么取当前的qpos(joint-state)

请添加图片描述

简单讲:就是时刻t都会预测未来的k步的qpos,那第k时刻的qpos等于0-t时刻的t+1个(qpos)做加权, 代码如下:

if config['policy_class'] == "ACT":
	if t % query_frequency == 0:
		all_actions = policy(qpos, curr_image)
	if temporal_agg:
		all_time_actions[[t], t:t+num_queries] = all_actions
		actions_for_curr_step = all_time_actions[:, t]
		actions_populated = torch.all(actions_for_curr_step != 0, axis=1)
		actions_for_curr_step = actions_for_curr_step[actions_populated]
		k = 0.01
		exp_weights = np.exp(-k * np.arange(len(actions_for_curr_step)))
		exp_weights = exp_weights / exp_weights.sum()
		exp_weights = torch.from_numpy(exp_weights).cuda().unsqueeze(dim=1)
		# 对数加权求和
		raw_action = (actions_for_curr_step * exp_weights).sum(dim=0, keepdim=True)
	else:
		raw_action = all_actions[:, t % query_frequency]
elif config['policy_class'] == "CNNMLP":
	raw_action = policy(qpos, curr_image)
else:
	raise NotImplementedError

# 主要看这步
# raw_action = (actions_for_curr_step * exp_weights).sum(dim=0, keepdim=True)

上述内容只是个人理解,如果不对之处,欢迎指出,请评论区留言一起讨论,感谢^_^