{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Εφαρμογή τεχνικών Μηχανικής Μάθησης για τον εντοπισμό περιοχών ενδιαφέροντος**","metadata":{}},{"cell_type":"markdown","source":"# ML, Computer Vision και Object Detection\n\nΗ **όραση υπολογιστών** είναι ο επιστημονικός κλάδος που έχει ως στόχο τη δημιουργία συστημάτων που ”βλέπουν”, αντιλαμβάνονται δηλαδή μέσω της εικόνας τον κόσμο και εξάγουν συμπεράσματα. Σχεδόν το σύνολο των σύγχρονων μεθόδων που χρησιμοποιούνται στα πλαίσια της όρασης υπολογιστών εντάσσονται στον τομέα της **Μηχανικής Μάθησης**, προσανατολίζονται δηλαδή στην επίλυση του κάθε προβλήματος όχι μέσω ρητού προγραμματισμού, αλλά μέσω της εκπαίδευσης πάνω σε διαθέσιμα δεδομένα και της εξαγωγής πληροφορίας από αυτά.\n\nΒασικές κατηγορίες προβλημάτων με τα οποία ασχολείται η μηχανική όραση:\n- **Ταξινόμηση Εικόνων (Image Classification)**: δέχεται ως είσοδο μία εικόνα και προβλέπει τι απεικονίζεται (αφορά την εικόνα ως σύνολο, όχι ανά pixel).\n- **Ανίχνευση Αντικειμένου (Object Detection)**: δέχεται ως είσοδο μία εικόνα και εντοπίζει τη θέση των διαφόρων αντικειμένων σε αυτήν, καθώς και την κλάση τους (αφορά την εικόνα ως σύνολο, όχι ανά pixel).\n- **Σημασιολογική Κατάτμηση Εικόνας (Semantic Segmentation)**: δέχεται ως είσοδο μία εικόνα και προβλέπει την κλάση κάθε pixel.\n- **Κατάτμηση Στιγμιοτύπων Εικόνας (Instance Segmentation)**: συνδυασμός της ανίχνευσης αντικειμένου με την σημασιολογική κατάτμηση. Δέχεται ως είσοδο μία εικόνα και εντοπίζει τα διάφορα αντικείμενα που υπάρχουν σε αυτή (και την κλάση τους) σε επίπεδο pixel.","metadata":{}},{"cell_type":"markdown","source":"# Ζητούμενο\n\nΤα δεδομένα που θα χρησιμοποιηθούν σε αυτή την άσκηση προέρχονται από ένα Dataset της Airbus, το οποίο έγινε πρώτη φορά διαθέσιμο στο Kaggle στα πλαίσια του [Airbus Ship Detection Challenge](https://www.kaggle.com/competitions/airbus-ship-detection/overview).\n\nΖητούμενο είναι η ανάπτυξη ενός Συνελικτικού Νευρωνικού Δικτύου ικανού να εντοπίσει με όσο το δυνατόν μεγαλύτερη ακρίβεια τα σημεία μίας δορυφορικής εικόνας που αντιστοιχούν σε πλοία, σε επίπεδο εικονοστοιχείου, επιστρέφοντας τόσο το σημείο στην εικόνα όσο και μία μάσκα με το ακριβές σχήμα του πλοίου.\n<div style=\"width:100%;text-align: center;\"> <img align=middle src=\"https://github.com/samlin001/Mask_RCNN/raw/master/assets/ship_mask_example.png\" alt=\"Heat beating\" style=\"height:300px;margin-top:3rem;\"> </div>\n\nΠροκειται για ένα πραγματικό πρόβλημα, χαρακτηριστικό παράδειγμα Κατάτμισης Στιγμιοτύπων, που συνοψίζει βασικές έννοιες της Μηχανικής Μάθησης και της Όρασης Υπολογιστών και μπορεί να χρησιμοποιηθεί ως ξεκίνημα για πιο περίπλοκα μοντέλα.","metadata":{}},{"cell_type":"markdown","source":"# Επιλογή Νευρωνικού Δικτύου\n\n## (Βαθιά) Συνελικτικά Νευρωνικά Δίκτυα (CNN)\n\n![](https://miro.medium.com/max/720/1*kkyW7BR5FZJq4_oBTx3OPQ.webp)\n\nΧρησιμοποιούνται για **εξαγωγή χαρακτηριστικών** μέσω της εφαρμογής συνελικτικών φίλτρων που διατρέχουν την εικόνα και έτσι εκμεταλλεύονται τις χωρικές συσχετίσεις μεταξύ εικονοστοιχείων. Τα βάρη των διαδοχικών συνελικτικών layers εκπαιδεύονται ώστε να αναγνωρίζουν μοτίβα, σε πρώτο επίπεδο βασικά όπως γραμμές/όρια αντικειμένων, στη συνέχεια βασικών σχημάτων και τέλος χαρακτηριστικών υψηλού επιπέδου. Τα χαρακτηριστικά αυτά είναι εξαιρετικά χρήσιμα για το πρόβλημα της **ταξινόμησης εικόνων**.\n\n## Συνελικτικά Δίκτυα Εντοπισμού Αντικειμένων\n\nΓια το πιο περίπλοκο πρόβλημα του **εντοπισμού αντικειμένων σε εικόνες** χρειάζεται προσαρμογή της παραπάνω ιδέας. Υπάρχουν πολλές διαφορετικές προσεγγίσεις, με επικρατέστερες τo Yolo και τις διάφορες παραλλαγές του R-CNN (ενδεικτικά [R-CNN, Fast R-CNN, Faster R-CNN, YOLO — Object Detection Algorithms](https://towardsdatascience.com/r-cnn-fast-r-cnn-faster-r-cnn-yolo-object-detection-algorithms-36d53571365e)).\n\n### You Only Look Once (YOLO)\nΤο [YOLO](https://pjreddie.com/darknet/yolo/) χωρίζει την εικόνα σε ένα grid υπο-εικόνων και πραγματοποιεί classification τμηματικά. Έχει έτσι σημαντικά μειωμένους χρόνους ανίχνευσης, αλλά δεν έχει επαρκή απόδοση σε αντικείμενα με μεγάλη διαφορά μεγέθους, ή πολύ μικρά αντικείμενα σε σχέση με τη συνολική εικόνα.\n\n![](https://github.com/samlin001/Mask_RCNN/raw/master/assets/YOLO_model_arXiv_1506.02640.png)\n\n### R-CNN\n\nΤο [R-CNN]() και οι μεταγενέστερες βελτιωμένες εκδοχές του [Fast R-CNN]() και [Faster R-CNN]() χρησιμοποιούν έναν αλγόριθμο πρότασης υποψήφιων περιοχών, η κάθε μία από τις οποίες γίνεται είσοδος σε ένα CNN για εξαγωγή χαρακτηριστικών. Με βάση αυτό το διάνυσμα χαρακτηριστικών αποφασίζεται η ύπαρξη ή όχι αντικειμένου στη συγκεκριμένη περιοχή\n\n![](https://media.geeksforgeeks.org/wp-content/uploads/20200219125702/faster-RCNN.png)\n\n## Συνελικτικά Δίκτυα Κατάτμισης Στιγμιοτύπων\n\n### Mask R-CNN\n\nΤο [Mask R-CNN](https://github.com/facebookresearch/Detectron) επιλέχθηκε για το συγκεκριμένο πρόβλημα ως η επικρατέστερηη αρχιτεκτονική κατάτμισης στιγμιοτύπων. Αποτελεί ουσιαστικά μία επέκταση του Faster R-CNN, με προσθήκη ενός τελικού συνελικτικού δικτύου FCN που υπολογίζει το ακριβές σχήμα (μάσκα) του κάθε αντικειμένου.\n![](https://github.com/samlin001/Mask_RCNN/raw/master/assets/Mask_R_CNN_Head_Architecture_%20arXiv1703.06870.png)","metadata":{}},{"cell_type":"markdown","source":"# Αρχικά Βήματα\n## Βιβλιοθήκες\n\nΑρχικά εισάγουμε τις απαραίτητες Python βιβλιοθήκες, οι οποίες είναι ήδη διαθέσιμες στο Kaggle.\n\nΕάν είναι απαραίτητη κάποια βιβλιοθήκη που δεν είναι ήδη διαθέσιμη, υπάρχει η δυνατότητα να εγκατασταθεί κανονικά.","metadata":{}},{"cell_type":"code","source":"import numpy as np              # linear algebra\nimport pandas as pd             # data processing\nimport matplotlib.pyplot as plt # plot & image processing\nfrom skimage.io import imread\n\nimport os\nimport time\nimport sys\nimport random\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:13.508722Z","iopub.execute_input":"2022-12-03T12:01:13.509049Z","iopub.status.idle":"2022-12-03T12:01:13.608670Z","shell.execute_reply.started":"2022-12-03T12:01:13.508993Z","shell.execute_reply":"2022-12-03T12:01:13.607979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Παραμετροποίηση\n\nΓια να είναι πιο ξεκάθαρα τα παρακάτω βήματα, ορίζουμε εδώ όλες τις βασικές παραμέτρους της εκπαίδευσης.","metadata":{}},{"cell_type":"code","source":"# paths\nWORKDIR = '../working'\nINPUTS_PATH = '../input/airbus-ship-detection'\nOUTPUTS_PATH = '../output'\nTRAINED_MODEL_PATH = '../input/trained-model/mask_rcnn_asdc_gpu_0015.h5'\n\n# data\nTRAIN_RATIO = 0.75\nVAL_RATIO = 0.15\nTEST_RATIO = 0.10\nTRAIN_DATA = os.path.join(INPUTS_PATH, 'train_v2')\nTRAIN_SHIP_SEGMENTATIONS_PATH = os.path.join(INPUTS_PATH, 'train_ship_segmentations_v2.csv')\n\n# model\nMASK_RCNN_PATH = os.path.join(WORKDIR, 'Mask_RCNN-master')\nCOCO_WEIGHTS_PATH = os.path.join(WORKDIR, \"mask_rcnn_coco.h5\")\nSHIP_CLASS_NAME = 'ship'\nIMAGE_WIDTH = 768\nIMAGE_HEIGHT = 768\nSHAPE = (IMAGE_WIDTH, IMAGE_HEIGHT)","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:14.396942Z","iopub.execute_input":"2022-12-03T12:01:14.397247Z","iopub.status.idle":"2022-12-03T12:01:14.404452Z","shell.execute_reply.started":"2022-12-03T12:01:14.397190Z","shell.execute_reply":"2022-12-03T12:01:14.403388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Σύνολο Δεδομένων\n\n## Διερεύνηση και προετοιμασία\n\nΤα δεδομένα του Dataset της Airbus αποτελούνται από:\n- δορυφορικές εικόνες (tiles) συγκεκριμένης διάστασης, στις οποίες μπορεί να απεικονίζονται ή όχι πλοία\n- ένα αρχείο csv το οποίο περιέχει κωδικοποιημένες όλες τις τοποθεσίες όπου υπάρχουν πλοία στις συγκεκριμένες εικόνες\n\nΞεκινάμε εξετάζοντας το αρχείο των κατατμήσεων και μετατρέποντάς το σε μία πιο χρήσιμη μορφή.","metadata":{}},{"cell_type":"code","source":"# Read labels\nlabels_df = pd.read_csv(TRAIN_SHIP_SEGMENTATIONS_PATH)\nlabels_df['HasShips'] = labels_df['EncodedPixels'].map(lambda v: 1 if isinstance(v, str) else 0)\nlabels_df[:10]","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:15.044867Z","iopub.execute_input":"2022-12-03T12:01:15.045238Z","iopub.status.idle":"2022-12-03T12:01:16.276516Z","shell.execute_reply.started":"2022-12-03T12:01:15.045185Z","shell.execute_reply":"2022-12-03T12:01:16.275769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_df = labels_df.groupby('ImageId').agg({'HasShips': 'sum'})\nimages_df['Masks'] = labels_df.groupby('ImageId')['EncodedPixels'].apply(list)\nimages_df = images_df[images_df['HasShips'] > 0].reset_index()\nimages_df[:10]","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:16.280686Z","iopub.execute_input":"2022-12-03T12:01:16.282673Z","iopub.status.idle":"2022-12-03T12:01:31.502152Z","shell.execute_reply.started":"2022-12-03T12:01:16.282621Z","shell.execute_reply":"2022-12-03T12:01:31.501373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_df['HasShips'].describe()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:31.504075Z","iopub.execute_input":"2022-12-03T12:01:31.504536Z","iopub.status.idle":"2022-12-03T12:01:31.517940Z","shell.execute_reply.started":"2022-12-03T12:01:31.504332Z","shell.execute_reply":"2022-12-03T12:01:31.517003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Διαχωρισμός σε train, validation, test δεδομένα","metadata":{}},{"cell_type":"code","source":"# split to training & validation sets \nfrom sklearn.model_selection import train_test_split\ntrain_ids, val_test_ids = train_test_split(images_df, test_size=1-TRAIN_RATIO, stratify=images_df['HasShips'], random_state=42)\nval_ids, test_ids = train_test_split(val_test_ids, test_size=TEST_RATIO/(TEST_RATIO+VAL_RATIO), stratify=val_test_ids['HasShips'], random_state=42)\n\nfig, axs = plt.subplots(1, 2, figsize = (20, 5))\nfig.suptitle('Number of ships')\naxs[0].hist(images_df['HasShips'], bins=np.arange(0,16)+0.5, ec=\"k\")\naxs[0].set_title('Entire training set')\naxs[1].hist(train_ids['HasShips'], bins=np.arange(0,16)+0.5, ec=\"k\")\naxs[1].hist(val_ids['HasShips'], bins=np.arange(0,16)+0.5, ec=\"k\")\naxs[1].hist(test_ids['HasShips'], bins=np.arange(0,16)+0.5, ec=\"k\")\naxs[1].set_title('Divided to training and validation data')\nplt.show()\n\nprint('Split results:', train_ids.shape[0], 'training masks, and', val_ids.shape[0], 'validation masks and', test_ids.shape[0], 'test masks.')","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:31.520399Z","iopub.execute_input":"2022-12-03T12:01:31.520862Z","iopub.status.idle":"2022-12-03T12:01:32.260217Z","shell.execute_reply.started":"2022-12-03T12:01:31.520649Z","shell.execute_reply":"2022-12-03T12:01:32.259203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Αποκωδικοποίηση και οπτικοποίηση των δεδομένων\n\nΠαρακάτω ορίζουμε κάποιες χρήσιμες συναρτήσεις και ενδεικτικά οπτικοποιούμε κάποια δεδομένα.","metadata":{}},{"cell_type":"code","source":"mask_rgb_color = np.array([50,200,150])\nalpha = 0.4\n\n# https://www.kaggle.com/paulorzp/run-length-encode-and-decode\ndef rle_decode(mask_rle, shape=SHAPE):\n    '''\n    mask_rle: run-length as string formated: [start0] [length0] [start1] [length1]... in 1d array\n    shape: (height,width) of array to return \n    Returns numpy array according to the shape, 1 - mask, 0 - background\n    '''\n    s = mask_rle.split()\n    # gets starts & lengths 1d arrays \n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0::2], s[1::2])]\n    starts -= 1\n    # gets ends 1d array\n    ends = starts + lengths\n    # creates blank mask image 1d array\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    # sets mark pixles\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    # reshape as a 2d mask image\n    return img.reshape(shape).T  # Needed to align to RLE direction\n\ndef masks_to_image(in_mask_list, shape=SHAPE):\n    '''\n    use list of rle masks to create single mask array\n    '''\n    all_masks = np.zeros(shape, dtype = np.int16)\n    for mask in in_mask_list:\n        if isinstance(mask, str):\n            all_masks += rle_decode(mask)\n    return np.expand_dims(all_masks, -1)\n\ndef get_masks(image_id, path=TRAIN_DATA):\n    '''\n    return mask array of image with image_id\n    '''\n    rle = labels_df.query('ImageId==\"{}\"'.format(image_id))['EncodedPixels']    \n    return masks_to_image(rle)\n\ndef show_image_grid(path=TRAIN_DATA):\n    '''\n    show grid of images with masks\n    '''\n    plt.figure(figsize=(20,20))\n    images = [random.choice(list(images_df['ImageId'])) for i in range(36)]\n    for i, image_id in enumerate(images):\n        image = imread(os.path.join(path, image_id))\n        mask = get_masks(image_id)\n        plt.subplot(6, 6, i + 1)\n        plt.axis(\"off\")\n        plt.imshow(image, aspect='auto')\n        plt.imshow(mask*mask_rgb_color, aspect='auto', alpha=alpha)\n    plt.subplots_adjust(hspace=0, wspace=0)\n    plt.show()\n\ndef show_image_and_mask(image_id, path=TRAIN_DATA):\n    '''\n    show image and mask separately and together\n    '''\n    fig, axs = plt.subplots(1, 3, figsize = (20, 5))\n    fig.suptitle('Image ' + image_id)\n    image = imread(os.path.join(path, image_id))\n    mask = get_masks(image_id)\n    axs[0].imshow(image)\n    axs[0].set_title('Satellite Image')\n    axs[1].imshow(mask*mask_rgb_color)\n    axs[1].set_title('Ship Mask')\n    axs[2].imshow(image)\n    axs[2].imshow(mask*mask_rgb_color, alpha=alpha)\n    axs[2].set_title('Satellite Image with mask')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:32.261229Z","iopub.execute_input":"2022-12-03T12:01:32.261480Z","iopub.status.idle":"2022-12-03T12:01:32.278783Z","shell.execute_reply.started":"2022-12-03T12:01:32.261431Z","shell.execute_reply":"2022-12-03T12:01:32.278228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_image_grid()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:32.279844Z","iopub.execute_input":"2022-12-03T12:01:32.280296Z","iopub.status.idle":"2022-12-03T12:01:39.502801Z","shell.execute_reply.started":"2022-12-03T12:01:32.280234Z","shell.execute_reply":"2022-12-03T12:01:39.501561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_image_and_mask(random.choice(list(images_df['ImageId'])))\nshow_image_and_mask(random.choice(list(images_df['ImageId'])))","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:39.506694Z","iopub.execute_input":"2022-12-03T12:01:39.506969Z","iopub.status.idle":"2022-12-03T12:01:41.408859Z","shell.execute_reply.started":"2022-12-03T12:01:39.506925Z","shell.execute_reply":"2022-12-03T12:01:41.408113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Mask R-CNN\n\n## Εισαγωγή μοντέλου\n\nΣτη συγκεκριμένη περίπτωση, θα χρησιμοποιήσουμε την [ανοικτού κώδικα υλοποίηση για Keras και Tensorflow της matterport](https://github.com/matterport/Mask_RCNN). Το μόνο που χρειάζεται αφού κατεβάσουμε τον κώδικα και να γίνουν import τα αντίστοιχα modules.","metadata":{}},{"cell_type":"code","source":"# if to clone Mask_R-CNN git when it exists \nUPDATE_MASK_RCNN = False\n\nos.chdir(WORKDIR)\nif UPDATE_MASK_RCNN:\n    !rm -rf {MASK_RCNN_PATH}\n\n# Downlaod Mask RCNN code to a local folder \nif not os.path.exists(MASK_RCNN_PATH):\n    ! wget https://github.com/samlin001/Mask_RCNN/archive/master.zip -O Mask_RCNN-master.zip\n    ! unzip Mask_RCNN-master.zip 'Mask_RCNN-master/mrcnn/*'\n    ! rm Mask_RCNN-master.zip\n\n# Import Mask RCNN\nsys.path.append(MASK_RCNN_PATH)  # To find local version of the library\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log    ","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:41.411816Z","iopub.execute_input":"2022-12-03T12:01:41.412340Z","iopub.status.idle":"2022-12-03T12:01:52.919340Z","shell.execute_reply.started":"2022-12-03T12:01:41.412288Z","shell.execute_reply":"2022-12-03T12:01:52.918427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Προσαρμογή στο Dataset\n\nΓια να μπορούν τα δεδομένα να χρησιμοποιηθούν για την εκπαίδευση του μοντέλου, πρέπει να οριστεί μία κλάση για ταα συγκεκριμένο Dataset, η οποία θα περιλαμβάνει συγκεκριμένες συναρτήσεις που περιγράφουν πώς γίνεται η επιλογή των εικόνων και των ετικετών από το Mask R-CNN.","metadata":{}},{"cell_type":"code","source":"class ShipDetectionDataset(utils.Dataset):\n    \"\"\"Airbus Ship Detection Challenge Dataset\n    \"\"\"\n    def __init__(self, image_file_dir, ids, masks, image_width=IMAGE_WIDTH, image_height=IMAGE_HEIGHT):\n        super().__init__(self)\n        self.image_file_dir = image_file_dir\n        self.ids = ids\n        self.masks = masks\n        self.image_width = image_width\n        self.image_height = image_height\n        \n        # Add classes\n        self.add_class(SHIP_CLASS_NAME, 1, SHIP_CLASS_NAME)\n        self.load_dataset()\n        \n    def load_dataset(self):\n        \"\"\"Load dataset from the path\n        \"\"\"\n        # Add images\n        for index, row in self.ids.iterrows():\n            image_id = row['ImageId']\n            image_path = os.path.join(self.image_file_dir, image_id)\n            rle_mask_list = row['Masks']\n            #print(rle_mask_list)\n            self.add_image(\n                SHIP_CLASS_NAME,\n                image_id=image_id,\n                path=image_path,\n                width=self.image_width, height=self.image_height,\n                rle_mask_list=rle_mask_list)\n\n    def load_mask(self, image_id):\n        \"\"\"Generate instance masks for shapes of the given image ID.\n        \"\"\"\n        info = self.image_info[image_id]\n        rle_mask_list = info['rle_mask_list']\n        mask_count = len(rle_mask_list)\n        mask = np.zeros([info['height'], info['width'], mask_count],\n                        dtype=np.uint8)\n        i = 0\n        for rel in rle_mask_list:\n            if isinstance(rel, str):\n                np.copyto(mask[:,:,i], rle_decode(rel))\n            i += 1\n        \n        # Return mask, and array of class IDs of each instance. Since we have\n        # one class ID only, we return an array of 1s\n        return mask.astype(np.bool), np.ones([mask.shape[-1]], dtype=np.int32)\n    \n    def image_reference(self, image_id):\n        \"\"\"Return the path of the image.\"\"\"\n        info = self.image_info[image_id]\n        if info['source'] == SHIP_CLASS_NAME:\n            return info['path']\n        else:\n            super(self.__class__, self).image_reference(image_id)","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:52.921097Z","iopub.execute_input":"2022-12-03T12:01:52.921468Z","iopub.status.idle":"2022-12-03T12:01:52.934874Z","shell.execute_reply.started":"2022-12-03T12:01:52.921412Z","shell.execute_reply":"2022-12-03T12:01:52.933909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Προετοιμασία και φόρτωση των δεδομένων\n\nΣτη συνέχεια με χρήση της κλάσης ShipDetectionDataset() που ορίσαμε παραπάνω δημιουργούνται 3 dataset στη μορφή που τα περιμένει το Mask R-CNN, για train, validation και testing αντίστοιχα.","metadata":{}},{"cell_type":"code","source":"# Training dataset.\ndataset_train = ShipDetectionDataset(image_file_dir=TRAIN_DATA, ids=train_ids, masks=labels_df)\ndataset_train.prepare()\n\n# Validation dataset\ndataset_val = ShipDetectionDataset(image_file_dir=TRAIN_DATA, ids=val_ids, masks=labels_df)\ndataset_val.prepare()\n\n# Testing dataset\ndataset_test = ShipDetectionDataset(image_file_dir=TRAIN_DATA, ids=test_ids, masks=labels_df)\ndataset_test.prepare()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:52.936039Z","iopub.execute_input":"2022-12-03T12:01:52.936558Z","iopub.status.idle":"2022-12-03T12:01:56.445045Z","shell.execute_reply.started":"2022-12-03T12:01:52.936491Z","shell.execute_reply":"2022-12-03T12:01:56.444121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Παραμετροποίηση Μοντέλου\n\nΠριν την εκπαίδευση πρέπει επίσης να οριστούν κάποιες βασικές [παράμετροι εκτέλεσης](https://github.com/samlin001/Mask_RCNN/blob/master/mrcnn/config.py).","metadata":{}},{"cell_type":"code","source":"class ShipDetectionConfig(Config):\n    \"\"\"\n    Configuration of Airbus Ship Detection Challenge Dataset \n    Overrides values in the base Config class.\n    From https://github.com/samlin001/Mask_RCNN/blob/master/mrcnn/config.py\n    \"\"\"\n    # https://www.kaggle.com/docs/kernels#technical-specifications\n    NAME = 'ASDC_GPU'\n    # NUMBER OF GPUs to use.\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 2\n    \n    NUM_CLASSES = 2  # ship or background\n    IMAGE_MIN_DIM = IMAGE_WIDTH\n    IMAGE_MAX_DIM = IMAGE_WIDTH\n    STEPS_PER_EPOCH = 300\n    VALIDATION_STEPS = 50\n    SAVE_BEST_ONLY = True\n    \n    # Minimum probability value to accept a detected instance\n    # ROIs below this threshold are skipped\n    DETECTION_MIN_CONFIDENCE = 0.95\n\n    # Non-maximum suppression threshold for detection\n    # Keep it small to merge overlapping ROIs \n    DETECTION_NMS_THRESHOLD = 0.05\n\n    \nconfig = ShipDetectionConfig()\nconfig.display()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:56.445898Z","iopub.execute_input":"2022-12-03T12:01:56.446153Z","iopub.status.idle":"2022-12-03T12:01:56.461452Z","shell.execute_reply.started":"2022-12-03T12:01:56.446104Z","shell.execute_reply":"2022-12-03T12:01:56.460315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Μεταφορά Μάθησης\n\nΑντί να αρχικοποιήσουμε το μοντέλο με τυχαία βάρη, μπορούμε να χρησιμοποιήσουμε τα προ-εκπαιδευμένα βάρη της ίδιας αρχιτεκτονικής σε κάποιο άλλο dataset, στη συγκεκριμένη περίπτωση στο MS COCO, εκμεταλλευόμενοι έτσι το γεγονός ότι για τα αρχικά τουλάχιστον στάδια, της εξαγωγής βασικών χαρακτηριστικών, τα βάρη είναι πολύ παρόμοια.","metadata":{}},{"cell_type":"code","source":"model = modellib.MaskRCNN(mode=\"training\", config=config, model_dir=WORKDIR)\n\nimport errno\ntry:\n    weights_path = model.find_last()\n    load_weights = True\nexcept FileNotFoundError:\n    # if there is no previous trained weights, load COCO\n    load_weights = True\n    weights_path = COCO_WEIGHTS_PATH\n    utils.download_trained_weights(weights_path)\n    \nif load_weights:\n    print(\"Loading weights: \", weights_path)\n    model.load_weights(weights_path, by_name=True, exclude=[\n                \"mrcnn_class_logits\", \"mrcnn_bbox_fc\",\n                \"mrcnn_bbox\", \"mrcnn_mask\"])","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:01:56.462566Z","iopub.execute_input":"2022-12-03T12:01:56.462806Z","iopub.status.idle":"2022-12-03T12:02:24.820385Z","shell.execute_reply.started":"2022-12-03T12:01:56.462760Z","shell.execute_reply":"2022-12-03T12:02:24.819608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Εκπαίδευση του μοντέλου\n\nΗ εκπαίδευση του μοντέλου γίνεται με απλή κλήση της συνάρτησης train(), χρησιμοποιώντας τα dataset_train και dataset_val για εκπαίδευση και validation αντίστοιχα.","metadata":{}},{"cell_type":"code","source":"start_time = time.time()    \n\nmodel.train(dataset_train, dataset_val,\n            learning_rate=config.LEARNING_RATE * 1.5,\n            epochs=20,\n            layers='all')\n\nprint(\"Training time:\", time.time() - start_time)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Αποτελέσματα: Πρόβλεψη (Inference)\n\nΗ πρόβλεψη με χρήση του εκπαιδευμένου μοντέλου πάνω σε εικόνες από το dataset_test γίνεται χρησιμοποιώντας τη συνάρτηση detect().","metadata":{}},{"cell_type":"code","source":"class InferenceConfig(ShipDetectionConfig):\n    GPU_COUNT = 1\n    # 1 image for inference \n    IMAGES_PER_GPU = 1\n\ninference_config = InferenceConfig()\n\n# create a model in inference mode\ninfer_model = modellib.MaskRCNN(mode=\"inference\", config=inference_config, model_dir=WORKDIR)\n\n# Load trained weights\n# model_path = infer_model.find_last()\nmodel_path = TRAINED_MODEL_PATH\nprint(\"Loading weights from \", model_path)\ninfer_model.load_weights(model_path, by_name=True)\n\n# Compute VOC-Style mean Average Precision @ IoU=0.5\n# Running on a few (20) images. Increase for better accuracy.\nAPs = []\nfor i, image_id in enumerate(dataset_test.image_ids):\n    if i > 20:\n        break\n    # Load image and ground truth data\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset_test, inference_config,\n                               image_id, use_mini_mask=False)\n    molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0)\n    # Run object detection\n    results = infer_model.detect([image], verbose=0)\n    r = results[0]\n    visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], \n                            dataset_test.class_names, r['scores'])\n\n    # Compute AP\n    AP, precisions, recalls, overlaps =\\\n        utils.compute_ap(gt_bbox, gt_class_id, gt_mask,\n                         r[\"rois\"], r[\"class_ids\"], r[\"scores\"], r['masks'])\n    APs.append(AP)\n    print(\"mAP: \", np.mean(APs))\n","metadata":{"execution":{"iopub.status.busy":"2022-12-03T12:02:24.821279Z","iopub.execute_input":"2022-12-03T12:02:24.821566Z","iopub.status.idle":"2022-12-03T12:03:04.663190Z","shell.execute_reply.started":"2022-12-03T12:02:24.821515Z","shell.execute_reply":"2022-12-03T12:03:04.662466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Clean up","metadata":{}},{"cell_type":"code","source":"# model_path = model.find_last()\n# print(model_path)\n\n# !cd /kaggle/working\n# !tar -czvf my_work.zip asdc_gpu20221202T1353/mask_rcnn_asdc_gpu_0015.h5\n\n# from IPython.display import FileLink\n# FileLink(r'asdc_gpu20221202T1353/mask_rcnn_asdc_gpu_0015.h5')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" !rm -rf ../working/*","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}