본문 바로가기
Coursera 강의/Deep Learning

Sequence models & Attention mechnism / Speech recognition(CTC)

by 별준 2020. 12. 28.
해당 내용은 Coursera의 딥러닝 특화과정(Deep Learning Specialization)의 다섯 번째 강의 Recurrent Neural Network를 듣고 정리한 내용입니다. (Week 3)

Various sequence to sequence architectures

[Basic Models]

이번 강의부터는 Sequence-to-sequence 모델에 대해서 배우게 된다. Basic model부터 시작해서 Beam search와 attention model에 대해서 알아보자.

 

'Jane viste l'Afrique en septembre'라는 프랑스어로 된 문장을 영어 문장으로 변환하고 싶다면, 프랑스어로 된 문장 시퀀스를 \(x^{<1>}\)부터 \(x^{<5>}\)까지 표시하고, \(y^{<1>}\)에서 \(y^{<6>}\)까지 사용해서 output 시퀀스 단어를 표시한다.

그렇다면 어떻게 새로운 network를 학습해서 시퀀스 x를 입력으로 하고 시퀀스 y를 출력할 수 있을까?

위와 같은 모델을 통해서 가능한데, 이 모델은 인코더(Encoder) 네트워크와 디코더(Decoder) 네트워크로 구성된다.

인코더 네트워크를 통해서 프랑스어 단어를 입력 받고, 디코더 네트워크를 통해서 영어 단어 하나하나를 출력하게 된다.

이 모델은 충분한 프랑스어 문장과 영어 문장의 데이터셋이 있을 때, 효과가 있다는 것이 밝혀졌다.

 

이와 비슷한 구조로 Image captioning(이미지 캡션)도 수행할 수 있다.

이 슬라이드에서는 pre-trained된 AlexNet을 사용해서, 마지막 softmax layer를 삭제한 후에 AlexNet으로 4096 차원의 특성 벡터를 출력하게 되는데, 이 부분이 이미지의 인코더 네트워크라고 할 수 있다. 그리고 RNN 모델을 디코더 네트워크로 사용해서 4096차원의 특성벡터를 입력으로 사용해서 이미지를 설명하는 단어들이 출력으로 나오게 된다.

 

위에서 언급한 두 모델에서 우리는 무작위로 선택된 번역을 원하지 않거나, 가장 정확한 번역을 원할 수 있고, 이미지 캡션 또한, 무작위의 캡션을 원하지 않고, 가장 정확한 캡션을 원할 수 있다. 

다음으로 어떻게 정확한 번역이나 캡션을 생성할 수 있는지 알아보도록 하자.

 

[Picking the most likely sentence]

Machine translation(기계번역) 모델과 강의의 첫 주에 배웠던 language 모델은 몇 가지 비슷한 점과 차이점이 있다.

기계번역은 conditional language model(조건부 언어모델)로 생각할 수 있는데, 아래의 기계번역 모델의 구성을 살펴보면, 뒤쪽의 디코더 네트워크가 language 모델과 유사한 것을 볼 수 있다.

즉, language 모델은 0벡터에서 시작했지만, 기계번역 모델에서는 인코더 네트워크를 통과한 출력이 language 모델로 입력되는 것과 같다.

 

그리고, 입력으로 프랑스어 문장 x과 출력인 영어 문장 y가 주어진다면, 모델은 입력(프랑스어문장)에 대한 출력(영어문장)의 확률을 알려준다.

\[P(y^{<1>}, \cdots, y^{<T_y>} | x^{<1>}, \cdots, x^{<T_x>})\]

 

결국 우리가 위 모델을 통해서 프랑스어 문장을 영어로 번역하려면, 가장 높은 확률의 번역(\(P^{<1>}, \cdots, y^{<T_y>}|x)\))을 찾아야 한다.

위에서 언급했지만, 모델은 입력인 프랑스어 문장에 대해서 영어 문장들의 조건부 확률을 출력한다.

