MinkowskiEngine demo ModelNet40分类

本文将看一个简单的演示示例,该示例训练用于分类的3D卷积神经网络。输入是稀疏张量,卷积也定义在稀疏张量上。该网络是以下体系结构的扩展,但具有剩余的块和更多的层。

创建ModelNet40数据加载器

首先,需要创建一个数据加载器,以返回网格的稀疏张量表示。如果仅使用顶点,则3D模型的网格表示可能会稀疏。

首先以相同的密度采样点。

def resample_mesh(mesh_cad, density=1):

'''

    https://chrischoy.github.io/research/barycentric-coordinate-for-mesh-sampling/

    Samples point cloud on the surface of the model defined as vectices and

    faces. This function uses vectorized operations so fast at the cost of some

    memory.

    param mesh_cad: low-polygon triangle mesh in o3d.geometry.TriangleMesh

    param density: density of the point cloud per unit area

    param return_numpy: return numpy format or open3d pointcloud format

    return resampled point cloud

    Reference :

      [1] Barycentric coordinate system

      \begin{align}

        P = (1 - \sqrt{r_1})A + \sqrt{r_1} (1 - r_2) B + \sqrt{r_1} r_2 C

      \end{align}

    '''

faces = np.array(mesh_cad.triangles).astype(int)

vertices = np.array(mesh_cad.vertices)

vec_cross = np.cross(vertices[faces[:, 0], :] - vertices[faces[:, 2], :],

vertices[faces[:, 1], :] - vertices[faces[:, 2], :])

face_areas = np.sqrt(np.sum(vec_cross**2, 1))

n_samples = (np.sum(face_areas) * density).astype(int)

n_samples_per_face = np.ceil(density * face_areas).astype(int)

floor_num = np.sum(n_samples_per_face) - n_samples

if floor_num > 0:

indices = np.where(n_samples_per_face > 0)[0]

floor_indices = np.random.choice(indices, floor_num, replace=True)

n_samples_per_face[floor_indices] -= 1

n_samples = np.sum(n_samples_per_face)

# Create a vector that contains the face indices

sample_face_idx = np.zeros((n_samples,), dtype=int)

acc = 0

for face_idx, _n_sample in enumerate(n_samples_per_face):

sample_face_idx[acc:acc + _n_sample] = face_idx

acc += _n_sample

r = np.random.rand(n_samples, 2)

A = vertices[faces[sample_face_idx, 0], :]

B = vertices[faces[sample_face_idx, 1], :]

C = vertices[faces[sample_face_idx, 2], :]

P = (1 - np.sqrt(r[:, 0:1])) * A + \

np.sqrt(r[:, 0:1]) * (1 - r[:, 1:]) * B + \

np.sqrt(r[:, 0:1]) * r[:, 1:] * C

return P

上面的函数将以相同的密度对网格上的点进行采样。接下来,在量化步骤之前经历了一系列数据扩充步骤。

数据扩充

稀疏张量由两个部分组成:1)坐标和2)与这些坐标关联的特征。必须对这两个组件都应用数据增强,以最大化固定数据集的效用,并使网络对噪声具有鲁棒性。

这在图像数据增强中并不是什么新鲜事。对图像应用随机平移,剪切,缩放,所有这些都是坐标数据扩充。颜色失真(例如色平移,颜色通道上的高斯噪声,色相饱和度增强)都具有数据增强功能。

由于在ModelNet40数据集中只有坐标作为数据,将仅应用坐标数据增强。

class RandomRotation:

def _M(self, axis, theta):

return expm(np.cross(np.eye(3), axis / norm(axis) * theta))

def __call__(self, coords, feats):

R = self._M(

np.random.rand(3) - 0.5, 2 * np.pi * (np.random.rand(1) - 0.5))

return coords @ R, feats

class RandomScale:

def __init__(self, min, max):

self.scale = max - min

self.bias = min

def __call__(self, coords, feats):

s = self.scale * np.random.rand(1) + self.bias

return coords * s, feats

class RandomShear:

def __call__(self, coords, feats):

T = np.eye(3) + np.random.randn(3, 3)

return coords @ T, feats

class RandomTranslation:

def __call__(self, coords, feats):

trans = 0.05 * np.random.randn(1, 3)

return coords + trans, feats

训练ResNet进行ModelNet40分类

主要训练功能很简单。没有使用基于时间的训练,而是使用了基于迭代的训练。与基于时间的训练相比,基于迭代的训练的一个优势在于,训练逻辑独立于批处理大小。

def train(net, device, config):

optimizer = optim.SGD(

net.parameters(),

lr=config.lr,

momentum=config.momentum,

weight_decay=config.weight_decay)

scheduler = optim.lr_scheduler.ExponentialLR(optimizer, 0.95)

crit = torch.nn.CrossEntropyLoss()

...

net.train()

train_iter = iter(train_dataloader)

val_iter = iter(val_dataloader)

logging.info(f'LR: {scheduler.get_lr()}')

for i in range(curr_iter, config.max_iter):

s = time()

data_dict = train_iter.next()

d = time() - s

optimizer.zero_grad()

sin = ME.SparseTensor(data_dict['feats'],

data_dict['coords'].int()).to(device)

sout = net(sin)

loss = crit(sout.F, data_dict['labels'].to(device))

loss.backward()

optimizer.step()

t = time() - s

...

运行示例

集成所有代码块时,可以运行自主ModelNet40分类网络。

python -m examples.modelnet40 --batch_size 128 --stat_freq 100

