논문 읽기/Classification

[논문 읽기] ShuffleNetV2(2018) 리뷰, Practical Guidelines for Efficient CNN Architecture Design

AI 꿈나무 2021. 3. 23. 20:58
반응형

 안녕하세요! 이번에 읽어볼 논문은 ShuffleNetV2 입니다. ShuffleNetV1의 후속작인데요. ShuffleNetV1은 제한된 연산량을 최대한 활용하기 위해 channel shuffle와 pointwise group convolution을 제안한 모델입니다. ShuffleNetV2은 연산량이 Inference 속도와 절대적인 관계가 없다고 합니다. 예를 들어, 모델이 가벼워도 실제 task에서 작동되는 속도는 느릴 수 있습니다. 따라서 연산량(FLOPs)가 아닌 inference speed에 집중을 합니다. 그리고, 모델의 Inference 속도를 향상시키는 4가지 가이드라인을 제시합니다. 가이드라인에 따라 구축한 모델이 ShuffleNetV2 입니다.

 

 참고로 Inference 속도가 빨라야 object detection 등 real time task에 적용하기 좋습니다. 저자는 연산량(FLOPs)보다 이 inference 속도에 집중합니다.

 

FLOPs vs Speed

 일반적으로 모델 경량화의 지표는 FLOPs(float-point operations) 였습니다. FLOPs는 speed나 latency에 근사화할 뿐이고 직접적인 metric은 아니라고 합니다. 예를 들어, MobileNetV2는 NASNET-A보다 빠르지만 FLOPs는 많습니다. 아래 그림을 살펴보겠습니다.

 

 

  GPU와 ARM 두 가지 platform에서 진행된 실험입니다. 그림(c)와 (d)를 보면 FLOPs는 비슷한데, 속도에서 많이 차이가 납니다. 그러므로 FLOPs는 연산량을 위한 지표일 뿐이고, 이를 사용하는 것은 잘못된 모델 디자인으로 이끌 수 있습니다.

 

 왜 이런 차이가 나는걸까요?! 저자는 두 가지 이유를 제시합니다.

 

(1) FLOPs에서 설명되지 않고, 속도에 영향을 미치는 여러 중요한 요인들이 존재합니다. 그 중 하나가 MAC(memory access cost)입니다. 이 MAC은 group convolution과 같은 연산이 큰 부분을 차지합니다. 그리고 이는 device에서 bottleneck이 될 수 있습니다. MAC은 모델을 설계하는데에 있어서 무시하면 안될 요인입니다. 또 다른 하나는 degree of parallelism 입니다. 동일한 FLOPs에서 high degree of parallelism은 low degree보다 훨씬 더 빠릅니다. (high degree of parallelism은 얼마나 병렬처리를 잘 활용하냐를 의미하는 것 같습니다. 아시는 분은 댓글 남겨주시면 감사하겠습니다.)

 

(2) 동일한 FLOPs를 갖더라도 연산이 Platform에 따라 속도가 다릅니다. 여기서 연산은 ReLU, conv, element-wise add를 의미합니다. FLOP을 낮추기 위해 tensor decomposition을 많이 사용했습니다. 하지만 decomposition 으로 75% FLOPs를 낮추더라도 GPU에서 속도가 느리다는 것으로 밝혀졌습니다. 이것은 CUDNN 라이브러리가 3x3 conv에 최적화되었기 때문이라고 합니다. 3x3 conv 연산은 잘하는데 그 외에 덧셈 등 다른 연산은 ARM에 뒤쳐진다는 것입니다. 또한 3x3 conv는 1x1 conv보다 연산량이 9배 적지만 속도가 9배 느리진 않습니다. 이처럼 연산의 연산량이 속도로 이어지지 않습니다. 아래 그림을 보면 GPU는 3x3 conv 연산에 강점을 보이지만, 그 외에 Elemwise는 ARM보다 비효율적으로 연산하네요.

 

 

 이를 기반으로 논문에서 효율적인 구조를 디자인하기 위해 두 가지 원칙을 제안합니다. 첫 번째로 metric을 speed로 사용하는것과 두 번째는 GPU, ARM 두개의 plafform에서 평가하는 것입니다.

 

Practical Guidelines for Efficient Network Design

 저자는 FLOPs가 아닌 MAC(memory access cost)에 집중합니다. 그리고 이 MAC을 최소화하여 모델을 설계하기 위한 4가지 가이드라인을 제시합니다.

 

(1) Equal channel width minimizes memory access cost

 경량화 모델은 주로 depthwise separable convolution을 사용합니다. 그 중 pointwise convolution(1x1 conv)이 연산량의 대부분을 차지합니다. 1x1 conv의 파라미터는 입력 채널(c1), 출력 채널(c2) 두 가지 이므로 이 두가지를 바꿔가면서 실험을 합니다.

 

 

 입력 채널(c1) : 출력 채널(c2) = 1 : 1일때, 속도가 제일 빠르다는 것을 실험으로 증명합니다.

 

