yolov3前向传播(二)-- yolov3相关模块的解析与实现(二)

yolov3相关模块的解析与实现(二)

接上一篇

三、上采样函数

作用:用于将特征图扩展到想要的尺寸大小,和其他特征叠加到一起使用。
上采样的方法为近邻差值法

上采样函数的实现

# 定义上采样函数
def _upsample(inputs, out_shape):
    '''

    :param inputs:  输入  类型tensor  形状 [batch, height_in, width_in, channels].
    :param out_shape: 调整后的tensor的形状 类型tensor out_shape = [batch, new_height, new_width,channels]
    :return: 返回一个 调整大小后的tensor
    '''
    # 由于上采样的填充方式不同,tf.image.resize_bilinear会对结果影响很大
    # 以近邻插值法来修改输入tensor(图片)的大小
    inputs = tf.image.resize_nearest_neighbor(inputs, (out_shape[1], out_shape[2]))
    # 返回一个和形参inputs一样的新的tensor。实际是为了将tensor利用tf.identity()来转化为op。因为只有op才会受操作域约束
    inputs = tf.identity(inputs, name='upsampled')
    return inputs

四、Yolo前向传播函数

1、yolo前向传播的网络结构

在这里插入图片描述

2、yolo前向传播的网络结构的实现

# 定义yolo函数
def yolo_v3(inputs, num_classes, is_training=False, data_format='NHWC', reuse=False):
    '''

    :param inputs: 输入  类型tensor  形状 [batch, height_in, width_in, channels].
    :param num_classes: 分类个数 类型int
    :param is_training:是否是训练状态 类型bool
    :param data_format: 数据格式
    :param reuse: 变量是否重用
    :return:
    '''
    # 判断data_format 是否等于'NHWC' 是则继续执行  否则报错
    assert data_format == 'NHWC'

    img_size = inputs.get_shape().as_list()[1:3]  # 获得输入图片大小

    inputs = inputs / 255  # 输入图片归一化

    # 用字典定义批量归一化参数
    batch_norm_params = {
        'decay': _BATCH_NORM_DECAY,
        'epsilon': _BATCH_NORM_EPSILON,
        'scale': True,
        'is_training': is_training,
        'fused': None,
    }

    # 定义yolo网络.
    # 定义超参数管理作用域 在此作用域下 指定的op操作函数的形参默认赋值
    # 即:在arg_scope中定义一个或多个操作的许多默认参数,这些参数将会在这些操作中传递下去。
    with slim.arg_scope([slim.conv2d, slim.batch_norm], data_format=data_format, reuse=reuse):
        with slim.arg_scope([slim.conv2d], normalizer_fn=slim.batch_norm, normalizer_params=batch_norm_params,
                            biases_initializer=None, activation_fn=lambda x: tf.nn.leaky_relu(x, alpha=_LEAKY_RELU)):
            # 定义名称为darknet-53的变量作用域,darknet53函数返回三个尺度的特征图
            with tf.variable_scope('darknet-53'):
                route_1, route_2, inputs = darknet53(inputs)
            # 定义名称为yolo-v3的变量作用域
            with tf.variable_scope('yolo-v3'):
                # ===============================================================================尺寸为13*13的特征图的处理
                # 13*13的特征图经过_yolo_block块处理,得到两个特征图 一个inputs 一个route
                route, inputs = _yolo_block(inputs, 512)  # (-1, 13, 13, 1024)
                # 使用候选框参数来辅助识别
                # inputs再通过yolo检测快,获得基于13*13的特征图的预测值
                detect_1 = _detection_layer(inputs, num_classes, _ANCHORS[6:9], img_size, data_format)
                # 将基于13*13的特征图的预测值转化成一个op
                detect_1 = tf.identity(detect_1, name='detect_1')

                # 再将route进行卷积操作,目的是修改通道数,然后让后将route变成和尺度26*26的特征图一样大小的特征图并和darknet53输出的尺度为26*26的特征图组合到了一起
                inputs = slim.conv2d(route, 256, 1, stride=1, padding='SAME')  # 正常卷积
                upsample_size = route_2.get_shape().as_list()
                inputs = _upsample(inputs, upsample_size)
                inputs = tf.concat([inputs, route_2], axis=3)
                # ================================================================================尺寸为26*26的特征图的处理
                # 将组合的特征图输入_yolo_block块处理,得到两个特征图 一个inputs 一个route
                route, inputs = _yolo_block(inputs, 256)  # (-1, 26, 26, 512)
                # inputs再通过yolo检测快,获得基于26*26的特征图的预测值
                detect_2 = _detection_layer(inputs, num_classes, _ANCHORS[3:6], img_size, data_format)
                # 将基于darknet53输出的尺度为26*26的特征图和darknet53输出的_yolo_block块处理53*53的特征图经过下采样组合的特征图得到的预测值转化成一个op
                detect_2 = tf.identity(detect_2, name='detect_2')
                # 再将route进行卷积操作,目的是修改通道数,然后将route变成和尺度13*13的特征图一样大小的特征图并和darknet53输出的尺度为13*13的特征图组合到了一起
                inputs = slim.conv2d(route, 128, 1, stride=1, padding='SAME')  # 正常卷积
                upsample_size = route_1.get_shape().as_list()
                inputs = _upsample(inputs, upsample_size)
                inputs = tf.concat([inputs, route_1], axis=3)
                # ================================================================================尺寸为52*52的特征图的处理
                # inputs再通过yolo检测快,获得基于52*52的特征图的预测值
                _, inputs = _yolo_block(inputs, 128)  # (-1, 52, 52, 256)

                detect_3 = _detection_layer(inputs, num_classes, _ANCHORS[0:3], img_size, data_format)
                detect_3 = tf.identity(detect_3, name='detect_3')

                # 将三个尺度的特征图的预测值组合到一起
                detections = tf.concat([detect_1, detect_2, detect_3], axis=1)
                detections = tf.identity(detections, name='detections')
                return detections  # 返回了3个尺度。每个尺度里又包含3个结果(-1, 10647( 507 +2028 + 8112), 5+c)

经过以上 yolo的前向传播就结束了,后面就是非极大值抑制函数的实现以及预测结果的显示。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值