for textmining

SVD와 PCA, 그리고 잠재의미분석(LSA)

|

이번 포스팅에서는 차원축소(dimension reduction) 기법으로 널리 쓰이고 있는 특이값분해(Singular Value Decomposion)주성분분석(Principal Component Analysis)에 대해 알아보도록 하겠습니다. 마지막으로는 이러한 기법이 잠재의미분석(Latent Sematic Analysis)와 어떻게 연결되는지 이야기해보도록 하겠습니다. 이번 글은 고려대 강필성 교수님, 한양대 이상화 교수님 강의와 quora, 또 다크프로그래머의 블로그를 참고했음을 미리 밝힙니다. 그럼 시작하겠습니다.

주성분 분석

PCA는 데이터의 분산(variance)을 최대한 보존하면서 서로 직교하는 새 기저(축)를 찾아, 고차원 공간의 표본들을 선형 연관성이 없는 저차원 공간으로 변환하는 기법입니다. 이를 그림으로 나타내면 아래와 같습니다. 3차원 공간에 있는 데이터들이 서로 수직인 두 개의 주성분(PC1, PC2)을 새로운 기저로, 선형변환된 것을 확인할 수 있습니다. PCA 관련 자세한 내용은 이곳을 참고하시기 바랍니다.

원 데이터의 분산을 최대화하는 새로운 기저를 찾는 목표를 달성하려면 우선 데이터 행렬 $A$의 공분산 행렬부터 구해야 합니다. 데이터가 각 변수별로 평균이 0으로 맞춰져 있을 때(centering 작업 이미 수행되어 있다고 가정) 공분산 행렬은 아래와 같이 구합니다.

[cov(A)=\frac { 1 }{ n-1 } A{ A }^{ T }\propto A{ A }^{ T }]

PCA의 새로운 축을 찾기 위해서는 위 공분산행렬을 아래처럼 고유분해(Eigen decomposition)를 수행해주어야 합니다. 아래 식에서 $Λ​$는 대각성분이 공분산행렬의 고유값이고 나머지 요소는 0인 행렬, $U​$는 열벡터가 공분산행렬 $AA^T​$의 고유벡터로 이뤄진 행렬입니다.

[A{ A }^{ T }=U\Lambda { U }^{T }]

여기에서 $Λ$의 대각성분은 데이터 행렬 $A$의 각 변수에 해당하는 분산을 의미합니다. 원 데이터의 분산을 최대화하는 새로운 기저를 찾는 것이 PCA 목표인 만큼 가장 큰 고유값 몇 개를 고르고, 그에 해당하는 고유벡터를 새로운 기저로 하여 원데이터를 사영(선형변환)해주면 PCA 작업이 완료되게 됩니다.

예컨대 변수가 100개(100차원)인 데이터에 PCA를 적용한 후 가장 큰 고유값 두 개에 해당하는 고유벡터로 원 데이터를 사영시키면 원데이터의 분산을 최대한 보존하면서도 그 차원수를 100차원에서 2차원으로 줄일 수 있게 됩니다.

특이값 분해

특이값분해는 m x n 크기의 데이터 행렬 $A$를 아래와 같이 분해하는 걸 말합니다.

[A=U\Sigma { V }^{ T }\]

행렬 $U$와 $V$에 속한 열벡터는 특이벡터(singular vector)로 불리고요, 모든 특이벡터는 서로 직교하는 성질을 지닙니다.

[U=\begin{bmatrix} \overrightarrow { { u }{ 1 } } & \overrightarrow { { u }{ 2 } } & … & \overrightarrow { { u }{ m } } \end{bmatrix}\ V=\begin{bmatrix} \overrightarrow { { v }{ 1 } } & \overrightarrow { v_{ 2 } } & … & \overrightarrow { { v }{ n } } \end{bmatrix}\ \overrightarrow { { u }{ k } } =\begin{bmatrix} { u }{ k1 } \ { u }{ k2 } \ … \ { u }{ km } \end{bmatrix}\quad \overrightarrow { { v }{ k } } =\begin{bmatrix} { v }{ k1 } \ v{ k2 } \ … \ { v }{ kn } \end{bmatrix}\ { \overrightarrow { { u }{ k } } }^{ T }\overrightarrow { { u }{ k } } =1,\quad { U }^{ T }U=I\ { \overrightarrow { { v }{ k } } }^{ T }\overrightarrow { { v }_{ k } } =1,\quad { V }^{ T }V=I]

행렬 $Σ$의 특이값은 모두 0보다 크거나 같으며 내림차순으로 정렬돼 있습니다. 행렬 $Σ$의 $k$번째 대각원소에 해당하는 특이값 $Σ_k$는 행렬 $A{A}^{T}$의 $k$번째 고유값에 제곱근을 취한 값과 같습니다.

[{ \Sigma }{ k }=\sqrt { { \lambda }{ k } } ​]

그러면 특이값 분해를 주성분 분석과 비교해보기 위해 행렬 $A$를 제곱해 보겠습니다. 이후 식을 정리하면 아래와 같습니다.

[\begin{align} A{ A }^{ T }&=U\Sigma { V }^{ T }{ (U\Sigma { V }^{ T }) }^{ T }\ &=U\Sigma { V }^{ T }V\Sigma { U }^{ T }\ &=U{ \Sigma }^{ 2 }{ U }^{ T }\ &=U\Lambda { U }^{ T } \end{align}]

여기서 대각성분이 행렬 $A$의 특이값이고 나머지 성분이 0인 행렬 $Σ$에 주의할 필요가 있습니다. $Σ$는 대각행렬(diagonal matrix)인데요, 대각행렬의 거듭제곱은 대각원소들만 거듭제곱을 해준 결과와 같습니다.

따라서 $Σ$의 제곱은 각 대각원소, 즉 행렬 $A$의 특이값들을 제곱해준 값과 똑같습니다. 그런데 행렬 $A$의 특이값은 $A{A}^T$의 고유값에 제곱근을 취한 값과 동일하므로, $Σ$을 제곱한 행렬은 행렬 $AA^T$의 고유값으로 이뤄진 행렬 $Λ$가 됩니다. 이는 정확히 주성분 분석의 결과와 같습니다.

특이값 분해의 여러 변형들

thin SVD

thin SVD는 $Σ$ 행렬의 아랫부분(비대각 파트, 모두 0)과 $U$에서 여기에 해당하는 부분을 모두 제거합니다. 이렇게 $U$와 $Σ$를 줄여도 $U_sΣ_sV^T$로 $A$를 원복할 수 있습니다.

compact SVD

compact SVD는 $Σ$ 행렬에서 비대각파트뿐 아니라 대각원소(특이값)가 0인 부분도 모두 제거한 형태입니다. 여기에 대응하는 $U$와 $V$의 요소 또한 제거합니다. 다시 말해 특이값이 양수인 부분만 골라낸다는 뜻입니다. 이렇게 $U$와 $Σ$, $V$를 줄여도 $U_rΣ_rV_r^T$로 $A$를 원복할 수 있습니다.

truncated SVD

truncated SVD는 $Σ$ 행렬의 대각원소(특이값) 가운데 상위 $t$개만 골라낸 형태입니다. 이렇게 하면 행렬 $A$를 원복할 수 없게 되지만, 데이터 정보를 상당히 압축했음에도 행렬 $A$를 근사할 수 있게 됩니다. 이후 설명드릴 잠재의미분석은 바로 이 방법을 사용합니다.

SVD 예시

[A=U\Sigma { V }^{ T } \ \ \begin{bmatrix} 2 & 3 \ 1 & 4 \ 0 & 0 \ 0 & 0 \end{bmatrix}=\begin{bmatrix} 0.82 & -0.58 & 0 & 0 \ 0.58 & 0.82 & 0 & 0 \ 0 & 0 & 1 & 0 \ 0 & 0 & 0 & 1 \end{bmatrix}\begin{bmatrix} 5.47 & 0 & 0 & 0 \ 0 & 0.37 & 0 & 0 \ 0 & 0 & 0 & 0 \ 0 & 0 & 0 & 0 \end{bmatrix}\begin{bmatrix} 0.40 & 0.91 \ -0.91 & 0.40 \end{bmatrix}]

truncated SVD 예시

[\begin{align} { A }^{ ‘ }&={ U }_{ 1 }{ \Sigma }_{ 1 }{ V }_{ 1 }^{ T }\ \ \begin{bmatrix} 1.79 & 4.08 \ 1.27 & 2.89 \ 0 & 0 \ 0 & 0 \end{bmatrix}&=\begin{bmatrix} 0.82 \ 0.58 \ 0 \ 0 \end{bmatrix}\begin{bmatrix} 5.47 \end{bmatrix}\begin{bmatrix} 0.40 & 0.91 \end{bmatrix} \end{align}]

잠재의미분석 개요

예컨대 다음과 같은 문서들이 있다고 하면, 우리는 이를 토대로 단어-문서행렬 $A$를 만들 수 있습니다.

doc1 : 나,는,학교,에,가,ㄴ,다

doc2 : 학교,에,가,는,영희

doc3 : 나,는,영희,는,좋,다

- doc1 doc2 doc3
1 0 0
1 1 2
학교 1 1 0
1 1 0
1 1 0
1 0 0
1 0 1
영희 0 1 1
0 0 1

