YOLOv3代码详解之网络架构详解

        下面将对YOLOv3的网络架构进行详细的解析,通过使用tensorflow2.0来搭建整个YOLOv3的网络,为了看的更加清楚,这里并没有使用函数,而是一步一步的构建,对照着YOLOv3网络架构的图片,可以更加清楚的看清整个YOLOv3的网络。
        DarkNet-53:
在这里插入图片描述
        YOLOv3:
在这里插入图片描述
        Tensorflow2.0代码:

import tensorflow as tf
from tensorflow.keras.layers import Conv2D, Add, ZeroPadding2D, BatchNormalization, Input, UpSampling2D, Concatenate
from tensorflow.keras.layers import LeakyReLU
from tensorflow.keras.regularizers import l2

# 输入
input = Input((416, 416, 3))

#-------------------------------
#   主干特征提取网络DarkNet-53
#-------------------------------

# 单次卷积
# x = DarknetConv2D_BN_Leaky(32, (3, 3))(x)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(input)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

#------------------------------
# x = resblock_body(x, 64, 1)
#------------------------------
x = ZeroPadding2D(((1, 0), (1, 0)))(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=(2, 2), padding="valid", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
# 重复1次
y = Conv2D(filters=64//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

#------------------------------
# x = resblock_body(x, 128, 2)
#------------------------------
x = ZeroPadding2D(((1, 0), (1, 0)))(x)
x = Conv2D(filters=128, kernel_size=(3, 3), strides=(2, 2), padding="valid", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
# 重复2次
y = Conv2D(filters=128//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=128//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

#--------------------------------
# x = resblock_body(x, 256, 8)
#--------------------------------
x = ZeroPadding2D(((1, 0), (1, 0)))(x)
x = Conv2D(filters=256, kernel_size=(3, 3), strides=(2, 2), padding="valid", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
# 重复8次
y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=256//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

#-----------------------
#  DarkNet-53的第一个输出层
#-----------------------
feat1 = x

#-------------------------------
# x = resblock_body(x, 512, 8)
#-------------------------------
x = ZeroPadding2D(((1, 0), (1, 0)))(x)
x = Conv2D(filters=512, kernel_size=(3, 3), strides=(2, 2), padding="valid", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
# 重复8次
y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=512//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

#-----------------------
#  DarkNet-53的第二个输出层
#-----------------------
feat2 = x

#--------------------------------
# x = resblock_body(x, 1024, 4)
#--------------------------------
x = ZeroPadding2D(((1, 0), (1, 0)))(x)
x = Conv2D(filters=1024, kernel_size=(3, 3), strides=(2, 2), padding="valid", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
# 重复4次
y = Conv2D(filters=1024//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=1024, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=1024//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=1024, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=1024//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=1024, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

y = Conv2D(filters=1024//2, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
y = Conv2D(filters=1024, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)
x = Add()([x, y])

#-----------------------
#  DarkNet-53的第三个输出层
#-----------------------
feat3 = x

# # 打印三个有效特征层
# # feat1:(None, 52, 52, 256)、feat2:(None, 26, 26, 512)、feat3:(None, 13, 13, 1024)
# model = tf.keras.Model(inputs=input, outputs=[feat1, feat2, feat3])
# print(model.summary())
# print(feat1, feat2, feat3)

#-----------------------
#  产生YOLOv3的三个有效特征层
#-----------------------

#-----------------------
#  YOLOv3的第一个有效特征层
#-----------------------
# 五次卷积
x = Conv2D(filters=512, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(feat3)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=512*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=512, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=512*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=512, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

# 调整最后的通道数
y = Conv2D(filters=512*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)

# 3*(20+5):3表示每个网格当中有3个anchor box、20表示每个anchor box预测20个类别概率、5表示每个anchor box预测4个位置信息和一个置信度
y = Conv2D(filters=3*(20+5), kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y1 = LeakyReLU(alpha=0.1)(y)

#-----------------------
#  YOLOv3的第二个有效特征层
#-----------------------
# 卷积
x = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

# 上采样
x = UpSampling2D(2)(x)

# 拼接
x = Concatenate()([x, feat2])

# 五次卷积
x = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=256*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=256*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

# 调整最后的通道数
y = Conv2D(filters=256*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)

# 3*(20+5):3表示每个网格当中有3个anchor box、20表示每个anchor box预测20个类别概率、5表示每个anchor box预测4个位置信息和一个置信度
y = Conv2D(filters=3*(20+5), kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y2 = LeakyReLU(alpha=0.1)(y)

#-----------------------
#  YOLOv3的第三个有效特征层
#-----------------------
# 卷积
x = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

# 上采样
# 输入:(batch_size, rows, cols, channels)
# 输出:(batch_size, rows*2, cols*2, channels)
# 默认使用最近邻插值(也可以选择线性插值)
x = UpSampling2D(2)(x)

# 拼接
x = Concatenate()([x, feat1])

# 五次卷积
x = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=128*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=128*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

x = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)

# 调整最后的通道数
y = Conv2D(filters=128*2, kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(x)
y = BatchNormalization()(y)
y = LeakyReLU(alpha=0.1)(y)

# 3*(20+5):3表示每个网格当中有3个anchor box、20表示每个anchor box预测20个类别概率、5表示每个anchor box预测4个位置信息和一个置信度
y = Conv2D(filters=3*(20+5), kernel_size=(3, 3), strides=(1, 1), padding="same", use_bias=False, kernel_regularizer=l2(5e-4))(y)
y = BatchNormalization()(y)
y3 = LeakyReLU(alpha=0.1)(y)

# 打印三个有效特征层
# y1:(None, 13, 13, 75)、y2:(None, 26, 26, 75)、y3:(None, 52, 52, 75)
model = tf.keras.Model(inputs=input, outputs=[y1, y2, y3])
print(model.summary())
print(y1, y2, y3)

你可能感兴趣的:(网络,深度学习,卷积神经网络,tensorflow,神经网络)