• 9.FPN网络代码实现


    代码如下:

    1. # import torch.nn as nn
    2. # import torch
    3. # import torch.nn.functional as F
    4. # import math
    5. #
    6. # #1.resNet的基本BottleBlock类
    7. #
    8. # class Bottleneck(nn.Module):
    9. # expension=4
    10. # def __init__(self,in_planes,planes,stride=1,downsample=None):
    11. # super(Bottleneck,self).__init__()
    12. #
    13. # self.bottleneck=nn.Sequential(
    14. # #1.对输入变量x进行卷积、归一化、RELU激活
    15. # nn.Conv2d(in_planes,planes,1,bias=False),
    16. # nn.BatchNorm2d(planes),
    17. # nn.ReLU(inplace=True),
    18. #
    19. # #2.构造f(x)输出
    20. # nn.Conv2d(planes,planes,3,stride,1,bias=False),
    21. # nn.BatchNorm2d(planes),
    22. # nn.ReLU(inplace=True),
    23. #
    24. # nn.Conv2d(planes,self.expension*planes,1,bias=False),
    25. # nn.BatchNorm2d(self.expension*planes)
    26. # )
    27. #
    28. # #3.构造激活函数,构造下采样函数为None
    29. # self.relu=nn.ReLU(inplace=True)
    30. # #self.downsample=downsample
    31. # self.downsample =nn.Sequential(
    32. # nn.Conv2d(in_planes,self.expension*planes,1,1),
    33. # nn.BatchNorm2d(self.expension*planes)
    34. # )
    35. #
    36. #
    37. # def forward(self,x):
    38. #
    39. # identity=x
    40. #
    41. # #4.构造f(x)
    42. # out=self.bottleneck(x)
    43. #
    44. # #5.如果有下采样,则进行下采样
    45. # if self.downsample is not None:
    46. # identity=self.downsample(x)
    47. #
    48. # #6.构造 x+f(x)
    49. # out+=identity
    50. #
    51. # #7.对 x+f(x) 进行激活
    52. # out=self.relu(out)
    53. #
    54. # #8.返回激活后的 x+f(x)
    55. # return out
    56. #
    57. #
    58. # if __name__ == '__main__':
    59. #
    60. #
    61. # input=torch.randn(1,64,56,56)
    62. #
    63. # ss=Bottleneck(64,256)
    64. #
    65. # hh=ss(input)
    66. # print(hh.shape)
    67. import torch.nn as nn
    68. import torch
    69. import torch.nn.functional as F
    70. #1.resNet的基本BottleBlock类
    71. class Bottleneck(nn.Module):
    72. expension=4
    73. def __init__(self,in_planes,planes,stride=1,downsample=None):
    74. super(Bottleneck,self).__init__()
    75. self.bottleneck=nn.Sequential(
    76. #1.对输入变量x进行卷积、归一化、RELU激活
    77. nn.Conv2d(in_planes,planes,1,bias=False),
    78. nn.BatchNorm2d(planes),
    79. nn.ReLU(inplace=True),
    80. #2.构造f(x)输出
    81. nn.Conv2d(planes,planes,3,stride,1,bias=False),
    82. nn.BatchNorm2d(planes),
    83. nn.ReLU(inplace=True),
    84. nn.Conv2d(planes,self.expension*planes,1,bias=False),
    85. nn.BatchNorm2d(self.expension*planes)
    86. )
    87. #3.构造激活函数,构造下采样函数为None
    88. self.relu=nn.ReLU(inplace=True)
    89. self.downsample=downsample
    90. # self.downsample =nn.Sequential(
    91. # nn.Conv2d(in_planes,self.expension*planes,1,1),
    92. # nn.BatchNorm2d(self.expension*planes)
    93. # )
    94. def forward(self,x):
    95. identity=x
    96. #4.构造f(x)
    97. out=self.bottleneck(x)
    98. #5.如果有下采样,则进行下采样
    99. if self.downsample is not None:
    100. identity=self.downsample(x)
    101. #6.构造 x+f(x)
    102. out+=identity
    103. #7.对 x+f(x) 进行激活
    104. out=self.relu(out)
    105. #8.返回激活后的 x+f(x)
    106. return out
    107. #2.FPN的类,初始化需要一个list,代表ResNet的每一个阶段的Bottleneck数量
    108. class FPN(nn.Module):
    109. def __init__(self,layers):
    110. super(FPN,self).__init__()
    111. self.inplanes=64
    112. #1.处理输入的C1模块
    113. self.conv1=nn.Conv2d(3,64,7,2,3,bias=False)
    114. self.bn1=nn.BatchNorm2d(64)
    115. self.relu=nn.ReLU(inplace=True)
    116. self.maxpool=nn.MaxPool2d(3,2,1)
    117. #2.搭建自上而下的C2,C3,C4,C5
    118. self.layer1=self.make_layer(64,layers[0])
    119. self.layer2=self.make_layer(128,layers[1],2)
    120. self.layer3 = self.make_layer(256, layers[2],2)
    121. self.layer4 = self.make_layer(512, layers[3],2)
    122. #3.对C5减少通道数,得到P5 输入通道数2048,输出通道数256,卷积核大小1,步长为1,0填充
    123. self.toplayer=nn.Conv2d(2048,256,1,1,0)
    124. #4.3X3卷积融合特征
    125. self.smooth1=nn.Conv2d(256,256,3,1,1)
    126. self.smooth2 = nn.Conv2d(256, 256, 3, 1, 1)
    127. self.smooth3 = nn.Conv2d(256, 256, 3, 1, 1)
    128. #5.横向连接,保证通道数相同
    129. self.latlayer1=nn.Conv2d(1024,256,1,1,0)
    130. self.latlayer2= nn.Conv2d(512, 256, 1, 1, 0)
    131. self.latlayer3= nn.Conv2d(256, 256, 1, 1, 0)
    132. #2.构造C2到C5,注意区分stride为1和2的情况
    133. def make_layer(self,planes,blocks,stride=1):
    134. downsample=None
    135. if stride!=1 or self.inplanes!=Bottleneck.expension*planes:
    136. #下采样的卷积核大小为1,目的是使输入x和输出的f(x)的通道数相同,使x的通道数是输入的4倍,这样残差网络才能做 x+f(x) 运算
    137. downsample=nn.Sequential(
    138. nn.Conv2d(self.inplanes,Bottleneck.expension*planes,1,stride,bias=False),
    139. nn.BatchNorm2d(Bottleneck.expension*planes)
    140. )
    141. layers=[]
    142. #加入第一层
    143. layers.append(Bottleneck(self.inplanes,planes,stride,downsample))
    144. self.inplanes=planes*Bottleneck.expension
    145. # C2,C3,C4,C5的bottleneck个数不同,其个数分别是[3,4,6,3]
    146. for i in range(1,blocks):
    147. layers.append(Bottleneck(self.inplanes,planes))
    148. return nn.Sequential(*layers)
    149. #3.自上而下的上采样模块
    150. def _upsample(self,x,y):
    151. _,_,H,W=y.shape
    152. #用最近邻插值法进行下采样
    153. return F.upsample(x,size=(H,W),mode="bilinear")+y
    154. def forward(self,x):
    155. #1.自下而上的C1,C2,C3,C4,C5
    156. c1=self.maxpool(self.relu(self.bn1(self.conv1(x))))
    157. c2=self.layer1(c1)
    158. c3=self.layer2(c2)
    159. c4=self.layer3(c3)
    160. c5=self.layer4(c4)
    161. #2.自上而下的上采样
    162. p5=self.toplayer(c5)
    163. p4=self._upsample(p5,self.latlayer1(c4))
    164. p3 = self._upsample(p5, self.latlayer2(c3))
    165. p2 = self._upsample(p5, self.latlayer3(c2))
    166. #3.卷积融合,平滑处理
    167. p4=self.smooth1(p4)
    168. p3=self.smooth2(p3)
    169. p2=self.smooth3(p2)
    170. return p2,p3,p4,p5
    171. if __name__ == '__main__':
    172. net_fpn=FPN([3,4,6,3])
    173. # print(net_fpn.conv1)
    174. # print(net_fpn.layer1)
    175. input=torch.randn(1,3,224,224)
    176. output=net_fpn(input)
    177. print(len(output),output[0].shape)#print(len(output),output[0].shape)#
    178. print( output[1].shape)#[1, 256, 28, 28]
    179. print(output[2].shape)#[1, 256, 14, 14]
    180. print(output[3].shape)#[1, 256, 7, 7]

  • 相关阅读:
    最佳Linux防病毒软件推荐!
    Android sqlcipher 对于加密的Sqlite库在Mac上进行解密的正确姿势
    优思学院|简单而强大的5W1H提问法
    如何处理MindSpore Lite推理失败的问题
    排列组合总结
    kubectl系列(六)-kubectl describe
    java计算机毕业设计水质监测数据采集系统源码+系统+数据库+lw文档+mybatis+运行部署
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    基础不牢的把vue的插槽再好好看下吧
    Python基础教程:装饰器的详细教程
  • 原文地址:https://blog.csdn.net/weixin_71719718/article/details/133827470