Upload 37 files
Browse files- .gitattributes +10 -0
- contact_graspnet_train_and_test/checkpoint.txt +6 -0
- contact_graspnet_train_and_test/config.yaml +192 -0
- contact_graspnet_train_and_test/contact_graspnet.py +438 -0
- contact_graspnet_train_and_test/log_train.txt +0 -0
- contact_graspnet_train_and_test/model.ckpt-143887.data-00000-of-00001 +3 -0
- contact_graspnet_train_and_test/model.ckpt-143887.index +0 -0
- contact_graspnet_train_and_test/train.py +224 -0
- scene_2048_bs3_rad2_32/checkpoint +6 -0
- scene_2048_bs3_rad2_32/config.yaml +186 -0
- scene_2048_bs3_rad2_32/model.ckpt-144144.data-00000-of-00001 +3 -0
- scene_2048_bs3_rad2_32/model.ckpt-144144.index +0 -0
- scene_test_2048_bs3_hor_sigma_001/checkpoint +6 -0
- scene_test_2048_bs3_hor_sigma_001/config.yaml +187 -0
- scene_test_2048_bs3_hor_sigma_001/log_train.txt +0 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-144144.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-144144.index +0 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-45045.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-45045.index +0 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-54054.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-54054.index +0 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-72072.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_001/model.ckpt-72072.index +0 -0
- scene_test_2048_bs3_hor_sigma_001/pointnet2_grasp_direct.py +437 -0
- scene_test_2048_bs3_hor_sigma_001/train_grasp_direct.py +292 -0
- scene_test_2048_bs3_hor_sigma_0025/checkpoint +6 -0
- scene_test_2048_bs3_hor_sigma_0025/config.yaml +188 -0
- scene_test_2048_bs3_hor_sigma_0025/log_train.txt +0 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-144144.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-144144.index +0 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-45045.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-45045.index +0 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-54054.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-54054.index +0 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-72072.data-00000-of-00001 +3 -0
- scene_test_2048_bs3_hor_sigma_0025/model.ckpt-72072.index +0 -0
- scene_test_2048_bs3_hor_sigma_0025/pointnet2_grasp_direct.py +437 -0
- scene_test_2048_bs3_hor_sigma_0025/train_grasp_direct.py +292 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,13 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
contact_graspnet_train_and_test/model.ckpt-143887.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
scene_2048_bs3_rad2_32/model.ckpt-144144.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
scene_test_2048_bs3_hor_sigma_001/model.ckpt-144144.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
scene_test_2048_bs3_hor_sigma_001/model.ckpt-45045.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
scene_test_2048_bs3_hor_sigma_001/model.ckpt-54054.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
scene_test_2048_bs3_hor_sigma_001/model.ckpt-72072.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-144144.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-45045.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-54054.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-72072.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
contact_graspnet_train_and_test/checkpoint.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_checkpoint_path: "model.ckpt-143887"
|
| 2 |
+
all_model_checkpoint_paths: "model.ckpt-107915"
|
| 3 |
+
all_model_checkpoint_paths: "model.ckpt-116908"
|
| 4 |
+
all_model_checkpoint_paths: "model.ckpt-125901"
|
| 5 |
+
all_model_checkpoint_paths: "model.ckpt-134894"
|
| 6 |
+
all_model_checkpoint_paths: "model.ckpt-143887"
|
contact_graspnet_train_and_test/config.yaml
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
DATA:
|
| 2 |
+
classes: null
|
| 3 |
+
data_path: /volume/pekdat/datasets/public/acronym/original
|
| 4 |
+
depth_augm:
|
| 5 |
+
clip: 0.005
|
| 6 |
+
gaussian_kernel: 0
|
| 7 |
+
sigma: 0.001
|
| 8 |
+
gripper_width: 0.08
|
| 9 |
+
input_normals: false
|
| 10 |
+
intrinsics: kinect_azure
|
| 11 |
+
labels:
|
| 12 |
+
bin_weights:
|
| 13 |
+
- 0.16652107
|
| 14 |
+
- 0.21488856
|
| 15 |
+
- 0.37031708
|
| 16 |
+
- 0.55618503
|
| 17 |
+
- 0.75124664
|
| 18 |
+
- 0.93943357
|
| 19 |
+
- 1.07824539
|
| 20 |
+
- 1.19423112
|
| 21 |
+
- 1.55731375
|
| 22 |
+
- 3.17161779
|
| 23 |
+
filter_z: true
|
| 24 |
+
k: 1
|
| 25 |
+
max_radius: 0.005
|
| 26 |
+
num_neg_contacts: 0
|
| 27 |
+
num_pos_contacts: 8000
|
| 28 |
+
offset_bins:
|
| 29 |
+
- 0
|
| 30 |
+
- 0.00794435329
|
| 31 |
+
- 0.0158887021
|
| 32 |
+
- 0.0238330509
|
| 33 |
+
- 0.0317773996
|
| 34 |
+
- 0.0397217484
|
| 35 |
+
- 0.0476660972
|
| 36 |
+
- 0.055610446
|
| 37 |
+
- 0.0635547948
|
| 38 |
+
- 0.0714991435
|
| 39 |
+
- 0.08
|
| 40 |
+
to_gpu: false
|
| 41 |
+
z_val: -0.1
|
| 42 |
+
ndataset_points: 20000
|
| 43 |
+
num_point: 2048
|
| 44 |
+
num_test_scenes: 1000
|
| 45 |
+
pc_augm:
|
| 46 |
+
clip: 0.005
|
| 47 |
+
occlusion_dropout_rate: 0.0
|
| 48 |
+
occlusion_nclusters: 0
|
| 49 |
+
sigma: 0.0
|
| 50 |
+
raw_num_points: 20000
|
| 51 |
+
scene_contacts_path: scene_contacts_train_test
|
| 52 |
+
train_and_test: false
|
| 53 |
+
train_on_scenes: true
|
| 54 |
+
use_farthest_point: false
|
| 55 |
+
use_uniform_quaternions: false
|
| 56 |
+
view_sphere:
|
| 57 |
+
distance_range:
|
| 58 |
+
- 0.9
|
| 59 |
+
- 1.3
|
| 60 |
+
elevation:
|
| 61 |
+
- 30
|
| 62 |
+
- 150
|
| 63 |
+
LOSS:
|
| 64 |
+
min_geom_loss_divisor: 1.0
|
| 65 |
+
offset_loss_type: sigmoid_cross_entropy
|
| 66 |
+
too_small_offset_pred_bin_factor: 0
|
| 67 |
+
topk_confidence: 512
|
| 68 |
+
MODEL:
|
| 69 |
+
asymmetric_model: true
|
| 70 |
+
bin_offsets: true
|
| 71 |
+
dir_vec_length_offset: false
|
| 72 |
+
grasp_conf_head:
|
| 73 |
+
conv1d: 1
|
| 74 |
+
dropout_keep: 0.5
|
| 75 |
+
grasp_dir_head:
|
| 76 |
+
conv1d: 3
|
| 77 |
+
dropout_keep: 0.7
|
| 78 |
+
joint_head:
|
| 79 |
+
conv1d: 4
|
| 80 |
+
dropout_keep: 0.7
|
| 81 |
+
joint_heads: false
|
| 82 |
+
model: contact_graspnet
|
| 83 |
+
pointnet_fp_modules:
|
| 84 |
+
- mlp:
|
| 85 |
+
- 256
|
| 86 |
+
- 256
|
| 87 |
+
- mlp:
|
| 88 |
+
- 256
|
| 89 |
+
- 128
|
| 90 |
+
- mlp:
|
| 91 |
+
- 128
|
| 92 |
+
- 128
|
| 93 |
+
- 128
|
| 94 |
+
pointnet_sa_module:
|
| 95 |
+
group_all: true
|
| 96 |
+
mlp:
|
| 97 |
+
- 256
|
| 98 |
+
- 512
|
| 99 |
+
- 1024
|
| 100 |
+
pointnet_sa_modules_msg:
|
| 101 |
+
- mlp_list:
|
| 102 |
+
- - 32
|
| 103 |
+
- 32
|
| 104 |
+
- 64
|
| 105 |
+
- - 64
|
| 106 |
+
- 64
|
| 107 |
+
- 128
|
| 108 |
+
- - 64
|
| 109 |
+
- 96
|
| 110 |
+
- 128
|
| 111 |
+
npoint: 2048
|
| 112 |
+
nsample_list:
|
| 113 |
+
- 32
|
| 114 |
+
- 64
|
| 115 |
+
- 128
|
| 116 |
+
radius_list:
|
| 117 |
+
- 0.02
|
| 118 |
+
- 0.04
|
| 119 |
+
- 0.08
|
| 120 |
+
- mlp_list:
|
| 121 |
+
- - 64
|
| 122 |
+
- 64
|
| 123 |
+
- 128
|
| 124 |
+
- - 128
|
| 125 |
+
- 128
|
| 126 |
+
- 256
|
| 127 |
+
- - 128
|
| 128 |
+
- 128
|
| 129 |
+
- 256
|
| 130 |
+
npoint: 512
|
| 131 |
+
nsample_list:
|
| 132 |
+
- 64
|
| 133 |
+
- 64
|
| 134 |
+
- 128
|
| 135 |
+
radius_list:
|
| 136 |
+
- 0.04
|
| 137 |
+
- 0.08
|
| 138 |
+
- 0.16
|
| 139 |
+
- mlp_list:
|
| 140 |
+
- - 64
|
| 141 |
+
- 64
|
| 142 |
+
- 128
|
| 143 |
+
- - 128
|
| 144 |
+
- 128
|
| 145 |
+
- 256
|
| 146 |
+
- - 128
|
| 147 |
+
- 128
|
| 148 |
+
- 256
|
| 149 |
+
npoint: 128
|
| 150 |
+
nsample_list:
|
| 151 |
+
- 64
|
| 152 |
+
- 64
|
| 153 |
+
- 128
|
| 154 |
+
radius_list:
|
| 155 |
+
- 0.08
|
| 156 |
+
- 0.16
|
| 157 |
+
- 0.32
|
| 158 |
+
pred_contact_approach: false
|
| 159 |
+
pred_contact_base: false
|
| 160 |
+
pred_contact_offset: true
|
| 161 |
+
pred_contact_success: true
|
| 162 |
+
pred_grasps_adds: true
|
| 163 |
+
pred_grasps_adds_gt2pred: false
|
| 164 |
+
OPTIMIZER:
|
| 165 |
+
adds_gt2pred_loss_weight: 1
|
| 166 |
+
adds_loss_weight: 10
|
| 167 |
+
approach_cosine_loss_weight: 1
|
| 168 |
+
batch_size: 3
|
| 169 |
+
bn_decay_clip: 0.99
|
| 170 |
+
bn_decay_decay_rate: 0.5
|
| 171 |
+
bn_decay_decay_step: 200000
|
| 172 |
+
bn_init_decay: 0.5
|
| 173 |
+
decay_rate: 0.7
|
| 174 |
+
decay_step: 200000
|
| 175 |
+
dir_cosine_loss_weight: 1
|
| 176 |
+
learning_rate: 0.001
|
| 177 |
+
max_epoch: 16
|
| 178 |
+
momentum: 0.9
|
| 179 |
+
offset_loss_weight: 1
|
| 180 |
+
optimizer: adam
|
| 181 |
+
score_ce_loss_weight: 1
|
| 182 |
+
TEST:
|
| 183 |
+
allow_zero_margin: 0
|
| 184 |
+
bin_vals: max
|
| 185 |
+
center_to_tip: 0.0
|
| 186 |
+
extra_opening: 0.005
|
| 187 |
+
filter_thres: 0.0001
|
| 188 |
+
first_thres: 0.23
|
| 189 |
+
max_farthest_points: 150
|
| 190 |
+
num_samples: 200
|
| 191 |
+
second_thres: 0.19
|
| 192 |
+
with_replacement: false
|
contact_graspnet_train_and_test/contact_graspnet.py
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import numpy as np
|
| 4 |
+
import tensorflow.compat.v1 as tf
|
| 5 |
+
tf.disable_eager_execution()
|
| 6 |
+
TF2 = True
|
| 7 |
+
|
| 8 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 9 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 10 |
+
|
| 11 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 12 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 13 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2'))
|
| 14 |
+
|
| 15 |
+
import tf_util
|
| 16 |
+
from pointnet_util import pointnet_sa_module, pointnet_fp_module, pointnet_sa_module_msg
|
| 17 |
+
from tf_sampling import farthest_point_sample, gather_point
|
| 18 |
+
from tf_grouping import query_ball_point, group_point, knn_point
|
| 19 |
+
|
| 20 |
+
import mesh_utils
|
| 21 |
+
|
| 22 |
+
def placeholder_inputs(batch_size, num_input_points=20000, input_normals=False):
|
| 23 |
+
"""
|
| 24 |
+
Creates placeholders for input pointclouds, scene indices, camera poses and training/eval mode
|
| 25 |
+
|
| 26 |
+
Arguments:
|
| 27 |
+
batch_size {int} -- batch size
|
| 28 |
+
num_input_points {int} -- number of input points to the network (default: 20000)
|
| 29 |
+
|
| 30 |
+
Keyword Arguments:
|
| 31 |
+
input_normals {bool} -- whether to use normals as input (default: {False})
|
| 32 |
+
|
| 33 |
+
Returns:
|
| 34 |
+
dict[str:tf.placeholder] -- dict of placeholders
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
pl_dict = {}
|
| 38 |
+
dim = 6 if input_normals else 3
|
| 39 |
+
pl_dict['pointclouds_pl'] = tf.placeholder(tf.float32, shape=(batch_size, num_input_points, dim))
|
| 40 |
+
pl_dict['scene_idx_pl'] = tf.placeholder(tf.int32, ())
|
| 41 |
+
pl_dict['cam_poses_pl'] = tf.placeholder(tf.float32, shape=(batch_size, 4, 4))
|
| 42 |
+
pl_dict['is_training_pl'] = tf.placeholder(tf.bool, shape=())
|
| 43 |
+
|
| 44 |
+
return pl_dict
|
| 45 |
+
|
| 46 |
+
def get_bin_vals(global_config):
|
| 47 |
+
"""
|
| 48 |
+
Creates bin values for grasping widths according to bounds defined in config
|
| 49 |
+
|
| 50 |
+
Arguments:
|
| 51 |
+
global_config {dict} -- config
|
| 52 |
+
|
| 53 |
+
Returns:
|
| 54 |
+
tf.constant -- bin value tensor
|
| 55 |
+
"""
|
| 56 |
+
bins_bounds = np.array(global_config['DATA']['labels']['offset_bins'])
|
| 57 |
+
if global_config['TEST']['bin_vals'] == 'max':
|
| 58 |
+
bin_vals = (bins_bounds[1:] + bins_bounds[:-1])/2
|
| 59 |
+
bin_vals[-1] = bins_bounds[-1]
|
| 60 |
+
elif global_config['TEST']['bin_vals'] == 'mean':
|
| 61 |
+
bin_vals = bins_bounds[1:]
|
| 62 |
+
else:
|
| 63 |
+
raise NotImplementedError
|
| 64 |
+
|
| 65 |
+
if not global_config['TEST']['allow_zero_margin']:
|
| 66 |
+
bin_vals = np.minimum(bin_vals, global_config['DATA']['gripper_width']-global_config['TEST']['extra_opening'])
|
| 67 |
+
|
| 68 |
+
tf_bin_vals = tf.constant(bin_vals, tf.float32)
|
| 69 |
+
return tf_bin_vals
|
| 70 |
+
|
| 71 |
+
def get_model(point_cloud, is_training, global_config, bn_decay=None):
|
| 72 |
+
"""
|
| 73 |
+
Contact-GraspNet model consisting of a PointNet++ backbone and multiple output heads
|
| 74 |
+
|
| 75 |
+
Arguments:
|
| 76 |
+
point_cloud {tf.placeholder} -- batch of point clouds
|
| 77 |
+
is_training {bool} -- train or eval mode
|
| 78 |
+
global_config {dict} -- config
|
| 79 |
+
|
| 80 |
+
Keyword Arguments:
|
| 81 |
+
bn_decay {tf.variable} -- batch norm decay (default: {None})
|
| 82 |
+
|
| 83 |
+
Returns:
|
| 84 |
+
[dict] -- endpoints of the network
|
| 85 |
+
"""
|
| 86 |
+
|
| 87 |
+
model_config = global_config['MODEL']
|
| 88 |
+
data_config = global_config['DATA']
|
| 89 |
+
|
| 90 |
+
radius_list_0 = model_config['pointnet_sa_modules_msg'][0]['radius_list']
|
| 91 |
+
radius_list_1 = model_config['pointnet_sa_modules_msg'][1]['radius_list']
|
| 92 |
+
radius_list_2 = model_config['pointnet_sa_modules_msg'][2]['radius_list']
|
| 93 |
+
|
| 94 |
+
nsample_list_0 = model_config['pointnet_sa_modules_msg'][0]['nsample_list']
|
| 95 |
+
nsample_list_1 = model_config['pointnet_sa_modules_msg'][1]['nsample_list']
|
| 96 |
+
nsample_list_2 = model_config['pointnet_sa_modules_msg'][2]['nsample_list']
|
| 97 |
+
|
| 98 |
+
mlp_list_0 = model_config['pointnet_sa_modules_msg'][0]['mlp_list']
|
| 99 |
+
mlp_list_1 = model_config['pointnet_sa_modules_msg'][1]['mlp_list']
|
| 100 |
+
mlp_list_2 = model_config['pointnet_sa_modules_msg'][2]['mlp_list']
|
| 101 |
+
|
| 102 |
+
npoint_0 = model_config['pointnet_sa_modules_msg'][0]['npoint']
|
| 103 |
+
npoint_1 = model_config['pointnet_sa_modules_msg'][1]['npoint']
|
| 104 |
+
npoint_2 = model_config['pointnet_sa_modules_msg'][2]['npoint']
|
| 105 |
+
|
| 106 |
+
fp_mlp_0 = model_config['pointnet_fp_modules'][0]['mlp']
|
| 107 |
+
fp_mlp_1 = model_config['pointnet_fp_modules'][1]['mlp']
|
| 108 |
+
fp_mlp_2 = model_config['pointnet_fp_modules'][2]['mlp']
|
| 109 |
+
|
| 110 |
+
input_normals = data_config['input_normals']
|
| 111 |
+
offset_bins = data_config['labels']['offset_bins']
|
| 112 |
+
joint_heads = model_config['joint_heads']
|
| 113 |
+
|
| 114 |
+
# expensive, rather use random only
|
| 115 |
+
if 'raw_num_points' in data_config and data_config['raw_num_points'] != data_config['ndataset_points']:
|
| 116 |
+
point_cloud = gather_point(point_cloud, farthest_point_sample(data_config['ndataset_points'], point_cloud))
|
| 117 |
+
|
| 118 |
+
end_points = {}
|
| 119 |
+
l0_xyz = tf.slice(point_cloud, [0,0,0], [-1,-1,3])
|
| 120 |
+
l0_points = tf.slice(point_cloud, [0,0,3], [-1,-1,3]) if input_normals else None
|
| 121 |
+
|
| 122 |
+
# Set abstraction layers
|
| 123 |
+
l1_xyz, l1_points = pointnet_sa_module_msg(l0_xyz, l0_points, npoint_0, radius_list_0, nsample_list_0, mlp_list_0, is_training, bn_decay, scope='layer1')
|
| 124 |
+
l2_xyz, l2_points = pointnet_sa_module_msg(l1_xyz, l1_points, npoint_1, radius_list_1, nsample_list_1,mlp_list_1, is_training, bn_decay, scope='layer2')
|
| 125 |
+
|
| 126 |
+
if 'asymmetric_model' in model_config and model_config['asymmetric_model']:
|
| 127 |
+
l3_xyz, l3_points = pointnet_sa_module_msg(l2_xyz, l2_points, npoint_2, radius_list_2, nsample_list_2,mlp_list_2, is_training, bn_decay, scope='layer3')
|
| 128 |
+
l4_xyz, l4_points, _ = pointnet_sa_module(l3_xyz, l3_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer4')
|
| 129 |
+
|
| 130 |
+
# Feature Propagation layers
|
| 131 |
+
l3_points = pointnet_fp_module(l3_xyz, l4_xyz, l3_points, l4_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 132 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 133 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 134 |
+
|
| 135 |
+
l0_points = l1_points
|
| 136 |
+
pred_points = l1_xyz
|
| 137 |
+
else:
|
| 138 |
+
l3_xyz, l3_points, _ = pointnet_sa_module(l2_xyz, l2_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer3')
|
| 139 |
+
|
| 140 |
+
# Feature Propagation layers
|
| 141 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 142 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 143 |
+
l0_points = tf.concat([l0_xyz, l0_points],axis=-1) if input_normals else l0_xyz
|
| 144 |
+
l0_points = pointnet_fp_module(l0_xyz, l1_xyz, l0_points, l1_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 145 |
+
pred_points = l0_xyz
|
| 146 |
+
|
| 147 |
+
if joint_heads:
|
| 148 |
+
head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 149 |
+
head = tf_util.dropout(head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 150 |
+
head = tf_util.conv1d(head, 4, 1, padding='VALID', activation_fn=None, scope='fc2')
|
| 151 |
+
grasp_dir_head = tf.slice(head, [0,0,0], [-1,-1,3])
|
| 152 |
+
grasp_dir_head = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 153 |
+
binary_seg_head = tf.slice(head, [0,0,3], [-1,-1,1])
|
| 154 |
+
else:
|
| 155 |
+
# Head for grasp direction
|
| 156 |
+
grasp_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 157 |
+
grasp_dir_head = tf_util.dropout(grasp_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 158 |
+
grasp_dir_head = tf_util.conv1d(grasp_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3')
|
| 159 |
+
grasp_dir_head_normed = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 160 |
+
|
| 161 |
+
# Head for grasp approach
|
| 162 |
+
approach_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_app', bn_decay=bn_decay)
|
| 163 |
+
approach_dir_head = tf_util.dropout(approach_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1_app')
|
| 164 |
+
approach_dir_head = tf_util.conv1d(approach_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3_app')
|
| 165 |
+
approach_dir_head_orthog = tf.math.l2_normalize(approach_dir_head - tf.reduce_sum(tf.multiply(grasp_dir_head_normed, approach_dir_head), axis=2, keepdims=True)*grasp_dir_head_normed, axis=2)
|
| 166 |
+
|
| 167 |
+
# Head for grasp width
|
| 168 |
+
if model_config['dir_vec_length_offset']:
|
| 169 |
+
grasp_offset_head = tf.norm(grasp_dir_head, axis=2, keepdims=True)
|
| 170 |
+
elif model_config['bin_offsets']:
|
| 171 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 172 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, len(offset_bins)-1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 173 |
+
else:
|
| 174 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 175 |
+
grasp_offset_head = tf_util.dropout(grasp_offset_head, keep_prob=0.7, is_training=is_training, scope='dp1_off')
|
| 176 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 177 |
+
|
| 178 |
+
# Head for contact points
|
| 179 |
+
binary_seg_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_seg', bn_decay=bn_decay)
|
| 180 |
+
binary_seg_head = tf_util.dropout(binary_seg_head, keep_prob=0.5, is_training=is_training, scope='dp1_seg')
|
| 181 |
+
binary_seg_head = tf_util.conv1d(binary_seg_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_seg')
|
| 182 |
+
|
| 183 |
+
end_points['grasp_dir_head'] = grasp_dir_head_normed
|
| 184 |
+
end_points['binary_seg_head'] = binary_seg_head
|
| 185 |
+
end_points['binary_seg_pred'] = tf.math.sigmoid(binary_seg_head)
|
| 186 |
+
end_points['grasp_offset_head'] = grasp_offset_head
|
| 187 |
+
end_points['grasp_offset_pred'] = tf.math.sigmoid(grasp_offset_head) if model_config['bin_offsets'] else grasp_offset_head
|
| 188 |
+
end_points['approach_dir_head'] = approach_dir_head_orthog
|
| 189 |
+
end_points['pred_points'] = pred_points
|
| 190 |
+
|
| 191 |
+
return end_points
|
| 192 |
+
|
| 193 |
+
def build_6d_grasp(approach_dirs, base_dirs, contact_pts, thickness, use_tf=False, gripper_depth = 0.1034):
|
| 194 |
+
"""
|
| 195 |
+
Build 6-DoF grasps + width from point-wise network predictions
|
| 196 |
+
|
| 197 |
+
Arguments:
|
| 198 |
+
approach_dirs {np.ndarray/tf.tensor} -- Nx3 approach direction vectors
|
| 199 |
+
base_dirs {np.ndarray/tf.tensor} -- Nx3 base direction vectors
|
| 200 |
+
contact_pts {np.ndarray/tf.tensor} -- Nx3 contact points
|
| 201 |
+
thickness {np.ndarray/tf.tensor} -- Nx1 grasp width
|
| 202 |
+
|
| 203 |
+
Keyword Arguments:
|
| 204 |
+
use_tf {bool} -- whether inputs and outputs are tf tensors (default: {False})
|
| 205 |
+
gripper_depth {float} -- distance from gripper coordinate frame to gripper baseline in m (default: {0.1034})
|
| 206 |
+
|
| 207 |
+
Returns:
|
| 208 |
+
np.ndarray -- Nx4x4 grasp poses in camera coordinates
|
| 209 |
+
"""
|
| 210 |
+
if use_tf:
|
| 211 |
+
grasps_R = tf.stack([base_dirs, tf.linalg.cross(approach_dirs,base_dirs),approach_dirs], axis=3)
|
| 212 |
+
grasps_t = contact_pts + tf.expand_dims(thickness,2)/2 * base_dirs - gripper_depth * approach_dirs
|
| 213 |
+
ones = tf.ones((contact_pts.shape[0], contact_pts.shape[1], 1, 1), dtype=tf.float32)
|
| 214 |
+
zeros = tf.zeros((contact_pts.shape[0], contact_pts.shape[1], 1, 3), dtype=tf.float32)
|
| 215 |
+
homog_vec = tf.concat([zeros, ones], axis=3)
|
| 216 |
+
grasps = tf.concat([tf.concat([grasps_R, tf.expand_dims(grasps_t, 3)], axis=3), homog_vec], axis=2)
|
| 217 |
+
else:
|
| 218 |
+
grasps = []
|
| 219 |
+
for i in range(len(contact_pts)):
|
| 220 |
+
grasp = np.eye(4)
|
| 221 |
+
|
| 222 |
+
grasp[:3,0] = base_dirs[i] / np.linalg.norm(base_dirs[i])
|
| 223 |
+
grasp[:3,2] = approach_dirs[i] / np.linalg.norm(approach_dirs[i])
|
| 224 |
+
grasp_y = np.cross( grasp[:3,2],grasp[:3,0])
|
| 225 |
+
grasp[:3,1] = grasp_y / np.linalg.norm(grasp_y)
|
| 226 |
+
# base_gripper xyz = contact + thickness / 2 * baseline_dir - gripper_d * approach_dir
|
| 227 |
+
grasp[:3,3] = contact_pts[i] + thickness[i] / 2 * grasp[:3,0] - gripper_depth * grasp[:3,2]
|
| 228 |
+
# grasp[0,3] = finger_width
|
| 229 |
+
grasps.append(grasp)
|
| 230 |
+
grasps = np.array(grasps)
|
| 231 |
+
|
| 232 |
+
return grasps
|
| 233 |
+
|
| 234 |
+
def get_losses(pointclouds_pl, end_points, dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam, global_config):
|
| 235 |
+
"""
|
| 236 |
+
Computes loss terms from pointclouds, network predictions and labels
|
| 237 |
+
|
| 238 |
+
Arguments:
|
| 239 |
+
pointclouds_pl {tf.placeholder} -- bxNx3 input point clouds
|
| 240 |
+
end_points {dict[str:tf.variable]} -- endpoints of the network containing predictions
|
| 241 |
+
dir_labels_pc_cam {tf.variable} -- base direction labels in camera coordinates (bxNx3)
|
| 242 |
+
offset_labels_pc {tf.variable} -- grasp width labels (bxNx1)
|
| 243 |
+
grasp_success_labels_pc {tf.variable} -- contact success labels (bxNx1)
|
| 244 |
+
approach_labels_pc_cam {tf.variable} -- approach direction labels in camera coordinates (bxNx3)
|
| 245 |
+
global_config {dict} -- config dict
|
| 246 |
+
|
| 247 |
+
Returns:
|
| 248 |
+
[dir_cosine_loss, bin_ce_loss, offset_loss, approach_cosine_loss, adds_loss,
|
| 249 |
+
adds_loss_gt2pred, gt_control_points, pred_control_points, pos_grasps_in_view] -- All losses (not all are used for training)
|
| 250 |
+
"""
|
| 251 |
+
|
| 252 |
+
grasp_dir_head = end_points['grasp_dir_head']
|
| 253 |
+
grasp_offset_head = end_points['grasp_offset_head']
|
| 254 |
+
approach_dir_head = end_points['approach_dir_head']
|
| 255 |
+
|
| 256 |
+
bin_weights = global_config['DATA']['labels']['bin_weights']
|
| 257 |
+
tf_bin_weights = tf.constant(bin_weights)
|
| 258 |
+
|
| 259 |
+
min_geom_loss_divisor = tf.constant(float(global_config['LOSS']['min_geom_loss_divisor'])) if 'min_geom_loss_divisor' in global_config['LOSS'] else tf.constant(1.)
|
| 260 |
+
pos_grasps_in_view = tf.math.maximum(tf.reduce_sum(grasp_success_labels_pc, axis=1), min_geom_loss_divisor)
|
| 261 |
+
|
| 262 |
+
### ADS Gripper PC Loss
|
| 263 |
+
if global_config['MODEL']['bin_offsets']:
|
| 264 |
+
thickness_pred = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(grasp_offset_head, axis=2), axis=2))
|
| 265 |
+
thickness_gt = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(offset_labels_pc, axis=2), axis=2))
|
| 266 |
+
else:
|
| 267 |
+
thickness_pred = grasp_offset_head[:,:,0]
|
| 268 |
+
thickness_gt = offset_labels_pc[:,:,0]
|
| 269 |
+
pred_grasps = build_6d_grasp(approach_dir_head, grasp_dir_head, pointclouds_pl, thickness_pred, use_tf=True) # b x num_point x 4 x 4
|
| 270 |
+
gt_grasps_proj = build_6d_grasp(approach_labels_pc_cam, dir_labels_pc_cam, pointclouds_pl, thickness_gt, use_tf=True) # b x num_point x 4 x 4
|
| 271 |
+
pos_gt_grasps_proj = tf.where(tf.broadcast_to(tf.expand_dims(tf.expand_dims(tf.cast(grasp_success_labels_pc, tf.bool),2),3), gt_grasps_proj.shape), gt_grasps_proj, tf.ones_like(gt_grasps_proj)*100000)
|
| 272 |
+
# pos_gt_grasps_proj = tf.reshape(pos_gt_grasps_proj, (global_config['OPTIMIZER']['batch_size'], -1, 4, 4))
|
| 273 |
+
|
| 274 |
+
gripper = mesh_utils.create_gripper('panda')
|
| 275 |
+
gripper_control_points = gripper.get_control_point_tensor(global_config['OPTIMIZER']['batch_size']) # b x 5 x 3
|
| 276 |
+
sym_gripper_control_points = gripper.get_control_point_tensor(global_config['OPTIMIZER']['batch_size'], symmetric=True)
|
| 277 |
+
|
| 278 |
+
gripper_control_points_homog = tf.concat([gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 279 |
+
sym_gripper_control_points_homog = tf.concat([sym_gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 280 |
+
|
| 281 |
+
# only use per point pred grasps but not per point gt grasps
|
| 282 |
+
control_points = tf.keras.backend.repeat_elements(tf.expand_dims(gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 283 |
+
sym_control_points = tf.keras.backend.repeat_elements(tf.expand_dims(sym_gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 284 |
+
pred_control_points = tf.matmul(control_points, tf.transpose(pred_grasps, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_point x 5 x 3
|
| 285 |
+
|
| 286 |
+
### Pred Grasp to GT Grasp ADD-S Loss
|
| 287 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 288 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 289 |
+
|
| 290 |
+
squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 291 |
+
sym_squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(sym_gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 292 |
+
|
| 293 |
+
# symmetric ADD-S
|
| 294 |
+
neg_squared_adds = -tf.concat([squared_add,sym_squared_add], axis=2) # b x num_point x 2num_pos_grasp_point
|
| 295 |
+
neg_squared_adds_k = tf.math.top_k(neg_squared_adds, k=1, sorted=False)[0] # b x num_point
|
| 296 |
+
# If any pos grasp exists
|
| 297 |
+
min_adds = tf.minimum(tf.reduce_sum(grasp_success_labels_pc, axis=1, keepdims=True), tf.ones_like(neg_squared_adds_k[:,:,0])) * tf.sqrt(-neg_squared_adds_k[:,:,0])#tf.minimum(tf.sqrt(-neg_squared_adds_k), tf.ones_like(neg_squared_adds_k)) # b x num_point
|
| 298 |
+
adds_loss = tf.reduce_mean(end_points['binary_seg_pred'][:,:,0] * min_adds)
|
| 299 |
+
|
| 300 |
+
### GT Grasp to pred Grasp ADD-S Loss
|
| 301 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 302 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 303 |
+
|
| 304 |
+
neg_squared_adds = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 305 |
+
neg_squared_adds_sym = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(sym_gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 306 |
+
|
| 307 |
+
neg_squared_adds_k_gt2pred, pred_grasp_idcs = tf.math.top_k(neg_squared_adds, k=1, sorted=False) # b x num_pos_grasp_point
|
| 308 |
+
neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs = tf.math.top_k(neg_squared_adds_sym, k=1, sorted=False) # b x num_pos_grasp_point
|
| 309 |
+
pred_grasp_idcs_joined = tf.where(neg_squared_adds_k_gt2pred<neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs, pred_grasp_idcs)
|
| 310 |
+
min_adds_gt2pred = tf.minimum(-neg_squared_adds_k_gt2pred, -neg_squared_adds_k_sym_gt2pred) # b x num_pos_grasp_point x 1
|
| 311 |
+
# min_adds_gt2pred = tf.math.exp(-min_adds_gt2pred)
|
| 312 |
+
masked_min_adds_gt2pred = tf.multiply(min_adds_gt2pred[:,:,0], grasp_success_labels_pc)
|
| 313 |
+
|
| 314 |
+
batch_idcs = tf.meshgrid(tf.range(pred_grasp_idcs_joined.shape[1]), tf.range(pred_grasp_idcs_joined.shape[0]))
|
| 315 |
+
gather_idcs = tf.stack((batch_idcs[1],pred_grasp_idcs_joined[:,:,0]), axis=2)
|
| 316 |
+
nearest_pred_grasp_confidence = tf.gather_nd(end_points['binary_seg_pred'][:,:,0], gather_idcs)
|
| 317 |
+
adds_loss_gt2pred = tf.reduce_mean(tf.reduce_sum(nearest_pred_grasp_confidence*masked_min_adds_gt2pred, axis=1) / pos_grasps_in_view)
|
| 318 |
+
|
| 319 |
+
### Grasp baseline Loss
|
| 320 |
+
cosine_distance = tf.constant(1.)-tf.reduce_sum(tf.multiply(dir_labels_pc_cam, grasp_dir_head),axis=2)
|
| 321 |
+
# only pass loss where we have labeled contacts near pc points
|
| 322 |
+
masked_cosine_loss = tf.multiply(cosine_distance, grasp_success_labels_pc)
|
| 323 |
+
dir_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_cosine_loss, axis=1) / pos_grasps_in_view)
|
| 324 |
+
|
| 325 |
+
### Grasp Approach Loss
|
| 326 |
+
approach_labels_orthog = tf.math.l2_normalize(approach_labels_pc_cam - tf.reduce_sum(tf.multiply(grasp_dir_head, approach_labels_pc_cam), axis=2, keepdims=True)*grasp_dir_head, axis=2)
|
| 327 |
+
cosine_distance_approach = tf.constant(1.)-tf.reduce_sum(tf.multiply(approach_labels_orthog, approach_dir_head), axis=2)
|
| 328 |
+
masked_approach_loss = tf.multiply(cosine_distance_approach, grasp_success_labels_pc)
|
| 329 |
+
approach_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_approach_loss, axis=1) / pos_grasps_in_view)
|
| 330 |
+
|
| 331 |
+
### Grasp Offset/Thickness Loss
|
| 332 |
+
if global_config['MODEL']['bin_offsets']:
|
| 333 |
+
if global_config['LOSS']['offset_loss_type'] == 'softmax_cross_entropy':
|
| 334 |
+
offset_loss = tf.losses.softmax_cross_entropy(offset_labels_pc, grasp_offset_head)
|
| 335 |
+
else:
|
| 336 |
+
offset_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=offset_labels_pc, logits=grasp_offset_head)
|
| 337 |
+
|
| 338 |
+
if 'too_small_offset_pred_bin_factor' in global_config['LOSS'] and global_config['LOSS']['too_small_offset_pred_bin_factor']:
|
| 339 |
+
too_small_offset_pred_bin_factor = tf.constant(global_config['LOSS']['too_small_offset_pred_bin_factor'], tf.float32)
|
| 340 |
+
collision_weight = tf.math.cumsum(offset_labels_pc, axis=2, reverse=True)*too_small_offset_pred_bin_factor + tf.constant(1.)
|
| 341 |
+
offset_loss = tf.multiply(collision_weight, offset_loss)
|
| 342 |
+
|
| 343 |
+
offset_loss = tf.reduce_mean(tf.multiply(tf.reshape(tf_bin_weights,(1,1,-1)), offset_loss),axis=2)
|
| 344 |
+
else:
|
| 345 |
+
offset_loss = (grasp_offset_head[:,:,0] - offset_labels_pc[:,:,0])**2
|
| 346 |
+
masked_offset_loss = tf.multiply(offset_loss, grasp_success_labels_pc)
|
| 347 |
+
offset_loss = tf.reduce_mean(tf.reduce_sum(masked_offset_loss, axis=1) / pos_grasps_in_view)
|
| 348 |
+
|
| 349 |
+
### Grasp Confidence Loss
|
| 350 |
+
bin_ce_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.expand_dims(grasp_success_labels_pc,axis=2), logits=end_points['binary_seg_head'])
|
| 351 |
+
if 'topk_confidence' in global_config['LOSS'] and global_config['LOSS']['topk_confidence']:
|
| 352 |
+
bin_ce_loss,_ = tf.math.top_k(tf.squeeze(bin_ce_loss), k=global_config['LOSS']['topk_confidence'])
|
| 353 |
+
bin_ce_loss = tf.reduce_mean(bin_ce_loss)
|
| 354 |
+
|
| 355 |
+
return dir_cosine_loss, bin_ce_loss, offset_loss, approach_cosine_loss, adds_loss, adds_loss_gt2pred
|
| 356 |
+
|
| 357 |
+
def multi_bin_labels(cont_labels, bin_boundaries):
|
| 358 |
+
"""
|
| 359 |
+
Computes binned grasp width labels from continous labels and bin boundaries
|
| 360 |
+
|
| 361 |
+
Arguments:
|
| 362 |
+
cont_labels {tf.Variable} -- continouos labels
|
| 363 |
+
bin_boundaries {list} -- bin boundary values
|
| 364 |
+
|
| 365 |
+
Returns:
|
| 366 |
+
tf.Variable -- one/multi hot bin labels
|
| 367 |
+
"""
|
| 368 |
+
bins = []
|
| 369 |
+
for b in range(len(bin_boundaries)-1):
|
| 370 |
+
bins.append(tf.math.logical_and(tf.greater_equal(cont_labels, bin_boundaries[b]), tf.less(cont_labels,bin_boundaries[b+1])))
|
| 371 |
+
multi_hot_labels = tf.concat(bins, axis=2)
|
| 372 |
+
multi_hot_labels = tf.cast(multi_hot_labels, tf.float32)
|
| 373 |
+
|
| 374 |
+
return multi_hot_labels
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
def compute_labels(pos_contact_pts_mesh, pos_contact_dirs_mesh, pos_contact_approaches_mesh, pos_finger_diffs, pc_cam_pl, camera_pose_pl, global_config):
|
| 378 |
+
"""
|
| 379 |
+
Project grasp labels defined on meshes onto rendered point cloud from a camera pose via nearest neighbor contacts within a maximum radius.
|
| 380 |
+
All points without nearby successful grasp contacts are considered negativ contact points.
|
| 381 |
+
|
| 382 |
+
Arguments:
|
| 383 |
+
pos_contact_pts_mesh {tf.constant} -- positive contact points on the mesh scene (Mx3)
|
| 384 |
+
pos_contact_dirs_mesh {tf.constant} -- respective contact base directions in the mesh scene (Mx3)
|
| 385 |
+
pos_contact_approaches_mesh {tf.constant} -- respective contact approach directions in the mesh scene (Mx3)
|
| 386 |
+
pos_finger_diffs {tf.constant} -- respective grasp widths in the mesh scene (Mx1)
|
| 387 |
+
pc_cam_pl {tf.placeholder} -- bxNx3 rendered point clouds
|
| 388 |
+
camera_pose_pl {tf.placeholder} -- bx4x4 camera poses
|
| 389 |
+
global_config {dict} -- global config
|
| 390 |
+
|
| 391 |
+
Returns:
|
| 392 |
+
[dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam] -- Per-point contact success labels and per-contact pose labels in rendered point cloud
|
| 393 |
+
"""
|
| 394 |
+
label_config = global_config['DATA']['labels']
|
| 395 |
+
model_config = global_config['MODEL']
|
| 396 |
+
|
| 397 |
+
nsample = label_config['k']
|
| 398 |
+
radius = label_config['max_radius']
|
| 399 |
+
filter_z = label_config['filter_z']
|
| 400 |
+
z_val = label_config['z_val']
|
| 401 |
+
|
| 402 |
+
xyz_cam = pc_cam_pl[:,:,:3]
|
| 403 |
+
pad_homog = tf.ones((xyz_cam.shape[0],xyz_cam.shape[1], 1))
|
| 404 |
+
pc_mesh = tf.matmul(tf.concat([xyz_cam, pad_homog], 2), tf.transpose(tf.linalg.inv(camera_pose_pl),perm=[0, 2, 1]))[:,:,:3]
|
| 405 |
+
|
| 406 |
+
contact_point_offsets_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_finger_diffs,0), pc_mesh.shape[0], axis=0)
|
| 407 |
+
|
| 408 |
+
pad_homog2 = tf.ones((pc_mesh.shape[0], pos_contact_dirs_mesh.shape[0], 1))
|
| 409 |
+
contact_point_dirs_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0)
|
| 410 |
+
contact_point_dirs_batch_cam = tf.matmul(contact_point_dirs_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 411 |
+
|
| 412 |
+
pos_contact_approaches_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_approaches_mesh,0), pc_mesh.shape[0], axis=0)
|
| 413 |
+
pos_contact_approaches_batch_cam = tf.matmul(pos_contact_approaches_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 414 |
+
|
| 415 |
+
contact_point_batch_mesh = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_pts_mesh,0), pc_mesh.shape[0], axis=0)
|
| 416 |
+
contact_point_batch_cam = tf.matmul(tf.concat([contact_point_batch_mesh, pad_homog2], 2), tf.transpose(camera_pose_pl, perm=[0, 2, 1]))[:,:,:3]
|
| 417 |
+
|
| 418 |
+
if filter_z:
|
| 419 |
+
dir_filter_passed = tf.keras.backend.repeat_elements(tf.math.greater(contact_point_dirs_batch_cam[:,:,2:3], tf.constant([z_val])), 3, axis=2)
|
| 420 |
+
contact_point_batch_mesh = tf.where(dir_filter_passed, contact_point_batch_mesh, tf.ones_like(contact_point_batch_mesh)*100000)
|
| 421 |
+
|
| 422 |
+
squared_dists_all = tf.reduce_sum((tf.expand_dims(contact_point_batch_cam,1)-tf.expand_dims(xyz_cam,2))**2,axis=3)
|
| 423 |
+
neg_squared_dists_k, close_contact_pt_idcs = tf.math.top_k(-squared_dists_all, k=nsample, sorted=False)
|
| 424 |
+
squared_dists_k = -neg_squared_dists_k
|
| 425 |
+
|
| 426 |
+
# Nearest neighbor mapping
|
| 427 |
+
grasp_success_labels_pc = tf.cast(tf.less(tf.reduce_mean(squared_dists_k, axis=2), radius*radius), tf.float32) # (batch_size, num_point)
|
| 428 |
+
|
| 429 |
+
grouped_dirs_pc_cam = group_point(contact_point_dirs_batch_cam, close_contact_pt_idcs)
|
| 430 |
+
grouped_approaches_pc_cam = group_point(pos_contact_approaches_batch_cam, close_contact_pt_idcs)
|
| 431 |
+
grouped_offsets = group_point(tf.expand_dims(contact_point_offsets_batch,2), close_contact_pt_idcs)
|
| 432 |
+
|
| 433 |
+
dir_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_dirs_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 434 |
+
approach_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_approaches_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 435 |
+
offset_labels_pc = tf.reduce_mean(grouped_offsets, axis=2)
|
| 436 |
+
|
| 437 |
+
return dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam
|
| 438 |
+
|
contact_graspnet_train_and_test/log_train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
contact_graspnet_train_and_test/model.ckpt-143887.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8b92cf08a978dee3d2316a2dae685c26eb506a5ce5ee5a14c0a3840c1ceeba0e
|
| 3 |
+
size 27961560
|
contact_graspnet_train_and_test/model.ckpt-143887.index
ADDED
|
Binary file (25.8 kB). View file
|
|
|
contact_graspnet_train_and_test/train.py
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from genericpath import exists
|
| 2 |
+
import os
|
| 3 |
+
import sys
|
| 4 |
+
import argparse
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
import numpy as np
|
| 7 |
+
import time
|
| 8 |
+
from tqdm import tqdm
|
| 9 |
+
|
| 10 |
+
CONTACT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 11 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 12 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 13 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 14 |
+
sys.path.append(os.path.join(ROOT_DIR))
|
| 15 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'models'))
|
| 16 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 17 |
+
|
| 18 |
+
# os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
| 19 |
+
# os.environ["CUDA_VISIBLE_DEVICES"] = "0"
|
| 20 |
+
import tensorflow.compat.v1 as tf
|
| 21 |
+
tf.disable_eager_execution()
|
| 22 |
+
TF2 = True
|
| 23 |
+
physical_devices = tf.config.experimental.list_physical_devices('GPU')
|
| 24 |
+
print(physical_devices)
|
| 25 |
+
tf.config.experimental.set_memory_growth(physical_devices[0], True)
|
| 26 |
+
|
| 27 |
+
import config_utils
|
| 28 |
+
from data import PointCloudReader, load_scene_contacts, center_pc_convert_cam
|
| 29 |
+
from summaries import build_summary_ops, build_file_writers
|
| 30 |
+
from tf_train_ops import load_labels_and_losses, build_train_op
|
| 31 |
+
from contact_grasp_estimator import GraspEstimator
|
| 32 |
+
|
| 33 |
+
def train(global_config, log_dir):
|
| 34 |
+
"""
|
| 35 |
+
Trains Contact-GraspNet
|
| 36 |
+
|
| 37 |
+
Arguments:
|
| 38 |
+
global_config {dict} -- config dict
|
| 39 |
+
log_dir {str} -- Checkpoint directory
|
| 40 |
+
"""
|
| 41 |
+
|
| 42 |
+
contact_infos = load_scene_contacts(global_config['DATA']['data_path'],
|
| 43 |
+
scene_contacts_path=global_config['DATA']['scene_contacts_path'])
|
| 44 |
+
|
| 45 |
+
num_train_samples = len(contact_infos)-global_config['DATA']['num_test_scenes']
|
| 46 |
+
num_test_samples = global_config['DATA']['num_test_scenes']
|
| 47 |
+
|
| 48 |
+
print('using %s meshes' % (num_train_samples + num_test_samples))
|
| 49 |
+
if 'train_and_test' in global_config['DATA'] and global_config['DATA']['train_and_test']:
|
| 50 |
+
num_train_samples = num_train_samples + num_test_samples
|
| 51 |
+
num_test_samples = 0
|
| 52 |
+
print('using train and test data')
|
| 53 |
+
|
| 54 |
+
pcreader = PointCloudReader(
|
| 55 |
+
root_folder=global_config['DATA']['data_path'],
|
| 56 |
+
batch_size=global_config['OPTIMIZER']['batch_size'],
|
| 57 |
+
estimate_normals=global_config['DATA']['input_normals'],
|
| 58 |
+
raw_num_points=global_config['DATA']['raw_num_points'],
|
| 59 |
+
use_uniform_quaternions = global_config['DATA']['use_uniform_quaternions'],
|
| 60 |
+
scene_obj_scales = [c['obj_scales'] for c in contact_infos],
|
| 61 |
+
scene_obj_paths = [c['obj_paths'] for c in contact_infos],
|
| 62 |
+
scene_obj_transforms = [c['obj_transforms'] for c in contact_infos],
|
| 63 |
+
num_train_samples = num_train_samples,
|
| 64 |
+
num_test_samples = num_test_samples,
|
| 65 |
+
use_farthest_point = global_config['DATA']['use_farthest_point'],
|
| 66 |
+
intrinsics=global_config['DATA']['intrinsics'],
|
| 67 |
+
elevation=global_config['DATA']['view_sphere']['elevation'],
|
| 68 |
+
distance_range=global_config['DATA']['view_sphere']['distance_range'],
|
| 69 |
+
pc_augm_config=global_config['DATA']['pc_augm'],
|
| 70 |
+
depth_augm_config=global_config['DATA']['depth_augm']
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
with tf.Graph().as_default():
|
| 74 |
+
|
| 75 |
+
# Build the model
|
| 76 |
+
grasp_estimator = GraspEstimator(global_config)
|
| 77 |
+
ops = grasp_estimator.build_network()
|
| 78 |
+
|
| 79 |
+
# contact_tensors = load_contact_grasps(contact_infos, global_config['DATA'])
|
| 80 |
+
|
| 81 |
+
loss_ops = load_labels_and_losses(grasp_estimator, contact_infos, global_config)
|
| 82 |
+
|
| 83 |
+
ops.update(loss_ops)
|
| 84 |
+
ops['train_op'] = build_train_op(ops['loss'], ops['step'], global_config)
|
| 85 |
+
|
| 86 |
+
# Add ops to save and restore all the variables.
|
| 87 |
+
saver = tf.train.Saver(save_relative_paths=True, keep_checkpoint_every_n_hours=4)
|
| 88 |
+
|
| 89 |
+
# Create a session
|
| 90 |
+
config = tf.ConfigProto()
|
| 91 |
+
config.gpu_options.allow_growth = True
|
| 92 |
+
config.allow_soft_placement = True
|
| 93 |
+
sess = tf.Session(config=config)
|
| 94 |
+
|
| 95 |
+
# Log summaries
|
| 96 |
+
summary_ops = build_summary_ops(ops, sess, global_config)
|
| 97 |
+
|
| 98 |
+
# Init/Load weights
|
| 99 |
+
grasp_estimator.load_weights(sess, saver, log_dir, mode='train')
|
| 100 |
+
|
| 101 |
+
# sess = tf_debug.LocalCLIDebugWrapperSession(sess)
|
| 102 |
+
# sess.add_tensor_filter("has_inf_or_nan", tf_debug.has_inf_or_nan)
|
| 103 |
+
file_writers = build_file_writers(sess, log_dir)
|
| 104 |
+
|
| 105 |
+
## define: epoch = arbitrary number of views of every training scene
|
| 106 |
+
cur_epoch = sess.run(ops['step']) // num_train_samples
|
| 107 |
+
for epoch in range(cur_epoch, global_config['OPTIMIZER']['max_epoch']):
|
| 108 |
+
log_string('**** EPOCH %03d ****' % (epoch))
|
| 109 |
+
|
| 110 |
+
sess.run(ops['iterator'].initializer)
|
| 111 |
+
epoch_time = time.time()
|
| 112 |
+
step = train_one_epoch(sess, ops, summary_ops, file_writers, pcreader)
|
| 113 |
+
log_string('trained epoch {} in: {}'.format(epoch, time.time()-epoch_time))
|
| 114 |
+
|
| 115 |
+
# Save the variables to disk.
|
| 116 |
+
save_path = saver.save(sess, os.path.join(log_dir, "model.ckpt"), global_step=step, write_meta_graph=False)
|
| 117 |
+
log_string("Model saved in file: %s" % save_path)
|
| 118 |
+
|
| 119 |
+
if num_test_samples > 0:
|
| 120 |
+
eval_time = time.time()
|
| 121 |
+
eval_validation_scenes(sess, ops, summary_ops, file_writers, pcreader)
|
| 122 |
+
log_string('evaluation time: {}'.format(time.time()-eval_time))
|
| 123 |
+
|
| 124 |
+
def train_one_epoch(sess, ops, summary_ops, file_writers, pcreader):
|
| 125 |
+
""" ops: dict mapping from string to tf ops """
|
| 126 |
+
|
| 127 |
+
log_string(str(datetime.now()))
|
| 128 |
+
loss_log = np.zeros((10,7))
|
| 129 |
+
get_time = time.time()
|
| 130 |
+
|
| 131 |
+
for batch_idx in range(pcreader._num_train_samples):
|
| 132 |
+
|
| 133 |
+
batch_data, cam_poses, scene_idx = pcreader.get_scene_batch(scene_idx=batch_idx)
|
| 134 |
+
|
| 135 |
+
# OpenCV OpenGL conversion
|
| 136 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 137 |
+
|
| 138 |
+
feed_dict = {ops['pointclouds_pl']: batch_data, ops['cam_poses_pl']: cam_poses,
|
| 139 |
+
ops['scene_idx_pl']: scene_idx, ops['is_training_pl']: True}
|
| 140 |
+
|
| 141 |
+
step, summary, _, loss_val, dir_loss, bin_ce_loss, \
|
| 142 |
+
offset_loss, approach_loss, adds_loss, adds_gt2pred_loss, scene_idx = sess.run([ops['step'], summary_ops['merged'], ops['train_op'], ops['loss'], ops['dir_loss'],
|
| 143 |
+
ops['bin_ce_loss'], ops['offset_loss'], ops['approach_loss'], ops['adds_loss'],
|
| 144 |
+
ops['adds_gt2pred_loss'], ops['scene_idx']], feed_dict=feed_dict)
|
| 145 |
+
assert scene_idx[0] == scene_idx
|
| 146 |
+
|
| 147 |
+
loss_log[batch_idx%10,:] = loss_val, dir_loss, bin_ce_loss, offset_loss, approach_loss, adds_loss, adds_gt2pred_loss
|
| 148 |
+
|
| 149 |
+
if (batch_idx+1)%10 == 0:
|
| 150 |
+
file_writers['train_writer'].add_summary(summary, step)
|
| 151 |
+
f = tuple(np.mean(loss_log, axis=0)) + ((time.time() - get_time) / 10., )
|
| 152 |
+
log_string('total loss: %f \t dir loss: %f \t ce loss: %f \t off loss: %f \t app loss: %f adds loss: %f \t adds_gt2pred loss: %f \t batch time: %f' % f)
|
| 153 |
+
get_time = time.time()
|
| 154 |
+
|
| 155 |
+
return step
|
| 156 |
+
|
| 157 |
+
def eval_validation_scenes(sess, ops, summary_ops, file_writers, pcreader, max_eval_objects=500):
|
| 158 |
+
""" ops: dict mapping from string to tf ops """
|
| 159 |
+
is_training = False
|
| 160 |
+
log_string(str(datetime.now()))
|
| 161 |
+
loss_log = np.zeros((min(pcreader._num_test_samples, max_eval_objects),7))
|
| 162 |
+
|
| 163 |
+
# resets accumulation of pr and auc data
|
| 164 |
+
sess.run(summary_ops['pr_reset_op'])
|
| 165 |
+
|
| 166 |
+
for batch_idx in np.arange(min(pcreader._num_test_samples, max_eval_objects)):
|
| 167 |
+
|
| 168 |
+
batch_data, cam_poses, scene_idx = pcreader.get_scene_batch(scene_idx=pcreader._num_train_samples + batch_idx)
|
| 169 |
+
|
| 170 |
+
# OpenCV OpenGL conversion
|
| 171 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 172 |
+
|
| 173 |
+
feed_dict = {ops['pointclouds_pl']: batch_data, ops['cam_poses_pl']: cam_poses,
|
| 174 |
+
ops['scene_idx_pl']: scene_idx, ops['is_training_pl']: False}
|
| 175 |
+
|
| 176 |
+
scene_idx, step, loss_val, dir_loss, bin_ce_loss, offset_loss, approach_loss, adds_loss, adds_gt2pred_loss, pr_summary,_,_,_ = sess.run([ops['scene_idx'], ops['step'], ops['loss'], ops['dir_loss'], ops['bin_ce_loss'],
|
| 177 |
+
ops['offset_loss'], ops['approach_loss'], ops['adds_loss'], ops['adds_gt2pred_loss'],
|
| 178 |
+
summary_ops['merged_eval'], summary_ops['pr_update_op'],
|
| 179 |
+
summary_ops['auc_update_op']] + [summary_ops['acc_update_ops']], feed_dict=feed_dict)
|
| 180 |
+
assert scene_idx[0] == (pcreader._num_train_samples + batch_idx)
|
| 181 |
+
|
| 182 |
+
loss_log[batch_idx,:] = loss_val, dir_loss, bin_ce_loss, offset_loss, approach_loss, adds_loss, adds_gt2pred_loss
|
| 183 |
+
|
| 184 |
+
file_writers['test_writer'].add_summary(pr_summary, step)
|
| 185 |
+
f = tuple(np.mean(loss_log, axis=0))
|
| 186 |
+
log_string('mean val loss: %f \t mean val dir loss: %f \t mean val ce loss: %f \t mean off loss: %f \t mean app loss: %f \t mean adds loss: %f \t mean adds_gt2pred loss: %f' % f)
|
| 187 |
+
|
| 188 |
+
return step
|
| 189 |
+
|
| 190 |
+
if __name__ == "__main__":
|
| 191 |
+
|
| 192 |
+
parser = argparse.ArgumentParser()
|
| 193 |
+
parser.add_argument('--ckpt_dir', default='checkpoints/contact_graspnet', help='Checkpoint dir')
|
| 194 |
+
parser.add_argument('--data_path', type=str, default=None, help='Grasp data root dir')
|
| 195 |
+
parser.add_argument('--max_epoch', type=int, default=None, help='Epochs to run')
|
| 196 |
+
parser.add_argument('--batch_size', type=int, default=None, help='Batch Size during training')
|
| 197 |
+
parser.add_argument('--arg_configs', nargs="*", type=str, default=[], help='overwrite config parameters')
|
| 198 |
+
FLAGS = parser.parse_args()
|
| 199 |
+
|
| 200 |
+
ckpt_dir = FLAGS.ckpt_dir
|
| 201 |
+
if not os.path.exists(ckpt_dir):
|
| 202 |
+
if not os.path.exists(os.path.dirname(ckpt_dir)):
|
| 203 |
+
ckpt_dir = os.path.join(BASE_DIR, ckpt_dir)
|
| 204 |
+
os.makedirs(ckpt_dir, exist_ok=True)
|
| 205 |
+
|
| 206 |
+
os.system('cp {} {}'.format(os.path.join(CONTACT_DIR, 'contact_graspnet.py'), ckpt_dir)) # bkp of model def
|
| 207 |
+
os.system('cp {} {}'.format(os.path.join(CONTACT_DIR, 'train.py'), ckpt_dir)) # bkp of train procedure
|
| 208 |
+
|
| 209 |
+
LOG_FOUT = open(os.path.join(ckpt_dir, 'log_train.txt'), 'w')
|
| 210 |
+
LOG_FOUT.write(str(FLAGS)+'\n')
|
| 211 |
+
def log_string(out_str):
|
| 212 |
+
LOG_FOUT.write(out_str+'\n')
|
| 213 |
+
LOG_FOUT.flush()
|
| 214 |
+
print(out_str)
|
| 215 |
+
|
| 216 |
+
global_config = config_utils.load_config(ckpt_dir, batch_size=FLAGS.batch_size, max_epoch=FLAGS.max_epoch,
|
| 217 |
+
data_path= FLAGS.data_path, arg_configs=FLAGS.arg_configs, save=True)
|
| 218 |
+
|
| 219 |
+
log_string(str(global_config))
|
| 220 |
+
log_string('pid: %s'%(str(os.getpid())))
|
| 221 |
+
|
| 222 |
+
train(global_config, ckpt_dir)
|
| 223 |
+
|
| 224 |
+
LOG_FOUT.close()
|
scene_2048_bs3_rad2_32/checkpoint
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_checkpoint_path: "model.ckpt-144144"
|
| 2 |
+
all_model_checkpoint_paths: "model.ckpt-108108"
|
| 3 |
+
all_model_checkpoint_paths: "model.ckpt-117117"
|
| 4 |
+
all_model_checkpoint_paths: "model.ckpt-126126"
|
| 5 |
+
all_model_checkpoint_paths: "model.ckpt-135135"
|
| 6 |
+
all_model_checkpoint_paths: "model.ckpt-144144"
|
scene_2048_bs3_rad2_32/config.yaml
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
DATA:
|
| 2 |
+
gripper_width: 0.08
|
| 3 |
+
input_normals: false
|
| 4 |
+
intrinsics: realsense
|
| 5 |
+
labels:
|
| 6 |
+
bin_weights:
|
| 7 |
+
- 0.16652107
|
| 8 |
+
- 0.21488856
|
| 9 |
+
- 0.37031708
|
| 10 |
+
- 0.55618503
|
| 11 |
+
- 0.75124664
|
| 12 |
+
- 0.93943357
|
| 13 |
+
- 1.07824539
|
| 14 |
+
- 1.19423112
|
| 15 |
+
- 1.55731375
|
| 16 |
+
- 3.17161779
|
| 17 |
+
contact_gather: knn
|
| 18 |
+
filter_z: true
|
| 19 |
+
k: 1
|
| 20 |
+
max_radius: 0.005
|
| 21 |
+
min_unique_pos_contacts: 1
|
| 22 |
+
num_neg_contacts: 0
|
| 23 |
+
num_pos_contacts: 4000
|
| 24 |
+
offset_bins:
|
| 25 |
+
- 0
|
| 26 |
+
- 0.00794435329
|
| 27 |
+
- 0.0158887021
|
| 28 |
+
- 0.0238330509
|
| 29 |
+
- 0.0317773996
|
| 30 |
+
- 0.0397217484
|
| 31 |
+
- 0.0476660972
|
| 32 |
+
- 0.055610446
|
| 33 |
+
- 0.0635547948
|
| 34 |
+
- 0.0714991435
|
| 35 |
+
- 0.08
|
| 36 |
+
to_gpu: false
|
| 37 |
+
z_val: -0.1
|
| 38 |
+
ndataset_points: 20000
|
| 39 |
+
num_point: 2048
|
| 40 |
+
num_test_scenes: 1000
|
| 41 |
+
raw_num_points: 20000
|
| 42 |
+
train_and_test: false
|
| 43 |
+
train_on_scenes: true
|
| 44 |
+
use_farthest_point: false
|
| 45 |
+
use_uniform_quaternions: false
|
| 46 |
+
LOSS:
|
| 47 |
+
max_geom_loss_divisor: 100.0
|
| 48 |
+
min_geom_loss_divisor: 1.0
|
| 49 |
+
offset_loss_type: sigmoid_cross_entropy
|
| 50 |
+
too_small_offset_pred_bin_factor: 0
|
| 51 |
+
topk_confidence: 512
|
| 52 |
+
MODEL:
|
| 53 |
+
asymmetric_model: true
|
| 54 |
+
bin_offsets: true
|
| 55 |
+
contact_distance_offset: true
|
| 56 |
+
dir_vec_length_offset: false
|
| 57 |
+
grasp_conf_head:
|
| 58 |
+
conv1d: 1
|
| 59 |
+
dropout_keep: 0.5
|
| 60 |
+
grasp_dir_head:
|
| 61 |
+
conv1d: 3
|
| 62 |
+
dropout_keep: 0.7
|
| 63 |
+
joint_head:
|
| 64 |
+
conv1d: 4
|
| 65 |
+
dropout_keep: 0.7
|
| 66 |
+
joint_heads: false
|
| 67 |
+
larger_model: false
|
| 68 |
+
model: contact_graspnet
|
| 69 |
+
pointnet_fp_modules:
|
| 70 |
+
- mlp:
|
| 71 |
+
- 256
|
| 72 |
+
- 256
|
| 73 |
+
- mlp:
|
| 74 |
+
- 256
|
| 75 |
+
- 128
|
| 76 |
+
- mlp:
|
| 77 |
+
- 128
|
| 78 |
+
- 128
|
| 79 |
+
- 128
|
| 80 |
+
pointnet_sa_module:
|
| 81 |
+
group_all: true
|
| 82 |
+
mlp:
|
| 83 |
+
- 256
|
| 84 |
+
- 512
|
| 85 |
+
- 1024
|
| 86 |
+
pointnet_sa_modules_msg:
|
| 87 |
+
- mlp_list:
|
| 88 |
+
- - 32
|
| 89 |
+
- 32
|
| 90 |
+
- 64
|
| 91 |
+
- - 64
|
| 92 |
+
- 64
|
| 93 |
+
- 128
|
| 94 |
+
- - 64
|
| 95 |
+
- 96
|
| 96 |
+
- 128
|
| 97 |
+
npoint: 2048
|
| 98 |
+
nsample_list:
|
| 99 |
+
- 32
|
| 100 |
+
- 64
|
| 101 |
+
- 128
|
| 102 |
+
radius_list:
|
| 103 |
+
- 0.02
|
| 104 |
+
- 0.04
|
| 105 |
+
- 0.08
|
| 106 |
+
- mlp_list:
|
| 107 |
+
- - 64
|
| 108 |
+
- 64
|
| 109 |
+
- 128
|
| 110 |
+
- - 128
|
| 111 |
+
- 128
|
| 112 |
+
- 256
|
| 113 |
+
- - 128
|
| 114 |
+
- 128
|
| 115 |
+
- 256
|
| 116 |
+
npoint: 512
|
| 117 |
+
nsample_list:
|
| 118 |
+
- 64
|
| 119 |
+
- 64
|
| 120 |
+
- 128
|
| 121 |
+
radius_list:
|
| 122 |
+
- 0.04
|
| 123 |
+
- 0.08
|
| 124 |
+
- 0.16
|
| 125 |
+
- mlp_list:
|
| 126 |
+
- - 64
|
| 127 |
+
- 64
|
| 128 |
+
- 128
|
| 129 |
+
- - 128
|
| 130 |
+
- 128
|
| 131 |
+
- 256
|
| 132 |
+
- - 128
|
| 133 |
+
- 128
|
| 134 |
+
- 256
|
| 135 |
+
npoint: 128
|
| 136 |
+
nsample_list:
|
| 137 |
+
- 64
|
| 138 |
+
- 64
|
| 139 |
+
- 128
|
| 140 |
+
radius_list:
|
| 141 |
+
- 0.08
|
| 142 |
+
- 0.16
|
| 143 |
+
- 0.32
|
| 144 |
+
pred_contact_approach: false
|
| 145 |
+
pred_contact_base: false
|
| 146 |
+
pred_contact_offset: true
|
| 147 |
+
pred_contact_success: true
|
| 148 |
+
pred_grasps_adds: true
|
| 149 |
+
pred_grasps_adds_gt2pred: false
|
| 150 |
+
OPTIMIZER:
|
| 151 |
+
adds_gt2pred_loss_weight: 1
|
| 152 |
+
adds_loss_weight: 10
|
| 153 |
+
approach_cosine_loss_weight: 1
|
| 154 |
+
batch_size: 1
|
| 155 |
+
bn_decay_clip: 0.99
|
| 156 |
+
bn_decay_decay_rate: 0.5
|
| 157 |
+
bn_decay_decay_step: 200000
|
| 158 |
+
bn_init_decay: 0.5
|
| 159 |
+
decay_rate: 0.7
|
| 160 |
+
decay_step: 200000
|
| 161 |
+
dir_cosine_loss_weight: 1
|
| 162 |
+
learning_rate: 0.001
|
| 163 |
+
max_epoch: 16
|
| 164 |
+
momentum: 0.9
|
| 165 |
+
offset_loss_weight: 1
|
| 166 |
+
optimizer: adam
|
| 167 |
+
score_ce_loss_weight: 1
|
| 168 |
+
TEST:
|
| 169 |
+
center_to_tip: 0.0
|
| 170 |
+
allow_zero_margin: 0
|
| 171 |
+
bin_vals: max
|
| 172 |
+
extra_opening: 0.005
|
| 173 |
+
first_thres: 0.23
|
| 174 |
+
second_thres: 0.19
|
| 175 |
+
max_farthest_points: 150
|
| 176 |
+
num_samples: 200
|
| 177 |
+
save: false
|
| 178 |
+
scale_fac:
|
| 179 |
+
- 1.25
|
| 180 |
+
- 1.0
|
| 181 |
+
- 0.75
|
| 182 |
+
- 0.5
|
| 183 |
+
scales: false
|
| 184 |
+
with_replacement: false
|
| 185 |
+
filter_thres: 0.0001
|
| 186 |
+
|
scene_2048_bs3_rad2_32/model.ckpt-144144.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9811b79d977ad2f1cf18a78755befc8421189652f1179c73febbaea05ceaf9b1
|
| 3 |
+
size 27860696
|
scene_2048_bs3_rad2_32/model.ckpt-144144.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_001/checkpoint
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_checkpoint_path: "model.ckpt-54054"
|
| 2 |
+
all_model_checkpoint_paths: "model.ckpt-108108"
|
| 3 |
+
all_model_checkpoint_paths: "model.ckpt-117117"
|
| 4 |
+
all_model_checkpoint_paths: "model.ckpt-126126"
|
| 5 |
+
all_model_checkpoint_paths: "model.ckpt-135135"
|
| 6 |
+
all_model_checkpoint_paths: "model.ckpt-144144"
|
scene_test_2048_bs3_hor_sigma_001/config.yaml
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
DATA:
|
| 2 |
+
gripper_width: 0.08
|
| 3 |
+
input_normals: false
|
| 4 |
+
use_uniform_quaternions: False
|
| 5 |
+
train_on_scenes: True
|
| 6 |
+
labels:
|
| 7 |
+
to_gpu: False
|
| 8 |
+
bin_weights:
|
| 9 |
+
- 0.16652107
|
| 10 |
+
- 0.21488856
|
| 11 |
+
- 0.37031708
|
| 12 |
+
- 0.55618503
|
| 13 |
+
- 0.75124664
|
| 14 |
+
- 0.93943357
|
| 15 |
+
- 1.07824539
|
| 16 |
+
- 1.19423112
|
| 17 |
+
- 1.55731375
|
| 18 |
+
- 3.17161779
|
| 19 |
+
contact_gather: knn
|
| 20 |
+
filter_z: true
|
| 21 |
+
k: 1
|
| 22 |
+
max_radius: 0.005
|
| 23 |
+
min_unique_pos_contacts: 1
|
| 24 |
+
num_neg_contacts: 0
|
| 25 |
+
num_pos_contacts: 10000
|
| 26 |
+
offset_bins:
|
| 27 |
+
- 0
|
| 28 |
+
- 0.00794435329
|
| 29 |
+
- 0.0158887021
|
| 30 |
+
- 0.0238330509
|
| 31 |
+
- 0.0317773996
|
| 32 |
+
- 0.0397217484
|
| 33 |
+
- 0.0476660972
|
| 34 |
+
- 0.055610446
|
| 35 |
+
- 0.0635547948
|
| 36 |
+
- 0.0714991435
|
| 37 |
+
- 0.08
|
| 38 |
+
z_val: -0.1
|
| 39 |
+
raw_num_points: 20000
|
| 40 |
+
ndataset_points: 20000
|
| 41 |
+
num_point: 2048
|
| 42 |
+
sigma: 0.001
|
| 43 |
+
clip: 0.005
|
| 44 |
+
use_farthest_point: false
|
| 45 |
+
train_and_test: false
|
| 46 |
+
num_test_scenes: 1000
|
| 47 |
+
intrinsics: 'realsense'
|
| 48 |
+
LOSS:
|
| 49 |
+
min_geom_loss_divisor: 1.0
|
| 50 |
+
max_geom_loss_divisor: 100.0
|
| 51 |
+
offset_loss_type: sigmoid_cross_entropy
|
| 52 |
+
too_small_offset_pred_bin_factor: 0
|
| 53 |
+
topk_confidence: 512
|
| 54 |
+
MODEL:
|
| 55 |
+
bin_offsets: true
|
| 56 |
+
contact_distance_offset: true
|
| 57 |
+
dir_vec_length_offset: false
|
| 58 |
+
grasp_conf_head:
|
| 59 |
+
conv1d: 1
|
| 60 |
+
dropout_keep: 0.5
|
| 61 |
+
grasp_dir_head:
|
| 62 |
+
conv1d: 3
|
| 63 |
+
dropout_keep: 0.7
|
| 64 |
+
joint_head:
|
| 65 |
+
conv1d: 4
|
| 66 |
+
dropout_keep: 0.7
|
| 67 |
+
joint_heads: false
|
| 68 |
+
larger_model: false
|
| 69 |
+
asymmetric_model: true
|
| 70 |
+
model: contact_graspnet
|
| 71 |
+
pointnet_fp_modules:
|
| 72 |
+
- mlp:
|
| 73 |
+
- 256
|
| 74 |
+
- 256
|
| 75 |
+
- mlp:
|
| 76 |
+
- 256
|
| 77 |
+
- 128
|
| 78 |
+
- mlp:
|
| 79 |
+
- 128
|
| 80 |
+
- 128
|
| 81 |
+
- 128
|
| 82 |
+
pointnet_sa_module:
|
| 83 |
+
group_all: true
|
| 84 |
+
mlp:
|
| 85 |
+
- 256
|
| 86 |
+
- 512
|
| 87 |
+
- 1024
|
| 88 |
+
pointnet_sa_modules_msg:
|
| 89 |
+
- mlp_list:
|
| 90 |
+
- - 32
|
| 91 |
+
- 32
|
| 92 |
+
- 64
|
| 93 |
+
- - 64
|
| 94 |
+
- 64
|
| 95 |
+
- 128
|
| 96 |
+
- - 64
|
| 97 |
+
- 96
|
| 98 |
+
- 128
|
| 99 |
+
npoint: 2048
|
| 100 |
+
nsample_list:
|
| 101 |
+
- 32
|
| 102 |
+
- 64
|
| 103 |
+
- 128
|
| 104 |
+
radius_list:
|
| 105 |
+
- 0.02
|
| 106 |
+
- 0.04
|
| 107 |
+
- 0.08
|
| 108 |
+
- mlp_list:
|
| 109 |
+
- - 64
|
| 110 |
+
- 64
|
| 111 |
+
- 128
|
| 112 |
+
- - 128
|
| 113 |
+
- 128
|
| 114 |
+
- 256
|
| 115 |
+
- - 128
|
| 116 |
+
- 128
|
| 117 |
+
- 256
|
| 118 |
+
npoint: 512
|
| 119 |
+
nsample_list:
|
| 120 |
+
- 64
|
| 121 |
+
- 64
|
| 122 |
+
- 128
|
| 123 |
+
radius_list:
|
| 124 |
+
- 0.04
|
| 125 |
+
- 0.08
|
| 126 |
+
- 0.16
|
| 127 |
+
- mlp_list:
|
| 128 |
+
- - 64
|
| 129 |
+
- 64
|
| 130 |
+
- 128
|
| 131 |
+
- - 128
|
| 132 |
+
- 128
|
| 133 |
+
- 256
|
| 134 |
+
- - 128
|
| 135 |
+
- 128
|
| 136 |
+
- 256
|
| 137 |
+
npoint: 128
|
| 138 |
+
nsample_list:
|
| 139 |
+
- 64
|
| 140 |
+
- 64
|
| 141 |
+
- 128
|
| 142 |
+
radius_list:
|
| 143 |
+
- 0.08
|
| 144 |
+
- 0.16
|
| 145 |
+
- 0.32
|
| 146 |
+
pred_contact_approach: true
|
| 147 |
+
pred_contact_base: true
|
| 148 |
+
pred_contact_offset: true
|
| 149 |
+
pred_contact_success: true
|
| 150 |
+
pred_grasps_adds: false
|
| 151 |
+
pred_grasps_adds_gt2pred: false
|
| 152 |
+
OPTIMIZER:
|
| 153 |
+
adds_gt2pred_loss_weight: 1
|
| 154 |
+
adds_loss_weight: 10
|
| 155 |
+
approach_cosine_loss_weight: 1
|
| 156 |
+
batch_size: 14
|
| 157 |
+
bn_decay_clip: 0.99
|
| 158 |
+
bn_decay_decay_rate: 0.5
|
| 159 |
+
bn_decay_decay_step: 200000
|
| 160 |
+
bn_init_decay: 0.5
|
| 161 |
+
decay_rate: 0.7
|
| 162 |
+
decay_step: 200000
|
| 163 |
+
dir_cosine_loss_weight: 1
|
| 164 |
+
learning_rate: 0.001
|
| 165 |
+
max_epoch: 16
|
| 166 |
+
momentum: 0.9
|
| 167 |
+
offset_loss_weight: 1
|
| 168 |
+
optimizer: adam
|
| 169 |
+
score_ce_loss_weight: 1
|
| 170 |
+
TEST:
|
| 171 |
+
center_to_tip: 0.0
|
| 172 |
+
allow_zero_margin: 0
|
| 173 |
+
bin_vals: max
|
| 174 |
+
extra_opening: 0.005
|
| 175 |
+
first_thres: 0.23
|
| 176 |
+
second_thres: 0.18
|
| 177 |
+
max_farthest_points: 150
|
| 178 |
+
num_samples: 200
|
| 179 |
+
save: false
|
| 180 |
+
scale_fac:
|
| 181 |
+
- 1.25
|
| 182 |
+
- 1.0
|
| 183 |
+
- 0.75
|
| 184 |
+
- 0.5
|
| 185 |
+
scales: false
|
| 186 |
+
with_replacement: false
|
| 187 |
+
filter_thres: 0.0001
|
scene_test_2048_bs3_hor_sigma_001/log_train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-144144.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ffbd3968ed8526e5b27982eb8e6533bb697e72a5efd56c2f7c2f321f7dc5c9a6
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-144144.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-45045.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:60575929774dd116b539a10680a123c4117f666e4750c404f41b00a4723f72a5
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-45045.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-54054.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:992e15e60e353796542f44acb33f062cbb7d9a313f42a13b420cf4d0c0275de2
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-54054.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-72072.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c760637a20f3cd271aba8c97b91c14acd6648dca854705fe4c817af0a2fdc52d
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_001/model.ckpt-72072.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_001/pointnet2_grasp_direct.py
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 4 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 5 |
+
|
| 6 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 7 |
+
sys.path.append(os.path.join(BASE_DIR, 'utils'))
|
| 8 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 9 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2'))
|
| 10 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2'))
|
| 11 |
+
try:
|
| 12 |
+
import tensorflow.compat.v1 as tf
|
| 13 |
+
tf.disable_eager_execution()
|
| 14 |
+
TF2 = True
|
| 15 |
+
except:
|
| 16 |
+
import tensorflow as tf
|
| 17 |
+
TF2 = False
|
| 18 |
+
|
| 19 |
+
import numpy as np
|
| 20 |
+
import tf_util
|
| 21 |
+
from pointnet_util import pointnet_sa_module, pointnet_fp_module, pointnet_sa_module_msg
|
| 22 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/sampling'))
|
| 23 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/grouping'))
|
| 24 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/3d_interpolation'))
|
| 25 |
+
from tf_sampling import farthest_point_sample, gather_point
|
| 26 |
+
from tf_grouping import query_ball_point, group_point, knn_point
|
| 27 |
+
from tf_interpolate import three_nn, three_interpolate
|
| 28 |
+
import tf_utils
|
| 29 |
+
|
| 30 |
+
def placeholder_inputs(global_config):
|
| 31 |
+
batch_size = global_config['OPTIMIZER']['batch_size']
|
| 32 |
+
if 'raw_num_points' in global_config['DATA']:
|
| 33 |
+
num_point = global_config['DATA']['raw_num_points']
|
| 34 |
+
else:
|
| 35 |
+
num_point = global_config['DATA']['num_point']
|
| 36 |
+
|
| 37 |
+
input_normals = global_config['DATA']['input_normals']
|
| 38 |
+
|
| 39 |
+
pl_dict = {}
|
| 40 |
+
dim = 6 if input_normals else 3
|
| 41 |
+
pl_dict['pointclouds_pl'] = tf.placeholder(tf.float32, shape=(batch_size, num_point, dim))
|
| 42 |
+
pl_dict['obj_idx_pl'] = tf.placeholder(tf.int32, ())
|
| 43 |
+
pl_dict['cam_poses_pl'] = tf.placeholder(tf.float32, shape=(batch_size, 4, 4))
|
| 44 |
+
pl_dict['is_training_pl'] = tf.placeholder(tf.bool, shape=())
|
| 45 |
+
|
| 46 |
+
return pl_dict #, labels_pl
|
| 47 |
+
|
| 48 |
+
def get_bin_vals(global_config):
|
| 49 |
+
bins_bounds = np.array(global_config['DATA']['labels']['offset_bins'])
|
| 50 |
+
if global_config['TEST']['bin_vals'] == 'max':
|
| 51 |
+
bin_vals = (bins_bounds[1:] + bins_bounds[:-1])/2
|
| 52 |
+
bin_vals[-1] = bins_bounds[-1]
|
| 53 |
+
elif global_config['TEST']['bin_vals'] == 'mean':
|
| 54 |
+
bin_vals = bins_bounds[1:]
|
| 55 |
+
else:
|
| 56 |
+
raise NotImplementedError
|
| 57 |
+
|
| 58 |
+
if not global_config['TEST']['allow_zero_margin']:
|
| 59 |
+
bin_vals = np.minimum(bin_vals, global_config['DATA']['gripper_width']-global_config['TEST']['extra_opening'])
|
| 60 |
+
|
| 61 |
+
tf_bin_vals = tf.constant(bin_vals, tf.float32)
|
| 62 |
+
return tf_bin_vals
|
| 63 |
+
|
| 64 |
+
def get_model(point_cloud, is_training, global_config, bn_decay=None):
|
| 65 |
+
""" Grasp direction PointNet++ """
|
| 66 |
+
|
| 67 |
+
model_config = global_config['MODEL']
|
| 68 |
+
data_config = global_config['DATA']
|
| 69 |
+
|
| 70 |
+
radius_list_0 = model_config['pointnet_sa_modules_msg'][0]['radius_list']
|
| 71 |
+
radius_list_1 = model_config['pointnet_sa_modules_msg'][1]['radius_list']
|
| 72 |
+
nsample_list_0 = model_config['pointnet_sa_modules_msg'][0]['nsample_list']
|
| 73 |
+
nsample_list_1 = model_config['pointnet_sa_modules_msg'][1]['nsample_list']
|
| 74 |
+
mlp_list_0 = model_config['pointnet_sa_modules_msg'][0]['mlp_list']
|
| 75 |
+
mlp_list_1 = model_config['pointnet_sa_modules_msg'][1]['mlp_list']
|
| 76 |
+
npoint_0 = model_config['pointnet_sa_modules_msg'][0]['npoint']
|
| 77 |
+
npoint_1 = model_config['pointnet_sa_modules_msg'][1]['npoint']
|
| 78 |
+
fp_mlp_0 = model_config['pointnet_fp_modules'][0]['mlp']
|
| 79 |
+
fp_mlp_1 = model_config['pointnet_fp_modules'][1]['mlp']
|
| 80 |
+
fp_mlp_2 = model_config['pointnet_fp_modules'][2]['mlp']
|
| 81 |
+
|
| 82 |
+
#larger model
|
| 83 |
+
radius_list_2 = model_config['pointnet_sa_modules_msg'][2]['radius_list']
|
| 84 |
+
nsample_list_2 = model_config['pointnet_sa_modules_msg'][2]['nsample_list']
|
| 85 |
+
npoint_2 = model_config['pointnet_sa_modules_msg'][2]['npoint']
|
| 86 |
+
mlp_list_2 = model_config['pointnet_sa_modules_msg'][2]['mlp_list']
|
| 87 |
+
|
| 88 |
+
input_normals = data_config['input_normals']
|
| 89 |
+
gripper_width = data_config['gripper_width']
|
| 90 |
+
offset_bins = data_config['labels']['offset_bins']
|
| 91 |
+
joint_heads = model_config['joint_heads']
|
| 92 |
+
|
| 93 |
+
# expensive, rather use random only
|
| 94 |
+
if 'raw_num_points' in data_config and data_config['raw_num_points'] != data_config['ndataset_points']:
|
| 95 |
+
point_cloud = gather_point(point_cloud, farthest_point_sample(data_config['ndataset_points'], point_cloud))
|
| 96 |
+
|
| 97 |
+
batch_size = point_cloud.get_shape()[0]
|
| 98 |
+
num_point = point_cloud.get_shape()[1]
|
| 99 |
+
end_points = {}
|
| 100 |
+
l0_xyz = tf.slice(point_cloud, [0,0,0], [-1,-1,3])
|
| 101 |
+
l0_points = tf.slice(point_cloud, [0,0,3], [-1,-1,3]) if input_normals else None
|
| 102 |
+
|
| 103 |
+
l_xyz = [l0_xyz]
|
| 104 |
+
l_points = [l0_points]
|
| 105 |
+
pred_points = l0_xyz
|
| 106 |
+
|
| 107 |
+
# Set abstraction layers
|
| 108 |
+
l1_xyz, l1_points = pointnet_sa_module_msg(l0_xyz, l0_points, npoint_0, radius_list_0, nsample_list_0, mlp_list_0, is_training, bn_decay, scope='layer1')
|
| 109 |
+
l2_xyz, l2_points = pointnet_sa_module_msg(l1_xyz, l1_points, npoint_1, radius_list_1, nsample_list_1,mlp_list_1, is_training, bn_decay, scope='layer2')
|
| 110 |
+
|
| 111 |
+
# large model
|
| 112 |
+
if 'larger_model' in model_config and model_config['larger_model']:
|
| 113 |
+
fp_mlp_3 = model_config['pointnet_fp_modules'][3]['mlp']
|
| 114 |
+
|
| 115 |
+
l3_xyz, l3_points = pointnet_sa_module_msg(l2_xyz, l2_points, npoint_2, radius_list_2, nsample_list_2,mlp_list_2, is_training, bn_decay, scope='layer3')
|
| 116 |
+
l4_xyz, l4_points, _ = pointnet_sa_module(l3_xyz, l3_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer4')
|
| 117 |
+
|
| 118 |
+
# Feature Propagation layers
|
| 119 |
+
l3_points = pointnet_fp_module(l3_xyz, l4_xyz, l3_points, l4_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 120 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 121 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 122 |
+
|
| 123 |
+
l0_points = tf.concat([l0_xyz, l0_points],axis=-1) if input_normals else l0_xyz
|
| 124 |
+
l0_points = pointnet_fp_module(l0_xyz, l1_xyz, l0_points, l1_points, fp_mlp_3, is_training, bn_decay, scope='fa_layer4')
|
| 125 |
+
elif 'asymmetric_model' in model_config and model_config['asymmetric_model']:
|
| 126 |
+
l3_xyz, l3_points = pointnet_sa_module_msg(l2_xyz, l2_points, npoint_2, radius_list_2, nsample_list_2,mlp_list_2, is_training, bn_decay, scope='layer3')
|
| 127 |
+
l4_xyz, l4_points, _ = pointnet_sa_module(l3_xyz, l3_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer4')
|
| 128 |
+
|
| 129 |
+
# Feature Propagation layers
|
| 130 |
+
l3_points = pointnet_fp_module(l3_xyz, l4_xyz, l3_points, l4_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 131 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 132 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 133 |
+
|
| 134 |
+
l0_points = l1_points
|
| 135 |
+
pred_points = l1_xyz
|
| 136 |
+
else:
|
| 137 |
+
l3_xyz, l3_points, _ = pointnet_sa_module(l2_xyz, l2_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer3')
|
| 138 |
+
|
| 139 |
+
# Feature Propagation layers
|
| 140 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 141 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 142 |
+
|
| 143 |
+
l0_points = tf.concat([l0_xyz, l0_points],axis=-1) if input_normals else l0_xyz
|
| 144 |
+
l0_points = pointnet_fp_module(l0_xyz, l1_xyz, l0_points, l1_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 145 |
+
|
| 146 |
+
if joint_heads:
|
| 147 |
+
head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 148 |
+
# end_points['feats'] = head
|
| 149 |
+
head = tf_util.dropout(head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 150 |
+
head = tf_util.conv1d(head, 4, 1, padding='VALID', activation_fn=None, scope='fc2')
|
| 151 |
+
grasp_dir_head = tf.slice(head, [0,0,0], [-1,-1,3])
|
| 152 |
+
grasp_dir_head = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 153 |
+
binary_seg_head = tf.slice(head, [0,0,3], [-1,-1,1])
|
| 154 |
+
else:
|
| 155 |
+
# FC layers for grasp direction
|
| 156 |
+
grasp_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 157 |
+
# end_points['feats'] = grasp_dir_head
|
| 158 |
+
grasp_dir_head = tf_util.dropout(grasp_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 159 |
+
grasp_dir_head = tf_util.conv1d(grasp_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3')
|
| 160 |
+
grasp_dir_head_normed = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
# FC layers for grasp direction
|
| 164 |
+
approach_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_app', bn_decay=bn_decay)
|
| 165 |
+
# end_points['feats'] = approach_dir_head
|
| 166 |
+
approach_dir_head = tf_util.dropout(approach_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1_app')
|
| 167 |
+
approach_dir_head = tf_util.conv1d(approach_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3_app')
|
| 168 |
+
approach_dir_head_orthog = tf.math.l2_normalize(approach_dir_head - tf.reduce_sum(tf.multiply(grasp_dir_head_normed, approach_dir_head), axis=2, keepdims=True)*grasp_dir_head_normed, axis=2)
|
| 169 |
+
|
| 170 |
+
if model_config['dir_vec_length_offset']:
|
| 171 |
+
grasp_offset_head = tf.norm(grasp_dir_head, axis=2, keepdims=True)
|
| 172 |
+
elif model_config['bin_offsets']:
|
| 173 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 174 |
+
# end_points['feats'] = grasp_offset_head
|
| 175 |
+
# grasp_offset_head = tf_util.dropout(grasp_offset_head, keep_prob=0.7, is_training=is_training, scope='dp1_off')
|
| 176 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, len(offset_bins)-1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 177 |
+
else:
|
| 178 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 179 |
+
# end_points['feats'] = grasp_offset_head
|
| 180 |
+
grasp_offset_head = tf_util.dropout(grasp_offset_head, keep_prob=0.7, is_training=is_training, scope='dp1_off')
|
| 181 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 182 |
+
|
| 183 |
+
binary_seg_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_seg', bn_decay=bn_decay)
|
| 184 |
+
binary_seg_head = tf_util.dropout(binary_seg_head, keep_prob=0.5, is_training=is_training, scope='dp1_seg')
|
| 185 |
+
binary_seg_head = tf_util.conv1d(binary_seg_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_seg')
|
| 186 |
+
|
| 187 |
+
end_points['grasp_dir_head'] = grasp_dir_head_normed
|
| 188 |
+
end_points['binary_seg_head'] = binary_seg_head
|
| 189 |
+
end_points['binary_seg_pred'] = tf.math.sigmoid(binary_seg_head)
|
| 190 |
+
end_points['grasp_offset_head'] = grasp_offset_head
|
| 191 |
+
end_points['grasp_offset_pred'] = tf.math.sigmoid(grasp_offset_head) if model_config['bin_offsets'] else grasp_offset_head
|
| 192 |
+
end_points['approach_dir_head'] = approach_dir_head_orthog
|
| 193 |
+
end_points['pred_points'] = pred_points
|
| 194 |
+
|
| 195 |
+
return end_points
|
| 196 |
+
|
| 197 |
+
def build_6d_grasp(approach_dirs, base_dirs, contact_pts, thickness, use_tf=False, gripper_depth = 0.1034):
|
| 198 |
+
|
| 199 |
+
if use_tf:
|
| 200 |
+
grasps_R = tf.stack([base_dirs, tf.linalg.cross(approach_dirs,base_dirs),approach_dirs], axis=3)
|
| 201 |
+
grasps_t = contact_pts + tf.expand_dims(thickness,2)/2 * base_dirs - gripper_depth * approach_dirs
|
| 202 |
+
ones = tf.ones((contact_pts.shape[0], contact_pts.shape[1], 1, 4), dtype=tf.float32)
|
| 203 |
+
grasps = tf.concat([tf.concat([grasps_R, tf.expand_dims(grasps_t, 3)], axis=3), ones], axis=2)
|
| 204 |
+
else:
|
| 205 |
+
grasps = []
|
| 206 |
+
for i in range(len(contact_pts)):
|
| 207 |
+
grasp = np.eye(4)
|
| 208 |
+
|
| 209 |
+
grasp[:3,0] = base_dirs[i] / np.linalg.norm(base_dirs[i])
|
| 210 |
+
grasp[:3,2] = approach_dirs[i] / np.linalg.norm(approach_dirs[i])
|
| 211 |
+
grasp_y = np.cross( grasp[:3,2],grasp[:3,0])
|
| 212 |
+
grasp[:3,1] = grasp_y / np.linalg.norm(grasp_y)
|
| 213 |
+
# base_gripper xyz = contact + thickness / 2 * baseline_dir - gripper_d * approach_dir
|
| 214 |
+
grasp[:3,3] = contact_pts[i] + thickness[i] / 2 * grasp[:3,0] - gripper_depth * grasp[:3,2]
|
| 215 |
+
# grasp[0,3] = finger_width
|
| 216 |
+
grasps.append(grasp)
|
| 217 |
+
grasps = np.array(grasps)
|
| 218 |
+
|
| 219 |
+
return grasps
|
| 220 |
+
|
| 221 |
+
def multi_bin_labels(cont_labels, bin_boundaries):
|
| 222 |
+
|
| 223 |
+
# multi_hot_labels = tf.zeros_like((cont_labels.shape[0], cont_labels.shape[1], len(bin_boundaries)-1), tf.bool)
|
| 224 |
+
bins = []
|
| 225 |
+
for b in range(len(bin_boundaries)-1):
|
| 226 |
+
bins.append(tf.math.logical_and(tf.greater_equal(cont_labels, bin_boundaries[b]), tf.less(cont_labels,bin_boundaries[b+1])))
|
| 227 |
+
# cont_labels = tf.where(condition, b*tf.ones_like(condition, tf.float32), cont_labels)
|
| 228 |
+
multi_hot_labels = tf.concat(bins, axis=2)
|
| 229 |
+
multi_hot_labels = tf.cast(multi_hot_labels, tf.float32)
|
| 230 |
+
|
| 231 |
+
return multi_hot_labels
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
def get_losses(pointclouds_pl, end_points, dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam, global_config):
|
| 235 |
+
""" pred: (batch_size, num_point, 3),
|
| 236 |
+
label: (batch_size, num_point, 3),
|
| 237 |
+
grasp_success_labels_pc: (batch_size, num_point)
|
| 238 |
+
"""
|
| 239 |
+
|
| 240 |
+
grasp_dir_head = end_points['grasp_dir_head']
|
| 241 |
+
grasp_offset_head = end_points['grasp_offset_head']
|
| 242 |
+
approach_dir_head = end_points['approach_dir_head']
|
| 243 |
+
|
| 244 |
+
bin_weights = global_config['DATA']['labels']['bin_weights']
|
| 245 |
+
tf_bin_weights = tf.constant(bin_weights)
|
| 246 |
+
|
| 247 |
+
min_geom_loss_divisor = tf.constant(float(global_config['LOSS']['min_geom_loss_divisor'])) if 'min_geom_loss_divisor' in global_config['LOSS'] else tf.constant(1.)
|
| 248 |
+
pos_grasps_in_view = tf.math.maximum(tf.reduce_sum(grasp_success_labels_pc, axis=1), min_geom_loss_divisor)
|
| 249 |
+
|
| 250 |
+
### ADS Gripper PC Loss
|
| 251 |
+
if global_config['MODEL']['bin_offsets']:
|
| 252 |
+
thickness_pred = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(grasp_offset_head, axis=2), axis=2))
|
| 253 |
+
thickness_gt = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(offset_labels_pc, axis=2), axis=2))
|
| 254 |
+
else:
|
| 255 |
+
thickness_pred = grasp_offset_head[:,:,0]
|
| 256 |
+
thickness_gt = offset_labels_pc[:,:,0]
|
| 257 |
+
pred_grasps = build_6d_grasp(approach_dir_head, grasp_dir_head, pointclouds_pl, thickness_pred, use_tf=True) # b x num_point x 4 x 4
|
| 258 |
+
gt_grasps_proj = build_6d_grasp(approach_labels_pc_cam, dir_labels_pc_cam, pointclouds_pl, thickness_gt, use_tf=True) # b x num_point x 4 x 4
|
| 259 |
+
pos_gt_grasps_proj = tf.where(tf.broadcast_to(tf.expand_dims(tf.expand_dims(tf.cast(grasp_success_labels_pc, tf.bool),2),3), gt_grasps_proj.shape), gt_grasps_proj, tf.ones_like(gt_grasps_proj)*100000)
|
| 260 |
+
# pos_gt_grasps_proj = tf.reshape(pos_gt_grasps_proj, (global_config['OPTIMIZER']['batch_size'], -1, 4, 4))
|
| 261 |
+
|
| 262 |
+
gripper_control_points = tf_utils.get_control_point_tensor(global_config['OPTIMIZER']['batch_size'])[:,1:,:] # b x 5 x 3
|
| 263 |
+
sym_gripper_control_points = tf_utils.get_control_point_tensor(global_config['OPTIMIZER']['batch_size'], symmetric=True)[:,1:,:]
|
| 264 |
+
|
| 265 |
+
gripper_control_points_homog = tf.concat([gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 266 |
+
sym_gripper_control_points_homog = tf.concat([sym_gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 267 |
+
|
| 268 |
+
# only use per point pred grasps but not per point gt grasps
|
| 269 |
+
control_points = tf.keras.backend.repeat_elements(tf.expand_dims(gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 270 |
+
sym_control_points = tf.keras.backend.repeat_elements(tf.expand_dims(sym_gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 271 |
+
pred_control_points = tf.matmul(control_points, tf.transpose(pred_grasps, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_point x 5 x 3
|
| 272 |
+
|
| 273 |
+
### Pred Grasp to GT Grasp ADD-S Loss
|
| 274 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 275 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 276 |
+
|
| 277 |
+
squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 278 |
+
sym_squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(sym_gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 279 |
+
|
| 280 |
+
# symmetric ADD-S
|
| 281 |
+
neg_squared_adds = -tf.concat([squared_add,sym_squared_add], axis=2) # b x num_point x 2num_pos_grasp_point
|
| 282 |
+
neg_squared_adds_k = tf.math.top_k(neg_squared_adds, k=1, sorted=False)[0] # b x num_point
|
| 283 |
+
# If any pos grasp exists
|
| 284 |
+
min_adds = tf.minimum(tf.reduce_sum(grasp_success_labels_pc, axis=1, keepdims=True), tf.ones_like(neg_squared_adds_k[:,:,0])) * tf.sqrt(-neg_squared_adds_k[:,:,0])#tf.minimum(tf.sqrt(-neg_squared_adds_k), tf.ones_like(neg_squared_adds_k)) # b x num_point
|
| 285 |
+
adds_loss = tf.reduce_mean(end_points['binary_seg_pred'][:,:,0] * min_adds)
|
| 286 |
+
|
| 287 |
+
### GT Grasp to pred Grasp ADD-S Loss
|
| 288 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 289 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 290 |
+
|
| 291 |
+
neg_squared_adds = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 292 |
+
neg_squared_adds_sym = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(sym_gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 293 |
+
|
| 294 |
+
neg_squared_adds_k_gt2pred, pred_grasp_idcs = tf.math.top_k(neg_squared_adds, k=1, sorted=False) # b x num_pos_grasp_point
|
| 295 |
+
neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs = tf.math.top_k(neg_squared_adds_sym, k=1, sorted=False) # b x num_pos_grasp_point
|
| 296 |
+
pred_grasp_idcs_joined = tf.where(neg_squared_adds_k_gt2pred<neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs, pred_grasp_idcs)
|
| 297 |
+
min_adds_gt2pred = tf.minimum(-neg_squared_adds_k_gt2pred, -neg_squared_adds_k_sym_gt2pred) # b x num_pos_grasp_point x 1
|
| 298 |
+
# min_adds_gt2pred = tf.math.exp(-min_adds_gt2pred)
|
| 299 |
+
masked_min_adds_gt2pred = tf.multiply(min_adds_gt2pred[:,:,0], grasp_success_labels_pc)
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
batch_idcs = tf.meshgrid(tf.range(pred_grasp_idcs_joined.shape[1]), tf.range(pred_grasp_idcs_joined.shape[0]))
|
| 303 |
+
gather_idcs = tf.stack((batch_idcs[1],pred_grasp_idcs_joined[:,:,0]), axis=2)
|
| 304 |
+
nearest_pred_grasp_confidence = tf.gather_nd(end_points['binary_seg_pred'][:,:,0], gather_idcs)
|
| 305 |
+
adds_loss_gt2pred = tf.reduce_mean(tf.reduce_sum(nearest_pred_grasp_confidence*masked_min_adds_gt2pred, axis=1) / pos_grasps_in_view)
|
| 306 |
+
|
| 307 |
+
### Grasp baseline Loss
|
| 308 |
+
cosine_distance = tf.constant(1.)-tf.reduce_sum(tf.multiply(dir_labels_pc_cam, grasp_dir_head),axis=2)
|
| 309 |
+
# only pass loss where we have labeled contacts near pc points
|
| 310 |
+
masked_cosine_loss = tf.multiply(cosine_distance, grasp_success_labels_pc)
|
| 311 |
+
dir_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_cosine_loss, axis=1) / pos_grasps_in_view)
|
| 312 |
+
|
| 313 |
+
### Grasp Approach Loss
|
| 314 |
+
approach_labels_orthog = tf.math.l2_normalize(approach_labels_pc_cam - tf.reduce_sum(tf.multiply(grasp_dir_head, approach_labels_pc_cam), axis=2, keepdims=True)*grasp_dir_head, axis=2)
|
| 315 |
+
cosine_distance_approach = tf.constant(1.)-tf.reduce_sum(tf.multiply(approach_labels_orthog, approach_dir_head), axis=2)
|
| 316 |
+
masked_approach_loss = tf.multiply(cosine_distance_approach, grasp_success_labels_pc)
|
| 317 |
+
approach_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_approach_loss, axis=1) / pos_grasps_in_view)
|
| 318 |
+
|
| 319 |
+
### Grasp Offset/Thickness Loss
|
| 320 |
+
if global_config['MODEL']['bin_offsets']:
|
| 321 |
+
if global_config['LOSS']['offset_loss_type'] == 'softmax_cross_entropy':
|
| 322 |
+
offset_loss = tf.losses.softmax_cross_entropy(offset_labels_pc, grasp_offset_head)
|
| 323 |
+
else:
|
| 324 |
+
offset_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=offset_labels_pc, logits=grasp_offset_head)
|
| 325 |
+
|
| 326 |
+
if 'too_small_offset_pred_bin_factor' in global_config['LOSS'] and global_config['LOSS']['too_small_offset_pred_bin_factor']:
|
| 327 |
+
too_small_offset_pred_bin_factor = tf.constant(global_config['LOSS']['too_small_offset_pred_bin_factor'], tf.float32)
|
| 328 |
+
collision_weight = tf.math.cumsum(offset_labels_pc, axis=2, reverse=True)*too_small_offset_pred_bin_factor + tf.constant(1.)
|
| 329 |
+
offset_loss = tf.multiply(collision_weight, offset_loss)
|
| 330 |
+
|
| 331 |
+
offset_loss = tf.reduce_mean(tf.multiply(tf.reshape(tf_bin_weights,(1,1,-1)), offset_loss),axis=2)
|
| 332 |
+
else:
|
| 333 |
+
offset_loss = (grasp_offset_head[:,:,0] - offset_labels_pc[:,:,0])**2
|
| 334 |
+
masked_offset_loss = tf.multiply(offset_loss, grasp_success_labels_pc)
|
| 335 |
+
offset_loss = tf.reduce_mean(tf.reduce_sum(masked_offset_loss, axis=1) / pos_grasps_in_view)
|
| 336 |
+
|
| 337 |
+
### Grasp Confidence Loss
|
| 338 |
+
bin_ce_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.expand_dims(grasp_success_labels_pc,axis=2), logits=end_points['binary_seg_head'])
|
| 339 |
+
if 'topk_confidence' in global_config['LOSS'] and global_config['LOSS']['topk_confidence']:
|
| 340 |
+
bin_ce_loss,_ = tf.math.top_k(tf.squeeze(bin_ce_loss), k=global_config['LOSS']['topk_confidence'])
|
| 341 |
+
bin_ce_loss = tf.reduce_mean(bin_ce_loss)
|
| 342 |
+
|
| 343 |
+
return dir_cosine_loss, bin_ce_loss, offset_loss, approach_cosine_loss, adds_loss, adds_loss_gt2pred, gt_control_points, pred_control_points, pos_grasps_in_view
|
| 344 |
+
|
| 345 |
+
def compute_labels(pos_contact_pts_mesh, pos_contact_dirs_mesh, pos_contact_offsets, pos_contact_approaches_mesh, pos_finger_diffs, neg_contact_pts_mesh,
|
| 346 |
+
neg_contact_dirs_mesh, neg_contact_offsets, neg_contact_approaches_mesh, neg_finger_diffs, pc_cam_pl, camera_pose_pl, global_config):
|
| 347 |
+
"""
|
| 348 |
+
for every point find nearest contact points
|
| 349 |
+
group and average labels
|
| 350 |
+
"""
|
| 351 |
+
label_config = global_config['DATA']['labels']
|
| 352 |
+
model_config = global_config['MODEL']
|
| 353 |
+
|
| 354 |
+
contact_distance_offset = model_config['contact_distance_offset']
|
| 355 |
+
bin_offsets = model_config['bin_offsets']
|
| 356 |
+
|
| 357 |
+
mode = label_config['contact_gather']
|
| 358 |
+
nsample = label_config['k']
|
| 359 |
+
radius = label_config['max_radius']
|
| 360 |
+
filter_z = label_config['filter_z']
|
| 361 |
+
z_val = label_config['z_val']
|
| 362 |
+
|
| 363 |
+
xyz_cam = pc_cam_pl[:,:,:3]
|
| 364 |
+
pad_homog = tf.ones((xyz_cam.shape[0],xyz_cam.shape[1], 1))
|
| 365 |
+
pc_mesh = tf.matmul(tf.concat([xyz_cam, pad_homog], 2), tf.transpose(tf.linalg.inv(camera_pose_pl),perm=[0, 2, 1]))[:,:,:3]
|
| 366 |
+
|
| 367 |
+
if contact_distance_offset:
|
| 368 |
+
# finger_diff = tf.norm(pos_contact_pts_mesh[1::2,:]-pos_contact_pts_mesh[::2,:] + 0.0000001, axis=1, keepdims=True)
|
| 369 |
+
# finger_diff = tf.keras.backend.repeat_elements(finger_diff, 2, axis=0)
|
| 370 |
+
contact_point_offsets_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_finger_diffs,0), pc_mesh.shape[0], axis=0)
|
| 371 |
+
else:
|
| 372 |
+
contact_point_offsets_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_offsets,0), pc_mesh.shape[0], axis=0)
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
pad_homog2 = tf.ones((pc_mesh.shape[0], pos_contact_dirs_mesh.shape[0], 1))
|
| 376 |
+
contact_point_dirs_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0)
|
| 377 |
+
contact_point_dirs_batch_cam = tf.matmul(contact_point_dirs_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 378 |
+
|
| 379 |
+
pos_contact_approaches_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_approaches_mesh,0), pc_mesh.shape[0], axis=0)
|
| 380 |
+
pos_contact_approaches_batch_cam = tf.matmul(pos_contact_approaches_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 381 |
+
|
| 382 |
+
contact_point_batch_mesh = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_pts_mesh,0), pc_mesh.shape[0], axis=0)
|
| 383 |
+
contact_point_batch_cam = tf.matmul(tf.concat([contact_point_batch_mesh, pad_homog2], 2), tf.transpose(camera_pose_pl, perm=[0, 2, 1]))[:,:,:3]
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
# orthogonal = tf.reduce_sum(pos_contact_approaches_batch_cam * contact_point_dirs_batch_cam, axis=2)
|
| 387 |
+
if filter_z:
|
| 388 |
+
dir_filter_passed = tf.keras.backend.repeat_elements(tf.math.greater(contact_point_dirs_batch_cam[:,:,2:3], tf.constant([z_val])), 3, axis=2)
|
| 389 |
+
contact_point_batch_mesh = tf.where(dir_filter_passed, contact_point_batch_mesh, tf.ones_like(contact_point_batch_mesh)*100000)
|
| 390 |
+
# contact_point_dirs_batch_cam = tf.boolean_mask(contact_point_dirs_batch_cam, dir_filter_passed)
|
| 391 |
+
# print(contact_point_dirs_batch_cam.shape)
|
| 392 |
+
# contact_point_batch_mesh = tf.boolean_mask(contact_point_batch_mesh, dir_filter_passed)
|
| 393 |
+
# else:
|
| 394 |
+
# contact_point_dirs_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0)
|
| 395 |
+
|
| 396 |
+
# TODO: Divide into positive and negative grasps; for now only insert positive contacts (otherwise mean direction does not make sense)
|
| 397 |
+
if mode == 'mean':
|
| 398 |
+
close_contact_pt_idcs,_ = query_ball_point(radius, nsample, contact_point_batch_mesh, pc_mesh) # (batch_size, npoint, nsample)
|
| 399 |
+
|
| 400 |
+
grasp_success_labels_pc = tf.cast(tf.reduce_sum(close_contact_pt_idcs, axis=2)>0, tf.float32) # (batch_size, num_point)
|
| 401 |
+
|
| 402 |
+
# contact_point to contact_dir mapping
|
| 403 |
+
grouped_dirs_mesh = group_point(contact_point_dirs_batch, close_contact_pt_idcs) # (batch_size, num_point, nsample, 3)
|
| 404 |
+
|
| 405 |
+
# grouped_dirs_mesh = tf.gather_nd(tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0), close_contact_pt_idcs)
|
| 406 |
+
elif mode == 'knn':
|
| 407 |
+
# dists, close_contact_pt_idcs = knn_point(nsample, contact_point_batch_mesh, pc_mesh) # (batch_size, num_point, nsample)
|
| 408 |
+
|
| 409 |
+
# squared_dists_all = tf.reduce_sum((tf.expand_dims(contact_point_batch_mesh,1)-tf.expand_dims(pc_mesh,2))**2,axis=3)
|
| 410 |
+
squared_dists_all = tf.reduce_sum((tf.expand_dims(contact_point_batch_cam,1)-tf.expand_dims(xyz_cam,2))**2,axis=3)
|
| 411 |
+
neg_squared_dists_k, close_contact_pt_idcs = tf.math.top_k(-squared_dists_all, k=nsample, sorted=False)
|
| 412 |
+
squared_dists_k = -neg_squared_dists_k
|
| 413 |
+
|
| 414 |
+
# Distance check, careful it depends on point density
|
| 415 |
+
grasp_success_labels_pc = tf.cast(tf.less(tf.reduce_mean(squared_dists_k, axis=2), radius*radius), tf.float32) # (batch_size, num_point)
|
| 416 |
+
|
| 417 |
+
grouped_dirs_pc_cam = group_point(contact_point_dirs_batch_cam, close_contact_pt_idcs)
|
| 418 |
+
grouped_approaches_pc_cam = group_point(pos_contact_approaches_batch_cam, close_contact_pt_idcs)
|
| 419 |
+
grouped_offsets = group_point(tf.expand_dims(contact_point_offsets_batch,2), close_contact_pt_idcs)
|
| 420 |
+
# not sure for nsample > 1
|
| 421 |
+
dir_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_dirs_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 422 |
+
approach_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_approaches_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 423 |
+
offset_labels_pc = tf.reduce_mean(grouped_offsets, axis=2)
|
| 424 |
+
|
| 425 |
+
else:
|
| 426 |
+
raise NotImplementedError
|
| 427 |
+
# if filter_z:
|
| 428 |
+
# pad_homog3 = tf.ones((dir_labels_mesh.shape[0], dir_labels_mesh.shape[1], 1))
|
| 429 |
+
# dir_labels_pc_cam = tf.matmul(tf.concat([dir_labels_mesh,pad_homog3], 2), tf.transpose(camera_pose_pl, perm=[0, 2, 1]))[:,:,:3] # (batch_size, num_point, 3)
|
| 430 |
+
|
| 431 |
+
return dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam
|
| 432 |
+
|
| 433 |
+
if __name__=='__main__':
|
| 434 |
+
with tf.Graph().as_default():
|
| 435 |
+
inputs = tf.zeros((32,2048,6))
|
| 436 |
+
net, _ = get_model(inputs, tf.constant(True))
|
| 437 |
+
print(net)
|
scene_test_2048_bs3_hor_sigma_001/train_grasp_direct.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import argparse
|
| 4 |
+
import math
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
import numpy as np
|
| 7 |
+
import socket
|
| 8 |
+
import importlib
|
| 9 |
+
import time
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
import glob
|
| 12 |
+
import json
|
| 13 |
+
import yaml
|
| 14 |
+
|
| 15 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 17 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 18 |
+
sys.path.append(os.path.join(ROOT_DIR))
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
import tensorflow.compat.v1 as tf
|
| 22 |
+
tf.disable_eager_execution()
|
| 23 |
+
TF2 = True
|
| 24 |
+
physical_devices = tf.config.experimental.list_physical_devices('GPU')
|
| 25 |
+
print(physical_devices)
|
| 26 |
+
tf.config.experimental.set_memory_growth(physical_devices[0], True)
|
| 27 |
+
except:
|
| 28 |
+
import tensorflow as tf
|
| 29 |
+
TF2 = False
|
| 30 |
+
|
| 31 |
+
POINT_DIR_NGC = os.path.join(ROOT_DIR, 'pointnet2')
|
| 32 |
+
if os.path.exists(POINT_DIR_NGC):
|
| 33 |
+
sys.path.append(os.path.join(POINT_DIR_NGC, 'models'))
|
| 34 |
+
sys.path.append(os.path.join(POINT_DIR_NGC, 'utils'))
|
| 35 |
+
else:
|
| 36 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'models'))
|
| 37 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 38 |
+
|
| 39 |
+
import provider
|
| 40 |
+
import sample
|
| 41 |
+
import utilities
|
| 42 |
+
from data import PointCloudReader, load_mesh_path_and_scale, preprocess_pc_for_inference, load_filtered_contact_data, load_scene_contacts, load_obj_scales_cats, inverse_transform, center_pc_convert_cam
|
| 43 |
+
from summaries import top_grasp_acc_summaries, build_summary_ops, build_file_writers
|
| 44 |
+
from tf_train_ops import load_labels_and_losses, build_train_op
|
| 45 |
+
from surface_grasp_estimator import GraspEstimator
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def train(global_config, LOG_DIR):
|
| 49 |
+
|
| 50 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 51 |
+
mesh_scales, mesh_cats = load_obj_scales_cats(global_config['DATA']['data_path'])
|
| 52 |
+
contact_infos, scene_obj_paths, scene_obj_transforms = load_scene_contacts(global_config['DATA']['data_path'])
|
| 53 |
+
num_train_samples = len(contact_infos)-global_config['DATA']['num_test_scenes']
|
| 54 |
+
num_test_samples = global_config['DATA']['num_test_scenes']
|
| 55 |
+
else:
|
| 56 |
+
scene_obj_paths, scene_obj_transforms = None, None
|
| 57 |
+
train_contact_paths, test_contact_paths, contact_infos, mesh_scales = load_filtered_contact_data(global_config['DATA']['data_path'], min_pos_contacts=1, classes=global_config['DATA']['classes'])
|
| 58 |
+
num_train_samples = len(train_contact_paths)
|
| 59 |
+
num_test_samples = len(test_contact_paths)
|
| 60 |
+
|
| 61 |
+
print('using %s meshes' % (num_train_samples + num_test_samples))
|
| 62 |
+
|
| 63 |
+
if 'train_and_test' in global_config['DATA'] and global_config['DATA']['train_and_test']:
|
| 64 |
+
num_train_samples = num_train_samples + num_test_samples
|
| 65 |
+
num_test_samples = 0
|
| 66 |
+
print('using train and test data')
|
| 67 |
+
|
| 68 |
+
pcreader = PointCloudReader(
|
| 69 |
+
root_folder=global_config['DATA']['data_path'],
|
| 70 |
+
batch_size=global_config['OPTIMIZER']['batch_size'],
|
| 71 |
+
num_grasp_clusters=None,
|
| 72 |
+
estimate_normals=global_config['DATA']['input_normals'],
|
| 73 |
+
npoints=global_config['DATA']['num_point'],
|
| 74 |
+
raw_num_points=global_config['DATA']['raw_num_points'],
|
| 75 |
+
use_uniform_quaternions = global_config['DATA']['use_uniform_quaternions'],
|
| 76 |
+
run_in_another_process = False,
|
| 77 |
+
mesh_scales = mesh_scales,
|
| 78 |
+
scene_obj_paths = scene_obj_paths,
|
| 79 |
+
scene_obj_transforms = scene_obj_transforms,
|
| 80 |
+
num_train_samples = num_train_samples,
|
| 81 |
+
num_test_samples = num_test_samples,
|
| 82 |
+
use_farthest_point = global_config['DATA']['use_farthest_point'],
|
| 83 |
+
intrinsics=global_config['DATA']['intrinsics']
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
with tf.Graph().as_default():
|
| 87 |
+
|
| 88 |
+
# Build the model
|
| 89 |
+
grasp_estimator = GraspEstimator(global_config)
|
| 90 |
+
|
| 91 |
+
ops = grasp_estimator.build_network()
|
| 92 |
+
|
| 93 |
+
# contact_tensors = load_contact_grasps(contact_infos, global_config['DATA'])
|
| 94 |
+
|
| 95 |
+
loss_ops = load_labels_and_losses(grasp_estimator, contact_infos, global_config)
|
| 96 |
+
|
| 97 |
+
ops.update(loss_ops)
|
| 98 |
+
ops['train_op'] = build_train_op(ops['loss'], ops['step'], global_config)
|
| 99 |
+
|
| 100 |
+
# Add ops to save and restore all the variables.
|
| 101 |
+
saver = tf.train.Saver(save_relative_paths=True, keep_checkpoint_every_n_hours=4)
|
| 102 |
+
|
| 103 |
+
# Create a session
|
| 104 |
+
config = tf.ConfigProto()
|
| 105 |
+
config.gpu_options.allow_growth = True
|
| 106 |
+
config.allow_soft_placement = True
|
| 107 |
+
# config.log_device_placement = False
|
| 108 |
+
sess = tf.Session(config=config)
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
summary_ops = build_summary_ops(ops, sess, global_config)
|
| 112 |
+
|
| 113 |
+
grasp_estimator.load_weights(sess, saver, LOG_DIR, mode='train')
|
| 114 |
+
file_writers = build_file_writers(sess, LOG_DIR)
|
| 115 |
+
|
| 116 |
+
batches_per_epoch = num_train_samples #// global_config['OPTIMIZER']['batch_size'] + 1
|
| 117 |
+
cur_epoch = sess.run(ops['step']) // (batches_per_epoch * global_config['OPTIMIZER']['batch_size'])
|
| 118 |
+
for epoch in range(cur_epoch, global_config['OPTIMIZER']['max_epoch']):
|
| 119 |
+
log_string('**** EPOCH %03d ****' % (epoch))
|
| 120 |
+
|
| 121 |
+
sess.run(ops['iterator'].initializer)
|
| 122 |
+
epoch_time = time.time()
|
| 123 |
+
step = train_one_epoch(sess, ops, summary_ops, file_writers, pcreader)
|
| 124 |
+
print('trained %s batches in: ' % batches_per_epoch, time.time()-epoch_time)
|
| 125 |
+
|
| 126 |
+
# Save the variables to disk.
|
| 127 |
+
if (epoch+1) % 1 == 0:
|
| 128 |
+
save_path = saver.save(sess, os.path.join(LOG_DIR, "model.ckpt"), global_step=step, write_meta_graph=False)
|
| 129 |
+
log_string("Model saved in file: %s" % save_path)
|
| 130 |
+
|
| 131 |
+
if epoch % 1 == 0 and num_test_samples > 0:
|
| 132 |
+
eval_time = time.time()
|
| 133 |
+
eval_test_objects(sess, ops, summary_ops, file_writers, pcreader)
|
| 134 |
+
print('evaluation time: ', time.time()-eval_time)
|
| 135 |
+
|
| 136 |
+
def train_one_epoch(sess, ops, summary_ops, file_writers, pcreader):
|
| 137 |
+
""" ops: dict mapping from string to tf ops """
|
| 138 |
+
is_training = True
|
| 139 |
+
|
| 140 |
+
log_string(str(datetime.now()))
|
| 141 |
+
|
| 142 |
+
loss_sum, loss_sum_dir, loss_sum_ce, loss_sum_off, loss_sum_app, loss_sum_adds, loss_sum_adds_gt2pred, time_sum = 8 * [0]
|
| 143 |
+
|
| 144 |
+
# batches_per_epoch = pcreader._num_train_samples // pcreader._batch_size
|
| 145 |
+
## define one epoch = all objects/scenes seen
|
| 146 |
+
batches_per_epoch = pcreader._num_train_samples
|
| 147 |
+
|
| 148 |
+
# run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE, report_tensor_allocations_upon_oom = True)
|
| 149 |
+
|
| 150 |
+
for batch_idx in range(batches_per_epoch):
|
| 151 |
+
get_time = time.time()
|
| 152 |
+
|
| 153 |
+
batch_data, cam_poses, obj_idx = pcreader.get_batch(batch_idx)
|
| 154 |
+
print(time.time()- get_time)
|
| 155 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 156 |
+
# OpenCV OpenGL conversion
|
| 157 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 158 |
+
print(time.time() - get_time)
|
| 159 |
+
# Augment batched point clouds by rotation and jittering
|
| 160 |
+
# aug_data = provider.random_scale_point_cloud(batch_data, scale_low=0.8, scale_high=1.25)
|
| 161 |
+
if 'sigma' in global_config['DATA'] and global_config['DATA']['sigma'] > 0:
|
| 162 |
+
batch_data[:,:,0:3] = provider.jitter_point_cloud(batch_data[:,:,0:3],
|
| 163 |
+
sigma=global_config['DATA']['sigma'],
|
| 164 |
+
clip=global_config['DATA']['clip']*2)
|
| 165 |
+
|
| 166 |
+
feed_dict = {ops['pointclouds_pl']: batch_data,
|
| 167 |
+
ops['cam_poses_pl']: cam_poses,
|
| 168 |
+
ops['obj_idx_pl']: obj_idx,
|
| 169 |
+
# ops['labels_pl']: batch_label,
|
| 170 |
+
ops['is_training_pl']: is_training}
|
| 171 |
+
|
| 172 |
+
step, summary, _, loss_val, dir_loss, bin_ce_loss, \
|
| 173 |
+
offset_loss, approach_loss, adds_loss, adds_gt2pred_loss,pos_grasps_in_view, scene_idx = sess.run([ops['step'], summary_ops['merged'], ops['train_op'],
|
| 174 |
+
ops['loss'], ops['dir_loss'], ops['bin_ce_loss'],
|
| 175 |
+
ops['offset_loss'], ops['approach_loss'], ops['adds_loss'],
|
| 176 |
+
ops['adds_gt2pred_loss'], ops['pos_grasps_in_view'], ops['scene_idx']], feed_dict=feed_dict)
|
| 177 |
+
print(time.time()- get_time)
|
| 178 |
+
print(pos_grasps_in_view)
|
| 179 |
+
print(scene_idx, obj_idx)
|
| 180 |
+
assert scene_idx[0] == obj_idx
|
| 181 |
+
|
| 182 |
+
loss_sum += loss_val
|
| 183 |
+
loss_sum_dir += dir_loss
|
| 184 |
+
loss_sum_ce += bin_ce_loss
|
| 185 |
+
loss_sum_off += offset_loss
|
| 186 |
+
loss_sum_app += approach_loss
|
| 187 |
+
loss_sum_adds += adds_loss
|
| 188 |
+
loss_sum_adds_gt2pred += adds_gt2pred_loss
|
| 189 |
+
time_sum += time.time() - get_time
|
| 190 |
+
|
| 191 |
+
if (batch_idx+1)%10 == 0:
|
| 192 |
+
file_writers['train_writer'].add_summary(summary, step)
|
| 193 |
+
log_string('total loss: %f \t dir loss: %f \t ce loss: %f \t off loss: %f \t app loss: %f adds loss: %f \t adds_gt2pred loss: %f \t batch time: %f' % (loss_sum/10,loss_sum_dir/10,loss_sum_ce/10, loss_sum_off/10, loss_sum_app/10, loss_sum_adds/10, loss_sum_adds_gt2pred/10, time_sum/10))
|
| 194 |
+
# log_string('accuracy: %f' % (total_correct / float(total_seen)))
|
| 195 |
+
loss_sum, loss_sum_dir, loss_sum_ce, loss_sum_off, loss_sum_app, loss_sum_adds, loss_sum_adds_gt2pred, time_sum = 8 * [0]
|
| 196 |
+
|
| 197 |
+
return step
|
| 198 |
+
|
| 199 |
+
def eval_test_objects(sess, ops, summary_ops, file_writers, pcreader, max_eval_objects=500):
|
| 200 |
+
""" ops: dict mapping from string to tf ops """
|
| 201 |
+
is_training = False
|
| 202 |
+
|
| 203 |
+
log_string(str(datetime.now()))
|
| 204 |
+
losses = []
|
| 205 |
+
losses_dir = []
|
| 206 |
+
losses_ce = []
|
| 207 |
+
losses_off = []
|
| 208 |
+
losses_app = []
|
| 209 |
+
losses_add = []
|
| 210 |
+
losses_add_gt2pred = []
|
| 211 |
+
|
| 212 |
+
# resets accumulation of pr and auc data
|
| 213 |
+
sess.run(summary_ops['pr_reset_op'])
|
| 214 |
+
|
| 215 |
+
for batch_idx in np.arange(min(pcreader._num_test_samples, max_eval_objects)):
|
| 216 |
+
|
| 217 |
+
batch_data, cam_poses, obj_idx = pcreader.get_batch(obj_idx=pcreader._num_train_samples + batch_idx)
|
| 218 |
+
|
| 219 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 220 |
+
# OpenCV OpenGL conversion
|
| 221 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 222 |
+
# Augment batched point clouds by rotation and jittering
|
| 223 |
+
# aug_data = provider.random_scale_point_cloud(batch_data)
|
| 224 |
+
# batch_data[:,:,0:3] = provider.jitter_point_cloud(batch_data[:,:,0:3])
|
| 225 |
+
feed_dict = {ops['pointclouds_pl']: batch_data,
|
| 226 |
+
ops['cam_poses_pl']: cam_poses,
|
| 227 |
+
ops['obj_idx_pl']: obj_idx,
|
| 228 |
+
ops['is_training_pl']: is_training}
|
| 229 |
+
|
| 230 |
+
scene_idx, step, loss_val, dir_loss, bin_ce_loss, offset_loss, approach_loss, adds_loss, adds_gt2pred_loss, pr_summary,_,_,_ = sess.run([ops['scene_idx'], ops['step'], ops['loss'], ops['dir_loss'], ops['bin_ce_loss'],
|
| 231 |
+
ops['offset_loss'], ops['approach_loss'], ops['adds_loss'], ops['adds_gt2pred_loss'],
|
| 232 |
+
summary_ops['merged_eval'], summary_ops['pr_update_op'],
|
| 233 |
+
summary_ops['auc_update_op']] + [summary_ops['acc_update_ops']], feed_dict=feed_dict)
|
| 234 |
+
assert scene_idx[0] == (pcreader._num_train_samples + batch_idx)
|
| 235 |
+
losses.append(loss_val)
|
| 236 |
+
losses_dir.append(dir_loss)
|
| 237 |
+
losses_ce.append(bin_ce_loss)
|
| 238 |
+
losses_off.append(offset_loss)
|
| 239 |
+
losses_app.append(approach_loss)
|
| 240 |
+
losses_add.append(adds_loss)
|
| 241 |
+
losses_add_gt2pred.append(adds_gt2pred_loss)
|
| 242 |
+
|
| 243 |
+
loss_mean = np.mean(losses)
|
| 244 |
+
losses_dir_mean = np.mean(losses_dir)
|
| 245 |
+
loss_ce_mean = np.mean(losses_ce)
|
| 246 |
+
loss_off_mean = np.mean(losses_off)
|
| 247 |
+
loss_app_mean = np.mean(losses_app)
|
| 248 |
+
loss_add_mean = np.mean(losses_add)
|
| 249 |
+
loss_add_gt2pred_mean = np.mean(losses_add_gt2pred)
|
| 250 |
+
|
| 251 |
+
file_writers['test_writer'].add_summary(pr_summary, step)
|
| 252 |
+
|
| 253 |
+
log_string('mean val loss: %f \t mean val dir loss: %f \t mean val ce loss: %f \t mean off loss: %f \t mean app loss: %f \t mean adds loss: %f \t mean adds_gt2pred loss: %f' % (loss_mean, losses_dir_mean, loss_ce_mean, loss_off_mean, loss_app_mean, loss_add_mean, loss_add_gt2pred_mean))
|
| 254 |
+
|
| 255 |
+
return step
|
| 256 |
+
|
| 257 |
+
if __name__ == "__main__":
|
| 258 |
+
|
| 259 |
+
parser = argparse.ArgumentParser()
|
| 260 |
+
parser.add_argument('--gpu', type=int, default=0, help='GPU to use [default: GPU 0]')
|
| 261 |
+
parser.add_argument('--log_dir', default='/result', help='Log dir [default: log]')
|
| 262 |
+
parser.add_argument('--data_path', type=str, default=None, help='internal grasp root dir')
|
| 263 |
+
parser.add_argument('--max_epoch', type=int, default=None, help='Epoch to run [default: 201]')
|
| 264 |
+
parser.add_argument('--batch_size', type=int, default=None, help='Batch Size during training [default: 32]')
|
| 265 |
+
parser.add_argument('--classes', nargs="*", type=str, default=None, help='train or test classes')
|
| 266 |
+
parser.add_argument('--arg_configs', nargs="*", type=str, default=[], help='overwrite config parameters')
|
| 267 |
+
FLAGS = parser.parse_args()
|
| 268 |
+
|
| 269 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = str(FLAGS.gpu)
|
| 270 |
+
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
| 271 |
+
|
| 272 |
+
if not os.path.exists(FLAGS.log_dir):
|
| 273 |
+
os.makedirs(FLAGS.log_dir)
|
| 274 |
+
|
| 275 |
+
os.system('cp pointnet2_grasp_direct.py %s' % (FLAGS.log_dir)) # bkp of model def
|
| 276 |
+
os.system('cp train_grasp_direct.py %s' % (FLAGS.log_dir)) # bkp of train procedure
|
| 277 |
+
|
| 278 |
+
LOG_FOUT = open(os.path.join(FLAGS.log_dir, 'log_train.txt'), 'w')
|
| 279 |
+
LOG_FOUT.write(str(FLAGS)+'\n')
|
| 280 |
+
def log_string(out_str):
|
| 281 |
+
LOG_FOUT.write(out_str+'\n')
|
| 282 |
+
LOG_FOUT.flush()
|
| 283 |
+
print(out_str)
|
| 284 |
+
|
| 285 |
+
global_config = utilities.load_config(FLAGS.log_dir, batch_size=FLAGS.batch_size, max_epoch=FLAGS.max_epoch, data_path= FLAGS.data_path, classes=FLAGS.classes, arg_configs=FLAGS.arg_configs)
|
| 286 |
+
|
| 287 |
+
log_string(str(global_config))
|
| 288 |
+
log_string('pid: %s'%(str(os.getpid())))
|
| 289 |
+
|
| 290 |
+
train(global_config, FLAGS.log_dir)
|
| 291 |
+
|
| 292 |
+
LOG_FOUT.close()
|
scene_test_2048_bs3_hor_sigma_0025/checkpoint
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_checkpoint_path: "model.ckpt-45045"
|
| 2 |
+
all_model_checkpoint_paths: "model.ckpt-108108"
|
| 3 |
+
all_model_checkpoint_paths: "model.ckpt-117117"
|
| 4 |
+
all_model_checkpoint_paths: "model.ckpt-126126"
|
| 5 |
+
all_model_checkpoint_paths: "model.ckpt-135135"
|
| 6 |
+
all_model_checkpoint_paths: "model.ckpt-144144"
|
scene_test_2048_bs3_hor_sigma_0025/config.yaml
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
DATA:
|
| 2 |
+
gripper_width: 0.08
|
| 3 |
+
input_normals: false
|
| 4 |
+
use_uniform_quaternions: False
|
| 5 |
+
train_on_scenes: True
|
| 6 |
+
labels:
|
| 7 |
+
to_gpu: False
|
| 8 |
+
bin_weights:
|
| 9 |
+
- 0.16652107
|
| 10 |
+
- 0.21488856
|
| 11 |
+
- 0.37031708
|
| 12 |
+
- 0.55618503
|
| 13 |
+
- 0.75124664
|
| 14 |
+
- 0.93943357
|
| 15 |
+
- 1.07824539
|
| 16 |
+
- 1.19423112
|
| 17 |
+
- 1.55731375
|
| 18 |
+
- 3.17161779
|
| 19 |
+
contact_gather: knn
|
| 20 |
+
filter_z: true
|
| 21 |
+
k: 1
|
| 22 |
+
max_radius: 0.005
|
| 23 |
+
min_unique_pos_contacts: 1
|
| 24 |
+
num_neg_contacts: 0
|
| 25 |
+
num_pos_contacts: 10000
|
| 26 |
+
offset_bins:
|
| 27 |
+
- 0
|
| 28 |
+
- 0.00794435329
|
| 29 |
+
- 0.0158887021
|
| 30 |
+
- 0.0238330509
|
| 31 |
+
- 0.0317773996
|
| 32 |
+
- 0.0397217484
|
| 33 |
+
- 0.0476660972
|
| 34 |
+
- 0.055610446
|
| 35 |
+
- 0.0635547948
|
| 36 |
+
- 0.0714991435
|
| 37 |
+
- 0.08
|
| 38 |
+
z_val: -0.1
|
| 39 |
+
raw_num_points: 20000
|
| 40 |
+
ndataset_points: 20000
|
| 41 |
+
num_point: 2048
|
| 42 |
+
sigma: 0.0025
|
| 43 |
+
clip: 0.005
|
| 44 |
+
use_farthest_point: false
|
| 45 |
+
train_and_test: false
|
| 46 |
+
num_test_scenes: 1000
|
| 47 |
+
intrinsics: 'realsense'
|
| 48 |
+
LOSS:
|
| 49 |
+
min_geom_loss_divisor: 1.0
|
| 50 |
+
max_geom_loss_divisor: 100.0
|
| 51 |
+
offset_loss_type: sigmoid_cross_entropy
|
| 52 |
+
too_small_offset_pred_bin_factor: 0
|
| 53 |
+
topk_confidence: 512
|
| 54 |
+
MODEL:
|
| 55 |
+
bin_offsets: true
|
| 56 |
+
contact_distance_offset: true
|
| 57 |
+
dir_vec_length_offset: false
|
| 58 |
+
grasp_conf_head:
|
| 59 |
+
conv1d: 1
|
| 60 |
+
dropout_keep: 0.5
|
| 61 |
+
grasp_dir_head:
|
| 62 |
+
conv1d: 3
|
| 63 |
+
dropout_keep: 0.7
|
| 64 |
+
joint_head:
|
| 65 |
+
conv1d: 4
|
| 66 |
+
dropout_keep: 0.7
|
| 67 |
+
joint_heads: false
|
| 68 |
+
larger_model: false
|
| 69 |
+
asymmetric_model: true
|
| 70 |
+
model: contact_graspnet
|
| 71 |
+
pointnet_fp_modules:
|
| 72 |
+
- mlp:
|
| 73 |
+
- 256
|
| 74 |
+
- 256
|
| 75 |
+
- mlp:
|
| 76 |
+
- 256
|
| 77 |
+
- 128
|
| 78 |
+
- mlp:
|
| 79 |
+
- 128
|
| 80 |
+
- 128
|
| 81 |
+
- 128
|
| 82 |
+
pointnet_sa_module:
|
| 83 |
+
group_all: true
|
| 84 |
+
mlp:
|
| 85 |
+
- 256
|
| 86 |
+
- 512
|
| 87 |
+
- 1024
|
| 88 |
+
pointnet_sa_modules_msg:
|
| 89 |
+
- mlp_list:
|
| 90 |
+
- - 32
|
| 91 |
+
- 32
|
| 92 |
+
- 64
|
| 93 |
+
- - 64
|
| 94 |
+
- 64
|
| 95 |
+
- 128
|
| 96 |
+
- - 64
|
| 97 |
+
- 96
|
| 98 |
+
- 128
|
| 99 |
+
npoint: 2048
|
| 100 |
+
nsample_list:
|
| 101 |
+
- 32
|
| 102 |
+
- 64
|
| 103 |
+
- 128
|
| 104 |
+
radius_list:
|
| 105 |
+
- 0.02
|
| 106 |
+
- 0.04
|
| 107 |
+
- 0.08
|
| 108 |
+
- mlp_list:
|
| 109 |
+
- - 64
|
| 110 |
+
- 64
|
| 111 |
+
- 128
|
| 112 |
+
- - 128
|
| 113 |
+
- 128
|
| 114 |
+
- 256
|
| 115 |
+
- - 128
|
| 116 |
+
- 128
|
| 117 |
+
- 256
|
| 118 |
+
npoint: 512
|
| 119 |
+
nsample_list:
|
| 120 |
+
- 64
|
| 121 |
+
- 64
|
| 122 |
+
- 128
|
| 123 |
+
radius_list:
|
| 124 |
+
- 0.04
|
| 125 |
+
- 0.08
|
| 126 |
+
- 0.16
|
| 127 |
+
- mlp_list:
|
| 128 |
+
- - 64
|
| 129 |
+
- 64
|
| 130 |
+
- 128
|
| 131 |
+
- - 128
|
| 132 |
+
- 128
|
| 133 |
+
- 256
|
| 134 |
+
- - 128
|
| 135 |
+
- 128
|
| 136 |
+
- 256
|
| 137 |
+
npoint: 128
|
| 138 |
+
nsample_list:
|
| 139 |
+
- 64
|
| 140 |
+
- 64
|
| 141 |
+
- 128
|
| 142 |
+
radius_list:
|
| 143 |
+
- 0.08
|
| 144 |
+
- 0.16
|
| 145 |
+
- 0.32
|
| 146 |
+
pred_contact_approach: true
|
| 147 |
+
pred_contact_base: true
|
| 148 |
+
pred_contact_offset: true
|
| 149 |
+
pred_contact_success: true
|
| 150 |
+
pred_grasps_adds: false
|
| 151 |
+
pred_grasps_adds_gt2pred: false
|
| 152 |
+
OPTIMIZER:
|
| 153 |
+
adds_gt2pred_loss_weight: 1
|
| 154 |
+
adds_loss_weight: 10
|
| 155 |
+
approach_cosine_loss_weight: 1
|
| 156 |
+
batch_size: 14
|
| 157 |
+
bn_decay_clip: 0.99
|
| 158 |
+
bn_decay_decay_rate: 0.5
|
| 159 |
+
bn_decay_decay_step: 200000
|
| 160 |
+
bn_init_decay: 0.5
|
| 161 |
+
decay_rate: 0.7
|
| 162 |
+
decay_step: 200000
|
| 163 |
+
dir_cosine_loss_weight: 1
|
| 164 |
+
learning_rate: 0.001
|
| 165 |
+
max_epoch: 16
|
| 166 |
+
momentum: 0.9
|
| 167 |
+
offset_loss_weight: 1
|
| 168 |
+
optimizer: adam
|
| 169 |
+
score_ce_loss_weight: 1
|
| 170 |
+
TEST:
|
| 171 |
+
center_to_tip: 0.0
|
| 172 |
+
allow_zero_margin: 0
|
| 173 |
+
bin_vals: max
|
| 174 |
+
extra_opening: 0.005
|
| 175 |
+
first_thres: 0.23
|
| 176 |
+
second_thres: 0.18
|
| 177 |
+
max_farthest_points: 150
|
| 178 |
+
num_samples: 200
|
| 179 |
+
save: false
|
| 180 |
+
scale_fac:
|
| 181 |
+
- 1.25
|
| 182 |
+
- 1.0
|
| 183 |
+
- 0.75
|
| 184 |
+
- 0.5
|
| 185 |
+
scales: false
|
| 186 |
+
with_replacement: false
|
| 187 |
+
filter_thres: 0.0001
|
| 188 |
+
|
scene_test_2048_bs3_hor_sigma_0025/log_train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-144144.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:60e005e6497eddeb241dae9c665ca9a43031d3c7e9816038b3bcde4d9619a40f
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-144144.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-45045.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d11992fc4ba7b17891e03788669efcd4795f62f53111137e1c2099c2d8e0dbda
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-45045.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-54054.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e4954c0868a1fde7f6d9cf5da594356538bd17691f34697573701132c9dd0095
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-54054.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-72072.data-00000-of-00001
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4eb1a8476d86815d6ac2aeeb9e8f0ae3dc665024b51fa46bbc6dfad006398226
|
| 3 |
+
size 27860696
|
scene_test_2048_bs3_hor_sigma_0025/model.ckpt-72072.index
ADDED
|
Binary file (21.2 kB). View file
|
|
|
scene_test_2048_bs3_hor_sigma_0025/pointnet2_grasp_direct.py
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 4 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 5 |
+
|
| 6 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 7 |
+
sys.path.append(os.path.join(BASE_DIR, 'utils'))
|
| 8 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 9 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2'))
|
| 10 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2'))
|
| 11 |
+
try:
|
| 12 |
+
import tensorflow.compat.v1 as tf
|
| 13 |
+
tf.disable_eager_execution()
|
| 14 |
+
TF2 = True
|
| 15 |
+
except:
|
| 16 |
+
import tensorflow as tf
|
| 17 |
+
TF2 = False
|
| 18 |
+
|
| 19 |
+
import numpy as np
|
| 20 |
+
import tf_util
|
| 21 |
+
from pointnet_util import pointnet_sa_module, pointnet_fp_module, pointnet_sa_module_msg
|
| 22 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/sampling'))
|
| 23 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/grouping'))
|
| 24 |
+
sys.path.append(os.path.join(ROOT_DIR, 'pointnet2', 'tf_ops/3d_interpolation'))
|
| 25 |
+
from tf_sampling import farthest_point_sample, gather_point
|
| 26 |
+
from tf_grouping import query_ball_point, group_point, knn_point
|
| 27 |
+
from tf_interpolate import three_nn, three_interpolate
|
| 28 |
+
import tf_utils
|
| 29 |
+
|
| 30 |
+
def placeholder_inputs(global_config):
|
| 31 |
+
batch_size = global_config['OPTIMIZER']['batch_size']
|
| 32 |
+
if 'raw_num_points' in global_config['DATA']:
|
| 33 |
+
num_point = global_config['DATA']['raw_num_points']
|
| 34 |
+
else:
|
| 35 |
+
num_point = global_config['DATA']['num_point']
|
| 36 |
+
|
| 37 |
+
input_normals = global_config['DATA']['input_normals']
|
| 38 |
+
|
| 39 |
+
pl_dict = {}
|
| 40 |
+
dim = 6 if input_normals else 3
|
| 41 |
+
pl_dict['pointclouds_pl'] = tf.placeholder(tf.float32, shape=(batch_size, num_point, dim))
|
| 42 |
+
pl_dict['obj_idx_pl'] = tf.placeholder(tf.int32, ())
|
| 43 |
+
pl_dict['cam_poses_pl'] = tf.placeholder(tf.float32, shape=(batch_size, 4, 4))
|
| 44 |
+
pl_dict['is_training_pl'] = tf.placeholder(tf.bool, shape=())
|
| 45 |
+
|
| 46 |
+
return pl_dict #, labels_pl
|
| 47 |
+
|
| 48 |
+
def get_bin_vals(global_config):
|
| 49 |
+
bins_bounds = np.array(global_config['DATA']['labels']['offset_bins'])
|
| 50 |
+
if global_config['TEST']['bin_vals'] == 'max':
|
| 51 |
+
bin_vals = (bins_bounds[1:] + bins_bounds[:-1])/2
|
| 52 |
+
bin_vals[-1] = bins_bounds[-1]
|
| 53 |
+
elif global_config['TEST']['bin_vals'] == 'mean':
|
| 54 |
+
bin_vals = bins_bounds[1:]
|
| 55 |
+
else:
|
| 56 |
+
raise NotImplementedError
|
| 57 |
+
|
| 58 |
+
if not global_config['TEST']['allow_zero_margin']:
|
| 59 |
+
bin_vals = np.minimum(bin_vals, global_config['DATA']['gripper_width']-global_config['TEST']['extra_opening'])
|
| 60 |
+
|
| 61 |
+
tf_bin_vals = tf.constant(bin_vals, tf.float32)
|
| 62 |
+
return tf_bin_vals
|
| 63 |
+
|
| 64 |
+
def get_model(point_cloud, is_training, global_config, bn_decay=None):
|
| 65 |
+
""" Grasp direction PointNet++ """
|
| 66 |
+
|
| 67 |
+
model_config = global_config['MODEL']
|
| 68 |
+
data_config = global_config['DATA']
|
| 69 |
+
|
| 70 |
+
radius_list_0 = model_config['pointnet_sa_modules_msg'][0]['radius_list']
|
| 71 |
+
radius_list_1 = model_config['pointnet_sa_modules_msg'][1]['radius_list']
|
| 72 |
+
nsample_list_0 = model_config['pointnet_sa_modules_msg'][0]['nsample_list']
|
| 73 |
+
nsample_list_1 = model_config['pointnet_sa_modules_msg'][1]['nsample_list']
|
| 74 |
+
mlp_list_0 = model_config['pointnet_sa_modules_msg'][0]['mlp_list']
|
| 75 |
+
mlp_list_1 = model_config['pointnet_sa_modules_msg'][1]['mlp_list']
|
| 76 |
+
npoint_0 = model_config['pointnet_sa_modules_msg'][0]['npoint']
|
| 77 |
+
npoint_1 = model_config['pointnet_sa_modules_msg'][1]['npoint']
|
| 78 |
+
fp_mlp_0 = model_config['pointnet_fp_modules'][0]['mlp']
|
| 79 |
+
fp_mlp_1 = model_config['pointnet_fp_modules'][1]['mlp']
|
| 80 |
+
fp_mlp_2 = model_config['pointnet_fp_modules'][2]['mlp']
|
| 81 |
+
|
| 82 |
+
#larger model
|
| 83 |
+
radius_list_2 = model_config['pointnet_sa_modules_msg'][2]['radius_list']
|
| 84 |
+
nsample_list_2 = model_config['pointnet_sa_modules_msg'][2]['nsample_list']
|
| 85 |
+
npoint_2 = model_config['pointnet_sa_modules_msg'][2]['npoint']
|
| 86 |
+
mlp_list_2 = model_config['pointnet_sa_modules_msg'][2]['mlp_list']
|
| 87 |
+
|
| 88 |
+
input_normals = data_config['input_normals']
|
| 89 |
+
gripper_width = data_config['gripper_width']
|
| 90 |
+
offset_bins = data_config['labels']['offset_bins']
|
| 91 |
+
joint_heads = model_config['joint_heads']
|
| 92 |
+
|
| 93 |
+
# expensive, rather use random only
|
| 94 |
+
if 'raw_num_points' in data_config and data_config['raw_num_points'] != data_config['ndataset_points']:
|
| 95 |
+
point_cloud = gather_point(point_cloud, farthest_point_sample(data_config['ndataset_points'], point_cloud))
|
| 96 |
+
|
| 97 |
+
batch_size = point_cloud.get_shape()[0]
|
| 98 |
+
num_point = point_cloud.get_shape()[1]
|
| 99 |
+
end_points = {}
|
| 100 |
+
l0_xyz = tf.slice(point_cloud, [0,0,0], [-1,-1,3])
|
| 101 |
+
l0_points = tf.slice(point_cloud, [0,0,3], [-1,-1,3]) if input_normals else None
|
| 102 |
+
|
| 103 |
+
l_xyz = [l0_xyz]
|
| 104 |
+
l_points = [l0_points]
|
| 105 |
+
pred_points = l0_xyz
|
| 106 |
+
|
| 107 |
+
# Set abstraction layers
|
| 108 |
+
l1_xyz, l1_points = pointnet_sa_module_msg(l0_xyz, l0_points, npoint_0, radius_list_0, nsample_list_0, mlp_list_0, is_training, bn_decay, scope='layer1')
|
| 109 |
+
l2_xyz, l2_points = pointnet_sa_module_msg(l1_xyz, l1_points, npoint_1, radius_list_1, nsample_list_1,mlp_list_1, is_training, bn_decay, scope='layer2')
|
| 110 |
+
|
| 111 |
+
# large model
|
| 112 |
+
if 'larger_model' in model_config and model_config['larger_model']:
|
| 113 |
+
fp_mlp_3 = model_config['pointnet_fp_modules'][3]['mlp']
|
| 114 |
+
|
| 115 |
+
l3_xyz, l3_points = pointnet_sa_module_msg(l2_xyz, l2_points, npoint_2, radius_list_2, nsample_list_2,mlp_list_2, is_training, bn_decay, scope='layer3')
|
| 116 |
+
l4_xyz, l4_points, _ = pointnet_sa_module(l3_xyz, l3_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer4')
|
| 117 |
+
|
| 118 |
+
# Feature Propagation layers
|
| 119 |
+
l3_points = pointnet_fp_module(l3_xyz, l4_xyz, l3_points, l4_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 120 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 121 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 122 |
+
|
| 123 |
+
l0_points = tf.concat([l0_xyz, l0_points],axis=-1) if input_normals else l0_xyz
|
| 124 |
+
l0_points = pointnet_fp_module(l0_xyz, l1_xyz, l0_points, l1_points, fp_mlp_3, is_training, bn_decay, scope='fa_layer4')
|
| 125 |
+
elif 'asymmetric_model' in model_config and model_config['asymmetric_model']:
|
| 126 |
+
l3_xyz, l3_points = pointnet_sa_module_msg(l2_xyz, l2_points, npoint_2, radius_list_2, nsample_list_2,mlp_list_2, is_training, bn_decay, scope='layer3')
|
| 127 |
+
l4_xyz, l4_points, _ = pointnet_sa_module(l3_xyz, l3_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer4')
|
| 128 |
+
|
| 129 |
+
# Feature Propagation layers
|
| 130 |
+
l3_points = pointnet_fp_module(l3_xyz, l4_xyz, l3_points, l4_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 131 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 132 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 133 |
+
|
| 134 |
+
l0_points = l1_points
|
| 135 |
+
pred_points = l1_xyz
|
| 136 |
+
else:
|
| 137 |
+
l3_xyz, l3_points, _ = pointnet_sa_module(l2_xyz, l2_points, npoint=None, radius=None, nsample=None, mlp=model_config['pointnet_sa_module']['mlp'], mlp2=None, group_all=model_config['pointnet_sa_module']['group_all'], is_training=is_training, bn_decay=bn_decay, scope='layer3')
|
| 138 |
+
|
| 139 |
+
# Feature Propagation layers
|
| 140 |
+
l2_points = pointnet_fp_module(l2_xyz, l3_xyz, l2_points, l3_points, fp_mlp_0, is_training, bn_decay, scope='fa_layer1')
|
| 141 |
+
l1_points = pointnet_fp_module(l1_xyz, l2_xyz, l1_points, l2_points, fp_mlp_1, is_training, bn_decay, scope='fa_layer2')
|
| 142 |
+
|
| 143 |
+
l0_points = tf.concat([l0_xyz, l0_points],axis=-1) if input_normals else l0_xyz
|
| 144 |
+
l0_points = pointnet_fp_module(l0_xyz, l1_xyz, l0_points, l1_points, fp_mlp_2, is_training, bn_decay, scope='fa_layer3')
|
| 145 |
+
|
| 146 |
+
if joint_heads:
|
| 147 |
+
head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 148 |
+
# end_points['feats'] = head
|
| 149 |
+
head = tf_util.dropout(head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 150 |
+
head = tf_util.conv1d(head, 4, 1, padding='VALID', activation_fn=None, scope='fc2')
|
| 151 |
+
grasp_dir_head = tf.slice(head, [0,0,0], [-1,-1,3])
|
| 152 |
+
grasp_dir_head = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 153 |
+
binary_seg_head = tf.slice(head, [0,0,3], [-1,-1,1])
|
| 154 |
+
else:
|
| 155 |
+
# FC layers for grasp direction
|
| 156 |
+
grasp_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1', bn_decay=bn_decay)
|
| 157 |
+
# end_points['feats'] = grasp_dir_head
|
| 158 |
+
grasp_dir_head = tf_util.dropout(grasp_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1')
|
| 159 |
+
grasp_dir_head = tf_util.conv1d(grasp_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3')
|
| 160 |
+
grasp_dir_head_normed = tf.math.l2_normalize(grasp_dir_head, axis=2)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
# FC layers for grasp direction
|
| 164 |
+
approach_dir_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_app', bn_decay=bn_decay)
|
| 165 |
+
# end_points['feats'] = approach_dir_head
|
| 166 |
+
approach_dir_head = tf_util.dropout(approach_dir_head, keep_prob=0.7, is_training=is_training, scope='dp1_app')
|
| 167 |
+
approach_dir_head = tf_util.conv1d(approach_dir_head, 3, 1, padding='VALID', activation_fn=None, scope='fc3_app')
|
| 168 |
+
approach_dir_head_orthog = tf.math.l2_normalize(approach_dir_head - tf.reduce_sum(tf.multiply(grasp_dir_head_normed, approach_dir_head), axis=2, keepdims=True)*grasp_dir_head_normed, axis=2)
|
| 169 |
+
|
| 170 |
+
if model_config['dir_vec_length_offset']:
|
| 171 |
+
grasp_offset_head = tf.norm(grasp_dir_head, axis=2, keepdims=True)
|
| 172 |
+
elif model_config['bin_offsets']:
|
| 173 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 174 |
+
# end_points['feats'] = grasp_offset_head
|
| 175 |
+
# grasp_offset_head = tf_util.dropout(grasp_offset_head, keep_prob=0.7, is_training=is_training, scope='dp1_off')
|
| 176 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, len(offset_bins)-1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 177 |
+
else:
|
| 178 |
+
grasp_offset_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_off', bn_decay=bn_decay)
|
| 179 |
+
# end_points['feats'] = grasp_offset_head
|
| 180 |
+
grasp_offset_head = tf_util.dropout(grasp_offset_head, keep_prob=0.7, is_training=is_training, scope='dp1_off')
|
| 181 |
+
grasp_offset_head = tf_util.conv1d(grasp_offset_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_off')
|
| 182 |
+
|
| 183 |
+
binary_seg_head = tf_util.conv1d(l0_points, 128, 1, padding='VALID', bn=True, is_training=is_training, scope='fc1_seg', bn_decay=bn_decay)
|
| 184 |
+
binary_seg_head = tf_util.dropout(binary_seg_head, keep_prob=0.5, is_training=is_training, scope='dp1_seg')
|
| 185 |
+
binary_seg_head = tf_util.conv1d(binary_seg_head, 1, 1, padding='VALID', activation_fn=None, scope='fc2_seg')
|
| 186 |
+
|
| 187 |
+
end_points['grasp_dir_head'] = grasp_dir_head_normed
|
| 188 |
+
end_points['binary_seg_head'] = binary_seg_head
|
| 189 |
+
end_points['binary_seg_pred'] = tf.math.sigmoid(binary_seg_head)
|
| 190 |
+
end_points['grasp_offset_head'] = grasp_offset_head
|
| 191 |
+
end_points['grasp_offset_pred'] = tf.math.sigmoid(grasp_offset_head) if model_config['bin_offsets'] else grasp_offset_head
|
| 192 |
+
end_points['approach_dir_head'] = approach_dir_head_orthog
|
| 193 |
+
end_points['pred_points'] = pred_points
|
| 194 |
+
|
| 195 |
+
return end_points
|
| 196 |
+
|
| 197 |
+
def build_6d_grasp(approach_dirs, base_dirs, contact_pts, thickness, use_tf=False, gripper_depth = 0.1034):
|
| 198 |
+
|
| 199 |
+
if use_tf:
|
| 200 |
+
grasps_R = tf.stack([base_dirs, tf.linalg.cross(approach_dirs,base_dirs),approach_dirs], axis=3)
|
| 201 |
+
grasps_t = contact_pts + tf.expand_dims(thickness,2)/2 * base_dirs - gripper_depth * approach_dirs
|
| 202 |
+
ones = tf.ones((contact_pts.shape[0], contact_pts.shape[1], 1, 4), dtype=tf.float32)
|
| 203 |
+
grasps = tf.concat([tf.concat([grasps_R, tf.expand_dims(grasps_t, 3)], axis=3), ones], axis=2)
|
| 204 |
+
else:
|
| 205 |
+
grasps = []
|
| 206 |
+
for i in range(len(contact_pts)):
|
| 207 |
+
grasp = np.eye(4)
|
| 208 |
+
|
| 209 |
+
grasp[:3,0] = base_dirs[i] / np.linalg.norm(base_dirs[i])
|
| 210 |
+
grasp[:3,2] = approach_dirs[i] / np.linalg.norm(approach_dirs[i])
|
| 211 |
+
grasp_y = np.cross( grasp[:3,2],grasp[:3,0])
|
| 212 |
+
grasp[:3,1] = grasp_y / np.linalg.norm(grasp_y)
|
| 213 |
+
# base_gripper xyz = contact + thickness / 2 * baseline_dir - gripper_d * approach_dir
|
| 214 |
+
grasp[:3,3] = contact_pts[i] + thickness[i] / 2 * grasp[:3,0] - gripper_depth * grasp[:3,2]
|
| 215 |
+
# grasp[0,3] = finger_width
|
| 216 |
+
grasps.append(grasp)
|
| 217 |
+
grasps = np.array(grasps)
|
| 218 |
+
|
| 219 |
+
return grasps
|
| 220 |
+
|
| 221 |
+
def multi_bin_labels(cont_labels, bin_boundaries):
|
| 222 |
+
|
| 223 |
+
# multi_hot_labels = tf.zeros_like((cont_labels.shape[0], cont_labels.shape[1], len(bin_boundaries)-1), tf.bool)
|
| 224 |
+
bins = []
|
| 225 |
+
for b in range(len(bin_boundaries)-1):
|
| 226 |
+
bins.append(tf.math.logical_and(tf.greater_equal(cont_labels, bin_boundaries[b]), tf.less(cont_labels,bin_boundaries[b+1])))
|
| 227 |
+
# cont_labels = tf.where(condition, b*tf.ones_like(condition, tf.float32), cont_labels)
|
| 228 |
+
multi_hot_labels = tf.concat(bins, axis=2)
|
| 229 |
+
multi_hot_labels = tf.cast(multi_hot_labels, tf.float32)
|
| 230 |
+
|
| 231 |
+
return multi_hot_labels
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
def get_losses(pointclouds_pl, end_points, dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam, global_config):
|
| 235 |
+
""" pred: (batch_size, num_point, 3),
|
| 236 |
+
label: (batch_size, num_point, 3),
|
| 237 |
+
grasp_success_labels_pc: (batch_size, num_point)
|
| 238 |
+
"""
|
| 239 |
+
|
| 240 |
+
grasp_dir_head = end_points['grasp_dir_head']
|
| 241 |
+
grasp_offset_head = end_points['grasp_offset_head']
|
| 242 |
+
approach_dir_head = end_points['approach_dir_head']
|
| 243 |
+
|
| 244 |
+
bin_weights = global_config['DATA']['labels']['bin_weights']
|
| 245 |
+
tf_bin_weights = tf.constant(bin_weights)
|
| 246 |
+
|
| 247 |
+
min_geom_loss_divisor = tf.constant(float(global_config['LOSS']['min_geom_loss_divisor'])) if 'min_geom_loss_divisor' in global_config['LOSS'] else tf.constant(1.)
|
| 248 |
+
pos_grasps_in_view = tf.math.maximum(tf.reduce_sum(grasp_success_labels_pc, axis=1), min_geom_loss_divisor)
|
| 249 |
+
|
| 250 |
+
### ADS Gripper PC Loss
|
| 251 |
+
if global_config['MODEL']['bin_offsets']:
|
| 252 |
+
thickness_pred = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(grasp_offset_head, axis=2), axis=2))
|
| 253 |
+
thickness_gt = tf.gather_nd(get_bin_vals(global_config), tf.expand_dims(tf.argmax(offset_labels_pc, axis=2), axis=2))
|
| 254 |
+
else:
|
| 255 |
+
thickness_pred = grasp_offset_head[:,:,0]
|
| 256 |
+
thickness_gt = offset_labels_pc[:,:,0]
|
| 257 |
+
pred_grasps = build_6d_grasp(approach_dir_head, grasp_dir_head, pointclouds_pl, thickness_pred, use_tf=True) # b x num_point x 4 x 4
|
| 258 |
+
gt_grasps_proj = build_6d_grasp(approach_labels_pc_cam, dir_labels_pc_cam, pointclouds_pl, thickness_gt, use_tf=True) # b x num_point x 4 x 4
|
| 259 |
+
pos_gt_grasps_proj = tf.where(tf.broadcast_to(tf.expand_dims(tf.expand_dims(tf.cast(grasp_success_labels_pc, tf.bool),2),3), gt_grasps_proj.shape), gt_grasps_proj, tf.ones_like(gt_grasps_proj)*100000)
|
| 260 |
+
# pos_gt_grasps_proj = tf.reshape(pos_gt_grasps_proj, (global_config['OPTIMIZER']['batch_size'], -1, 4, 4))
|
| 261 |
+
|
| 262 |
+
gripper_control_points = tf_utils.get_control_point_tensor(global_config['OPTIMIZER']['batch_size'])[:,1:,:] # b x 5 x 3
|
| 263 |
+
sym_gripper_control_points = tf_utils.get_control_point_tensor(global_config['OPTIMIZER']['batch_size'], symmetric=True)[:,1:,:]
|
| 264 |
+
|
| 265 |
+
gripper_control_points_homog = tf.concat([gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 266 |
+
sym_gripper_control_points_homog = tf.concat([sym_gripper_control_points, tf.ones((global_config['OPTIMIZER']['batch_size'], gripper_control_points.shape[1], 1))], axis=2) # b x 5 x 4
|
| 267 |
+
|
| 268 |
+
# only use per point pred grasps but not per point gt grasps
|
| 269 |
+
control_points = tf.keras.backend.repeat_elements(tf.expand_dims(gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 270 |
+
sym_control_points = tf.keras.backend.repeat_elements(tf.expand_dims(sym_gripper_control_points_homog,1), gt_grasps_proj.shape[1], axis=1) # b x num_point x 5 x 4
|
| 271 |
+
pred_control_points = tf.matmul(control_points, tf.transpose(pred_grasps, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_point x 5 x 3
|
| 272 |
+
|
| 273 |
+
### Pred Grasp to GT Grasp ADD-S Loss
|
| 274 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 275 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(pos_gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 276 |
+
|
| 277 |
+
squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 278 |
+
sym_squared_add = tf.reduce_sum((tf.expand_dims(pred_control_points,2)-tf.expand_dims(sym_gt_control_points,1))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 279 |
+
|
| 280 |
+
# symmetric ADD-S
|
| 281 |
+
neg_squared_adds = -tf.concat([squared_add,sym_squared_add], axis=2) # b x num_point x 2num_pos_grasp_point
|
| 282 |
+
neg_squared_adds_k = tf.math.top_k(neg_squared_adds, k=1, sorted=False)[0] # b x num_point
|
| 283 |
+
# If any pos grasp exists
|
| 284 |
+
min_adds = tf.minimum(tf.reduce_sum(grasp_success_labels_pc, axis=1, keepdims=True), tf.ones_like(neg_squared_adds_k[:,:,0])) * tf.sqrt(-neg_squared_adds_k[:,:,0])#tf.minimum(tf.sqrt(-neg_squared_adds_k), tf.ones_like(neg_squared_adds_k)) # b x num_point
|
| 285 |
+
adds_loss = tf.reduce_mean(end_points['binary_seg_pred'][:,:,0] * min_adds)
|
| 286 |
+
|
| 287 |
+
### GT Grasp to pred Grasp ADD-S Loss
|
| 288 |
+
gt_control_points = tf.matmul(control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 289 |
+
sym_gt_control_points = tf.matmul(sym_control_points, tf.transpose(gt_grasps_proj, perm=[0, 1, 3, 2]))[:,:,:,:3] # b x num_pos_grasp_point x 5 x 3
|
| 290 |
+
|
| 291 |
+
neg_squared_adds = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 292 |
+
neg_squared_adds_sym = -tf.reduce_sum((tf.expand_dims(pred_control_points,1)-tf.expand_dims(sym_gt_control_points,2))**2, axis=(3,4)) # b x num_point x num_pos_grasp_point x ( 5 x 3)
|
| 293 |
+
|
| 294 |
+
neg_squared_adds_k_gt2pred, pred_grasp_idcs = tf.math.top_k(neg_squared_adds, k=1, sorted=False) # b x num_pos_grasp_point
|
| 295 |
+
neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs = tf.math.top_k(neg_squared_adds_sym, k=1, sorted=False) # b x num_pos_grasp_point
|
| 296 |
+
pred_grasp_idcs_joined = tf.where(neg_squared_adds_k_gt2pred<neg_squared_adds_k_sym_gt2pred, pred_grasp_sym_idcs, pred_grasp_idcs)
|
| 297 |
+
min_adds_gt2pred = tf.minimum(-neg_squared_adds_k_gt2pred, -neg_squared_adds_k_sym_gt2pred) # b x num_pos_grasp_point x 1
|
| 298 |
+
# min_adds_gt2pred = tf.math.exp(-min_adds_gt2pred)
|
| 299 |
+
masked_min_adds_gt2pred = tf.multiply(min_adds_gt2pred[:,:,0], grasp_success_labels_pc)
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
batch_idcs = tf.meshgrid(tf.range(pred_grasp_idcs_joined.shape[1]), tf.range(pred_grasp_idcs_joined.shape[0]))
|
| 303 |
+
gather_idcs = tf.stack((batch_idcs[1],pred_grasp_idcs_joined[:,:,0]), axis=2)
|
| 304 |
+
nearest_pred_grasp_confidence = tf.gather_nd(end_points['binary_seg_pred'][:,:,0], gather_idcs)
|
| 305 |
+
adds_loss_gt2pred = tf.reduce_mean(tf.reduce_sum(nearest_pred_grasp_confidence*masked_min_adds_gt2pred, axis=1) / pos_grasps_in_view)
|
| 306 |
+
|
| 307 |
+
### Grasp baseline Loss
|
| 308 |
+
cosine_distance = tf.constant(1.)-tf.reduce_sum(tf.multiply(dir_labels_pc_cam, grasp_dir_head),axis=2)
|
| 309 |
+
# only pass loss where we have labeled contacts near pc points
|
| 310 |
+
masked_cosine_loss = tf.multiply(cosine_distance, grasp_success_labels_pc)
|
| 311 |
+
dir_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_cosine_loss, axis=1) / pos_grasps_in_view)
|
| 312 |
+
|
| 313 |
+
### Grasp Approach Loss
|
| 314 |
+
approach_labels_orthog = tf.math.l2_normalize(approach_labels_pc_cam - tf.reduce_sum(tf.multiply(grasp_dir_head, approach_labels_pc_cam), axis=2, keepdims=True)*grasp_dir_head, axis=2)
|
| 315 |
+
cosine_distance_approach = tf.constant(1.)-tf.reduce_sum(tf.multiply(approach_labels_orthog, approach_dir_head), axis=2)
|
| 316 |
+
masked_approach_loss = tf.multiply(cosine_distance_approach, grasp_success_labels_pc)
|
| 317 |
+
approach_cosine_loss = tf.reduce_mean(tf.reduce_sum(masked_approach_loss, axis=1) / pos_grasps_in_view)
|
| 318 |
+
|
| 319 |
+
### Grasp Offset/Thickness Loss
|
| 320 |
+
if global_config['MODEL']['bin_offsets']:
|
| 321 |
+
if global_config['LOSS']['offset_loss_type'] == 'softmax_cross_entropy':
|
| 322 |
+
offset_loss = tf.losses.softmax_cross_entropy(offset_labels_pc, grasp_offset_head)
|
| 323 |
+
else:
|
| 324 |
+
offset_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=offset_labels_pc, logits=grasp_offset_head)
|
| 325 |
+
|
| 326 |
+
if 'too_small_offset_pred_bin_factor' in global_config['LOSS'] and global_config['LOSS']['too_small_offset_pred_bin_factor']:
|
| 327 |
+
too_small_offset_pred_bin_factor = tf.constant(global_config['LOSS']['too_small_offset_pred_bin_factor'], tf.float32)
|
| 328 |
+
collision_weight = tf.math.cumsum(offset_labels_pc, axis=2, reverse=True)*too_small_offset_pred_bin_factor + tf.constant(1.)
|
| 329 |
+
offset_loss = tf.multiply(collision_weight, offset_loss)
|
| 330 |
+
|
| 331 |
+
offset_loss = tf.reduce_mean(tf.multiply(tf.reshape(tf_bin_weights,(1,1,-1)), offset_loss),axis=2)
|
| 332 |
+
else:
|
| 333 |
+
offset_loss = (grasp_offset_head[:,:,0] - offset_labels_pc[:,:,0])**2
|
| 334 |
+
masked_offset_loss = tf.multiply(offset_loss, grasp_success_labels_pc)
|
| 335 |
+
offset_loss = tf.reduce_mean(tf.reduce_sum(masked_offset_loss, axis=1) / pos_grasps_in_view)
|
| 336 |
+
|
| 337 |
+
### Grasp Confidence Loss
|
| 338 |
+
bin_ce_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.expand_dims(grasp_success_labels_pc,axis=2), logits=end_points['binary_seg_head'])
|
| 339 |
+
if 'topk_confidence' in global_config['LOSS'] and global_config['LOSS']['topk_confidence']:
|
| 340 |
+
bin_ce_loss,_ = tf.math.top_k(tf.squeeze(bin_ce_loss), k=global_config['LOSS']['topk_confidence'])
|
| 341 |
+
bin_ce_loss = tf.reduce_mean(bin_ce_loss)
|
| 342 |
+
|
| 343 |
+
return dir_cosine_loss, bin_ce_loss, offset_loss, approach_cosine_loss, adds_loss, adds_loss_gt2pred, gt_control_points, pred_control_points, pos_grasps_in_view
|
| 344 |
+
|
| 345 |
+
def compute_labels(pos_contact_pts_mesh, pos_contact_dirs_mesh, pos_contact_offsets, pos_contact_approaches_mesh, pos_finger_diffs, neg_contact_pts_mesh,
|
| 346 |
+
neg_contact_dirs_mesh, neg_contact_offsets, neg_contact_approaches_mesh, neg_finger_diffs, pc_cam_pl, camera_pose_pl, global_config):
|
| 347 |
+
"""
|
| 348 |
+
for every point find nearest contact points
|
| 349 |
+
group and average labels
|
| 350 |
+
"""
|
| 351 |
+
label_config = global_config['DATA']['labels']
|
| 352 |
+
model_config = global_config['MODEL']
|
| 353 |
+
|
| 354 |
+
contact_distance_offset = model_config['contact_distance_offset']
|
| 355 |
+
bin_offsets = model_config['bin_offsets']
|
| 356 |
+
|
| 357 |
+
mode = label_config['contact_gather']
|
| 358 |
+
nsample = label_config['k']
|
| 359 |
+
radius = label_config['max_radius']
|
| 360 |
+
filter_z = label_config['filter_z']
|
| 361 |
+
z_val = label_config['z_val']
|
| 362 |
+
|
| 363 |
+
xyz_cam = pc_cam_pl[:,:,:3]
|
| 364 |
+
pad_homog = tf.ones((xyz_cam.shape[0],xyz_cam.shape[1], 1))
|
| 365 |
+
pc_mesh = tf.matmul(tf.concat([xyz_cam, pad_homog], 2), tf.transpose(tf.linalg.inv(camera_pose_pl),perm=[0, 2, 1]))[:,:,:3]
|
| 366 |
+
|
| 367 |
+
if contact_distance_offset:
|
| 368 |
+
# finger_diff = tf.norm(pos_contact_pts_mesh[1::2,:]-pos_contact_pts_mesh[::2,:] + 0.0000001, axis=1, keepdims=True)
|
| 369 |
+
# finger_diff = tf.keras.backend.repeat_elements(finger_diff, 2, axis=0)
|
| 370 |
+
contact_point_offsets_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_finger_diffs,0), pc_mesh.shape[0], axis=0)
|
| 371 |
+
else:
|
| 372 |
+
contact_point_offsets_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_offsets,0), pc_mesh.shape[0], axis=0)
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
pad_homog2 = tf.ones((pc_mesh.shape[0], pos_contact_dirs_mesh.shape[0], 1))
|
| 376 |
+
contact_point_dirs_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0)
|
| 377 |
+
contact_point_dirs_batch_cam = tf.matmul(contact_point_dirs_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 378 |
+
|
| 379 |
+
pos_contact_approaches_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_approaches_mesh,0), pc_mesh.shape[0], axis=0)
|
| 380 |
+
pos_contact_approaches_batch_cam = tf.matmul(pos_contact_approaches_batch, tf.transpose(camera_pose_pl[:,:3,:3], perm=[0, 2, 1]))[:,:,:3]
|
| 381 |
+
|
| 382 |
+
contact_point_batch_mesh = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_pts_mesh,0), pc_mesh.shape[0], axis=0)
|
| 383 |
+
contact_point_batch_cam = tf.matmul(tf.concat([contact_point_batch_mesh, pad_homog2], 2), tf.transpose(camera_pose_pl, perm=[0, 2, 1]))[:,:,:3]
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
# orthogonal = tf.reduce_sum(pos_contact_approaches_batch_cam * contact_point_dirs_batch_cam, axis=2)
|
| 387 |
+
if filter_z:
|
| 388 |
+
dir_filter_passed = tf.keras.backend.repeat_elements(tf.math.greater(contact_point_dirs_batch_cam[:,:,2:3], tf.constant([z_val])), 3, axis=2)
|
| 389 |
+
contact_point_batch_mesh = tf.where(dir_filter_passed, contact_point_batch_mesh, tf.ones_like(contact_point_batch_mesh)*100000)
|
| 390 |
+
# contact_point_dirs_batch_cam = tf.boolean_mask(contact_point_dirs_batch_cam, dir_filter_passed)
|
| 391 |
+
# print(contact_point_dirs_batch_cam.shape)
|
| 392 |
+
# contact_point_batch_mesh = tf.boolean_mask(contact_point_batch_mesh, dir_filter_passed)
|
| 393 |
+
# else:
|
| 394 |
+
# contact_point_dirs_batch = tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0)
|
| 395 |
+
|
| 396 |
+
# TODO: Divide into positive and negative grasps; for now only insert positive contacts (otherwise mean direction does not make sense)
|
| 397 |
+
if mode == 'mean':
|
| 398 |
+
close_contact_pt_idcs,_ = query_ball_point(radius, nsample, contact_point_batch_mesh, pc_mesh) # (batch_size, npoint, nsample)
|
| 399 |
+
|
| 400 |
+
grasp_success_labels_pc = tf.cast(tf.reduce_sum(close_contact_pt_idcs, axis=2)>0, tf.float32) # (batch_size, num_point)
|
| 401 |
+
|
| 402 |
+
# contact_point to contact_dir mapping
|
| 403 |
+
grouped_dirs_mesh = group_point(contact_point_dirs_batch, close_contact_pt_idcs) # (batch_size, num_point, nsample, 3)
|
| 404 |
+
|
| 405 |
+
# grouped_dirs_mesh = tf.gather_nd(tf.keras.backend.repeat_elements(tf.expand_dims(pos_contact_dirs_mesh,0), pc_mesh.shape[0], axis=0), close_contact_pt_idcs)
|
| 406 |
+
elif mode == 'knn':
|
| 407 |
+
# dists, close_contact_pt_idcs = knn_point(nsample, contact_point_batch_mesh, pc_mesh) # (batch_size, num_point, nsample)
|
| 408 |
+
|
| 409 |
+
# squared_dists_all = tf.reduce_sum((tf.expand_dims(contact_point_batch_mesh,1)-tf.expand_dims(pc_mesh,2))**2,axis=3)
|
| 410 |
+
squared_dists_all = tf.reduce_sum((tf.expand_dims(contact_point_batch_cam,1)-tf.expand_dims(xyz_cam,2))**2,axis=3)
|
| 411 |
+
neg_squared_dists_k, close_contact_pt_idcs = tf.math.top_k(-squared_dists_all, k=nsample, sorted=False)
|
| 412 |
+
squared_dists_k = -neg_squared_dists_k
|
| 413 |
+
|
| 414 |
+
# Distance check, careful it depends on point density
|
| 415 |
+
grasp_success_labels_pc = tf.cast(tf.less(tf.reduce_mean(squared_dists_k, axis=2), radius*radius), tf.float32) # (batch_size, num_point)
|
| 416 |
+
|
| 417 |
+
grouped_dirs_pc_cam = group_point(contact_point_dirs_batch_cam, close_contact_pt_idcs)
|
| 418 |
+
grouped_approaches_pc_cam = group_point(pos_contact_approaches_batch_cam, close_contact_pt_idcs)
|
| 419 |
+
grouped_offsets = group_point(tf.expand_dims(contact_point_offsets_batch,2), close_contact_pt_idcs)
|
| 420 |
+
# not sure for nsample > 1
|
| 421 |
+
dir_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_dirs_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 422 |
+
approach_labels_pc_cam = tf.math.l2_normalize(tf.reduce_mean(grouped_approaches_pc_cam, axis=2),axis=2) # (batch_size, num_point, 3)
|
| 423 |
+
offset_labels_pc = tf.reduce_mean(grouped_offsets, axis=2)
|
| 424 |
+
|
| 425 |
+
else:
|
| 426 |
+
raise NotImplementedError
|
| 427 |
+
# if filter_z:
|
| 428 |
+
# pad_homog3 = tf.ones((dir_labels_mesh.shape[0], dir_labels_mesh.shape[1], 1))
|
| 429 |
+
# dir_labels_pc_cam = tf.matmul(tf.concat([dir_labels_mesh,pad_homog3], 2), tf.transpose(camera_pose_pl, perm=[0, 2, 1]))[:,:,:3] # (batch_size, num_point, 3)
|
| 430 |
+
|
| 431 |
+
return dir_labels_pc_cam, offset_labels_pc, grasp_success_labels_pc, approach_labels_pc_cam
|
| 432 |
+
|
| 433 |
+
if __name__=='__main__':
|
| 434 |
+
with tf.Graph().as_default():
|
| 435 |
+
inputs = tf.zeros((32,2048,6))
|
| 436 |
+
net, _ = get_model(inputs, tf.constant(True))
|
| 437 |
+
print(net)
|
scene_test_2048_bs3_hor_sigma_0025/train_grasp_direct.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import argparse
|
| 4 |
+
import math
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
import numpy as np
|
| 7 |
+
import socket
|
| 8 |
+
import importlib
|
| 9 |
+
import time
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
import glob
|
| 12 |
+
import json
|
| 13 |
+
import yaml
|
| 14 |
+
|
| 15 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
+
ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR))
|
| 17 |
+
sys.path.append(os.path.join(BASE_DIR))
|
| 18 |
+
sys.path.append(os.path.join(ROOT_DIR))
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
import tensorflow.compat.v1 as tf
|
| 22 |
+
tf.disable_eager_execution()
|
| 23 |
+
TF2 = True
|
| 24 |
+
physical_devices = tf.config.experimental.list_physical_devices('GPU')
|
| 25 |
+
print(physical_devices)
|
| 26 |
+
tf.config.experimental.set_memory_growth(physical_devices[0], True)
|
| 27 |
+
except:
|
| 28 |
+
import tensorflow as tf
|
| 29 |
+
TF2 = False
|
| 30 |
+
|
| 31 |
+
POINT_DIR_NGC = os.path.join(ROOT_DIR, 'pointnet2')
|
| 32 |
+
if os.path.exists(POINT_DIR_NGC):
|
| 33 |
+
sys.path.append(os.path.join(POINT_DIR_NGC, 'models'))
|
| 34 |
+
sys.path.append(os.path.join(POINT_DIR_NGC, 'utils'))
|
| 35 |
+
else:
|
| 36 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'models'))
|
| 37 |
+
sys.path.append(os.path.join(BASE_DIR, 'pointnet2', 'utils'))
|
| 38 |
+
|
| 39 |
+
import provider
|
| 40 |
+
import sample
|
| 41 |
+
import utilities
|
| 42 |
+
from data import PointCloudReader, load_mesh_path_and_scale, preprocess_pc_for_inference, load_filtered_contact_data, load_scene_contacts, load_obj_scales_cats, inverse_transform, center_pc_convert_cam
|
| 43 |
+
from summaries import top_grasp_acc_summaries, build_summary_ops, build_file_writers
|
| 44 |
+
from tf_train_ops import load_labels_and_losses, build_train_op
|
| 45 |
+
from surface_grasp_estimator import GraspEstimator
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def train(global_config, LOG_DIR):
|
| 49 |
+
|
| 50 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 51 |
+
mesh_scales, mesh_cats = load_obj_scales_cats(global_config['DATA']['data_path'])
|
| 52 |
+
contact_infos, scene_obj_paths, scene_obj_transforms = load_scene_contacts(global_config['DATA']['data_path'])
|
| 53 |
+
num_train_samples = len(contact_infos)-global_config['DATA']['num_test_scenes']
|
| 54 |
+
num_test_samples = global_config['DATA']['num_test_scenes']
|
| 55 |
+
else:
|
| 56 |
+
scene_obj_paths, scene_obj_transforms = None, None
|
| 57 |
+
train_contact_paths, test_contact_paths, contact_infos, mesh_scales = load_filtered_contact_data(global_config['DATA']['data_path'], min_pos_contacts=1, classes=global_config['DATA']['classes'])
|
| 58 |
+
num_train_samples = len(train_contact_paths)
|
| 59 |
+
num_test_samples = len(test_contact_paths)
|
| 60 |
+
|
| 61 |
+
print('using %s meshes' % (num_train_samples + num_test_samples))
|
| 62 |
+
|
| 63 |
+
if 'train_and_test' in global_config['DATA'] and global_config['DATA']['train_and_test']:
|
| 64 |
+
num_train_samples = num_train_samples + num_test_samples
|
| 65 |
+
num_test_samples = 0
|
| 66 |
+
print('using train and test data')
|
| 67 |
+
|
| 68 |
+
pcreader = PointCloudReader(
|
| 69 |
+
root_folder=global_config['DATA']['data_path'],
|
| 70 |
+
batch_size=global_config['OPTIMIZER']['batch_size'],
|
| 71 |
+
num_grasp_clusters=None,
|
| 72 |
+
estimate_normals=global_config['DATA']['input_normals'],
|
| 73 |
+
npoints=global_config['DATA']['num_point'],
|
| 74 |
+
raw_num_points=global_config['DATA']['raw_num_points'],
|
| 75 |
+
use_uniform_quaternions = global_config['DATA']['use_uniform_quaternions'],
|
| 76 |
+
run_in_another_process = False,
|
| 77 |
+
mesh_scales = mesh_scales,
|
| 78 |
+
scene_obj_paths = scene_obj_paths,
|
| 79 |
+
scene_obj_transforms = scene_obj_transforms,
|
| 80 |
+
num_train_samples = num_train_samples,
|
| 81 |
+
num_test_samples = num_test_samples,
|
| 82 |
+
use_farthest_point = global_config['DATA']['use_farthest_point'],
|
| 83 |
+
intrinsics=global_config['DATA']['intrinsics']
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
with tf.Graph().as_default():
|
| 87 |
+
|
| 88 |
+
# Build the model
|
| 89 |
+
grasp_estimator = GraspEstimator(global_config)
|
| 90 |
+
|
| 91 |
+
ops = grasp_estimator.build_network()
|
| 92 |
+
|
| 93 |
+
# contact_tensors = load_contact_grasps(contact_infos, global_config['DATA'])
|
| 94 |
+
|
| 95 |
+
loss_ops = load_labels_and_losses(grasp_estimator, contact_infos, global_config)
|
| 96 |
+
|
| 97 |
+
ops.update(loss_ops)
|
| 98 |
+
ops['train_op'] = build_train_op(ops['loss'], ops['step'], global_config)
|
| 99 |
+
|
| 100 |
+
# Add ops to save and restore all the variables.
|
| 101 |
+
saver = tf.train.Saver(save_relative_paths=True, keep_checkpoint_every_n_hours=4)
|
| 102 |
+
|
| 103 |
+
# Create a session
|
| 104 |
+
config = tf.ConfigProto()
|
| 105 |
+
config.gpu_options.allow_growth = True
|
| 106 |
+
config.allow_soft_placement = True
|
| 107 |
+
# config.log_device_placement = False
|
| 108 |
+
sess = tf.Session(config=config)
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
summary_ops = build_summary_ops(ops, sess, global_config)
|
| 112 |
+
|
| 113 |
+
grasp_estimator.load_weights(sess, saver, LOG_DIR, mode='train')
|
| 114 |
+
file_writers = build_file_writers(sess, LOG_DIR)
|
| 115 |
+
|
| 116 |
+
batches_per_epoch = num_train_samples #// global_config['OPTIMIZER']['batch_size'] + 1
|
| 117 |
+
cur_epoch = sess.run(ops['step']) // (batches_per_epoch * global_config['OPTIMIZER']['batch_size'])
|
| 118 |
+
for epoch in range(cur_epoch, global_config['OPTIMIZER']['max_epoch']):
|
| 119 |
+
log_string('**** EPOCH %03d ****' % (epoch))
|
| 120 |
+
|
| 121 |
+
sess.run(ops['iterator'].initializer)
|
| 122 |
+
epoch_time = time.time()
|
| 123 |
+
step = train_one_epoch(sess, ops, summary_ops, file_writers, pcreader)
|
| 124 |
+
print('trained %s batches in: ' % batches_per_epoch, time.time()-epoch_time)
|
| 125 |
+
|
| 126 |
+
# Save the variables to disk.
|
| 127 |
+
if (epoch+1) % 1 == 0:
|
| 128 |
+
save_path = saver.save(sess, os.path.join(LOG_DIR, "model.ckpt"), global_step=step, write_meta_graph=False)
|
| 129 |
+
log_string("Model saved in file: %s" % save_path)
|
| 130 |
+
|
| 131 |
+
if epoch % 1 == 0 and num_test_samples > 0:
|
| 132 |
+
eval_time = time.time()
|
| 133 |
+
eval_test_objects(sess, ops, summary_ops, file_writers, pcreader)
|
| 134 |
+
print('evaluation time: ', time.time()-eval_time)
|
| 135 |
+
|
| 136 |
+
def train_one_epoch(sess, ops, summary_ops, file_writers, pcreader):
|
| 137 |
+
""" ops: dict mapping from string to tf ops """
|
| 138 |
+
is_training = True
|
| 139 |
+
|
| 140 |
+
log_string(str(datetime.now()))
|
| 141 |
+
|
| 142 |
+
loss_sum, loss_sum_dir, loss_sum_ce, loss_sum_off, loss_sum_app, loss_sum_adds, loss_sum_adds_gt2pred, time_sum = 8 * [0]
|
| 143 |
+
|
| 144 |
+
# batches_per_epoch = pcreader._num_train_samples // pcreader._batch_size
|
| 145 |
+
## define one epoch = all objects/scenes seen
|
| 146 |
+
batches_per_epoch = pcreader._num_train_samples
|
| 147 |
+
|
| 148 |
+
# run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE, report_tensor_allocations_upon_oom = True)
|
| 149 |
+
|
| 150 |
+
for batch_idx in range(batches_per_epoch):
|
| 151 |
+
get_time = time.time()
|
| 152 |
+
|
| 153 |
+
batch_data, cam_poses, obj_idx = pcreader.get_batch(batch_idx)
|
| 154 |
+
print(time.time()- get_time)
|
| 155 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 156 |
+
# OpenCV OpenGL conversion
|
| 157 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 158 |
+
print(time.time() - get_time)
|
| 159 |
+
# Augment batched point clouds by rotation and jittering
|
| 160 |
+
# aug_data = provider.random_scale_point_cloud(batch_data, scale_low=0.8, scale_high=1.25)
|
| 161 |
+
if 'sigma' in global_config['DATA'] and global_config['DATA']['sigma'] > 0:
|
| 162 |
+
batch_data[:,:,0:3] = provider.jitter_point_cloud(batch_data[:,:,0:3],
|
| 163 |
+
sigma=global_config['DATA']['sigma'],
|
| 164 |
+
clip=global_config['DATA']['clip']*2)
|
| 165 |
+
|
| 166 |
+
feed_dict = {ops['pointclouds_pl']: batch_data,
|
| 167 |
+
ops['cam_poses_pl']: cam_poses,
|
| 168 |
+
ops['obj_idx_pl']: obj_idx,
|
| 169 |
+
# ops['labels_pl']: batch_label,
|
| 170 |
+
ops['is_training_pl']: is_training}
|
| 171 |
+
|
| 172 |
+
step, summary, _, loss_val, dir_loss, bin_ce_loss, \
|
| 173 |
+
offset_loss, approach_loss, adds_loss, adds_gt2pred_loss,pos_grasps_in_view, scene_idx = sess.run([ops['step'], summary_ops['merged'], ops['train_op'],
|
| 174 |
+
ops['loss'], ops['dir_loss'], ops['bin_ce_loss'],
|
| 175 |
+
ops['offset_loss'], ops['approach_loss'], ops['adds_loss'],
|
| 176 |
+
ops['adds_gt2pred_loss'], ops['pos_grasps_in_view'], ops['scene_idx']], feed_dict=feed_dict)
|
| 177 |
+
print(time.time()- get_time)
|
| 178 |
+
print(pos_grasps_in_view)
|
| 179 |
+
print(scene_idx, obj_idx)
|
| 180 |
+
assert scene_idx[0] == obj_idx
|
| 181 |
+
|
| 182 |
+
loss_sum += loss_val
|
| 183 |
+
loss_sum_dir += dir_loss
|
| 184 |
+
loss_sum_ce += bin_ce_loss
|
| 185 |
+
loss_sum_off += offset_loss
|
| 186 |
+
loss_sum_app += approach_loss
|
| 187 |
+
loss_sum_adds += adds_loss
|
| 188 |
+
loss_sum_adds_gt2pred += adds_gt2pred_loss
|
| 189 |
+
time_sum += time.time() - get_time
|
| 190 |
+
|
| 191 |
+
if (batch_idx+1)%10 == 0:
|
| 192 |
+
file_writers['train_writer'].add_summary(summary, step)
|
| 193 |
+
log_string('total loss: %f \t dir loss: %f \t ce loss: %f \t off loss: %f \t app loss: %f adds loss: %f \t adds_gt2pred loss: %f \t batch time: %f' % (loss_sum/10,loss_sum_dir/10,loss_sum_ce/10, loss_sum_off/10, loss_sum_app/10, loss_sum_adds/10, loss_sum_adds_gt2pred/10, time_sum/10))
|
| 194 |
+
# log_string('accuracy: %f' % (total_correct / float(total_seen)))
|
| 195 |
+
loss_sum, loss_sum_dir, loss_sum_ce, loss_sum_off, loss_sum_app, loss_sum_adds, loss_sum_adds_gt2pred, time_sum = 8 * [0]
|
| 196 |
+
|
| 197 |
+
return step
|
| 198 |
+
|
| 199 |
+
def eval_test_objects(sess, ops, summary_ops, file_writers, pcreader, max_eval_objects=500):
|
| 200 |
+
""" ops: dict mapping from string to tf ops """
|
| 201 |
+
is_training = False
|
| 202 |
+
|
| 203 |
+
log_string(str(datetime.now()))
|
| 204 |
+
losses = []
|
| 205 |
+
losses_dir = []
|
| 206 |
+
losses_ce = []
|
| 207 |
+
losses_off = []
|
| 208 |
+
losses_app = []
|
| 209 |
+
losses_add = []
|
| 210 |
+
losses_add_gt2pred = []
|
| 211 |
+
|
| 212 |
+
# resets accumulation of pr and auc data
|
| 213 |
+
sess.run(summary_ops['pr_reset_op'])
|
| 214 |
+
|
| 215 |
+
for batch_idx in np.arange(min(pcreader._num_test_samples, max_eval_objects)):
|
| 216 |
+
|
| 217 |
+
batch_data, cam_poses, obj_idx = pcreader.get_batch(obj_idx=pcreader._num_train_samples + batch_idx)
|
| 218 |
+
|
| 219 |
+
if 'train_on_scenes' in global_config['DATA'] and global_config['DATA']['train_on_scenes']:
|
| 220 |
+
# OpenCV OpenGL conversion
|
| 221 |
+
cam_poses, batch_data = center_pc_convert_cam(cam_poses, batch_data)
|
| 222 |
+
# Augment batched point clouds by rotation and jittering
|
| 223 |
+
# aug_data = provider.random_scale_point_cloud(batch_data)
|
| 224 |
+
# batch_data[:,:,0:3] = provider.jitter_point_cloud(batch_data[:,:,0:3])
|
| 225 |
+
feed_dict = {ops['pointclouds_pl']: batch_data,
|
| 226 |
+
ops['cam_poses_pl']: cam_poses,
|
| 227 |
+
ops['obj_idx_pl']: obj_idx,
|
| 228 |
+
ops['is_training_pl']: is_training}
|
| 229 |
+
|
| 230 |
+
scene_idx, step, loss_val, dir_loss, bin_ce_loss, offset_loss, approach_loss, adds_loss, adds_gt2pred_loss, pr_summary,_,_,_ = sess.run([ops['scene_idx'], ops['step'], ops['loss'], ops['dir_loss'], ops['bin_ce_loss'],
|
| 231 |
+
ops['offset_loss'], ops['approach_loss'], ops['adds_loss'], ops['adds_gt2pred_loss'],
|
| 232 |
+
summary_ops['merged_eval'], summary_ops['pr_update_op'],
|
| 233 |
+
summary_ops['auc_update_op']] + [summary_ops['acc_update_ops']], feed_dict=feed_dict)
|
| 234 |
+
assert scene_idx[0] == (pcreader._num_train_samples + batch_idx)
|
| 235 |
+
losses.append(loss_val)
|
| 236 |
+
losses_dir.append(dir_loss)
|
| 237 |
+
losses_ce.append(bin_ce_loss)
|
| 238 |
+
losses_off.append(offset_loss)
|
| 239 |
+
losses_app.append(approach_loss)
|
| 240 |
+
losses_add.append(adds_loss)
|
| 241 |
+
losses_add_gt2pred.append(adds_gt2pred_loss)
|
| 242 |
+
|
| 243 |
+
loss_mean = np.mean(losses)
|
| 244 |
+
losses_dir_mean = np.mean(losses_dir)
|
| 245 |
+
loss_ce_mean = np.mean(losses_ce)
|
| 246 |
+
loss_off_mean = np.mean(losses_off)
|
| 247 |
+
loss_app_mean = np.mean(losses_app)
|
| 248 |
+
loss_add_mean = np.mean(losses_add)
|
| 249 |
+
loss_add_gt2pred_mean = np.mean(losses_add_gt2pred)
|
| 250 |
+
|
| 251 |
+
file_writers['test_writer'].add_summary(pr_summary, step)
|
| 252 |
+
|
| 253 |
+
log_string('mean val loss: %f \t mean val dir loss: %f \t mean val ce loss: %f \t mean off loss: %f \t mean app loss: %f \t mean adds loss: %f \t mean adds_gt2pred loss: %f' % (loss_mean, losses_dir_mean, loss_ce_mean, loss_off_mean, loss_app_mean, loss_add_mean, loss_add_gt2pred_mean))
|
| 254 |
+
|
| 255 |
+
return step
|
| 256 |
+
|
| 257 |
+
if __name__ == "__main__":
|
| 258 |
+
|
| 259 |
+
parser = argparse.ArgumentParser()
|
| 260 |
+
parser.add_argument('--gpu', type=int, default=0, help='GPU to use [default: GPU 0]')
|
| 261 |
+
parser.add_argument('--log_dir', default='/result', help='Log dir [default: log]')
|
| 262 |
+
parser.add_argument('--data_path', type=str, default=None, help='internal grasp root dir')
|
| 263 |
+
parser.add_argument('--max_epoch', type=int, default=None, help='Epoch to run [default: 201]')
|
| 264 |
+
parser.add_argument('--batch_size', type=int, default=None, help='Batch Size during training [default: 32]')
|
| 265 |
+
parser.add_argument('--classes', nargs="*", type=str, default=None, help='train or test classes')
|
| 266 |
+
parser.add_argument('--arg_configs', nargs="*", type=str, default=[], help='overwrite config parameters')
|
| 267 |
+
FLAGS = parser.parse_args()
|
| 268 |
+
|
| 269 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = str(FLAGS.gpu)
|
| 270 |
+
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
| 271 |
+
|
| 272 |
+
if not os.path.exists(FLAGS.log_dir):
|
| 273 |
+
os.makedirs(FLAGS.log_dir)
|
| 274 |
+
|
| 275 |
+
os.system('cp pointnet2_grasp_direct.py %s' % (FLAGS.log_dir)) # bkp of model def
|
| 276 |
+
os.system('cp train_grasp_direct.py %s' % (FLAGS.log_dir)) # bkp of train procedure
|
| 277 |
+
|
| 278 |
+
LOG_FOUT = open(os.path.join(FLAGS.log_dir, 'log_train.txt'), 'w')
|
| 279 |
+
LOG_FOUT.write(str(FLAGS)+'\n')
|
| 280 |
+
def log_string(out_str):
|
| 281 |
+
LOG_FOUT.write(out_str+'\n')
|
| 282 |
+
LOG_FOUT.flush()
|
| 283 |
+
print(out_str)
|
| 284 |
+
|
| 285 |
+
global_config = utilities.load_config(FLAGS.log_dir, batch_size=FLAGS.batch_size, max_epoch=FLAGS.max_epoch, data_path= FLAGS.data_path, classes=FLAGS.classes, arg_configs=FLAGS.arg_configs)
|
| 286 |
+
|
| 287 |
+
log_string(str(global_config))
|
| 288 |
+
log_string('pid: %s'%(str(os.getpid())))
|
| 289 |
+
|
| 290 |
+
train(global_config, FLAGS.log_dir)
|
| 291 |
+
|
| 292 |
+
LOG_FOUT.close()
|