anygrap复现结果

本文介绍了GraspNet-1Billion数据集,包含大量RGB-D图像,用于训练和评估物体抓取模型。文章详细描述了数据集特点、模型加载和处理过程,以及如何进行碰撞检测和可视化。此外,还提到了在实际应用中可能需要进行目标检测来适应特定场景的要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://graspnet.net/

https://github.com/graspnet/graspnet-baseline

https://blog.csdn.net/weixin_48319333/article/details/129640460

0.论文

graspnet

https://www.bilibili.com/video/BV1av411A7wN/?spm_id_from=333.337.search-card.all.click&vd_source=3aec03706e264c240796359c1c4d7ddc 作者视频b站

GraspNet-1Billion 数据集

  • 规模:这个数据集包含了超过 10 亿个抓取姿态,得名“1Billion”。它由 97,280 张 RGB-D 图像组成,这些图像是从 190 多个不同的杂乱场景中捕获的。
  • 内容:数据集中的图像涵盖了从不同视角观察的各种物体组合。88 个不同的物体被精确地建模为 3D 网格模型,并在每个场景中密集标注了物体的 6D pose(位置和方向)以及抓取姿态。
  • 多样性:物体集合包括从 YCB 数据集中选取的适合抓取的物体、DexNet 2.0 中的对抗性物体,以及 GraspNet 研究者自行收集的物体,涵盖了各种日常物品。

demo复现

自己的数据集测试demo

parser = argparse.ArgumentParser()
parser.add_argument('--checkpoint_path', required=True, help='Model checkpoint path')
parser.add_argument('--num_point', type=int, default=20000, help='Point Number [default: 20000]')
parser.add_argument('--num_view', type=int, default=300, help='View Number [default: 300]')
parser.add_argument('--collision_thresh', type=float, default=0.01, help='Collision Threshold in collision detection [default: 0.01]')
parser.add_argument('--voxel_size', type=float, default=0.01, help='Voxel Size to process point clouds before collision detection [default: 0.01]')
cfgs = parser.parse_args()


def get_net():
    # 模型初始化+读取权重
    net = GraspNet(input_feature_dim=0, num_view=cfgs.num_view, num_angle=12, num_depth=4,
            cylinder_radius=0.05, hmin=-0.02, hmax_list=[0.01,0.02,0.03,0.04], is_training=False)
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net.to(device)
    # Load checkpoint
    checkpoint = torch.load(cfgs.checkpoint_path)
    net.load_state_dict(checkpoint['model_state_dict'])
    start_epoch = checkpoint['epoch']
    print("-> loaded checkpoint %s (epoch: %d)"%(cfgs.checkpoint_path, start_epoch))
    # set model to eval mode
    net.eval()
    return net

def get_and_process_data(data_dir):
    # 读取数据:rgb,dep,mask,meta,内参,深度因子
    color = np.array(Image.open(os.path.join(data_dir, 'color.png')), dtype=np.float32) / 255.0
    depth = np.array(Image.open(os.path.join(data_dir, 'depth.png')))
    workspace_mask = np.array(Image.open(os.path.join(data_dir, 'workspace_mask.png')))
    meta = scio.loadmat(os.path.join(data_dir, 'meta.mat'))
    intrinsic = meta['intrinsic_matrix']
    factor_depth = meta['factor_depth']

    # generate cloud
    camera = CameraInfo(1280.0, 720.0, intrinsic[0][0], intrinsic[1][1], intrinsic[0][2], intrinsic[1][2], factor_depth)
    cloud = create_point_cloud_from_depth_image(depth, camera, organized=True)

    # get valid points
    mask = (workspace_mask & (depth > 0))
    cloud_masked = cloud[mask]
    color_masked = color[mask]

    # sample points
    if len(cloud_masked) >= cfgs.num_point:
        idxs = np.random.choice(len(cloud_masked), cfgs.num_point, replace=False)
    else:
        idxs1 = np.arange(len(cloud_masked))
        idxs2 = np.random.choice(len(cloud_masked), cfgs.num_point-len(cloud_masked), replace=True)
        idxs = np.concatenate([idxs1, idxs2], axis=0)
    cloud_sampled = cloud_masked[idxs]
    color_sampled = color_masked[idxs]

    # convert data
    cloud = o3d.geometry.PointCloud()
    cloud.points = o3d.utility.Vector3dVector(cloud_masked.astype(np.float32))
    cloud.colors = o3d.utility.Vector3dVector(color_masked.astype(np.float32))
    end_points = dict()
    cloud_sampled = torch.from_numpy(cloud_sampled[np.newaxis].astype(np.float32))
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    cloud_sampled = cloud_sampled.to(device)
    end_points['point_clouds'] = cloud_sampled
    end_points['cloud_colors'] = color_sampled

    return end_points, cloud

def get_grasps(net, end_points):
    # 前向传播
    with torch.no_grad():
        end_points = net(end_points)
        grasp_preds = pred_decode(end_points)
    gg_array = grasp_preds[0].detach().cpu().numpy()
    gg = GraspGroup(gg_array)
    return gg

def collision_detection(gg, cloud):
    mfcdetector = ModelFreeCollisionDetector(cloud, voxel_size=cfgs.voxel_size)
    collision_mask = mfcdetector.detect(gg, approach_dist=0.05, collision_thresh=cfgs.collision_thresh)
    gg = gg[~collision_mask]
    return gg

def vis_grasps(gg, cloud):
    gg.nms()
    gg.sort_by_score()
    gg = gg[:50]
    grippers = gg.to_open3d_geometry_list()
    o3d.visualization.draw_geometries([cloud, *grippers])

