Para essa atividade importamos as libs necessárias para o treinamento do modelo, o objetivo e usar a lib transformes
import numpy as np
import pandas as pd
from datasets import load_dataset,Dataset
from transformers import AutoTokenizer, DataCollatorWithPadding
from transformers import TrainingArguments
from transformers import AutoModelForSequenceClassification
from transformers import Trainer
from datasets import load_metric
from ml_things import plot_dict, plot_confusion_matrix, fix_text
Nessa etapa os dados já foram processados para o formato que a biblioteca aceita para o processo de treinamento e validação.
treino = pd.read_csv('treino_bert_filter.csv',lineterminator='\n')
teste = pd.read_csv('teste_bert_filter.csv',lineterminator='\n')
Um tokenizer está encarregado de preparar as entradas para um modelo. Portanto, nessa etapa o objetivo é transformar o pedido e reposta em vetores de embeddings, para esse processo se faz necessário um modelo treinado em uma base com domínio em português para que todas as palavras presentes na nossa base consiga se adaptar ao processo, desse modo, para essa etapa usamos o modelo pierreguillou/bert-base-cased-squad-v1.1-portuguese disponibilizado gratuitamente na plataforma Hugginface.
checkpoint = "pierreguillou/bert-base-cased-squad-v1.1-portuguese"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
def tokenize_function(example):
return tokenizer(example["sentence1"],example["sentence2"], truncation=True,max_length=512)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
def process_df(train,teste):
dataset_train = Dataset.from_pandas(train)
dataset_teste = Dataset.from_pandas(teste)
tokenized_train = dataset_train.map(tokenize_function, batched=True)
tokenized_test = dataset_teste.map(tokenize_function, batched=True)
return tokenized_train, tokenized_test
result = []
Nessa etapa iremos utilizar a métrica Acurácia como refecia para avaliar nosso modelo, lembrando que:
No nosso contexto, dado que a variável de interesse é o atendimento do pedido, temos:
Falso Positivo (FP): O modelo previu que o pedido foi atendido, entretanto, não foi.
Falso Negativo (FN): O modelo previu que o pedido não foi atendido, entretanto, ele foi.
Verdadeiro Negativo (VN): O modelo previu que o pedido não foi atendido, e de fato ele não foi.
Verdadeiro Positivo (VP): O modelo previu que o pedido foi atendido, e de fato ele foi.
VP + VN / (VP + FP + VN + FN)
def compute_metrics(eval_preds):
metric = load_metric("accuracy")
logits, labels = eval_preds
predictions = np.argmax(logits, axis=-1)
result.append(predictions)
return metric.compute(predictions=predictions, references=labels)
training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
training_args.report_to = []
Iremos utilizar um modelo de arquitetura BERT para a classificação das 3 classes, para entender melhor:
BERT (Bidirectional Encoder Representations from Transformers) é um artigo recente publicado por pesquisadores do Google AI Language. Isso causou um rebuliço na comunidade de aprendizado de máquina ao apresentar resultados de última geração em uma ampla variedade de tarefas de NLP, incluindo resposta a perguntas (SQuAD v1.1), inferência de linguagem natural (MNLI) e outras. A principal inovação técnica do BERT é a aplicação do treinamento bidirecional do Transformer, um modelo de atenção popular, à modelagem de linguagem. Isso está em contraste com os esforços anteriores que olhavam para uma sequência de texto da esquerda para a direita ou treinamento combinado da esquerda para a direita e da direita para a esquerda. Os resultados do artigo mostram que um modelo de linguagem que é treinado bidirecionalmente pode ter um senso mais profundo de contexto e fluxo de linguagem do que modelos de linguagem de direção única. No artigo, os pesquisadores detalham uma nova técnica chamada Masked LM (MLM) que permite o treinamento bidirecional em modelos nos quais era impossível anteriormente
Para realizar o treinamento em cima desse modelo realizamos o processo de adaptação ao nosso problema de classificação das três classes e usando como entrada o pedido e resposta ao pedido para que desse modo o modelo gerado conseguisse classificar entre Não Atendido, Parcialmente Atendido e Atendido, para isso realizamos o processo de Transfer Learning.
O Transfer Learning é uma técnica em que um modelo de aprendizado profundo treinado em um grande conjunto de dados é usado para realizar tarefas semelhantes em outro conjunto de dados. Chamamos esse modelo de aprendizado profundo de modelo pré-treinado. Os exemplos mais renomados de modelos pré-treinados são os modelos de aprendizado profundo de visão computacional treinados no conjunto de dados ImageNet . Portanto, é melhor usar um modelo pré-treinado como ponto de partida para resolver um problema, em vez de construir um modelo do zero. Desse modo, para o nosso problema é melhor reutilizar um modelo com amplo domínio da língua portuguesa e consequentemente ajuda no processo de entediamento geral das sentenças.
model = AutoModelForSequenceClassification.from_pretrained("viniaraujoo/bert_transparencia_brasil", num_labels=3)
tokenized_train, tokenized_test = process_df(treino,teste)
## Treino
trainer = Trainer(
model,
training_args,
train_dataset=tokenized_train,
eval_dataset=tokenized_test,
data_collator=data_collator,
tokenizer=tokenizer,
compute_metrics=compute_metrics
)
%%time
trainer.train()
The following columns in the training set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence1, sentence2, __index_level_0__. ***** Running training ***** Num examples = 6899 Num Epochs = 3 Instantaneous batch size per device = 8 Total train batch size (w. parallel, distributed & accumulation) = 8 Gradient Accumulation steps = 1 Total optimization steps = 2589
Epoch | Training Loss | Validation Loss | Accuracy |
---|---|---|---|
1 | 0.195500 | 0.802048 | 0.846847 |
2 | 0.078400 | 0.962511 | 0.824968 |
3 | 0.045000 | 0.934875 | 0.846203 |
Saving model checkpoint to test-trainer\checkpoint-500 Configuration saved in test-trainer\checkpoint-500\config.json Model weights saved in test-trainer\checkpoint-500\pytorch_model.bin tokenizer config file saved in test-trainer\checkpoint-500\tokenizer_config.json Special tokens file saved in test-trainer\checkpoint-500\special_tokens_map.json The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence1, sentence2, __index_level_0__. ***** Running Evaluation ***** Num examples = 1554 Batch size = 8 Saving model checkpoint to test-trainer\checkpoint-1000 Configuration saved in test-trainer\checkpoint-1000\config.json Model weights saved in test-trainer\checkpoint-1000\pytorch_model.bin tokenizer config file saved in test-trainer\checkpoint-1000\tokenizer_config.json Special tokens file saved in test-trainer\checkpoint-1000\special_tokens_map.json Saving model checkpoint to test-trainer\checkpoint-1500 Configuration saved in test-trainer\checkpoint-1500\config.json Model weights saved in test-trainer\checkpoint-1500\pytorch_model.bin tokenizer config file saved in test-trainer\checkpoint-1500\tokenizer_config.json Special tokens file saved in test-trainer\checkpoint-1500\special_tokens_map.json The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence1, sentence2, __index_level_0__. ***** Running Evaluation ***** Num examples = 1554 Batch size = 8 Saving model checkpoint to test-trainer\checkpoint-2000 Configuration saved in test-trainer\checkpoint-2000\config.json Model weights saved in test-trainer\checkpoint-2000\pytorch_model.bin tokenizer config file saved in test-trainer\checkpoint-2000\tokenizer_config.json Special tokens file saved in test-trainer\checkpoint-2000\special_tokens_map.json Saving model checkpoint to test-trainer\checkpoint-2500 Configuration saved in test-trainer\checkpoint-2500\config.json Model weights saved in test-trainer\checkpoint-2500\pytorch_model.bin tokenizer config file saved in test-trainer\checkpoint-2500\tokenizer_config.json Special tokens file saved in test-trainer\checkpoint-2500\special_tokens_map.json The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence1, sentence2, __index_level_0__. ***** Running Evaluation ***** Num examples = 1554 Batch size = 8 Training completed. Do not forget to share your model on huggingface.co/models =)
Wall time: 13min 27s
TrainOutput(global_step=2589, training_loss=0.10984043680871025, metrics={'train_runtime': 807.4821, 'train_samples_per_second': 25.632, 'train_steps_per_second': 3.206, 'total_flos': 5165725772096190.0, 'train_loss': 0.10984043680871025, 'epoch': 3.0})
Vamos avaliar como está o comportamento do nosso modelo, em relação á métrica de acurácia e também a como o modelo está se comportando em relação a cada uma das classes de classificação, analisar o processo de distribuição de predição entre as classes para podermos considerar a real utilidade do modelo.
trainer.evaluate()
C:\Users\LMD\anaconda3\lib\site-packages\ipykernel\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above. and should_run_async(code) The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence1, sentence2, __index_level_0__. ***** Running Evaluation ***** Num examples = 1554 Batch size = 8
{'eval_loss': 0.9348747730255127, 'eval_accuracy': 0.8462033462033463, 'eval_runtime': 19.7775, 'eval_samples_per_second': 78.574, 'eval_steps_per_second': 9.86, 'epoch': 3.0}
Nosso modelo obteve uma Acurácia de 84.62%, para o nosso problema envolvendo as 3 classes e considerando o desbalanceamento entre elas conseguimos bons resultados para esse modelo.
predictions_labels = result[1]
plot_confusion_matrix(y_true=teste['label'], y_pred=predictions_labels,
classes=['Nao Atendido','Parcialmente Atendido','Atendido'], normalize=True,
magnify=0.1,
);
Normalized confusion matrix
Observamos que modelo se comportou muito bem para a classe de Não Atendido acetando 90% dos casos, acompanhado de Atendido em que ele acertou 82% dos casos e depôs acertando 65% dos exemplos da classe de Parcialmente, considerando os problemas envolvendo os Parcialmente e sua baixa quantidade de exemplo na base o nosso modelo teve um ótimo desempenho.
Considerando o processo que o nosso modelo foi ótimo, iremos subir essa versão 1.1 para o repositório tbrasil da ong transparência Brasil para que posa ser utilizado, nessa etapa usamos a plataforma Hugginface para auxiliar.
trainer.model.push_to_hub("tbrasil/classificador_de_atendimento_3_classes_v1.1")
C:\Users\LMD\anaconda3\lib\site-packages\ipykernel\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above. and should_run_async(code) Configuration saved in tbrasil/classificador_de_atendimento_3_classes_v1.1\config.json Model weights saved in tbrasil/classificador_de_atendimento_3_classes_v1.1\pytorch_model.bin
'https://huggingface.co/tbrasil/classificador_de_atendimento_3_classes_v1.1/commit/c7825e99fb9b49e3f7b6ef33f020f799ac24568d'