잠재의미분석이란 위와 같은 단어-문서행렬(Word-Document Matrix), 단어-문맥행렬(window based co-occurrence matrix) 등 입력 데이터에 특이값 분해를 수행해 데이터의 차원수를 줄여 계산 효율성을 키우는 한편 행간에 숨어있는(latent) 의미를 이끌어내기 위한 방법론입니다. 대략적인 개념은 아래 그림과 같습니다.

잠재의미분석을 수행하는 절차는 이렇습니다. $n$개의 문서를 $m$개의 단어로 표현된 입력데이터 행렬 $A$가 주어졌다고 칩시다. $A$의 0보다 큰 고유값의 개수를 $r$이라고 할 때, $r$보다 작은 $k$를 연구자가 임의로 설정하고 $Σ_k$를 만듭니다. 이후 $U$와 $V$ 행렬에서 여기에 대응하는 부분만 남겨 $U_k$와 $V_k$를 만들어줍니다. 이렇게 되면 $A$와 비슷한 $A_k$ 행렬을 구축할 수 있습니다.

[{ A }{ k }={ U }{ k }{ \Sigma }{ k }{ V }{ k }^{ T }]

위 식 양변에 $U_k$의 전치행렬을 곱해준 것을 $X_1$, $V_k$를 곱해준 것을 $X_2$라고 둡니다. 그러면 $X_1$의 경우 $n$개의 문서는 원래 단어수 $m$보다 훨씬 작은 $k$개 변수로 표현된 결과가 됩니다. $X_2$는 $m$개의 단어가 원래 문서 수 $n$보다 작은 $k$개 변수로 표현한 결과입니다. 이는 주성분 분석에서의 차원축소 효과와 비슷한 것으로 이해하면 좋을 것 같습니다.

[{ { U }{ k }^{ T }A }{ k }={ { U }{ k }^{ T }U }{ k }{ \Sigma }{ k }{ V }{ k }^{ T }=I{ \Sigma }{ k }{ V }{ k }^{ T }={ \Sigma }{ k }{ V }{ k }^{ T }={ X }{ 1 }\ { A }{ k }{ V }{ k }={ U }{ k }{ \Sigma }{ k }{ V }{ k }^{ T }{ V }{ k }={ U }{ k }{ \Sigma }{ k }^{ T }I={ U }{ k }{ V }{ k }^{ T }={ X }{ 2 }]

잠재의미분석 예시

자, 그럼 위에서 예로 든 단어-문서행렬 $A$를 가지고 잠재의미분석을 수행해 보겠습니다. $A$에 SVD를 수행하면 아래와 같이 쓸 수 있습니다. 숫자들이 엄청 많은데요, ‘아 이렇게 분해될 수 있구나’ 정도로 보고 슥 넘어가시면 될 것 같습니다.

[A=U\Sigma { V }^{ T }\ \ \begin{bmatrix} 1 & 0 & 0 \ 1 & 1 & 2 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 0 & 0 \ 1 & 0 & 1 \ 0 & 1 & 1 \ 0 & 0 & 1 \end{bmatrix}=\begin{bmatrix} -0.17 & 0.27 & -0.40 \ -0.63 & -0.41 & -0.03 \ -0.32 & 0.37 & 0.21 \ -0.32 & 0.37 & 0.21 \ -0.32 & 0.37 & 0.21 \ -0.17 & 0.27 & -0.40 \ -0.33 & -0.12 & -0.52 \ -0.30 & -0.29 & 0.49 \ -0.15 & -0.39 & -0.13 \end{bmatrix}\begin{bmatrix} 3.61 & 0 & 0 \ 0 & 2.04 & 0 \ 0 & 0 & 1.34 \end{bmatrix}\begin{bmatrix} -0.63 & -0.53 & -0.57 \ 0.56 & 0.20 & -0.80 \ -0.54 & 0.83 & -0.17 \end{bmatrix}]

그럼 $Σ$ 행렬의 특이값 가운데 상위 2개(3.61과 2.04)만 남기고 나머지를 제거하는 방식으로 truncated SVD를 수행해 보겠습니다. 아래와 같습니다.

[{ A }^{ ‘ }={ U }{ 2 }{ \Sigma }{ 2 }{ V }_{ 2 }^{ T }\ \begin{bmatrix} 0.71 & 0.44 & -0.09 \ 0.97 & 1.04 & 1.99 \ 1.15 & 0.76 & 0.04 \ 1.15 & 0.76 & 0.04 \ 1.15 & 0.76 & 0.04 \ 0.71 & 0.45 & -0.09 \ 0.62 & 0.58 & 0.88 \ 0.36 & 0.45 & 1.11 \ -0.09 & 0.14 & 0.97 \end{bmatrix}=\begin{bmatrix} -0.17 & 0.27 \ -0.63 & -0.41 \ -0.32 & 0.37 \ -0.32 & 0.37 \ -0.32 & 0.37 \ -0.17 & 0.27 \ -0.33 & -0.12 \ -0.30 & -0.29 \ -0.15 & -0.39 \end{bmatrix}\begin{bmatrix} 3.61 & 0 \ 0 & 2.04 \end{bmatrix}\begin{bmatrix} -0.63 & -0.53 & -0.57 \ 0.56 & 0.20 & -0.80 \end{bmatrix}]

솔직히 이렇게 봐서는 $A’$가 원데이터 행렬 $A$에 제대로 근사한 것인지 아리송합니다. $A’$의 각 요소값을 반올림해서 원 행렬 $A$와 비교해보겠습니다. 6행과 7행의 요소값이 조금 다를 뿐 거의 유사한 것을 확인할 수 있습니다.

[round({ A }^{ ‘ })=\begin{bmatrix} 1 & 0 & 0 \ 1 & 1 & 2 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 0 & 0 \ 1 & 1 & 1 \ 0 & 0 & 1 \ 0 & 0 & 1 \end{bmatrix},\quad A=\begin{bmatrix} 1 & 0 & 0 \ 1 & 1 & 2 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 1 & 0 \ 1 & 0 & 0 \ 1 & 0 & 1 \ 0 & 1 & 1 \ 0 & 0 & 1 \end{bmatrix}]

그럼 $A’=U_2Σ_2V^T_2$ 양변의 맨 앞에 $U_2$의 전치행렬을 각각 곱해줄까요? 그 결과를 $X_1$이라고 두면 아래와 같습니다.

[X_{1}=\begin{bmatrix} -2.28 & -1.90 & -2.07 \ 1.14 & 0.42 & -1.64 \end{bmatrix}]

원데이터인 $A$와 SVD 결과인 $X_1$의 열(column)은 문서(문장)를 의미합니다. 단어-문맥행렬 $A$에서 각 문서들은 9개 단어(변수)들로 표현됐으나 $X_1$에서는 단 두 개의 변수들만으로도 표현이 가능해졌습니다. 이렇게 만든 $X_1$에 다양한 데이터마이닝 기법을 적용해 여러 가지 문제를 풀게 되는 것입니다.

자, 이제는 반대로 $A’=U_2Σ_2V^T_2$ 양변의 맨 뒤에 $V_2$를 각각 곱해볼까요? 그 결과를 $X_2$라고 두면 다음과 같습니다.

[{ X }_{ 2 }=\begin{bmatrix} -0.63 & 0.56 \ -2.30 & -0.84 \ -1.16 & 0.76 \ -1.16 & 0.76 \ -1.16 & 0.76 \ -0.63 & 0.56 \ -1.20 & -0.24 \ -1.10 & -0.60 \ -0.57 & -0.80 \end{bmatrix}]

원데이터인 $A$와 SVD 결과인 $X_2$의 행(row)은 단어를 의미합니다. 단어-문맥행렬 $A$에서 각 단어들은 3개 문서(변수)들로 표현됐으나 $X_2$에서는 단 두 개의 변수들만으로도 표현이 가능해졌습니다. 이렇게 만든 $X_2$에 마찬가지로 다양한 데이터마이닝 기법을 적용해 여러 가지 문제를 풀게 됩니다.

잠재의미분석의 효과

이제까지 든 예시에서는 차원축소의 효과가 도드라져 보이진 않지만 데이터가 클 경우 그 효과가 드라마틱하다고 합니다. 실제로 네이버, 카카오 등 현업에서도 이러한 방법론을 많이 쓰고 있는 것으로 알려져 있습니다. 잠재의미분석은 이외에도 많은 장점이 있다고 합니다. Deerwester et ak.(1990)과 Landauer and Dumais(1997)은 이 기법을 적용하면 단어와 문맥 간의 내재적인 의미(latent/hidden meaning)을 효과적으로 보존할 수 있게 돼 결과적으로 문서 간 유사도 측정 등 모델의 성능 향상에 도움을 줄 수 있다고 합니다. Rapp(2003)은 입력 데이터의 노이즈 제거, Vozalis and Margaritis(2003)은 입력데이터의 sparsity를 줄이게 돼 그 효과가 좋다고 합니다. 잠재의미분석은 입력데이터의 크기가 m x n이고 문서당 평균 단어수가 $c$일 경우 계산복잡도가 $O(mnc)$이어서 그다지 무거운 알고리즘은 아닙니다. 하지만 새로운 문서나 단어가 추가되면 아예 처음부터 작업을 새로 시작해야 합니다. 이 때문에 최근에는 Word2Vec 등 뉴럴네트워크 기반의 representation 방법론도 각광을 받고 있습니다.

