{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":91249,"databundleVersionId":11294684,"sourceType":"competition"},{"sourceId":244553093,"sourceType":"kernelVersion"},{"sourceId":245461949,"sourceType":"kernelVersion"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"https://www.kaggle.com/code/mirenaborisova/byu-yolo-train-04","metadata":{}},{"cell_type":"code","source":"!pip install ultralytics -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:02:00.134877Z","iopub.execute_input":"2025-06-24T07:02:00.135140Z","iopub.status.idle":"2025-06-24T07:03:34.383480Z","shell.execute_reply.started":"2025-06-24T07:02:00.135119Z","shell.execute_reply":"2025-06-24T07:03:34.382603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport random\n\nSEED = 42\nnp.random.seed(SEED)\nrandom.seed(SEED)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.384854Z","iopub.execute_input":"2025-06-24T07:03:34.385085Z","iopub.status.idle":"2025-06-24T07:03:34.389412Z","shell.execute_reply.started":"2025-06-24T07:03:34.385061Z","shell.execute_reply":"2025-06-24T07:03:34.388882Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"byu_yolo_dataset_path = '/kaggle/input/byu-yolo-datasets-01/BYU_YOLO_dataset'\nvalidation_path = byu_yolo_dataset_path + '/images/val'\n\nyolo_weights_path = '/kaggle/working/yolo_weights'\n# yolo_pretrained_weights = 'yolov8n.pt'\nyolo_pretrained_weights = \\\n    '/kaggle/input/byu-yolo-train-01/yolo_weights/flagellar_motor_detector/weights/best.pt'\n\ndataset_yaml_path = '/kaggle/input/byu-yolo-datasets-01/BYU_YOLO_dataset/dataset.yaml'\nupload_yaml_path = '/kaggle/working/upload_dataset.yaml'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.390017Z","iopub.execute_input":"2025-06-24T07:03:34.390239Z","iopub.status.idle":"2025-06-24T07:03:34.408260Z","shell.execute_reply.started":"2025-06-24T07:03:34.390223Z","shell.execute_reply":"2025-06-24T07:03:34.407762Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nos.makedirs(yolo_weights_path, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.410127Z","iopub.execute_input":"2025-06-24T07:03:34.410484Z","iopub.status.idle":"2025-06-24T07:03:34.427550Z","shell.execute_reply.started":"2025-06-24T07:03:34.410468Z","shell.execute_reply":"2025-06-24T07:03:34.426929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"weights_path = yolo_weights_path + '/flagellar_motor_detector'\nresults_csv_path = os.path.join(weights_path, 'results.csv')\ndfl_plot_path = weights_path + '/dfl_plot_02.png'\npredictions_plot_path = '/kaggle/working/predictions_02.png'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.428148Z","iopub.execute_input":"2025-06-24T07:03:34.428297Z","iopub.status.idle":"2025-06-24T07:03:34.444207Z","shell.execute_reply.started":"2025-06-24T07:03:34.428285Z","shell.execute_reply":"2025-06-24T07:03:34.443518Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Rectangle\n\nNUM_IMAGES = 4\nBOX_SIZE = 24\ndef generalization(model):\n    \n    validation_images = os.listdir(validation_path)\n    \n    img_files = random.sample(validation_images, NUM_IMAGES)\n    \n    fig, axes = plt.subplots(2, 2, figsize=(12, 12))\n    axes = axes.flatten()\n    \n    for i, img_file in enumerate(img_files):\n            \n        img_path = os.path.join(validation_path, img_file)\n        \n        results = model.predict(img_path, conf=0.25)[0]\n        \n        img = Image.open(img_path)\n        axes[i].imshow(np.array(img), cmap='gray')\n        \n        try:\n            img_file_split = img_file.split('_')\n            y_startswith = [y for y in img_file_split if y.startswith('y')]\n            x_startswith = [x for x in img_file_split if x.startswith('x')]\n            \n            if y_startswith and x_startswith:\n                y_coordinate = int(y_startswith[0][1:])\n                x_coordinate = int(x_startswith[0][1:].split('.')[0])\n                \n                rectangle = Rectangle((x_coordinate - BOX_SIZE // 2,\n                                       y_coordinate - BOX_SIZE // 2), \n                                      BOX_SIZE, \n                                      BOX_SIZE, \n                                      linewidth=1, \n                                      edgecolor='lime', \n                                      facecolor='none')\n                axes[i].add_patch(rectangle)\n        except:\n            pass\n        \n        if len(results.boxes) > 0:\n            boxes = results.boxes.xyxy.cpu().numpy()\n            confs = results.boxes.conf.cpu().numpy()\n            \n            for box, conf in zip(boxes, confs):\n                x_start, y_start, x_end, y_end = box\n                rectangle_pred = Rectangle((x_start, y_start), \n                                           x_end - x_start, \n                                           y_end-y_start, \n                                           linewidth=1,\n                                           edgecolor='deeppink',\n                                           facecolor='none')\n                axes[i].add_patch(rectangle_pred)\n                axes[i].text(x_start, y_start-5, f'{conf:.2f}', color='cyan')\n        \n        axes[i].set_title(f\"IMAGE: {img_file}\\nACTUAL (lime) vs PREDICTION (deeppink)\")\n    \n    plt.tight_layout()\n    \n    plt.savefig(predictions_plot_path)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.444933Z","iopub.execute_input":"2025-06-24T07:03:34.445474Z","iopub.status.idle":"2025-06-24T07:03:34.462570Z","shell.execute_reply.started":"2025-06-24T07:03:34.445456Z","shell.execute_reply":"2025-06-24T07:03:34.461895Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndef plot_distribution_focal_loss():\n    \n    results_df = pd.read_csv(results_csv_path)\n    \n    train_dfl_cols = [col for col in results_df.columns if 'train/dfl_loss' in col]\n    val_dfl_cols = [col for col in results_df.columns if 'val/dfl_loss' in col]\n    \n    train_dfl_cols = train_dfl_cols[0]\n    val_dfl_cols = val_dfl_cols[0]\n\n    best_epoch = results_df[val_dfl_cols].idxmin()\n    best_val_loss = results_df.loc[best_epoch, val_dfl_cols]\n    \n    plt.figure(figsize=(10, 6))\n    \n    plt.plot(results_df['epoch'], \n             results_df[train_dfl_cols], \n             label='TRAIN DISTRIBUTION FOCAL LOSS')\n    plt.plot(results_df['epoch'], \n             results_df[val_dfl_cols],\n             label='VALIDATION DISTRIBUTION FOCAL LOSS')\n    \n    plt.axvline(x=results_df.loc[best_epoch, 'epoch'], \n                color='deeppink', \n                label=f'BEST MODEL (BEST_EPOCH {int(results_df.loc[best_epoch, \"epoch\"])}, ' + \\\n                      f' BEST_VAL_LOSS: {best_val_loss:.4f})')\n    \n    plt.xlabel('EPOCH')\n    plt.ylabel('DISTRIBUTION FOCAL LOSS')\n    plt.title('TRAIN & VALIDATION DISTRIBUTION FOCAL LOSS')\n    plt.legend()\n    plt.grid(True, linestyle='--', alpha=0.7)\n    \n    plt.savefig(dfl_plot_path)\n    \n    plt.close()\n\n    return best_epoch, best_val_loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.463290Z","iopub.execute_input":"2025-06-24T07:03:34.463490Z","iopub.status.idle":"2025-06-24T07:03:34.785651Z","shell.execute_reply.started":"2025-06-24T07:03:34.463475Z","shell.execute_reply":"2025-06-24T07:03:34.785078Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\nimport yaml\n\nEPOCHS = 30\n# EPOCHS = 36\n# EPOCHS = 24\n\nBATCH_SIZE = 16\n# BATCH_SIZE = 32\n# BATCH_SIZE = 8\n# BATCH_SIZE = 64\n# BATCH_SIZE = 24\n\n# IMG_SIZE = 640\n# IMG_SIZE = 320\nIMG_SIZE = 1280\n# IMG_SIZE = 2560 crashed\n\n# PATIENCE = 5\nPATIENCE = 0\n\nSAVE_PERIOD = 5\nVAL = True\nVERBOSE = True\n\ndef train_yolo_model(yaml_path):\n\n    model = YOLO(yolo_pretrained_weights)\n    \n    results = model.train(data=yaml_path,\n                          epochs=EPOCHS,\n                          batch=BATCH_SIZE,\n                          imgsz=IMG_SIZE,\n                          project=yolo_weights_path,\n                          name='flagellar_motor_detector',\n                          exist_ok=True,\n                          patience=PATIENCE,\n                          save_period=SAVE_PERIOD,\n                          val=VAL,\n                          verbose=VERBOSE)\n    \n    best_epoch_info = plot_distribution_focal_loss()\n    \n    if best_epoch_info:\n        best_epoch, best_val_loss = best_epoch_info\n        print(f\"\\nBEST EPOCH: {best_epoch} , BEST_VAL_LOSS: {best_val_loss:.4f}\")\n    \n    return model, results","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:34.786446Z","iopub.execute_input":"2025-06-24T07:03:34.786748Z","iopub.status.idle":"2025-06-24T07:03:40.669069Z","shell.execute_reply.started":"2025-06-24T07:03:34.786729Z","shell.execute_reply":"2025-06-24T07:03:40.668336Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def upload_dataset(dataset_yaml_path):\n    \n    with open(dataset_yaml_path, 'r') as f:\n        yaml_data = yaml.safe_load(f)\n        \n    if 'path' in yaml_data:\n        yaml_data['path'] = byu_yolo_dataset_path\n    \n    with open(upload_yaml_path, 'w') as f:\n        yaml.dump(yaml_data, f)\n    \n    return upload_yaml_path","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:40.669919Z","iopub.execute_input":"2025-06-24T07:03:40.670315Z","iopub.status.idle":"2025-06-24T07:03:40.674541Z","shell.execute_reply.started":"2025-06-24T07:03:40.670286Z","shell.execute_reply":"2025-06-24T07:03:40.673941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"yaml_path = upload_dataset(dataset_yaml_path)\n\nwith open(yaml_path, 'r') as f:\n    yaml_content = f.read()\n    \nmodel, results = train_yolo_model(yaml_path)\n\ngeneralization(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T07:03:40.676373Z","iopub.execute_input":"2025-06-24T07:03:40.676624Z","iopub.status.idle":"2025-06-24T08:12:54.363531Z","shell.execute_reply.started":"2025-06-24T07:03:40.676602Z","shell.execute_reply":"2025-06-24T08:12:54.362503Z"}},"outputs":[],"execution_count":null},{"cell_type":"raw","source":"","metadata":{}}]}