0 votes
1 view
in Data Science by (12.2k points)

Here is a snippet code to design a Keras deep Model() based some simple blocks:

def conv_bn_activation(x, filters, kernel_size, strides, data_format, is_training, activation=relu,

                       name=None):

    """

    Parameters

    ----------

    x

    filters

    kernel_size

    strides

    data_format

    activation

    is_training

    name

    Returns

    -------

    """

    conv = tks.Conv2D(filters=filters,

                      kernel_size=kernel_size,

                      strides=strides,

                      padding='same',

                      data_format=data_format,

                      activation=None,

                      use_bias=False,

                      name=name)(x)

    bn = batch_norm(x=conv, is_training=is_training, data_format=data_format)

    if activation is not None:

        return activation(bn)

    else:

        return bn

def basic_block(x, filters, is_training, data_format):

    """

    Basic block function

    Parameters

    ----------

    x

    filters

    data_format

    is_training

    Returns

    -------

    """

    conv = conv_bn_activation(x=x, filters=filters, kernel_size=3, strides=1,

                              is_training=is_training, data_format=data_format)

    conv = conv_bn_activation(x=conv, filters=filters, kernel_size=3, strides=1,

                              is_training=is_training, data_format=data_format)

    axis = 3 if data_format == 'channels_last' else 1

    input_channels = x.get_shape().as_list()[axis]

    if input_channels == filters:

        short_cut = x

    else:

        short_cut = conv_bn_activation(x=x, filters=filters, kernel_size=1, strides=1,

                                       is_training=is_training, data_format=data_format)

    return conv + short_cut

img_input_shape = [None, None, 3]

inputs = []

img_input = Input(shape=img_input_shape)

inputs.append(img_input)

conv = conv_bn_activation(x=img_input, filters=16,

                          kernel_size=7, strides=1,

                          data_format="channels_last",

                          is_training=True,

                          name="base_layer_conv_1")

conv = conv_bn_activation(x=conv, filters=16, kernel_size=3, strides=1,

                          data_format="channels_last",

                          is_training=True, name="base_layer_conv_2")

out = basic_block(conv, 64, True, data_format="channels_last")

# outputs = [conv] this work fine

outputs = [out]

model = Model(inputs=inputs, outputs=outputs)

I got this error ValueError: Output tensors to a Model must be the output of a TensorFlow Layer (thus holding past layer metadata). Found: Tensor("add:0", shape=(?, ?, ?, 64), dtype=float32)

The problem is in the basic_block() function but I could not find it!

1 Answer

0 votes
by (12.2k points)

Here, the problem is in the addition conv + short_cut.

So, we will use Add() function.

def conv_bn_activation(x, filters, kernel_size, strides, data_format, is_training, activation=relu,

                       name=None):

    """

    Parameters

    ----------

    x

    filters

    kernel_size

    strides

    data_format

    activation

    is_training

    name

    Returns

    -------

    """

    conv = tks.Conv2D(filters=filters,

                      kernel_size=kernel_size,

                      strides=strides,

                      padding='same',

                      data_format=data_format,

                      activation=None,

                      use_bias=False,

                      name=name)(x)

    bn = batch_norm(x=conv, is_training=is_training, data_format=data_format)

    if activation is not None:

        return activation(bn)

    else:

        return bn

def basic_block(x, filters, is_training, data_format):

    """

    Basic block function

    Parameters

    ----------

    x

    filters

    data_format

    is_training

    Returns

    -------

    """

    conv = conv_bn_activation(x=x, filters=filters, kernel_size=3, strides=1,

                              is_training=is_training, data_format=data_format)

    conv = conv_bn_activation(x=conv, filters=filters, kernel_size=3, strides=1,

                              is_training=is_training, data_format=data_format)

    axis = 3 if data_format == 'channels_last' else 1

    input_channels = x.get_shape().as_list()[axis]

    if input_channels == filters:

        short_cut = x

    else:

        short_cut = conv_bn_activation(x=x, filters=filters, kernel_size=1, strides=1,

                                       is_training=is_training, data_format=data_format)

    return tks.Add()([conv,  short_cut])

img_input_shape = [None, None, 3]

inputs = []

img_input = Input(shape=img_input_shape)

inputs.append(img_input)

conv = conv_bn_activation(x=img_input, filters=16,

                          kernel_size=7, strides=1,

                          data_format="channels_last",

                          is_training=True,

                          name="base_layer_conv_1")

conv = conv_bn_activation(x=conv, filters=16, kernel_size=3, strides=1,

                          data_format="channels_last",

                          is_training=True, name="base_layer_conv_2")

out = basic_block(conv, 64, True, data_format="channels_last")

# outputs = [conv] this work fine

outputs = [out]

model = Model(inputs=inputs, outputs=outputs)

...