그래서 모델의 확률 분포를 얻어서 샘플링했을 때, 괜찮은 번역을 얻을 수도 있고, 좋지 않은 번역을 얻을 수도 있다.

그렇기 때문에 좋은 번역을 얻기 위해서 우리는 조건부 확률을 최대로하는 영어 문장을 찾아야 한다.

즉, 기계번역 시스템을 개발할 때, 우리가 해야할 일 중의 하나는 이 조건부 확률을 최대화하는 알고리즘을 고안하는 것이다. 자주 사용되는 알고리즘은 Beam Search인데, 이것은 잠시 후에 알아보자.

 

Greedy 알고리즘도 있는데, 이 알고리즘은 사용하면 안된다. 이 알고리즘은 첫 번째 단어를 예측할 때, 가장 높은 확률의 단어 하나만 선택한 후에, 가장 높은 확률 두 번째 단어를 선택하고, 그후에 가장 높은 확률의 세 번째 단어를 선택한다. 

우리가 원하는 것은 전체 결과 시퀀스의 확률을 최대화하는 것이기 때문에, 가장 높은 단어만을 선택하는 접근 방법은 효과가 없다.

위 예시처럼, 'Jane is'까지 두 단어를 선택한 후에, 세번째 단어를 선택할 때를 살펴보자.

Jane is 다음에는 going이라는 단어가 더 흔하게 사용되기 때문에 greedy 알고리즘으로는 going이 선택될 확률이 높다. 하지만, 전체 결과를 보다시피, going을 선택한 문장은 잘못된 번역이라는 것을 확인할 수 있다. 이처럼 가장 높은 확률의 단어만을 찾아가는 접근법은 효과가 없다는 것을 볼 수 있다.

 

따라서, 마지막 단어까지 도달하면서 가장 높은 확률의 문장을 찾아야하는데, voca size를 고려하면 모든 단어들을 평가기는 불가능하다. 따라서 heuristics 탐색 알고리즘을 사용해서 대략적인 최대치를 찾는다. 항상 최대 확률의 결과를 보장하지는 않지만, 이정도로 충분할 수 있다.

 

[Beam Search]

Beam Search는 가장 확률이 높은 output을 찾기 위해서 사용되는 알고리즘이다. Greedy 알고리즘은 가장 확률이 높은 단 하나의 단어만을 계속 선택하지만, Beam Search 알고리즘은 다양한 경우를 고려한다.

 

Beam Search가 어떻게 동작하는지 살펴보자.

먼저 Beam search는 B라는 매개변수를 가지고 있는데, 이것은 Beam width라고 불린다. 여기에서 B=3으로 설정했는데, 이는 beam search가 3개의 가장 높은 가능성을 고려한다는 것을 의미한다. 

그래서 Step 1에서 가장 확률(\(P(y^{<1>}|x)\))이 높은 단어 3개 'in', 'jane', 'september'를 선택하게 된다.

 

Step 2에서는 두 번째에 위치하는 단어를 예측하는데, Step 1에서 선택된 3개의 단어의 조건부 확률을 구한다. 즉, Step 1에서 선택한 3개의 단어를 Step 2의 입력으로 사용해서 가장 높은 확률(\(P(y^{<1>}, y^{<2>}|x) = P(y^{<1>}|x)P(y^{<2>}|x, y^{<1>})\))을 가지는 3개의 출력을 다시 선택하게 되는 것이다.

 

결과적으로 'in September', 'jane is', 'jane visits'가 선택되었다고 하자.

Step 3도 동일하게 진행하고, 가장 높은 가능성을 가진 3개의 확률을 선택하게 된다. 이렇게 계속 진행하다가 <EOS>를 만나게 되면, 종료하게 되고 영어 문장을 출력하게 된다.

 

위 과정은 B=3일 때의 탐색 과정을 살펴본 것이고, 만약 B=1이라면 Greedy 알고리즘과 동일하게 된다.

 

다음으로 Beam search를 더욱 극대화할 수 있는 몇 가지 팁에 대해서 알아보자.

 

[Refinements to Beam Search]

 

