keras-yolo3项目之三:model.py文件

model.py文件是用keras模块编写的yolo模型文件,主要包含14个函数:

  • DarknetConv2D:为二维卷积层设置Darknet参数。
  • DarknetConv2D_BN_Leaky:由二维卷积层DarknetConv2D与正则化层BatchNormalization、激活函数LeakyReLU组合而成。
  • resblock_body:封装了一个循环体:包含2个卷积核大小不同的DarknetConv2D_BN_Leaky
  • darknet_bodyDarknent网络结构,含有52个二维卷积层。
  • make_last_layers:最后几个函数层,由6个DarknetConv2D_BN_Leaky层和1个Conv2D_linear层组成。
  • yolo_bodyyolo网络结构。
  • tiny_yolo_bodytiny_yolo网络结构。
  • yolo_head:将最终网络层特征转换为边界框参数。
  • yolo_correct_boxes:获取正确的边界框。
  • yolo_boxes_and_scores:处理卷积层输出。
  • yolo_eval:在给定的输入和返回过滤框上评估YOLO模型。
  • preprocess_true_boxes:将true_boxes预处理为训练输入格式
  • box_iou:检测框与原标注框的交并比。
  • yolo_loss:模型损失。

详细内容如下:

"""YOLO_v3 Model Defined in Keras."""

from functools import wraps

import numpy as np
import tensorflow as tf
from keras import backend as K
from keras.layers import Conv2D, Add, ZeroPadding2D, UpSampling2D, Concatenate, MaxPooling2D
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.normalization import BatchNormalization
from keras.models import Model
from keras.regularizers import l2

from yolo3.utils import compose


@wraps(Conv2D)
def DarknetConv2D(*args, **kwargs):
    """
    Wrapper to set Darknet parameters for Convolution2D.
    为2维卷积层设置Darknet参数
    
    返回带有Darknet参数的2维卷积层
    """
    darknet_conv_kwargs = {
   'kernel_regularizer': l2(5e-4)}
    darknet_conv_kwargs['padding'] = 'valid' if kwargs.get('strides')==(2,2) else 'same'
    darknet_conv_kwargs.update(kwargs)
    return Conv2D(*args, **darknet_conv_kwargs)    #带有Darknet参数的2维卷积层

def DarknetConv2D_BN_Leaky(*args, **kwargs):
    """
    Darknet Convolution2D followed by BatchNormalization and LeakyReLU.
    封装3个网络层:
    1.带有Darknet参数的2维卷积层
    2.批量正则化网络层:按批正则化前一个网络层的激活
    3.激活函数层
    """
    no_bias_kwargs = {
   'use_bias': False}
    no_bias_kwargs.update(kwargs)
    return compose(
        DarknetConv2D(*args, **no_bias_kwargs),    #带有Darknet参数的2维卷积层
        BatchNormalization(),    #按批正则化前一个网络层的激活
        LeakyReLU(alpha=0.1))    #激活函数

