반응형

2024년 12월 29일 제주항공 2216편이 무안공항에서 추락한지 어느덧 1주년이 되었지만 사고 원인은 여전히 오리무중이다.

그동안 국토교통부나 항철위는 고작해야 몇장 안되는 사고 전경사진으로 채워진 예비 보고서 하나를 내놓았을 뿐 관제사 교신 내역, 조종석 계기판의 엔진, 기어 조작 스위치 등 핵심적인 증거자료는 일체 내놓지 않고 있다.

 

사고 후 1년만에 드디어 국회 차원의 특별 조사 위원회가 구성되어 지지부진한 사고 조사에 탄력을 받을지 관심이 모아지고 있지만 과연 제대로된 진실이 밝혀질지는 여전히 미지수다.

 

왜인지는 모르겠으나 KBS에서 이 사고와 관련하여 여러 영상들을 제작하고 있는데,

나름대로는 여러가지 영상 증거와 목격자 증언을 종합하여 비행기의 궤적을 추적하는 등의 노력을 하고는 있다. 

 

하지만 본인의 생각으로는 사고의 원인을 파악하기 보다는 당시 조종사들이 얼마나 힘겹게 비행기를 조종해서 착륙했는지에 너무 중점이 맞춰져있지 않나 하는 생각이 든다.

https://youtu.be/siv9fDYkXVI?si=CgfMuj_jsxN7vyqo

 

하지만 세때와의 충돌은 사고가 발생하게 된 여러 원인중의 하나일 뿐이고 현대의 제트항공 여객기는 결코 한가지 원인으로 인해 추락하지 않는다는 점을 명확히 해야 한다.

 

아래 기사를 보면 항철위는 사고의 원인으로 조종사 과실 즉, 새떼로 인해 고장난 우측엔진 대신 멀쩡한 좌측 엔진을 꺼버려서 급하게 착륙해야 했다는 식으로 설명했다.

 

[취재파일] 무안공항 참사⑤ "조종사가 껐다?" 비공개 설명회서 사과한 항철위
출처 : SBS 뉴스
원본 링크 : https://news.sbs.co.kr/news/endPage.do?news_id=N1008256434&plink=COPYPASTE&cooper=SBSNEWSEND
 

[취재파일] 무안공항 참사⑤ "조종사가 껐다?" 비공개 설명회서 사과한 항철위

지난주, 여객기 참사 비공개 설명회…7월 중간 발표 논란 사과 지난주, 무안공항 제주항공 여객기 참사를 조사하는 항공철도사고조사위원회가 유족들과 여객기참사특위 소속 국회의원들을 상

news.sbs.co.kr

 

위 KBS의 영상에서도 해당 상황을 가정하여 기체의 속도가 줄어들고 급하게 착륙하게 된 경위를 설명하고 있지만

정작 착륙할때는 어떻게 엔진을 잃은 비행기가 200노트가 넘는 고속으로 활주로에 접지하였는지는 설명하지 않고 넘어갔다. 

KBS영상 중 활주로에 정대한 시점의 속도와 고도

 

정상적인 엔진을 껐다는 상황 하에 고장난 엔진이 기적적으로 어느정도 출력을 만들었다는 가정에 가정을 해서 기를 쓰고 재현을 해내서 만든 속도가 180노트다.

 

그런데 정작 사고 영상 속 실제 2216편 항공기는 착륙 당시 속도가 200 - 210노트 정도 였던 것으로 확인된다. 

엔진 2개가 모두 꺼진 비행기에서는 있을 수 없는 속도다.

 

본인은 지난 글에서도 마찬가지로 왜 비행기의 속도가 줄지 않았는가, 여기에 모든 문제의 핵심이 담겨있다고 밝힌바 있다.

 

다음은 사고 영상에서 확인할 수 있는 지형지물과의 대조를 통해 사고 여객기의 충돌 직전 속도를 산출한 과정을 정리한 영상이다.

https://youtu.be/5APONU4YVIg

 