Comment  Read more

CNN의 역전파(backpropagation)

|

이번 포스팅에서는 Convolutional Neural Networks(CNN)역전파(backpropagation)를 살펴보도록 하겠습니다. 많이 쓰는 아키텍처이지만 그 내부 작동에 대해서는 제대로 알지 못한다는 생각에 저 스스로도 정리해볼 생각으로 이번 글을 쓰게 됐습니다. 수학에 약한지라 최대한 수식은 배제하고 직관적으로 설명해볼까 합니다. 이번 글은 미국 스탠포드대학의 CS231n 강의이곳을 많이 참고하였습니다. 그런데 이들 설명도 저한테 확 와닿지 않아서 상당 부분은 제 스타일대로 그림을 다시 그리거나 해석했음을 미리 밝혀둡니다. 그럼 시작하겠습니다.

CNN의 forward pass

CNN은 필터가 입력데이터를 슬라이딩하면서 지역적 특징(feature)을 추출합니다. 이후 이 특징을 최대값(Max Pooling)이나 평균값(Average Pooling)으로 압축해 다음 레이어로 보냅니다. 이런 과정을 반복해 분류 등 원하는 결과를 만들어내는 것이 CNN의 일반적인 구조입니다. CNN의 forward pass에 대해서는 이미 많은 글에서 소개된 바 있으므로 이번 포스팅에서는 아래 그림을 인용하는 것으로 설명을 간단히 마치겠습니다.

이번 포스팅에서는 아래와 같이 가장 간단한 구조의 CNN을 예시로 설명해보려고 합니다. (CNN은 마지막 레이어에 Fully Connected Layer(FC)가 붙는 경우가 많은데, FC에 대한 역전파에 대해서는 이미 잘 정리된 글이 많고 우리의 목적은 CNN의 역전파를 세밀히 살피는 것이므로 여기서는 생략하겠습니다)

보시다시피 입력값은 3x3 행렬입니다. $x_{ij}$는 각각 입력값의 $i$번째 행, $j$번째 열의 요소를 뜻합니다. 필터(커널) 크기는 2x2입니다. CNN은 필터가 입력벡터를 슬라이딩을 하면서 지역정보를 추출하게 되는데, 스트라이드는 한칸으로 설정했습니다. 바꿔 말해 $x_{11}$, $x_{12}$, $x_{21}$, $x_{22}$가 필터와 합성곱이 되어서 conv 레이어의 1행 1열이 됩니다. 다음번엔 $x_{12}$, $x_{13}$, $x_{22}$, $x_{23}$이 필터와 합성곱이 되어서 conv 레이어의 1행 2열이 됩니다.

필터의 색깔과 위 계산그래프의 화살표 색깔을 맞춰서 보시면 어떻게 연산이 되는지 직관적으로 확인 가능하실 겁니다. 이후 conv 레이어에 최대값이나 평균값을 취해서 정보를 압축(pooling)합니다. 위 그림 기준으로는 2x2 행렬이 2x1 벡터로 바뀐 점을 확인할 수 있습니다. 아래는 이해를 돕기 위해 만든 움짤입니다. 내용은 위 그림과 동일합니다.

CNN의 backward pass

Average Pooling

이번 포스팅의 핵심인 역전파 과정을 살펴보도록 하겠습니다. 바로 뒤 레이어로부터 전파된 그래디언트가 $d_1$, $d_2$라고 칩시다. 그러면 Average Pooling 레이어의 그래디언트 전파 과정은 아래와 같습니다.

위 그림은 CS231n의 계산그래프 형태로 나타낸 것인데요. 현재 지점의 그래디언트는 미분의 연쇄법칙(chain rule)에 의해 흘러들어온 그래디언트에 로컬그래디언트를 곱한 것과 같습니다. 평균은 모든 값을 더한 뒤 개체수로 나누어 구하게 되는데요. 만약에 $m$개 요소로 구성돼 있다고 한다면 Average Pooling을 하는 지점의 로컬 그래디언트는 $1/m$이 됩니다. 이를 흘러들어온 그래디언트($d_1$)과 곱해주면 $d_{11}$을 구할 수가 있습니다. $d_{12}$, $d_{21}$, $d_{22}$도 같은 방식으로 구할 수 있습니다.

Max Pooling

최대값으로 풀링을 했다고 하면 역전파 과정은 아래와 같습니다. 즉, 최대값이 속해 있는 요소의 로컬 그래디언트는 1, 나머지는 0이기 때문에 여기에 흘러들어온 그래디언트를 곱해 구하게 됩니다.

conv layer

자, 이제 이번 글의 핵심인 conv layer의 역전파를 할 차례입니다. 우선 $x_{11}$을 보겠습니다.

$x_{11}$은 forward compute pass 과정에서 2x2필터 가운데 빨간색($w_1$) 가중치하고만 합성곱이 수행이 됐습니다. 그렇다면 역전파 때도 마찬가지로 딱 한번의 역전파가 일어나게 되겠네요. 이를 Kapathy의 계산그래프 형태로 나타내면 우측 상단 그림과 같습니다.

즉 $x_{11}$의 그래디언트는 흘러들어온 그래디언트 $d_{11}$에 로컬그래디언트($w_1$)를 곱해서 구할 수 있습니다. (곱셈 연산의 로컬그래디언트는 ‘상대방 변화량’입니다) 마찬가지로 $w_1$의 그래디언트는 흘러들어온 그래디언트 $d_{11}$에 로컬그래디언트($x_{11}$)를 곱해 계산합니다. 역전파와 관련해 자세한 내용은 이곳을 참고하면 좋을 것 같습니다.

이런 식으로 모든 경우의 수에 대해 계산하면 conv layer의 역전파 수행이 완료됩니다. 아직 헷갈리실 수 있으니 하나 더 예를 들어보겠습니다. $x_{22}$를 한번 보겠습니다. 아래 그림은 계산해야할 경우의 수가 $x_{11}$에 비해 늘었을 뿐 본질적으로 달라진 것은 없습니다.

그런데 다 이렇게 하나하나 따져가면서 구하려면 골치가 꽤나 아플 겁니다. conv layer의 역전파를 할 때 약간의 트릭을 쓰면 조금 더 간단히 그래디언트를 구할 수 있게 됩니다. 바로 아래 그림처럼요.

흘러들어온 그래디언트 행렬(2x2 크기)을 conv layer를 만들 때 썼던 필터가 슬라이딩하면서 값을 구한다는 겁니다! 대신 필터 요소의 순서를 정반대로 바꿔서요. 예컨대 빨-파-노-초 필터를 초-노-파-빨 필터로 바꿔서 그래디언트행렬에 합성곱을 수행해주면 입력벡터에 대한 그래디언트를 구할 수 있습니다. 가령 $x_{11}$의 그래디언트는 $w_1$(필터에서 빨간색 요소) x $d_{11}$이라고 설명드린 바 있는데요, 위 그림 오른쪽에 좌측 상단을 보시면 이것과 정확히 일치하는 것을 알 수가 있습니다. 마찬가지로 $x_{22}$의 그래디언트도 흘러들어온 그래디언트 행렬에 초-노-파-빨 필터 사이의 합성곱 결과와 동일합니다.

그럼 필터의 그래디언트는 어떻게 구하게 될까요? 흘러들어온 그래디언트 행렬의 첫번째 요소인 $d_{11}$은 $x_{11}$, $x_{12}$, $x_{21}$, $x_{22}$와 연결되어 있는 걸 확인할 수 있습니다. 계산그래프를 그려서 설명드렸던 것처럼 필터의 그래디언트는 흘러들어온 그래디언트($d_{11}$, $d_{12}$, $d_{21}$, $d_{22}$)에 로컬 그래디언트를 곱해서 구하게 되는데요. 각각의 로컬 그래디언트는 합성곱 필터 가중치로 연결된 입력값들이기 때문에 $dw_{11}$은 $x_{11}d_{11}+x_{12}d_{12}+x_{21}d_{21}+x_{22}d_{22}$입니다.

Comment  Read more

한국어의 유형론적 위치

|

이번 포스팅에서는 한국어가 세계 언어 가운데 유형론적으로 어디에 위치해 있는가에 대해 살펴보도록 하겠습니다. 이번 글은 경희대 이선웅 교수님과 고려대 정연주 선생님 강의, 이화여대 최형용 교수님 저서를 참고로 했음을 먼저 밝힙니다. 그럼 시작하겠습니다.

언어 유형론

언어유형론(linguistic typology)이란 ‘공유하는 형식적 특징에 근거한 언어나 언어 성분의 분류’를 뜻합니다. 쉽게 얘기하면 비슷한 언어끼리 묶어보는 거죠. 더 나아가서는 인간의 언어가 가지는 보편적인 성격을 탐구하는 학문입니다.

이와 관련해 Greenberg(1966)는 세계 언어를 연구한 뒤 “전치사를 가진 언어에서 소유격은 거의 언제나 지배 명사를 뒤따르지만 후치사를 사용하는 언어에서 소유격은 거의 언제나 지배 명사를 앞선다” 따위의 45개나 되는 보편성을 확인했다고 밝힌 바 있습니다.

Whaley(1997)에 의하면 구강 폐쇄음을 가진 언어의 38%는 6개에서 8개의 구강 폐쇄음을 가지고 있는 것으로 나타났고 14개 이상의 구강 폐쇄음을 가진 언어는 매우 희귀한 언어 유형에 속한다는 사실을 확인했습니다.

