我正试图从一篇研究论文中重建一个模型。没有错误发生,但准确性度量不会改变。我尝试了很多不同的解决方案,其中大多数通常以错误告终,我不得不追踪,直到我失去希望。
数据是使用PyTorch Geometric创建的图形。我确保数据是有效的,没有任何问题。每个图有18个节点,每个节点有18个特征。图是稀疏的,边的数量从一个图到另一个图是不同的。图的边被加权。
为了您的方便,完整的代码沿着数据可以在Colab上找到。
如果你喜欢代码在这里。需要构建的模型:
class GCNModel(nn.Module):
def __init__(self):
super(GCNModel, self).__init__()
# Block1
self.conv1 = GCNConv(in_channels=18, out_channels=64) # Graph Convolution
self.relu1 = nn.ReLU()
self.conv2 = GCNConv(in_channels=64, out_channels=32) # Graph Convolution
self.relu2 = nn.ReLU()
self.pool = global_mean_pool
# Block2
self.fc1 = nn.Linear(32, 32) # Fully Connected
self.dropout1 = nn.Dropout(0.3) # Dropout layer with p=0.3
self.relu3 = nn.ReLU()
self.fc2 = nn.Linear(32, 16) # Fully Connected
self.dropout2 = nn.Dropout(0.3) # Dropout layer with p=0.3
self.relu4 = nn.ReLU()
self.fc3 = nn.Linear(16, 1) # Fully Connected
def forward(self, data):
x, edge_index, edge_attr, batch = data.x, data.edge_index, data.edge_attr, data.batch
# Block1
x = self.conv1(x, edge_index, edge_attr) # Pass edge_attr to the convolution
x = self.relu1(x)
# ReLU Graph Convolution
x = self.conv2(x, edge_index, edge_attr) # Pass edge_attr to the convolution
x = self.relu2(x)
# Average pooling along the spatial dimension
x = self.pool(x, batch)
# Block2 Fully Connected
x = self.fc1(x)
x = self.dropout1(x) # Apply dropout
x = self.relu3(x)
# ReLU Fully Connected
x = self.fc2(x)
x = self.dropout2(x) # Apply dropout
x = self.relu4(x)
# ReLU Fully Connected
x = self.fc3(x)
return x
培训、验证和测试程序:
# Instantiate GCNModel
model = GCNModel()
# Define optimizer and learning rate
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=0.0001)
# Define your loss function
criterion = nn.CrossEntropyLoss()
# Define the data loaders
train_loader = DataLoader(data_train, batch_size=64, shuffle=True)
val_loader = DataLoader(data_val, batch_size=64, shuffle=False)
test_loader = DataLoader(data_test, batch_size=64, shuffle=False)
# Training loop
def train(epoch):
model.train()
for data in train_loader:
optimizer.zero_grad()
output = model(data)
loss = criterion(output, data.y.view(-1, 1).float())
loss.backward()
optimizer.step()
# Function to compute accuracy
def compute_accuracy(loader):
model.eval()
predictions = []
labels = []
with torch.no_grad():
for data in loader:
output = model(data)
predictions.extend(torch.argmax(output, axis=1).cpu().numpy()) # Use argmax for predicted labels
labels.extend(data.y.cpu().numpy())
accuracy = accuracy_score(labels, predictions)
return accuracy
# Training and validation
num_epochs = 50 # Train for 50 epochs
for epoch in range(1, num_epochs + 1):
train(epoch)
train_acc = compute_accuracy(train_loader) # Compute accuracy on training data
val_acc = compute_accuracy(val_loader)
print(f"Epoch [{epoch}/{num_epochs}], Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f}")
# Testing
test_acc = compute_accuracy(test_loader)
print(f"Testing Accuracy: {test_acc:.4f}")
输出量:
Epoch [1/50], Train Acc: 0.4471, Val Acc: 0.4470
Epoch [2/50], Train Acc: 0.4471, Val Acc: 0.4470
.
.
.
Epoch [50/50], Train Acc: 0.4471, Val Acc: 0.4470
谢谢你的帮助
2条答案
按热度按时间xjreopfe1#
这是因为根据你的代码,最后一层以一个完全连接的层结束,你错过了输入Softmax层进行预测,因此模型并没有真正学习到任何重要的东西。修改代码的forward方法,在最后一层添加softmax,如下所示:
编辑2:我还发现了一些与您构建的模型不一致的地方,根据您提供的模型配置,正确的模型应该如下所示:
打印输出:
你看,现在跟你的型号配置匹配了:
mm9b1k5b2#
问题已解决。它需要编辑模型并从头开始重写。我也使用SkLearn来计算准确度。代码可以在上面提供的Colab链接中找到,只要它可以在线获得。