{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \nfrom tqdm import tqdm\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score\nimport scipy.optimize as opt\nimport cv2\nimport matplotlib.pyplot as plt\nfrom imgaug import augmenters as iaa\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential, Model\nfrom tensorflow import keras\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten, Activation\nfrom tensorflow.keras.metrics import categorical_accuracy, top_k_categorical_accuracy, categorical_crossentropy\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.applications import MobileNet\nfrom tensorflow.keras import backend as K\nimport tensorflow as tf\nfrom tensorflow.keras.applications.mobilenet import preprocess_input\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e35421adb7b8f6731a88b4d5e4f256dde0c15a86"},"cell_type":"code","source":"PATH = './'\nTRAIN = '../input/train/'\nTEST = '../input/test/'\nLABELS = '../input/train.csv'\nSAMPLE = '../input/sample_submission.csv'","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"_kg_hide-output":false,"_kg_hide-input":false},"cell_type":"code","source":"name_label_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:  'Peroxisomes',\n9:  'Endosomes',\n10:  'Lysosomes',\n11:  'Intermediate filaments',\n12:  'Actin filaments',\n13:  'Focal adhesion sites',   \n14:  'Microtubules',\n15:  'Microtubule ends',  \n16:  'Cytokinetic bridge',   \n17:  'Mitotic spindle',\n18:  'Microtubule organizing center',  \n19:  'Centrosome',\n20:  'Lipid droplets',\n21:  'Plasma membrane',   \n22:  'Cell junctions', \n23:  'Mitochondria',\n24:  'Aggresome',\n25:  'Cytosol',\n26:  'Cytoplasmic bodies',   \n27:  'Rods & rings' }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4612f5997b904c0fb52bfc868760448057977e1"},"cell_type":"code","source":"n_classes = len(name_label_dict)\nimg_shape = (224,224,3)\nbatchsize = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"93ff64691e78cfbbbff21f0da398813a986346c5"},"cell_type":"code","source":"def get_input(path, shape): #a function that reads RGBY image\n    colors = ['red','green','blue','yellow']\n    flags = cv2.IMREAD_GRAYSCALE\n    img = [cv2.imread(path+'_'+color+'.png', flags).astype(np.float32)/255\n           for color in colors]\n    img[1] += img[3]/2\n    img[2] += img[3]/2\n    img = np.stack(img[:3], axis=-1)\n    \n    img = cv2.resize(img, (shape[0], shape[1]))\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"730ee4aec5286f480c62ea887d42cf78a9964832"},"cell_type":"code","source":"data = pd.read_csv('../input/train.csv')\n\ntrain_dataset_info = []\nfor name, labels in zip(data['Id'], data['Target'].str.split(' ')):\n    train_dataset_info.append({\n        'path':os.path.join(TRAIN, name),\n        'labels':np.array([int(label) for label in labels])})\ntrain_dataset_info = np.array(train_dataset_info)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ab2fced2e836b0d1c29c9183865b30abd487087"},"cell_type":"code","source":"train_ids, test_ids, train_targets, test_target = train_test_split(\n    data['Id'], data['Target'], test_size=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6f79ac1b7fc5b69fa3b6778c6dde47750f967d53"},"cell_type":"code","source":"class data_generator:\n    \n    def create_train(dataset_info, batch_size, shape, augument=True):\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, 28))\n            for i, idx in enumerate(random_indexes):\n                image = data_generator.load_image(\n                    dataset_info[idx]['path'], shape)   \n                if augument:\n                    image = data_generator.augment(image)\n                batch_images[i] = image\n                batch_labels[i][dataset_info[idx]['labels']] = 1\n            yield batch_images, batch_labels\n            \n\n    def load_image(path, shape):\n        return get_input(path, shape)\n\n            \n    def augment(image):\n        augment_img = iaa.Sequential([\n            iaa.OneOf([\n                iaa.Affine(rotate=0),\n                iaa.Affine(rotate=90),\n                iaa.Affine(rotate=180),\n                iaa.Affine(rotate=270),\n                iaa.Fliplr(0.5),\n                iaa.Flipud(0.5),\n            ])], random_order=True)\n        \n        image_aug = augment_img.augment_image(image)\n        return image_aug","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ac3aa9e49e2248b69b95fd67c19727bb45a8a0b6"},"cell_type":"code","source":"# create train datagen\ntrain_datagen = data_generator.create_train(\n    train_dataset_info[train_ids.index], batchsize, img_shape, augument=True)\n\nvalidation_generator = data_generator.create_train(\n    train_dataset_info[test_ids.index], 256, img_shape, augument=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a7131219da38d35bccadaf1ad47d737585f14ed8"},"cell_type":"code","source":"# create visualization datagen\nvis_datagen = data_generator.create_train(\n    train_dataset_info, 5, img_shape, augument=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"41473ca212081cfce32b8e4a9199cc07363ee24e"},"cell_type":"code","source":"images, labels = next(vis_datagen)\n\nfig, ax = plt.subplots(1,5,figsize=(25,5))\nfor i in range(5):\n    ax[i].imshow(images[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c073926fbd113c24bac84fa4c53ea4b6498f6218"},"cell_type":"code","source":"def f1(y_true, y_pred):\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return K.mean(f1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f0f309328c71910757429ba3ec7c4aa1a63dd808"},"cell_type":"code","source":"def create_model(input_shape, n_out):\n    base_model = MobileNet(input_shape=input_shape, include_top=False, weights=None, classes=n_out)\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Activation('relu')(x)\n    x = Dropout(0.2)(x)\n    x = Dense(1024)(x)\n    x = Activation('relu')(x)\n    x = Dense(n_out)(x)\n    logits = Activation('softmax')(x)\n    \n    for layer in base_model.layers:\n        layer.trainable = True\n        \n    return Model(inputs=base_model.input, outputs=logits)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ed7fb67a7d32a7fa8528d13aa45ce06ddb8e27f5"},"cell_type":"code","source":"model = create_model(img_shape, n_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a0154cb934759b2f78ea626527b0bedcbcedffee"},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=0.002), loss='categorical_crossentropy',\n              metrics=[categorical_crossentropy, categorical_accuracy, f1])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9ed9b008a23a93582b6135137870b5c5039b426d"},"cell_type":"code","source":"def gen_graph(history, title):\n    plt.plot(history.history['categorical_accuracy'])\n    plt.plot(history.history['val_categorical_accuracy'])\n    plt.title('Accuracy ' + title)\n    plt.ylabel('Accuracy')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()\n    plt.plot(history.history['categorical_crossentropy'])\n    plt.plot(history.history['val_categorical_crossentropy'])\n    plt.title('Loss ' + title)\n    plt.ylabel('MLogLoss')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()\n    plt.plot(history.history['f1'])\n    plt.plot(history.history['val_f1'])\n    plt.title('F1 ' + title)\n    plt.ylabel('Score')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"53756ff028be975ecab9cbec9c9f3eeef643c918"},"cell_type":"code","source":"STEPS = 1000\nepochs = 30","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fcaaf940bd3c71a0f88912e270e1f0262bcc4a98"},"cell_type":"code","source":"callbacks = [\n    ReduceLROnPlateau(monitor='val_categorical_accuracy', factor=0.5, patience=5,\n                      min_delta=0.005, mode='max', cooldown=3, verbose=1)\n]\n\nhist = model.fit_generator(\n    train_datagen, steps_per_epoch=STEPS, epochs=epochs, verbose=1,\n    validation_data=next(validation_generator),\n    callbacks = callbacks\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ab3df8199878b786710e90af05dd638bda75e45c"},"cell_type":"code","source":"gen_graph(hist, \"MobileNet\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0cd434ca0ac882c010707d96d542368d9db4683d"},"cell_type":"code","source":"submit = pd.read_csv('../input/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"450213806713539592f289db45b9e71d63530297"},"cell_type":"code","source":"predicted = []\nfor name in tqdm(submit['Id']):\n    path = os.path.join('../input/test/', name)\n    image = data_generator.load_image(path, img_shape)\n    score_predict = model.predict(image[np.newaxis])[0]\n    label_predict = np.arange(28)[score_predict>=0.5]\n    str_predict_label = ' '.join(str(l) for l in label_predict)\n    predicted.append(str_predict_label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a4f91c2157ad0c811cdc31fdfd168d6c92d46854"},"cell_type":"code","source":"submit['Predicted'] = predicted\nsubmit.to_csv('submission.csv', index=False)","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}