{"cells":[{"metadata":{},"cell_type":"markdown","source":"### this notebook is based [Md. Rezwanul Haque's notebook](https://www.kaggle.com/rezwan249/keras-model-creation-and-pe-detection-submission)."},{"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\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Input, Dense, Dropout, Conv2D\n\nimport os\nimport gc\nimport time\nfrom IPython.display import clear_output\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.callbacks import ModelCheckpoint as MC\nfrom tensorflow.keras import backend as K\nimport pydicom\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Reading test data...')\ntest = pd.read_csv(\"../input/rsna-str-pulmonary-embolism-detection/test.csv\")\nprint(test.shape)\ntest.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import regularizers\nREG = 1e-4\nDO = 0\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Copyright 2019 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n# pylint: disable=invalid-name\n\"\"\"EfficientNet models for Keras.\n\nReference paper:\n  - [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks]\n    (https://arxiv.org/abs/1905.11946) (ICML 2019)\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport copy\nimport math\nimport os\n\nfrom tensorflow.python.keras import backend\nfrom tensorflow.python.keras import layers\nfrom tensorflow.python.keras.applications import imagenet_utils\nfrom tensorflow.python.keras.engine import training\nfrom tensorflow.python.keras.utils import data_utils\nfrom tensorflow.python.keras.utils import layer_utils\nfrom tensorflow.python.util.tf_export import keras_export\n\n\nBASE_WEIGHTS_PATH = 'https://storage.googleapis.com/keras-applications/'\n\nWEIGHTS_HASHES = {\n    'b0': ('902e53a9f72be733fc0bcb005b3ebbac',\n           '50bc09e76180e00e4465e1a485ddc09d'),\n    'b1': ('1d254153d4ab51201f1646940f018540',\n           '74c4e6b3e1f6a1eea24c589628592432'),\n    'b2': ('b15cce36ff4dcbd00b6dd88e7857a6ad',\n           '111f8e2ac8aa800a7a99e3239f7bfb39'),\n    'b3': ('ffd1fdc53d0ce67064dc6a9c7960ede0',\n           'af6d107764bb5b1abb91932881670226'),\n    'b4': ('18c95ad55216b8f92d7e70b3a046e2fc',\n           'ebc24e6d6c33eaebbd558eafbeedf1ba'),\n    'b5': ('ace28f2a6363774853a83a0b21b9421a',\n           '38879255a25d3c92d5e44e04ae6cec6f'),\n    'b6': ('165f6e37dce68623721b423839de8be5',\n           '9ecce42647a20130c1f39a5d4cb75743'),\n    'b7': ('8c03f828fec3ef71311cd463b6759d99',\n           'cbcfe4450ddf6f3ad90b1b398090fe4a'),\n}\n\nDEFAULT_BLOCKS_ARGS = [{\n    'kernel_size': 3,\n    'repeats': 1,\n    'filters_in': 32,\n    'filters_out': 16,\n    'expand_ratio': 1,\n    'id_skip': True,\n    'strides': 1,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 3,\n    'repeats': 2,\n    'filters_in': 16,\n    'filters_out': 24,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 2,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 5,\n    'repeats': 2,\n    'filters_in': 24,\n    'filters_out': 40,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 2,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 3,\n    'repeats': 3,\n    'filters_in': 40,\n    'filters_out': 80,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 2,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 5,\n    'repeats': 3,\n    'filters_in': 80,\n    'filters_out': 112,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 1,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 5,\n    'repeats': 4,\n    'filters_in': 112,\n    'filters_out': 192,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 2,\n    'se_ratio': 0.25\n}, {\n    'kernel_size': 3,\n    'repeats': 1,\n    'filters_in': 192,\n    'filters_out': 320,\n    'expand_ratio': 6,\n    'id_skip': True,\n    'strides': 1,\n    'se_ratio': 0.25\n}]\n\nCONV_KERNEL_INITIALIZER = {\n    'class_name': 'VarianceScaling',\n    'config': {\n        'scale': 2.0,\n        'mode': 'fan_out',\n        'distribution': 'truncated_normal'\n    }\n}\n\nDENSE_KERNEL_INITIALIZER = {\n    'class_name': 'VarianceScaling',\n    'config': {\n        'scale': 1. / 3.,\n        'mode': 'fan_out',\n        'distribution': 'uniform'\n    }\n}\n\n\ndef EfficientNet(\n    width_coefficient,\n    depth_coefficient,\n    default_size,\n    dropout_rate=0.2,\n    drop_connect_rate=0.2,\n    depth_divisor=8,\n    activation='swish',\n    blocks_args='default',\n    model_name='efficientnet',\n    include_top=True,\n    weights='imagenet',\n    input_tensor=None,\n    input_shape=None,\n    pooling=None,\n    classes=1000,\n    classifier_activation='softmax',\n):\n  \"\"\"Instantiates the EfficientNet architecture using given scaling coefficients.\n\n  Optionally loads weights pre-trained on ImageNet.\n  Note that the data format convention used by the model is\n  the one specified in your Keras config at `~/.keras/keras.json`.\n\n  Arguments:\n    width_coefficient: float, scaling coefficient for network width.\n    depth_coefficient: float, scaling coefficient for network depth.\n    default_size: integer, default input image size.\n    dropout_rate: float, dropout rate before final classifier layer.\n    drop_connect_rate: float, dropout rate at skip connections.\n    depth_divisor: integer, a unit of network width.\n    activation: activation function.\n    blocks_args: list of dicts, parameters to construct block modules.\n    model_name: string, model name.\n    include_top: whether to include the fully-connected\n        layer at the top of the network.\n    weights: one of `None` (random initialization),\n          'imagenet' (pre-training on ImageNet),\n          or the path to the weights file to be loaded.\n    input_tensor: optional Keras tensor\n        (i.e. output of `layers.Input()`)\n        to use as image input for the model.\n    input_shape: optional shape tuple, only to be specified\n        if `include_top` is False.\n        It should have exactly 3 inputs channels.\n    pooling: optional pooling mode for feature extraction\n        when `include_top` is `False`.\n        - `None` means that the output of the model will be\n            the 4D tensor output of the\n            last convolutional layer.\n        - `avg` means that global average pooling\n            will be applied to the output of the\n            last convolutional layer, and thus\n            the output of the model will be a 2D tensor.\n        - `max` means that global max pooling will\n            be applied.\n    classes: optional number of classes to classify images\n        into, only to be specified if `include_top` is True, and\n        if no `weights` argument is specified.\n    classifier_activation: A `str` or callable. The activation function to use\n        on the \"top\" layer. Ignored unless `include_top=True`. Set\n        `classifier_activation=None` to return the logits of the \"top\" layer.\n\n  Returns:\n    A `keras.Model` instance.\n\n  Raises:\n    ValueError: in case of invalid argument for `weights`,\n      or invalid input shape.\n    ValueError: if `classifier_activation` is not `softmax` or `None` when\n      using a pretrained top layer.\n  \"\"\"\n  if blocks_args == 'default':\n    blocks_args = DEFAULT_BLOCKS_ARGS\n\n  if not (weights in {'imagenet', None} or os.path.exists(weights)):\n    raise ValueError('The `weights` argument should be either '\n                     '`None` (random initialization), `imagenet` '\n                     '(pre-training on ImageNet), '\n                     'or the path to the weights file to be loaded.')\n\n  if weights == 'imagenet' and include_top and classes != 1000:\n    raise ValueError('If using `weights` as `\"imagenet\"` with `include_top`'\n                     ' as true, `classes` should be 1000')\n\n  # Determine proper input shape\n  input_shape = imagenet_utils.obtain_input_shape(\n      input_shape,\n      default_size=default_size,\n      min_size=32,\n      data_format=backend.image_data_format(),\n      require_flatten=include_top,\n      weights=weights)\n\n  if input_tensor is None:\n    img_input = layers.Input(shape=input_shape)\n  else:\n    if not backend.is_keras_tensor(input_tensor):\n      img_input = layers.Input(tensor=input_tensor, shape=input_shape)\n    else:\n      img_input = input_tensor\n\n  bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1\n\n  def round_filters(filters, divisor=depth_divisor):\n    \"\"\"Round number of filters based on depth multiplier.\"\"\"\n    filters *= width_coefficient\n    new_filters = max(divisor, int(filters + divisor / 2) // divisor * divisor)\n    # Make sure that round down does not go down by more than 10%.\n    if new_filters < 0.9 * filters:\n      new_filters += divisor\n    return int(new_filters)\n\n  def round_repeats(repeats):\n    \"\"\"Round number of repeats based on depth multiplier.\"\"\"\n    return int(math.ceil(depth_coefficient * repeats))\n\n  # Build stem\n  x = img_input\n  #x = layers.Rescaling(1. / 255.)(x)\n  x = layers.Normalization(axis=bn_axis)(x)\n\n  x = layers.ZeroPadding2D(\n      padding=imagenet_utils.correct_pad(x, 3),\n      name='stem_conv_pad')(x)\n  x = layers.Conv2D(\n      round_filters(32),\n      3,\n      strides=2,\n      padding='valid',\n      use_bias=False,\n      kernel_initializer=CONV_KERNEL_INITIALIZER,\n      name='stem_conv',\n      kernel_regularizer=regularizers.l2(REG))(x)\n  x = layers.BatchNormalization(axis=bn_axis, name='stem_bn')(x)\n  x = layers.Activation(activation, name='stem_activation')(x)\n  #x = layers.Dropout(0.01, name='top_dropout0')(x)\n\n  # Build blocks\n  blocks_args = copy.deepcopy(blocks_args)\n\n  b = 0\n  blocks = float(sum(args['repeats'] for args in blocks_args))\n  for (i, args) in enumerate(blocks_args):\n    assert args['repeats'] > 0\n    # Update block input and output filters based on depth multiplier.\n    args['filters_in'] = round_filters(args['filters_in'])\n    args['filters_out'] = round_filters(args['filters_out'])\n\n    for j in range(round_repeats(args.pop('repeats'))):\n      # The first block needs to take care of stride and filter size increase.\n      if j > 0:\n        args['strides'] = 1\n        args['filters_in'] = args['filters_out']\n      x = block(\n          x,\n          activation,\n          drop_connect_rate * b / blocks,\n          name='block{}{}_'.format(i + 1, chr(j + 97)),\n          **args)\n      b += 1\n\n  # Build top\n  x = layers.Conv2D(\n      round_filters(1280),\n      1,\n      padding='same',\n      use_bias=False,\n      kernel_initializer=CONV_KERNEL_INITIALIZER,\n      name='top_conv',\n      kernel_regularizer=regularizers.l2(REG))(x)\n  x = layers.BatchNormalization(axis=bn_axis, name='top_bn')(x)\n  x = layers.Activation(activation, name='top_activation')(x)\n  if include_top:\n    x = layers.GlobalAveragePooling2D(name='avg_pool')(x)\n    if dropout_rate > 0:\n      x = layers.Dropout(dropout_rate, name='top_dropout1')(x)\n    imagenet_utils.validate_activation(classifier_activation, weights)\n    x = layers.Dense(\n        classes,\n        activation=classifier_activation,\n        kernel_initializer=DENSE_KERNEL_INITIALIZER,\n        name='predictions',\n          kernel_regularizer=regularizers.l2(REG))(x)\n  else:\n    if pooling == 'avg':\n      x = layers.GlobalAveragePooling2D(name='avg_pool')(x)\n    elif pooling == 'max':\n      x = layers.GlobalMaxPooling2D(name='max_pool')(x)\n\n  # Ensure that the model takes into account\n  # any potential predecessors of `input_tensor`.\n  if input_tensor is not None:\n    inputs = layer_utils.get_source_inputs(input_tensor)\n  else:\n    inputs = img_input\n\n  # Create model.\n  model = training.Model(inputs, x, name=model_name)\n\n  # Load weights.\n  if weights == 'imagenet':\n    if include_top:\n      file_suffix = '.h5'\n      file_hash = WEIGHTS_HASHES[model_name[-2:]][0]\n    else:\n      file_suffix = '_notop.h5'\n      file_hash = WEIGHTS_HASHES[model_name[-2:]][1]\n    file_name = model_name + file_suffix\n    weights_path = data_utils.get_file(\n        file_name,\n        BASE_WEIGHTS_PATH + file_name,\n        cache_subdir='models',\n        file_hash=file_hash)\n    model.load_weights(weights_path)\n  elif weights is not None:\n    model.load_weights(weights)\n  return model\n\n\ndef block(inputs,\n          activation='swish',\n          drop_rate=0.,\n          name='',\n          filters_in=32,\n          filters_out=16,\n          kernel_size=3,\n          strides=1,\n          expand_ratio=1,\n          se_ratio=0.,\n          id_skip=True):\n  \"\"\"An inverted residual block.\n\n  Arguments:\n      inputs: input tensor.\n      activation: activation function.\n      drop_rate: float between 0 and 1, fraction of the input units to drop.\n      name: string, block label.\n      filters_in: integer, the number of input filters.\n      filters_out: integer, the number of output filters.\n      kernel_size: integer, the dimension of the convolution window.\n      strides: integer, the stride of the convolution.\n      expand_ratio: integer, scaling coefficient for the input filters.\n      se_ratio: float between 0 and 1, fraction to squeeze the input filters.\n      id_skip: boolean.\n\n  Returns:\n      output tensor for the block.\n  \"\"\"\n  bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1\n\n  # Expansion phase\n  filters = filters_in * expand_ratio\n  if expand_ratio != 1:\n    x = layers.Conv2D(\n        filters,\n        1,\n        padding='same',\n        use_bias=False,\n        kernel_initializer=CONV_KERNEL_INITIALIZER,\n        name=name + 'expand_conv',\n          kernel_regularizer=regularizers.l2(REG))(\n            inputs)\n    x = layers.BatchNormalization(axis=bn_axis, name=name + 'expand_bn')(x)\n    x = layers.Activation(activation, name=name + 'expand_activation')(x)\n    #x = layers.Dropout(0.01, name=name+'top_dropout3')(x)\n  else:\n    x = inputs\n\n  # Depthwise Convolution\n  if strides == 2:\n    x = layers.ZeroPadding2D(\n        padding=imagenet_utils.correct_pad(x, kernel_size),\n        name=name + 'dwconv_pad')(x)\n    conv_pad = 'valid'\n  else:\n    conv_pad = 'same'\n  x = layers.DepthwiseConv2D(\n      kernel_size,\n      strides=strides,\n      padding=conv_pad,\n      use_bias=False,\n      depthwise_initializer=CONV_KERNEL_INITIALIZER,\n      name=name + 'dwconv')(x)\n  x = layers.BatchNormalization(axis=bn_axis, name=name + 'bn')(x)\n  x = layers.Activation(activation, name=name + 'activation')(x)\n  #x = layers.Dropout(0.01, name=name+'top_dropout')(x)\n\n  # Squeeze and Excitation phase\n  if 0 < se_ratio <= 1:\n    filters_se = max(1, int(filters_in * se_ratio))\n    se = layers.GlobalAveragePooling2D(name=name + 'se_squeeze')(x)\n    se = layers.Reshape((1, 1, filters), name=name + 'se_reshape')(se)\n    se = layers.Conv2D(\n        filters_se,\n        1,\n        padding='same',\n        activation=activation,\n        kernel_initializer=CONV_KERNEL_INITIALIZER,\n        name=name + 'se_reduce',\n          kernel_regularizer=regularizers.l2(REG))(\n            se)\n    #se = layers.Dropout(0.1, name=name+'top_dropout5')(se)\n    se = layers.Conv2D(\n        filters,\n        1,\n        padding='same',\n        activation='sigmoid',\n        kernel_initializer=CONV_KERNEL_INITIALIZER,\n        name=name + 'se_expand',\n          kernel_regularizer=regularizers.l2(REG))(se)\n    #se = layers.Dropout(0.1, name=name+'top_dropout6')(se)\n    x = layers.multiply([x, se], name=name + 'se_excite')\n\n  # Output phase\n  x = layers.Conv2D(\n      filters_out,\n      1,\n      padding='same',\n      use_bias=False,\n      kernel_initializer=CONV_KERNEL_INITIALIZER,\n      name=name + 'project_conv',\n      kernel_regularizer=regularizers.l2(REG))(x)\n  x = layers.BatchNormalization(axis=bn_axis, name=name + 'project_bn')(x)\n  if id_skip and strides == 1 and filters_in == filters_out:\n    if drop_rate > 0:\n      x = layers.Dropout(\n          drop_rate, noise_shape=(None, 1, 1, 1), name=name + 'drop')(x)\n    x = layers.add([x, inputs], name=name + 'add')\n  return x\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB0',\n              'keras.applications.EfficientNetB0')\ndef EfficientNetB0(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.0,\n      1.0,\n      224,\n      0.5,\n      model_name='efficientnetb0',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB1',\n              'keras.applications.EfficientNetB1')\ndef EfficientNetB1(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.0,\n      1.1,\n      240,\n      0.2,\n      model_name='efficientnetb1',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB2',\n              'keras.applications.EfficientNetB2')\ndef EfficientNetB2(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.1,\n      1.2,\n      260,\n      0.3,\n      model_name='efficientnetb2',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB3',\n              'keras.applications.EfficientNetB3')\ndef EfficientNetB3(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.2,\n      1.4,\n      300,\n      0.3,\n      model_name='efficientnetb3',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB4',\n              'keras.applications.EfficientNetB4')\ndef EfficientNetB4(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.4,\n      1.8,\n      380,\n      0.4,\n      model_name='efficientnetb4',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB5',\n              'keras.applications.EfficientNetB5')\ndef EfficientNetB5(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.6,\n      2.2,\n      456,\n      0.4,\n      model_name='efficientnetb5',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB6',\n              'keras.applications.EfficientNetB6')\ndef EfficientNetB6(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      1.8,\n      2.6,\n      528,\n      0.5,\n      model_name='efficientnetb6',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.EfficientNetB7',\n              'keras.applications.EfficientNetB7')\ndef EfficientNetB7(include_top=True,\n                   weights='imagenet',\n                   input_tensor=None,\n                   input_shape=None,\n                   pooling=None,\n                   classes=1000,\n                   **kwargs):\n  return EfficientNet(\n      2.0,\n      3.1,\n      600,\n      0.5,\n      model_name='efficientnetb7',\n      include_top=include_top,\n      weights=weights,\n      input_tensor=input_tensor,\n      input_shape=input_shape,\n      pooling=pooling,\n      classes=classes,\n      **kwargs)\n\n\n@keras_export('keras.applications.efficientnet.preprocess_input')\ndef preprocess_input(x, data_format=None):  # pylint: disable=unused-argument\n  return x\n\n\n@keras_export('keras.applications.efficientnet.decode_predictions')\ndef decode_predictions(preds, top=5):\n  \"\"\"Decodes the prediction result from the model.\n\n  Arguments\n    preds: Numpy tensor encoding a batch of predictions.\n    top: Integer, how many top-guesses to return.\n\n  Returns\n    A list of lists of top class prediction tuples\n    `(class_name, class_description, score)`.\n    One list of tuples per sample in batch input.\n\n  Raises\n    ValueError: In case of invalid shape of the `preds` array (must be 2D).\n  \"\"\"\n  return imagenet_utils.decode_predictions(preds, top=top)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model(train_type=0):\n    inputs = Input((256, 256, 3))\n    #x = Conv2D(3, (1, 1), activation='relu')(inputs)\n    base_model = EfficientNetB3(\n        include_top=False,\n        weights=None,\n        input_shape=[256,256,3]\n    )\n    #print(len(base_model.layers))\n    if train_type==1:\n        base_model.trainable = False\n    \n    if train_type==2:\n        for layer in base_model.layers[-20:]:\n            if not isinstance(layer, layers.BatchNormalization):\n                layer.trainable = True\n\n    outputs = base_model(inputs)#, training=True)\n    outputs = keras.layers.GlobalAveragePooling2D()(outputs)\n    outputs = layers.BatchNormalization()(outputs)\n    outputs = Dropout(0.25)(outputs)\n    nefp = Dense(1, activation='sigmoid', name='negative_exam_for_pe')(outputs)\n    rlrg1 = Dense(1, activation='sigmoid', name='rv_lv_ratio_gte_1')(outputs)\n    rlrl1 = Dense(1, activation='sigmoid', name='rv_lv_ratio_lt_1')(outputs) \n    lspe = Dense(1, activation='sigmoid', name='leftsided_pe')(outputs)\n    cpe = Dense(1, activation='sigmoid', name='chronic_pe')(outputs)\n    rspe = Dense(1, activation='sigmoid', name='rightsided_pe')(outputs)\n    aacpe = Dense(1, activation='sigmoid', name='acute_and_chronic_pe')(outputs)\n    cnpe = Dense(1, activation='sigmoid', name='central_pe')(outputs)\n    indt = Dense(1, activation='sigmoid', name='indeterminate')(outputs)\n\n    model = Model(inputs=inputs, outputs={'negative_exam_for_pe':nefp,\n                                          'rv_lv_ratio_gte_1':rlrg1,\n                                          'rv_lv_ratio_lt_1':rlrl1,\n                                          'leftsided_pe':lspe,\n                                          'chronic_pe':cpe,\n                                          'rightsided_pe':rspe,\n                                          'acute_and_chronic_pe':aacpe,\n                                          'central_pe':cnpe,\n                                          'indeterminate':indt})\n\n    opt = keras.optimizers.Adam(lr=0.001)\n    #loss = binary_focal_loss()\n    model.compile(optimizer=opt,\n                  #loss=loss,\n                  loss='binary_crossentropy',\n                  metrics=['AUC'])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def convert_to_rgb(array):\n    array = array.reshape((256, 256, 3))\n    return array#np.stack([array, array, array], axis=2).reshape((256, 256, 3))\n    \ndef custom_dcom_image_generator(batch_size, dataset, test=False, debug=False):\n    \n    fnames = dataset[['StudyInstanceUID', 'SeriesInstanceUID', 'SOPInstanceUID']]\n    \n    if not test:\n        Y = dataset[['negative_exam_for_pe', 'rv_lv_ratio_gte_1', 'rv_lv_ratio_lt_1',\n                     'leftsided_pe', 'chronic_pe', 'rightsided_pe',\n                     'acute_and_chronic_pe', 'central_pe', 'indeterminate']]\n        prefix = 'input/rsna-str-pulmonary-embolism-detection/train'\n        \n    else:\n        prefix = 'input/rsna-str-pulmonary-embolism-detection/test'\n    \n    X = []\n    batch = 0\n    for st, sr, so in fnames.values:\n        if debug:\n            print(f\"Current file: ../{prefix}/{st}/{sr}/{so}.dcm\")\n\n        dicom = get_img(f\"../{prefix}/{st}/{sr}/{so}.dcm\")\n        image = convert_to_rgb(dicom)\n        X.append(image)\n        \n        del st, sr, so\n        \n        if len(X) == batch_size:\n            if test:\n                yield np.array(X)\n                del X\n            else:\n                yield np.array(X), Y[batch*batch_size:(batch+1)*batch_size].values\n                del X\n                \n            gc.collect()\n            X = []\n            batch += 1\n        \n    if test:\n        yield np.array(X)\n    else:\n        yield np.array(X), Y[batch*batch_size:(batch+1)*batch_size].values\n        del Y\n    del X\n    gc.collect()\n    return","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MAX_LENGTH = 256.\nfrom scipy.ndimage.interpolation import zoom\ndef window(img, WL=50, WW=350):\n    upper, lower = WL+WW//2, WL-WW//2\n    X = np.clip(img.copy(), lower, upper)\n    X = X - np.min(X)\n    X = X / np.max(X)\n    #X = (X*255.0)\n    return X\n\ndef img_convert(image):\n    image_lung = np.expand_dims(window(image, WL=-600, WW=1500), axis=-1)\n    image_mediastinal = np.expand_dims(window(image, WL=40, WW=400), axis=-1)\n    image_pe_specific = np.expand_dims(window(image, WL=100, WW=700), axis=-1)\n    image = np.concatenate([image_mediastinal, image_pe_specific, image_lung], axis=-1)\n    rat = MAX_LENGTH / np.max(image.shape[1:])\n    image = zoom(image, [rat,rat,1.], prefilter=False, order=1)\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cnt=0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import vtk\nfrom vtk.util import numpy_support\nimport cv2\n\nreader = vtk.vtkDICOMImageReader()\n\n\ndef get_img(path):\n    dicoms = pydicom.dcmread(path)\n    M = float(dicoms.RescaleSlope)\n    B = float(dicoms.RescaleIntercept)\n    # Assume all images are axial\n    z_pos = [float(dicoms.ImagePositionPatient[-1])]\n    dicoms = np.asarray([dicoms.pixel_array])\n    dicoms = dicoms[np.argsort(z_pos)]\n    dicoms = dicoms * M\n    dicoms = dicoms + B\n    image = dicoms\n    image_lung = np.expand_dims(window(image, WL=-600, WW=1500), axis=3)\n    image_mediastinal = np.expand_dims(window(image, WL=40, WW=400), axis=3)\n    image_pe_specific = np.expand_dims(window(image, WL=100, WW=700), axis=3)\n    image = np.concatenate([image_mediastinal, image_pe_specific, image_lung], axis=3)\n    rat = MAX_LENGTH / np.max(image.shape[1:])\n    image = zoom(image, [1.,rat,rat,1.], prefilter=False, order=1)\n\n    #plt.imshow(image[0])\n    #plt.show()\n\n    return image[0]\n\nfrom tensorflow.keras import backend as K\n\npredictions = {}\nstopper = 3600 * 8.75 #9 hours limit for prediction\npred_start_time = time.time()\n\np, c = time.time(), time.time()\nbatch_size = 1536\n    \nl = 0\nn = test.shape[0]\n\nmodel = build_model(train_type=1)\nmodel.load_weights(\"../input/rsnaefnetb3v2/fold-0.h5\")\n\nfor x in custom_dcom_image_generator(batch_size, test, True, False):\n    clear_output(wait=True)\n    \n    preds = model.predict(x, batch_size=32, verbose=1)\n    #print(preds)\n    try:\n        for key in preds.keys():\n            predictions[key] += preds[key].flatten().tolist()\n            \n    except Exception as e:\n        print(e)\n        for key in preds.keys():\n            predictions[key] = preds[key].flatten().tolist()\n            \n    l = (l+batch_size)%n\n    print('Total predicted:', len(predictions['indeterminate']),'/', n)\n    p, c = c, time.time()\n    print(\"One batch time: %.2f seconds\" %(c-p))\n    print(\"ETA: %.2f\" %((n-l)*(c-p)/batch_size))\n    \n    if c - pred_start_time >= stopper:\n        print(\"Time's up!\")\n        break\n    \n    #del model\n    #K.clear_session()\n    \n    del x, preds\n    gc.collect()\n    #break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for key in predictions.keys():\n    print(key, np.array(predictions[key]).shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_ids = []\nfor v in test.StudyInstanceUID:\n    if v not in test_ids:\n        test_ids.append(v)\n        \ntest_preds = test.copy()\ntest_preds = pd.concat([test_preds, pd.DataFrame(predictions)], axis=1)\ntest_preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IDS = []\nlabels = []\n\nfor label in ['negative_exam_for_pe', 'rv_lv_ratio_gte_1', 'rv_lv_ratio_lt_1',\n                 'leftsided_pe', 'chronic_pe', 'rightsided_pe',\n                 'acute_and_chronic_pe', 'central_pe', 'indeterminate']:\n    for key in test_ids:\n        temp = test_preds.loc[test_preds.StudyInstanceUID==key]\n        \n        IDS.append('_'.join([key, label]))\n        labels.append(np.max(temp[label]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IDS += test_preds.SOPInstanceUID.tolist()\nlabels += test_preds['negative_exam_for_pe'].tolist()\n\nsub = pd.DataFrame({\"id\":IDS, 'label':labels})\nsub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.fillna(0.28, inplace=True)\nsub.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}