Download pointcept/models/point_transformer/point_transformer_cls.py from dfki-av/BIMStruct3D-segmentation: direct link, hf CLI and curl.
- Browser
- Download file 4.09 kB
-
https://huggingface.co/dfki-av/BIMStruct3D-segmentation/resolve/7ab05dd198d38ea08e60bb1e4f3f04aa369975c2/pointcept/models/point_transformer/point_transformer_cls.py
- Command line
-
hf download hf://dfki-av/BIMStruct3D-segmentation@7ab05dd198d38ea08e60bb1e4f3f04aa369975c2/pointcept/models/point_transformer/point_transformer_cls.py
-
curl -L -o point_transformer_cls.py https://huggingface.co/dfki-av/BIMStruct3D-segmentation/resolve/7ab05dd198d38ea08e60bb1e4f3f04aa369975c2/pointcept/models/point_transformer/point_transformer_cls.py
4.09 kB
| """ | |
| Point Transformer V1 for Object Classification | |
| Might be a bit different from the original paper | |
| Author: Xiaoyang Wu (xiaoyang.wu.cs@gmail.com) | |
| Please cite our work if the code is helpful to you. | |
| """ | |
| import torch | |
| import torch.nn as nn | |
| from .point_transformer_seg import TransitionDown, Bottleneck | |
| from pointcept.models.builder import MODELS | |
| class PointTransformerCls(nn.Module): | |
| def __init__(self, block, blocks, in_channels=6, num_classes=40): | |
| super().__init__() | |
| self.in_channels = in_channels | |
| self.in_planes, planes = in_channels, [32, 64, 128, 256, 512] | |
| fpn_planes, fpnhead_planes, share_planes = 128, 64, 8 | |
| stride, nsample = [1, 4, 4, 4, 4], [8, 16, 16, 16, 16] | |
| self.enc1 = self._make_enc( | |
| block, | |
| planes[0], | |
| blocks[0], | |
| share_planes, | |
| stride=stride[0], | |
| nsample=nsample[0], | |
| ) # N/1 | |
| self.enc2 = self._make_enc( | |
| block, | |
| planes[1], | |
| blocks[1], | |
| share_planes, | |
| stride=stride[1], | |
| nsample=nsample[1], | |
| ) # N/4 | |
| self.enc3 = self._make_enc( | |
| block, | |
| planes[2], | |
| blocks[2], | |
| share_planes, | |
| stride=stride[2], | |
| nsample=nsample[2], | |
| ) # N/16 | |
| self.enc4 = self._make_enc( | |
| block, | |
| planes[3], | |
| blocks[3], | |
| share_planes, | |
| stride=stride[3], | |
| nsample=nsample[3], | |
| ) # N/64 | |
| self.enc5 = self._make_enc( | |
| block, | |
| planes[4], | |
| blocks[4], | |
| share_planes, | |
| stride=stride[4], | |
| nsample=nsample[4], | |
| ) # N/256 | |
| self.cls = nn.Sequential( | |
| nn.Linear(planes[4], 256), | |
| nn.BatchNorm1d(256), | |
| nn.ReLU(inplace=True), | |
| nn.Dropout(p=0.5), | |
| nn.Linear(256, 128), | |
| nn.BatchNorm1d(128), | |
| nn.ReLU(inplace=True), | |
| nn.Dropout(p=0.5), | |
| nn.Linear(128, num_classes), | |
| ) | |
| def _make_enc(self, block, planes, blocks, share_planes=8, stride=1, nsample=16): | |
| layers = [ | |
| TransitionDown(self.in_planes, planes * block.expansion, stride, nsample) | |
| ] | |
| self.in_planes = planes * block.expansion | |
| for _ in range(1, blocks): | |
| layers.append( | |
| block(self.in_planes, self.in_planes, share_planes, nsample=nsample) | |
| ) | |
| return nn.Sequential(*layers) | |
| def forward(self, data_dict): | |
| p0 = data_dict["coord"] | |
| x0 = data_dict["feat"] | |
| o0 = data_dict["offset"].int() | |
| x0 = p0 if self.in_channels == 3 else torch.cat((p0, x0), 1) | |
| p1, x1, o1 = self.enc1([p0, x0, o0]) | |
| p2, x2, o2 = self.enc2([p1, x1, o1]) | |
| p3, x3, o3 = self.enc3([p2, x2, o2]) | |
| p4, x4, o4 = self.enc4([p3, x3, o3]) | |
| p5, x5, o5 = self.enc5([p4, x4, o4]) | |
| x = [] | |
| for i in range(o5.shape[0]): | |
| if i == 0: | |
| s_i, e_i, cnt = 0, o5[0], o5[0] | |
| else: | |
| s_i, e_i, cnt = o5[i - 1], o5[i], o5[i] - o5[i - 1] | |
| x_b = x5[s_i:e_i, :].sum(0, True) / cnt | |
| x.append(x_b) | |
| x = torch.cat(x, 0) | |
| x = self.cls(x) | |
| return x | |
| class PointTransformerCls26(PointTransformerCls): | |
| def __init__(self, **kwargs): | |
| super(PointTransformerCls26, self).__init__( | |
| Bottleneck, [1, 1, 1, 1, 1], **kwargs | |
| ) | |
| class PointTransformerCls38(PointTransformerCls): | |
| def __init__(self, **kwargs): | |
| super(PointTransformerCls38, self).__init__( | |
| Bottleneck, [1, 2, 2, 2, 2], **kwargs | |
| ) | |
| class PointTransformerCls50(PointTransformerCls): | |
| def __init__(self, **kwargs): | |
| super(PointTransformerCls50, self).__init__( | |
| Bottleneck, [1, 2, 3, 5, 2], **kwargs | |
| ) | |