基于Tensorflow的Darknet53实现

官网:https://pjreddie.com/darknet/imagenet/

import tensorflow as tf
filter_initializer = tf.contrib.layers.xavier_initializer()


# 定义卷积操作
def conv_op(input_op, name, kh, kw, n_out, dh, dw, relu='leaky', normal=True, train=True):
    n_in = input_op.get_shape()[-1].value    # 获取输入图像的通道channel数
    with tf.variable_scope(name) as scope:         # 命名空间
        kernel = tf.get_variable("w",
                                 shape = [kh, kw, n_in, n_out],
                                 dtype = tf.float32,
                                 initializer = tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)) #定义卷积核以及初始化方法

        biases = tf.get_variable('bases',
                                 shape=[n_out],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))

        conv = tf.nn.conv2d(input_op, kernel, strides=[1, dh, dw, 1], padding='SAME')
        conv = tf.nn.bias_add(conv, biases)

        if normal:
            conv = tf.layers.batch_normalization(inputs=conv, momentum=0.99, epsilon=1e-3, training=train,
                                          name=name+'_normal')
        if relu == 'leaky':
            conv = tf.nn.leaky_relu(conv, alpha = 0.1, name=name+relu)
        elif relu == 'lrn':
            tf.nn.lrn(conv, depth_radius=4, bias=1.0, alpha=0.01 / 9.0, beta=0.75, name=name+relu)
        elif relu == 'relu':
            conv = tf.nn.relu(conv, name=name+relu)
        else:
            pass
        return conv


#定义池化层
def mpool_op(input_op, name, kh, kw, dh, dw):
    pool = tf.nn.max_pool(input_op, ksize=[1, kh, kw, 1], strides=[1, dh, dw, 1], padding='SAME', name= name)
    return pool


#定义池化层
def avgpool_op(input_op, name, kh, kw, dh, dw, padding='SAME'):
    pool = tf.nn.avg_pool(input_op, ksize=[1, kh, kw, 1], strides=[1, dh, dw, 1], padding=padding, name=name)
    return pool


def unmaxpool_op(input_op, name, k):
    shape = input_op.get_shape()
    unpool = tf.image.resize_nearest_neighbor(input_op, [k * shape[1], k * shape[2]], name=name)
    return unpool


def side_branch(inputs, filters, upsample_factor):
    # 反置卷积
    kernel_size = [2 * upsample_factor, 2 * upsample_factor]
    outputs = tf.layers.conv2d_transpose(inputs,
                                         filters,
                                         kernel_size,
                                         strides=(upsample_factor, upsample_factor),
                                         padding='same',
                                         activation=None,
                                         use_bias=True,
                                         kernel_initializer=filter_initializer,
                                         kernel_regularizer=None)
    return outputs

#定义normlization层
def batch_normalization_layer(input_layer, name = None, training = True, norm_decay = 0.99, norm_epsilon = 1e-3):
    '''
    Introduction
    ------------
        对卷积层提取的feature map使用batch normalization
    Parameters
    ----------
        input_layer: 输入的四维tensor
        name: batchnorm层的名字
        trainging: 是否为训练过程
        norm_decay: 在预测时计算moving average时的衰减率
        norm_epsilon: 方差加上极小的数,防止除以0的情况
    Returns
    -------
        bn_layer: batch normalization处理之后的feature map
    '''
    bn_layer = tf.layers.batch_normalization(inputs=input_layer,
        momentum=norm_decay, epsilon = norm_epsilon, center=True,
        scale=True, training=training, name=name)
    return tf.nn.leaky_relu(bn_layer, alpha = 0.1)


#定义全连接操作
def fc_op(input_op, name, n_out):
    dim = input_op.get_shape()[-1].value
    with tf.variable_scope(name) as scope:
        weights = tf.get_variable('weights',
                                  shape=[dim, n_out],
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
        biases = tf.get_variable('bases',
                                 shape=[n_out],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))

        fc = tf.nn.leaky_relu(tf.matmul(input_op, weights) + biases, alpha=0.1, name='fc')
        return fc


def params_usage():
    """统计参数数量"""
    total = 0
    for v in tf.trainable_variables():
        shape = v.get_shape()
        cnt = 1
        for dim in shape:
            cnt *= dim.value
        total += cnt
    return total


