Darknet53网络

Darknet53网络结构及代码

本文链接: https://blog.csdn.net/leiduifan6944/article/details/104857968

Darknet是最经典的一个深层网络,结合Resnet的特点在保证对特征进行超强表达的同时又避免了网络过深带来的梯度问题,主要有Darknet19和Darknet53,当然,如果你觉得这还不够深,在你条件允许的情况下你也可以延伸到99,199,999,…。

1、结构图大致如下

(这张图是从网上扒来的,凑合着,懒得自己画了)

Ait

2、清楚结构之后,那么,这么深的网络,一层一层的写出来的话,每层还有卷积、归一化、激活…那得写多少行才能写完呀?

莫捉急,清楚了结构,再把他狠狠封装成块,一波带走
1、先把卷积装一块
class Conv(nn.Module):
	def __init__(self, c_in, c_out, k, s, p, bias=True):
		"""
		自定义一个卷积块,一次性完成卷积+归一化+激活,这在类似于像DarkNet53这样的深层网络编码上可以节省很多代码
		:param c_in: in_channels
		:param c_out: out_channels
		:param k: kernel_size
		:param s:  stride
		:param p: padding
		:param bias: …
		"""
		super(Conv, self).__init__()
		self.conv = nn.Sequential(
			nn.Conv2d(c_in, c_out, k, s, p),
			nn.BatchNorm2d(c_out),
			nn.LeakyReLU(0.1),
		)

	def forward(self, entry):
		return self.conv(entry)
2、再把残差单元装一块
class ConvResidual(nn.Module):
	def __init__(self, c_in):		# converlution * 2 + residual
		"""
		自定义残差单元,只需给出通道数,该单元完成两次卷积,并进行加残差后返回相同维度的特征图
		:param c_in: 通道数
		"""
		c = c_in // 2
		super(ConvResidual, self).__init__()
		self.conv = nn.Sequential(
			Conv(c_in, c, 1, 1, 0),
			Conv(c, c_in, 3, 1, 1),
		)

	def forward(self, entry):
		return entry + self.conv(entry)
3、最后按照结构图把残差和卷积装一块
class Darknet53(nn.Module):
	def __init__(self):
		super(Darknet53, self).__init__()
		self.conv1 = Conv(3, 32, 3, 1, 1)			# 一个卷积块 = 1层卷积
		self.conv2 = Conv(32, 64, 3, 2, 1)
		self.conv3_4 = ConvResidual(64)				# 一个残差块 = 2层卷积
		self.conv5 = Conv(64, 128, 3, 2, 1)
		self.conv6_9 = nn.Sequential(				# = 4层卷积
			ConvResidual(128),
			ConvResidual(128),
		)
		self.conv10 = Conv(128, 256, 3, 2, 1)
		self.conv11_26 = nn.Sequential(				# = 16层卷积
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
			ConvResidual(256),
		)
		self.conv27 = Conv(256, 512, 3, 2, 1)
		self.conv28_43 = nn.Sequential(				# = 16层卷积
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
			ConvResidual(512),
		)
		self.conv44 = Conv(512, 1024, 3, 2, 1)
		self.conv45_52 = nn.Sequential(				# = 8层卷积
			ConvResidual(1024),
			ConvResidual(1024),
			ConvResidual(1024),
			ConvResidual(1024),
		)

	def forward(self, entry):
		conv1 = self.conv1(entry)
		conv2 = self.conv2(conv1)
		conv3_4 = self.conv3_4(conv2)
		conv5 = self.conv5(conv3_4)
		conv6_9 = self.conv6_9(conv5)
		conv10 = self.conv10(conv6_9)
		conv11_26 = self.conv11_26(conv10)
		conv27 = self.conv27(conv11_26)
		conv28_43 = self.conv28_43(conv27)
		conv44 = self.conv44(conv28_43)
		conv45_52 = self.conv45_52(conv44)
		return conv45_52, conv28_43, conv11_26		# YOLOv3用,所以输出了3次特征
4、Last but not least
print('The End !')
发布了8 篇原创文章 · 获赞 2 · 访问量 1859

猜你喜欢

转载自blog.csdn.net/leiduifan6944/article/details/104857968