赞
踩
第一篇博文,就是想记录一下学习过程,最终目的是实现faster rcnn,本科生跟着老师学习目标检测。
我是参考了b站up主霹雳吧啦Wz的利用pytorch搭建resnet网络的视频,这里附上链接6.2 使用pytorch搭建ResNet并基于迁移学习训练
想要搭建resnet网络,首先我们得参考它的原理图
第一首先无论是resnet几层的网络,它的conv1和conv2_x的maxpool都是一样的
- import torch.nn as nn
- class resnet(nn.Module):
- def __init__(self):
- super(resnet,self).__init__()
- #假设输入图片大小为600x600x3
- #600x600x3-->300x300x64
- self.conv1=nn.Conv2d(3,64,kernel_size=7,stride=2,padding=3,bias=False)
- self.bn=nn.BatchNorm2d(64)
- self.relu=nn.ReLU(inplace=True)
- #ceil_mode向上取整
- self.maxpooling=nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True)
-
- def forward(self, x):
- x = self.conv1(x)
- x = self.bn(x)
- x = self.relu(x)
- x = self.maxpooling(x)
- return x
- net=resnet()
- print(net)
可以打印看下
- resnet(
- (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
- (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- (maxpooling): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
- )
然后我们就要进入到残差结构中了,这里conv2_x到conv5_x简称第一层到第四层,可以看到resnet18、34层中第一层到第四层内的层结构内它们的卷积核维度是不变的,但是resnet50、101、152的层内的层结构就不一样了,每一层层结构内的卷积核三的维度都是卷积核一的三倍,所以对于这两类不同的层结构,我们需要定义两类结构来区别18、34层和50、101、152层。
对于resnet18、34层它每一个层结构中有两个卷积核,且维度不变,但是它每一个层结构的第一层需要对上一层的图片宽高减半,维度乘2,除了第一层有一个maxpooling层是特殊的,这里的downsample内容尚未定义,代码如下
- import torch.nn as nn
- import torch
- #定义18和34层的瓶颈结构,也就是每一层里的结构
- #如果维度改变则需要将输出加上downsample
- class bottleneck1(nn.Module):
- #层结构中卷积核的维度是一样的
- expansion=1
- def __init__(self,in_channels,out_channels,stride=1,downsample=None):
- super(bottleneck1, self).__init__()
- self.conv1=nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=3,stride=stride,padding=1,bias=False)
- self.bn1=nn.BatchNorm2d(out_channels)
- self.relu=nn.ReLU(inplace=True)
-
- self.conv2=nn.Conv2d(in_channels=out_channels,out_channels=out_channels,kernel_size=3,stride=1,padding=1,bias=False)
- self.bn2=nn.BatchNorm2d(out_channels)
- self.downsample=downsample
-
- def forward(self,x):
- #判断是否需要加上downsample,是否需要对图片宽高减半
- a=x
- if self.downsample is True:
- a=self.downsample(x)
- x=self.conv1(x)
- x=self.bn1(x)
- x=self.relu(x)
- x=self.conv2(x)
- x=self.bn2(x)
- #如果有downsample则需要加上
- x+=a
- #将合运用激活函数
- x=self.relu(x)
- return x
对于resnet50、101、152,它每一层内的第三个卷积核会将维度*4,代码如下
- #定义50,101,152的层结构
- class bottleneck2(nn.Module):
- expansion=4
- def __init__(self,in_channels,out_channels,stride=1,downsample=None):
- super(bottleneck2,self).__init__()
- self.conv1=nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=1,stride=1,padding=1,bias=False)
- self.bn1=nn.BatchNorm2d(out_channels)
- self.conv2=nn.Conv2d(in_channels=out_channels,out_channels=out_channels,kernel_size=3,stride=stride,padding=1,bias=False)
- self.bn2=nn.BatchNorm2d(out_channels)
- #第三层的维度要阔张4倍
- self.conv3=nn.Conv2d(in_channels=out_channels,out_channels=out_channels*self.expansion,kernel_size=1,stride=1,bias=False)
- self.bn3=nn.BatchNorm2d(out_channels*self.expansion)
- self.downsample=downsample
- self.relu=nn.ReLU(inplace=True)
-
- def forward(self,x):
- a=x
- if self.downsample is True:
- a=self.downsample(x)
- x=self.conv1(x)
- x=self.bn1(x)
- x=self.relu(x)
- x=self.conv2(x)
- x=self.bn2(x)
- x=self.relu(x)
- x=self.conv3(x)
- x=self.bn3(x)
- x+=a
- x=self.relu(x)
-
-
- net=bottleneck2(in_channels=64,out_channels=128,stride=1)
- print(net)
看一下输出结果,每一层的第三层需要维度*4
- bottleneck2(
- (conv1): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), padding=(1, 1), bias=False)
- (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
将这两个瓶颈结构定义完后,需要在resnet类中定义一个函数来包含每一层结构内的所有操作
- #block代表使用bottleneck1 or bottleneck2
- #channel代表每一层残差结构中第一层的通道数
- #block_num代表每一层有多少个残差结构,resnet50为【3,4,6,3】
- def makelayer(self,block,channel,block_num,stride=1):
- downsample=None
- #如果步距不为1则代表有残差结构或者expension不为1也有
- if stride!=1 or self.in_channel!=channel*block.expansion:
- downsample=nn.Sequential(nn.Conv2d(in_channels=self.in_channel,out_channels=channel*block.expansion,kernel_size=1,stride=stride,bias=False),
- nn.BatchNorm2d(channel*block.expansion))
- #把第一层的结构放到列表里
- layers=[]
- layers.append(block(self.in_channel,channel,stride,downsample))
- #第二层的输入是第一层的输出
- self.in_channel=channel*block.expansion
- for i in range(1,block_num):
- layers.append(block(self.in_channel,channel))
- return nn.Sequential(*layers)
定义完了makelayer之后我们就可以开始前向传播了
- class resnet(nn.Module):
- in_channel = 64
- def __init__(self,block,block_num,num_classes=1000):
- super(resnet,self).__init__()
- #假设输入图片大小为600x600x3
- #600x600x3-->300x300x64
- self.conv1=nn.Conv2d(3,64,kernel_size=7,stride=2,padding=3,bias=False)
- self.bn=nn.BatchNorm2d(64)
- self.relu=nn.ReLU(inplace=True)
- #ceil_mode向上取整
- self.maxpooling=nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True)
- #第一层步距为1
- self.layer1=self.makelayer(block=block,channel=64,block_num=block_num[0])
- #从第二层开始,每一层都要downsamole
- self.layer2=self.makelayer(block=block,channel=128,block_num=block_num[1],stride=2)
- self.layer3=self.makelayer(block=block,channel=256,block_num=block_num[2],stride=2)
- self.layer4=self.makelayer(block=block,channel=512,block_num=block_num[3],stride=2)
- #自适应平均池化下采样,无论输入图片的高宽是多少,都变成1,1
- self.avgpool=nn.AdaptiveAvgPool2d((1,1))
- self.fc=nn.Linear(512*block.expansion,num_classes)
- #卷积层初始化
- for m in self.modules():
- if isinstance(m,nn.Conv2d):
- nn.init.kaiming_normal(m.weight,mode="fan_out",nonlinearity='relu')
-
-
- # self.layer1=
- def forward(self,x):
- x=self.conv1(x)
- x=self.bn(x)
- x=self.relu(x)
- x=self.maxpooling(x)
- x=self.layer1(x)
- x=self.layer2(x)
- x=self.layer3(x)
- x=self.avgpool(x)
- x=torch.flatten(x,dims=1)
- x=self.fc(x)
- return x
最后是平均池化和全连接层,到此resnet网络就定义完毕了,以下附上全部代码
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2022/5/12 16:37
- # @Author : 半岛铁盒
- # @File : resnet 50.py
- # @Software: win10 python3.6
- import torch.nn as nn
- import torch
- #定义18和34层的瓶颈结构,也就是每一层里的结构
- #如果维度改变则需要将输出加上downsample
- class bottleneck1(nn.Module):
- #层结构中卷积核的维度是一样的
- expansion=1
- def __init__(self,in_channels,out_channels,stride=1,downsample=None):
- super(bottleneck1, self).__init__()
- self.conv1=nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=3,stride=stride,padding=1,bias=False)
- self.bn1=nn.BatchNorm2d(out_channels)
- self.relu=nn.ReLU(inplace=True)
-
- self.conv2=nn.Conv2d(in_channels=out_channels,out_channels=out_channels,kernel_size=3,stride=1,padding=1,bias=False)
- self.bn2=nn.BatchNorm2d(out_channels)
- self.downsample=downsample
-
- def forward(self,x):
- #判断是否需要加上downsample
- a=x
- if self.downsample is True:
- a=self.downsample(x)
- x=self.conv1(x)
- x=self.bn1(x)
- x=self.relu(x)
- x=self.conv2(x)
- x=self.bn2(x)
- #如果有downsample则需要加上
- x+=a
- #将合运用激活函数
- x=self.relu(x)
- return x
-
- #定义50,101,152的层结构
- class bottleneck2(nn.Module):
- expansion=4
- def __init__(self,in_channels,out_channels,stride=1,downsample=None):
- super(bottleneck2,self).__init__()
- self.conv1=nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=1,stride=1,bias=False)
- self.bn1=nn.BatchNorm2d(out_channels)
- self.conv2=nn.Conv2d(in_channels=out_channels,out_channels=out_channels,kernel_size=3,stride=stride,padding=1,bias=False)
- self.bn2=nn.BatchNorm2d(out_channels)
- #第三层的维度要阔张4倍
- self.conv3=nn.Conv2d(in_channels=out_channels,out_channels=out_channels*self.expansion,kernel_size=1,stride=1,bias=False)
- self.bn3=nn.BatchNorm2d(out_channels*self.expansion)
- self.downsample=downsample
- self.relu=nn.ReLU(inplace=True)
-
- def forward(self,x):
- a=x
- if self.downsample is True:
- a=self.downsample(x)
- x=self.conv1(x)
- x=self.bn1(x)
- x=self.relu(x)
- x=self.conv2(x)
- x=self.bn2(x)
- x=self.relu(x)
- x=self.conv3(x)
- x=self.bn3(x)
- x+=a
- x=self.relu(x)
-
-
- class resnet(nn.Module):
- in_channel = 64
- def __init__(self,block,block_num,num_classes=1000):
- super(resnet,self).__init__()
- #假设输入图片大小为600x600x3
- #600x600x3-->300x300x64
- self.conv1=nn.Conv2d(3,self.in_channel,kernel_size=7,stride=2,padding=3,bias=False)
- self.bn=nn.BatchNorm2d(self.in_channel)
- self.relu=nn.ReLU(inplace=True)
- #ceil_mode向上取整
- self.maxpooling=nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True)
- #第一层步距为1
- self.layer1=self.makelayer(block=block,channel=64,block_num=block_num[0])
- #从第二层开始,每一层都要downsamole
- self.layer2=self.makelayer(block=block,channel=128,block_num=block_num[1],stride=2)
- self.layer3=self.makelayer(block=block,channel=256,block_num=block_num[2],stride=2)
- self.layer4=self.makelayer(block=block,channel=512,block_num=block_num[3],stride=2)
- #自适应平均池化下采样,无论输入图片的高宽是多少,都变成1,1
- self.avgpool=nn.AdaptiveAvgPool2d((1,1))
- self.fc=nn.Linear(512*block.expansion,num_classes)
- #卷积层初始化
- for m in self.modules():
- if isinstance(m,nn.Conv2d):
- nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
-
-
- #block代表使用bottleneck1 or bottleneck2
- #channel代表每一层残差结构中第一层的通道数
- #block_num代表每一层有多少个残差结构,resnet50为【3,4,6,3】
- def makelayer(self,block,channel,block_num,stride=1):
- downsample=None
- #如果步距不为1则代表有残差结构或者expension不为1也有
- if stride!=1 or self.in_channel!=channel*block.expansion:
- downsample=nn.Sequential(nn.Conv2d(in_channels=self.in_channel,out_channels=channel*block.expansion,kernel_size=1,stride=stride,bias=False),
- nn.BatchNorm2d(channel*block.expansion))
- #把第一层的结构放到列表里
- layers=[]
- layers.append(block(self.in_channel,channel,stride,downsample))
- #第二层的输入是第一层的输出
- self.in_channel=channel*block.expansion
- for i in range(1,block_num):
- layers.append(block(self.in_channel,channel))
- return nn.Sequential(*layers)
-
- def forward(self,x):
- x=self.conv1(x)
- x=self.bn(x)
- x=self.relu(x)
- x=self.maxpooling(x)
- x=self.layer1(x)
- x=self.layer2(x)
- x=self.layer3(x)
- x=self.avgpool(x)
- x=torch.flatten(x,dims=1)
- x=self.fc(x)
- return x
-
-
- net=resnet(block=bottleneck2,block_num=[3,4,6,3])
-
- print(net)
打印一下最终结果看一下resnet的网络结构
- resnet(
- (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
- (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- (maxpooling): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
- (layer1): Sequential(
- (0): bottleneck2(
- (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (downsample): Sequential(
- (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- )
- (relu): ReLU(inplace=True)
- )
- (1): bottleneck2(
- (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (2): bottleneck2(
- (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- )
- (layer2): Sequential(
- (0): bottleneck2(
- (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (downsample): Sequential(
- (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
- (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- )
- (relu): ReLU(inplace=True)
- )
- (1): bottleneck2(
- (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (2): bottleneck2(
- (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (3): bottleneck2(
- (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- )
- (layer3): Sequential(
- (0): bottleneck2(
- (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (downsample): Sequential(
- (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
- (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- )
- (relu): ReLU(inplace=True)
- )
- (1): bottleneck2(
- (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (2): bottleneck2(
- (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (3): bottleneck2(
- (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (4): bottleneck2(
- (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (5): bottleneck2(
- (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- )
- (layer4): Sequential(
- (0): bottleneck2(
- (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (downsample): Sequential(
- (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
- (1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- )
- (relu): ReLU(inplace=True)
- )
- (1): bottleneck2(
- (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- (2): bottleneck2(
- (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
- (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
- (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
- (relu): ReLU(inplace=True)
- )
- )
- (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
- (fc): Linear(in_features=2048, out_features=1000, bias=True)
- )
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。