vqa_layoutlm.py 7.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# copyright (c) 2021 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.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
from paddle import nn

from paddlenlp.transformers import LayoutXLMModel, LayoutXLMForTokenClassification, LayoutXLMForRelationExtraction
from paddlenlp.transformers import LayoutLMModel, LayoutLMForTokenClassification
文幕地方's avatar
文幕地方 已提交
24
from paddlenlp.transformers import LayoutLMv2Model, LayoutLMv2ForTokenClassification, LayoutLMv2ForRelationExtraction
littletomatodonkey's avatar
littletomatodonkey 已提交
25
from paddlenlp.transformers import AutoModel
26

littletomatodonkey's avatar
littletomatodonkey 已提交
27
__all__ = ["LayoutXLMForSer", "LayoutLMForSer"]
28

文幕地方's avatar
文幕地方 已提交
29
pretrained_model_dict = {
littletomatodonkey's avatar
littletomatodonkey 已提交
30 31 32 33 34 35 36 37 38 39 40
    LayoutXLMModel: {
        "base": "layoutxlm-base-uncased",
        "vi": "layoutxlm-wo-backbone-base-uncased",
    },
    LayoutLMModel: {
        "base": "layoutlm-base-uncased",
    },
    LayoutLMv2Model: {
        "base": "layoutlmv2-base-uncased",
        "vi": "layoutlmv2-wo-backbone-base-uncased",
    },
文幕地方's avatar
文幕地方 已提交
41 42
}

43 44 45 46 47

