3D Geodata Academy

3D Deep Learning Complete Guide

The complete 101 on 3D deep learning in Python: why point clouds break ordinary networks, permutation invariance, honest data prep, and the road from PointNet to KPConv.

Published on August 5, 2026 • 20 min read

3D Deep Learning • KPConv • Machine Learning • Neural Networks

You can point a pretrained image classifier at a folder of photos and have working predictions before your coffee cools. Try the same trick on a laser scan of a stairwell, and every instinct you trusted quietly stops working.

How 3D deep learning reads a top-down scene for classification
A network learning to read a scene, one representation feeding the next.

That gap is where 3D deep learning starts, and it catches almost everyone who crosses into three dimensions. A network built to read a grid of pixels cannot read a loose bag of coordinates. Once you understand why, the rest of the field snaps into an order you can actually follow.

So this guide is the whole map, start to finish. What breaks, what fixes it, how to prepare your data without lying to yourself, the three architectures worth your time, and the order to learn them in.

Diagram of the permutation-invariance recipe for 3D deep learning, showing a shared function applied per point then a symmetric max or sum pool producing one order-independent descriptor
The idea under nearly every point network: run the same small function on each point, then fold the results with a symmetric pool so input order stops mattering. Keep this in view, because the whole guide is one path across it.

What you’ll learn in this article:

  • Why an unordered set of points jams an ordinary neural network, and the single operation that unjams it
  • How to write a permutation-invariant max-pool in a dozen lines of PyTorch and prove it holds
  • The data preparation step that quietly decides whether your model learns or memorizes noise
  • How PointNet, PointNet++, and KPConv answer the same question three different ways
  • A concrete order to learn all of it in, from a first tensor to your own architecture

Estimated reading time: 12 minutes


Why Point Clouds Break Ordinary Neural Networks

Start with a photo, since that is the comfortable case. A photo is a grid, and row twelve column forty is always the same pixel with the same neighbors. A convolution can march across it precisely because every pixel sits in a fixed, knowable neighborhood.

Now swap in a room captured by a scanner. What comes back is a list of XYZ triplets, maybe two million of them, in whatever sequence the hardware happened to fire. There is no row twelve. There is no fixed neighbor.

Large-scale per-instance segmentation of a whole building in Neurones 3D
Large-scale per-instance segmentation of a whole building, the kind of output a trained model produces.

Here is the part that surprises people. Shuffle every line of that file and you are looking at the exact same room, unchanged in every physical way. The geometry did not move a millimeter.

So what happens when you push that list into a plain fully connected network? It reads position number five as one specific input slot with its own weights. Reorder the file, and every slot now holds a different point, so the network computes something new for a room that never moved. A chair has to register as a chair whether its points arrive front to back or scrambled, and a slot-based network cannot promise that.

What Permutation Invariance Actually Means

The fix is cleaner than the problem, which is my favorite kind of fix. The property you want has a name, permutation invariance, and it means the output must not depend on input order.

You buy it with a two-move recipe. First, run the same small function over each point on its own, so no single point gets a privileged slot. Second, fold those per-point results together with a symmetric operation that returns the same value no matter how you list its inputs.

Which operations are symmetric, and which quietly are not? A max lands on the same value whichever order you read it in. So does a sum, and so does a mean. Concatenation does the opposite: it cares deeply about which value sits in which slot, so it shatters the invariance you just built.

Comparison diagram of pooling operations for 3D deep learning showing max, sum, and mean keeping permutation invariance while concatenation breaks it
Max, sum, and mean stay order-blind, so any of them preserves permutation invariance. Concatenation does not, and that one choice would undo the whole design.

PointNet reaches for the max, and there is a reason. A mean keeps the invariance but blunts the sharp responses, and a max keeps the strongest signal per channel while staying order-blind. That single decision let PointNet train on raw points, and it still holds up nearly everything built since.

🦥 Geeky Note: The pooling here is a channel-wise max across all N points, each lifted to a 1024-dimensional vector by the shared perceptron. Drop the descriptor width from 1024 to 256 and you trade richness for speed, and the invariance survives untouched. The max is the load-bearing line, not the width you pick around it.

The Tiny PyTorch Model That Proves It

Let me show this small enough to read in one breath. The module below lifts every point through a shared multilayer perceptron, meaning the same weights process each point separately, then squashes the entire set into a single descriptor with a max across the point axis.

The last few lines are the honest part. They shuffle the input and check the output did not budge.

import torch
import torch.nn as nn


