PointNet and PointNet++ on Raw Points
Points arrive shuffled with no grid. PointNet reads each point alone then max-pools so order never matters; PointNet++ adds local neighborhoods.
Why Does This Exist?
Point clouds are sets: shuffling points must not change the answer, which rules out plain sequence nets. PointNet exists as the order-free baseline that point cloud processing introduces: shared MLPs plus symmetric pooling. PointNet++ fixes its blindness to local curves by grouping neighborhoods hierarchically. The architecture-deep version lives in core ML PointNet; this page is the vision use and the merged Plus upgrade.
Graph and attention successors are DGCNN and Point Transformer.
Think of It Like This
Judging Lego builds from sorted piles
Dump two identical Lego builds on tables in different orders and judge by counting brick types, not sequence. Then zoom into wheels and windows locally before judging the whole castle.
Max-pooling is the counting and set abstraction is the zoom. The analogy stops at rotation: brick counts ignore pose while points need alignment, handled by a small spatial transformer.
How It Actually Works
PointNet maps each point through shared into dims, then gives permutation invariance since max ignores order. A mini spatial transformer predicts a alignment from the cloud itself. PointNet++ samples farthest points, balls -neighborhoods around each, runs mini-PointNets locally, and repeats: set abstraction layers shrink to to centroids with growing radii , , m, capturing curves at multiple scales.
Worked numbers
Four points , , , through give , , , ; max-pool gives regardless of input order. Shuffling the list returns the same . On ModelNet40 with points, reference accuracy moves from about percent PointNet to percent PointNet++.
Code
def pointnet_pool(feats: list[list[float]]) -> list[float]: dims = len(feats[0]) return [max(f[d] for f in feats) for d in range(dims)] # symmetric: order-free
print(pointnet_pool([[0, 0], [1, 0], [1, 0], [0, 1]])) # -> [1, 1]Watch Out For
Expecting fine local detail from vanilla PointNet
Global pooling keeps one max per channel, so small handles and thin legs vanish. The symptom is great classification with blobby segmentations. Use PointNet++ grouping or a local operator such as KPConv when parts matter.
The Quick Version
- PointNet reads raw points with shared MLPs plus max-pooling for order freedom.
- Shuffled inputs give identical global vectors by construction.
- A learned transform adds rough rotation robustness.
- PointNet++ groups neighborhoods hierarchically for local geometry.
- Reference ModelNet40 rises from to percent with hierarchy.
- Use Plus or local operators when parts and curves matter.