{"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"}],"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-datasets-01?scriptVersionId=244507304","metadata":{}},{"cell_type":"code","source":"!pip install ultralytics -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:29:51.165257Z","iopub.execute_input":"2025-06-14T16:29:51.165944Z","iopub.status.idle":"2025-06-14T16:31:05.510421Z","shell.execute_reply.started":"2025-06-14T16:29:51.165918Z","shell.execute_reply":"2025-06-14T16:31:05.509751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport random\nimport torch\n\nnp.random.seed(42)\nrandom.seed(42)\ntorch.manual_seed(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:31:05.512020Z","iopub.execute_input":"2025-06-14T16:31:05.512301Z","iopub.status.idle":"2025-06-14T16:31:08.689290Z","shell.execute_reply.started":"2025-06-14T16:31:05.512278Z","shell.execute_reply":"2025-06-14T16:31:08.688552Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"byu_yolo_dataset_path = '/kaggle/input/byu-yolo-datasets-01/BYU_YOLO_dataset'\nyolo_weights_path = '/kaggle/working/yolo_weights'\nyolo_pretrained_weights = 'yolov8n.pt'\n\ndataset_yaml_path = '/kaggle/input/byu-yolo-datasets-01/BYU_YOLO_dataset/dataset.yaml'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:31:08.690013Z","iopub.execute_input":"2025-06-14T16:31:08.690300Z","iopub.status.idle":"2025-06-14T16:31:08.694207Z","shell.execute_reply.started":"2025-06-14T16:31:08.690283Z","shell.execute_reply":"2025-06-14T16:31:08.693389Z"}},"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-14T16:31:08.695931Z","iopub.execute_input":"2025-06-14T16:31:08.696579Z","iopub.status.idle":"2025-06-14T16:31:08.708460Z","shell.execute_reply.started":"2025-06-14T16:31:08.696554Z","shell.execute_reply":"2025-06-14T16:31:08.707767Z"}},"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_path = byu_yolo_dataset_path + '/images/val'\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}\\nGround Truth (green) vs Prediction (red)\")\n    \n    plt.tight_layout()\n    \n    plt.savefig('/kaggle/working/predictions.png')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:31:08.709060Z","iopub.execute_input":"2025-06-14T16:31:08.709261Z","iopub.status.idle":"2025-06-14T16:31:08.718101Z","shell.execute_reply.started":"2025-06-14T16:31:08.709246Z","shell.execute_reply":"2025-06-14T16:31:08.717521Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndef plot_distribution_focal_loss(weights_path):\n    \n    results_csv = os.path.join(weights_path, 'results.csv')\n    results_df = pd.read_csv(results_csv)\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'], results_df[train_dfl_cols], label='TRAIN DISTRIBUTION FOCAL LOSS')\n    plt.plot(results_df['epoch'], results_df[val_dfl_cols], label='VALIDATION DISTRIBUTION FOCAL LOSS')\n    \n    plt.axvline(x=results_df.loc[best_epoch, 'epoch'], \n                color='deeppink', \n                label=f'Best Model (Epoch {int(results_df.loc[best_epoch, \"epoch\"])}, ' + \\\n                      f' 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    plot_path = weights_path + '/dfl_plot.png'\n    plt.savefig(plot_path)\n    \n    plt.savefig('/kaggle/working/dfl_plot.png')\n    \n    print(f\"Loss curve saved to {plot_path}\")\n    plt.close()\n\n    return best_epoch, best_val_loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:31:08.719057Z","iopub.execute_input":"2025-06-14T16:31:08.719277Z","iopub.status.idle":"2025-06-14T16:31:09.073734Z","shell.execute_reply.started":"2025-06-14T16:31:08.719252Z","shell.execute_reply":"2025-06-14T16:31:09.072989Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\nimport yaml\n\nEPOCHS = 30\nBATCH_SIZE = 16\nIMG_SIZE = 640\n# PATIENCE = 5\nPATIENCE = 0\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    weights_path = yolo_weights_path + '/flagellar_motor_detector'\n    \n    best_epoch_info = plot_distribution_focal_loss(weights_path)\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-14T16:31:09.074578Z","iopub.execute_input":"2025-06-14T16:31:09.074940Z","iopub.status.idle":"2025-06-14T16:31:09.512568Z","shell.execute_reply.started":"2025-06-14T16:31:09.074910Z","shell.execute_reply":"2025-06-14T16:31:09.511959Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def upload_dataset(yaml_path):\n    \n    with open(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    upload_yaml_path = \"/kaggle/working/upload_dataset.yaml\"\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-14T16:31:09.513162Z","iopub.execute_input":"2025-06-14T16:31:09.513365Z","iopub.status.idle":"2025-06-14T16:31:09.517787Z","shell.execute_reply.started":"2025-06-14T16:31:09.513348Z","shell.execute_reply":"2025-06-14T16:31:09.516851Z"}},"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-14T16:31:09.518629Z","iopub.execute_input":"2025-06-14T16:31:09.518865Z","iopub.status.idle":"2025-06-14T16:56:21.220897Z","shell.execute_reply.started":"2025-06-14T16:31:09.518838Z","shell.execute_reply":"2025-06-14T16:56:21.220015Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}