논문 리뷰/vision language

Show, Attend and Tell : Image Captioning에서 Soft Attention, Hard Attention

모끼주인 2019. 5. 12. 16:26

논문 링크 : https://arxiv.org/pdf/1502.03044.pdf

참조 블로그 링크 : http://sanghyukchun.github.io/93/

 

Show, Attend and Tell: Neural Image Caption Generation with Visual Attention (ICML2015) - README

주어진 이미지에 대한 설명을 하는 문장, 혹은 캡션을 생성하는 문제를 image caption 문제라고 한다. 이 문제는 여러 가지 문제들이 복합적으로 얽혀있는 문제라고 할 수 있는데, 먼저 이미지가 어떤 것에 대한 이미지인지 판별하기 위하여 object recognition을 정확하게 할 수 있어야한다. 그 다음에는 detect한 object들 사이의 관계를 추론하여 이미지가 나타내는 event가 무엇인지 알아내어야 하고, 마지막으로 event를 cap

sanghyukchun.github.io

참조 강의 링크 : https://www.youtube.com/playlist?list=PLep-kTP3NkcOjOS1a30UNW-tH2FSoGYfg

* 고려대 주재걸 교수님의 attention, memory network 전반에 관한 NLP강의입니다. 논문을 읽기 전 전반적인 기초 지식을 다지기에 정말 좋습니다!

 

2018_2 Short Course on Attention Models and Memory Networks - YouTube

 

www.youtube.com

참조 코드 링크 :

(1) https://github.com/sgrvinod/a-PyTorch-Tutorial-to-Image-Captioning

* 논문과 거의 유사하게 pytorch로 구현해 놓은 코드입니다. 논문을 더 깊게 이해하고 어떻게 구현하였는지 알고 싶은 분들이 참조하시기에 좋을 것 같습니다!(단점은 hard attention은 구현되지 않고 soft attention만 구현되었다는 것입니다..ㅠㅠ)

 

sgrvinod/a-PyTorch-Tutorial-to-Image-Captioning

Show, Attend, and Tell | a PyTorch Tutorial to Image Captioning - sgrvinod/a-PyTorch-Tutorial-to-Image-Captioning

github.com

(2) https://github.com/Kyushik/Attention

* 기본적인 hard attention, soft attention의 구현에 관하여 이해할 수 있습니다.

 

Kyushik/Attention

Repository for Attention Algorithm. Contribute to Kyushik/Attention development by creating an account on GitHub.

github.com

 

* 이번 포스팅은 Show, Attend and Tell논문을 바탕으로 image captioning에서의 hard attention, soft attention 적용에 관해 이야기해보겠습니다. 논문 이해 과정에서는 위 블로그, 강의 및 깃허브 코드를 참조하였음을 먼저 밝힙니다.

 

 

Show, Attend and Tell(CVPR, 2015)을 이야기하기 전에, 위 논문의 기반이 된 것은 Show and Tell(CVPR, 2014)이다.

 

Show and Tell에서는, 기존의 object detection을 통해 물체와 자연어를 연결하는 방법 등을 벗어나 end-to-end 방식으로 image captioning의 성능을 크게 향상시킨 할아버지뻘(?) 논문이다.

 

Show and Tell에서는 기본적으로 이미지를 CNN으로 인코딩하고, caption부분을 LSTM으로 디코딩하는 CNN + LSTM구조를 취하고 있다.

여기에 attention을 적용(해당 단어가 이미지의 어느 부분을 나타내는가? 가중치 적용)시켜 그 성능을 더 향상시킨 것이 Show, Attend and Tell이다.

 

Show, Attend and Tell이후로 다양한 방법으로 attention을 적용시켜 성능을 더 향상시킨 논문들이 많이 나왔고,

Transformer이후 Memory Network구조를 활용하여 Self-Attention을 적용하는 모델들도 많이 나오고 있다고 한다!

 

이번 포스팅에서는 가장 기본적인 image captioning구조인 CNN + LSTM에, 역시 가장 기본적인 attention 구조를 적용한 모델에 대해 살펴보고자 한다.

 

 

1. Image Captioning Model Structure

 

기존의 Show and Tell 구조가 아래와 같은 모습이었다면 : 

