Kalaoke commited on
Commit
eb39c91
·
1 Parent(s): 18285a9

add custom pipeline

Browse files
__pycache__/bert_for_sequence_classification.cpython-37.pyc ADDED
Binary file (3.92 kB). View file
 
__pycache__/bibert_multitask_classification.cpython-37.pyc ADDED
Binary file (1.92 kB). View file
 
bert_for_sequence_classification.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import transformers
3
+ from torch import nn
4
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
5
+ from typing import List, Optional, Tuple, Union
6
+
7
+ from transformers import BertTokenizer
8
+ from transformers import models, DataCollatorWithPadding, AutoTokenizer
9
+ from transformers.modeling_outputs import SequenceClassifierOutput
10
+
11
+ from transformers.models.bert.configuration_bert import BertConfig
12
+ from transformers.models.bert.modeling_bert import (
13
+ BertPreTrainedModel,
14
+ BERT_INPUTS_DOCSTRING,
15
+ _TOKENIZER_FOR_DOC,
16
+ _CHECKPOINT_FOR_DOC,
17
+ BERT_START_DOCSTRING,
18
+ _CONFIG_FOR_DOC,
19
+ _SEQ_CLASS_EXPECTED_OUTPUT,
20
+ _SEQ_CLASS_EXPECTED_LOSS,
21
+ BertModel,
22
+ )
23
+
24
+ from transformers.file_utils import (
25
+ add_code_sample_docstrings,
26
+ add_start_docstrings_to_model_forward,
27
+ add_start_docstrings
28
+ )
29
+
30
+ @add_start_docstrings(
31
+ """
32
+ Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
33
+ output) e.g. for GLUE tasks.
34
+ """,
35
+ BERT_START_DOCSTRING,
36
+ )
37
+ class BertForSequenceClassification(BertPreTrainedModel):
38
+ def __init__(self, config, **kwargs):
39
+ super().__init__(transformers.PretrainedConfig())
40
+ #task_labels_map={"binary_classification": 2, "label_classification": 5}
41
+ self.tasks = kwargs.get("tasks_map", {})
42
+ self.config = config
43
+
44
+ self.bert = BertModel(config)
45
+ classifier_dropout = (
46
+ config.classifier_dropout
47
+ if config.classifier_dropout is not None
48
+ else config.hidden_dropout_prob
49
+ )
50
+ self.dropout = nn.Dropout(classifier_dropout)
51
+ ## add task specific output heads
52
+ self.classifier1 = nn.Linear(
53
+ config.hidden_size, self.tasks[0].num_labels
54
+ )
55
+ self.classifier2 = nn.Linear(
56
+ config.hidden_size, self.tasks[1].num_labels
57
+ )
58
+
59
+ self.init_weights()
60
+
61
+ @add_start_docstrings_to_model_forward(
62
+ BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")
63
+ )
64
+ @add_code_sample_docstrings(
65
+ processor_class=_TOKENIZER_FOR_DOC,
66
+ checkpoint=_CHECKPOINT_FOR_DOC,
67
+ output_type=SequenceClassifierOutput,
68
+ config_class=_CONFIG_FOR_DOC,
69
+ expected_output=_SEQ_CLASS_EXPECTED_OUTPUT,
70
+ expected_loss=_SEQ_CLASS_EXPECTED_LOSS,
71
+ )
72
+ def forward(
73
+ self,
74
+ input_ids: Optional[torch.Tensor] = None,
75
+ attention_mask: Optional[torch.Tensor] = None,
76
+ token_type_ids: Optional[torch.Tensor] = None,
77
+ position_ids: Optional[torch.Tensor] = None,
78
+ head_mask: Optional[torch.Tensor] = None,
79
+ inputs_embeds: Optional[torch.Tensor] = None,
80
+ labels: Optional[torch.Tensor] = None,
81
+ output_attentions: Optional[bool] = None,
82
+ output_hidden_states: Optional[bool] = None,
83
+ return_dict: Optional[bool] = None,
84
+ task_ids=None,
85
+ ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]:
86
+ r"""
87
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`):
88
+ Labels for computing the sequence classification/regression loss. Indices should be in :obj:`[0, ...,
89
+ config.num_labels - 1]`. If :obj:`config.num_labels == 1` a regression loss is computed (Mean-Square loss),
90
+ If :obj:`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
91
+ """
92
+ return_dict = (
93
+ return_dict if return_dict is not None else self.config.use_return_dict
94
+ )
95
+
96
+ outputs = self.bert(
97
+ input_ids,
98
+ attention_mask=attention_mask,
99
+ token_type_ids=token_type_ids,
100
+ position_ids=position_ids,
101
+ head_mask=head_mask,
102
+ inputs_embeds=inputs_embeds,
103
+ output_attentions=output_attentions,
104
+ output_hidden_states=output_hidden_states,
105
+ return_dict=return_dict,
106
+ )
107
+
108
+ pooled_output = outputs[1]
109
+
110
+ pooled_output = self.dropout(pooled_output)
111
+
112
+ unique_task_ids_list = torch.unique(task_ids).tolist()
113
+ loss_list = []
114
+ logits = None
115
+ for unique_task_id in unique_task_ids_list:
116
+
117
+ loss = None
118
+ task_id_filter = task_ids == unique_task_id
119
+
120
+ if unique_task_id == 0:
121
+ logits = self.classifier1(pooled_output[task_id_filter])
122
+ elif unique_task_id == 1:
123
+ logits = self.classifier2(pooled_output[task_id_filter])
124
+
125
+
126
+ if labels is not None:
127
+ loss_fct = CrossEntropyLoss()
128
+ loss = loss_fct(logits.view(-1, self.tasks[unique_task_id].num_labels), labels[task_id_filter].view(-1))
129
+ loss_list.append(loss)
130
+
131
+ # logits are only used for eval. and in case of eval the batch is not multi task
132
+ # For training only the loss is used
133
+
134
+ if loss_list:
135
+ loss = torch.stack(loss_list).mean()
136
+ if not return_dict:
137
+ output = (logits,) + outputs[2:]
138
+ return ((loss,) + output) if loss is not None else output
139
+
140
+ return SequenceClassifierOutput(
141
+ loss=loss,
142
+ logits=logits,
143
+ hidden_states=outputs.hidden_states,
144
+ attentions=outputs.attentions,
145
+ )
bibert_multitask_classification.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import Pipeline
2
+ import numpy as np
3
+ import torch
4
+
5
+ def softmax(_outputs):
6
+ maxes = np.max(_outputs, axis=-1, keepdims=True)
7
+ shifted_exp = np.exp(_outputs - maxes)
8
+ return shifted_exp / shifted_exp.sum(axis=-1, keepdims=True)
9
+
10
+ class BiBert_MultiTaskPipeline(Pipeline):
11
+
12
+ def _sanitize_parameters(self, **kwargs):
13
+
14
+ preprocess_kwargs = {}
15
+ if "task_id" in kwargs:
16
+ preprocess_kwargs["task_id"] = kwargs["task_id"]
17
+
18
+ forward_kwargs = {}
19
+ if "task_id" in kwargs:
20
+ forward_kwargs["task_id"] = kwargs["task_id"]
21
+ return preprocess_kwargs, forward_kwargs, {}
22
+
23
+ def preprocess(self, inputs, task_id):
24
+ return_tensors = self.framework
25
+ feature = self.tokenizer(inputs, padding = True, return_tensors=return_tensors).to(self.device)
26
+ task_ids = np.full(shape=1,fill_value=task_id, dtype=int)
27
+ feature["task_ids"] = torch.IntTensor(task_ids)
28
+ return feature
29
+
30
+ def _forward(self, model_inputs, task_id):
31
+ return self.model(**model_inputs)
32
+
33
+ def postprocess(self, model_outputs):
34
+ outputs = model_outputs["logits"][0]
35
+ outputs = outputs.numpy()
36
+ scores = softmax(outputs)
37
+
38
+ dict_scores = [
39
+ {"label": self.model.config.id2label[i], "score": score.item()} for i, score in enumerate(scores)
40
+ ]
41
+ return dict_scores