XuyangBai / D3Feat

[TensorFlow] Official implementation of CVPR'20 oral paper - D3Feat: Joint Learning of Dense Detection and Description of 3D Local Features https://arxiv.org/abs/2003.03164
MIT License
259 stars 38 forks source link

Question about score for FCGF network #7

Closed SwagJ closed 4 years ago

SwagJ commented 4 years ago

Hi,

Thank you very much for your work. I tried to implement the detector of yours on FCGF because in your paper. It mentions that your detector will help FCGF performance. And during the training process, after a few iteration, the detect loss reaches 0, score drops to 0 as well. It is the same for positive loss. I was wondering do you come across the same problem for FCGF as well? I am looking forward to your reply. Thank you very much!

XuyangBai commented 4 years ago

Hi @SwagJ , Thanks for your interest in our work.

For our detector loss, it can be near 0 or even less than zero if the positive and negative are already well separated, but it can still give the correct gradient to the detection score. And it also happens in my experiments. However, the detection scores should not be all zeros because we are calculating the score by checking the local maximum and channel-wise maximum. Could you make it more clear about "score drops to 0 as well"? If I remember correctly, I haven't met this problem for FCGF. It is also weird to have positive loss drop to zero, and that should only happen when the distance between the positive pair are all below the positive margin. You may also print out the distance of positive pairs and negative pairs to see how they changed? Experimentally, I observed that the triplet loss and contrastive loss are prone to collapse if the number of pairs or the safe radius is not set properly.

And there are also some details you may want to check when using the detector:

  1. Before calculating the saliency score, we first perform a point cloud level normalization to improve the convergence and avoid NAN value.
  2. The hard selection strategy is only used during testing to emulate the non-maximum suppression and avoid having the keypoints lie too close to each other, and during training the detection scores should not have many zeros.
  3. The local neighborhood we used to calculate the detection score is the radius neighborhood in the first layer of convolution, which has the radius equals 2.5 * voxel_size. So you need to change this value according to your voxel size since D3Feat are using different voxel size with FCGF.

Best, Xuyang

SwagJ commented 4 years ago

Dear Xuyang,