def demo(data_dir):
    net = get_net()                                           # 模型初始化+读取权重
    end_points, cloud = get_and_process_data(data_dir)        # 读取数据+预处理
    gg = get_grasps(net, end_points)                          # 前向传播
    if cfgs.collision_thresh > 0:                             # 碰撞检测
        gg = collision_detection(gg, np.array(cloud.points)) 
    vis_grasps(gg, cloud)                                     # 可视化

if __name__=='__main__':
    data_dir = 'doc/example_data'
    demo(data_dir)

他有一个mask,把结果限定在桌面内部

好像抓不了小目标

还得先做个目标检测才行,应该是去背景检测,或者提前限定要物体在图里面的范围,因为他们的相机是在手上的,我们是胸口

分数top10:

<think>嗯,用户想复现MAE模型的实验结果,我需要先理清楚MAE的关键点。根据引用里的资料,MAE有几个核心部分:高掩码率、非对称的编码器-解码器结构、还有像素重构的目标。首先,高掩码率通常达到75%,这比BERT的高很多,所以用户需要注意在数据预处理时应用这样的随机mask策略。然后是模型结构,编码器只处理可见的patch,而解码器要处理所有patch,包括被mask的,所以编码器的设计需要轻量,可能用ViT-base或更大的变体,解码器可能更小。 接下来是数据预处理部分,用户需要按照MAE的方法对图像进行分块,然后随机mask掉大部分。这里可能需要用PyTorch或者其他的框架来实现这个mask机制。另外,非对称的结构意味着编码器和解码器的参数可能不一样,比如编码器用更大的层数,解码器层数较少,但具体参数需要参考原论文或者引用里的资料。 然后是训练策略,MAE用了较长的训练周期,比如1600个epoch,这需要大量的计算资源,可能用户需要准备好足够的GPU或者TPU。优化器方面,AdamW和余弦学习率衰减是常用的,需要正确设置初始学习率和权重衰减参数。还有数据增强的方法,比如RandomResizedCrop,可能也要应用。 复现结果时,用户可能遇到收敛速度慢的问题,这时候需要检查学习率是否合适,或者数据增强是否正确。另外,重构效果不理想的话,可能需要调整解码器的设计,或者损失函数是否正确计算了MSE。引用里提到MAE的损失函数只计算被mask的部分,所以实现时要确保只这部分参与损失计算。 还有,用户可能需要参考已有的代码库,比如Facebook Research的官方实现,或者社区中的开源项目,这样可以避免重复造轮子。同时,注意论文中的超参数设置,比如batch size、学习率等,这些对结果影响很大。 最后,验证复现结果要和原论文中的指标对比,比如在ImageNet上的线性探测准确率或者重构图像的PSNR等。如果结果有差距,可能需要检查模型结构是否正确,或者训练过程是否有疏漏。总之,复现MAE需要仔细处理每个模块,并确保每一步都符合论文的描述。</think>### MAE模型复现步骤详解 ### 一、核心组件搭建 1. **Mask策略实现** - 输入图像分割为$16×16$的patch,随机mask掉75%的patch[^4] - 代码示例: ```python def random_masking(images, mask_ratio=0.75): B, C, H, W = images.shape patch_size = 16 num_patches = (H // patch_size) * (W // patch_size) noise = torch.rand(B, num_patches) # 均匀分布随机数 mask = noise < mask_ratio # 生成布尔掩码矩阵 return mask ``` 2. **非对称编码器-解码器设计** - 编码器:仅处理可见patch,使用ViT-base结构(12层Transformer) - 解码器:处理全部patch(含mask token),仅需8层Transformer[^2] - 参数对比: ``` 编码器参数量:约86M 解码器参数量:约20M ``` ### 二、关键训练配置 1. **数据集准备** - 使用ImageNet-1K数据集(128万张训练图像) - 预处理流程: ```python transform = transforms.Compose([ transforms.RandomResizedCrop(224, scale=(0.2, 1.0)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) ``` 2. **优化器配置** ```python optimizer = AdamW(model.parameters(), lr=1.5e-4, betas=(0.9, 0.95), weight_decay=0.05) scheduler = CosineAnnealingLR(optimizer, T_max=1600) ``` ### 三、训练实施细节 1. **硬件要求** - 建议使用8×NVIDIA A100 (40GB) - 训练时间参考:1600 epochs约需3天 2. **关键超参数** | 参数名称 | 值 | |---------------|------------| | Batch size | 4096 | | Warmup epochs | 40 | | 学习率峰值 | 1.5e-4 | | Weight decay | 0.05 | ### 四、结果验证方法 1. **像素重构评估** - 计算MSE损失:仅mask区域参与计算 $$ \mathcal{L} = \frac{1}{|M|}\sum_{i \in M}(x_i - \hat{x}_i)^2 $$ - 可视化示例: ![输入图像] vs [mask图像] vs [重构图像] 2. **迁移学习验证** - 线性探测(Linear Probing):冻结编码器,训练线性分类头 - 在ImageNet验证集上应达到68%准确率(ViT-Base)[^3] ### 五、常见问题解决方案 1. **训练不收敛** - 检查mask比例是否严格75% - 确认位置编码是否正确添加到可见patch 2. **显存不足** - 使用梯度累积(gradient accumulation) - 降低分辨率至196×196(需调整patch划分) 3. **重构图像模糊** - 增加解码器深度(可尝试12层) - 在损失函数中加入感知损失(需修改目标函数)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值