Data/Information

Hugging Face, Token classification

neulvo 2022. 3. 16. 01:15
 

Main NLP tasks - Hugging Face Course

The first application we’ll explore is token classification. This generic task encompasses any problem that can be formulated as “attributing a label to each token in a sentence,” such as: Of course, there are many other types of token classification

huggingface.co

이전에 Tokenizer에 대해 학습하였는데 이제는 그것을 활용해서

토큰을 분류해주는 Token classification에 대해 학습해보고자 한다.

 

여기서 소개하는 것은 NER, POS, Chunking의 세 가지 방법론이다.

NER은 Entity(사람, 장소, 조직 등의 문장 주요 요소) 기반으로 토큰을 인식하는 방법이고

POS는 주로 문장에서의 문법 요소로 단어(토큰)를 파악하는 방법이다.

Chunking은 같은 Entity에 속하는 토큰을 찾는 방법이며 NER, POS 등과 함께 사용될 수 있고

B-, I-, O- 등의 Beginning, Inside, Out 을 지칭하는 라벨을 토큰에 붙임으로써 사용되는 방법론이다.

 

tagging이 완료된 학습용 데이터셋을 불러오고

tokens과 ner_tags를 나란히 출력하는 데까지 해보았다.

MISC는 miscellaneous(다양한) entity라고

PER, ORG, LOC (person, organization, location) 외의 entity에 해당하는 듯하다.

 

AutoTokenizer 패키지를 불러와서 Tokenizer를 캐싱해주었다.

lamb가 la와 ##mb로 나뉜 것을 볼 수 있는데

inputs 과 labels의 불일치를 막기 위해서라도 이를 적절히 처리해주어야 한다.

그래서 작성한 것이 아래의 align_labels_with_tokens 함수이다.

문장의 시작과 끝에 들어가는 special token에 -100 라벨을 부여하였다.

이는 loss function 계산에서 무시되기 위한 것이다.

그리고 아래 라벨에서 0이 하나 더 추가된 것을 볼 수 있는데

이는 앞에서 언급한 subword로 나누어진 ##mb를 처리하기 위한 것이다.

 

raw_datasets 전체에 위의 공정을 처리하기 위해서

tokenizer 후 labels을 새로이 붙여주는 함수를 작성하고 map 함수로 이를 처리했다.

 

data_collator를 사용하여 inputs size에 맞게 labels에 -100이 패딩된 것을 볼 수 있다.

 

token classification prediction을 evaluate하기 위해 seqeval 라이브러리를 설치 후

load_metric() 함수를 통해 불러와주었다.

그리고 이 metric이 labels lists를 integeres가 아닌 strings으로 받기 때문에

fake prediction을 만들고 index 2의 value를 바꾸어주었다.

precision, recall, f1, overall_accuray등을 계산해주는 것을 볼 수 있다.

 

logits의 argmax 값을 받고 그것을 predictions으로 전환해주는 compute_metrics 함수를 작성했다.

(보통, logits과 probabilities의 정렬 순서가 같기 때문에 softmax를 적용하지 않아도 된다.)

labels과 predictions을 integers에서 strings로 변환해주었다. (위 단락의 이유)

 

이제 Classification 문제를 다루기 위해 model을 정의해주는데

여기서 labels에 대한 정보를 모델에 건네주어야 한다.

기존에 가지고 있는 label_names 정보에서 id2label, label2id를 추출해서 모델에 넣어주었다.

그리고 labels의 수가 맞는지 확인해주었다.

 

epoch, learning_rate, decay 등의 하이퍼 파라미터를 정해주었고 (fine-tuning)

push_to_hub 옵션을 통해 Model Hub에 결과를 매 epoch마다 업로드하도록 해주었다.

Model Hub에 업로드하는 만큼 

위의 코드로 notebook_login()을 해주라고 했는데 귀찮아서 무시하고 진행했다.

그런데,

Trainer를 돌려보니 이미 로그인이 되어 있었다...

Loss나 Precision, Recall, F1, Accuray 등을 확인할 수 있다.

 

이제 Full training loop를 만들어보자.

Datasets를 가지고 DataLoader 함수를 빌드, 배치를 만들어주는 거라 보면 된다.

새롭게 모델을 다시 초기화.

 

Optimizer(AdamW)를 세팅하고

Accelerator에 모델, 옵티마이저, 데이터로더를 넣어주었다.

 

트레이닝 스케쥴러를 작성.

dataloader의 길이는 변할 수 있기 때문에 그것이 정의된 후에 사용해 주어야 한다.

 

predictions과 labels를 lists of strings로 변환해주는 함수.

evaluation을 위한 준비작업이다.

 

열심히 돌아가고 있는 Training Session.

모델로 배치가 들어간 후 loss를 가지고 backwrad pass 그리고 optimizer step을 밟는다.

 

accelerator.pad_across_process() 함수로 predictions와 labels의 shape동일하게 만들어준다.

batch 이후에 padding이 다르게 되었을 수 있기 때문에.

 

epoch 마다의 결과.

 

그리고 accelerator의 세 코드에 대해 설명하는데

Trainer를 사용하지 않는 좀 다른 방법론인 것 같다. 앞으로도 종종 볼일이 있을 것 같다.

 

끝으로, 이렇게 파이프라인을 활용해 문제를 해결할 수도 있다.

728x90

'Data > Information' 카테고리의 다른 글

Hugging Face, Translation  (3) 2022.03.17
Hugging Face, Fine-tuning a masked language model  (2) 2022.03.16
Huggig Face, Tokenizers  (0) 2022.02.25
Hugging Face, Datasets  (0) 2022.02.24
Hugging Face, Hub와 Repository 활용  (0) 2022.02.22