지난 주 FlowNet 1.0 리뷰에 이어 이번에는 FlowNet 2.0 을 리뷰하고자 합니다.
먼저 기존에 FlowNet 1.0의 경우, 속도적인 측면에서는 GPU를 사용하다보니, 기존 Hand-craft based optical flow method보다 빨랐습니다.하지만 성능은 예상했던 것보다 매우 좋지 않았습니다. FlowNet 1.0에 대해 궁금하신 분은 지난 주 리뷰를 참고하시면 좋을 것 같습니다.
그래서 이번 FlowNet 2.0은 어떻게하면 성능을 크게 개선시킬 수 있는지에 대해 아래와 같은 방법들을 제안합니다.
- 학습하는 방식(스케쥴링) 변경
- stacked architercture
- small displacement를 위한 새로운 데이터 셋
Dataset Schedules
기존에 FlowNet은 FlyingChairs Dataset(편의상 Chairs라고 하겠습니다.)이란 데이터 셋을 만들어서 학습하였습니다. 이 데이터 셋은 총 22k의 의자 image pairs가 존재합니다.
그리고 각각에 영상에 대해 랜덤한 affine 변환을 적용함으로써, 마치 물체(의자)가 움직이는 것처럼 표현을 한 것입니다.하지만 해당 데이터 셋은 affine 변환을 적용하였기 때문에, 오직 평면 운동(planar motion)만을 나타냅니다.
이러한 Chairs 데이터 셋과 달리, FlyingThings3D (편의상 Things3D) 데이터 셋은 3차원 모션과 조도 변화 등이 적용된 데이터 셋으로 기존 Chairs 데이터 셋 보다 더 현실적이고 사실적인 데이터 셋으로 보시면 될 것 같습니다.
논문에 저자는 이러한 두 데이터 셋을 이용해서 먼저 기존 FlowNet 1.0의 네트워크를 학습시켰습니다. 해당 결과는 아래와 같습니다.
테이블에 대한 분석을 살펴보자면, 먼저 S_{short}, S_{long}, S_{fine} 는 각각 학습 시에 사용한 iteration을 뜻합니다. short는 600k iteration, long은 1.2M iteration, fine은 lr을 더 작게 줄이면서 최대 1.7M iteration을 돌린 것을 의미합니다.
데이터 셋을 통한 결과를 살펴보면, Chairs Dataset으로 학습한 것이 Things3D 데이터 셋으로 학습한 것보다 더 좋은 성능을 내는 것을 확인할 수 있습니다.
분명 3D motion, lighting effect 등이 추가된 Things3D는 사실적인 데이터 셋이므로, 당연히 Chairs Dataset로 학습한 네트워크 보다 Things3D Dataset으로 학습한 것이 더 좋은 성능을 낼 것이라고 예상했지만 그렇지 않았던 것이죠.
논문에서는 위와 같은 결과에 대해 Things3D과 같은 어려운 학습 데이터 셋보다, 심플한 Chairs Dataset이 네트워크한테는 optical flow의 가장 근본적인 목표인 컬러 매칭을 학습하는데 더 도움이 되었다고 말합니다.
그 외에도 Things3D와 Chairs Dataset을 섞은 mixed dataset 역시 Chairs Dataset보다 성능이 낮은 것으로 나왔습니다.
그래서 최종적으로 논문에서는, 비교적 간단한 Chairs Dataset으로 먼저 학습을 시키고, 그 후에 심화된 장면이 많은 Things3D 데이터 셋으로 fine tuning을 진행하였고 해당 방식이 제일 우수한 결과를 나타내었습니다.
그리고 부가적인 얘기를 드리면, 기존 FlowNet 1.0에서는 FlowNetS와 FlowNetC 네트워크 총 2가지 모델 구조를 제안하였습니다.
이론적으로는 두 영상간에 correlation을 계산하는 layer가 추가된 FlowNetC가 FlowNetS보다 더 좋은 성능을 내야하는 것이 맞지만, 이상하게도 FlowNet 1.0논문의 저자는 그렇지 않다고 리포팅합니다.
FlowNetC와 FlowNetS의 성능이 일관되게 나오지 않고, 어느 테스트 셋에 대해서는 FlowNetC가 더 우세할 때도, 그렇지 않을 때도 있다고 한 것입니다.(보다 자세한 내용은 FlowNet1.0에서 확인하시면 됩니다.)
하지만 FlowNet2.0에서는 보시면 FlowNetC가 S보다 더 좋은 성능을 낸 것을 확인하실 수 있는데요, 논문의 저자는 FlotNet1.0 저자가 아무래도 실험세팅을 잘못 설정한 것으로 보인다고 말하였습니다. 제 생각에도 이전 저자가 잘못 실험한 것 같아요.
Stacking Networks
기존에 Hand-craft based method에서는 iteration refinement 방식을 통해서 보다 정확한 optical flow vector map를 구하였습니다.
논문의 저자는 그럼 Deep learning based optical flow method에서도 한번 이 iteration 방식을 적용해보자가 해당 챕터에 핵심입니다.
Iteration refinement의 컨셉은 전에도 설명드렸지만 간단합니다. 한번 구한 optical flow vector map을 이용해 영상을 warping 시키고, warping된 영상을 통해 optical flow를 또 구하여 warping 시키고, 이 과정을 계속 반복하여 정확한 optical flow를 근사할 수 있도록 하는 것입니다.
아래 테이블은 iteration refinement 성능표입니다.
먼저 Net1은 위에 Data Scheduled에서 설명드린대로 Charis Dataset으로 학습 후 Things3D dataset으로 fine tune 한 FlowNetS를 의미하며, Net2는 random initialized 한 FlowNetS입니다.
보시면 기존 FlowNet1.0처럼 단일 네트워크(Net1)일 때에 비해 두 네트워크를 합친 것(Net1 + Net2)이 Chairs test Dataset에서는 더 좋은 성능을 보이지만, Sintel Dataset에서는 더 낮은 성능을 보입니다.
이러한 결과가 나오게 된 이유로는 두 네트워크를 합침으로써 네트워크가 깊어지다보니, 학습되는 파라미터가 많아지고, 결국 train data의 overfitting이 되버린 것입니다. 이는 첫번째 네트워크를 freeze 시키나 안시키나 상관없이 기존 단일 네트워크에 비해 성능이 좋지 못하였습니다.
그래서 train data와 매우 유사한 Chairs test Dataset에서는 성능이 오른 반면, 새로운 DataSet인 Sintel에 대해서는 좋지 못한 성능을 보여주는 것입니다.
또한 두 번째는 기존 iteration refinement에서 했던 것처럼, warping을 추가하는 것입니다. 즉 image1과 image2를 인풋으로 하여 Net1을 통해 나온 optical flow vector 값으로 image2영상을 warping 시킨 image2’와 image1을 Net2의 인풋으로 하는 것이죠.
이러한 warping을 추가함으로써 네트워크를 기존 iteration refinement method처럼 작동하게 되어, 단일 네트워크를 사용했을 때 보다 더 좋은 성능을 나타나게 되었습니다.
Stacking Multiple Diverse Networks
멀티 네트워크가 단일 네트워크보다 더 좋은 성능을 내는 것을 확인하였으니, 이제는 어떤 방식으로 네트워크를 쌓으면 좋을지에 대해 알아봅시다.
방법은 간단합니다. 기존 FlowNet 1.0에서 제안된 FlowNetC와 FlowNetS를 어떠한 조합으로 몇개까지 쌓을 것이냐는 것이죠. 해당 논문에서는 최대 3개까지 붙여서 실험을 진행하였는데 그 결과는 아래와 같습니다.
표를 보면 아시다시피, 제일 최고의 성능을 보인 구조는 바로 제일 앞에 FlowNetC 1개와 그 뒤에 FlowNetS를 두 개 이어 붙인 것이었습니다.
아무래도 FlowNetC를 여러개 붙이면 모델의 크기가 너무 커지기 때문에 앞에 하나만 사용한 듯 보입니다. 참고로 대문자(C, S)와 달리 소문자(c, s)는 레이어의 채널 수를 줄여 네트워크를 경량화 한 것을 의미하며, 그래서 성능은 대문자에 비해 못하지만, 속도가 더 빠른 모습입니다.
Small Displacements
마지막으로 알아볼 것은 Small Displacement 입니다. 기존에 hand-craft based method들은 대부분 Large Displacement 상황에서 성능이 크게 떨어졌으며, 이를 해결하고자 다양한 방법론들을 제안했었습니다.
하지만 deep learning 기반인 FlowNet 1.0에 경우에는 오히려 Large Displacement는 잘 맞추지만, Small Displacement에서 정확한 예측을 하지 못하는 아이러니한 결과가 나왔습니다.
그래서 FlowNet 2.0에서는 이러한 문제를 해결하기 위해 크게 두 가지 방법을 생각했습니다. 하나는 Dataset을 조정한 것이고, 나머지 하나는 Small Displacement 전용 Layer를 추가하는 것이죠.
먼저 Dataset 부분은 간단합니다. 기존에 FlowNet같은 경우에는 평가 데이터 셋으로 Sintel을 사용하였는데, 이러한 Sintel에서의 성능을 높이기 위해, Chairs Dataset의 경향성(displacement historgram)을 Sintel과 유사하게 제작했었습니다.
하지만 Sintel Dataset은 주로 역동적이고, 빠른 액션을 다루는 장면들이 많습니다. 그래서인지, 기존 Chairs Dataset으로 학습하게 되면 Small Displacement에 대한 성능이 좋지 못하였기에, 해당 논문에서는 상대적으로 적은 움직임을 보이는 UCF101 Dataset을 사용하였습니다.
정확히는 UCF101과 유사한 displacement histogram을 가지게끔 Chairs Dataset을 바꾸었으며, 이렇게 새로 만들어진 Chairs Dataset을 논문에서는 ChairsSDHom이라고 합니다.
Small Displacement Network and Fusion
두 번째는 새로운 Network를 추가하는 것입니다. 위에 Network stack에서 설명드렸던 FlowNet2-CSS를 Things3D와 ChairsSDHom으로 학습 시켰더니 Small Displacement에 대한 에러가 크게 줄었습니다.
FlowNet1.0에서는 noise가 많이 존재하는 반면, FlowNet2는 smooth한 모습.
하지만 아직도 subpixel motion에서는 predict 값이 깔끔 선명하게 나오지 않고, 위의 좌측 그림과 같이 잡음같은 것들이 많이 존재하습니다. 그래서 해당 논문에서는 기존 FlowNet의 구조 자체가 Small Displacement에는 적합하지 않다고 판단하였고, 이를 해결하고자 새로운 네트워크를 추가하였습니다.
새롭게 추가된 네트워크는 크게 달라진 것은 없고, 기존 FlowNet의 구조를 조금 수정한 것입니다. 기존 FlowNetS는 첫번째 레이어에서 커널 사이즈가 3×3에 stride가 2였는데, 이러한 stride를 줄이고, kernel 사이즈를 7×7, 5×5로 늘렸다고 합니다.
또한 upconvolution 레이어 사이에 컨볼루션 레이어를 추가함으로써 자잘한 노이즈들을 생기는 것을 방지하였습니다.
위와같은 과정들을 통해 최종적으로 FlowNet2의 구조는 다음과 같습니다.
Experiments
위에는 정량적인 결과표를 나타낸 것이며, FlowNet2의 성능이 FlowNet1은 물론, hand-craft 기반 방법론들과도 견주었을 때 좋은 성능을 나타내었으며, 또한 GPU를 사용하는 것 답게 속도측면에서는 압도적인 모습을 보여주었습니다.
위 사진은 정성적인 결과로 FlowNet2의 결과가 상당히 smooth하고 GT와 유사한 것을 확인하실 수 있습니다.
Optical flow에 대해서 좀 조사를 해봤는데, OpenCV에서도 optical flow에 관련된 Lucas-Kanade method 같은 다양한 라이브러리를 지원하네요. Lucas-Kanade method도 feature가 sparse한 경우와 dense한 경우 나누어서 지원하네요. 여기서 궁금증이 feature가 sparse하단 것이 feature가 거의 없다로 받아들이면 될까요? sparse하고 dense한 경우를 나누어서 지원하는 이유가 궁금합니다. 연산속도 때문일까요?
그리고, BroxOpticalFlow, FarnebackOpticalFlow, DualTVL1OpticalFlow.같은 gpu 기반의 optical flow도 라이브러리로 있는거 같은데 이들과 Optical flow 2.0랑 비교하면 많이 떨어질까요? optical flow가 주된 관심사가 아닐경우 라이브러리로 가져다안쓰고 구현해서 쓰는 것의 이점을 생각해보려고 드린 질문입니다.
음 질문해주신 내용들이 FlowNet과는 연관성이 크게 없어 자세한 답변을 드리기가 힘들지만 제가 아는 선에서 답변드리겠습니다.
먼저 루카스 카나디 기법은 가장 기본적으로 강제로 섹션을 나누어 under determined를 풀어나가는 sparse방법과 variation 제약을 추가하여 방정식을 풀어나가는 dense방식이 존재합니다.
저도 opencv함수를 통해 직접 해보지는 못하였지만 sparse방법은 강제로 섹션을 나누어 optical flow vector를 구할 듯 싶으며 dense방식은 각 픽셀별 optical flow를 구할 것 같습니다.
즉 댄스한 방식이 훨씬 정확도가 높으며 sparse한 방식은 속도가 더 빠른 대신에 정확도는 상대적으로 떨어질 듯 합니다.
두번째 질문으로는 opencv에서 제공하는 다양한 optical flow 라이브러리에 대해 물어보셨는데 해당 함수들의 이름을 처음 들어봤기에 작동 과정에 대해서는 저도 자세히 알지는 못합니다.
하지만 라이브러리로 제공하고 있는 만큼 제 생각엔 해당 함수들은 모두 hand-craft 기반 방식들로 예상되며 이를 flownet2와 비교한다면 당연히 성능 및 속도 면에서 flownet2가 더 우세하다고 생각됩니다.