{"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":"### Import","metadata":{}},{"cell_type":"code","source":"!pip install ipyplot -q\n\nimport pandas as pd\nimport numpy as np\nimport ipyplot\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport os\n\n%matplotlib inline\n\npath = '../input/hpa-single-cell-image-classification/'\ndf_train = pd.read_csv(path + 'train.csv')\n\ndf_sub = pd.read_csv(path + 'sample_submission.csv')\n\n\ncolours = ['_red.png', '_green.png', '_blue.png', '_yellow.png']\nTRAIN_PATHS = '/kaggle/input/hpa-single-cell-image-classification/train'\ntrain_paths = [[os.path.join(TRAIN_PATHS, df_train.iloc[idx,0]) + colour for colour in colours] for idx in range(len(df_train))]\ntrain_paths[1]","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:30:55.82413Z","iopub.execute_input":"2021-05-20T14:30:55.824498Z","iopub.status.idle":"2021-05-20T14:31:05.648522Z","shell.execute_reply.started":"2021-05-20T14:30:55.824465Z","shell.execute_reply":"2021-05-20T14:31:05.647311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### EDA","metadata":{}},{"cell_type":"code","source":"l_dict = {\n0:  \"Nucleoplasm\", \n1:  \"Nuclear Membrane\",   \n2:  \"Nucleoli\",   \n3:  \"Nucleoli Fibrillar Center\" ,  \n4:  \"Nuclear Speckles\",\n5:  \"Nuclear Bodies\",\n6:  \"Endoplasmic Reticulum\",   \n7:  \"Golgi Apparatus\",\n8:  \"Intermediate Filaments\",\n9:  \"Actin Filaments\", \n10: \"Microtubules\",\n11:  \"Mitotic Spindle\",\n12:  \"Centrosome\",   \n13:  \"Plasma Membrane\",\n14:  \"Mitochondria\",   \n15:  \"Aggresome\",\n16:  \"Cytosol\",   \n17:  \"Vesicles and Punctate Cytosolic Patterns\",   \n18:  \"Negative\"\n}","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:05.65105Z","iopub.execute_input":"2021-05-20T14:31:05.651735Z","iopub.status.idle":"2021-05-20T14:31:05.658808Z","shell.execute_reply.started":"2021-05-20T14:31:05.651682Z","shell.execute_reply":"2021-05-20T14:31:05.657928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.Label.value_counts()[:50].sort_values().plot.barh(figsize=(10,10), title=\"Raw Label Count\")","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:05.660021Z","iopub.execute_input":"2021-05-20T14:31:05.660525Z","iopub.status.idle":"2021-05-20T14:31:06.324398Z","shell.execute_reply.started":"2021-05-20T14:31:05.660477Z","shell.execute_reply":"2021-05-20T14:31:06.323564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_counts = df_train.Label.str.split(\"|\").explode().astype(int).value_counts().sort_values().rename(index=l_dict)\nlabel_counts.plot.barh(figsize=(10,10), title=\"Individual Label Counts\")","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:06.325617Z","iopub.execute_input":"2021-05-20T14:31:06.326091Z","iopub.status.idle":"2021-05-20T14:31:06.662846Z","shell.execute_reply.started":"2021-05-20T14:31:06.32603Z","shell.execute_reply":"2021-05-20T14:31:06.661943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_counts.plot.pie(figsize=(10,10), title=\"Individual Label Distribution\", ylabel=\"\", autopct='%1.1f%%', fontsize=10, startangle=0)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:06.666071Z","iopub.execute_input":"2021-05-20T14:31:06.666481Z","iopub.status.idle":"2021-05-20T14:31:06.995664Z","shell.execute_reply.started":"2021-05-20T14:31:06.66644Z","shell.execute_reply":"2021-05-20T14:31:06.994671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['Label Count'] = df_train.Label.str.split(\"|\").str.len()\ndf_train['Label Count'].value_counts().plot.bar(title=\"Label Length Count\")","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:06.997081Z","iopub.execute_input":"2021-05-20T14:31:06.997398Z","iopub.status.idle":"2021-05-20T14:31:07.457518Z","shell.execute_reply.started":"2021-05-20T14:31:06.997343Z","shell.execute_reply":"2021-05-20T14:31:07.456165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from itertools import product\n\nlabel_list = df_train.Label.str.split(\"|\").to_list()\n\nitems = [map(int, a) for l in label_list for a in list(product(l, l))]\n\ndc_df = pd.DataFrame(items, columns = ['LabelA', 'LabelB']) \ncmatrix = pd.crosstab(dc_df.LabelA, dc_df.LabelB)\nnp.fill_diagonal(cmatrix.values, 0)\n\nf = plt.figure(figsize=(10, 10))\nsns.heatmap(cmatrix, cmap=\"Blues\")\nplt.title(\"Label Co-occurrence\")","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:07.45917Z","iopub.execute_input":"2021-05-20T14:31:07.45963Z","iopub.status.idle":"2021-05-20T14:31:08.284973Z","shell.execute_reply.started":"2021-05-20T14:31:07.459583Z","shell.execute_reply":"2021-05-20T14:31:08.283845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visual Inspection","metadata":{"trusted":true}},{"cell_type":"code","source":"def read_imgs(paths):\n    return [plt.imread(a) for a in paths]\n    \ndef rgby2rgb(rgby_arr):\n    rgby_arr = np.dstack(np.array(rgby_arr))\n    rgb_mat = np.zeros_like(rgby_arr)\n    \n    rgb_mat[:,:,0] = rgby_arr[:,:,0] + rgby_arr[:,:,3]\n    rgb_mat[:,:,1] = rgby_arr[:,:,1] + rgby_arr[:,:,3]/2\n    rgb_mat[:,:,2] = rgby_arr[:,:,2]\n    \n    return rgb_mat[:,:,:3]","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:08.287048Z","iopub.execute_input":"2021-05-20T14:31:08.287511Z","iopub.status.idle":"2021-05-20T14:31:08.298326Z","shell.execute_reply.started":"2021-05-20T14:31:08.287465Z","shell.execute_reply":"2021-05-20T14:31:08.296909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for entry in range(0, 19):    \n    num = 10\n    if entry == 11:\n        continue \n        \n    try:\n        #Find Separate Channel Iamge Files per class\n        i_sample = df_train[df_train.Label == str(entry)].iloc[:num]\n    except:\n        continue\n\n    fig, axs = plt.subplots(1, num, figsize =(30,30))\n\n    train_imgs = [os.path.join(TRAIN_PATHS, ex[1].ID) + \"_green.png\" for ex in i_sample.iterrows()]\n    img_list = read_imgs(train_imgs)\n\n    #Display individual RGBY channels\n    for item_i in range(num):\n        if item_i == len(img_list):\n            break\n        img_mat = np.zeros(list(img_list[item_i].shape) + [3])\n        img_mat[:,:,1] = img_list[item_i]\n        axs[item_i].imshow(img_mat)\n\n    plt.suptitle(l_dict[entry], fontsize=16, y=0.55)\n    plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[])\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:31:08.29964Z","iopub.execute_input":"2021-05-20T14:31:08.299958Z","iopub.status.idle":"2021-05-20T14:34:53.437761Z","shell.execute_reply.started":"2021-05-20T14:31:08.299928Z","shell.execute_reply":"2021-05-20T14:34:53.436541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"titles = ['Microtubules','Proteins of Interest', 'Nuclei', 'Endoplasmic Reticulums', 'Blended']\n\nfor entry in range(0, 19):    \n    for i in range(0, 3):        \n        try:\n            #Find Separate Channel Iamge Files per class\n            i_sample = df_train[df_train.Label == str(entry)].iloc[i]\n        except:\n            continue\n\n        fig, axs = plt.subplots(1, 5, figsize =(30,30))\n\n        train_imgs = [os.path.join(TRAIN_PATHS, i_sample.ID)+ colour for colour in colours]\n        img_list = read_imgs(train_imgs)\n\n        #Display individual RGBY channels\n        for channel in range(4):\n            img_mat = np.zeros(list(img_list[channel].shape) + [3])\n\n            if channel != 3:\n                img_mat[:,:,channel] = img_list[channel]\n            else:\n                img_mat[:,:,0] = img_list[channel] \n                img_mat[:,:,1] = img_list[channel]\n\n            axs[channel].imshow(img_mat)\n\n        #Display blended image\n        blended_img = rgby2rgb(img_list)\n        axs[4].imshow(blended_img)\n\n        plt.suptitle(l_dict[int(i_sample.Label)], fontsize=16, y=0.6)\n\n        #Set subplot titles\n        for ti, t in enumerate(titles):\n            axs[ti].set_title(t)\n\n        plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[])\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:34:53.440248Z","iopub.execute_input":"2021-05-20T14:34:53.440903Z","iopub.status.idle":"2021-05-20T14:41:16.052223Z","shell.execute_reply.started":"2021-05-20T14:34:53.440854Z","shell.execute_reply":"2021-05-20T14:41:16.05113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Datset Prep\nThe rest of the notebook will require TPU support.","metadata":{}},{"cell_type":"code","source":"!pip install efficientnet -q\nimport tensorflow as tf\nimport efficientnet.tfkeras as efn\n\ndef auto_select_accelerator():\n    try:\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n        tf.config.experimental_connect_to_cluster(tpu)\n        tf.tpu.experimental.initialize_tpu_system(tpu)\n        strategy = tf.distribute.experimental.TPUStrategy(tpu)\n        print(\"Running on TPU:\", tpu.master())\n    except ValueError:\n        strategy = tf.distribute.get_strategy()\n    print(f\"Running on {strategy.num_replicas_in_sync} replicas\")\n    \n    return strategy\n\n\ndef build_decoder(with_labels=True, target_size=(256, 256), ext='png'):\n    def decode(path):\n        file_bytes = tf.io.read_file(path)\n\n        if ext == 'png':\n            img = tf.image.decode_png(file_bytes, channels=3)\n        elif ext in ['jpg', 'jpeg']:\n            img = tf.image.decode_jpeg(file_bytes, channels=3)\n        else:\n            raise ValueError(\"Image extension not supported\")\n        img = tf.cast(img, tf.float32) / 255.0\n        img = tf.image.resize(img, target_size)\n\n        return img\n    \n    def decode_with_labels(path, label):\n        return decode(path), label\n    \n    return decode_with_labels if with_labels else decode\n\n\ndef build_augmenter(with_labels=True):\n    def augment(img):\n        img = tf.image.random_flip_left_right(img)\n        img = tf.image.random_flip_up_down(img)\n        return img\n    \n    def augment_with_labels(img, label):\n        return augment(img), label\n    \n    return augment_with_labels if with_labels else augment\n\n\ndef build_dataset(paths, labels=None, bsize=128, cache=True,\n                  decode_fn=None, augment_fn=None,\n                  augment=True, repeat=True, shuffle=1024, \n                  cache_dir=\"\"):\n    if cache_dir != \"\" and cache is True:\n        os.makedirs(cache_dir, exist_ok=True)\n    \n    if decode_fn is None:\n        decode_fn = build_decoder(labels is not None)\n    \n    if augment_fn is None:\n        augment_fn = build_augmenter(labels is not None)\n    \n    AUTO = tf.data.experimental.AUTOTUNE\n    slices = paths if labels is None else (paths, labels)\n    \n    dset = tf.data.Dataset.from_tensor_slices(slices)\n    dset = dset.map(decode_fn, num_parallel_calls=AUTO)\n    dset = dset.cache(cache_dir) if cache else dset\n    dset = dset.map(augment_fn, num_parallel_calls=AUTO) if augment else dset\n    dset = dset.repeat() if repeat else dset\n    dset = dset.shuffle(shuffle) if shuffle else dset\n    dset = dset.batch(bsize).prefetch(AUTO)\n    \n    return dset\n\nstrategy = auto_select_accelerator()\nBATCH_SIZE = strategy.num_replicas_in_sync * 16","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:41:17.450196Z","iopub.execute_input":"2021-05-20T14:41:17.450659Z","iopub.status.idle":"2021-05-20T14:41:33.695838Z","shell.execute_reply.started":"2021-05-20T14:41:17.450622Z","shell.execute_reply":"2021-05-20T14:41:33.694825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label2id_dict = {\n 'Nucleoplasm': 0,\n 'Nuclear Membrane': 1,\n 'Nucleoli': 2,\n 'Nucleoli Fibrillar Center': 3,\n 'Nuclear Speckles': 4,\n 'Nuclear Bodies': 5,\n 'Endoplasmic Reticulum': 6,\n 'Golgi Apparatus': 7,\n 'Intermediate Filaments': 8,\n 'Actin Filaments': 9,\n 'Microtubules': 10,\n 'Mitotic Spindle': 11,\n 'Centrosome': 12,\n 'Plasma Membrane': 13,\n 'Mitochondria': 14,\n 'Aggresome': 15,\n 'Cytosol': 16,\n 'Vesicles': 17,\n 'Negative': 18\n}\n\nload_dir = \"gs://green_channels/\"\n\n#Preprocessing Dataset \ndf = pd.read_csv('../input/classification-label-csv-green/df_green.csv')\nlabel_cols = df.columns[2:21]\npaths = load_dir + df['ID']\nlabels = df[label_cols].values\n\n# df['label_count'] = df.Label.str.split(\"|\").str.len()\n# df = df[df.label_count == 1]\n# df['label_name'] = df[\"Label\"].apply(lambda x: l_dict[int(x)])\n\ndf['path'] = df[\"ID\"].apply(lambda x: load_dir + x + \"\")","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:42:52.689275Z","iopub.execute_input":"2021-05-20T14:42:52.689724Z","iopub.status.idle":"2021-05-20T14:42:52.763487Z","shell.execute_reply.started":"2021-05-20T14:42:52.689689Z","shell.execute_reply":"2021-05-20T14:42:52.762621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_indices = []\nfor i in range(0, 19):\n    idx_list = df[df[\"Label\"] == str(i)].sample(frac=.2).index\n    test_indices.extend(list(idx_list))\n\ntraining_df = df.loc[~df.index.isin(test_indices)]\ntest_df = df.loc[test_indices]\n\nvalid_indices = []\nfor i in range(0, 19):\n    idx_list = training_df[training_df[\"Label\"] == str(i)].sample(frac=.2).index\n    valid_indices.extend(list(idx_list))\n\nvalid_df = training_df.loc[valid_indices]\ntraining_df = training_df.loc[~training_df.index.isin(valid_indices)]\n\nlabel_cols = df.columns[2:21]\n\ntraining_paths = load_dir + training_df['ID']\ntraining_labels = training_df[label_cols].values\n\nvalid_paths = load_dir + valid_df['ID']\nvalid_labels = valid_df[label_cols].values\n\ntest_paths = load_dir + test_df['ID']\ntest_labels = test_df[label_cols].values\n\n\n# training_df[\"img_mean\"] = training_df[\"path\"].apply(lambda x: plt.imread(x).ravel().mean())\n# valid_df[\"img_mean\"] = valid_df[\"path\"].apply(lambda x: plt.imread(x).ravel().mean())\n\n# training_df.to_csv(\"training_df.csv\", index=False)\n# valid_df.to_csv(\"valid_df.csv\", index=False)\n# test_df.to_csv(\"test_df.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:18:59.872907Z","iopub.status.idle":"2021-05-20T14:18:59.873821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def filter_95_percent(target_df):\n    refined_training_df = []\n    target_df[\"Label\"] = target_df[\"Label\"].astype(str)\n    for i in range(0, 19):\n        filtered_df = target_df[target_df[\"Label\"].str.contains(str(i))]\n        mean_stats = filtered_df.describe()[\"img_mean\"]\n\n        max_std = mean_stats[\"mean\"] + (2 * mean_stats[\"std\"])\n        min_std = mean_stats[\"mean\"] - (2 * mean_stats[\"std\"])\n\n        id_list = filtered_df[(filtered_df[\"img_mean\"] >= min_std) & (filtered_df[\"img_mean\"] <= max_std)].index \n        refined_training_df.extend(list(id_list))\n\n    refined_training_df = target_df.loc[set(refined_training_df)]\n    \n    return refined_training_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_cols = df.columns[2:21]\n\nfile_format = \"\"\n\ntraining_df = pd.read_csv(\"../input/dataset-df/training_df.csv\")\ntrain_paths = load_dir + training_df['ID'] + file_format\ntraining_df[\"path\"] = train_paths\ntrain_labels = training_df[label_cols].values\n\nvalid_df = pd.read_csv(\"../input/dataset-df/valid_df.csv\")\nvalid_paths = load_dir + valid_df['ID'] + file_format\nvalid_df[\"path\"] = valid_paths\nvalid_labels = valid_df[label_cols].values\n\ntest_df = pd.read_csv(\"../input/dataset-df/test_df.csv\")\ntest_paths = load_dir + test_df['ID'] + file_format\ntest_df[\"path\"] = test_paths\ntest_labels = test_df[label_cols].values\n\nsample_df = df.sample(frac=0.01)\nsample_paths = load_dir + sample_df['ID'] + file_format\nsample_labels = sample_df[label_cols].values\n\nrefined_training_df = filter_95_percent(training_df)\ntrain_paths = load_dir + refined_training_df['ID'] + file_format\ntrain_labels = refined_training_df[label_cols].values\n\nrefined_valid_df = filter_95_percent(valid_df)\nvalid_paths = load_dir + refined_valid_df['ID'] + file_format\nvalid_labels = refined_valid_df[label_cols].values","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom sklearn.model_selection import train_test_split\n\nIMSIZE = (224, 600)\nIMS = 1\n\ndecoder = build_decoder(with_labels=True, target_size=(IMSIZE[IMS], IMSIZE[IMS]))\ntest_decoder = build_decoder(with_labels=False, target_size=(IMSIZE[IMS], IMSIZE[IMS]))\n\ntrain_dataset = build_dataset(\n    train_paths, train_labels, bsize=BATCH_SIZE, decode_fn=decoder, repeat=True, augment=True\n)\n\nvalid_dataset = build_dataset(\n    valid_paths, valid_labels, bsize=BATCH_SIZE, decode_fn=decoder, \n    repeat=False, shuffle=False, augment=False\n)\n    \ntest_dataset = build_dataset(\n    test_paths, test_labels, bsize=BATCH_SIZE, repeat=False, \n    shuffle=False, augment=False, cache=False,\n    decode_fn=decoder\n)\n\nsample_dataset = build_dataset(\n    sample_paths, sample_labels, bsize=BATCH_SIZE, decode_fn=decoder, \n    repeat=False, shuffle=False, augment=False\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### EfficientNet Training","metadata":{}},{"cell_type":"code","source":"try:\n    n_labels = train_labels.shape[1]\nexcept:\n    n_labels = 1\n    \nwith strategy.scope():\n    model = tf.keras.Sequential([\n        efn.EfficientNetB7(\n            input_shape=(IMSIZE[IMS], IMSIZE[IMS], 3),\n            weights='imagenet',\n            include_top=False),\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(n_labels, activation='sigmoid')\n    ])\n    model.compile(\n        optimizer = tf.keras.optimizers.Adam(),\n        loss = tf.keras.losses.BinaryCrossentropy(),\n        metrics=[tf.keras.metrics.AUC(multi_label=True)])\n        \n    model.summary()\n    \n# model_path = \"model_path\"\n# model = tf.keras.models.load_model(model_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_weight = {}\nimg_count = len(training_df)\n\nfor i in range(0, 19):\n    count_i = training_df[str(i)].value_counts()[1]\n    weight = 1 - count_i / img_count\n    class_weight[i] = weight\n    \nclass_weight","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"steps_per_epoch = train_paths.shape[0] // BATCH_SIZE\ncheckpoint = tf.keras.callbacks.ModelCheckpoint(f'prefileter_CE.h5', save_best_only=True, monitor='val_loss', mode='min')\nlr_reducer = tf.keras.callbacks.ReduceLROnPlateau(monitor=\"val_loss\", patience=3, min_lr=1e-6, mode='auto')\nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)\n\nhistory = model.fit(\n    train_dataset, \n    epochs=20,\n    verbose=1,\n    callbacks = [checkpoint, lr_reducer, early_stopping],\n    steps_per_epoch=steps_per_epoch,\n    class_weight = class_weight,\n    validation_data=valid_dataset\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Performance Evaluation","metadata":{}},{"cell_type":"code","source":"import seaborn as sn\nfrom sklearn.metrics import classification_report, confusion_matrix\n\nprediction_probs = model.predict(test_dataset, verbose=1)\nprediction_classes = np.argmax(prediction_probs, axis=-1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_true = list(test_df[\"Label\"])\ny_true = list(map(lambda x: int(x), y_true))\n\ncmat = confusion_matrix(y_true, prediction_classes)\nfigure = plt.figure(figsize=(12,12))\nsn.heatmap(cmat,annot=True, fmt='')\nprint(classification_report(y_true, prediction_classes))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Color Histogram Distribution","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport cv2 as cv\nfrom matplotlib import pyplot as plt\nfrom collections import defaultdict\nfrom tqdm import tqdm \n\nfor img_path in tqdm(list(training_df[\"path\"])[:30]):\n    img = plt.imread(img_path,0)\n    img_ravel = img.ravel()\n    hist, bins = np.histogram(img.ravel(),256,[0,256])    \n    plt.hist(img_ravel, 10)\n    plt.axvline(img_ravel.mean(), color='k', linestyle='dashed', linewidth=1)\n    plt.show()\n    \n    plt.imshow(img)\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm \n\nmin_val = 0.00\nmax_val = 0.3\npath_list = list(training_df[(training_df[\"img_mean\"] <= min_val) | (training_df[\"img_mean\"] >= max_val)] [\"path\"])\nprint(len(path_list))\n\nfor idx, img_path in tqdm(enumerate(path_list)):\n    img = plt.imread(img_path,0)\n    plt.imshow(img)\n    plt.show()\n    if idx == 20:\n        break","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.manifold import TSNE\nfrom collections import defaultdict\n\nhist_embedded = TSNE(n_components=2).fit_transform(hist_list)\n\nhist_dict = defaultdict(list)\n\nfig = plt.figure(figsize=(20,20))\n\nfor idx, i in enumerate(list(training_df[\"Label\"][:100])):\n    hist_dict[int(i)].append(hist_embedded[idx])\n    \nimg_paths = list(training_df[\"path\"])[:100]\n\nfor i in range(0, 19):\n    points = np.array(hist_dict[i])\n    if len(points):\n        plt.scatter(points[:,0], points[:,1])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Clustering","metadata":{}},{"cell_type":"code","source":"try:\n    n_labels = train_labels.shape[1]\nexcept:\n    n_labels = 1\n    \nwith strategy.scope():\n    model = tf.keras.Sequential([\n        efn.EfficientNetB7(\n            input_shape=(IMSIZE[IMS], IMSIZE[IMS], 3),\n            weights='imagenet',\n            include_top=False),\n        tf.keras.layers.GlobalAveragePooling2D(),\n    ])\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(),\n        loss = tf.keras.losses.BinaryCrossentropy(),\n        metrics=[\"categorical_accuracy\"])\n        \n    model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_raw = model.predict(sample_dataset)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.manifold import TSNE\nfrom sklearn.decomposition import PCA\nfrom collections import defaultdict\n\nX_embedded = TSNE(n_components=2).fit_transform(X_raw)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib.offsetbox import OffsetImage, AnnotationBbox\n\ndef getImage(path):\n    return OffsetImage(plt.imread(path), zoom=0.02)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_dict = defaultdict(list)\n\nfig = plt.figure(figsize=(5,5))\nfor idx, i in enumerate(list(sample_df[\"Label\"])):\n    cat_dict[int(i)].append(X_embedded[idx])\n    \ncounter = 0\nimg_paths = list(df[\"path\"])\n\nfor i in range(0, 19):\n    points = np.array(cat_dict[i])\n    if len(points):\n        plt.scatter(points[:,0], points[:,1])\n        \nplt.title(\"EfficientNet B7 Embeddings - t-SNE\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"###  SIFT-BOVW Representation","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport cv2 as cv\nimport matplotlib.pyplot as plt\n\ndef load_images_from_folder(paths):\n    images = []\n    for p in paths:\n        img = cv.imread(p,0) \n        images.append(img)\n    return images\n\nimages = load_images_from_folder(sample_df[\"path\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm \n\ndef sift_features(images):\n    sift_vectors = []\n    descriptor_list = []\n    sift = cv.SIFT_create()\n    keypt_list = []\n    for img in tqdm(images):\n        kp, des = sift.detectAndCompute(img,None)\n        \n        for d in des:\n            descriptor_list.append(d)\n        \n        sift_vectors.append(des)\n        keypt_list.append(kp)\n    return descriptor_list, sift_vectors, keypt_list\n\ndescriptor_list, desc_vectors, keypt_vectors = sift_features(images) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.cluster import MiniBatchKMeans\n\nk = 100\nbatch_size = len(desc_vectors) * 3\nkmeans = MiniBatchKMeans(n_clusters=k, batch_size=batch_size, verbose=0).fit(descriptor_list)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kmeans.verbose = False\n\nhisto_list = []\n\nfor kp, des in zip(keypt_vectors, desc_vectors):\n    histo = np.zeros(k)\n    nkp = np.size(kp)\n\n    for d in des:\n        idx = kmeans.predict([d])\n        histo[idx] += 1/nkp # Because we need normalized histograms, I prefere to add 1/nkp directly\n\n    histo_list.append(histo)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.manifold import TSNE\n\nhist_tsne = TSNE(n_components=2).fit_transform(histo_list)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict\n\nbovw_dict = defaultdict(list)\nfig = plt.figure(figsize=(5,5))\n\nfor idx, i in enumerate(list(sample_df[\"Label\"])):\n    bovw_dict[int(i)].append(hist_tsne[idx])\n    \nfor i in range(0, 19):\n    points = np.array(bovw_dict[i])\n    if len(points):\n        plt.scatter(points[:,0], points[:,1])\n\nplt.title(\"SIFT-BOVW - t-SNE\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Fine-tuned EfficientNet Embeddings","metadata":{}},{"cell_type":"code","source":"from keras.models import Model\n\nmodel_path = \"../input/hpa-classification-efnb7-train/model_green.h5\"\nmodel = tf.keras.models.load_model(model_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model= Model(inputs=model.input, outputs=model.layers[-1].output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"decoder = build_decoder(with_labels=True, target_size=(600, 600))\nsample_dataset = build_dataset(\n    sample_paths, sample_labels, bsize=BATCH_SIZE, decode_fn=decoder, \n    repeat=False, shuffle=False, augment=False\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fine_tuned_embeddings = model.predict(sample_dataset)\nfine_tsne = TSNE(n_components=2).fit_transform(fine_tuned_embeddings)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib.offsetbox import OffsetImage, AnnotationBbox\n\ndef getImage(path):\n    return OffsetImage(plt.imread(path), zoom=0.02)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fine_tsne_dict = defaultdict(list)\nfig = plt.figure(figsize=(5,5))\n\nfor idx, i in enumerate(list(sample_df[\"Label\"])):\n    fine_tsne_dict[int(i)].append(fine_tsne[idx])\n        \ncounter = 0\nimg_paths = list(sample_df[\"path\"])\n\nfor i in range(0, 19):\n    points = np.array(fine_tsne_dict[i])\n    if len(points):\n        plt.scatter(points[:,0], points[:,1])\n\nplt.title(\"Fine-tuned EfficientNet Embeddings - t-SNE\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### U-Net","metadata":{}},{"cell_type":"code","source":"!pip install keras-unet","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras_unet.models import vanilla_unet\nfrom keras.models import Model\nfrom sklearn.manifold import TSNE\n\ndecoder = build_decoder(with_labels=True, target_size=(240, 240))\nsample_dataset = build_dataset(\n    sample_paths, sample_labels, bsize=BATCH_SIZE, decode_fn=decoder, \n    repeat=False, shuffle=False, augment=False\n)\n\nmodel = vanilla_unet(input_shape=(240, 240, 3))\nmodel_layer = Model(inputs=model.input, outputs=model.layers[-1].output)\nmodel = tf.keras.Sequential([\n        model_layer,\n        tf.keras.layers.GlobalMaxPooling2D()\n    ])\n\nunet_embeddings = model.predict(sample_dataset)\nunet_tsne = TSNE(n_components=2).fit_transform(unet_embeddings)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(5,5))\n\nunet_tsne_dict = defaultdict(list)\n\nfor idx, i in enumerate(list(sample_df[\"Label\"])):\n    unet_tsne_dict[int(i)].append(unet_tsne[idx])\n    \nfor i in range(0, 19):\n    points = np.array(unet_tsne_dict[i])\n    if len(points):\n        plt.scatter(points[:,0], points[:,1])\n        \nplt.title(\"UNet Embeddings - t-SNE\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Individual Cell Segmentation","metadata":{}},{"cell_type":"code","source":"!pip install -q \"../input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\"\n!pip install -q \"../input/hpapytorchzoozip/pytorch_zoo-master\"\n!pip install -q \"../input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"\nimport hpacellseg.cellsegmentator as cellsegmentator\nfrom hpacellseg.utils import label_cell\n\nsingle_label_images = df_train[df_train[\"Label Count\"] == 1]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def format4segmentator(train_paths, n=4):\n    \"\"\"\n    restructures the image paths into a list of lists\n    \"\"\"\n    zipped = list(map(list, zip(*train_paths[:n])))\n    return [zipped[0], zipped[3], zipped[2]]\n    \nsample_list = format4segmentator(train_paths)\nsample_list","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"segmentator = cellsegmentator.CellSegmentator(\n    \"./nuclei-model.pth\",\n    \"./cell-model.pth\",\n    scale_factor=0.25,\n    device=\"cuda\",\n    padding=False,\n    multi_channel_model=True,\n)\n\n# For nuclei\nnuc_segmentations = segmentator.pred_nuclei(sample_list[2])\n\n# For full cells\ncell_segmentations = segmentator.pred_cells(sample_list)\n\n# post-processing\nnuclei_mask = label_nuclei(nuc_segmentations[0])\nnuclei_mask, cell_mask = label_cell(nuc_segmentations[0], cell_segmentations[0])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Show the original image\nimg = rgby2rgb(read_imgs(train_paths[0]))\nplt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T14:41:16.05433Z","iopub.execute_input":"2021-05-20T14:41:16.054699Z","iopub.status.idle":"2021-05-20T14:41:17.448336Z","shell.execute_reply.started":"2021-05-20T14:41:16.054661Z","shell.execute_reply":"2021-05-20T14:41:17.447322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Calculates the cell contours\ncontours, hierarchy= cv2.findContours(cell_mask.astype('uint8'), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plot individual cells\nfor i in x:\n    cnt = contours[i]\n    ix,yc,w,h = cv2.boundingRect(cnt)\n\n    plt.figure(figsize=(15, 15))\n    plt.subplot(1, 3, 1)\n    plt.imshow(poi[yc:yc+h, ix:ix+w])\n    plt.title('Cell Image')\n    plt.axis('off')\n\n    plt.subplot(1, 3, 2)\n    plt.imshow(cell_mask[yc:yc+h, ix:ix+w])\n    plt.title('Cell Mask')\n    plt.axis('off')\n\n    plt.subplot(1, 3, 3)\n    plt.imshow(poi[yc:yc+h, ix:ix+w])\n    plt.imshow(cell_mask[yc:yc+h, ix:ix+w], alpha=0.6)\n    plt.title('Cell Image + Mask')\n    plt.axis('off')\n    plt.show()","metadata":{},"execution_count":null,"outputs":[]}]}