class NLPBaseModel(nn.Layer):
    def __init__(self,
                 base_model_class,
                 model_class,
littletomatodonkey's avatar
littletomatodonkey 已提交
48 49
                 mode="base",
                 type="ser",
文幕地方's avatar
文幕地方 已提交
50
                 pretrained=True,
51 52 53
                 checkpoints=None,
                 **kwargs):
        super(NLPBaseModel, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
54
        if checkpoints is not None:  # load the trained model
55
            self.model = model_class.from_pretrained(checkpoints)
littletomatodonkey's avatar
littletomatodonkey 已提交
56 57 58
        else:  # load the pretrained-model
            pretrained_model_name = pretrained_model_dict[base_model_class][
                mode]
59
            if pretrained is True:
文幕地方's avatar
文幕地方 已提交
60 61 62
                base_model = base_model_class.from_pretrained(
                    pretrained_model_name)
            else:
littletomatodonkey's avatar
littletomatodonkey 已提交
63 64
                base_model = base_model_class.from_pretrained(pretrained)
            if type == "ser":
65
                self.model = model_class(
littletomatodonkey's avatar
littletomatodonkey 已提交
66
                    base_model, num_classes=kwargs["num_classes"], dropout=None)
67 68 69
            else:
                self.model = model_class(base_model, dropout=None)
        self.out_channels = 1
littletomatodonkey's avatar
littletomatodonkey 已提交
70
        self.use_visual_backbone = True
71 72


文幕地方's avatar
文幕地方 已提交
73
class LayoutLMForSer(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
74 75 76 77 78
    def __init__(self,
                 num_classes,
                 pretrained=True,
                 checkpoints=None,
                 mode="base",
79
                 **kwargs):
文幕地方's avatar
文幕地方 已提交
80 81 82
        super(LayoutLMForSer, self).__init__(
            LayoutLMModel,
            LayoutLMForTokenClassification,
littletomatodonkey's avatar
littletomatodonkey 已提交
83 84
            mode,
            "ser",
文幕地方's avatar
文幕地方 已提交
85 86
            pretrained,
            checkpoints,
littletomatodonkey's avatar
littletomatodonkey 已提交
87 88
            num_classes=num_classes, )
        self.use_visual_backbone = False
文幕地方's avatar
文幕地方 已提交
89 90 91 92

    def forward(self, x):
        x = self.model(
            input_ids=x[0],
93 94 95
            bbox=x[1],
            attention_mask=x[2],
            token_type_ids=x[3],
文幕地方's avatar
文幕地方 已提交
96 97 98 99 100 101
            position_ids=None,
            output_hidden_states=False)
        return x


class LayoutLMv2ForSer(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
102 103 104 105 106
    def __init__(self,
                 num_classes,
                 pretrained=True,
                 checkpoints=None,
                 mode="base",
文幕地方's avatar
文幕地方 已提交
107 108 109 110
                 **kwargs):
        super(LayoutLMv2ForSer, self).__init__(
            LayoutLMv2Model,
            LayoutLMv2ForTokenClassification,
littletomatodonkey's avatar
littletomatodonkey 已提交
111 112
            mode,
            "ser",
文幕地方's avatar
文幕地方 已提交
113
            pretrained,
114 115
            checkpoints,
            num_classes=num_classes)
littletomatodonkey's avatar
littletomatodonkey 已提交
116 117 118 119
        self.use_visual_backbone = True
        if hasattr(self.model.layoutlmv2, "use_visual_backbone"
                   ) and self.model.layoutlmv2.use_visual_backbone is False:
            self.use_visual_backbone = False
120 121

    def forward(self, x):
littletomatodonkey's avatar
littletomatodonkey 已提交
122 123 124 125
        if self.use_visual_backbone is True:
            image = x[4]
        else:
            image = None
126 127
        x = self.model(
            input_ids=x[0],
128 129 130
            bbox=x[1],
            attention_mask=x[2],
            token_type_ids=x[3],
littletomatodonkey's avatar
littletomatodonkey 已提交
131
            image=image,
132 133 134
            position_ids=None,
            head_mask=None,
            labels=None)
littletomatodonkey's avatar
littletomatodonkey 已提交
135 136 137 138 139
        if self.training:
            res = {"backbone_out": x[0]}
            res.update(x[1])
            return res
        else:
140
            return x
141 142


文幕地方's avatar
文幕地方 已提交
143
class LayoutXLMForSer(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
144 145 146 147 148
    def __init__(self,
                 num_classes,
                 pretrained=True,
                 checkpoints=None,
                 mode="base",
149
                 **kwargs):
文幕地方's avatar
文幕地方 已提交
150 151 152
        super(LayoutXLMForSer, self).__init__(
            LayoutXLMModel,
            LayoutXLMForTokenClassification,
littletomatodonkey's avatar
littletomatodonkey 已提交
153 154
            mode,
            "ser",
文幕地方's avatar
文幕地方 已提交
155
            pretrained,
156 157
            checkpoints,
            num_classes=num_classes)
littletomatodonkey's avatar
littletomatodonkey 已提交
158
        self.use_visual_backbone = True
159 160

    def forward(self, x):
littletomatodonkey's avatar
littletomatodonkey 已提交
161 162 163 164
        if self.use_visual_backbone is True:
            image = x[4]
        else:
            image = None
165
        x = self.model(
文幕地方's avatar
文幕地方 已提交
166 167 168 169
            input_ids=x[0],
            bbox=x[1],
            attention_mask=x[2],
            token_type_ids=x[3],
littletomatodonkey's avatar
littletomatodonkey 已提交
170
            image=image,
文幕地方's avatar
文幕地方 已提交
171 172 173
            position_ids=None,
            head_mask=None,
            labels=None)
littletomatodonkey's avatar
littletomatodonkey 已提交
174 175 176 177 178
        if self.training:
            res = {"backbone_out": x[0]}
            res.update(x[1])
            return res
        else:
179
            return x
文幕地方's avatar
文幕地方 已提交
180 181 182


class LayoutLMv2ForRe(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
183 184 185 186 187
    def __init__(self, pretrained=True, checkpoints=None, mode="base",
                 **kwargs):
        super(LayoutLMv2ForRe, self).__init__(
            LayoutLMv2Model, LayoutLMv2ForRelationExtraction, mode, "re",
            pretrained, checkpoints)
文幕地方's avatar
文幕地方 已提交
188 189 190 191 192

    def forward(self, x):
        x = self.model(
            input_ids=x[0],
            bbox=x[1],
193 194 195
            attention_mask=x[2],
            token_type_ids=x[3],
            image=x[4],
文幕地方's avatar
文幕地方 已提交
196 197
            position_ids=None,
            head_mask=None,
198
            labels=None,
文幕地方's avatar
文幕地方 已提交
199 200
            entities=x[5],
            relations=x[6])
201 202 203 204
        return x


class LayoutXLMForRe(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
205 206 207 208 209 210 211 212 213
    def __init__(self, pretrained=True, checkpoints=None, mode="base",
                 **kwargs):
        super(LayoutXLMForRe, self).__init__(
            LayoutXLMModel, LayoutXLMForRelationExtraction, mode, "re",
            pretrained, checkpoints)
        self.use_visual_backbone = True
        if hasattr(self.model.layoutxlm, "use_visual_backbone"
                   ) and self.model.layoutxlm.use_visual_backbone is False:
            self.use_visual_backbone = False
214 215

    def forward(self, x):
littletomatodonkey's avatar
littletomatodonkey 已提交
216 217 218 219
        if self.use_visual_backbone is True:
            image = x[4]
        else:
            image = None
220 221 222
        x = self.model(
            input_ids=x[0],
            bbox=x[1],
223 224
            attention_mask=x[2],
            token_type_ids=x[3],
littletomatodonkey's avatar
littletomatodonkey 已提交
225
            image=image,
226 227
            position_ids=None,
            head_mask=None,
228
            labels=None,
229 230 231
            entities=x[5],
            relations=x[6])
        return x