Thank you very much about your reply. First about my FCGF setting. safe radius is set to be 0.1m. num of positive pair sampled are 256. batch_size =2. local neighborhood search radius is set to be 0.075m. and about the local neighborhood extraction strategy. I used a mask to mask out the points out of safe radius and later in hardest negative distance generation. I set the neg distance in the safe radius to be the max of all neg pair distance * 100. This should gives the hardest negative right?

  1. I have checked NaN, which doesn't happen.
  2. Yes, I have computed score and formed detector loss as stated in your paper. However, for memory reduction purpose, I calculated only positive pair score in train time, since in your paper, only the score at between positive pair are used. And the score here are actually the sum of (SAi, and SBi)
  3. I used 0.05m as my voxel size for FCGF ` 05/26 22:01:02 Epoch: 1, LR: [0.1] 05/26 22:01:06 Train Epoch: 1 [0/1829], Current Loss: 3.477e-01 Pos: 2.243 Neg: 4.852 L_desc: 7.095, L_det: -4.313, score0: 3.316, score1: 3.331 Data time: 2.3753, Train time: 1.3938, Iter time: 3.7690 05/26 22:04:12 Train Epoch: 1 [40/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3605, Train time: 1.2818, Iter time: 4.6422 05/26 22:06:59 Train Epoch: 1 [80/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9870, Train time: 1.1843, Iter time: 4.1714 05/26 22:09:57 Train Epoch: 1 [120/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2396, Train time: 1.2180, Iter time: 4.4576 05/26 22:13:32 Train Epoch: 1 [160/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.9856, Train time: 1.3880, Iter time: 5.3736 05/26 22:16:17 Train Epoch: 1 [200/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9571, Train time: 1.1685, Iter time: 4.1257 05/26 22:19:11 Train Epoch: 1 [240/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1268, Train time: 1.2224, Iter time: 4.3492 05/26 22:22:16 Train Epoch: 1 [280/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3702, Train time: 1.2469, Iter time: 4.6171 05/26 22:25:19 Train Epoch: 1 [320/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3173, Train time: 1.2456, Iter time: 4.5630 05/26 22:28:03 Train Epoch: 1 [360/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9415, Train time: 1.1602, Iter time: 4.1016 05/26 22:30:58 Train Epoch: 1 [400/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1818, Train time: 1.1994, Iter time: 4.3812 05/26 22:34:00 Train Epoch: 1 [440/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2864, Train time: 1.2671, Iter time: 4.5535 05/26 22:37:16 Train Epoch: 1 [480/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.5936, Train time: 1.3025, Iter time: 4.8961 05/26 22:40:22 Train Epoch: 1 [520/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3503, Train time: 1.2989, Iter time: 4.6491 05/26 22:43:06 Train Epoch: 1 [560/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9239, Train time: 1.1796, Iter time: 4.1035 05/26 22:46:05 Train Epoch: 1 [600/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2340, Train time: 1.2424, Iter time: 4.4764 05/26 22:49:03 Train Epoch: 1 [640/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2370, Train time: 1.2077, Iter time: 4.4447 05/26 22:52:57 Train Epoch: 1 [680/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 4.3171, Train time: 1.5280, Iter time: 5.8451 05/26 22:56:30 Train Epoch: 1 [720/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.9442, Train time: 1.3870, Iter time: 5.3312 05/26 22:59:23 Train Epoch: 1 [760/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1128, Train time: 1.1962, Iter time: 4.3089 05/26 23:02:33 Train Epoch: 1 [800/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.4315, Train time: 1.3231, Iter time: 4.7546 05/26 23:05:24 Train Epoch: 1 [840/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0828, Train time: 1.1953, Iter time: 4.2781 05/26 23:08:41 Train Epoch: 1 [880/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.5419, Train time: 1.3907, Iter time: 4.9326 05/26 23:11:28 Train Epoch: 1 [920/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9961, Train time: 1.1756, Iter time: 4.1717 05/26 23:14:25 Train Epoch: 1 [960/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1709, Train time: 1.2508, Iter time: 4.4216 05/26 23:18:22 Train Epoch: 1 [1000/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 4.5887, Train time: 1.3325, Iter time: 5.9212 05/26 23:21:23 Train Epoch: 1 [1040/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2691, Train time: 1.2564, Iter time: 4.5256 05/26 23:24:32 Train Epoch: 1 [1080/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.4115, Train time: 1.3001, Iter time: 4.7116 05/26 23:27:22 Train Epoch: 1 [1120/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0657, Train time: 1.1921, Iter time: 4.2578 05/26 23:30:21 Train Epoch: 1 [1160/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1917, Train time: 1.2844, Iter time: 4.4761 05/26 23:33:17 Train Epoch: 1 [1200/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1911, Train time: 1.2132, Iter time: 4.4043 05/26 23:36:31 Train Epoch: 1 [1240/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.5475, Train time: 1.2935, Iter time: 4.8409 05/26 23:39:45 Train Epoch: 1 [1280/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.5430, Train time: 1.2972, Iter time: 4.8402 05/26 23:42:33 Train Epoch: 1 [1320/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0418, Train time: 1.1673, Iter time: 4.2091 05/26 23:45:34 Train Epoch: 1 [1360/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2645, Train time: 1.2505, Iter time: 4.5150 05/26 23:48:31 Train Epoch: 1 [1400/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2109, Train time: 1.2147, Iter time: 4.4256 05/26 23:51:28 Train Epoch: 1 [1440/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2030, Train time: 1.2226, Iter time: 4.4255 05/26 23:54:12 Train Epoch: 1 [1480/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9333, Train time: 1.1675, Iter time: 4.1008 05/26 23:56:57 Train Epoch: 1 [1520/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9510, Train time: 1.1716, Iter time: 4.1225 05/26 23:59:50 Train Epoch: 1 [1560/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1104, Train time: 1.2089, Iter time: 4.3193 05/27 00:02:28 Train Epoch: 1 [1600/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.8053, Train time: 1.1434, Iter time: 3.9487 05/27 00:05:25 Train Epoch: 1 [1640/1829], Current Loss: 6.991e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -0.008, score0: 0.000, score1: 0.005 Data time: 3.2346, Train time: 1.2090, Iter time: 4.4435 05/27 00:08:10 Train Epoch: 1 [1680/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9297, Train time: 1.1793, Iter time: 4.1091 05/27 00:11:01 Train Epoch: 1 [1720/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0912, Train time: 1.2010, Iter time: 4.2922 05/27 00:14:01 Train Epoch: 1 [1760/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.2726, Train time: 1.2260, Iter time: 4.4986 05/27 00:17:03 Train Epoch: 1 [1800/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3086, Train time: 1.2323, Iter time: 4.5409 05/27 00:19:16 Saving checkpoint: ./outputs/ThreeDMatchPairDataset-v0.05/DetectandDescribeLossTrainer/ThreeDSmoothNet/modelnout32/lr_rate_1e-1/pos_sample_256/batch_4/checkpoint_1.pth ... 05/27 00:19:16 Epoch: 2, LR: [0.09801] 05/27 00:19:20 Train Epoch: 2 [0/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.7887, Train time: 1.1820, Iter time: 3.9707 05/27 00:22:26 Train Epoch: 2 [40/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.3544, Train time: 1.3042, Iter time: 4.6586 05/27 00:25:22 Train Epoch: 2 [80/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.1561, Train time: 1.2269, Iter time: 4.3830 05/27 00:28:11 Train Epoch: 2 [120/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0366, Train time: 1.1940, Iter time: 4.2306 05/27 00:30:57 Train Epoch: 2 [160/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9601, Train time: 1.1775, Iter time: 4.1376 05/27 00:33:47 Train Epoch: 2 [200/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0719, Train time: 1.1963, Iter time: 4.2682 05/27 00:37:34 Train Epoch: 2 [240/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 4.2109, Train time: 1.4657, Iter time: 5.6766 05/27 00:40:46 Train Epoch: 2 [280/1829], Current Loss: 6.990e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -0.008, score0: 0.000, score1: 0.005 Data time: 3.4452, Train time: 1.3333, Iter time: 4.7785 05/27 00:43:29 Train Epoch: 2 [320/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 2.9126, Train time: 1.1618, Iter time: 4.0744 05/27 00:46:17 Train Epoch: 2 [360/1829], Current Loss: 7.000e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: 0.000, score0: 0.000, score1: 0.000 Data time: 3.0033, Train time: 1.2107, Iter time: 4.2140 05/27 00:49:00 Train Epoch: 2 [400/1829], Current Loss: 6.991e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -0.008, score0: 0.000, score1: 0.005 Data time: 2.9047, Train time: 1.1545, Iter time: 4.0592 05/27 00:51:54 Train Epoch: 2 [440/1829], Current Loss: 6.884e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -0.093, score0: 0.061, score1: 0.006 Data time: 3.1297, Train time: 1.2304, Iter time: 4.3601 05/27 00:54:56 Train Epoch: 2 [480/1829], Current Loss: 6.590e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -0.328, score0: 0.095, score1: 0.139 Data time: 3.3129, Train time: 1.2272, Iter time: 4.5401 05/27 00:57:51 Train Epoch: 2 [520/1829], Current Loss: -1.157e-01 Pos: 0.062 Neg: 5.600 L_desc: 5.662, L_det: -6.588, score0: 2.466, score1: 2.289 Data time: 3.1495, Train time: 1.2307, Iter time: 4.3802 05/27 01:00:26 Train Epoch: 2 [560/1829], Current Loss: -2.641e-01 Pos: 0.027 Neg: 5.600 L_desc: 5.627, L_det: -7.740, score0: 2.779, score1: 2.774 Data time: 2.7721, Train time: 1.1106, Iter time: 3.8828 05/27 01:03:10 Train Epoch: 2 [600/1829], Current Loss: -2.733e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.786, score0: 2.771, score1: 2.791 Data time: 2.9271, Train time: 1.1785, Iter time: 4.1056 05/27 01:06:46 Train Epoch: 2 [640/1829], Current Loss: -2.694e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.756, score0: 2.773, score1: 2.768 Data time: 3.9876, Train time: 1.4060, Iter time: 5.3936 05/27 01:09:35 Train Epoch: 2 [680/1829], Current Loss: -2.736e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.789, score0: 2.784, score1: 2.779 Data time: 3.0269, Train time: 1.1964, Iter time: 4.2232 05/27 01:12:38 Train Epoch: 2 [720/1829], Current Loss: -2.721e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.777, score0: 2.777, score1: 2.778 Data time: 3.2900, Train time: 1.2836, Iter time: 4.5736 05/27 01:15:38 Train Epoch: 2 [760/1829], Current Loss: -2.730e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.784, score0: 2.780, score1: 2.781 Data time: 3.2497, Train time: 1.2420, Iter time: 4.4917 05/27 01:18:27 Train Epoch: 2 [800/1829], Current Loss: -2.699e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.759, score0: 2.771, score1: 2.771 Data time: 3.0347, Train time: 1.1919, Iter time: 4.2266 05/27 01:21:18 Train Epoch: 2 [840/1829], Current Loss: -2.705e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.764, score0: 2.777, score1: 2.769 Data time: 3.0668, Train time: 1.1972, Iter time: 4.2640 05/27 01:24:14 Train Epoch: 2 [880/1829], Current Loss: -2.709e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.768, score0: 2.773, score1: 2.776 Data time: 3.2102, Train time: 1.2055, Iter time: 4.4157 05/27 01:27:23 Train Epoch: 2 [920/1829], Current Loss: -2.720e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.777, score0: 2.776, score1: 2.779 Data time: 3.4432, Train time: 1.2658, Iter time: 4.7090 05/27 01:30:12 Train Epoch: 2 [960/1829], Current Loss: -2.735e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.788, score0: 2.783, score1: 2.781 Data time: 3.0411, Train time: 1.1850, Iter time: 4.2261 05/27 01:33:33 Train Epoch: 2 [1000/1829], Current Loss: -2.701e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.761, score0: 2.763, score1: 2.780 Data time: 3.7009, Train time: 1.3375, Iter time: 5.0384 05/27 01:36:29 Train Epoch: 2 [1040/1829], Current Loss: -2.715e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.772, score0: 2.775, score1: 2.776 Data time: 3.1609, Train time: 1.2235, Iter time: 4.3844 05/27 01:39:48 Train Epoch: 2 [1080/1829], Current Loss: -2.737e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.790, score0: 2.783, score1: 2.781 Data time: 3.6405, Train time: 1.3282, Iter time: 4.9687 05/27 01:43:11 Train Epoch: 2 [1120/1829], Current Loss: -2.716e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.773, score0: 2.778, score1: 2.774 Data time: 3.7849, Train time: 1.3059, Iter time: 5.0908 05/27 01:45:59 Train Epoch: 2 [1160/1829], Current Loss: -2.717e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.774, score0: 2.776, score1: 2.777 Data time: 3.0059, Train time: 1.1917, Iter time: 4.1976 05/27 01:48:50 Train Epoch: 2 [1200/1829], Current Loss: -2.722e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.778, score0: 2.778, score1: 2.779 Data time: 3.0791, Train time: 1.1948, Iter time: 4.2739 05/27 01:51:49 Train Epoch: 2 [1240/1829], Current Loss: -2.700e-01 Pos: 0.002 Neg: 5.600 L_desc: 5.602, L_det: -7.762, score0: 2.777, score1: 2.769 Data time: 3.2209, Train time: 1.2387, Iter time: 4.4596 05/27 01:54:37 Train Epoch: 2 [1280/1829], Current Loss: -2.733e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.787, score0: 2.779, score1: 2.783 Data time: 3.0117, Train time: 1.2004, Iter time: 4.2121 05/27 01:57:22 Train Epoch: 2 [1320/1829], Current Loss: -2.719e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.775, score0: 2.783, score1: 2.771 Data time: 2.9463, Train time: 1.1747, Iter time: 4.1210 05/27 02:00:24 Train Epoch: 2 [1360/1829], Current Loss: -2.734e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.788, score0: 2.786, score1: 2.777 Data time: 3.2956, Train time: 1.2603, Iter time: 4.5559 05/27 02:03:18 Train Epoch: 2 [1400/1829], Current Loss: -2.696e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.757, score0: 2.773, score1: 2.768 Data time: 3.1630, Train time: 1.1915, Iter time: 4.3545 05/27 02:05:59 Train Epoch: 2 [1440/1829], Current Loss: -2.688e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.752, score0: 2.763, score1: 2.775 Data time: 2.8683, Train time: 1.1437, Iter time: 4.0121 05/27 02:09:02 Train Epoch: 2 [1480/1829], Current Loss: -2.724e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.779, score0: 2.773, score1: 2.783 Data time: 3.3108, Train time: 1.2599, Iter time: 4.5708 05/27 02:11:46 Train Epoch: 2 [1520/1829], Current Loss: -2.730e-01 Pos: 0.000 Neg: 5.600 L_desc: 5.600, L_det: -7.784, score0: 2.767, score1: 2.793 Data time: 2.9208, Train time: 1.1845, Iter time: 4.1053 05/27 02:15:23 Train Epoch: 2 [1560/1829], Current Loss: -2.737e-01 Pos: 0.001 Neg: 5.600 L_desc: 5.601, L_det: -7.790, score0: 2.779, score1: 2.787 Data time: 4.0441, Train time: 1.3796, Iter time: 5.4237

` This is the example of terminal printing. The pos loss and neg loss here is the same as that in your paper. I will print some pos distance and neg distance to check this result.

