基于pyg实现ACGRN实现犯罪分布预测
此处仍采用纽约犯罪数据进行分析,犯罪历史分布图如下:
预处理模块
此处预处理部分采用单个图进行计算,也就是batch取1,论文这块还没仔细读,但是接口处好像不太支持batch处理,代码如下:
def nn_seq_gat( seq_len, B, pred_step_size,train,val,test,TempArea): TempTrain = np.reshape(train,[TempArea,-1]) edge_index = knn(torch.from_numpy(train.reshape(TempArea,-1)),torch.from_numpy(train.reshape(TempArea,-1)),3) graph = Data(x=TempTrain,edge_index=edge_index) # graph = create_graph(num_nodes, train) def process(dataset, batch_size, step_size, shuffle): nodes, timeLength = dataset.shape[0], dataset.shape[1] # print(nodes,timeLength) dataset = dataset.tolist() feature = [] target = [] graphs = [] for i in tqdm(range(0, timeLength - seq_len - pred_step_size, step_size)): train_seq = [] for j in range(i, i + seq_len): x = [] for c in range(nodes): ##存储过去时间段的二维图矩阵 x.append(dataset[c][j][0]) # temp = functools.reduce(operator.concat, x) # print(temp) train_seq.append(x) # 下几个时刻的所有变量 train_labels = [] for k in range(i + seq_len, i+seq_len+step_size): train_label = [] for j in range(nodes): train_label.append(dataset[j][k][0]) # print(train_label) # temp1 = functools.reduce(operator.concat, train_label) # print(temp1) train_labels.append(train_label)) feature.append(np.array(train_seq).T) target.append(np.array(train_labels).reshape(-1).T) # temp = Data(x=train_seq, edge_index=graph.edge_index, y=train_labels) # # print(temp) # graphs.append(temp) # # # loader = torch_geometric.loader.DataLoader(graphs, batch_size=batch_size, # shuffle=shuffle, drop_last=True) loader = StaticGraphTemporalSignal(edge_index=graph.edge_index,edge_weight=np.ones(graph.edge_index.shape[1]), features=feature,targets=target) return loader,graphs Dtr,Dtrgraphs = process(train, B, step_size=1, shuffle=True) Val,Valgraphs = process(val, val.shape[1] - seq_len - pred_step_size, step_size=1, shuffle=True) Dte,Dtegraphs = process(test,test.shape[1] - seq_len - pred_step_size, step_size=1, shuffle=False) b = test.shape[1] - seq_len - pred_step_size c = val.shape[1] - seq_len - pred_step_size return graph, Dtr, Val, Dte, b, c
网络模块如下:
class AST(torch.nn.Module): def __init__(self): super(AST, self).__init__() self.recurrent = AGCRN(number_of_nodes=256, in_channels=6, out_channels=2, K=2, embedding_dimensions=10) self.linear = torch.nn.Linear(2, 1) def forward(self, data, e, h): x = data.x.view(1,256,6) h_0 = self.recurrent(x, e, h) y = F.relu(h_0) y = self.linear(y) return y, h_0
训练过程如下:
数据处理后的格式:
Data(x=[256, 6], edge_index=[2, 768], edge_attr=[768], y=[256])
训练的的代码块:
for epoch in tqdm(range(300)): train_losses = [] # tar_val = list(enumerate(val_loader))##迁移部分 # print(tar_val[0]) h = None for tr in train_loader: # _, x_tar = tar_val[batch_j] # x_tar = x_tar.to(device) # batch_j += 1# # if batch_j >= len(tar_val):# # batch_j = 0# # print(tr) model.train() label = tr.to(device).y.float() y_src,_ = model(tr.to(device),e,h) #,batch,timeStep,Areas, ##cpu().detach().numpy() y_src = y_src.float() loss = loss_function(y_src, label) print(loss) optimizer.zero_grad() loss.backward() optimizer.step() train_losses.append(loss.item()) # validation val_loss, test_loss,result = test(model, val_loader,test_loader,b,c,h) print('Epoch {:03d} train_loss {:.4f} val_loss {:.4f} test mape {:.4f}'.format(epoch , np.mean(train_losses), val_loss, test_loss))
训练losss
loss总体还是呈下降趋势,后续的验证此处不在叙述