Dimios45 commited on
Commit
5861243
·
verified ·
1 Parent(s): 022720f

Upload models/geomatch.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. models/geomatch.py +182 -0
models/geomatch.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 DeepMind Technologies Limited
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+
16
+ """GeoMatch model definition."""
17
+
18
+ from models.gnn import GCN
19
+ from models.mlp import MLP
20
+ import torch
21
+ from torch import nn
22
+
23
+
24
+ class GeoMatchARModule(nn.Module):
25
+ """Autoregressive module class for GeoMatch."""
26
+
27
+ def __init__(self, config, n_kp) -> None:
28
+ super().__init__()
29
+
30
+ self.config = config
31
+ self.n_kp = n_kp
32
+ self.final_fc = MLP(128 + 3 * self.n_kp, 1, 3, 256)
33
+
34
+ def forward(self, obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev):
35
+ robot_i_embed = (
36
+ robot_proj_embed[:, self.n_kp][..., None]
37
+ .transpose(2, 1)
38
+ .repeat(1, self.config.obj_pc_n, 1)
39
+ )
40
+ obj_robot_embed = torch.cat((obj_proj_embed, robot_i_embed), dim=-1)
41
+
42
+ diff_xyz_tensor = []
43
+ for i in range(self.n_kp):
44
+ diff_xyz = obj_pc - xyz_prev[:, i, :][..., None].transpose(2, 1)
45
+ diff_xyz_tensor.append(diff_xyz)
46
+
47
+ diff_xyz_tensor = torch.stack(diff_xyz_tensor, dim=-1)
48
+ diff_xyz_tensor = diff_xyz_tensor.view(
49
+ diff_xyz_tensor.shape[0], diff_xyz_tensor.shape[1], -1
50
+ )
51
+ inp = torch.cat((obj_robot_embed, diff_xyz_tensor), dim=-1)
52
+ pred_curr = self.final_fc(inp)
53
+
54
+ return pred_curr
55
+
56
+ def calc_loss(self, pred, label):
57
+ pred = pred.view(pred.shape[0] * pred.shape[1], 1)
58
+ label = label.view(label.shape[0] * label.shape[1], 1)
59
+
60
+ pos_weight = torch.tensor([1000.0]).cuda()
61
+ loss = nn.BCEWithLogitsLoss(pos_weight=pos_weight)(pred, label)
62
+ return torch.mean(loss)
63
+
64
+
65
+ class GeoMatch(nn.Module):
66
+ """GeoMatch model class."""
67
+
68
+ def __init__(self, config) -> None:
69
+ super().__init__()
70
+
71
+ self.config = config
72
+ self.n_kp = config.keypoint_n
73
+ self.robot_weighting = config.robot_weighting
74
+ self.match_weighting = config.matchnet_weighting
75
+ self.dist_loss_weight = config.dist_loss_weight
76
+ self.match_loss_weight = config.match_loss_weight
77
+
78
+ self.obj_encoder = GCN(
79
+ nfeat=config.obj_in_feats,
80
+ nhid=config.hidden_n,
81
+ nout=config.obj_out_feats,
82
+ dropout=0.5,
83
+ num_hidden=config.num_hidden,
84
+ )
85
+
86
+ self.robot_encoder = GCN(
87
+ nfeat=config.robot_in_feats,
88
+ nhid=config.hidden_n,
89
+ nout=config.robot_out_feats,
90
+ dropout=0.5,
91
+ num_hidden=config.num_hidden,
92
+ )
93
+
94
+ self.obj_proj = nn.Linear(self.config.obj_out_feats, 64, bias=False)
95
+ self.robot_proj = nn.Linear(self.config.robot_out_feats, 64, bias=False)
96
+ self.kp_ar_model_1 = GeoMatchARModule(config, 1)
97
+ self.kp_ar_model_2 = GeoMatchARModule(config, 2)
98
+ self.kp_ar_model_3 = GeoMatchARModule(config, 3)
99
+ self.kp_ar_model_4 = GeoMatchARModule(config, 4)
100
+ self.kp_ar_model_5 = GeoMatchARModule(config, 5)
101
+
102
+ def encode_embed(self, encoder, feature, adj_mat, normalize_emb=True):
103
+ x = encoder(feature, adj_mat)
104
+ if normalize_emb:
105
+ x = x.clone() / (torch.norm(x, dim=-1, keepdim=True) + 1e-6)
106
+ return x
107
+
108
+ def forward(
109
+ self, obj_pc, robot_pc, robot_key_point_idx, obj_adj, robot_adj, xyz_prev
110
+ ):
111
+ obj_embed = self.encode_embed(self.obj_encoder, obj_pc, obj_adj)
112
+ robot_embed = self.encode_embed(self.robot_encoder, robot_pc, robot_adj)
113
+
114
+ robot_feat_size = robot_embed.shape[2]
115
+ keypoint_feat = torch.gather(
116
+ robot_embed,
117
+ 1,
118
+ robot_key_point_idx[..., None].long().repeat(1, 1, robot_feat_size),
119
+ )
120
+ contact_map_pred = torch.matmul(obj_embed, keypoint_feat.transpose(2, 1))[
121
+ ..., None
122
+ ]
123
+
124
+ obj_proj_embed = self.obj_proj(obj_embed)
125
+ robot_proj_embed = self.robot_proj(robot_embed)
126
+
127
+ output_1 = self.kp_ar_model_1(
128
+ obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev
129
+ )
130
+ output_2 = self.kp_ar_model_2(
131
+ obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev
132
+ )
133
+ output_3 = self.kp_ar_model_3(
134
+ obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev
135
+ )
136
+ output_4 = self.kp_ar_model_4(
137
+ obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev
138
+ )
139
+ output_5 = self.kp_ar_model_5(
140
+ obj_proj_embed, obj_pc, robot_proj_embed, xyz_prev
141
+ )
142
+
143
+ output = torch.cat(
144
+ (output_1, output_2, output_3, output_4, output_5), dim=-1
145
+ )[..., None]
146
+
147
+ return contact_map_pred, output
148
+
149
+ def calc_loss(self, gt_contact_map, contact_map_pred, pred, label):
150
+ flat_contact_map_pred = contact_map_pred.view(
151
+ contact_map_pred.shape[0]
152
+ * contact_map_pred.shape[1]
153
+ * contact_map_pred.shape[2],
154
+ 1,
155
+ )
156
+ flat_gt_contact_map = gt_contact_map.view(
157
+ gt_contact_map.shape[0]
158
+ * gt_contact_map.shape[1]
159
+ * gt_contact_map.shape[2],
160
+ 1,
161
+ )
162
+
163
+ pos_weight = torch.Tensor([self.robot_weighting]).cuda()
164
+ loss = nn.BCEWithLogitsLoss(pos_weight=pos_weight)(
165
+ flat_contact_map_pred, flat_gt_contact_map
166
+ )
167
+ l_dist = torch.mean(loss)
168
+
169
+ pos_weight = torch.tensor([self.match_weighting]).cuda()
170
+
171
+ loss = []
172
+ for i in range(self.n_kp - 1):
173
+ pred_i = pred[:, :, i]
174
+ label_i = label[:, :, i]
175
+ pred_i = pred_i.view(pred_i.shape[0] * pred_i.shape[1], 1)
176
+ label_i = label_i.view(label_i.shape[0] * label_i.shape[1], 1)
177
+ loss.append(nn.BCEWithLogitsLoss(pos_weight=pos_weight)(pred_i, label_i))
178
+
179
+ loss = torch.stack(loss)
180
+ l_match = torch.mean(loss)
181
+
182
+ return self.dist_loss_weight * l_dist + self.match_loss_weight * l_match