{"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":"# <span style=\"font-family:candara; background:#99ffff; font-size: 30px; test-align: center;\">HUMAN PROTEIN ATLAS</span>\n\nThe word *Protein* comes from Greek word *Proteios* meaning primary or in the lead. Proteins are of immense importance in our body. From catalysing reactions and passing signals at cellular level to growth and maintainance of tissues, many of the major life functions are carried out by proteins.\n\nBut why did I choose this topic??\n* Instead of one RGB image, four channels images i.e. red, green, blue, yellow images are provided separately.\n* Multilabel classification.\n\nMoreover, I would like to use **tf.data** API which enables us to build asynchronous and highly efficient input pipeline.\n\nSo, let's get started.","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport os\nimport keras\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nimport cv2\nfrom keras import applications\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Input\nfrom keras.models import Model\nfrom keras.optimizers import Adam","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/human-protein-atlas-image-classification/train.csv')","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_SHAPE = (512, 512, 3)\nBATCH_SIZE = 16\npath_to_train = '/kaggle/input/human-protein-atlas-image-classification/train/'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"complete_path\"] = path_to_train + df[\"Id\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span style=\"font-family:candara; background:#99ffff; font-size: 25px; test-align: center;\">PLOTTING RANDOM CELL IMAGES</span>","metadata":{}},{"cell_type":"code","source":"import random\nfig, axes = plt.subplots(3, 4, figsize=(11, 11))\nfor i in range(3):\n    for j in range(4):\n        idx = random.randint(0, df.shape[0])\n        row = df.iloc[idx,:]\n        path = row.complete_path\n        red = np.array(Image.open(path + '_red.png'))\n        green = np.array(Image.open(path + '_green.png'))\n        blue = np.array(Image.open(path + '_blue.png'))\n        im = np.stack((\n                red,\n                green,\n                blue),-1)\n        axes[i][j].imshow(im)\n        axes[i][j].set_title(row.Target)\n        axes[i][j].set_xticks([])\n        axes[i][j].set_yticks([])\nfig.tight_layout()\nfig.show();","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train, val = train_test_split(df, test_size=0.2, random_state=42)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Shape of train: {train.shape}')\nprint(f'Shape of val: {val.shape}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It may happen that row.Target.split() won't work. In that case, you can try row.Target.str.split() instead.","metadata":{}},{"cell_type":"code","source":"def get_clean_data(df):\n    targets = []\n    paths = []\n    for _, row in df.iterrows():\n        target_np = np.zeros((28))\n        t = [int(t) for t in row.Target.split()]\n        target_np[t] = 1\n        targets.append(target_np)\n        paths.append(row.complete_path)\n    return np.array(paths), np.array(targets)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path, train_target = get_clean_data(train)\nval_path, val_target = get_clean_data(val)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Train path shape: {train_path.shape}')\nprint(f'Train target shape: {train_target.shape}')\nprint(f'Val path shape: {val_path.shape}')\nprint(f'Val target shape: {val_target.shape}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span style=\"font-family:candara; background:#99ffff; font-size: 25px; test-align: center;\">CREATING DATASET FROM FILE AND TARGETS</span>","metadata":{}},{"cell_type":"code","source":"train_data = tf.data.Dataset.from_tensor_slices((train_path, train_target))\nval_data = tf.data.Dataset.from_tensor_slices((val_path, val_target))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span style=\"font-family:candara; background:#99ffff; font-size: 25px; test-align: center;\">READING IMAGES FROM FILES</span>","metadata":{}},{"cell_type":"code","source":"def load_data(path, target):\n    red = tf.squeeze(tf.image.decode_png(tf.io.read_file(path+'_red.png'), channels=1), [2])\n    blue = tf.squeeze(tf.image.decode_png(tf.io.read_file(path+'_blue.png'), channels=1), [2])\n    green = tf.squeeze(tf.image.decode_png(tf.io.read_file(path+'_green.png'), channels=1), [2])\n    img = tf.stack((\n                red,\n                green,\n                blue), axis=2)\n    return img, target\n\nAUTOTUNE = tf.data.experimental.AUTOTUNE\n\ntrain_data = train_data.map(load_data, num_parallel_calls=AUTOTUNE)\nval_data = val_data.map(load_data, num_parallel_calls=AUTOTUNE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If you want you can also resize the images using **tf.image.resize_images** function. I would like to keep the original dimensions :)","metadata":{}},{"cell_type":"markdown","source":"# <span style=\"font-family:candara; background:#99ffff; font-size: 25px; test-align: center;\">IMAGE AUGMENTATION</span>\nNow, I augment the training set images below by appling random contrast, brightness and flip. There are multiple other augmentations that you can apply.","metadata":{}},{"cell_type":"code","source":"def image_augment(img, target):\n    img = tf.image.random_contrast(img, lower=0.3, upper=2.0)\n    img = tf.image.random_flip_up_down(img)\n    img = tf.image.random_brightness(img, max_delta=0.1)\n    return img, target\n    \ntrain_data = train_data.map(image_augment, num_parallel_calls=AUTOTUNE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_batches = train_data.batch(BATCH_SIZE).prefetch(buffer_size=AUTOTUNE)\nval_data_batches = val_data.batch(BATCH_SIZE).prefetch(buffer_size=AUTOTUNE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span style=\"font-family:candara; background:#99ffff; font-size: 25px; test-align: center;\">TRAINING</span>","metadata":{}},{"cell_type":"markdown","source":"Loading pretrained ResNet50 model, adding final layers and training it:","metadata":{}},{"cell_type":"code","source":"resnet_model = applications.ResNet50(include_top=False, weights='imagenet')\n\nresnet_model.trainable = True\n\ninput_layer = Input(shape=INPUT_SHAPE)\nx = resnet_model(input_layer)\nx = Flatten()(x)\nx = Dropout(0.5)(x)\nx = Dense(512, activation='relu')(x)\nx = Dropout(0.5)(x)\noutput = Dense(28, activation='sigmoid')(x)\nmodel = Model(input_layer, output)\n\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer=Adam(1e-3), loss='binary_crossentropy', metrics=['binary_accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_data_batches, steps_per_epoch = 150, validation_data = val_data_batches, epochs=3)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To get more information about tf.data you can refer to it's [official docs](http://www.tensorflow.org/guide/data)","metadata":{}},{"cell_type":"markdown","source":"**If you like my notebook, please upvote it :)**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}