이렇듯 유형론은 언어 사이의 공통점과 차이점, 그리고 전반에 나타나는 보편성 등을 연구하는 학문입니다.

위 그림은 각국 언어학자들이 분석해 만든 언어의 세계지도(The World Atlas of Language Structures) 가운데 일부 분석 요소를 기준으로 한 지도를 캡처한 화면입니다. 보시다시피 한국어는 주변 나라들과 뚜렷한 차이가 나는 언어라고 볼 수 있겠네요.

위 그림에서도 나타나듯 지역적으로 가까운 거리에 있다고 해서 비슷한 유형의 언어일 것이라는 가정은 오해입니다. 실제로 이러한 오해 때문에 한국어는 몽골어와 함께 알타이 어족으로 20세기 초반부터 오랫동안 묶여 있었는데요. 알타이어족으로 분류하기 어렵다는 연구성과가 속속 소개된 최근에 이르러서야 한국어가 주변국과 다른 유형의 언어인 것 아니냐는 공감대를 얻고 있습니다. 어쨌든 언어 유형을 분류하는 작업은 언어유형론의 기본 관심사 가운데 하나입니다.

고립어, 굴절어, 교착어, 포합어

세계 언어는 형태론적 유형에 따라 고립어(孤立語), 굴절어(屈折語), 교착어(膠着語), 포합어(抱合語)로 나뉩니다. 분류 기준은 크게 두 가지가 있다고 합니다.

첫째는 ‘통합’의 지표입니다. 한 단어에 얼마나 많은 형태소들을 사용하는가에 따라 언어 유형을 분류할 수 있습니다. 한 단어가 하나의 형태소로 이뤄져 있는 경우 고립어로 분류됩니다. 중국어가 대표적인 고립어입니다. 반대로 한 단어에 다수의 형태소가 있는 언어를 포합어라고 합니다.

둘째는 ‘융합’의 지표입니다. 형태소들이 얼마나 쉽게 분리되는가에 따라 굴절어와 교착어로 나뉩니다. 이상적인 고립어와 이상적인 포합어 사이에 있는 언어(=한 단어에 여러 형태소들을 사용하는 언어)들을 대상으로 따지는 기준입니다.

교착어의 경우 형태소들을 비교적 쉽게 분리할 수 있는 언어를 말합니다. 대표적인 것이 한국어입니다. 어간과 접사, 어미 사이의 경계가 상대적으로 명확합니다. ‘드시었겠다’라는 형태의 경우 ‘드-(eat)’, ‘-시-(높임)’, ‘-었-(과거)’, ‘-겠-(추측)’, ‘-다(평서/종결)’로 분석할 수 있습니다.

반면 굴절어는 형태소의 경계가 명확하지 않습니다. 굴절어인 라틴어의 경우 flora(꽃)이란 단어가 flora(주격-단수)-florae(속격-단수)-floram(대격 단수)-florarum(속격-복수)처럼 변화한다고 합니다. 굴절어에서는 이처럼 시제, 수, 성(性), 격 등 문법 정보에 대응하는 형태소를 하나씩 떼어서 분석해내기가 어렵습니다.

Bickel&Nichols(2005)는 단어당 문법 범주 수를 토대로 고립어, 굴절어, 교착어를 양적으로 분석한 바 있는데요. 예컨대 한국어의 ‘들리시었겠습니다’의 경우 이 방법에 따른 범주 숫자는 7입니다. 한국어는 아래 표 가운데 단어당 범주수가 6~7개인 언어로 분류되어 있습니다. 고립어인 영어는 2~3개, 굴절어인 러시아어는 4~5개로 분석됩니다.

구분 개체수
단어당 범주수 0~1개인 언어 5
단어당 범주수 2~3개인 언어 24
단어당 범주수 4~5개인 언어 52
단어당 범주수 6~7개인 언어 31
단어당 범주수 8~9개인 언어 24
단어당 범주수 10~11개인 언어 7
단어당 범주수 12~13개인 언어 2
145

한국어의 특성

세계 969개 언어를 조사한 Dryer(2013)는 언어의 유형을 아래와 같이 총 6개로 정리했습니다.

구분 개체수
굴절이 거의 없거나 전혀 없는 언어 141
접미사가 지배적인 언어 406
접미사를 선호하는 언어 123
접미사와 접두사가 대략 같은 언어 147
접두사를 선호하는 언어 94
접두사가 지배적인 언어 58
969

위 연구 결과를 한국어를 대상으로 따져보도록 하겠습니다. 우선 국립국어연구원(2002)이 ‘표준국어대사전’의 표제어를 분석한 결과 전체 44만594개 표제어 가운데 조사는 357개, 어미는 2526개, 접사는 656개인 것으로 조사됐습니다. 접사 656개 가운데 접두사는 200개, 접미사는 456개입니다.

조사와 어미는 물론 접사가 아닙니다만, 교착어인 한국어를 세계 다른 언어들과 비교하려면 이를 접사로 분류해야 분석의 일관성과 체계를 세울 수 있다고 합니다. 굴절어나 고립어에는 조사나 어미에 해당하는 문법범주가 존재하지 않기 때문이라고 합니다.

어쨌든 한국어에서 조사와 어미를 접미사로 분류하게 되면 한국어의 접두사와 접미사 비율은 200:3339, 즉 1:17 정도나 됩니다. 위 연구에서도 한국어를 ‘접미사가 지배적인 언어’로 분류하고 있습니다.

실제로 한국어는 어간에 조사나 어미와 같은 문법 형태소들이 차례로 결합하여 문법적인 기능을 실현하는 ‘교착어’입니다. 어간이나 명사에 여러 개의 문법 형태소가 결합돼 복합적인 문법적 기능을 실현합니다. 예컨대 ‘나는 빵을 먹는다’는 문장을 분석하면 다음과 같이 7개 형태소로 나뉩니다.

나,는,빵,을,먹,는,다

‘나(me)’라는 명사에 격조사 ‘-는’이 붙어 주어로 실현됐습니다. 마찬가지로 ‘빵(bread)’과 격조사 ‘-을’이 붙어 목적어로, ‘먹-(eat)’과 선어말어미 ‘-는-(현재)’, 문말어미 ‘-다(평서형)’가 붙어 서술어로 실현됐습니다. 한국어에서 조사/어미의 형식과 기능은 대개 이와 같이 1대1 대응됩니다.

한국어 문법 범주의 실현은 거의 문법 형태소에 의해 이뤄집니다. 아래 예시와 같이 영어 의문문을 만들 때 중요한 요소는 어순인 반면 한국어는 어미가 그 핵심입니다.

구분 평서문 의문문
한국어 철수가 방에 있다. 철수가 방에 있느냐?
영어 John is in the room. Is John in the room?

이러한 성격은 어순이 자유로운 한국어의 특징과도 밀접한 관련이 있습니다. 명사구(Noun Phrase)의 자격이 격조사 등과 같은 문법형태소로 표시되기 때문입니다. 아래 예시에서 (ㄱ)과 (ㄴ)은 같은 의미를 갖지만, (ㄷ)과 (ㄹ)은 그 의미가 완전히 다른 문장입니다.

(ㄱ) 철수가 영희를 만났다

(ㄴ) 영희를 철수가 만났다

(ㄷ) John met Mary

(ㄹ) Mary met John

다만 한국어에서 기본이 되는 어순은 주어(S), 목적어(O), 동사(V)입니다. Dryer(2013)은 전세계 1377개 언어를 대상으로 아래와 같이 조사했는데요. 이 기준에서 보면 한국어는 그렇게 별난 언어는 아닌 것 같습니다.

구분 개체수
SOV 565
SVO 488
VSO 95
VOS 25
OVS 11
OSV 4
지배적 어순이 없는 언어 189
1377

한편 Nichols&Bickel(2005)에서는 235개 세계 각 언어들이 소유격 명사구에서 어디에 소유격 ‘표지’를 나타내는지에 대해 다음과 같은 통계를 제시하고 있습니다. 소유격 명사구에서 핵은 명사입니다.

구분 개체수
핵인 명사에 표시하는 언어 77
의존어에 표시하는 언어 98
핵과 의존어에 모두 표시하는 언어 22
핵과 의존어 모두 표시하지 않는 언어 32
기타 유형의 언어 6
235

그럼 한국어를 살펴볼까요? 한번 예를 들어보겠습니다. 아래 예시에서 볼 수 있듯 한국어에서 소유격은 의존어에 표시되고 있다는 걸 알 수 있습니다.

(가) 나의 책, 그의 발, 너의 집

그럼 동사 핵은 어떨까요? Nichols&Bickel(2005)은 직접 목적어와 관련해 표지가 어디에서 실현되는지 조사했습니다.

구분 개체수
핵인 동사에 표시하는 언어 71
의존어인 목적어에 표시하는 언어 63
핵과 의존어에 모두 표시하는 언어 57
핵과 의존어 모두 표시하지 않는 언어 42
기타 유형의 언어 2
235

또 한국어 예시를 살펴보겠습니다.

(나) 철수가 책을 동생에게 주었다.

