2018년 8월 9일 목요일

MnasNet

Mobile platform에 최적인 넷 구조를 NAS로 찾는다.

1. 최적화할 목적함수를 accuracy와 실제 폰에서 측정한 latency(지연시간,연산시간) 2개를 합쳐 사용한다.
1-1. 실측 이유는 연산시간은 폰 의존적이고 폰 사양은 매우 다양하다. 필드에서 직접 관찰이 중요하다. 실험에 쓴 구글 픽셀 one 폰은 단일 쓰레드 CPU 환경이다.
1-2. accuracy와 latency 둘 다를 목적함수 하나로 합치기 위해 Pareto optimal을 사용한다. hard와 soft constraint 2가지를 정의하고 soft를 사용했다.

2. 기존 NAS는 동일 cell 타입을 층으로 쌓았다. 같은 3x3 conv라도 입출력 shape이 달라지면 지연량이 다름을 고려치 않았다. MnasNet은 block별로 구조나 연결이 다른 넷을 구성한다.

3. 후보 샘플링->넷 구성->reward 계산->RNN 학습. 절차는 기존 sampling기반 NAS와 동일하다.




넷 구조 형성에는 Factorized Hierarchical Search 공간을 정의하고 탐색한다.
CNN은 Net 앞 단이 더 큰 data를 처리하므로, 동일한 Block(또는 cell) 구조를 누적 사용할 경우, 뒷 단 보다 latency에 끼치는 영향이 크다.  Block에 들어가는 data 크기에 따라 구조나 연결이 달라야 한다.
MnasNet은 data shape에 따라 Block 구조도 달라진다.


References
[1] MnasNet paper
[2] Google AI BLog: MnasNet
[3] Pytorch-MnasNet





2018년 8월 2일 목요일

DARTS

Differentiable Architecture Search(DARTS)는 NAS 알고리즘 일종으로 기존 NAS에서 사용하던 강화학습 기반의 discrete한 후보 선택 방법을 미분 가능하고 연속적인 최적화 방법으로 바꾸었다.

입력 $x=[64,3,32,32]$에 연산자 $op$를 적용한다. $op$ 후보가 8개라 가정하자. 이 중 1번만 적용하고 나머지 7개는 무시하면 $x'=op_1(x)$이다.

만일 2번, 5번 연산자를 동일한 가중치로 적용하고 나머지를 무시하면
$x'=0.5 \cdot op_2(x)+0.5 \cdot op_5(x)$
이다. 단, 이 연산이 성립하려면 $op_2(x)$와 $op_5(x)$는 같은 shape를 가져야 한다.

8개 모두 적용 시
$x'=\sum w_i \cdot op_i(x)$
이다.
DARTS는 $w_i(i=0...7)$ 탐색을 통해 $x'$가 연결되어 만든 net의 validation loss 최소화로 NAS 해결방법을 찾았다.


이는 $x'$가 만드는 loss를 $w_i$에 대해 편미분해 구한다.
통상 CNN에서 층(layer)이라 함은 Conv나 ReLu 등 연산을 선택 후, 이 $op$에 관련된 학습 가중치를 net loss가 최소화되게 구하는 것이다.
그런데, 이종의 $op$가 결합되어 층 하나를 구성한다면 어떤 연산을 지배적으로 사용할건지를 나타내는 연산 가중치 $w_i$ 결정과 각 연산에 들어 있는 학습 가중치 결정 2가지 문제를 함께 풀어야 한다.


두 타입 인자 결정을 동시에 할 수는 없다. $op$ 가중치 최적화, CNN 학습 가중치 최적화를 차례로 수행해야 한다. DARTS는 두 단계 수행 방법을 설명한다.


Reference
[1] DARTS paper
[2] pytorch-DARTS



2018년 7월 31일 화요일

Efficient NAS