Beam Search는 위와 같이 결국에는 조건부 확률의 최대가 되는 경우를 찾는 것이다. 그리고 조건부 확률을 풀어서 쓰면 다음과 같다.

\[P(y^{<1>}, \cdots, y^{<T_y>}|x) = P(y^{<1>}|x)P(y^{<2>}|x, y^{<1>})\cdots P(y^{<T_y>}|x, y^{<1>}, \cdots, y^{<T_y - 1>})\]

P는 확률이기 때문에 모든 값이 1보다 작고, 결국 P를 곱하다 보면 그 값은 1보다 훨씬 작아지게 된다. 특히나, 단어가 많을 수록 그 값은 기하급수적으로 작아지며, 컴퓨터가 그 값을 정확하게 표현(저장)하기에는 너무 작아질 수도 있다.

또한 1보다 너무 작아지게 되면, 모델이 짧은 번역을 더 선호하게 되는 문제가 발생할 수도 있다.(short output 선호)

 

이런 문제점을 방지하기 위해서 확률에 log를 취해서 최대가 되는 값을 찾는다.

log함수도 마찬가지로 증가하는 함수이기 때문에 \(logP(y|x)\)를 최대화하는 것은 P(y|x)를 최대화하는 것과 동일하며, 이렇게 log를 취해주게 되면 수치적으로 더 안정적이게 된다.

 

그런데, 이 경우에도 확률은 항상 1보다 작거나 같기 때문에, 더 많은 단어가 있을수록 음수가 점점 커지게 된다.

그래서 알고리즘이 더욱 잘 동작하도록하는 방법이 있는데, 그 방법은 단어의 수 \(T_y\)로 normalization하는 것이다.

또한, \(T_y\)가 너무 큰 경우의 페널티를 감소시키기 위해서 \(\alpha\)승을 사용할 수도 있는데, 위 방법은 이론적인 근거가 딱히 존재하지는 않지만, 경험과 실험을 통해서 효과가 있다는 것을 발견했다.

 

(위 방법을 normalized log propability라고 부르기도 한다.)

 

마지막으로 Beam width B에 대해서 이야기해보자.

B의 크기는 어떻게 선택해야 할까?

만약 B의 크기가 아주 크다면, 많은 가능성들 고려하게 되고, 따라서 더 좋은 결과를 얻는 경향이 있다. 하지만, 더 느려지고 메모리도 많이 차지하게 된다.

반면, B의 크기가 매우 작다면, 고려하는 경우의 수가 적기 때문에 대체로 좋지 않은 결과를 얻게 되지만, 속도는 더 빠르고 메모리 또한 덜 차지하게 된다. 

예시는 3개의 가능성을 살펴보았지만(B=3), 실제 시스템에서는 10개를 사용하기도 하고, 최고의 결과를 위해서 1000~3000개를 사용하기도 한다.

 

그리고 BFS나 DFS와 같은 탐색 알고리즘과 다르게, Beam 탐색은 훨씬 더 빠른 알고리즘이다. 하지만, 정확한 최대값을 보장하지는 않는다는 것을 기억하자.

 

[Error analysis in beam search]

이번에는 딥러닝 특화과정 3번째 강의에서 살펴보았던 내용과 연관있는 Error analysis에 대해서 살펴보자.

(참고:

2020/10/28 - [Coursera 강의/Deep Learning] - ML Strategy 2-1 (Error Analysis, Data mismatched))

Beam Search는 휴리스틱 탐색 알고리즘이며, 항상 best 확률의 문장을 출력하지는 않는다. 

이때, 만약 Beam Search에서 mistake가 있으면 어떻게 해야할까?

이번에는 Error analysis를 통해서, beam search에 문제가 있는지 확인할 수 있는 방법에 대해서 알아보자.

 

프랑스어 문장을 예시로, 아래에 인간이 번역한 것(\(y^\star\))과 알고리즘 모델이 번역한 결과물(\(\hat{y}\))이 있다.

