Model Summary
Este modelo identifica aspectos, opiniões e polaridades em reviews.
Foi treinado com 10k reviews de pessoas que registraram um ou mais comentários num site de e-commerce.
Nesse contexto aspectos estão relacionados a um ou mais produtos ou serviços, opiniões esta relacionado a caracteristica destacada e polaridade a satisfação com o respectivo produto ou serviço.
No dataset usado os reviews pertencem a 10 dominios: Restaurants, Electronics, Home, Laptop, Fashion, Beauty, Toy, Grocery, Pet e Book.
O modelo foi treinado com um review especifico para cada dominio, esse review foi reescrito para tornar mais claro e consistente o processo de identificar os produtos ou serviços, a opinião expressa e a polaridade do review.
O modelo pré-treinado google/flan-t5-base foi usado como modelo base e o LORA foi configurado para usar apenas uma pequena parte dos parametros treinaveis e assim conseguir usar todos registros no dataset sem esgotar a memória da VM na GCP.
Durante o treinamento o modelo foi instruído para seguir o exemplo dado e retornar uma sentença no mesmo formato do exemplo.
How to use
Carregar o modelo:
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
from peft import PeftModel, PeftConfig
repo_model = "SilvioLima/absa_10_domains"
model_name_or_path = repo_model
config = PeftConfig.from_pretrained(model_name_or_path)
model = AutoModelForSeq2SeqLM.from_pretrained(config.base_model_name_or_path)
model = PeftModel.from_pretrained(model, model_name_or_path)
tokenizer = AutoTokenizer.from_pretrained(repo_model)
max_length = 256
prefix_fs = "Follow the example, rewrite the sentence and answer in the same format of example\n."
example_task_parafrase = "Example:\nSentence = 'The pizza was delicious because pizza came hot.'\nAnswer = Pizza is great because it came hot."
review = 'This book is amazing, story is intersting and price is good.'
input_text = prefix_fs + example_task_parafrase + review + 'Answer='
inputs = tokenizer(input_text, max_length=max_length, truncation=True , return_tensors="pt", padding="max_length")
input_ids = inputs['input_ids']
outputs = model.generate(input_ids = input_ids, max_new_tokens=max_length)
#outputs = model.generate(inputs_ids, max_length=max_length) #do_sample=True, temperature=(temperature).astype('float'))
generated = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(generated):
- "book is great because book is amazing,
- story is great because story is intersting,
- price is great because price is cheap."
A partir da saída formatada são extraídos os termos aspectos, opiniões e polaridades identificados no review.
Training
O modelo foi treinado com um dataset que separado em 3 partes, sendo 80% para treinamento, 10% para validação e 10% para teste.
O modelo pré-treinado escolhido foi o google/flan-t5-base que possue 248 M de parametros, que foi treinado com diversos corpus para diversas tarefas.
Durante o treinamento foi acompanhado os valores de rouge1 e rouge2 para avaliar a capacidade de aprendizado do modelo.
O modelo final foi avaliado com os dados de testes. A avaliação foi feita por dominio.
O critério de avaliação definido foi que os termos aspectos, opiniões e polaridades presentes na parafrase gerada pelo modelo, devem ser iguais aos termos usados na construção da parafrase fornecida durante o treinamento.
O prompt usado na tokenização dos dados de treinamento, apresenta uma instrução que o modelo deve seguir. Um exemplo de review / sentence de cada dominio e a parafrase gerada é apresentada ao modelo, seguida de uma nova sentence que o modelo deverá gerar, seguindo o formato do exemplo apresentado.
prefix_fs = "Follow the example, rewrite the sentence and answer in the same format of example.\n"
input_str = f"{prefix_fs} Example:\nSentence = {sentence_example} \nAnswer = {target_example} \nSentence = {sentence} \nAnswer = "
Exemplo:
- Restaurant_sentence: 'Excellent atmosphere , delicious dishes good and friendly service.'
- Restaurant_target : "atmosphere is great because atmosphere is Excellent , dishes is great because dishes is delicious , service is great because service is good , service is great because service is friendly "
- Restaurant_triple':"[('atmosphere', 'Excellent', 'POS'), ('dishes', 'delicious', 'POS'), ('service', 'good', 'POS'), ('service', 'friendly', 'POS')]"
Reviews do mesmo dominio do exemplo usado são apresentados para o que o modelo gera um nova review no mesmo formato.
Triples
As reviews geradas pelo modelo são compostas pelos aspectos, opiniões e polaridades que ao final do treinamento são extraidas e avaliadas se cada conjunto de aspecto/opinião/polaridade estão presentes no mesmo conjunto usado na construção da parafrase de treinamento.
Exemplo:
Parafrase gerada pelo modelo:
"atmosphere is great because atmosphere is Excellent , dishes is great because dishes is amazing , service is great because service is good , location is bad because location is danger"
A triple ou o conjunto aspecto/opiniao/polaridade é extraida da parafrase:
-[('atmosphere', 'Excellent', 'POS'), ('dishes', 'amazing', 'POS'), ('service', 'good', 'POS'), ('location', 'danger', 'NEG')]"
As triples extraídas da parafrase gerada pelo modelo devem ser iguais as triples correspondentes no review de entrada.
A review apresentada ao modelo para que seja feita a parafrase, tem um conjunto que corresponde a parafrase correta relacionada a review apresentada ao modelo.
Métricas: Precision, Recall e F1-score
True Positive (TP)) corresponde a triple extraida da parafrase gerada pelo modelo que é exatamente igual a triple de entrada.
False Positive (FP) corresponde a triple extraída que não se encontra na triple de entrada.
A Quantidade de FN é a quantidade de triples de entrada menos quantidade de triples encontrados na saida.
A partir desses valores é calculada a Precisão, o Recall e F1-score do modelo.
Domain
Restaurant 76.325581
Laptop 73.551020
pet 47.375000
beauty 39.033333
book 34.888889
grocery 33.200000
toy 33.111111
home 32.300000
electronics 30.121212
fashion 28.360000
F1-score%:
62.07236842105263
Training Details
- Model: "google/flan-t5-base"
- Tokenizer: T5Tokenizer / T5ForConditionalGeneration
- Dataset: 13513
- Train: 10810
- Valid/Test: 1352
- Batch-size: 4
- Max_length: 512
- Num_Epochs: 10
Global Parameters
L_RATE = 3e-4
BATCH_SIZE = batch_size
PER_DEVICE_EVAL_BATCH = batch_size
WEIGHT_DECAY = 0.01
SAVE_TOTAL_LIM = 1
NUM_EPOCHS = num_epochs
MAX_NEW_TOKENS = max_length
Set up training arguments
training_args = Seq2SeqTrainingArguments(
output_dir="./results/absa_domain_parafrase_v512_2",
evaluation_strategy="epoch",
save_strategy="epoch",
learning_rate=L_RATE,
per_device_train_batch_size=BATCH_SIZE,
per_device_eval_batch_size=PER_DEVICE_EVAL_BATCH,
gradient_accumulation_steps=8,
weight_decay=WEIGHT_DECAY,
save_total_limit=SAVE_TOTAL_LIM,
load_best_model_at_end=True,
num_train_epochs=NUM_EPOCHS,
predict_with_generate=True,
logging_dir="./logs",
logging_strategy="epoch",
logging_steps=100,
report_to = 'wandb',
push_to_hub=True
)
Lora config:
- lora_config = LoraConfig( task_type = TaskType.SEQ_2_SEQ_LM, r = 16, lora_alpha = 32, lora_dropout = 0.1, target_modules = ["q", "v"] )