SW/인공지능

인공지능 : Recurrent Neural Networks(RNN) 개념, 분석

얇은생각 2019. 6. 11. 12:30
반응형

자연어를 이해하는 방법을 기계에게 가르치는 방법


소개

인간은 매초마다 생각을 처음부터 시작하는 것이 아닙니다. 이 에세이를 읽으면서, 여러분은 이전의 단어들에 대한 이해를 바탕으로 각각의 단어를 이해하게 됩니다. 모든 것을 버리고 처음부터 다시 생각하기 시작하는 것은 아닙니다. 당신의 생각은 끈기가 있어요.


전통적인 신경망은 이것을 할 수 없습니다. 그리고 이것은 주요한 단점처럼 보입니다. 예를 들어, 영화의 모든 지점에서 어떤 종류의 이벤트가 발생하는지 분류하고 싶다고 상상해 보세요. 전통적인 신경 네트워크가 어떻게 이 영화의 이전 사건에 대한 추론을 나중에 그 사실을 알리기 위해 사용할 수 있을지는 분명하지 않습니다.


반복 신경망(RNN)이 이 문제를 해결합니다. 이것은 정보가 지속되도록 해주는 루프가 있는 네트워크입니다.


인공지능 : Recurrent Neural Networks(RNN) 개념, 분석


위 다이어그램에서 신경망 A 덩어리가 일부 입력 xt를 보고 값 ht를 출력합니다. 루프를 사용하면 네트워크의 한 단계에서 다음 단계로 정보를 전달할 수 있습니다. 반복되는 신경망은 동일한 네트워크의 여러 복사본으로 생각할 수 있으며, 각 복사본은 후임자에게 메시지를 전달합니다. 루프를 풀 경우 어떻게 되는지 고려해볼 수 있습니다.


인공지능 : Recurrent Neural Networks(RNN) 개념, 분석


이 사슬과 같은 성질은 반복되는 신경망이 배열과 밀접하게 관련되어 있다는 것을 보여줍니다. 그러한 데이터에 사용하기 위한 신경 네트워크의 자연적인 구조입니다. 그리고 확실히 사용됩니다! 지난 몇 년간 RNN을 언어 인식, 언어 모델링, 번역, 이미지 캡션 등 다양한 문제에 적용하여 놀라운 성공을 거두었습니다. 




Recurrent Neural Networkd(RNN)란 무엇입니까?

Vanilla Neural Networks(또 Convolutional Networks)의 제한 사항은 API가 너무 제한적이라는 것입니다. 즉, 고정 크기의 벡터를 입력(예: 이미지)으로 받아들이고 고정된 크기의 벡터를 출력(예: 서로 다른 클래스의 확률)으로 생성합니다. 뿐만 아니라, 이러한 모델은 고정된 양의 계산 단계(예: 모델의 레이어 수)를 사용하여 이 매핑을 수행합니다.


Recurrent net이 더 흥미로운 이유는 벡터의 시퀀스(입력, 출력 또는 가장 일반적인 경우)를 통해 작동하게 하기 때문입니다.


몇 가지 예를 통해 보다 구체적으로 확인할 수 있습니다.


인공지능 : Recurrent Neural Networks(RNN) 개념, 분석


각 직사각형은 벡터이고 화살표는 함수(예: 행렬 곱하기)를 나타냅니다. 입력 벡터는 빨간색으로, 출력 벡터는 파란색으로, 녹색 벡터는 RNN의 상태를 유지합니다(자세한 내용은 곧). 왼쪽에서 오른쪽으로 각 모형을 논해보겠습니다.


- 고정 크기 입력에서 고정 크기 출력(예: 영상 분류)까지 RNN이 없는 처리 모드입니다.

- 시퀀스 출력(예: 영상 캡션은 이미지를 가져오고 단어의 문장을 출력)입니다.

- 시퀀스 입력(예: 주어진 문장이 양 또는 음의 정서를 표현하는 것으로 분류되는 정서 분석)입니다.

- 시퀀스 입력 및 시퀀스 출력(예: Machine Translation: RNN은 영어로 문장을 읽은 다음 프랑스어로 문장을 출력)합니다.