여기에서 유용한 방법은 모델을 사용해서 \(P(y^\star |x)\)와 \(P(\hat{y}|x)\)를 계산하는 것이다. 그리고 둘 중의 어느 값이 더 큰 지 확인한다. 

이렇게 두 값을 비교하는 것으로 모델의 오류(RNN의 문제인지, Beam Search의 문제인지)를 명확하게 설명할 수 있다.

만약 \(P(y^\star |x)\)가 \(P(\hat{y}|x)\)보다 더 크다면, Beam Search가 더 높은 확률의 번역을 선택하지 못한 것이므로 Beam Search 알고리즘에 문제가 있다고 판단할 수 있다.

반대로 \(P(y^\star |x)\)가 \(P(\hat{y}|x)\)보다 작거나 같다면, RNN 모델이 잘못된 번역을 더 높은 확률로 예측했으므로, RNN 모델에 문제가 있다고 판단할 수 있다.

 

그리고 아래 과정을 통해서 RNN의 모델과 Beam Search 알고리즘에 의한 오류의 수를 파악할 수 있다. 이런 Error analysis process를 통해서 효율적으로 개발의 방향을 설정할 수 있다.

 

[Bleu(Blingual Evaluation Understudy) Score]

기계번역(Machine Translation)에서의 challenge 중의 하나는 꽤 괜찮은 번역을 여러 개 만들 수 있다는 것이다.

하나의 정답이 있는 이미지 인식과는 달리 여러가지의 좋은 정답이 있다면 기계번역 시스템은 어떻게 이것들을 평가할 수 있을까?

정확성을 측정하면되는데, 보편적으로 Bleu Score라는 방법이 사용된다.

 

아래 주어진 프랑스어 문장 'Le chat est sur le tapis'에 대해 괜찮은 번역이 두 개가 있다(Ref1, Ref2).

실제 두 번역은 잘 번역된 것이고, Bleu Score는 번역이 얼마나 괜찮은지 측정하는 점수를 측정할 수 있게 해준다. 만약 모델이 예측한 결과가 사람이 제공한 reference와 가깝다면 Bleu Score는 높게 된다.

Bleu Score는 직관적으로 기계가 생성하는 글의 유형을 최소한 인간이 만들어낸 reference에서 나타나는지 살펴보는 방법이다. 극단적인 기계번역(MT)의 결과를 가지고 어떻게 점수가 계산되는지 살펴보자.

MT output이 얼마나 괜찮은지 측정하는 한가지 방법은 출력된 각 단어를 보고 reference 안에 그 단어가 존재하는지 살펴보는 것이다. 이것을 MT output의 Precision(정밀도)라고 부른다.

MT output : 'the the the the the the the'에서 7개의 단어가 있으며, 이 단어는 Ref1이나 Ref2에 모두 나타난다.

따라서 이 단어들은 꽤 괜찮은 단어처럼 보일 수 있고, 정밀도는 7/7이 된다. 결과만 봐선 아주 좋은 결과같아 보인다.

이 MT output이 매우 정확하다는 것을 의미하지만 이것은 보다시피 유용한 방법이 아니다.

 

대신, 우리가 사용할 것은 Modified Precision이다. 이 방법은 각 단어에 대해서 중복을 제거하고, reference 문장에 나타난 최대 횟수만큼 점수를 부여한다. Ref1에서는 'the'가 2번 나타나고, Ref2에서는 'the'가 1번 나타난다. 따라서, Modified precision은 2/7가 된다.

 

방금까지 우리는 각 단어를 개별적(isolated word)으로 살펴보았다. 즉, 단어의 순서를 고려하지 않았다.

Bleu Score로 평가할 때, 단어 쌍으로 Bleu Score를 정의해서 사용할 수 있다.

bigrams에서 Bleu score는 MT output의 각 단어들을 서로 근접한 두 개의 단어들로 묶어서, Reference에 얼마나 나타나는지 체크해서 Modificed Precision을 계산한다.

즉, MT output 에서 각 단어 쌍들의 Count와, MT output의 단어쌍들이 Reference에 얼마나 등장하는지 Count해서 계산하게 된다.

 