class MaxPoolPointNet(nn.Module):
    """Turn an unordered set of points into one order-independent descriptor."""

    def __init__(self, in_dim=3, width=64, code=1024):
        super().__init__()
        self.per_point = nn.Sequential(
            nn.Linear(in_dim, width),
            nn.ReLU(),
            nn.Linear(width, code),
        )

    def forward(self, cloud):                  # cloud: (B, N, in_dim)
        lifted = self.per_point(cloud)         # (B, N, code), same weights per point
        descriptor, _ = lifted.max(dim=1)      # (B, code), max across the N points
        return descriptor


net = MaxPoolPointNet()
points = torch.rand(1, 512, 3)
reordered = points[:, torch.randperm(512), :]
assert torch.allclose(net(points), net(reordered), atol=1e-6)   # order changes nothing

The line that earns its keep is descriptor, _ = lifted.max(dim=1). Everything above it is an ordinary PyTorch network you could have written for tabular data. That one max over the point axis is the entire reason the descriptor comes out identical after a shuffle.

It helps to watch the tensor shape as it travels, because the point axis is where the magic hides. The cloud goes in as (B, N, 3), the shared perceptron lifts it to (B, N, C) while keeping every point separate, and only the max collapses that middle axis into a single (B, C) descriptor per cloud.

Diagram of tensor shapes moving through a tiny 3D deep learning model, from batch by points by three, through a shared MLP, to a max over the point axis producing one descriptor per cloud
The point count N stays alive right up to the max pool, which is the only step that drops it. B is the batch, N the number of points, C the descriptor width.

If the assert passes on your machine, you have just proven permutation invariance by hand. That is worth more than reading ten explanations of it, and it takes about thirty seconds to run.

The One Training Step That Teaches Per-Point Labels

The shuffle test proved the descriptor holds still. It did not make the network right about anything, since a fresh model just emits noise. Training is the part that pushes its guesses toward the truth, and the smallest honest version of it is a single step: predict, measure the miss, nudge the weights.

A point cloud dataset from the AHN4 national LiDAR campaign
Real training data at national scale, the kind of input these models actually see.

Trade the one global descriptor for a per-point head, and the same shared perceptron now emits a class score row for every point instead of one vector for the whole cloud. That is exactly the segmentation output you are after, a label sitting on each point.

A textured room mesh and the same scene labeled by a segmentation model in Neurones 3D
A textured room mesh and the same scene labeled by a segmentation model.
import torch
import torch.nn as nn


class PerPointHead(nn.Module):
    """The shared-MLP idea again, but score every point instead of pooling to one vector."""

    def __init__(self, in_dim=3, width=64, num_classes=5):
        super().__init__()
        self.per_point = nn.Sequential(
            nn.Linear(in_dim, width),
            nn.ReLU(),
            nn.Linear(width, num_classes),
        )

    def forward(self, cloud):              # cloud: (B, N, in_dim)
        return self.per_point(cloud)       # (B, N, num_classes), one score row per point


model = PerPointHead(num_classes=5)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()

cloud = torch.rand(4, 1024, 3)             # (B, N, 3), a batch of prepared samples
labels = torch.randint(0, 5, (4, 1024))    # (B, N), the true class of each point

logits = model(cloud)                                        # (B, N, 5)
loss = loss_fn(logits.reshape(-1, 5), labels.reshape(-1))    # flatten points, then score
optimizer.zero_grad()
loss.backward()                            # gradients: how each weight moved the loss
optimizer.step()                           # walk every weight a small step downhill

The pair carrying the whole lesson is loss.backward() and optimizer.step(). The loss measures how far the per-point guesses sit from the labels, and that pair walks every weight a small distance down the gradient. Loop it over batches and the guesses drift toward the truth.

Notice the reshape too. Cross-entropy wants a flat list of point scores against a flat list of labels, so you fold the batch and point axes together, judge every point at once, and let one number cover the whole cloud. Get that loop running on toy tensors first, because the real work is feeding it clouds that were prepared honestly. Producing those per-point labels in the first place is its own task, and our guide to 3D point cloud labeling in Python covers it.

Why Data Preparation Decides Your 3D Deep Learning Model

Here is the truth the polished tutorials skip past. The hours you pour into cleaning and shaping clouds will outweigh the hours you spend fitting a model, and when the shaping is wrong, no architecture rescues you.

Think about what a network like PointNet demands at the door. Every sample the same size, often 1024 or 4096 points, recentered and normalized, sometimes with color or normal channels riding alongside the raw XYZ. Your scans offer none of that. One room hands you two million points, and the next has barely 300,000.

Voxels shaded by their surface normals in Neurones 3D
Voxels shaded by their surface normals, one of the input signals a network learns from.

