{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"!/opt/conda/bin/python3.7 -m pip install --upgrade pip\n! pip install -q efficientnet","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers\nimport os\nimport re\nimport math\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom kaggle_datasets import KaggleDatasets\nimport efficientnet.tfkeras as efn\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"GCS_DS_PATH = KaggleDatasets().get_gcs_path('ranzcr-clip-catheter-line-classification')\nGCS_DS_PATH","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(GCS_DS_PATH+\"/train.csv\")\ntrain_df.index = train_df[\"StudyInstanceUID\"]\ndel train_df[\"StudyInstanceUID\"]\n\ntrain_annot_df = pd.read_csv(GCS_DS_PATH+\"/train_annotations.csv\")\ntrain_annot_df.index = train_annot_df[\"StudyInstanceUID\"]\ndel train_annot_df[\"StudyInstanceUID\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_annot_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = list(train_df.columns[:-1])\nclasses_normal= [name for name in classes[:-1] if name.split(\" - \")[1] == \"Normal\"]\nclasses_abnormal= [name for name in classes[:-1] if name.split(\" - \")[1] == \"Abnormal\"]\nclasses_borderline = [name for name in classes[:-1] if name.split(\" - \")[1] == \"Borderline\"]\nclasses_count = train_df[classes].sum(axis = 0)\nnum_classes = len(classes_count)\n\n\nprint(\"Number of Classes: {}\".format(num_classes))\nclasses_count","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weights = {}\nls = list(classes_count.values)\ntot_samples = sum(ls)\n\nfor i in range(num_classes):\n    class_weights[i] = tot_samples/(num_classes*ls[i])\n\nclass_weights","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"patient_ids = train_df[\"PatientID\"].unique()\npatientwise_count = train_df['PatientID'].value_counts()\nnum_patients = len(patientwise_count)\nprint(\"Number of patients: \",num_patients)\npatientwise_count","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"try:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver() \n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy() \n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZE = [600,600]\nHEIGHT,WIDTH = IMAGE_SIZE[0],IMAGE_SIZE[1]\nCHANNELS = 3\n\nAUTO = tf.data.experimental.AUTOTUNE\n\nFILENAMES = tf.io.gfile.glob(GCS_DS_PATH + '/train_tfrecords/*.tfrec')\nTRAINING_FILENAMES = FILENAMES[:-2]\nVALIDATION_FILENAMES = FILENAMES[-2:]\nTEST_FILENAMES = tf.io.gfile.glob(GCS_DS_PATH + '/test_tfrecords/*.tfrec')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.image.resize(image, [*IMAGE_SIZE])\n    return image\n\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"StudyInstanceUID\"           : tf.io.FixedLenFeature([], tf.string),\n        \"image\"                      : tf.io.FixedLenFeature([], tf.string),\n        \"ETT - Abnormal\"             : tf.io.FixedLenFeature([], tf.int64), \n        \"ETT - Borderline\"           : tf.io.FixedLenFeature([], tf.int64), \n        \"ETT - Normal\"               : tf.io.FixedLenFeature([], tf.int64), \n        \"NGT - Abnormal\"             : tf.io.FixedLenFeature([], tf.int64), \n        \"NGT - Borderline\"           : tf.io.FixedLenFeature([], tf.int64), \n        \"NGT - Incompletely Imaged\"  : tf.io.FixedLenFeature([], tf.int64), \n        \"NGT - Normal\"               : tf.io.FixedLenFeature([], tf.int64), \n        \"CVC - Abnormal\"             : tf.io.FixedLenFeature([], tf.int64), \n        \"CVC - Borderline\"           : tf.io.FixedLenFeature([], tf.int64), \n        \"CVC - Normal\"               : tf.io.FixedLenFeature([], tf.int64), \n        \"Swan Ganz Catheter Present\" : tf.io.FixedLenFeature([], tf.int64),\n    }\n    \n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    label = [example['ETT - Abnormal'],\n                 example['ETT - Borderline'],\n                 example['ETT - Normal'],\n                 example['NGT - Abnormal'],\n                 example['NGT - Borderline'],\n                 example['NGT - Incompletely Imaged'],\n                 example['NGT - Normal'],\n                 example['CVC - Abnormal'],\n                 example['CVC - Borderline'],\n                 example['CVC - Normal'],\n                 example['Swan Ganz Catheter Present']]\n    label = [tf.cast(i,tf.float32) for i in label]\n    return image, label\n\n\ndef read_unlabeled_tfrecord(example):\n    UNLABELED_TFREC_FORMAT = {\n        \"StudyInstanceUID\"           : tf.io.FixedLenFeature([], tf.string),\n        \"image\"                      : tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    idnum = example['StudyInstanceUID']\n    return image, idnum\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO) \n    dataset = dataset.with_options(ignore_order)\n    dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord, num_parallel_calls=AUTO)\n    return dataset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow.experimental.numpy as tnp\n\n@tf.function\ndef data_augment(image, label):\n    p_spatial = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_rotate = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_pixel_1 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_pixel_2 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_pixel_3 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_crop = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    \n    if p_pixel_1 >= .4:\n        image = tf.image.random_saturation(image, lower=.7, upper=1.3)\n    if p_pixel_2 >= .4:\n        image = tf.image.random_contrast(image, lower=.8, upper=1.2)\n    if p_pixel_3 >= .4:\n        image = tf.image.random_brightness(image, max_delta=.1)\n        \n    \n    if p_crop > .7:\n        if p_crop > .9:\n            image = tf.image.central_crop(image, central_fraction=.7)\n        elif p_crop > .8:\n            image = tf.image.central_crop(image, central_fraction=.8)\n        else:\n            image = tf.image.central_crop(image, central_fraction=.9)\n    elif p_crop > .4:\n        crop_size = tf.random.uniform([], int(HEIGHT*.8), HEIGHT, dtype=tf.int32)\n        image = tf.image.random_crop(image, size=[crop_size, crop_size, CHANNELS])\n        \n    image = tf.image.resize(image, [*IMAGE_SIZE])\n    image = tf.image.random_flip_left_right(image)\n    return image,label   \n\ndef get_training_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, labeled=True)\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() \n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\ndef get_validation_dataset(ordered=False):\n    dataset = load_dataset(VALIDATION_FILENAMES, labeled=True, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.cache()\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\ndef get_test_dataset(ordered=False):\n    dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\ndef count_data_items(filenames):\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames]\n    return np.sum(n)\n\nNUM_TRAINING_IMAGES = count_data_items(TRAINING_FILENAMES)\nNUM_VALIDATION_IMAGES = count_data_items(VALIDATION_FILENAMES)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\nprint('Dataset: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES, NUM_VALIDATION_IMAGES, NUM_TEST_IMAGES))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 16 * strategy.num_replicas_in_sync\n\ntrain_ds = get_training_dataset()\nvalid_ds = get_validation_dataset()\ntest_ds = get_test_dataset()\n\nprint(\"Training:\", train_ds)\nprint(\"Validation:\",valid_ds)\nprint(\"Test:\", test_ds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Training data shapes:\")\nfor image, label in train_ds.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training data label examples:\", label.numpy())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Test data shapes:\")\nfor image, idnum in test_ds.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model():\n    efficient_net = {\n        0 : efn.EfficientNetB0(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        1 : efn.EfficientNetB1(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        2 : efn.EfficientNetB2(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        3 : efn.EfficientNetB3(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        4 : efn.EfficientNetB4(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        5 : efn.EfficientNetB5(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        6 : efn.EfficientNetB6(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        7 : efn.EfficientNetB7(weights=\"noisy-student\",include_top=False ,input_shape=[*IMAGE_SIZE, 3]),\n        8 : tf.keras.applications.Xception(include_top=False, weights='imagenet',input_shape=[*IMAGE_SIZE, 3]),\n        9 : tf.keras.applications.ResNet50(include_top=False, weights='imagenet',input_shape=[*IMAGE_SIZE, 3]),\n        10: tf.keras.applications.ResNet101(include_top=False, weights='imagenet',input_shape=[*IMAGE_SIZE, 3]),\n        11: tf.keras.applications.ResNet152(include_top=False, weights='imagenet',input_shape=[*IMAGE_SIZE, 3])\n    }\n    \n    ls = [7]\n    output = {}\n    inputs = tf.keras.Input(shape=(*IMAGE_SIZE, 3))\n    for i in ls:\n        pretrained_model = efficient_net[i]\n        x = pretrained_model(inputs)\n        x = tf.keras.layers.GlobalAveragePooling2D()(x)\n        x = tf.keras.layers.Dense(512) (x)\n        x = tf.keras.layers.LeakyReLU(alpha=0.2) (x)\n        x = tf.keras.layers.Dropout(0.3) (x)\n        x = tf.keras.layers.Dense(256) (x)\n        x = tf.keras.layers.LeakyReLU(alpha=0.2) (x)\n        x = tf.keras.layers.GaussianDropout(0.4) (x)\n        output[i] = tf.keras.layers.Dense(num_classes,activation=\"sigmoid\", dtype='float32')(x)\n        \n    if len(ls)>1:\n        outputs = tf.keras.layers.average(list(output.values()))\n    else:\n        outputs = list(output.values())[0]\n        \n    model = tf.keras.Model(inputs, outputs)\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def compile_model(model, lr=0.0001):\n    \n    optimizer = tf.keras.optimizers.Adam(lr=lr)\n    \n    loss = tf.keras.losses.BinaryCrossentropy(label_smoothing=0.05)\n        \n    metrics = [\n        tf.keras.metrics.AUC(name='auc',multi_label=True)\n    ]\n\n    model.compile(optimizer=optimizer, loss=loss, metrics=metrics)\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_callbacks(model_save_path):\n    \n    \n    if not os.path.exists(model_save_path):\n        os.makedirs(model_save_path)\n    \n    cpk_path = f'{model_save_path}/model.h5'\n\n    checkpoint = tf.keras.callbacks.ModelCheckpoint(\n        filepath=cpk_path,\n        monitor='val_auc',\n        mode='max',\n        save_best_only=True,\n        verbose=1\n    )\n\n    reducelr = tf.keras.callbacks.ReduceLROnPlateau(\n        monitor='val_auc',\n        mode='max',\n        factor=0.1,\n        patience=3,\n        verbose=0\n    )\n\n    earlystop = tf.keras.callbacks.EarlyStopping(\n        monitor='val_auc',\n        mode='max',\n        patience=10, \n        verbose=1\n    )\n    \n    callbacks = [checkpoint, reducelr, earlystop]\n    \n    return callbacks","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EPOCHS= 30\nVERBOSE =1\nMODEL_PATH = '.'\nSTEPS_PER_EPOCH = NUM_TRAINING_IMAGES//(BATCH_SIZE)\n\ntf.keras.backend.clear_session()\nwith strategy.scope():\n    model = create_model()\n    model = compile_model(model, lr=0.0001)\n   \n    callbacks = create_callbacks(MODEL_PATH)\n    \n    history = model.fit(train_ds, \n                        epochs=EPOCHS,\n                        callbacks=callbacks,\n                        validation_data = valid_ds,\n                        steps_per_epoch = STEPS_PER_EPOCH,\n                        verbose=VERBOSE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = tf.keras.models.load_model(\"./model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_ids=[]\ntest_pred = []\nfor batch in test_ds:\n    images,ids_batch = batch\n    pred_batch = model.predict(images)\n    for i,ids in enumerate(ids_batch):\n        test_ids.append(ids)\n        test_pred.append(pred_batch[i])\n\ntest_ids = [np.array(i).astype(\"str\").tolist() for i in test_ids]\ntest_df = pd.DataFrame(test_pred,index=test_ids,columns=classes)\ntest_df.index.name = \"StudyInstanceUID\"\ntest_df.to_csv(\"./submission.csv\")","execution_count":null,"outputs":[]}],"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}