본문 바로가기
소소한 일상

[Insight] 3D 생성을 위한 개념 학습 과정과 도출점

by MFDO 2024. 11. 21.

 

 

 

 

많은 개념을 보고 학습해왔는데

어떤 과정으로 사고를 하며 발전시켜왔는지

정리가 필요한 순간이 왔다고 느껴졌다.

 

이번 내용은 현재까지의 나의 고초들을 요약하려고 한다.

 

 


 

어떻게 공부하지

 

목적 : 한 장의 사진으로 해당 인물의 정교한 3D 모델 생성을 해낼것

나는 이 목적을 제안받아 연구하고 개발해나가야했다.

가장 먼저 한 것은 정말 단순하게 인터넷 창에 3D Object Generate라고 검색했다.

최최신의 연구결과로 바로 돌입하기엔 내 배경 지식이 전무했다.

 

가장 많이 보였던 키워드인 NeRF에 대해 공부해보고자 했다.

이것도 단순히 구글 scholar, arxiv에 NeRF넣고 비교적 직관적인 논문을 읽거나

유명 논문의 경우 멋쟁이 블로거 선생님들이 번역이나 자신만의 해석을 적어두셨기에 참고하며 함께 읽었다.

 


NeRF??

이 친구를 개념을 뭉개어 간단하게 일컫는다면

픽셀 단위로 방사 필드를 학습하는 방식으로 공간 내의 밀도를 추정해내는 것이다.

단일/다중 뷰에 대한 시점 제한 문제를 극복해내었다는 점에서 굉장한 이점을 지니며 각광받게 되었다.

하지만 CNN, MLP 기반으로 개발되었기에 고해상도의 결과물 도출을 위해서는

너무나도 큰 메모리를 잡아먹게 되는것이 단점이다.

시중에 나온 모델의 해상도가 255*255인 정도로 아쉬운 해상도를 지녔다.

=> 이러한 단점에서 내 맘 속에서는 탈락했지만 다른 의문으로 이어져 공부를 지속했다.

 


3D Object의 Loss 추정법??

사실 기존에 인공지능 개발을 했다고만 할 뿐 가장 기본적인 Loss를 이용했을 뿐이다.

이전에 시간을 주지 않아 공부를 소홀히 했던 역전파 과정이 여기서는 꽤나 작지 않은 문제로 다가왔다.

 

역전파도 간단히 짚고 넘어가면,

역전파는 손실 함수의 변화율(기울기)을 계산해, 가중치와 편향이 손실 함수에 미치는 영향을 파악한 뒤 이를 기반으로 학습 파라미터(가중치, 편향)를 업데이트한다. 이 과정에서 손실 함수의 변화율을 계산하기 위해 미분이 사용된다.

학습 과정에서 중요한 점은 손실 함수의 기울기를 이용해 가중치와 편향을 얼마나 조정할지를 결정하는 건데, 이 조정 과정이 최적화 알고리즘(경사하강법, Adom, RMSProp 등등~)으로 진행된다.

 

사실 저기서 중요한건 미분이 사용된다는 점이다.

 


3D Object 미분하기????

 

수학을 즐기지 않던 나로는 이렇게나 막막할 수가 없다.

우선 미분 가능의 조건을 잘 파악하고 있다면 좋을 것이다.

간단하게 하자면 미분이 가능하기 위해서는 모든 값들이 연속적이어야한다. f(x) = 1/x 이런 예가 직관적일 것이다

또한 모든 곳에서 미분 계수가 존재해야한다. 즉, 특정 순간에 방향이 모두 존재해야한다. f(x) = |x|가 대표적 예다.

 

3D Object들을 미분 가능하도록 만들기 위해 이미 많은 똑똑한 분들이 시간과 열정을 쏟아주셨다.

면대 면이 결합해서, 각진 모양이라, 텍스쳐 입힐 때 계단 함수를 써서, 조명이 관여해서 등 미분 불가할 이유로만 가득한 친구들에게 미분을 가능하게 하는 대안은 많이 제시되었다.

 

1) 근사 함수 이용하기