CNN으로 이미지 encoding -> 이미지 전체 정보를 요약한 fc Layer vector와 단어 embedding vector x를 RNN의 맨 처음 input으로 대입

 

Show and Attend Tell에서는 아래의 그림과 같이 attention을 적용한다.

CNN으로 이미지 정보 요약 -> RNN의 매 timestep 마다 특정 위치에서의 이미지 정보를 함께 input으로 대입

 

그림이 살짝(?) 지저분하지만

 

1) Encoder : VGGNet

 

여기서는 기존과 달리 막단의 fc layer를 사용하지 않는다!!!

 

즉, convolution layer를 모두 거친 후 feature map의 크기가 14*14*512 (width*height*filter_num)이었다면,

padding을 적용하여 max pooling하면 똑같이 14*14*512의 크기가 될 것이다.

 

여기서 기존의 경우 100352*1 크기의 fc layer로 모두 concatenate 해주었다면,

여기서는 196*512 (L*D) 로 각 필터 별로 flatten해 준다!

(L : 각 feature vector의 수, D : feature vector의 차원)

 

논문에서는 feature vector를 annotation vector라고 이름 붙였으며,

각 annotation vector의 특정 위치에서의 정보만을 가져오기 위해 기존과 달리 fc layer로 concate하지 않은 것이다.

 

이 벡터에 attention을 적용하여 각 caption에서 annotation vector의 어느 위치 정보를 가져와야 할지 알아낼 것이다!

 

[annotation vector 설명 : CNN에서의 의미]

 

 

CNN의 output은 L*D로, L은 각 filter의 개수, D는 전체 filter의 차원을 뜻한다.

 

이때, CNN의 각 filter들은 하나의 특징에 대한 정보를 담고 있다.

예를 들어, input이 고양이 이미지라면 각 filter는 고양이 눈 정보, 고양이 털 정보, 고양이 코 등에 대한 정보를 담고 있을 것이다.

 

이 때 만약 고양이눈 filter에 대해 14*14*1 을 196*1로 flatten 시켰더라도,

CNN filter가 순차적으로 이동하며 정보를 추출하므로

196*1 vector의 첫 번째 vector는 (위치 i=1) 맨 왼쪽 상단의 부분에 눈이 있는지에 대한 정보가 될 것이고

맨 끝 vector는 (위치 i=L) 맨 오른쪽 하단에 눈이 있는지에 대한 정보가 될 것이다.

 

이 feature vector들을 모두 모아 표현하면, 위 그림에서 'CNN결과'부분과 같이 될 것이다.

파란색 부분으로 표현한 것은 각 vector에서 큰 값을 나타내고 있는 부분이라고 가정하자.

예를 들면 고양이 눈 vector의 경우 파란색 위치의 index에 고양이 눈 정보를 포함하고 있다고 보면 된다.

 

이것들을 잘 조합해서, 해당 caption에서 중요한 이미지 위치만 요약한 zt를 만들어 쓰겠다는 것이다!

(그림에서처럼 모든 위치 정보를 조금씩 이용 : soft attention, 위치 하나만 선택 : hard attention)

 

 

2) Decoder : LSTM

 

Decoder단에서는 똑같이 LSTM을 사용하는데, input으로 기존 LSTM에 사용되는 ht-1(hidden vector)과 xt(word embedding vector) 뿐만 아니라 zt를 함께 사용한다.

 

zt는 모든 annotation vector ai에 대하여 이를 잘 조합하여 (Φ함수, hard 및 soft attention, 아래에 자세히 설명),

각 timestep t에서의 input word에 따라 이미지의 어떤 부분을 더 가져올지 점수화한 vector를 만든 것이다.

아래 수식을 보면 기존 LSTM과의 차이를 잘 살펴볼 수 있다.

위의 기존 LSTM수식은 Show and Tell에서 사용한 것으로, Show and Tell의 경우 단어 embedding set (x0, ... , xt)의 맨 앞에 x-1로 CNN의 output fc vector를 사용한다. 즉, 이미지는 초기 hidden state vector h0를 구할 때에만 직접적으로 연산에 대입되고, 이후에는 cell state에 문장과 결합된 정보만이 남아 decoding에 영향을 미치게 된다.

 