unigrams와 bigrams에서 bleu score를 구하는 방법을 살펴보았고, n-grams로 확장하면 다음과 같이 계산할 수 있다.

만약 MT output이 Ref1이나 Ref2와 정확히 같다면, \(P_1, P_2\)는 1.0과 같다.

 

최종 Bleu Score를 만들기 위해서 \(P_n\)을 합치도록 한다.

\(p_n\)이 n-grams에서 bleu score고, 만약 1,2,3,4-grams를 사용한다면, 최종 Bleu score는 아래와 같이 계산될 수 있다.

\[\text{Combined Bleu score: }BPexp(\frac{1}{4}\sum_{n=1}^{4}p_n)\]

BP는 Brevity Penalty로 짧은 번역이 높은 score를 얻는 것에 대해 페널티를 부여하는 것을 의미한다.

 

Bleu Score는 완벽하지는 않지만 수치적으로 평가할 수 있는 꽤 괜찮은 Metric이다.

 

[Attention Model]

대부분의 기계번역은 Encoder-Decoder Architecture를 사용하고 있고, 하나의 RNN에서 입력 문장을 읽고, 다른 RNN에서 문장을 출력한다. 이 아키텍처에서는 일반적으로 짧은 문장에서 잘 동작하고, 입력 문장의 길이가 길어질수록 성능이 낮아져서 Bleu score가 낮아지는 것을 볼 수 있다(파란색 그래프).

 

여기에 Attention model을 사용하면 긴 문장에서도 성능을 유지할 수 있게 된다(초록색 그래프).

사람이 번역할 때, 문장 전체를 외워서 처음부터 번역하는 것이 아닌 중간중간 번역하는 것처럼 Attention model은 사람과 유사하게 번역한다. 매 예측시점마다 인코더에서의 입력 문장을 다시 참고하는데, 이때, 전체 입력 문장을 참고하는 것이 아닌 예측할 단어와 연관되는 부분만 집중해서('Attention') 참조하게 된다.

 

Attention model은 처음에 기계번역 용도로 개발되었지만, 여러 App 영역에서도 적용되고 있다.

 

그렇다면 Attention model이 어떤 방식으로 동작하는지 간단하게 살펴보자.

우선 Encoder에 해당하는 RNN model(BRNN)이 있다. 그리고 Decoder에 해당하는 RNN model을 사용하는데, 여기에 사용되는 activation을 헷갈리지 않기 위해서 s로 표기한다. 

간략하게 위 슬라이드를 설명하면, BRNN(Encoder)을 통해서 계산된 activation을 사용해서 C를 구하는데, 이때 일부 activation만 참조한다. 그리고, C를 Decoder의 입력으로 사용해서 단어를 예측한다. C를 계산하는 방법은 잠시 후에 설명하도록 한다.

 

다음 단어들도 동일한 방법을 사용해서 각 단어들을 예측하게 된다.

 

[Attention Model]

Attention model은 이름에서 알 수 있듯이 입력의 일부에 집중(attention)하도록 하는데, 첫 번째 단어를 예측하는 과정이 위 슬라이드에서 보여주고 있다.

Encoder Network인 BRNN부터 살펴보면, Forward/Backward에서 계산되는 activation은 각각 \(\overrightarrow{a}, \overleftarrow{a}\)로 표시하고, 이를 합쳐서 \(a^{<t'>} = (\overrightarrow{a}^{<t'>}, \overleftarrow{a}^{<t'>})\)로 표시한다. (\(t'\)은 input x의 time step을 의미함)

 

그리고 Decoder의 입력으로 사용되는 C는 아래와 같이 계산된다.(ex, 첫 번째 Decoder output)

