자연어처리

Simple Transformers 를 사용하는 자연어처리 BERT

coding art 2022. 6. 22. 10:51
728x90

Bidirectional Encoder Representations From Transformers

참조: Simple Transformers

https://simpletransformers.ai/docs/qa-model/

참조: Build a custom Q&A model using BERT in easy steps!

https://medium.datadriveninvestor.com/build-a-custom-q-a-model-using-bert-in-easy-steps-241547d6310f

 

이미 자연어 처리를 위한 BERT 기법이 수년전부터 많이 알려져 있으나 초보자가 접근하기엔 난이도 문제도 있고 해서 다루어 보기 힘들기도 하며 여전히 까다로운 주제로 남아 있다. 처음부터 복잡해 보이는 알고리듬을 살펴보느니 오히려 그 사용법을 즉 응용 방법을 먼저 알아보고 난 후 알고리듬의 특성에 대해서 생각해 보는 것이 BERT 를 이해할 수 있는 지름길이 아닌기 한다. 

 

BERT 자연어 처리에서 가장 핵심적인 기능은 이미 Corpus를 학습 완료한 상태에서 문장에 비어있는 괄호에 적절한 단어를 찾아내는 일이라 하겠다. 이 작업은 그다지 어려울게 없다. 그 다음 관심을 가질만한 BERT 의 기능은 단연코 Q&A  일 것이다. Q&A 자체가 그다지 어려울 것은 없겠으나 컴퓨터 언어에 의해 컴퓨터가 인식할 정도가 되어야 하니 나름대로 형식냊;는 형태에 대해서 알아볼 필요가 있다. 처음부터 Q&A 알고리듬 구조를 검토할 것이 아니라 어떤 방식으로 코드가 돌아가는지 예제 코드를 실행시켜 파악하는 것이 지름길 인듯 하다. 

 

Hugging face 사의  자연어 처리 BERT 중에서 Transformers 라이브러리가 주로 사용되고 있지만 한편 Hugging face 사에 의해 Transformers로 부터 파생된 Simple Transformers 사용법을 간단히 알아보자. 어느 것이 사용에 편리하거나 아니면 복잡성으로 인해 불편한지 살펴 보기로 하자. 라이브러리 명에 Simple 이 추가되었듯이 얼마나 간단해졌는지 Q&A 성능 중심으로 확인해 보자. 

 

학습용 데이터를 포함하고 있는 json  확장자 파일을 준비하자.

context 가 주어진 지문이며 그 내용은 "선적을 위한 HSN 코드가 3994번이며 6월 24일까지 배달될 것이다."

이 지문을 대상으로 한 3개의 질문(Question) 으로는 "HSN 코드는 무엇인가?", "선적물은 언제 배달되는가?","선적물의 내용물은 무엇인가?" 로 구성된다. 마지막 질문인 선적물의 내용물은 정보가 없으므로 비워둔다.

train_data = [
  {
   "context": "The HSN code for the shipment is 3004 and will be delivered by June 24.",
        "qas": [
            {
                "id": "00001",
                "is_impossible": False,
                "question": "What is the HSN code?",
                "answers": [
                    {
                        "text": "3004",
                        "answer_start": 33,
                    }
                ],
            },
            {
                "id": "00002",
                "is_impossible": False,
                "question": "When will the shipment be delivered?",
                "answers": [
                    {
                        "text": "June 24",
                        "answer_start": 63,
                    }
                ],
            },
            {
                "id": "00003",
                "is_impossible": True,
                "question": "What does the shipment contain?",
                "answers": [],
            }
        ]
    }]

 validation 을 위한 test_data 도 tarain_data 와 비슷하게 아래와 같이 json 확자자 파일로 준비하자.

context 내용은 " 그 동물의 ID가 0012 이며 동물의 나이를 뜻한다."

이 지문을 대상으로 한 3개의 질문(Question) 으로 "동물의 ID는 무엇인가?", "동물의 ID는 무엇을 의미하는가?","무슨 동물인가?" 로 구성된다. 마지막 질문에서 무슨 동물인지 정보가 없음에 유의한다.

준비하자.

                    
test_data = [
  {
   "context""The ID of the animal is 0012 and means the age of the animal.",
        "qas": [
            {
                "id""00001",
                "is_impossible"False,
                "question""What is the ID of the animal?",
                "answers": [
                    {
                        "text""0012",
                        "answer_start"25,
                    }
                ],
            },
            {
                "id""00002",
                "is_impossible"False,
                "question""What does the ID mean?",
                "answers": [
                    {
                        "text""age",
                        "answer_start"45,
                    }
                ],
            },
            {
                "id""00003",
                "is_impossible"True,
                "question""What is the animal?",
                "answers": [],
            }
            
        ]
        
    }]