그러나 아래의 attention+LSTM수식은, input단에서 매번 zt를 함께 대입하여 준다. 즉 input으로 Eyt-1 : 단어 embedding vector, ht-1 : hidden state vector, zt : image feature vector 세 가지가 사용되는 것이다!

 

zt는 LSTM내부의 input gate, forget gate, output gate를 계산할 때 영향을 모두 미치며 이후 cell state, hidden state를 계산할 때는 각 gate에서 영향을 미친 값이 계산되게 된다.

 

또한 3.1.2절의 맨 마지막 부분에 보면 먼저 LSTM의 cell state, hidden state 초기값은 위 수식과 같이 annotation vector들의 평균으로 초기화해 준다고 되어있다.

 

보통 0으로 많이 초기화 하지만, 여기서는 첫 부분에서는 이미지의 전체 평균값을 바탕으로, 이후부터는 단어에 해당하는 이미지의 부분(attention 결과)을 바탕으로 caption을 생성하도록 하였다!!

 

2. Attention Mechanism

*먼저 2에서는 attention계산 과정에 대해 설명하고, 아래의 3 및 4에서 실제 image captioning(본 논문)에서 어떻게 이를 적용하였는지 알아보도록 하겠습니다.

 

Attention은 두 벡터 (위 그림에서는 ht, hs)간의 유사도를 구하는 것이다.

 

가장 대표적인 첫 번째 방법인 내적(dot)을 살펴보자.

만약 ht = [100, 0] ,hs = [0.3, 200] 이라면 두 벡터의 내적값은 30 + 0 = 30이 될 것이다.

그러나 hs = [200, 0.3]이라면 내적값은 20000 + 0 = 20000이 될 것이다.

 

이와 같이 같은 인덱스에서 똑같이 큰 값을 가질수록 내적 값이 커지는 것을 확인할 수 있다.

CNN feature vector에서 인덱스는 이미지의 pixel 위치를 나타내므로, attention 연산을 통해 caption의 어느 부분이 이미지의 어느 위치 벡터와 가장 유사한지 파악할 수 있다!! -> 그 이미지 부분만 가져다 씀(아래에 설명)

 

두 번째 방법인 general은, ht와 hs사이에 weight parameter W를 추가하여 학습을 통해 두 벡터 사이의 연관도를 나타내겠다는 것이다.

 

세 번째 방법인 concat은, 두 번째 방법과 동일하게 학습을 사용하지만, 두 번째 방법에서처럼 벡터 사이에 W를 두는 것이 아니라, 두 벡터를 concat한 후 학습시키는 방법이다. 아래와 같은 그림으로 나타낼 수 있다.

그림 출처 : 주재걸 교수님 Youtube강의를 참조

즉, concat한 후 W와 곱하고(attention parameter) tanh를 씌운 후, va와 곱하여 하나의 값으로 만들어 주는 것이다.

 

 

3. Stochastic Hard Attention

 

Hard Attention은 말 그대로 hard하게 어느 부분에 집중해야 할 지 고르겠다는 것이다.

 

그래서 annotation vector 중에 딱 하나의 위치만 선택한다!!

그러기 위해 어느 위치를 선택할 지 나타내 준 location variable st를 사용한다.

 

St는 (annotation vector의 차원 D) * 1 크기의 vector로, 전부다 0이고 하나의 값만 1이다. (one-hot encoding)

즉 st의 i번째 인덱스 값이 1이라면 annotation vector의 i번째 위치를 선택한 것이 된다!

 

아래 그림은 hard attention의 과정을 나타낸 것이다.

 

 

갑자기 수식이 등장하지만 sj<t, t번째 단어보다 이전 단어들의 indicatior vector s와 image feature vector a 들에 대하여, (LSTM은 순차 모델이므로 이전 정보를 저장한 ht-1(s와 a에 의해 계산됨)을 이용하고, 따라서 다음과 같은 조건부 확률로 objective function을 표현한다)

st에서의 i번째 값이 1일때의 확률 값을 αt,i라고 하자.

 

여기서 확률변수 st는 다항분포가 된다!!

즉 동전 앞면이 나올 확률이 0.5, 뒷면이 나올 확률이 0.5인 것 처럼

St,0이 나올 확률이 ⍺t,0, St,1이 나올 확률이 ⍺t,1, .... 이런 다항 분포가 되는 것이다.

 