(나) 문장의 전체 핵심어 ‘주-‘는 나머지 성분을 지배하고 있습니다. 이 경우 주어 ‘철수가’, 목적어 ‘책을’, 부사어 ‘동생에게’는 의존어라고 할 수 있습니다. 그런데 자세히 살펴보면 지배 표지(가, 을, 에게)가 모두 의존어에서 실현되고 있는 점을 알 수 있습니다. 실제로 한국어는 명사 핵이든 동사 핵이든 그 표지를 일관적으로 의존어에 표시하는 언어라고 합니다.

Comment  Read more

Recursive Neural Networks

|

이번 포스팅에선 Recursive Neural Networks(RNN)에 대해 다뤄보려고 합니다. RNN은 Recurrent Neural Networks와 더불어 최근 자연언어처리 분야에서 각광받고 있는 모델인데요. 두 모델 모두 음성, 문자 등 순차적 데이터 처리에 강점을 지니고 있고 이름마저 유사해서 헷갈릴 수 있겠습니다만, 조금 차이가 있는 모델입니다. Recurrent Neural Networks에 대한 자세한 내용은 이곳을 참고하시기 바랍니다. 이번 글은 미국 스탠포드대학의 CS224d 강의를 참고로 하되 순전파와 역전파 계산그래프는 제가 작성했음을 먼저 밝힙니다. 그럼 시작하겠습니다.

recurrent vs convolutional vs recursive

Recurrent Neural Networks는 입력값을 순서대로 받아 하나씩 순차적으로 처리하는 네트워크 구조입니다. 위 그림처럼 ‘the country of my birth’라는 입력이 있을 때 첫 입력값은 ‘the’에 대응하는 단어벡터, 그 다음은 ‘country’, 이후엔 각각 ‘of’, ‘my’, ‘birth’가 됩니다. 그림을 보시면 아시겠지만 입력값 중간에 건너뛰거나 하는 부분이 없고 등장순서대로 그대로 처리하는 구조입니다. 그리고 위 예시에선 은닉층이 하나인 구조를 띄고 있는데요, 마지막 히든 노드인 (2.5, 3.8)은 이전까지의 모든 맥락(the, country, of, my)과 함께 현재 입력값(birth) 정보가 모두 반영된 것을 알 수 있습니다.

이제 Convolutional Neural Networks(CNN)를 볼까요? 입력값을 생략없이 모두 반영한다는 점에서는 Recurrent Neural Networks와 큰 차이는 없습니다. 하지만 입력값을 하나씩(the, country…) 보는 Recurrent Neural Networks와 달리 CNN은 위 그림을 보면 2개 단어씩(the country, country of, of my…) 한번에 분석하고 있는 것을 알 수 있죠. 이건 필터(filter)라는 존재 때문입니다. 여기서는 필터의 크기가 단어 2개로 세팅되어 있는데, 이 필터가 한칸씩 슬라이딩하면서 문장을 단어 두개씩 읽어들여 분석하는 구조입니다. Recurrent Neural Networks는 입력값이 순차적으로 주어지는 데 반해 CNN은 입력값이 한번에 주어지고 필터가 슬라이딩하면서 문장의 지역적인 정보를 반영한다는 점도 조금 다른 점입니다. 위 그림에서 삼각형의 상단 꼭지점에 해당하는 (3,3.5)가 이 문장의 전체 정보가 모두 반영된 벡터입니다.

Recursive Neural Networks(RNN)은 입력값으로 주어지는 몇 개 단어를 묶어서 분석한다는 점에 있어서는 CNN과 유사합니다. 하지만 CNN이 모든 지역정보를 생략없이 반영하는 데 비해 RNN은 일부 정보는 스킵한다는 점에 큰 차이를 보입니다. 예컨대 위 예시에서 ‘the country’는 ‘of my birth’의 수식을 받는 구조입니다. 또 ‘the country’, ‘my birth’는 ‘country of’나 ‘of my’보다는 응집성이 높은 표현입니다. CNN의 방식처럼 ‘the country’, ‘country of’, ‘of my’… 이렇게 모두 분석할 필요가 없다는 것이지요. RNN은 이러한 언어의 hiarchy한 성질을 네트워크 구조에 적극 차용한 모델이라고 볼 수 있습니다.

실제로 언어학에서는 문장을 아래와 같이 계층적으로 나누어 분석하고 있습니다. 한국어 파싱과 관련해서는 이곳을 참고하면 좋을 것 같습니다.

다만 RNN은 Recurrent Neural Networks나 CNN과 달리 트리 구조의 입력값을 반드시 필요로 합니다. 예컨대 아래와 같은데요. 이런 구조의 데이터를 생성하려면 대단히 많은 시간과 비용을 들여야 하는데다 계산도 복잡하기 때문에 RNN이 CNN이나 Recurrent Neural Networks에 비해 주목을 덜 받는 경향이 있는 것 같습니다.

( ( ( The ) ( actors ) ) ( ( ( are ) ( fantastic ) ) ( . ) ) )

마지막으로 Recurrent Neural Networks는 Recursive Neural Networks의 특수 케이스라는 점을 짚어보겠습니다. 만약 Recursive Neural Networks가 모든 지역정보를 순서대로 빠짐없이 반영한다고 하면 아래와 같이 구조를 그릴 수 있는데요, 이를 각도 회전해놓고 보면 본질적으로 Recurrent Neural Networks와 같습니다.

Simple RNN의 구조

RNN은 다음과 같이 여러 단어의 결합으로 이뤄진 표현을 벡터공간에 임베딩해 파싱(parsing), 감성분석(sentiment analysis) 등 특정과업을 수행하는 걸 목표로 합니다.

가장 간단한 형태의 Simple RNN 구조는 아래 그림처럼 나타낼 수 있습니다.

위 그림을 천천히 살펴보면 자식노드(child node)에 해당하는 단어벡터 $c_1$과 $c_2$가 1차적으로 부모노드(parent node) $p_1$으로 합쳐지고, $c_3$는 $p_1$과 함께 $p_2$를 만들고 있음 확인할 수 있습니다. RNN은 부모노드를 만들 때마다 점수(score)도 함께 생성합니다. 만약 파싱을 위한 RNN이라면 이 스코어는 합쳐진 단어들이 얼마나 말이 되는지를 나타내는 점수가 될 것이고, 감성분석을 위한 RNN이라면 해당 점수는 긍/부정 극성을 나타내는 지표가 됩니다.

한편 $p_2$는 또 다른 부모노드와 합쳐지기 위해 또 다시 분석대상이 됩니다. 이를 도식화한 것이 우측 상단의 그림인데요, 실선 방향은 계산그래프의 forward pass, 점선 방향은 그래디언트가 전파되는 backward pass로 이해하시면 좋을 것 같습니다.

$i$번째 부모노드인 $p_i$의 값은 아래처럼 정의됩니다. 각 파라메터의 차원수 또한 아래처럼 정의됩니다. 아래 식에서 pleft와 pright는 각각 $i$번째 부모노드의 좌측, 우측 자식노드입니다. 위 그림 기준으로 하면 $p_2$의 pleft는 $c_3$, pright는 $p_1$이 되는 셈이죠. $d$는 은닉층의 차원수로서 사용자가 지정해주는 하이퍼파라메터입니다.

[{ p }{ i }=\tanh { (W\cdot \begin{bmatrix} { p }{ left } \ { p }{ right } \end{bmatrix}+b) } \ { p }{ i }\in { R }^{ d },\quad b\in { R }^{ d },\quad W\in { R }^{ d\times 2d }\quad]

위 식에서 $W$와 pleft, pright의 결합은 아래와 같습니다.

[W\cdot \begin{bmatrix} { p }{ left } \ { p }{ right } \end{bmatrix}=\begin{bmatrix} { w }{ 1 } & { w }{ 2 } \end{bmatrix}\cdot \begin{bmatrix} { p }{ left } \ { p }{ right } \end{bmatrix}={ w }{ 1 }{ \times p }{ left }+{ w }{ 2 }{ \times p }{ right }]

$i$번째 부모노드의 스코어, $s_i$를 구하는 식은 다음과 같습니다.

[{ s }{ i }={ W }{ s }{ p }{ i }+{ b }{ s }]

RNN은 이렇게 부모노드로부터 계산된 스코어와 해당 부분에 해당하는 정답 레이블과 비교한 후 오차를 최소화하는 방향으로 역전파(backpropagation)를 수행해 파라메터($W$, $b$, $W_s$, $b_s$)를 업데이트하는 방식으로 학습을 합니다. 이와 더불어 말단노드의 입력값들에도 그래디언트를 역전파해 학습시킨다면 벡터공간에 임베딩된 단어벡터를 얻어낼 수 있을 겁니다.

다만 여기서 주의할 것은 forward pass 수행 과정에서 경우의 수를 모두 고려해 스코어가 높은 선택지만을 뽑아 트리 구조를 만든다는 사실입니다. 아래 예시를 보면 처음 부모노드를 만들 때 그럭저럭 말이 되는 ‘The cat’, ‘the mat’만 결합시킵니다. 이후엔 ‘on the mat’을 만듭니다. 이런 식으로 반복 수행해서 전체 문장 ‘The cat sat on the mat’의 트리 구조를 구축하는데요. 학습 초기엔 이런 결합이 중구난방 이루어지다가 어느 정도 학습이 진행되면 정답과 유사하게 트리 구조가 만들어지게 됩니다.

