Spaces:
Sleeping
Sleeping
| import os | |
| import pickle | |
| import numpy as np | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from flask import Flask, render_template, request, jsonify | |
| from torch_geometric.nn import SAGEConv | |
| class RenameUnpickler(pickle.Unpickler): | |
| def find_class(self, module, name): | |
| if module == 'numpy._core.multiarray': | |
| module = 'numpy.core.multiarray' | |
| elif module == 'numpy._core': | |
| module = 'numpy.core' | |
| return super().find_class(module, name) | |
| class GraphSAGE(nn.Module): | |
| def __init__(self, in_dim, hidden_dim, dropout=0.3): | |
| super().__init__() | |
| self.conv1 = SAGEConv(in_dim, hidden_dim, aggr='max') | |
| self.conv2 = SAGEConv(hidden_dim, hidden_dim, aggr='max') | |
| self.conv3 = SAGEConv(hidden_dim, hidden_dim, aggr='max') | |
| self.dropout = nn.Dropout(dropout) | |
| def forward(self, x, edge_index): | |
| x = F.relu(self.conv1(x, edge_index)) | |
| x = self.dropout(x) | |
| x = F.relu(self.conv2(x, edge_index)) | |
| x = self.dropout(x) | |
| x = F.relu(self.conv3(x, edge_index)) | |
| x = self.dropout(x) | |
| return x | |
| class LinkPredictor(nn.Module): | |
| def __init__(self, hidden_dim, dropout=0.3): | |
| super().__init__() | |
| self.mlp = nn.Sequential( | |
| nn.Linear(hidden_dim, hidden_dim), | |
| nn.ReLU(), | |
| nn.Dropout(dropout), | |
| nn.Linear(hidden_dim, 1) | |
| ) | |
| def forward(self, h, edge): | |
| src = h[edge[:, 0]] | |
| dst = h[edge[:, 1]] | |
| return self.mlp(src * dst).squeeze() | |
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') | |
| with open("node2idx.pkl", "rb") as f: | |
| node2idx = RenameUnpickler(f).load() | |
| valid_proteins = list(node2idx.keys()) | |
| with open("protein_embeddings_protT5_1056.pkl", "rb") as f: | |
| prot_embeddings = RenameUnpickler(f).load() | |
| embedding_dim = len(next(iter(prot_embeddings.values()))) | |
| x_array = np.zeros((len(node2idx), embedding_dim)) | |
| for node, idx in node2idx.items(): | |
| x_array[idx] = prot_embeddings[node] | |
| x = torch.tensor(x_array, dtype=torch.float).to(device) | |
| edge_index = torch.load("edge_index.pt", map_location=device) | |
| checkpoint = torch.load("graphsage_asd_model.pth", map_location=device) | |
| sage = GraphSAGE(checkpoint['embedding_dim'], checkpoint['hidden_dim']).to(device) | |
| link = LinkPredictor(checkpoint['hidden_dim']).to(device) | |
| sage.load_state_dict(checkpoint['sage_state_dict']) | |
| link.load_state_dict(checkpoint['link_state_dict']) | |
| sage.eval() | |
| link.eval() | |
| with torch.no_grad(): | |
| h_global = sage(x, edge_index) | |
| app = Flask(__name__) | |
| def home(): | |
| return render_template('index.html') | |
| def get_proteins(): | |
| return jsonify(valid_proteins) | |
| def predict(): | |
| try: | |
| p1 = request.form.get('protein1', '').strip() | |
| p2 = request.form.get('protein2', '').strip() | |
| if not p1 or not p2: | |
| return jsonify({"status": "error", "message": "ID Protein tidak valid"}) | |
| if p1 not in node2idx or p2 not in node2idx: | |
| return jsonify({"status": "error", "message": "Protein tidak ditemukan dalam database graf"}) | |
| idx1 = node2idx[p1] | |
| idx2 = node2idx[p2] | |
| edge = torch.tensor([[idx1, idx2]], dtype=torch.long, device=device) | |
| with torch.no_grad(): | |
| logits = link(h_global, edge) | |
| prob = logits.sigmoid().item() | |
| return jsonify({ | |
| "status": "success", | |
| "protein1": p1, | |
| "protein2": p2, | |
| "probability": prob | |
| }) | |
| except Exception as e: | |
| return jsonify({"status": "error", "message": str(e)}) | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860) |