Kaggle Biohub 세포 추적 대회 은메달 풀이와, Public LB에 휘둘렸던 이야기
요약
본 글은 Kaggle Biohub 세포 추적 대회 참가 경험을 바탕으로 작성되었으며, 3D 현미경 이미지에서 세포를 탐지하고 시간 흐름에 따라 추적하는 과정을 다룹니다. 특히 public LB의 결과에만 의존하여 모델 구성(헤드)을 변경했던 것이 private LB에서는 효과가 없었음을 반성하며, 대회 풀이 과정과 평가 지표 분석을 공유합니다.
핵심 포인트
- 세포 추적은 3D 현미경 이미지에서 노드와 에지 연결로 이루어집니다.
- 평가 지표는 Jaccard 유사도 기반이며, 특히 분열(division) 일치도가 중요했습니다.
- Public LB에만 집중하여 모델을 변경하는 것은 Private LB 결과에 영향을 주지 않을 수 있습니다.
서론
Kaggle의 Biohub - Cell Tracking During Development 대회에 참가하여 private LB에서 **3,947개 팀 중 122위(은메달)**를 달성했습니다.
- public LB: 0.965 (56위)
- private LB: 0.926 (122위, 은메달은 상위 197위까지)
이 글에서는 대회의 개요, 사용한 파이프라인, 직접 추가한 '분열 단계', 그리고 public LB에서 선택했던 구성이 private LB에서 바뀌었던 반성거를 정리합니다.
※ 순위는 Kaggle 검증 전의 잠정치입니다.
대회 개요
지라프피쉬 배아의 3D 타임랩스 현미경 이미지로부터 세포를 하나씩 탐지하고 시간 방향으로 추적하는 과제입니다.
- 입력: 1 클립 = 3D 이미지 × 100 프레임 (복셀은 z 1.625 µm, y/x 0.406 µm). 배아는 2 계통.
- 출력: 각 프레임의 세포 위치(노드)와, 인접한 프레임에서 같은 세포를 연결하는 선(에지). 세포가 분열하면 하나의 궤적이 두 개로 나뉩니다.
- 형식: 코드 대회. Kaggle의 T4 GPU에서 노트북을 재실행 (인터넷 OFF). 채점에 약 7.5시간이 걸리며, 하루 5회 제출까지 가능합니다.
- 테스트: 숨겨진 테스트 약 199 클립. public은 약 29% (약 58 클립), private은 약 71%。
평가 지표
정답 노드와 7 µm 이내에서 대응이 이루어진 것을 전제로, 에지 일치도(Jaccard)가 주된 항목입니다. 예측 노드가 정답보다 너무 많으면 감점되며, 분열의 일치도가 0.1배로 가산됩니다.
상위권 팀들은 에지 정확도가 거의 비슷한 수준이었기 때문에, 분열(division) 항목에서 차이가 나는 구조였습니다.
풀이 전체 개요
①부터 ④까지는 공개된 노트북의 기반을 그대로 사용했으며, 직접 기여한 부분은 마지막 분열 단계 ⑤에 집중했습니다.
①~④ 공개 기반
- 기반은 공개 노트북 anvithpothula/biohub-x138 (public 0.953)입니다. 탐지 및 연결 가중치는 pilkwang 님의 공개 데이터셋을 사용했습니다.
- ②의 좌표 보정 헤드는 처음에는 x138의 비공개 구성 요소였습니다. 대회 막바지인 09-25에 저자가 공개했기 때문에 그것을 사용했습니다 (이동량을 1.15배하여 사용).
- ④의 ILP(Integer Linear Programming, 정수 선형 계획)는
표
| 날짜 | 구성(이전 변경 사항) | public | private |
|---|---|---|
| 09-28 | 최종 선택 A: B + 분열의 임계값 0.7 | 0.964 | 0.926 |
| 09-26 | 최종 선택 B: 저자 헤드의 이동량 × 1.15 | 0.965 | 0.926 |
| 09-26 | 저자 헤드의 이동량 × 0.85 | 0.961 | 0.928 |
| 09-26 | 좌표 보정 헤드를 저자의 공개 버전에 대체 | 0.963 | 0.925 |
... |
public은 0.944 → 0.965까지 늘어났지만, private는 09-24 이후 0.923~0.929로 거의 수평을 유지했습니다.
효과가 없었던 것
| 조치 | public의 변화 |
|---|---|
| 헤드의 이동량 배율(0.85~1.45, 축별도) | ±0.002 범위에서 평탄 |
| ... | |
| 마지막 linefit은 좌표 보정 헤드가 없는 기반으로 측정하여 +0.0007이었습니다. 헤드를 넣은 기반에서는 −0.003입니다. 헤드가 한 점씩 수정한 위치를, 평활화가 궤적의 직선으로 되돌려 상쇄했다고 생각합니다. |
반성: public LB에 휘둘린 것
가장 큰 반성은 최종 제출 선택이었습니다.
- 최종 2개는 둘 다 '저자 헤드 + 자체 분열 구간'이라는 함정에 빠져, private는 일제히 0.926이었습니다.
- 총 66개의 제출 중 private 최고점은,
**public에서 밀렸던 자체 헤드의 버전(0.929)**이었습니다. 저자 헤드는 public에서 +0.005~0.008로 앞서고 있었지만, private에서는 −0.003으로 뒤처져 있었습니다. - 배율 탐색도 마찬가지로, public에서 선택한 1.15보다, public 최하위의 0.85가 private에서는 더 높았습니다.
public은 약 58 클립밖에 없어서, 같은 파이프라인 근방의 변종은 ±0.002 정도 흔들립니다. 이 정도 차이로 구성을 선택하는 것은 거의 최대값을 잡는 것이었습니다.
다음부터의 규칙
- 최종 2개는 다른 계통에서 선택할 것(예: 자체 모델계 1개 + public 최고점계 1개). private는 2개가 좋은 것으로 결정되므로, 같은 오차를 가진 2개를 나란히 놓아도 보험이 되지 않습니다.
- public의 차이가 흔들림 범위에 속하는 성분은, 손으로 직접 검증하여 순위가 매겨지지 않는 한 public에서 선택하지 않을 것입니다.
- 상류(upstream)로 오차 분포를 바꾸는 부품(학습된 좌표 보정 등)을 추가하면, 하류의 조절값은 다시 측정할 것입니다.
기타 잘한 것
- 제출 사전 등록: 제출 전에 '무엇을 바꿨는지・예측 값・어떤 통계가 움직여야 하는지・결과별 판단'을 장부에 적고 제출했습니다. 사후 해석을 막을 수 있고, 결과가 나온 순간에 판단이 끝납니다. -
제출 전 구조 체크: Kaggle 상의 commit 출력을 다운로드하여 노드 수・분열 추가 수・CSV의 이상치를 자동으로 확인한 후 제출했습니다. 제출물의 해시가 확인한 것과 일치하는 것도 스크립트로 보장합니다. -
공개 노트는 점수 순으로 매일 확인: 기반의 x138을 3일간 놓쳤습니다. 제목이나 설명문의 점수 표기는 믿을 수 없으며(‘0.948’이라고 쓰인 노트의 실력은 0.935), 노트 페이지의 Public Score를 읽는 것이 확실합니다.
맺음말
금메달(private 0.941 이상)에는 미치지 못했지만, 은권에 들었습니다. 공개 기반을 활용하면서도 자체 분열 구간으로 +0.010을 쌓을 수 있었던 것은 좋았습니다. 다만, 마지막 선택은 public에 끌렸습니다. 다음에는 최종 2개의 선택 방법을 사전에 정하고 임할 것입니다.
공개 노트・데이터셋을 공유해 주신 anvithpothula님, pilkwang님을 비롯한 참가자 여러분께 감사드립니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기