{"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":45867,"databundleVersionId":6924515,"sourceType":"competition"}],"dockerImageVersionId":30616,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\n\nimport pandas as pd\nimport numpy as np\n\nimport seaborn as sns\nimport pickle\n\nimport matplotlib.pyplot as plt\n\n\nfrom keras.utils import set_random_seed\n\nimport tensorflow as tf\nimport keras_core as keras\nimport datetime","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","ExecuteTime":{"end_time":"2023-12-13T10:37:29.450638900Z","start_time":"2023-12-13T10:37:27.062625200Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.230907Z","iopub.execute_input":"2023-12-13T11:06:22.231928Z","iopub.status.idle":"2023-12-13T11:06:22.236889Z","shell.execute_reply.started":"2023-12-13T11:06:22.231885Z","shell.execute_reply":"2023-12-13T11:06:22.236056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reproducibility","metadata":{}},{"cell_type":"markdown","source":"# configuration","metadata":{}},{"cell_type":"code","source":"def set_reproducibility(seed=42):\n    np.random.seed(seed)\n    set_random_seed(seed)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:37:31.166307300Z","start_time":"2023-12-13T10:37:31.163307700Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.238902Z","iopub.execute_input":"2023-12-13T11:06:22.239204Z","iopub.status.idle":"2023-12-13T11:06:22.248466Z","shell.execute_reply.started":"2023-12-13T11:06:22.23918Z","shell.execute_reply":"2023-12-13T11:06:22.247576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"    \nSEED = 42\n    \nds_src = \"/kaggle/input/UBC-OCEAN/\"\ndst_path = \"\"\n    \n# Training\ntrain_csv_path =        f\"{ds_src}train.csv\"\ntrain_thumbnail_paths = f\"{ds_src}train_thumbnails\"\ntrain_dir =             f\"{ds_src}train_images\"\nbatch_size = 8\nepochs = 100\n    \n# Test\ntest_csv_path =        f\"{ds_src}test.csv\"\ntest_thumbnail_paths = f\"{ds_src}test_thumbnails\"\ntest_dir =             f\"{ds_src}test_images\"\n    \n# Experiment\nexperiment_name = \"experiment_1\"\nexp_id = \"id1\"\nactivation_function = keras.activations.softmax\nloss_func = keras.losses.categorical_crossentropy\nmomentum = 0.9\nlr = 0.001\nimage_size = 256\n\ndate_str = datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\nlog_dir = f\"./logdir/{date_str}{experiment_name}_{str(exp_id)}\"\n\n# dictionnary \nid_to_name_dst = f\"{dst_path}id_to_name.pkl\"\n# model\nmodel_name = \"thumbnail-weighted_basic\"\nmodel_path = f\"{dst_path}{model_name}.weights.h5\"\n","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:37:31.417599500Z","start_time":"2023-12-13T10:37:31.370805300Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.250095Z","iopub.execute_input":"2023-12-13T11:06:22.250376Z","iopub.status.idle":"2023-12-13T11:06:22.259874Z","shell.execute_reply.started":"2023-12-13T11:06:22.250352Z","shell.execute_reply":"2023-12-13T11:06:22.259049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nset_reproducibility(SEED)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:37:32.764667200Z","start_time":"2023-12-13T10:37:32.754588300Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.260992Z","iopub.execute_input":"2023-12-13T11:06:22.261279Z","iopub.status.idle":"2023-12-13T11:06:22.26942Z","shell.execute_reply.started":"2023-12-13T11:06:22.261255Z","shell.execute_reply":"2023-12-13T11:06:22.268558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# loading train data","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(train_csv_path)\ntrain.head()","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:37:33.732610900Z","start_time":"2023-12-13T10:37:33.718100200Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.270542Z","iopub.execute_input":"2023-12-13T11:06:22.270852Z","iopub.status.idle":"2023-12-13T11:06:22.287243Z","shell.execute_reply.started":"2023-12-13T11:06:22.270822Z","shell.execute_reply":"2023-12-13T11:06:22.286348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# dataset pre processing\n","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(train_csv_path)\n\n# Create the thumbnail df where is_tma == False\ndf = df[df[\"is_tma\"] == False]\n\n# Get basic statistics about the dataset\nnum_rows = df.shape[0]\nnum_unique_images = df['image_id'].nunique()\nnum_unique_labels = df['label'].nunique()\nunique_labels = df['label'].unique()\n\nprint(f\"{num_rows=}\")\nprint(f\"{num_unique_images=}\")\nprint(f\"{num_unique_labels=}\")\nprint(f\"{unique_labels=}\")\n\n# Plot the distribution of the target classes\nplt.figure(figsize=(10, 6))\nsns.countplot(data=df, x='label', order=df['label'].value_counts().index)\nplt.title('Distribution of Target Classes')\nplt.xlabel('Label')\nplt.ylabel('Count')\nplt.show()","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:38:47.488892900Z","start_time":"2023-12-13T10:38:47.371918400Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.289459Z","iopub.execute_input":"2023-12-13T11:06:22.290147Z","iopub.status.idle":"2023-12-13T11:06:22.550455Z","shell.execute_reply.started":"2023-12-13T11:06:22.290121Z","shell.execute_reply":"2023-12-13T11:06:22.549528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# encoder (for training only)","metadata":{}},{"cell_type":"markdown","source":" ### Perform one-hot encoding of the 'label' column and explicitly convert to integer type","metadata":{}},{"cell_type":"code","source":"df_one_hot = pd.get_dummies(df[\"label\"], prefix=\"label\").astype(int)\ndf_one_hot.head()","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.620485100Z","start_time":"2023-12-13T10:22:04.463047100Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.551754Z","iopub.execute_input":"2023-12-13T11:06:22.552138Z","iopub.status.idle":"2023-12-13T11:06:22.564131Z","shell.execute_reply.started":"2023-12-13T11:06:22.552103Z","shell.execute_reply":"2023-12-13T11:06:22.563195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Concatenate the original DataFrame with the one-hot encoded labels\n","metadata":{}},{"cell_type":"code","source":"train_df = pd.concat([df[\"image_id\"], df_one_hot], axis=1)\ntrain_df.head()    ","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.621995300Z","start_time":"2023-12-13T10:22:04.467046Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.565368Z","iopub.execute_input":"2023-12-13T11:06:22.565626Z","iopub.status.idle":"2023-12-13T11:06:22.581774Z","shell.execute_reply.started":"2023-12-13T11:06:22.565604Z","shell.execute_reply":"2023-12-13T11:06:22.580884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Get the thumbnail image paths","metadata":{}},{"cell_type":"code","source":"train_df[\"image_thumbnail_path\"] = train_df[\"image_id\"].apply(lambda x: f\"{train_thumbnail_paths}/{x}_thumbnail.png\")\ntrain_df.head()","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.623005900Z","start_time":"2023-12-13T10:22:04.476046300Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.58459Z","iopub.execute_input":"2023-12-13T11:06:22.584943Z","iopub.status.idle":"2023-12-13T11:06:22.599139Z","shell.execute_reply.started":"2023-12-13T11:06:22.584897Z","shell.execute_reply":"2023-12-13T11:06:22.598215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### make a list with all png thumbnail path","metadata":{}},{"cell_type":"code","source":"image_thumbnail_paths = train_df[\"image_thumbnail_path\"].values\nprint(image_thumbnail_paths[:5])","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.623005900Z","start_time":"2023-12-13T10:22:04.487073600Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.600499Z","iopub.execute_input":"2023-12-13T11:06:22.600802Z","iopub.status.idle":"2023-12-13T11:06:22.608076Z","shell.execute_reply.started":"2023-12-13T11:06:22.600772Z","shell.execute_reply":"2023-12-13T11:06:22.607101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = train_df[[col for col in train_df.columns if col.startswith(\"label_\")]].values\nprint(labels[:5])","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.624007400Z","start_time":"2023-12-13T10:22:04.492074500Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.609382Z","iopub.execute_input":"2023-12-13T11:06:22.609735Z","iopub.status.idle":"2023-12-13T11:06:22.61862Z","shell.execute_reply.started":"2023-12-13T11:06:22.609704Z","shell.execute_reply":"2023-12-13T11:06:22.617643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_names = [col for col in train_df.columns if col.startswith(\"label_\")]\nprint(label_names)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.624007400Z","start_time":"2023-12-13T10:22:04.502966900Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.619913Z","iopub.execute_input":"2023-12-13T11:06:22.62024Z","iopub.status.idle":"2023-12-13T11:06:22.630016Z","shell.execute_reply.started":"2023-12-13T11:06:22.620216Z","shell.execute_reply":"2023-12-13T11:06:22.628979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"name_to_id = {key.replace(\"label_\", \"\"):value for value,key in enumerate(label_names)}\nprint(name_to_id)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.624007400Z","start_time":"2023-12-13T10:22:04.505966100Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.63125Z","iopub.execute_input":"2023-12-13T11:06:22.631649Z","iopub.status.idle":"2023-12-13T11:06:22.639251Z","shell.execute_reply.started":"2023-12-13T11:06:22.631616Z","shell.execute_reply":"2023-12-13T11:06:22.638345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id_to_name = {key:value for value, key in name_to_id.items()}\nprint(id_to_name)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.624007400Z","start_time":"2023-12-13T10:22:04.516968800Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.640455Z","iopub.execute_input":"2023-12-13T11:06:22.64084Z","iopub.status.idle":"2023-12-13T11:06:22.648499Z","shell.execute_reply.started":"2023-12-13T11:06:22.640809Z","shell.execute_reply":"2023-12-13T11:06:22.647553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"     # Save to dictionary to disk\nwith open(id_to_name_dst, \"wb\") as f:\n    pickle.dump(id_to_name, f)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.637519400Z","start_time":"2023-12-13T10:22:04.528329600Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.649898Z","iopub.execute_input":"2023-12-13T11:06:22.65025Z","iopub.status.idle":"2023-12-13T11:06:22.658264Z","shell.execute_reply.started":"2023-12-13T11:06:22.650201Z","shell.execute_reply":"2023-12-13T11:06:22.657264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Création des poids d'apprentissage","metadata":{}},{"cell_type":"code","source":"class_weights = np.sum(labels) - np.sum(labels, axis=0)\nclass_weights = class_weights / np.sum(class_weights) # Normalize the weights\n\nclass_weights = {idx:weight for idx, weight in enumerate(class_weights)}\n\nfor idx, weight in class_weights.items():\n    print(f\"{id_to_name[idx]}: {weight:0.2f}\")","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2023-12-13T10:22:04.638519Z","start_time":"2023-12-13T10:22:04.531837400Z"},"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.659494Z","iopub.execute_input":"2023-12-13T11:06:22.659856Z","iopub.status.idle":"2023-12-13T11:06:22.669369Z","shell.execute_reply.started":"2023-12-13T11:06:22.659826Z","shell.execute_reply":"2023-12-13T11:06:22.668276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"    # dataset pipeline","metadata":{}},{"cell_type":"code","source":"def read_image(path):\n    file = tf.io.read_file(path)\n    image = tf.io.decode_png(file, 3)\n    image = tf.image.resize(image, (256, 256))\n    image = tf.image.per_image_standardization(image)\n    return image","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.641036800Z","start_time":"2023-12-13T10:22:04.540916500Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.673762Z","iopub.execute_input":"2023-12-13T11:06:22.67406Z","iopub.status.idle":"2023-12-13T11:06:22.680031Z","shell.execute_reply.started":"2023-12-13T11:06:22.674035Z","shell.execute_reply":"2023-12-13T11:06:22.678873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = (\n    tf.data.Dataset.from_tensor_slices(image_thumbnail_paths)\n    .map(read_image, num_parallel_calls=tf.data.AUTOTUNE)\n)\ny = tf.data.Dataset.from_tensor_slices(labels)\n\n# Zip the x and y together\nds = tf.data.Dataset.zip((x, y))\n\n# Create the training and validation splits\nval_ds = (\n    ds\n    .take(50)\n    .batch(batch_size)\n    .prefetch(tf.data.AUTOTUNE)\n)\ntrain_ds = (\n    ds\n    .skip(50)\n    .shuffle(batch_size * 10)\n    .batch(batch_size)\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.680057500Z","start_time":"2023-12-13T10:22:04.542916700Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:22.681328Z","iopub.execute_input":"2023-12-13T11:06:22.681632Z","iopub.status.idle":"2023-12-13T11:06:25.651333Z","shell.execute_reply.started":"2023-12-13T11:06:22.681603Z","shell.execute_reply":"2023-12-13T11:06:25.650365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_ds.enumerate)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.715083400Z","start_time":"2023-12-13T10:22:04.601048Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:25.652571Z","iopub.execute_input":"2023-12-13T11:06:25.652888Z","iopub.status.idle":"2023-12-13T11:06:25.657794Z","shell.execute_reply.started":"2023-12-13T11:06:25.652856Z","shell.execute_reply":"2023-12-13T11:06:25.656869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# build the model","metadata":{}},{"cell_type":"code","source":"lr = 0.0001\n\nmodel = keras.models.Sequential([\n    keras.layers.Conv2D(32, (3, 3), activation=keras.activations.relu, input_shape=(256, 256, 3), padding='same'),\n    keras.layers.Conv2D(32, (3, 3), activation=keras.activations.relu, input_shape=(32, 32, 3), padding='same'),\n    keras.layers.MaxPooling2D((2, 2)),\n\n\n    keras.layers.Conv2D(64, (3, 3), activation=keras.activations.relu, input_shape=(32, 32, 3), padding='same'),\n    keras.layers.Conv2D(64, (3, 3), activation=keras.activations.relu, input_shape=(32, 32, 3), padding='same'),\n    keras.layers.MaxPooling2D((2, 2)),\n\n    keras.layers.Conv2D(128, (3, 3), activation=keras.activations.relu, input_shape=(32, 32, 3), padding='same'),\n    keras.layers.Conv2D(128, (3, 3), activation=keras.activations.relu, input_shape=(32, 32, 3), padding='same'),\n    keras.layers.MaxPooling2D((2, 2)),\n\n    keras.layers.Flatten(),\n    keras.layers.Dense(5, activation=keras.activations.softmax),\n])\nmodel.compile(\n    loss=loss_func,\n    optimizer=keras.optimizers.Adam(learning_rate=lr),\n    metrics=['accuracy']\n)\n","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.975737700Z","start_time":"2023-12-13T10:22:04.615486700Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:25.659003Z","iopub.execute_input":"2023-12-13T11:06:25.659278Z","iopub.status.idle":"2023-12-13T11:06:25.779193Z","shell.execute_reply.started":"2023-12-13T11:06:25.659254Z","shell.execute_reply":"2023-12-13T11:06:25.778193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# training\n","metadata":{}},{"cell_type":"markdown","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-11T11:49:05.61252Z","iopub.execute_input":"2023-12-11T11:49:05.613373Z","iopub.status.idle":"2023-12-11T11:49:05.64239Z","shell.execute_reply.started":"2023-12-11T11:49:05.613325Z","shell.execute_reply":"2023-12-11T11:49:05.641292Z"}}},{"cell_type":"code","source":"model.summary()","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:04.990417100Z","start_time":"2023-12-13T10:22:04.673551700Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:25.780553Z","iopub.execute_input":"2023-12-13T11:06:25.781228Z","iopub.status.idle":"2023-12-13T11:06:25.809734Z","shell.execute_reply.started":"2023-12-13T11:06:25.781192Z","shell.execute_reply":"2023-12-13T11:06:25.808887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Inspecter train_ds\nfor images, labels in train_ds.take(1):  # Prend le premier batch pour l'inspection\n    print(\"Taille du batch dans train_ds:\")\n    print(\"  - Images:\", images.shape)  # Taille des images dans le batch\n    print(\"  - Labels:\", labels.shape)  # Taille des labels dans le batch\n\n# Inspecter val_ds\nfor images, labels in val_ds.take(1):  # Prend le premier batch pour l'inspection\n    print(\"Taille du batch dans val_ds:\")\n    print(\"  - Images:\", images.shape)  # Taille des images dans le batch\n    print(\"  - Labels:\", labels.shape)  # Taille des labels dans le batch","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:22:07.541868300Z","start_time":"2023-12-13T10:22:04.692066900Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:25.810719Z","iopub.execute_input":"2023-12-13T11:06:25.810994Z","iopub.status.idle":"2023-12-13T11:06:35.535853Z","shell.execute_reply.started":"2023-12-13T11:06:25.81097Z","shell.execute_reply":"2023-12-13T11:06:35.534942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### callbacks","metadata":{}},{"cell_type":"code","source":"early_stopping = keras.callbacks.EarlyStopping(\n    patience=10,\n    min_delta=0.001,\n    restore_best_weights=True,\n)\n","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2023-12-13T10:22:07.542870300Z","start_time":"2023-12-13T10:22:07.539869400Z"},"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-12-13T11:06:35.537154Z","iopub.execute_input":"2023-12-13T11:06:35.537468Z","iopub.status.idle":"2023-12-13T11:06:35.541987Z","shell.execute_reply.started":"2023-12-13T11:06:35.537441Z","shell.execute_reply":"2023-12-13T11:06:35.541005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(\n    train_ds,\n    epochs=epochs,\n    validation_data=val_ds,\n    callbacks=[\n        early_stopping,\n        keras.callbacks.TensorBoard(log_dir)\n    ],\n    class_weight= class_weights\n)\n\nmodel.save_weights(model_path)","metadata":{"ExecuteTime":{"end_time":"2023-12-13T10:23:52.656304600Z","start_time":"2023-12-13T10:22:07.544868200Z"},"execution":{"iopub.status.busy":"2023-12-13T11:06:35.543392Z","iopub.execute_input":"2023-12-13T11:06:35.543732Z","iopub.status.idle":"2023-12-13T11:12:30.455784Z","shell.execute_reply.started":"2023-12-13T11:06:35.5437Z","shell.execute_reply":"2023-12-13T11:12:30.454973Z"},"trusted":true},"execution_count":null,"outputs":[]}]}