squeezenet.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import paddle
  15. from paddle import ParamAttr
  16. import paddle.nn as nn
  17. import paddle.nn.functional as F
  18. from paddle.nn import Conv2D, BatchNorm, Linear, Dropout
  19. from paddle.nn import AdaptiveAvgPool2D, MaxPool2D, AvgPool2D
  20. from paddlex.ppcls.utils.save_load import load_dygraph_pretrain, load_dygraph_pretrain_from_url
  21. MODEL_URLS = {
  22. "SqueezeNet1_0":
  23. "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SqueezeNet1_0_pretrained.pdparams",
  24. "SqueezeNet1_1":
  25. "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SqueezeNet1_1_pretrained.pdparams",
  26. }
  27. __all__ = list(MODEL_URLS.keys())
  28. class MakeFireConv(nn.Layer):
  29. def __init__(self,
  30. input_channels,
  31. output_channels,
  32. filter_size,
  33. padding=0,
  34. name=None):
  35. super(MakeFireConv, self).__init__()
  36. self._conv = Conv2D(
  37. input_channels,
  38. output_channels,
  39. filter_size,
  40. padding=padding,
  41. weight_attr=ParamAttr(name=name + "_weights"),
  42. bias_attr=ParamAttr(name=name + "_offset"))
  43. def forward(self, x):
  44. x = self._conv(x)
  45. x = F.relu(x)
  46. return x
  47. class MakeFire(nn.Layer):
  48. def __init__(self,
  49. input_channels,
  50. squeeze_channels,
  51. expand1x1_channels,
  52. expand3x3_channels,
  53. name=None):
  54. super(MakeFire, self).__init__()
  55. self._conv = MakeFireConv(
  56. input_channels, squeeze_channels, 1, name=name + "_squeeze1x1")
  57. self._conv_path1 = MakeFireConv(
  58. squeeze_channels, expand1x1_channels, 1, name=name + "_expand1x1")
  59. self._conv_path2 = MakeFireConv(
  60. squeeze_channels,
  61. expand3x3_channels,
  62. 3,
  63. padding=1,
  64. name=name + "_expand3x3")
  65. def forward(self, inputs):
  66. x = self._conv(inputs)
  67. x1 = self._conv_path1(x)
  68. x2 = self._conv_path2(x)
  69. return paddle.concat([x1, x2], axis=1)
  70. class SqueezeNet(nn.Layer):
  71. def __init__(self, version, class_num=1000):
  72. super(SqueezeNet, self).__init__()
  73. self.version = version
  74. if self.version == "1.0":
  75. self._conv = Conv2D(
  76. 3,
  77. 96,
  78. 7,
  79. stride=2,
  80. weight_attr=ParamAttr(name="conv1_weights"),
  81. bias_attr=ParamAttr(name="conv1_offset"))
  82. self._pool = MaxPool2D(kernel_size=3, stride=2, padding=0)
  83. self._conv1 = MakeFire(96, 16, 64, 64, name="fire2")
  84. self._conv2 = MakeFire(128, 16, 64, 64, name="fire3")
  85. self._conv3 = MakeFire(128, 32, 128, 128, name="fire4")
  86. self._conv4 = MakeFire(256, 32, 128, 128, name="fire5")
  87. self._conv5 = MakeFire(256, 48, 192, 192, name="fire6")
  88. self._conv6 = MakeFire(384, 48, 192, 192, name="fire7")
  89. self._conv7 = MakeFire(384, 64, 256, 256, name="fire8")
  90. self._conv8 = MakeFire(512, 64, 256, 256, name="fire9")
  91. else:
  92. self._conv = Conv2D(
  93. 3,
  94. 64,
  95. 3,
  96. stride=2,
  97. padding=1,
  98. weight_attr=ParamAttr(name="conv1_weights"),
  99. bias_attr=ParamAttr(name="conv1_offset"))
  100. self._pool = MaxPool2D(kernel_size=3, stride=2, padding=0)
  101. self._conv1 = MakeFire(64, 16, 64, 64, name="fire2")
  102. self._conv2 = MakeFire(128, 16, 64, 64, name="fire3")
  103. self._conv3 = MakeFire(128, 32, 128, 128, name="fire4")
  104. self._conv4 = MakeFire(256, 32, 128, 128, name="fire5")
  105. self._conv5 = MakeFire(256, 48, 192, 192, name="fire6")
  106. self._conv6 = MakeFire(384, 48, 192, 192, name="fire7")
  107. self._conv7 = MakeFire(384, 64, 256, 256, name="fire8")
  108. self._conv8 = MakeFire(512, 64, 256, 256, name="fire9")
  109. self._drop = Dropout(p=0.5, mode="downscale_in_infer")
  110. self._conv9 = Conv2D(
  111. 512,
  112. class_num,
  113. 1,
  114. weight_attr=ParamAttr(name="conv10_weights"),
  115. bias_attr=ParamAttr(name="conv10_offset"))
  116. self._avg_pool = AdaptiveAvgPool2D(1)
  117. def forward(self, inputs):
  118. x = self._conv(inputs)
  119. x = F.relu(x)
  120. x = self._pool(x)
  121. if self.version == "1.0":
  122. x = self._conv1(x)
  123. x = self._conv2(x)
  124. x = self._conv3(x)
  125. x = self._pool(x)
  126. x = self._conv4(x)
  127. x = self._conv5(x)
  128. x = self._conv6(x)
  129. x = self._conv7(x)
  130. x = self._pool(x)
  131. x = self._conv8(x)
  132. else:
  133. x = self._conv1(x)
  134. x = self._conv2(x)
  135. x = self._pool(x)
  136. x = self._conv3(x)
  137. x = self._conv4(x)
  138. x = self._pool(x)
  139. x = self._conv5(x)
  140. x = self._conv6(x)
  141. x = self._conv7(x)
  142. x = self._conv8(x)
  143. x = self._drop(x)
  144. x = self._conv9(x)
  145. x = F.relu(x)
  146. x = self._avg_pool(x)
  147. x = paddle.squeeze(x, axis=[2, 3])
  148. return x
  149. def _load_pretrained(pretrained, model, model_url, use_ssld=False):
  150. if pretrained is False:
  151. pass
  152. elif pretrained is True:
  153. load_dygraph_pretrain_from_url(model, model_url, use_ssld=use_ssld)
  154. elif isinstance(pretrained, str):
  155. load_dygraph_pretrain(model, pretrained)
  156. else:
  157. raise RuntimeError(
  158. "pretrained type is not available. Please use `string` or `boolean` type."
  159. )
  160. def SqueezeNet1_0(pretrained=False, use_ssld=False, **kwargs):
  161. model = SqueezeNet(version="1.0", **kwargs)
  162. _load_pretrained(
  163. pretrained, model, MODEL_URLS["SqueezeNet1_0"], use_ssld=use_ssld)
  164. return model
  165. def SqueezeNet1_1(pretrained=False, use_ssld=False, **kwargs):
  166. model = SqueezeNet(version="1.1", **kwargs)
  167. _load_pretrained(
  168. pretrained, model, MODEL_URLS["SqueezeNet1_1"], use_ssld=use_ssld)
  169. return model