Reference:
- https://tkipf.github.io/graph-convolutional-networks/
- https://blog.youkuaiyun.com/chanbo8205/article/details/119275065

Input & Output
Takes as input:
- A feature description x i x_i xi for every node i i i; summarized in a N × D N×D N×D feature matrix X X X ( N N N: number of nodes, D D D: number of input features)
- A representative description of the graph structure in matrix form; typically in the form of an adjacency matrix
A
A
A (or some function thereof)
Produces a node-level output Z Z Z (an N × F N×F N×F feature matrix, where F F F is the number of output features per node)
Basic Understanding of GCN
Reference: Kipf & Welling (ICLR 2017)

Every neural network layer can then be written as a non-linear function
H
(
L
+
1
)
=
f
(
H
(
L
)
,
A
)
H^{(L+1)}=f(H^{(L)},A)
H(L+1)=f(H(L),A)
with
H
(
0
)
=
X
H^{(0)}=X
H(0)=X and
H
(
L
)
=
Z
H^{(L)}=Z
H(L)=Z (or
Z
Z
Z for graph-level outputs),
L
L
L being the number of layers. The specific models then differ only in how
f
(
⋅
,
⋅
)
f(⋅,⋅)
f(⋅,⋅) is chosen and parameterized.
Refer to this article for a simple to complex model process: Kipf & Welling (ICLR 2017)
Notes Below:
For a model with out_features=2, the activation layer of softmax and the cross entropy function are required.
class GCN(nn.Module):
def __init__(self, in_features, hidden_features, out_features):
super(GCN, self).__init__()
self.conv1 = GCNConv(in_features, hidden_features)
self.conv2 = GCNConv(hidden_features, out_features)
def forward(self, x, edge_list, device, edge_attr=None, node_mask=None):
x = F.relu(self.conv1(x, edge_list, device, edge_attr))
x = self.conv2(x, edge_list, device, edge_attr)
x = torch.softmax(x, dim=-1)
return x
model = GCN(in_features=10, hidden_features=32, out_features=2).to(device)
criterion = nn.CrossEntropyLoss()
For a model with out_features=1, the activation layer of sigmoid and the BCELoss function are required.
class GCN(nn.Module):
def __init__(self, in_features, hidden_features, out_features):
super(GCN, self).__init__()
self.conv1 = GCNConv(in_features, hidden_features)
self.conv2 = GCNConv(hidden_features, out_features)
def forward(self, x, edge_list, device, edge_attr=None, node_mask=None):
x = F.relu(self.conv1(x, edge_list, device, edge_attr))
x = self.conv2(x, edge_list, device, edge_attr)
x = torch.sigmoid(x)
return x
model = GCN(in_features=10, hidden_features=32, out_features=1).to(device)
criterion = nn.BCELoss()
In contrast:
If you use the binary_cross_entropy function, it usually expects the input and target tensor shapes to match exactly, and for binary classification problems, the input tensor should usually be (N, 1), the target tensor should also be (N, 1), and an error will be reported if there is no match.
CrossEntropyLoss is more suitable for multi-classification problems. When out_feature is 2, CrossEntropyLoss can handle the shape difference between the input and the target tensor well, avoiding the problem of shape error (inner softmax).
LSTM-GCN Model (Brief)
- LSTM is good at handling sequential data, capturing temporal dependencies.
- GCN is effective for graph-structured data, learning node features by aggregating information from neighbors.
In the example code above, the input is a two-dimensional tensor, if the input is a sequence:
We need to convert the data into two dimensions before entering it into GCN, and the easiest way is through the LSTM model.
LSTM processes sequential data first, generating features. Then, these features are fed into GCN, which exploits graph structure.
2312

被折叠的 条评论
为什么被折叠?



