class Attention_Head(nn.Module):
def __init__(self, embed_dim, head_dim):
super().__init__()
self.q = nn.Linear(embed_dim, head_dim)
self.k = nn.Linear(embed_dim, head_dim)
self.v = nn.Linear(embed_dim, head_dim)
def forward(self, hidden_state):
attention_outputs = scaled_dot_product_attention(
self.q(hidden_state), self.k(hidden_state), self.v(hidden_state))
return attention_outputs
class Multi_Head_Attention(nn.Module):
def __init__(self, config):
super().__init__()
embed_dim = config.hidden_size
head_num = config.num_attention_heads
head_dim = embed_dim // head_num
self.heads = nn.ModuleList(
[Attention_Head(embed_dim, head_dim) for _ in range(head_num)]
)
self.output_linear = nn.Linear(embed_dim, dembed_dim)
def forward(self, hidden_state):
x = torch.cat([h(hidden_state) for h in self.heads], dim=-1)
x = self.output_linear(x)
return x
class FeedForward(nn.Module):
def __init__(self, config):
super().__init__()
self.linear_1 = nn.Linear(config.hidden_size, config.intermediate_size)
self.linear_2 = nn.Linear(config.intermediate_size, config.hidden_size)
self.gelu = nn.GELU()
self.dropout = nn.Dropout(config.hidden_dropout_prob)
def forward(self, x):
x = self.linear_1(x)
x = self.gelu(x)
x = self.linear_2(x)
x = self.dropout(x)
return x
class Transformer_Encoder(nn.Module):
def __init__(self, config):
super().__init__()
self.embeddings = Embeddings(config)
self.layers = nn.ModuleList([TransformerEncoder(config)
for _ in range(config.num_hidden_layers)])
self.layer_norm_1 = nn.LayerNorm(config.hidden_size)
self.layer_norm_2 = nn.LayerNorm(config.hidden_size)
self.attetion = Multi_Head_Attention(config)
self.feed_forward = FeedForward(config)
def forward(self, x):
x = self.embeddings(x)
for layer in self.Layers:
x = Layer(x)
hidden_state = self.layer_norm_1(x)
x = x + self.attention(hidden_state)
x = x + self.feed_forward(self.layer_norm_2(x))
return x
위의 논문에서는 Convolution, Recurrent 등의 신경망의 구성요소를 모두 제거하고
"오로지 Attention만으로 신경망을 구현한다."
cf. 문맥 고려 임베딩(Contextualized Embedding)은 transformer가 개발되기 전, ELMo같은 언어모델에서 모든 토큰 임베딩을 비율을 달리해 통합하여 문맥을 내포하도록 하는 방법이다.
transformer가 한번에 처리하기에 이로 인해 순환신경망이 갖는 bottleneck문제를 해결할 수 있다.
🧐 기본적인 Architecture
<Encoder> 단어는 embedding을 통해d차원의 embedding벡터로 표현된다. (논문에서는d= 512를 사용) Inputs라는 부분에 입력이 되며, 이때 Sequential 구조가 아님을 알 수 있다. 즉, transformer는 모든 단어를"한번에 입력"한다. 이렇게"한번에 입력"받는 방식은"Self-Attention"을 가능하게 한다.
{Positional Encoding} 단어의 위치정보를 보완하기 위해 positional encoding을 통해"embedding벡터에 위치정보를 더한다".
{MHA : Multi-head Attention} Encoder에MHA(Multi-Head Attention)층과FF(Feed Foward)층이 존재. 이때,MHA층은"Self-Attention"을 수행한다! - multi-head라는 말처럼h개 head가 독립적으로 self-attention을 수행, 결과를 결합한다. - MHA층의 출력은 FF층의 입력이 된다. (MHA->FF) - 또한, FF(Feed Forward)층은FC(Fully-Connected) layer로 이루어진다.
MHA층과 FF층 모두Add&Norm을 적용한다. -Add는 Shortcut Connection을 -Norm은 layer Normalization을 의미한다. - Nx는 Encoder block이 N개 연결되었다는 것을 의미한다. (논문에서는N=6을 사용)
<Decoder> Encoder처럼 단어 embedding과 Positional Encoding을 통해 변환된 단어들이"한번에 입력"된다. 예를들어, 한국어문장은 Inputs에, 영어문장은 Outputs에 입력된다.
- Decoder에는②~③에 표시된 2개의MHA층과FF층이 존재하며 출력에Add&Norm을 적용한다. - 이후 출력층은 "softmax"를 통해 확률벡터를 출력하며, 이런 Decoder block이 N개 연결되어 있다. ①~③은 3개의 MHA층으로 Attention을 담당하는 핵심요소이다. -①은Encoder에서 입력문장을 구성하는 단어간의 Attention을 처리한다. 같은 문장을 구성하는 단어간의 Attention이기에 이를 "Self-Attention"이라 부른다.
-② Masked MHA의 의미는 다음과 같다. Decoder는 i일 때, 1, 2, ..., i-1까지만 관찰해야한다. 그렇기에Mask를 사용해 i+1, i+2, ... 등을 감추어야(masked) 한다.
-③은Encoder가 처리한 입력과 Decoder가 처리하고있는 출력사이의 Attention을 다룬다. 따라서③은"Self-Attention이 아니다!!" 이때, Encoder의 state벡터는 key와 value이고 Decoder의 state는 query로 작용하며 Encoder와 Decoder는③의 MHA를 통해 정보를 교환한다.
①과②로 표시한MHA(Multi-Head Attention)층의 "Self-Attention"은 transformer의 main idea이다.
이제 전반적인 Transformer의 Architecture를 보았으니 좀 더 세부적으로 Encoder와 Decoder의 동작에 대해 설명하겠다.
[Encoder의 동작과정]
🧐 Input Embedding. &. Positional Encoding encoder는 입력문장의 단어를 임베딩 후d_model차원의 벡터로 변환한다. (논문에서는 d=512로 설정) 또한, 모든 단어를 "한번에 입력"하기 위해 문장을T×d_model 크기의S행렬로 표현한다. (이때,T는 단어의 개수이다.)
행렬S의 모든 행이 동시에 처리되서순서정보를 신경망이 얻지 못할 가능성을 배제하기 위해위치정보를 표현한 행렬P를S행렬에 더해X행렬을 만들고X를 신경망에 입력한다. 이때, 3가지 행렬 모두 같은 size를 갖는다. 이 과정을 "Positional Encoding"이라 한다. 위치행렬P를 생성하는 여러 방법 중, 아래 식과 같은 sin, cos함수를 사용한다.
🧐 Self-Attention X행렬에 대해①의 MHA로 "Self-Attention"을 수행한다.
Self-Attention을 구현하는 여러 방법 중 transformer architecture를 소개한 "Attention is All You Need"논문에서 다룬"Scaled dot-product Attention"이 가장 일반적이며 이 메커니즘은 4단계로 구현된다. - 각 token embedding을 Q, K, V 3개의 벡터로 투영
- Attention Score 계산: similarity function를 사용해 Q와 K가 얼마나 관련되는지 계산 이때, QK의 dot곱 값이 커지면 비슷하다는 것을 의미한다. 또한, n개의 input token이 있는 sequence일때, 크기가 n×n인 attention matrix가 생성된다.
- Attention weight를 계산: 일반적으로 dot곱은 임의의 큰 수를 생성→ 훈련과정이 불안정해진다. 이를 처리하기 위해 Attention score에 scaling factor(인자)를 곱해 분산을 정규화하고 softmax를 적용해 모든 열 합이 1이 되게 한다. 이를 통해 만들어진n×n행렬에는 attention weightwij가 넣어진다.
- token embedding update, attention weight가 계산되면 벡터 v를 곱한다.
"Self-Attention의 본질" 이때, query는 확장이 필요한데, 하나의 벡터q로 표현하는 Bahdanau attention과 달리 Self-Attention에서는 query가T개의 행을 갖는 행렬Q가 되기에 확장된 query행렬은 다음과 같이 나타내며, 이때Q, K, V는 모두T×d_model크기의 행렬이고 이 식의 결과인C도 T×d_model행렬이다. "Self-Attention 구현의 가장 단순한 방법"은 바로Q, K, V를 모두X로 설정하고 위의 식을 적용하는 것이다. 하지만 transformer는 이런 단순한 방법이 아닌 query, key, value를 가중치 행렬 WQ, WK, WV를 이용해 X를 변환해 사용하며, 이때, QKT는 √d_key로 나누어 정규화를 거친다. 이를 식으로 나타내면 아래와 같다. X:T×d_model 행렬 WQ:d_model×d_key 행렬 WV:d_model×d_value 행렬 Q, K:T×d_key 행렬 V:T×d_value 행렬 (보통d_model>d_value,d_key 로 설정한다.)
🧐 Multi-Head Attention Architecture에서①로 표시한 MHA에는 여러 head가 있으며각 head는고유한 transform matrix WQ, WK, WV를 갖고 softmax식을 이용해"Self-Attention"을 독립적으로 수행해 상호보완한다. 즉, 여러 head로 self-attention을 진행, 결과를 결합해 성능향상을 진행시킨다.
따라서 MHA의 동작을 아래와 같은 식으로 정의한다.
예를 들어보자.
이후 MHA를 통과한C행렬은 Add&Norm층을 통과하는데, Skip connection과 Layer Normalization을 진행한다. - Skip-connection: MHA층의 출력특징맵C와 입력특징맵X를 더하는 연산 - Layer Normalization: mini-batch를 구성하는 sample별로 특징맵의 분포가 N(0,1)이 되게하는 방법이다.
🧐 position-wiseFeedForward layer MHA에서 사용된 아래 식에 따라 출력한X'을 입력으로 받아X''을 출력한다. 아래 X''을 구하는 식을 보면 MLP를 구하는 방법처럼 linear transformation을 사용하는 것을 알 수 있다. X와X''은 모두 encoder의 최초 입력X와 같이 Txd의 행렬이다. 이는 transformer가신경망을 흐르는 tensor의 모양이 유지시켜 행렬연산이 원활히 이루어짐을 알 수 있다.
position-wise FF라 부르는 이유??
[Decoder의 동작과정]
encoder와 거의 비슷하게 동작하기에 다른 부분에 주안점을 두어 설명을 진행한다.
🧐 Masked Multi-Head Attention 층 Decoder에②로 표시된 Masked MHA층은 행렬일부를 마스크로 가린다는 점을 제외하면①의 MHA층과 같다. i = 1일 때, <SOS>를 입력하면 모델은 'That'을 예측하고 i = 2일 때, 'That'을 보고 'can't'를 예측하는 이런 방식을 재귀적으로 수행하는 자귀회귀방식을 적용해 언어번역을 진행한다.
다만, 학습단계는 추론단계와 상황이 다른데, - 예측단계는 출력문장을 모른채 동작하지만 - 학습단계는 입출력문장이 모두 주어지고 자귀회귀방식을 사용가능하다. (다만 교사강요; teacher forcing방식을 주로 사용한다.) 이는 잘못 예측했을 경우, 이후 단어는 계속 틀릴 가능성이 높기 때문이다. 교사강요에서는 '<SOS> That can't turn red by itself <EOS>'를 decoder에 한꺼번에 입력한다.
transformer도 교사강요로 학습을 수행하는데,예측단계의 자기회귀를 모사한 "Masking"을 사용한다.
Masked MHA층은 이 행렬의 대각윗행렬의 모든 원소를 무한대에 가까운 음수로 설정하면, 이전에 나온 단어들에만 주목할 수 있게 되는데, 예를 들어보면 아래와 같다.
🧐 Encoder와 연결된 Multi-Head Attention 층 (Not Self-Attention) 위의 그림에서③으로 표시된 MHA층은 encoder와 decoder가 상호작용한다. ①:이 MHA층은 입력문장내의 단어간의 Attention을 처리하는 "Self-Attention"이다. ②:이 MHA층은 출력문장내의 단어간의 Attention을 처리하는 "Self-Attention"이다. ③:이 MHA층은 Decoder로 입력된 문장의 단어가 Encoder로 입력된 문장의 단어에 주목할 정보를 처리한다. "Self-Attention"이라는 점만 제외하고 모든 연산은①과②의 MHA층과 동일하다.
①에서의 식은 "Self-Attention"을 처리하기에 같은 문장에서 구한 행렬X만 존재한다. ∴ query와 key, value 계산 시 모두X를 사용한다.
하지만③의 MHA층은 encoder의X와 decoder의X가 존재한다. 이를 구별하기 위해X_enc,X_dec라 할 때, key와 value는X_enc를 사용하고 query는X_dec를 사용한다. 이를 통해 query가 key와 value에 주목하는 정도를 계산할 수 있으며 아래와 같이 나타낼 수 있다. 여기서 MHA층의 출력 행렬은 Architecture에서 볼 수 있듯 Add&Norm층, FC층, Add&Norm층을 거친 후 Linear와 softmax로 구성된 출력층으로 전달된다.
[Transformer의 주요 도전과제]
언어 - pretrain이 대부분 영어로 되어 data가 소량이거나 거의 없을 때
Data 가용성 - labeling된 data가 없거나 소량인 경우
긴 문서 처리 - Self-Attention의 경우, text길이가 문단정도될 때, 잘 동작 - 문서와 같이 긴 text는 cost가 많이 든다.
불투명성 - 다른 Deep Learning모델과 마찬가지로 Black-Box모델이다. - 즉, 모델의 예측이유를 설명하기 어렵거나 불가하다.
편향 - 인터넷의 text data로 pretrain을 진행하기에 data에 있는 편향이 모델에 그대로 전이될 수 있다.
🧐 RNN (RecurrentNeuralNetwork) 일반적으로 i의 단어는 그 이전에 발생한 i-1개 단어와 상호작용한다.
RNN
🧐 Long Term Dependency과 LSTM(LongShort-Term-Memory)
Long Range Dependency: RNN은 시간을 처리할 수 있는 능력을 갖추지만 길이가 긴 sample에는 한계가 있다. hi는 1, 2, ..., i 순간에 발생하는 단어의 정보가 혼합되기에 오래된 단어의 정보는 희미해진다. 즉, 앞쪽단어와 멀리있는 단어가 밀접하게 상호작용하는 long-range dependency를 제대로 처리하지 못하는 문제가 발생한다.
LSTM: RNN을 개조해 long-term dependency를 처리하는 능력을 강화한다. input과 output을 열거나 막는 gate를 두어 선별적으로 기억하는 기능으로 여닫는 정도를 조절한다. 이때, 여닫는 정도는 학습으로 알아낸 가중치로 결정된다.
ex) 한국어→영어로 번역 시, 둘의 문장길이가 달라 seq2seq model이 필요하다.
- 학습 시 Decoder의 input부분과 output부분이 모두 동작한다. 즉, 정답에 해당하는 출력을 알려주는 교사강요(teacher forcing)방법을 사용한다.
- 예측 시 정답을 모르기 때문에 위의 회색표시한 input 부분을 제외하고 자기회귀(auto-regressive) 방식으로 동작한다. 자기회귀에서 <SOS>가 입력되면 첫 단어 'That'을 출력하고 'That'을 보고 그 다음 둘째 단어 'can't'를 출력한다. 즉, 이전에 출력된 단어를 보고 현재단어를 출력하는 일을 반복하며, 문장끝을 나타내는 <EOS>가 발생하면 멈춘다.
- 한계 : 가장 큰 문제는encoder의 마지막 hidden state만 decoder에 전달한다는 점이다. 그림에서 보면h5만 decoder로 전달된다. 따라서 encoder는마지막 hidden state에 모든 정보를 압축해야하는 부담이 존재한다.
[query-key-value로 계산하는attention] _ NLP
🧐 query-key-value
QKV: attention을 계산하는 방법을 여러가지인데, 최근에는 query가 key와 유사한 정도를 측정하고 유사성 정보를 가중치로 사용해 value를 가중합하는 방법을 주로 사용한다.
벡터의 차원을d라 하면,q는 1xd행렬이고K와V는nxd행렬이다. 이때,n은 key와 value가 갖는 벡터의 개수이다.
[seq2seq withAttention] _ NLP
seq2seq는 입력문장의 모든 정보를 encoder의 마지막 hidden stateh5에 압축해 넣어야하는 부담이 있다. Bahdanau는 아래 식의 attention을 이용해 decoder가 encoder의 모든 state(h1,h2, ... ,h5)에 접근할 수 있게 허용하여 성능을 향상한다.[Bahdanau2014;https://arxiv.org/abs/1409.0473]
🧐Bahdanau Attention 위의 seq2seq의 경우, decoder는 i=6일 때, encoder가 i=2일 때, 단어 '저절로'에 주목해야 'itself'라는 단어를 제대로 생성할 수 있다. decoder가 i=6일 때, (.01 .9 .02 .03 .04)처럼 2번째 원소값이 큰 attention vectora를 생성하면 encoder의 두번째 단어 '저절로'에 더 주목할 수 있어 성능이 향상될 수 있다.
- 이에 대해 query, key, value가 무엇이 되어야 위와 같이 될 수 있는지 살펴보자.
토큰화(tokenization)란 문장을 토큰으로 나누는 과정으로 수행대상에 따라 다음 세 방법이 있다. - 문자 - 단어 - 서브워드
§ 문자 단위 토큰화 - 한글 위주로 표현된 데이터로 언어 모델을 만든다 하자. 한글 음절 수는 1만1172개이므로 알파벳, 숫자 등을 고려 해도 어휘 집합 크기는 최대 1만5000개를 넘기 어렵다. 게다가 해당 언어의 모든 문자를 어휘 집합에 포함하므로 미등록 토큰(unknown token) 문제로부터 자유롭다. 미등록 토큰이란 어휘 집합에 없는 토큰이다. (주로 신조어 등에서 발생)
하지만 문자 단위로 토큰화를 수행할 경우 단점도 있는데, 각 문자 토큰은 의미 있는 단위가 되기 어려운데, 예를 들어 어제와 어미간의 어의 구분이 모호해지는 것처럼 단점이 존재한다. 어제 카페 갔었어 > 어 / 제 / 카 / 페 / 갔 / 었 / 어 어제 카페 갔었는데요 > 어 / 제 / 카 / 페 / 갔 / 었 / 는 / 데 / 요
뿐만 아니라 문자 단위 토큰화는 앞의 단어 단위와 비교할 때 분석 결과인 토큰 시퀀스의 길이가 상대적으로 길어졌음을 확인할 수 있다. 언어 모델에 입력할 토큰 시퀀스가 길면 모델이 해당 문장을 학습하기가 어려워지고 결과적으로 성능이 떨어지게 된다.
§ 단어(어절) 단위 토큰화 - 가장 쉽게 생각해보면 공백으로 분리할 수 있다. 어제 카페 갔었어 > 어제 / 카페 / 갔었어 어제 카페 갔었는데요 > 어제 / 카페 / 갔었는데요
공백으로 분리하면 별도의 토크나이저를 쓰지 않아도 된다는 장점이 있다. 다만, 어휘 집합의 크기가 매우 커질 수 있는데, 갔었어, 갔었는데요 처럼 표현이 살짝만 바뀌어도 모든 경우의 수가 어휘 집합에 포함돼야 하기 때문이다.
만약 학습된 토크나이저를 사용하면 어휘 집합의 크기가 커지는 것을 조금 완화할 수는 있다. 예를 들어 같은 문장을 은전한닢으로 토큰화하면 다음과 같다. 예시가 적어서 효과가 도드라져 보이지는 않지만, 의미 있는 단위로, (예를 들면 갔었) 토큰화해 어휘 집합이 급격하게 커지는 것을 다소 막을 수 있다. 어제 카페 갔었어 > 어제 / 카페 / 갔었 / 어 어제 카페 갔었는데요 > 어제 / 카페 / 갔었 / 는데요
그렇지만 위 같은 토크나이저를 사용하더라도 어휘 집합 크기가 지나치게 커지는 것은 막기 어려운데, 보통 언어 하나로 모델을 구축할 때 어휘 집합 크기는 10만 개를 훌쩍 넘는 경우가 다반사이기에 어휘 집합 크기가 커지면 그만큼 모델 학습이 어려워질 수 있다.
§ 서브워드 단위 토큰화 - 단위 토큰화는 단어와 문자 단위 토큰화의 중간에 있는 형태로. 둘의 장점만을 취한 형태이다. 어휘 집합 크기가 지나치게 커지지 않으면서도 미등록 토큰 문제를 피하고, 분석된 토큰 시퀀스가 너무 길어지지 않게 한다. - 대표적인 서브워드 단위 토큰화 기법이라면 바이트 페어 인코딩을 들 수 있는데 아래에서 소개하겠다.
※ Byte Pair Encoding Algorithm
- BPE는 정보를 압축하는 알고리즘으로 원래 제안된 것으로 데이터에서 최빈문자열을 병합해 압축하는 기법이다.
최근에는 자연어 처리모델에서 쓰이는 토큰화 기법이다.
GPT 모델은 BPE기법으로 토큰화를 수행
BERT모델은 BPE와 유사한 워드피스(wordpiece)를 토크나이저로 사용
예를 들어 다음과 같은 데이터가 있다고 가정하자.
aaabdaaabac
BPE는 데이터에 등장한 글자(a,b,c,d)를 초기 사전으로 구성하며, 연속된 두 글자를 한 글자로 병합한다.
이 문자열에선aa가 가장 많이 나타났으므로 이를Z로 병합(치환)하면 다음과 같이 압축할 수 있다.
ZabdZabac
이 문자열은 한번 더 압축 가능한데, ab가 가장 많이 나타났으므로 이를Y로 병합(치환)한다.
ZYdZYac
물론ab대신Za를 병합할 수도 있지만 둘의 빈도수가 2로 같으므로 알파벳 순으로 앞선ab를 먼저 병합한다.
ZY역시X로 병합할 수 있습니다. 이미 병합된 문자열 역시 한 번 더 병합할 수 있다는 얘기로 다음과 같다.
XdXac
※ BPE 어휘집합 구축하기.
1. pre-tokenize 진행 (말뭉치를 준비 후 모든 문장을 공백으로 나눠줌. 물론 다른 기준으로 나눌 수도 있음)
2. pre-tokenize 진행 후 그 빈도를 모두 세어 초기 어휘 집합을 구한다.
3. 위의 어휘집합을 바이그램 쌍(토큰을 2개씩 묶어 나열)으로 만들고 바이그램 쌍을 합친다.
4. 가장 많이 등장한 바이그램쌍을 합쳐 집합에 추가 (위를 예로 들면 u, g를 합친 ug를 바이그램에 추가)
>> b / g / h / n / p / s / u / ug
이후 계속 사용자가 정한 크기 전까지 반복해서 진행.
5. 입력이 들어오면 입력을 문자단위로 분리 후 병합의 우선순위(by 빈도)에 따라 merge 진행.
만약 input으로 mug가 들어온다면?
따라서 출력은 다음과 같이 <unk>, ug로 나오며 <unk>는 unkown token(미등록 토큰)을 의미.
※ WordPiece.
BPE와 비슷하지만 빈도를 기준으로 merge를 진행하는 BPE와는 달리
Wordpiece는 likelihood를 기준으로 likelihood가 높은 쌍을 merge한다.
자연어(natural language)란 우리가 일상 생활에서 사용하는 언어로 자연어 처리(natural language processing)란 이러한 자연어의 의미를 분석하여 컴퓨터가 처리하는 것이다. 좀 더 구체화 시키면 입력(자연어)을 받아서 해당 입력이 특정 범주일 확률을 반환하는 확률함수이다. 이런 확률을 기반으로 후처리(post processing)을 해서 자연어형태로 바꿔줄 수 도 있다.
자연어 처리는 음성 인식, 내용 요약, 번역, 사용자의 감성 분석, 영화 평론의 긍정 및 부정, 텍스트 분류 작업(스팸 메일 분류, 뉴스 기사 카테고리 분류), 질의 응답 시스템, 챗봇과 같은 곳에서 사용되는 분야 등 다양하다.
이런 자연어 처리에 다양한 모델이 사용되고 요즘 가장 인기있는 모델은 단연, 딥러닝이다. 딥러닝 가운데서도 딥러닝 기반 자연어 처리 모델에는 BERT, GPT 등이 있다.
※ Task란?
- 준비한 모델, 최적화 방법 및 학습과정 등이 정의되어 있는 것. - 우리는 특정 조건에서 모델의 output과 정답의 차이를 작게하는게 중요, optimizer, learning rate scheduler를 정의.
모델 학습은 batch단위로 이뤄지는데, batch를 모델에 입력한 후 모델 출력을 정답과 비교해 차이를 계산한다. 그 후 차이를 최소화하는 방향으로 모델을 update하는데, 이런 일련의 과정을 step이라 하며 task의 학습과정은 1step을 기준으로 정의한다.
※ Transfer Learning
특정 data를 학습한 모델을 다른 data train을 할 때 재사용하는 방법
- 장점: 학습속도가 기존보다 빠르고 새로운 data를 더 잘 수행할 수 있어 BERT, GPT 등도 transfer learning이 적용된다.
§ Upstream Task - Transfer Learning이 주목된 것은 upstream task와 pretrain덕분으로 자연어의 다양한 context를 모델에 내재화하고 다양한 down stream task에 적용해 성능을 끌어올렸기 때문이다. 이는 기존의 지도학습과 달리 다량의 학습데이터를 웹문서, 뉴스 등의 쉽게 구할 수 있는 데이터와 이를 upstream task를 통해 수행하여 성능이 월등히 좋아졌다. 즉, 데이터 내에서 정답을 만들고 이를 통해 모델을 학습하는 자기지도학습(self-supervised learning)을 진행.
▶ Masked Language Model - 아래와 같이 빈칸에 들어가야할 단어에 대해 주변 문맥을 보고 해당 빈칸의 단어에 해당하는 확률은 높이고 나머지 단어들의 확률을 낮추는 방향으로 모델 전체를 update한다.
§ Downstream Task - 위에서 진행한 upstream으로 pretrain을 한 이유는 downstream task을 잘하기 위해서이다. 이런 downstream task는 자연어처리의 구체적인 과제들이다. 예를 들자면 분류(classification)처럼 입력이 어떤 범주에 해당하는지 확률형태로 반환한다. - 문장생성을 제외한 대부분은 pretrain을 마친 Masked Language Model (BERT, etc.)을 사용한다.
ex. 문서분류, 자연어 추론, 개체명 인식, 질의응답, 문장생성 등에 대해 처리한다.
▶ Fine-tuning - downstream task의 학습방식 중 하나로 pretrain을 마친 모델을 downstream task에 맞게 update하는 기법이다.