我是pytorch的新手,正在尝试为图形数据编写分类器。我有一个91个adj矩阵的数据集(比率为50/41的两类,从fMRI数据中获得的相关矩阵(。目前,我正在努力完成分类任务:我的训练和测试准确性没有改变,尽管损失看起来很正常(?(。这是我的模型的一些代码:
from torch.nn import Linear,Sigmoid
import torch.nn.functional as F
from torch_geometric.nn import GCNConv, BatchNorm, GraphConv
from torch_geometric.nn import global_mean_pool
class GCN(torch.nn.Module):
def __init__(self, hidden_channels):
super(GCN, self).__init__()
torch.manual_seed(12345)
self.conv1 = GCNConv(dataset.num_node_features, hidden_channels)
self.conv2 = GCNConv(hidden_channels, hidden_channels)
self.conv3 = GCNConv(hidden_channels, hidden_channels)
self.lin = Linear(hidden_channels, 1)
def forward(self, x, edge_index, edge_weight, batch):
# 1. Obtain node embeddings
h = self.conv1(x, edge_index, edge_weight)
h = h.relu()
h = self.conv2(h, edge_index, edge_weight)
h = h.relu()
h = self.conv3(h, edge_index, edge_weight)
# 2. Readout layer
h = global_mean_pool(h, batch) # [batch_size, hidden_channels]
# 3. Apply a final classifier
h = F.dropout(h, p=0.5, training=self.training)
h = self.lin(h)
return h
和训练循环:
model = GCN(hidden_channels=32)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# criterion = torch.nn.CrossEntropyLoss()
criterion = torch.nn.BCELoss()
# criterion = torch.nn.MSELoss()
model = model.to(device)
def train():
model.train()
total_loss = 0
batch_count = 0
for data in train_loader: # Iterate in batches over the training dataset.
data = data.to(device)
out = model(data.x, data.edge_index, data.edge_weight, data.batch) # Perform a single forward pass.
target = data.y
target = target.unsqueeze(1)
target = target.float()
loss = criterion(out, target) # Compute the loss.
loss.backward() # Derive gradients.
optimizer.step() # Update parameters based on gradients.
optimizer.zero_grad() # Clear gradients.
total_loss += loss.detach()
batch_count += 1
mean_loss = total_loss/batch_count
return mean_loss
def test(loader):
model.eval()
correct = 0
for data in loader: # Iterate in batches over the training/test dataset.
data = data.to(device)
out = model(data.x, data.edge_index, data.edge_weight, data.batch)
pred = out.argmax(dim=1) # Use the class with highest probability.
correct += int((pred == data.y).sum()) # Check against ground-truth labels.
return correct / len(loader.dataset) # Derive ratio of correct predictions.
test_acc_summ = []
train_acc_summ = []
loss_summ = []
for epoch in range(1, 100):
loss = train()
train_acc = test(train_loader)
test_acc = test(test_loader)
test_acc_summ.append(test_acc)
train_acc_summ.append(train_acc)
loss_summ.append(loss)
print(f'Epoch: {epoch:03d}, Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}, Loss: {loss:.4f}')
我得到的输出:
Epoch: 001, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 1.0981
Epoch: 002, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 1.0983
Epoch: 003, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 1.1312
Epoch: 004, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 1.0880
Epoch: 005, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.8857
Epoch: 006, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.9774
Epoch: 007, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.8917
Epoch: 008, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.8679
Epoch: 009, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.9000
Epoch: 010, Train Acc: 0.4568, Test Acc: 0.3000, Loss: 0.8371
训练和测试acc无论历元数如何都保持不变,但损失会减少。是不是有一些我看不到的bug,还是有更复杂的问题?
尝试添加nn。Sigmoid((位于self.lin输出顶部并删除丢失的