{"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":39763,"databundleVersionId":11756775,"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\nimport tensorflow as tf\nprint(\"Num GPUs Available: \", len(tf.config.list_physical_devices('GPU')))\n\nimport os\nos.makedirs(\"/kaggle/working/models\", exist_ok=True)\nos.listdir('/kaggle/working')\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:30.160203Z","iopub.execute_input":"2025-06-14T12:14:30.160518Z","iopub.status.idle":"2025-06-14T12:14:34.682912Z","shell.execute_reply.started":"2025-06-14T12:14:30.160493Z","shell.execute_reply":"2025-06-14T12:14:34.682304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"flat_data_a = np.load('/kaggle/input/waveform-inversion/train_samples/FlatVel_A/data/data2.npy')\nflat_vel_a = np.load('/kaggle/input/waveform-inversion/train_samples/FlatVel_A/model/model2.npy')\n\ncurve_data_a = np.load('/kaggle/input/waveform-inversion/train_samples/CurveVel_A/data/data2.npy')\ncurve_vel_a = np.load('/kaggle/input/waveform-inversion/train_samples/CurveVel_A/model/model2.npy')\n\nstyle_data_a = np.load('/kaggle/input/waveform-inversion/train_samples/Style_A/data/data2.npy')\nstyle_vel_a = np.load('/kaggle/input/waveform-inversion/train_samples/Style_B/model/model2.npy')\n\n\n\nprint(\"Loaded\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:34.684452Z","iopub.execute_input":"2025-06-14T12:14:34.684863Z","iopub.status.idle":"2025-06-14T12:14:35.373863Z","shell.execute_reply.started":"2025-06-14T12:14:34.684845Z","shell.execute_reply":"2025-06-14T12:14:35.373201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#500 échantillons\nprint(flat_data_a.shape)#70x70\nprint(flat_vel_a.shape)#5x1000x70\n\nprint(curve_data_a.shape)#70x70\nprint(curve_vel_a.shape)#5x1000x70\n\nprint(style_data_a.shape)#70x70\nprint(style_vel_a.shape)#5x1000x70","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:35.374729Z","iopub.execute_input":"2025-06-14T12:14:35.375024Z","iopub.status.idle":"2025-06-14T12:14:35.379354Z","shell.execute_reply.started":"2025-06-14T12:14:35.374999Z","shell.execute_reply":"2025-06-14T12:14:35.378589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nsample = 400\n\nfig, axs = plt.subplots(1, 3, figsize=(12, 4)) \n\ndef plot_velocity(ax, velocity_tensor, title, sample=400):\n    img = ax.imshow(velocity_tensor[sample, 0, :, :], cmap='jet')\n    ax.set_xticks(range(0, 70, 10))\n    ax.set_xticklabels(range(0, 700, 100))\n    ax.set_yticks(range(0, 70, 10))\n    ax.set_yticklabels(range(0, 700, 100))\n    ax.set_ylabel('Depth (m)', fontsize=10)\n    ax.set_xlabel('Offset (m)', fontsize=10) #=largeur, != decalage\n    ax.set_title(title, fontsize=11)\n\n    clb = plt.colorbar(img, ax=ax, shrink=0.7)\n    clb.ax.set_title('km/s', fontsize=8)\n\nplot_velocity(axs[0], flat_vel_a, \"Flat Velocity A\", sample)\nplot_velocity(axs[1], curve_vel_a, \"Curve Velocity A\", sample)\nplot_velocity(axs[2], style_vel_a, \"Style Velocity A\", sample)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:35.380135Z","iopub.execute_input":"2025-06-14T12:14:35.380356Z","iopub.status.idle":"2025-06-14T12:14:36.003916Z","shell.execute_reply.started":"2025-06-14T12:14:35.380340Z","shell.execute_reply":"2025-06-14T12:14:36.003223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"source=0\nreceiver=35\n\nwaveform = style_data_a[sample, source, :, receiver]\nplt.figure(figsize=(12,4))\nplt.plot(waveform)\nplt.title(f\"Forme d'onde captée - Echantillon 0, Source {source}, Récepteur {receiver}\")\nplt.xlabel(\"Temps\")\nplt.ylabel(\"Amplitude\")\nplt.grid()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:36.005729Z","iopub.execute_input":"2025-06-14T12:14:36.006006Z","iopub.status.idle":"2025-06-14T12:14:36.157114Z","shell.execute_reply.started":"2025-06-14T12:14:36.005987Z","shell.execute_reply":"2025-06-14T12:14:36.156297Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_selected=128\n\n\nX = np.concatenate([flat_data_a[:sample_selected],curve_data_a[:sample_selected],style_data_a[:sample_selected]])\ny = np.concatenate([flat_vel_a[:sample_selected],curve_vel_a[:sample_selected],style_vel_a[:sample_selected]])\n\nfrom sklearn.utils import shuffle\nX, y = shuffle(X, y, random_state=42)\n\nprint(X.shape,y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:36.157831Z","iopub.execute_input":"2025-06-14T12:14:36.158041Z","iopub.status.idle":"2025-06-14T12:14:36.504432Z","shell.execute_reply.started":"2025-06-14T12:14:36.158025Z","shell.execute_reply":"2025-06-14T12:14:36.503690Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X.min(), X.max())\nprint(y.min(), y.max())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:36.505181Z","iopub.execute_input":"2025-06-14T12:14:36.505537Z","iopub.status.idle":"2025-06-14T12:14:36.719368Z","shell.execute_reply.started":"2025-06-14T12:14:36.505509Z","shell.execute_reply":"2025-06-14T12:14:36.718639Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_min = np.min(X)\nX_max = np.max(X)\ny_min = np.min(y)\ny_max = np.max(y)\n\nscale_X = (X_max - X_min)\nscale_y = (y_max - y_min)\n\n\nX_normalized = (X - X_min) / scale_X\ny_normalized = (y - y_min) / scale_y\n\nprint(\"X min/max/mean/std après normalisation:\", X_normalized.min(), X_normalized.max(), X_normalized.mean(), X_normalized.std())\nprint(\"y min/max/mean/std après normalisation:\", y_normalized.min(), y_normalized.max(), y_normalized.mean(), y_normalized.std())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:36.720146Z","iopub.execute_input":"2025-06-14T12:14:36.720403Z","iopub.status.idle":"2025-06-14T12:14:37.655170Z","shell.execute_reply.started":"2025-06-14T12:14:36.720382Z","shell.execute_reply":"2025-06-14T12:14:37.654306Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=0)\n\nX_train = X_train[..., np.newaxis]\nX_val   = X_val[..., np.newaxis]\n\ny_train = y_train.squeeze()\ny_val = y_val.squeeze()\n\nprint(\"X_train shape:\", X_train.shape)\nprint(\"X_val shape:\", X_val.shape)\nprint(\"y_train shape:\", y_train.shape) \nprint(\"y_val shape:\", y_val.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:37.656033Z","iopub.execute_input":"2025-06-14T12:14:37.656374Z","iopub.status.idle":"2025-06-14T12:14:37.873315Z","shell.execute_reply.started":"2025-06-14T12:14:37.656354Z","shell.execute_reply":"2025-06-14T12:14:37.872388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import ConvLSTM2D, BatchNormalization, Conv2D, Flatten, Dense, Reshape, Input\nfrom tensorflow.keras.optimizers import Adam\n\ndef build_ConvLSTM2D():\n    model = Sequential([\n        Input(shape=(5, 1000, 70, 1)),\n\n        ConvLSTM2D(filters=32, kernel_size=(5, 5), padding=\"same\", return_sequences=False, activation='relu'),\n        BatchNormalization(),\n\n        Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'),\n        Flatten(),\n        Dense(128, activation='relu'),\n        Dense(70 * 70, activation='linear'),\n        Reshape((70, 70))\n    ])\n    return model\n\ndef mae(y_true, y_pred):\n    y_true_phys = y_true * scale_y + y_min\n    y_pred_phys = y_pred * scale_y + y_min\n    return tf.reduce_mean(tf.abs(y_true_phys - y_pred_phys))\n\nmodel=build_ConvLSTM2D()\noptimizer = Adam(learning_rate=1e-3)\nmodel.compile(optimizer=optimizer , loss='mae', metrics=[\"mae\"])\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:37.874212Z","iopub.execute_input":"2025-06-14T12:14:37.874538Z","iopub.status.idle":"2025-06-14T12:14:39.058197Z","shell.execute_reply.started":"2025-06-14T12:14:37.874511Z","shell.execute_reply":"2025-06-14T12:14:39.057629Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping\n\nearly_stop = EarlyStopping(\n    monitor='val_loss',\n    patience=5,             \n    restore_best_weights=True  \n)\n\nhistory = model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=100, batch_size=16,callbacks=[early_stop], verbose=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mae = model.evaluate(X_val, y_val)\nprint(f\"MAE sur le jeu de validation : {mae}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:14:51.273611Z","iopub.execute_input":"2025-06-14T12:14:51.274321Z","iopub.status.idle":"2025-06-14T12:15:07.260169Z","shell.execute_reply.started":"2025-06-14T12:14:51.274298Z","shell.execute_reply":"2025-06-14T12:15:07.259549Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#model.save_weights(\"/kaggle/working/models/W1_(350).weights.h5\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#model.save_weights(\"/kaggle/working/models/W2_(266).weights.h5\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save_weights(\"/kaggle/working/models/W3_(random).weights.h5\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T12:15:27.352445Z","iopub.execute_input":"2025-06-14T12:15:27.352735Z","iopub.status.idle":"2025-06-14T12:15:30.150397Z","shell.execute_reply.started":"2025-06-14T12:15:27.352719Z","shell.execute_reply":"2025-06-14T12:15:30.149651Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\n\nplt.plot(history.history['mae'], label='MAE (train)')\nplt.plot(history.history['val_mae'], label='MAE (val)')\nplt.xlabel('Epoch')\nplt.ylabel('Mean Absolute Error')\nplt.title('Évolution de la MAE pendant l’entraînement')\nplt.legend()\nplt.grid(True)\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"index = 12\n\npred = model.predict(X_val[:index])[0] * scale_y + y_min\ntrue = y_val[index] * scale_y + y_min\n\n# 4. Visualisation\nplt.figure(figsize=(10, 4))\nplt.subplot(1, 2, 1)\nplt.title(\"Vitesse prédite\")\nplt.imshow(pred, cmap='RdYlGn')\nplt.colorbar()\n\nplt.subplot(1, 2, 2)\nplt.title(\"Vitesse réelle\")\nplt.imshow(true, cmap='RdYlGn')\nplt.colorbar()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}