{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":87793,"databundleVersionId":11228175,"sourceType":"competition"},{"sourceId":10890759,"sourceType":"datasetVersion","datasetId":6766674}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\n\n# os.listdir(\"/kaggle/input/rna-fm\")\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-03T02:57:46.563077Z","iopub.execute_input":"2025-03-03T02:57:46.563323Z","iopub.status.idle":"2025-03-03T02:57:46.916458Z","shell.execute_reply.started":"2025-03-03T02:57:46.563290Z","shell.execute_reply":"2025-03-03T02:57:46.915474Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import sys\nsys.path.append(\"/kaggle/input/rna-fm/\")\n\n%pip install /kaggle/input/rna-fm/ptflops-0.7.4-py3-none-any.whl\n%ls /kaggle/input/rna-fm/RNA-FM_pretrained.pth\n\nimport fm\n\n# model, alphabet = fm.downstream.build_rnafm_resnet(type=\"ss\", model_location=\"/kaggle/input/rna-fm/RNA-FM-ResNet_PDB-All.pth\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-03T02:57:57.768318Z","iopub.execute_input":"2025-03-03T02:57:57.768622Z","iopub.status.idle":"2025-03-03T02:58:10.780342Z","shell.execute_reply.started":"2025-03-03T02:57:57.768595Z","shell.execute_reply":"2025-03-03T02:58:10.779671Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport fm\n\n# Load RNA-FM model\nmodel, alphabet = fm.pretrained.rna_fm_t12(model_location=\"/kaggle/input/rna-fm/RNA-FM_pretrained.pth\")\nbatch_converter = alphabet.get_batch_converter()\nmodel.eval()  # disables dropout for deterministic results\n\n# Prepare data\n# data = [\n#     (\"RNA1\", \"GGGUGCGAUCAUACCAGCACUAAUGCCCUCCUGGGAAGUCCUCGUGUUGCACCCCU\"),\n#     (\"RNA2\", \"GGGUGUCGCUCAGUUGGUAGAGUGCUUGCCUGGCAUGCAAGAAACCUUGGUUCAAUCCCCAGCACUGCA\"),\n#     (\"RNA3\", \"CGAUUCNCGUUCCC--CCGCCUCCA\"),\n# ]\n\n\ndef gen_seq_label_df(sequence_file_path, label_file_path, with_label=True):\n    seq_df = pd.read_csv(sequence_file_path)\n    raw = []\n    for idx,rows in seq_df.iterrows():\n        RNA_name = rows['target_id']\n        sequence = rows[\"sequence\"][:1022]\n        data = [\n            (\"RNA\", sequence)\n        ]\n        batch_labels, batch_strs, batch_tokens = batch_converter(data)\n    \n        # Extract embeddings (on CPU)\n        with torch.no_grad():\n            # print(sequence, len(sequence))\n            results = model(batch_tokens, repr_layers=[12])\n        token_embeddings = results[\"representations\"][12].squeeze(dim=0)\n        assert len(token_embeddings)-2 == len(sequence)\n        for idx, resname in enumerate(sequence, start=1):\n            ID = RNA_name + \"_\" + str(idx)\n            raw.append((ID, resname, np.concatenate((token_embeddings[0,:], token_embeddings[idx,:]))))\n    \n    df = pd.DataFrame(raw, columns=[\"ID\", \"resname\", \"repr\"])\n\n    if with_label:\n        label_df = pd.read_csv(label_file_path)\n        df = df.merge(label_df.drop(columns=['resname', 'resid']), how=\"left\", on=[\"ID\"])\n    df.info()\n\n    return df\n\ntrain_seq_df = gen_seq_label_df(\"/kaggle/input/stanford-rna-3d-folding/train_sequences.csv\", \"/kaggle/input/stanford-rna-3d-folding/train_labels.csv\")\nvalid_seq_df = gen_seq_label_df(\"/kaggle/input/stanford-rna-3d-folding/validation_sequences.csv\", \"/kaggle/input/stanford-rna-3d-folding/validation_labels.csv\")\ntest_seq_df  = gen_seq_label_df(\"/kaggle/input/stanford-rna-3d-folding/test_sequences.csv\", None, with_label=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-03T02:59:46.058483Z","iopub.execute_input":"2025-03-03T02:59:46.058768Z","iopub.status.idle":"2025-03-03T03:03:50.003279Z","shell.execute_reply.started":"2025-03-03T02:59:46.058749Z","shell.execute_reply":"2025-03-03T03:03:50.002418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def to_X_Y(df):\n    X_l = []\n    Y_l = []\n    for i in range(df.shape[0]):\n        X_l.append(df.iloc[i, 2])\n        Y_l.append(df.iloc[i, 3:6].to_list())\n    return np.array(X_l), np.array(Y_l)\n\n\ntrain_seq_df = train_seq_df.dropna()\ntrain_X, train_Y = to_X_Y(train_seq_df)\nprint(\"train_X.shape:\", train_X.shape, \"train_Y.shape:\", train_Y.shape, \"train_Y.dtype:\", train_Y.dtype)\n\nvalid_X, valid_Y = to_X_Y(valid_seq_df)\nprint(\"valid_X.shape:\", valid_X.shape, \"valid_Y.shape:\", valid_Y.shape)\n\ndef to_X(df):\n    X_l = []\n    for i in range(df.shape[0]):\n        X_l.append(df.iloc[i, 2])\n    return np.array(X_l)\n\ntest_X = to_X(test_seq_df)\nprint(\"test_X.shape:\", test_X.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-03T03:03:55.023492Z","iopub.execute_input":"2025-03-03T03:03:55.023815Z","iopub.status.idle":"2025-03-03T03:04:04.536225Z","shell.execute_reply.started":"2025-03-03T03:03:55.023788Z","shell.execute_reply":"2025-03-03T03:04:04.535496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# print(train_X)\n# print(train_Y)\n\ndef find_objects(arr):\n  \"\"\"\n  在一个 dtype 为 object 的 NumPy 数组中查找非数值对象。\n\n  参数：\n    arr: dtype 为 object 的 NumPy 数组。\n\n  返回：\n    包含非数值对象索引的列表。\n  \"\"\"\n\n  object_indices = []\n  for index, item in np.ndenumerate(arr):\n    if isinstance(item, object) and not isinstance(item, (int, float, np.integer, np.floating)):\n      print(\"item:\", item)\n      object_indices.append(index)\n  return object_indices\n\nprint(find_objects(train_Y))\nprint(train_Y.dtype)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\n\n# 训练配置\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\n\n# 自定义 Dataset\nclass RNADataset(Dataset):\n    def __init__(self, X, Y):\n        self.X = torch.tensor(X, dtype=torch.float32).to(device)\n        self.Y = torch.tensor(Y, dtype=torch.float32).to(device)\n        \n    def __len__(self):\n        return len(self.X)\n    \n    def __getitem__(self, idx):\n        return self.X[idx], self.Y[idx]\n\nprint(train_X.dtype)\nprint(train_Y.dtype)\ntrain_Y = np.nan_to_num(train_Y, nan=0.0)\n\ntrain_dataset = RNADataset(train_X, train_Y)\ntrain_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)\n\n# valid_dataset = RNADataset(valid_X, valid_Y)\n# valid_dataloader = DataLoader(valid_dataset, batch_size=32, shuffle=False)\n\n# 残差连接 (Residual Connection)\nclass ResidualBlock(nn.Module):\n    def __init__(self, dim):\n        super().__init__()\n        self.fc = nn.Linear(dim, dim)\n        self.norm = nn.LayerNorm(dim)\n        self.act = nn.ReLU()\n\n    def forward(self, x):\n        return x + self.fc(self.norm(x))\n\nclass FCN(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.net = nn.Sequential(\n            nn.LayerNorm(640*2),\n            nn.Linear(640*2, 1024),\n            nn.ReLU(),\n            nn.Dropout(0.3),\n\n            nn.Linear(1024, 512),\n            nn.ReLU(),\n            nn.Dropout(0.3),\n\n            ResidualBlock(512),\n\n            nn.Linear(512, 256),\n            nn.ReLU(),\n\n            nn.Linear(256, 3)  # 3D坐标输出\n        )\n\n    def forward(self, x):\n        return self.net(x)\n        \n# FCN 网络定义\n# class FCN(nn.Module):\n#     def __init__(self, input_dim=640, hidden_dim=256, output_dim=3):\n#         super(FCN, self).__init__()\n#         self.fc = nn.Sequential(\n#             nn.Linear(input_dim, hidden_dim),\n#             nn.ReLU(),\n#             nn.Linear(hidden_dim, hidden_dim),\n#             nn.ReLU(),\n#             nn.Linear(hidden_dim, hidden_dim),\n#             nn.ReLU(),\n#             nn.Linear(hidden_dim, output_dim)\n#         )\n\n#     def forward(self, x):\n#         return self.fc(x)\n\n\n\n# 训练循环\ndef train(model, train_dataloader, epochs=100):\n    model.train()\n    for epoch in range(epochs):\n        total_train_loss = 0\n        for X_batch, Y_batch in train_dataloader:\n            X_batch, Y_batch = X_batch.to(device), Y_batch.to(device)\n\n            optimizer.zero_grad()\n            outputs = model(X_batch)\n            loss = criterion(outputs, Y_batch)\n            loss.backward()\n            optimizer.step()\n            \n            total_train_loss += loss.item()\n        \n        avg_train_loss = total_train_loss / len(train_dataloader)\n        \n        # 验证集评估\n        # model.eval()\n        # total_val_loss = 0\n        # with torch.no_grad():\n        #     for X_val, Y_val in val_dataloader:\n        #         X_val, Y_val = X_val.to(device), Y_val.to(device)\n        #         val_outputs = model(X_val)\n        #         val_loss = criterion(val_outputs, Y_val)\n        #         total_val_loss += val_loss.item()\n        # avg_val_loss = total_val_loss / len(val_dataloader)\n\n        print(f\"Epoch {epoch+1}/{epochs}, Train Loss: {avg_train_loss:.6f}\")\n\n\nout_df = pd.read_csv(\"/kaggle/input/stanford-rna-3d-folding/sample_submission.csv\")[['ID','resname','resid']]\n\nfcn_model_list = []\nfor i in range(1,6):\n    torch.manual_seed(i) #设置 CPU 上的随机种子。\n    torch.cuda.manual_seed(i) #设置当前 GPU 上的随机种子。\n\n    fcn_model = FCN().to(device)\n    criterion = nn.SmoothL1Loss()\n    optimizer = optim.Adam(fcn_model.parameters(), lr=1e-4)\n\n    # 执行训练\n    train(fcn_model, train_dataloader)\n\n    test_tensor = torch.tensor(test_X, dtype=torch.float32).to(device)\n\n    result = fcn_model(test_tensor)\n\n    result = result.cpu().detach().numpy()\n\n    print(result, result.shape)\n\n    col_x, col_y, col_z = f\"x_{i}\", f\"y_{i}\", f\"z_{i}\"\n    df = pd.DataFrame(result, columns=[col_x, col_y, col_z])\n    out_df = pd.concat([out_df, df], axis=1)\n\nout_df.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}