(self, x)
| 36 | nn.init.constant_(self.y2, 0.5) |
| 37 | |
| 38 | def forward(self, x): |
| 39 | |
| 40 | # if the two scalars are negative then we setting them to 0 |
| 41 | if (self.y1[0] < 0): |
| 42 | y1 = torch.cuda.FloatTensor(1, ) |
| 43 | self.y1 = nn.Parameter(y1) |
| 44 | nn.init.constant_(self.y1, 0.01) |
| 45 | |
| 46 | if (self.y2[0] < 0): |
| 47 | y2 = torch.cuda.FloatTensor(1, ) |
| 48 | self.y2 = nn.Parameter(y2) |
| 49 | nn.init.constant_(self.y2, 0.01) |
| 50 | |
| 51 | # normalization along the temporal dimensione |
| 52 | T2 = torch.ones([self.t1, 1], device="cuda") |
| 53 | x2 = torch.mean(x, dim=2) |
| 54 | x2 = torch.reshape(x2, (x2.shape[0], x2.shape[1], 1)) |
| 55 | |
| 56 | std = torch.std(x, dim=2) |
| 57 | std = torch.reshape(std, (std.shape[0], std.shape[1], 1)) |
| 58 | # it can be possible that the std of some temporal slices is 0, and this produces inf values, so we have to set them to one |
| 59 | std[std < 1e-4] = 1 |
| 60 | |
| 61 | diff = x - (x2 @ (T2.T)) |
| 62 | Z2 = diff / (std @ (T2.T)) |
| 63 | |
| 64 | X2 = self.l2 @ T2.T |
| 65 | X2 = X2 * Z2 |
| 66 | X2 = X2 + (self.B2 @ T2.T) |
| 67 | |
| 68 | # normalization along the feature dimension |
| 69 | T1 = torch.ones([self.d1, 1], device="cuda") |
| 70 | x1 = torch.mean(x, dim=1) |
| 71 | x1 = torch.reshape(x1, (x1.shape[0], x1.shape[1], 1)) |
| 72 | |
| 73 | std = torch.std(x, dim=1) |
| 74 | std = torch.reshape(std, (std.shape[0], std.shape[1], 1)) |
| 75 | |
| 76 | op1 = x1 @ T1.T |
| 77 | op1 = torch.permute(op1, (0, 2, 1)) |
| 78 | |
| 79 | op2 = std @ T1.T |
| 80 | op2 = torch.permute(op2, (0, 2, 1)) |
| 81 | |
| 82 | z1 = (x - op1) / (op2) |
| 83 | X1 = (T1 @ self.l1.T) |
| 84 | X1 = X1 * z1 |
| 85 | X1 = X1 + (T1 @ self.B1.T) |
| 86 | |
| 87 | # weighing the imporance of temporal and feature normalization |
| 88 | x = self.y1 * X1 + self.y2 * X2 |
| 89 | |
| 90 | return x |
nothing calls this directly
no outgoing calls
no test coverage detected