def construct_conv_bn_block(current, net, weights, start_weight_index,
                            param_names, layer_names, stride, keep_prob,
                            is_training):
    # conv
    kernel = weights[start_weight_index][1]
    kernel = utils.get_variable(kernel, name=param_names[0])
    if stride == 1:
        current = tf.nn.conv2d(current,
                               kernel,
                               strides=[1, 1, 1, 1],
                               padding='SAME',
                               name=layer_names[0])
    else:
        kernel_size = kernel.shape[0]
        padding = int((int(kernel_size) - 1) / 2)
        current = tf.nn.conv2d(tf.pad(
            current,
            tf.constant([[0, 0], [padding, padding], [padding, padding],
                         [0, 0]])),
                               kernel,
                               strides=[1, stride, stride, 1],
                               padding='VALID',
                               name=layer_names[0])
    net[layer_names[0]] = tf.nn.dropout(current, keep_prob=keep_prob)

    # bn
    # print(layer_names)
    # print(param_names)
    # print()
    current, net = construct_batch_normalisation_block(current, net, weights,
                                                       start_weight_index,
                                                       param_names,
                                                       layer_names,
                                                       is_training)
    return current, net
def construct_batch_normalisation_block(current, net, weights,
                                        start_weight_index, param_names,
                                        layer_names, is_training):
    scale = weights[start_weight_index + 1][1].reshape(-1)
    scale = utils.get_variable(scale, name=param_names[1])

    offset = weights[start_weight_index + 2][1].reshape(-1)
    offset = utils.get_variable(offset, name=param_names[2])

    mean = weights[start_weight_index + 3][1][:, 0].reshape(-1)
    mean = utils.get_variable(mean, name=param_names[3] + '_mean')

    variance = weights[start_weight_index + 3][1][:, 1].reshape(-1)
    variance = utils.get_variable(variance * variance,
                                  name=param_names[3] + '_variance')

    batch_mean, batch_var = tf.nn.moments(current, [0, 1, 2],
                                          name='batch_moments')
    decay = 1 - weights[start_weight_index + 3][2][0][0]
    ema = tf.train.ExponentialMovingAverage(decay=decay)

    # decay = 0.9999

    def mean_var_with_update():
        ema_apply_op = ema.apply([batch_mean, batch_var])
        with tf.control_dependencies([ema_apply_op]):
            return tf.identity(batch_mean), tf.identity(batch_var)

    mean, variance = tf.cond(
        is_training, mean_var_with_update, lambda:
        (ema.average(batch_mean), ema.average(batch_var)))

    current = tf.nn.batch_normalization(current,
                                        mean,
                                        variance,
                                        offset,
                                        scale,
                                        1e-5,
                                        name=layer_names[1])

    net[layer_names[1]] = current

    return current, net
Example #3
0
def resnet101_net(image, weights):
    net = {}
    current = image
    start_param_index = 0

    # conv1 block
    conv1_layer_names = ['conv1', 'bn_conv1', 'conv1_relu', 'pool1']
    conv1_param_names = create_param_names_from_layers(conv1_layer_names)
    current, net = construct_conv_bn_relu_block(current, net, weights, start_param_index, conv1_param_names, conv1_layer_names, 2)
    current = tf.nn.max_pool(current, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name=conv1_layer_names[3])
    net[conv1_layer_names[3]] = current
    start_param_index += 4

    current, net, start_param_index = construct_res_xa_block(2, current, net, weights, start_param_index, False)
    current, net, start_param_index = construct_res_xxx_block(2, 'b', current, net, weights, start_param_index)
    current, net, start_param_index = construct_res_xxx_block(2, 'c', current, net, weights, start_param_index)

    current, net, start_param_index = construct_res_xa_block(3, current, net, weights, start_param_index, True)
    for i in range(1, 4):
        current, net, start_param_index = construct_res_xxx_block(3, 'b' + str(i), current, net, weights, start_param_index)

    current, net, start_param_index = construct_res_xa_block(4, current, net, weights, start_param_index, True)
    for i in range(1, 23):
        current, net, start_param_index = construct_res_xxx_block(4, 'b' + str(i), current, net, weights, start_param_index)

    current, net, start_param_index = construct_res_xa_block(5, current, net, weights, start_param_index, True)
    current, net, start_param_index = construct_res_xxx_block(5, 'b', current, net, weights, start_param_index)
    current, net, start_param_index = construct_res_xxx_block(5, 'c', current, net, weights, start_param_index)

    current = tf.nn.avg_pool(current, ksize=[1, 7, 7, 1], strides=[1, 1, 1, 1], padding='VALID', name='pool5')
    net['pool5'] = current

    fc1000_kernel = utils.get_variable(weights[start_param_index][1], name='fc1000_filter')
    fc1000_bias = utils.get_variable(weights[start_param_index + 1][1].reshape(-1), name='fc1000_bias')
    current = tf.nn.bias_add(tf.nn.conv2d(current, fc1000_kernel, strides=[1, 1, 1, 1], padding="VALID"), fc1000_bias, name='fc1000')
    net['fc1000'] = current

    current = tf.nn.softmax(current, name='prob')
    net['prob'] = current

    return net
def vgg_net(weights, image):
    layers = (
        'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1',
        'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
        'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3',
        'relu3_3', 'conv3_4', 'relu3_4', 'pool3',
        'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3',
        'relu4_3', 'conv4_4', 'relu4_4', 'pool4',
        'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'conv5_3',
        'relu5_3', 'conv5_4', 'relu5_4', 'pool5',
        'fc6', 'relu6', 'fc7', 'relu7', 'fc8', 'prob'
    )
    net = {}
    current = image
    for i, name in enumerate(layers):
        if len(name) >= 4:
            kind = name[:4]
        else:
            kind = name[:2]
        if kind == 'conv' or kind == 'fc':
            kernels, bias = weights[i][0][0][0][0]
            print('Kernel size:', kernels.shape)
            print('Bias size:', bias.shape)
            # matconvnet: weights are [width, height, in_channels, out_channels]
            # tensorflow: weights are [height, width, in_channels, out_channels]
            # kernels = utils.get_variable(np.transpose(kernels, (0, 1, 2, 3)), name=name + "_w")
            kernels = utils.get_variable(kernels, name=name + "_W")
            bias = utils.get_variable(bias.reshape(-1), name=name + "_b")
            if kind == 'conv':
                current = utils.conv2d_basic(current, kernels, bias)
            elif kind == 'fc':
                current = tf.nn.bias_add(tf.nn.conv2d(current, kernels, strides=[1, 1, 1, 1], padding="VALID"), bias)
        elif kind == 'relu':
            current = tf.nn.relu(current, name=name)
        elif kind == 'pool':
            current = utils.max_pool_2x2(current)
        elif kind == 'prob':
            current = tf.nn.softmax(current, name=name)
        net[name] = current
    return net