faceboxnet.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. # Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
  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. from __future__ import absolute_import
  15. from __future__ import division
  16. from __future__ import print_function
  17. from paddle import fluid
  18. from paddle.fluid.param_attr import ParamAttr
  19. from ppdet.core.workspace import register
  20. __all__ = ['FaceBoxNet']
  21. @register
  22. class FaceBoxNet(object):
  23. """
  24. FaceBoxes, see https://https://arxiv.org/abs/1708.05234
  25. Args:
  26. with_extra_blocks (bool): whether or not extra blocks should be added
  27. lite_edition (bool): whether or not is FaceBoxes-lite
  28. """
  29. def __init__(self, with_extra_blocks=True, lite_edition=False):
  30. super(FaceBoxNet, self).__init__()
  31. self.with_extra_blocks = with_extra_blocks
  32. self.lite_edition = lite_edition
  33. def __call__(self, input):
  34. if self.lite_edition:
  35. return self._simplified_edition(input)
  36. else:
  37. return self._original_edition(input)
  38. def _simplified_edition(self, input):
  39. conv_1_1 = self._conv_norm_crelu(
  40. input=input,
  41. num_filters=8,
  42. filter_size=3,
  43. stride=2,
  44. padding=1,
  45. act='relu',
  46. name="conv_1_1")
  47. conv_1_2 = self._conv_norm_crelu(
  48. input=conv_1_1,
  49. num_filters=24,
  50. filter_size=3,
  51. stride=2,
  52. padding=1,
  53. act='relu',
  54. name="conv_1_2")
  55. pool1 = fluid.layers.pool2d(
  56. input=conv_1_2,
  57. pool_size=3,
  58. pool_padding=1,
  59. pool_type='avg',
  60. name="pool_1")
  61. conv_2_1 = self._conv_norm(
  62. input=pool1,
  63. num_filters=48,
  64. filter_size=3,
  65. stride=2,
  66. padding=1,
  67. act='relu',
  68. name="conv_2_1")
  69. conv_2_2 = self._conv_norm(
  70. input=conv_2_1,
  71. num_filters=64,
  72. filter_size=1,
  73. stride=1,
  74. padding=0,
  75. act='relu',
  76. name="conv_2_2")
  77. conv_inception = conv_2_2
  78. for i in range(3):
  79. conv_inception = self._inceptionA(conv_inception, i)
  80. layers = []
  81. layers.append(conv_inception)
  82. conv_3_1 = self._conv_norm(
  83. input=conv_inception,
  84. num_filters=128,
  85. filter_size=1,
  86. stride=1,
  87. padding=0,
  88. act='relu',
  89. name="conv_3_1")
  90. conv_3_2 = self._conv_norm(
  91. input=conv_3_1,
  92. num_filters=256,
  93. filter_size=3,
  94. stride=2,
  95. padding=1,
  96. act='relu',
  97. name="conv_3_2")
  98. layers.append(conv_3_2)
  99. if not self.with_extra_blocks:
  100. return layers[-1]
  101. return layers[-2], layers[-1]
  102. def _original_edition(self, input):
  103. conv_1 = self._conv_norm_crelu(
  104. input=input,
  105. num_filters=24,
  106. filter_size=7,
  107. stride=4,
  108. padding=3,
  109. act='relu',
  110. name="conv_1")
  111. pool_1 = fluid.layers.pool2d(
  112. input=conv_1,
  113. pool_size=3,
  114. pool_stride=2,
  115. pool_padding=1,
  116. pool_type='max',
  117. name="pool_1")
  118. conv_2 = self._conv_norm_crelu(
  119. input=pool_1,
  120. num_filters=64,
  121. filter_size=5,
  122. stride=2,
  123. padding=2,
  124. act='relu',
  125. name="conv_2")
  126. pool_2 = fluid.layers.pool2d(
  127. input=conv_1,
  128. pool_size=3,
  129. pool_stride=2,
  130. pool_padding=1,
  131. pool_type='max',
  132. name="pool_2")
  133. conv_inception = pool_2
  134. for i in range(3):
  135. conv_inception = self._inceptionA(conv_inception, i)
  136. layers = []
  137. layers.append(conv_inception)
  138. conv_3_1 = self._conv_norm(
  139. input=conv_inception,
  140. num_filters=128,
  141. filter_size=1,
  142. stride=1,
  143. padding=0,
  144. act='relu',
  145. name="conv_3_1")
  146. conv_3_2 = self._conv_norm(
  147. input=conv_3_1,
  148. num_filters=256,
  149. filter_size=3,
  150. stride=2,
  151. padding=1,
  152. act='relu',
  153. name="conv_3_2")
  154. layers.append(conv_3_2)
  155. conv_4_1 = self._conv_norm(
  156. input=conv_3_2,
  157. num_filters=128,
  158. filter_size=1,
  159. stride=1,
  160. padding=0,
  161. act='relu',
  162. name="conv_4_1")
  163. conv_4_2 = self._conv_norm(
  164. input=conv_4_1,
  165. num_filters=256,
  166. filter_size=3,
  167. stride=2,
  168. padding=1,
  169. act='relu',
  170. name="conv_4_2")
  171. layers.append(conv_4_2)
  172. if not self.with_extra_blocks:
  173. return layers[-1]
  174. return layers[-3], layers[-2], layers[-1]
  175. def _conv_norm(self,
  176. input,
  177. filter_size,
  178. num_filters,
  179. stride,
  180. padding,
  181. num_groups=1,
  182. act='relu',
  183. use_cudnn=True,
  184. name=None):
  185. parameter_attr = ParamAttr(
  186. learning_rate=0.1,
  187. initializer=fluid.initializer.MSRA(),
  188. name=name + "_weights")
  189. conv = fluid.layers.conv2d(
  190. input=input,
  191. num_filters=num_filters,
  192. filter_size=filter_size,
  193. stride=stride,
  194. padding=padding,
  195. groups=num_groups,
  196. act=None,
  197. use_cudnn=use_cudnn,
  198. param_attr=parameter_attr,
  199. bias_attr=False)
  200. return fluid.layers.batch_norm(input=conv, act=act)
  201. def _conv_norm_crelu(self,
  202. input,
  203. filter_size,
  204. num_filters,
  205. stride,
  206. padding,
  207. num_groups=1,
  208. act='relu',
  209. use_cudnn=True,
  210. name=None):
  211. parameter_attr = ParamAttr(
  212. learning_rate=0.1,
  213. initializer=fluid.initializer.MSRA(),
  214. name=name + "_weights")
  215. conv = fluid.layers.conv2d(
  216. input=input,
  217. num_filters=num_filters,
  218. filter_size=filter_size,
  219. stride=stride,
  220. padding=padding,
  221. groups=num_groups,
  222. act=None,
  223. use_cudnn=use_cudnn,
  224. param_attr=parameter_attr,
  225. bias_attr=False)
  226. conv_a = fluid.layers.batch_norm(input=conv, act=act)
  227. conv_b = fluid.layers.scale(conv_a, -1)
  228. concat = fluid.layers.concat([conv_a, conv_b], axis=1)
  229. return concat
  230. def _pooling_block(self,
  231. conv,
  232. pool_size,
  233. pool_stride,
  234. pool_padding=0,
  235. ceil_mode=True):
  236. pool = fluid.layers.pool2d(
  237. input=conv,
  238. pool_size=pool_size,
  239. pool_type='max',
  240. pool_stride=pool_stride,
  241. pool_padding=pool_padding,
  242. ceil_mode=ceil_mode)
  243. return pool
  244. def _inceptionA(self, data, idx):
  245. idx = str(idx)
  246. pool1 = fluid.layers.pool2d(
  247. input=data,
  248. pool_size=3,
  249. pool_padding=1,
  250. pool_type='avg',
  251. name='inceptionA_' + idx + '_pool1')
  252. conv1 = self._conv_norm(
  253. input=pool1,
  254. filter_size=1,
  255. num_filters=32,
  256. stride=1,
  257. padding=0,
  258. act='relu',
  259. name='inceptionA_' + idx + '_conv1')
  260. conv2 = self._conv_norm(
  261. input=data,
  262. filter_size=1,
  263. num_filters=32,
  264. stride=1,
  265. padding=0,
  266. act='relu',
  267. name='inceptionA_' + idx + '_conv2')
  268. conv3 = self._conv_norm(
  269. input=data,
  270. filter_size=1,
  271. num_filters=24,
  272. stride=1,
  273. padding=0,
  274. act='relu',
  275. name='inceptionA_' + idx + '_conv3_1')
  276. conv3 = self._conv_norm(
  277. input=conv3,
  278. filter_size=3,
  279. num_filters=32,
  280. stride=1,
  281. padding=1,
  282. act='relu',
  283. name='inceptionA_' + idx + '_conv3_2')
  284. conv4 = self._conv_norm(
  285. input=data,
  286. filter_size=1,
  287. num_filters=24,
  288. stride=1,
  289. padding=0,
  290. act='relu',
  291. name='inceptionA_' + idx + '_conv4_1')
  292. conv4 = self._conv_norm(
  293. input=conv4,
  294. filter_size=3,
  295. num_filters=32,
  296. stride=1,
  297. padding=1,
  298. act='relu',
  299. name='inceptionA_' + idx + '_conv4_2')
  300. conv4 = self._conv_norm(
  301. input=conv4,
  302. filter_size=3,
  303. num_filters=32,
  304. stride=1,
  305. padding=1,
  306. act='relu',
  307. name='inceptionA_' + idx + '_conv4_3')
  308. concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
  309. return concat