본문 바로가기
  • 컴공생의 공부 일기
  • 공부보단 일기에 가까운 것 같은
  • 블로그
Club|Project/졸업 프로젝트 연구 트랙

💥 Zoobot 모델 - 은하 병합 파인튜닝 테스트 : 데이터

by 정람지 2025. 4. 2.

한번 테스트를 해 보장

기존 SOTA를 이해해야

멀티모달 아키텍처로 개선해 볼 수 있을 것이당


 

✅ 내 컴퓨터 구성 분석

CPU i5-14600KF (6P+8E, 최대 5.3GHz) 멀티코어 성능이 우수해서 학습보다는 데이터 전처리, 추론 등에 적합
쿨러 3RSYS 360mm 수랭 쿨러 발열 많은 작업도 안정적 처리 가능
메인보드 B760M AORUS ELITE AX PCIe 4.0, M.2, Wi-Fi 등 학습용 구성에 충분
RAM DDR5 32GB (16GB x2, 5600MHz) 딥러닝 학습엔 최소 수준, 추론이나 중간 규모 데이터 처리엔 충분
GPU RTX 4070 Ti SUPER 16GB DL 학습 가능, TNG50 + Zoobot fine-tuning 규모에 적당
SSD SK hynix P31 1TB (NVMe Gen3) 빠르고 충분한 용량 (추가 저장 필요 시 외장 or HDD 필요)
파워 750W 80PLUS GOLD 고성능 GPU 안정적으로 지원 가능
케이스 확장성 좋고 쿨링 우수 고사양 유지에 적합

 

 

🚧 한계점 (대규모 학습 시)

RAM 대형 모델 또는 수천 장 이미지 학습 시 부족할 수 있음 (64GB 이상 권장됨)
GPU VRAM 16GB는 CNN 모델 fine-tuning에는 충분하지만, ViT 기반 Zoobot 같은 large model에서 batch size가 제한됨
스토리지 TNG50 이미지가 많아지면 (10k장 이상) 1TB SSD로 부족할 수 있음 (추가 외장 SSD 추천)

 

조앙

먼지만 쌓이던 데스크탑 봉인 해제


💥 파인튜닝용 TNG 데이터 

뇽뇽

 

 

IllustrisTNG - Data Access - Specifications

Most all original fields from the group catalogs are also available, reordered into the same order as the merger trees for convenience. See the group catalog description for their units, dimensions, and descriptions. Fields: Group_M_Crit200, Group_M_Mean20

www.tng-project.org

 

(y) Merger History 부분

 

모든 서브할로(=은하)의 병합 이력과 통계를 포함하는 카탈로그로, 전체 시간대를 다룸.

 

병합은 세 가지 범주로 나뉨:

 주병합(major merger): 별질량 비율이 1/4보다 큼

 부병합(minor merger): 별질량 비율이 1/10 ~ 1/4 사이

 전체 병합(all mergers): 별질량 비율 무관

 

 

⚠️ 병합 이벤트 선별 기준:

1. 스쳐 지나가는(flyby) 병합이나 재병합(re-merger) 방지를 위해,

 두 은하가 각기 다른 FoF 그룹에서 유래했을 때만 병합으로 인정.

2. 비우주론적(subgrid) 하위 구조(clump) 제거:

 SubhaloFlag == False인 서브할로 무시.

 보조 은하가 2개 이하의 스냅샷에만 존재한 경우 병합으로 간주하지 않음.

 

 

📁 주요 변수 설명:

변수명 단위 설명
SnapNumLastMajorMerger - 마지막 주병합이 발생한 스냅샷 번호
SnapNumNextMajorMerger - 다음 주병합이 일어날 스냅샷 번호 (없으면 -1)
NumMajorMergers{time} - 최근 {기간} 내 주병합 횟수
NumMajorMergersTotal - 전체 기간 동안 주병합 횟수
SnapNumLastMinorMerger - 마지막 부병합 발생 시점
SnapNumNextMinorMerger - 다음 부병합 시점 (-1은 없음)
NumMinorMergers{time} - 최근 {기간} 내 부병합 횟수
NumMinorMergersTotal - 전체 기간 동안의 부병합 횟수
SnapNumLastMerger - 마지막 병합 시점 (모든 병합 포함)
SnapNumNextMerger - 다음 병합 시점 (-1은 없음)
NumMergers{time} - 최근 {기간} 내 병합 횟수 (전체)
NumMergersTotal - 전체 병합 횟수
{time} 값은 다음 중 하나일 수 있음:
Last250Myr, Last500Myr, LastGyr, SinceRedshiftOne, SinceRedshiftTwo

 

 

