Solves the GEM dual QP described in the paper given a proposed gradient "gradient", and a memory of task gradients "memories". Overwrites "gradient" with the final projected update. input: gradient, p-vector input: memories, (t * p)-vector output:
(gradient, memories, margin=0.5, eps=1e-3)
| 62 | |
| 63 | |
| 64 | def project2cone2(gradient, memories, margin=0.5, eps=1e-3): |
| 65 | """ |
| 66 | Solves the GEM dual QP described in the paper given a proposed |
| 67 | gradient "gradient", and a memory of task gradients "memories". |
| 68 | Overwrites "gradient" with the final projected update. |
| 69 | |
| 70 | input: gradient, p-vector |
| 71 | input: memories, (t * p)-vector |
| 72 | output: x, p-vector |
| 73 | """ |
| 74 | |
| 75 | memories_np = memories.cpu().t().double().numpy() |
| 76 | gradient_np = gradient.cpu().contiguous().view(-1).double().numpy() |
| 77 | t = memories_np.shape[0] |
| 78 | P = np.dot(memories_np, memories_np.transpose()) |
| 79 | P = 0.5 * (P + P.transpose()) + np.eye(t) * eps |
| 80 | q = np.dot(memories_np, gradient_np) * -1 |
| 81 | G = np.eye(t) |
| 82 | h = np.zeros(t) + margin |
| 83 | v = quadprog.solve_qp(P, q, G, h)[0] |
| 84 | x = np.dot(v, memories_np) + gradient_np |
| 85 | gradient.copy_(torch.Tensor(x).view(-1, 1)) |
| 86 | |
| 87 | |
| 88 | class Net(nn.Module): |