ranahanocka / MeshCNN

Convolutional Neural Network for 3D meshes in PyTorch
MIT License
1.56k stars 314 forks source link

Code crashing under certain examples #40

Open ismaelGomez87 opened 4 years ago

ismaelGomez87 commented 4 years ago

Hi Rana,

first of all, thanks for this contribution. It really looks promising!

I am working with your code in order to analyze a set of meshes formed by molecular shapes. The objects I work with are all genus 0 manifolds (i.e. no holes). I am running your code with segmentation options (although I don't really have any segments defined).

I could run the code with some dummy examples. But, when I try to extend it to a more general set, I run into the following error:

Traceback (most recent call last):
  File "train.py", line 36, in <module>
    model.optimize_parameters()
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/mesh_classifier.py", line 72, in optimize_parameters
    out = self.forward()
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/mesh_classifier.py", line 59, in forward
    out = self.net(self.edge_features, self.mesh)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 209, in __call__
    return self.forward(x, meshes)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 202, in forward
    fe, before_pool = self.encoder((x, meshes))
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 363, in __call__
    return self.forward(x)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 347, in forward
    fe, before_pool = conv((fe, meshes))
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 228, in __call__
    return self.forward(x)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/networks.py", line 250, in forward
    x2 = self.pool(x2, meshes)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/layers/mesh_pool.py", line 21, in __call__
    return self.forward(fe, meshes)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/layers/mesh_pool.py", line 34, in forward
    self.__pool_main(mesh_index)
  File "/Users/ismael.gomez/Documents/Software/MeshCNN/MeshCNN-unsupervised v2/models/layers/mesh_pool.py", line 50, in __pool_main
    value, edge_id = heappop(queue)
IndexError: index out of range

Adding some marks within your code, I could identify that his happens in cases where there are -1's in the gemm-edges structure, but I don't understand why is this. My surfaces are all (allegedly) closed, so no boundary edges exist.

Do you have any idea of why this is happening?

Thanks in advance, Ismael.

ranahanocka commented 4 years ago

Hi @ismaelGomez87 ,

What is the resolution (how many edges) are in your meshes? The issue is that the network is running out of edges to collapse, notice the error message:

value, edge_id = heappop(queue)

IndexError: index out of range

You should modify the pooling resolution to fit the size of your input meshes. I assume you are working with the configuration file from the human_seg , so notice that the pooling res flag ends at 600 edges:

https://github.com/ranahanocka/MeshCNN/blob/f49f78060757458fdc0ed2a1d0d172860a4112b2/scripts/human_seg/train.sh#L11

you should increase it for your meshes. depending on how large they are, you should be able to pool to 30% or 40% of the input mesh resolution.

ismaelGomez87 commented 4 years ago

Hi @ranahanocka ,

thanks for your answer. My meshes have 480 edges each. I could augment the resolution but not reduce it. I defined my --pool_res argument accordingly:

--pool_res 240 120 60 \

With these values I get the error. If I understand your comment correctly, I shouldn't reduce the minimum resolution of pooling below 30-40% of my initial number of edges (which would let me with around 150 edges). Would this be the error?

Edit: I'd like to get a lower resolution intermediate layer, that's why I'm reducing it so much. Is there a possible workaround for this (in case the error is caused by the small number of edges)?

patrick100 commented 4 years ago

I had the same problem in classification, but you can check the boundary of each model in your dataset and then choose the best last pool_res according to the boundary in the dataset, or you can attend each model with pool_res exceded as a particular case.

ranahanocka commented 4 years ago

Hi @ismaelGomez87 ,

My meshes have 480 edges each. I could augment the resolution but not reduce it. I defined my --pool_res argument accordingly:

--pool_res 240 120 60 \

That is rather aggressive pooling. You can probably get to 144 edges (i.e., the last number in --pool_res) , but it will also depend on the genus (shapes with high genus not able to be collapsed as much) and also the number of boundary edges. Are the meshes watertight? What is the genus?

With these values I get the error. If I understand your comment correctly, I shouldn't reduce the minimum resolution of pooling below 30-40% of my initial number of edges (which would let me with around 150 edges). Would this be the error?

yes.

Edit: I'd like to get a lower resolution intermediate layer, that's why I'm reducing it so much. Is there a possible workaround for this (in case the error is caused by the small number of edges)?

We perform a clean edges when encountering "bad" (valence 3) vertices. The issue is that these "valence 3" vertices cause many edges to be unable to be collapsed. See this illustration, on the left is a valid edge collapse, on the right is a collapse which results in a non-manifold geometry: image When we encounter such a vertex we clean it. You could search for these more often and clean them more often -- it will enable the mesh to be able to be collapsed further.

claell commented 4 years ago

@ranahanocka I think I run into a similar issue. I have an own dataset, I want to analyze. I already used your blender script to simplify the face numbers. I used 600 as target number of faces.

To make the code work then, I had to set ninput_edges to about 2000, much below that I was running into #18.

I also tried different combinations for pool_res, however, I still get the error (a bit different from the one posted above):

Traceback (most recent call last):
  File "train.py", line 30, in <module>
    model.optimize_parameters()
  File "/kaggle/working/MeshCNN/models/mesh_classifier.py", line 66, in optimize_parameters
    out = self.forward()
  File "/kaggle/working/MeshCNN/models/mesh_classifier.py", line 57, in forward
    out = self.net(self.edge_features, self.mesh)
  File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
    result = self.forward(*input, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py", line 150, in forward
    return self.module(*inputs[0], **kwargs[0])
  File "/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
    result = self.forward(*input, **kwargs)
  File "/kaggle/working/MeshCNN/models/networks.py", line 150, in forward
    x = getattr(self, 'pool{}'.format(i))(x, mesh)
  File "/kaggle/working/MeshCNN/models/layers/mesh_pool.py", line 21, in __call__
    return self.forward(fe, meshes)
  File "/kaggle/working/MeshCNN/models/layers/mesh_pool.py", line 34, in forward
    self.__pool_main(mesh_index)
  File "/kaggle/working/MeshCNN/models/layers/mesh_pool.py", line 50, in __pool_main
    value, edge_id = heappop(queue)
IndexError: index out of range
claell commented 4 years ago

Update: --pool_res 4000 2000 1500 1000 for example worked. Seems I still just had a too low resolution.

Unfortunately now I run into #46.

claell commented 4 years ago

After working around #46 setting slide_verts to 0, I am now facing the issue above again.

claell commented 4 years ago

Works now for me, I have used problematic input data before.

claell commented 4 years ago

Works for me now, I have used problematic input data before.

zhoujinhai commented 3 years ago

Hi @ismaelGomez87 ,

My meshes have 480 edges each. I could augment the resolution but not reduce it. I defined my --pool_res argument accordingly: --pool_res 240 120 60 \

That is rather aggressive pooling. You can probably get to 144 edges (i.e., the last number in --pool_res) , but it will also depend on the genus (shapes with high genus not able to be collapsed as much) and also the number of boundary edges. Are the meshes watertight? What is the genus?

With these values I get the error. If I understand your comment correctly, I shouldn't reduce the minimum resolution of pooling below 30-40% of my initial number of edges (which would let me with around 150 edges). Would this be the error?

yes.

Edit: I'd like to get a lower resolution intermediate layer, that's why I'm reducing it so much. Is there a possible workaround for this (in case the error is caused by the small number of edges)?

We perform a clean edges when encountering "bad" (valence 3) vertices. The issue is that these "valence 3" vertices cause many edges to be unable to be collapsed. See this illustration, on the left is a valid edge collapse, on the right is a collapse which results in a non-manifold geometry: image When we encounter such a vertex we clean it. You could search for these more often and clean them more often -- it will enable the mesh to be able to be collapsed further.

I had the same problem with the test. I have two test models with same faces. One test can get results, and the other can't!And I checked the model through meshLab, check Render>show non-manifold edges and also Render>show non-manifold vertices, Do you have any suggestions for this situation? Screenshot from 2020-12-16 16-46-25

1

Screenshot from 2020-12-16 16-35-49

2 Screenshot from 2020-12-16 16-33-10