{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:51:24.710693Z","iopub.execute_input":"2025-06-12T10:51:24.710917Z","iopub.status.idle":"2025-06-12T10:51:24.980435Z","shell.execute_reply.started":"2025-06-12T10:51:24.710891Z","shell.execute_reply":"2025-06-12T10:51:24.979864Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler, LabelEncoder\nfrom sklearn.model_selection import StratifiedShuffleSplit\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.metrics import f1_score\nimport joblib\nfrom tqdm import tqdm\nfrom sklearn.utils.class_weight import compute_class_weight\nimport matplotlib.pyplot as plt\nimport seaborn as sns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:51:24.981429Z","iopub.execute_input":"2025-06-12T10:51:24.981824Z","iopub.status.idle":"2025-06-12T10:51:29.744180Z","shell.execute_reply.started":"2025-06-12T10:51:24.981805Z","shell.execute_reply":"2025-06-12T10:51:29.743605Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv')\ndf_test = pd.read_csv('/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:51:29.744811Z","iopub.execute_input":"2025-06-12T10:51:29.745070Z","iopub.status.idle":"2025-06-12T10:52:00.182327Z","shell.execute_reply.started":"2025-06-12T10:51:29.745053Z","shell.execute_reply":"2025-06-12T10:52:00.181733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:00.184182Z","iopub.execute_input":"2025-06-12T10:52:00.184900Z","iopub.status.idle":"2025-06-12T10:52:06.457915Z","shell.execute_reply.started":"2025-06-12T10:52:00.184866Z","shell.execute_reply":"2025-06-12T10:52:06.457278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.set_option('display.max_rows', 400)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.458584Z","iopub.execute_input":"2025-06-12T10:52:06.458880Z","iopub.status.idle":"2025-06-12T10:52:06.462283Z","shell.execute_reply.started":"2025-06-12T10:52:06.458857Z","shell.execute_reply":"2025-06-12T10:52:06.461523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# missing_data = df_train.isnull().sum()\n# missing_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.462905Z","iopub.execute_input":"2025-06-12T10:52:06.463076Z","iopub.status.idle":"2025-06-12T10:52:06.475898Z","shell.execute_reply.started":"2025-06-12T10:52:06.463063Z","shell.execute_reply":"2025-06-12T10:52:06.475312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.476518Z","iopub.execute_input":"2025-06-12T10:52:06.476706Z","iopub.status.idle":"2025-06-12T10:52:06.491253Z","shell.execute_reply.started":"2025-06-12T10:52:06.476691Z","shell.execute_reply":"2025-06-12T10:52:06.490725Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler = StandardScaler()\nle = LabelEncoder()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.491943Z","iopub.execute_input":"2025-06-12T10:52:06.492161Z","iopub.status.idle":"2025-06-12T10:52:06.502088Z","shell.execute_reply.started":"2025-06-12T10:52:06.492133Z","shell.execute_reply":"2025-06-12T10:52:06.501484Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train['gesture_encoded'] = le.fit_transform(df_train['gesture'])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.502726Z","iopub.execute_input":"2025-06-12T10:52:06.503028Z","iopub.status.idle":"2025-06-12T10:52:06.599501Z","shell.execute_reply.started":"2025-06-12T10:52:06.503003Z","shell.execute_reply":"2025-06-12T10:52:06.598986Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_updated_train = df_train.drop(['row_id', 'sequence_type', 'sequence_counter', 'subject',\n       'orientation', 'behavior', 'phase', 'gesture'], axis=1)\n\n#df_updated_test = df_test.drop(['row_id', 'sequence_type', 'subject'], axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:06.601700Z","iopub.execute_input":"2025-06-12T10:52:06.601902Z","iopub.status.idle":"2025-06-12T10:52:07.054841Z","shell.execute_reply.started":"2025-06-12T10:52:06.601887Z","shell.execute_reply":"2025-06-12T10:52:07.054071Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"feature_cols = df_updated_train.drop(['sequence_id', 'gesture_encoded'], axis=1).columns\ndf_training = df_updated_train[feature_cols].ffill().bfill().fillna(0)\n#df_testing = df_updated_test[feature_cols].ffill().bfill().fillna(0)\n\ndf_training.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:07.055601Z","iopub.execute_input":"2025-06-12T10:52:07.055826Z","iopub.status.idle":"2025-06-12T10:52:19.012069Z","shell.execute_reply.started":"2025-06-12T10:52:07.055810Z","shell.execute_reply":"2025-06-12T10:52:19.011308Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lst_cols = list(feature_cols)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:19.012567Z","iopub.execute_input":"2025-06-12T10:52:19.012798Z","iopub.status.idle":"2025-06-12T10:52:19.016591Z","shell.execute_reply.started":"2025-06-12T10:52:19.012780Z","shell.execute_reply":"2025-06-12T10:52:19.015894Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_scaled_train = scaler.fit_transform(df_training)\n#X_scaled_test = scaler.transform(df_testing)\nX_scaled_train[0:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:19.017439Z","iopub.execute_input":"2025-06-12T10:52:19.017715Z","iopub.status.idle":"2025-06-12T10:52:21.770264Z","shell.execute_reply.started":"2025-06-12T10:52:19.017700Z","shell.execute_reply":"2025-06-12T10:52:21.769533Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_scaled_train = pd.DataFrame(X_scaled_train, columns=feature_cols)\ndf_scaled_train[['sequence_id', 'gesture_encoded']] = df_updated_train[['sequence_id', 'gesture_encoded']]\n#df_scaled_test = pd.DataFrame(X_scaled_test, columns=feature_cols)\n#df_scaled_test[['sequence_id', 'gesture_encoded']] = df_updated_test[['sequence_id', 'gesture_encoded']]\n\n\ndf_scaled_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:21.771078Z","iopub.execute_input":"2025-06-12T10:52:21.771347Z","iopub.status.idle":"2025-06-12T10:52:21.799087Z","shell.execute_reply.started":"2025-06-12T10:52:21.771323Z","shell.execute_reply":"2025-06-12T10:52:21.798485Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sequence_lengths = df_scaled_train.groupby('sequence_id').size()\nprint(sequence_lengths.describe(percentiles=[0.25, 0.5, 0.75, 0.9, 0.95, 0.99]))\n\n\nplt.figure(figsize=(10, 6))\nsns.histplot(sequence_lengths, bins=100, kde=True)\nplt.title(\"Distribution of Sequence Lengths\")\nplt.xlabel(\"Sequence Length\")\nplt.ylabel(\"Frequency\")\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:21.799720Z","iopub.execute_input":"2025-06-12T10:52:21.799981Z","iopub.status.idle":"2025-06-12T10:52:22.371433Z","shell.execute_reply.started":"2025-06-12T10:52:21.799965Z","shell.execute_reply":"2025-06-12T10:52:22.370830Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BATCH_SIZE=8\nEPOCHS=10\nLEARNING_RATE = 1e-3\nSEQUENCE_LENGTH = 150\nINPUT_DIM = len(feature_cols)\nOUTPUT_DIM = df_scaled_train['gesture_encoded'].nunique()\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.372305Z","iopub.execute_input":"2025-06-12T10:52:22.372646Z","iopub.status.idle":"2025-06-12T10:52:22.440726Z","shell.execute_reply.started":"2025-06-12T10:52:22.372607Z","shell.execute_reply":"2025-06-12T10:52:22.440019Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gesture_map = {label: idx for idx, label in enumerate(le.classes_)}\ngesture_map","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.441543Z","iopub.execute_input":"2025-06-12T10:52:22.441832Z","iopub.status.idle":"2025-06-12T10:52:22.446947Z","shell.execute_reply.started":"2025-06-12T10:52:22.441807Z","shell.execute_reply":"2025-06-12T10:52:22.446250Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BFRDDataset(Dataset):\n    def __init__(self, df, sequence_length):\n        self.df = df\n        self.sequence_ids = df['sequence_id'].unique()\n        self.sequence_len = sequence_length\n        self.feature_cols = feature_cols\n\n    def __len__(self):\n        return len(self.sequence_ids)\n\n    def pad_or_truncate(self, X):\n        padded = np.zeros((self.sequence_len, X.shape[1]))\n        length = min(self.sequence_len, len(X))\n        padded[:length] = X[:length]\n        return padded\n\n    def __getitem__(self, idx):\n        sequence_id = self.sequence_ids[idx]\n        sequence_df = self.df[self.df['sequence_id']==sequence_id]\n        X = sequence_df[self.feature_cols].to_numpy()\n        X = self.pad_or_truncate(X)\n\n        gesture = sequence_df['gesture_encoded'].iloc[0]\n#        target = self.gesture_map[gesture]\n\n        return torch.tensor(X, dtype=torch.float32), torch.tensor(gesture, dtype=torch.long)\n        \n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.447753Z","iopub.execute_input":"2025-06-12T10:52:22.447991Z","iopub.status.idle":"2025-06-12T10:52:22.457940Z","shell.execute_reply.started":"2025-06-12T10:52:22.447969Z","shell.execute_reply":"2025-06-12T10:52:22.457304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_weights = compute_class_weight('balanced', classes=np.unique(df_scaled_train['gesture_encoded']), y=df_scaled_train['gesture_encoded'])\nclass_weights = torch.tensor(class_weights, dtype=torch.float).to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.458542Z","iopub.execute_input":"2025-06-12T10:52:22.458763Z","iopub.status.idle":"2025-06-12T10:52:22.711043Z","shell.execute_reply.started":"2025-06-12T10:52:22.458727Z","shell.execute_reply":"2025-06-12T10:52:22.710463Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_data = BFRDDataset(df_scaled_train, SEQUENCE_LENGTH)\n#testing_data = BFRDDataset(df_scaled_test, SEQUENCE_LENGTH)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.711657Z","iopub.execute_input":"2025-06-12T10:52:22.711874Z","iopub.status.idle":"2025-06-12T10:52:22.740249Z","shell.execute_reply.started":"2025-06-12T10:52:22.711857Z","shell.execute_reply":"2025-06-12T10:52:22.739780Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(training_data, batch_size=BATCH_SIZE, shuffle=True)\n#test_loader = DataLoader(testing_data, batch_size=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.740915Z","iopub.execute_input":"2025-06-12T10:52:22.741124Z","iopub.status.idle":"2025-06-12T10:52:22.744587Z","shell.execute_reply.started":"2025-06-12T10:52:22.741100Z","shell.execute_reply":"2025-06-12T10:52:22.744080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"feature_cols.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.745426Z","iopub.execute_input":"2025-06-12T10:52:22.745619Z","iopub.status.idle":"2025-06-12T10:52:22.759015Z","shell.execute_reply.started":"2025-06-12T10:52:22.745605Z","shell.execute_reply":"2025-06-12T10:52:22.758361Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Attention(nn.Module):\n    def __init__(self, hidden_size):\n        super().__init__()\n        self.attn = nn.Linear(hidden_size, 1)\n\n    def forward(self, lstm_out):\n        scores = self.attn(lstm_out)\n        weights = torch.softmax(scores, dim=1)\n        context = torch.sum(weights*lstm_out, dim=1)\n        return context, weights","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.759567Z","iopub.execute_input":"2025-06-12T10:52:22.759800Z","iopub.status.idle":"2025-06-12T10:52:22.772765Z","shell.execute_reply.started":"2025-06-12T10:52:22.759776Z","shell.execute_reply":"2025-06-12T10:52:22.772055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Model_Architecture(nn.Module):\n    def __init__(self, input_dim=332, hidden_dim=128, output_dim=18, num_layers=3, sequence_len=200):\n        super(Model_Architecture, self).__init__()\n\n        self.input_size = input_dim\n        self.hidden_size = hidden_dim\n        self.output_size = output_dim\n        self.sequence_len = sequence_len\n        self.num_layers=num_layers\n\n        self.lstm = nn.LSTM(input_size=self.input_size, hidden_size=self.hidden_size, num_layers=self.num_layers, dropout=0.2, batch_first=True, device=device)\n        self.ln = nn.LayerNorm(self.hidden_size)\n        self.attention = Attention(hidden_size=self.hidden_size)\n        self.fc = nn.Linear(self.hidden_size, self.output_size)\n\n    def forward(self, x):\n        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)\n        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)\n\n        out, (hn, cn) = self.lstm(x, (h0, c0))\n        out = self.ln(out)\n        out, weights = self.attention(out)\n        out = self.fc(out)\n        #out = self.fc(out[:, -1, :])\n        return out\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.773492Z","iopub.execute_input":"2025-06-12T10:52:22.773943Z","iopub.status.idle":"2025-06-12T10:52:22.787206Z","shell.execute_reply.started":"2025-06-12T10:52:22.773925Z","shell.execute_reply":"2025-06-12T10:52:22.786570Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target_gesture_names = ['Cheek - pinch skin', 'Forehead - pull hairline', 'Neck - scratch',\n       'Neck - pinch skin', 'Eyelash - pull hair', 'Eyebrow - pull hair',\n       'Forehead - scratch', 'Above ear - pull hair']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.787809Z","iopub.execute_input":"2025-06-12T10:52:22.788040Z","iopub.status.idle":"2025-06-12T10:52:22.802842Z","shell.execute_reply.started":"2025-06-12T10:52:22.788025Z","shell.execute_reply":"2025-06-12T10:52:22.802278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def evaluate_bfrb_f1(y_true_encoded, y_pred_encoded, label_encoder, target_gestures):\n    \"\"\"\n    Evaluates Binary F1 and Macro F1 as per the BFRB competition rules.\n    \n    Parameters:\n    - y_true_encoded: array-like of encoded true gesture labels\n    - y_pred_encoded: array-like of encoded predicted gesture labels\n    - label_encoder: fitted sklearn.preprocessing.LabelEncoder\n    - target_gestures: list of gesture names considered as target gestures (BFRB)\n    \n    Returns:\n    - A dictionary with binary_f1, macro_f1, and final_score\n    \"\"\"\n    # Decode labels back to gesture names\n    y_true = label_encoder.inverse_transform(y_true_encoded)\n    y_pred = label_encoder.inverse_transform(y_pred_encoded)\n    \n    # Convert to binary: 'target' vs 'non_target'\n    y_true_binary = ['target' if gesture in target_gestures else 'non_target' for gesture in y_true]\n    y_pred_binary = ['target' if gesture in target_gestures else 'non_target' for gesture in y_pred]\n\n    binary_f1 = f1_score(y_true_binary, y_pred_binary, average='binary', pos_label='target')\n\n    # Collapse all non-target gestures into 'non_target' for macro F1\n    y_true_collapsed = [gesture if gesture in target_gestures else 'non_target' for gesture in y_true]\n    y_pred_collapsed = [gesture if gesture in target_gestures else 'non_target' for gesture in y_pred]\n\n    macro_f1 = f1_score(y_true_collapsed, y_pred_collapsed, average='macro')\n\n    final_score = (binary_f1 + macro_f1) / 2\n\n    return {\n        'binary_f1': binary_f1,\n        'macro_f1': macro_f1,\n        'final_score': final_score\n    }    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.803521Z","iopub.execute_input":"2025-06-12T10:52:22.803787Z","iopub.status.idle":"2025-06-12T10:52:22.816020Z","shell.execute_reply.started":"2025-06-12T10:52:22.803766Z","shell.execute_reply":"2025-06-12T10:52:22.815523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def model_training(model, optimizer, criterion, epochs=50):\n    train_losses, test_losses = [], []\n\n    for epoch in range(epochs):\n        model.train()\n        epoch_loss = 0\n        all_preds = []\n        all_targets = []\n\n        for X_batch, y_batch in tqdm(train_loader, desc=f\"Epoch {epoch+1}/{epochs}\"):\n            X_batch, y_batch = X_batch.to(device), y_batch.to(device)\n            optimizer.zero_grad()\n            outputs = model(X_batch)\n            loss = criterion(outputs, y_batch)\n            loss.backward()\n            optimizer.step()\n            \n            epoch_loss += loss.item()\n\n            predicted = torch.argmax(outputs, dim=1)\n            all_preds.extend(predicted.cpu().numpy())\n            all_targets.extend(y_batch.cpu().numpy())\n\n        f1 = f1_score(all_targets, all_preds, average='macro')\n        # model.eval()\n        # test_loss = 0\n        # test_preds = []\n        # test_labels = []\n        # with torch.no_grad():\n        #     for X_batch, y_batch in test_loader:\n        #         X_batch, y_batch = features.to(device), labels.to(device)\n        #         outputs = model(X_batch)\n        #         loss = criterion(outputs, y_batch)\n        #         test_loss += loss.item()\n        #         predicted = torch.argmax(outputs, dim=1)\n        #         test_preds.extend(predicted.cpu().numpy())\n        #         test_labels.extend(y_batch.cpu().numpy())\n            \n        #     test_f1 = f1_score(all_targets, all_preds, average='macro')\n        \n        custom_f1 = evaluate_bfrb_f1(all_targets, all_preds, le, target_gesture_names)\n        print(f\"Epoch {epoch+1}/{EPOCHS} | Loss: {epoch_loss:.4f} | Macro F1: {f1:.4f}\")\n        print(f\"Binary F1: {custom_f1['binary_f1']:.4f}\")\n        print(f\"Macro F1: {custom_f1['macro_f1']:.4f}\")\n        print(f\"Final Score: {custom_f1['final_score']:.4f}\")\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.816799Z","iopub.execute_input":"2025-06-12T10:52:22.817298Z","iopub.status.idle":"2025-06-12T10:52:22.835262Z","shell.execute_reply.started":"2025-06-12T10:52:22.817277Z","shell.execute_reply":"2025-06-12T10:52:22.834697Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train['gesture_encoded'].nunique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.838220Z","iopub.execute_input":"2025-06-12T10:52:22.838429Z","iopub.status.idle":"2025-06-12T10:52:22.855412Z","shell.execute_reply.started":"2025-06-12T10:52:22.838415Z","shell.execute_reply":"2025-06-12T10:52:22.854852Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = Model_Architecture(input_dim=332, hidden_dim=256, output_dim=18, num_layers=3, sequence_len=SEQUENCE_LENGTH).to(device)\ncriterion = nn.CrossEntropyLoss(weight=class_weights)\noptimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:22.856028Z","iopub.execute_input":"2025-06-12T10:52:22.856180Z","iopub.status.idle":"2025-06-12T10:52:25.405472Z","shell.execute_reply.started":"2025-06-12T10:52:22.856168Z","shell.execute_reply":"2025-06-12T10:52:25.404921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_training(model, optimizer, criterion, epochs=EPOCHS)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T10:52:25.406106Z","iopub.execute_input":"2025-06-12T10:52:25.406416Z","iopub.status.idle":"2025-06-12T11:48:56.761072Z","shell.execute_reply.started":"2025-06-12T10:52:25.406400Z","shell.execute_reply":"2025-06-12T11:48:56.760404Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"torch.save(model.state_dict(), \"model_weights.pth\")\njoblib.dump(le, 'label_encoder.pkl')\njoblib.dump(scaler, 'scaler.pkl')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-12T11:48:56.761880Z","iopub.execute_input":"2025-06-12T11:48:56.762093Z","iopub.status.idle":"2025-06-12T11:48:56.779622Z","shell.execute_reply.started":"2025-06-12T11:48:56.762077Z","shell.execute_reply":"2025-06-12T11:48:56.778975Z"}},"outputs":[],"execution_count":null}]}