{"cells":[{"metadata":{},"cell_type":"markdown","source":"Human Protein Atlas - Single Cell Classification competition, \nThis is a weakly supervised multi-label classification problem. Given images of cells from our microscopes and labels of protein location assigned together for all cells in the image, We will develop models capable of segmenting and classifying each individual cell with precise labels. \n\nThis starter notebook to get an idea, on how to approach this competition.\n\nNotebooks referred to create this kernel are given the comment of this notebook. If this helped give an upvote."},{"metadata":{},"cell_type":"markdown","source":"# **Importing Libraries**"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os, sys\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport cv2\nimport seaborn as sns\nfrom collections import defaultdict, Counter\nfrom sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\nfrom tensorflow.keras import models, layers\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau,EarlyStopping, ModelCheckpoint\nfrom keras.layers import Input, Flatten, Dense, Conv2D, MaxPooling2D, GlobalAveragePooling2D, Dropout, BatchNormalization\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.applications import InceptionV3\nfrom keras.optimizers import Adam\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **BASIC EDA**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_path=\"../input/hpa-single-cell-image-classification/train.csv\"\ntrain_images_path=\"../input/hpa-single-cell-image-classification/train\"\ntest_images_path=\"../input/hpa-single-cell-image-classification/test\"\nsample_df_path=\"../input/hpa-single-cell-image-classification/sample_submission.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df=pd.read_csv(train_df_path)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset= []\nfor name, labels in zip(train_df['ID'], train_df['Label'].str.split('|')):\n    train_dataset.append({\n        'path':os.path.join(train_images_path, name),\n        'labels':np.array([int(label) for label in labels])})\ntrain_dataset= np.array(train_dataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df[\"nb_labels\"] = train_df[\"Label\"].apply(lambda x: len(x.split(\"|\")))\nprint(f\"Max number of labels attached to a single sample: {train_df['nb_labels'].max()}\")\nprint(f\"Min  number of labels attached to a single sample: {train_df['nb_labels'].min()}\")\nprint(50*\"-\")\nprint(\"All counts:\")\nprint(50*\"-\")\nprint(train_df[\"nb_labels\"].value_counts())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set(rc={'figure.figsize':(15,5)})\nsns.set_style('whitegrid')\n\nva=sns.countplot(y=\"nb_labels\",data=train_df,palette=\"flare\")\nplt.xlabel(\"Number of labels\",fontsize=20)\nplt.ylabel(\"Count\",fontsize=20)\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_labels_count = train_df[train_df['nb_labels']==1]['nb_labels'].count()\nmulti_labels_count = train_df[train_df['nb_labels']>1]['nb_labels'].count()\n\n# Plot the value counts for each count\nplt.figure(figsize=(10,5))\nsns.barplot(x=['Single label', 'Multi-label'], y=[single_labels_count, multi_labels_count],palette='flare')\nplt.title(\"Single vs Multi label distribution\", fontsize=16)\nplt.xlabel(\"Label type\", fontsize=16)\nplt.ylabel(\"Count\", fontsize=16)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels_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}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Split the labels\nlabels = train_df[\"Label\"].apply(lambda x: x.split(\"|\"))\n\n# Create a counter. This initializes the count for each class with a value of zero\nlabels_count = defaultdict(int)\n\n# Update the counter \nfor label in labels:\n    if len(labels) > 1:\n        for l in label:\n            labels_count[labels_dict[int(l)]]+=1\n    else:\n        labels_count[labels_dict[int(label)]]+=1\n\n# Plot         \nplt.figure(figsize=(15,10))\nsns.barplot(x=list(labels_count.values()), y=list(labels_count.keys()),palette='flare', orient='h')\nplt.title(\"Distribution of cell types\", fontsize=16)\nplt.xlabel(\"Count\", fontsize=16)\nplt.ylabel(\"Type of cell\", fontsize=16)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **LOADING THE DATASET**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_image(path, shape):\n    R = cv2.imread(path+'_red.png',cv2.IMREAD_UNCHANGED)\n    Y = cv2.imread(path+'_yellow.png',cv2.IMREAD_UNCHANGED)\n    G = cv2.imread(path+'_green.png',cv2.IMREAD_UNCHANGED)\n    B = cv2.imread(path+'_blue.png',cv2.IMREAD_UNCHANGED)\n    image = np.stack((\n            R/2 + Y/2, \n            G/2 + Y/2, \n            B),-1)\n        \n    image = cv2.resize(image, (shape[0], shape[1]))\n    image = np.divide(image, 255)\n    return image  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(load_image(\"../input/hpa-single-cell-image-classification/train/000a6c98-bb9b-11e8-b2b9-ac1f6b6435d0\",(331,331)))\nplt.axis(\"off\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_train(dataset_info, batch_size, shape):\n    assert shape[2] == 3\n    while True:\n        random_indexes = np.random.choice(len(dataset_info), batch_size)\n        batch_images = np.empty((batch_size, shape[0], shape[1], shape[2]))\n        batch_labels = np.zeros((batch_size, 19))\n        for i, idx in enumerate(random_indexes):\n            image = load_image(dataset_info[idx]['path'], shape)   \n            batch_images[i] = image\n            batch_labels[i][dataset_info[idx]['labels']] = 1\n        yield batch_images, batch_labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_ids, test_ids, train_targets, test_target = train_test_split(train_df['ID'],train_df['Label'], test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = create_train(train_dataset[train_ids.index], 4, (256,256,3))\nvalidation_generator =create_train(train_dataset[test_ids.index], 4, (256,256,3))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Define the model**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_model(input_shape):\n    inputs= Input(shape=input_shape)\n    base_model = InceptionV3(include_top=False,\n                   weights='imagenet',\n                   input_shape=input_shape)\n    for layer in base_model.layers:\n        layer.trainable = False\n    bn = BatchNormalization()(inputs)\n    x = base_model(bn)\n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(0.3)(x)\n    predictions = Dense(19, activation='sigmoid',name='Final')(x)\n\n    model = Model(inputs=inputs, outputs=predictions)\n\n    model.compile(optimizer =Adam(1e-03),\n                  loss = 'binary_crossentropy',\n                  metrics = tf.keras.metrics.AUC(multi_label=True)) \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_callbacks = [EarlyStopping(monitor = 'val_loss', \n                              min_delta = 0.001,\n                              patience = 3, \n                              mode = 'min', \n                              verbose = 1,\n                              restore_best_weights = True),\n                ModelCheckpoint(filepath='model.h5', \n                                save_best_only = True, \n                                monitor = 'val_loss', \n                                mode = 'min', verbose = 1),\n                ReduceLROnPlateau(monitor='val_loss',\n                                  factor=0.1,\n                                  patience=2, \n                                  min_lr=0.00001,\n                                  mode='min',\n                                  verbose=1)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model=make_model((256,256,3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **TRAINING THE MODEL**"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(train_generator,\n                    steps_per_epoch=100,\n                    validation_data = next(validation_generator),\n                    epochs =10, \n                    callbacks =my_callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_acc = history.history['auc']\nval_acc = history.history['val_auc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(1, len(train_acc) + 1)\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))\nfig.set_size_inches(20,10)\n\nax1.plot(epochs , train_acc , 'go-' , label = 'Training AUC')\nax1.plot(epochs , val_acc , 'ro-' , label = 'Validation AUC')\nax1.set_title('Training & Validation Accuracy')\nax1.legend()\nax1.set_xlabel(\"Epochs\")\nax1.set_ylabel(\"Accuracy\")\n\nax2.plot(epochs , loss , 'g-o' , label = 'Training Loss')\nax2.plot(epochs , val_loss , 'r-o' , label = 'Validation Loss')\nax2.set_title('Testing Accuracy & Loss')\nax2.legend()\nax2.set_xlabel(\"Epochs\")\nax2.set_ylabel(\"Training & Validation Loss\")\n       \nfig.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Scores are not that high, we need to try out various techniques to improve the score."},{"metadata":{},"cell_type":"markdown","source":"# **Next step is try out with image augmentation**"},{"metadata":{},"cell_type":"markdown","source":"**Work under progress**"}],"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":4,"nbformat_minor":4}