Gated Mechanism For Attention Based Multimodal Sentiment Analysis

Abstract

Multimodal Sentiment Analysis(이하 msa)는 최근 인기를 얻고 있는데 그 이유는 social media가 발전하고 있기 때문이다.

이 논문에서는 msa의 세 가지 면을 소개한다.

  1. 얼마나 많은 modality가 sentiment에 기여하는지
  2. 장기 의존성을 해결할 수 있는지
  3. unimodal의 fusion과 cross modal cue

이 세가지 면에서 cross modal interaction을 배우는 것이 이 문제를 해결하는데 효과적인 것을 알 수 있었다.

CMU-MOSI나 CMU-MOSEI 데이터셋에서 좋은 성능을 보였다.

1. Introduction

Facebook, Whatsapp, Instagram and YouTube와 같은 소셜 미디어들이 발전하면서 sentiment analysis가 중요해졌다. msa는 acoustic, visual, textual를 같이 사용한다.

msa를 하는 방법에는 다음 세 가지 타입이 있다.

  1. modality를 각각 학습하고 output을 fuse 하는 방법
  2. 여러 개의 modality를 jointly 학습하는 방법
  3. attention based technique을 사용해서 각 unimodal들이 얼마나 기여하는지 알아보는 방법

그래서 더 나은 cross modal information을 배우기 위해서 cross interaction 동안 정보를 조절하는 conditional gating mechanism을 제안한다.

게다가 video에서 장기 의존성을 잡기 위해서 각 unimodal contextual representation에 self-attention layer를 적용한다. self-attention을 사용하는 장점은 direct interaction을 가능하게 하고, network에서 제한없는 information flow를 제공한다.

논문에서 제안하는 방법에서 중요한 것은 다음과 같다.

  1. cross interaction간에 정보를 조절할 수 있는 gating mechanism을 배운다.
  2. self-attend가 장기 의존성을 잡을 수 있다.
  3. self 및 gated 기반의 recurrent layer는 더 정확한 multimodal을 얻을 수 있다.

2. Proposed Approach

학습가능한 gate에 의해 조절되는 서로 다른 modality사이에 interaction을 배우는 것이 목적이다. 전체적인 구조는 아래와 같다.

2.1 Contextual Utterance Representation

Bi-GRU를 통해서 각 modality에서 specific contextual representation을 얻는다. 다음은 text를 뜻하는 representation이다.

2.2 Self Attention

장기 의존성을 잡기 위해서 bilinear attention을 사용한다. 100개의 utterance가 있어도 self-attention은 장기 context를 잡을 수 있다. Text에 대해서 다음과 같이 계산한다.

2.3 Cross Attention

msa는 서로 다른 modality간에 interaction을 배울 기회를 제공한다. modality를 두 쌍씩 묶어서 co-attention matrix를 배운다.

2.4 Gating Mechanism for Cross Interaction

imperfect modality을 fusing하는 문제가 생기게 된다.

각 modality에서 발생하는 noise를 해결하기 위해서 선택적으로 cross fused vector를 배우기 위해 gating mechanism을 제안한다.

gated cross fused vector는 다음과 같이 얻는다.

여기서 fusion kernel fusion(,)은 gated combination of cross interaction과 contextual representation을 사용한다.

Cross interaction인 X(P,Q)은 P는 cross attended vector, Q는 contextual representation인 비선형변환이다. Gating function인 G(P,Q)은 cross interaction에서 다음 layer로 pass되는 정보를 조절한다.

따라서 최종 계산은 다음과 같다.

modality의 특성이 보완적인 경우, gating function은 cross interaction을 선호하기 때문에 더 높은 값을 가질 것이다. 반면에 그렇지 않은 경우 contextual representation을 선호할 것이고, 낮은 값을 가질 것이다.

2.5 Deep Multimodal Fusion

self 와 gated cross interaction을 합하기 위해 Bi-GRU를 사용해서 합친다.


3. Experiments

3.1 Dataset

CMU-MOSI와 CMU-MOSEI를 사용한다. values가 0 이상이면 긍정으로 반대면 부정으로 했다.

3.2 Implementation Details

word feature에 대해서는 Glove를 사용했고, visual은 Facets, acoustic은 CovaRep을 사용했다.

3.3 Results and Analysis

3.3.1 Baselines and Ablation Study

제안한 방법을 분석하기 위해서 여러 실험을 수행했다.

B1 : unimodal

B2 : B1+Self+Attention

B3 : bimodal baseline

B4 : gating mechanism

B6 : our model

3.3.2 Benchmarking

종합적으로 비교하기 위해서 다른 multimodal sentiment analysis와 비교해보았다.

제일 좋았다.

4. Conclusions and future work

self-attention과 gating mechanism을 사용해서 msa를 발전시켰다.

gating 함수는 unimodal한 정보가 sentiment를 결정하기 충분하지 않을 때 cross-interaction을 강화하고, 충분하다면 cross-modal information에 낮은 가중치를 부여한다.

앞으로는 audio 데이터의 질이 낮은 실제 데이터에도 적용해보는 것이 목적이다.

문제:

풀이방법:

 효율적으로 풀어야 하는 문제이기 때문에 O(N^2) 방법으로는 시간초과에 걸릴 것이다. 따라서 투 포인터를 사용하는 슬라이딩 윈도우를 사용해서 풀었다. 

 우선 앞에서부터 뒷 포인터를 이동시키면서 모든 보석을 포함할 때까지 이동한다. 모든 보석을 포함하게 된다면 앞 포인터를 움직여서 가장 앞에 존재했던 보석을 뺀다. 그래도 모든 보석이 포함되어 있다면 앞 포인터를 움직여서 다시 앞을 빼고, 모든 보석이 포함되어 있지 않다면 뒷 포인터를 움직여서 다시 모든 보석을 포함시킬 때까지 움직인다. 

이 과정을 반복하면서 가장 짧은 길이의 포인터들을 저장해두고 최종적으로 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def solution(gems):
    answer = []
    initGems = len(set(gems))
    
    gemCount = {}
    gemSet = set()
    
    start,answerStart = 00
    last,answerLast = 00
    diff = 999999999
    swLast = -1
    
    for s in range(len(gems)):
        findsw = False
        for l in range(swLast+1,len(gems)):
            if len(gemSet) == initGems:
                findsw = True
                if abs(l-s-1< diff:
                    diff = abs(l-s-1)
                    answerStart = s
                    answerLast = l-1
                swLast = l-1
                break
            if not gemCount.get(gems[l]):
                gemCount[gems[l]] = 1
                gemSet.add(gems[l])
            else:
                gemCount[gems[l]] +=1
        if not findsw:
            if len(gemSet) == initGems:
                findsw = True
                if abs(l-s) < diff:
                    diff = abs(l-s)
                    answerStart = s
                    answerLast = l
                swLast = l
            break
 
        if gemCount.get(gems[s]):
            if gemCount[gems[s]]==1:
                del gemCount[gems[s]]
                gemSet.remove(gems[s])
            else:
                gemCount[gems[s]] -=1
                
    answer.append([answerStart+1,answerLast+1])
    return answer[0]
cs

문제링크:

https://programmers.co.kr/learn/courses/30/lessons/67258

 

코딩테스트 연습 - 보석 쇼핑

["DIA", "RUBY", "RUBY", "DIA", "DIA", "EMERALD", "SAPPHIRE", "DIA"] [3, 7]

programmers.co.kr

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]18258. 큐2  (0) 2020.07.23
[BOJ]4963. 섬의 개수  (0) 2020.07.21
[BOJ]2164. 카드2  (0) 2020.07.14
[Programmers]2020 카카오 인턴십. 수식 최대화  (0) 2020.07.09
[Programmers]2020 카카오 인턴십. 키패드 누르기  (0) 2020.07.07

문제:

풀이방법:

 처음에는 스택으로 구축할까 생각하다가 많이 복잡할 것 같아서 슬라이싱을 활용한 문자열 비교로 해결하기로 하였다. 

문자열의 길이가 1이면 항상 답은 1이라는 예외처리로 시작한다. 몇 개 단위로 자르는 것이 가장 짧은 방법인지 알지 못하므로 1부터 len(s)까지 분할 하도록 한다. i개의 단어로 자르면서 앞과 현재가 같다면 count를 하나올려주도록 한다. 만약 다르다면 count를 비교해보도록 한다. count가 1이라면 그냥 문자열에 더하고, 1이 아니라면 숫자를 같이 더해주도록 한다.

 이렇게 각 길이의 단위로 자른 문자열을 모두 담았다면 가장 작은 값을 반환하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def solution(s):
    answers=[]
    if len(s)==1:
        return 1
    for i in range(1,len(s)):
        answer = ''
        count = 1
        for j in range(i,len(s),i):
            if s[j-i:j]==s[j:j+i]:
                count+=1
            else:
                if count==1:
                    answer+=s[j-i:j]
                else:
                    answer+=str(count)+s[j-i:j]
                    count=1
        if len(s[j:j+i])==i:
            if count==1:
                answer+=s[j-i:j]
            else:
                answer+=str(count)+s[j-i:j]
                count=1
        else:
            answer+=s[j:j+i]
        answers.append(len(answer))
    return min(answers)
cs

 

문제링크:

https://programmers.co.kr/learn/courses/30/lessons/60057

 

코딩테스트 연습 - 문자열 압축 | 프로그래머스

데이터 처리 전문가가 되고 싶은 어피치는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여 더 짧은 문자열로 줄여서 표현하는 알고리즘을 공부하고 있습니다. 간단한 예로 aabbaccc의 경우 2a2ba3c(문자가 반복되지 않아 한번만 나타난 경우 1은 생략함)와 같이 표현할 수

programmers.co.kr

 

'Algorithm > Python' 카테고리의 다른 글

[Programmers]2018 Kakao.방금그곡  (0) 2019.12.01
[Programmers]2020 Kakao.괄호 변환  (0) 2019.11.15
[BOJ]2358. 평행선  (0) 2019.11.13
[BOJ]GIT- 정리  (0) 2019.11.12
[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11

+ Recent posts