- 시퀀스 입력 및 출력(예: 비디오의 각 프레임에 레이블을 지정하려는 비디오 분류)을 동기화합니다.


녹색이 고정되어 있고 원하는 횟수만큼 적용할 수 있기 때문에 모든 경우 길이 순서에 사전 지정된 제약 조건이 없습니다.


RNN은 입력 벡터와 상태 벡터를 결합하여 새로운 상태 벡터를 생성합니다.




RNN Computation

그러면 이런 것들이 어떻게 동작할까요?


입력 벡터 x를 수신하고 출력 벡터 y를 제공합니다. 그러나 이 출력 벡터의 내용은 방금 입력한 입력뿐만 아니라 과거에 입력한 입력의 전체 기록에 영향을 받습니다. 클래스로 작성된 RNN의 API는 단일 단계 기능으로 구성됩니다.



rnn = RNN() y = rn.step(x) # x는 입력 벡터, y는 RNN의 출력 벡터입니다.



RNN 클래스는 단계를 호출할 때마다 업데이트되는 일부 내부 상태를 가집니다. 가장 간단한 경우 이 상태는 숨겨진 단일 벡터 h로 구성됩니다. 다음은 Vanilla RNN에서 단계 기능을 구현한 것입니다.



class RNN:
# ...
def step(self, x):
# 숨겨진 상태를 업데이트합니다.
self.h = np.tanh(np.dot(self.W_hh, self.h) + np.dot(self.W_xh, x))
# 출력 벡터를 계산합니다.
y = np.dot(self.W_hy, self.h)
return y


위는 바닐라 RNN의 정방향 패스를 지정합니다. 이 RNN의 매개 변수는 다음과 같은 세 가지 매트릭스입니다.


- W_h : 이전 숨김 상태를 기준으로 매트릭스입니다.

- W_xh : Current 입력에 기반한 매트릭스입니다.

- W_hy : 숨겨진 상태와 출력 사이의 매트릭스입니다.


숨겨진 상태 self.h는 zero vector로 초기화됩니다. np.tanh(하이퍼볼릭 접선) 함수는 활성도를  [-1, 1] 범위로 누르는 비선형성을 구현합니다.


tanh의 내부에는 두 가지 용어가 있습니다. 하나는 이전 숨겨진 상태에 기초하고 다른 하나는 현재 입력에 기초합니다. numpy np.dot는 행렬 곱셈입니다. 이 두 중간자는 덧셈과 상호작용을 하고, 그리고 나서 tanh에 의해 새로운 상태 벡터로 들어갑니다.


숨겨진 상태 업데이트에 대한 산술 표기법은 다음과 같습니다.


RNN의 행렬을 무작위 숫자로 초기화하며, 트레인 중 대부분의 작업은 바람직한 동작을 발생시키는 매트릭스를 찾는 것으로, 입력 순서에 대응하여 보고자 하는 출력의 종류를 나타내는 손실 함수로 측정됩니다.



y1 = rnn1.step(x)
y = rnn2.step(y1)


즉, 두 개의 RNN이 있습니다. 한 개의 RNN은 입력 벡터를 수신하고 두 번째 RNN은 첫 번째 RNN의 출력을 입력으로 수신합니다. 이러한 RNN은 알지도 못하고 신경도 쓰지 않습니다. 모두 벡터만 들어오고 나갈 뿐이며, 백프로파그 중에 각 모듈을 통해 흐르는 일부 gradients도 있습니다.


LSTM(Long Sort-Term Memory) 네트워크와는 약간 다른 공식 방식을 사용한다는 것을 간단히 언급하고자 합니다. LSTM은 보다 강력한 업데이트 방정식과 일부 매력적인 백프로파제이션 역학적 특성 때문에 실제로 약간 더 잘 작동하는 특정 유형의 RNN입니다. 업데이트 계산을 위한 수학적 형태(self.h = ...)는 조금 더 복잡해집니다. 


LSTM은 별도의 포스팅에서 다루겠습니다.




예제 - 문자 수준 언어 모델

