RAFT: Recurrent All-Pairs Field Transforms for Optical Flow
저자 : Zachary Teed, Jia Deng
출간 : ECCV 2020 (ECCV 2020 best paper)
주제 : Optical Flow
출처 : 2003.12039.pdf (arxiv.org)
Github : princeton-vl/RAFT (github.com)
- 요약
raft는 여러 resolution으로 correlation을 뽑아내고, 이들을 RNN 기법 중 GRU란 unit을 통과시켜서 optical flow를 예측합니다. 속도, 정확도 모두 뛰어납니다.
* 제가 이 논문을 알게 된 건 supervised I2I task 중 성능이 뛰어난 CoCosNetv2 을 통해 알게되었습니다. CoCosNet v2 는 v1보다 정확도를 훨씬 높이면서 sota를 만들어냈는데, 가장 큰 차이점이 RAFT 기술을 활용했다는 점입니다. 이미지와 관련된 최신 기술들을 이해하려면 단순히 neural network architecture에 대한 이해를 넘어 computer vision에 대한 이해도 함께 필요하다는걸 느끼게 되네요.
1. Introduction
optical flow는 pixel단위로 pixel의 이동을 추정하는 알고리즘을 말합니다. 현재에도 빠르게 움직이는 물체, occlusion, motion blur, textureless 한 이미지에 대해선 한계점을 보이고 있습니다. 본 논문에서 소개하는 RAFT 모델은 정확도에서 SOTA를 달성했고, 다양한 이미지에도 적용 가능하며 높은 효율성을 보입니다.
- RAFT의 구조는 크게 Feature encoder, Correlation layer, Update operator(GRU) 인 3가지로 구성되어 있습니다.
- feature encoder는 feature를 추출합니다.
- correlation layer는 두 이미지의 similarity를 계산합니다.
- update operator는 예측을 optimization하는 알고리즘입니다.
(1) RAFT는 single fixed flow를 유지하면서 coarse-to-fine의 한계를 극복해냅니다. (FPN 차용하지 않음.)
(2) update operator가 가볍습니다.
(3) update operator는 RNN의 새로운 디자인인 GRU로 구성되어 있으며, 이를 통해 4D scale의 correaltion volume을 탐지합니다.
2. Related work
Optical Flow as Energy Minimization
기존에 사용하던 Taylor approximation 방법은 large displacements를 잘 잡아내지 못했습니다. 이를 극복하기 위해 coarse-to-fine strategy를 이용하였지만, 이 방법은 빠르게 움직이는 물체를 못잡아내는 등 다른 단점들이 발견되었습니다.
본 논문에선 하나의 feature를 뽑아내고, correaltion volume을 여러개 산출하여 small, large displacements를 모두 잡아내는 방법입니다.
Direct Flow Prediction
FPN을 사용하지 않고 high resolution 하나만 사용했다는 내용으로 위와 동일합니다.
Iterative Refinement for Optical Flow
IRR(Iterative Residual Refinement) 방법을 GRU를 사용해서 했습니다. 또 모든 반복을 동일한 layer에서 하기 때문에 weight가 공유되면서 훨씬 가볍습니다.
Learning to Optimize
IRR을 사용하는데 gradient를 명확하게 정의해놓지 않고 모델이 자연스럽게 학습할 수 있도록 바꿨다는 내용입니다.
(정확한 차이는 Solving ill-posed inverse problems using iterative deep neural networks나 TVNet을 읽어봐야 알 수 있겠네요.)
3. Approach
이제 진짜 본론 시작입니다.
3.1 Feature Extraction
Encoder : \(g_{\theta}\)
Context Feature Network : \(h_{\theta}\)
Encoder는 t 시점의 이미지와 t+1 시점의 이미지를 받습니다. 최종 output은 1/8 크기로 줄어들고 256 채널입니다.
(Encoder에서 추출된 output 2개가 동시에 correlation layer로 들어갑니다.)
Context Feature Network는 t시점의 이미지인 \(I_{1}\) 만 받습니다. (여기서 뽑은 feature는 나중에 correlation output과 함께 GRU로 들어갑니다.)
3.2 Computing Vision Similarity
Encoder를 통과한 두 이미지의 모든 픽셀을 dot product하여 correlation을 산출합니다.
행렬 곱의 shape 변환처럼 correlation의 shape은 [H*W, D] * [D, H*W] = [H*W, H*W] 의 크기를 가집니다. (기호는 편한대로 사용하겠습니다.)
그 다음 FPN을 사용하지 않는 대신, Correlation을 4개의 다른 크기를 가진 kernel로 각각 pooling하여 4개의 correlation pyramid를 갖게 됩니다.
4번째 줄에 보이듯이 pooling은 H, W 안에 들어있는 H, W에 적용이 됩니다. 이를 통해 small displacements와 large displacements, fast-moving objects 까지 파악할 수 있게 됩니다.
Correlation Lookup
(H, W, H, W) 로 뽑은 correlation에서 또 다시 neighborhood 픽셀만 뽑습니다. 논문에서는 4 pixel (k=4) 주변의 이미지를 bilinear sampling을 통해 뽑아냅니다. -4부터 +4까지니까 가로 9, 세로 9 해서 총 9x9 픽셀의 정보를 뽑아내며, 앞에서 correlation을 4개로 뽑았기 때문에 이 또한 4번 반복합니다. 최종적으로 (N, H, W, 324) 모양의 correlation이 산출됩니다.
요약하자면 (H, W, H, W) --> (H, W, H', W')x4 --> (H, W, 9, 9)x4 --> (H, W, 9x9x4) 과정으로 1개의 feature가 됩니다.
pooling을 통해 연산량이 줄어들게 된다는 내용입니다. 이 연산은 update operator(GRU)가 반복될 때마다 실행됩니다.
3.3 Iterative Update
iterative update는 flow, correlation, h(x1)이 input으로 들어갑니다. hidden state를 지속적으로 업데이트하면서 반복하기 때문에 tied weights를 사용했다고 하는 것 같습니다. 또 bounded activations는 sigmoid와 tanh를 사용하는 gru의 특징을 말한 것 같네요.
- 반복을 시작하는 시점에서 모든 flow는 0으로 초기화됩니다.
- correlation, flow, context가 각각 conv를 거친 뒤 하나의 feature로 통합됩니다.
- GRU에 관한 내용.
- flow prediction은 원본 이미지의 1/8크기입니다.
- Iterative update 도중에 2개의 conv를 통해 upsample용 mask도 학습합니다. flow image를 뽑을 땐 이를 활용하여 1/8크기의 이미지를 다시 upsample하여 처음 크기와 맞춥니다.
3.4 Supervision
반복을 많이 거친 뒤쪽에 더 많은 가중치를 두고, 앞쪽엔 가중치를 줄입니다.
4. Experiments
실험은 best paper답게 정말 훌륭합니다. 직접 구경해보세요.
5. Conclusion
속도와 성능 둘다 잡았다.
- 코드실습
그냥 문제 없이 잘 돌아갑니다. flownet과 달리 correlation layer를 cuda 뿐만 아니라 python으로도 구현해 놓았기 때문에 CPU에서도 디버깅이 가능합니다.