zoukankan      html  css  js  c++  java
  • 将yolov3的backbone由darknet53变为mobilenet v2的想法

    https://github.com/GuodongQi/yolo3_tensorflow

    import tensorflow as tf
    
    #darknet53的卷积等封装
    def convolutional(input_data, filters_shape, trainable, name, downsample=False, activate=True, bn=True):
    
        with tf.variable_scope(name):
            if downsample:
                pad_h, pad_w = (filters_shape[0] - 2) // 2 + 1, (filters_shape[1] - 2) // 2 + 1
                paddings = tf.constant([[0, 0], [pad_h, pad_h], [pad_w, pad_w], [0, 0]])
                input_data = tf.pad(input_data, paddings, 'CONSTANT')
                strides = (1, 2, 2, 1)
                padding = 'VALID'
            else:
                strides = (1, 1, 1, 1)
                padding = "SAME"
    
            #讨论initializer对卷积的影响 0513
            weight = tf.get_variable(name='weight', dtype=tf.float16, trainable=True,shape=filters_shape,
                                     # initializer=tf.random_normal_initializer(stddev=0.01)) #run ok
                                     initializer=tf.truncated_normal_initializer(stddev=0.01)) #run ok
                                     # initializer=tf.contrib.layers.xavier_initializer()) #not ok
                                     # initializer=tf.glorot_normal_initializer()) #not ok
                                     # initializer=tf.keras.initializers.he_normal()) #not ok
                                     # initializer=tf.random_uniform_initializer())#not ok
    
            conv = tf.nn.conv2d(input=input_data, filter=weight, strides=strides, padding=padding)
            if bn:
                conv = tf.layers.batch_normalization(conv, beta_initializer=tf.zeros_initializer(),
                                                     gamma_initializer=tf.ones_initializer(),
                                                     moving_mean_initializer=tf.zeros_initializer(),
                                                     moving_variance_initializer=tf.ones_initializer(), training=trainable)
            else:
                bias = tf.get_variable(name='bias', shape=filters_shape[-1], trainable=True,
                                       dtype=tf.float16, initializer=tf.constant_initializer(0.0))
                conv = tf.nn.bias_add(conv, bias)
    
            if activate == True: conv = tf.nn.leaky_relu(conv, alpha=0.1)
    
        return conv
    
    def residual_block(input_data, input_channel, filter_num1, filter_num2, trainable, name):
        short_cut = input_data
        with tf.variable_scope(name):
            input_data = convolutional(input_data, filters_shape=(1, 1, input_channel, filter_num1),
                                       trainable=trainable, name='conv1')
            input_data = convolutional(input_data, filters_shape=(3, 3, filter_num1,   filter_num2),
                                       trainable=trainable, name='conv2')
    
            residual_output = input_data + short_cut
    
        return residual_output
    
    def route(name, previous_output, current_output):
    
        with tf.variable_scope(name):
            output = tf.concat([current_output, previous_output], axis=-1)
    
        return output
    
    def upsample(input_data, name, method="deconv"):
        assert method in ["resize", "deconv"]
    
        if method == "resize":
            with tf.variable_scope(name):
                input_shape = tf.shape(input_data)
                output = tf.image.resize_nearest_neighbor(input_data, (input_shape[1] * 2, input_shape[2] * 2))
    
        if method == "deconv":
            # replace resize_nearest_neighbor with conv2d_transpose To support TensorRT optimization
            numm_filter = input_data.shape.as_list()[-1]
            output = tf.layers.conv2d_transpose(input_data, numm_filter, kernel_size=2, padding='same',
                                                strides=(2,2), kernel_initializer=tf.random_normal_initializer())
    
        return output
    
    
    #mobilenet_v2的卷积等封装
    xavier_initializer = tf.initializers.glorot_uniform(dtype=tf.float16)
    leaky_alpha = 0.1
    
    def conv_block(x, filters, stride, out_channel,is_training, name='', relu=True):
        """
        :param x: input :nhwc
        :param filters: list [f_w, f_h]
        :param stride: list int
        :param out_channel: int, out_channel
        :param net_type: cnn mobilenet
        :param is_training: used in BN
        :param name: str
        :param relu: boolean
        :return: depwise and pointwise out
        """
        with tf.name_scope('' + name):
            in_channel = x.shape[3].value
            tmp_channel = out_channel * 3 #中间的临时channel
    
            with tf.name_scope('expand_pointwise'):
                pointwise_weight = tf.Variable(xavier_initializer([1, 1, in_channel, tmp_channel]))
                x = tf.nn.conv2d(x, pointwise_weight, [1, 1, 1, 1], 'SAME')
                x = tf.layers.batch_normalization(x, training=is_training)
                x = tf.nn.relu6(x)
            with tf.name_scope('depthwise'):
                depthwise_weight = tf.Variable(xavier_initializer([filters[0], filters[1], tmp_channel, 1]))
                x = tf.nn.depthwise_conv2d(x, depthwise_weight, [1, stride[0], stride[1], 1], 'SAME')
                x = tf.layers.batch_normalization(x, training=is_training)
                x = tf.nn.relu6(x)
            with tf.name_scope('project_pointwise'):
                pointwise_weight = tf.Variable(xavier_initializer([1, 1, tmp_channel, out_channel]))
                x = tf.nn.conv2d(x, pointwise_weight, [1, 1, 1, 1], 'SAME')
                if relu:
                    x = tf.layers.batch_normalization(x, training=is_training)
                else:
                    bias = tf.Variable(tf.zeros(shape=out_channel),dtype=tf.float16)
                    x += bias
        return x
    
    def residual(x,is_training, out_channel=1, expand_time=1, stride=1,name=''):
        shortcut = x
        in_channel = x.shape[3].value
        tmp_channel = in_channel * expand_time
        with tf.name_scope(name):
            with tf.name_scope('expand_pointwise'):#点卷积 拓展,生成一个高维信息域 参考《深度可分离卷积文档》
                pointwise_weight = tf.Variable(xavier_initializer([1, 1, in_channel, tmp_channel]))
                x = tf.nn.conv2d(x, pointwise_weight, [1, 1, 1, 1], 'SAME')
                x = tf.layers.batch_normalization(x, training=is_training)
                x = tf.nn.relu6(x)
            with tf.name_scope('depthwise'):#深度卷积
                depthwise_weight = tf.Variable(xavier_initializer([3, 3, tmp_channel, 1]))
                x = tf.nn.depthwise_conv2d(x, depthwise_weight, [1, stride, stride, 1], 'SAME')
                x = tf.layers.batch_normalization(x, training=is_training)
                x = tf.nn.relu6(x)
            with tf.name_scope('project_pointwise'):#点卷积
                pointwise_weight = tf.Variable(xavier_initializer([1, 1, tmp_channel, out_channel]))
                x = tf.nn.conv2d(x, pointwise_weight, [1, 1, 1, 1], 'SAME')
                x = tf.layers.batch_normalization(x, training=is_training)
            x += shortcut
            return x
    
    def mobilenet_v2_body(x,is_training):  # 特征检测网络
        """
        :param x:
        :param is_training:
        :return:
        """
        with tf.variable_scope('mobilenet_v2'):
            # x为 416×416 图像  标准的mobilnet v2 输入为 224 ×224有一定差异
            x = conv_block(x, [3, 3],[2, 2],32,is_training=is_training)  # conv2d正常卷积,输出208×208×32通道
            x = conv_block(x, [3, 3], [2, 2], 16,  is_training=is_training)  # 残差块卷积,输出104×104×16 下采样
            x = conv_block(x, [3, 3], [1, 1], 24,  is_training=is_training)  # 残差块卷积,输出104×104×24
            x = residual(x, is_training, 24, 1)  # 残差块卷积,输出104×104×24
            x = conv_block(x, [3, 3], [2, 2], 32, is_training=is_training)  # 残差块卷积,输出52×52×32   下采样
    
            for i in range(2):  # 残差块卷积 输出 52×52×32
                x = residual(x, is_training, 32, 1)
            route2 = x #[52,52,32]
    
            x = conv_block(x, [3, 3], [2, 2], 64,is_training=is_training)  # 残差块卷积,输出26×26×64   下采样
            for i in range(3):  # 残差块卷积 输出 26×26×64
                x = residual(x, is_training, 64, 6)
            x = conv_block(x, [3, 3], [1, 1], 96, is_training=is_training)  # 残差块卷积,输出26×26×96   更改输出通道
            for i in range(2):  # 残差块卷积 输出 26×26×64
                x = residual(x, is_training, 96, 6)
            route1 = x #[26,26,64]
    
            # down sample
            x = conv_block(x, [3, 3], [2, 2], 160, is_training=is_training)  # 残差块卷积,输出13×13×160 下采样
            for i in range(2):
                x = residual(x, is_training, 160, 1)
            x = conv_block(x, [3, 3], [1, 1], 320, is_training=is_training)  # 残差块卷积,输出13×13×320 更改输出通道
    
            return x, route1, route2
    
    def darknet_depthwise(input_data,training):  # 特征检测网络
        """
        :param x:
        :param is_training:
        :return:
        """
        with tf.variable_scope('darknet_depthwise'):
            input_data = conv_block(input_data,filters=[3, 3],stride=[1, 1],out_channel=32, is_training=training, name='conv0')
            input_data = conv_block(input_data,filters=[3, 3],stride=[2, 2],out_channel=64, is_training=training, name='conv1')
            for i in range(1):
                input_data = residual(input_data,is_training=training,out_channel=64,name='residual%d' % (i + 0))
            #[?,208,208,64]
            input_data = conv_block(input_data, filters=[3, 3],stride=[2,2],out_channel=128, is_training=training, name='conv4')
            #[?,104,104,128]
            for i in range(2):
                input_data = residual(input_data,is_training=training,out_channel=128,name='residual%d' % (i + 1))
            # [?,104,104,128]
            input_data = conv_block(input_data, filters=[3, 3], stride=[2, 2], out_channel=256, is_training=training,name='conv9')
            # [?,52,52,256]
            for i in range(8):
                input_data = residual(input_data, is_training=training, out_channel=256, name='residual%d' % (i + 3))
    
            input_data = conv_block(input_data, filters=[3, 3], stride=[2, 2], out_channel=512, is_training=training,name='conv26')
            # [?,26,26,512]
            for i in range(8):
                input_data = residual(input_data, is_training=training, out_channel=512, name='residual%d' % (i + 11))
    
            input_data = conv_block(input_data, filters=[3, 3], stride=[2, 2], out_channel=1024, is_training=training,name='conv43')
            # [?,13,13,512]
            for i in range(4):
                input_data = residual(input_data, is_training=training, out_channel=1024, name='residual%d' % (i + 19))
            return input_data
    

      

  • 相关阅读:
    运维ipvsadm配置负载均衡
    vue--存储
    vue--v-model表单控件绑定
    CSS--外发光与内阴影
    vue运行报错--preventDefault
    vue运行报错--dependency
    vue--移动端兼容问题
    vue--生命周期
    vue--vuex
    Vue--vux组件库
  • 原文地址:https://www.cnblogs.com/liutianrui1/p/13197881.html
Copyright © 2011-2022 走看看