完整的代码可以在example / modelnet40.py找到。

https://github.com/NVIDIA/MinkowskiEngine/blob/master/examples/modelnet40.py

警告

ModelNet40数据加载和体素化是训练中最耗时的部分。因此,该示例将所有ModelNet40数据缓存到内存中,这将占用大约10G的内存。

MinkowskiEngine demo ModelNet40分类的更多相关文章

  1. (转)JQM 日期插件 mobiscroll Demo

    (原)http://www.wglong.com/main/artical!details?id=11  JQM 日期插件 mobiscroll Demo 2013-04-25 / 分类:Jquery ...

  2. jQuery EasyUI 1.3.4 离线API、Demo

    [原]jQuery EasyUI 1.3.4 离线API.Demo (最新)   说明 本文下载包为 jQuery EasyUI 1.3.4 离线API.Demo. API 按照分类整理做成了离线版本 ...

  3. [原] jQuery EasyUI 1.3.4 离线API、Demo (最新)

    说明 本文下载包为 jQuery EasyUI 1.3.4 离线API.Demo. API 按照分类整理做成了离线版本,文档保证和官网完全一致: Demo 按照分类整理为合集. 1.3.3版本中新增 ...

  4. JS菜单条智能定位效果

    JS仿淘宝详情页菜单条智能定位效果 2014-01-15 15:40 by 龙恩0707, 1366 阅读, 9 评论, 收藏, 编辑 类似于淘宝详情页菜单条智能定位 对于每个人来说并不陌生!如下截图 ...

  5. JS数量输入控件

    JS数量输入控件 很早看到kissy首页 有数量输入控件,就随便看了下功能 感觉也不怎么难 所以也就试着自己也做了一个, 当然基本的功能和他们的一样,只是用了自己的编码思想来解决这么一个问题.特此给大 ...

  6. 动手Jquery插件

    自己动手Jquery插件 最近Web应用程序中越来越多地用到了JQuery等Web前端技术.这些技术框架有效地改善了用户的操作体验,同时也提高了开发人员构造丰富客户 端UI的效率.JQuery本身提供 ...

  7. JSON无限折叠菜单

    JSON无限折叠菜单编写 2013-12-14 22:37 by 龙恩0707, 103 阅读, 1 评论, 收藏, 编辑 最近看了一篇关于JSON无限折叠菜单的文章 感觉写的不错,也研究了下代码,所 ...

  8. YPreLoad

    Javascript库   发布我的控件系列:图片预加载控件YPreLoad v1.0 摘要: 介绍大家好!很高兴向大家介绍我的图片预加载控件YPreLoad.它可以帮助您预加载图片,并且能显示加载的 ...

  9. uploadify的使用

    uploadify的使用 课程设计需要实现上传文件模块,本来ASP.NET是有内置的控件,但是ASP.NET MVC没有,所以就有两种方法:自定义和采用第三方插件.由于时间的关系,故采用第三方插件:u ...

随机推荐

  1. 看了这篇还不会Linux性能分析和优化,你来打我

    前言 一般互联网的项目都是部署在linux服务器上的,如果linux服务器出了问题,那么咱们平时学习的高并发,稳定性之类的是没有任何意义的,所以对linux性能的把握就显得非常重要,当然很多同学可能觉 ...

  2. UVA10382喷水装置

    题意:       给你一个矩形的空地,然后有一些圆形的喷水装置,每个装置的圆心都在矩形宽的中间位置,然偶给你每个矩形的圆心位置和半径,问你最少多少个喷水装置可以把矩形的所有编辑都覆盖上. 思路:   ...

  3. 『政善治』Postman工具 — 4、HTTP请求基础组成部分介绍

    目录 1.Method 2.URL 3.Headers 4.body 一般来说,所有的HTTP Request都有最基础的4个部分组成:URL. Method. Headers和body. 1.Met ...

  4. 【python】Leetcode每日一题-直方图的水量(接雨水)

    [python]Leetcode每日一题-直方图的水量(接雨水) [题目描述] 给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1. 上面是由数组 ...

  5. Error starting userland proxy: /forwards/expose/port returned unexpected status: 500.

    欢迎关注微信公众号 Error starting userland proxy: /forwards/expose/port returned unexpected status: 500. dock ...

  6. 【Tavern】1.tavern测试框架介绍

    目录 1. Tavern 和 Postman 2. 安装Python 3. 安装Tavern 4. 第一个测试用例 1. Tavern 和 Postman Tavern是一个用Python实现的接口自 ...

  7. 重新整理 .net core 实践篇————配置应用[一]

    前言 本来想整理到<<重新整理.net core 计1400篇>>里面去,但是后来一想,整理 .net core 实践篇 是偏于实践,故而分开. 因为是重新整理,那么就从配置开 ...

  8. Bash技巧:使用 set 内置命令帮助调试 shell 脚本

    Bash技巧:使用 set 内置命令帮助调试 shell 脚本 霜鱼片发布于 2020-02-03   在 bash 中,可以使用 set 内置命令设置和查看 shell 的属性.这些属性会影响 sh ...

  9. 【Git】git clone报错 git fatal: Unable to find remote helper for 'https'

    [参考资料] https://stackoverflow.com/questions/8329485/unable-to-find-remote-helper-for-https-during-git ...

  10. 012.Kubernetes的configmap和secret配置

    使用configmap对多有的配置文件进行统一管理 一 configmap配置管理 1.1 检查mysql的配置 [root@docker-server1 storage]# kubectl get ...