This commit is contained in:
106
ppocr/modeling/heads/rec_rfl_head.py
Normal file
106
ppocr/modeling/heads/rec_rfl_head.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# copyright (c) 2022 PaddlePaddle Authors. All Rights Reserve.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""
|
||||
This code is refer from:
|
||||
https://github.com/hikopensource/DAVAR-Lab-OCR/blob/main/davarocr/davar_rcg/models/sequence_heads/counting_head.py
|
||||
"""
|
||||
import paddle
|
||||
import paddle.nn as nn
|
||||
from paddle.nn.initializer import TruncatedNormal, Constant, Normal, KaimingNormal
|
||||
|
||||
from .rec_att_head import AttentionLSTM
|
||||
|
||||
kaiming_init_ = KaimingNormal()
|
||||
zeros_ = Constant(value=0.0)
|
||||
ones_ = Constant(value=1.0)
|
||||
|
||||
|
||||
class CNTHead(nn.Layer):
|
||||
def __init__(self, embed_size=512, encode_length=26, out_channels=38, **kwargs):
|
||||
super(CNTHead, self).__init__()
|
||||
|
||||
self.out_channels = out_channels
|
||||
|
||||
self.Wv_fusion = nn.Linear(embed_size, embed_size, bias_attr=False)
|
||||
self.Prediction_visual = nn.Linear(
|
||||
encode_length * embed_size, self.out_channels
|
||||
)
|
||||
|
||||
def forward(self, visual_feature):
|
||||
b, c, h, w = visual_feature.shape
|
||||
visual_feature = visual_feature.reshape([b, c, h * w]).transpose([0, 2, 1])
|
||||
visual_feature_num = self.Wv_fusion(visual_feature) # batch * 26 * 512
|
||||
b, n, c = visual_feature_num.shape
|
||||
# using visual feature directly calculate the text length
|
||||
visual_feature_num = visual_feature_num.reshape([b, n * c])
|
||||
prediction_visual = self.Prediction_visual(visual_feature_num)
|
||||
|
||||
return prediction_visual
|
||||
|
||||
|
||||
class RFLHead(nn.Layer):
|
||||
def __init__(
|
||||
self,
|
||||
in_channels=512,
|
||||
hidden_size=256,
|
||||
batch_max_legnth=25,
|
||||
out_channels=38,
|
||||
use_cnt=True,
|
||||
use_seq=True,
|
||||
**kwargs,
|
||||
):
|
||||
super(RFLHead, self).__init__()
|
||||
assert use_cnt or use_seq
|
||||
self.use_cnt = use_cnt
|
||||
self.use_seq = use_seq
|
||||
if self.use_cnt:
|
||||
self.cnt_head = CNTHead(
|
||||
embed_size=in_channels,
|
||||
encode_length=batch_max_legnth + 1,
|
||||
out_channels=out_channels,
|
||||
**kwargs,
|
||||
)
|
||||
if self.use_seq:
|
||||
self.seq_head = AttentionLSTM(
|
||||
in_channels=in_channels,
|
||||
out_channels=out_channels,
|
||||
hidden_size=hidden_size,
|
||||
**kwargs,
|
||||
)
|
||||
self.batch_max_legnth = batch_max_legnth
|
||||
self.num_class = out_channels
|
||||
self.apply(self.init_weights)
|
||||
|
||||
def init_weights(self, m):
|
||||
if isinstance(m, nn.Linear):
|
||||
kaiming_init_(m.weight)
|
||||
if isinstance(m, nn.Linear) and m.bias is not None:
|
||||
zeros_(m.bias)
|
||||
|
||||
def forward(self, x, targets=None):
|
||||
cnt_inputs, seq_inputs = x
|
||||
if self.use_cnt:
|
||||
cnt_outputs = self.cnt_head(cnt_inputs)
|
||||
else:
|
||||
cnt_outputs = None
|
||||
if self.use_seq:
|
||||
if self.training:
|
||||
seq_outputs = self.seq_head(
|
||||
seq_inputs, targets[0], self.batch_max_legnth
|
||||
)
|
||||
else:
|
||||
seq_outputs = self.seq_head(seq_inputs, None, self.batch_max_legnth)
|
||||
return cnt_outputs, seq_outputs
|
||||
else:
|
||||
return cnt_outputs
|
||||
Reference in New Issue
Block a user