당시 여객기는 활주로 남단 끝 120미터 거리를 1.4초만에 지나가버렸다. 

이것은 무려 160노트를 넘는 속도이다. 

다시말해 70톤이 넘는 737-800여객기가 200노트 속도로 동체착륙을 했는데 대략 1.5킬로미터 정도를 내달렸음에도 속도는 고작 40노트 또는 시속 70km만 줄었다는 얘기다.

마찰력이 거의 없는 얼음판 위도 아니고 콘크리트로 지어진 활주로에 70톤에 달하는 육중한 물체가 무려 1.5키로미터나 되는 거리를 긁으며 지나는 동안 겨우 70키로밖에 속도가 줄지 않았다는 점은 매우 의아하다.

다음은 ChatGPT에게 737여객기가 랜딩기어, 플랩이 전개되지 않고 엔진이 꺼진상태로 210노트의 속도로 착륙했을때 얼마만큼 지나서 정지하는지를 물은 결과이다.

Given / assumed parameters

Aircraft

  • Boeing 737-800
  • “Fully loaded” → mass ≈ 70,000 kg (≈690 kN weight)
    (exact mass doesn’t matter much for pure friction braking)

Touchdown

  • Groundspeed: 210 kt ≈ 108 m/s
  • Flaps up
  • No thrust
  • No spoilers
  • Gear up (belly landing)
  • Dry runway
  • Touchdown on centerline, no yaw

Dominant deceleration mechanisms

  1. Sliding friction (belly vs concrete)
    This dominates once the aircraft is on the ground.Coefficient of friction μ ≈ 0.2–0.35
  2. Published data for aluminum/steel structures scraping on concrete is sparse, but accident reconstructions typically use:
  3. Aerodynamic drag
    • Still significant at 210 kt initially
    • Decreases rapidly with speed
    • Adds maybe 10–25% extra deceleration early in the slide

We can bracket the answer using friction alone, then note aero drag shortens it slightly.


Skid distance calculation (baseline)

Deceleration from sliding friction:

a=μga = \mu g

Stopping distance:

s=v22as = \frac{v^2}{2a}

Case 1: Conservative (low friction)

  • μ = 0.20
  • a = 1.96 m/s²

s=10822×1.96=116643.92≈3,000 ms = \frac{108^2}{2 \times 1.96} = \frac{11664}{3.92} \approx \mathbf{3,000\ m}

Case 2: Typical dry concrete scrape

  • μ = 0.30
  • a = 2.94 m/s²

s=116645.88≈2,000 ms = \frac{11664}{5.88} \approx \mathbf{2,000\ m}

Case 3: High friction / heavy structural damage

  • μ = 0.35
  • a = 3.43 m/s²

s≈1,700 ms \approx \mathbf{1,700\ m}

 

위 결과를 보면 마찰계수가 0.2인 경우에는 3000미터가 필요하다고 되어있으나 이것은 금속 대 금속인 경우에나 가능한 수치이고 일반적으로는 0.3 이상을 적용하고 실제는 표면 상태에 따라 다를 수 있지만 대략 2000미터 이내에서 완전히 "정지"함을 확인할 수 있다.

실제 사례도 있다.

2011년 11월 1일에 폴란드의 LOT Polish Airlines Flight 16 편은 유압장치가 모두 고장나면서 랜딩기어가 내려가지 않아 비상착륙을 실시했다. 총 231명이 탑승한 767 여객기는 랜딩기어가 올려진채로 127노트의 속도로 터치다운하여 1200미터를 내달린 끝에 완전히 정지하였다.

https://en.wikipedia.org/wiki/LOT_Polish_Airlines_Flight_16

 

터치다운 속도는 80노트(140키로)정도 차이가 나지만 사고 당시 착륙 직전 767항공기의 무게가 118톤으로 737에 비해 1.7배에 달하는 무게로 착륙 당시 운동에너지는 거의 비슷하다고 볼 수 있다.

 

200노트로 터치다운한 제주항공 2216편 여객기는 어떻게 엔진이 꺼진채로 1500 - 1800미터를 넘게 바닥을 긁으며 달렸음에도 불구하고 160노트가 넘는 속도가 유지되어 콘크리트 둔덕에 충돌 폭발하는 지경에 이르렀는지는 매우 매우 이상하고 할 수 있다.

 

모든 경우를 더하더라도 제주항공 여객기가 1800미터를 지난 시점에는 최소 50노트 혹은 시속 90키로미터 정도로 감속할 수 있었을 것이다. 그리고 이 속도라면 비록 콘크리트에 부딫혔다 하더라도 승객 전원이 사망하는 사고로 이어지지는 않았을 것이다.

 

부디 이번에 구성된 국회 특조위에서는 이 미스테리가 풀릴 수 있기를 바란다.

반응형
반응형

이 과정을 진행한지 한참 지났지만 리마인드를 위해서 정리해본다.

1. 객체 인식 개요

영상인식은 크게 영상 식별(Image classification) 그리고 영상 인식(Image detection) 또는 객체 인식(Object detection)으로 분류되는데,

영상 식별은 특정한 이미지가 개에 가까운지 또는 고양이에 가까운지를 판단하는 것이라면

영상 인식은 이미지 안에 개도 있고 고양이가 있다면 고양이는 어디에 있는지, 개는 어디에 있는지를 판단하는 것이라고 할 수 있다.

어떻게 보면 영상 인식은 영상 식별의 하위 개념으로 볼 수 있는데

rCNN의 원리 또한 입력 이미지를 특정한 알고리즘으로 여러가지 영역(Region)으로 분류한 다음 CNN(합성곱 뉴럴넷)을 적용하여 부분 부분의 이미지를 식별하는 것과 유사하다. 

다만 이미지를 잘개 쪼개고 각각에 대해서 CNN알고리즘을 적용하다보면 매우 높은 연산 량이 필요하므로 실시간 처리에 적용하기에는 매우 불리하다. 

2. YOLO

실제로 인간의 시각은 들어온 영상에서 영역을 자르고 해당 영역을 식별하는 순서로 처리하지 않는다.

대신 한번에 들어온 전체 이미지에서 특징점을 얻어내고 기존에 학습된 특징점과 비교하여 확률이 높은 영역을 찾는 방식으로 동작한다. 

Joseph Redmon, Santosh Divvala, Ross Girshick, Ali Farhadi 은 인간 시각의 이러한 특징에 착안하여 영상 인식을 회귀(Regression)문제로 접근하였다. 그래서 제안된 방법이 YOLO(You Only Look Once)이다.

YOLO는 단일 신경망에서 한번의 예측 단계로 모든 객체를 동시에 탐지하므로 매우 빠르게 동작한다. 

논문의 원문은 다음에서 찾을 수 있다.

https://arxiv.org/pdf/1506.02640

그리고 이 논문에서 제안하는 알고리즘은 darknet이라는 이름으로 오픈소스로 공개되었다.

 

보다 자세한 설명은 다음 링크를 참조하기 바란다.

https://www.datacamp.com/blog/yolo-object-detection-explained

 

https://youtu.be/69Ii3HjUiTM?si=2RIyr9XaHH-1VS00

2025년 2월 현재 YOLO는 v11까지 발표되었다.

https://docs.ultralytics.com/models/yolo11/

 

YOLO11 🚀 NEW

Discover YOLO11, the latest advancement in state-of-the-art object detection, offering unmatched accuracy and efficiency for diverse computer vision tasks.

docs.ultralytics.com

본문에서는 YOLOv4를 기준으로 객체 인식하는 과정을 설명한다.

 

3. YOLO 인식 과정 요약

YOLO 알고리즘이 동작하기 위해서는 다음과 같은 과정이 필요하다.

1. 식별하고자 하는 이미지가 포함된 이미지 셋(Image set)을 준비한다.

2. 이미지셋에서 식별하고자 하는 이미지를 라벨링 한다.

3. 이미지셋을 훈련용시험용으로 분류한다.

4. 신경망 네트워크 설정 파일(cfg파일)을 YOLO 버전, 이미지 클래스, GPU사양에 맞게 수정한다. 

5. YOLO 버전에 맞는 pre-trained weight함수 파일을 다운로드 한다. 

6. darknet을 실행하여 트레이닝을 실행한다. 여기서 final weight 함수 파일이 생성된다.

7. 6에서 생성한 weight 함수 파일과 설정파일을 darknet_ros와 같은 runtime 프레임 워크에 설치한다.

 

4. 시스템 준비하기

참고로 본 글은 RTX3070이 설치된 ASUS의 Rog Strix Scar G533Z 랩탑에서 수행되었다.

자세한 사양은 다음과 같다.

- CPU: 14-Core Intel i9-12900H

- RAM: 16GB DDR5

- GPU: NVIDIA GeForce RTX 3070 Ti 8GB

- OS: Ubuntu 20.04 LTS

4. 1. darknet 설치

YOLO 알고리즘의 오픈소스 버전은 darknet이라는 이름으로 깃허브에 공개되었다.

본 글은 YOLOv4기준으로 작성된 Alexey의 https://github.com/AlexeyAB/darknet 의 darknet을 fork하여 수정한 버전으로 설치하였다. CUDA 버전12 이후에서 발생하는 오류를 해결한다.

아래 repository에서 다운받으면 된다.

https://github.com/kyuhyong/darknet

 

GitHub - kyuhyong/darknet: YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Da

YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Darknet ) - kyuhyong/darknet

github.com

 

4. 1. 1. CUDA 설치하기

darknet은 GPU의 성능을 최대한으로 끌어내기 위해 C를 기반으로 CUDA 아키텍쳐를 사용하여 작성되었다.

그런 이유로 darknet을 정상적으로 설치하기 위해서는 n사의 GPU와 함께 CUDA가 설치되어야 한다.

참고로 본 글은 다음 CUDA 버전에서 작성되었다.

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Tue_Jun_13_19:16:58_PDT_2023
Cuda compilation tools, release 12.2, V12.2.91
Build cuda_12.2.r12.2/compiler.32965470_0

CUDA의 자세한 설치 방법은 다음에 설명한다.

4. 1. 2. OpenCV 설치하기

영상 처리를 다루므로 opencv역시 설치되어야 한다.

CUDA를 지원해야 하므로 apt install로 설치하면 안되고 직접 opencv패키지를 다운로드해서 CUDA지원을 활성화한 상태로 cmake 하여 빌드 인스톨한다.

참고로 현재 설치된 opencv 버전은 다음과 같다.

$ pkg-config --modversion opencv
4.8.0

 

4. 1. 3. Makefile 수정하기

각자의 시스템에 맞춰서 Makefile을 수정한다.

- GPU=1 :CUDA 가속 기능을 켠다(/usr/local/cuda에 설치되어있을 것)

- CUDNN=1 :CUDA의 뉴럴넷 가속 기능(cuDNN)을 켠다(/usr/local/cudnn에 설치되어있을 것)

- CUDNN_HALF=1 : 검출과 트레이닝 속도를 가속하기 위한 Tensor Core를 빌드한다.

- OPENCV=1: 카메라 영상, 비디오 입력을 처리하기 위해 사용한다.

GPU가 지원하는 아키텍쳐에 맞는 ARCH 넘버를 지정한다.

ARCH= -gencode arch=compute_35,code=sm_35 \
      -gencode arch=compute_50,code=[sm_50,compute_50] \
      -gencode arch=compute_52,code=[sm_52,compute_52] \
	  -gencode arch=compute_61,code=[sm_61,compute_61]


 터미널에서 darknet 루트 폴더로 이동한 다음 make 명령으로 빌드한다.

 

5. 이미지셋 만들기

5. 1. 이미지 모으기

darknet 폴더 안에 인식하고자 하는 대상이 포함된 여러 이미지 데이터 폴더를 만든다.

예를 들어 "image_data" 라는 폴더 안에 "images"라는 폴더를 만들고 여러 이미지들을 image_##.jpg 등으로 정리하여 한곳에 넣는다.

폴더 구조는 다음과 같다.

darknet
├── image_data
│   ├── images
|   │   ├── image_1.jpg
│   |   ├── image_2.jpg
|   |   |   ...
│   |   └── image_n.jpg

- 다양한 배경과 조명 환경에서 촬영된 이미지가 필요하다.

 

 

5. 2. 이미지 라벨링 하기

이미지에 사각 박스를 그리고 각각의 class를 지정하는 과정이다.

5. 2. 1 프로그램 다운로드

이 작업을 위해 다음 프로그램이 도움이 된다. 
https://github.com/HumanSignal/labelImg

 

GitHub - HumanSignal/labelImg: LabelImg is now part of the Label Studio community. The popular image annotation tool created by

LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out Label Studio, the open source ...

github.com

5. 2. 2. classes.txt 파일 준비

먼저 앞서 만든 image_data 폴더에 classes.txt 파일을 하나 만들고 각 행마다 class 이름을 입력하고 저장한다.

만약 구별하고자 하는 항목이 clock, toy_car, mouse 라면 classes.txt파일은 다음과 같다.

clock
toy_car
mouse

 5.2.1 에서 다운로드한 labelimg 폴더로 이동하여 python3 labelimg.py 를 실행하면 다음과 같은 화면이 나타난다.

 

Open Dir을 눌러 위에서 만든 image_data 폴더를 연다.

해당 이미지에서 검출하고자 하는 물체 주변으로 박스를 그린다. 각 박스마다 해당하는 class를 지정한다.

이렇게 하면 각 image_##.jpg 마다 해당되는 class의 위치가 저장된 image_##.txt 파일이 생성된다.

 

5.3 이미지 분류하기 

라벨링된 이미지와 각 이미지의 class위치가 저장된 txt 파일이 모두 얻어졌다면,

해당 파일들을 각각 훈련용 데이터셋과 테스트용 데이터 셋으로 분류하고 각 파일의 경로를 지정해주어야 한다.

Train 데이터와 Test 데이터의 비율은 보통 7:3 정도가 적절하다고 한다.

darknet 폴더에서 다음명령을 실행한다. (이미지 데이터가 image_data폴더인 경우)

python split_images.py image_data 

이 프로그램은 자동으로 image_data 안의 images 폴더를 검색하여 train.txt 파일과 test.txt 파일을 생성한다.

이제 폴더 구조가 다음과 같이 변경되었다.

darknet
├── image_data
│   ├── images
|   |   ├── classes.txt
|   |   ├── image_n.jpg
|   |   ├── image_n.txt
|   |   └── 
│   ├── test.txt
│   └── train.txt

5. 4. yolo 설정파일 cfg 파일 만들기

image_data/cfg 폴더 안에 사용하고자 하는 YOLO 버전에 맞는 cfg 설정 파일을 만들어야 한다.

yolov4-tiny 버전을 사용할 예정이므로 darknet/cfg 폴더에서 yolov4-tiny.cfg 파일을 복사해서 

image_data/cfg 폴더에 넣는다.

인식할 이미지 클래스의 갯수, 사용하는 GPU 메모리등에 따라 수정이 필요하다.