(2) Excessive group convolution increases MAC

 ResNext에서 제안된 Group Convolution을 사용하면 연산량이 감소되기 때문에, 제한된 연산량안에서 더 많은 피쳐맵을 활용할 수 있었습니다. 따라서 최신 모델들은 Group Convolution을 사용했었었죠. 이 Group Convolution은 FLOPs를 감소하지만 오히여 MAC은 증가시킵니다. 아래 실험 결과를 살펴보겠습니다.

 

 large group number는 running speed를 상당히 감소시킵니다. 예를 들어, GPU에서 8groups를 사용하는 것은 1group을 사용하는 것보다 두 배는 느립니다. CPU에서는 30% 느리네요.

 

 따라서 저자는 group number를 task와 platform에 따라 신중히 선택해야 한다고 합니다. group number를 사용하면 정확도에 이점이 있지만 MAC가 상승하기 때문입니다.

 

(3) Network fragmenttion reduces degree of parallelism

 GoogLeNet 시리즈의 블락과 Auto ML의 Cell은 여러 연산으로 이루어져있습니다. 논문에서는 fragmented operation이라고 표현합니다. 큰 operation을 사용하는 것보다 작고 여러개의 operation을 사용하는데요. 대표적으로 NasNet은 여러 conv, pooling 연산이 하나의 block에 포함되어 있습니다. 반대로 ResNet은 규칙적인 구조로 이루어져 있습니다.

 

 이 fragmented structure은 정확도에 이점을 보이지만, 효율성이 감소됩니다. GPU같은 기기에 최적화되지 않기 때문이라고 하네요. 저자는 실험을 위해 서로 다른 fragmentation로 구성된 block을 실험합니다.

 

 1-fragment가 가장 빠르네요.

 

(4) Element-wise operations are non-negligible

 연산량을 계산할 때, element-wise operation은 고려하지 않았습니다. 하지만 이 element-wise operation은 특히 GPU에서 큰 비중을 차지합니다. 아래 그림을 보면 element-wise가 상당한 비중을 차지하네요.

 element-wise operation은 ReLU, ADDTensor, AddBias 를 의미합니다. 이 연산들은 FLOPs수는 적지만 상대적으로 MAC가 큽니다. 아래 실험은 ReLU와 shortcur의 유무에 따른 속도 비교입니다. ReLU와 shortcut을 사용하지 않을 때가 제일 빠르네요.

 

(5) 정리

 위 4가지를 정리하면 다음과 같습니다. (1) 채널이 같도록 convolution을 사용하기 (2) group convoltion을 사용할 때, MAC 비용 생각하기. (3) fragmentation 줄이기. (4) element-wise operation 줄이기.

 그리고, 이 성질들은 platform(GPU, CPU)에 따라 다르게 나타납니다. 따라서 목적에 맞는 설계를 해야합니다.

 

ShuffleNetV2 Unit

 4가지 가이드라인에 따라 ShuffleNetV2 Unit이 탄생합니다.

 

(c): basic, (d) down-sampling

 

 ShuffleNetV2 unit의 특징은 Channel Split, Concat, Channel Shuffle을 사용하는 것입니다. 이 세가지를 살펴보겠습니다. Channel Split은 입력 채널을 2개의 branch로 split합니다. 논문에서는 동일한 채널 수로 분할합니다. 한 branch는 identity mapping이 되고, 다른 branch는 3 conv layer를 거칩니다. 그리고 각 branch 출력값은 Concat 됩니다. Concat된 값은 Channel Shuffle을 통해 값들이 섞입니다.

 

 (d)는 down-sampling을 위해 사용합니다. channel split이 제거됬네요. 입력값이 split되지 않기 때문에 채널 수를 보존한 채로 두개의 branch로 전달됩니다. 그리고 conv 연산을 거친뒤에 concat을 거쳐서 채널 수는 2배 됩니다.

 

 Channel Split 덕분에 절반의 channel이 곧바로 다음 unit으로 전달됩니다. 따라서 feature reuse효과가 있습니다. 

 

 아래 그림은 SE block와 residual을 사용한 ShuffleNetV2 unit입니다. large model을 만들 때 사용합니다.

 

 전체 구조는 다음과 같습니다.

 stage에는 ShuffleNet unit을 사용합니다. 특이한 점은 GlobalPool 이전에 1x1conv layer를 사용합니다. 특징들을 섞어주기 위함이라고 하네요.

 

Performance

 ShuffleNetV2에 SE block과 residual을 사용하면 large model을 만들 수 있습니다. large model일 떄의 성능 비교입니다.

 

 여러 모델과의 성능 비교입니다.


참고 자료

[1] arxiv.org/abs/1807.11164

반응형