ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [cs231n] 10강 순환 신경망 (Recurrent Neural Network) (3/4, 이미지 캡셔닝 (image captioning))
    AI 2021. 4. 13. 15:36

    저는 안드레이 (Andrej)와 이 논문을 몇 년전에 썼는데, 많은 이런 모델을 훈련시켰고 이 모델들의 브레인으로 들어가서 그것들이 무엇을 하고 있는지, 왜 그것들이 동작하는 지에 대해서 알아내려고 했죠. 그래서 우리는 이 순환 신경망 (recurrent neural network)들이 이 숨겨진 벡터들을 가지고 있고, 그 벡터는 매 시점마다 업데이트 되는 어떤 벡터라는 것을 알았죠. 그다음 우리는 이 벡터의 어떤 요소가 어떤 구문론적 해석가능한 의미를 가지고 있는 지를 알아 내려고 했습니다. 우리는 신경망 언어 모델을 훈련시켰는데, 이 문자 수준 (character level) 모델 중 하나를 이 데이타 셋 (data set)중의 하나에 대해서 했죠. 그리고 그 숨겨진 벡터 (vector) 내의 요소 중 하나를 선택하고 순열의 과정 (course of a sequence)에 걸쳐서 그 숨겨진 벡터의 값이 무엇인지를 들여다 보며 이 여러 숨겨진 상태들이 무엇을 찾고 있는 지에 대한 감을 잡으려고 노력했습니다.

    이런 것을 하면, 결국은 그것들 중 많은 것이 임의의 횡설수설하는 쓰레기 같은 것처럼 보이는 것으로 끝납니다. 그래서 여기서 우리는 그 벡터의 하나의 원소를 고른 다음 훈련된 모델을 통해 순열을 순방향으로 실행하면 순열을 읽을 때 매 시점 (time step)마다 숨겨진 벡터의 단일 스케일러 (scaler) 요소의 크기에 따라 각 문자에 색이 칠해지도록 했죠. 이 숨겨진 상태 내의 많은 벡터들이 별로 해석 가능하지 않다는 것을 알게 되는데요. 그것들은 이런 낮은 수준의 언어 모델링을 해서 어떤 글자가 다음에 와야 하는지 알아내려는 것 같습니다.

    그들 중 몇몇은 꽤 좋은 결과를 보여주죠. 여기서는 이 벡터가 인용 (quotes)을 찾고 있다는 것을 알아냈죠. 이 하나의 숨겨진 상태 (hidden state) 즉, 벡터 내의 하나의 원소가 있다는 것을 알 수 있고, 그건 파란색의 off, off, off, off, off 죠. 그리고 인용을 찾으면 켜지고, 이 인용 문구 동안 계속 켜져있습니다. 그리고 두번째 인용부호를 만나면, 그 셀 (cell)은 꺼지죠. 그래서 어쨌든, 이 모델이 순열에서 다음 문자를 예측하도록만 훈련되긴 했지만, 그건 이걸 하기 위한 유용한 것을 학습했죠. 인용을 감지하려는 어떤 셀이 있는 것 같습니다.

    우리는 또한 이 다른 셀도 찾았는데, 줄바꿈 이후 문자의 숫자를 세고 있는 것처럼 보이죠. 각 줄의 시작에서 이 원소는 0부터 시작합니다. 그 줄을 거쳐가면서, 그건 점점 더 빨간색이 되고 그 값은 커지죠. 그다음 줄바꿈 문자가 나온 이후에, 그건 0으로 리셋 (reset)됩니다. 그래서 아마도 이 셀은 망이 이런 줄바꿈 문자를 언제 써야 하는지를 추적하도록 해 준다고 생각할 수 있죠.

    또한 우리는 리눅스 소스 코드에 대해 훈련시킬 때, if 문의 조건절 내에서 켜지는 몇 가지 예들을 발견했습니다. 그래서 이건 아마도 망이 if문 안에 있는지 혹은 그 조건 안에 있는 지에 대해 따라 달라지도록 해 준다는 거고 이것이 이런 순열들을 더 잘 모델링하게 해주죠.

    우린 또한 주석에서 켜지는 것들도 좀 발견했고,

    들여쓰기 수준의 숫자를 세는 것처럼 보이는 것들도 발견했죠. 이것들은 모두 그냥 정말 멋진 것들이죠. 왜냐면 우리가 이 모델에게 다음 문자를 예측하도록 훈련시키기만 했는데, 그게 결국은 어쨌든 입력 데이타에 대한 많은 유용한 구조를 배웠으니까요.

    지금까지는 이건 사실 컴퓨터 비전은 아니었죠. 이 수업은 비전 클래스니까 다시 컴퓨터 비전으로 돌아와야죠. 우리는 여러번 이 이미지 캡셔닝 (captioning) 모델에 대해서 얘기했는데, 어떤 이미지를 집어넣어서 자연어로 된 캡션을 출력할 수 있는 모델을 만들고 싶은 겁니다. 몇 년 전에 많은 논문들이 나왔고, 그것들 모두는 비교적 비슷한 접근 방법들을 가졌죠. 그러나 저는 우리 연구실에서 나온 논문에 있는 그림을 전혀 선입견 없는 방식으로 보여드리겠습니다. 여기서의 아이디어는 그 캡션이 이 길이가 다양한 순열이고 그 순열은 다양한 캡션에 대해 다양한 숫자의 단어들을 가질 것입니다. 그래서 이건 순환 신경망 자연어 모델에 완전히 자연스럽게 맞아 떨어지는 거죠.

    그 다음 우리는 어떤 합성곱 망 (convolutional network)을 갖게 될 텐데, 그건 이미지를 입력으로 받아들입니다. 우리는 합성곱 망이 이 지점에서 어떻게 동작하는지 많이 봤죠. 그 합성곱 망은 이미지에 대한 요약 벡터를 만들어 낼 거고 그것이 이런 순환 신경망 언어 모델중 하나의 첫번째 시점 (time step)으로 들어갑니다. 그 모델은 한번에 하나씩 캡션의 단어들을 만들어 내는 거죠.

    그래서 모델이 훈련된 다음 테스트 시에 이것이 동작하는 방식은 조금 전에 우리가 봤던 이런 문자 수준 언어 모델이 동작하는 방식과 거의 완전히 똑같아 보입니다.

    입력 이미지를 받아서, 합성곱 망으로 집어 넣죠.

    그러나 이미지로부터 소프트맥스 점수를 얻는 대신, 우리는 모델의 끝에서 나오는 이 4,096 차원의 벡터를 받아서

    그걸 사용해서 이미지의 전체 문맥을 요약합니다. 이제 우리가 RNN 언어 모델에 대해서 얘기했을 때를 기억해 보면, 첫번째 초기 입력이 있는 언어 모델을 보고 그 모델에게 텍스트를 만들기 시작하라고 얘기할 필요가 있다고 했죠. 이 경우에는, 그것에게 어떤 특별한 시작 토큰을 주는 겁니다. '헤이, 이것이 문장의 시작이야. 이 이미지 정보에 대해 조건적인 어떤 텍스트를 생성하는 것을 시작해 봐!'라고 얘기하는 토큰인거죠.

    이전에, 우리는 이 RNN언어 모델에서 이런 행렬 (matrix)을 봤었는데, 현재 시점에서 이전 입력을 받고 이전 시점의 숨겨진 상태를 받아서 그것들을 합쳐서 다음 숨겨진 상태 (hidden state)를 얻는 거죠. 이제 우리는 이 이미지 정보도 더해야 합니다. 사람들은 이 이미지 정보를 통합하기 위해 다양한 방법을 해 보는데요. 한가지 간단한 방법은 각 시점마다 이 이미지 정보를 더하는 세번째 가중치 행렬을 더해서 다음 숨겨진 상태를 계산하는 겁니다.

    이제 우리는 어휘의 모든 점수에 대한 이런 분포를 계산할 거고, 우리의 어휘는 모든 영어 단어 같은 것이 되겠죠. 그러므로 그건 매우 클 겁니다. 우리는 그 분포로부터 샘플링할거고 그 단어를 다음 시점에서 입력으로 전달할 겁니다.

    그리고 그 단어를 입력하고 다시 어휘 (vocabulary)내의 모든 단어들에 대한 분포를 얻는 거죠. 

    또 샘플링해서 다음 단어를 만들어내고요.

    그다음 그게 다 되면, 우리는 아미다도 이 완전한 문장을 생성할 겁니다.

    일단 특수한 끝 (end) 토큰을 샘플링하고 나면, 우리는 생성을 멈춥니다. 그 토큰은 문장 끝의 마침표에 해당하는 거죠. 일단 망이 이 끝 토큰을 샘플링하면, 우리는 생성을 멈추고 끝낸 것이고, 이 이미지에 대한 캡션을 얻은 거죠. 그리고 이제, 훈련 중에, 우리는 모든 캡션의 끝에 끝 토큰을 넣은 거고 망은 끝 토큰이 순열의 끝에 온다는 것을 훈련 중에 학습한거죠. 그래서, 테스트시에 생성을 끝내고 나면 그것은 이런 끝 토큰들을 샘플링하곤 하죠. 우리는 이 모델을 완전히 지도된 (supervised) 방식으로 훈련시킵니다. 여러분은 이미지와 자연어 캡션이 있는 데이타 셋 (data set)을 찾을 수 있는데요. 마이크로소프트 COCO가 아마도 이 작업을 위해 가장 크고 가장 널리 사용되는 것입니다. 그러나 여러분은 이 모델을 순전히 지도된 방식으로 훈련시킬 수 있죠. 그리고 나서 이 순환 신경망 자연어 모델을 훈련시키기 위해서 역전파하고 경사를 이 CNN의 최종 계층으로 경사를 전달하고 추가적으로 CNN의 가중치를 업데이트해서 모델의 모든 부분을 튜닝해서 이 작업을 수행하는거죠.

    일단 이 모델들을 훈련시키면, 그것들은 사실 꽤 합리적인 것들을 합니다. 이런 것들은 이 훈련된 모델들 중 하나에서 실제로 나온 몇 가지 결과들입니다. 그건 고양이가 서류가방 바닥에 앉아 있다고 얘기하네요. 꽤 인상적이죠. 그건 고양이가 나뭇가지에 앉아 있다는 것에 대해서도 알죠. 역시 꽤 멋집니다. 그건 두 사람이 해변을 서핑보드를 가지고 걷고 있는 것도 알죠. 이 모델들은 사실 꽤 강력해서 이미지를 묘사하는 비교적 복잡한 캡션들도 생성할 수 있죠.

    그러나 얘기했지만, 이 모델들은 사실 완벽하지 않습니다. 마법이 아닌거죠. 다른 기계 학습 모델처럼, 훈련 데이타와 매우 다른 데이타에 대해 실행시켜 보면, 그것들은 잘 동작하지 않죠. 이 예를 보면, 여자가 손에 고양이를 들고 있다고 하죠. 분명히 이미지에는 고양이가 없죠. 그러나 그녀가 모피 코트를 입고 있어서 아마도 코트의 질감이 모델에게는 고양이처럼 보였나 봅니다.여기 어떤 여자가 서핑 보드를 들고 해변에 서 있다고 써 있는 걸 보는데요. 그녀는 분명히 서핑 보드를 들고 있지 않고 그녀는 물구나무서기를 하고 있죠. 이게 저 이미지에서 재미있는 부분인데, 모델은 완전히 그걸 놓쳤죠. 여기 보면, 이 예는 나무가지에 거미줄이 있는 그림인데, 모델은 새가 나무가지에 앉아 있다고 얘기하고 있죠. 그건 거미를 완전히 놓쳤지만 훈련중에 그건 거미 예제를 전혀 본 적이 없습니다. 그건 훈련 동안엔 나뭇 가지에 앉아 있는 새만 아는 거죠. 그래서 그건 이런 합리적인 실수를 하는 거죠. 또는 여기 아래쪽에, 이 사람이 공을 던지는 지 받는 지의 차이를 사실 구별하지 못하죠. 그러나 그림이 야구 선수이고 공 같은 것이 연관되어 있다는 것은 아는거죠. 다시 얘기 하지만, 이 모델들은 완벽하지 않습니다. 그것들은 훈련 데이타와 비슷한 이미지에 대해 캡션을 하라고 해야 꽤 잘 동작하죠. 그러나 그 이상을 훨씬 넘어서 일반화하려고 하면 분명 어려워 할 겁니다.

    앞으로 가끔 볼 만한 다른 것은 이 약간 더 진보된 모델인 어텐션 (attention)입니다. 이런 캡션의 단어들을 생성할 때, 우리는 모델이 이미지의 여러 부분에 주목하도록 조정할 수 있습니다. 여기에 많은 시간을 쓰고 싶지는 않습니다.

    그러나 이것이 동작하는 일반적인 방식은 이제 합성곱 망이 전체 이미지를 요약하는 단일 벡터를 생성하는 것이 아니라 어떤 벡터의 그리드 (grid)를 만들어 내서, 이미지의 각 공간 위치마다 하나의 벡터를 제공하는 겁니다.

    이제 이 모델이 실행이 되면,

    매 시점마다 어휘를 샘플링할 뿐만 아니라, 그 모델이 보고 싶은 이미지의 위치에 대한 분포도 만들어 냅니다. 이미지 위치에 대한 이 분포가 어텐션으로 보일 수 있고 그 모델이 훈련동안 봐야 하는 곳이죠. 그래서 첫번째 숨겨진 상태가 이미지 위치에 대한 이 분포를 계산하고, 그건 벡터의 집합으로 돌아가서 단일 요약 벡터를 제공하는데, 그 벡터는 그 이미지의 하나의 부분에 주목하고 있는 겁니다.

    이제 그 요약 벡터가 신경망의 다음 시점에서 추가적인 입력으로 들어옵니다.

    이제 그건 2개의 출력을 만들어 내죠. 하나는 어휘 단어들에 대한 분포이죠. 다른 하나는 이미지 위치에 대한 분포입니다.

    이 전체 과정은 계속되고, 그건 매 시점마다 이 두가지를 할 겁니다.

    모델을 훈련시킨 다음에, 그것이 캡션에서 만들어낸 모든 단어들에 대해 이미지 여기 저기에 어텐션을 이동시키면서 볼 겁니다. 여기서는 그것이 캡션을 만들어 낸다는 것을 알 수 있죠. 새가 위를 날라 간다인데, 그 다음은 잘 안보이네요. 그러나 여러분은 어텐션이 이미지의 여러 부분으로 움직인다는 것을 알 수 있죠. 그것이 만들어 내는 캡션의 각 단어들에 대해서요. 하드 어텐션 (hard attention)과 소프트 어텐션 (soft attention)이라는 개념이 있는데, 너무 많이 들어가고 싶지는 않습니다만, 소프트 어텐션 아이디어로는, 모든 이미지 위치로부터 모든 피쳐들의 조합을 얻는 거죠. 반면 하드 어텐션의 경우는, 모델이 매 시점마다 이미지에서 정확히 하나의 위치만 선택하도록 강요하는 겁니다. 그래서 하드 어텐션의 경우는 우리가 하나의 이미지 위치를 고르는 경우인데 약간 까다롭죠. 왜냐면 그건 미분할 수 있는 함수가 아니어서 그 시나리오에서 모델을 훈련시키려면 바닐라 (vanilla) 역전파 보다 좀 더 멋진 무언가를 해야 하거든요. 나중에 강화 학습에 관한 강의에서 그것에 대해 조금 얘기할 것 같네요.

    이제 이런 어텐션 모델 하나를 훈련시킨 다음 캡션을 생성하기 위해 실행시키면, 캡션을 생성할 때 이미지의 핵심적인 혹은 의미적으로 중요한 부분에 어텐션을 집중하는 경향이 있다는 것을 알게 됩니다. 캡션을 보면 어떤 여자가 프리스비 (frisbee)를 공원에서 던진다고 되어 있죠. 모델이 프리스비라는 단어를 생성했을 때, 동시에, 프리스비를 진짜로 포함하고 있는 이 이미지 영역에 어텐션이 집중되어 있다는 것을 알 수 있죠. 이건 정말 멋진거죠. 우리는 모델에게 매 시점마다 어디를 봐야 한다고 얘기하지 않았습니다. 그건 훈련 과정동안 스스로 그 모든 것을 알아낸거죠. 왜냐면, 어쨌든, 그건 그 이미지 영역을 보는 것이 이 이미지에 대해 해야 할 일이라는 것을 알아냈으니까요. 그리고 이 모델의 모든 것은 미분가능하기때문에, 우리는 이 모든 소프트 어텐션 과정을 통해 역전파할 수 있고, 이 모든 소프트 어텐션은 훈련 과정을 통해 나오는 거죠. 그건 정말 정말 멋지죠.

    그런데 이 순환 신경망과 어텐션 아이디어는 사실 이미지 캡셔닝 (image captioning)을 넘어서 다른 작업에서도 사용되고 있습니다. 하나의 최근의 예는 이 시각 질의 응답 (visual question answer)의 아이디어죠. 여기서 모델은 2개를 입력으로 받습니다. 이미지를 입력으로 받을 거고 또한 이미지에 대해 묻는 어떤 자연어 질문을 받습니다. 여기서 왼쪽의 이미지를 보고 트럭에 그려진 멸종위기 동물이 무엇이냐고 물을 수 있죠. 그럼 모델은 어떤 것이 이미지의 문맥에서 그 질문에 제대로 답했는 지에 대해 4가지 자연어 답 중에서 하나를 골라야 합니다.

    CNN과 RNN을 자연스러운 방식으로 사용해서 이 모델을 같이 붙이는 것을 생각할 수 있죠. 우리는 지금 다대일 시나리오에 있고, 이제 모델은 이 자연어 순열을 입력으로 받아들여야 하니까, 순환 신경망을 입력 질문의 각 원소에 대해 실행시켜서 입력 질문을 단일 벡터로 요약하는 것을 생각해 볼 수 있죠. 그리고 우리는 CNN이 이미지를 요약하게 하고 CNN으로부터의 벡터와 질문과 코딩 RNN으로부터의 벡터를 합쳐서 답에 대한 분포를 예측할 수 있습니다. 여러분은 또한 가끔 소프트 공간 어텐션 아이디어가 시각 질의 응답 같은 것에 포함되는 것을 볼 겁니다. 그래서 여러분은 이 모델이 또한 질문에 대한 답을 결정하려고 할 때, 이미지에 대한 공간 어텐션을 가지는 것을 볼 수 있죠.

    댓글

Designed by Tistory.