Python/Transformers

[Transformers] Bert Tokenizer 알아보기

언킴 2022. 12. 4. 16:00
반응형

Contents

     

    Transformers 패키지는 자연어처리(NLP) 분야에서 엄청 많이 사용되는 패키지 중 하나이다. BERT 등과 같은 모델을 구축할 때 Transformers 패키지를 사용하면 매우 편하게 구축할 수 있다. 이번 글에서는 Transformers에 존재하는 BERT에서 사용하는 tokenizer 함수를 뜯어본다. 

     

    BertTokenizer

    BertTokenizer는 PreTrainedTokenizer를 상속받는다. PreTranedTokenizer는 나중에 알아보도록하고, 단순히 사전 학습된 tokenizer 정도로 이해하면 된다. BertTokenizer 내에는 vocab_file, do_lower_case, unk_token 등 다양한 파라미터들이 존재하는데, 중요한 파라미터 위주로 알아보자. 

     

    vocab_file

    저장된 vocabulary를 사용하고 싶다면 vocabulary가 저장된 경로를 지정해서 넣어주면 된다. 

     

    do_lower_case

    이는 입력되는 text에 lower 함수를 적용할 것인지에 대한 내용이다. Optional이며, 기본값은 True로 대문자가 들어오더라도 전부 소문자로 변환한다. 만약 False로 지정하는 경우에는 User, user 등과 같은 단어를 서로 다른 단어로 인식하게 된다. 개체명 인식(NER) 모델을 구축하고 싶은 경우에는 do_lower_case=False를 지정해 대문자를 살려주어야 한다. 

     

    unk_token

    unk_token은 Unknown 단어를 어떻게 처리할 것인지에 대한 내용이다. 기본값은 "[UNK]" token이 되며, 사전에 존재하지 않는 단어인 경우에는 "[UNK]" 으로 표현하게 된다. BERT의 Vocabulary의 경우 30522개의 단어를 포함하고 있는데, 그 외에 단어의 경우 "[UNK]"으로 출력된다.

     

    sep_token

    sep_token은 문장의 구분을 지어주기 위해 사용된다. 혹은 문장의 끝을 알려주기 위해 사용된다. 만약 Q&A와 같은 경우 질문에 해당하는 문장이 먼저 들어간 후 답변에 해당하는 문장이 들어올 것이다. 이때 두 문장을 구분지어주기 위해 두 문장 사이에 "[SEP]" token을 사용하여 문장을 구분지어 준다. 입력 문장이 하나인 경우에는 문장의 끝을 알려주는 token으로 사용된다. 

     

    pad_token

    pad_token은 입력 문장의 길이가 다를 때 사용된다. 우리가 입력 문장의 최대 길이를 512로 설정하게 된다면, 문장의 길이가 512보다 작은 경우에는 나머지 값을 "[PAD]"로 채우게 된다. 이때 "[PAD]"는 id가 0이 되며, 별도로 학습을 하지 않는다. 

     

    cls_token

    cls_token은 "[CLS]" token을 의미하며, 문장의 시작에 들어간다. 문장의 시작으로 사용되는 "[CLS]"는 다른 단어들을 학습할 때 모두 사용되기 때문에 나중에 감성분석을 수행하거나 그럴 때 "[CLS]" token을 호출해 사용한다. 

     

    mask_token

    Bert는 self-supervised learning 중 하나인 masking 방법을 사용하고 있다. masking 기법은 문장 내에 단어들 중 무작위로 선택하여 masking처리를 하고 해당 단어를 맞추는 형태로 진행하면서 모델의 성능을 향상시키는 기법이다. 

     

     

    encode_plus

    encode_plus를 사용하여도 되고 __call__을 사용하여도 된다. 이는 문장을 입력으로 사용하고 최대 길이를 설정하거나 "[CLS]", "[MASK]" 등과 같은 special token을 어떻게 할 것인지 등을 파라미터로 가지고 있다. encode_plus에 있는 파라미터 중 중요한 파라미터에 대해서 알아보자.

     

    text

    text는 말그대로 우리가 tokenizer하고 싶은 target text를 말한다. target text를 넣으면 tokenizing해준다.

     

    add_special_tokens

    add_special_tokens은 special token을 추가할 것인지에 대한 것을 의미한다. 만약 False로 지정하게 된다면, "[CLS]" token과 "[SEP]" token을 각 문장의 시작과 끝에 작성해주어야 한다. True로 지정한다면 함수 내부에서 자동적으로 "[CLS]" token과 "[SEP]" token을 입력해준다. 

    sample = 'I love Seoul'
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    tokenizer.encode_plus(sample, add_special_tokens=True)['input_ids']
    # [101, 1045, 2293, 10884, 102]
    
    tokenizer.encode_plus(sample, add_special_tokens=False)['input_ids']
    # [1045, 2293, 10884]
    
    sample = '[CLS] I love Seoul [SEP]'
    tokenizer.encode_plus(sample, add_special_tokens=False)['input_ids']
    # [101, 1045, 2293, 10884, 102]

    "[CLS]" token은 id가 101이고, "[SEP]" token의 id는 102 인 것을 확인할 수 있다. 

     

    padding, truncation, max_length

    padding은 True를 하게 된다면 가장 긴 단어를 기준으로 padding을 해준다. 일반적으로는 'max_length'를 작성해 우리가 선언한 최대 문장 길이를 제한하여 사용한다. 이때 trauncation을 함께 사용하면서 적절하게 길이를 설정할 수 있다. 

     

    return_tensors

    return_tensors는 유용하게 사용할 수 있는 파라미터다. 만약 tensorflow를 사용한다면, 'tf'를 입력하면 되고, Pytorch인 경우에는 'pt'를 입력하고, numpy는 'np'를 입력하면 입력된 값에 맞는 자료형으로 출력해준다. 

     

    return_token_type_ids, return_attention_mask

    return_token_type_ids와 return_attention_mask는 bert를 사용할 때 입력으로 사용되는 인자다. token_type_ids는 segment_id를 의미한다. Q&A와 같은 경우 질문과 답변이 함께 들어올 수 있는데, 이때 구분하기 위해 첫 번째 입력으로 들어온 문장의 경우 0으로 표기하고, 두 번째 들어온 문장의 경우 1로 표기해서 구분을 지어준다. attention_mask는 어떤 단어에 집중을 해야하는지 알려준다. padding으로 된 단어의 경우 계산할 필요가 없기 때문에 attention_mask 는 0으로 출력된다. 

    sample1 = 'What do you like country?'
    sample2 = 'I love Seoul'
    
    tokenizer.encode_plus(sample1, sample2, max_length=20, padding='max_length')
    
    # {'input_ids': [101, 2054, 2079, 2017, 2066, 2406, 1029, 102, 1045, 2293, 10884, 102, 0, 0, 0, 0, 0, 0, 0, 0], 
    # 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
    # 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]}