So preparation is not a chore you rush through. It is the part that quietly decides your ceiling. Two steps deserve special care, and beginners underestimate both. Our guide to point cloud data preparation for 3D deep learning walks the full prep pipeline.

Sampling A Scan Down To A Fixed Size

You cannot feed a variable point count into a fixed model, so you sample down to a set size. The lazy way is random downsampling, and it works until it does not. Random keeps clumps where the cloud was dense and leaves gaps where it was thin, so a corner of your object can vanish.

Farthest point sampling fixes that. It picks each new point to be as far as possible from the ones already chosen, so the survivors spread evenly across the shape instead of piling up.

Diagram comparing farthest point sampling and random downsampling for 3D deep learning, showing random leaving clumps and gaps while farthest point sampling keeps even coverage and corners
Both cut a dense scan to the same fixed count. Random downsampling leaves clumps and thin corners, while farthest point sampling keeps the shape evenly covered.

Is farthest point sampling slower? Yes, noticeably, because each pick scans the remaining points. For a 1024-point sample the cost is nothing you will feel, and the even coverage pays you back at training time.

Normalizing Coordinates So Training Moves

Now the step that once cost me a full week. A network fed raw coordinates in meters, running from roughly minus fifty to plus sixty, will often refuse to train at all, with the loss sitting flat as a table.

The fix is two operations. Center every cloud on its own centroid so it sits at the origin, then scale it so it fits inside a unit sphere. Suddenly every axis lives in a tidy range near zero, and the same architecture that sat dead now converges.

Diagram of coordinate normalization for 3D deep learning, showing raw meter coordinates offset far from the origin being centered on the centroid and scaled into a unit sphere
Center on the centroid, then scale to a unit sphere. Raw meters sit far from the origin at a large scale, and normalizing is what lets training move at all.

During training you also augment: random rotations about the vertical axis and a little jitter, so the model learns the shape rather than one frozen pose. Get any link in that chain wrong and the failure is sneaky, since the loss drops, training accuracy looks respectable, and the thing generalizes to nothing.

🦚 Florent’s Note: That input-scale bug is the dullest on the whole list, and it taught me more than any of them. I lost a week to a network that would not budge for a hundred epochs, and the cause was coordinates in meters that never got normalized. Now the first line of every prep script centers on the centroid and rescales into a unit sphere, no exceptions, because the same model on raw meters teaches you nothing but frustration.

🌱 Growing Note: Do not start on point clouds. Build a plain classifier on six or seven handcrafted descriptors first, normals plus curvature plus height above ground, and train it in scikit-learn on a labeled scan. You get a real baseline in an afternoon, and every deep model afterward has a number to beat. A network that cannot clear a random forest on the same data is telling you the prep is broken, not the architecture.

PointNet PointNet++ And KPConv Compared

All three ask one question: how do you learn descriptors on an unordered set of points? They answer in three flavors, and the lineage tells you which to reach for and, more usefully, which to learn first.

PointNet, published by Qi and coauthors in 2017, is the clean place to begin. Every point runs through the shared perceptron you already met, then a single global max pool folds the whole set into one vector describing the object. Read the original PointNet paper once you have done the data prep by hand, since it names every piece you just wrestled with.

Its weakness sits right in the design. That lone global pool sees the whole and misses the parts, so fine local structure slips past it.

Neural network applications across raster, vector, and 3D point data
The same core idea adapts across data types. 3D is one branch of a bigger family.

So the same authors patched their own model. PointNet++ runs PointNet inside a hierarchy, applying it to small local groups, pooling those, then repeating on the pooled result. It builds descriptors from local up to global, the way a convolutional network stacks edges into objects.

Diagram of receptive field growth in 3D deep learning, contrasting PointNet pooling the whole set once with PointNet++ widening its neighborhoods layer by layer
PointNet pools the entire set in one shot. PointNet++ grows what each point sees layer by layer, which is exactly why it reads the detail its parent blurred.

Then KPConv swung differently. Instead of pooling neighborhoods, it defines a genuine convolution for points, using kernel points placed at fixed offsets that weight nearby points by distance. A real scanned point gets its contribution blended across the closest kernel points, so the convolution lives in continuous space rather than on a fixed grid.

Diagram of a KPConv kernel for 3D deep learning, showing fixed kernel points weighting a real scanned point by distance so the convolution lives in continuous space
A KPConv kernel is a small cloud of fixed points, each holding a learned weight matrix. A real point’s weight blends across the closest of them, which is what lets a convolution cope with uneven density.

I nearly told you to start with PointNet++, since it is the stronger model you will reach for in practice. Then I caught myself, because that is backward. Learn the simple invariant first, and the hierarchy reads as an obvious next move rather than a black box. For a build-along, our step-by-step guide to a 3D object recognition algorithm puts one of these networks to work.

