728x90

 

 

 이번에 다뤄볼 것은 어텐션 레이어의 특별한 케이스로 셀프 어텐션 계층이 있습니다. 셀프 어텐션 계층은 입력 벡터 집합 하나만을 사용하는 것인데, 우리가 할일은 각각의 입력 벡터 셋에 있는 각각의 입력 벡터를 다른 입력 벡터와 비교하겠습니다. 이걸 위해서 우리가 할 작업은 또 다른 학습 가능한 가중치 행렬을 추가하는것인데,

 

 쿼리 벡터들을 입력으로 사용하는것이아니라, 쿼리 벡터들을 입력 벡터들을 변환시켜 추정해냅니다. 그다음에는 이전에 본것과 동일하게 동작합니다. 이 과정이 어떻게 동작하는지 그림으로 보자면 오른쪽에 입력 벡터 x1, x2, x3의 집합을 입력으로 받습니다.

 

 이번에는 각 입력 벡터를 쿼리 행렬과 곱하여 쿼리 벡터로 변환시키겠습니다.

 

 

 그러고나서 비슷하게 입력 벡터를 키 행렬을 사용해서 키 벡터로 바꾸고,

 

 각 키 벡터와 각 쿼리 벡터 사이의 배정 스코어를 계산할수가 있겠습니다. 이 배정 스코어는 입력 시퀀스 x의 각 입력끼리의 쌍간의 유사도라고 할수 있겠습니다.

 

 이제 이전과 똑같이 소프트맥스 함수를 사용해서 각 컬럼방향으로 확률 분포를 구해내고,

 

 

 입력 벡터들을 값 벡터로 변환시키겠습니다.

 

 그러고나서 값 벡터와 가중화된 유사도를 구하고, 출력 벡터 y 집합을 만들어내겠습니다. 이 과정이 전반적인 메커니즘이라고 할수 있겠습니다.

 

 지금까지 한것들 전체가 새로운 종류의 신경망 레이어라고 할수 있는데, 벡터 집합을 입력으로 받아 벡터 집합을 출력하는데다가, 내부적으로 하는 일은 입력에서의 한 벡터를 다른 각 벡터들과 비교하게되며 신경망은 스스로 어떤 비선형 함수를 사용할지 결정합니다.

 

 셀프 어텐션 레이어의 놀라운 점은 우리가 입력 벡터의 순서를 바꾼 경우에 볼수 있는데, 입력 벡터를 같은 것들을 가지고 있으나 1, 2, 3 순서가 아니라 3, 1, 2로 하는경우 어떤 일이 일어날까요.

 

 

그렇더라도 동일한 키 벡터들과 동일한 쿼리 벡터들을 구할수 있겠습니다. 키 벡터와 쿼리 벡터는 서로 서로 영향을 주지 않기 때문입니다. 다만 정확하게 같은 키 벡터와 쿼리 벡터를 구할수 있지만 입력 벡터의 순서대로 뒤바뀌겠습니다.

 

 다음으로 뒤바뀐 벡터들 사이의 유사도 스코어들을 계산할때, 모든 유사도 스코어는 동일하지만 행과 열이 바뀌었기때문에 이 행렬 자체도 뒤바뀌어 있겠습니다. 하지만 값 자체는 동일해요. 

 

 이전과 비슷하게 어텐션 가중치를 계산할수 있겠고, 값 자체는 동일하나 여전히 뒤바뀌어 있겠다.

 값 벡터들 자체도 동일하나 뒤바뀌어있고,

 출력 벡터도 동일하지만 뒤바뀌어있다.

 

 이 현상이 무엇을 의미하냐면 기술적으로 이야기하면 셀프 어텐션 계층, 셀프 어텐션 연산은 동등 치환 permutation equivalent(동일하나 순서를 바꾼다?? 정도로 이해)이며, 이 동등 치환이라는 것은 우리가 입력 벡터 x를 치환 연산 s를 적용한 다음에 출력을 계산한 것 f(s(x))과 치환/변환?하지않은 입력으로 결과를 구한뒤 치환시킨것 s(f(x))이 동일하다는 의미가 되겠습니다.

 

 그리고 셀프 어텐션 레이어를 다른 방향으로 고민해보자면, 이 셀프 어텐션 레이어는 입력의 순서를 신경쓰지 않습니다. 순서를 고려하지 않는 다는 점에서 새로운 종류의 신경망 계층이기도 하며, 벡터의 집합만을 가지고 연산하겠습니다.

 

 셀프 어텐션 레이어가 하는건 여러 벡터들 x을 가지고 각 벡터들 q, k을 서로 서로 비교해서 새로운 벡터 집합 y을 구하는 일을 하겠습니다.

 

