解决 PyTorch Geometric GCN 网络中的边连接关系错误
根据报错信息,发现在 GCN 的 forward 函数中,通过 self.conv1 进行卷积操作时出现了错误。具体错误是在 scatter 函数中,index 1 超出了维度为 0 的大小 1。
这个错误可能是由于边连接关系的数据格式不正确导致的。请确保边连接关系的数据格式正确,并且与节点特征数据和标签数据匹配。边连接关系应该是一个大小为 2xN 的张量,其中 N 是边的数量。另外,请确保边连接关系中的节点索引在节点特征数据和标签数据的合理范围内。
如果边连接关系的数据格式正确,你还可以尝试将边连接关系的数据类型转换为 'torch.long',并将其发送到相同的设备(GPU 或 CPU)上作为节点特征数据和标签数据。
如果问题仍然存在,请提供更多关于边连接关系数据的信息以及完整的报错信息,以便更好地帮助你解决问题。
代码示例:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision.transforms import transforms
import os
import numpy as np
from PIL import Image
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
import torch_geometric as pyg
from torch_geometric.data import Data, Dataset
# Define CNN network for image feature extraction
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(64 * 20 * 20, 128)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = x.view(-1, 64 * 20 * 20)
x = F.relu(self.fc1(x))
return x
# Define GCN network for node classification
class GCN(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(GCN, self).__init__()
self.conv1 = pyg.nn.GCNConv(input_dim, hidden_dim)
self.conv2 = pyg.nn.GCNConv(hidden_dim, output_dim)
def forward(self, x, edge_index):
print(x.shape)
print(edge_index.shape)
x = self.conv1(x, edge_index)
x = F.relu(x)
x = self.conv2(x, edge_index)
return x
# Define dataset class
class MyDataset(Dataset):
def __init__(self, data_list, label_list):
self.data_list = data_list
self.label_list = label_list
def __len__(self):
return len(self.data_list)
def __getitem__(self, idx):
data = self.data_list[idx]
label = self.label_list[idx]
return data, label
# Define dataloader class
class MyDataLoader(DataLoader):
def __init__(self, dataset, batch_size=1, shuffle=True):
super(MyDataLoader, self).__init__(dataset, batch_size=batch_size, shuffle=shuffle)
# Set paths
image_folder = 'C:\Users\jh\Desktop\data\input\images'
label_folder = 'C:\Users\jh\Desktop\data\input\labels'
edge_file = 'C:\Users\jh\Desktop\data\input\edges_L.csv'
# Load images and labels
data_list = []
label_list = []
for i in range(1, num_graphs+1):
for j in range(num_nodes):
image_path = os.path.join(image_folder, f'{i}.png_{j}.png')
label_path = os.path.join(label_folder, f'{i}_{j}.txt')
image = Image.open(image_path)
image = image.convert('RGB')
image = transforms.ToTensor()(image)
data_list.append(image)
label = np.loadtxt(label_path)
label_list.append(label)
# Split train and test data
train_data_list, test_data_list, train_label_list, test_label_list = train_test_split(data_list, label_list, test_size=4)
# Create CNN network
cn = CNN()
cn.eval()
# Preprocess data for GCN
train_data = []
train_label = []
for i in range(len(train_data_list)):
data = train_data_list[i].unsqueeze(0)
data = cn(data)
train_data.append(data)
train_label.append(torch.tensor(train_label_list[i]))
# Test data
test_data = []
test_label = []
for i in range(len(test_data_list)):
data = test_data_list[i].unsqueeze(0)
data = cn(data)
test_data.append(data)
test_label.append(torch.tensor(test_label_list[i]))
# Create GCN network
input_dim = cn.fc1.out_features
hidden_dim = 64
output_dim = num_labels
gcn = GCN(input_dim, hidden_dim, output_dim)
# Set device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
gcn = gcn.to(device)
# Create edge index
edge_data = pd.read_csv(edge_file, header=None)
edge_index = torch.tensor(edge_data.values.T, dtype=torch.long).to(device)
# Define loss function and optimizer
criterion = nn.MultiLabelSoftMarginLoss()
optimizer = optim.Adam(gcn.parameters(), lr=0.01)
# Train GCN
for epoch in range(10):
running_loss = 0.0
for i in range(len(train_data)):
data = train_data[i].to(device)
label = train_label[i].to(device)
# Forward pass
output = gcn(data, edge_index)
loss = criterion(output, label)
# Backward and optimize
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch+1} loss: {running_loss / len(train_data)}')
# Test GCN
gcn.eval()
y_true = []
y_pred = []
for i in range(len(test_data)):
data = test_data[i].to(device)
label = test_label[i]
# Forward pass
output = gcn(data, edge_index)
output = torch.sigmoid(output)
predicted_labels = output[-7:].detach().cpu().numpy().round()
true_labels = label[-7:].numpy()
y_true.append(true_labels)
y_pred.append(predicted_labels)
y_true = np.array(y_true)
y_pred = np.array(y_pred)
accuracy = accuracy_score(y_true.flatten(), y_pred.flatten())
print('Accuracy:', accuracy)
原文地址: https://www.cveoy.top/t/topic/pgHH 著作权归作者所有。请勿转载和采集!