{"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":"# Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nfrom tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.utils import load_img, img_to_array, array_to_img\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications.imagenet_utils import preprocess_input, decode_predictions\n\nimport cv2\nimport time\nfrom tqdm.notebook import tqdm\n\nfrom sklearn.metrics.pairwise import cosine_distances,pairwise_distances,cosine_similarity","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-02T14:30:24.715039Z","iopub.execute_input":"2022-12-02T14:30:24.715405Z","iopub.status.idle":"2022-12-02T14:30:24.722692Z","shell.execute_reply.started":"2022-12-02T14:30:24.715375Z","shell.execute_reply":"2022-12-02T14:30:24.721783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Get Semisupervised Data","metadata":{}},{"cell_type":"code","source":"SEMI_PATH = r\"/kaggle/input/sartorius-cell-instance-segmentation/train_semi_supervised\"","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:30:25.391778Z","iopub.execute_input":"2022-12-02T14:30:25.392604Z","iopub.status.idle":"2022-12-02T14:30:25.396427Z","shell.execute_reply.started":"2022-12-02T14:30:25.392575Z","shell.execute_reply":"2022-12-02T14:30:25.395428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Amount of semisupervised images: \", len(os.listdir(SEMI_PATH)))","metadata":{"execution":{"iopub.status.busy":"2022-12-02T15:20:45.162036Z","iopub.execute_input":"2022-12-02T15:20:45.162430Z","iopub.status.idle":"2022-12-02T15:20:45.170191Z","shell.execute_reply.started":"2022-12-02T15:20:45.162399Z","shell.execute_reply":"2022-12-02T15:20:45.168937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper Functions","metadata":{}},{"cell_type":"code","source":"def get_image_embedding(model, img_path):\n    \"\"\"\n    Returns image embedding as a pandas dataframe\n    \n    Args:\n        model: a desired model for prediction\n        img_path: a str that specifies location of image file\n    \"\"\"\n    image = load_img(img_path, target_size=(224, 224))\n    image = img_to_array(image)\n    image = np.expand_dims(image, axis=0) # (no.samples, h, w, c)\n    image = preprocess_input(image)\n    pred = model.predict(image)\n    pred_df = pd.DataFrame(pred[0]).T\n    return pred_df","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:30:25.886514Z","iopub.execute_input":"2022-12-02T14:30:25.887091Z","iopub.status.idle":"2022-12-02T14:30:25.892531Z","shell.execute_reply.started":"2022-12-02T14:30:25.887059Z","shell.execute_reply":"2022-12-02T14:30:25.891542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_img(img_path, title):\n    #img_path = SEMI_PATH + str(image_name)\n    im = cv2.imread(img_path)\n    im = cv2.resize(im, (224, 224))\n    plt.axis('off')\n    plt.imshow(im[:,:,::-1])\n    plt.title(title)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-02T15:21:25.243944Z","iopub.execute_input":"2022-12-02T15:21:25.244304Z","iopub.status.idle":"2022-12-02T15:21:25.250652Z","shell.execute_reply.started":"2022-12-02T15:21:25.244274Z","shell.execute_reply":"2022-12-02T15:21:25.249646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fetch_most_similar_images(image_name, n_similar=7):\n    \"\"\"\n    Plots specified n similar images\n    \n    Args:\n        image_name: a str that is path to image\n        n_similar: an int that is the number of plotted similar images\n    \"\"\"\n    print(\"=\"*42*2)\n    print(\"Original Cell\")\n    show_img(image_name, image_name)\n    print(\"=\"*42*2)\n    curr_idx = img_embedding_df[img_embedding_df[\"image\"] == image_name].index[0]\n    closest_img = pd.DataFrame(cos_sim_df.iloc[curr_idx].nlargest(n_similar+1)[1:])\n    print(\"Similar Cells\", image_name)\n    for idx, image in (closest_img).iterrows():\n        sim_img_name = img_embedding_df.iloc[idx][\"image\"]\n        sim = np.round(image.iloc[0], 3)\n        title = str(\"Image: \" + sim_img_name + \"\\nSimilarity: \" + str(sim) + \"%\")\n        show_img(sim_img_name, title)\n    print(\"*\"*42*2)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:18:04.094037Z","iopub.execute_input":"2022-12-02T16:18:04.095423Z","iopub.status.idle":"2022-12-02T16:18:04.105376Z","shell.execute_reply.started":"2022-12-02T16:18:04.095380Z","shell.execute_reply":"2022-12-02T16:18:04.103934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fetch_least_similar_images(image_name, n_similar=7):\n    \"\"\"\n    Plots specified n similar images\n    \n    Args:\n        image_name: a str that is path to image\n        n_similar: an int that is the number of plotted similar images\n    \"\"\"\n    print(\"=\"*42*2)\n    print(\"Original Cell:\")\n    show_img(image_name,image_name)\n    print(\"=\"*42*2)\n    curr_idx = img_embedding_df[img_embedding_df[\"image\"] == image_name].index[0]\n    closest_img = pd.DataFrame(cos_sim_df.iloc[curr_idx].nsmallest(n_similar+1)[1:])\n    print(\"Different Cells\", image_name)\n    for idx, image in (closest_img).iterrows():\n        sim_img_name = img_embedding_df.iloc[idx][\"image\"]\n        sim = np.round(image.iloc[0], 3)\n        title = str(\"Image: \" + sim_img_name + \"\\nSimilarity: \" + str(sim) + \"%\")\n        show_img(sim_img_name, title)\n    print(\"*\"*42*2)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:18:04.379372Z","iopub.execute_input":"2022-12-02T16:18:04.380488Z","iopub.status.idle":"2022-12-02T16:18:04.388270Z","shell.execute_reply.started":"2022-12-02T16:18:04.380444Z","shell.execute_reply":"2022-12-02T16:18:04.387291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Find Image Embeddings","metadata":{}},{"cell_type":"code","source":"model = ResNet50(include_top=False, weights=\"imagenet\", pooling=\"avg\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:30:26.058623Z","iopub.execute_input":"2022-12-02T14:30:26.059014Z","iopub.status.idle":"2022-12-02T14:30:27.474218Z","shell.execute_reply.started":"2022-12-02T14:30:26.058985Z","shell.execute_reply":"2022-12-02T14:30:27.473275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sanity check\nsample_path = \"/kaggle/input/sartorius-cell-instance-segmentation/train_semi_supervised/astro[hippo]_D1-1_Vessel-361_2020-09-14_13h00m00s_Ph_1.png\"\n\n# second last layer of resnet50 has 2048 vector size\nget_image_embedding(model, sample_path)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:30:27.669447Z","iopub.execute_input":"2022-12-02T14:30:27.669861Z","iopub.status.idle":"2022-12-02T14:30:28.723474Z","shell.execute_reply.started":"2022-12-02T14:30:27.669821Z","shell.execute_reply":"2022-12-02T14:30:28.721588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# list of image names\nSEMI_IMG_NAMES = os.listdir(SEMI_PATH)\n\n# empty data frame\nimg_embedding_df = pd.DataFrame()\n\n# get image embeddings and add them to empty df\nfor filename in tqdm(SEMI_IMG_NAMES):\n    img_path = os.path.join(SEMI_PATH, filename)\n    current_df = get_image_embedding(model, img_path)\n    current_df[\"image\"] = img_path\n    img_embedding_df = pd.concat([img_embedding_df, current_df], ignore_index=True)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:30:30.710245Z","iopub.execute_input":"2022-12-02T14:30:30.710868Z","iopub.status.idle":"2022-12-02T14:36:06.696493Z","shell.execute_reply.started":"2022-12-02T14:30:30.710839Z","shell.execute_reply":"2022-12-02T14:36:06.695523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Shape of Image Embeddings: \", img_embedding_df.shape, \"\\n\")\n\nimg_embedding_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-02T15:26:46.277904Z","iopub.execute_input":"2022-12-02T15:26:46.278322Z","iopub.status.idle":"2022-12-02T15:26:46.312143Z","shell.execute_reply.started":"2022-12-02T15:26:46.278290Z","shell.execute_reply":"2022-12-02T15:26:46.309947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Calculate Cosine Similarities","metadata":{}},{"cell_type":"code","source":"# cosine similarity data frame of embeddings\ncos_sim_df = pd.DataFrame(cosine_similarity(img_embedding_df.drop(\"image\", axis=1)))","metadata":{"execution":{"iopub.status.busy":"2022-12-02T14:36:06.775615Z","iopub.execute_input":"2022-12-02T14:36:06.776535Z","iopub.status.idle":"2022-12-02T14:36:06.852680Z","shell.execute_reply.started":"2022-12-02T14:36:06.776498Z","shell.execute_reply":"2022-12-02T14:36:06.851476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Shape of Cosine Similarity Matrix: \", cos_sim_df.shape, \"\\n\")\n\ncos_sim_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-02T15:26:14.823258Z","iopub.execute_input":"2022-12-02T15:26:14.823636Z","iopub.status.idle":"2022-12-02T15:26:14.850833Z","shell.execute_reply.started":"2022-12-02T15:26:14.823604Z","shell.execute_reply":"2022-12-02T15:26:14.850089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Distribution of Cell Types","metadata":{}},{"cell_type":"code","source":"cell_paths = {}\n\nfor filename in SEMI_IMG_NAMES:\n    cell_type = filename.split(\"_\")[0]\n    if not cell_type in cell_paths:\n        cell_paths[cell_type] = []\n    else:\n        cell_paths[cell_type].append(filename)\n        \nprint(\"Cell types\\n\\n\", list(cell_paths.keys()))","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:14:18.539373Z","iopub.execute_input":"2022-12-02T16:14:18.539783Z","iopub.status.idle":"2022-12-02T16:14:18.547890Z","shell.execute_reply.started":"2022-12-02T16:14:18.539747Z","shell.execute_reply":"2022-12-02T16:14:18.546936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cell_freqs = {}\n\nfor k in cell_paths.keys():\n    cell_freqs[k] = len(cell_paths[k])\n\ncell_freqs","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:03:29.324911Z","iopub.execute_input":"2022-12-02T16:03:29.325247Z","iopub.status.idle":"2022-12-02T16:03:29.332983Z","shell.execute_reply.started":"2022-12-02T16:03:29.325224Z","shell.execute_reply":"2022-12-02T16:03:29.331680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"freq_df = pd.DataFrame([cell_freqs.keys(), cell_freqs.values()]).T\nfreq_df.rename(columns={0: \"cell_type\",\n                       1: \"count\"}, inplace=True)\n\nfreq_df","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:03:37.245086Z","iopub.execute_input":"2022-12-02T16:03:37.245479Z","iopub.status.idle":"2022-12-02T16:03:37.258391Z","shell.execute_reply.started":"2022-12-02T16:03:37.245449Z","shell.execute_reply":"2022-12-02T16:03:37.257579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15,15))\nsns.barplot(freq_df[\"cell_type\"], freq_df[\"count\"])\nplt.savefig(\"semisupervised_freq.png\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:03:46.832344Z","iopub.execute_input":"2022-12-02T16:03:46.832765Z","iopub.status.idle":"2022-12-02T16:03:47.150185Z","shell.execute_reply.started":"2022-12-02T16:03:46.832718Z","shell.execute_reply":"2022-12-02T16:03:47.148994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualize","metadata":{}},{"cell_type":"markdown","source":"## Heatmap of Cosine Similarities","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(20, 20))\nsns.heatmap(cos_sim_df, cmap=\"BuPu\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T15:04:27.688301Z","iopub.execute_input":"2022-12-02T15:04:27.688689Z","iopub.status.idle":"2022-12-02T15:04:34.008264Z","shell.execute_reply.started":"2022-12-02T15:04:27.688655Z","shell.execute_reply":"2022-12-02T15:04:34.006594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_cos_sim_cells(sim_type=\"most\", rank=5):\n    if sim_type == \"most\":\n        for cell_type in cell_paths.keys():\n            fetch_most_similar_images(os.path.join(SEMI_PATH, cell_paths[cell_type][rank]))\n    \n    elif sim_type == \"least\":\n        for cell_type in cell_paths.keys():\n            fetch_least_similar_images(os.path.join(SEMI_PATH, cell_paths[cell_type][rank]))\n\n    else:\n        print(\"You must pass 'most' or 'least' as similarity type and rank must be an integer.\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:34:36.847580Z","iopub.execute_input":"2022-12-02T16:34:36.847975Z","iopub.status.idle":"2022-12-02T16:34:36.854314Z","shell.execute_reply.started":"2022-12-02T16:34:36.847941Z","shell.execute_reply":"2022-12-02T16:34:36.853401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Plot The Most Similar Cells for Each Type","metadata":{}},{"cell_type":"code","source":"plot_cos_sim_cells(sim_type=\"most\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:34:52.989125Z","iopub.execute_input":"2022-12-02T16:34:52.989480Z","iopub.status.idle":"2022-12-02T16:35:01.838840Z","shell.execute_reply.started":"2022-12-02T16:34:52.989453Z","shell.execute_reply":"2022-12-02T16:35:01.837633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cell_paths.keys()","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:45:32.257375Z","iopub.execute_input":"2022-12-02T16:45:32.257786Z","iopub.status.idle":"2022-12-02T16:45:32.266434Z","shell.execute_reply.started":"2022-12-02T16:45:32.257718Z","shell.execute_reply":"2022-12-02T16:45:32.265139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"######################################################################\n\n### Most Similar Cells by Order\n\n* astro[hippo] : astro[hippo], astros[cereb]\n* shsy5y[diff] : shsy5y[diff]\n* astros[cereb] : astros[cereb]\n* cort[pre-treat] : cort[6-OHDA], cort[density], cort[6-OHDA], cort[pretreat]\n* cort[6-OHDA] : cort[6-OHDA], cort[density], cort[pretreat]\n* cort[density] : cort[density]\n* cort[oka-low] : cort[oka-high], cort[6-OHDA], cort[density], cort[pretreat]\n* cort[oka-high] : cort[oka-low], cort[6-OHDA], cort[density]\n* cort[debris] : cort[density], cort[debris], cort[pre-treat]\n\n######################################################################\n","metadata":{}},{"cell_type":"markdown","source":"## Plot The Least Similar Cells for Each Type","metadata":{}},{"cell_type":"code","source":"plot_cos_sim_cells(sim_type=\"least\")","metadata":{"execution":{"iopub.status.busy":"2022-12-02T16:35:27.828834Z","iopub.execute_input":"2022-12-02T16:35:27.829220Z","iopub.status.idle":"2022-12-02T16:37:05.951157Z","shell.execute_reply.started":"2022-12-02T16:35:27.829188Z","shell.execute_reply":"2022-12-02T16:37:05.950105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"######################################################################\n\n### Least Similar Cells by Order\n\n* astro[hippo] : cort[oka-low], cort[density], shsy5y[diff], cort[debris]\n\n* shsy5y[diff] : astro[hippo], cort[density]\n\n* astros[cereb] : cort[oka-low], shsy5y[diff], astro[hippo], cort[debris], cort[density]\n\n* cort[pre-treat] : astros[cereb], astro[hippo]\n\n* cort[6-OHDA] : cort[density], astro[hippo]\n\n* cort[density] : astro[hippo]\n\n* cort[oka-low] : astro[hippo], cort[density], astros[cereb]\n\n* cort[oka-high] : astro[hippo]\n\n* cort[debris] : astros[cereb], astro[hippo]\n\n######################################################################\n","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}