|
67 | 67 | "outputs": [], |
68 | 68 | "source": [ |
69 | 69 | "class SymmetricParametrization(nn.Module):\n", |
70 | | - " def forward(X):\n", |
| 70 | + " def forward(self, X):\n", |
71 | 71 | " A = X.triu()\n", |
72 | 72 | " return A + A.T " |
73 | 73 | ] |
|
113 | 113 | "source": [ |
114 | 114 | "class PruningParametrization(nn.Module):\n", |
115 | 115 | " def __init__(self, X, p_drop=0.2):\n", |
| 116 | + " super().__init__()\n", |
116 | 117 | " # sample zeros with probability p_drop\n", |
117 | 118 | " mask = torch.full_like(X, 1.0 - p_drop)\n", |
118 | | - " self.mask = torch.bernoulli(mask)\n", |
| 119 | + " self.register_buffer(\"mask\", torch.bernoulli(mask))\n", |
119 | 120 | "\n", |
120 | 121 | " def forward(self, X):\n", |
121 | 122 | " return X * self.mask" |
|
322 | 323 | "# In other words, right_inverse is a right inverse of forward.\n", |
323 | 324 | "\n", |
324 | 325 | "model = nn.Linear(5, 5)\n", |
| 326 | + "with torch.no_grad():\n", |
| 327 | + " model.weight.copy_(model.weight - model.weight.T)\n", |
325 | 328 | "P.register_parametrization(model, \"weight\", Skew())\n", |
326 | 329 | "# Just computes `model.weight` once\n", |
327 | 330 | "with P.cached():\n", |
|
347 | 350 | " def forward(self, A):\n", |
348 | 351 | " # Cayley map: (I + A)(I - A)^{-1}\n", |
349 | 352 | " # This is orthogonal whenever A is skew-symmetric\n", |
350 | | - " Id = torch.eye(A.size(0))\n", |
| 353 | + " Id = torch.eye(A.size(0), dtype=A.dtype, device=A.device)\n", |
351 | 354 | " return self.B @ torch.linalg.solve(Id - A, Id + A)\n", |
352 | 355 | "\n", |
353 | 356 | " def is_orthogonal(self, X):\n", |
354 | | - " Id = torch.eye(X.size(0))\n", |
| 357 | + " Id = torch.eye(X.size(0), dtype=X.dtype, device=X.device)\n", |
355 | 358 | " return torch.allclose(X.T @ X, Id, atol=1e-6)\n", |
356 | 359 | "\n", |
357 | 360 | " def right_inverse(self, X):\n", |
|
362 | 365 | " return torch.zeros_like(X)\n", |
363 | 366 | "\n", |
364 | 367 | "\n", |
365 | | - "model = nn.Linear(5,5)\n", |
| 368 | + "model = nn.Linear(4, 4)\n", |
| 369 | + "X = torch.zeros_like(model.weight)\n", |
| 370 | + "X.diagonal(offset=1)[::2] = 1.0\n", |
| 371 | + "X = X - X.T\n", |
| 372 | + "with torch.no_grad():\n", |
| 373 | + " model.weight.copy_(X)\n", |
366 | 374 | "P.register_parametrization(model, \"weight\", Skew())\n", |
367 | | - "P.register_parametrization(model, \"weight\", Orthogonal(5))\n", |
| 375 | + "P.register_parametrization(model, \"weight\", Orthogonal(4))\n", |
368 | 376 | "\n", |
369 | 377 | "# Sample an orthogonal matrix and initialise the layer\n", |
370 | 378 | "X = torch.empty_like(model.weight)\n", |
|
0 commit comments