sghong977 / Daily_AIML

Computer Vision, Deep Learning, 그외 MLOps 찍먹 등. 매일 새롭게 배운 것을 정리합니다.
0 stars 0 forks source link

[2023.01.16] NeuMan Rendering 코드 뜯기 #23

Open sghong977 opened 1 year ago

sghong977 commented 1 year ago

일단 학습 돌려놓고 그동안 코드부터 미리 봐놓자... 이전 git issue가 너무 길어져서 분리함

Render 보는데 뭔가 이상하다

상황

scene만 렌더링 하는거야 걍 vanilla trainer에서 긁으면 되기야 한다만... pretrained 사람을 얹고싶어서. 암튼 NeuManReader class 이해해야겠엄

-

scene = neuman_helper.NeuManReader.read_scene(...) scene_dir = data/sample로 넣음

sghong977 commented 1 year ago

모델이 어떻게 생겨먹은거지. 여기서 발생하는 의문 리스트를 만들테니 답을 하자

checkpoint.pth.tar 읽기

keys: ['epoch', 'iteration', 'optim_state_dict', 'hybrid_model_state_dict']
여기서 human 돌리기 전에는 hybrid 대신에 'coarse_model_state_dict' 이렇게 되어있음.

epoch, iteration: 0, 1000으로 들어간거 봐서 방금 humanNeRF 학습 시작했다고 초기화 된걸까... optim_state_dict: ['state', 'param_groups'] hybrid_model_state_dict

아무튼 (인퍼런스용) 모델이 coarse_bkg, fine_bkg, coarse_human 이렇게 셋으로 나뉘는 듯.

의식의 흐름으로 코드 보기

렌더링 하는 부분 -> 학습하는 부분 -> 각 모델 이러면서 봄... scene, human NeRF 모델 구조를 대략 알았음! smpl model은 귀찮아서 일단 패스.. CheckList

utils -> render_utils 보면, render_hybrid_nerf: reposing에서 이거 쓰게 되어있음 net, cap, posed_verts, faces, Ts, rays_per_batch=32768, samples_per_ray=64, importance_samples_per_ray=128, white_bkg=True, geo_threshold=DEFAULT_GEO_THRESH, return_depth=False):

render_vanilla: 배경만 렌더링하는것 (scene nerf 학습의 validation때 이거씀) coarse_net, cap, fine_net=None, rays_per_batch=32768, samples_per_ray=64, importance_samples_per_ray=128, white_bkg=True, near_far_source='bkg', return_depth=False, ablate_nerft=False): 렌더링 할때는 out = coarse_net(_pts, _dirs) 이렇게 하고. vanilla_nerf_trainer.py에서 학습하고 렌더링할때 쓰는게 그냥 coarse_net인데, train.py에서 bkg 옵션을 주면 scene nerf만 학습되는 train_background() 실행되는데, 이때 coarse_net, fine_net = vanilla.build_nerf(opt) 이렇게 만들어짐. opt에 뭐 별다를게 없다면 coarse, fine을 둘다 만드는 것 같긴 한데. 둘이 파라미터가 다른가? 뭐지 왜 모델 하나인줄 알았지... 저장할때도 보면 fine이 None이 아니면 coarse_model_state_dict만 저장함. 그러면 vanilla의 build_nerf를 보면? (models/vanilla.py) 그냥 NeRF 클래스 사용. positional encoding, viewing direction도 encoding해서 넣는거. (이건 중간부터 들어가겠지) 기본적인 NeRF로 구성됨. 그럼 HumanNeRF는 어떻게 정의되어있을까?

render_smpl_nerf net, cap, posed_verts, faces, Ts, rays_per_batch=32768, samples_per_ray=64, white_bkg=True, render_can=False, geo_threshold=DEFAULT_GEO_THRESH, return_depth=False, return_mask=False, interval_comp=1.0):

render_hybrid_nerf_multi_persons: telegathering에 쓴다. bkg_model, cap, human_models, posed_verts, faces, Ts, rays_per_batch=32768, samples_per_ray=64, importance_samples_per_ray=128, white_bkg=True, geo_threshold=DEFAULT_GEO_THRESH, return_depth=False): 근데 bkg_net이든, 각각의 actor든간에 전부 똑같이 human_nerf.HumanNeRF(opt)로 불러오는데 머임? weight만 다른데서 불러오는데, 전부 각 pth파일의 'hybrid_model_state_dict'을 읽어오게 되어있음.

그럼 human_nerf.HumanNeRF()를 봐야겠네.

sghong977 commented 1 year ago

Q. neuman_helper.NeuManReader.read_scene() 뭐하는거임?

결론: 암튼 weights path 무관하게 걍 전처리 데이터들 싹 불러온다 생각하면 되겠구나

1. read_captures() 얘가 리턴하는 것

2. update_near_far()로 값 업데이트 update_near_far(scene, keys, range_scale)를 저 함수 내부에서 정의함. 그리고 keys에 bkg, human 둘중 하나 넣음. 사람과 배경 scale 범위가 다른가벼.

