构建darknet53网络
1、首先定义残差网络模块
class BasicBlock(nn.Module): #继承自nn.module模块
def __init__(self, inplanes, planes):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(inplanes, planes[0], kernel_size=1, stride=1, padding=0, bias=False)
self.bn1 = nn.BatchNorm2d(planes[0])
self.relu1 = nn.LeakyReLU(0.1)
self.conv2 = nn.Conv2d(planes[0], planes[1], kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes[1])
self.relu2 = nn.LeakyReLU(0.1)
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu1(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu2(out)
out += residual # 相比于正常的定义网络就是这里加入了一部跳连接
return out
以上定义出了一个继承自module类的BasicBlock网络层
2、然后搭建darknet网络主体
lass DarkNet(nn.Module): #网络同样继承自Module
def __init__(self, layers):
super(DarkNet, self).__init__()
self.inplanes = 32
self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(self.inplanes)
self.relu1 = nn.LeakyReLU(0.1)
self.layer1 = self._make_layer([32, 64], layers[0]) # self._make_layer是这里自定的包含残差网络的网络模块 416,416,32 -> 208,208,64
self.layer2 = self._make_layer([64, 128], layers[1]) # 208,208,64 -> 104,104,128
self.layer3 = self._make_layer([128, 256], layers[2]) # 104,104,128 -> 52,52,256
self.layer4 = self._make_layer([256, 512], layers[3]) # 52,52,256 -> 26,26,512
self.layer5 = self._make_layer([512, 1024], layers[4]) # 26,26,512 -> 13,13,1024
........
def _make_layer(self, planes, blocks): #这个函数自定义构造残差网络模块
layers = []
# 在一个列表中创建网络层,每个元素有两个子元素,第一个是网络名,第二个是torch.nn.modules.conv.Conv2d格式的网络层,append摞起来就行
# 下采样,步长为2,卷积核大小为3
layers.append(("ds_conv", nn.Conv2d(self.inplanes, planes[1], kernel_size=3, stride=2, padding=1, bias=False)))
layers.append(("ds_bn", nn.BatchNorm2d(planes[1])))
layers.append(("ds_relu", nn.LeakyReLU(0.1)))
# 加入残差结构
self.inplanes = planes[1]
for i in range(0, blocks):
layers.append(("residual_{}".format(i), BasicBlock(self.inplanes, planes))) #这里也是一个名+一个网络层,继续往layer列表里添加
return nn.Sequential(OrderedDict(layers)) #最后通过OrderDict函数将封装好各网络层的layer列表转换成collections.OrderedDict变量,最终再使用nn.Sequential函数将其转换成torch.nn.modules.container.Sequential,变为module类网络,供后续使用
def forward(self, x): # 定义前向传播
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
x = self.layer1(x)
x = self.layer2(x)
out3 = self.layer3(x)
out4 = self.layer4(out3)
out5 = self.layer5(out4)
return out3, out4, out5
# 最后,实例化darknet网络
def darknet53():
model = DarkNet([1, 2, 8, 8, 4])
return model