그렇다면 αt,i의 값은 어떻게 구할까??

위의 2번에서 보았던 attention mechanism들을 이용하여 구한다!! 

각 ai와 이전 단계 LSTM의 output vector간의 유사도(내적, concat 등등..)를 구한 후 : [32, 0.4, 5, ...] 이런 식으로 점수로 나열됨

이 벡터에 softmax를 취해 확률 값으로 변환하는 것이다!!

 

즉 αt,i는 이미지 벡터 ai와 LSTM output간의 attention 점수를 확률로 표현한 것이다!!

맨 위 2번에서의 attention mechanism 그림입니다!~

 

Attention을 구하는 tensorflow코드 하나를 참고용으로 가져와 봤다.(아래 방법은 concat 사용)

출처 : https://github.com/Kyushik/Attention

 

어쨌든 LSTM의 weight가 학습됨에 따라 α값도 함께 변하게 되고, α는 학습 parameter가 아닌 학습 과정에서 사용하는 유사도 값이다.

 

결론적으로 다항 분포 확률 변수 St로부터 새로운 확률 변수 (Random Variable) Zt를 정의할 수 있다.

Zt의 의미는 위의 hard attention 그림에서 확인할 수 있듯이, annotation vector들 중 확률값이 가장 높은 하나의 위치만 선택한 결과가 된다.

1) Loss Function

이제 만든 zt 벡터를 다음 timestep의 LSTM에 대입할 것이고, caption y의 예측값을 얻어낼 것이다.

 

따라서 loss function은 아래와 같다.

 

LSTM모델 구조에 따라 annotation vector a에 대한 caption y의 확률값 p(y|a)가 loss function인데, 여기에 log를 취해 미분이 더 잘 되도록 만들어 준 값이다.

 

logp(y|a)는 s에 관해 적분한 기댓값 형태로 위와 같이 나타낼 수 있는데, 이것의 lower bound를 구하면 맨 위의 수식이 된다!

 

이 lower bound를 loss function으로 잡고, back propagation을 진행하여 optimal 지점에 가까이 다가갈 것이다.

(lower bound가 optimal 지점에 도달하면 logp(y|a)값도 optimal에 가까워짐)

 

2) Backwards : "Stochastic" hard attention인 이유

앞서 구한 lower bound를 neural network의 weight parameter W로 미분하면 아래와 같다.

 

여기서, 모든 s에 대하여 값을 계산하기에는 computational cost가 너무 크다!!

 

왜냐하면 vector s는 앞서 보았듯이 이미지의 어느 부분을 선택할지에 대한 one hot encoding vector인데,

feature vector의 dimension이 196이라면 st = [0, 0, ..... , 1, 0, 0, ....]로 1*196크기의 vector이기 때문이다.

 

모든 위치 i에 대해 모든 경우의 수를 다 계산하기는 어려우므로 여기서는 Monte Carlo Sampling을 이용한다.

mini batch와 비슷한 개념으로 sampling하여 gradient를 계산하겠다는 것이다!!

이 때문에 "Stochastic"이라는 이름이 앞에 붙은 것이다!

 

따라서 s를 sampling해야 하는데,,,

 

앞서 s는 동전 던지기의 앞/뒷면과 비슷한 Multinoulli 분포를 따르고 있다고 정의했다!!

(si가 1일 확률은 αi로 정의)

따라서 Multinoulli({αi})에서 st를 n번 sampling하고, 이를 평균값 낸 것을 모든 s에 대한 적분값 대신 가져다 쓸 것이다.

 

그러나 sampling하게 되면 단점은, variance가 커진다는 것이다.

전체 데이터에서 임의로 추출하는 것 이므로, 매 추출 시마다 서로 다른 지역에 편향되어 데이터가 추출되면 분산이 커지는 것은 당연한 일이다.

 

이를 방지하기 위해, MINE논문 포스팅에서도 소개했던 exponential moving average를 사용한다!

위 수식에서와 같이 기존의 정보를 0.9만큼, 새로운 정보를 0.1만큼의 비율로 유지하며 bk값을 update하겠다는 것이 exponential moving average다.

 