그런데 학습 과정에서의 트리 탐색은 탐욕적(greedy)인 방식입니다. CS224d 강의에 따르면 트리 구조 탐색시 Beam Search Algorithm 등을 이용한다고 합니다. Beam Search 알고리즘은 최고우선탐색(Best-First Search) 기법을 기본으로 하되 기억해야 하는 노드 수를 제한해 효율성을 높인 방식입니다. Beam Search 알고리즘에 대해 좀 더 자세히 살펴보시려면 이곳을 참고하시면 좋을 것 같습니다.

Simple RNN의 forward pass

지금까지 이야기한 simple RNN 구조를 다시 그림으로 그리면 아래와 같습니다. 방향이 바뀌어서 헷갈리실 수도 있는데요, 계산그래프를 좀 더 예쁘게 그리려고 회전한 것이지 본질적으론 같은 그림이니 너무 놀라지 마셔요. 어쨌든 부모노드마다 스코어값이 모두 나온다는 점에 유의해서 보시면 좋을 것 같은데요. $p_1$에서 나오는 스코어는 $s_1$이고요, 마찬가지로 $p_2$에선 $s_2$가 나옵니다.

위 그림을 토대로 forward compute pass를 그리면 아래 그림과 같습니다. 우선 첫번째 부모노드 $p_1$이 만들어지는 과정을 보시죠. 이전 챕터에서 소개드린 수식을 계산그래프로 바꿔놓은 것일 뿐입니다.

이어서 $p_2$를 만드는 과정을 소개해드립니다. $p_2$는 $c_3$에 위 그림에서 만들어진 $p_1$을 결합해 만듭니다.

Simple RNN의 backward pass

역전파 관련 내용이 생소하시거나 헷갈리시는 분은 미국 스탠포드대학의 CS231n 강의를 참고하시면 좋을 것 같습니다. 아시다시피 역전파는 계산과정의 맨 마지막 부분에서 시작되어야 합니다.

우선 forward pass 과정에서 산출된 $s_2$와 정답을 비교해서 계산된 손실(Loss)값은 이미 구해졌다고 칩시다. 그렇다면 $s_2$의 그래디언트, 즉 $dL/ds_2$가 최초로 전파된 그래디언트값이 될 겁니다. 이를 편의상 $ds_2$라고 적었습니다. 계산그래프에서 덧셈연산은 흘러들어온 그래디언트가 그대로 전파되므로 $dL/db_s$는 흘러들어온 그대로 $ds_2$가 될 겁니다.

곱셈 연산은 [흘러들어온 그래디언트 * 로컬 그래디언트(상대방의 변화량)]이므로 $dW_s$는 $p_2 * ds_2$가 됩니다. 마찬가지로 $dp_2$는 $W_s * ds_2$가 됩니다. 하이퍼볼릭탄젠트 $tanh(x)$의 로컬 그래디언트는 $1-tanh^2(x)$이므로 $dp2raw$는 여기에 흘러들어온 그래디언트 $dp_2$를 곱해준 값이 됩니다.

$dp2raw$는 덧셈 그래프를 타고 그대로 분배가 되기 때문에 $db$는 그대로 $dp2raw$가 됩니다. $dW$와 $dp2concat$의 로컬 그래디언트는 각각 $p2concat$, $W$이므로 여기에 흘러들어온 그래디언트 $dp2raw$를 곱해주면 $dW$와 $dp2concat$을 구할 수 있습니다.

마지막 $dc_3$와 $dp_1$에 주의할 필요가 있는데요. $c_3$($d$차원 벡터)과 $p_1$($d$차원 벡터)은 사실 별도의 연산을 하지 않고 그냥 합치기만 한 후 ($2d$차원 x $d$차원) 크기의 가중치 행렬 $W$을 곱해 $p_2$를 만들어 나가게 되는데요. 역전파를 할 때는 이 가중치 행렬의 절반이 $c_3$의 그래디언트에, 나머지 절반이 $p_1$의 그래디언트에 영향을 미치게 됩니다.

따라서 $c_3$의 그래디언트는 $dp2concat$의 첫번째 절반, $p_1$의 그래디언트는 $dp2concat$의 나머지 절반이 됩니다. 혹시 헷갈리신다면 RNN의 기본구조 챕터에서 $W$와 pleft, pright의 결합 부분을 별도로 설명한 식을 보시면 좋을 것 같습니다.

한편 $p_1$의 그래디언트, 즉 $dp_1$은 별도로 별표 표시를 해두었는데요. Recursive Neural Networks는 이름 그대로 부모노드의 값을 재귀적으로 구해 나가는 구조이기 때문에 역전파 과정에서 그래디언트도 재귀적으로 반영되게 됩니다. 다음 그림에서 $dp_1$이 어떻게 반영되는지를 살펴볼까요?

자, 이제 첫번째 부모노드 $p_1$을 구하는 그래프로 왔습니다. 우선 $p_1$을 통해서도 스코어 $s_1$이 계산되기 때문에 여기에서 전파되어 들어오는 그래디언트가 있습니다. 이를 ■로 표시했습니다. 그리고 앞선 그림에서 설명드렸듯이 ★ 또한 역전파 과정에서 흘러들어오게 됩니다. 따라서 위 그림에서 $dp_1$은 ■와 ★를 더해 만들어지게 되는 것이죠.

이후 역전파 과정은 이전에 설명했던 과정과 동일합니다. 지금은 이해를 돕기 위해 가장 단순한 구조의 RNN을 예로 들어서 설명을 드렸지만 이 구조가 깊어지면 각 층위마다 그래디언트가 재귀적으로 더해지면서 복잡한 양상을 띄게 됩니다.

Syntatically-Untied RNN

Syntatically-Unitied RNN(SU-RNN)은 동사구, 명사구 등 기능이 다른 표현에 각기 다른 가중치를 적용하는 RNN 구조입니다. 반면 Simple RNN은 품사 정보에 상관없이 모든 구(phrase)에 같은 가중치를 씁니다. 둘의 비교는 아래 그림과 같습니다.

아래는 학습이 잘 된 SU-RNN의 가중치를 시각화한 그림입니다. 붉은색일수록 그 가중치가 높은데요. DT(관사)-NP(명사구)를 맡은 가중치 $W$를 보시면 DT를 커버하는 $w_1$의 대각성분보다 NP를 담당하는 $w_2$의 대각성분의 값이 큰 걸 확인할 수 있습니다. 이는 SU-RNN이 과업을 수행할 때 관사보다는 명사구를 중요하게 취급했다는 반증인데요. 실제로 ‘a cat’, ‘the cat’ 같은 표현에서 a, the보다는 cat이라는 명사가 중요한 의미를 가지니 직관적으로 납득할 만한 결과인 것 같습니다. 반면 VP(동사구)-NP(명사구)의 경우 둘 모두 중요하게 취급하고 있는 점을 볼 수 있습니다.

마치며

이상으로 RNN과 Recurrent/Convolutional Neural Networks를 비교하고 Simple RNN의 구조와 foward/backward compute pass에 대해 살펴보았습니다. RNN 역시 다른 구조의 딥러닝 아키텍처와 마찬가지로 자연언어처리에 강점을 가진 구조로 널리 알려져 있는데요. 발전된 RNN 모델에 대해 살펴보시려면 이곳을 참고하시면 좋을 것 같습니다. 여기까지 읽어주셔서 진심으로 감사드립니다.

Comment  Read more

로지스틱 회귀

|

이번 포스팅에선 범주형 변수를 예측하는 모델인 로지스틱 회귀(Logistic Regression)에 대해 살펴보려고 합니다. 이번 글은 고려대 강필성 교수님과 역시 같은 대학의 김성범, 정순영 교수님 강의를 정리했음을 먼저 밝힙니다. 로지스틱회귀의 파라메터 추정에 관해서는 이곳을 참고하시면 좋을 것 같습니다. 그럼 시작하겠습니다.

문제의식

다중선형회귀(Multiple Linear Regression)는 수치형 설명변수 $X$와 연속형 숫자로 이뤄진 종속변수 $Y$ 간의 관계를 선형으로 가정하고 이를 가장 잘 표현할 수 있는 회귀계수를 데이터로부터 추정하는 모델입니다. 이 회귀계수들은 모델의 예측값과 실제값의 차이, 즉 오차제곱합(error sum of squares)을 최소로 하는 값들입니다. 이를 만족하는 최적의 계수들은 회귀계수에 대해 미분한 식을 0으로 놓고 풀면 명시적인 해를 구할 수 있습니다. 선형회귀의 파라메터 추정과 관련해서는 이곳을 참고하시면 좋을 것 같습니다.

어쨌든 설명변수가 $p$개인 다중선형회귀의 일반 식은 아래와 같이 쓸 수 있습니다.

[y={ \beta }{ 0 }+{ \beta }{ 1 }{ x }{ 1 }+{ \beta }{ 2 }{ x }{ 2 }+…+{ \beta }{ p }{ x }_{ p }+\varepsilon]

한번 예를 들어보겠습니다. 33명의 성인 여성에 대한 나이와 혈압 데이터가 좌측 하단 표와 같이 주어졌다고 칩시다. 그러면 우리는 오차제곱합을 최소로 하는 회귀계수를 구할 수 있고 이를 그래프로 그리면 우측 하단 그림과 같습니다. 나이라는 설명변수에 대응하는 계수는 1.222로 나타났는데요, 이를 통해 우리는 나이를 한살 더 먹으면 혈압이 1.222mm/Hg만큼 증가한다는 걸 알 수 있게 됩니다.

