solve min_a GW(C1,C2,a, a2) by gradient descent
(C1, C2, a2, nb_iter_max=100, lr=1e-2)
| 109 | |
| 110 | |
| 111 | def min_weight_gw(C1, C2, a2, nb_iter_max=100, lr=1e-2): |
| 112 | """solve min_a GW(C1,C2,a, a2) by gradient descent""" |
| 113 | |
| 114 | # use pyTorch for our data |
| 115 | C1_torch = torch.tensor(C1) |
| 116 | C2_torch = torch.tensor(C2) |
| 117 | |
| 118 | a0 = rng.rand(C1.shape[0]) # random_init |
| 119 | a0 /= a0.sum() # on simplex |
| 120 | a1_torch = torch.tensor(a0).requires_grad_(True) |
| 121 | a2_torch = torch.tensor(a2) |
| 122 | |
| 123 | loss_iter = [] |
| 124 | |
| 125 | for i in range(nb_iter_max): |
| 126 | loss = gromov_wasserstein2(C1_torch, C2_torch, a1_torch, a2_torch) |
| 127 | |
| 128 | loss_iter.append(loss.clone().detach().cpu().numpy()) |
| 129 | loss.backward() |
| 130 | |
| 131 | # print("{:03d} | {}".format(i, loss_iter[-1])) |
| 132 | |
| 133 | # performs a step of projected gradient descent |
| 134 | with torch.no_grad(): |
| 135 | grad = a1_torch.grad |
| 136 | a1_torch -= grad * lr # step |
| 137 | a1_torch.grad.zero_() |
| 138 | a1_torch.data = ot.utils.proj_simplex(a1_torch) |
| 139 | |
| 140 | a1 = a1_torch.clone().detach().cpu().numpy() |
| 141 | |
| 142 | return a1, loss_iter |
| 143 | |
| 144 | |
| 145 | a0_est, loss_iter0 = min_weight_gw(C0, C1, ot.unif(n), nb_iter_max=100, lr=1e-2) |
no test coverage detected