그 외에도 variance를 줄이기 위해 entropy term H[s]를 더하고, 각 이미지에 대해 0.5의 확률로 s대신 sampling된 s들의 기댓값(평균값) α를 대입하였다고 한다. 이러한 여러가지 trick을 적용하고 나면 최종 loss의 gradient는 아래와 같이 변한다!

 

 

즉 여기서 새롭게 도입되는 parameter는 moving average를 적용한 값의 비율을 정해줄 λr, entropy term 적용 비율을 정해줄 λe가 된다.

 

이는 reinforcement learning의 update식과 같다고 하는데, 자세히는 모르겠지만 위의 수식이 아마 sampling된 임의의 행동에 대해 보상을 주는 모습과 같기 문에 그런 거 같다!

 

 

4. Deterministic Soft Attention

 

결론부터 설명하면, soft attention은 hard attention과 달리 하나만 고르지 않고, 어느 것을 얼만큼 사용할 것인지 비율에 맞게 가져다 사용한다.

 

즉 기존의 st = [0, 0, ...., 1, 0, ...] 이었다면 여기서는 [0.0001, 0.03, 0.0006, ...., 0.9, 0.0001, ....] 과 같이 한 곳에 가중치가 몰린 확률 vector가 되는 것이다.

 

따라서 sampling하지 않아도 되고, end-to-end로 학습이 가능하다는 장점이 있다!!

 

즉, soft attention에서의 zt는 위와 같다.

 

hard attention에서와 같이, α값은 이전 단계 LSTM의 output과 이미지 벡터 ai간의 attention점수에 softmax를 취해 어떤 부분의 이미지를 가져다 쓸 지 확률 점수 값으로 만든 것이다.

 

hard attention에서는 st를 정의하여 α값(확률 값)이 가장 높은 하나만 가져다 썼다면,

soft attention에서는 st대신 α자체를 ai에 곱하여 zt를 표현하는 것이다. (가중치에 맞게 ai 벡터를 조합하여 zt 생성)

 

즉, 벡터 zt는 location variable st에 대한 기댓값으로 표현되는 것이다.

 

 

1) Loss Function

Soft Attention에서의 Loss Function은, Hard Attention에서와 마찬가지로 log p(y|a)이다.

즉 annotation vector a가 주어졌을 때 정답 y를 고를 확률을 최대화 하는 것이다. (최대 우도 추정)

 

Hard Attention에서는 s를 sampling해야 하였으므로 여러가지 trick을 적용하였지만, 

Soft Attention은 end-to-end 방식이므로 그대로 계산하면 된다.

 

추가적으로는 주어진 정답 확률 분포 p(y|a)와 모델의 예측 확률 분포 p(y|a) 간의 차를 줄여주는 것 이므로, 일반적으로 cross entropy를 이용하며, 앞에 -를 붙여 negative log likelihood를 근한다.

 

 

- Upgrade Loss Function

 

또한, 논문에서는 soft attention에서 아래와 같이 loss function을 변형하면 더 좋다고 주장한다.

Hard attention에서와 같이 loss는 log(p(y|x))인데, 여기에 α값들의 합이 꼭 1이 아니어도 된다는 조건을 추가하는 것이다.

(λ라는 새로운 parameter가 생겼다.)

이렇게 loss를 변형하면 더 좋은 이유는 α값들의 합에 걸린 제약 조건을 풀어줌으로써, 쓸모 없는 정보가 많을 때 꼭 합이 1이 되기 위해 그것들을 끌어다 쓸 필요가 없기 때문이라고 논문에서 주장하고 있다.

 

 

2) Soft Attention에서 Loss Function에 관한 이해

 

논문을 읽다 보면 뜬금 없이 NWGM이 튀어나오면서 nt를 정의하는 것을 확인할 수 있다.

이 부분은 앞서 정의한 loss p(y|a)를 Soft Attention의 관점에서 해석하는 부분이다!

 

먼저 이해를 위해 앞 부분의 3.1.2절 Decoder: LSTM부분을 보아야 한다.

K : word 개수, m : embedding dimension, n : hidden dimension, D : feature vectors 개수

3.1.2절에서는 위와 같은 수식을 볼 수 있는데, 의미는 loss값인 p(yt |a, yt-1)이 오른쪽 수식에 비례한다는 것이다.

이유는 deep output RNN구조를 사용하였기 때문이라고 되어있고, deep RNN관련 논문인 "How to Construct Deep Recurrent Neural Networks(ICLR, 2014)"가 인용되어 있다.

 