Is this result so far looks normal?

XuyangBai commented 4 years ago

Hi @SwagJ

  1. I suggest using 0.05 * 2.5 = 0.125 as your neighborhood radius if the voxel size is 0.05. As for the safe radius, I remember that FCGF mixed the random triplets with hardest-negative triplets to avoid collapse which is similar with the safe radius mechanism in D3Feat, so I just used their method for generating negative pairs.
  2. There are some unnormal results for your log file: First, if you are using the hardest-contrastive loss in FCGF, then the L_desc should not be 5.6 since the distance between two L2-normalized features is bounded in [0,2]. I wonder do you use L2-normalization for the feature descriptor? Second, the Pos (represent pos loss?) is always 0 which means all the distance of positive pairs are all below your pos margin. I suspect your network collapse and all the features converge to a single point (See discussion in FCGF paper after Eq.6) so that d_pos and d_neg are all zero. You may first try the original setting of FCGF and add the detector loss after you are sure that the description part is OK. Third, do the score0 and score1 represent the mean score of the pos pair? It looks larger than what I usually get, and I think you should either use the L2-normalized feature to calculate the score or do the normalization step as in here.

Hope that helps.

SwagJ commented 4 years ago

HI @XuyangBai ,

Thanks for your help. In the previous log, there's actually an error in logging the info of metrics. I forgot to take mean over a batch. So below is the new log example. In this log, pos and neg stands for positive distance and negative distance. Still model seems to collapse to one point? About using FCGF default setting, I tried with hardest contrastive loss using hashing. Theoretically, it indeed will be the same as the mining technique used in your paper. However, not every positive has a negative after hashing. So that's why I adopted your mining strategy. Feature L2 Norm is performed as well.

