작업실 노트

당신의 폴더 이름이 곧 학습 데이터였어요

이 앱을 만드는 기반이 된 아카이브는 파일 314,391개, 약 사진 223,000장과 동영상 91,000개로 이루어져 있고, 6 TB 외장 드라이브에 담겨 있어요. 한 가족의 시각적 기록 전체이고, 많은 가족이 그렇듯 이 가족도 완전히 다른 두 시대를 거쳐 왔어요.

2004년부터 2016년까지는 행사마다 각자의 폴더가 있었고, 그 일이 있고 나서 다음 날 손수 이름을 붙였어요. 2012-04 — the spring trip 같은 식이었죠. 이런 폴더가 대략 600개예요. 그러다 2016년쯤부터 폴더 만들기가 멈췄어요. 그 자리를 대신한 건 요즘 흔한 방식이었어요. 거대하고 평평한 폰 백업 덩어리, IMG_4471.HEIC처럼 이름 붙은 수천 개의 파일이 백업이 돌아간 날짜 범위 말고는 아무 기준 없이 뭉쳐 있었어요. (최근 몇 년치가 아직 폰 안에 갇혀 있다면, iPhone 옮기기 가이드에서 드라이브로 옮기는 방법을 다뤄요.)

이런 도구라면 당연히 이름 붙은 시대와 뭉텅이로 쌓인 시대 가리지 않고 아카이브 전체에서 행사를 자동으로 감지하고 이름을 자동으로 생성하는 게 계획이겠죠. 시작하기 전에는 예상하지 못했던 건, 이름 붙은 시대가 그냥 보기 좋기만 한 게 아니라 공짜로 얻은, 12년치 깊이의 라벨링된 데이터셋이었다는 점이에요.

추측이 아니라 정답 데이터

"하나의 행사"로 칠 수 있는 범위를 사람이 직접 그린 경계선이 600개나 있다는 건, 원래라면 돈을 주고서라도 구하고 싶은 종류의 데이터예요. 이 가족은 이미 하나의 순간이 어디서 끝나고 다음이 어디서 시작하는지를 행사마다 결정하는 작업을 다 해놓은 상태였어요. 그래서 기성 행사 클러스터링 방식을 골라잡고 그럴싸하기를 바라는 대신, 이름 붙은 폴더를 이 특정 가족이 시간을 행사로 나누는 방식에 대한 정답 데이터로 삼아서, 거기에 직접 맞춰 조정했어요.

클러스터링 방식 자체는 일부러 단순하게 만들었어요. 연속된 타임스탬프 사이의 간격이 임계값 아래로 유지되면 같은 행사로 묶는, 시간 간격 기반 방식이에요. 실질적으로 조정할 수 있는 값은 그 간격을 어디로 잡느냐 하나뿐이에요. 저는 이걸 지루하지만 정확한 방법으로 측정했어요. 바로 쌍별 공동 소속 일치도예요. 이름 붙은 시대의 모든 사진 쌍에 대해 사람이 나눈 폴더 구분과 알고리즘의 구분이 일치하는지(둘 다 같은 행사이거나, 둘 다 다른 행사이거나) 확인하고, 일치하는 비율을 점수로 매겼어요. 임계값을 훑으면서 곡선을 그리고, 그 정점을 골랐어요.

314,391
기준이 된 아카이브의 파일 수
~600
손수 이름 붙인 행사 폴더, 2004~2016년
F1 0.93
24시간 간격 임계값 기준

정점은 24시간 간격에서 나왔고, 이름 붙은 폴더 대비 F1 점수는 0.93이었어요. 이건 논문에 나오는 벤치마크가 아니라, 한 가족이 12년 동안 자기 행사가 어디서 시작하고 끝나는지 내린 판단에 맞춰 조정된 숫자예요. 바로 이게 핵심이에요. "올바른" 클러스터링 임계값은 보편적인 게 아니라 특정 가족이 사는 방식의 속성이에요. 이 가족은 이틀짜리 여행 중간에 어딘가에서 잤다는 이유만으로 그걸 두 개의 행사로 나누지 않는 것 같아요. 24시간 간격이 바로 그걸 포착해요. 다른 가족의 이름 붙은 폴더라면 정점이 완전히 다른 곳에서 나올 수도 있고, 그래서 이 앱은 미리 가정하는 대신 아카이브마다 다시 측정하도록 만들어졌어요.