🪐 System Thinking Note: Notice what you really learned in the max-pool section. Apply a shared function per element, then combine with a symmetric operation, and you get a network that respects an unordered set. That pattern is not stuck to point clouds, since the same shape drives networks over molecules, graphs, and any collection where order carries no meaning. Learn it once as geometry and you own a tool that transfers far past the scan on your screen.

🦥 Geeky Note: KPConv’s kernel is a little cloud of roughly fifteen positions arranged inside a sphere, each carrying its own learned weight matrix. That is the trick that lets a convolution sit in continuous 3D space, and it is why KPConv stays steady when point density swings across an aerial or mobile scan.

What A Trained Model Hands You

Let us ground this, since the point of the whole stack was never the papers. You prep a scan into fixed-size normalized samples, run it through a trained PointNet or KPConv, and receive a class on every point: ground, building, vegetation, vehicle.

Those per-point classes are the raw material behind a city digital twin, a hands-off progress check on a building site, or a vehicle’s read of the road ahead. Label one room reliably and the same recipe scales to a district, then a country.

But the output is only as trustworthy as the signal going in. Bare coordinates on a rooftop and bare coordinates on a paved street can read almost identically to a network, since both are just flat patches. Fuse the scan with aligned imagery so each point also carries color, and you hand the model something real to separate on.

The Order To Learn 3D Deep Learning In

So where does a beginner actually start? Not at the top. The fastest way to stall is to open a KPConv repository on day one and drown.

Here is the order that works, easy rung first. Build a classical baseline so you have a number to beat. Build a plain training loop so the 3D models stop feeling like magic. Code PointNet yourself, since it teaches the one invariant everything reuses. Then, and only then, reach for the density-aware architectures, and reach for them as a library call rather than a from-scratch rebuild.

Diagram of the recommended learning order for 3D deep learning, from a classical baseline through a training loop and PointNet to borrowing PointNet++ and KPConv from a library
Each rung reuses the one before it. Code the first three yourself, and leave the hierarchy and point convolution as a library call until the basics are solid.

Why borrow the last rung instead of building it? Because the difficulty jump from PointNet to KPConv is steep, and nobody hands you a medal for starting at the hard end. For the wider set of resources and roadmaps, see our 3D deep learning essentials guide.

Propagating learned semantic tags across the segments of a room in Neurones 3D
Propagating learned semantic tags across the segments of a room.

🌱 Growing Note: You do not have to rebuild these to run them. Open3D-ML bundles working PointNet++ and KPConv alongside loaders for common benchmarks, so you train on real data and read the reference code together. Code PointNet yourself to learn the internals, and treat KPConv as an import at first, since the honest goal is understanding the field, not proving you can suffer.

🦚 Florent’s Note: My rule when a shiny new architecture drops: do not rebuild the pipeline around it. Freeze your data prep and your evaluation harness, swap only the model, and measure the honest delta. Nine times in ten the real gain is a fraction of the abstract promise, and now you can prove it instead of feeling it. That one habit separates a practitioner who compounds from one the field keeps knocking flat.

Where 3D Deep Learning Fits In Your Spatial AI Path

This guide is one stop on a longer route. The full map lives in the 3D Spatial AI with Python complete guide, which lays out the road from raw sensing through to reasoning about whole scenes.

Two natural clicks sit on either side of this one. Before you train anything, you want clean structured point groups, which is the job of 3D point cloud segmentation and clustering in Python, where plane fitting and density clustering carve a raw scan into parts a network can later learn to reproduce and outdo. After you can label points, the frontier is meaning, and semantic and spatial AI with scene graphs in Python takes over once single-point classes run out.

When you want the training loop, the debugging instincts, and the thousand small choices a paper never spells out, structured teaching earns its keep. The 3D Spatial AI Program is where I teach this end to end, from raw cloud to trained model, with the parameter intuition you cannot get from a single article.

Start Training Your First Point Cloud Model This Week

Reading about invariance is not what makes it stick. Running it once is.

So run the small loop this week. Prep a real scan into fixed-size normalized samples, fit a bare PointNet on a tidy benchmark, and label every point. Leave PointNet++ and KPConv alone until that first loop runs end to end on your own machine, because the simpler model teaches the mechanics the fancier ones reuse.

If you want a first real 3D Python task to run right now, the free mission hands you one to build this week. And when you are ready to go deep, the 3D Spatial AI Program takes you from this first loop all the way to designing your own architectures.

So which will you reach for first: the classical baseline that gives you a number to beat, or the network that learns the descriptors you used to design by hand?

