import torch
import torch.nn.functional as F
from torch_geometric.data import Data
import os
import random
import torch.optim as optim
from torch_geometric.data import Data, DataLoader
class Encoder(torch.nn.Module):
def init(self, n_node_features, n_hidden):
super(Encoder, self).init()
self.lin_node = torch.nn.Linear(n_node_features, n_hidden)
def forward(self, x, edge_index, edge_attr):
x = F.relu(self.lin_node(x))
print("Encoder output:", x.shape)
return x
class Processor(torch.nn.Module):
def init(self, n_edge_features, n_hidden):
super(Processor, self).init()
self.lin_edge = torch.nn.Linear(n_edge_features, n_hidden)
self.gru = torch.nn.GRUCell(n_hidden, n_hidden)
def forward(self, x, edge_index, edge_attr):
edge_attr = edge_attr.repeat(1, 16)
print("Processor input x:", x.shape)
print("Processor input edge_index:", edge_index.shape)
print("Processor input edge_attr:", edge_attr.shape)
edge_attr = F.relu(self.lin_edge(edge_attr))
print("Processor edge_attr after lin_edge:", edge_attr.shape)
row, col = edge_index
aggr = self.gru(edge_attr, x[col])
print("Processor aggr:", aggr.shape)
x = aggr[row].sum(dim=1)
print("Processor output:", x.shape)
return x
class Decoder(torch.nn.Module):
def init(self, n_hidden, n_output):
super(Decoder, self).init()
self.lin_out = torch.nn.Linear(n_hidden, n_output)
def forward(self, x, edge_index, edge_attr):
x = F.relu(self.lin_out(x))
x = x.mean(dim=0)
print("Decoder output:", x.shape)
return x
class MPNN(torch.nn.Module):
def init(self, n_node_features, n_edge_features, n_hidden, n_output):
super(MPNN, self).init()
self.encoder = Encoder(n_node_features, n_hidden)
self.processor = Processor(n_edge_features, n_hidden)
self.decoder = Decoder(n_hidden, n_output)
def forward(self, data):
x, edge_index, edge_attr = data.x, data.edge_index, data.edge_attr
x = self.encoder(x, edge_index, edge_attr) #output of encoder
x = self.processor(x, edge_index, edge_attr)
x = self.decoder(x, edge_index, edge_attr)
print("MPNN output:", x.shape)
return x
def read_labeled_data_file(file_path):
with open(file_path, ‘r’) as f:
content = f.readlines()
adj_matrix = []
for line in content:
line = line.strip()
if line: # Skip empty lines
row = list(map(int, line.split(',')))
adj_matrix.append(row)
max_flow = adj_matrix[-1][-1]
adj_matrix = adj_matrix[:-1] # Remove last row containing max flow
return adj_matrix, max_flow
def adjacency_matrix_to_edge_index(adj_matrix):
edge_index = []
edge_features = []
for i in range(len(adj_matrix)):
for j in range(len(adj_matrix[i])):
if adj_matrix[i][j] > 0:
edge_index.append([i, j])
edge_features.append([adj_matrix[i][j]])
return torch.tensor(edge_index, dtype=torch.long).t().contiguous(), torch.tensor(edge_features, dtype=torch.float32)
def create_mpnn_data(adj_matrix, max_flow):
node_features = torch.eye(len(adj_matrix), dtype=torch.float32)
edge_index, edge_features = adjacency_matrix_to_edge_index(adj_matrix)
data = Data(x=node_features, edge_index=edge_index, edge_attr=edge_features, y=torch.tensor([max_flow], dtype=torch.float32))
return data
def read_and_process_files(file_paths):
data_list = []
for file_path in file_paths:
adj_matrix, max_flow = read_labeled_data_file(file_path)
data = create_mpnn_data(adj_matrix, max_flow)
data_list.append(data)
return data_list
data_dir = ‘C:/Users/Admin/Desktop/working_codes/data/’
file_paths = [os.path.join(data_dir, f) for f in os.listdir(data_dir) if os.path.isfile(os.path.join(data_dir, f))]
random.shuffle(file_paths)
train_ratio, test_ratio = 0.7, 0.2
n_files = len(file_paths)
train_files = file_paths[:int(train_ratio * n_files)]
test_files = file_paths[int(train_ratio * n_files):int((train_ratio + test_ratio) * n_files)]
eval_files = file_paths[int((train_ratio + test_ratio) * n_files):]
train_data = read_and_process_files(train_files)
test_data = read_and_process_files(test_files)
eval_data = read_and_process_files(eval_files)
print(train_data[0])
train_loader = DataLoader(train_data, batch_size=32, shuffle=True)
test_loader = DataLoader(test_data, batch_size=32, shuffle=False)
eval_loader = DataLoader(eval_data, batch_size=32, shuffle=False)
sample_data = train_data[0]
n_node_features = sample_data.x.shape[1]
n_edge_features =2
n_hidden = 16
n_output = 1
model = MPNN(n_node_features, n_edge_features, n_hidden, n_output)
loss_function = torch.nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 10
validation_interval = 10
for epoch in range(num_epochs):
model.train()
total_loss = 0
for batch in train_loader:
optimizer.zero_grad()
output = model(batch)
loss = loss_function(output, batch.y)
loss.backward()
optimizer.step()
total_loss += loss.item()
avg_loss = total_loss / len(train_loader)
print(f"Epoch: {epoch + 1}, Loss: {avg_loss:.4f}")
if (epoch + 1) % validation_interval == 0:
model.eval()
total_val_loss = 0
with torch.no_grad():
for val_batch in test_loader:
val_output = model(val_batch)
val_loss = loss_function(val_output, val_batch.y)
total_val_loss += val_loss.item()
avg_val_loss = total_val_loss / len(test_loader)
print(f"Validation Loss: {avg_val_loss:.4f}")
This is the error on the console:
File ~\anaconda3\envs\t_3_10\lib\site-packages\torch\nn\modules\linear.py:114 in forward
return F.linear(input, self.weight, self.bias)
RuntimeError: mat1 and mat2 shapes cannot be multiplied (2810x16 and 2x16)