행사가 이미 가족이 나누던 방식대로 묶이고 나면, 다음 문제는 이름 짓기고, 여기서도 같은 요령이 또 통해요. 600개의 이름 붙은 폴더는 그저 경계선이 아니라 스타일 가이드이기도 해요. 2012-04 — the spring trip은 이 가족의 관례가 날짜 접두사, 줄표, 소문자, 그리고 일반적인 표현("Family Outing" 같은) 대신 짧고 구체적인 표현("the spring trip")이라는 걸 알려줘요. 이름 붙지 않은 10년치를 위한 자동 이름 짓기는 일반적인 목소리를 강요하는 대신 이 가족의 목소리를 그대로 학습해요.

조용히 모든 걸 망가뜨렸을 뻔한 세 가지 함정

이걸 만들면서 기록해 둘 만한 세 가지 문제가 나타났어요. 셋 다 일부러 찾아보기 전에는 눈에 띄지 않고, 만약 겉으로 뻔해 보이는 정답 소스를 그대로 믿었다면 셋 다 타임라인을 조용히 망가뜨렸을 거예요.

카메라 시계는 거짓말을 하지만, 폴더 이름은 그렇지 않아요. 이름 붙은 시대에는 카메라 시계가 가끔 1년씩 어긋나 있었어요. 아주 심하게는 아니고, 배터리를 갈고 나서나 날짜 변경선을 넘는 여행을 하고 나서 아무도 다시 맞춰주지 않을 때 카메라 시계가 흔히 틀어지는 딱 그 정도였어요. 해결책은 EXIF를 날짜의 기본 정답으로 무조건 믿는 걸 그만두고, 둘이 어긋날 때는 사람이 직접 입력한 폴더의 날짜 접두사가 이기도록 하는 거였어요. 그 일이 있던 주에 폴더 이름에 2012-04라고 입력한 사람이, 몇 년째 확인도 안 한 카메라 내장 시계보다 더 믿을 만한 증인이에요.

디지털화한 미디어는 잘못된 날짜를 두 번 지니고 있어요. 나중에 디지털화한 오래된 캠코더 테이프는 더 심해요. 파일 자체의 타임스탬프 메타데이터는 영상을 촬영한 시점이 아니라 디지털화 작업을 한 시점을 반영하거든요. 이 종류의 파일에서 EXIF는 가끔 틀린 정도가 아니라, 특정하고 구조적인 방식으로 틀려 있어요. 해결책은 카메라 시계 문제와 같은 형태를 한 단계 위에 적용한 거예요. 스캔하거나 디지털화한 미디어는, 가족이 분류해 둔 연도 폴더가 파일 자체의 타임스탬프보다 우선해요. 폴더는 추억을 설명하고, 타임스탬프는 스캔 작업을 설명하는 거니까요.

여행을 여행으로 인식하려면 열정에 속지 않는 "집"의 정의가 필요해요. 여행을, 즉 평범한 일상에서 벗어난 일탈을 여행으로 감지하려면 앱은 "평범한 일상"이 어디였는지 알아야 하는데, 이건 가족이 이사를 다니면서 22년에 걸쳐 계속 바뀌어요. 순진한 접근법인 장소별 사진 수 세기는 생각해 보면 뻔히 실패해요. 5일짜리 휴가는 집에서 보낸 평범한 5일보다 훨씬 많은 사진을 만들어내니까, 일주일 동안 딱 한 번 방문한 장소가 실제로 6개월을 산 집을 손쉽게 이겨버릴 수 있어요. 해결책은 사진 수가 아니라 한 장소에 머문 서로 다른 일수를 기준으로 반년 단위로 투표하는 "집" 모델이에요. 어떤 장소가 "집"으로 인정받으려면 며칠 안 되는 날에 사진을 많이 찍혔다는 게 아니라, 여러 날에 걸쳐 실제로 그곳에서 살았다는 게 조건이에요. 사진 대신 일수를 쓴다는 이 한 가지 치환이, 여행을 집이 어디였는지를 조용히 다시 써버리는 대신 집에서의 일탈로 제대로 인식하게 해줘요.

이름 붙은 시절은 그저 라벨만 얻은 게 아니에요. 이 가족의 손으로 직접, "행사"라는 게 대체 뭔지를 정의할 기회를 얻은 거예요.

이 중 어느 것도 "이게 정답 임계값이니 그대로 출시하면 돼"라는 식으로 일반화되지는 않아요. 일반화되는 건 방법론이에요. 아카이브의 일부가 그 순간을 직접 산 사람들의 손으로 라벨링돼 있었다면, 그 부분은 그저 보기 좋은 정도가 아니라 정답 데이터이고, 기본값이 어지간히 맞겠거니 가정하는 대신 거기에 맞춰 측정해 보는 수고를 들일 가치가 있어요. 보통의 가족 아카이브에 있는 나머지 2만 개 파일은 애초에 관리자의 세심한 관심을 받을 일이 없었을 거예요. 하지만 그중 12년치라면, 보통은 받을 수 있어요.

← 모든 글 보기