I am trying to run a graph classification problem. For testing purposes, I am using a list of data objects, each of which looks like:
dataset = produceDataset(directory_path,
embeddings_path,
user_features_path,
labels_path,
train_frac=0.6,
val_frac=0.2,
binary_classification=True)
dataset[0]
Data(edge_attr=[1306, 1], edge_index=[2, 1306], x=[1281, 768], y=[1])
The structure of my data is a set of N graphs and N binary labels for each. I am not sure if the above structure is correctly created.
Then I build the loaders and assign pieces of the list for training and testing:
train_dataset, test_dataset = dataset[:2], dataset[2:]
train_loader = DataLoader(train_dataset,
batch_size=2,
shuffle=True)
test_loader = DataLoader(test_dataset,
batch_size=1,
shuffle=False)
I define the model:
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = GCNConv(768, 16)
self.conv2 = GCNConv(16, 2)
def forward(self, data):
x, edge_index = data.x, data.edge_index
x = self.conv1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, training=self.training)
x = self.conv2(x, edge_index)
return F.softmax(x, dim=1)
and try to train it:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
model = Net().to(device)
def train():
model.train()
for data in train_loader:
data_cuda = data.to(device)
optimizer.zero_grad()
out = model(data_cuda)#.unsqueeze(0).type(torch.float).mean(1).type(torch.int32).type(torch.float)
y = data_cuda.y.type(torch.long)
loss = CrossEntropyLoss(out, y)
optimizer.step()
def test(loader):
correct = []
for data in loader:
model.eval()
data_cuda = data.to(device)
pred = model(data_cuda).unsqueeze(0).type(torch.int32)
correct += [1 if pred.eq(data_cuda.y).item() else 0]
acc = sum(correct) / len(data)
print('Accuracy: {:.4f}'.format(acc))
for epoch in range(1, 21):
train()
test(test_loader)
I don’t know if the output of my model is correct for my task, it’s most likely not, as if I print the shapes of
out
and y
from the train method, they look like:
torch.Size([1484, 2])
torch.Size([2])
So I see that, for a batch size of 2, the node feature matrix just gets stacked, lacking a batch dimension. This is the first time I’m using Pytorch Geometric, and I am trying to understand this code, since I need to work on it for a project. Can someone please help me in getting it running?
EDIT
I tried transposing the output. Now out and y are of shapes:
torch.Size([2, 1484])
torch.Size([2])
but when I pass them to the CrossEntropyLoss, I get:
RuntimeError: bool value of Tensor with more than one value is ambiguous
However, if I test this code:
loss = CrossEntropyLoss()
input = torch.randn(3, 15, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)
the shapes of input and target are:
torch.Size([3, 15])
torch.Size([3])
And it does work. I really don’t understand what’s wrong.