Colab에서 아래와 같이 simpletransformers 라이브러리를 설치하자. 

!pip install simpletransformers

 

라이브러리가 설치되었으면 모델과 인수들로 구성되는 working model 을 불러 들이자.

from simpletransformers.question_answering import QuestionAnsweringModel, QuestionAnsweringArgs

바닐라 BERT 모델을 미세조정( fine-tuning ) 하도록 하자. 어떤 모델을 택하느냐는 문제에서 선택의 폭은 다양하다. bert-base-case 모델 말고도 roberta 나 distilbert  또는 electra 와 같은 모델을 택할 수도 있다. BERT를 많이 경험해야 어떤 모델들이 있는지 알게 될 것이다.

model_type="bert"
model_name= "bert-base-cased"

바로 앞에서 언급한 모델 유형들 전체는 다음과 같이 13종이 있음을 알 수 있다.

모델 명(model_name)은 정확한 아키텍쳐와 사용하게 될 웨이트 값들을 함께 지정한다. Hugging Face 와 호환 모델일수도 있으며 한편 커뮤니티 모델일 수도 있다. 이는 Hugging Face 의 모델들에 대해서 수많은 호환 모델들이 있을 수 있음을 의미한다.

 

아래와 같이 클라스 QuestionAnsweringArgs()를 사용하여 적절한 모델 인수값들을 책정 후 모델 QuestionAnsweringModel에 입력하자. 

model_args = QuestionAnsweringArgs()
model_args.train_batch_size = 16
model_args.n_best_size=3
model_args.num_train_epochs=10
model_args.evaluate_during_training = True
model = QuestionAnsweringModel(
    model_type, model_name, args=model_args
)

파라메터 설정 “model_args.evaluate_during_training” to True 는 테스트 데이터 세트 상의 새 모델의 정확도와 성능 계산을 가능하게 한다. 만약 그 값을 False 로 두면 별도의 테스트 데이터 없이 학습만으로도 진행이 가능하다. 하지만 여기서는 test_data를 준비하였으므로 True 로 설정한다.

모델을 학습시키도록 하자. 모델을 평가해 볼 수 있도록 하기 위해서는 블로그 첫부분에서 학습용 데이터를 설정했던것 처럼 모델 평가를 위한 테스트용 데이터를 만들 수 있다. 

그런데 과연 train_data 하나를 가지고 BERT 학습이 가능할까? 

미세조정(fine-tuned)이란 이미 학습된 BERT 레이어들에 대한 웨이트 값들을 가지고 있으므로 여기에서 데이터 하나를 추가한 후 재학습을 시키게 되면 기존 웨이트 값들은 어느 정도 수렴된 값들이기때문에 미세 조정된 변화가 일어나게 될 것이다. 보다 구체적인 내용은 Transfer Learning 에서 fine-tuned 와 frozen  사례를 공부하도록 하자.

model.train_model(train_data, eval_data=test_data)

미세조정(fine-tuned)을 위한 하나의 새 데이터 세트를 준비하여 Q&A 를 해보자.

cpmtext 의 지문은 벤더 명과 GSTIN 은 각각 ABC 스포츠와 27AAACR0123H56 이다. 즉 벤더 명은 ABC 스포츠이며 GSTIN 번호는 27AAACR0123H56 이다.

predict_data = [
    {
        "context": "The vendor name and GSTIN is ABC sports and 27AAACR0123H56 respectively.",
        "qas": [
            {
                "question": "What is the vendor GSTIN?",
                "id": "0",
            }
        ],
    }
]answers, probabilities = model.predict(predict_data)
print(answers)

Colab에서 런타임 유형을 반드시 GPU 모드로 설정하고 각 셀들을 실행시키자. 특히 학습과정에는 GPU 를 사용하드라도 수분의 시간이 소모된다.

제대로 실행이 이루어지면 아래의 결과가 얻어진다. 인수(argument) 설정에서 n_best_size = 3 으로 두었음을 상기하자.해답이 3개가 나왔다.  

[{'id': '0', 'answer': ['0123H56', '0123', '27AAACR0123H56']}]

 

이 예제 코드 하나를 성공적으로 실행시켰지만 아직은  BERT 의 사용방법의 전체적인 이해를 위한 시작에 불과하다.

 

SimpleQ&A.ipynb
0.22MB