General Problems Solved with LSTM
- Sequence labeling
POS tagging, NER
- Language modeling
: 다음에 들어올 단어 예측
- Sequence classification
: text가 들어왔을 때, spam메일인지 아닌지 분류하는 것
** NER은 조화평균으로 성능을 평가함
Sequence to Sequence transduction
encoder / decoder framework - 기계번역등에 활용
BERT는 encoder로, GPT3와 같은것은 decoder로 만든 것임
LSTM의 활용 사례
RNN의 단점: vanishing gradient problem
LSTM의 단점: 계산량이 많음
→ GRU(Gated Recurren Unit)로 계산을 간소화함
Bi-LSTM을 활용한 NER실습에서 참고할 내용들 정리
[preprocess]
def get_train_iterator(self, train_data):
train_iterator = torchtext.legacy.data.BucketIterator(
train_data,
device=self.device,
batch_size=self.args.train_batch_size,
sort_key=lambda x: len(x.text),
repeat=False,
train=True,
sort=True)
return list(train_iterator)
위의 코드에서는 각각 비슷한 길이의 데이터 example을 묶어주는 iterator를 정의한 것임
아래는 pretrained 된 word embedding(Glove)를 가져와서 embedding vector를 초기화 하는 것임
def load_pretrained_word_embed(self, data):
print('We are using pre-trained word embeddings.')
self.LABEL.build_vocab(data)
vectors = torchtext.vocab.Vectors(name='/content/data/glove.6B.50d.txt')
return self.TEXT.build_vocab(data, vectors = vectors)
>> 나중에 모델에서는 nn.Embedding.from_pretrained(embeddings=text_filed.vocab.vectors)로 불러오면 됨
[model]
class LSTMCRFNER(torch.nn.Module):
def __init__(self, text_field, label_field, emb_dim, hidden_size, emb_tuning=False):
super(LSTMCRFNER, self).__init__()
voc_size = len(text_field.vocab)
self.n_labels = len(label_field.vocab)
# Input(Embedding) layer initialized from Glove embedding
# - Defined embedding matrix
# - Initialized weight from processed vocab vectors
# <variable_name:self.word_embedding , dim: (vocab_size, embedding_dim)>
self.word_embedding = nn.Embedding.from_pretrained(embeddings=text_field.vocab.vectors)
# LSTM layer
# <variable_name:self.lstm>
self.lstm = nn.LSTM(input_size=emb_dim, hidden_size = hidden_size, bidirectional=True)
# Output(Fully connected) layer
self.linear = nn.Linear(2*hidden_size, self.n_labels)
#CRF layer
self.crf = CRF(self.n_labels)
# pad information
self.pad_word_id = text_field.vocab.stoi[text_field.pad_token]
self.pad_label_id = label_field.vocab.stoi[label_field.pad_token]
# output layer단에서 보면
마지막에 foward된 LSTM과 backward된 LSTM을 concat해서 사용하므로
nn.Linear의 hidden_size를 2배해준 것임
# CRF layer에서는
torch crf를 사용하는데, 거기서는 label의 개수만 넣어주면 됨
CRF 사용이유:
LSTM 역할: 입력 단어 사이의 관계 및 정보를 반영
CRF 역할: 예측 되는 label 사이의 관계 및 정보를 반영
위 그림에서 '레알', '마드리드', 'FC'라는 단어가 들어왔을 때
이 레이블간의 관계(빨강색 선)를 잘 나타내기 위한것이 CRF임
(TAG의 순차적 정보를 잘 나타낼 수 있음)
→ LSTM에 CRF를 추가하는 것이 더 성능이 좋음
'IT > 자연어분석' 카테고리의 다른 글
BERT2 (0) | 2022.05.26 |
---|---|
BERT1 (0) | 2022.05.26 |
Word Vector and Word embedding (0) | 2022.05.06 |
[자연어]Statistical Parsing (0) | 2022.04.20 |
[자연어]Part of Speech Tagging, Sequence Labeling, HMM (0) | 2022.04.08 |