05/27 14:53:37 Epoch: 1, LR: [0.1] 05/27 14:53:42 Train Epoch: 1 [0/1829], Current Loss: 3.333e-01 Pos: 0.648 Neg: 0.426 L_desc: 1.763, L_det: -1.096, score0: 0.828, score1: 0.824 Data time: 3.3038, Train time: 1.7985, Iter time: 5.1023 05/27 14:56:20 Train Epoch: 1 [40/1829], Current Loss: 2.641e-01 Pos: 0.004 Neg: 0.000 L_desc: 1.400, L_det: -0.872, score0: 0.296, score1: 0.327 Data time: 2.8060, Train time: 1.1594, Iter time: 3.9654 05/27 14:59:08 Train Epoch: 1 [80/1829], Current Loss: -2.430e-01 Pos: 0.058 Neg: 0.001 L_desc: 1.415, L_det: -1.901, score0: 0.700, score1: 0.674 Data time: 3.0012, Train time: 1.1977, Iter time: 4.1989 05/27 15:02:04 Train Epoch: 1 [120/1829], Current Loss: -2.550e-01 Pos: 0.059 Neg: 0.000 L_desc: 1.418, L_det: -1.927, score0: 0.694, score1: 0.699 Data time: 3.1910, Train time: 1.2043, Iter time: 4.3954 05/27 15:05:22 Train Epoch: 1 [160/1829], Current Loss: -2.564e-01 Pos: 0.055 Neg: 0.000 L_desc: 1.414, L_det: -1.926, score0: 0.693, score1: 0.696 Data time: 3.6394, Train time: 1.3075, Iter time: 4.9469 05/27 15:08:21 Train Epoch: 1 [200/1829], Current Loss: -2.623e-01 Pos: 0.050 Neg: 0.000 L_desc: 1.411, L_det: -1.936, score0: 0.700, score1: 0.693 Data time: 3.2288, Train time: 1.2343, Iter time: 4.4631 05/27 15:11:03 Train Epoch: 1 [240/1829], Current Loss: -2.573e-01 Pos: 0.053 Neg: 0.001 L_desc: 1.414, L_det: -1.929, score0: 0.700, score1: 0.692 Data time: 2.9040, Train time: 1.1544, Iter time: 4.0584 05/27 15:13:59 Train Epoch: 1 [280/1829], Current Loss: -2.724e-01 Pos: 0.036 Neg: 0.000 L_desc: 1.405, L_det: -1.950, score0: 0.699, score1: 0.699 Data time: 3.1726, Train time: 1.2150, Iter time: 4.3876 05/27 15:17:06 Train Epoch: 1 [320/1829], Current Loss: -2.610e-01 Pos: 0.036 Neg: 0.000 L_desc: 1.406, L_det: -1.928, score0: 0.686, score1: 0.696 Data time: 3.3895, Train time: 1.2847, Iter time: 4.6742 05/27 15:20:13 Train Epoch: 1 [360/1829], Current Loss: -2.690e-01 Pos: 0.024 Neg: 0.000 L_desc: 1.401, L_det: -1.939, score0: 0.692, score1: 0.694 Data time: 3.3783, Train time: 1.3069, Iter time: 4.6852 05/27 15:23:55 Train Epoch: 1 [400/1829], Current Loss: -2.675e-01 Pos: 0.033 Neg: 0.000 L_desc: 1.404, L_det: -1.939, score0: 0.696, score1: 0.693 Data time: 4.1206, Train time: 1.4355, Iter time: 5.5561 05/27 15:27:01 Train Epoch: 1 [440/1829], Current Loss: -2.683e-01 Pos: 0.026 Neg: 0.000 L_desc: 1.403, L_det: -1.940, score0: 0.694, score1: 0.695 Data time: 3.4033, Train time: 1.2302, Iter time: 4.6334 05/27 15:30:02 Train Epoch: 1 [480/1829], Current Loss: -2.699e-01 Pos: 0.024 Neg: 0.000 L_desc: 1.401, L_det: -1.941, score0: 0.692, score1: 0.696 Data time: 3.2863, Train time: 1.2300, Iter time: 4.5163 05/27 15:33:10 Train Epoch: 1 [520/1829], Current Loss: -2.683e-01 Pos: 0.026 Neg: 0.000 L_desc: 1.402, L_det: -1.938, score0: 0.694, score1: 0.693 Data time: 3.4521, Train time: 1.2622, Iter time: 4.7144

