2018년 5월 8일 화요일

Attention

$\underline{Dense\ attention}$

입력 특징(속성)의 어떤 하나에 attention

inputs = Input(shape=(32,)) #32개 중 중요한 것 찾음.

# Dense출력수는 inputs수와 같고 softmax로 확률값 만듬
attention_probs = Dense(32, activation='softmax')(inputs) #attention vector

#dense출력을 inputs에 곱해 어떤 값에 attention할지 $\mathit{dense가\ 학습}$
attention_mul = merge( [inputs, attention_probs], output_shape=32, mode='mul')

# attention된 vector를 분류기에 넣음
attention_mul = Dense(64)(attention_mul)
output = Dense(1, activation='sigmoid')(attention_mul)

model = Model(input=[inputs], output=output)



$\underline{시계열\ attention}$

Timestep 어떤 순간에 attention하게 한다.

# 20 Timestep 중 중요한 step
# inputs.shape = (batch_size, TIME_STEPS, input_dim) #(None,20,32)

# Timestep <-> 특징축 교환
a = Permute((2, 1))(inputs) #(None,32,20)

#Timestep축 값 20에 대한 정규화
a = Dense(TIME_STEPS, activation='softmax')(a) #(None,32,20):

# 다시 되돌림
a_probs = Permute((2, 1))(a) #(None,20,32)

#두 값 곱함:(None,20,32)
#Timestep 어디에 attention할지 $\mathit{dense가\ 학습}$
output_attention_mul = merge([inputs, a_probs], mode='mul')



$\underline{영어-일어\ 번역}$

$\mathit{먼저\ encoder-decoder\ 구조\ 만듬}$

# (None,20) -> (None,20,64): 20자 영단어를 64차원 임베딩
encoder = Embedding(54, 64, input_length=20, mask_zero=True)(encoder_input)

# 매 Timestep마다 출력(64개)
encoder = LSTM(64, return_sequences=True, unroll=True)(encoder)

#맨 마지막 timestep 값(None, 64)
encoder_last = encoder[:,-1,:]

# (None,20) -> (None,20,64) #20자 일단어를 64차원 임베딩
decoder = Embedding(89, 64, input_length=20, mask_zero=True)(decoder_input)

# encoder 출력 (None,64) 2개를 초기 state로 입력
decoder = LSTM(64, return_sequences=True, unroll=True)(decoder, initial_state=[encoder_last, encoder_last])



$\mathit{attention\ 기능\ 부가}$

###################################################
# encoder, decoder 출력은 같은 뜻이니 서로 유사해야 한다고 하면
# 영어 추출한 64개 속성과 일어추출 64 속성은 비슷해야 한다.
# -> 둘 다 2번축끼리 곱함: (None,20,64)x(None,20,64)->(None,20,20)
#
# 아래 코드 보면 decoder가 앞, encoder가 뒤 이므로 출력 Tensor는 (None,20,20)이고 
# 1번축 20개는 decoder timestep, 2번축 20개는 encoder timestep이면서 pdf로 정규화.
# 1번축 $i$번째 step입력에 대응되는 encoder 20개 입력간 유사성을 pdf로 표현한다.
attention = dot([decoder, encoder], axes=[2, 2])

# (None,20,20) 속성 2번축 20개 값 정규화
attention = Activation('softmax', name='attention')(attention)

# 이는 encoder 출력 중 어디에 집중해 주어야 하는지를 모델링
# attention=(None,20,20) 2번축 x encoder=(None,20,64) 1번축
#    -> (None, 20,64)
# encoder timestep에 대한 prob.
context = dot([attention, encoder], axes=[2,1])
#
#
# attention된 encoder features + decoder features 결합
# encoder 집중화 출력(context정보)과 decoder출력을 묶음
# (None,20,64)+(None,20,64) -> (None,20,128)
decoder_combined_context = concatenate([context, decoder])


# Has another weight + tanh layer as described in equation (5) of the paper
# 128 -> 64 -> 89: 3층 분류기
output = TimeDistributed(Dense(64, activation="tanh"))(decoder_combined_context)
output = TimeDistributed(Dense(89, activation="softmax"))(output)

# 모델
model = Model(inputs=[encoder_input, decoder_input], outputs=[output])
model.compile(optimizer='adam', loss='binary_crossentropy')


$\cdot$앞에서는 input를 dense에 넣어 input 어디에 attention할지를 dense가 학습
$\cdot$여기서는 dense 대신 decoder 사용. 즉, decoder출력 만드는 RNN 후반부가 attention 학습

$\cdot$영어->일어 번역으로 encoder에 영어입력, decoder에 일어 입력이다.
$\cdot$일어입력 20 timestep 어떤 순간 특징 64개는 영어 20 timestep 각 순간 특징(64개)와 유사성 체크.
(ex.) 일어 5 step째 입력과 영어 0~19 step별 유사성: decoder X encoder이므로 (None,5,:)에 저장.
       일어 7 step째 입력과 영어 0~19 step별 유사성: (None,7,:)에 저장.