{"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":22422,"databundleVersionId":2153105,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# ==============================================================================\n# CELL 1: SETUP FOR KAGGLE - Run this cell first!\n# ==============================================================================\n\n# --- Necessary Imports ---\nimport torch, torch.nn as nn, torch.nn.functional as F, torchvision.models as models\nfrom torch.utils.data import Dataset\nfrom torchvision import transforms\nimport os, pandas as pd, shutil\nfrom PIL import Image\nfrom tqdm.notebook import tqdm\n\nprint(\"All necessary libraries imported.\")\n\n# ------------------------------------------------------------------------------\n# --- Path Definitions for Kaggle Environment ---\n# ------------------------------------------------------------------------------\nFULL_DATA_PATH = '/kaggle/input/bms-molecular-translation'\nFULL_IMAGES_FOLDER = os.path.join(FULL_DATA_PATH, 'train')\nFULL_LABELS_FILE = os.path.join(FULL_DATA_PATH, 'train_labels.csv')\nSUBSET_PATH = '/kaggle/working/dataset_subset'\nSUBSET_IMAGES_FOLDER = os.path.join(SUBSET_PATH, 'images')\nSUBSET_LABELS_FILE = os.path.join(SUBSET_PATH, 'labels.csv')\nSAMPLE_SIZE = 30000\n\n# ------------------------------------------------------------------------------\n# --- Create the Dataset Subset ---\n# ------------------------------------------------------------------------------\nprint(\"Creating dataset subset...\")\nos.makedirs(SUBSET_IMAGES_FOLDER, exist_ok=True)\nfull_labels_df = pd.read_csv(FULL_LABELS_FILE)\nsubset_df = full_labels_df.sample(n=SAMPLE_SIZE, random_state=42)\nsubset_df.to_csv(SUBSET_LABELS_FILE, index=False)\n\nprint(f\"Copying {SAMPLE_SIZE} images... (This may take a few minutes)\")\nfor i, row in tqdm(subset_df.iterrows(), total=len(subset_df)):\n    image_id = row['image_id']\n    filename = f\"{image_id[0]}/{image_id[1]}/{image_id[2]}/{image_id}.png\"\n    source_path = os.path.join(FULL_IMAGES_FOLDER, filename)\n    destination_path = os.path.join(SUBSET_IMAGES_FOLDER, f\"{image_id}.png\")\n    shutil.copy(source_path, destination_path)\n    \nprint(\"✅ Dataset subset is ready.\")\n\n# ------------------------------------------------------------------------------\n# --- Class Definitions (Corrected Versions) ---\n# ------------------------------------------------------------------------------\nclass Vocabulary:\n    def __init__(self):\n        self.char2idx, self.idx2char = {\"<pad>\": 0, \"<start>\": 1, \"<end>\": 2, \"<unk>\": 3}, {0: \"<pad>\", 1: \"<start>\", 2: \"<end>\", 3: \"<unk>\"}\n    def __len__(self): return len(self.char2idx)\n    def build_vocab(self, text_series):\n        chars = set(''.join(text_series))\n        for char in sorted(list(chars)):\n            if char not in self.char2idx:\n                idx = len(self.char2idx)\n                self.char2idx[char], self.idx2char[idx] = idx, char\n\nclass EncoderCNN(nn.Module):\n    def __init__(self):\n        super(EncoderCNN, self).__init__()\n        resnet = models.resnet34(weights=models.ResNet34_Weights.DEFAULT)\n        for param in resnet.parameters(): param.requires_grad = False\n        self.resnet = nn.Sequential(*list(resnet.children())[:-2])\n    def forward(self, images):\n        features = self.resnet(images)\n        batch_size, num_channels = features.size(0), features.size(1)\n        return features.view(batch_size, num_channels, -1).permute(0, 2, 1)\n\nclass Attention(nn.Module):\n    def __init__(self, encoder_dim, decoder_dim, attention_dim):\n        super(Attention, self).__init__()\n        self.encoder_att, self.decoder_att = nn.Linear(encoder_dim, attention_dim), nn.Linear(decoder_dim, attention_dim)\n        self.full_att = nn.Linear(attention_dim, 1)\n        self.relu, self.softmax = nn.ReLU(), nn.Softmax(dim=1)\n    def forward(self, encoder_out, decoder_hidden):\n        att1, att2 = self.encoder_att(encoder_out), self.decoder_att(decoder_hidden)\n        att = self.full_att(self.relu(att1 + att2.unsqueeze(1))).squeeze(2)\n        alpha = self.softmax(att)\n        return (encoder_out * alpha.unsqueeze(2)).sum(dim=1), alpha\n\nclass DecoderRNN(nn.Module):\n    def __init__(self, embed_size, hidden_size, vocab_size, num_layers, encoder_dim=512, attention_dim=512):\n        super(DecoderRNN, self).__init__()\n        self.attention = Attention(encoder_dim, hidden_size, attention_dim)\n        self.embedding = nn.Embedding(vocab_size, embed_size)\n        self.lstm = nn.LSTMCell(embed_size + encoder_dim, hidden_size)\n        self.init_h, self.init_c = nn.Linear(encoder_dim, hidden_size), nn.Linear(encoder_dim, hidden_size)\n        self.fcn = nn.Linear(hidden_size, vocab_size)\n        self.vocab_size = vocab_size\n    def init_hidden_state(self, encoder_out):\n        mean_encoder_out = encoder_out.mean(dim=1)\n        return self.init_h(mean_encoder_out), self.init_c(mean_encoder_out)\n    def forward(self, features, captions, lengths):\n        batch_size, vocab_size = features.size(0), self.vocab_size\n        predictions = torch.zeros(batch_size, max(lengths), vocab_size).to(features.device)\n        embeddings, (h, c) = self.embedding(captions), self.init_hidden_state(features)\n        for t in range(max(lengths)):\n            batch_size_t = sum(l > t for l in lengths)\n            attention_weighted_encoding, _ = self.attention(features[:batch_size_t], h[:batch_size_t])\n            lstm_input = torch.cat((embeddings[:batch_size_t, t, :], attention_weighted_encoding), dim=1)\n            h, c = self.lstm(lstm_input, (h[:batch_size_t], c[:batch_size_t]))\n            predictions[:batch_size_t, t, :] = self.fcn(h)\n        return predictions\n\nclass EncoderDecoder(nn.Module):\n    def __init__(self, embed_size, hidden_size, vocab_size, num_layers, encoder_dim=512):\n        super(EncoderDecoder, self).__init__()\n        self.encoder, self.decoder = EncoderCNN(), DecoderRNN(embed_size, hidden_size, vocab_size, num_layers, encoder_dim)\n    def forward(self, images, captions, lengths):\n        return self.decoder(self.encoder(images), captions, lengths)\n\nprint(\"✅ All classes are defined and ready to use!\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-14T02:22:33.587632Z","iopub.execute_input":"2025-10-14T02:22:33.587881Z","iopub.status.idle":"2025-10-14T02:25:53.925477Z","shell.execute_reply.started":"2025-10-14T02:22:33.587865Z","shell.execute_reply":"2025-10-14T02:25:53.924755Z"}},"outputs":[],"execution_count":null}]}