elevne's Study Note

BERT 감성분석 (2) 본문

Machine Learning/NLP

BERT 감성분석 (2)

elevne 2022. 11. 8. 00:22

전처리 단계까지 완료하였으니 이제 BERT 기반 모델을 만들어 학습을 진행할 차례이다. 다음과 같은 코드로 모델을 만들어주었다.

 

 

class Bert(tf.keras.Model):
  def __init__(self, model):
    super(Bert, self).__init__()
    self.bert = TFBertModel.from_pretrained(model, cache_dir="./")
    self.dropout = tf.keras.layers.Dropout(self.bert.config.hidden_dropout_prob)
    self.classifier = tf.keras.layers.Dense(2, kernel_initializer=tf.keras.initializers.TruncatedNormal(self.bert.config.initializer_range), name="classifier")
  def call(self, input, attention_mask=None, token_type_ids=None, training=False):
    # outputs : Sequence_output, Pooled_output, Hidden_states, Attentions
    outputs = self.bert(input, attention_mask=attention_mask, token_type_ids=token_type_ids)
    pooled_output = outputs[1]
    pooled_output = self.dropout(pooled_output, training=training)
    result = self.classifier(pooled_output)
    return result

 

 

 

위 Class의 self.bert로 TFBertModel 을 사용하였다. TFBertModel.from_pretained 함수를 사용하여 사전학습 모델의 가중치를 가져올 수 있다. 학습단계(call 함수 부분)에서는 TFBertModel의 output list에서 1 번 값을 가져와서 사용하는데 이는 Pooled output에 해당한다. 이 결과값을 사용하여 Dropout, Dense layer을 하나씩 더 통과시켜 최종 output을 2개(긍정/부정)로 분류되어 나오게끔 설계한다.

 

 

 

optimizer = tf.keras.optimizers.Adam(3e-5)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')
model.compile(optimizer=optimizer, loss=loss, metrics=[metric])

 

 

위와 같이 손실함수, 최적화 함수를 지정해주었다. 

 

 

그 후 아래 코드를 사용하여 학습을 진행해주었다. Colab GPU 환경에서도 시간이 꽤나 걸려서 epoch 수를 3으로 설정하였다.

 

 

from keras.callbacks import EarlyStopping, ModelCheckpoint

earlystop_callback = EarlyStopping(monitor='val_accuracy', min_delta=0.0001,patience=2)

cp_callback = ModelCheckpoint(
    "./BertWeights.h5", monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=True)

history = model.fit(train_movie_inputs, train_data_labels, epochs=3, batch_size=256,
                    validation_split = 0.15, callbacks=[earlystop_callback, cp_callback])

print(history.history)

 

 

Training...

 

 

마지막으로 다음과 같은 함수를 만들어서 예측을 진행해볼 수 있도록 하였다.

 

def predict(sent):
  input_ids = []
  input_id, _, _ = bert_tokenizer(sent, 30)
  input_ids.append(input_id)
  input_ids = np.array(input_ids, dtype=int)
  print(input_ids)
  return model.predict(input_ids)

 

 

predict()

 

 

 

 

참고로 전처리한 데이터들을 잃지 않고 계속 활용하기 위해 Pickle 라이브러리를 사용하여 다음과 같이 저장/불러오기를 진행하였다.

 

 

import pickle

# 저장
with open("/content/train_movie_inputs.pickle", "wb") as f:
  pickle.dump(train_movie_inputs, f)
with open("train_data_labels.pickle", "wb") as f:
  pickle.dump(train_data_labels, f)
  
# 불러오기
with open("/content/train_data_labels.pickle", "rb") as f:
  train_data_labels = pickle.load(f)

with open("/content/train_movie_inputs.pickle", "rb") as d:
  train_movie_inputs = pickle.load(d)

 

 

 

출처:

https://dacon.io/competitions/official/235747/codeshare/2905

https://huggingface.co/docs/transformers/main_classes/tokenizer

 

 

'Machine Learning > NLP' 카테고리의 다른 글

BART: Bidirectional and Auto-Regressive Transformer  (0) 2022.11.12
Text Summarization 시작해보기  (0) 2022.11.11
BERT 감성분석 (1)  (0) 2022.11.06
BERT 모델에 대해서~  (0) 2022.11.01
NLP 공부 (5-3: Transformer)  (0) 2022.10.28