| 42 | |
| 43 | |
| 44 | class GCN(nn.Module): |
| 45 | def __init__(self, seq, n_fea, adj_dense): |
| 46 | super(GCN, self).__init__() |
| 47 | self.nodes = adj_dense.shape[0] |
| 48 | self.encoder = nn.Conv2d(self.nodes, self.nodes, (n_fea, n_fea)) |
| 49 | self.gcn_l1 = nn.Linear(seq-n_fea+1, seq-n_fea+1) |
| 50 | self.gcn_l2 = nn.Linear(seq-n_fea+1, seq-n_fea+1) |
| 51 | self.A = adj_dense |
| 52 | self.act = nn.ReLU() |
| 53 | self.decoder = nn.Linear(seq-n_fea+1, 1) |
| 54 | |
| 55 | # calculate A_delta matrix |
| 56 | deg = torch.sum(adj_dense, dim=0) |
| 57 | deg = torch.diag(deg) |
| 58 | deg_delta = torch.linalg.inv(torch.sqrt(deg)) |
| 59 | a_delta = torch.matmul(torch.matmul(deg_delta, adj_dense), deg_delta) |
| 60 | self.A = a_delta |
| 61 | |
| 62 | def forward(self, occ, prc): # occ.shape = [batch, node, seq] |
| 63 | x = torch.stack([occ, prc], dim=3) |
| 64 | x = self.encoder(x) |
| 65 | # l1 |
| 66 | x = self.gcn_l1(x) |
| 67 | x = torch.matmul(self.A, x) |
| 68 | x = self.act(x) |
| 69 | # l2 |
| 70 | x = self.gcn_l2(x) |
| 71 | x = torch.matmul(self.A, x) |
| 72 | x = self.act(x) |
| 73 | x = self.decoder(x) |
| 74 | return x |
| 75 | |
| 76 | |
| 77 | class LstmGcn(nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected