WRITING · 2026-11-02

산불 4건으로 시공간 딥러닝 학습하기

데이터가 35개 시점뿐일 때 어떻게 학습시켰고, 다시 보니 무엇이 부족했는지. U-LSTM 산불 확산 예측 모델 회고.

딥러닝시공간 데이터TensorFlowArcGIS회고

학부 캡스톤에서 산불 확산 경로 예측 모델을 만들었습니다. 지금 시점의 화선(불이 붙은 경계)과 바람·지형·식생 정보를 넣으면, 다음 시점에 불이 어디까지 번질지 300×300 지도로 예측하는 모델입니다. 저는 4인 팀에서 모델 설계와 학습을 맡았습니다.

이 글은 "데이터가 너무 적을 때 무엇을 했는지", 그리고 3년 뒤 코드를 다시 정리하면서 "무엇이 부족했는지"에 대한 기록입니다.

데이터: 산불 4건, 35개 시점

국내 대형 산불 4건(울진·삼척, 밀양, 군위, 강릉)의 산림청 산불 상황도를 ArcGIS로 래스터화했습니다. 각 시점마다 5개 채널을 같은 격자에 맞췄습니다.

채널 의미
화선 해당 시점에 불이 붙은 영역
풍향 · 풍속 확산 방향과 속도를 좌우
고도(DEM) 불은 경사를 타고 빠르게 오름
식생지수(NDVI) 탈 것이 얼마나 있는지

딥러닝 기준으로는 턱없이 적은 양입니다. 4건을 모두 합쳐 35개 시점뿐이었고, 그중 강릉은 일반화 성능을 보기 위해 학습에서 완전히 뺐습니다.

적은 데이터에 맞춘 두 가지 선택

① 모델을 작게 만들었습니다. Conv2D로 공간 특징을 줄이고(300→75), LSTM을 거쳐 다시 300×300으로 복원하는 U-LSTM 구조인데, 전체 파라미터를 2,736개로 제한했습니다. 데이터보다 모델이 훨씬 크면 학습 데이터를 외워 버리기 때문입니다.

② 슬라이딩 윈도우로 학습 샘플을 늘렸습니다. 한 산불의 시점 1~N을 길이 1부터 19까지의 구간으로 잘라 "이전 시점들 → 다음 시점" 쌍을 만들었습니다. 이렇게 학습 배치 151개를 구성했습니다.

결과적으로 학습에 쓰지 않은 강릉 산불에서 시점이 지날수록 실제 확산 형태를 비슷하게 재현했습니다. 초기 시점은 화선 정보 자체가 작아 부정확했지만, 불이 커질수록 모양을 따라갔습니다.

데이터 Overall Accuracy F1-score
검증 (밀양) 0.95 0.81
테스트 (강릉, 미학습) 0.90 0.85

최종 결과보고서 기준. 아래 '다시 읽은 코드'에서 설명하듯, 검증 구간이 학습과 일부 겹쳐 있어 숫자는 테스트 쪽이 더 믿을 만합니다.

3년 뒤 다시 읽은 코드

포트폴리오를 위해 팀 노트북을 다시 열었을 때, 같은 코드를 사건마다 복사하고 학습 샘플을 train_x_1부터 train_x_161까지 변수로 하나씩 잘라 둔 상태였습니다. 이를 설정 파일 하나와 함수 몇 개로 재구성하고, 테스트로 "원본과 같은 배치 수(151)·같은 파라미터 수(2,736)"를 확인했습니다.

그 과정에서 당시에는 몰랐던 점들이 보였습니다. 숨기지 않고 저장소 README에도 적어 두었습니다.

LSTM이 시간 축을 보고 있지 않았다

이름은 U-LSTM이지만, 실제로 LSTM은 75×75 격자를 5,625 길이의 시퀀스로 펼친 공간 축 위에서 동작하고 있었습니다. 각 샘플은 t → t+1을 독립적으로 예측합니다. 여러 시점의 흐름을 직접 학습하려면 ConvLSTM처럼 시간 축을 입력으로 받는 구조가 맞습니다.