XuyangBai commented 4 years ago

@SwagJ Yes, the model seems to collapse as all your pairs are having 0 distances. Theoretically, the number of positive pair and negative pair can be different for the contrastive loss but I was assuming each positive pair corresponds with a negative pair in D3Feat. And if you are using the same mining strategy as mine, I suggest you reduce the number of pos and neg pair (from 256 to 64) because it is harder for the network to distinguish the hardest-negative mined from 256 pairs. I also have met this problem when training D3Feat, so I keep the keypts_num to 64 when using the contrastive loss with the hardest mining. Another suggestion is you may try the circle loss as I mentioned in the README, which gives better convergence than contrastive loss.

SwagJ commented 4 years ago

Thank you very much for your reply. I will reduce correspondance number to be 64 and increases neighborhood radius. Again, thank you very much for your help!

SwagJ commented 4 years ago

Hi @XuyangBai ,

I followed your suggestions. Increasing local neighborhood radius and reduce num of correspondance 64, even 32 doesn't help. Then I tried FCGF's original Hardest Contrastive Loss with pos pairs that has no negative mining equipped with all negatives' avg after mining. With this Contrastive loss stands alone, pos distance won't drop to 0 also the neg distance. However, after I adding scoring and detector loss, it starts to collapse. Do you have any idea? Also, about your implementation: Do you applied ground truth GT in sampling correspondence between frames that overlap more than 30%?

XuyangBai commented 4 years ago

Hi @SwagJ

