{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":11000,"databundleVersionId":875412,"sourceType":"competition"},{"sourceId":291925667,"sourceType":"kernelVersion"}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport pickle\nimport pandas as pd\nimport scipy\nimport time\nimport os\nimport pickle\nimport gc\nfrom scipy.stats import kurtosis, skew\nfrom sklearn.preprocessing import StandardScaler, MinMaxScaler\n\ntorch.cuda.empty_cache()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:03:55.101497Z","iopub.execute_input":"2026-01-14T08:03:55.101878Z","iopub.status.idle":"2026-01-14T08:03:55.112965Z","shell.execute_reply.started":"2026-01-14T08:03:55.101843Z","shell.execute_reply":"2026-01-14T08:03:55.112308Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Ensuring CPU is connected\n\nprint(torch.cuda.is_available())\nprint(torch.cuda.get_device_name())\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:03:55.114186Z","iopub.execute_input":"2026-01-14T08:03:55.114479Z","iopub.status.idle":"2026-01-14T08:03:55.119759Z","shell.execute_reply.started":"2026-01-14T08:03:55.114456Z","shell.execute_reply":"2026-01-14T08:03:55.119058Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.makedirs(\"./Models\", exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:03:55.120927Z","iopub.execute_input":"2026-01-14T08:03:55.121292Z","iopub.status.idle":"2026-01-14T08:03:55.132889Z","shell.execute_reply.started":"2026-01-14T08:03:55.121255Z","shell.execute_reply":"2026-01-14T08:03:55.132311Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Setting General Hyperparameters\n\nbatch_size = 100 # number of patches per batch\nvalid_rate = 0.1 # fraction of data dedicated to validation\noverlap_rate = 0.2 # overlap\n\n# Parameters\n\nnrows = 50_000_000\nseed = 1\npatch_size = 150_000","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:03:55.134097Z","iopub.execute_input":"2026-01-14T08:03:55.134350Z","iopub.status.idle":"2026-01-14T08:03:55.147297Z","shell.execute_reply.started":"2026-01-14T08:03:55.134330Z","shell.execute_reply":"2026-01-14T08:03:55.146448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Loading Data\n\nrootpath = \"../input/LANL-Earthquake-Prediction/\"\n\ntrain_data = pd.read_csv(rootpath + \"train.csv\", usecols = ['acoustic_data', 'time_to_failure'], \\\n                         dtype = {'acoustic_data': np.int16, 'time_to_failure': np.float64}, nrows = nrows)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:03:55.148117Z","iopub.execute_input":"2026-01-14T08:03:55.148424Z","iopub.status.idle":"2026-01-14T08:04:05.361192Z","shell.execute_reply.started":"2026-01-14T08:03:55.148402Z","shell.execute_reply":"2026-01-14T08:04:05.360592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = torch.squeeze(torch.tensor(train_data['acoustic_data'].values, dtype = torch.int16))\nY = torch.squeeze(torch.tensor(train_data['time_to_failure'].values, dtype = torch.float64))\n\ndel train_data\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:05.362861Z","iopub.execute_input":"2026-01-14T08:04:05.363102Z","iopub.status.idle":"2026-01-14T08:04:05.597726Z","shell.execute_reply.started":"2026-01-14T08:04:05.363081Z","shell.execute_reply":"2026-01-14T08:04:05.596864Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def patching(patch_size, X, Y, overlap_rate):\n\n    overlap = int(patch_size*overlap_rate)\n    L = X.shape[0]\n    n_patch = int(np.floor((L-patch_size)/(patch_size-overlap)+1))\n    ids_no_seism = []\n\n    X_patch = torch.zeros(n_patch,patch_size)\n    Y_patch = torch.zeros(n_patch)\n\n    for i in range (n_patch):\n        X_patch[i,:] = X[i*(patch_size-overlap):(i+1)*patch_size-i*overlap]\n        Y_patch[i] = Y[(i+1)*patch_size - i*overlap]\n\n        if torch.min(Y[i*(patch_size-overlap):(i+1)*patch_size - i*overlap]) > 0.001:\n            ids_no_seism.append(i)\n\n    X_patch = X_patch[ids_no_seism]\n    Y_patch = Y_patch[ids_no_seism]\n\n    return(n_patch, X_patch, Y_patch)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:05.598772Z","iopub.execute_input":"2026-01-14T08:04:05.599049Z","iopub.status.idle":"2026-01-14T08:04:05.605583Z","shell.execute_reply.started":"2026-01-14T08:04:05.599025Z","shell.execute_reply":"2026-01-14T08:04:05.604657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Normalizing Data (Global for Y, prepare for per-window for X)\n\n# Only Min-Max scale Y globally\nmm = MinMaxScaler()\nY = torch.squeeze(torch.from_numpy(mm.fit_transform(np.array(Y).reshape(-1, 1))))\n\n# X (acoustic_data) will be standardized per window later. It remains in its raw form here.","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:05.606702Z","iopub.execute_input":"2026-01-14T08:04:05.607210Z","iopub.status.idle":"2026-01-14T08:04:06.004346Z","shell.execute_reply.started":"2026-01-14T08:04:05.607181Z","shell.execute_reply":"2026-01-14T08:04:06.003652Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Distribution of data in patches\n\n_, X_patch_raw, Y_patch = patching(patch_size, X, Y, overlap_rate = overlap_rate)\n\ndel X; del Y # X was raw acoustic data, Y was globally min-max scaled time_to_failure\ngc.collect()\n\n# Apply StandardScaler to each window (patch) in X_patch_raw individually\nss_per_window = StandardScaler()\n# Pre-allocate tensor for scaled data, ensuring float type for StandardScaler\nX_patch_scaled = torch.empty_like(X_patch_raw, dtype=torch.float32)\n\nfor i in range(X_patch_raw.shape[0]):\n    # Convert patch to numpy, reshape for StandardScaler, scale, and convert back to tensor\n    patch_np = X_patch_raw[i, :].numpy().reshape(-1, 1)\n    X_patch_scaled[i, :] = torch.from_numpy(ss_per_window.fit_transform(patch_np).flatten()).float()\n\nX_patch = X_patch_scaled # Replace raw X_patch with scaled X_patch\n\nprint(X_patch.shape)\nprint(\"There are \", X_patch.shape[0], \"time series available for training and validation after patching with overlap. \\n\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:06.005282Z","iopub.execute_input":"2026-01-14T08:04:06.005561Z","iopub.status.idle":"2026-01-14T08:04:07.026097Z","shell.execute_reply.started":"2026-01-14T08:04:06.005532Z","shell.execute_reply":"2026-01-14T08:04:07.025314Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Initializing Data Sets\n\n# For time-series split, data should not be shuffled. X_patch and Y_patch are already ordered temporally.\nN_samples = X_patch.shape[0]\nN_valid = int(valid_rate*N_samples) # number of validation patches\nN_train = N_samples - N_valid # number of training patches\n\n# Split data: X_train and Y_train are the earlier samples, X_valid and Y_valid are the later samples\nX_train = X_patch[:N_train,:].cpu()\nY_train = Y_patch[:N_train].cpu()\n\nX_valid = X_patch[N_train:,:].cpu()\nY_valid = Y_patch[N_train:].cpu()\n\n\n# Inputs of nn.Conv1d must have the following shape: (N, C_in, *),\n#where N: number of samples (batch size), C_in: number of input channels, *: can be any dimension (150_000 for our time series)\n\n# Add channel dimension to X_valid\nX_valid = torch.unsqueeze(X_valid, 1)\n\n# N_train was already calculated\n\nn_batch = int(X_train.shape[0] / batch_size) # Number of batch per epoch\n\nX_train = X_train.reshape([N_train, 1, patch_size])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:07.027235Z","iopub.execute_input":"2026-01-14T08:04:07.027529Z","iopub.status.idle":"2026-01-14T08:04:07.033525Z","shell.execute_reply.started":"2026-01-14T08:04:07.027505Z","shell.execute_reply":"2026-01-14T08:04:07.032591Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Plotting Graphs\n\ndef plot_and_save_results(train_losses, valid_losses, best_mvd, best_mtd, min_tl, min_vl, mm, model_name):\n\n    best_epoch = np.fromiter(valid_losses, dtype=float).argmin()\n\n    fig, ax = plt.subplots(1, 2, figsize = (20,10))\n    plt.rcParams['font.size'] = '20'\n    ax[0].set(title = \"Losses: Training and Validation\")\n    ax[0].set_xlabel(\"epochs\", fontsize = 20)\n    ax[0].set_ylabel(\"MSE\", fontsize = 20)\n    ax[0].plot(train_losses,\"r\", label = \"Training\", linewidth = 3)\n    ax[0].plot(valid_losses, \"b\", label = \"Validation\", linewidth = 3)\n    ax[0].legend(loc = \"upper right\", fontsize = 18)\n    ax[0].axvline(x=int(best_epoch), color = 'black', linestyle =\"--\", linewidth = 3)\n    ax[0].annotate(\"Best epoch: {}\\nMSE_train: {:.3f}\\nMSE_valid: {:.3f}\".format(int(best_epoch), min_tl, min_vl), \\\n                   xy = (0.5,0.5), xycoords = 'axes fraction')\n\n    best_mvd_plot = mm.inverse_transform(best_mvd.reshape(-1, 1))\n    best_mtd_plot = mm.inverse_transform(best_mtd.reshape(-1, 1))\n\n    N_valid = best_mvd_plot.shape[0]\n\n    mean = float(np.mean(best_mvd_plot))\n    std_dev = float(np.std(best_mvd_plot))\n    kurt = float(kurtosis(best_mvd_plot))\n    skewn = float(skew(best_mvd_plot))\n    q1 = float(np.quantile(best_mvd_plot, 0.25))\n    median = float(np.quantile(best_mvd_plot, 0.5))\n    q3 = float(np.quantile(best_mvd_plot, 0.75))\n    mae = np.absolute(best_mvd_plot).sum() / N_valid\n    mse = np.square(best_mvd_plot).sum() / N_valid\n\n    text = \"mean: {:.3f}\\nstd: {:.3f}\\nkurt: {:.3f}\\nskew: {:.3f}\\nq1: {:.3f}\\nmed: {:.3f}\\nq3: {:.3f}\\niqr: {:.3f}\\nmae: {:.3f}\\nmse: {:.3f}\\n\".format(mean, std_dev, kurt, skewn, q1, median, q3, q3-q1, mae, mse)\n\n    ax[1].hist(best_mvd_plot, alpha = 0.3, label = \"validation set\", bins = 100, density = True, range = (-16, 16))\n    ax[1].set(title = \"TTF error distributions at best epoch\")\n    ax[1].set_xlabel(\"Error (seconds)\", fontsize = 20)\n    ax[1].set_ylabel(\"Density\", fontsize = 20)\n    ax[1].hist(best_mtd_plot, alpha = 0.3, label = \"training set\", bins = 100, density = True, range = (-16, 16))\n    ax[1].annotate(text, xy =(-15, 0.1))\n    ax[1].legend()\n\n\n    plt.gcf()\n    plt.savefig('Models/' + model_name + '/' + model_name + \"_plot.jpg\")\n    plt.show()\n\n    model_features = {\"N_samples\": N_samples, \"N_train\": N_train, \"N_valid\": N_valid, \\\n                      \"overlap_rate\": overlap_rate, \"learning_rate\": learning_rate, \"num_epochs\": num_epochs, \\\n                     \"seed\": seed, \"batch_size\": batch_size, \"train_losses\": train_losses, \"valid_losses\": valid_losses, \\\n                     \"valid_differences\": valid_differences, \"best_mtd\": best_mtd, \"best_mvd\": best_mvd, \"min_tl\": min_tl, \\\n                      \"min_vl\": min_vl}\n\n    pickle.dump(model_features, open('Models/' + model_name + '/' + model_name + \".p\", \"wb\" ))\n\n    model_features_display = {\"N_samples\": N_samples, \"N_train\": N_train, \"N_valid\": N_valid, \\\n                  \"overlap_rate\": overlap_rate, \"learning_rate\": learning_rate, \"num_epochs\": num_epochs, \\\n                 \"seed\": seed, \"batch_size\": batch_size}\n\n    pickle.dump(model_features_display, open('Models/' + model_name + '/' + model_name + \"display.p\", \"wb\" ))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:07.035912Z","iopub.execute_input":"2026-01-14T08:04:07.036125Z","iopub.status.idle":"2026-01-14T08:04:07.049714Z","shell.execute_reply.started":"2026-01-14T08:04:07.036105Z","shell.execute_reply":"2026-01-14T08:04:07.049075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Hyperparameters specific to LSTM\n\nnum_epochs = 1000 #1000 epochs\nlearning_rate = 0.001 #0.001 lr\nhidden_size = 32 #number of features in hidden state\nnum_layers = 2 #number of stacked lstm layers => should stay at 1 unless you want to combine two LSTMs together\nN_sub_patches = 250\nN_features = 10\ndevice = \"cuda\"\nn_batch = 1 # One batch with all training data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:07.050602Z","iopub.execute_input":"2026-01-14T08:04:07.050935Z","iopub.status.idle":"2026-01-14T08:04:07.064761Z","shell.execute_reply.started":"2026-01-14T08:04:07.050902Z","shell.execute_reply":"2026-01-14T08:04:07.064110Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def feature_expansion(X, N_sub_patches, L_sub_patch):\n    N_samples = X.shape[0]\n    x = X.reshape(N_samples, N_sub_patches, L_sub_patch)\n    x_mean = np.mean(x, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_std = np.std(x, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_skew = np.array(scipy.stats.skew(x, axis = 2), dtype = np.double).reshape(N_samples, N_sub_patches, 1)\n    x_kurt = np.array(scipy.stats.kurtosis(x, axis = 2), dtype = np.double).reshape(N_samples, N_sub_patches, 1)\n    x_min = np.min(x, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_max = np.max(x, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_q1 = np.quantile(x, 0.25, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_med = np.quantile(x, 0.5, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_q3 = np.quantile(x, 0.75, axis = 2).reshape(N_samples, N_sub_patches, 1)\n    x_iqr = x_q3 - x_q1\n\n    X_rearranged = np.concatenate((x_mean, x_std, x_skew, x_kurt, x_min, x_max, x_q1, x_med, x_q3, x_iqr), axis = 2)\n    return X_rearranged\n\n\ndef lstm_feature_engineering(X_train, Y_train, X_valid, Y_valid, patch_size, N_sub_patches):\n    X_train = np.array(torch.squeeze(X_train)); Y_train = np.array(Y_train)\n    X_valid = np.array(torch.squeeze(X_valid)); Y_valid = np.array(Y_valid)\n\n    L_seq = X_train.shape[1]\n    L_sub_patch = int(L_seq / N_sub_patches)\n    N_features = 10 # mean, std, skew, kurt, min, max, quantiles 0.25, 0.5, 0.75, inter-quartile range\n\n    X_train_rearranged = feature_expansion(X_train, N_sub_patches, L_sub_patch)\n    X_valid_rearranged = feature_expansion(X_valid, N_sub_patches, L_sub_patch)\n\n    X_train = torch.from_numpy(X_train_rearranged)\n    X_valid = torch.from_numpy(X_valid_rearranged)\n\n    Y_train = torch.from_numpy(Y_train); Y_valid = torch.from_numpy(Y_valid)\n    #Y_train = torch.unsqueeze(Y_train, -1); Y_valid = torch.unsqueeze(Y_valid, -1)\n\n    return X_train, Y_train, X_valid, Y_valid","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:07.065581Z","iopub.execute_input":"2026-01-14T08:04:07.065832Z","iopub.status.idle":"2026-01-14T08:04:07.078550Z","shell.execute_reply.started":"2026-01-14T08:04:07.065799Z","shell.execute_reply":"2026-01-14T08:04:07.078026Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train_, Y_train_, X_valid_, Y_valid_ = lstm_feature_engineering(X_train, Y_train, X_valid, Y_valid, patch_size, N_sub_patches = N_sub_patches)\nN_features = X_train_.shape[-1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:07.079423Z","iopub.execute_input":"2026-01-14T08:04:07.079718Z","iopub.status.idle":"2026-01-14T08:04:10.978948Z","shell.execute_reply.started":"2026-01-14T08:04:07.079690Z","shell.execute_reply":"2026-01-14T08:04:10.978146Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Lstm(nn.Module):\n    def __init__(self, N_features, hidden_size, num_layers, seq_length):\n        super(Lstm, self).__init__()\n\n        self.num_layers = num_layers # number of layers\n        self.N_features = N_features # number of features\n        self.hidden_size = hidden_size # hidden state\n        self.seq_length = seq_length # sequence length\n\n        self.lstm = nn.LSTM(input_size=N_features, hidden_size=hidden_size,\n                          num_layers=num_layers, batch_first=True) #lstm => Input Shape : (N_batch, L_seq, N_feature)\n\n    def forward(self,x):\n        output, (_,_) = self.lstm(x.float())\n        out = output[:,-1,0] # Retrieving predicted time at the end of the training\n\n        return out","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:10.980006Z","iopub.execute_input":"2026-01-14T08:04:10.980333Z","iopub.status.idle":"2026-01-14T08:04:10.986253Z","shell.execute_reply.started":"2026-01-14T08:04:10.980307Z","shell.execute_reply":"2026-01-14T08:04:10.985569Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"L_seq = N_sub_patches\nmodel = Lstm(N_features, hidden_size, num_layers, L_seq) #our lstm class\nmodel.cuda()\nloss = torch.nn.MSELoss()    # mean-squared error for regression\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:10.987433Z","iopub.execute_input":"2026-01-14T08:04:10.987790Z","iopub.status.idle":"2026-01-14T08:04:11.003862Z","shell.execute_reply.started":"2026-01-14T08:04:10.987755Z","shell.execute_reply":"2026-01-14T08:04:11.003120Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Training LSTM\ntorch.cuda.empty_cache()\n\ntrain_losses, valid_losses = [], []\ntrain_mae, valid_mae = [], []\nbest_mvd, best_mtd = [], []\n\nmin_vl = 1000\nmin_tl = 1000\n\nstart = time.perf_counter()\n\nfor epoch in range(num_epochs):\n\n    outputs = model.forward(X_train_.cuda())  # forward pass\n    optimizer.zero_grad()  # calculate the gradient, manually setting to 0\n    # obtain the loss function\n    _loss = loss(outputs, Y_train_.cuda())\n    _loss.backward()  # calculates the loss of the loss function\n    running_loss = _loss.item()\n    optimizer.step()  # improve from loss, i.e backprop\n\n    # MAE calculation for training set\n    train_pred = torch.squeeze(outputs).cpu()\n    train_differences = train_pred[:] - Y_train_[:]\n    train_mae_epoch = np.mean(np.abs(train_differences.detach().numpy()))\n\n    model.eval()\n    with torch.no_grad():\n        Y_valid_pred = torch.squeeze(model(X_valid_.cuda())).cpu()\n        valid_loss = loss(Y_valid_pred, Y_valid_)\n        valid_differences = Y_valid_pred[:] - Y_valid_[:]\n        valid_mae_epoch = np.mean(np.abs(valid_differences.detach().numpy()))\n\n        valid_losses.append(valid_loss.item())\n        train_losses.append(running_loss / n_batch)\n        train_mae.append(train_mae_epoch)\n        valid_mae.append(valid_mae_epoch)\n\n        if valid_loss < min_vl:\n            min_vl = valid_loss\n            min_tl = running_loss\n\n            best_mvd = valid_differences\n\n            Y_final = torch.squeeze(model(X_train_.cuda())).cpu()\n\n            best_mtd = Y_train_ - Y_final\n            best_mtd = best_mtd.cpu().detach().numpy()\n\n    model.train()\n\n    if epoch % 10 == 0:\n        print(\"Epoch: {}\\t\".format(epoch),\n              \"train Loss: {:.5f}.. \".format(train_losses[-1]),\n              \"valid Loss: {:.5f}.. \".format(valid_losses[-1]),\n              \"train MAE: {:.5f}.. \".format(train_mae[-1]),\n              \"valid MAE: {:.5f}.. \".format(valid_mae[-1]))\n\nprint(\"---------- Best : {:.3f}\".format(min(valid_losses)), \" at epoch \"\n      , np.fromiter(valid_losses, dtype=float).argmin(), \" / \", epoch + 1)\n\nend = time.perf_counter()\nprint(\"\\ntime elapsed: {:.3f}\".format(end - start))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:11.004812Z","iopub.execute_input":"2026-01-14T08:04:11.005110Z","iopub.status.idle":"2026-01-14T08:04:21.463044Z","shell.execute_reply.started":"2026-01-14T08:04:11.005087Z","shell.execute_reply":"2026-01-14T08:04:21.462215Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_name = \"Lstm\"\nos.makedirs('Models/' + model_name, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:21.464046Z","iopub.execute_input":"2026-01-14T08:04:21.464351Z","iopub.status.idle":"2026-01-14T08:04:21.468427Z","shell.execute_reply.started":"2026-01-14T08:04:21.464328Z","shell.execute_reply":"2026-01-14T08:04:21.467692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_and_save_results(train_losses, valid_losses, best_mvd, best_mtd, min_tl, min_vl, mm, model_name)\ntorch.save(model.state_dict(), 'Models/' + model_name + '/' + model_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:21.469391Z","iopub.execute_input":"2026-01-14T08:04:21.469642Z","iopub.status.idle":"2026-01-14T08:04:22.273585Z","shell.execute_reply.started":"2026-01-14T08:04:21.469611Z","shell.execute_reply":"2026-01-14T08:04:22.272849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del X_train; gc.collect()\ndel X_valid; gc.collect()\ndel Y_valid; gc.collect()\ndel Y_train; gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:22.274725Z","iopub.execute_input":"2026-01-14T08:04:22.274980Z","iopub.status.idle":"2026-01-14T08:04:22.953317Z","shell.execute_reply.started":"2026-01-14T08:04:22.274958Z","shell.execute_reply":"2026-01-14T08:04:22.952785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Retrieve Test Data\n\nrootpath = \"../input/LANL-Earthquake-Prediction/\"\n\nX_test_ = []\n\nfor filename in os.listdir(rootpath + \"test\"):\n    temp_df = pd.read_csv(rootpath + \"test/\" + filename)\n    X_test_.append(temp_df)\n\npatch_size = X_test_[0].shape[0]\nsample_submission = pd.read_csv(rootpath + \"sample_submission.csv\")\n\nX_test = torch.zeros((len(X_test_), patch_size))\nfor i in range(len(X_test_)):\n    X_test[i,:] = torch.tensor(X_test_[i][\"acoustic_data\"], dtype = torch.float32)\n\ndel X_test_; gc.collect()\n\nY_test = torch.tensor(sample_submission[\"time_to_failure\"])\n\nN_test = X_test.shape[0]\nX_test = X_test.reshape([N_test, 1, patch_size])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:04:22.954064Z","iopub.execute_input":"2026-01-14T08:04:22.954318Z","iopub.status.idle":"2026-01-14T08:05:50.775521Z","shell.execute_reply.started":"2026-01-14T08:04:22.954296Z","shell.execute_reply":"2026-01-14T08:05:50.774848Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Load Model\n\nmodel = Lstm(N_features, hidden_size, num_layers, L_seq).cuda()\nmodel.load_state_dict(torch.load('Models/Lstm/Lstm'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:05:50.776368Z","iopub.execute_input":"2026-01-14T08:05:50.776608Z","iopub.status.idle":"2026-01-14T08:05:50.786659Z","shell.execute_reply.started":"2026-01-14T08:05:50.776585Z","shell.execute_reply":"2026-01-14T08:05:50.785985Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"L_sub_patch = int(patch_size / N_sub_patches)\nX_test = np.array(torch.squeeze(X_test))\nX_test_expanded = feature_expansion(X_test, N_sub_patches, L_sub_patch)\nX_test_expanded = torch.from_numpy(X_test_expanded).cuda()\n\nmodel.eval()\nwith torch.no_grad():\n    Y_test_predicted = model(X_test_expanded)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:05:50.787553Z","iopub.execute_input":"2026-01-14T08:05:50.787817Z","iopub.status.idle":"2026-01-14T08:06:18.323770Z","shell.execute_reply.started":"2026-01-14T08:05:50.787796Z","shell.execute_reply":"2026-01-14T08:06:18.322920Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_test_predicted = np.array(Y_test_predicted.cpu()).squeeze()\n# Inverse transform the predictions to the original scale\nY_test_predicted = mm.inverse_transform(Y_test_predicted.reshape(-1, 1)).flatten()\nsample_submission['time_to_failure'] = Y_test_predicted\nsample_submission.to_csv('submission.csv', index = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:06:18.324937Z","iopub.execute_input":"2026-01-14T08:06:18.325203Z","iopub.status.idle":"2026-01-14T08:06:18.347413Z","shell.execute_reply.started":"2026-01-14T08:06:18.325180Z","shell.execute_reply":"2026-01-14T08:06:18.346526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# score: 3.43051\n# name: 村田大和\n# id: 62418698","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-14T08:06:18.348512Z","iopub.execute_input":"2026-01-14T08:06:18.348838Z","iopub.status.idle":"2026-01-14T08:06:18.352609Z","shell.execute_reply.started":"2026-01-14T08:06:18.348812Z","shell.execute_reply":"2026-01-14T08:06:18.351977Z"}},"outputs":[],"execution_count":null}]}