Views
No views yet
transformers library for text classification.1import torch
2import torch.nn as nn
3from transformers import DebertaV2Model, DebertaV2Config, AutoTokenizer, PreTrainedModel, pipeline, AutoModelForSequenceClassification
4from transformers.models.deberta.modeling_deberta import ContextPooler
5
6sent_pipe = pipeline(
7 "sentiment-analysis",
8 model="cardiffnlp/twitter-xlm-roberta-base-sentiment",
9 tokenizer="cardiffnlp/twitter-xlm-roberta-base-sentiment",
10 top_k=None, # return all 3 sentiment scores
11)
12
13class CustomModel(PreTrainedModel):
14 config_class = DebertaV2Config
15 def __init__(self, config, sentiment_dim=3, num_labels=2, *args, **kwargs):
16 super().__init__(config, *args, **kwargs)
17 self.deberta = DebertaV2Model(config)
18 self.pooler = ContextPooler(config)
19 output_dim = self.pooler.output_dim
20 self.dropout = nn.Dropout(0.1)
21 self.classifier = nn.Linear(output_dim + sentiment_dim, num_labels)
22
23 def forward(self, input_ids, positive, neutral, negative, token_type_ids=None, attention_mask=None, labels=None):
24 outputs = self.deberta(input_ids=input_ids, attention_mask=attention_mask)
25 encoder_layer = outputs[0]
26 pooled_output = self.pooler(encoder_layer)
27 sentiment_features = torch.stack((positive, neutral, negative), dim=1).to(pooled_output.dtype)
28 combined_features = torch.cat((pooled_output, sentiment_features), dim=1)
29 logits = self.classifier(self.dropout(combined_features))
30 return {'logits': logits}
31
32model_name = "MatteoFasulo/mdeberta-v3-base-subjectivity-sentiment-arabic"
33tokenizer = AutoTokenizer.from_pretrained("microsoft/mdeberta-v3-base")
34config = DebertaV2Config.from_pretrained(
35 model_name,
36 num_labels=2,
37 id2label={0: 'OBJ', 1: 'SUBJ'},
38 label2id={'OBJ': 0, 'SUBJ': 1},
39 output_attentions=False,
40 output_hidden_states=False
41)
42model = CustomModel(config=config, sentiment_dim=3, num_labels=2).from_pretrained(model_name)
43
44def classify_subjectivity(text: str):
45 # get full sentiment distribution
46 dist = sent_pipe(text)[0]
47 pos = next(d["score"] for d in dist if d["label"] == "positive")
48 neu = next(d["score"] for d in dist if d["label"] == "neutral")
49 neg = next(d["score"] for d in dist if d["label"] == "negative")
50
51 # tokenize the text
52 inputs = tokenizer(text, padding=True, truncation=True, max_length=256, return_tensors='pt')
53
54 # feeding in the three sentiment scores
55 with torch.no_grad():
56 outputs = model(
57 input_ids=inputs["input_ids"],
58 attention_mask=inputs["attention_mask"],
59 positive=torch.tensor(pos).unsqueeze(0).float(),
60 neutral=torch.tensor(neu).unsqueeze(0).float(),
61 negative=torch.tensor(neg).unsqueeze(0).float()
62 )
63
64 # compute probabilities and pick the top label
65 probs = torch.softmax(outputs.get('logits')[0], dim=-1)
66 label = model.config.id2label[int(probs.argmax())]
67 score = probs.max().item()
68
69 return {"label": label, "score": score}
70
71examples = [
72 "ستشمل الشحنة الأولية نصف الجرعات، يليها النصف الثاني بعد ثلاثة أسابيع.",
73 "وهكذا بدأت النساء يعين أهمية دورهن في عدم الصمت أمام هذه الاقتحامات ورفضها بإعلاء صيحات الله أكبر.",
74]
75for text in examples:
76 result = classify_subjectivity(text)
77 print(f"Text: {text}")
78 print(f"→ Subjectivity: {result['label']} (score={result['score']:.2f})\n")| Training Loss | Epoch | Step | Validation Loss | Macro F1 | Macro P | Macro R | Subj F1 | Subj P | Subj R | Accuracy |
|---|---|---|---|---|---|---|---|---|---|---|
| No log | 1.0 | 153 | 0.6885 | 0.5224 | 0.5299 | 0.5268 | 0.4068 | 0.4706 | 0.3582 | 0.5503 |
| No log | 2.0 | 306 | 0.6932 | 0.5204 | 0.5602 | 0.5416 | 0.3510 | 0.5248 | 0.2637 | 0.5803 |
| No log | 3.0 | 459 | 0.6928 | 0.5480 | 0.5748 | 0.5589 | 0.4087 | 0.5410 | 0.3284 | 0.5910 |
| 0.6721 | 4.0 | 612 | 0.7125 | 0.5485 | 0.5492 | 0.5500 | 0.5059 | 0.4820 | 0.5323 | 0.5525 |
| 0.6721 | 5.0 | 765 | 0.7238 | 0.5220 | 0.5667 | 0.5448 | 0.3490 | 0.5361 | 0.2587 | 0.5846 |
| 0.6721 | 6.0 | 918 | 0.7442 | 0.5426 | 0.5472 | 0.5442 | 0.4457 | 0.4910 | 0.4080 | 0.5632 |
1@misc{fasulo2025aiwizardscheckthat2025,
2 title={AI Wizards at CheckThat! 2025: Enhancing Transformer-Based Embeddings with Sentiment for Subjectivity Detection in News Articles},
3 author={Matteo Fasulo and Luca Babboni and Luca Tedeschini},
4 year={2025},
5 eprint={2507.11764},
6 archivePrefix={arXiv},
7 primaryClass={cs.CL},
8 url={https://arxiv.org/abs/2507.11764},
9}