{"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":41880,"databundleVersionId":5677426,"sourceType":"competition"},{"sourceId":10305230,"sourceType":"datasetVersion","datasetId":6379051},{"sourceId":210794,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":179704,"modelId":201975}],"dockerImageVersionId":30823,"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-01-01T07:48:23.97544Z","iopub.execute_input":"2025-01-01T07:48:23.975748Z","iopub.status.idle":"2025-01-01T07:48:27.473741Z","shell.execute_reply.started":"2025-01-01T07:48:23.975721Z","shell.execute_reply":"2025-01-01T07:48:27.473061Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport glob\nimport pandas as pd\n\n\ntrain_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog'\ntest_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/test/defog'\n\n\ntrain_files = glob.glob(os.path.join(train_dir, '*.csv'))\ntrain_data = pd.concat([pd.read_csv(file) for file in train_files], ignore_index=True)\n\n\ntest_files = glob.glob(os.path.join(test_dir, '*.csv'))\ntest_data = pd.concat([pd.read_csv(file) for file in test_files], ignore_index=True)\n\n\nprint(\"Train Data Info:\")\nprint(train_data.info())\nprint(\"\\nTest Data Info:\")\nprint(test_data.info())\n\n\nprint(\"\\nFirst 5 rows of Train Data:\")\nprint(train_data.head())\n\nprint(\"\\nFirst 5 rows of Test Data:\")\nprint(test_data.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T07:48:37.110615Z","iopub.execute_input":"2025-01-01T07:48:37.110997Z","iopub.status.idle":"2025-01-01T07:49:03.97232Z","shell.execute_reply.started":"2025-01-01T07:48:37.110974Z","shell.execute_reply":"2025-01-01T07:49:03.971617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\nphysical_devices = tf.config.list_physical_devices('GPU')\nif physical_devices:\n    print(\"GPU is available:\", physical_devices)\n    for device in physical_devices:\n        try:\n            tf.config.experimental.set_memory_growth(device, True)\n            print(f\"Memory growth enabled for {device}\")\n        except:\n            print(f\"Invalid device or cannot modify virtual devices once initialized: {device}\")\nelse:\n    print(\"No GPU devices found. Running on CPU\")\n\n# Optional: Set mixed precision policy for faster training on modern GPUs\ntf.keras.mixed_precision.set_global_policy('mixed_float16')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T07:59:48.82576Z","iopub.execute_input":"2025-01-01T07:59:48.826054Z","iopub.status.idle":"2025-01-01T07:59:56.583195Z","shell.execute_reply.started":"2025-01-01T07:59:48.826031Z","shell.execute_reply":"2025-01-01T07:59:56.582312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"missing_train = train_data.isnull().sum()\nprint(\"\\nMissing Values in Train Data:\")\nprint(missing_train[missing_train > 0])\n\n\nmissing_test = test_data.isnull().sum()\nprint(\"\\nMissing Values in Test Data:\")\nprint(missing_test[missing_test > 0])\n\n\ntrain_data.fillna(train_data.median(), inplace=True)\ntest_data.fillna(test_data.median(), inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T07:59:59.369784Z","iopub.execute_input":"2025-01-01T07:59:59.370362Z","iopub.status.idle":"2025-01-01T08:00:00.912264Z","shell.execute_reply.started":"2025-01-01T07:59:59.370332Z","shell.execute_reply":"2025-01-01T08:00:00.911321Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sensor_columns = ['AccV', 'AccML', 'AccAP']\nprint(train_data[sensor_columns].describe())\nprint(train_data[sensor_columns].skew())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:05.224955Z","iopub.execute_input":"2025-01-01T08:00:05.225293Z","iopub.status.idle":"2025-01-01T08:00:07.195103Z","shell.execute_reply.started":"2025-01-01T08:00:05.225257Z","shell.execute_reply":"2025-01-01T08:00:07.194412Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"people_df = pd.read_csv(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/subjects.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:39.084787Z","iopub.execute_input":"2025-01-01T08:00:39.08508Z","iopub.status.idle":"2025-01-01T08:00:39.092064Z","shell.execute_reply.started":"2025-01-01T08:00:39.085058Z","shell.execute_reply":"2025-01-01T08:00:39.091379Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"people_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:41.314773Z","iopub.execute_input":"2025-01-01T08:00:41.315093Z","iopub.status.idle":"2025-01-01T08:00:41.329382Z","shell.execute_reply.started":"2025-01-01T08:00:41.315062Z","shell.execute_reply":"2025-01-01T08:00:41.32862Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Load the dataset (replace with the actual path if needed)\npeople_df = pd.read_csv(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/subjects.csv\")\n\n# Basic DataFrame check\nprint(people_df.info())\nprint(people_df.describe())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:43.00993Z","iopub.execute_input":"2025-01-01T08:00:43.010228Z","iopub.status.idle":"2025-01-01T08:00:43.561918Z","shell.execute_reply.started":"2025-01-01T08:00:43.010206Z","shell.execute_reply":"2025-01-01T08:00:43.561037Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tasks_df = pd.read_csv(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/tasks.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:46.119679Z","iopub.execute_input":"2025-01-01T08:00:46.119961Z","iopub.status.idle":"2025-01-01T08:00:46.132866Z","shell.execute_reply.started":"2025-01-01T08:00:46.11994Z","shell.execute_reply":"2025-01-01T08:00:46.132138Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tasks_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:47.945333Z","iopub.execute_input":"2025-01-01T08:00:47.945632Z","iopub.status.idle":"2025-01-01T08:00:47.954726Z","shell.execute_reply.started":"2025-01-01T08:00:47.945608Z","shell.execute_reply":"2025-01-01T08:00:47.953855Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\n\n#Calculate the Task Duration by subtracting Begin Time from End Time\ntasks_df['Task Duration (s)'] = tasks_df['End'] - tasks_df['Begin']\n\n# Task Summary: Mean, Max, Min Task Durations\nmean_duration = tasks_df['Task Duration (s)'].mean()\nmax_duration = tasks_df['Task Duration (s)'].max()\nmin_duration = tasks_df['Task Duration (s)'].min()\n\nprint(f\"Mean Task Duration: {mean_duration} seconds\")\nprint(f\"Max Task Duration: {max_duration} seconds\")\nprint(f\"Min Task Duration: {min_duration} seconds\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:49.735142Z","iopub.execute_input":"2025-01-01T08:00:49.735503Z","iopub.status.idle":"2025-01-01T08:00:49.74291Z","shell.execute_reply.started":"2025-01-01T08:00:49.735478Z","shell.execute_reply":"2025-01-01T08:00:49.741921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport pywt\nimport numpy as np\n\n# Define the directory containing Defog data\ntrain_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog'\n\n# Define a function to apply DWT\ndef apply_dwt(signal, wavelet='db4', level=4):\n    \"\"\"\n    Apply Discrete Wavelet Transform to a signal.\n    Returns approximation and detail coefficients.\n    \"\"\"\n    coeffs = pywt.wavedec(signal, wavelet=wavelet, level=level)\n    return coeffs  # [A_n, D_n, D_n-1, ..., D_1]\n\n# Initialize a list to store features\nfeatures = []\n\n# Iterate over all CSV files in the directory\nfor file in os.listdir(train_dir):\n    if file.endswith('.csv'):\n        # Load the CSV file\n        file_path = os.path.join(train_dir, file)\n        data = pd.read_csv(file_path)\n        \n        # Extract relevant columns (e.g., acceleration signals)\n        acc_v = data['AccV']  # Vertical acceleration\n        acc_ml = data['AccML']  # Mediolateral acceleration\n        acc_ap = data['AccAP']  # Anteroposterior acceleration\n        \n        # Apply DWT to each signal\n        coeffs_v = apply_dwt(acc_v)\n        coeffs_ml = apply_dwt(acc_ml)\n        coeffs_ap = apply_dwt(acc_ap)\n        \n        # Extract statistical features from the coefficients\n        features_v = [np.mean(c) for c in coeffs_v] + [np.std(c) for c in coeffs_v]\n        features_ml = [np.mean(c) for c in coeffs_ml] + [np.std(c) for c in coeffs_ml]\n        features_ap = [np.mean(c) for c in coeffs_ap] + [np.std(c) for c in coeffs_ap]\n        \n        # Combine all features into a single row\n        feature_row = features_v + features_ml + features_ap\n        features.append(feature_row)\n\n# Convert features to a DataFrame\ncolumns = [f'coeff_{i}' for i in range(len(features[0]))]\nfeatures_df = pd.DataFrame(features, columns=columns)\n\n# Save the extracted features for modeling\nfeatures_df.to_csv('dwt_features.csv', index=False)\nprint(\"DWT features saved as 'dwt_features.csv'\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:00:51.625596Z","iopub.execute_input":"2025-01-01T08:00:51.625907Z","iopub.status.idle":"2025-01-01T08:01:02.983742Z","shell.execute_reply.started":"2025-01-01T08:00:51.625881Z","shell.execute_reply":"2025-01-01T08:01:02.982434Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"features_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:24.259454Z","iopub.execute_input":"2025-01-01T08:01:24.25973Z","iopub.status.idle":"2025-01-01T08:01:24.277708Z","shell.execute_reply.started":"2025-01-01T08:01:24.259708Z","shell.execute_reply":"2025-01-01T08:01:24.276898Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport pywt\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Define the directory containing Defog data\ntrain_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog'\n\n# Define a function to apply DWT\ndef apply_dwt(signal, wavelet='db4', level=4):\n    \"\"\"\n    Apply Discrete Wavelet Transform to a signal.\n    Returns approximation and detail coefficients.\n    \"\"\"\n    coeffs = pywt.wavedec(signal, wavelet=wavelet, level=level)\n    return coeffs  # [A_n, D_n, D_n-1, ..., D_1]\n\n# Load and process one file for visualization\nfile_to_visualize = None\nfor file in os.listdir(train_dir):\n    if file.endswith('.csv'):\n        file_to_visualize = os.path.join(train_dir, file)\n        break\n\n# Read the CSV file\ndata = pd.read_csv(file_to_visualize)\n\n# Extract the vertical acceleration signal\nacc_v = data['AccV']\n\n# Apply DWT\ncoeffs_v = apply_dwt(acc_v)\napproximation = coeffs_v[0]\ndetails = coeffs_v[1:]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:26.705424Z","iopub.execute_input":"2025-01-01T08:01:26.705702Z","iopub.status.idle":"2025-01-01T08:01:26.811921Z","shell.execute_reply.started":"2025-01-01T08:01:26.705681Z","shell.execute_reply":"2025-01-01T08:01:26.81125Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nfrom glob import glob\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:29.809461Z","iopub.execute_input":"2025-01-01T08:01:29.809737Z","iopub.status.idle":"2025-01-01T08:01:29.949254Z","shell.execute_reply.started":"2025-01-01T08:01:29.809716Z","shell.execute_reply":"2025-01-01T08:01:29.948586Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class FOGDataLoader:\n    def __init__(self, base_path):\n        self.base_path = base_path\n\n    def load_metadata(self):\n        metadata = {\n            'daily': pd.read_csv(os.path.join(self.base_path, 'daily_metadata.csv')),\n            'defog': pd.read_csv(os.path.join(self.base_path, 'defog_metadata.csv')),\n            'tdcsfog': pd.read_csv(os.path.join(self.base_path, 'tdcsfog_metadata.csv')),\n            'events': pd.read_csv(os.path.join(self.base_path, 'events.csv')),\n            'subjects': pd.read_csv(os.path.join(self.base_path, 'subjects.csv')),\n            'tasks': pd.read_csv(os.path.join(self.base_path, 'tasks.csv'))\n        }\n        return metadata\n\n    def load_series(self, dataset_type='train', source='tdcsfog'):\n        path = os.path.join(self.base_path, dataset_type, source, '*.csv')\n        series_files = glob(path)\n\n        series_data = []\n        for file in series_files:\n            df = pd.read_csv(file)\n            df['series_id'] = os.path.basename(file).split('.')[0]\n            series_data.append(df)\n\n        return pd.concat(series_data, axis=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:33.375223Z","iopub.execute_input":"2025-01-01T08:01:33.375529Z","iopub.status.idle":"2025-01-01T08:01:33.381791Z","shell.execute_reply.started":"2025-01-01T08:01:33.375504Z","shell.execute_reply":"2025-01-01T08:01:33.380817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class FeatureProcessor:\n    @staticmethod\n    def process_series(series_df):\n        # Normalize accelerometer data\n        for col in ['AccV', 'AccML', 'AccAP']:\n            if col in series_df:\n                series_df[col] = series_df[col] / 9.81\n        \n        # Add derived features\n        series_df['magnitude'] = np.sqrt(\n            series_df['AccV']**2 + series_df['AccML']**2 + series_df['AccAP']**2\n        )\n        series_df['jerk_v'] = series_df['AccV'].diff().fillna(0)\n        series_df['jerk_ml'] = series_df['AccML'].diff().fillna(0)\n        series_df['jerk_ap'] = series_df['AccAP'].diff().fillna(0)\n\n        return series_df.fillna(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:36.686108Z","iopub.execute_input":"2025-01-01T08:01:36.686452Z","iopub.status.idle":"2025-01-01T08:01:36.691527Z","shell.execute_reply.started":"2025-01-01T08:01:36.686427Z","shell.execute_reply":"2025-01-01T08:01:36.690629Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class WindowCreator:\n    def __init__(self, window_size=128, stride=64):\n        self.window_size = window_size\n        self.stride = stride\n\n    def create_windows(self, series_df):\n        windows, labels = [], []\n\n        for series_id in series_df['series_id'].unique():\n            series = series_df[series_df['series_id'] == series_id]\n\n            for i in range(0, len(series) - self.window_size, self.stride):\n                window = series.iloc[i:i + self.window_size]\n                windows.append(window[['AccV', 'AccML', 'AccAP', 'magnitude', \n                                       'jerk_v', 'jerk_ml', 'jerk_ap']].values)\n\n                if 'StartHesitation' in series.columns:\n                    has_event = (window[['StartHesitation', 'Turn', 'Walking']].sum().sum() > 0)\n                    labels.append(int(has_event))\n\n        return np.array(windows), np.array(labels) if labels else None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:38.555249Z","iopub.execute_input":"2025-01-01T08:01:38.555539Z","iopub.status.idle":"2025-01-01T08:01:38.561249Z","shell.execute_reply.started":"2025-01-01T08:01:38.555517Z","shell.execute_reply":"2025-01-01T08:01:38.560218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class MeanAveragePrecision(tf.keras.metrics.Metric):\n    def __init__(self, name='mAP', **kwargs):\n        super().__init__(name=name, **kwargs)\n        self.true_positives = self.add_weight(name='tp', initializer='zeros')\n        self.false_positives = self.add_weight(name='fp', initializer='zeros')\n        self.false_negatives = self.add_weight(name='fn', initializer='zeros')\n        \n    def update_state(self, y_true, y_pred, sample_weight=None):\n        y_pred = tf.cast(y_pred > 0.5, tf.float32)\n        y_true = tf.cast(y_true, tf.float32)\n        \n        self.true_positives.assign_add(tf.reduce_sum(y_true * y_pred))\n        self.false_positives.assign_add(tf.reduce_sum((1 - y_true) * y_pred))\n        self.false_negatives.assign_add(tf.reduce_sum(y_true * (1 - y_pred)))\n        \n    def result(self):\n        precision = self.true_positives / (self.true_positives + self.false_positives + tf.keras.backend.epsilon())\n        recall = self.true_positives / (self.true_positives + self.false_negatives + tf.keras.backend.epsilon())\n        return precision * recall  # Simplified mAP calculation\n    \n    def reset_state(self):\n        self.true_positives.assign(0.)\n        self.false_positives.assign(0.)\n        self.false_negatives.assign(0.)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:41.365136Z","iopub.execute_input":"2025-01-01T08:01:41.365439Z","iopub.status.idle":"2025-01-01T08:01:41.373369Z","shell.execute_reply.started":"2025-01-01T08:01:41.365418Z","shell.execute_reply":"2025-01-01T08:01:41.372364Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler\n\n# GPU Setup\nphysical_devices = tf.config.list_physical_devices('GPU')\nif physical_devices:\n    print(\"GPU is available:\", physical_devices)\n    for device in physical_devices:\n        try:\n            tf.config.experimental.set_memory_growth(device, True)\n            print(f\"Memory growth enabled for {device}\")\n        except:\n            print(f\"Invalid device or cannot modify virtual devices once initialized: {device}\")\nelse:\n    print(\"No GPU devices found. Running on CPU\")\n\n# Enable mixed precision for better GPU performance\ntf.keras.mixed_precision.set_global_policy('mixed_float16')\n\nCFG = {\n    'block_size': 15552,\n    'block_stride': 15552//16,\n    'patch_size': 18,\n    'fog_model_dim': 320,\n    'fog_model_num_heads': 6,\n    'fog_model_num_encoder_layers': 5,\n    'fog_model_num_lstm_layers': 2,\n    'fog_model_first_dropout': 0.1,\n    'fog_model_encoder_dropout': 0.1,\n    'fog_model_mha_dropout': 0.0,\n}\n\nclass EncoderLayer(tf.keras.layers.Layer):\n    def __init__(self, d_model, num_heads, dropout_rate=0.1):\n        super().__init__()\n        self.mha = layers.MultiHeadAttention(\n            num_heads=num_heads,\n            key_dim=d_model,\n            dropout=dropout_rate\n        )\n        self.ffn = tf.keras.Sequential([\n            layers.Dense(d_model * 4, activation='relu'),\n            layers.Dropout(dropout_rate),\n            layers.Dense(d_model),\n            layers.Dropout(dropout_rate)\n        ])\n        self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)\n        self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)\n        self.add = layers.Add()\n\n    def call(self, x, training=True):\n        attn_output = self.mha(x, x, x)\n        x = self.add([x, attn_output])\n        x = self.layernorm1(x)\n        ffn_output = self.ffn(x)\n        x = self.add([x, ffn_output])\n        x = self.layernorm2(x)\n        return x\n\nclass ImprovedFOGModel(tf.keras.Model):\n    def __init__(self, input_shape=(128, 7), num_heads=4, d_model=128):\n        super().__init__()\n        self.d_model = d_model\n        self.sequence_len = input_shape[0]\n        \n        self.input_projection = layers.Dense(d_model)\n        self.pos_encoding = self._create_positional_encoding()\n        self.dropout = layers.Dropout(0.1)\n        \n        self.encoder_layers = [\n            EncoderLayer(\n                d_model=d_model,\n                num_heads=num_heads,\n                dropout_rate=0.1\n            ) for _ in range(3)\n        ]\n        \n        self.global_avg_pool = layers.GlobalAveragePooling1D()\n        self.final_dense1 = layers.Dense(64, activation='relu')\n        self.final_dropout = layers.Dropout(0.3)\n        self.output_projection = layers.Dense(1, activation='sigmoid')\n\n    def _create_positional_encoding(self):\n        position = np.arange(self.sequence_len)[:, np.newaxis]\n        div_term = np.exp(\n            np.arange(0, self.d_model, 2) * -(np.log(10000.0) / self.d_model)\n        )\n        pos_enc = np.zeros((1, self.sequence_len, self.d_model))\n        pos_enc[0, :, 0::2] = np.sin(position * div_term)\n        pos_enc[0, :, 1::2] = np.cos(position * div_term)\n        return tf.constant(pos_enc, dtype=tf.float32)\n\n    def call(self, x, training=True):\n        batch_size = tf.shape(x)[0]\n        x = self.input_projection(x)\n        pos_enc = tf.tile(self.pos_encoding, [batch_size, 1, 1])\n        x = x + pos_enc\n        x = self.dropout(x, training=training)\n        \n        for encoder_layer in self.encoder_layers:\n            x = encoder_layer(x, training=training)\n        \n        x = self.global_avg_pool(x)\n        x = self.final_dense1(x)\n        x = self.final_dropout(x, training=training)\n        x = self.output_projection(x)\n        return x\n\n@tf.function\ndef prepare_data_for_gpu(x, y):\n    return tf.cast(x, tf.float32), tf.cast(y, tf.float32)\n\n# Data loading and processing\nwith tf.device('/CPU:0'):  # Keep data preprocessing on CPU\n    base_path = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction'\n    loader = FOGDataLoader(base_path)\n    tdcsfog_train = loader.load_series(dataset_type='train', source='tdcsfog')\n    \n    processor = FeatureProcessor()\n    tdcsfog_train = processor.process_series(tdcsfog_train)\n    \n    windower = WindowCreator(window_size=128, stride=64)\n    X_windows, y_windows = windower.create_windows(tdcsfog_train)\n    \n    scaler = StandardScaler()\n    X_windows = scaler.fit_transform(X_windows.reshape(-1, X_windows.shape[-1])).reshape(X_windows.shape)\n    \n    X_train, X_val, y_train, y_val = train_test_split(\n        X_windows, y_windows, test_size=0.2, random_state=42\n    )\n\n# Create optimized datasets for GPU\nBATCH_SIZE = 32\nAUTOTUNE = tf.data.AUTOTUNE\n\ntrain_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))\ntrain_dataset = train_dataset.map(prepare_data_for_gpu, num_parallel_calls=AUTOTUNE)\ntrain_dataset = train_dataset.cache()\ntrain_dataset = train_dataset.shuffle(buffer_size=1000)\ntrain_dataset = train_dataset.batch(BATCH_SIZE)\ntrain_dataset = train_dataset.prefetch(AUTOTUNE)\n\nval_dataset = tf.data.Dataset.from_tensor_slices((X_val, y_val))\nval_dataset = val_dataset.map(prepare_data_for_gpu, num_parallel_calls=AUTOTUNE)\nval_dataset = val_dataset.batch(BATCH_SIZE)\nval_dataset = val_dataset.prefetch(AUTOTUNE)\n\n# Model training on GPU\nwith tf.device('/GPU:0'):\n    model = ImprovedFOGModel(input_shape=(128, 7))\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n        loss='binary_crossentropy',\n        metrics=['accuracy', tf.keras.metrics.AUC(name='auc')]\n    )\n    \n    callbacks = [\n        tf.keras.callbacks.EarlyStopping(\n            monitor='val_auc',\n            patience=5,\n            restore_best_weights=True,\n            mode='max'\n        ),\n        tf.keras.callbacks.ReduceLROnPlateau(\n            monitor='val_auc',\n            factor=0.5,\n            patience=3,\n            mode='max'\n        ),\n        tf.keras.callbacks.TensorBoard(\n            log_dir='./logs',\n            update_freq='epoch'\n        )\n    ]\n    \n    history = model.fit(\n        train_dataset,\n        validation_data=val_dataset,\n        epochs=10,\n        callbacks=callbacks\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-01T08:01:46.164261Z","iopub.execute_input":"2025-01-01T08:01:46.164584Z","iopub.status.idle":"2025-01-01T08:06:26.78324Z","shell.execute_reply.started":"2025-01-01T08:01:46.164558Z","shell.execute_reply":"2025-01-01T08:06:26.78198Z"}},"outputs":[],"execution_count":null}]}