This commit is contained in:
Xu Ma 2021-10-04 03:54:06 -04:00
parent 9f5d3b187e
commit 404c207db5
6 changed files with 26 additions and 1648 deletions

View file

@ -1,52 +1,3 @@
from __future__ import absolute_import
from .pct import PCT
from .pointConv import PointConv
from .GDANet import GDANET
from .GBNet import GBNet, DGCNN
# from .PAconv import PAConv # could not excuted.
from .CurveNet import CurveNet
from .pctmlp import PCTMLP
from .pointnet_noBN import PointNetNoBN
from .pointnet2_affine import PointNet2Affine
from .pointnet import PointNet
from .pointnet_deep import PointNetDeep
from .pointnet_deep_noBN import PointNetDeepNoBN
from .pointnet2 import PointNet2
from .pointnet2_noBN import PointNet2NoBN
from .pointnetmlp import PointNetMLP
from .model25 import model25H
from .model26 import model26H, model26A, model26B, model26C, model26D
from .model31 import model31A, model31B, model31C, model31D, model31E, model31F, model31G, model31H, model31I, \
model31J, model31K, model31L, model31M, model31N
from .model31NoRes import model31CNoRes
from .model32 import model32A,model32C,model32D, model32E, model32F, model32G, model32H, model32I, model32J, model32K,\
model32L, model32M, model32N, model32A2, model32A3, model32A4
from .model33 import model33A, model33B, model33C, model33D, model33E, model33F, model33G, model33H
from .pointsformer1 import pointsformer1A, pointsformer1B, pointsformer1C, pointsformer1D, pointsformer1H, \
pointsformer1E, pointsformer1F, pointsformer1G, pointsformer1I
from .modelelite import modeleliteA, modeleliteB, modeleliteC, modeleliteD, modeleliteE, modeleliteF, modeleliteG
from .modelelite2 import modelelite2A, modelelite2B, modelelite2C, modelelite2D, modelelite2E, modelelite2F, \
modelelite2G, modelelite2H, modelelite2I, modelelite2J, modelelite2K, modelelite2L, \
modelelite2A2, modelelite2B2, modelelite2C2, modelelite2D2, modelelite2E2, modelelite2F2, \
modelelite2G2, modelelite2H2, modelelite2I2, modelelite2J2, modelelite2K2, modelelite2L2, \
modelelite2A3, modelelite2B3, modelelite2C3, modelelite2D3, modelelite2E3, modelelite2F3, \
modelelite2G3, modelelite2H3, modelelite2I3, modelelite2J3, modelelite2K3, modelelite2L3
from .modelelite3 import modelelite3A1, modelelite3A2, modelelite3B1, modelelite3B2, modelelite3C1, modelelite3C2, \
modelelite3D1, modelelite3D2, modelelite3E1, modelelite3E2, modelelite3F1, modelelite3F2, modelelite3G1, \
modelelite3G2, modelelite3H1, modelelite3H2, modelelite3I1, modelelite3I2, modelelite3J1, modelelite3J2, \
modelelite3K1, modelelite3K2, modelelite3L1, modelelite3L2, modelelite3X1, modelelite3X2, modelelite3X3, \
modelelite3X4, modelelite3X5, modelelite3X6, modelelite3X7, modelelite3X8, modelelite3X9, modelelite3X10, \
modelelite3X11, modelelite3X12, modelelite3X13
from .pointsformer2 import pointsformer2A, pointsformer2B, pointsformer2C, pointsformer2D, pointsformer2E, \
pointsformer2F, pointsformer2G, pointsformer2H, pointsformer2I, pointsformer2J, pointsformer2K, \
pointsformer2L, pointsformer2M, pointsformer2N, pointsformer2O, pointsformer2P, pointsformer2Q, pointsformer2R
# from .pointsformer2 import pointsformer2A, pointsformer2B
from .pointmlp import pointMLP, pointMLPElite

View file