그러면 혈압이라는 연속형 숫자 대신 범주형 변수를 이용해 위와 같은 회귀모델을 구축한다면 어떤 일이 발생할까요? 좌측 하단과 같이 나이와 암 발생여부(1이면 발병, 0이면 정상) 데이터가 주어졌다고 칩시다. 이를 위와 동일한 방식으로 회귀모델을 구축하고 그래프로 그리면 우측 하단과 같이 우스꽝스러운 모양이 될 겁니다.

위와 같은 문제가 발생하는 근본적인 이유는 종속변수 Y의 성질 때문입니다. 혈압의 경우 숫자 그 자체로 의미를 지니는 변수이지만, 암 발생여부는 그렇지 않습니다. 발병(1)과 정상(0) 사이에 중간 범주가 없을 뿐더러 심지어 정상을 1, 발병을 0으로 바꾸어도 큰 상관이 없습니다. 숫자가 아무 의미를 지니지 않는다는 얘기죠. 이처럼 Y가 범주형(categorical) 변수일 때는 다중선형회귀 모델을 그대로 적용할 수 없다는 겁니다. 이러한 문제 때문에 로지스틱 회귀 모델이 제안됐습니다.

로지스틱 함수, Odds

우선 로지스틱 함수(Logistic Function)승산(Odds)에 대해 알아보겠습니다. 로지스틱 회귀의 뼈대가 되는 아이디어이기 때문입니다.

실제 많은 자연, 사회현상에서는 특정 변수에 대한 확률값이 선형이 아닌 S-커브 형태를 따르는 경우가 많다고 합니다. 이러한 S-커브를 함수로 표현해낸 것이 바로 로지스틱 함수입니다. 분야에 따라 시그모이드 함수로도 불리기도 합니다.

로지스틱 함수는 $x$값으로 어떤 값이든 받을 수가 있지만 출력 결과는 항상 0에서 1사이 값이 됩니다. 즉 확률밀도함수(probability density function) 요건을 충족시키는 함수라는 이야기입니다. 그 식과 그래프 모양은 아래와 같습니다.

[y=\frac { 1 }{ 1+{ e }^{ -x } }]

승산(Odds)이란 임의의 사건 $A$가 발생하지 않을 확률 대비 일어날 확률의 비율을 뜻하는 개념입니다. 아래와 같은 식으로 쓸 수가 있습니다.

[odds=\frac { P(A) }{ P({ A }^{ c }) } =\frac { P(A) }{ 1-P(A) }]

만약 $P(A)$가 1에 가까울 수록 승산은 치솟을 겁니다. 반대로 $P(A)$가 0이라면 0이 될 겁니다. 바꿔 말하면 승산이 커질수록 사건 $A$가 발생할 확률이 커진다고 이해해도 될 겁니다. $P(A)$를 $x$축, 사건 $A$의 승산을 $y$축에 놓고 그래프를 그리면 아래와 같습니다.

이항 로지스틱 회귀

이제 우리는 범주가 두 개인 분류 문제를 풀어야 합니다. 앞선 챕터에서 말씀드렸듯 종속변수 $Y$가 연속형 숫자가 아닌 범주일 때는 기존 회귀 모델을 적용할 수 없습니다.

그럼 문제를 바꿔서 풀어봅시다. 회귀식의 장점은 그대로 유지하되 종속변수 $Y$를 범주가 아니라 (범주1이 될)확률로 두고 식을 세워 보자는 것입니다. 우변은 그대로 두고 좌변만 확률로 바꾸면 다음과 같습니다.

[\begin{align} P(Y=1|X=\overrightarrow { x } )=&{ \beta }_{ 0 }+{ \beta }_{ 1 }{ x }_{ 1 }+{ \beta }_{ 2 }{ x }_{ 2 }+…+{ \beta }_{ p }{ x }_{ p }\=&{ \overrightarrow { \beta } }^{ T }\overrightarrow { x } \end{align}]

그런데 위 식에서 좌변의 범위는 0~1 사이입니다. 하지만 좌변은 음의 무한대에서 양의 무한대 범위를 가지기 때문에 식이 성립하지 않는 경우가 존재할 수 있습니다. 여기서 식을 한번 더 바꿔서, 좌변을 승산(odds)으로 설정해 보겠습니다. 아래 식처럼 쓸 수 있습니다.

[\frac { P(Y=1 X=\overrightarrow { x } ) }{ 1-P(Y=1 X=\overrightarrow { x } ) } ={ \overrightarrow { \beta } }^{ T }\overrightarrow { x }]

하지만 이번에도 양변의 범위가 서로 맞지 않습니다. 좌변(승산)의 범위는 0에서 무한대의 범위를 갖습니다. 하지만 우변(회귀식)은 그대로 음의 무한대에서 양의 무한대 범위입니다.

여기서 좌변(승산)에 로그를 취하면 어떻게 될까요? 로그 승산의 그래프는 아래와 같은데요. 이렇게 되면 로그 승산의 범위 또한 우변처럼 음의 무한대에서 양의 무한대가 됩니다. 이제야 비로소 좌변(승산)이 우변(회귀식)의 범위와 일치하게 되는 셈이지요.

지금까지 말씀드린 내용을 종합해 로지스틱 회귀 모델의 식을 쓰면 다음과 같습니다.

[\log { (\frac { P(Y=1 X=\overrightarrow { x } ) }{ 1-P(Y=1 X=\overrightarrow { x } ) } ) } ={ \overrightarrow { \beta } }^{ T }\overrightarrow { x }]

위 식 회귀계수 벡터 $β$의 의미는 이렇습니다. 예컨대 입력벡터 $x$의 첫번째 요소인 $x_1$에 대응하는 회귀계수 $β_1$이 학습 결과 2.5로 정해졌다고 칩시다. 그렇다면 $x_1$이 1단위 증가하면 범주 1에 해당하는 로그 승산이 2.5 커집니다.

위 식을 입력벡터 $x$가 주어졌을 때 범주1일 확률을 기준으로 정리해주면 다음과 같습니다. ($x$가 주어졌을 때 범주1일 확률을 $p(x)$, 위 식 우변을 $a$로 치환해 정리)

[\begin{align} \frac { p\left( x \right) }{ 1-p\left( x \right) } =&{ e }^{ a }\ \p\left( x \right) =&{ e }^{ a }\left{ 1-p\left( x \right) \right} \ =&{ e }^{ a }-{ e }^{ a }p\left( x \right) \ \p\left( x \right) \left( 1+{ e }^{ a } \right) =&{ e }^{ a }\ \p\left( x \right) =&\frac { { e }^{ a } }{ 1+{ e }^{ a } } =\frac { 1 }{ 1+{ e }^{ -a } } \ \ \therefore P(Y=1|X=\overrightarrow { x } )=&\frac { 1 }{ 1+{ e }^{ -{ \overrightarrow { \beta } }^{ T }\overrightarrow { x } } } \end{align}]

최종 도출된 식은 어디서 많이 본 형태 아닙니까? 네 맞습니다. 바로 직전 챕터에서 설명드린 로지스틱 함수의 꼴과 같습니다. 이 때문에 로지스틱 회귀라는 이름이 붙은 것 같습니다.

이항 로지스틱 회귀의 결정경계

위와 같은 이항 로지스틱 모델에 범주 정보를 모르는 입력벡터 $x$를 넣으면 범주 1에 속할 확률을 반환해 줍니다. 그럼 그 확률값이 얼마나 되어야 범주 1로 분류할 수 있을까요? 여러 선택지가 있겠으나 가장 간단한 방식은 다음과 같을 겁니다.

[P(Y=1 X=\overrightarrow { x } )>P(Y=0 X=\overrightarrow { x } )]

범주가 두 개뿐이므로, 위 식 좌변을 $p(x)$로 치환하면 식을 다음과 같이 정리할 수 있습니다.

[p\left( x \right) >1-p\left( x \right) \ \frac { p\left( x \right) }{ 1-p\left( x \right) } >1\ \log { \frac { p\left( x \right) }{ 1-p\left( x \right) } } >0 \ \ \therefore { \overrightarrow { \beta } }^{ T }\overrightarrow { x } >0]

마찬가지로 $β^Tx<0$ 이면 해당 데이터의 범주를 0으로 분류하게 됩니다. 따라서 로지스틱모델의 결정경계(decision boundry)는 $β^Tx=0$인 하이퍼플레인(hyperplane)입니다. 입력벡터가 2차원인 경우 아래와 같이 시각화할 수 있습니다.

공간적으로 이해하기

회귀계수 벡터 $β$는 임의의 두 벡터의 차로 표시할 수 있다고 칩시다($β=β_0-β_1$). 그렇다면 범주가 1이 될 확률은 아래와 같이 쓸 수 있습니다.