그래서 이 레이어는 입력 벡터를 처리할때 그 벡터들의 순서가 어떻게 되는지 잘 모르겠습니다. 하지만 벡터들의 순서를 알아야하는 경우도 있을거에요 예를 들자면 번역이나 캡셔닝 작업같은 경우에는 시퀀스를 생성하고, <end> 토큰으로 마무리 합니다.

 

 이와 같은 어떤 작업들의 경우 모델이 벡터가 어느 위치에 있는지 아는게 중요한 경우도 있습니다. 하지만 셀프 어텐션 레이어는 동등 치환이다보니, 어떤 벡터가 첫번째인지 어느것이 맨마지막인지 알 방법이 없습니다. 

 

 

 그렇지만 각 입력 벡터에 위치 인코딩을 함으로서 위치 이동에대한 민감도를 절반정도 복원시킬수가 있습니다. 이걸 구현하는 다양한 방법들이 있는데 이들 중 한 방법은 룩업 테이블을 학습하는 방법입니다.

 

 이 신경망에다가 학습가능항 가중치 행렬을 추가시키는것인데, 벡터 하나로 첫번째 위치를 학습하고, 다른 한 벡터로 두번쨰 위치를 학습하고, 다른 벡터로 세번쨰 위치를 학습하겠다. 그러고나서 신경망 순전파 연산을 수행할때에는 첫번째 벡터 아래에다가 학습한 위치 벡터를 붙이고, 두번째 입력 벡터  신경망 순전파를할때, 첫번째 벡터 아래에 학습된 위치 벡터를 붙이고, 두번째 위치 벡터를 붙이고 그런식으로 가겠다.

 

 이렇게 함으로서 모델은 시퀀스의 파트들이 시작부분인지, 끝부분인지 구분할수 있게 되었으며 이것을 위치 인코딩 positional encoding이라고 부르며, 이것들이 가끔 셀프 어텐션 모델에서 사용되는걸 볼수 있겠다.

 

 

 다른 셀프 어텐션 레이어의 변형으로 마스크 셀프 어텐션 레이어라고 부르는 방법이 있는데,

 

 이 방법을 정리하자면 어떤 작업들을 할때 모델이 이전의 정보만 사용하기를 원할때, 순환 신경망은 은닉 상태가 진행하도록 설계된다는점을 떠올려보면 언어 모델 같은걸 모델링할시, 이전의 모든 토큰이 주어질때 다음 토큰을 추정할겁니다.

 

 디폴트 셀프 어텐션 레이어를 사용하면 모든 출력 벡터를 만드는 과정에서 모든 벡터를 사용하게 될건데, 언어 모델 같은 종류의 작업에서는 잘 동작하지 않게 될겁니다. 하지만 이문제는 어텐션 매트릭스에 어떤 구조를 추가해서 고칠수가 있습니다.

 

 예를들어 모델이 과거 정보만 사용하도록 강제로 만들려면, 이 추정 행렬 e에서 집중하지 않아야하는 모든 위치에다가 -무한대를 넣으면 됩니다. 그래서 이 예시에서 첫번째 입력과 q1에 대한 출력 벡터를 만든다고할때, 첫번째 출력은 첫번째 입력으로만 구하면되겠습니다.

 

 그래서 이런 과정을 행렬에다가 음의 무한대를 넣어서 할수 있고, 소프트맥스 함수로 계산하면 -무한대는 어텐션 가중치로 0의 값을 들을 가지게 되겠습니다. 이런 구조를 마스크화된 셀프 어텐션 레이어라고 부르며, 출력을 생성할때 입력 일부만 보도록 마스크시켜주는 역활을 하기 때문입니다.

 

 이 구조가 언어 모델 작업과 같이 모델이 이전 단어들만 사용해서 다음 단어를 추정해야하는 언어 모델 작업과 같은곳에서 자주 사용됩니다.

 

  이러한 셀프어텐션 레이어의 또 다른 버전으로 멀티 해드 셀프 어텐션이 있습니다. 이 방법은 해드의 개수 h를 지정하고, 셀프 어텐션 레이어를 병렬로 독립적으로 동작시킬건데 여기다가 입력 벡터를 분할해서 주는데, 입력 벡터 x가 d 차원이라면 각 입력 벡터들을 동일한 h개의 덩어리로 분할시켜주겠습니다.

 

 이 각각의 입력 벡터 덩어리들을 병렬화된 셀프 어텐션에다가 각각 넣어주고, 각 하부 셀프 어텐션레이어는 각 입력에대해서 각 출력들을 만들어낼것이고, 이러한 멀티해드 셀프 어텐션 레이어로부터 최종 출력을 얻기위해서 이 각 출력들은 연결시키겠습니다.

 

 이 멀티해드 셀프어텐션 레이어는 실제로도 자주 사용되고 있으며, 여기서 기본적으로 두 하이퍼파라미터를 가지는데 하나는 쿼리 벡터의 차원과 우리가 추정하고자하는 출력 y의 최종 차원가 있겠습니다. 이번에 이 모델에서 내부적으로 우리가 지정해주어야하는 두 하이퍼 파라미터로 하나는 내부 키 벡터 Dq의 차원과 다른 하나는 해드 h의 갯수가 되겠습니다.

 

 이 값 둘다 실제 셀프 어텐션 레이어들을 사용하는걸 볼때 볼수 있으며, 사람들이 각 레이어의 전반적인 폭지정해둔것을 볼수 있는데 이건 쿼리벡터 Dq의 차원이며, 셀프 어텐션 레이어의 해드 갯수 h를 지정한것을 볼수 있겠습니다.

 

 

300x250

+ Recent posts