I picked the correspondence by first finding the point cloud pairs with more than 30% overlapping, then sampling the anchor points from one point cloud, finally find the corresponding points in another point cloud under the GT transformation. It is hard to find out the reason without more information. Could you provide your log file or training curve? When training D3Feat, I did find at the beginning both the pos distance and neg distance go small (but never to zero), and then go larger in the later stage. And this happened both with and without the detector loss.

SwagJ commented 4 years ago

Hi @XuyangBai ,

The log is included. And the pos and neg distance are not zero after printing more digits. However, it doesn't change that much. Is the model still collapse to one point? [log.txt](https://github.com/XuyangBai/D3Feat/files/4701546/log.txt)

XuyangBai commented 4 years ago

@SwagJ Yes, from the log file I think the network still collapses to one point. Some potential reasons:

  1. The L_desc = 1.95 after first several iterations. If you are using the default setting of FCGF (pos margin 0.1, neg margin 1.4), then the L_desc should be about 1.4 if the pos and neg distance are near zero. And I am confused about Then I tried FCGF's original Hardest Contrastive Loss with pos pairs that has no negative mining equipped with all negatives' avg after mining. Could you please explain more detail about how you pick the negative pairs? Maybe you can copy your code of contrastive_hardest_negative_loss function or other related code here.
  2. The idea of our detector loss is to use the current feature matching result to evaluate the discriminativeness of each correspondence and provide guidance on the gradient. In your log, the pos distance is always larger than the neg distance, so the detector loss may not going to work properly if the feature matching results are almost wrong. Another thing is the value of detector loss is also weird, since your d_pos and d_neg are all about zero, the value should not be -2.9 if you look at the Eq.15. Usually in D3Feat, we have L_det around -0.25 when the network converge. Did you normalize the detector loss by the number of correspondences?
SwagJ commented 4 years ago

Hi @XuyangBai ,

Thank you for your reply. the code is shown below, where the neighbor0 and neighbor1 is the neighboring point index of all points in frame 0 and frame 1. num_neighbor0 and num_neighbor1 is an array containing total number of neighboring points of all points.