RNN 문자 수준의 언어 모델을 알아보겠습니다. 즉, RNN에 엄청난 양의 텍스트를 제공하고, 이전 문자의 시퀀스가 주어진 시퀀스에서 다음 문자의 확률 분포를 모델링하도록 요청할 것입니다. 그러면 한 번에 한 문자씩 새 텍스트를 생성할 수 있습니다.


예를 들어, 단지 4개의 가능한 단어 "헬로"만을 가지고 있고 훈련 순서 "헬로"에 대한 RNN을 훈련하기를 원했다고 가정해보세요. 이 트레인 시퀀스는 사실상 4가지 개별 교육 예제인 것입니다.


- "h"의 문맥으로 볼 때 "e"의 확률은 높아야 합니다.

- "l"은 "he"의 맥락에서 가능해야 합니다.

- "hel"의 맥락을 고려할 때 "l"도 그럴 가능성이 높습니다.

- "hell"의 맥락을 고려할 때 "o"가 될 가능성이 높습니다.


구체적으로, 우리는 1-of-k 인코딩을 사용하여 각 문자를 벡터로 인코딩하고 단계 기능의 도움을 받아 한 번에 하나씩 RNN에 공급할 것입니다. 그런 다음 4차원 출력 벡터(문자당 1차원)의 시퀀스를 관찰합니다. 이 시퀀스에서 RNN이 현재 다음 각 문자에 할당하는 신뢰도로 해석합니다. 


인공지능 : Recurrent Neural Networks(RNN) 개념, 분석


예를 들어, RNN이 문자 "h"를 보았을 때 첫 번째 단계에서 1.0의 신뢰도를 다음 문자 "h", 2.2에서 "e", -3.0에서 "l" 그리고 4.1에서 "o"로 지정했습니다. 트레인 데이터("hello" 문자열)에서 다음 문자는 "e"이므로, 신뢰도(녹색)를 높이고 다른 모든 문자(빨간색)의 신뢰도를 낮추려고 합니다. 마찬가지로, 네트워크에서 더 높은 신뢰도를 할당하고자 하는 4가지 단계마다 원하는 대상 문자가 있습니다.


RNN은 전적으로 다른 작동으로 구성되므로 백프로그래그 알고리즘(미적분학에서 체인 규칙을 재귀적용)을 실행하여 모든 가중치를 어떤 방향으로 조정하여 정확한 목표값(녹색 굵은 숫자)의 점수를 높여야 하는지 파악할 수 있습니다.


그런 다음 파라미터 업데이트를 수행할 수 있습니다. 이 업데이트는 모든 가중치를 이 경사 방향으로 아주 작은 양으로 누르는 것입니다. 매개변수 업데이트 후 RNN에 동일한 입력을 입력하면 올바른 문자(예: 처음 단계의 "e")의 점수가 약간 더 높고(예: 2.2가 아닌 2.3) 잘못된 문자의 점수가 약간 더 낮다는 것을 알 수 있습니다.


그런 다음 네트워크가 통합되고 네트워크가 예측하는 내용이 다음에 항상 예측되는 트레인 데이터와 일관될 때까지 이 프로세스를 여러 번 반복합니다.


보다 기술적인 설명은 모든 출력 벡터에 대해 표준 소프트맥스 분류기(일반적으로 cross entropy loss)를 동시에 사용한다는 것입니다. RNN은 미니 배치 Stochastic Gradient Descent로 트레인되었으며, 업데이트를 안정화하기 위해 RMSProp 또는 Adam(매 변수별 적응 학습 속도 방법)을 사용하는 것을 좋아합니다.


또한 문자 "l"을 처음 입력하면 대상이 "l"이지만 두 번째 대상은 "o"입니다. 따라서 RNN은 입력에만 의존할 수 없으며 이 작업을 수행하려면 컨텍스트를 추적하기 위해 반복 연결을 사용해야 합니다.


테스트 시점에 문자를 RNN에 입력하여 다음에 올 문자에 대한 분포를 얻습니다. 우리는 이 분포를 샘플로 추출하고, 다음 문자를 받기 위해 바로 다시 공급합니다. 이 과정을 반복하면 텍스트 샘플링이 됩니다.

반응형