ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [cs231n] 10강 순환 신경망 (Recurrent Neural Network) (1/4, 계산 그래프 (computational graph))
    AI 2021. 4. 12. 19:10

    기억을 되살려보면, 지난시간에 우리는 CNN 아키텍처에 대해 이야기 했죠. 우리는 이미지넷 (ImageNet) 분류 대회의 여러 우승자들 중 몇개를 시간 순서로 봤습니다. 돌파구가 발견된 결과였던 것 같죠. 봤듯이 2012년에는 알렉스넷 (AlexNet) 아키텍처였죠, 9개 계층의 합성곱 신경망이었습니다. 그건 놀랍게 잘 했고, 그것이 컴퓨터 비전에 있어서 이 전체 딥러닝 혁명을 시작한 거죠. 그리고 이 많은 모델들을 주류 (mainstream)로 끌어올렸죠.

    그리고 나서 우리는 2년 정도 건너 뛰어서 2014년 이미지넷 대회에서 2개의 매우 재미있는 모델인 VGG와 구글넷 (GoogLeNet)을 봤습니다. 그것들은 훨씬 더 깊었죠. VGG는 16과 19 계층 모델이 있었고 구글넷은 22 계층 모델이었던 것 같네요. 그런데 한가지 이 모델들에 대해서 재밌는 것은, 2014년 이미지넷 대회는 배치 정규화 (batch normalization)가 발명되기 직전이었다는 겁니다. 그래서 이 때에는, 배치 정규화 발명전이어서, 이런 약 20계층의 비교적 깊은 모델들을 훈련시키는 것은 매우 도전적 (challenging)이었죠. 그래서 사실, 이 두 모델 모두 깊은 모델들이 수렴하도록 하기 위해서 약간의 해킹에 의존해야 했습니다. 그래서 VGG에 대해서는 16과 19계층 모델이 있지만, 사실 먼저 11 계층 모델을 훈련시켰죠. 왜냐면, 수렴하도록 할 수 있는 것이 그것이었으니까요. 그 다음 몇 개의 추가적인 임의의 계층을 중간에 넣었고 훈련을 계속해서 16과 19 계층 모델을 훈련시킨 거죠. 그래서 이런 훈련 과정을 관리하는 것이 2014년, 배치 정규화가 발명되기 전에는, 매우 도전적이었습니다. 비슷하게, 구글넷에 대해서는, 구글넷이 이런 보조적인 (auxiliary) 분류기가 있다는 것을 봤는데요. 그건 망의 낮은 계층에 붙어 있었죠. 이런 것들은 사실 좋은 분류 성능을 얻기 위해서 진짜 필요한 것이 아닙니다. 이것은 그냥 추가적인 경사가 망의 더 낮은 계층으로 바로 들어가게 하도록 하는 방법이었던 거죠. 이것도 또한 배치 정규화 발명 이전이므로, 일단 이런 망에 배치 정규화가 있다면, 이 더 깊은 모델들을 수렴하도록 하기 위해서 더 이상 이런 약간 예쁘지 않은 해킹을 할 필요가 없는 거죠. 

    그다음 우리는 2015년 이미지넷 대회에서 이 정말 멋진 레즈넷 (ResNet)이라고 불리는 모델을 봤죠. 이 중복 망 (residual network)은 이런 단축 연결들 (shortcut connections)이 있어서 이런 작은 중복 블록들  (residual blocks)을 가지고 있고, 여기서 우리의 입력을 받아 들이고, 중복 블록으로 통과시킨 다음, 그 블럭에 대한 입력을 이 합성곱 계층으로부터의 출력에 더하는 거죠. 이건 일종의 재밌는 아키텍처지만 2개의 매우 좋은 특성을 가지고 있습니다. 하나는 만약 이 중복 블록에서 모든 가중치를 0으로 설정하면, 이 블록은 항등 (identity)과 경쟁한다는 겁니다. 그래서 어떤 방면에서는, 이 모델이 필요로하지 않는 계층을 사용하지 않고 학습하는 것은 비교적 쉽죠. 게다가, 그건 이 신경망의 문맥에서 L2 정규화에 대한 이런 해석을 추가합니다. 왜냐면, L2 정규화를 망의 가중치에 일단 넣으면, 그것이 모든 파라미터를 0을 향해 몰아 붙입 (drive)니다. 아마 표준적인 합성곱 아키텍처가 0을 향해 밀어붙인다면, 그건 말이 안되죠. 그러나 중복 망의 문맥에서는, 모든 파라미터를 0을 향해 밀어붙이면, 그건 모델이 필요하지 않은 계층을 사용하지 않도록 유도하는 거죠. 왜냐면, 그건 그 중복 블록들을 항등으로 몰아붙일거니까요. 그게 분류에 필요하던 필요하지 않던간에요. 이 중복 망 (residual network)의 진짜 유용한 다른 특성은 역방향 경로에서의 경사 흐름과 관련되어 있습니다. 역방향 전달에서 이 더하기 게이트 (addition gate)에서 무슨 일이 벌어지는지 기억해 보면, 업스트림 경사 (upstream gradient)가 더하기 게이트로 들어올 때, 그건 나눠지고 2개의 다른 경로로 분기되죠. 그래서 업스트림 경사가 들어오면, 이 합성곱 블록을 지나면서 하나의 경로로 갑니다. 그러나 그건 또한 이 중복 연결 (residual connection)을 통해 경사가 직접적으로 연결되죠. 그래서 이 중복 블록을 서로서로 많이 쌓는 것을 생각해 보면, 우리의 망은 잠재적으로는 결국 수백개의 계층이 있게 될 겁니다. 그럼 이 중복 연결은 일종의 경사 슈퍼 고속도로를 제공해서 경사가 전체 망을 통과하면서 거꾸로 흐르도록 하는 거죠. 그래서 이건 훨씬 더 쉽고 훨씬 더 빠르게 훈련할 수 있도록 해 줍니다. 그리고 사실상 이것들이 합리적으로 잘 수렴되게 하죠. 심지어 모델이 잠재적으로 수백개의 계층 깊이라고 하더라도 말입니다. 그리고 모델에서 이런 경사 흐름을 관리하는 아이디어는 사실 머신 러닝의 모든 곳에서 슈퍼 중요합니다. 순환망 (recurrent network)에서도 슈퍼 널리 사용되죠 (prevailent). 그래서 이 경사 흐름에 대한 아이디어를 오늘 수업에서 분명히 다시 또 볼 겁니다.

    우리는 또한 몇 개의 더 이국적이고 더 최근의 CNN 아키텍처들을 봤죠. 덴스넷 (DenseNet)과 프랙탈넷 (FractalNet)을 포함해서요. 이 아키텍처들을 경사 흐름에서 생각하면, 그것들은 더 잘 이해가 됩니다. 덴스넷과 프랙탈넷 같은 것들은 모델 내에서 이 더하기 단축 혹은 항등 연결 (identity connections)을 더하고 있는 거죠. 이 모델들 내에서 역방향 전달에서 어떤 일이 벌어지는지 생각해 보면, 이 추가적인 웃긴 위상들은 사실 경사가 망의 제일 끝의 손실로부터 흐를 수 있는 직접적인 경로를 제공하고 있는 겁니다. 망의 모든 여러 계층으로 쉽게 흐를 수 있도록 말입니다. 다시 얘기하지만 CNN 아키텍처에서 이 경사 흐름을 적절히 관리하는 아이디어는 지난 몇 년 동안 우리가 진짜 많이 보게 된 것입니다. 그리고 아마도 더 이상한 아키텍처들이 발명되면서 점점 더 진보해 나가는 것을 보게 될 겁니다.

    우리는 또한 이런 좋은 플롯 (plot)을 보았는데요. 이 다양한 모델들의 연산숫자 대 (vs.) 파라미터 숫자 대 (vs.) 실행시간에 대한 성능을 그린거죠. 여기에는 몇 가지 재미있는 특징들이 있으니 이 플롯을 깊이 살펴봐도 좋습니다.

    VGG와 알렉스넷은 엄청나게 많은 수의 파라미터들을 가지고 있고, 이 파라미터들은 사실 대부분 모델의 완전 연결 계층 (fully connected layer)에 있습니다. 알렉스넷은 약 6천2백만 파라미터를 가지고 있고, 마지막 완전 연결 계층을 보면, 알렉스넷에서 그 마지막 완전 연결 계층은 6 x 6 x 256 활성 볼륨 (activation volume)으로부터 이 496의 완전 연결 벡터로 들어오고 있죠. 가중치 행렬이 그 계층에서 어떻게 보여야 하는지를 생각해 보면, 그 가중치 행렬은 거대하죠. 6 x 6 x 6 x 256 x 496개의 항목이 있습니다. 그걸 다 곱해보면, 하나의 계층이 3천8백만 파라미터를 가진다는 것을 알 수 있죠. 전체 알렉스넷 모델의 파라미터중 절반 이상이 마지막 완전 연결 계층에 있는 겁니다. 그리고 알렉스넷의 완전 연결 계층들에 있는 모든 파라미터들을 다 더하면, 이 다른 완전 연결 계층들도 다 포함해서요, 보다시피 알렉스넷의 6천2백만개 바라미터중 5천9백만개가 이 완전 연결 계층들에 있는거죠. 그래서 구글넷이나 레즈넷 같은 다른 아키텍처로 가면, 그들은 많은 이 큰 완전 연결 계층을 없애고, 망 끝에서 전체 평균 풀링 (global average pooling)하는 것을 선호하죠. 이건 이러한 더 좋은 아키텍처들이 정말로 파라미터 숫자들을 줄이려고 하고 있는거죠.

    여기까지가 지난시간에 우리가 본 CNN 아키텍처에 대한 간단한 정리였고, 오늘은 제가 좋아하는 주제중 하나인, 순환 신경망 (recurrent neural networks)으로 넘어가겠습니다.

    지금까지, 이 수업에서는, 우리가 본 것은, 일종의 바닐라 피드포워드 망 (vanilla feed forward network)이었다고 생각하고 싶네요. 우리의 망 아키텍처 모두 이런 특징이 있죠. 어떤 입력을 받고, 그 입력은 고정된 크기의 객체 (obect)이죠. 이미지나 벡터일 수 있습니다. 그 입력이 몇 가지 숨겨진 계층의 집합을 통과하도록 넣고 단일 출력을 내는 거죠. 분류일 수도 있고, 카테고리 집합에 대한 분류 점수 집할 수도 있죠.

    그러나 기계 학습 문맥에서는, 우리는 모델이 처리할 수 있는 데이타 종류에 있어서 더 많은 유연성을 가지고 싶습니다. 그래서 일단 이 순환 신경망 아이디어로 넘어가면, 우리는 망이 처리할 수 있는 여러 타입의 입력과 출력 데이타를 가지고 이것 저것 해볼 수 있는 기회가 훨씬 더 많아지죠. 그래서 일단 순환 신경망이 있으면, 우리는 소위 이런 일대다 모델을 할 수 있습니다. 혹은 어쩌면 입력은 이미지 같은 어떤 정해진 크기의 객체이지만, 이제 우리의 출력은, 캡션 (caption)같은 일련의 변수 길이가 될 수 있죠. 여기서는 여러 캡션들이 다양한 숫자의 단어들을 가질 수 있어서, 출력의 길이가 변할 필요가 있는 겁니다.

    우리는 또한 다대일 모델도 가질 수가 있어서, 입력은 다양한 크기가 될 수 있죠. 이건 텍스트 조각같은 것일 수도 있고, 우리는 그 텍스트의 감성 (sentiment)이, 긍정인지 부정인지를 얘기하고 싶을 겁니다. 혹은 컴퓨터 비전 문맥에서는, 입력으로 비디오를 받는 것을 생각할 수 있죠. 그리고 그 비디오는 아마 다양한 숫자의 프레임 (frame)을 가지고 있을 겁니다. 그럼 우리는 다양한 길이일 수 있는 이 전체 비디오를 읽고 싶겠죠. 그리고 결국은, 그 비디오에서 어떤 작업이나 활동이 일어나고 있는지 분류 결정할 (classification decision) 수 있습니다.

    또 입력과 출력이 모두 길이가 다양한 문제가 있을 수 있죠. 이런 것을 볼 수 있는데, 기계 번역에서, 우리의 입력은 영어로 된 어떤 문장이고, 길이는 다양할 수 있습니다. 출력은 프랑스어로 된 문장인데, 역시 길이가 다양할 수 있죠. 그리고 중요한 건, 영어 문장의 길이가 프랑스어 문장의 길이와 다를 수 있다는 겁니다. 그래서 입력과 출력 둘 다의 다양한 길이의 순열 (sequence)을 받아들일 수 있는 어떤 모델이 필요한 거죠.

    마지막으로 , 또한 다양한 숫자의 프레임이 있는 비디오 순열 같은, 입력이 길이가 다양한 문제를 생각해 볼 수 있죠. 그리고는 그 입력 순열의 각 원소에 대해 결정을 내리고 싶은 겁니다. 비디오 문맥에서는, 비디오의 매 프레임마다 어떤 분류 결정을 내리는 것일 수 있습니다. 그리고 순환 신경망이 이러한 다양한 크기의 순열 데이타를 처리하는 종류의 일반적인 패러다임이죠. 그건 모델에서 이 모든 다양한 종류의 셋업을 꽤 자연스럽게 잡아내게 (capture) 해 줍니다.

    순환 신경망에서 사실 중요한 것은, 고정된 크기의 입력과 고정된 크기의 출력이 있는 문제에 대해서도 순환 신경망이 여전히 꽤 유용하다는 겁니다. 이 예제에서, 우리는 입력의 순차적인 처리를 하려고 하겠죠. 여기서 이미지 같은 고정된 크기의 입력을 받고, 어떤 숫자가 이미지에서 보이는지 분류 결정을 내리고 싶을 겁니다. 그러나, 그냥 단일 피드포워드 전달을 하고 한번에 모든 결정을 내리기보다는, 이 망은 이미지를 여기저기 둘러보고 이미지의 여러 부분들을 다양하게 잠깐씩 보는 겁니다. 그다음 여러번 잠깐씩 본 다음, 어떤 종류의 숫자가 있는지 최종 결정을 하는 거죠. 입력이 이미지고, 출력은 분류 결정이지만, 이러한 문맥에서도, 순환 신경망으로 다양한 길이를 처리할 수 있다는 이 아이디어가 진짜 재미있는 종류의 모델에 이르도록 해줍니다.

    제가 좋아하는 진짜 멋진 논문이 있는데, 이 같은 종류의 아이디어를 적용해서 새로운 이미지들을 만들어 내는 것이죠. 이제 모델이 훈련중에서 봤던 것과 같은 종류처럼 보이는 완전 새로운 이미지를 만들어 내길 바라는 겁니다. 그리고 순환 신경망을 사용해서 이 출력 이미지를 색칠하게 할 수 있죠. 출력에서 한번에 한 조각씩이요. 출력은 이런 정해진 크기의 이미지이지만, 시간에 따라 순차적으로 한번에 하나씩, 출력의 부분들을 계산하는 이런 모델들을 얻을 수 있습니다. 그런 종류의 셋업 (setup)에 대해서도 순환 신경망을 사용할 수 있죠.

    RNN이 할 수 있는 이 모든 멋진 것들에 대한 이런 종류의 이야기를 듣고 나면, 이런 것들이 도대체 어떻게 생긴 건지 궁금할 겁니다. 일반적으로, 순환 신경망은 이 작은 순환 코어 셀 (core cell)이 있고, 어떤 입력 x를 받아 들여서 그 입력을 RNN으로 넣습니다. 그리고 RNN은 어떤 내부의 숨겨진 상태 (internal hidden state)가 있고, 그 내부의 숨겨진 상태는 RNN이 새로운 입력을 읽을 때마다 매번 업데이트 됩니다.

    그리고 종종, RNN이 각 단계 마다 어떤 출력을 내게 하고 싶을 겁니다. 그래서 우리는 이런 패턴을 가지는 거죠. 어떤 입력을 읽고, 숨겨진 상태를 업데이트하고, 그다음 출력을 내는 패턴이요.

    그 다음 궁금한 건 우리가 계산하고 있는 이 순환 관계의 함수적 형태가 무엇이냐는 거죠. 그래서 이 작은 녹색 RNN 블록 내에서, 함수 f로 어떤 순환 관계를 계산하는 거죠. 그래서 이 함수 f는 어떤 가중치 W에 의존할 거고, 이전 숨겨진 상태 h_t-1을 받아들이고, 뿐만 아니라, 현재 상태에서의 입력 x_t를 받고, 그다음 이건 다음 숨겨진 상태를 출력하게 됩니다. 혹은 h_t라고 부르는 업데이트된 숨겨진 상태를 출력하죠. 그다음 다음 입력을 읽으면, 다음 입력 x_t+1을 읽을 때 이 새로운 숨겨진 상태 h_t는 같은 함수로 넘겨지죠.  이제, 이 망의 각 시점 (time step)마다 어떤 출력을 만들어 내고 싶다면, 각 시점마다 이 h_t를 읽어 들이는 어떤 추가적인 완전 연결 계층을 붙일 겁니다. 그리고는 각 시점 마다 숨겨진 상태에 근거해서 결정을 내리는 거죠.

    한가지 주목할 점은 우리가 각 시점에서 계산마다 같은 함수 f와 같은 가중치 W를 사용한다는 겁니다.

    생각해 볼 수 있는 가장 간단한 종류의 함수 형태는 소위 바닐라 순환 신경망이라고 부르는 겁니다. 여기에 앞 슬라이드에서 본 것과 같은 함수 형태가 있는데요. 이전 숨겨진 상태와 현재 입력을 받아들이고 다음 숨겨진 상태를 만들어 내야 하는 거죠. 그리고 생각할 수 있는 가장 간단한 종류는 어떤 가중치 행렬 W_xh가 있어서 입력 x_t에 대해 곱하는 거고, 뿐만 아니라 또 다른 가중치 행렬 W_hh가 있어서 이전 숨겨진 상태와 곱하는 것이죠. 그래서 두개의 상태에 대해 이 두 곱하기를 하고 그것들을 더하고, tanh를 통해 한쪽으로 몰면, 시스템에서 어떤 종류의 비선형 (non-linearity)을 얻게 됩니다. 왜 여기서 tanh를 쓰고 다른 종류의 비선형성을 쓰지 않는지 궁금할 수 있을 텐데요. 앞선 강의에서 tanh에 대해 부정적인 것들을 말했는데 말입니다. 좀 더 진보된 아키텍처인 LSTM 같은 것을 얘기할 때 나중에 다시 돌아와서 보겠습니다. 그리고, 이 아키텍처에 이외에, 매 시점마다 어떤 y_t를 만들어 내고 싶다면, 다른 가중치 행렬인 W를 가질 수 있죠. 그건 이 숨겨진 상태를 받아들이고 어떤 y로 변형시켜서 매 시점마다 어떤 클래스 점수 예측으로 만들 수 있을 겁니다.

    순환 신경망에 대해서 생각할 때, 여러분은 순환 신경망을 2가지 방식으로 생각할 수 있는데요. 하나는 자기 자신으로 피드백하는 숨겨진 상태를 가지는 컨셉이죠. 그러나 제가 보기엔 저 그림이 약간 혼란을 주는 것 같아요. 가끔, 저는 여러 시점에 대해서 이 계산 그래프 (computational graph)를 펼치는 것 (unrolling)에 대해서 생각해 보는 것이 더 명확하다는 것을 발견합니다. 그렇면 숨겨진 상태, 입력, 그리고 출력과 가중치의 데이타 흐름이 약간 더 명확해 지죠. 그래서 첫 시점에서, 우리는 어떤 초기 숨겨진 상태 h_0가 있을 거고, 이건 보통 대부분의 문맥에서 0으로 초기화 되죠. 그리고 어떤 입력 x_t가 있을 겁니다. 이 초기 숨겨진 상태 h_0와 현재 입력 x_t는 우리의 f_W 함수로 들어갈 겁니다. 이것이 다음 숨겨진 상태인 h_1을 만들어 내죠.

    그리고 나서 다음 입력을 받을 때, 이 과정을 반복합니다. 현재 h_1 과 x_1은 같은 함수 f_W로 들어가고 다음 출력 h_2를 만들어 내죠.

    이 과정은 계속 반복되고, 일련의 입력인 입력 x_t들 모두 사용하게 되는 거죠.

    한 가지 주목할 건, 우리는 계산 그래프에서 이걸 훨씬 더 명시적으로 만들어서 W 행렬을 작성할 수 있다는 거죠. 그리고 여기서 우리가 모든 시점 계산에서 같은 W 행렬을 재사용하고 있다는 것을 알 수 있죠. 그래서 이제 우리가 이 작은 f_W 블록을 가질 때마다, 그건 고유한 h와 고유한 x를 받고 있는 거지만, 이 모든 블록들은 같은 W를 받아 들이는 거죠. 역전파에서 경사가 어떻게 흐르는 지 얘기했던 것이 기억날지 모르겠지만, 계산 그래프에서 같은 노드를 여러번 재사용하면, 역방향 전파동안 d손실과 dW를 계산할 때 경사를 W 행렬로 결국 더하게 된다는 것을 기억할 겁니다. 만약 이 모델에 대한 역전파를 생각한다면, 이 타임 스텝 각각으로부터 흐르는 W에 대한 별도의 경사가 있을 거고 W의 최종 경사는 타임스탭 각각 마다의 경사를 모두 더한 것이 될 겁니다.

    또한 이 y_t를 이 계산 그래프에서 명시적으로 적을 수 있죠. 그 다음 이 출력 h_t는 매 시점마다, 어떤 다른 작은 신경망으로 들어가서 y_t를 만들어 낼 수 있을 거고, 그건 각 시점 마다의 어떤 클래스 점수 같은 것이 되겠죠.

    또한 손실을 더 명시적으로 만들 수 있습니다. 많은 경우에, 여러분의 순열의 각 시점마다 어떤 정답 (ground truth) 레이블 (label)을 가지는 것을 생각해 볼 수 있고, 그럼 이 출력 y_t의 각각의 시점마다 어떤 각각의 손실을 계산하게 될 겁니다. 그리고 이 손실은 자주 소프트맥스 (softmax) 손실 같은 것이 되겠죠. 아마 순열의 모든 시점마다 정답 레이블을 가지고 있는 경우라면 말입니다.

    그리고 이 전체 훈련 과정을 위한 최종 손실이 개별 손실들의 합이 될 겁니다. 이제 우리는 매 시점마다 스케일러 (scaler) 손실이 있나요? 우리는 그냥 그것들을 모두 더해서 망의 꼭대기에서 최종 스케일러 손실을 구하는 겁니다. 그리고 이제, 다시 이것을 통한 역전파를 생각해 보면, 모델을 훈련시키기 위해서는 W에 대한 손실 경사를 계산할 필요가 있습니다. 그래서 우리는 그 최종 손실로부터 이 시점 각각으로 흘러들어오는 손실을 가질 겁니다. 그리고 그 시점들 각각은 가중치 W에 대한 지역 경사를 계산할 거고, 모두 더해져서 가중치 W에 대한 최종 경사로 구해질 겁니다.

    이제 우리가 이런 다대일 상황에서 감성 분석 같은 것을 하고 싶다면, 우리는 전형적으로 이 망의 최종 숨겨진 상태에 기반한 결정을 내릴 겁니다. 왜냐면, 이 마지막 숨겨진 상태는 전체 순열로부터의 모든 문맥을 요약한다고 볼 수 있기 때문이죠.

    또한 일종의 일대다 상황이 되어서, 정해진 크기의 입력을 받고 다양한 크기의 출력을 만들어 내고 싶다면, 여러분은 흔히 그 고정된 크기의 입력을 사용해서 모델의 초기 숨겨진 상태를 초기화하고 순환 망은 출력의 각각의 셀에 대해 체크 표시를 (tick)할 겁니다. 이제 다양한 크기의 출력을 만들면서, 출력에서 각각의 항목에 대한 그래프를 펼치게 (unroll) 될 겁니다.

    시퀀스 투 시퀀스 (sequent to sequence) 모델에 대해서 이야기할 때, 여러분은 아마 기계 번역같은 것을 할 거고, 다양한 크기의 입력과 다양한 크기의 출력을 가지고 있을 겁니다. 여러분은 이것을 다대일 더하기 일대다의 조합으로 생각할 수 있습니다. 그래서 우리는 소위 인코더 (encoder) 와 디코더 (decoder)라고 부르는 두 단계로 진행할 겁니다. 만약 여러분이 인코더라면, 우리는 다양한 크기의 입력을 받을 텐데, 그건 영어로 된 문장일 수 있죠. 그리고 인코더 망의 최종 숨겨진 상태를 이용해서 그 전체 문장을 요약할 겁니다.

    이제 우리는 이런 다대일 상황에 있는데요. 여기서는 이 단일 벡터에서 이 다양한 크기의 입력을 요약할 거고, 이제 두번째 디코더 망이 있습니다. 그건 일대다 상황이고, 그 입력 문장을 요약하는 단일 벡터를 입력하죠. 그리고 이제 이 다양한 크기의 출력을 만들어내는데, 그 출력은 다른 언어의 문장이 되는거죠. 그리고 이제 이 다양한 크기의 출력에서, 매 시점마다 어떤 예측을 합니다. 아마도 어떤 단어를 사용할지를 예측하겠죠. 그리고 이 계산 그래프를 펼침으로 (unrolling) 이 전체를 훈련시키는 걸 생각할 수 있습니다. 출력 순열에서 손실을 다 더하는 거죠. 그리고 평소처럼 그냥 역전파를 수행하는 겁니다.

    댓글

Designed by Tistory.