Metric#
다섯 모델이 같은 지표를 쓴다. 이 페이지는 그 지표가 각각 무엇을 말해 주는지, 어느 공간에서 계산하는지,
어떤 상황에서 믿을 만한지를 정리한다. 코드는 utils/metric.py 의 compute_submetric 과
models/base_model.py 의 검증·평가 루프에 있다.
먼저 큰 그림부터. 이 프로젝트에서 지표는 두 종류로 나뉜다.
- 절대 지표(
mae,mse,rmse) — 오차를 물리 단위 그대로 말해 준다. "평균 몇 m/s 틀렸다" 처럼 읽을 수 있어서 보통 이쪽이 1차 기준이다. - 상대 지표(
wmape%,rel_l2%,r2) — 정답 크기로 나눈 값이다. 스케일이 다른 필드끼리 비교할 수 있는 대신, 정답이 0 근처에 몰린 필드에서는 분모가 작아져서 값이 쉽게 커진다.
이 프로젝트의 필드는 대체로 0 근처가 넓다. 그래서 mae 와 눈으로 보는 품질은 대체로 같이 가지만,
rel_l2% 는 평가 이미지에 문제가 없어 보여도 수십 % 가 나오곤 한다. 어떤 필드에서 어떤 지표를 봐야 하는지는
해석 기준 에 정리했다.
표기#
아래 식에서 쓰는 기호다. 한 샘플의 fluid 격자점(mesh 모델이면 vertex) 집합이 이고 다. 점 에서
- 는 정답, 는 예측,
- 는 채널축 L2 노름 — velocity 는 , 스칼라 필드는 절댓값
- 는 fluid 영역 공간평균
mesh 모델은 vertex 마다 질량 를 달아 가중 평균한다. 아래 식에서 를 로 바꿔 읽으면 된다.
지표 정의#
| 지표 | 정의 | 종류 |
|---|---|---|
mae |
절대 | |
mse |
절대 | |
rmse |
절대 | |
wmape% |
상대 | |
rel_l2% |
상대 | |
r2 |
상대 |
읽는 요령이 몇 개 있다. rmse 는 격자점 수로 나눈 진짜 RMS 다. rel_l2% 는 풀어 보면
이므로, 정답의 RMS 가 작을수록 커진다. r2 의 분모는 정답의 공간 분산이라서
정답 자체가 거의 균일한 필드에서는 값이 쉽게 나빠진다.
설정 파일의 기본값은 다섯 모델이 같다.
metric_names: ['mae', 'mse'] # 검증·조기종료
test_metric_names: ['mae', 'mse', 'rmse', 'wmape%', 'rel_l2%', 'r2'] # 테스트
생성 모델(AE·EDM)은 test_metric_names 에 fid 계열이 추가된다.
계산 단위#
| 모델 | metric 을 계산하는 공간 |
|---|---|
| aicfd-grid-building-physical, aicfd-grid-indoor-physical | 물리 단위 (nondim_to_physical 이후) |
| aicfd-mesh-nasal-physical | WSS 물리 단위 (nondim_to_physical 이후) |
| aicfd-grid-building-rgb, aicfd-grid-nasal-rgb | [0,255] 화소값 (to_img 로 [-1,1] 에서 환산) |
물리량을 다루는 3종은 모든 지표를 물리 단위에서 한 번에 계산한다. 상대 지표를 nondim 공간에서
따로 구할 필요는 없다. 샘플 단위로 계산하면 샘플마다 붙는 스칼라 계수가 분자와 분모에서 상쇄돼서
두 공간의 값이 같아지기 때문이다.
nondim 공간 지표를 쓰는 곳은 조기 종료 하나뿐이다. 서로 다른 fold 와 epoch 를 견줘야 하는
판정이라, 풍속으로 정규화된 값이어야 비교가 성립한다.
샘플 단위와 집계#
지표는 샘플 하나씩 계산한 뒤 샘플끼리 평균낸다. 여기서 샘플이 무엇인지는 경로마다 물리적으로 정해져 있다.
| 경로 | 샘플 1개 |
|---|---|
| 2D | 이미지 1장 |
| 3D 학습·검증 | 깊이 윈도우 1개 |
| 3D 테스트 | 케이스 전체 ((1,c,d,h,w) 로 접어서 전달) |
| mesh | mesh 1개 |
배치 안에서 샘플별 지표를 평균한 다음, 배치를 합칠 때 샘플 수로 가중해서 다시 평균한다.
따라서 배치 크기를 바꿔도 값이 변하지 않는다.
비율 지표는 샘플 단위를 고정해야 정의가 성립한다
wmape%·rel_l2%·r2 는 비율로 정의된 지표라, 샘플마다 구한 값을 평균한 것과 여러 샘플을 합쳐 한 번에 계산한 것이 서로 다르다.
배치 전체를 한 덩어리로 모아 계산하면 배치 크기를 바꿀 때마다 값이 조금씩 달라진다.
그래서 compute_submetric 은 마스크 인자를 받지 않고 샘플 하나만 받는다. 샘플마다 잘라서 호출하는 것은 호출자가 맡는다.
fluid 영역 한정#
grid 모델은 batch_dict['input']['mask'][:, :1] 의 도메인 채널로 fluid 격자점만 골라 계산한다.
dom_flag = dom_mask[i, 0].bool() # (h,w) 또는 (d,h,w)
pred = preds_tuple[j][i][:, dom_flag] # (c,n)
샘플 하나 안에서는 마스크가 전 채널 공통이라, 마지막 차원 불리언 인덱싱 한 번이면 끝난다. 3D 경로는 입력 dict 를 지우기 전에 케이스별 마스크를 미리 확보해 두고, latent 계열은 인코딩하기 전에 화소 해상도 마스크를 따로 챙겨 둔다.
mesh 모델은 모든 vertex 가 fluid 라 고를 것이 없다. 대신 vertex 질량으로 면적가중한다 — . 이렇게 해야 vertex 가 촘촘한 쪽으로 지표가 쏠리지 않는다.
fluid 한정이 걸리지 않는 경로도 있다. contour AE 는 Collator 가 마스크를 넘기지 않고, 도메인 AE 는 복원 대상이 마스크 자체라서 캔버스 전체로 계산한다. building 2종의 확산 계열 평가도 마찬가지로 캔버스 전체다.
해석 기준#
어떤 지표를 믿을지는 필드 이름이 아니라 값이 어떻게 분포하는지에 따라 정해진다. 크게 두 부류로 나뉜다.
값이 대부분 0 근처인 필드#
velocity, velocity-magnitude, k, WSS 가 여기 속한다. 값이 음수로 내려가지 않고, 정지 영역은 0 근처에 깔려 있고, 전단이나 제트가 있는 곳에만 값이 몰려 있다.
- 먼저 볼 것은
mae(물리 단위) 와r2다. rel_l2%는 분모가 되는 신호 RMS 가 작아서 원래 큰 값이 나온다. 다른 논문과 숫자를 맞춰 볼 때나 쓰지, 품질을 판단하는 데는 쓰지 않는다.r2는 제트 같은 구조가 분산을 만들어 주기 때문에 여기서는 믿을 만하다.
0 을 기준으로 부호가 갈리는 필드#
temperature(기준온도와의 차), gauge pressure 가 여기 속한다. 대부분의 값이 0 근처에 모여 있고 몇 군데에서만 값이 크게 벗어난다.
- 여기서 믿을 것은
mae하나 다. r2는 정답 분산이 작아서 값이 쉽게 나빠진다. 음수가 나와도 계산이 잘못된 것은 아니므로 참고만 한다.- 상대 지표는 어느 공간에서 계산하든 해석할 만한 의미가 없다.
공통#
두 부류 모두 정답 크기로 나누지 않는다. 정규화가 꼭 필요하면 입구 조건에서 오는 고정 외부 스케일 (, , )을 쓴다. 정답으로 나누면 0 근처에서 분모가 무너진다.
L2 계열 지표와 눈으로 본 품질이 어긋날 수 있다
물리량 모델의 필드는 0 근처가 대부분이고 큰 값은 몇 군데뿐이다. 오차를 제곱하는 rel_l2%·rmse 는
그 몇 군데에 좌우되고, 분모가 되는 RMS 는 작아서 비율이 크게 나온다. 반대로 평가 이미지에서는 그 몇 군데가
화소 몇 개라 눈에 띄지 않는다. 그래서 평가 이미지로는 문제가 없어 보이는데 지표만 나쁘게 나오는 상황이 생긴다.
계산이 틀린 게 아니라 지표가 원래 그렇게 동작한다. 실제로 오차가 어디에 몰려 있는지는 실측 결과 에서 분해해 두었다.
조기 종료와 EMA 선택#
| 경로 | 조기 종료 기준 |
|---|---|
| 회귀 (물리량) | nondim 공간 mae 를 채널 수로 정규화한 값 |
| 회귀 (렌더) | [0,255] 화소값 mae 의 필드 합 |
| 확산 | 학습 공간(edm/ldm) MSE 합 |
| mesh | nondim 공간 mae 의 필드 합 |
post-hoc EMA 선택은 EMA 표준편차 후보를 여러 개 재구성해 각각 평가한 뒤 제일 좋은 것을 고르는 절차다. 점수는 평가 경로를 그대로 타므로 물리 단위에서 나오고, 필드마다 채널 수로 나눠 더한다. 후보끼리는 같은 fold, 같은 epoch 의 가중치를 견주는 것이라 정규화 공간을 따로 맞출 필요가 없다.