r"""Bayesian Xception models.

This file contains modified architectures of the Xception model for producing uncertainty estimates.
We have three classes of models:

1. Full model: Contains the same depth and same number of feature maps as the xception model and has
   dropout layers in different regions of the entry, middle and exit flows of the network.

2. Intermediate model: Contains the same depth as the xception model but the number of feature maps
   are reduced by a factor of 8.

3. Reduced model: Contains 1 xception block in the entry flow, 6 blocks in the middle flow and 1
   block in the exit flow. The number of feature maps of the network are also reduced by a factor of 8.
"""

from xception import xception_block
from xception import xception

"""Defining the full Bayesian Xception models below."""
def bayesian_xception_full_entry_flow(inputs,
                                    num_classes=None,
                                    is_training=True,
                                    global_pool=True,
                                    keep_prob=0.5,
                                    output_stride=None,
                                    regularize_depthwise=False,
                                    multi_grid=None,
                                    reuse=None,
                                    scope='bayesian_xception_full'):
  """Bayesian Xception full with dropout present in the entry flow only."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[128, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[256, 256, 256],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[728, 1024, 1024],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[1536, 1536, 2048],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_full_exit_flow(inputs,
                                   num_classes=None,
                                   is_training=True,
                                   global_pool=True,
                                   keep_prob=0.5,
                                   output_stride=None,
                                   regularize_depthwise=False,
                                   multi_grid=None,
                                   reuse=None,
                                   scope='bayesian_xception_full'):
  """Bayesian Xception full with dropout present in the exit flow only."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[128, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[256, 256, 256],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[728, 1024, 1024],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[1536, 1536, 2048],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_full_middle_flow(inputs,
                                     num_classes=None,
                                     is_training=True,
                                     global_pool=True,
                                     keep_prob=0.5,
                                     output_stride=None,
                                     regularize_depthwise=False,
                                     multi_grid=None,
                                     reuse=None,
                                     scope='bayesian_xception_full'):
  """Bayesian Xception full with dropout present in the middle flow only.
     There are 16 xception modules in the middle flow but we apply dropout
     after every fourth xception modules. So there are a total of 4 dropout
     layers."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[128, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[256, 256, 256],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block2',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block4',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block5',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block6',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block7',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block8',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[728, 1024, 1024],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[1536, 1536, 2048],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_full_entry_exit_flow(inputs,
                                         num_classes=None,
                                         is_training=True,
                                         global_pool=True,
                                         keep_prob=0.5,
                                         output_stride=None,
                                         regularize_depthwise=False,
                                         multi_grid=None,
                                         reuse=None,
                                         scope='bayesian_xception_full'):
  """Bayesian Xception full with dropout present in both the entry and exit flows."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[128, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[256, 256, 256],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[728, 1024, 1024],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[1536, 1536, 2048],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_full_entry_middle_exit_flow(inputs,
                                                num_classes=None,
                                                is_training=True,
                                                global_pool=True,
                                                keep_prob=0.5,
                                                output_stride=None,
                                                regularize_depthwise=False,
                                                multi_grid=None,
                                                reuse=None,
                                                scope='bayesian_xception_full'):
  """Bayesian Xception full with dropout present in the entry, middle and exit flows.
     There are 16 xception modules in the middle flow but we apply dropout
     after every fourth xception modules. So there are a total of 4 dropout
     layers in the middle flow."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[128, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[256, 256, 256],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block2',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block3',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block4',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block5',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block6',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block7',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block8',
                     depth_list=[728, 728, 728],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[728, 1024, 1024],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[1536, 1536, 2048],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)




"""=============================================================================
   Defining the intermediate Bayesian Xception models below."""

def bayesian_xception_inter_entry_flow(inputs,
                                    num_classes=None,
                                    is_training=True,
                                    global_pool=True,
                                    keep_prob=0.5,
                                    output_stride=None,
                                    regularize_depthwise=False,
                                    multi_grid=None,
                                    reuse=None,
                                    scope='bayesian_xception_inter'):
  """Bayesian Xception inter with dropout present in the entry flow only."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[16, 16, 16],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[32, 32, 32],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[91, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[192, 192, 256],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_inter_exit_flow(inputs,
                                   num_classes=None,
                                   is_training=True,
                                   global_pool=True,
                                   keep_prob=0.5,
                                   output_stride=None,
                                   regularize_depthwise=False,
                                   multi_grid=None,
                                   reuse=None,
                                   scope='bayesian_xception_inter'):
  """Bayesian Xception inter with dropout present in the exit flow only."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[16, 16, 16],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[32, 32, 32],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[91, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[192, 192, 256],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_inter_middle_flow(inputs,
                                     num_classes=None,
                                     is_training=True,
                                     global_pool=True,
                                     keep_prob=0.5,
                                     output_stride=None,
                                     regularize_depthwise=False,
                                     multi_grid=None,
                                     reuse=None,
                                     scope='bayesian_xception_inter'):
  """Bayesian Xception inter with dropout present in the middle flow only.
     There are 16 xception modules in the middle flow but we apply dropout
     after every fourth xception modules. So there are a total of 4 dropout
     layers."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[16, 16, 16],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[32, 32, 32],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block2',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block4',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block5',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block6',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block7',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block8',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[91, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[192, 192, 256],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_inter_entry_exit_flow(inputs,
                                         num_classes=None,
                                         is_training=True,
                                         global_pool=True,
                                         keep_prob=0.5,
                                         output_stride=None,
                                         regularize_depthwise=False,
                                         multi_grid=None,
                                         reuse=None,
                                         scope='bayesian_xception_inter'):
  """Bayesian Xception inter with dropout present in both the entry and exit flows."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[16, 16, 16],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[32, 32, 32],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=16,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[91, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[192, 192, 256],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


def bayesian_xception_inter_entry_middle_exit_flow(inputs,
                                                num_classes=None,
                                                is_training=True,
                                                global_pool=True,
                                                keep_prob=0.5,
                                                output_stride=None,
                                                regularize_depthwise=False,
                                                multi_grid=None,
                                                reuse=None,
                                                scope='bayesian_xception_inter'):
  """Bayesian Xception inter with dropout present in the entry, middle and exit flows.
     There are 16 xception modules in the middle flow but we apply dropout
     after every fourth xception modules. So there are a total of 4 dropout
     layers in the middle flow."""
  blocks = [
      xception_block('entry_flow/block1',
                     depth_list=[16, 16, 16],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block2',
                     depth_list=[32, 32, 32],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('entry_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('middle_flow/block1',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block2',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block3',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block4',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block5',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block6',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('middle_flow/block7',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=False,
                     num_units=3,
                     stride=1),
      xception_block('middle_flow/block8',
                     depth_list=[91, 91, 91],
                     skip_connection_type='sum',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1),
      xception_block('exit_flow/block1',
                     depth_list=[91, 128, 128],
                     skip_connection_type='conv',
                     activation_fn_in_separable_conv=False,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=2),
      xception_block('exit_flow/block2',
                     depth_list=[192, 192, 256],
                     skip_connection_type='none',
                     activation_fn_in_separable_conv=True,
                     regularize_depthwise=regularize_depthwise,
                     dropout=True,
                     num_units=1,
                     stride=1,
                     unit_rate_list=multi_grid),
  ]
  return xception(inputs,
                  blocks=blocks,
                  num_classes=num_classes,
                  is_training=is_training,
                  global_pool=global_pool,
                  keep_prob=keep_prob,
                  output_stride=output_stride,
                  reuse=reuse,
                  scope=scope)


"""==========================================================================================
Defining the reduced Bayesian Xception models below."""

# def bayesian_xception_red_entry_flow(inputs,
#                                     num_classes=None,
#                                     is_training=True,
#                                     global_pool=True,
#                                     keep_prob=0.5,
#                                     output_stride=None,
#                                     regularize_depthwise=False,
#                                     multi_grid=None,
#                                     reuse=None,
#                                     scope='bayesian_xception_inter'):
#   """Bayesian Xception reduced with dropout present in the entry flow only."""
#   blocks = [
#       xception_block('entry_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='conv',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=2),
#       xception_block('middle_flow/block1',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=6,
#                      stride=1),
#       xception_block('exit_flow/block1',
#                      depth_list=[128, 192, 256],
#                      skip_connection_type='none',
#                      activation_fn_in_separable_conv=True,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1,
#                      unit_rate_list=multi_grid),
#   ]
#   return xception(inputs,
#                   blocks=blocks,
#                   num_classes=num_classes,
#                   is_training=is_training,
#                   global_pool=global_pool,
#                   keep_prob=keep_prob,
#                   output_stride=output_stride,
#                   reuse=reuse,
#                   scope=scope)
#
#
# def bayesian_xception_red_exit_flow(inputs,
#                                     num_classes=None,
#                                     is_training=True,
#                                     global_pool=True,
#                                     keep_prob=0.5,
#                                     output_stride=None,
#                                     regularize_depthwise=False,
#                                     multi_grid=None,
#                                     reuse=None,
#                                     scope='bayesian_xception_inter'):
#   """Bayesian Xception reduced with dropout present in the exit flow only."""
#   blocks = [
#       xception_block('entry_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='conv',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=2),
#       xception_block('middle_flow/block1',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=6,
#                      stride=1),
#       xception_block('exit_flow/block1',
#                      depth_list=[128, 192, 256],
#                      skip_connection_type='none',
#                      activation_fn_in_separable_conv=True,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1,
#                      unit_rate_list=multi_grid),
#   ]
#   return xception(inputs,
#                   blocks=blocks,
#                   num_classes=num_classes,
#                   is_training=is_training,
#                   global_pool=global_pool,
#                   keep_prob=keep_prob,
#                   output_stride=output_stride,
#                   reuse=reuse,
#                   scope=scope)
#
#
# def bayesian_xception_red_middle_flow(inputs,
#                                     num_classes=None,
#                                     is_training=True,
#                                     global_pool=True,
#                                     keep_prob=0.5,
#                                     output_stride=None,
#                                     regularize_depthwise=False,
#                                     multi_grid=None,
#                                     reuse=None,
#                                     scope='bayesian_xception_inter'):
#   """Bayesian Xception reduced with dropout present in the exit flow only."""
#   blocks = [
#       xception_block('entry_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='conv',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=2),
#       xception_block('middle_flow/block1',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block3',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block4',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block5',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block6',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('exit_flow/block1',
#                      depth_list=[128, 192, 256],
#                      skip_connection_type='none',
#                      activation_fn_in_separable_conv=True,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1,
#                      unit_rate_list=multi_grid),
#   ]
#   return xception(inputs,
#                   blocks=blocks,
#                   num_classes=num_classes,
#                   is_training=is_training,
#                   global_pool=global_pool,
#                   keep_prob=keep_prob,
#                   output_stride=output_stride,
#                   reuse=reuse,
#                   scope=scope)
#
#
# def bayesian_xception_red_entry_exit_flow(inputs,
#                                     num_classes=None,
#                                     is_training=True,
#                                     global_pool=True,
#                                     keep_prob=0.5,
#                                     output_stride=None,
#                                     regularize_depthwise=False,
#                                     multi_grid=None,
#                                     reuse=None,
#                                     scope='bayesian_xception_inter'):
#   """Bayesian Xception reduced with dropout present in the entry and exit flows."""
#   blocks = [
#       xception_block('entry_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='conv',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=2),
#       xception_block('middle_flow/block1',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=6,
#                      stride=1),
#       xception_block('exit_flow/block1',
#                      depth_list=[128, 192, 256],
#                      skip_connection_type='none',
#                      activation_fn_in_separable_conv=True,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1,
#                      unit_rate_list=multi_grid),
#   ]
#   return xception(inputs,
#                   blocks=blocks,
#                   num_classes=num_classes,
#                   is_training=is_training,
#                   global_pool=global_pool,
#                   keep_prob=keep_prob,
#                   output_stride=output_stride,
#                   reuse=reuse,
#                   scope=scope)
#
#
# def bayesian_xception_red_entry_middle_exit_flow(inputs,
#                                     num_classes=None,
#                                     is_training=True,
#                                     global_pool=True,
#                                     keep_prob=0.5,
#                                     output_stride=None,
#                                     regularize_depthwise=False,
#                                     multi_grid=None,
#                                     reuse=None,
#                                     scope='bayesian_xception_inter'):
#   """Bayesian Xception reduced with dropout present in the entry, middle and exit flows."""
#   blocks = [
#       xception_block('entry_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='conv',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=2),
#       xception_block('middle_flow/block1',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block2',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block3',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block4',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block5',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=False,
#                      num_units=1,
#                      stride=1),
#       xception_block('middle_flow/block6',
#                      depth_list=[91, 91, 91],
#                      skip_connection_type='sum',
#                      activation_fn_in_separable_conv=False,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1),
#       xception_block('exit_flow/block1',
#                      depth_list=[128, 192, 256],
#                      skip_connection_type='none',
#                      activation_fn_in_separable_conv=True,
#                      regularize_depthwise=regularize_depthwise,
#                      dropout=True,
#                      num_units=1,
#                      stride=1,
#                      unit_rate_list=multi_grid),
#   ]
#   return xception(inputs,
#                   blocks=blocks,
#                   num_classes=num_classes,
#                   is_training=is_training,
#                   global_pool=global_pool,
#                   keep_prob=keep_prob,
#                   output_stride=output_stride,
#                   reuse=reuse,
#                   scope=scope)