{"cells":[{"metadata":{"_uuid":"7f0565611b70a04b553b465c34cc345d2833f898"},"cell_type":"markdown","source":"# Cellular organelle recognition\n\nDevelop models capable of classifying mixed patterns of proteins in microscope images. An already trained model is located in \"../models/quantity_1.h5\"."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nimport os\noriginal_dataset_dir = \"../input\"\nprint(os.listdir(original_dataset_dir))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"52ea23437ff4f3ec2553b7410b16674a0a540b77"},"cell_type":"markdown","source":"# Data description\n* The folders 'train' and 'test' contain PNG files (512 x 512). All image samples are represented by four filters (stored as individual files), the protein of interest (green) plus three cellular landmarks: nucleus (blue), microtubules (red), endoplasmic reticulum (yellow). The green filter should hence be used to predict the label, and the other filters are used as references.\n* The names of the files in 'train' appear in 'train.csv' together with the organelles present in that image. These labels are encoded with a non-negative integer less 28. "},{"metadata":{"trusted":true,"_uuid":"50b35e4aa29b77187bb42059bed4abf926e2e711","_kg_hide-output":false,"_kg_hide-input":true},"cell_type":"code","source":"target_names = {\n    0:  \"Nucleoplasm\",  \n    1:  \"Nuclear membrane\",   \n    2:  \"Nucleoli\",   \n    3:  \"Nucleoli fibrillar center\",   \n    4:  \"Nuclear speckles\",\n    5:  \"Nuclear bodies\",   \n    6:  \"Endoplasmic reticulum\",   \n    7:  \"Golgi apparatus\",   \n    8:  \"Peroxisomes\",   \n    9:  \"Endosomes\",   \n    10:  \"Lysosomes\",   \n    11:  \"Intermediate filaments\",   \n    12:  \"Actin filaments\",   \n    13:  \"Focal adhesion sites\",   \n    14:  \"Microtubules\",   \n    15:  \"Microtubule ends\",   \n    16:  \"Cytokinetic bridge\",   \n    17:  \"Mitotic spindle\",   \n    18:  \"Microtubule organizing center\",   \n    19:  \"Centrosome\",   \n    20:  \"Lipid droplets\",   \n    21:  \"Plasma membrane\",   \n    22:  \"Cell junctions\",   \n    23:  \"Mitochondria\",   \n    24:  \"Aggresome\",   \n    25:  \"Cytosol\",   \n    26:  \"Cytoplasmic bodies\",   \n    27:  \"Rods & rings\"\n}\n\ntarget_numbers = dict((v,int(k)) for k,v in target_names.items())\n\ntarget_names","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8e176949fe4b917e66ea7d48a27c2edcd0322c77"},"cell_type":"markdown","source":"Importing and inspecting the csv files"},{"metadata":{"trusted":true,"_uuid":"ea1513e8bf29da6a5d947ffdff203813949fbe95","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"train_data = pd.read_csv('../input/train.csv')\ntrain_data.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"30d06607dc3035228837547d5c9301450c9580fd"},"cell_type":"markdown","source":"   How many images?"},{"metadata":{"trusted":true,"_uuid":"2d7ae73db2b77405f99f88bdc50bba0499f84800","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"num_samples = train_data.shape[0]\nnum_samples","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a55366fe8304817b96fb41541652a793ce0bf28e"},"cell_type":"markdown","source":"An alternative representation of the train data "},{"metadata":{"_kg_hide-output":false,"_kg_hide-input":true,"trusted":true,"_uuid":"692e16908b42ba50e711d45adbcf125aabdd9aad"},"cell_type":"code","source":"for target in target_names.keys() :\n    train_data[target_names[target]] = 0\n\ndef fill_rows(row) :\n    row.Target = np.array(row.Target.split(\" \")).astype(np.int)\n    for num in row.Target:\n        name = target_names[int(num)]\n        row.loc[name] = int(1)\n    return row\n\ntrain_data = train_data.apply(fill_rows, axis=1)\ntrain_data.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"de36c185748d3a09a268bfdec5cacbfceacc7b37"},"cell_type":"markdown","source":"# Looking at a few images"},{"metadata":{"trusted":true,"_uuid":"b1b035dbe1baea7d2a02a59dfff9bdcae8049f91","_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"from imageio import imread\n\ndef load_image(basepath, image_id):\n    images = np.zeros(shape=(4,512,512))\n    images[0,:,:] = imread(basepath + image_id + \"_green\" + \".png\")\n    images[1,:,:] = imread(basepath + image_id + \"_red\" + \".png\")\n    images[2,:,:] = imread(basepath + image_id + \"_blue\" + \".png\")\n    images[3,:,:] = imread(basepath + image_id + \"_yellow\" + \".png\")\n    return images\n\ndef make_image_row(image, subax, title=\"Title\"):\n    subax[0].imshow(image[0], cmap=\"Greens\")\n    subax[1].imshow(image[1], cmap=\"Reds\")\n    subax[1].set_title(\"stained microtubules\")\n    subax[2].imshow(image[2], cmap=\"Blues\")\n    subax[2].set_title(\"stained nucleus\")\n    subax[3].imshow(image[3], cmap=\"Oranges\")\n    subax[3].set_title(\"stained endoplasmatic reticulum\")\n    subax[0].set_title(title)\n    return subax\n\ndef make_title(file_id):\n    file_targets = train_data.loc[train_data.Id==file_id, \"Target\"].values[0]\n    title = \" | \"\n    for n in file_targets:\n        title += target_names[n] + \" | \"\n    return title","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2f52857419c83f4e2a6dece114bb25ac40d32c3e","_kg_hide-input":true},"cell_type":"code","source":"for row in train_data.iloc[4:7].itertuples() :\n    fig, ax = plt.subplots(1, 4, figsize=(24,24))\n    make_image_row(load_image(\"../input/train/\", row.Id), ax, make_title(row.Id))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"05a76e29c5df7f6779f57a03b00809d3221c5b93"},"cell_type":"markdown","source":"# The prior probability of seeing a given organelle"},{"metadata":{"trusted":true,"_uuid":"b72cfd6e59d08688aef3d9d5686e5005fecf69ac","_kg_hide-input":true},"cell_type":"code","source":"target_prob = train_data.drop([\"Id\", \"Target\"],axis=1).sum(axis=0).sort_values(ascending=False)\nplt.figure(figsize=(20,10))\nsns.barplot(y=target_prob.index.values, x=(target_prob.values)/num_samples, palette=\"Blues_d\")\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6f6ba4034985b1c33cbd0cacf4116c79c7382150"},"cell_type":"markdown","source":"# The prior probability for of seeing a given number of distinct types of organelles"},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"49d7dcead7d44d0050ccb040cae597d8a02be4ff","_kg_hide-input":true},"cell_type":"code","source":"train_data[\"Quantity\"] = train_data.drop([\"Id\", \"Target\"],axis=1).sum(axis=1)\ncount = train_data[\"Quantity\"].value_counts()\nplt.figure(figsize=(15,5))\nsns.barplot(y=(count.values)/num_samples, x=count.index.values, palette=\"ch:2.5,-.2,dark=.3\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"90ec09ae13269cb51ba4aa19bd8a5b55bcb05156"},"cell_type":"markdown","source":" # Building a convet to predict the number of distinct substructures present in an image\n ###### At this stage of development we will use the green images only."},{"metadata":{"trusted":true,"_uuid":"7b72383abe547bfb9c1c52ec49f25c57f7f1d454","_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"train_data[\"Id_green\"] = train_data['Id'].apply(lambda row: row + '_green')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"77b744fd39f865332c7260dcb744d3a99fbd78dc"},"cell_type":"markdown","source":"## Preprocessing and Generating Data\n###### We will use Keras ImageDataGenerator to pass batches of preprocessed images to our model."},{"metadata":{"trusted":true,"_uuid":"127d9c73fcbbc1c795a54a90a845f063f8302b24","_kg_hide-input":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ndatagen=ImageDataGenerator(rescale=1./255.,validation_split=0.25)\n\ntrain_generator=datagen.flow_from_dataframe(\n                dataframe=train_data,\n                directory=\"../input/train/\",\n                x_col=\"Id_green\",\n                y_col=\"Quantity\",\n                has_ext=False,                                      \n                subset=\"training\",\n                batch_size=64,\n                seed=42,\n                shuffle=True,\n                class_mode=\"categorical\",\n                target_size=(512,512),\n                color_mode = 'grayscale')\n\nvalidation_generator=datagen.flow_from_dataframe(\n                dataframe=train_data,\n                directory=\"../input/train/\",\n                x_col=\"Id_green\",\n                y_col=\"Quantity\",\n                has_ext=False,\n                subset=\"validation\",\n                batch_size=64,\n                seed=42,\n                shuffle=True,\n                class_mode=\"categorical\",\n                target_size=(512,512),\n                color_mode = 'grayscale')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cc3ffa0cda95f722b8ba39ceaf50e9723767d5b5","_kg_hide-input":true},"cell_type":"code","source":"for data_batch, labels_batch in train_generator:\n    print('data batch shape:', data_batch.shape)\n    print('labels batch shape:', labels_batch.shape)\n    break","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2948e98389ad7e3cf9afa96b7c0a464e01743587"},"cell_type":"markdown","source":"### We use a sequential convolutional network\n###### Let us train the network or load it"},{"metadata":{"trusted":true,"_uuid":"71d1e1df4c5969eccd72d3d36147e3847a627136","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"from keras import Sequential\nfrom keras import layers, models\nfrom keras import optimizers\n\nmodel = models.Sequential()\n\nmodel.add(layers.Conv2D(32, (3, 3), activation='relu',\n                        input_shape=(512, 512, 1)))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(64, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dense(5, activation='sigmoid'))\n\nprint(model.summary())\n\nmodel.compile(loss='categorical_crossentropy',\n          optimizer=optimizers.RMSprop(lr=1e-4),\n          metrics=['acc'])\n\nhistory = model.fit_generator(\n      train_generator,\n      steps_per_epoch=300,\n      epochs=8,\n      validation_data=validation_generator,\n      validation_steps=80,\n      use_multiprocessing=True,\n      workers=8)\n\nmodel.save('quantity_1.h5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9a0a71050646cf3f5df7824066113042d769c38f"},"cell_type":"markdown","source":"#### Plotting the history of the model"},{"metadata":{"trusted":true,"_uuid":"79f3908ab269f5bd5bc134d1bf56d72f938c573a","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}