📊 누적 병합 통계 (cumulative merger statistics):

 

이 값들은 병합의 누적 영향을 측정한 것.

병합 시점은 트리 상에서 가지가 합쳐지는 시점이고, 보조 은하의 특성은 최대 별질량 시점에서 측정됨.

변수명 단위 설명
MeanGasFraction - 병합된 보조 은하들의 평균 ‘차가운 가스’ 비율 (별질량 가중 평균)
MeanLookbackTime Gyr 병합이 일어난 평균 과거 시간 (lookback time)
MeanMassRatio - 평균 병합 별질량 비율 (보조 은하 기준, 별질량 가중)
MeanRedshift - 병합이 일어난 평균 적색편이 (별질량 가중)

 

 

⏱ 기간 기반 병합 통계:

변수명 단위 설명
AccretedStellarMass{time} 10^{10} M_\odot/h {기간} 동안 병합으로 유입된 별질량 총합
MeanRedshiftAtPeakMass{time} - 병합된 보조 은하가 최대 별질량을 가진 시점의 평균 적색편이
MeanStellarMass{time} 10^{10} M_\odot/h 병합된 은하들의 평균 별질량 (보조 은하 기준)
MeanStellarMassRatio{time} - 병합의 평균 별질량 비율
NumMajorMergers{time} - {기간} 동안 주병합 횟수
NumMinorMergers{time} - {기간} 동안 부병합 횟수
NumMergers{time} - {기간} 동안 전체 병합 횟수
여기서 {time} 값은 다음 중 하나:
Last2Gyr, Last5Gyr, Last8Gyr, SinceRedshift5

 

 

🧼 TNG50-1 전용 필터 데이터 (WithConstraint 그룹):

 보조 은하가 생애 중 50개 이상의 별 입자를 가진 적이 없으면 병합 통계에서 제외함.

 더 작고 비현실적인 은하 병합을 제외하고 정제된 통계 제공.

 이 그룹은 Eisert+ (2022)  Sotillo-Ramos+ (2022) 논문 결과 재현.


💥 논문 라벨링 시나리오

 

📌 1. 병합 정의 (Merger labeling)

 병합 여부 기준: 중심 은하가 ±0.5 Gyr 이내에 병합 이벤트를 겪었는지 여부로 병합 여부 결정.

 병합 여부는 merger trees 정보를 기반으로 함.

 병합은 stellar mass ratio ≥ 1:10일 경우만 고려.

 

📌 2. 이미지 생성 (Mock observations)

 사용한 시뮬레이션: TNG50-1

 이미지 생성 방식:

 SKIRT radiative transfer code로 gri 합성 이미지 생성

 해상도: 300x300 pixels

 HSC-SSP 스타일과 비슷하게 포스트프로세싱하여 실제 관측과 유사하게 표현

 

📌 3. 학습용 데이터 구성

 총 68,303개의 은하 샘플 중 병합 여부에 따라 다음과 같이 분류됨:

 병합 은하 (Merging): 8,346개

 비병합 은하 (Non-merging): 59,957개

 

📌 4. 라벨링 정확도 향상을 위한 전처리

 비병합 샘플에서 잘못된 non-merger 라벨 제거를 위해 조건부 필터링 적용

 SKIRT 코드로 생성한 이미지의 광도/형태 정보를 통해 시각적 품질 보장

 

📌 5. 훈련/검증 분할

 훈련: 80%

 검증/테스트: 20%

 학습 전 이미지 정규화 및 리사이징 처리 포함


음..

간단하게 진행해 보자

 

 

 

📌1. TNG50 Subhalo merger catalog 기반으로 병합/비병합 은하 분류

 데이터: TNG merger catalog (HDF5)

 선택 기준:

 병합 은하: SnapNumLastMerger가 현재 snapshot 기준 0.5 Gyr 이내인 경우

 비병합 은하: 병합 이력이 없거나 SnapNumLastMerger가 너무 오래 전인 경우

 

