Trikang
[Python] 3D Gaussian splatting 여러 데이터 셋에 대해 일괄 학습-평가 진행하기 본문
gaussian splatting의 코드를 모두 들고와서, 코드를 돌릴 준비가 끝났다고 가정함. gaussian-splatting 디렉토리에 위치시킨 후 아래 코드 실행
- 본인은 nerf_synthetic, LLFF, Tanks and Temples 데이터 셋에 대해서 진행함
- 아래 두 스크립트를 각각의 .py 파일로 만들어서 gaussian-splatting 디렉토리에서 실행하면 문제 없이 동작함을 확인함
여러 데이터 셋에 대해 COLMAP 처리하기
import subprocess
import time
import os
datasets = ['nerf_synthetic_hotdog', 'nerf_synthetic_drums', 'nerf_llff_fern', 'nerf_llff_flower',
'tanks_and_temples_Train', 'nerf_synthetic_ship', 'nerf_synthetic_ficus',
'tanks_and_temples_Playground', 'nerf_llff_leaves',
'nerf_llff_horns', 'nerf_llff_fortress', 'nerf_llff_orchids', 'nerf_llff_room',
'tanks_and_temples_M60', 'tanks_and_temples_Truck', 'nerf_synthetic_lego',
'nerf_synthetic_mic'] # 여러 데이터셋의 이름
for dataset_name in datasets:
subprocess.run(["python", "convert.py", "-s", f"data/{dataset_name}"])
COLMAP이 처리된 데이터 셋들에 대해 학습 및 평가 진행
아래와 같이 두 가지 함수를 작성함
- gs_process_with_fileio_realtime: 실시간으로 프로세스의 결과를 파일에 저장. 이로 인한 오버헤드가 너무 클 것이 우려됨. 처음에 내가 짠 코드가 잘 작동하는지 확인하기 위해 주로 해당 함수를 사용함
- gs_process_with_fileio_nrt: 파일 입출력에 대한 오버헤드를 줄이기 위해 subprocess 통신이 끝났을 때만 파일에 기록함
기본적으로 gs_process_with_fileio_nrt 함수로 동작하도록 구현함. 각 모델의 평과 결과(SSIM, PSNR, L)는 output/{데이터 셋 이름}/metrics_{데이터 셋 이름}_{실행시각}.txt 파일에 저장됨.
import subprocess
import time
import os
datasets = ['nerf_llff_fern', 'nerf_llff_flower', 'nerf_synthetic_hotdog', 'nerf_synthetic_drums',
'tanks_and_temples_Train', 'nerf_synthetic_ship', 'nerf_synthetic_ficus',
'tanks_and_temples_Playground', 'nerf_llff_leaves',
'nerf_llff_horns', 'nerf_llff_fortress', 'nerf_llff_orchids', 'nerf_llff_room',
'tanks_and_temples_M60', 'tanks_and_temples_Truck', 'nerf_synthetic_lego',
'nerf_synthetic_mic'] # 여러 데이터셋의 이름
# 실시간으로 파일 입출력을 기록할 수 있지만 오버헤드가 많이 발생할 것으로 예상됨
def gs_process_with_fileio_realtime():
for dataset_name in datasets:
print(f'target dataset: {dataset_name}')
# 디렉토리 생성
output_directory = f"output/{dataset_name}"
os.makedirs(output_directory, exist_ok=True)
# train.py 실행
print('train.py')
train_start_time = time.time()
with open(f"{output_directory}/train_{dataset_name}_{int(train_start_time)}.txt", "w") as f:
train_process = subprocess.Popen(["python", "train.py", "-s", f"data/{dataset_name}", "-m", f"output/{dataset_name}", "--eval"], stdout=f, stderr=f)
train_process.wait() # 프로세스 종료를 기다림
train_end_time = time.time()
with open(f"{output_directory}/train_{dataset_name}_{int(train_end_time)}.txt", "a") as f:
f.write(f"Training completed in {train_end_time - train_start_time} seconds.")
# render.py 실행
print('render.py')
render_start_time = time.time()
with open(f"{output_directory}/render_{dataset_name}_{int(render_start_time)}.txt", "w") as f:
render_process = subprocess.Popen(["python", "render.py", "-m", f"output/{dataset_name}"], stdout=f, stderr=f)
render_process.wait() # 프로세스 종료를 기다림
render_end_time = time.time()
with open(f"{output_directory}/render_{dataset_name}_{int(render_end_time)}.txt", "a") as f:
f.write(f"Rendering completed in {render_end_time - render_start_time} seconds.")
# metrics.py 실행
print('metrics.py')
metrics_start_time = time.time()
with open(f"{output_directory}/metrics_{dataset_name}_{int(metrics_start_time)}.txt", "w") as f:
metrics_process = subprocess.Popen(["python", "metrics.py", "-m", f"output/{dataset_name}"], stdout=f, stderr=f)
metrics_process.wait() # 프로세스 종료를 기다림
metrics_end_time = time.time()
with open(f"{output_directory}/metrics_{dataset_name}_{int(metrics_end_time)}.txt", "a") as f:
f.write(f"Metrics calculation completed in {metrics_end_time - metrics_start_time} seconds.")
# 파일 입출력에 대한 오버헤드를 줄인 코드
def gs_process_with_fileio_nrt():
for dataset_name in datasets:
print(f'target dataset: {dataset_name}')
# 디렉토리 생성
output_directory = f"output/{dataset_name}"
os.makedirs(output_directory, exist_ok=True)
# train.py 실행
print('train.py')
train_start_time = time.time()
train_process = subprocess.Popen(["python", "train.py", "-s", f"data/{dataset_name}", "-m", f"output/{dataset_name}", "--eval"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
train_output, train_error = train_process.communicate()
train_end_time = time.time()
with open(f"{output_directory}/train_{dataset_name}_{int(train_end_time)}.txt", "w") as f:
f.write(train_output.decode())
f.write(train_error.decode())
f.write(f"Training completed in {train_end_time - train_start_time} seconds.")
# render.py 실행
print('render.py')
render_start_time = time.time()
render_process = subprocess.Popen(["python", "render.py", "-m", f"output/{dataset_name}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
render_output, render_error = render_process.communicate()
render_end_time = time.time()
with open(f"{output_directory}/render_{dataset_name}_{int(render_end_time)}.txt", "w") as f:
f.write(render_output.decode())
f.write(render_error.decode())
f.write(f"Rendering completed in {render_end_time - render_start_time} seconds.")
# metrics.py 실행
print('metrics.py')
metrics_start_time = time.time()
metrics_process = subprocess.Popen(["python", "metrics.py", "-m", f"output/{dataset_name}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
metrics_output, metrics_error = metrics_process.communicate()
metrics_end_time = time.time()
with open(f"{output_directory}/metrics_{dataset_name}_{int(metrics_end_time)}.txt", "w") as f:
f.write(metrics_output.decode())
f.write(metrics_error.decode())
f.write(f"Metrics calculation completed in {metrics_end_time - metrics_start_time} seconds.")
if __name__ == "__main__":
gs_process_with_fileio_nrt()
'공부 > ML' 카테고리의 다른 글
Tri-MipRF 코드 빌드 (1) | 2024.03.05 |
---|---|
Gaussian Shader 모델 코드 빌드 (0) | 2024.03.03 |
[리눅스] nerfstudio docker 이용해서 실행하기 (0) | 2024.03.02 |
tetra-nerf 코드 빌드 환경 설정(cmake, OptiX, CGAL 5.5.2) (0) | 2024.03.02 |
[리눅스] nerfstudio에서 여러 데이터 셋 한 번에 COMLAP 처리하기(python 코드 작성) (0) | 2024.03.02 |
Comments