gnn-lam / app /inference_wrapper.py
mayaj5's picture
Set up Docker
f8cd57c
Raw
History Blame Contribute Delete
2.41 kB
from typing import Optional
import torch
import torch.nn as nn
import torch.nn.functional as F
class InferenceGraphSAGE(nn.Module):
def __init__(self, in_dim: int = 768, hidden_dim: int = 256, num_layers: int = 2, dropout: float = 0.1):
super().__init__()
self.dropout = float(dropout)
self.linears = nn.ModuleList()
cur_in = in_dim
for _ in range(num_layers):
self.linears.append(nn.Linear(cur_in * 2, hidden_dim))
cur_in = hidden_dim
self.class_wheeze = nn.Linear(cur_in, 1)
self.class_crackle = nn.Linear(cur_in, 1)
self.act = nn.ReLU()
def forward(self, x: torch.Tensor, adj: torch.Tensor):
for lin in self.linears:
deg = adj.sum(dim=-1, keepdim=True).clamp(min=1.0)
neighbor_mean = torch.matmul(adj, x) / deg
h = torch.cat([x, neighbor_mean], dim=-1)
h = self.act(lin(h))
h = F.dropout(h, p=self.dropout, training=self.training)
x = h
wheeze = torch.sigmoid(self.class_wheeze(x).squeeze(-1))
crackle = torch.sigmoid(self.class_crackle(x).squeeze(-1))
return wheeze, crackle
def load_checkpoint_flexible(model: nn.Module, path: str, map_location: Optional[str] = "cpu") -> nn.Module:
ck = torch.load(path, map_location=map_location)
if isinstance(ck, dict) and ("state_dict" in ck or "model_state_dict" in ck):
state = ck.get("state_dict", ck.get("model_state_dict"))
else:
state = ck
try:
model.load_state_dict(state, strict=False)
return model
except Exception:
ms = model.state_dict()
incoming = {}
for k, v in state.items():
k2 = k[7:] if k.startswith("module.") else k
incoming[k2] = v
resolved = {}
for k, v in incoming.items():
if k in ms and ms[k].shape == v.shape:
resolved[k] = v
for k_in, v in incoming.items():
if k_in in resolved:
continue
for k_model, v_model in ms.items():
if k_model in resolved:
continue
if v_model.shape == v.shape and k_model.endswith(k_in.split(".")[-1]):
resolved[k_model] = v
break
ms.update(resolved)
model.load_state_dict(ms)
return model