solve min_a GW(C1,C2,a, a2) by gradient descent
(nb_nodes, C2, a2, nb_iter_max=100, lr=1e-2)
| 198 | |
| 199 | |
| 200 | def graph_compression_gw(nb_nodes, C2, a2, nb_iter_max=100, lr=1e-2): |
| 201 | """solve min_a GW(C1,C2,a, a2) by gradient descent""" |
| 202 | |
| 203 | # use pyTorch for our data |
| 204 | |
| 205 | C2_torch = torch.tensor(C2) |
| 206 | a2_torch = torch.tensor(a2) |
| 207 | |
| 208 | a0 = rng.rand(nb_nodes) # random_init |
| 209 | a0 /= a0.sum() # on simplex |
| 210 | a1_torch = torch.tensor(a0).requires_grad_(True) |
| 211 | C0 = np.eye(nb_nodes) |
| 212 | C1_torch = torch.tensor(C0).requires_grad_(True) |
| 213 | |
| 214 | loss_iter = [] |
| 215 | |
| 216 | for i in range(nb_iter_max): |
| 217 | loss = gromov_wasserstein2(C1_torch, C2_torch, a1_torch, a2_torch) |
| 218 | |
| 219 | loss_iter.append(loss.clone().detach().cpu().numpy()) |
| 220 | loss.backward() |
| 221 | |
| 222 | # print("{:03d} | {}".format(i, loss_iter[-1])) |
| 223 | |
| 224 | # performs a step of projected gradient descent |
| 225 | with torch.no_grad(): |
| 226 | grad = a1_torch.grad |
| 227 | a1_torch -= grad * lr # step |
| 228 | a1_torch.grad.zero_() |
| 229 | a1_torch.data = ot.utils.proj_simplex(a1_torch) |
| 230 | |
| 231 | grad = C1_torch.grad |
| 232 | C1_torch -= grad * lr # step |
| 233 | C1_torch.grad.zero_() |
| 234 | C1_torch.data = torch.clamp(C1_torch, 0, 1) |
| 235 | |
| 236 | a1 = a1_torch.clone().detach().cpu().numpy() |
| 237 | C1 = C1_torch.clone().detach().cpu().numpy() |
| 238 | |
| 239 | return a1, C1, loss_iter |
| 240 | |
| 241 | |
| 242 | nb_nodes = 3 |
no test coverage detected