` input args: F0, F1: features N*32

neighbor0,neighbor1: neighboring point index of all points N*20, in preprocessingset max to be 20 and for those with less than 20, pack it with len(F0) or len(F1) to make it (1,20)

num_neighbor0, num_neighbor1: total number of neighboring point in of all points in frame0 and frame1.

Generate negative pairs

N0, N1 = len(F0), len(F1)
N_pos_pairs = len(positive_pairs)
hash_seed = max(N0, N1)
sel0 = np.random.choice(N0, min(N0, num_hn_samples), replace=False)
sel1 = np.random.choice(N1, min(N1, num_hn_samples), replace=False)

# generate positive sampling index
if N_pos_pairs > num_pos:
  pos_sel = np.random.choice(N_pos_pairs, num_pos, replace=False)
  sample_pos_pairs = positive_pairs[pos_sel]
else:
  sample_pos_pairs = positive_pairs
  num_pos = N_pos_pairs

# generate negative sampling index
subF0, subF1 = F0[sel0], F1[sel1]
# sample pos
pos_ind0 = sample_pos_pairs[:, 0].long()
pos_ind1 = sample_pos_pairs[:, 1].long()
posF0, posF1 = F0[pos_ind0], F1[pos_ind1]
# sample negatives
D01 = pdist(posF0, subF1, dist_type='L2')
D10 = pdist(posF1, subF0, dist_type='L2')
D01min, D01ind = D01.min(1)
D10min, D10ind = D10.min(1)

# search for hardest negatives
if not isinstance(positive_pairs, np.ndarray):
  positive_pairs = np.array(positive_pairs, dtype=np.int64)

pos_keys = _hash(positive_pairs, hash_seed)

D01ind = sel1[D01ind.cpu().numpy()]
D10ind = sel0[D10ind.cpu().numpy()]
neg_keys0 = _hash([pos_ind0.numpy(), D01ind], hash_seed)
neg_keys1 = _hash([D10ind, pos_ind1.numpy()], hash_seed)

mask0 = torch.from_numpy(
    np.logical_not(np.isin(neg_keys0, pos_keys, assume_unique=False)))
mask1 = torch.from_numpy(
    np.logical_not(np.isin(neg_keys1, pos_keys, assume_unique=False)))

#print("mask0 shape:",np.where(mask0==False))
#print("mask1 shape:",np.where(mask1==False))
#print("D01min shape:",D01min.shape)
#print("D10min shape:",D10min.shape)
D01min_avg = D01min.mean()
D10min_avg = D10min.mean()
D01min[mask0==False] = D01min_avg
D10min[mask1==False] = D10min_avg

pos_loss = F.relu((posF0 - posF1).pow(2).sum(1) - self.pos_thresh)
neg_loss0 = F.relu(self.neg_thresh - D01min).pow(2)
neg_loss1 = F.relu(self.neg_thresh - D10min).pow(2)
neg_loss = (neg_loss0 + neg_loss1) / 2

pos_dist = (posF0 - posF1).pow(2).sum(1) 
neg_dist = (D01min + D10min)/2

#print("mask0 shape:",np.where(mask0==False))
#print("mask1 shape:",np.where(mask1==False))
# calculate alpha score

shadow_F = torch.zeros(1,32).float().to(self.device)
F0 = torch.cat((F0,shadow_F),dim=0)
F1 = torch.cat((F1,shadow_F),dim=0)

neighbor_feat0 = F0[neighbor0[pos_ind0],:]
neighbor_feat1 = F1[neighbor1[pos_ind1],:]

neighbor_avg0 = torch.sum(neighbor_feat0,dim=1) / torch.cat([num_neighbor0[pos_ind0].unsqueeze(1)]*self.model_n_out,dim=1) #sub,32
neighbor_avg1 = torch.sum(neighbor_feat1,dim=1) / torch.cat([num_neighbor1[pos_ind1].unsqueeze(1)]*self.model_n_out,dim=1) #sub,32
saliency0 = F0[pos_ind0] - neighbor_avg0
saliency1 = F1[pos_ind1] - neighbor_avg1

alpha0 = F.softplus(saliency0) # N0,32
alpha1 = F.softplus(saliency1) # N1,32
if torch.isnan(alpha0).any() == True:
  print("Nan at alpha0")

#beta score
max0_beta,_ = torch.max(posF0,dim=1)
max1_beta,_ = torch.max(posF1,dim=1)
#print("min max0_beta:",max0_beta.min())
if torch.isnan(max0_beta).any() == True:
  print("Nan at max0_beta")

if torch.isnan(torch.stack([max0_beta]*self.model_n_out,dim=1)).any() == True:
  print("Nan at stacked_max0_beta")
#print("stacked max0_beta:",torch.stack([max0_beta]*self.model_n_out,dim=1).shape)
#print("posF0:",posF0.shape)
beta0 = posF0 / torch.stack([max0_beta + 1e-7]*self.model_n_out,dim=1)
beta1 = posF1 / torch.stack([max1_beta + 1e-7]*self.model_n_out,dim=1)
if torch.isnan(beta0).any() == True:
  print("Nan at beta0")

score0,_ = torch.max(alpha0 * beta0,dim=1)
score1,_ = torch.max(alpha1 * beta1,dim=1)

L_desc = pos_loss.mean() + self.neg_weight * neg_loss.mean() 
L_det = ((pos_loss - neg_loss0)*(score0 + score1)).mean()

# if torch.isnan(L_det).any() == True:
#   print("Nan at L_det")
#   print("current N0 N1:",N0,N1)
# if torch.isnan(L_desc).any() == True:
#   print("Nan at L_desc")
# if torch.isnan(score0).any() == True:
#   print("Nan at score0")
# if torch.isnan(score1).any() == True:
#   print("Nan at score1")
# if torch.isnan(pos_loss).any() == True:
#   print("Nan at pos_loss")
# if torch.isnan(neg_loss).any() == True:
#   print("Nan at neg_loss")

return (posF0 - posF1).pow(2).sum(1).mean(), neg_dist.mean(), L_desc, L_det ,score0.mean(),score1.mean()

` I think maybe the problem is that L_desc uses neg_loss, which is the avg of neg_loss0 and neg_loss1 , while for L_det, it only uses neg_loss0. As you can see, I did take normalization over detector loss by the num of correspondance, although I only calculated score at correspondence instead of all points.

XuyangBai commented 4 years ago

Hi @SwagJ Just some quick findings: 1. How do you decide the max neighborhood size to be 20? It might be too small in my experience since the point cloud in 3DMatch is quite dense. Maybe use 40 instead, although it might not be the main reason of the model collapse. 2. Your pos_dist is the L2-squared distance while the neg_dist is not squared? 3. I have tried using both row-wise and col-wise neg loss and it has a negligible impact on the final performance, so I think it probably not because of neg_loss0 and neg_loss1 and you can have a try. 4. And I just find the formulation of L_det is not correct. It should be L_det = ((pos_dist - neg_dist) * (score0 + score1)).mean(). In Eq.15 of our paper, we are using the pos distance and neg distance instead of pos loss and neg loss to measure the discriminative of each correspondence. If d_pos < d_neg, it indicates this correspondence can be correctly matched by nearest neighbor search, so we encourage the score to be higher.

You may check these problems and have a try?

SwagJ commented 4 years ago

Hi @XuyangBai,

Thank you for pointing out the issue on L_det. After the correcting this and increasing number of neighborhood. The model seems not collapsing. However, i do have a small question. In the early epoch of training, the model seems the total loss ,L_det and L_desc are not minimized a lot. On the contrary, they seems to dampening a lot. Is this normal? The log is attached. Thank you very much. log.txt

XuyangBai commented 4 years ago

Hi @SwagJ Glad to hear that. And the log file looks normal to me so far. You may print out more metrics such as the feature matching recall per epoch or the accuracy (percentage of d_pos < d_neg) as what I did in D3Feat training to monitor the training process. Good luck.

SwagJ commented 4 years ago

Hi @XuyangBai,