def resblock_body(x, num_filters, num_blocks):
    '''
    A series of resblocks starting with a downsampling Convolution2D
    封装了一个循环体:包含2个卷积核大小不同的DarknetConv2D_BN_Leaky
    x:输入的图像张量
    num_filters:输出空间的维度
    num_blocks:循环次数
    
    本函数包含2个步骤:
    1.填充,计算DarknetConv2D_BN_Leaky,输出维度为num_filters的x;
    2.循环累加(循环体),将步骤1的输出作为该步骤的初始输入x:
    首先计算1*1卷积核,然后将1*1卷积核的结果作为3*3卷积核的输入,计算出结果y
    循环累加的初始输入x与得到的y进行相加,将相加结果赋值给x,进入下一次循环
    '''
    # Darknet uses left and top padding instead of 'same' mode
    x = ZeroPadding2D(((1,0),(1,0)))(x)    #对2维输入的的左侧和上侧进行0填充,((1,0),(1,0))表示((上,下),(左,右))
    x = DarknetConv2D_BN_Leaky(num_filters, (3,3), strides=(2,2))(x)   #3*3的卷积核,卷积步长(2,2)
    
    for i in range(num_blocks):
        y = compose(
                DarknetConv2D_BN_Leaky(num_filters//2, (1,1)),    #1*1的卷积核
                DarknetConv2D_BN_Leaky(num_filters, (3,3)))(x)    #3*3的卷积核
        x = Add()([x,y])    #求和,输出维度与x,y一致
    return x

def darknet_body(x):
    '''
    Darknent body having 52 Convolution2D layers
    Darknent网络层主干,主要作用是对图像进行特征提取,包含52个2维卷积核层:52=1+3+5+17+17+9
    1个DarknetConv2D_BN_Leaky里包含1个2维卷积层,1个批量正则化层,1个激活层
    1个resblock_body包含1+2*num_blocks个DarknetConv2D_BN_Leaky
    '''
    x = DarknetConv2D_BN_Leaky(32, (3,3))(x)    #1
    x = resblock_body(x, 64, 1)    #1+2*1=3
    x = resblock_body(x, 128, 2)    #1+2*2=5
    x = resblock_body(x, 256, 8)    #1+2*8=17
    x = resblock_body(x, 512, 8)    #1+2*8=17
    x = resblock_body(x, 1024, 4)    #1+2*4=9
    return x

def make_last_layers(x, num_filters, out_filters):
    '''
    6 Conv2D_BN_Leaky layers followed by a Conv2D_linear layer
    7个2维卷积层
    5个DarknetConv2D_BN_Leaky计算得x
    1个DarknetConv2D_BN_Leaky,1个DarknetConv2D计算得y
    
    num_filters:中间卷积层x得输出通道数,也可以理解为特征数量
    out_filters:最终层y的通道数
    返回x,y
    '''
    x = compose(
            DarknetConv2D_BN_Leaky(num_filters, (1,1)),
            DarknetConv2D_BN_Leaky(num_filters*2, (3,3)),
            DarknetConv2D_BN_Leaky(num_filters, (1,1)),
            DarknetConv2D_BN_Leaky(num_filters*2, (3,3)),
            DarknetConv2D_BN_Leaky(num_filters, (1,1)))(x)
    y = compose(
            DarknetConv2D_BN_Leaky(num_filters*2, (3,3)),
            DarknetConv2D(out_filters, (1,1)))(x)
    return x, y


def yolo_body(inputs, num_anchors, num_classes):
    """
    Create YOLO_V3 model CNN body in Keras.
    YOLO_V3卷积神经网络主干,共包含75个卷积层
    
    1.Darknent模型,包含52个卷积层  
    2.Darknent模型的输出作为make_last_layers输入,输出x,y1,包含7个卷积层  
    3.将x进行DarknetConv2D_BN_Leaky,UpSampling2D计算,并将结果与Darknent模型的152层的输出进行拼接,得x,包含1个卷积层  
    4.将输出x作为make_last_layers输入,输出x,y2,包含7个卷积层  
    5.将x进行DarknetConv2D_BN_Leaky,UpSampling2D计算,并将结果与Darknent模型的92层的输出进行拼接,得x,包含1个卷积层  
    6.将输出x作为make_last_layers输入,输出x,y3,包含7个卷积层  
    """
    darknet = Model(inputs, darknet_body(inputs))   #Model(inputs, outputs, name=None)
    x, y1 = make_last_layers(darknet.output, 512, num_anchors*(num_classes+5))

    x = compose(
            DarknetConv2D_BN_Leaky(256, (1,1)),
            UpSampling2D(2))(x)
    x = Concatenate()([x,darknet.layers[152].output])    #拼接
    x, y2 = make_last_layers(x, 256, num_anchors*(num_classes+5))

    x = compose(
            DarknetConv2D_BN_Leaky(128, (1,1)),
            UpSampling2D(2))(x)
    x = Concatenate()([x,darknet.layers[92].output])
    x, y3 = make_last_layers(x, 128, num_anchors*(num_classes+5))

    return Model(inputs, [y1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

great-wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值