The nested depth levels of ML, neural networks, and deep learning
Where deep learning sits inside machine learning, drawn as nested scopes.

Frequently Asked Questions

Why Can’t A Standard Neural Network Read A Point Cloud?

An ordinary network treats each input position as a fixed slot with its own weights, and a point cloud has no fixed order, so reshuffling the same points produces a different answer for the same geometry. The fix is permutation invariance through a symmetric pooling operation, introduced in the PointNet paper and kept by nearly every point model since.

Which 3D Deep Learning Model Should You Learn First?

Start with PointNet, always. It carries the single idea, order-independent pooling, that the later models build on, so learning it turns PointNet++ and KPConv into small steps rather than fresh mountains. If you want that groundwork taught in order, the 3D Spatial AI Program walks it from a first tensor to your own architecture.

How Important Is Data Preparation For Training PointNet?

It matters more than the architecture you pick. Sampling to a fixed point count, centering, scaling to a unit sphere, and augmenting with rotation and jitter decide whether the model learns the shape or memorizes noise. Practice it against real benchmark loaders in Open3D-ML rather than a toy set that hides the hard parts.

Does 3D Deep Learning Work On City-Scale Outdoor LiDAR?

Yes, and the density-aware models were built for exactly that. KPConv handles the uneven point density of aerial and mobile LiDAR well, because its kernel points weight neighbors by real distance rather than assuming a fixed grid, which is why it copes with scans that thin out with range.

Do You Need A GPU To Learn 3D Deep Learning?

To learn the concepts, no. You can prototype the tiny max-pool model and a small training run on a CPU, and the shuffle test in this guide runs in seconds without one. For full-resolution benchmarks and hierarchical models you will want a GPU, and you can start that step with a free run on the free mission.

Ready to start?

2,800+ engineers started exactly here. Free. No credit card. No tricks.

Get Instant access

✓ Used by teams at Meta, Airbus, CNRS

Architect Spatial Intelligence.

The Brain-to-Deploy methodology. From first principles to production-grade 3D AI.

The Foundation
€1 997 €7 249
Founding Price Lifetime Access

Master the core 3D AI stack. For innovators building a strategic edge in spatial intelligence.

  • Spatial Accelerator (17 Episodes) The 17-episode deep-dive on the Brain-to-Deploy methodology. From mental models to shipped production systems.
  • Full 3D Course Library (20+ Courses) The complete curriculum. Point clouds, meshing, segmentation, deep learning 3D, spatial reasoning.
  • Neurones 3D Software Suite The software suite I built to unify 3D reconstruction, segmentation, and spatial analysis in one stack. Standard commercial license included.
  • Monthly Spatial AI Nuggets A monthly briefing on what moved in 3D AI. Research, code, and market signals I think you should know.
  • Private Job & Market Intelligence
Secure Foundation Access
Best Value
Professional
€2 997 €13 997
Founding Price Lifetime Production Access

Scale from prototype to industrial-grade deployment. For founders architecting proprietary spatial systems.

  • Everything in Foundation
  • 4 OS Deep-Dive Production Tracks Complete tracks: Spatial Reconstructor, Segmentor, Deep Learning 3D, and more. Each ships with 12 months of active updates and support, with optional annual renewal. Each track valued at €1,497.
  • 5 Forge .exe Apps + AI Agent Toolkit Five ready-to-run Windows apps plus the AI agent toolkit. Run 3D AI pipelines without touching infrastructure code.
  • 12-Month Strategic Production Briefs Every month I spot a real market opportunity and hand you the full step-by-step blueprint to build it. Twelve briefs, twelve shipped tools or software over the year.
  • Monthly Live Q&A Sessions Monthly live calls. Ask anything technical or strategic and get a direct answer from me.
Accelerate to Professional
Architect
€4 997 €19 249
Strictly Limited: 15 Seats Direct Access

Elite 1-on-1 advisory. I personally review your architecture and deliver custom Brain-to-Deploy blueprints.

  • Everything in Professional
  • Onboarding + Annual Strategy Sessions A kickoff session to map your system, plus recurring strategy calls where I pressure-test your architecture and roadmap.
  • Private 48h Priority Channel A direct line to me for architecture reviews and technical unblocks. Guaranteed response within 48h on business days.
  • Co-Built Custom 3D AI Solution Not built for you, but with you. I code alongside you to architect and ship a custom 3D AI solution for your specific use case.
  • Portfolio & Project Endorsement
Apply for Architect Advisory

Reach out or book a call
to keep learning

Reach out for tailored support, or book a call to have more information about new courses.

Scroll to Top