vqa_layoutlm.py 7.5 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
    LayoutXLMModel: {
        "base": "layoutxlm-base-uncased",
littletomatodonkey's avatar
littletomatodonkey 已提交
32
        "vi": "vi-layoutxlm-base-uncased",
littletomatodonkey's avatar
littletomatodonkey 已提交
33 34 35 36 37 38
    },
    LayoutLMModel: {
        "base": "layoutlm-base-uncased",
    },
    LayoutLMv2Model: {
        "base": "layoutlmv2-base-uncased",
littletomatodonkey's avatar
littletomatodonkey 已提交
39
        "vi": "vi-layoutlmv2-base-uncased",
littletomatodonkey's avatar
littletomatodonkey 已提交
40
    },
文幕地方'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
        if hasattr(self.model.layoutlmv2, "use_visual_backbone"
                   ) and self.model.layoutlmv2.use_visual_backbone is False:
            self.use_visual_backbone = False
119 120

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


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

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


class LayoutLMv2ForRe(NLPBaseModel):
littletomatodonkey's avatar
littletomatodonkey 已提交
184 185 186 187 188
    def __init__(self, pretrained=True, checkpoints=None, mode="base",
                 **kwargs):
        super(LayoutLMv2ForRe, self).__init__(
            LayoutLMv2Model, LayoutLMv2ForRelationExtraction, mode, "re",
            pretrained, checkpoints)
littletomatodonkey's avatar
littletomatodonkey 已提交
189 190 191
        if hasattr(self.model.layoutlmv2, "use_visual_backbone"
                   ) and self.model.layoutlmv2.use_visual_backbone is False:
            self.use_visual_backbone = False
文幕地方's avatar
文幕地方 已提交
192 193 194 195 196

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


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

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