[기계 학습] Transformer 모델을 사용한 텍스트 분류(Attention 기반 식별자)

목표



Tensorflow 튜토리얼의 "언어 이해를위한 Transformer 모델"의 일부를 수정하고,
텍스트 분류 작업을 할 수 있습니다.

Notebook



노트북을 Github에 올리고 있습니다.
transformer_classify

해설



튜토리얼과의 주요 차이점은 다음과 같습니다.

사용 데이터는 livedoor 뉴스 코퍼스


  • 본 기사에서 소개한 분류 태스크는, 업무에 활용하는 경우에는 일본어의 문서 분류가 된다고 상정하고 있습니다.
  • 그 때문에 데이터는 기계 학습에서 자주 이용되는 livedoor 뉴스 코퍼스를 이용하였습니다.

  • 문장 나눗셈에 Juman 사용


  • 일본어의 몫에 정평이 있는 Juman을 사용하고 있습니다.
  • Juman 다운로드, 설치를 자동화한 Dockerfile은 여기

  • Decoder 삭제


  • Decoder는 Encoder의 출력을 받아 다른 언어 벡터로 변환하는 메커니즘입니다.
  • 이번은 타언어 벡터로의 변환이 아니고 분류 태스크이기 때문에, Decoder는 이용하지 않습니다.

  • Transformer 수정


  • Decoder를 제거하는 대신 Encoder에서 얻은 출력에 Dense 레이어를 겹쳐 출력 레이어로 추가합니다.
  • 입력되는 텍스트 벡터가 어떤 클래스로 분류되는지를 확률적으로 표현한 값으로 변환하기 위해,
    활성화 함수에는 Softmax 함수를 사용합니다.

  • transformer_classify.ipynb
    NUMLABELS = 9
    
    class Transformer(tf.keras.Model):
      def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, 
                   target_vocab_size, pe_input, pe_target, rate=0.1):
        super(Transformer, self).__init__()
    
        self.encoder = Encoder(num_layers, d_model, num_heads, dff, 
                               input_vocab_size, pe_input, rate)
        self.dense1 = tf.keras.layers.Dense(d_model, activation='tanh')
        self.dropout1 = tf.keras.layers.Dropout(rate)   
        self.final_layer = tf.keras.layers.Dense(NUMLABELS, activation='softmax')
    
      def call(self, inp, tar, training, enc_padding_mask):
    
        enc_output = self.encoder(inp, training, enc_padding_mask)  # (batch_size, inp_seq_len, d_model)
        enc_output = self.dense1(enc_output[:,0])
        enc_output = self.dropout1(enc_output, training=training)
        final_output = self.final_layer(enc_output )  # (batch_size, tar_seq_len, target_vocab_size)
    
        return final_output
    

    손실 함수


  • 출력 레이어의 활성화 함수는 Softmax 함수를 사용하므로 손실 함수에는 다 클래스 교차 엔트로피를 사용합니다.
  • One-hot 벡터화되어 있지 않기 때문에, SparseCategoricalCrossentropy()를 이용하고 있습니다.

  • transformer_classify.ipynb
    loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
    
    def loss_function(labels, pred):
      loss_ = loss_object(labels, pred)
      return loss_
    

    val_step 추가


  • train_step 뒤에 valid 데이터를 사용한 val_step을 추가하고 있습니다.
  • validation이므로 dropout 레이어를 건너 뛰기 위해 traininng은 false로 설정됩니다.

  • 결과



    그다지 좋은 정밀도는 낼 수 없었습니다.



    참고 URL



    tf2_classify
    BERT with SentencePiece for Korean text.
    만들어 이해하기 Transformer / Attention
    Transformer model for language understanding

    좋은 웹페이지 즐겨찾기