[\begin{align} y&=\frac { 1 }{ 1+exp({ -\beta }^{ T }x) } \ &=\frac { exp(-{ \beta }_{ 1 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp({ -\beta }^{ T }x-{ \beta }_{ 1 }^{ T }x) } \ &=\frac { exp(-{ \beta }_{ 1 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp{ -{ (\beta }_{ 0 }^{ T }-{ \beta }_{ 1 }^{ T }+{ \beta }_{ 1 }^{ T })x} } \ &=\frac { exp(-{ \beta }_{ 1 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp(-{ \beta }_{ 0 }^{ T }x) } \end{align}]

이항 로지스틱 회귀이므로 범주가 0일 확률은 $1-y$가 됩니다. 아래와 같습니다.

[\begin{align} 1-y&=1-\frac { exp(-{ \beta }_{ 1 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp(-{ \beta }_{ 0 }^{ T }x) } \ &=\frac { exp(-{ \beta }_{ 1 }^{ T }x)+exp(-{ \beta }_{ 0 }^{ T }x)-exp(-{ \beta }_{ 1 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp(-{ \beta }_{ 0 }^{ T }x) } \ &=\frac { exp(-{ \beta }_{ 0 }^{ T }x) }{ exp(-{ \beta }_{ 1 }^{ T }x)+exp(-{ \beta }_{ 0 }^{ T }x) } \end{align}]

$y$와 $1-y$ 모두 분모가 같으므로 분자가 결정적인 역할을 합니다. 범주가 1이 될 확률에 중요한 역할을 하는 건 벡터 $β_1$, 0이 될 확률에 중요한 역할을 하는 건 벡터 $β_0$입니다. 이 둘을 각각 범주1과 범주0의 대표 벡터로 해석할 수 있습니다. 이를 그림으로 도식화하면 아래와 같습니다

.

그런데 두 클래스의 데이터가 같은 방향에 존재할 경우 $β_0, β_1$만으로는 분류하기 어려울 수도 있습니다.

벡터 $β$에 포함된 bias term $β_{k0}$(스칼라)는 범주를 잘 구분하도록 입력값 $x$를 평행이동시키는 역할을 합니다.

뉴럴넷과의 관계

feed-forward neural network의 Fully connected Layer의 하나의 셀에 활성함수(activation function)로 시그모이드를 쓰면 이항 로지스틱 회귀와 같습니다. (그림 출처 : 스탠포드 CS231n) 다시 말해 이항로지스틱회귀와 시그모이드 함수가 깊은 관련을 맺고 있습니다.

다항 로지스틱 회귀

그렇다면 범주가 세 개 이상이면 어떻게 해야 할까요? 우선 범주가 3개뿐이라고 가정해 보겠습니다. 그러면 이항 로지스틱 회귀 모델 두 개로 문제를 해결할 수 있습니다.

[\log { \frac { P(Y=1 X=\overrightarrow { x } ) }{ P(Y=3 X=\overrightarrow { x } ) } } ={ \beta }_{ 1 }^{ T }{ \overrightarrow { x } }\ \log { \frac { P(Y=2 X=\overrightarrow { x } ) }{ P(Y=3 X=\overrightarrow { x } ) } } ={ \beta }_{ 2 }^{ T }{ \overrightarrow { x } }]

범주가 3개인데 왜 이항 로지스틱 회귀 모델 두 개밖에 안쓰냐고요? ‘세번째 범주에 속할 확률=1-첫번째 범주에 속할 확률-두번째 범주에 속할 확률’이라는 사실을 활용해, 위 두 개 수식을 정리해 대입해 풀면 범주별로 아래와 같이 정리할 수 있습니다.

[P(Y=1 X=\overrightarrow { x } )=\frac { { e }^{ { \overrightarrow { { \beta }{ 1 } } }^{ T }\overrightarrow { x } } }{ 1+{ e }^{ { \overrightarrow { { \beta }{ 1 } } }^{ T }\overrightarrow { x } }+{ e }^{ { \overrightarrow { { \beta }_{ 2 } } }^{ T }\overrightarrow { x } } } \ P(Y=2 X=\overrightarrow { x } )=\frac { { e }^{ { { \overrightarrow { { { \beta } }{ 2 } } } }^{ T }\overrightarrow { x } } }{ 1+{ e }^{ { \overrightarrow { { \beta }{ 1 } } }^{ T }\overrightarrow { x } }+{ e }^{ { \overrightarrow { { \beta }_{ 2 } } }^{ T }\overrightarrow { x } } } \ P(Y=3 X=\overrightarrow { x } )=\frac { 1 }{ 1+{ e }^{ { \overrightarrow { { \beta }{ 1 } } }^{ T }\overrightarrow { x } }+{ e }^{ { \overrightarrow { { \beta }{ 2 } } }^{ T }\overrightarrow { x } } }]

$K$개 범주를 분류하는 다항로지스틱 회귀 모델의 입력벡터 $x$가 각 클래스로 분류될 확률은 아래 식과 같습니다.

[\begin{align} P(Y=k|X=\overrightarrow { x } )=&\frac { { e }^{ { \overrightarrow { { { \beta } }_{ k } } }^{ T }\overrightarrow { x } } }{ 1+\sum _{ i=1 }^{ K-1 }{ { e }^{ { \overrightarrow { { { \beta } }_{ i } } }^{ T }\overrightarrow { x } } } } \quad (k=0,1,…,K-1)\ P(Y=K|X=\overrightarrow { x } )=&\frac { 1 }{ 1+\sum _{ i=1 }^{ K-1 }{ { e }^{ { \overrightarrow { { { \beta } }_{ i } } }^{ T }\overrightarrow { x } } } } \end{align}]

다항로지스틱회귀와 소프트맥스

로그승산을 활용해 $K$개 범주를 분류하는 다항로지스틱 회귀 모델을 유도하게 되면, 이항로지스틱 회귀 모델 $K-1$개를 써서 $K-1$개 회귀계수 벡터가 도출됩니다. 따라서 $K$번째 범주에 속할 확률은 이 범주에 해당하는 회귀계수 벡터 없이도 자동적으로 정해지게 됩니다. 즉 1에서 $K-1$개 각각의 범주에 속할 확률의 합을 뺀 나머지입니다.

그러면 $K$번째 범주에 해당하는 회귀계수 벡터도 구할 수 없을까요? 모델을 다음과 같이 구축해 봅시다.

우선 ‘로그승산’으로 된 좌변을 ‘로그확률’로 바꿉니다. 0을 제외한 범위에서 확률($x$)은 승산($x/(1-x)$)보다 작으므로(참고), 식을 변형하면서 원래 좌변보다는 작아진 셈입니다. 이에 우변에서 어떤 값을 빼줍니다. 그런데 다항로지스틱 회귀 모델에서 승산의 분모는 $K$번째 범주에 속할 확률로 모두 같으므로 $K$개 식 모두에 같은 값을 빼면 됩니다. 다음과 같습니다.

[\log { P(Y=1 X=\overrightarrow { x } ) } ={ \overrightarrow { { { \beta } }_{ 1 } } }^{ T }\overrightarrow { x } -\log { Z } \ \log { P(Y=2 X=\overrightarrow { x } ) } ={ \overrightarrow { { { \beta } }_{ 2 } } }^{ T }\overrightarrow { x } -\log { Z } \ …\ \log { P(Y=K X=\overrightarrow { x } ) } ={ \overrightarrow { { { \beta } }_{ K } } }^{ T }\overrightarrow { x } -\log { Z }]

로그 성질을 활용해 $c$번째 범주에 속할 확률을 기준으로 식을 정리하면 다음과 같습니다.

[\log { P(Y=c) } +\log { Z } ={ \overrightarrow { { { \beta } }{ c } } }^{ T }\overrightarrow { x } \ \log { \left{ P(Y=c)\times Z \right} } ={ \overrightarrow { { { \beta } }{ c } } }^{ T }\overrightarrow { x } \ P(Y=c)\times Z={ e }^{ { \overrightarrow { { { \beta } }{ c} } }^{ T }\overrightarrow { x } }\ P(Y=c)=\frac { 1 }{ Z } { e }^{ { \overrightarrow { { { \beta } }{ c } } }^{ T }\overrightarrow { x } }]

식을 변형했더라도 전체 확률합은 1이 되어야 합니다. 이 성질을 활용해 $Z$를 유도하면 다음과 같습니다.

[\begin{align} 1=&\sum _{ k=1 }^{ K }{ P(Y=k) } \ =&\sum _{ k=1 }^{ K }{ \frac { 1 }{ Z } { e }^{ { \overrightarrow { { { \beta } }_{ k } } }^{ T }\overrightarrow { x } } } \ =&\frac { 1 }{ Z } \sum _{ k=1 }^{ K }{ { e }^{ { \overrightarrow { { { \beta } }_{ k } } }^{ T }\overrightarrow { x } } } \ \ \therefore &Z=\sum _{ k=1 }^{ K }{ { e }^{ { \overrightarrow { { { \beta } }_{ k } } }^{ T }\overrightarrow { x } } } \end{align}]

따라서 $c$번째 범주에 속할 확률은 다음과 같습니다. 소프트맥스 함수와 그 모양이 동일함을 확인할 수 있습니다.

[P(Y=c)=\frac { { e }^{ { \overrightarrow { { { \beta } }{ c } } }^{ T }\overrightarrow { x } } }{ \sum _{ k=1 }^{ K }{ { e }^{ { \overrightarrow { { { \beta } }{ k } } }^{ T }\overrightarrow { x } } } }]

요컨대 다항로지스틱 회귀는 소프트맥스 함수와 깊은 관련을 맺고 있다는 이야기입니다. 자세한 내용은 위키피디아를 참고하시면 좋을 것 같습니다.

Comment  Read more