여기서 deep output RNN이란 현재 우리가 대체적으로 이해하고 있는 deep RNN의 구조로, hidden state를 여러 개 갖는 RNN을 뜻한다!

 

hidden state를 여러 개 가질 때 각 state를 어떻게 연산하느냐에 따라서 논문에서는 다양한 deep RNN으로 구분하였는데, deep output RNN은 흔히 알고 있는 다중 RNN구조이다. 

출처 : How to Construct Deep Recurrent Neural Networks(ICLR, 2014)

즉, 위 그림에서와 같이 ht-1, xt로 처음 hidden state를 구하고, 이 hidden state를 linear projection시켜 최종 hidden state인 ht를 구하는 방법이라는 뜻이다.

 

다시 맨 위의 수식으로 돌아가 보면, 오른쪽 항 exp(Lo(E*yt-1 + Lh*ht + Lz*zt))은 Deep LSTM의 output gate 값에 exponential을 씌운 값이다.

 

output gate로부터 어떤 단어가 올 지 예측하여 caption을 생성하므로, 직관적으로 p(yt | a, yt-1)가 이에 비례하는 것을 이해할 수 있다!

 

 

---

 

다시 돌아가서 4.2절을 보게 되면,

LSTM에서 tanh(zt)에 linear projection을 취한 값은 ht이다.

그렇기 때문에, E[zt]를 한 번 forward prop하여 계산한 ht는 E[ht](ht들의 평균, 기댓값)를 1차 테일러 근사한 값과 같다고 한다.

 

즉, 1 - location variable st에 따른 ht의 평균값 E[ht]를 zt의 forward prop으로 계산 가능하다.

 

 

두 번째로는 2 - zt의 forward prop으로 st에 대한 output의 기댓값 E[output]을 구할 수 있다는 것을 보일 것이다.

 

위의 수식과 같이 여기서는 먼저 LSTM의 output gate를 통과한 값을 nt라고 두었다.

 

이 때 test time에서 k번째 단어를 prediction하기 위해서, 아래와 같이 NWGM(Normalized Weighted Geometric Mean)을 정의하게 된다.

자세히 들여다 보면, 수식의 모양은 softmax 확률을 취하고 있다.

분모는 1번째부터 마지막 단어까지 output gate를 통과한 값들의 총 합이고, 분모는 그 중에서 k번째 단어가 output gate를 통과한 값이므로, 

주어진 annotation vector a에 대해 yt = k번째 단어일 때의 확률값을 뜻한다.

 

또한 아래와 같이, 이전의 연구에 의하면 NWGM은 softmax를 사용할 때 p(y|a)의 기댓값으로 근사가 된다고 한다.

즉, 모든 attention location st에 대해 구한 output의 평균값(기댓값) NWGM[p(y|a)]는 E[zt]를 feedforward propagation함으로써 근사될 수 있다는 뜻이다.

 

총합하면, zt를 forward prop 함으로써 location variable st에 대한 ht의 기댓값을 구할 수 있고, ht로부터 계산되는 output의 기댓값 또한 구할 수 있다는 것이다.

 

결론적으로, deterministic attention model (Soft Attention)은 모든 attention location에 대한 marginal likelihood를 근사한다는 것이다!!!

 

 

 

논문에서는 end-to-end 방법인 Soft Attention을 사용하자고 이야기하며 실제로도 Soft Attention을 더 많이 사용한다.

 

5. 성능 평가

위의 표에서 보듯이, Flickr dataset 및 COCO dataset 모두에서 attention을 적용한 모델의 성능(BLEU score)이 더 높았다.

BLEU 스코어란, 이 역시 주재걸 교수님의 Youtube강의를 보면 친절하게 설명해 주시는데,

N-gram 단위로 정답 caption과의 유사도를 측정하는 것이다.

 

만약 BLEU-2라면 2-gram 단위로 정답 caption과의 mapping 정도를 확인하는 것이다. 주로 BLEU-4내외의 값을 중요하게 생각한다.

 

 

다음 포스팅에서는, image captioning에 attention을 활용한 본 Show, Attend and Tell 논문을 구현하고 이에 대해 설명하도록 하겠습니다!