Neural Architecture Search(NAS)는 딥러닝 넷 구조를 자동으로 찾는 알고리즘이다. 이미지 분류용 NAS 알고리즘을 살펴보자.
먼저 입력(image or feature map)에 적용할 복수의 연산 후보들을 정의하고, net 내 레이어들이 어떤 연산을 선택할지, 그리고 레이어들을 상호간 어떻게 연결할지를 함께 결정해야 한다.
CNN 구조의 경우, 연산 후보는 sepconv3x3, sepconv5x5, maxpool3x3, avgpool3x3, identity(skip-connection) 등이 될 수 있다.

NAS는 2가지로 달성 가능한데, Macro 및 Micro search이다.
Macro는 전체 넷을 한번에 설계한다. 이 경우 개입되는 파라메터가 너무 많아 문제 규모가 커지므로 풀기도 어렵고 성능도 낮다.
Micro는 Macro 문제점을 해결하기 위해 Cell 개념을 도입한다. Cell이란 내부에 소규모 연결 요소들을 가지는 단위 구조이다. Cell을 먼저 설계하고 Cell간을 연결하여 전체 구조를 만든다.  Cell간 연결은 다음 처럼 미리 정해 놓는다.

CNN 경우,

Cell(N)-Cell(N)-Cell(R)-Cell(N)-Cell(N)-Cell(R)

로 할 수 있다.

N은 Normal, R은 Reduction인 2가지 타입 cell이 있다. Normal은 입력 이미지(특징맵) 크기를 유지하여 출력하고 Reduction은 입력 크기를 절반으로 줄여 출력한다.
Cell은 입력 2개와 출력 1개를 가지며 이전 Cell 출력을 입력으로 사용한다. 맨 앞 Cell 입력 2개는 이미지 입력을 동일하게 사용한다.

정리하면, Micro 탐색으로 Cell 구조를 먼저 설계하고 이들을 연결하여 전체 넷을 구성하면 설계 파라메터도 줄이고 실용적이며 성능도 좋다.


CNN 예에서 N셀은 4개이며 내부 구조가 동일하다. 2개의 R셀도 동일 구조이다. N과 R은 서로 구조가 다르므로 생성 알고리즘은 같지만 객체는 따로 유지한다.

Cell 설계는 RNN을 사용한다. RNN 사용 이유는 Cell 내 노드(layer) 연결은 입력 2개에서 시작하여 차례로 새로운 노드(layer)을 생성, 추가하면서 구조를 키워 나가는데, 생성 노드는 이전 노드에 의존적이고 노드 상관성을 가지기 때문이다.
더 이상 후속 연결이 없는 노드들은 concat으로 합쳐 단일 출력으로 내 보낸다.


RNN 출력 예를 보면,
2255/3355/4455/5555/6655
이고 5회 step 동안 전부 20개의 출력을 준다. 숫자는 리스트 크기이고, 인덱스를 저장한다.

각 step 당 4개 출력은 (node_L, node_R, op_L, op_R)이다. node_L과 node_R은 이전 입력 어떤 것을 선택할지를, op_L, op_R은  입력에 어떤 연산을 적용할지를 보여준다.

예를 들면, 2255에서 길이 2는 node_L이 cell 두 입력 중 1개를 선택하며 one-hot vector [0,1] 또는 [1,0]를 사용하기 때문이다. 길이 5는 후보 연산 중 1개를 선택하므로 [0,1,0,0,0] 또는 [0,0,0,1,0] 등이다.

3355는 Cell에 들어간 두 입력을 이용하여 앞 단계에서 새로운 노드(layer)가 이미 생성되었으므로 이제 선정할 후보는 세개이다. 따라서 3이 되고, 연산 후보는 불변이니 5로 유지된다.


References
[1] ENAS paper
[2] Keras-enas
[2] Tensorflow-enas




2018년 7월 5일 목요일

Mask R-CNN

github (https://github.com/matterport/Mask_RCNN)
paper (https://arxiv.org/pdf/1703.06870.pdf)

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,:)에 저장.