RRF / model_skeletons /model_class_4.py
antonypamo's picture
Upload 26 files (#6)
ce680a7 verified
Raw
History Blame Contribute Delete
1.68 kB
# Auto-extracted class source (static)
class DiracGraphConv(nn.Module):
def __init__(self, in_dim: int, out_dim: int, alpha: float = 1.0, bias: bool = True):
super().__init__()
self.lin = nn.Linear(in_dim, out_dim, bias=bias)
self.alpha = nn.Parameter(torch.tensor(alpha, dtype=torch.float32))
self.bias_edge = nn.Parameter(torch.tensor(0.0, dtype=torch.float32))
@staticmethod
def cosine_corr(z_i: torch.Tensor, z_j: torch.Tensor, eps: float = 1e-9) -> torch.Tensor:
num = (z_i * z_j).sum(dim=-1)
den = torch.clamp(z_i.norm(dim=-1) * z_j.norm(dim=-1), min=eps)
return num / den
def forward(self, x: torch.Tensor, edge_index: torch.Tensor, z: torch.Tensor) -> torch.Tensor:
N = x.size(0)
row, col = edge_index
corr = self.cosine_corr(z[row], z[col])
logits = self.alpha * corr + self.bias_edge
device = x.device
E = row.size(0)
ones = torch.ones(E, device=device)
max_per_row = torch.full((N,), -1e9, device=device)
max_per_row = max_per_row.index_put((row,), logits, accumulate=False).scatter_reduce_(0, row, logits, reduce="amax")
logits_centered = logits - max_per_row[row]
exp_logits = torch.exp(logits_centered)
denom = torch.zeros(N, device=device).index_add_(0, row, exp_logits)
attn = exp_logits / (denom[row] + 1e-9)
deg = torch.zeros(N, device=device).index_add_(0, row, ones)
norm = 1.0 / torch.clamp(deg[row], min=1.0)
msgs = norm.unsqueeze(-1) * attn.unsqueeze(-1) * x[col]
out = torch.zeros_like(x).index_add_(0, row, msgs)
return self.lin(out)