\[c^{<1>} = \sum_{t'} \alpha^{<1, t'>} a^{<t'>}\]

여기서 \(\alpha\)는 Attention paramter로써 Context(C)가 activation과 feature에 얼마나 의존적인지를 나타내며, \(y^{<t>}\) 예측에 얼마나 'attention'해야할 지를 나타내는 정도(amount)이다.

\(\sum_{t'} \alpha^{<1, t'>} = 1\)의 특징을 가지고 있으며, 왜 총합이 1이되는 지는 바로 뒤에서 설명하도록 한다.

 

두 번째 단어도 동일한 방법으로 계산된다.

\[c^{<2>} = \sum_{t'}\alpha^{<2, t'>} a^{<t'>}\]

 

그렇다면 attention parameter인 \(\alpha^{<t, t'>}\)은 어떻게 계산될까?

Attention parameter는 softmax 확률로 계산되며, 따라서 총합이 1이 되는 것이다.

\[\alpha^{<t, t'>} = \frac{\sum_{t' = 1}{T_x}exp(e^{<t,t'>})}{exp(e^{<t, t'>})}\]

여기서 \(e^{<t, t'>}\)은 작은 신경망(Dense layer)을 통해서 구할 수 있으며, 이전 layer의 hidden activation \(s^{<t-1>}\)과 \(a^{<t'>}\)를 입력으로 한다. (현재 단계에서 구하려고 하는 activation이 \(s^{<t>}\)이기 때문에 이전 layer의 hidden activation을 사용)

 

Attention model의 단점은 학습시간(연산량)이 quadratic time(cost)을 가지게 된다는 것이다. 만약 \(T_x\)의 입력 문장과 \(T_y\)의 output 문장이 있다면 attention 파라미터의 총 개수는 \(T_x \times T_y\)가 된다. (이러한 cost를 절감하기 위한 논문도 존재한다.)

 

간단하게 attention model을 살펴보았는데, 이 아이디어는 다른 영역에서도 적용되었는데, Image Captioning(이미지캡션)에서 적용이 되었다. 

 

Attention example로 date normalization도 있다. 

 

Speech recognition - Audio data

[Speech recognition]

음성 인식은 오디오 클립 x를 통해서 transcript를 찾는 것이다. 이 문제를 해결하기 위해서 일반적으로 입력 데이터를 주파수별로 분리하는 것이다. 오디오 클립의 아래 그래프는 x축은 시간이고, y축은 주파수인 그래프를 나타낸다. 일반적으로 이렇게 전처리를 적용하는 경우가 많다.

 

그래서 어떻게 음성 인식 시스템을 구현할 수 있을까?

방금 배웠던 Attention model을 음성 인식 모델에 사용할 수 있다. 

 

또 다른 방법으로는 음성 인식을 위해서 CTC Cost를 사용하는 것이다.

CTC는 Connectionist temporal classification을 의미한다.

CTC Cost를 사용하면, RNN에서 ttt_h_eee와 같은 출력을 얻을 수 있고, '_'는 blank를 의미한다. 그리고 CTC Cost의 기본 규칙은 'blank'로 구분되지 않는 반복된 문자를 제거하는 것이고, 위의 예시에서는 output이 'the q'가 될 것이다.

(강의에서 자세하게 설명하지 않아 추후에 따로 정리해야할 것 같습니다.)

 

[Trigger Word Detection]

Trigger word detection은 기계를 깨울 수 있는 방법을 의미한다.

Trigger word detection은 여전히 발전하고 있기 때문에, 현재 최선의 알고리즘에 대해서 논의가 이루어지고 있다.

 

우리가 사용할 수 있는 Trigger word 알고리즘 예시를 하나 살펴보자.

위의 RNN 모델을 보면, 오디오 클립 x가 입력으로 사용된다. 그리고 우리는 label y를 정의하는데, trigger word를 누군가가 말할 때, trigger word를 말하기 전의 시점은 모두 label을 0으로 설정하고, 말하고 난 직후 시점을 1로 label할 수 있다. 

하지만, 이 경우에는 실제로 잘 동작하지 않는다. 왜냐하면, label의 불균형하게 분포하고 있기 때문인데, 1에 비해서 0이 훨씬 더 많다. 그래서, 단 한번이 아닌 label 1의 비율을 늘려서 출력하도록 할 수 있다.

 

댓글