Just a question about descriptor quality during training. I added the FCGF evaluation protocol during training. And to my super is that the descriptor FMR is decreasing every epoch after epoch 1. The log is attached. In addition, as you can see, indeed L_det is minimized to around 0.1. However, it is not further minimized. The setting for this is with batch_size of 1 and momentum to be 0.8. I have also tried with batch_size of 3 and momentum of 0.98. However, it gives a worse result. Is this supposed to happen? Given the information you provided earlier, the pos_dist and neg_dist is minimized to almost 0 in early stage of training. However, it doesn't seems to be true in my case. I am looking forward to your reply. Again, thank you very much for your help! log.txt

XuyangBai commented 4 years ago

Hi @SwagJ

I said both the pos distance and neg distance go small (but never to zero) at the beginning of the training and will become larger as the training, and from your log the pos distance and neg distance indeed go to about 0.5 and 0.3 in the first several iterations, respectively. The absolute value might be smaller than my experience because of different sampling strategies (e.g the distance threshold to define a positive pair) and I think that's not the problem. Also, the batch_size and momentum should not be the reason, I use batch_size of 1 and default momentum of FCGF.

One thing I find unnormal is the acc. If you calculate the accuracy as the percentage of d_pos < d_neg, then it is weird because the accuracy of your network is mostly kept at 0%, which means the d_pos is always larger than d_neg. From the Pos and Neg, it is also showing that Pos > Neg. And obviously the network can not achieve an FMR with 81.2% with accuracy near zero (as you cannot even find the correct matching in 64 candidates). So I think there might be some other bugs in your code. And in my experiments, the descriptor loss is more critical for the whole learning process as well as the descriptor quality, and the detector loss affects the score calculation more and has a minor effect on the descriptor. So I still recommend you to train the network with descriptor loss only first, and add the detector loss after you confirmed that the network is working.

SwagJ commented 4 years ago

Hi @XuyangBai ,

The network is the original FCGF and the evaluation strategy is using 5000 sampling points, which is true for original FCGF hardest contrastive trainer. As you can see, at initialization time, the FMR has already achieved 41.7%. I will do a double check on my code though. Thank you again for your help.

SwagJ commented 4 years ago

Hi @XuyangBai ,

Sorry to bother you again. After I did a check on my code and your implement. I have a question about your descriptor loss. In your paper, you states that d_neg should be min(L2_dist(d_Ai - d_Bj)) with s.t. L2_dist(Bi - Bj) > safe radius R, which is what I implemented. However, in your descriptor loss here: https://github.com/XuyangBai/D3Feat/blob/3577482efbc5154affcd734e16b0d10a73560e37/utils/loss.py#L108. The descriptor loss doesn't involve any safe radius. Also, in your circle loss, I noticed that the you indeed used safe radius. However, it seems that the set of Bj in your equation is the points that in correspondence list from fragment Q instead of all points in fragment Q? Do I understand this correctly? Thank you very much

XuyangBai commented 4 years ago

Hi @SwagJ Thanks for your check. Actually that is a mistake by me. I used to check the safe radius and update the distance matrix before the desc_loss function so the code you referred will only find the negative outsides the safe radius (as you may see here, the distance matrix is modified to eliminate the effect of the false negative.) but I mixed it up when I cleaned up my code. I will fix it later. The safe radius is vital for the contrastive loss to converge and avoid collapsing.

SwagJ commented 4 years ago

HI @XuyangBai , Thank you very much for your reply. So, in the negative pair (Ai,Bj) here, Bj comes from all points in point cloud fragment or the points in B that is in sampled correspondence(Ai,Bi), i.e, all the Bi, Bj in eq.12 of your paper are points in the sampled correspondence right?

XuyangBai commented 4 years ago

Hi @SwagJ, Bj comes from the sampled correspondence.

SwagJ commented 4 years ago

Thank you very much for your reply. I see where the problem is in my implementation.

SwagJ commented 4 years ago

Hi @XuyangBai ,

Is that possible for you to provide some setting for FCGF training? Do you still remember the settings you use for FCGF, like voxel size, safe radius and max number of neighborhood? Also, do you still remember what the loss of detector and descriptor like when model converges? Thank you very much.

XuyangBai commented 4 years ago

Hi @SwagJ Like I said before, I use the default setting of FCGF (2.5cm voxel size, and no safe radius because FCGF mixed the random triplets with hardest-negative triplets to avoid collapse which is similar with the safe radius mechanism, max number of the neighborhood = 40). Could you provide an email address? Maybe I can send you the config file and the trainer.py. But I am afraid I didn't save the training loggings.

SwagJ commented 4 years ago

Thank you very much. I have sent a email to your github registration email address.

houyongkuo commented 2 years ago

你好@SwagJ就像我之前说的,我使用 FCGF 的默认设置(2.5 厘米体素大小,并且没有安全半径,因为FCGF mixed the random triplets with hardest-negative triplets to avoid collapse which is similar with the safe radius mechanism, 邻域的最大数量 = 40)。你能提供一个电子邮件地址吗?也许我可以把配置文件和trainer.py. 但恐怕我没有保存训练记录。

Hello, could you provide me with a copy, my email: houyongkuo@gmail.com, thank you.