📌2. TNG 웹사이트에서 gri projected map 다운로드

 해상도: 512x512 또는 300x300으로 줄여서 사용 가능

 → SKIRT로 따로 렌더링 안 해도 됨!

 

📌3. 간단한 데이터 전처리

 PNG 이미지를 300x300으로 resize

 병합/비병합 이진 라벨 부여

 학습셋/검증셋 나누기

 

📌4. Zoobot 파인튜닝

 Zoobot은 이미지 기반 self-supervised pretrained ViT 기반 모델이므로, 이진 분류(finetune)만 추가로 해주면 됨.

 PyTorch Lightning 기반 코드로 fine-tune

 

 


💥 데이터 얻기

 

TNG50-1 ( 가장 높은 해상도에 가장 높은 입자 수 ) 아무튼 제일짱데이터

https://www.tng-project.org/api/TNG50-1/files/merger_history/

 

 

 

데이터 내용 보기

하나의 파일에 689643개 정도의 은하 정보

=== merger_history.1.hdf5 ===
AccretedStellarMassLast2Gyr: shape=(689643,), dtype=float32
AccretedStellarMassLast5Gyr: shape=(689643,), dtype=float32
AccretedStellarMassLast8Gyr: shape=(689643,), dtype=float32
AccretedStellarMassSinceRedshift5: shape=(689643,), dtype=float32
MassLastMajorMerger: shape=(689643,), dtype=float32
MeanGasFraction: shape=(689643,), dtype=float32
MeanLookbackTime: shape=(689643,), dtype=float32
MeanMassRatio: shape=(689643,), dtype=float32
MeanRedshift: shape=(689643,), dtype=float32
MeanRedshiftAtPeakMassLast2Gyr: shape=(689643,), dtype=float32
MeanRedshiftAtPeakMassLast5Gyr: shape=(689643,), dtype=float32
MeanRedshiftAtPeakMassLast8Gyr: shape=(689643,), dtype=float32
MeanRedshiftAtPeakMassSinceRedshift5: shape=(689643,), dtype=float32
MeanStellarMassLast2Gyr: shape=(689643,), dtype=float32
MeanStellarMassLast5Gyr: shape=(689643,), dtype=float32
MeanStellarMassLast8Gyr: shape=(689643,), dtype=float32
MeanStellarMassRatioLast2Gyr: shape=(689643,), dtype=float32
MeanStellarMassRatioLast5Gyr: shape=(689643,), dtype=float32
MeanStellarMassRatioLast8Gyr: shape=(689643,), dtype=float32
MeanStellarMassRatioSinceRedshift5: shape=(689643,), dtype=float32
MeanStellarMassSinceRedshift5: shape=(689643,), dtype=float32
NumMajorMergersLast250Myr: shape=(689643,), dtype=uint32
NumMajorMergersLast2Gyr: shape=(689643,), dtype=uint32
NumMajorMergersLast500Myr: shape=(689643,), dtype=uint32
NumMajorMergersLast5Gyr: shape=(689643,), dtype=uint32
NumMajorMergersLast8Gyr: shape=(689643,), dtype=uint32
NumMajorMergersLastGyr: shape=(689643,), dtype=uint32
NumMajorMergersSinceRedshift5: shape=(689643,), dtype=uint32
NumMajorMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
NumMajorMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
NumMajorMergersTotal: shape=(689643,), dtype=uint32
NumMergersLast250Myr: shape=(689643,), dtype=uint32
NumMergersLast2Gyr: shape=(689643,), dtype=uint32
NumMergersLast500Myr: shape=(689643,), dtype=uint32
NumMergersLast5Gyr: shape=(689643,), dtype=uint32
NumMergersLast8Gyr: shape=(689643,), dtype=uint32
NumMergersLastGyr: shape=(689643,), dtype=uint32
NumMergersSinceRedshift5: shape=(689643,), dtype=uint32
NumMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
NumMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
NumMergersTotal: shape=(689643,), dtype=uint32
NumMinorMergersLast250Myr: shape=(689643,), dtype=uint32
NumMinorMergersLast2Gyr: shape=(689643,), dtype=uint32
NumMinorMergersLast500Myr: shape=(689643,), dtype=uint32
NumMinorMergersLast5Gyr: shape=(689643,), dtype=uint32
NumMinorMergersLast8Gyr: shape=(689643,), dtype=uint32
NumMinorMergersLastGyr: shape=(689643,), dtype=uint32
NumMinorMergersSinceRedshift5: shape=(689643,), dtype=uint32
NumMinorMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
NumMinorMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
NumMinorMergersTotal: shape=(689643,), dtype=uint32
SnapNumLastMajorMerger: shape=(689643,), dtype=int16
SnapNumLastMerger: shape=(689643,), dtype=int16
SnapNumLastMinorMerger: shape=(689643,), dtype=int16
SnapNumNextMajorMerger: shape=(689643,), dtype=int16
SnapNumNextMerger: shape=(689643,), dtype=int16
SnapNumNextMinorMerger: shape=(689643,), dtype=int16
WithConstraint/AccretedStellarMassLast2Gyr: shape=(689643,), dtype=float32
WithConstraint/AccretedStellarMassLast5Gyr: shape=(689643,), dtype=float32
WithConstraint/AccretedStellarMassLast8Gyr: shape=(689643,), dtype=float32
WithConstraint/AccretedStellarMassSinceRedshift5: shape=(689643,), dtype=float32
WithConstraint/MassLastMajorMerger: shape=(689643,), dtype=float32
WithConstraint/MeanGasFraction: shape=(689643,), dtype=float32
WithConstraint/MeanLookbackTime: shape=(689643,), dtype=float32
WithConstraint/MeanMassRatio: shape=(689643,), dtype=float32
WithConstraint/MeanRedshift: shape=(689643,), dtype=float32
WithConstraint/MeanRedshiftAtPeakMassLast2Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanRedshiftAtPeakMassLast5Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanRedshiftAtPeakMassLast8Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanRedshiftAtPeakMassSinceRedshift5: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassLast2Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassLast5Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassLast8Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassRatioLast2Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassRatioLast5Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassRatioLast8Gyr: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassRatioSinceRedshift5: shape=(689643,), dtype=float32
WithConstraint/MeanStellarMassSinceRedshift5: shape=(689643,), dtype=float32
WithConstraint/NumMajorMergersLast250Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersLast2Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersLast500Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersLast5Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersLast8Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersLastGyr: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersSinceRedshift5: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
WithConstraint/NumMajorMergersTotal: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLast250Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLast2Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLast500Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLast5Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLast8Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersLastGyr: shape=(689643,), dtype=uint32
WithConstraint/NumMergersSinceRedshift5: shape=(689643,), dtype=uint32
WithConstraint/NumMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
WithConstraint/NumMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
WithConstraint/NumMergersTotal: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLast250Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLast2Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLast500Myr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLast5Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLast8Gyr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersLastGyr: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersSinceRedshift5: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersSinceRedshiftOne: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersSinceRedshiftTwo: shape=(689643,), dtype=uint32
WithConstraint/NumMinorMergersTotal: shape=(689643,), dtype=uint32
WithConstraint/SnapNumLastMajorMerger: shape=(689643,), dtype=int16
WithConstraint/SnapNumLastMerger: shape=(689643,), dtype=int16
WithConstraint/SnapNumLastMinorMerger: shape=(689643,), dtype=int16
WithConstraint/SnapNumNextMajorMerger: shape=(689643,), dtype=int16
WithConstraint/SnapNumNextMerger: shape=(689643,), dtype=int16
WithConstraint/SnapNumNextMinorMerger: shape=(689643,), dtype=int16
SnapNumLastMajorMerger (first 10): [-1  1 -1 -1 -1 -1 -1 -1 -1 -1]

 

 

 

논문 따라 나도 이렇게 진행

TNG50-1 데이터
- 병합 은하(Merger): 
조건 : SnapNumLastMerger가 현재 snapshot 기준 0.5 Gyr 이내인 경우
개수 : 4000개 
- 비병합 은하(Non-merger):
조건 : 병합 이력이 없거나 SnapNumLastMerger가 너무 오래 전인 경우
개수: 4000개

 

 

아니 라벨링해 보니

아니 한 개도 없어...?

진짜 적나 보다

 

데이터 더 받아야겠다...