u2net.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. # Copyright (c) 2020 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. import paddle
  15. import paddle.nn as nn
  16. import paddle.nn.functional as F
  17. from paddlex.paddleseg.cvlibs import manager
  18. from paddlex.paddleseg.models import layers
  19. from paddlex.paddleseg.utils import utils
  20. __all__ = ['U2Net', 'U2Netp']
  21. @manager.MODELS.add_component
  22. class U2Net(nn.Layer):
  23. """
  24. The U^2-Net implementation based on PaddlePaddle.
  25. The original article refers to
  26. Xuebin Qin, et, al. "U^2-Net: Going Deeper with Nested U-Structure for Salient Object Detection"
  27. (https://arxiv.org/abs/2005.09007).
  28. Args:
  29. num_classes (int): The unique number of target classes.
  30. in_ch (int, optional): Input channels. Default: 3.
  31. pretrained (str, optional): The path or url of pretrained model for fine tuning. Default: None.
  32. """
  33. def __init__(self, num_classes, in_ch=3, pretrained=None):
  34. super(U2Net, self).__init__()
  35. self.stage1 = RSU7(in_ch, 32, 64)
  36. self.pool12 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  37. self.stage2 = RSU6(64, 32, 128)
  38. self.pool23 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  39. self.stage3 = RSU5(128, 64, 256)
  40. self.pool34 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  41. self.stage4 = RSU4(256, 128, 512)
  42. self.pool45 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  43. self.stage5 = RSU4F(512, 256, 512)
  44. self.pool56 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  45. self.stage6 = RSU4F(512, 256, 512)
  46. # decoder
  47. self.stage5d = RSU4F(1024, 256, 512)
  48. self.stage4d = RSU4(1024, 128, 256)
  49. self.stage3d = RSU5(512, 64, 128)
  50. self.stage2d = RSU6(256, 32, 64)
  51. self.stage1d = RSU7(128, 16, 64)
  52. self.side1 = nn.Conv2D(64, num_classes, 3, padding=1)
  53. self.side2 = nn.Conv2D(64, num_classes, 3, padding=1)
  54. self.side3 = nn.Conv2D(128, num_classes, 3, padding=1)
  55. self.side4 = nn.Conv2D(256, num_classes, 3, padding=1)
  56. self.side5 = nn.Conv2D(512, num_classes, 3, padding=1)
  57. self.side6 = nn.Conv2D(512, num_classes, 3, padding=1)
  58. self.outconv = nn.Conv2D(6 * num_classes, num_classes, 1)
  59. self.pretrained = pretrained
  60. self.init_weight()
  61. def forward(self, x):
  62. hx = x
  63. #stage 1
  64. hx1 = self.stage1(hx)
  65. hx = self.pool12(hx1)
  66. #stage 2
  67. hx2 = self.stage2(hx)
  68. hx = self.pool23(hx2)
  69. #stage 3
  70. hx3 = self.stage3(hx)
  71. hx = self.pool34(hx3)
  72. #stage 4
  73. hx4 = self.stage4(hx)
  74. hx = self.pool45(hx4)
  75. #stage 5
  76. hx5 = self.stage5(hx)
  77. hx = self.pool56(hx5)
  78. #stage 6
  79. hx6 = self.stage6(hx)
  80. hx6up = _upsample_like(hx6, hx5)
  81. #-------------------- decoder --------------------
  82. hx5d = self.stage5d(paddle.concat((hx6up, hx5), 1))
  83. hx5dup = _upsample_like(hx5d, hx4)
  84. hx4d = self.stage4d(paddle.concat((hx5dup, hx4), 1))
  85. hx4dup = _upsample_like(hx4d, hx3)
  86. hx3d = self.stage3d(paddle.concat((hx4dup, hx3), 1))
  87. hx3dup = _upsample_like(hx3d, hx2)
  88. hx2d = self.stage2d(paddle.concat((hx3dup, hx2), 1))
  89. hx2dup = _upsample_like(hx2d, hx1)
  90. hx1d = self.stage1d(paddle.concat((hx2dup, hx1), 1))
  91. #side output
  92. d1 = self.side1(hx1d)
  93. d2 = self.side2(hx2d)
  94. d2 = _upsample_like(d2, d1)
  95. d3 = self.side3(hx3d)
  96. d3 = _upsample_like(d3, d1)
  97. d4 = self.side4(hx4d)
  98. d4 = _upsample_like(d4, d1)
  99. d5 = self.side5(hx5d)
  100. d5 = _upsample_like(d5, d1)
  101. d6 = self.side6(hx6)
  102. d6 = _upsample_like(d6, d1)
  103. d0 = self.outconv(paddle.concat((d1, d2, d3, d4, d5, d6), 1))
  104. return [d0, d1, d2, d3, d4, d5, d6]
  105. def init_weight(self):
  106. if self.pretrained is not None:
  107. utils.load_entire_model(self, self.pretrained)
  108. ### U^2-Net small ###
  109. @manager.MODELS.add_component
  110. class U2Netp(nn.Layer):
  111. """Please Refer to U2Net above."""
  112. def __init__(self, num_classes, in_ch=3, pretrained=None):
  113. super(U2Netp, self).__init__()
  114. self.stage1 = RSU7(in_ch, 16, 64)
  115. self.pool12 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  116. self.stage2 = RSU6(64, 16, 64)
  117. self.pool23 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  118. self.stage3 = RSU5(64, 16, 64)
  119. self.pool34 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  120. self.stage4 = RSU4(64, 16, 64)
  121. self.pool45 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  122. self.stage5 = RSU4F(64, 16, 64)
  123. self.pool56 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  124. self.stage6 = RSU4F(64, 16, 64)
  125. # decoder
  126. self.stage5d = RSU4F(128, 16, 64)
  127. self.stage4d = RSU4(128, 16, 64)
  128. self.stage3d = RSU5(128, 16, 64)
  129. self.stage2d = RSU6(128, 16, 64)
  130. self.stage1d = RSU7(128, 16, 64)
  131. self.side1 = nn.Conv2D(64, num_classes, 3, padding=1)
  132. self.side2 = nn.Conv2D(64, num_classes, 3, padding=1)
  133. self.side3 = nn.Conv2D(64, num_classes, 3, padding=1)
  134. self.side4 = nn.Conv2D(64, num_classes, 3, padding=1)
  135. self.side5 = nn.Conv2D(64, num_classes, 3, padding=1)
  136. self.side6 = nn.Conv2D(64, num_classes, 3, padding=1)
  137. self.outconv = nn.Conv2D(6 * num_classes, num_classes, 1)
  138. self.pretrained = pretrained
  139. self.init_weight()
  140. def forward(self, x):
  141. hx = x
  142. #stage 1
  143. hx1 = self.stage1(hx)
  144. hx = self.pool12(hx1)
  145. #stage 2
  146. hx2 = self.stage2(hx)
  147. hx = self.pool23(hx2)
  148. #stage 3
  149. hx3 = self.stage3(hx)
  150. hx = self.pool34(hx3)
  151. #stage 4
  152. hx4 = self.stage4(hx)
  153. hx = self.pool45(hx4)
  154. #stage 5
  155. hx5 = self.stage5(hx)
  156. hx = self.pool56(hx5)
  157. #stage 6
  158. hx6 = self.stage6(hx)
  159. hx6up = _upsample_like(hx6, hx5)
  160. #decoder
  161. hx5d = self.stage5d(paddle.concat((hx6up, hx5), 1))
  162. hx5dup = _upsample_like(hx5d, hx4)
  163. hx4d = self.stage4d(paddle.concat((hx5dup, hx4), 1))
  164. hx4dup = _upsample_like(hx4d, hx3)
  165. hx3d = self.stage3d(paddle.concat((hx4dup, hx3), 1))
  166. hx3dup = _upsample_like(hx3d, hx2)
  167. hx2d = self.stage2d(paddle.concat((hx3dup, hx2), 1))
  168. hx2dup = _upsample_like(hx2d, hx1)
  169. hx1d = self.stage1d(paddle.concat((hx2dup, hx1), 1))
  170. #side output
  171. d1 = self.side1(hx1d)
  172. d2 = self.side2(hx2d)
  173. d2 = _upsample_like(d2, d1)
  174. d3 = self.side3(hx3d)
  175. d3 = _upsample_like(d3, d1)
  176. d4 = self.side4(hx4d)
  177. d4 = _upsample_like(d4, d1)
  178. d5 = self.side5(hx5d)
  179. d5 = _upsample_like(d5, d1)
  180. d6 = self.side6(hx6)
  181. d6 = _upsample_like(d6, d1)
  182. d0 = self.outconv(paddle.concat((d1, d2, d3, d4, d5, d6), 1))
  183. return [d0, d1, d2, d3, d4, d5, d6]
  184. def init_weight(self):
  185. if self.pretrained is not None:
  186. utils.load_entire_model(self, self.pretrained)
  187. class REBNCONV(nn.Layer):
  188. def __init__(self, in_ch=3, out_ch=3, dirate=1):
  189. super(REBNCONV, self).__init__()
  190. self.conv_s1 = nn.Conv2D(
  191. in_ch, out_ch, 3, padding=1 * dirate, dilation=1 * dirate)
  192. self.bn_s1 = nn.BatchNorm2D(out_ch)
  193. self.relu_s1 = nn.ReLU()
  194. def forward(self, x):
  195. hx = x
  196. xout = self.relu_s1(self.bn_s1(self.conv_s1(hx)))
  197. return xout
  198. ## upsample tensor 'src' to have the same spatial size with tensor 'tar'
  199. def _upsample_like(src, tar):
  200. src = F.upsample(src, size=paddle.shape(tar)[2:], mode='bilinear')
  201. return src
  202. ### RSU-7 ###
  203. class RSU7(nn.Layer): #UNet07DRES(nn.Layer):
  204. def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
  205. super(RSU7, self).__init__()
  206. self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)
  207. self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
  208. self.pool1 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  209. self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=1)
  210. self.pool2 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  211. self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=1)
  212. self.pool3 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  213. self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=1)
  214. self.pool4 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  215. self.rebnconv5 = REBNCONV(mid_ch, mid_ch, dirate=1)
  216. self.pool5 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  217. self.rebnconv6 = REBNCONV(mid_ch, mid_ch, dirate=1)
  218. self.rebnconv7 = REBNCONV(mid_ch, mid_ch, dirate=2)
  219. self.rebnconv6d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  220. self.rebnconv5d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  221. self.rebnconv4d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  222. self.rebnconv3d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  223. self.rebnconv2d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  224. self.rebnconv1d = REBNCONV(mid_ch * 2, out_ch, dirate=1)
  225. def forward(self, x):
  226. hx = x
  227. hxin = self.rebnconvin(hx)
  228. hx1 = self.rebnconv1(hxin)
  229. hx = self.pool1(hx1)
  230. hx2 = self.rebnconv2(hx)
  231. hx = self.pool2(hx2)
  232. hx3 = self.rebnconv3(hx)
  233. hx = self.pool3(hx3)
  234. hx4 = self.rebnconv4(hx)
  235. hx = self.pool4(hx4)
  236. hx5 = self.rebnconv5(hx)
  237. hx = self.pool5(hx5)
  238. hx6 = self.rebnconv6(hx)
  239. hx7 = self.rebnconv7(hx6)
  240. hx6d = self.rebnconv6d(paddle.concat((hx7, hx6), 1))
  241. hx6dup = _upsample_like(hx6d, hx5)
  242. hx5d = self.rebnconv5d(paddle.concat((hx6dup, hx5), 1))
  243. hx5dup = _upsample_like(hx5d, hx4)
  244. hx4d = self.rebnconv4d(paddle.concat((hx5dup, hx4), 1))
  245. hx4dup = _upsample_like(hx4d, hx3)
  246. hx3d = self.rebnconv3d(paddle.concat((hx4dup, hx3), 1))
  247. hx3dup = _upsample_like(hx3d, hx2)
  248. hx2d = self.rebnconv2d(paddle.concat((hx3dup, hx2), 1))
  249. hx2dup = _upsample_like(hx2d, hx1)
  250. hx1d = self.rebnconv1d(paddle.concat((hx2dup, hx1), 1))
  251. return hx1d + hxin
  252. ### RSU-6 ###
  253. class RSU6(nn.Layer): #UNet06DRES(nn.Layer):
  254. def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
  255. super(RSU6, self).__init__()
  256. self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)
  257. self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
  258. self.pool1 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  259. self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=1)
  260. self.pool2 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  261. self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=1)
  262. self.pool3 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  263. self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=1)
  264. self.pool4 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  265. self.rebnconv5 = REBNCONV(mid_ch, mid_ch, dirate=1)
  266. self.rebnconv6 = REBNCONV(mid_ch, mid_ch, dirate=2)
  267. self.rebnconv5d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  268. self.rebnconv4d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  269. self.rebnconv3d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  270. self.rebnconv2d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  271. self.rebnconv1d = REBNCONV(mid_ch * 2, out_ch, dirate=1)
  272. def forward(self, x):
  273. hx = x
  274. hxin = self.rebnconvin(hx)
  275. hx1 = self.rebnconv1(hxin)
  276. hx = self.pool1(hx1)
  277. hx2 = self.rebnconv2(hx)
  278. hx = self.pool2(hx2)
  279. hx3 = self.rebnconv3(hx)
  280. hx = self.pool3(hx3)
  281. hx4 = self.rebnconv4(hx)
  282. hx = self.pool4(hx4)
  283. hx5 = self.rebnconv5(hx)
  284. hx6 = self.rebnconv6(hx5)
  285. hx5d = self.rebnconv5d(paddle.concat((hx6, hx5), 1))
  286. hx5dup = _upsample_like(hx5d, hx4)
  287. hx4d = self.rebnconv4d(paddle.concat((hx5dup, hx4), 1))
  288. hx4dup = _upsample_like(hx4d, hx3)
  289. hx3d = self.rebnconv3d(paddle.concat((hx4dup, hx3), 1))
  290. hx3dup = _upsample_like(hx3d, hx2)
  291. hx2d = self.rebnconv2d(paddle.concat((hx3dup, hx2), 1))
  292. hx2dup = _upsample_like(hx2d, hx1)
  293. hx1d = self.rebnconv1d(paddle.concat((hx2dup, hx1), 1))
  294. return hx1d + hxin
  295. ### RSU-5 ###
  296. class RSU5(nn.Layer): #UNet05DRES(nn.Layer):
  297. def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
  298. super(RSU5, self).__init__()
  299. self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)
  300. self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
  301. self.pool1 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  302. self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=1)
  303. self.pool2 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  304. self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=1)
  305. self.pool3 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  306. self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=1)
  307. self.rebnconv5 = REBNCONV(mid_ch, mid_ch, dirate=2)
  308. self.rebnconv4d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  309. self.rebnconv3d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  310. self.rebnconv2d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  311. self.rebnconv1d = REBNCONV(mid_ch * 2, out_ch, dirate=1)
  312. def forward(self, x):
  313. hx = x
  314. hxin = self.rebnconvin(hx)
  315. hx1 = self.rebnconv1(hxin)
  316. hx = self.pool1(hx1)
  317. hx2 = self.rebnconv2(hx)
  318. hx = self.pool2(hx2)
  319. hx3 = self.rebnconv3(hx)
  320. hx = self.pool3(hx3)
  321. hx4 = self.rebnconv4(hx)
  322. hx5 = self.rebnconv5(hx4)
  323. hx4d = self.rebnconv4d(paddle.concat((hx5, hx4), 1))
  324. hx4dup = _upsample_like(hx4d, hx3)
  325. hx3d = self.rebnconv3d(paddle.concat((hx4dup, hx3), 1))
  326. hx3dup = _upsample_like(hx3d, hx2)
  327. hx2d = self.rebnconv2d(paddle.concat((hx3dup, hx2), 1))
  328. hx2dup = _upsample_like(hx2d, hx1)
  329. hx1d = self.rebnconv1d(paddle.concat((hx2dup, hx1), 1))
  330. return hx1d + hxin
  331. ### RSU-4 ###
  332. class RSU4(nn.Layer): #UNet04DRES(nn.Layer):
  333. def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
  334. super(RSU4, self).__init__()
  335. self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)
  336. self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
  337. self.pool1 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  338. self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=1)
  339. self.pool2 = nn.MaxPool2D(2, stride=2, ceil_mode=True)
  340. self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=1)
  341. self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=2)
  342. self.rebnconv3d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  343. self.rebnconv2d = REBNCONV(mid_ch * 2, mid_ch, dirate=1)
  344. self.rebnconv1d = REBNCONV(mid_ch * 2, out_ch, dirate=1)
  345. def forward(self, x):
  346. hx = x
  347. hxin = self.rebnconvin(hx)
  348. hx1 = self.rebnconv1(hxin)
  349. hx = self.pool1(hx1)
  350. hx2 = self.rebnconv2(hx)
  351. hx = self.pool2(hx2)
  352. hx3 = self.rebnconv3(hx)
  353. hx4 = self.rebnconv4(hx3)
  354. hx3d = self.rebnconv3d(paddle.concat((hx4, hx3), 1))
  355. hx3dup = _upsample_like(hx3d, hx2)
  356. hx2d = self.rebnconv2d(paddle.concat((hx3dup, hx2), 1))
  357. hx2dup = _upsample_like(hx2d, hx1)
  358. hx1d = self.rebnconv1d(paddle.concat((hx2dup, hx1), 1))
  359. return hx1d + hxin
  360. ### RSU-4F ###
  361. class RSU4F(nn.Layer): #UNet04FRES(nn.Layer):
  362. def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
  363. super(RSU4F, self).__init__()
  364. self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)
  365. self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
  366. self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=2)
  367. self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=4)
  368. self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=8)
  369. self.rebnconv3d = REBNCONV(mid_ch * 2, mid_ch, dirate=4)
  370. self.rebnconv2d = REBNCONV(mid_ch * 2, mid_ch, dirate=2)
  371. self.rebnconv1d = REBNCONV(mid_ch * 2, out_ch, dirate=1)
  372. def forward(self, x):
  373. hx = x
  374. hxin = self.rebnconvin(hx)
  375. hx1 = self.rebnconv1(hxin)
  376. hx2 = self.rebnconv2(hx1)
  377. hx3 = self.rebnconv3(hx2)
  378. hx4 = self.rebnconv4(hx3)
  379. hx3d = self.rebnconv3d(paddle.concat((hx4, hx3), 1))
  380. hx2d = self.rebnconv2d(paddle.concat((hx3d, hx2), 1))
  381. hx1d = self.rebnconv1d(paddle.concat((hx2d, hx1), 1))
  382. return hx1d + hxin