수정할 부분은 다음과 같다. (https://eehoeskrap.tistory.com/370 글 참조)

  • batch
    • GPU성능에 따라 달라진다.
    • 기본 값은 64
    • 3070Ti의 경우 4보다 큰 값을 넣으면 실패한다.
  • subdivisions
    • 배치 사이즈인 64를 얼마나 쪼개서 학습을 할건지에 대한 설정 값
    • 기본 값은 8 이지만 Out of memory 에러가 날 경우 16 또는 32 또는 64 로 조절하여 학습을 시도함
  • width 및 height
    • 기본 값은 416 이지만 608로 변경하여 학습 할 수 있음
    • 608로 변경 시 정확도가 좋아질 수 있음
  • 입력되는 데이터로부터 다양한 데이터를 학습하기 위한 설정 값
    • angle
      • augmentation에 관련된 값으로서, 이미지를 - + 몇 도 돌릴 것인지에 대한 설정 값
      • 보통 0으로 두거나, 다양한 각도에서 학습하고 싶은 경우 30 ~ 45 정도, 경우에 따라 90도 가능함
    • saturation
      • augmentation에 관련된 값으로서 이미지에 채도를 추가하고자 할 때 설정하는 값
    • exposure
      • augmentation에 관련된 값으로서 노출 값을 추가하고자 할 때 설정하는 값
    • hue
      • augmentation에 관련된 값으로서 색상을 변경하고자 할 때 설정하는 값

 

  • learning_rate
    • 보통 0.001 
    • multi-gpu 사용 시 학습률을 0.001 / gpu 수 만큼 조절하기도 함
      • 예를 들어 GPU 2장을 이용한 학습 시 0.001 / 2 = 0.0005 값을 사용
  • burn_in
    • 보통 1000 
    • multi-gpu 사용 시 몇 만큼의 iteration 이 지날 때 마다 학습률을 조정 할 것인지에 대한 값
    • multi-gpu 사용 시 1000 * gpu 수 만큼 조절함
      • 예를 들어 GPU 2장의 경우 1000 * 2 = 2000 으로 설정
  • max_batches
    • 언제까지 iteration을 돌건지 설정하는 값
    • 보통 class 수 * 2000 으로 설정 (넉넉하게 4000을 곱하는 경우도 있음)
      • 1 class 의 경우 (1 * 2000) + 200 = 2200
      • 80 class 의 경우 (80 * 2000) + 200 = 160,200 
      • 뒤에 붙인 200 값은 전 후로 알맞은 가중치를 얻기 위함임 
  • policy
    • 보통 steps
  • steps
    • 위에서 설정한 max_batches 사이즈(200을 더하지 않은..)의 80% 와 90%를 설정
      • 예를 들어 80 class 의 경우 128000,144000 으로 설정
  • scales
    • 보통 .1,.1

출처: https://eehoeskrap.tistory.com/370 [Enough is not enough:티스토리]

 

수정한 부분은

batch=4 (GPU의 메모리 용량에 따라 16, 64등 더 큰 숫자를 할 수 있다. 참고로 3070Ti에서는 4보다 크면 실패함)

classes=2

 

[convolutional]
...
filters=21

...

filters= (4 + 1 + 클래스 수) * 3

 

참고로 2개의 클래스가 있는 경우의 cfg 파일이다.

[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=4
subdivisions=1
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.00261
burn_in=1000

max_batches = 4000
policy=steps
steps=3200,3600
scales=.1,.1


#weights_reject_freq=1001
#ema_alpha=0.9998
#equidistant_point=1000
#num_sigmas_reject_badlabels=3
#badlabels_rejection_percentage=0.2

[convolutional]
batch_normalize=1
filters=32
size=3
stride=2
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=2
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[route]
layers=-1
groups=2
group_id=1

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[route]
layers = -1,-2

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky

[route]
layers = -6,-1

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[route]
layers=-1
groups=2
group_id=1

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[route]
layers = -1,-2

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[route]
layers = -6,-1

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[route]
layers=-1
groups=2
group_id=1

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[route]
layers = -1,-2

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[route]
layers = -6,-1

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

##################################

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=21
activation=linear

[yolo]
mask = 3,4,5
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=2
num=6
jitter=.3
scale_x_y = 1.05
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
ignore_thresh = .7
truth_thresh = 1
random=0
resize=1.5
nms_kind=greedynms
beta_nms=0.6
#new_coords=1
#scale_x_y = 2.0

[route]
layers = -4

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = -1, 23

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=21
activation=linear

[yolo]
mask = 1,2,3
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=2
num=6
jitter=.3
scale_x_y = 1.05
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
ignore_thresh = .7
truth_thresh = 1
random=0
resize=1.5
nms_kind=greedynms
beta_nms=0.6

 

image_data폴더에 "detector_data.txt"파일을 다음과 같이 만들어준다.

classes=3
train=image_data/train.txt
valid=image_data/test.txt
names=image_data/images/classes.txt
backup=image_data

 

이제 폴더 구조가 최종적으로 다음과 같이 만들어졌다.

darknet
├── image_data
│   ├── cfg
|   |   └── yolov4-tiny.cfg
│   ├── detector.data
│   ├── images
|   |   ├── classes.txt
|   |   ├── image_n.jpg
|   |   ├── image_n.txt
|   |   └── ...
│   ├── test.txt
│   └── train.txt

 

5. 5. 기본 weight함수 파일 다운로드 하기

weight함수를 생성하기 위해서는 yolo네트워크에 맞게 기본 설정된 weight함수 파일이 필요하다.

darknet/weight 폴더에 yolov4-tiny.conv.29 를 다운로드 하기 위해 https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.conv.29 파일을 다운로드한다.

 

5. 6. 트레이닝 하기

다음과 같이 darknet 명령을 실행하여 weight 함수 파일을 생성한다.

./darknet detector train image_data/detector.data image_data/cfg/yolov4-tiny.cfg weights/yolov4-tiny.conv.29 -map >> log/image_data.log

-map 옵션을 주면 훈련 과정이 그래프로 표시된다.

 

 

 

클래스의 갯수, GPU의 성능에 따라 트레이닝이 수행된 후 final weight 파일이 생성된다.

 Tensor Cores are used.
v3 (iou loss, Normalizer: (iou: 0.07, obj: 1.00, cls: 1.00) Region 30 Avg (IOU: 0.803308), count: 14, class_loss = 0.416282, iou_loss = 0.929667, total_loss = 1.345949 
v3 (iou loss, Normalizer: (iou: 0.07, obj: 1.00, cls: 1.00) Region 37 Avg (IOU: 0.787318), count: 8, class_loss = 0.853544, iou_loss = 8.100082, total_loss = 8.953627 
 total_bbox = 161341, rewritten_bbox = 0.000000 % 

 Tensor Cores are used.
v3 (iou loss, Normalizer: (iou: 0.07, obj: 1.00, cls: 1.00) Region 30 Avg (IOU: 0.918996), count: 22, class_loss = 0.001562, iou_loss = 4.227271, total_loss = 4.228833 
v3 (iou loss, Normalizer: (iou: 0.07, obj: 1.00, cls: 1.00) Region 37 Avg (IOU: 0.891980), count: 24, class_loss = 0.041704, iou_loss = 6.550589, total_loss = 6.592293 
 total_bbox = 161387, rewritten_bbox = 0.000000 % 

 Tensor Cores are used.
12Total Detection Time: 0 Seconds
Saving weights to image_data/yolov4-tiny_4000.weights
Saving weights to image_data/yolov4-tiny_last.weights
Saving weights to image_data/yolov4-tiny_final.weights

 

이제 이 final.weight 파일을 가져다 쓰면 된다.

반응형
반응형

무안공항에서 제주항공 2216편 참사가 발생한지 정확히 1달만인 2025년 1월 29일, 미국에서 가장 붐비는 공역 중 하나인 수도 워싱턴DC 레이건 공항에 착륙중이던 아메리칸 항공 CRJ 여객기가 미 육군 UH-60 헬기와 충돌, 탑승객 67명 전원이 사망하는 참사가 발생하였다.

 미국의 수도 한복판에서 그것도 비행기 고장이나 비상상황이 아닌 정상적으로 운항중인 항공기간의 충돌로 빚어진 사고라는 점 때문에 매우 충격적으로 다가왔다. 실제로 미국의 주요 매체에서 가장 Top으로 다루는 뉴스이고 많은 미국인들의 관심도 짐중된 사건이다.

 주요 공항 타워는 물론 대부분의 지역 관제 ATC까지 실시간으로 공개되는 미국 답게 연방교통안전국(NTSB)에서 사고 브리핑을 하기도 전에 해당 사고 관련 관제 녹음이 공개되어 유투브는 물론 주요 뉴스에서 헤드라인으로 다뤄졌다.

 

 이 글에서는 자세한 사고 경과나 원인을 분석하기 보다는 한국과 미국 양쪽에서 거의 비슷한 시기에 발생한 사고를 어떻게 다루고 있는가에 대해 중점적으로 다뤄보도록 하겠다.

 사실 이번 포토맥 강 충돌사고는 제주항공 사고와 달리 민간항공뿐 아니라 미국 정부 자산인 육군에서 운용하는 항공기도 관여되어 있기에 사고 원인에 따라 정치적으로 매우 민감할 수 있는 사안이다. 따라서 경우에 따라  혹시 미국 정부에 불리한 증거나 사실관계를 숨기려고 하는 거 아닌가 하는 음모론적 시각으로 볼 수 있다. 실제로 무안공항의 콘크리트로 만들어진 로컬라이저 둔덕이 참사의 원인으로 지목되자 한국 정부 (국토부)에서 항공 안전 기준에 맞춰서 설계 했다며 발빰해는 모습을 보면  그런 의심이 들 수 도 있겠다.

 

그럼 사고 2일 후 NTSB에서 발표한 브리핑 내용을 보자.

https://www.youtube.com/live/6WzoEb0m8x4?si=RAFVpmfC7AQgeGs8

 

사고 발생 당시의 ATC가 언론을 통해 이미 공개되었지만 NTSB에서 다시 시간별로 교신 내용을 다시 하나하나 명확하게 확인해준다.

이 브리핑을 통해 관제사가 헬기 조종사에게 CRJ 여객기를 육안 하였는지 여부를 확인하는 부분이 드러났다.

그리고 당시 관제사와 여객기, 그리고 관제사와 헬기 조종사간의 통신 환경 등을 구체적으로 설명하는 부분도 보인다.

(민간 항공기들은 VHF 주파수로 통신하는 반면 군 항공기들은 UHF 주파수로 통신하기 때문에 서로 상대방의 존재를 명확하게 인식하기 어려운 점도 사고에 기여한 측면이 있다)

기자들에게 최대한 자세하게 사실관계에 기반하여 설명하고있다.

 

이에 반해 국토부의 브리핑 내용은 어떠한가?

이 브리핑도 사고 2일 후인 1월1일에 발표한 내용이다.

https://youtu.be/e1ibHBpSnFA?si=7AooAghWbrfgw007

 

시작부터 뭔가 밝히기 어렵다는 말만 한다.

교신 내용을 공개하지 않는것도 문제지만


교신 내용에 뭐가 불명확한지도 모르는건 더 문제다.

 

국토부 항공안전정책관이라는 사람이 나와서 저런말을 하는것은 대한민국 항공 안전을 책임지고 근무하는 항공교통 관련 근무자들을 명백히 우롱하는 행위다. 

 조종사, 관제사들은 항상 명확한 관제 지시를 주고받기 위해 시험도 보고 정기적으로 훈련을 한다.

이 모든 것은 바로 이러한 급박한 상황에서도 불명확한 교신이나 오해가 발생하지 않게끔 하기 위함이다.

대체 국토부에서는 무얼 근거로 공개 주파수인(누구나 들을 수 있는) 항공교통 관제 녹취를 발표하지 않고 숨기고 있는지 분명하게 밝혀야할 일이다. 그러면 사고 경위 파악이 훨씬 쉽고 누구나 이해할 수 있게 된다.

반응형

+ Recent posts