|
--- |
|
license: mit |
|
base_model: |
|
- FacebookAI/roberta-large |
|
pipeline_tag: token-classification |
|
library_name: transformers |
|
tags: |
|
- LoRA |
|
- Adapter |
|
--- |
|
|
|
# Training |
|
This model adapter is designed for token classification tasks, enabling it to extract aspect terms and predict the sentiment polarity associated with the extracted aspect terms. |
|
The extracted aspect terms will be the span(s) from the input text on which a sentiment is being expressed. |
|
It has been created using [PEFT](https://huggingface.co/docs/peft/index) framework for [LoRA:Low-Rank Adaptation](https://arxiv.org/abs/2106.09685). |
|
|
|
## Datasets |
|
This model has been trained on the following datasets: |
|
|
|
1. Aspect Based Sentiment Analysis SemEval Shared Tasks ([2014](https://aclanthology.org/S14-2004/), [2015](https://aclanthology.org/S15-2082/), [2016](https://aclanthology.org/S16-1002/)) |
|
2. Multi-Aspect Multi-Sentiment [MAMS](https://aclanthology.org/D19-1654/) |
|
|
|
# Use |
|
|
|
* Loading the base model and merging it with LoRA parameters |
|
|
|
```python |
|
from transformers import AutoTokenizer, AutoModelForTokenClassification |
|
from peft import PeftModel |
|
|
|
# preparing the labels |
|
labels = {"B-neu": 1, "I-neu": 2, "O": 0, "B-neg": 3, "B-con": 4, "I-pos": 5, "B-pos": 6, "I-con": 7, "I-neg": 8, "X": -100} |
|
id2labels = {k:lab for lab, k in labels.items()} |
|
labels2ids = {k:lab for lab, k in id2labels.items()} |
|
|
|
# loading tokenizer and base_model |
|
base_id = 'FacebookAI/roberta-large' |
|
tokenizer = AutoTokenizer.from_pretrained(base_id) |
|
base_model = AutoModelForTokenClassification.from_pretrained(base_id, num_labels=len(labels), id2label=id2labels, label2id=labels2ids) |
|
|
|
# using this adapter with base model |
|
model = PeftModel.from_pretrained(base_model, 'gauneg/roberta-large-absa-ate-sentiment-lora-adapter', is_trainable=False) |
|
|
|
``` |
|
|
|
This model can be utilized in the following two methods: |
|
1. Making token level inference |
|
2. Using pipelines for end to end inference |
|
|
|
## Making token level inference |
|
|
|
```python |
|
# after loading base model and the adapter as shown in the previous snippet |
|
|
|
text_input = "Been here a few times and food has always been good but service really suffers when it gets crowded." |
|
tok_inputs = tokenizer(text_input, return_tensors="pt").to(device) |
|
|
|
y_pred = model(**tok_inputs) # predicting the logits |
|
|
|
y_pred_fin = y_pred.logits.argmax(dim=-1)[0] # selecting the most favoured labels for each token from the logits |
|
|
|
decoded_pred = [id2labels[logx.item()] for logx in y_pred_fin] |
|
|
|
tok_levl_pred = list(zip(tokenizer.convert_ids_to_tokens(tok_inputs['input_ids'][0]), decoded_pred))[1:-1] |
|
``` |
|
|
|
RESULTS in `tok_levl_pred` variable: |
|
```bash |
|
[('Be', 'O'), |
|
('en', 'O'), |
|
('Ġhere', 'O'), |
|
('Ġa', 'O'), |
|
('Ġfew', 'O'), |
|
('Ġtimes', 'O'), |
|
('Ġand', 'O'), |
|
('Ġfood', 'B-pos'), |
|
('Ġhas', 'O'), |
|
('Ġalways', 'O'), |
|
('Ġbeen', 'O'), |
|
('Ġgood', 'O'), |
|
('Ġbut', 'O'), |
|
('Ġservice', 'B-neg'), |
|
('Ġreally', 'O'), |
|
('Ġsuffers', 'O'), |
|
('Ġwhen', 'O'), |
|
('Ġit', 'O'), |
|
('Ġgets', 'O'), |
|
('Ġcrowded', 'O'), |
|
('.', 'O')] |
|
``` |
|
|
|
## Using end-to-end token classification pipeline |
|
|
|
```python |
|
# after loading base model and the adapter as shown in the previous snippet |
|
from transformers import pipeline |
|
|
|
ate_senti_pipeline = pipeline(task='ner', |
|
aggregation_strategy='simple', |
|
model=model, |
|
tokenizer=tokenizer) |
|
|
|
|
|
text_input = "Been here a few times and food has always been good but service really suffers when it gets crowded." |
|
ate_senti_pipeline(text_input) |
|
|
|
``` |
|
OUTPUT |
|
```bash |
|
[{'entity_group': 'pos', |
|
'score': 0.92310727, |
|
'word': ' food', |
|
'start': 26, |
|
'end': 30}, |
|
{'entity_group': 'neg', |
|
'score': 0.90695626, |
|
'word': ' service', |
|
'start': 56, |
|
'end': 63}] |
|
``` |
|
|