MCPcopy Create free account
hub / github.com/ZJUDataIntelligence/Ultrasound-CLIP / GraphEncoder

Class GraphEncoder

graph_encoder.py:9–140  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

7warnings.filterwarnings('ignore')
8
9class GraphEncoder(nn.Module):
10
11
12 def __init__(self, out_dim: int, args=None, hidden: int = 128, n_layers: int = 2, dropout: float = 0.1):
13 super().__init__()
14 self.out_dim = out_dim
15 self.hidden = hidden
16 self.n_layers = n_layers
17 self.dropout = nn.Dropout(p=dropout)
18
19 self.type_embeddings = nn.ParameterDict()
20
21 self.diag_emb = nn.Embedding(len(DIAGNOSIS_VOCAB) + 1, hidden)
22 self.desc_emb = nn.Embedding(len(DESCRIPTOR_VOCAB) + 1, hidden)
23 self.node_norm = nn.LayerNorm(hidden)
24
25 self.convs = nn.ModuleList([
26 HeteroGraphConv({}, aggregate='sum') for _ in range(n_layers)
27 ])
28
29 self.proj = nn.Linear(hidden, out_dim)
30
31 def _ensure_type_embeddings(self, g: dgl.DGLHeteroGraph, device):
32 for ntype in g.ntypes:
33 key = f"emb_{ntype}"
34 if key not in self.type_embeddings:
35 param = nn.Parameter(torch.zeros(self.hidden, device=device, dtype=torch.float32))
36 nn.init.xavier_uniform_(param.unsqueeze(0))
37 self.type_embeddings[key] = param
38
39 def _ensure_convs(self, g: dgl.DGLHeteroGraph, device):
40 for layer_idx in range(self.n_layers):
41 conv: HeteroGraphConv = self.convs[layer_idx]
42 if len(conv.mods) == 0:
43 mods = {}
44 for srctype, etype, dsttype in g.canonical_etypes:
45 mods[etype] = GraphConv(in_feats=self.hidden, out_feats=self.hidden, norm='both', allow_zero_in_degree=True)
46 conv.mods = nn.ModuleDict(mods)
47 self.convs[layer_idx] = conv.to(device)
48
49 def _infer_batch_size(self, g: dgl.DGLHeteroGraph) -> int:
50 if hasattr(g, 'batch_size'):
51 return g.batch_size
52 try:
53 if len(g.ntypes) > 0 and hasattr(g, 'batch_num_nodes'):
54 base_ntype = g.ntypes[0]
55 return len(g.batch_num_nodes(base_ntype))
56 except Exception:
57 pass
58 return 1
59
60 def _safe_mean_nodes(self, g: dgl.DGLHeteroGraph, ntype: str):
61 if ntype not in g.ntypes or g.num_nodes(ntype) == 0:
62 return None
63 pooled = dgl.mean_nodes(g, 'h', ntype=ntype)
64 if pooled is None:
65 return None
66 pooled = torch.nan_to_num(pooled, nan=0.0, posinf=0.0, neginf=0.0).float()

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected