def _conv_block(inp, convs, do_skip=True): x = inp count = 0 for conv in convs: if count == (len(convs) - 2) and do_skip: skip_connection = x count += 1 if conv['stride'] > 1: x = ZeroPadding2D(((1, 0), (1, 0)))( x) # unlike tensorflow darknet prefer left and top paddings x = Conv2D( conv['filter'], conv['kernel'], strides=conv['stride'], padding='valid' if conv['stride'] > 1 else 'same', # unlike tensorflow darknet prefer left and top paddings name='conv_' + str(conv['layer_idx']), use_bias=False if conv['bnorm'] else True)(x) if conv['bnorm']: x = BatchNormalization(epsilon=0.001, name='bnorm_' + str(conv['layer_idx']))(x) if conv['leaky']: x = LeakyReLU(alpha=0.1, name='leaky_' + str(conv['layer_idx']))(x) return add([skip_connection, x]) if do_skip else x
def residual_block( inputs, num_filters=16, kernel_size=3, strides=1, activation="relu", batch_normalization=True, conv_first=True, ): """2D Convolution-Batch Normalization-Activation stack builder # Arguments inputs (tensor): input tensor from input image or previous layer num_filters (int): Conv2D number of filters kernel_size (int): Conv2D square kernel dimensions strides (int): Conv2D square stride dimensions activation (string): activation name batch_normalization (bool): whether to include batch normalization conv_first (bool): conv-bn-activation (True) or bn-activation-conv (False) # Returns x (tensor): tensor as input to the next layer """ conv = Conv2D( num_filters, kernel_size=kernel_size, strides=strides, padding="same", kernel_initializer="he_normal", kernel_regularizer=l2(1e-4), activation=None, ) conv2 = Conv2D( num_filters, kernel_size=kernel_size, strides=strides, padding="same", kernel_initializer="he_normal", kernel_regularizer=l2(1e-4), activation="linear", ) x = conv(inputs) x = BatchNormalization()(x) x = Activation(activation)(x) x = conv2(x) x = add([inputs, x]) x = BatchNormalization()(x) x = Activation(activation)(x) return x
def _shortcut3d(input, residual): """3D shortcut to match input and residual and merges them with "sum".""" stride_dim1 = ceil(input.get_shape().as_list()[DIM1_AXIS] \ / residual.get_shape().as_list()[DIM1_AXIS]) stride_dim2 = ceil(input.get_shape().as_list()[DIM2_AXIS] \ / residual.get_shape().as_list()[DIM2_AXIS]) stride_dim3 = ceil(input.get_shape().as_list()[DIM3_AXIS] \ / residual.get_shape().as_list()[DIM3_AXIS]) equal_channels = residual.get_shape().as_list()[CHANNEL_AXIS] \ == input.get_shape().as_list()[CHANNEL_AXIS] shortcut = input if stride_dim1 > 1 or stride_dim2 > 1 or stride_dim3 > 1 \ or not equal_channels: shortcut = Conv3D( filters=residual.get_shape().as_list()[CHANNEL_AXIS], kernel_size=(1, 1, 1), strides=(stride_dim1, stride_dim2, stride_dim3), kernel_initializer="he_normal", padding="valid", kernel_regularizer=l2(1e-4) )(input) return add([shortcut, residual])
def identity_block_base(input_tensor, kernel_size, filters, stage, block, num_updates, dropout_rate=0., use_variational_layers=False): """The identity block is the block that has no conv layer at shortcut. Arguments: input_tensor: input tensor kernel_size: default 3, the kernel size of middle conv layer at main path filters: list of integers, the filters of 3 conv layer at main path stage: integer, current stage label, used for generating layer names block: 'a','b'..., current block label, used for generating layer names num_updates: integer, total steps in an epoch (for weighting the loss) dropout_rate: float, always-on dropout rate. use_variational_layers: boolean, if true train a variational model Returns: x: Output tensor for the block. """ filters1, filters2, filters3 = filters divergence_fn = lambda q, p, ignore: (tfd.kl_divergence(q, p) / num_updates ) if backend.image_data_format() == 'channels_last': bn_axis = 3 else: bn_axis = 1 conv_name_base = 'res' + str(stage) + block + '_branch' bn_name_base = 'bn' + str(stage) + block + '_branch' if not use_variational_layers: first_conv_2d = layers.Conv2D( filters1, (1, 1), use_bias=False, kernel_initializer='he_normal', kernel_regularizer=regularizers.l2(L2_WEIGHT_DECAY), name=conv_name_base + '2a') if dropout_rate > 0.: x = layers.Dropout(dropout_rate)(input_tensor, training=True) x = first_conv_2d(x) else: x = first_conv_2d(input_tensor) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2a')(x) x = layers.Activation('relu')(x) if dropout_rate > 0.: x = layers.Dropout(dropout_rate)(x, training=True) x = layers.Conv2D(filters2, kernel_size, use_bias=False, padding='same', kernel_initializer='he_normal', kernel_regularizer=regularizers.l2(L2_WEIGHT_DECAY), name=conv_name_base + '2b')(x) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2b')(x) x = layers.Activation('relu')(x) if dropout_rate > 0.: x = layers.Dropout(dropout_rate)(x, training=True) x = layers.Conv2D(filters3, (1, 1), use_bias=False, kernel_initializer='he_normal', kernel_regularizer=regularizers.l2(L2_WEIGHT_DECAY), name=conv_name_base + '2c')(x) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2c')(x) else: x = tfpl.Convolution2DFlipout( filters1, kernel_size=(1, 1), padding='SAME', name=conv_name_base + '2a', kernel_divergence_fn=divergence_fn, )(input_tensor) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2a')(x) x = layers.Activation('relu')(x) x = tfpl.Convolution2DFlipout( filters2, kernel_size=kernel_size, padding='SAME', activation=None, name=conv_name_base + '2b', kernel_divergence_fn=divergence_fn, )(x) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2b')(x) x = layers.Activation('relu')(x) x = tfpl.Convolution2DFlipout( filters3, kernel_size=(1, 1), padding='SAME', activation=None, name=conv_name_base + '2c', kernel_divergence_fn=divergence_fn, )(x) x = layers.BatchNormalization(axis=bn_axis, momentum=BATCH_NORM_DECAY, epsilon=BATCH_NORM_EPSILON, name=bn_name_base + '2c')(x) x = layers.add([x, input_tensor]) x = layers.Activation('relu')(x) return x
def inner(x): for i in range(n): x2 = conv(channels * k, strides if i == 0 else 1)(x) x = add([resize(x, K.int_shape(x2)), x2]) return x