diff --git a/ppocr/modeling/heads/det_db_head.py b/ppocr/modeling/heads/det_db_head.py index f76cb34d3..997d68e0f 100644 --- a/ppocr/modeling/heads/det_db_head.py +++ b/ppocr/modeling/heads/det_db_head.py @@ -31,13 +31,14 @@ def get_bias_attr(k): class Head(nn.Layer): - def __init__(self, in_channels, name_list): + def __init__(self, in_channels, name_list, kernel_list=[3, 2, 2]): super(Head, self).__init__() + self.conv1 = nn.Conv2D( in_channels=in_channels, out_channels=in_channels // 4, - kernel_size=3, - padding=1, + kernel_size=kernel_size[0], + padding=int(kernel_size[0] // 2), weight_attr=ParamAttr(), bias_attr=False) self.conv_bn1 = nn.BatchNorm( @@ -50,7 +51,7 @@ class Head(nn.Layer): self.conv2 = nn.Conv2DTranspose( in_channels=in_channels // 4, out_channels=in_channels // 4, - kernel_size=2, + kernel_size=kernel_size[1], stride=2, weight_attr=ParamAttr( initializer=paddle.nn.initializer.KaimingUniform()), @@ -65,7 +66,7 @@ class Head(nn.Layer): self.conv3 = nn.Conv2DTranspose( in_channels=in_channels // 4, out_channels=1, - kernel_size=2, + kernel_size=kernel_size[1], stride=2, weight_attr=ParamAttr( initializer=paddle.nn.initializer.KaimingUniform()), diff --git a/ppocr/modeling/necks/db_fpn.py b/ppocr/modeling/necks/db_fpn.py index 4f305df8a..ed58cfcd7 100644 --- a/ppocr/modeling/necks/db_fpn.py +++ b/ppocr/modeling/necks/db_fpn.py @@ -20,7 +20,7 @@ import paddle from paddle import nn import paddle.nn.functional as F from paddle import ParamAttr -from ppocr.backbones.det_mobilenet_v3 import SEModule +from ppocr.backbones.det_mobilenet_v3 import SEModule, ConvBNLayer class DBFPN(nn.Layer): @@ -179,3 +179,85 @@ class CAFPN(nn.Layer): fuse = paddle.concat([p5, p4, p3, p2], axis=1) return fuse + + +class FEPAN(nn.Layer): + def __init__(self, in_channels, out_channels, **kwargs): + super(FEPAN, self).__init__() + self.out_channels = out_channels + weight_attr = paddle.nn.initializer.KaimingUniform() + + self.ins_convs = [] + self.inp_convs = [] + # pan head + self.pan_head_conv = [] + self.pan_lat_conv = [] + + for i in range(len(in_channels)): + self.ins_conv.append( + nn.Conv2D( + in_channels=in_channels[0], + out_channels=self.out_channels, + kernel_size=1, + weight_attr=ParamAttr(initializer=weight_attr), + bias_attr=False)) + + self.inp_conv.append( + ConvBNLayer( + in_channels=self.out_channels, + out_channels=self.out_channels // 4, + kernel_size=9, + padding=4)) + + if i > 0: + self.pan_head_conv.append( + nn.Conv2D( + in_channels=self.out_channels // 4, + out_channels=self.out_channels // 4, + kernel_size=3, + padding=1, + stride=2, + weight_attr=ParamAttr(initializer=weight_attr), + bias_attr=False)) + self.pan_lat_conv.append( + ConvBNLayer( + in_channels=self.out_channels // 4, + out_channels=self.out_channels // 4, + kernel_size=9, + padding=4)) + + def forward(self, x): + c2, c3, c4, c5 = x + + in5 = self.ins_conv[3](c5) + in4 = self.ins_conv[2](c4) + in3 = self.ins_conv[1](c3) + in2 = self.ins_conv[0](c2) + + out4 = in4 + F.upsample( + in5, scale_factor=2, mode="nearest", align_mode=1) # 1/16 + out3 = in3 + F.upsample( + out4, scale_factor=2, mode="nearest", align_mode=1) # 1/8 + out2 = in2 + F.upsample( + out3, scale_factor=2, mode="nearest", align_mode=1) # 1/4 + + f5 = self.inp_conv[3](in5) + f4 = self.inp_conv[2](out4) + f3 = self.inp_conv[1](out3) + f2 = self.inp_conv[0](out2) + + pan3 = f3 + self.pan_head[0](f2) + pan4 = f4 + self.pan_head[1](pan3) + pan5 = f5 + self.pan_head[2](pan4) + + p2 = self.pan_lat[0](f2) + p3 = self.pan_lat[1](pan3) + p4 = self.pan_lat[2](pan4) + p5 = self.pan_lat[3](pan5) + + p5 = F.upsample(p5, scale_factor=8, mode="nearest", align_mode=1) + p4 = F.upsample(p4, scale_factor=4, mode="nearest", align_mode=1) + p3 = F.upsample(p3, scale_factor=2, mode="nearest", align_mode=1) + + fuse = paddle.concat([p5, p4, p3, p2], axis=1) + return fuse