본문 바로가기
DNN with Keras/NLP with Hugging Face

임베딩 훈련 (Training Embedding)

by goatlab 2024. 1. 11.
728x90
반응형
SMALL

임베딩 훈련 (Training Embedding)

 

 

레스토랑 리뷰를 긍정 또는 부정에 따라 분류하는 신경망을 만든다. 이 신경망은 여기에 주어진 것과 같은 문자열을 입력으로 받을 수 있다. 이 코드에는 각 리뷰에 대한 긍정 또는 부정 레이블도 포함된다.

 

from numpy import array
from tensorflow.keras.preprocessing.text import one_hot
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Embedding, Dense

# Define 10 restaurant reviews.
reviews = [
    'Never coming back!',
    'Horrible service',
    'Rude waitress',
    'Cold food.',
    'Horrible food!',
    'Awesome',
    'Awesome service!',
    'Rocks!',
    'poor work',
    'Couldn\'t have done better'
]

# Define labels (1=negative, 0=positive)
labels = array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0])

 

두 번째에서 마지막 레이블이 올바르지 않은 것을 확인할 수 있다. 대부분의 학습 데이터에는 약간의 노이즈가 있을 수 있으므로 이와 같은 오류는 그리 드문 일은 아니다. 어휘 크기를 50개 단어로 정의한다. 단어가 50개가 아니더라도 필요 이상으로 큰 값을 사용해도 괜찮다. 단어가 50개 이상인 경우, 훈련 세트에서 가장 사용 빈도가 낮은 단어는 훈련 중에 임베딩 레이어에서 자동으로 삭제된다. 입력의 경우, 문자열을 원핫 인코딩한다. 여기서는 Scikit-Learn이 아닌 TensorFlow 원핫 인코딩 방법을 사용한다. Scikit-learn은 일반적으로 더미 변수에서 볼 수 있는 것처럼 이러한 문자열을 0과 1로 확장한다. TensorFlow는 모든 단어를 인덱스 값으로 변환하고 각 단어를 해당 인덱스로 바꾼다.

 

VOCAB_SIZE = 50
encoded_reviews = [one_hot(d, VOCAB_SIZE) for d in reviews]
print(f"Encoded reviews: {encoded_reviews}")
Encoded reviews: [[22, 44, 10], [49, 6], [7, 29], [15, 37], [49, 37], [7], [7, 6], [46], [30, 30], [41, 7, 20, 10]]

 

원핫 인코딩은 이러한 리뷰를 단어 색인으로 인코딩하지만, 그 길이가 다르다. 이러한 리뷰를 4단어까지 채우고 4단어 이후의 단어는 잘라낸다.

 

MAX_LENGTH = 4
padded_reviews = pad_sequences(encoded_reviews, maxlen=MAX_LENGTH, padding='post')
print(padded_reviews)
[[22 44 10  0]
 [49  6  0  0]
 [ 7 29  0  0]
 [15 37  0  0]
 [49 37  0  0]
 [ 7  0  0  0]
 [ 7  6  0  0]
 [46  0  0  0]
 [30 30  0  0]
 [41  7 20 10]]

 

padding=post 설정에 지정된 대로 각 리뷰는 padding=post 설정에 지정된 대로 마지막에 0을 추가하여 패딩된다. 다음으로, 이러한 리뷰를 분류하는 방법을 학습하기 위해 신경망을 만든다.

 

model = Sequential()
embedding_layer = Embedding(VOCAB_SIZE, 8, input_length=MAX_LENGTH)
model.add(embedding_layer)
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
print(model.summary())
model.fit(padded_reviews, labels, epochs=100, verbose=0)
<keras.src.callbacks.History at 0x7861fd024670>

 

학습된 임베딩을 볼 수 있다. 각 단어의 벡터를 8차원 공간에서 긍정적인 리뷰와 연관된 단어가 다른 단어에 가까운 위치라고 생각하면 된다. 마찬가지로, 학습은 부정적인 리뷰를 서로 가깝게 배치한다. 이러한 임베딩을 설정하는 훈련 외에도 임베딩 레이어와 출력 뉴런 사이의 33개의 가중치는 이러한 임베딩을 실제 예측으로 변환하는 방법을 유사하게 학습한다. 이러한 임베딩은 여기에서 확인할 수 있다.

 

print(embedding_layer.get_weights()[0].shape)
print(embedding_layer.get_weights())

 

이제 임베딩과 학습된 고밀도 레이어를 포함하여 이 신경망의 정확도를 평가할 수 있다.

 

loss, accuracy = model.evaluate(padded_reviews, labels, verbose=0)
print(f'Accuracy: {accuracy}')
Accuracy : 1. 0

 

정확도가 1.0으로 완벽하여 과적합 가능성이 있음을 나타낸다. 더 복잡한 데이터 집합의 경우 과적합을 방지하기 위해 조기 중지를 사용하는 것이 좋다.

 

print(f'Log-loss: {loss}')
Log-loss: 0.4916592538356781

 

그러나 손실은 완벽하지 않다. 예측 확률이 모든 경우에서 정답을 예측했지만, 프로그램은 각 정답에 대해 절대적인 신뢰도를 얻지 못했다. 신뢰도가 낮은 이유는 데이터 세트에 소량의 노이즈가 있었기 때문일 수 있다. 긍정적 리뷰와 부정적 리뷰에 모두 등장한 일부 단어가 절대적인 확실성 부족에 기여했다.

728x90
반응형
LIST

'DNN with Keras > NLP with Hugging Face' 카테고리의 다른 글

임베딩 전송 (Transferring Embedding)  (0) 2024.01.11
Embedding Layers  (0) 2024.01.11
Training HUGGING FACE models  (0) 2024.01.11
Tokenizers  (0) 2024.01.10
Hugging Face API (2)  (0) 2024.01.10