[{'role': 'system', 'content': "You are an expert in machine learning and your task is to classify the code snippets into categories from the provided list of categories. List of categories: ['helper_functions', 'load_data', 'data_exploration', 'data_preprocessing', 'evaluation', 'modelling', 'prediction', 'result_visualization', 'save_results', 'comment_only']"}, {'role': 'user', 'content': 'Identify to which category the provided code belongs and assign the code snippet to at least 1 but up to 5 categories based on the probabilities, ignore if the probability of the category is negligible. Strictly provide your response as a list. Avoid providing any additional information, commentary, or personal opinions.\\nPython Code:########################################################################################################################\n# ======================================================================================================================\n# u_model_blocks\n# ======================================================================================================================\n########################################################################################################################\n# needed for u_model\n\n# standard-module imports\nfrom keras.layers import add, concatenate, Conv2D, MaxPooling2D\nfrom keras.layers import BatchNormalization, Lambda\nfrom keras.layers.advanced_activations import ELU, LeakyReLU\n\n\n# ======================================================================================================================\n# utility blocks needed for internal performance\n# ======================================================================================================================\n\ndef NConv2D(filters, kernel_size, strides=(1, 1), padding=\'valid\', dilation_rate=1,\n            activation=None, kernel_initializer=\'glorot_uniform\'):\n    """Create a (Normalized Conv2D followed by a chosen activation) function\n    Conv2D -> BatchNormalization -> activation()\n\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n    convolution)\n    :param kernel_size: An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution\n                        window. Can be a single integer to specify the same value for all spatial dimensions.\n    :param strides: An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height\n                    and width. Can be a single integer to specify the same value for all spatial dimensions.\n                    Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param dilation_rate: an integer or tuple/list of a single integer, specifying the dilation rate\n                    to use for dilated convolution. Currently, specifying any dilation_rate value != 1\n                    is incompatible with specifying any strides value != 1\n    :param activation:  string, one of \'elu\' or \'relu\' or None (case-sensitive),\n                        specifies activation function to be performed after BatchNormalization\n    :param kernel_initializer: Initializer for the kernel weights matrix (see initializers in keras documentation)\n    :return: a function, combined of 2D Convolution, followed by BatchNormalization across filters,\n             and specified activation in that order\n    """\n    assert activation in [\'relu\', \'elu\', None]\n    # actv is a function, not a string, like activation\n    actv = activation == \'relu\' and (lambda: LeakyReLU(0.0)) or activation == \'elu\' and (lambda: ELU(1.0)) or None\n\n    def f(_input):\n        conv = Conv2D(filters=filters, kernel_size=kernel_size, strides=strides, padding=padding,\n                      dilation_rate=dilation_rate, kernel_initializer=kernel_initializer)(_input)\n        norm = BatchNormalization(axis=3)(conv)\n        return actv()(norm)\n\n    return f\n\n\n# needed for rblock (residual block)\ndef _shortcut(_input, residual):\n    stride_width = _input._keras_shape[1] / residual._keras_shape[1]\n    stride_height = _input._keras_shape[2] / residual._keras_shape[2]\n    equal_channels = residual._keras_shape[3] == _input._keras_shape[3]\n\n    shortcut = _input\n    # 1 X 1 conv if shape is different. Else identity.\n    if stride_width > 1 or stride_height > 1 or not equal_channels:\n        shortcut = Conv2D(filters=residual._keras_shape[3], kernel_size=(1, 1),\n                          strides=(stride_width, stride_height),\n                          kernel_initializer="he_normal", padding="valid")(_input)\n\n    return add([shortcut, residual])\n\n\ndef rblock(inputs, filters, kernel_size, padding=\'valid\', activation=None, scale=0.1):\n    """Create a scaled Residual block connecting the down-path and the up-path of the u-net architecture\n\n    Activations are scaled by a constant to prevent the network from dying. Usually is set between 0.1 and 0.3. See:\n    https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output convolution filters)\n    :param kernel_size: An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution\n                        window. Can be a single integer to specify the same value for all spatial dimensions.\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param activation:  string, one of \'elu\' or \'relu\' or None (case-sensitive),\n                        specifies activation function to use everywhere in the block\n    :param scale: scaling factor preventing the network from dying out\n    :return: 4D tensor (samples, rows, cols, channels) output of a residual block, given inputs\n    """\n    assert activation in [\'relu\', \'elu\', None]\n    # actv is a function, not a string, like activation\n    actv = activation == \'relu\' and (lambda: LeakyReLU(0.0)) or activation == \'elu\' and (lambda: ELU(1.0)) or None\n\n    residual = Conv2D(filters=filters, kernel_size=kernel_size, padding=padding)(inputs)\n    residual = BatchNormalization(axis=3)(residual)\n    residual = Lambda(lambda x: x * scale)(residual)\n    res = _shortcut(inputs, residual)\n    return actv()(res)\n\n\n# ======================================================================================================================\n# information blocks\n# ======================================================================================================================\n\ndef convolution_block(inputs, filters, kernel_size=(3, 3), padding=\'valid\', activation=None,\n                      version=\'normalized\', pars={}, allowed_pars={}):\n    """Create a version of a convolution block.\n\n    Versions: with and without batch-normalization after convolutions.\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param kernel_size: An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution\n                        window. Can be a single integer to specify the same value for all spatial dimensions.\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param activation: string, specifies activation function to use everywhere in the block\n    :param version: version of the convolution block, one of \'not_normalized\', \'normalized\' (case sensitive)\n    :param pars: dictionary of parameters passed to u-net, determines the version, if this type of block is chosen\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n    :return: 4D tensor (samples, rows, cols, channels) output of a convolution block, given inputs\n    """\n    assert activation in [\'relu\', \'elu\', None]\n\n    # checking that the allowed version names did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'information_block\').get(\'convolution\').get(\'simple\') == [\'not_normalized\',\n                                                                                          \'normalized\']\n    # keep version argument if need to use without PARS\n    assert version in [\'not_normalized\', \'normalized\']\n    # setting the version from pars\n    if pars.get(\'information_block\').get(\'convolution\').get(\'simple\') is not None:\n        version = pars.get(\'information_block\').get(\'convolution\').get(\'simple\')\n\n    if version == \'normalized\':\n        conv1 = NConv2D(filters=filters, kernel_size=kernel_size, activation=activation, padding=padding)(inputs)\n        return NConv2D(filters=filters, kernel_size=kernel_size, activation=activation, padding=padding)(conv1)\n    else:\n        conv1 = Conv2D(filters=filters, kernel_size=kernel_size, activation=activation, padding=padding)(inputs)\n        return Conv2D(filters=filters, kernel_size=kernel_size, activation=activation, padding=padding)(conv1)\n\n\ndef dilated_convolution_block(inputs, filters, kernel_size=(3, 3), padding=\'valid\', activation=None,\n                              version=\'normalized\', pars={}, allowed_pars={}):\n    """Create a version of a dilated-convolution block.\n\n    Versions: with and without batch-normalization after dilated convolutions.\n\n    See more about dilated convolutions:\n    https://towardsdatascience.com/review-dilated-convolution-semantic-segmentation-9d5a5bd768f5\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param kernel_size: An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution\n                        window. Can be a single integer to specify the same value for all spatial dimensions.\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param activation: string, specifies activation function to use everywhere in the block\n    :param version: version of the dilated-convolution block, one of \'not_normalized\', \'normalized\' (case sensitive)\n    :param pars: dictionary of parameters passed to u-net, determines the version, if this type of block is chosen\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n    :return: 4D tensor (samples, rows, cols, channels) output of a dilated-convolution block, given inputs\n    """\n    assert activation in [\'relu\', \'elu\', None]\n\n    # checking that the allowed version names did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'information_block\').get(\'convolution\').get(\'dilated\') == [\'not_normalized\',\n                                                                                           \'normalized\']\n    # keep version argument if need to use without PARS\n    assert version in [\'not_normalized\', \'normalized\']\n    # setting the version from pars\n    if pars.get(\'information_block\').get(\'convolution\') is not None:\n        version = pars.get(\'information_block\').get(\'convolution\')\n\n    if version == \'normalized\':\n        conv1 = NConv2D(filters=filters, kernel_size=kernel_size, padding=padding,\n                        dilation_rate=2, activation=activation)(inputs)\n        return NConv2D(filters=filters, kernel_size=kernel_size, padding=padding,\n                       dilation_rate=1, activation=activation)(conv1)\n    else:\n        conv1 = Conv2D(filters=filters, kernel_size=kernel_size, padding=padding,\n                       dilation_rate=2, activation=activation)(inputs)\n        return Conv2D(filters=filters, kernel_size=kernel_size, padding=padding,\n                      dilation_rate=1, activation=activation)(conv1)\n\n\ndef inception_block_v1(inputs, filters, activation=None, version=\'b\', pars={}, allowed_pars={}):\n    """Create a version of v1 inception block described in:\n    https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202\n\n    Create an inception block described in v1, sections \'a\' (for naive version), or \'b\' (with dimension reduction)\n    Each version has 4 verticals in their structure. See the link above.\n\n    For all versions, verticals 1 and 2 of the block start with 2D convolution, which:\n        reduces the number of input filters to next convolutions (to make computation cheaper)\n        uses (1, 1) kernels, no Normalization\n        is NOT normalized\n        is followed by specified activation\n    For all versions, verticals 1, 2, 3:\n        the final convolution layer is not normalised and not activated since it will be dene after concatenation\n    Vertical 4 is just a Conv2D. Its gets normalized and activated after being concatenated with\n        outputs of other verticals.\n    The concatenated output of the verticals is normalised and then activated with a given activation\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n    convolution).\n    :param activation: string, specifies activation function to use everywhere in the block\n    :param version: version of inception block, one of \'a\', \'b\' (case sensitive)\n    :param pars: dictionary of parameters passed to u-net, determines the version, if this type of block is chosen\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n    :return: 4D tensor (samples, rows, cols, channels) output of an inception block, given inputs\n    """\n\n    assert filters % 16 == 0\n\n    # checking that the allowed version names did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'information_block\').get(\'inception\').get(\'v1\') == [\'a\', \'b\']\n    # keep version argument if need to use without PARS\n    assert version in [\'a\', \'b\']\n    # setting the version from pars\n    if pars.get(\'information_block\').get(\'inception\').get(\'v1\') is not None:\n        version = pars.get(\'information_block\').get(\'inception\').get(\'v1\')\n\n    assert activation in [\'relu\', \'elu\', None]\n    # actv is a function, not a string, like activation\n    actv = activation == \'relu\' and (lambda: LeakyReLU(0.0)) or activation == \'elu\' and (lambda: ELU(1.0)) or None\n\n    # vertical 1\n    if version == \'a\':\n        c1 = Conv2D(filters=filters // 8, kernel_size=(5, 5), padding=\'same\', kernel_initializer=\'he_normal\')(inputs)\n    else:\n        c1_1 = Conv2D(filters=filters // 16, kernel_size=(1, 1), padding=\'same\',\n                      activation=activation, kernel_initializer=\'he_normal\')(inputs)\n        c1 = Conv2D(filters=filters // 8, kernel_size=(5, 5), padding=\'same\', kernel_initializer=\'he_normal\')(c1_1)\n\n    # vertical 2\n    if version == \'a\':\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 3), padding=\'same\', kernel_initializer=\'he_normal\')(inputs)\n    else:\n        c2_1 = Conv2D(filters=filters // 8 * 3, kernel_size=(1, 1), padding=\'same\',\n                      activation=activation, kernel_initializer=\'he_normal\')(inputs)\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 3), padding=\'same\', kernel_initializer=\'he_normal\')(c2_1)\n\n    # vertical 3\n    p3_1 = MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding=\'same\')(inputs)\n    if version == \'b\':\n        c3 = Conv2D(filters=filters // 8, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(p3_1)\n    else:\n        c3 = p3_1\n\n    # vertical 4\n    c4_1 = Conv2D(filters=filters // 4, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(inputs)\n    c4 = c4_1\n\n    # concatenating verticals together, normalizing and applying activation\n    result = concatenate([c1, c2, c3, c4], axis=3)\n    result = BatchNormalization(axis=3)(result)\n    result = actv()(result)\n    return result\n\n\ndef inception_block_v2(inputs, filters, activation=None, version=\'b\', pars={}, allowed_pars={}):\n    """Create a version of v1 inception block described in:\n    https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202\n\n    Create an inception block described in v2, sections \'a\', \'b\', or \'c\'\n    Each version has 4 verticals in their structure. See the link above.\n\n    For all versions, verticals 1 and 2 of the block start with 2D convolution, which:\n        reduces the number of input filters to next convolutions (to make computation cheaper)\n        uses (1, 1) kernels, no Normalization\n        is NOT normalized\n        is followed by specified activation\n    For all versions, verticals 1, 2, 3:\n        the middle convolutions use NConv2D with given activation, see its docstring\n        the final convolution layer is not normalised and not activated since it will be dene after concatenation\n    Vertical 4 is just a Conv2D. Its gets normalized and activated after being concatenated with\n        outputs of other verticals.\n    The concatenated output of the verticals is normalised and then activated with a given activation\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param activation: string, specifies activation function to use everywhere in the block\n    :param version: version of inception block, one of \'a\', \'b\', \'c\' (case sensitive)\n    :param pars: dictionary of parameters passed to u-net, determines the version, if this type of block is chosen\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n    :return: 4D tensor (samples, rows, cols, channels) output of an inception block, given inputs\n    """\n    assert filters % 16 == 0\n\n    # checking that the allowed version names did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'information_block\').get(\'inception\').get(\'v2\') == [\'a\', \'b\', \'c\']\n    # keep version argument if need to use without PARS\n    assert version in [\'a\', \'b\', \'c\']\n    # setting the version from pars\n    if pars.get(\'information_block\').get(\'inception\').get(\'v2\') is not None:\n        version = pars.get(\'information_block\').get(\'inception\').get(\'v2\')\n\n    assert activation in [\'relu\', \'elu\', None]\n    # actv is a function, not a string, like activation\n    actv = activation == \'relu\' and (lambda: LeakyReLU(0.0)) or activation == \'elu\' and (lambda: ELU(1.0)) or None\n\n    # vertical 1\n    c1_1 = Conv2D(filters=filters // 16, kernel_size=(1, 1), padding=\'same\',\n                  activation=activation, kernel_initializer=\'he_normal\')(inputs)\n    if version == \'a\':\n        c1_2 = NConv2D(filters=filters // 8, kernel_size=3, padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_1)\n        c1 = Conv2D(filters=filters // 8, kernel_size=3, padding=\'same\', kernel_initializer=\'he_normal\')(c1_2)\n    elif version == \'b\':\n        c1_2 = NConv2D(filters=filters // 8, kernel_size=(1, 3), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_1)\n        c1_3 = NConv2D(filters=filters // 8, kernel_size=(3, 1), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_2)\n        c1_4 = NConv2D(filters=filters // 8, kernel_size=(1, 3), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_3)\n        c1 = Conv2D(filters=filters // 8, kernel_size=(3, 1), padding=\'same\', kernel_initializer=\'he_normal\')(c1_4)\n    else:\n        c1_2 = NConv2D(filters=filters // 8, kernel_size=(1, 3), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_1)\n        c1_3 = NConv2D(filters=filters // 8, kernel_size=3, padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_2)\n        c1_41 = Conv2D(filters=filters // 8, kernel_size=(1, 3), padding=\'same\', kernel_initializer=\'he_normal\')(c1_3)\n        c1_42 = Conv2D(filters=filters // 8, kernel_size=(3, 1), padding=\'same\', kernel_initializer=\'he_normal\')(c1_3)\n        c1 = concatenate([c1_41, c1_42], axis=3)\n\n    # vertical 2\n    c2_1 = Conv2D(filters=filters // 8 * 3, kernel_size=(1, 1), padding=\'same\',\n                  activation=activation, kernel_initializer=\'he_normal\')(inputs)\n    if version == \'a\':\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 3), padding=\'same\', kernel_initializer=\'he_normal\')(c2_1)\n    elif version == \'b\':\n        c2_2 = NConv2D(filters=filters // 2, kernel_size=(1, 3), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c2_1)\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 1), padding=\'same\', kernel_initializer=\'he_normal\')(c2_2)\n    else:\n        c2_21 = Conv2D(filters=filters // 2, kernel_size=(1, 3), padding=\'same\', kernel_initializer=\'he_normal\')(c2_1)\n        c2_22 = Conv2D(filters=filters // 2, kernel_size=(3, 1), padding=\'same\', kernel_initializer=\'he_normal\')(c2_1)\n        c2 = concatenate([c2_21, c2_22], axis=3)\n\n    # vertical 3\n    p3_1 = MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding=\'same\')(inputs)\n    c3 = Conv2D(filters=filters // 8, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(p3_1)\n\n    # vertical 4\n    c4 = Conv2D(filters=filters // 4, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(inputs)\n\n    # concatenating verticals together, normalizing and applying activation\n    result = concatenate([c1, c2, c3, c4], axis=3)\n    result = BatchNormalization(axis=3)(result)\n    result = actv()(result)\n    return result\n\n\ndef inception_block_et(inputs, filters, activation=\'relu\', version=\'b\', pars={}, allowed_pars={}):\n    """Create an inception block with 2 options.\n    For intuition read, parts v1 and v2:\n    https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202\n\n    Each version/option has 4 verticals in their structure. See the link above.\n    Default option: version=\'b\'\n        Create an inception block close to one described in v2, but keeps 5 as a factor for some convolutions\n    Alternative option: version=\'a\'\n        Create an inception block described in v1, section\n\n\n    Function author Edward Tyantov. That\'s why the name: inception_block_et.\n    My modifications\n\n        use version=\'a\' instead of split=False\n        use version=\'b\' instead of split=True\n\n        change default to version=\'b\', aka split=True\n\n        swap: Conv2D -> BatchNormalization -> activation\n        to:   NConv2D blocks. See NConv2D documentation for them.\n\n        swap: Conv2D -> activation\n        to:   Conv2D -> Conv2D(activation=activation)\n\n        change the order of the verticals to coincide with v2_paper notation\n\n        change names of the outputs of the block verticals to c1, c2, c3, c4\n\n        use \'result\' instead of \'res\' to avoid confusion with residuals\n\n    :param inputs: Input 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param activation: activation function to use everywhere in the block\n    :param version: version of inception block\n    :param pars: dictionary of parameters passed to u-net, determines the version, if this type of block is chosen\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n    :return: 4D tensor (samples, rows, cols, channels) output of an inception block, given inputs\n    """\n    assert filters % 16 == 0\n\n    # checking that the allowed version names did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'information_block\').get(\'inception\').get(\'et\') == [\'a\', \'b\']\n    # keep version argument if need to use without PARS\n    assert version in [\'a\', \'b\']\n    # setting the version from pars\n    if pars.get(\'information_block\').get(\'inception\').get(\'et\') is not None:\n        version = pars.get(\'information_block\').get(\'inception\').get(\'et\')\n\n    assert activation in [\'relu\', \'elu\', None]\n    # actv is a function, not a string, like activation\n    actv = activation == \'relu\' and (lambda: LeakyReLU(0.0)) or activation == \'elu\' and (lambda: ELU(1.0)) or None\n\n    # vertical 1\n    c1_1 = Conv2D(filters=filters // 16, kernel_size=(1, 1), padding=\'same\',\n                  activation=activation, kernel_initializer=\'he_normal\')(inputs)\n    if version == \'b\':\n        c1_2 = NConv2D(filters=filters // 8, kernel_size=(1, 5), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c1_1)\n        c1 = Conv2D(filters=filters // 8, kernel_size=(5, 1), kernel_initializer=\'he_normal\', padding=\'same\')(c1_2)\n    else:\n        c1 = Conv2D(filters=filters // 8, kernel_size=(5, 5), kernel_initializer=\'he_normal\', padding=\'same\')(c1_1)\n\n    # vertical 2\n    c2_1 = Conv2D(filters=filters // 8 * 3, kernel_size=(1, 1), padding=\'same\',\n                  activation=activation, kernel_initializer=\'he_normal\')(inputs)\n    if version == \'b\':\n        c2_2 = NConv2D(filters=filters // 2, kernel_size=(1, 3), padding=\'same\',\n                       activation=activation, kernel_initializer=\'he_normal\')(c2_1)\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 1), kernel_initializer=\'he_normal\', padding=\'same\')(c2_2)\n    else:\n        c2 = Conv2D(filters=filters // 2, kernel_size=(3, 3), kernel_initializer=\'he_normal\', padding=\'same\')(c2_1)\n\n    # vertical 3\n    p3_1 = MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding=\'same\')(inputs)\n    c3 = Conv2D(filters=filters // 8, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(p3_1)\n\n    # vertical 4\n    c4 = Conv2D(filters=filters // 4, kernel_size=(1, 1), padding=\'same\', kernel_initializer=\'he_normal\')(inputs)\n\n    # concatenating verticals together, normalizing and applying activation\n    result = concatenate([c1, c2, c3, c4], axis=3)\n    result = BatchNormalization(axis=3)(result)\n    result = actv()(result)\n    return result\n\n\n# ======================================================================================================================\n# Combining blocks, allowing to use different blocks from before\n# ======================================================================================================================\n\ndef pooling_block(inputs, filters, kernel_size=(3, 3), strides=(2, 2), padding=\'same\', activation=None,\n                  pool_size=(2, 2), trainable=True, pars={}, allowed_pars={}):\n    """Function returning the output of one of the pooling blocks.\n\n    Allows not to make different versions of the u-net in terms of how pooling operation is performed:\n        1) trainable (default): through NConv2D custom function, see its documentation\n        2) non-trainable (alternative): through MaxPooling operation\n\n    To get the expected behaviour when changing \'trainable\' assert strides == pool_size\n\n    Parameters starting with p_ are only to be used for (trainable=False) MaxPooling2D\n    Parameters starting with c_ are only to be used for (trainable=True) MaxPooling2D\n\n    :param inputs: 4D tensor (samples, rows, cols, channels)\n    :param filters:     NConv2D argument, filters\n    :param kernel_size: NConv2D argument, kernel_size\n    :param strides:     NConv2D argument, strides\n    :param padding:     NConv2D/MaxPooling2D argument, padding\n    :param activation:  NConv2D argument, activation\n    :param pool_size:   MaxPooling2D argument, pool_size\n\n    :param trainable: boolean specifying the version of a pooling block with default behaviour\n        trainable=True: NConv2D(inputs._keras_shape[3], kernel_size=kernel_size, strides=strides, padding=padding)(\n        inputs)\n        trainable=False: MaxPooling2D(pool_size=pool_size)(inputs)\n    :param pars: dictionary of parameters passed to u-net, determines the version of the block\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n\n    :return: 4D tensor (samples, rows, cols, channels) output of a pooling block\n    """\n    # checking that the allowed trainable parameters did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'pooling_block\').get(\'trainable\') == [True, False]\n    # keep trainable argument if need to use without PARS\n    assert trainable in [True, False]\n\n    # setting the version from pars\n    if pars.get(\'pooling_block\').get(\'trainable\') is not None:\n        trainable = pars.get(\'pooling_block\').get(\'trainable\')\n\n    # returning block\'s output\n    if trainable:\n        return NConv2D(filters=filters, kernel_size=kernel_size, strides=strides,\n                       padding=padding, activation=activation)(inputs)\n    else:\n        return MaxPooling2D(pool_size=pool_size, padding=padding)(inputs)\n\n\ndef information_block(inputs, filters, kernel_size=(3, 3), padding=\'valid\', activation=None,\n                      block=\'inception\', block_type=\'v2\', version=\'b\', pars={}, allowed_pars={}):\n    """Function returning the output of one of the information blocks.\n\n    :param inputs: 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param kernel_size: An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution\n                        window. Can be a single integer to specify the same value for all spatial dimensions.\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param activation: string, specifies activation function to use everywhere in the block\n\n    Next 3 parameters are there to be able to leave \'pars\' and \'allowed_pars\' empty\n    :param block:       one of \'inception\' or \'convolution\' (case-sensitive)\n    :param block_type:  if block == \'inception\', one of \'v1\', \'v2\', \'et\' (case-sensitive)\n                        if block == \'convolution\': one of \'simple\', \'dilated\' (case-sensitive)\n    :param version:     version of a block to use\n\n    :param pars: dictionary of parameters passed to u-net, determines the version of the block\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n\n    :return: 4D tensor (samples, rows, cols, channels) output of a information block\n    """\n    # getting which block, block_type, version to use as the information block\n    if pars.get(\'information_block\') is not None:\n        block = list(pars.get(\'information_block\').keys())[0]\n        block_type = list(pars.get(\'information_block\').get(block).keys())[0]\n        version = pars.get(\'information_block\').get(block).get(block_type)\n\n    # inception block\n    if block == \'inception\':\n        if block_type == \'v1\':\n            return inception_block_v1(inputs=inputs, filters=filters, activation=activation,\n                                      version=version, pars=pars, allowed_pars=allowed_pars)\n        elif block_type == \'v2\':\n            return inception_block_v2(inputs=inputs, filters=filters, activation=activation,\n                                      version=version, pars=pars, allowed_pars=allowed_pars)\n        else:\n            return inception_block_et(inputs=inputs, filters=filters, activation=activation,\n                                      version=version, pars=pars, allowed_pars=allowed_pars)\n    # convolution block\n    else:\n        if block_type == \'simple\':\n            return convolution_block(inputs=inputs, filters=filters, kernel_size=kernel_size,\n                                     padding=padding, activation=activation,\n                                     version=version, pars=pars, allowed_pars=allowed_pars)\n        else:\n            return dilated_convolution_block(inputs=inputs, filters=filters,\n                                             kernel_size=kernel_size, padding=padding,\n                                             activation=activation, version=version,\n                                             pars=pars, allowed_pars=allowed_pars)\n\n\ndef connection_block(inputs, filters, padding=\'valid\', activation=None,\n                     version=\'residual\', pars={}, allowed_pars={}):\n    """Function returning the output of one of the connection block.\n\n    :param inputs: 4D tensor (samples, rows, cols, channels)\n    :param filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the\n                    convolution).\n    :param padding: one of \'valid\' or \'same\' (case-insensitive), \'valid\' by default to have the same as Conv2D\n    :param activation:  string, one of \'elu\' or \'relu\' or None (case-sensitive),\n                        specifies activation function to use everywhere in the block\n\n    Version parameter is there to be able to leave \'pars\' and \'allowed_pars\' empty\n    :param version: one of \'not_residual\' or \'residual\', version of a block to use\n\n    :param pars: dictionary of parameters passed to u-net, determines the version of the block\n    :param allowed_pars: dictionary of all allowed to be passed to u-net parameters\n\n    :return: 4D tensor (samples, rows, cols, channels) output of a connection block\n    """\n    # checking that the allowed trainable parameters did not change in ALLOWED_PARS\n    if allowed_pars != {}:\n        assert allowed_pars.get(\'connection_block\') == [\'not_residual\', \'residual\']\n    # keep trainable argument if need to use without PARS\n    assert version in [\'not_residual\', \'residual\']\n    # setting the version from pars\n    if pars.get(\'connection_block\') is not None:\n        version = pars.get(\'connection_block\')\n\n    if version == \'residual\':\n        return rblock(inputs=inputs, filters=32, kernel_size=(1, 1), padding=\'same\', activation=activation)\n    else:\n        return Conv2D(filters=filters, kernel_size=(2, 2), padding=padding, kernel_initializer=\'he_normal\')(inputs)\n\''}, {'role': 'assistant', 'content': "['helper_functions', 'comment_only']"}]