def darknet53(inputs, filters=4):
    ###darknet53(53是指卷积层)网络结构
    conv1 = conv_op(inputs, name='conv1', kh=3, kw=3, n_out=filters, dh=1, dw=1, relu='leaky')

    # Downsample
    conv2 = conv_op(conv1, name='conv2', kh=3, kw=3, n_out=filters*2, dh=2, dw=2, relu='leaky')
    conv3 = conv_op(conv2, name='conv3', kh=1, kw=1, n_out=filters, dh=1, dw=1, relu='leaky')
    conv4 = conv_op(conv3, name='conv4', kh=3, kw=3, n_out=filters*2, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer5 = tf.concat([conv4, conv2], axis=-1, name='reslayer5')
    # Downsample
    conv6 = conv_op(reslayer5, name='conv6', kh=3, kw=3, n_out=filters*4, dh=2, dw=2, relu='leaky')
    conv7 = conv_op(conv6, name='conv7', kh=1, kw=1, n_out=filters*2, dh=1, dw=1, relu='leaky')
    conv8 = conv_op(conv7, name='conv8', kh=3, kw=3, n_out=filters*4, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer9 = tf.concat([conv8, conv6], axis=-1, name='reslayer9')
    conv10 = conv_op(reslayer9, name='conv10', kh=1, kw=1, n_out=filters*2, dh=1, dw=1, relu='leaky')
    conv11 = conv_op(conv10, name='conv11', kh=3, kw=3, n_out=filters*4, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer12 = tf.concat([conv11, reslayer9], axis=-1, name='reslayer12')

    # Downsample
    conv13 = conv_op(reslayer12, name='conv13', kh=3, kw=3, n_out=filters*8, dh=2, dw=2, relu='leaky')
    conv14 = conv_op(conv13, name='conv14', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv15 = conv_op(conv14, name='conv15', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer16 = tf.concat([conv15, conv13], axis=-1, name='reslayer16')
    conv17 = conv_op(reslayer16, name='conv17', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv18 = conv_op(conv17, name='conv18', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer19 = tf.concat([conv18, reslayer16], axis=-1, name='reslayer19')
    conv20 = conv_op(reslayer19, name='conv20', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv21 = conv_op(conv20, name='conv21', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer22 = tf.concat([conv21, reslayer19], axis=-1, name='reslayer22')
    conv23 = conv_op(reslayer22, name='conv23', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv24 = conv_op(conv23, name='conv24', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer25 = tf.concat([conv24, reslayer22], axis=-1, name='reslayer25')
    conv26 = conv_op(reslayer25, name='conv26', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv27 = conv_op(conv26, name='conv27', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer28 = tf.concat([conv27, reslayer25], axis=-1, name='reslayer28')
    conv29 = conv_op(reslayer28, name='conv29', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv30 = conv_op(conv29, name='conv30', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer31 = tf.concat([conv30, reslayer28], axis=-1, name='reslayer31')
    conv33 = conv_op(reslayer31, name='conv33', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='leaky')
    conv34 = conv_op(conv33, name='conv34', kh=3, kw=3, n_out=filters*8, dh=1, dw=1, relu='leaky')

    # Downsample
    conv35 = conv_op(conv34, name='conv35', kh=3, kw=3, n_out=filters*16, dh=2, dw=2, relu='leaky')
    conv36 = conv_op(conv35, name='conv36', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv37 = conv_op(conv36, name='conv37', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer38 = tf.concat([conv37, conv35], axis=-1, name='reslayer38')
    conv39 = conv_op(reslayer38, name='conv39', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv40 = conv_op(conv39, name='conv40', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer41 = tf.concat([conv40, reslayer38], axis=-1, name='reslayer41')
    conv42 = conv_op(reslayer41, name='conv42', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv43 = conv_op(conv42, name='conv43', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer44 = tf.concat([conv43, reslayer41], axis=-1, name='reslayer44')
    conv45 = conv_op(reslayer44, name='conv45', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv46 = conv_op(conv45, name='conv46', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer47 = tf.concat([conv46, reslayer44], axis=-1, name='reslayer47')
    conv48 = conv_op(reslayer47, name='conv48', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv49 = conv_op(conv48, name='conv49', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer50 = tf.concat([conv49, reslayer47], axis=-1, name='reslayer50')
    conv51 = conv_op(reslayer50, name='conv51', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv52 = conv_op(conv51, name='conv52', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer53 = tf.concat([conv52, reslayer50], axis=-1, name='reslayer53')
    conv54 = conv_op(reslayer53, name='conv54', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv55 = conv_op(conv54, name='conv55', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer56 = tf.concat([conv55, reslayer53], axis=-1, name='reslayer56')
    conv57 = conv_op(reslayer56, name='conv57', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv58 = conv_op(conv57, name='conv58', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer59 = tf.concat([conv58, reslayer56], axis=-1, name='reslayer59')
    conv60 = conv_op(reslayer59, name='conv60', kh=1, kw=1, n_out=filters*8, dh=1, dw=1, relu='leaky')
    conv61 = conv_op(conv60, name='conv61', kh=3, kw=3, n_out=filters*16, dh=1, dw=1, relu='leaky')

    # Downsample
    conv62 = conv_op(conv61, name='conv62', kh=3, kw=3, n_out=filters*32, dh=2, dw=2, relu='leaky')
    conv63 = conv_op(conv62, name='conv63', kh=1, kw=1, n_out=filters*16, dh=1, dw=1, relu='leaky')
    conv64 = conv_op(conv63, name='conv64', kh=3, kw=3, n_out=filters*32, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer65 = tf.concat([conv64, conv62], axis=-1, name='reslayer65')
    conv66 = conv_op(reslayer65, name='conv66', kh=1, kw=1, n_out=filters*16, dh=1, dw=1, relu='leaky')
    conv67 = conv_op(conv66, name='conv67', kh=3, kw=3, n_out=filters*32, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer68 = tf.concat([conv67, reslayer65], axis=-1, name='reslayer68')
    conv69 = conv_op(reslayer68, name='conv69', kh=1, kw=1, n_out=filters*16, dh=1, dw=1, relu='leaky')
    conv70 = conv_op(conv69, name='conv70', kh=3, kw=3, n_out=filters*32, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer71 = tf.concat([conv70, reslayer68], axis=-1, name='reslayer71')
    conv72 = conv_op(reslayer71, name='conv72', kh=1, kw=1, n_out=filters*16, dh=1, dw=1, relu='leaky')
    conv73 = conv_op(conv72, name='conv73', kh=3, kw=3, n_out=filters*32, dh=1, dw=1, relu='leaky')
    # shortcut
    reslayer74 = tf.concat([conv73, reslayer71], axis=-1, name='reslayer74')

    ###以上为darknet53(53是指卷积层)网络结构
    return reslayer74

 

你可能感兴趣的:(计算机视觉/图像处理,Python,YOLO系列)