Skip to content

Commit

Permalink
updated codes and readme with results
Browse files Browse the repository at this point in the history
  • Loading branch information
justanhduc committed Aug 30, 2019
1 parent f323012 commit 9cdfd03
Show file tree
Hide file tree
Showing 17 changed files with 554 additions and 940 deletions.
70 changes: 56 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 1,29 @@
# GraphX-Convolution

The official implementation of the ICCV paper "GraphX-convolution for point cloud deformation in 2D-to-3D conversion".
The official implementation of the ICCV 2019 paper
"GraphX-convolution for point cloud deformation in 2D-to-3D conversion".

![framework](./imgs/framework.jpg)

__Updates:__ We have achieved a better performance with `PointCloudResLowRankGraphXUpDecoder`,
which is an upgraded version of the best deformation network in the paper. The new network works
comparably with the best network in the paper but consumes much less memory.

## Prerequisite

[Pytorch](https://pytorch.org/get-started/locally/) (>=1.0.0)

[Neuralnet-pytorch](https://github.com/justanhduc/neuralnet-pytorch)
(branch [fancy](https://github.com/justanhduc/neuralnet-pytorch/tree/fancy))

[Gin-config](https://github.com/google/gin-config)

[Matplotlib](https://matplotlib.org/)

[TensorboardX](https://github.com/lanpa/tensorboardX)

The code has been tested on a Linux Ubuntu 16.04 machine.

## Data

The data we used in our experiment provided by [ShapeNet](https://www.shapenet.org/).
Expand All @@ -33,32 45,62 @@ python split.py path/to/the/downloaded/data/folder
### Training

After the database is setup, we are ready to train the model.
At the root of the project, execute
In the [configs](./src/configs) folder, we have prepared the basic training configs for several models
used in the paper.
After the data is downloaded, specify the data root in these config files.

```
cd src
python train.py path/to/the/downloaded/data/folder
```
By default, the script creates a `results` folder containing checkpoint folders
corresponding to the model name.
The model name can be specified in the config files.

To resume a half-done training, simply specify the folder containing the weight file using the checkpoint flag
Then, simply execute

```
python train.py path/to/the/downloaded/data/folder --checkpoint path/to/the/checkpoint/folder
cd src
python train.py path/to/a/config/file (--gpu 0)
```

For more options, use ```python train.py -h```.
To resume a half-done training, simply specify the checkpoint folder in the config file.
Then run the training script as in the training step.

### Evaluation

Be sure to use the same config file and specify the checkpoint folder in the config file.
After the model is fully trained, to test the model, use

```
python test.py path/to/the/downloaded/data/folder --checkpoint path/to/the/checkpoint/folder
python test.py path/to/a/config/file (--gpu 0)
```

The script calculates the Chamfer distance (CD) scores similar to [Pixel2mesh](https://github.com/nywang16/Pixel2Mesh).
The script calculates the Chamfer distance (CD) scores similar to
[Pixel2mesh](https://github.com/nywang16/Pixel2Mesh).

## Results

### Visualizations

<p align='center'>
<img src='imgs/results/airplane.gif' width="250px">
<img src='imgs/results/bench.gif' width="250px">
<img src='imgs/results/car.gif' width="250px">
</p>

<p align='center'>
<img src='imgs/results/lamp.gif' width="250px">
<img src='imgs/results/monitor.gif' width="250px">
<img src='imgs/results/table.gif' width="250px">
</p>

### Numerical results

|Methods|IoU|Chamfer|
|:-------:|:---:|:-------:|
|[3D-R2N2](http://3d-r2n2.stanford.edu/)|1.445|0.631|
|[PSG](https://arxiv.org/abs/1612.00603)|0.593|0.640|
|[Pixel2mesh](https://github.com/nywang16/Pixel2Mesh)|0.591|-|
|[GAL](https://link.springer.com/chapter/10.1007/978-3-030-01237-3_49)|-|0.712|
|Ours (UpResGraphX)|__0.252__|__0.725__|

## References
## Citation

In our experiment, we actually used a CUDA implementation of CD available [here](https://github.com/ThibaultGROUEIX/AtlasNet/tree/master/extension),
which is much more efficient in terms of memory and speed.
TBA
Binary file added imgs/results/airplane.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/results/bench.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/results/car.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/results/lamp.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/results/monitor.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/results/table.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/configs/fc-final.gin
Original file line number Diff line number Diff line change
@@ -0,0 1,24 @@
GraphX.data_root = '/media/hdd2/csh/ShapeNet7Class2'

GraphX.name = 'ICCV-fc-final'
GraphX.img_enc = @cnn18_enc
GraphX.pc_enc = @pc_enc
GraphX.pc_dec = @pc_dec
GraphX.adain = True
GraphX.projection = True

GraphX.color_img = False
GraphX.n_points = 2000
GraphX.bs = 4

GraphX.optimizer = @adam
GraphX.scheduler = @multistep_lr
GraphX.lr = 5e-5
GraphX.weight_decay = 1e-5
GraphX.gamma = .3
GraphX.milestones = (5, 8)
GraphX.n_epochs = 10
GraphX.print_freq = 1000
GraphX.val_freq = 10000

GraphX.checkpoint_folder = None
24 changes: 24 additions & 0 deletions src/configs/graphx-up-final.gin
Original file line number Diff line number Diff line change
@@ -0,0 1,24 @@
GraphX.data_root = '/media/hdd2/csh/ShapeNet7Class2'

GraphX.name = 'ICCV-graphx-conv-up-final'
GraphX.img_enc = @cnn18_enc
GraphX.pc_enc = @pc_enc
GraphX.pc_dec = @pc_upresgraphxdec
GraphX.adain = True
GraphX.projection = True

GraphX.color_img = False
GraphX.n_points = 250
GraphX.bs = 4

GraphX.optimizer = @adam
GraphX.scheduler = @multistep_lr
GraphX.lr = 5e-5
GraphX.weight_decay = 1e-5
GraphX.gamma = .3
GraphX.milestones = (5, 8)
GraphX.n_epochs = 10
GraphX.print_freq = 1000
GraphX.val_freq = 10000

GraphX.checkpoint_folder = None
25 changes: 25 additions & 0 deletions src/configs/lowrankgraphx-up-final.gin
Original file line number Diff line number Diff line change
@@ -0,0 1,25 @@
GraphX.data_root = '/media/hdd2/csh/ShapeNet7Class2'

GraphX.name = 'ICCV-lowrankgraphx-conv-up-final'
GraphX.img_enc = @cnn18_enc
GraphX.pc_enc = @pc_enc
GraphX.pc_dec = @pc_upreslowrankgraphxdec
GraphX.adain = True
GraphX.projection = True
decimation = .5

GraphX.color_img = False
GraphX.n_points = 250
GraphX.bs = 4

GraphX.optimizer = @adam
GraphX.scheduler = @multistep_lr
GraphX.lr = 5e-5
GraphX.weight_decay = 1e-5
GraphX.gamma = .3
GraphX.milestones = (5, 8)
GraphX.n_epochs = 10
GraphX.print_freq = 1000
GraphX.val_freq = 100000

GraphX.checkpoint_folder = None
18 changes: 6 additions & 12 deletions src/data_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 38,25 @@ def collate(batch):


class ShapeNet(Dataset):
def __init__(self, file_list, path, grayscale=None, type='train', n_points=2000, metadata=False, **kwargs):
def __init__(self, path, grayscale=None, type='train', n_points=2000, **kwargs):
assert type in ('train', 'valid', 'test')
self.n_points = n_points
self.grayscale = grayscale
self.file_list = file_list
self.file_list = os.listdir(path)
self.path = path
self.type = type if type in ('train', 'test') else 'test'
self.metadata = metadata
self.num_vals = kwargs.pop('num_vals', 30)
self.pkl_list = []
self.sample_weights = []
for folder in file_list:
for folder in self.file_list:
file_path = os.listdir(os.path.join(path, folder, self.type))
if type == 'valid':
idx = np.random.randint(len(file_path), size=self.num_vals // len(file_list))
idx = np.random.randint(len(file_path), size=self.num_vals // len(self.file_list))
file_path = [file_path[i] for i in idx]

file_path = [os.path.join(self.path, folder, self.type, f) for f in file_path]
self.pkl_list.extend(file_path)
self.sample_weights.extend([1 / len(file_path)] * len(file_path))
self.sample_weights.extend([1/len(file_path)] * len(file_path))

def __len__(self):
return len(self.pkl_list)
Expand All @@ -69,9 68,4 @@ def __getitem__(self, idx):
img = (np.transpose(img / 255.0, (2, 0, 1)) - .5) * 2
pc = np.array(contents[1], 'float32')[:, :3]
pc -= np.mean(pc, 0, keepdims=True)
item = (init_pointcloud_loader(self.n_points), np.array(img, 'float32'), pc)
if self.metadata:
metadata = pkl_path.split('\\')[-1][:-4]
item = (metadata,)

return item
return init_pointcloud_loader(self.n_points), np.array(img, 'float32'), pc
Loading

0 comments on commit 9cdfd03

Please sign in to comment.