검증 데이터가 학습과 겹쳤다

검증에 쓴 밀양 구간이 학습 윈도우와 일부 겹쳐 있었습니다. 강릉 테스트는 완전히 분리되어 있어 테스트 결과는 유효하지만, 하이퍼파라미터를 고르는 기준으로는 사건 단위 교차검증(leave-one-fire-out)이 더 엄밀합니다.

불균형 문제에 맞는 손실 함수가 아니었다

300×300 지도에서 화선 픽셀은 아주 일부입니다. 이런 불균형 문제에서 MSE와 Accuracy만 보면 "전부 불이 안 났다"고 예측해도 점수가 높게 나옵니다. Dice·Focal loss와 IoU를 함께 보는 것이 맞습니다.

배운 것

다시 만든다면 ConvLSTM, 사건 단위 교차검증, Dice loss + IoU, 그리고 위성 영상 기반 화선 자료를 추가하는 것부터 시작하겠습니다.

IAB 융합전공 — 시공간 딥러닝 기반 산불 확산 경로 예측 모델 (캡스톤)이 글에서 다룬 코드는 저장소에서 볼 수 있습니다.
GitHub 저장소 →포트폴리오로
다른 글겹쳐 있는 두 신호를 위상으로 가르기 — 파수 상관 필터링 석사 연구 정리중력과 자력 데이터를 같은 주파수 성분끼리 비교해, 함께 움직이는 성분과 반대로 움직이는 성분을 나눴다. 임계값을 감으로 정하지 않으려고 한 일들.점수를 지키면서 올리기 — VQA 챌린지에서 앙상블 후보를 고른 기준정확도가 조금 올라도 원래 맞히던 문제를 많이 틀리면 불안정한 개선이다. fixes와 breaks로 순기여를 따져 0.94608에서 시작한 점수를 쌓아 올린 과정.LLM이 붙인 [근거 N]을 코드로 다시 검사하기 — 국보 RAG 가이드의 인용 설계근거를 인용하라고 프롬프트에 써도 LLM은 없는 번호를 붙입니다. 근거 번호를 검색 단계에서 고정하고, 답변의 인용을 코드로 파싱해 없는 번호는 지우고 실제로 인용한 근거만 보여 주는 구조를 만든 기록.YAML 파일 하나로 포트폴리오·이력서·비공개 페이지까지 — 이 사이트를 만든 방식내용은 한 곳에만 쓰고, 웹 페이지·PDF 이력서·노션 문서는 빌드로 만든다. 공개하면 안 되는 내용은 저장소에 평문으로 남기지 않는다.데이터를 해석하기 전에 그 데이터가 만들어진 역사를 본다 — 학부 제1저자 논문 회고해외 대규모 CO2 저장소 8곳을 판구조 형성사와 탄성파 영상으로 비교했다. 처리 결과를 '그럴듯한지' 판단하는 기준을 어디서 가져올 것인가에 대한 이야기.길찾기에서 의사결정으로 — 배틀싸피 자동 플레이 봇을 세 번 고친 기록목표까지 가는 BFS 한 줄짜리 봇이, 사거리·장애물·탄약·보급·암호 해독까지 판단하는 봇이 되기까지. 매 턴 다시 계획하는 구조로 바꾼 이유.LLM 응답을 믿지 않는 파이프라인 설계LLM에는 판단만 맡기고, 결과는 코드로 검증한다. 댓글 분석 파이프라인과 AI 도서 추천을 만들며 정한 네 가지 원칙.순차 학습이 성능을 떨어뜨린 이유 — catastrophic forgetting 실험기단어 단위 → 문맥 단위로 차례로 학습하면 더 좋아질 줄 알았는데, BERTScore가 0.47에서 0.32로 떨어졌다. FLAN-T5 LoRA 학습 전략 비교.