잘 몰겠는데 암튼 이런거 스케일 조정 + 전처리 다 읽어다가 'scene' 변수 하나에 묶여서 리턴함. 이 안에 neutral인 Da-pose와 (smplx/smpl_uv.obj 읽은 것) 포즈도 읽어옴. smpls, world_verts, static_verts, Ts = cls.read_smpls(scene_dir, scene.captures, scale=scale, smpl_type=smpl_type) 요렇게 읽어와서 scene_dir에 있는 pose 읽어오는거임. smploutput{romp, refined}.pkl 둘중 하나 불러와서 프레임별 파라미터 읽는 듯? 의문: scene_dir말고, checkpoint에 있는건? humanNeRF를 학습했으면 최종 alignment 된 포즈 생기지 않나?

sghong977 commented 1 year ago

어쨌거나 오늘은 코드를 보고

sghong977 commented 1 year ago

ray 쏘는 부분, scene human nerf 학습시 실제 업데이트 하는 값, loss 확인 관련. near, far 나눠가지고 뭐 ray 쏘던데... 음... 그렇군요.. 모르겠군. 대충만 볼게요

학습시 모델 output도 궁금해. 이건 걍 NeRF forward 보면 알것다만 -> [rgb, alpha] 나옴 ㅇㅇ.

학습 loss 계산? 정말로 scene, human NeRF가 독립적일까?

따로 학습한다고는 하지만 상당히 미심쩍음 뭔가 맞물려있을것 같은 기분임.

우선, 데이터는 아예 분리되어있음.

Scene NeRF 학습?

사람 NeRF?

human_nerf_trainer.py -> train_batch() -> lossfunc() 구경 ㄱㄱ , fine_bkg_dirs, fine_bkg_z_vals, fine_bkg_out = self._eval_bkgsamples(batch, device) , human_dirs, human_z_vals, can_pts, can_dirs, human_out = self._eval_human_samples(batch, device) 이렇게 샘플을 가져오네. bkg 쓰잖아... ㅡㅡ

암튼 중간에 _eval_bkg_samples() 얘가 문제다.

sghong977 commented 1 year ago

자꾸 나오는 raw2outputs

걍 논문에서 보이는 뻔한 수식임. 근데 궁금한거: num_rays 개수만큼 나오던데. 이미지로 보이려면 얘네 위치는 어디로 지정되는거임?

image

-> 렌더링 유틸들 보니까 raw2outputs 계산해서 얻은 rgb map을 cap.shape()에 맞게 reshape해주는구나. cap이 뭐지? caps = read_novel_caps(opt, len(raw_verts), scene)

음............... 이해가 안가.... ray들이 있는건 알겠어 근데 그걸 이미지 픽셀좌표계에 어떻게 뿌려서 rgb 이미지로 만드는지 몰겠음........ 이걸 어떻게 구현했는지 몰겠음....... ray -> 2D 픽셀좌표 계산?????

sghong977 commented 1 year ago

위에 ray 관련해서는 화요일 미팅때 코드레벨로 설명을 엄청 잘해주셔서 이해했어! 맘편히 원래 하려던걸 보자 ㄱㄱ

sghong977 commented 1 year ago

Tensorboard Output들은 뭐지?

validation_data[‘render’] 이 안에 뭐가 들어있나요? Vanilla nerf를 보자.

render_utils.render_vanilla()

raw2outputs()를 봐야겠구나 암튼 니가 depthmap이랑 Rgb map 구하는건 알겠는데, 어떻게 얻냐고. Depth? Density가 커지는 최초의 위치인가? 그걸 결정하는 threshold가 따로 있는거야? 코드 볼게요

Q. 그런데 scene validation 결과를 tensorboard visualization으로 띄우는거 보면 coarse, fine 각각으로 나뉘잖아. 결과물도 좀 다른데? 그럼 Coarse fine 둘이 파라미터가 달라? 같이 학습하는건가? 뭔가 논문 볼때는 그렇게 회자되지 않았던것 같은데??

지금 대략 보기로는, 만약에 fineNet이 없다면 굳이 돌리지는 않는 것 같아. 다만 fine에서의 다른점은,

그리고 vanilla train의 validate()에서 render_utils.render_vanilla()를 두번 돌리는건 맞음. 근데 fineNet이 없으면 fine은 None으로 넣고, coarseNet똑같이 들어가고, 다른 파라미터는 중간에 변하지 않았기땜에 그냥 같은거 두번 돌리는 것 같은데...? 미묘하네

확인 결과? -> Appendix에 있어!

sghong977 commented 1 year ago

Tensorboard Output: HumanNeRF

결론: 4개는 순서대로 rgb_map, depth_map, acc_map, overlay이다.

각각 어디서 얻나요?

overlay_smpl()?

전처리에서 ROMP, refinement 거쳤지만 학습중에서 SMPL 파라미터는 업데이트됨. 그걸 visualization 하기 위한 함수.

render_smpl_nerf()?

앞에서랑 비슷하겠지만 궁금한게 몇가지 있음