{"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":"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)\nfrom tqdm import tqdm\nimport gc\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-05T14:13:46.650685Z","iopub.execute_input":"2022-09-05T14:13:46.651102Z","iopub.status.idle":"2022-09-05T14:13:46.657189Z","shell.execute_reply.started":"2022-09-05T14:13:46.651067Z","shell.execute_reply":"2022-09-05T14:13:46.656319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_PATH = \"../input/mayo-clinic-strip-ai\"\nOUT_BASE_PATH = \"Dataset-mayo\"","metadata":{"execution":{"iopub.status.busy":"2022-09-05T14:13:46.856549Z","iopub.execute_input":"2022-09-05T14:13:46.857156Z","iopub.status.idle":"2022-09-05T14:13:46.861624Z","shell.execute_reply.started":"2022-09-05T14:13:46.857121Z","shell.execute_reply":"2022-09-05T14:13:46.860432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(INPUT_PATH, \"train.csv\"))","metadata":{"execution":{"iopub.status.busy":"2022-09-05T14:13:47.032268Z","iopub.execute_input":"2022-09-05T14:13:47.032715Z","iopub.status.idle":"2022-09-05T14:13:47.050838Z","shell.execute_reply.started":"2022-09-05T14:13:47.032682Z","shell.execute_reply":"2022-09-05T14:13:47.049655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_paths = os.listdir(os.path.join(INPUT_PATH, \"train\"))","metadata":{"execution":{"iopub.status.busy":"2022-09-05T14:13:47.255139Z","iopub.execute_input":"2022-09-05T14:13:47.255917Z","iopub.status.idle":"2022-09-05T14:13:47.354873Z","shell.execute_reply.started":"2022-09-05T14:13:47.255872Z","shell.execute_reply":"2022-09-05T14:13:47.353576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EDA data folder","metadata":{}},{"cell_type":"code","source":"import json\nfrom multiprocessing import Process, JoinableQueue\nimport argparse\nimport os\nimport re\nimport shutil\nimport sys\nimport glob\nimport numpy as np\nimport math\nfrom unicodedata import normalize\nfrom skimage import io\nfrom skimage.color import rgb2hsv\nfrom skimage.util import img_as_ubyte\nfrom skimage import filters\nfrom PIL import Image, ImageFilter, ImageStat\n\nImage.MAX_IMAGE_PIXELS = None\n\nimport openslide\nfrom openslide import open_slide, ImageSlide\nfrom openslide.deepzoom import DeepZoomGenerator\n\nVIEWER_SLIDE_NAME = 'slide'\n\nclass TileWorker(Process):\n    \"\"\"A child process that generates and writes tiles.\"\"\"\n\n    def __init__(self, queue, slidepath, tile_size, overlap, limit_bounds,\n                quality, threshold):\n        Process.__init__(self, name='TileWorker')\n        self.daemon = True\n        self._queue = queue\n        self._slidepath = slidepath\n        self._tile_size = tile_size\n        self._overlap = overlap\n        self._limit_bounds = limit_bounds\n        self._quality = quality\n        self._threshold = threshold\n        self._slide = None\n\n    def run(self):\n        self._slide = open_slide(self._slidepath)\n        last_associated = None\n        dz = self._get_dz()\n        while True:\n            data = self._queue.get()\n            if data is None:\n                self._queue.task_done()\n                break\n            associated, level, address, outfile = data\n            if last_associated != associated:\n                dz = self._get_dz(associated)\n                last_associated = associated\n            try:\n                tile = dz.get_tile(level, address)\n                edge = tile.filter(ImageFilter.FIND_EDGES)\n                edge = ImageStat.Stat(edge).sum\n                edge = np.mean(edge)/(self._tile_size**2)\n                w, h = tile.size\n                if edge > self._threshold:\n                    if not (w==self._tile_size and h==self._tile_size):\n                        tile = tile.resize((self._tile_size, self._tile_size))\n                    tile.save(outfile, quality=self._quality)\n            except:\n                pass\n            self._queue.task_done()\n            \n\n    def _get_dz(self, associated=None):\n        if associated is not None:\n            image = ImageSlide(self._slide.associated_images[associated])\n        else:\n            image = self._slide\n        return DeepZoomGenerator(image, self._tile_size, self._overlap,\n                    limit_bounds=self._limit_bounds)\n\n\nclass DeepZoomImageTiler(object):\n    \"\"\"Handles generation of tiles and metadata for a single image.\"\"\"\n\n    def __init__(self, dz, basename, target_levels, mag_base, format, associated, queue, name=None):\n        self._dz = dz\n        self._basename = basename\n        self._format = format\n        self._associated = associated\n        self._queue = queue\n        self._processed = 0\n        self._target_levels = target_levels\n        self._mag_base = int(mag_base)\n        self._name = name\n\n    def run(self):\n        self._write_tiles()\n\n    def _write_tiles(self):\n        target_levels = [self._dz.level_count-i-1 for i in self._target_levels]\n        mag_list = [int(self._mag_base/2**i) for i in self._target_levels]\n        mag_idx = 0\n        for level in range(self._dz.level_count):\n            if not (level in target_levels):\n                continue\n            tiledir = os.path.join(\"%s_files\" % self._basename, str(mag_list[mag_idx]))\n            if not os.path.exists(tiledir):\n                os.makedirs(tiledir)\n            cols, rows = self._dz.level_tiles[level]\n            for row in range(rows):\n                for col in range(cols):\n                    tilename = os.path.join(tiledir, '%s_%d_%d.%s' % (\n                                    self._name, col, row, self._format))\n                    if not os.path.exists(tilename):\n                        self._queue.put((self._associated, level, (col, row),\n                                    tilename))\n                    self._tile_done()\n            mag_idx += 1\n\n    def _tile_done(self):\n        self._processed += 1\n        count, total = self._processed, self._dz.tile_count\n        if count % 100 == 0 or count == total:\n            print(\"Tiling %s: wrote %d/%d tiles\" % (\n                    self._associated or 'slide', count, total),\n                    end='\\r', file=sys.stderr)\n            if count == total:\n                print(file=sys.stderr)\n\n\nclass DeepZoomStaticTiler(object):\n    \"\"\"Handles generation of tiles and metadata for all images in a slide.\"\"\"\n\n    def __init__(self, slidepath, basename, mag_levels, base_mag, objective, format, tile_size, overlap,\n                limit_bounds, quality, workers, threshold, name=None):\n        self._slide = open_slide(slidepath)\n        self._basename = basename\n        self._format = format\n        self._tile_size = tile_size\n        self._overlap = overlap\n        self._mag_levels = mag_levels\n        self._base_mag = base_mag\n        self._objective = objective\n        self._limit_bounds = limit_bounds\n        self._queue = JoinableQueue(2 * workers)\n        self._workers = workers\n        self._name = name\n        self._dzi_data = {}\n        for _i in range(workers):\n            TileWorker(self._queue, slidepath, tile_size, overlap,\n                        limit_bounds, quality, threshold).start()\n\n    def run(self):\n        self._run_image()\n        self._shutdown()\n\n    def _run_image(self, associated=None):\n        \"\"\"Run a single image from self._slide.\"\"\"\n        if associated is None:\n            image = self._slide\n            basename = self._basename\n        else:\n            image = ImageSlide(self._slide.associated_images[associated])\n            basename = os.path.join(self._basename, self._slugify(associated))\n        dz = DeepZoomGenerator(image, self._tile_size, self._overlap,\n                    limit_bounds=self._limit_bounds)\n        \n        MAG_BASE = self._slide.properties.get(openslide.PROPERTY_NAME_OBJECTIVE_POWER)\n        if MAG_BASE is None:\n            MAG_BASE = self._objective\n        first_level = int(math.log2(float(MAG_BASE)/self._base_mag)) # raw / input, 40/20=2, 40/40=0\n        target_levels = [i+first_level for i in self._mag_levels] # levels start from 0\n        target_levels.reverse()\n        \n        tiler = DeepZoomImageTiler(dz, basename, target_levels, MAG_BASE, self._format, associated,\n                    self._queue, self._name)\n        tiler.run()\n\n    def _url_for(self, associated):\n        if associated is None:\n            base = VIEWER_SLIDE_NAME\n        else:\n            base = self._slugify(associated)\n        return '%s.dzi' % base\n\n    def _copydir(self, src, dest):\n        if not os.path.exists(dest):\n            os.makedirs(dest)\n        for name in os.listdir(src):\n            srcpath = os.path.join(src, name)\n            if os.path.isfile(srcpath):\n                shutil.copy(srcpath, os.path.join(dest, name))\n\n    @classmethod\n    def _slugify(cls, text):\n        text = normalize('NFKD', text.lower()).encode('ascii', 'ignore').decode()\n        return re.sub('[^a-z0-9]+', '_', text)\n\n    def _shutdown(self):\n        for _i in range(self._workers):\n            self._queue.put(None)\n        self._queue.join()\n\ndef nested_patches(img_slide, out_base, level=(0,), ext='jpeg'):\n    print('\\n Organizing patches')\n    img_name = img_slide.split(os.sep)[-1].split('.')[0]\n    img_class = img_slide.split(os.sep)[2]\n    n_levels = len(glob.glob('WSI_temp_files/*'))\n    print(out_base, \" --- \",  img_class, \" --- \", img_name)\n    bag_path = os.path.join(out_base, img_name)\n    os.makedirs(bag_path, exist_ok=True)\n    if len(level)==1:\n        patches = glob.glob(os.path.join('WSI_temp_files', '*', '*.'+ext))\n        for i, patch in enumerate(patches):\n            patch_name = patch.split(os.sep)[-1]\n            shutil.move(patch, os.path.join(bag_path, patch_name))\n            sys.stdout.write('\\r Patch [%d/%d]' % (i+1, len(patches)))\n        print('Done.')\n    else:\n        level_factor = 2**int(level[1]-level[0])\n        levels = [int(os.path.basename(i)) for i in glob.glob(os.path.join('WSI_temp_files', '*'))]\n        levels.sort()\n        low_patches = glob.glob(os.path.join('WSI_temp_files', str(levels[0]), '*.'+ext))\n        for i, low_patch in enumerate(low_patches):\n            low_patch_name = low_patch.split(os.sep)[-1]\n            shutil.move(low_patch, os.path.join(bag_path, low_patch_name))\n            low_patch_folder = low_patch_name.split('.')[0]\n            high_patch_path = os.path.join(bag_path, low_patch_folder)\n            os.makedirs(high_patch_path, exist_ok=True)\n            low_x = int(low_patch_folder.split('_')[0])\n            low_y = int(low_patch_folder.split('_')[1])\n            high_x_list = list( range(low_x*level_factor, (low_x+1)*level_factor) )\n            high_y_list = list( range(low_y*level_factor, (low_y+1)*level_factor) )\n            for x_pos in high_x_list:\n                for y_pos in high_y_list:\n                    high_patch = glob.glob(os.path.join('WSI_temp_files', str(levels[1]), '{}_{}.'.format(x_pos, y_pos)+ext))\n                    if len(high_patch)!=0:\n                        high_patch = high_patch[0]\n                        shutil.move(high_patch, os.path.join(bag_path, low_patch_folder, high_patch.split(os.sep)[-1]))\n            try:\n                os.rmdir(os.path.join(bag_path, low_patch_folder))\n                os.remove(low_patch)\n            except:\n                pass\n            sys.stdout.write('\\r Patch [%d/%d]' % (i+1, len(low_patches)))\n        print('Done.')","metadata":{"execution":{"iopub.status.busy":"2022-09-05T14:59:20.564465Z","iopub.execute_input":"2022-09-05T14:59:20.564913Z","iopub.status.idle":"2022-09-05T14:59:20.616774Z","shell.execute_reply.started":"2022-09-05T14:59:20.564877Z","shell.execute_reply":"2022-09-05T14:59:20.6156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# setup parameter \nImage.MAX_IMAGE_PIXELS = None\nparser = argparse.ArgumentParser(description='Patch extraction for WSI')\nparser.add_argument('-d', '--dataset', type=str, default='TCGA-lung', help='Dataset name')\nparser.add_argument('-e', '--overlap', type=int, default=0, help='Overlap of adjacent tiles [0]')\nparser.add_argument('-f', '--format', type=str, default='jpeg', help='Image format for tiles [jpeg]')\nparser.add_argument('-v', '--slide_format', type=str, default='svs', help='Image format for tiles [svs]')\nparser.add_argument('-j', '--workers', type=int, default=4, help='Number of worker processes to start [4]')\nparser.add_argument('-q', '--quality', type=int, default=70, help='JPEG compression quality [70]')\nparser.add_argument('-s', '--tile_size', type=int, default=256, help='Tile size [256]')\nparser.add_argument('-b', '--base_mag', type=float, default=20, help='Maximum magnification for patch extraction [20]')\nparser.add_argument('-m', '--magnifications', type=int, nargs='+', default=(0,), help='Levels for patch extraction [0]')\nparser.add_argument('-o', '--objective', type=float, default=20, help='The default objective power if metadata does not present [20]')\nparser.add_argument('-t', '--background_t', type=int, default=15, help='Threshold for filtering background [15]')  \nargs = parser.parse_args(args=[])","metadata":{"execution":{"iopub.status.busy":"2022-09-05T14:59:21.323941Z","iopub.execute_input":"2022-09-05T14:59:21.324368Z","iopub.status.idle":"2022-09-05T14:59:21.339868Z","shell.execute_reply.started":"2022-09-05T14:59:21.324332Z","shell.execute_reply":"2022-09-05T14:59:21.338692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"next_slide = ['65d1b4_0', '4f49c1_0', '9874eb_0', '59441e_0', \n              '4f9ac6_0', '7dd82f_1', '8b3323_0', '112b6e_1', \n              '690b81_0', '4f6fb1_1', '21b106_0', '8a17b7_0', \n              '008e5c_0', '1ec69e_0', '509042_0', '7cf058_0', \n              '2f73a2_0', '54838a_0', '6f9575_0', '56d177_2', \n              '86e319_2', '20d5cf_0', '977a49_0', '8781e2_0', \n              '0d4164_0', '777311_1', '6baf51_0', '055f6a_0', \n              '29a4f6_0', '4094c4_0', '6747be_0', '1db82d_1', \n              '282d0a_0', '41b4ea_1', '82399d_1', '2745fc_0', \n              '3fe8a3_0', '533a49_0', '599e16_0', '1d6d4f_0', \n              '05a1ec_0', '0468a8_0', '4919a7_0', '5f3f01_0', \n              '214cfa_1', '31588e_0', '15de51_0', '00c058_0', \n              '2a25b9_0', '0d718a_0', '2b49d6_0', '6fe1f2_0', \n              '827928_0', '3c2c23_0', '3b2c59_0', '33da32_0', \n              '12c8c9_0', '8fa951_0', '8be762_0', '2446b8_0', \n              '2e725a_0', '280c26_1', '8ebb0c_0', '140d1a_0', \n              '31adaa_0', '384052_0', '526dba_0', '037300_0', \n              '6fce60_0', '34a278_0', '4647d7_0', '54ddc7_0', \n              '5415fe_0', '957643_0', '9d71ef_0', '91fee7_0', \n              '2bd8fe_0', '4667f6_0', '5c30ec_0', '4e30e9_0', \n              '41b4ea_0', '45e3e0_0', '3d10be_4', '516e18_0', \n              '7f2ee2_0', '1fe0c4_0', '70c523_2', '992abf_0', \n              '395ea0_0', '1d1bf0_0', '113bb3_0', '821964_0', \n              '354f74_0', '6f6e0c_0', '5aec9b_0', '46e479_0', \n              '3d10be_3', '205025_0', '50ba15_0', '9961af_0', \n              '288156_0', '0c60b8_0', '8768db_0', '709b79_0', \n              '0cc0bc_0', '1f9d4f_0', '3020ef_0', '777311_0', \n              '33d071_0', '540410_0', '4dfe1e_0', '9efc03_0', \n              '24f8f5_0', '81092a_0', '0bddf9_0', '2e3749_0', \n              '4f9678_0', '5987c0_1', '245758_0', '2ecb46_0', '1295bb_0', '880f54_0', '70f515_0', '8e0244_0', '4f6fb1_3', \n              '2eb2d7_0', '3b7d81_0', '5588f9_0', '62dd90_0', '56d177_3', '379f1c_0', '5fde88_0', '09644e_4', '1ef6da_0', \n              '0ba49d_0', '48af1a_0', '53845a_0', '3982bf_0', '90ffa4_1', '5ae30a_0', '907f7b_0', '79753f_0', '85868f_0', \n              '68eb0e_0', '91b9d3_1', '7e9a65_0', '83198b_0', '0a3ad1_0', '827928_1', '616c62_1', '3d10be_2', '37258c_0', \n              '4929cd_0', '0f2961_0', '0ff6fc_0', '55809c_0', '915264_0', '9ee0e2_0', '79d1c1_0', '56d177_0', '83cedb_0', \n              '91b9d3_4', '6015f7_0', '79d52a_0', '045eb0_0', '2394f6_0', '53e0d7_0', '026c97_0', '3d10be_1', '8b90fa_0', \n              '34c9bc_0', '673181_0', '1f018f_0', '27afc7_0', '5d819a_0', '09644e_2', '280c26_0', '82399d_2', '79e30d_0', \n              '0e696a_0', '19dd95_0', '0ee750_1', '69d655_0', '5d4b88_0', '1bbcba_0', '32e44f_0', '369366_0', '98123e_0', \n              '81eb29_0', '15aab4_0', '6e08cb_0', '329006_0', '09644e_3', '516e18_1', '65fe16_0', '2268cf_0', '0d533f_0', \n              '856ae6_0', '1d0518_0', '45a0e5_1', '21726e_0', '4188be_0', '9010a1_0', '283f35_0', '250944_0', '6c4b62_0', \n              '4a1152_0', '931cea_0', '611a50_0', '028989_0', '112b6e_0', '6674a4_0', '0468a8_1', '488cd4_0', '70c523_1', \n              '4a4043_0', '03d1ec_0', '719165_0', '5d4b88_1', '3ab087_0', '6747be_1', '547474_0', '931cea_1', '214cfa_0', \n              '3d10be_0', '23d2c1_2', '507ac9_0', '8f71df_0', '8cf32b_0', '99c5c8_0', '36a149_0', '4ded24_0', '88623d_0', \n              '4b8777_0', '4f6fb1_2', '84f77e_0', '65aadd_0', '5c92f8_0', '70c523_0', '8fe2eb_0', '1d5335_0', '86e319_1', \n              '2c64b2_0', '652471_0', '006388_0', '4550fb_0', '42529f_0', '4bfb94_0', '13f372_0', '5cae18_1', '72df9e_0', \n              '991ad1_0', '2db520_0', '3fe88b_0', '0ff890_0', '72ead5_0', '6569ba_0', '0b7871_1', '032f10_0', '7fa91f_0', \n              '56d177_4', '5fdff2_0', '91b9d3_0', '194e3f_0', '7f3781_0', '4f6fb1_0', '0a47c9_0', '3ad0bb_0', '7633ea_0', \n              '497c27_0', '988131_0', '533081_0', '217b27_0', '424c9d_0', '392b24_0', '78c1c9_0', '23d2c1_1', '14d2fa_0', \n              '35b75a_0', '04439c_0', '3d80c7_0', '9a807e_0', '20914b_0', '49ea39_0', '5cae18_0', '7428fc_0', '3cbdf3_0', \n              '862501_1', '300145_0', '5f0b6f_0', '845d82_0', '41b23c_0', '0aff58_0', '1ffc5d_0', '2bcdd9_0', '029c68_0', \n              '5d3738_0', '3ee426_0', '45a0e5_0', '588e11_0', '45c6ce_0', '244aeb_2', '0415c3_0', '7c2739_0', '5bfaf8_0', \n              '7dd82f_0', '53845a_1', '60a950_0', '3bfe64_0', '313d30_0', '049194_1', '86e319_0', '9de0fa_0', '983df1_0', \n              '52d106_0', '08d3d8_0', '162cad_0', '0ed87f_1', '5f520a_1', '8fc6d5_0', '0372b0_0']\n","metadata":{"execution":{"iopub.status.busy":"2022-09-05T15:07:04.001694Z","iopub.execute_input":"2022-09-05T15:07:04.002106Z","iopub.status.idle":"2022-09-05T15:07:04.020864Z","shell.execute_reply.started":"2022-09-05T15:07:04.002071Z","shell.execute_reply":"2022-09-05T15:07:04.019517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# edit some parameter\nargs.magnifications = [1]\nargs.base_mag = 20\nargs.dataset = os.path.join(INPUT_PATH, \"train\")\nargs.slide_format = 'tif'\n\n#################################\nlevels = tuple(args.magnifications)\nassert len(levels)<=2, 'Only 1 or 2 magnifications are supported!'\npath_base = args.dataset\n\nif len(levels) == 2:\n    out_base =  os.path.join(OUT_BASE_PATH, 'pyramid')\nelse:\n    out_base = os.path.join(OUT_BASE_PATH, 'train')\nall_slides = glob.glob(os.path.join(path_base, '*.'+args.slide_format))\n\n# pos-i_pos-j -> x, y\nfor idx, c_slide in enumerate(all_slides):\n    c_slide_name = os.path.basename(c_slide).split('.')[0]\n    print('Process slide {}/{}'.format(idx+1, len(all_slides)))\n    if c_slide_name in next_slide:\n        continue\n    static_tiler_class = DeepZoomStaticTiler(c_slide, 'WSI_temp', \n                                             levels, args.base_mag, args.objective, args.format, args.tile_size, \n                                             args.overlap, True, args.quality, args.workers, args.background_t, name=c_slide_name).run()\n    nested_patches(c_slide, out_base, levels, ext=args.format)\n    shutil.rmtree('WSI_temp_files')\n    del static_tiler_class\n    gc.collect()\nprint('Patch extraction done for {} slides.'.format(len(all_slides)))","metadata":{"execution":{"iopub.status.busy":"2022-09-05T15:04:43.398714Z","iopub.execute_input":"2022-09-05T15:04:43.399427Z","iopub.status.idle":"2022-09-05T15:04:43.419344Z","shell.execute_reply.started":"2022-09-05T15:04:43.399388Z","shell.execute_reply":"2022-09-05T15:04:43.417622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ./Dataset-mayo/train/","metadata":{"execution":{"iopub.status.busy":"2022-09-05T15:02:17.89302Z","iopub.execute_input":"2022-09-05T15:02:17.89451Z","iopub.status.idle":"2022-09-05T15:02:19.053397Z","shell.execute_reply.started":"2022-09-05T15:02:17.89446Z","shell.execute_reply":"2022-09-05T15:02:19.052117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Instance embeddings","metadata":{}},{"cell_type":"markdown","source":"## 1. init Model instance embeddings","metadata":{}},{"cell_type":"code","source":"# # https://colab.research.google.com/github/bentrevett/pytorch-image-classification/blob/master/5_resnet.ipynb#scrollTo=4Cuqluk1ZNOW\n# import torch\n\n# torch.__version__","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:44:57.380838Z","iopub.execute_input":"2022-09-04T10:44:57.381222Z","iopub.status.idle":"2022-09-04T10:44:57.874289Z","shell.execute_reply.started":"2022-09-04T10:44:57.381184Z","shell.execute_reply":"2022-09-04T10:44:57.873171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n# device","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:45:01.050184Z","iopub.execute_input":"2022-09-04T10:45:01.051182Z","iopub.status.idle":"2022-09-04T10:45:01.127071Z","shell.execute_reply.started":"2022-09-04T10:45:01.05114Z","shell.execute_reply":"2022-09-04T10:45:01.125825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import torch.nn as nn\n# import torch.nn.functional as F\n# import torchvision.models as models\n\n\n# class ResNetSimCLR(nn.Module):\n\n#     def __init__(self, base_model, out_dim):\n#         super(ResNetSimCLR, self).__init__()\n#         self.resnet_dict = {\"resnet50\": models.resnet50(pretrained=True)}\n\n#         resnet = self._get_basemodel(base_model)\n#         num_ftrs = resnet.fc.in_features\n\n#         self.features = nn.Sequential(*list(resnet.children())[:-1])\n\n#         # projection MLP\n#         self.l1 = nn.Linear(num_ftrs, num_ftrs)\n#         self.l2 = nn.Linear(num_ftrs, out_dim)\n\n#     def _get_basemodel(self, model_name):\n#         try:\n#             model = self.resnet_dict[model_name]\n#             print(\"Feature extractor:\", model_name)\n#             return model\n#         except:\n#             raise (\"Invalid model name. Check the config file and pass one of: resnet18 or resnet50\")\n\n#     def forward(self, x):\n#         h = self.features(x)\n#         h = h.squeeze()\n\n#         x = self.l1(h)\n#         x = F.relu(x)\n#         x = self.l2(x)\n#         return h, x","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:45:01.32695Z","iopub.execute_input":"2022-09-04T10:45:01.327946Z","iopub.status.idle":"2022-09-04T10:45:01.68888Z","shell.execute_reply.started":"2022-09-04T10:45:01.327895Z","shell.execute_reply":"2022-09-04T10:45:01.687642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_ft = ResNetSimCLR(base_model='resnet50', out_dim=1024) # init model\n# if torch.cuda.is_available():\n#     print(\"using cuda\")\n#     model_ft.cuda()","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:45:02.455693Z","iopub.execute_input":"2022-09-04T10:45:02.456779Z","iopub.status.idle":"2022-09-04T10:45:06.745229Z","shell.execute_reply.started":"2022-09-04T10:45:02.456732Z","shell.execute_reply":"2022-09-04T10:45:06.744051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import gc","metadata":{"execution":{"iopub.status.busy":"2022-09-04T08:28:12.796013Z","iopub.execute_input":"2022-09-04T08:28:12.797461Z","iopub.status.idle":"2022-09-04T08:28:12.804205Z","shell.execute_reply.started":"2022-09-04T08:28:12.797404Z","shell.execute_reply":"2022-09-04T08:28:12.802664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# USE_GPU = True\n\n# if USE_GPU and torch.cuda.is_available():\n#     x = torch.randn([20,3,224,224]).to(device)\n#     output = model_ft(x) # output now has the features corresponding to input x\n#     del x\n#     gc.collect()\n#     torch.cuda.empty_cache()\n#     print(output[1].shape)","metadata":{"execution":{"iopub.status.busy":"2022-09-04T08:30:18.261447Z","iopub.execute_input":"2022-09-04T08:30:18.26184Z","iopub.status.idle":"2022-09-04T08:30:18.522875Z","shell.execute_reply.started":"2022-09-04T08:30:18.261811Z","shell.execute_reply":"2022-09-04T08:30:18.521327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. compression","metadata":{}},{"cell_type":"code","source":"# !ls ./Dataset-mayo/","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:45:06.864261Z","iopub.execute_input":"2022-09-04T10:45:06.86487Z","iopub.status.idle":"2022-09-04T10:45:07.872419Z","shell.execute_reply.started":"2022-09-04T10:45:06.86483Z","shell.execute_reply":"2022-09-04T10:45:07.871265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import gc\n# from tqdm import tqdm\n\n# input_path = OUT_BASE_PATH\n# train_dataset_path = os.path.join(input_path, \"train\")\n# compress_dataset_path = os.path.join(input_path, \"compress_train\")\n# total_list_path = os.path.join(input_path, \"list_slides_embedding.pth\")\n# if_free_memory = 100\n\n# if os.path.exists(compress_dataset_path) and os.path.isdir(compress_dataset_path):\n#     shutil.rmtree(compress_dataset_path)\n#     os.mkdir(compress_dataset_path)\n# else:\n#     os.mkdir(compress_dataset_path)\n\n# list_wsi_patches = os.listdir(train_dataset_path)\n# list_dict_arr_slide_information = []\n# for each_wsi_patching in tqdm(list_wsi_patches):\n#     abs_wsi_pathching = os.path.join(train_dataset_path, each_wsi_patching)\n#     torch_filename_save = os.path.join(compress_dataset_path, f\"{each_wsi_patching}.pt\")\n#     length_tissue = random.choices(glob.glob(os.path.join(abs_wsi_pathching, '*.'+ args.format)), k=if_free_memory)\n    \n#     # init variables\n#     list_instance_embedding_tissue = torch.zeros(if_free_memory, 1024, dtype=torch.float32)\n#     dict_information = dict()\n#     for idx, tissue in enumerate(length_tissue):\n#         if idx == if_free_memory:\n#             break\n#         tensor_image = np.asarray(Image.open(tissue), dtype=np.float32).transpose(2, 0, 1)\n#         tensor_image = torch.from_numpy(tensor_image)\n#         tensor_image = torch.unsqueeze(tensor_image, 0).to(device)\n#         instance_wsi_patch_embedding = model_ft(tensor_image)[1] # get embeddings\n#         list_instance_embedding_tissue[idx, :] = instance_wsi_patch_embedding\n#         del tensor_image, instance_wsi_patch_embedding\n#         gc.collect()\n#         torch.cuda.empty_cache()\n        \n#     torch.save(list_instance_embedding_tissue, torch_filename_save)\n    \n#     # serializer \n#     dict_information['slide'] = f'{each_wsi_patching}.pt'\n#     dict_information['shape'] = list_instance_embedding_tissue.size()\n#     dict_information['target'] = str(train_df[train_df['image_id'] == str(each_wsi_patching)]['label'].values[0])\n#     list_dict_arr_slide_information.append(dict_information)\n    \n#     print(f\"Slide name: {each_wsi_patching} -- numbers of tissue: {list_instance_embedding_tissue.shape[0]}\")\n#     del list_instance_embedding_tissue, dict_information\n#     gc.collect()\n#     torch.cuda.empty_cache()\n\n# torch.save(list_dict_arr_slide_information, total_list_path)\n\n# del list_dict_arr_slide_information\n# gc.collect()\n# torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2022-09-04T10:45:24.473561Z","iopub.execute_input":"2022-09-04T10:45:24.47393Z","iopub.status.idle":"2022-09-04T10:50:59.203729Z","shell.execute_reply.started":"2022-09-04T10:45:24.4739Z","shell.execute_reply":"2022-09-04T10:50:59.202598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test some function","metadata":{}}]}