{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":116062,"databundleVersionId":14875579,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":14053785,"sourceType":"datasetVersion","datasetId":8945796},{"sourceId":14239152,"sourceType":"datasetVersion","datasetId":9084547}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Save and reload embeddings\n* Save and run the previous \"CACF6 protT5 model\" notebook, protT5_embeddings.npy and protT5_embeddings.pt were saved in Output.\n* Click the Output tab → you will see the files\n* At the top of the Output tab, click Add to Dataset → Create a new dataset. This makes the notebook output into a permanent Kaggle dataset\n* Add the dataset to a new notebook (on the right panel, click Add Input\n","metadata":{}},{"cell_type":"code","source":"!pip install biopython transformers --quiet","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:20:39.664999Z","iopub.execute_input":"2025-12-22T06:20:39.665676Z","iopub.status.idle":"2025-12-22T06:20:43.104527Z","shell.execute_reply.started":"2025-12-22T06:20:39.665649Z","shell.execute_reply":"2025-12-22T06:20:43.103483Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:20:49.281627Z","iopub.execute_input":"2025-12-22T06:20:49.282216Z","iopub.status.idle":"2025-12-22T06:20:49.290198Z","shell.execute_reply.started":"2025-12-22T06:20:49.282193Z","shell.execute_reply":"2025-12-22T06:20:49.289548Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from Bio import SeqIO\ndef seqs(fasta_path):\n    records = []\n    for record in SeqIO.parse(fasta_path,\"fasta\"):\n        records.append({\n            \"id\":record.id.split(\"|\")[1],\n            \"sequence\": str(record.seq)\n        })\n\n    return pd.DataFrame(records)\n\ntrain_seqs = seqs(\"/kaggle/input/cafa-6-protein-function-prediction/Train/train_sequences.fasta\")\n\n\n\n\ndef load_test_ids(fasta_path):\n    ids = []\n    for record in SeqIO.parse(fasta_path, \"fasta\"):\n        ids.append(record.id.split()[0])  # clean ID\n    return ids\n\ntest_ids = load_test_ids(\"/kaggle/input/cafa-6-protein-function-prediction/Test/testsuperset.fasta\")\n\nprint(\"Loaded test IDs:\", len(test_ids))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:29:03.915932Z","iopub.execute_input":"2025-12-22T06:29:03.916305Z","iopub.status.idle":"2025-12-22T06:29:06.116778Z","shell.execute_reply.started":"2025-12-22T06:29:03.916276Z","shell.execute_reply":"2025-12-22T06:29:06.115922Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_seqs.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:18:12.508716Z","iopub.execute_input":"2025-12-22T06:18:12.508989Z","iopub.status.idle":"2025-12-22T06:18:12.513773Z","shell.execute_reply.started":"2025-12-22T06:18:12.508971Z","shell.execute_reply":"2025-12-22T06:18:12.513223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create Y\ntrain_terms = pd.read_csv(\"/kaggle/input/cafa-6-protein-function-prediction/Train/train_terms.tsv\", sep=\"\\t\")\ntrain_terms.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:20:59.510523Z","iopub.execute_input":"2025-12-22T06:20:59.510818Z","iopub.status.idle":"2025-12-22T06:20:59.724797Z","shell.execute_reply.started":"2025-12-22T06:20:59.510798Z","shell.execute_reply":"2025-12-22T06:20:59.724129Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"GO trems in 3 aspects (C,F,P) \n","metadata":{}},{"cell_type":"code","source":"# Drop rows with missing values in 'term' or 'aspect'\nclean_df = train_terms.dropna(subset=[\"term\", \"aspect\"])\n\n# Create dictionary using zip\ngo_to_aspect = dict(zip(clean_df[\"term\"], clean_df[\"aspect\"]))\ngo_to_aspect[\"GO:0000785\"]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:02.928336Z","iopub.execute_input":"2025-12-22T06:21:02.928654Z","iopub.status.idle":"2025-12-22T06:21:03.113145Z","shell.execute_reply.started":"2025-12-22T06:21:02.928630Z","shell.execute_reply":"2025-12-22T06:21:03.112337Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from scipy.sparse import csr_matrix\nimport numpy as np\n\nprotein_ids = train_seqs[\"id\"].tolist()\npid_to_idx = {pid: i for i, pid in enumerate(protein_ids)}\n\n# GO indec x mapping\ngo_terms = sorted(train_terms[\"term\"].unique())\ngo_to_idx = {go: i for i, go in enumerate(go_terms)}\n\n# build coordinate lists\nrow_idx = []\ncol_idx = []\nfor pid, go in zip(train_terms[\"EntryID\"], train_terms[\"term\"]):\n    row_idx.append(pid_to_idx[pid])\n    col_idx.append(go_to_idx[go])\ndata = np.ones(len(row_idx),dtype = np.float32)\nY_sparse = csr_matrix(\n    (data,(row_idx,col_idx)),\n    shape = (len(protein_ids),len(go_terms)),\n    dtype = np.float32\n)\nprint(\"Number of non-zero entries:\", Y_sparse.nnz)\nprint(Y_sparse.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:05.009811Z","iopub.execute_input":"2025-12-22T06:21:05.010123Z","iopub.status.idle":"2025-12-22T06:21:05.523605Z","shell.execute_reply.started":"2025-12-22T06:21:05.010101Z","shell.execute_reply":"2025-12-22T06:21:05.522875Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nY_coo = Y_sparse.tocoo()\n\nindices = torch.tensor(\n    np.vstack((Y_coo.row, Y_coo.col)),\n    dtype=torch.int64\n)\n\nvalues = torch.tensor(Y_coo.data, dtype=torch.float32)\n\nY_torch_sparse = torch.sparse_coo_tensor(\n    indices,\n    values,\n    size=Y_coo.shape,\n    dtype=torch.float32\n).coalesce()\n\nY_torch_sparse.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:09.020973Z","iopub.execute_input":"2025-12-22T06:21:09.021611Z","iopub.status.idle":"2025-12-22T06:21:09.088941Z","shell.execute_reply.started":"2025-12-22T06:21:09.021581Z","shell.execute_reply":"2025-12-22T06:21:09.088338Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load embeddings and labels\nimport numpy as np\nimport torch\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ntrain_path = \"/kaggle/input/prott5-embeddings/protT5_embeddings.npy\"\ntest_path = \"/kaggle/input/prott5-embeddings-test-npy/test_prott5_embeddings.npy\"\nX_train = np.load (train_path)\nX_test = np.load(test_path)\n\n# convert to torch\nX_train = torch.tensor(X_train,dtype = torch.float32)\nX_test = torch.tensor(X_test,dtype = torch.float32)\ny_train = Y_torch_sparse.to_dense()\nprint(\"X_train.shape:\", X_train.shape)\nprint(\"X_test.shape:\", X_test.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:12.000325Z","iopub.execute_input":"2025-12-22T06:21:12.001081Z","iopub.status.idle":"2025-12-22T06:21:15.519089Z","shell.execute_reply.started":"2025-12-22T06:21:12.001050Z","shell.execute_reply":"2025-12-22T06:21:15.516777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Dataset and DataLoader\nfrom torch.utils.data import TensorDataset, DataLoader\n\ntrain_dataset = TensorDataset(X_train,y_train)\ntrain_loader = DataLoader(\n    train_dataset,\n    batch_size = 64,\n    shuffle = True,\n    pin_memory = True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:18.296350Z","iopub.execute_input":"2025-12-22T06:21:18.297128Z","iopub.status.idle":"2025-12-22T06:21:18.808276Z","shell.execute_reply.started":"2025-12-22T06:21:18.297100Z","shell.execute_reply":"2025-12-22T06:21:18.807655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch.nn as nn\n\nclass MLP(nn.Module):\n    def __init__(self,in_dim,out_dim,hidden = 512,dropout = 0.3):\n        super().__init__()\n        self.net = nn.Sequential(\n            nn.Linear(in_dim,hidden),\n            nn.ReLU(),\n            nn.Dropout(dropout),\n            nn.Linear(hidden,out_dim)\n        )\n    def forward(self,x):\n        return self.net(x)\n\nmodel = MLP(\n    in_dim = X_train.shape[1],\n    out_dim = y_train.shape[1]\n).to(device)\n\ncriterion = nn.BCEWithLogitsLoss()\noptimizer = torch.optim.AdamW(model.parameters(),lr = 1e-3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:34.385633Z","iopub.execute_input":"2025-12-22T06:21:34.385934Z","iopub.status.idle":"2025-12-22T06:21:34.530164Z","shell.execute_reply.started":"2025-12-22T06:21:34.385914Z","shell.execute_reply":"2025-12-22T06:21:34.529332Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"epochs = 10\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    for xb,yb in train_loader:\n        xb = xb.to(device,non_blocking = True)\n        yb = yb.to(device,non_blocking = True)\n\n        optimizer.zero_grad()\n        logits = model(xb)\n        loss = criterion(logits,yb)\n        loss.backward()\n        optimizer.step()\n\n        total_loss +=loss.item()*xb.size(0)\n\n    avg_loss = total_loss/len(train_loader.dataset)\n    print(f\"Epoch {epoch+1}/{epochs} | Loss: {avg_loss:.4f}\")\n\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:21:39.269499Z","iopub.execute_input":"2025-12-22T06:21:39.270216Z","iopub.status.idle":"2025-12-22T06:23:43.213780Z","shell.execute_reply.started":"2025-12-22T06:21:39.270186Z","shell.execute_reply":"2025-12-22T06:23:43.213039Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\n\ntest_loader = DataLoader(\n    X_test,\n    batch_size=8,        # keep small\n    shuffle=False,\n    num_workers=0\n)\n\nthreshold = 0.01\nmax_terms = 1500\n\nwith open(\"GO.txt\", \"w\") as f:\n    with torch.no_grad():\n        for i, xb in enumerate(test_loader):\n            xb = xb.to(device, non_blocking=True)\n\n            logits = model(xb)\n            probs = torch.sigmoid(logits).cpu().numpy()\n\n            for j in range(probs.shape[0]):\n                pid = test_ids[i * test_loader.batch_size + j]\n\n                idxs = np.where(probs[j] > threshold)[0]\n                scores = probs[j][idxs]\n\n                order = np.argsort(scores)[::-1][:max_terms]\n\n                for k in order:\n                    go = go_terms[idxs[k]]\n                    score = round(float(scores[k]), 3)\n                    score = min(max(score, 1e-3), 1.0)\n                    f.write(f\"{pid}\\t{go}\\t{score}\\n\")\n\n            del xb, logits, probs\n            torch.cuda.empty_cache()\n\nprint(\"Inference complete. GO.txt written.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-22T06:29:20.473135Z","iopub.execute_input":"2025-12-22T06:29:20.473483Z","iopub.status.idle":"2025-12-22T06:31:02.281587Z","shell.execute_reply.started":"2025-12-22T06:29:20.473418Z","shell.execute_reply":"2025-12-22T06:31:02.280691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}