@ -1,624 +0,0 @@
"""
Based on model31, different configures for elite version.
Based on model30, change the grouper operation by normalization.
Based on model28, only change configurations, mainly the reducer.
Based on model27, change to x-a, reorgnized structure
Based on model25, simple LocalGrouper (not x-a), reorgnized structure
Based on model24, using ReLU to replace GELU
Based on model22, remove attention
Bsed on model21, change FPS to random sampling.
Exactly based on Model10, but ReLU to GeLU
Based on Model8, add dropout and max, avg combine.
Based on Local model, add residual connections.
The extraction is doubled for depth.
Learning Point Cloud with Progressively Local representation.
[B,3,N] - {[B,G,K,d]-[B,G,d]} - {[B,G',K,d]-[B,G',d]} -cls
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
# from torch import einsum
# from einops import rearrange, repeat
from einops.layers.torch import Rearrange
from pointnet2_ops import pointnet2_utils
def get_activation(activation):
if activation.lower() == 'gelu':
return nn.GELU()
elif activation.lower() == 'rrelu':
return nn.RReLU(inplace=True)
elif activation.lower() == 'selu':
return nn.SELU(inplace=True)
elif activation.lower() == 'silu':
return nn.SiLU(inplace=True)
elif activation.lower() == 'hardswish':
return nn.Hardswish(inplace=True)
elif activation.lower() == 'leakyrelu':
return nn.LeakyReLU(inplace=True)
else:
return nn.ReLU(inplace=True)
def square_distance(src, dst):
"""
Calculate Euclid distance between each two points.
src^T * dst = xn * xm + yn * ym + zn * zm
sum(src^2, dim=-1) = xn*xn + yn*yn + zn*zn;
sum(dst^2, dim=-1) = xm*xm + ym*ym + zm*zm;
dist = (xn - xm)^2 + (yn - ym)^2 + (zn - zm)^2
= sum(src**2,dim=-1)+sum(dst**2,dim=-1)-2*src^T*dst
Input:
src: source points, [B, N, C]
dst: target points, [B, M, C]
Output:
dist: per-point square distance, [B, N, M]
"""
B, N, _ = src.shape
_, M, _ = dst.shape
dist = -2 * torch.matmul(src, dst.permute(0, 2, 1))
dist += torch.sum(src ** 2, -1).view(B, N, 1)
dist += torch.sum(dst ** 2, -1).view(B, 1, M)
return dist
def index_points(points, idx):
"""
Input:
points: input points data, [B, N, C]
idx: sample index data, [B, S]
Return:
new_points:, indexed points data, [B, S, C]
"""
device = points.device
B = points.shape[0]
view_shape = list(idx.shape)
view_shape[1:] = [1] * (len(view_shape) - 1)
repeat_shape = list(idx.shape)
repeat_shape[0] = 1
batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
new_points = points[batch_indices, idx, :]
return new_points
def farthest_point_sample(xyz, npoint):
"""
Input:
xyz: pointcloud data, [B, N, 3]
npoint: number of samples
Return:
centroids: sampled pointcloud index, [B, npoint]
"""
device = xyz.device
B, N, C = xyz.shape
centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
distance = torch.ones(B, N).to(device) * 1e10
farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
batch_indices = torch.arange(B, dtype=torch.long).to(device)
for i in range(npoint):
centroids[:, i] = farthest
centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
dist = torch.sum((xyz - centroid) ** 2, -1)
distance = torch.min(distance, dist)
farthest = torch.max(distance, -1)[1]
return centroids
def query_ball_point(radius, nsample, xyz, new_xyz):
"""
Input:
radius: local region radius
nsample: max sample number in local region
xyz: all points, [B, N, 3]
new_xyz: query points, [B, S, 3]
Return:
group_idx: grouped points index, [B, S, nsample]
"""
device = xyz.device
B, N, C = xyz.shape
_, S, _ = new_xyz.shape
group_idx = torch.arange(N, dtype=torch.long).to(device).view(1, 1, N).repeat([B, S, 1])
sqrdists = square_distance(new_xyz, xyz)
group_idx[sqrdists > radius ** 2] = N
group_idx = group_idx.sort(dim=-1)[0][:, :, :nsample]
group_first = group_idx[:, :, 0].view(B, S, 1).repeat([1, 1, nsample])
mask = group_idx == N
group_idx[mask] = group_first[mask]
return group_idx
def knn_point(nsample, xyz, new_xyz):
"""
Input:
nsample: max sample number in local region
xyz: all points, [B, N, C]
new_xyz: query points, [B, S, C]
Return:
group_idx: grouped points index, [B, S, nsample]
"""
sqrdists = square_distance(new_xyz, xyz)
_, group_idx = torch.topk(sqrdists, nsample, dim=-1, largest=False, sorted=False)
return group_idx
class LocalGrouper(nn.Module):
def __init__(self, channel, groups, kneighbors, use_xyz=True, normalize="center", **kwargs):
"""
Give xyz[b,p,3] and fea[b,p,d], return new_xyz[b,g,3] and new_fea[b,g,k,d]
:param groups: groups number
:param kneighbors: k-nerighbors
:param kwargs: others
"""
super(LocalGrouper, self).__init__()
self.groups = groups
self.kneighbors = kneighbors
self.use_xyz = use_xyz
if normalize is not None:
self.normalize = normalize.lower()
else:
self.normalize = None
if self.normalize not in ["center", "anchor"]:
print(f"Unrecognized normalize parameter (self.normalize), set to None. Should be one of [center, anchor].")
self.normalize = None
if self.normalize is not None:
add_channel=3 if self.use_xyz else 0
self.affine_alpha = nn.Parameter(torch.ones([1,1,1,channel + add_channel]))
self.affine_beta = nn.Parameter(torch.zeros([1, 1, 1, channel + add_channel]))
def forward(self, xyz, points):
B, N, C = xyz.shape
S = self.groups
xyz = xyz.contiguous() # xyz [btach, points, xyz]
# fps_idx = torch.multinomial(torch.linspace(0, N - 1, steps=N).repeat(B, 1).to(xyz.device), num_samples=self.groups, replacement=False).long()
# fps_idx = farthest_point_sample(xyz, self.groups).long()
fps_idx = pointnet2_utils.furthest_point_sample(xyz, self.groups).long() # [B, npoint]
new_xyz = index_points(xyz, fps_idx) # [B, npoint, 3]
new_points = index_points(points, fps_idx) # [B, npoint, d]
idx = knn_point(self.kneighbors, xyz, new_xyz)
# idx = query_ball_point(radius, nsample, xyz, new_xyz)
grouped_xyz = index_points(xyz, idx) # [B, npoint, k, 3]
grouped_points = index_points(points, idx) # [B, npoint, k, d]
if self.use_xyz:
grouped_points = torch.cat([grouped_points, grouped_xyz],dim=-1) # [B, npoint, k, d+3]
if self.normalize is not None:
if self.normalize =="center":
std, mean = torch.std_mean(grouped_points, dim=2, keepdim=True)
if self.normalize =="anchor":
mean = torch.cat([new_points, new_xyz],dim=-1) if self.use_xyz else new_points
mean = mean.unsqueeze(dim=-2) # [B, npoint, 1, d+3]
std = torch.std(grouped_points-mean)
grouped_points = (grouped_points-mean)/(std + 1e-5)
grouped_points = self.affine_alpha*grouped_points + self.affine_beta
new_points = torch.cat([grouped_points, new_points.view(B, S, 1, -1).repeat(1, 1, self.kneighbors, 1)], dim=-1)
return new_xyz, new_points
class ConvBNReLU1D(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=1, bias=True, activation='relu'):
super(ConvBNReLU1D, self).__init__()
self.act = get_activation(activation)
self.net = nn.Sequential(
nn.Conv1d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, bias=bias),
nn.BatchNorm1d(out_channels),
self.act
)
def forward(self, x):
return self.net(x)
class ConvBNReLURes1D(nn.Module):
def __init__(self, channel, kernel_size=1, groups=1, res_expansion=1.0, bias=True, activation='relu'):
super(ConvBNReLURes1D, self).__init__()
self.act = get_activation(activation)
self.net1 = nn.Sequential(
nn.Conv1d(in_channels=channel, out_channels=int(channel * res_expansion),
kernel_size=kernel_size, groups=groups, bias=bias),
nn.BatchNorm1d(int(channel * res_expansion)),
self.act
)
self.net2 = nn.Sequential(
nn.Conv1d(in_channels=int(channel * res_expansion), out_channels=channel,
kernel_size=kernel_size, groups=groups, bias=bias),
nn.BatchNorm1d(channel)
)
def forward(self, x):
return self.act(self.net2(self.net1(x)) + x)
class PreExtraction(nn.Module):
def __init__(self, channels, out_channels, blocks=1, groups=1, res_expansion=1, bias=True,
activation='relu', use_xyz=True):
"""
input: [b,g,k,d]: output:[b,d,g]
:param channels:
:param blocks:
"""
super(PreExtraction, self).__init__()
in_channels = 3+2*channels if use_xyz else 2*channels
self.transfer = ConvBNReLU1D(in_channels, out_channels, bias=bias, activation=activation)
operation = []
for _ in range(blocks):
operation.append(
ConvBNReLURes1D(out_channels, groups=groups, res_expansion=res_expansion,
bias=bias, activation=activation)
)
self.operation = nn.Sequential(*operation)
def forward(self, x):
b, n, s, d = x.size() # torch.Size([32, 512, 32, 6])
x = x.permute(0, 1, 3, 2)
x = x.reshape(-1, d, s)
x = self.transfer(x)
batch_size, _, _ = x.size()
x = self.operation(x) # [b, d, k]
x = F.adaptive_max_pool1d(x, 1).view(batch_size, -1)
x = x.reshape(b, n, -1).permute(0, 2, 1)
return x
class PosExtraction(nn.Module):
def __init__(self, channels, blocks=1, groups=1, res_expansion=1, bias=True, activation='relu'):
"""
input[b,d,g]; output[b,d,g]
:param channels:
:param blocks:
"""
super(PosExtraction, self).__init__()
operation = []
for _ in range(blocks):
operation.append(
ConvBNReLURes1D(channels, groups=groups, res_expansion=res_expansion, bias=bias, activation=activation)
)
self.operation = nn.Sequential(*operation)
def forward(self, x): # [b, d, g]
return self.operation(x)
class modelelite3(nn.Module):
def __init__(self, points=1024, class_num=40, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=True, use_xyz=True, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs):
super(modelelite3, self).__init__()
self.stages = len(pre_blocks)
self.class_num = class_num
self.points = points
self.embedding = ConvBNReLU1D(3, embed_dim, bias=bias, activation=activation)
assert len(pre_blocks) == len(k_neighbors) == len(reducers) == len(pos_blocks) == len(dim_expansion), \
"Please check stage number consistent for pre_blocks, pos_blocks k_neighbors, reducers."
self.local_grouper_list = nn.ModuleList()
self.pre_blocks_list = nn.ModuleList()
self.pos_blocks_list = nn.ModuleList()
last_channel = embed_dim
anchor_points = self.points
for i in range(len(pre_blocks)):
out_channel = last_channel * dim_expansion[i]
pre_block_num = pre_blocks[i]
pos_block_num = pos_blocks[i]
kneighbor = k_neighbors[i]
reduce = reducers[i]
anchor_points = anchor_points // reduce
# append local_grouper_list
local_grouper = LocalGrouper(last_channel, anchor_points, kneighbor, use_xyz, normalize) # [b,g,k,d]
self.local_grouper_list.append(local_grouper)
# append pre_block_list
pre_block_module = PreExtraction(last_channel, out_channel, pre_block_num, groups=groups,
res_expansion=res_expansion,
bias=bias, activation=activation, use_xyz=use_xyz)
self.pre_blocks_list.append(pre_block_module)
# append pos_block_list
pos_block_module = PosExtraction(out_channel, pos_block_num, groups=groups,
res_expansion=res_expansion, bias=bias, activation=activation)
self.pos_blocks_list.append(pos_block_module)
last_channel = out_channel
self.act = get_activation(activation)
self.classifier = nn.Sequential(
nn.Linear(last_channel, 512),
nn.BatchNorm1d(512),
self.act,
nn.Dropout(0.5),
nn.Linear(512, 256),
nn.BatchNorm1d(256),
self.act,
nn.Dropout(0.5),
nn.Linear(256, self.class_num)
)
def forward(self, x):
xyz = x.permute(0, 2, 1)
batch_size, _, _ = x.size()
x = self.embedding(x) # B,D,N
for i in range(self.stages):
# Give xyz[b, p, 3] and fea[b, p, d], return new_xyz[b, g, 3] and new_fea[b, g, k, d]
xyz, x = self.local_grouper_list[i](xyz, x.permute(0, 2, 1)) # [b,g,3] [b,g,k,d]
x = self.pre_blocks_list[i](x) # [b,d,g]
x = self.pos_blocks_list[i](x) # [b,d,g]
x = F.adaptive_max_pool1d(x, 1).squeeze(dim=-1)
x = self.classifier(x)
return x
def modelelite3A1(num_classes=40, **kwargs) -> modelelite3: # 3.48M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3B1(num_classes=40, **kwargs) -> modelelite3: # 2.78M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.0625,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3C1(num_classes=40, **kwargs) -> modelelite3: # 4.87M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3D1(num_classes=40, **kwargs) -> modelelite3: # 2.26M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=8, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3E1(num_classes=40, **kwargs) -> modelelite3: # 2.43M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3F1(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3G1(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3H1(num_classes=40, **kwargs) -> modelelite3: # 3.56M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3I1(num_classes=40, **kwargs) -> modelelite3: # 0.90M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3J1(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3K1(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3L1(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=True, use_xyz=True, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
########version 2: 64 neighbors with 0.5 drop ratio ###########
def modelelite3A2(num_classes=40, **kwargs) -> modelelite3: # 3.48M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3B2(num_classes=40, **kwargs) -> modelelite3: # 2.78M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.0625,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3C2(num_classes=40, **kwargs) -> modelelite3: # 4.87M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3D2(num_classes=40, **kwargs) -> modelelite3: # 2.26M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=8, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3E2(num_classes=40, **kwargs) -> modelelite3: # 2.43M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3F2(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3G2(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3H2(num_classes=40, **kwargs) -> modelelite3: # 3.56M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3I2(num_classes=40, **kwargs) -> modelelite3: # 0.90M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3J2(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3K2(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3L2(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=True, use_xyz=True, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X1(num_classes=40, **kwargs) -> modelelite3: # 1.11M 1m47s/16s
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X2(num_classes=40, **kwargs) -> modelelite3: # 0.94M 121/18s
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=2, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X3(num_classes=40, **kwargs) -> modelelite3: # 0.94 87/14s
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X4(num_classes=40, **kwargs) -> modelelite3: # 2.77 107s/17s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X5(num_classes=40, **kwargs) -> modelelite3: # 1.59
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X6(num_classes=40, **kwargs) -> modelelite3: # 1.44
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X7(num_classes=40, **kwargs) -> modelelite3: # 1.11M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X8(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X9(num_classes=40, **kwargs) -> modelelite3: # 1.59M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X10(num_classes=40, **kwargs) -> modelelite3: # 0.72M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 2, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X11(num_classes=40, **kwargs) -> modelelite3: # 0.98M 79/13s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 0],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X12(num_classes=40, **kwargs) -> modelelite3: # 0.98M 78/13s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 0],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X13(num_classes=40, **kwargs) -> modelelite3: # 0.94M 90/15s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 2, 2, 2], pos_blocks=[1, 1, 0, 0],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
if __name__ == '__main__':
# data = torch.rand(2, 128, 10)
# model = ConvBNReLURes1D(128, groups=2, activation='relu')
# out = model(data)
# print(out.shape)
#
# batch, groups, neighbors, dim = 2, 512, 32, 16
# x = torch.rand(batch, groups, neighbors, dim)
# pre_extractor = PreExtraction(dim, 3)
# out = pre_extractor(x)
# print(out.shape)
#
# x = torch.rand(batch, dim, groups)
# pos_extractor = PosExtraction(dim, 3)
# out = pos_extractor(x)
# print(out.shape)
data = torch.rand(2, 3, 1024)
print("===> testing modelN ...")
model = modelelite3A1()
out = model(data)
print(out.shape)

View file

@ -1,18 +1,4 @@
"""
Based on model30, change the grouper operation by normalization.
Based on model28, only change configurations, mainly the reducer.
Based on model27, change to x-a, reorgnized structure
Based on model25, simple LocalGrouper (not x-a), reorgnized structure
Based on model24, using ReLU to replace GELU
Based on model22, remove attention
Bsed on model21, change FPS to random sampling.
Exactly based on Model10, but ReLU to GeLU
Based on Model8, add dropout and max, avg combine.
Based on Local model, add residual connections.
The extraction is doubled for depth.
Learning Point Cloud with Progressively Local representation.
[B,3,N] - {[B,G,K,d]-[B,G,d]} - {[B,G',K,d]-[B,G',d]} -cls
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
@ -291,12 +277,12 @@ class PosExtraction(nn.Module):
return self.operation(x)
class model31(nn.Module):
class Model(nn.Module):
def __init__(self, points=1024, class_num=40, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=True, use_xyz=True, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs):
super(model31, self).__init__()
super(Model, self).__init__()
self.stages = len(pre_blocks)
self.class_num = class_num
self.points = points
@ -359,130 +345,24 @@ class model31(nn.Module):
def model31A(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31B(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31C(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
def pointMLP(num_classes=40, **kwargs) -> Model:
return Model(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31D(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
def pointMLPElite(num_classes=40, **kwargs) -> Model:
return Model(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def model31E(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31F(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31G(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=16, res_expansion=2.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31H(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=128, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2], pre_blocks=[4, 4], pos_blocks=[4, 4],
k_neighbors=[32, 32], reducers=[4, 4], **kwargs)
def model31I(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=128, groups=1, res_expansion=1,
activation="gelu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2], pre_blocks=[4, 4], pos_blocks=[4, 4],
k_neighbors=[32, 32], reducers=[4, 4], **kwargs)
def model31J(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=128, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2], pre_blocks=[4, 4], pos_blocks=[4, 4],
k_neighbors=[24, 24], reducers=[4, 4], **kwargs)
def model31K(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=384, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 1], pre_blocks=[4, 4], pos_blocks=[4, 4],
k_neighbors=[32, 32], reducers=[4, 4], **kwargs)
def model31L(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=128, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2], pre_blocks=[3, 3, 3], pos_blocks=[3, 3, 3],
k_neighbors=[24, 24, 24], reducers=[4, 4, 2], **kwargs)
def model31M(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=128, groups=1, res_expansion=1,
activation="leakyrelu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2], pre_blocks=[4, 4], pos_blocks=[4, 4],
k_neighbors=[32, 32], reducers=[4, 4], **kwargs)
def model31N(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[4, 8, 4, 2], pos_blocks=[4, 8, 4, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 2, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
if __name__ == '__main__':
# data = torch.rand(2, 128, 10)
# model = ConvBNReLURes1D(128, groups=2, activation='relu')
# out = model(data)
# print(out.shape)
#
# batch, groups, neighbors, dim = 2, 512, 32, 16
# x = torch.rand(batch, groups, neighbors, dim)
# pre_extractor = PreExtraction(dim, 3)
# out = pre_extractor(x)
# print(out.shape)
#
# x = torch.rand(batch, dim, groups)
# pos_extractor = PosExtraction(dim, 3)
# out = pos_extractor(x)
# print(out.shape)
data = torch.rand(2, 3, 1024)
print("===> testing modelK ...")
model = model31K()
print("===> testing pointMLP ...")
model = pointMLP()
out = model(data)
print(out.shape)
print("===> testing modelL ...")
model = model31L()
out = model(data)
print(out.shape)
print("===> testing modelM ...")
model = model31M()
out = model(data)
print(out.shape)
print("===> testing modelN ...")
model = model31N()
out = model(data)
print(out.shape)

View file

@ -1,31 +1,3 @@
from __future__ import absolute_import
from .pointnet import PointNet
from .model21 import model21H
from .model1 import model1A, model1B, model1C, model1D, model1E, model1F
from .model2 import model2A1,model2A2, model2A3, model2A4, model2A5, model2A6, \
model2A7, model2A8, model2A9, model2A10, model2A11, model2A12
from .model3 import model3A1, model3A2, model3A3, model3A4, model3A5, model3A6, \
model3A7, model3A8, model3A9, model3A10, model3A11, model3A12
from .model4 import model4A1, model4A2, model4A3, model4A4, model4A5, model4A6, model4A7, model4A8
from .model22 import model22H
from .model23 import model23H
from .model24 import model24H
from .model25 import model25A, model25B, model25C, model25D, model25E, model25F, model25G, model25H, model25I, \
model25J, model25H1, model25H2, model25H3,model25H4, model25H5, model25H6, model25H7, model25H8
from .model26 import model26H, model26G
from .model27 import model27A, model27B, model27C, model27D, model27E, model27F, model27G, model27H, model27I, model27J
from .model28 import model28A, model28B, model28C, model28D, model28E, model28F, model28G, model28H, model28I, model28J
from .model29 import model29A, model29B, model29C, model29D, model29E, model29F, model29G, model29H, model29I, model29J
from .model30 import model30A, model30B, model30C, model30D, model30E, model30F, model30G, model30H, model30I, model30J
from .model31 import model31A, model31B, model31C, model31D, model31E, model31F, model31G, \
model31Ablation1111, model31Ablation1111NOnorm, model31Ablation3333, model31Ablation3333NOnorm, \
model31AblationNopre, model31AblationNopos, model31Ablation2222NOnorm
from .model32 import model32A, model32B, model32C, model32D
from .modelelite3 import modelelite3A1, modelelite3A2, modelelite3B1, modelelite3B2, modelelite3C1, modelelite3C2, \
modelelite3D1, modelelite3D2, modelelite3E1, modelelite3E2, modelelite3F1, modelelite3F2, modelelite3G1, \
modelelite3G2, modelelite3H1, modelelite3H2, modelelite3I1, modelelite3I2, modelelite3J1, modelelite3J2, \
modelelite3K1, modelelite3K2, modelelite3L1, modelelite3L2, modelelite3M1, modelelite3M2, \
modelelite3X1, modelelite3X2, modelelite3X3, modelelite3X4, modelelite3X5, modelelite3X6, modelelite3X7, \
modelelite3X8, modelelite3X9, modelelite3X10, modelelite3X11, modelelite3X12, modelelite3X13
from .pointmlp import pointMLP, pointMLPElite

View file

@ -1,639 +0,0 @@
"""
Based on model31, different configures for elite version.
Based on model30, change the grouper operation by normalization.
Based on model28, only change configurations, mainly the reducer.
Based on model27, change to x-a, reorgnized structure
Based on model25, simple LocalGrouper (not x-a), reorgnized structure
Based on model24, using ReLU to replace GELU
Based on model22, remove attention
Bsed on model21, change FPS to random sampling.
Exactly based on Model10, but ReLU to GeLU
Based on Model8, add dropout and max, avg combine.
Based on Local model, add residual connections.
The extraction is doubled for depth.
Learning Point Cloud with Progressively Local representation.
[B,3,N] - {[B,G,K,d]-[B,G,d]} - {[B,G',K,d]-[B,G',d]} -cls
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
# from torch import einsum
# from einops import rearrange, repeat
from einops.layers.torch import Rearrange
from pointnet2_ops import pointnet2_utils
def get_activation(activation):
if activation.lower() == 'gelu':
return nn.GELU()
elif activation.lower() == 'rrelu':
return nn.RReLU(inplace=True)
elif activation.lower() == 'selu':
return nn.SELU(inplace=True)
elif activation.lower() == 'silu':
return nn.SiLU(inplace=True)
elif activation.lower() == 'hardswish':
return nn.Hardswish(inplace=True)
elif activation.lower() == 'leakyrelu':
return nn.LeakyReLU(inplace=True)
else:
return nn.ReLU(inplace=True)
def square_distance(src, dst):
"""
Calculate Euclid distance between each two points.
src^T * dst = xn * xm + yn * ym + zn * zm
sum(src^2, dim=-1) = xn*xn + yn*yn + zn*zn;
sum(dst^2, dim=-1) = xm*xm + ym*ym + zm*zm;
dist = (xn - xm)^2 + (yn - ym)^2 + (zn - zm)^2
= sum(src**2,dim=-1)+sum(dst**2,dim=-1)-2*src^T*dst
Input:
src: source points, [B, N, C]
dst: target points, [B, M, C]
Output:
dist: per-point square distance, [B, N, M]
"""
B, N, _ = src.shape
_, M, _ = dst.shape
dist = -2 * torch.matmul(src, dst.permute(0, 2, 1))
dist += torch.sum(src ** 2, -1).view(B, N, 1)
dist += torch.sum(dst ** 2, -1).view(B, 1, M)
return dist
def index_points(points, idx):
"""
Input:
points: input points data, [B, N, C]
idx: sample index data, [B, S]
Return:
new_points:, indexed points data, [B, S, C]
"""
device = points.device
B = points.shape[0]
view_shape = list(idx.shape)
view_shape[1:] = [1] * (len(view_shape) - 1)
repeat_shape = list(idx.shape)
repeat_shape[0] = 1
batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
new_points = points[batch_indices, idx, :]
return new_points
def farthest_point_sample(xyz, npoint):
"""
Input:
xyz: pointcloud data, [B, N, 3]
npoint: number of samples
Return:
centroids: sampled pointcloud index, [B, npoint]
"""
device = xyz.device
B, N, C = xyz.shape
centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
distance = torch.ones(B, N).to(device) * 1e10
farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
batch_indices = torch.arange(B, dtype=torch.long).to(device)
for i in range(npoint):
centroids[:, i] = farthest
centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
dist = torch.sum((xyz - centroid) ** 2, -1)
distance = torch.min(distance, dist)
farthest = torch.max(distance, -1)[1]
return centroids
def query_ball_point(radius, nsample, xyz, new_xyz):
"""
Input:
radius: local region radius
nsample: max sample number in local region
xyz: all points, [B, N, 3]
new_xyz: query points, [B, S, 3]
Return:
group_idx: grouped points index, [B, S, nsample]
"""
device = xyz.device
B, N, C = xyz.shape
_, S, _ = new_xyz.shape
group_idx = torch.arange(N, dtype=torch.long).to(device).view(1, 1, N).repeat([B, S, 1])
sqrdists = square_distance(new_xyz, xyz)
group_idx[sqrdists > radius ** 2] = N
group_idx = group_idx.sort(dim=-1)[0][:, :, :nsample]
group_first = group_idx[:, :, 0].view(B, S, 1).repeat([1, 1, nsample])
mask = group_idx == N
group_idx[mask] = group_first[mask]
return group_idx
def knn_point(nsample, xyz, new_xyz):
"""
Input:
nsample: max sample number in local region
xyz: all points, [B, N, C]
new_xyz: query points, [B, S, C]
Return:
group_idx: grouped points index, [B, S, nsample]
"""
sqrdists = square_distance(new_xyz, xyz)
_, group_idx = torch.topk(sqrdists, nsample, dim=-1, largest=False, sorted=False)
return group_idx
class LocalGrouper(nn.Module):
def __init__(self, channel, groups, kneighbors, use_xyz=True, normalize="center", **kwargs):
"""
Give xyz[b,p,3] and fea[b,p,d], return new_xyz[b,g,3] and new_fea[b,g,k,d]
:param groups: groups number
:param kneighbors: k-nerighbors
:param kwargs: others
"""
super(LocalGrouper, self).__init__()
self.groups = groups
self.kneighbors = kneighbors
self.use_xyz = use_xyz
if normalize is not None:
self.normalize = normalize.lower()
else:
self.normalize = None
if self.normalize not in ["center", "anchor"]:
print(f"Unrecognized normalize parameter (self.normalize), set to None. Should be one of [center, anchor].")
self.normalize = None
if self.normalize is not None:
add_channel=3 if self.use_xyz else 0
self.affine_alpha = nn.Parameter(torch.ones([1,1,1,channel + add_channel]))
self.affine_beta = nn.Parameter(torch.zeros([1, 1, 1, channel + add_channel]))
def forward(self, xyz, points):
B, N, C = xyz.shape
S = self.groups
xyz = xyz.contiguous() # xyz [btach, points, xyz]
# fps_idx = torch.multinomial(torch.linspace(0, N - 1, steps=N).repeat(B, 1).to(xyz.device), num_samples=self.groups, replacement=False).long()
# fps_idx = farthest_point_sample(xyz, self.groups).long()
fps_idx = pointnet2_utils.furthest_point_sample(xyz, self.groups).long() # [B, npoint]
new_xyz = index_points(xyz, fps_idx) # [B, npoint, 3]
new_points = index_points(points, fps_idx) # [B, npoint, d]
idx = knn_point(self.kneighbors, xyz, new_xyz)
# idx = query_ball_point(radius, nsample, xyz, new_xyz)
grouped_xyz = index_points(xyz, idx) # [B, npoint, k, 3]
grouped_points = index_points(points, idx) # [B, npoint, k, d]
if self.use_xyz:
grouped_points = torch.cat([grouped_points, grouped_xyz],dim=-1) # [B, npoint, k, d+3]
if self.normalize is not None:
if self.normalize =="center":
std, mean = torch.std_mean(grouped_points, dim=2, keepdim=True)
if self.normalize =="anchor":
mean = torch.cat([new_points, new_xyz],dim=-1) if self.use_xyz else new_points
mean = mean.unsqueeze(dim=-2) # [B, npoint, 1, d+3]
std = torch.std(grouped_points-mean)
grouped_points = (grouped_points-mean)/(std + 1e-5)
grouped_points = self.affine_alpha*grouped_points + self.affine_beta
new_points = torch.cat([grouped_points, new_points.view(B, S, 1, -1).repeat(1, 1, self.kneighbors, 1)], dim=-1)
return new_xyz, new_points
class ConvBNReLU1D(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=1, bias=True, activation='relu'):
super(ConvBNReLU1D, self).__init__()
self.act = get_activation(activation)
self.net = nn.Sequential(
nn.Conv1d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, bias=bias),
nn.BatchNorm1d(out_channels),
self.act
)
def forward(self, x):
return self.net(x)
class ConvBNReLURes1D(nn.Module):
def __init__(self, channel, kernel_size=1, groups=1, res_expansion=1.0, bias=True, activation='relu'):
super(ConvBNReLURes1D, self).__init__()
self.act = get_activation(activation)
self.net1 = nn.Sequential(
nn.Conv1d(in_channels=channel, out_channels=int(channel * res_expansion),
kernel_size=kernel_size, groups=groups, bias=bias),
nn.BatchNorm1d(int(channel * res_expansion)),
self.act
)
self.net2 = nn.Sequential(
nn.Conv1d(in_channels=int(channel * res_expansion), out_channels=channel,
kernel_size=kernel_size, groups=groups, bias=bias),
nn.BatchNorm1d(channel)
)
def forward(self, x):
return self.act(self.net2(self.net1(x)) + x)
class PreExtraction(nn.Module):
def __init__(self, channels, out_channels, blocks=1, groups=1, res_expansion=1, bias=True,
activation='relu', use_xyz=True):
"""
input: [b,g,k,d]: output:[b,d,g]
:param channels:
:param blocks:
"""
super(PreExtraction, self).__init__()
in_channels = 3+2*channels if use_xyz else 2*channels
self.transfer = ConvBNReLU1D(in_channels, out_channels, bias=bias, activation=activation)
operation = []
for _ in range(blocks):
operation.append(
ConvBNReLURes1D(out_channels, groups=groups, res_expansion=res_expansion,
bias=bias, activation=activation)
)
self.operation = nn.Sequential(*operation)
def forward(self, x):
b, n, s, d = x.size() # torch.Size([32, 512, 32, 6])
x = x.permute(0, 1, 3, 2)
x = x.reshape(-1, d, s)
x = self.transfer(x)
batch_size, _, _ = x.size()
x = self.operation(x) # [b, d, k]
x = F.adaptive_max_pool1d(x, 1).view(batch_size, -1)
x = x.reshape(b, n, -1).permute(0, 2, 1)
return x
class PosExtraction(nn.Module):
def __init__(self, channels, blocks=1, groups=1, res_expansion=1, bias=True, activation='relu'):
"""
input[b,d,g]; output[b,d,g]
:param channels:
:param blocks:
"""
super(PosExtraction, self).__init__()
operation = []
for _ in range(blocks):
operation.append(
ConvBNReLURes1D(channels, groups=groups, res_expansion=res_expansion, bias=bias, activation=activation)
)
self.operation = nn.Sequential(*operation)
def forward(self, x): # [b, d, g]
return self.operation(x)
class modelelite3(nn.Module):
def __init__(self, points=1024, class_num=40, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=True, use_xyz=True, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs):
super(modelelite3, self).__init__()
self.stages = len(pre_blocks)
self.class_num = class_num
self.points = points
self.embedding = ConvBNReLU1D(3, embed_dim, bias=bias, activation=activation)
assert len(pre_blocks) == len(k_neighbors) == len(reducers) == len(pos_blocks) == len(dim_expansion), \
"Please check stage number consistent for pre_blocks, pos_blocks k_neighbors, reducers."
self.local_grouper_list = nn.ModuleList()
self.pre_blocks_list = nn.ModuleList()
self.pos_blocks_list = nn.ModuleList()
last_channel = embed_dim
anchor_points = self.points
for i in range(len(pre_blocks)):
out_channel = last_channel * dim_expansion[i]
pre_block_num = pre_blocks[i]
pos_block_num = pos_blocks[i]
kneighbor = k_neighbors[i]
reduce = reducers[i]
anchor_points = anchor_points // reduce
# append local_grouper_list
local_grouper = LocalGrouper(last_channel, anchor_points, kneighbor, use_xyz, normalize) # [b,g,k,d]
self.local_grouper_list.append(local_grouper)
# append pre_block_list
pre_block_module = PreExtraction(last_channel, out_channel, pre_block_num, groups=groups,
res_expansion=res_expansion,
bias=bias, activation=activation, use_xyz=use_xyz)
self.pre_blocks_list.append(pre_block_module)
# append pos_block_list
pos_block_module = PosExtraction(out_channel, pos_block_num, groups=groups,
res_expansion=res_expansion, bias=bias, activation=activation)
self.pos_blocks_list.append(pos_block_module)
last_channel = out_channel
self.act = get_activation(activation)
self.classifier = nn.Sequential(
nn.Linear(last_channel, 512),
nn.BatchNorm1d(512),
self.act,
nn.Dropout(0.5),
nn.Linear(512, 256),
nn.BatchNorm1d(256),
self.act,
nn.Dropout(0.5),
nn.Linear(256, self.class_num)
)
def forward(self, x):
xyz = x.permute(0, 2, 1)
batch_size, _, _ = x.size()
x = self.embedding(x) # B,D,N
for i in range(self.stages):
# Give xyz[b, p, 3] and fea[b, p, d], return new_xyz[b, g, 3] and new_fea[b, g, k, d]
xyz, x = self.local_grouper_list[i](xyz, x.permute(0, 2, 1)) # [b,g,3] [b,g,k,d]
x = self.pre_blocks_list[i](x) # [b,d,g]
x = self.pos_blocks_list[i](x) # [b,d,g]
x = F.adaptive_max_pool1d(x, 1).squeeze(dim=-1)
x = self.classifier(x)
return x
def modelelite3A1(num_classes=40, **kwargs) -> modelelite3: # 3.48M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3B1(num_classes=40, **kwargs) -> modelelite3: # 2.78M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.0625,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3C1(num_classes=40, **kwargs) -> modelelite3: # 4.87M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3D1(num_classes=40, **kwargs) -> modelelite3: # 2.26M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=8, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3E1(num_classes=40, **kwargs) -> modelelite3: # 2.43M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3F1(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3G1(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3H1(num_classes=40, **kwargs) -> modelelite3: # 3.56M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3I1(num_classes=40, **kwargs) -> modelelite3: # 0.90M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3J1(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3K1(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3L1(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=True, use_xyz=True, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3M1(num_classes=40, **kwargs) -> modelelite3: # 0.94M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2], pre_blocks=[4, 4, 4], pos_blocks=[4, 4, 4],
k_neighbors=[24, 24, 24], reducers=[2, 2, 2], **kwargs)
########version 2: 64 neighbors with 0.5 drop ratio ###########
def modelelite3A2(num_classes=40, **kwargs) -> modelelite3: # 3.48M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3B2(num_classes=40, **kwargs) -> modelelite3: # 2.78M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.0625,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3C2(num_classes=40, **kwargs) -> modelelite3: # 4.87M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3D2(num_classes=40, **kwargs) -> modelelite3: # 2.26M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=8, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3E2(num_classes=40, **kwargs) -> modelelite3: # 2.43M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3F2(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3G2(num_classes=40, **kwargs) -> modelelite3: # 0.85M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3H2(num_classes=40, **kwargs) -> modelelite3: # 3.56M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3I2(num_classes=40, **kwargs) -> modelelite3: # 0.90M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3J2(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3K2(num_classes=40, **kwargs) -> modelelite3: # 0.93M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3L2(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=8, res_expansion=0.25,
activation="relu", bias=True, use_xyz=True, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 4, 6, 3], pos_blocks=[3, 4, 6, 3],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3M2(num_classes=40, **kwargs) -> modelelite3: # 0.94M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2], pre_blocks=[4, 4, 4], pos_blocks=[4, 4, 4],
k_neighbors=[32, 32, 32], reducers=[2, 2, 2], **kwargs)
def modelelite3X1(num_classes=40, **kwargs) -> modelelite3: # 1.11M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X2(num_classes=40, **kwargs) -> modelelite3: # 0.94M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=2, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X3(num_classes=40, **kwargs) -> modelelite3: # 0.94
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X4(num_classes=40, **kwargs) -> modelelite3: # 2.77
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X5(num_classes=40, **kwargs) -> modelelite3: # 1.59
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X6(num_classes=40, **kwargs) -> modelelite3: # 1.44
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=4, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X7(num_classes=40, **kwargs) -> modelelite3: # 1.11M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X8(num_classes=40, **kwargs) -> modelelite3: # 0.95M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X9(num_classes=40, **kwargs) -> modelelite3: # 1.59M
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X10(num_classes=40, **kwargs) -> modelelite3: # 0.72M
return modelelite3(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 2, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X11(num_classes=40, **kwargs) -> modelelite3: # 0.98M 79/13s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 0],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X12(num_classes=40, **kwargs) -> modelelite3: # 0.98M 78/13s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 0],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
def modelelite3X13(num_classes=40, **kwargs) -> modelelite3: # 0.94M 90/15s
return modelelite3(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[1, 2, 2, 2], pre_blocks=[1, 2, 2, 2], pos_blocks=[1, 1, 0, 0],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
if __name__ == '__main__':
# data = torch.rand(2, 128, 10)
# model = ConvBNReLURes1D(128, groups=2, activation='relu')
# out = model(data)
# print(out.shape)
#
# batch, groups, neighbors, dim = 2, 512, 32, 16
# x = torch.rand(batch, groups, neighbors, dim)
# pre_extractor = PreExtraction(dim, 3)
# out = pre_extractor(x)
# print(out.shape)
#
# x = torch.rand(batch, dim, groups)
# pos_extractor = PosExtraction(dim, 3)
# out = pos_extractor(x)
# print(out.shape)
data = torch.rand(2, 3, 1024)
print("===> testing modelN ...")
model = modelelite3A1()
out = model(data)
print(out.shape)

View file

@ -1,18 +1,4 @@
"""
Based on model30, change the grouper operation by normalization.
Based on model28, only change configurations, mainly the reducer.
Based on model27, change to x-a, reorgnized structure
Based on model25, simple LocalGrouper (not x-a), reorgnized structure
Based on model24, using ReLU to replace GELU
Based on model22, remove attention
Bsed on model21, change FPS to random sampling.
Exactly based on Model10, but ReLU to GeLU
Based on Model8, add dropout and max, avg combine.
Based on Local model, add residual connections.
The extraction is doubled for depth.
Learning Point Cloud with Progressively Local representation.
[B,3,N] - {[B,G,K,d]-[B,G,d]} - {[B,G',K,d]-[B,G',d]} -cls
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
@ -291,12 +277,12 @@ class PosExtraction(nn.Module):
return self.operation(x)
class model31(nn.Module):
class Model(nn.Module):
def __init__(self, points=1024, class_num=40, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=True, use_xyz=True, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs):
super(model31, self).__init__()
super(Model, self).__init__()
self.stages = len(pre_blocks)
self.class_num = class_num
self.points = points
@ -359,172 +345,24 @@ class model31(nn.Module):
def model31A(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31B(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="center",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31C(num_classes=40, **kwargs) -> model31: # 85.219, 85.67, 85.115 , 85.566
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
def pointMLP(num_classes=40, **kwargs) -> Model:
return Model(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31D(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
def pointMLPElite(num_classes=40, **kwargs) -> Model:
return Model(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=0.25,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[20, 20, 20, 20], reducers=[2, 2, 2, 2], **kwargs)
def model31E(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=32, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31F(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=0.125,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
def model31G(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=16, res_expansion=2.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[32, 32, 32, 32], reducers=[2, 2, 2, 2], **kwargs)
"""
for ablation study
"""
def model31Ablation1111(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31Ablation1111NOnorm(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize=None,
dim_expansion=[2, 2, 2, 2], pre_blocks=[1, 1, 1, 1], pos_blocks=[1, 1, 1, 1],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31Ablation3333(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31Ablation3333NOnorm(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize=None,
dim_expansion=[2, 2, 2, 2], pre_blocks=[3, 3, 3, 3], pos_blocks=[3, 3, 3, 3],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31Ablation2222NOnorm(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize=None,
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31AblationNopre(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[0, 0, 0, 0], pos_blocks=[2, 2, 2, 2],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
def model31AblationNopos(num_classes=40, **kwargs) -> model31:
return model31(points=1024, class_num=num_classes, embed_dim=64, groups=1, res_expansion=1.0,
activation="relu", bias=False, use_xyz=False, normalize="anchor",
dim_expansion=[2, 2, 2, 2], pre_blocks=[2, 2, 2, 2], pos_blocks=[0, 0, 0, 0],
k_neighbors=[24, 24, 24, 24], reducers=[2, 2, 2, 2], **kwargs)
dim_expansion=[2, 2, 2, 1], pre_blocks=[1, 1, 2, 1], pos_blocks=[1, 1, 2, 1],
k_neighbors=[24,24,24,24], reducers=[2, 2, 2, 2], **kwargs)
if __name__ == '__main__':
# data = torch.rand(2, 128, 10)
# model = ConvBNReLURes1D(128, groups=2, activation='relu')
# out = model(data)
# print(out.shape)
#
# batch, groups, neighbors, dim = 2, 512, 32, 16
# x = torch.rand(batch, groups, neighbors, dim)
# pre_extractor = PreExtraction(dim, 3)
# out = pre_extractor(x)
# print(out.shape)
#
# x = torch.rand(batch, dim, groups)
# pos_extractor = PosExtraction(dim, 3)
# out = pos_extractor(x)
# print(out.shape)
data = torch.rand(2, 3, 1024)
print("===> testing model ...")
model = model31()
out = model(data)
print(out.shape)
print("===> testing modelA ...")
model = model31A()
out = model(data)
print(out.shape)
print("===> testing modelB ...")
model = model31B()
out = model(data)
print(out.shape)
print("===> testing modelC ...")
model = model31C()
out = model(data)
print(out.shape)
print("===> testing modelD ...")
model = model31D()
out = model(data)
print(out.shape)
print("===> testing model31Ablation1111 ...")
model = model31Ablation1111()
out = model(data)
print(out.shape)
print("===> testing model31Ablation1111NOnorm ...")
model = model31Ablation1111NOnorm()
out = model(data)
print(out.shape)
print("===> testing model31Ablation3333 ...")
model = model31Ablation3333()
out = model(data)
print(out.shape)
print("===> testing model31Ablation3333NOnorm ...")
model = model31Ablation3333NOnorm()
out = model(data)
print(out.shape)
print("===> testing model31AblationNopre ...")
model = model31AblationNopre()
out = model(data)
print(out.shape)
print("===> testing model31AblationNopos ...")
model = model31AblationNopos()
print("===> testing pointMLP ...")
model = pointMLP()
out = model(data)
print(out.shape)