아주 직관적으로는 < 이렇게 꺾여 존재하는 친구들을 근사함수를 통해 ( 부드럽게 이어주는 것이다.

대표적인 예로는 Smooth Appoxination, Softmax, Interpolation 등을 이용할 수 있다.

나는 연구원이지만 상업적 개발을 위한 연구원으로서 빠른 개발 추구를 위해 2)의 방식으로 가게 되었다.

 

2) 미분 가능한 렌더러

번역 그 자체로 모델 자체를 미분 가능한 렌더러로 3D 오브젝트를 생성하는 것이다.

대표적인 예로 nvdiffrast, pytorch3d 등이 있는데 KETI의 조언으로는 nvdiffrast가 2k까지의 랜더링을 지원하기에 추천한다고 하여 해당 렌더러를 이용하고자 하였다.

 


 

얼굴 방해 요소 제거

 

사진을 찍었을 때 얼굴에 반사된 빛이나 조명값, 안경과 머리카락은 모델 생성에 많은 방해가 된다.

이전 해당 개발을 진행한 선임님은 얼굴의 평균 색상을 기반으로 몸색상을 변경해주는 방향으로 얼굴과 몸의 부조화를 맞추셨다고 하셨다.

읽어본 논문에서는 랜드마크 색상 영역이나 피부 색상 영역의 분산값이 클수록 학습 패널티를 크게 먹여 학습에서의 영향도를 낮추었다고 한다.


Gaussian Splat

NeRF와 같은 방식은 CNN 방식을 이용한다. 그렇기에 화질을 높이기 위해서는 즉, 더 높은 차원이 요구될 경우 기하급수적인 연산 증가로 고해상도 연출에 한계를 가진 단점이 있다. 이런 단점에 대한 대안으로 속도를 개선한 NeRF 친구들이 많이 생겼으나, 다른 추론 기법으로는 Gaussian Splat이 대두되었다. Gaussian이라는 이름에 맞게 랜덤하게 값을 흩뿌려주어 더욱 부드러우면서 세밀한 연산을 할 수 있도록 해준다. NeRF는 광선을 쏘아 객체를 생성하게 되는데 이 과정의 병렬처리가 까다로우며, 신경망 호출로 많은 연산이 포함될 수 밖에 없다. Gaussian splat은 투영 과정이나 합성과정이 별도로 진행되고 필요 영역에만 gaussian을 생성하게 된다. 또한 분리 가능한 연산으로 병렬처리에도 효율적이기에 NeRF에 비해 더 적은 하드웨어 자원 소모로 더 높은 해상도와 적은 시간으로 객체를 생성할 수 있다.

 


 

SDF

Gaussian 생성이 필요 영역에 대해서만 생성될 수 있는 이유이자 표면생성을 위한 기술이다. SDF를 통해 해당 값이 객체 내부, 객체 표면, 외부 임을 판단할 수 있으며, 표면을 기준으로 거리값으로 표현된다. 


 

DMTet

이렇게 도출해낸 SDF값은 미분 불가한 형태이며, 최종적인 오브젝트화를 위해서는 메쉬로 변환하는 작업이 필요하다.

DMTet은 가볍게 나의 목적 용도로 말하면, 이런 SDF값을 메쉬로 변환해주는 역할을 한다.

기존 Marching cube 방식에서는 물체를 육면체로 표현하게 되는데, 이 요소가 적다면 당연하게도 굉장히 부자연 스러움을 겪을 수 있다. DMTet에서는 물체를 사면체를 이용한 표현으로 대상을 더욱 세밀하게 표현할 수 있게 된다.

 

 

그렇기에 현재 전체 파이프라인으로는 물체에 대한 학습 시 Gaussian splat을 이용해 더욱 세밀한 묘사를 하구 SDF를 이용한 표면 도출, DMTet으로 메쉬화를 해낸다. 그 이후 표정 계수에 대해서는 MLP를 이용해 학습을 하여 모델의 자세와 표정을 묘사한다.

이렇게 하나의 모델이 만들어지고 표정을 생성해낼 수 있다.

 

간략화하여 많은 내용이 생략되었지만 이 상호작용을 엮어내는 건 나에게는 그렇게 쉽지는 않은 과정이었다.

댓글