PaddleOCR Detection 모델 학습 가이드
이 문서는 현재 진행 중인 한국어 OCR Detection 모델 학습 프로젝트를 기반으로 작성되었습니다.
1. 학습 데이터 이해하기
1.1 데이터셋 구조
현재 프로젝트는 AIHub의 다중언어 OCR 데이터셋(한국어+영어)을 사용합니다.
원본 데이터 위치: S:\OCR_Data\
S:\OCR_Data\
├── Training\ # 학습용 데이터
│ ├── 01_data\ # 이미지 파일들
│ │ ├── TS_OCR_KE_CT\
│ │ ├── VS_OCR_KE_CT\
│ │ └── ...
│ └── 02_data\ # JSON 라벨 파일들
│ ├── TL_OCR_KE_CT\
│ ├── VL_OCR_KE_CT\
│ └── ...
└── Validation\ # 검증용 데이터
├── 03_data\ # 이미지 파일들
└── 04_data\ # JSON 라벨 파일들
변환된 데이터 위치: core/paddle_train/data/
core/paddle_train/data/
├── det\
│ ├── train_label.txt # 학습용 라벨 (164,998 라인)
│ └── val_label.txt # 검증용 라벨
├── image_index_train.pkl # 이미지 인덱스 캐시
└── image_index_val.pkl # 검증 이미지 인덱스 캐시
1.2 라벨 파일 형식 이해하기
PaddleOCR Detection 라벨 형식 (train_label.txt 예시):
이미지경로<TAB>JSON형식의어노테이션
실제 예시 (첫 번째 라인):
S:\OCR_Data\Training\01_data\TS_OCR_KE_CT\OCR_KE_C2_000006.jpeg [{"transcription": "가야", "points": [[1062, 629], [1313, 624], [1308, 763], [1062, 761]], "difficult": 0}, {"transcription": "문명의", "points": [[1338, 632], [1695, 622], [1690, 768], [1338, 758]], "difficult": 0}, ...]
각 필드 설명:
이미지경로: 전체 경로 (예:S:\OCR_Data\Training\01_data\TS_OCR_KE_CT\OCR_KE_C2_000006.jpeg)<TAB>: 탭 문자로 구분JSON 배열: 여러 텍스트 영역 정보를 담은 배열
각 텍스트 영역 (annotation) 구조:
{
"transcription": "가야", // 인식할 텍스트
"points": [[x1,y1], [x2,y2], [x3,y3], [x4,y4]], // 4개 점 좌표 (사각형의 네 모서리)
"difficult": 0 // 0=정상, 1=어려운 샘플 (선택적)
}
좌표 시스템:
- 이미지 좌상단이 원점 (0, 0)
points[0]: 좌상단points[1]: 우상단points[2]: 우하단points[3]: 좌하단
실제 예시 분석:
"transcription": "가야"
"points": [[1062, 629], [1313, 624], [1308, 763], [1062, 761]]
이것은:
- 이미지에서 (1062, 629) 위치에 "가야"라는 텍스트가 있음
- 텍스트 박스의 크기: 가로 약 251픽셀 (1313-1062), 세로 약 137픽셀 (763-626)
1.3 라벨 파일 직접 확인하는 방법
방법 1: 텍스트 에디터로 열기
# train_label.txt 파일 열기
notepad core\paddle_train\data\det\train_label.txt
방법 2: Python으로 읽어서 분석
# 라벨 파일 읽기 예제
label_file = "core/paddle_train/data/det/train_label.txt"
with open(label_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 첫 번째 라인 분석
first_line = lines[0]
image_path, annotation_json = first_line.strip().split('\t', 1)
print(f"이미지 경로: {image_path}")
print(f"어노테이션 개수: {len(annotation_json)} 문자")
# JSON 파싱
import json
annotations = json.loads(annotation_json)
print(f"텍스트 영역 개수: {len(annotations)}개")
# 첫 번째 텍스트 영역 상세 정보
first_ann = annotations[0]
print(f"텍스트: {first_ann['transcription']}")
print(f"좌표: {first_ann['points']}")
방법 3: 통계 정보 확인
label_file = "core/paddle_train/data/det/train_label.txt"
total_images = 0
total_annotations = 0
text_lengths = []
with open(label_file, 'r', encoding='utf-8') as f:
for line in f:
image_path, annotation_json = line.strip().split('\t', 1)
annotations = json.loads(annotation_json)
total_images += 1
total_annotations += len(annotations)
for ann in annotations:
text_lengths.append(len(ann['transcription']))
print(f"총 이미지 수: {total_images:,}개")
print(f"총 텍스트 영역 수: {total_annotations:,}개")
print(f"이미지당 평균 텍스트 영역: {total_annotations/total_images:.1f}개")
print(f"평균 텍스트 길이: {sum(text_lengths)/len(text_lengths):.1f}자")
현재 프로젝트 실제 데이터:
train_label.txt: 164,998 라인 (164,998개 이미지)val_label.txt: 약 20,700개 이미지
1.4 이미지와 라벨 매칭 확인하기
시각화 스크립트 예제:
import cv2
import json
import numpy as np
# 라벨 파일에서 한 라인 읽기
label_file = "core/paddle_train/data/det/train_label.txt"
with open(label_file, 'r', encoding='utf-8') as f:
line = f.readline()
image_path, annotation_json = line.strip().split('\t', 1)
annotations = json.loads(annotation_json)
# 이미지 읽기 (한글 경로 대응)
img_array = np.fromfile(image_path, dtype=np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
# 각 텍스트 영역에 박스 그리기
for ann in annotations:
points = np.array(ann['points'], dtype=np.int32)
text = ann['transcription']
# 4각형 그리기
cv2.polylines(img, [points], isClosed=True, color=(0, 255, 0), thickness=2)
# 텍스트 표시
x, y = points[0]
cv2.putText(img, text, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
# 결과 저장
cv2.imwrite("labeled_image.jpg", img)
2. 학습 개념 이해하기
2.1 Detection 모델이란?
OCR Detection은 이미지에서 "텍스트가 어디에 있는지"를 찾는 작업입니다.
입력: 이미지
출력: 텍스트 영역의 좌표 (bounding box 또는 polygon)
예시:
- 입력: 한국어 표지판 사진
- 출력: "가야"는 (1062, 629)에서 (1313, 763) 사각형 영역에 있음
2.2 Fine-tuning이란?
Pretrained 모델: 이미 대규모 데이터로 학습된 모델
- 현재 사용: PP-OCRv4 Detection 모델 (중국어 데이터로 사전 학습됨)
- 경로:
C:/Users/pak10/.paddleocr/models/ch_PP-OCRv4_det_train/best_accuracy
Fine-tuning: 특정 도메인(한국어)에 맞게 추가 학습
- Pretrained 모델의 가중치를 시작점으로 사용
- 한국어 데이터로 추가 학습하여 성능 향상
장점:
- 처음부터 학습하는 것보다 빠름
- 적은 데이터로도 좋은 성능 가능
- 현재 프로젝트: HMean 35% → 89.7% (pretrained → fine-tuned)
2.3 학습 프로세스 이해
학습의 기본 원리:
- Forward Pass (순전파)
- 이미지를 모델에 입력
- 모델이 예측한 텍스트 영역 좌표 출력
- Loss 계산 (손실 계산)
- 예측 좌표 vs 실제 라벨 좌표 비교
- 차이가 클수록 Loss 값이 큼
- 목표: Loss를 최소화하는 것
- Backward Pass (역전파)
- Loss를 이용해 모델의 가중치를 조정
- "어떻게 하면 더 정확하게 예측할 수 있을까?" 계산
- 가중치 업데이트
- 옵티마이저(Adam)가 가중치를 조금씩 수정
- 점점 더 정확해짐
한 번의 Step (반복):
1. 배치(batch) 준비: 16개 이미지 + 라벨
2. Forward: 16개 이미지를 모델에 입력
3. Loss 계산: 예측 vs 실제 비교
4. Backward: 가중치 조정 방향 계산
5. 업데이트: 가중치 조정
Epoch (에포크):
- 전체 데이터셋을 한 번 다 학습하는 것
- 현재 프로젝트: 164,998개 이미지를 모두 학습 = 1 epoch
- 현재 설정: 20 epoch (전체 데이터를 20번 반복 학습)
2.4 주요 개념 정리
Batch (배치):
- 한 번에 학습하는 이미지 개수
- 현재 설정:
batch_size_per_card: 16 - GPU 메모리가 크면 배치 크기를 늘릴 수 있음 (더 빠른 학습)
Step (스텝):
- 한 번의 forward + backward + 업데이트
- 현재 프로젝트: 1 epoch = 약 10,312 steps (164,998 이미지 / 16 배치)
Loss (손실):
- 모델이 얼마나 틀렸는지 측정하는 값
- 작을수록 좋음
- 현재: 1.14 (초기 1.64에서 개선)
Learning Rate (학습률):
- 한 번에 가중치를 얼마나 바꿀지 결정
- 너무 크면: 학습이 불안정
- 너무 작으면: 학습이 느림
- 현재: Cosine 스케줄링 (0.001에서 시작해 점점 감소)
Epoch vs Step:
- Epoch: 전체 데이터를 몇 번 학습할지
- Step: 실제 반복 횟수 (epoch × steps_per_epoch)
3. 현재 프로젝트 상세 분석
3.1 프로젝트 개요
목표: 한국어 표지판/문서에서 텍스트 영역을 정확하게 검출하는 모델 학습
데이터셋:
- 원본: AIHub 다중언어 OCR 데이터셋
- 학습용: 164,998개 이미지 (Training 폴더)
- 검증용: 약 20,700개 이미지 (Validation 폴더)
- 언어: 한국어 + 영어 혼합
모델: PP-OCRv4 Detection (DB 알고리즘)
3.2 모델 구조
Architecture (det_ke_finetune.yml 기준):
입력 이미지 (640x640)
↓
Backbone: PPLCNetV3 (scale: 0.75)
- 특징 추출 네트워크
- 이미지에서 패턴 학습
↓
Neck: RSEFPN (out_channels: 96)
- 특징 피라미드 네트워크
- 다양한 크기의 텍스트 처리
↓
Head: DBHead (k: 50)
- 텍스트 영역 예측
- 확률 맵 생성
↓
출력: 텍스트 영역 좌표
각 컴포넌트 설명:
- Backbone (PPLCNetV3)
- 이미지의 기본 특징 추출
- 텍스트, 배경, 패턴 등을 인식
- Neck (RSEFPN)
- 다양한 크기의 텍스트 처리
- 작은 텍스트와 큰 텍스트 모두 검출 가능
- Head (DBHead)
- 최종 예측 출력
- 각 픽셀이 텍스트인지 아닌지 확률 계산
3.3 학습 설정 상세
Global 설정 (det_ke_finetune.yml):
epoch_num: 20 # 전체 데이터셋을 20번 학습
save_epoch_step: 1 # 매 epoch 완료 시 체크포인트 저장
eval_batch_step: 4000 # 4000 step마다 검증 데이터로 평가
print_batch_step: 10 # 10 step마다 로그 출력
Train 설정:
batch_size_per_card: 16 # GPU당 16개 이미지씩 학습
num_workers: 4 # 데이터 로딩 스레드 4개
이미지 전처리 (Transforms):
- DecodeImage: 이미지 파일 읽기
- DetLabelEncode: 라벨 인코딩
- IaaAugment: 데이터 증강
- 좌우 반전 (50% 확률)
- 회전 (-10도 ~ +10도)
- 크기 조정 (0.5배 ~ 3배)
- EastRandomCropData: 640x640 크기로 크롭
- MakeBorderMap: 경계 맵 생성
- MakeShrinkMap: 축소 맵 생성
- NormalizeImage: 이미지 정규화
Optimizer 설정:
name: Adam
lr:
name: Cosine # 코사인 스케줄링
learning_rate: 0.001 # 초기 학습률
warmup_epoch: 1 # 1 epoch 동안 학습률 점진적 증가
Learning Rate 스케줄링:
- Warmup (1 epoch): 0 → 0.001로 점진적 증가
- 이후: Cosine 감소 (0.001에서 0으로 점진적 감소)
3.4 학습 진행 상황 읽는 방법
로그 파일 위치: output/det_ke_model/train.log
주요 로그 메시지 예시:
[2025/12/29 22:06:52] ppocr INFO: epoch: [2/20], global_step: 16120,
lr: 0.000998, precision: 0.000000, recall: 0.000000, hmean: 0.000000,
loss: 1.140402, loss_shrink_maps: 0.588803, loss_threshold_maps: 0.447291,
loss_binary_maps: 0.117934, loss_cbn: 0.000000,
avg_reader_cost: 0.01158 s, avg_batch_cost: 8.06978 s, avg_samples: 16.0,
ips: 1.98271 samples/s, eta: 15 days, 10:29:13,
max_mem_reserved: 11317 MB, max_mem_allocated: 10599 MB
각 항목 의미:
epoch: [2/20]: 현재 2번째 epoch, 총 20 epochglobal_step: 16120: 전체 누적 step 수lr: 0.000998: 현재 학습률loss: 1.140402: 전체 손실 (작을수록 좋음)loss_shrink_maps: 텍스트 축소 영역 손실loss_threshold_maps: 임계값 맵 손실loss_binary_maps: 이진 맵 손실avg_reader_cost: 0.01158 s: 이미지 읽기 평균 시간avg_batch_cost: 8.06978 s: 배치당 평균 시간ips: 1.98271 samples/s: 초당 처리 이미지 수 (samples per second)eta: 15 days, 10:29:13: 예상 완료 시간max_mem_reserved: 11317 MB: GPU 메모리 사용량
평가(Eval) 로그 예시:
[2025/12/29 21:51:31] ppocr INFO: cur metric, precision: 0.9117859126384815,
recall: 0.8831773716324306, hmean: 0.8972536573555815, fps: 32.61000227232837
precision: 0.912(91.2%): 검출한 것 중 정답 비율recall: 0.883(88.3%): 실제 텍스트 중 검출한 비율hmean: 0.897(89.7%): Precision과 Recall의 조화 평균 (주요 평가 지표)
3.5 성능 지표 이해
Precision (정밀도):
- 모델이 "텍스트다"라고 예측한 것 중 실제로 텍스트인 비율
- 높을수록: 잘못 검출(False Positive)이 적음
- 현재: 91.2%
Recall (재현율):
- 실제 텍스트 중 모델이 검출한 비율
- 높을수록: 놓친 텍스트(False Negative)가 적음
- 현재: 88.3%
HMean (조화 평균):
- Precision과 Recall의 균형
- 공식:
2 × (Precision × Recall) / (Precision + Recall) - 주요 평가 지표로 사용
- 현재: 89.7%
Loss (손실):
- 모델의 예측 오차
- 작을수록 좋음
- 현재: 1.14 (초기 1.64에서 개선)
3.6 체크포인트 저장 구조
저장 위치: output/det_ke_model/
파일 종류:
- best_accuracy.* (최고 성능 모델)
- Eval에서 HMean이 향상될 때마다 저장
- 추론/배포에 사용
- 최신: HMean 89.7% (2025-12-29 21:51:31)
- iter_epoch_N.* (Epoch별 체크포인트)
- 각 epoch 완료 시 저장
- 학습 재개에 사용
- 예:
iter_epoch_1.*,iter_epoch_2.*, ...
- latest.* (최신 체크포인트)
- 주기적으로 업데이트
- 최신 학습 상태 저장
파일 형식:
.pdparams: 모델 가중치 (13.72 MB).pdopt: 옵티마이저 상태 (27.07 MB).states: 학습 상태 정보 (epoch, step, lr 등)
3.7 학습 재개 방법
체크포인트에서 학습 재개:
cd C:\Pyg\Tools\PaddleOCR
python tools/train.py \
-c C:\Pyg\Projects\semi\yuzyproject-aimodels\core\paddle_train\configs\det_ke_finetune.yml \
-o Global.checkpoints="C:/Pyg/Projects/semi/yuzyproject-aimodels/output/det_ke_model/iter_epoch_1" \
Train.dataset.label_file_list="C:/Pyg/Projects/semi/yuzyproject-aimodels/core/paddle_train/data/det/train_label.txt" \
Eval.dataset.label_file_list="C:/Pyg/Projects/semi/yuzyproject-aimodels/core/paddle_train/data/det/val_label.txt"
재개 시점 선택:
- 특정 epoch에서 재개:
iter_epoch_1,iter_epoch_2, ... - 최신 상태에서 재개:
latest - 최고 성능 모델에서 재개:
best_accuracy(추천 안 함, eval용)
4. 데이터 변환 프로세스 이해
4.1 변환 스크립트: 01_convert_to_paddle_format.py
목적: AIHub JSON 형식을 PaddleOCR 학습 포맷으로 변환
입력 형식 (AIHub JSON):
{
"Images": {
"file_name": "OCR_KE_C2_000006.jpeg"
},
"Annotation": [
{
"text": "가야",
"polygon_points": [
{"x": 1062, "y": 629},
{"x": 1313, "y": 624},
{"x": 1308, "y": 763},
{"x": 1062, "y": 761}
]
}
]
}
출력 형식 (PaddleOCR Detection):
이미지경로<TAB>[{"transcription": "가야", "points": [[1062,629], [1313,624], [1308,763], [1062,761]], "difficult": 0}]
변환 과정:
- JSON 파일 읽기
- 좌표 형식 변환:
{"x": 1062, "y": 629}→[1062, 629] - 폴리곤 검증 및 정규화
- 중복 점 제거
- 좌표 클램핑 (이미지 범위 내)
- 시계방향 정렬
- Self-intersection 수정
- PaddleOCR 형식으로 저장
실행 방법:
cd core/paddle_train
python 01_convert_to_paddle_format.py \
--data_root S:\OCR_Data \
--output_dir C:\Pyg\Projects\semi\yuzyproject-aimodels\core\paddle_train\data \
--split train \
--task det
4.2 폴리곤 검증 과정
normalize_polygon_points 함수의 역할:
- 중복 점 제거: 1픽셀 이내 거리의 점 제거
- 좌표 클램핑: 이미지 범위를 벗어난 좌표 수정
- 정렬: 일관된 시계방향 정렬
- 검증: Shapely로 유효한 폴리곤인지 확인
- Self-intersection 수정: 교차하는 부분 자동 수정
- 최소 면적 체크: 너무 작은 폴리곤 제거
실제 적용 예시:
# 입력: 유효하지 않은 폴리곤
points = [[1062, 629], [1313, 624], [1062, 761], [1308, 763]] # 순서가 뒤섞임
# normalize_polygon_points 적용 후
normalized = [[1062, 629], [1313, 624], [1308, 763], [1062, 761]] # 시계방향 정렬됨
4.3 이미지 인덱스 캐시
목적: 이미지 파일을 빠르게 찾기 위한 인덱스
생성 파일: image_index_train.pkl, image_index_val.pkl
내용: 파일명 → 실제 경로 매핑
{
"ocr_ke_c2_000006.jpeg": "S:/OCR_Data/Training/01_data/TS_OCR_KE_CT/OCR_KE_C2_000006.jpeg",
"ocr_ke_c2_000011.jpeg": "S:/OCR_Data/Training/01_data/TS_OCR_KE_CT/OCR_KE_C2_000011.jpeg",
...
}
장점: 매번 전체 폴더를 스캔할 필요 없음
5. 학습 모니터링
5.1 실시간 모니터링 방법
방법 1: 로그 파일 확인
# 실시간 로그 확인 (Windows PowerShell)
Get-Content output\det_ke_model\train.log -Wait -Tail 20
방법 2: Python 스크립트로 분석
import re
from datetime import datetime
log_file = "output/det_ke_model/train.log"
# 최신 학습 로그 추출
with open(log_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
# epoch, step, loss 추출
pattern = r'epoch: \[(\d+)/20\], global_step: (\d+).*loss: ([\d.]+)'
latest_info = None
for line in lines:
match = re.search(pattern, line)
if match:
epoch, step, loss = match.groups()
latest_info = {
'epoch': int(epoch),
'step': int(step),
'loss': float(loss)
}
if latest_info:
print(f"Epoch: {latest_info['epoch']}/20")
print(f"Step: {latest_info['step']}")
print(f"Loss: {latest_info['loss']:.4f}")
방법 3: Eval 성능 추이 확인
log_file = "output/det_ke_model/train.log"
pattern = r'cur metric, precision: ([\d.]+), recall: ([\d.]+), hmean: ([\d.]+)'
with open(log_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
eval_results = []
for line in lines:
match = re.search(pattern, line)
if match:
prec, rec, hmean = map(float, match.groups())
eval_results.append({
'precision': prec,
'recall': rec,
'hmean': hmean
})
# 최신 결과
if eval_results:
latest = eval_results[-1]
print(f"최신 성능:")
print(f" Precision: {latest['precision']*100:.2f}%")
print(f" Recall: {latest['recall']*100:.2f}%")
print(f" HMean: {latest['hmean']*100:.2f}%")
5.2 학습이 제대로 되고 있는지 확인
체크포인트 1: Loss가 감소하는가?
- 초기 Loss: 약 1.6~1.8
- 현재 Loss: 약 1.1~1.2
- 감소 추세면 정상
체크포인트 2: Eval 성능이 향상되는가?
- 초기: HMean 35% (pretrained)
- 현재: HMean 89.7%
- 지속적으로 향상되면 정상
체크포인트 3: 모델 저장이 되는가?
best_accuracy.*파일이 주기적으로 업데이트됨iter_epoch_N.*파일이 epoch 완료 시 생성됨
체크포인트 4: GPU 사용률
- 정상: 90% 이상 사용
- 비정상: 0% 또는 매우 낮음 (CPU로 실행 중일 수 있음)
6. 문제 해결 가이드
6.1 "Invalid polygon geometry" 경고
의미: 폴리곤이 유효하지 않아 스킵됨
원인:
- Self-intersecting (교차)
- Zero area (면적 0)
- Out of bounds (이미지 범위 벗어남)
해결: 01_convert_to_paddle_format.py의 normalize_polygon_points 함수가 자동 수정
영향: 일부 샘플은 스킵되지만 학습은 계속 진행
6.2 학습 속도가 느린 경우
확인 사항:
- GPU 사용 여부:
use_gpu: true확인 - 배치 크기: 메모리 여유 있으면 16 → 20 증가
- 이미지 크기: 640 → 512로 감소 고려
- num_workers: 4가 적절한지 확인
현재 속도:
- IPS: 약 2.0 samples/s
- Epoch당: 약 22시간
- 전체 20 epoch: 약 18일
6.3 OOM (Out of Memory) 에러
증상: CUDA out of memory 에러
해결 방법:
- 배치 크기 감소: 16 → 12 → 8
- 이미지 크기 감소: 640 → 512
- num_workers 감소: 4 → 2
설정 파일 수정:
Train:
loader:
batch_size_per_card: 8 # 16에서 8로 감소
그리고:
Train:
transforms:
- EastRandomCropData:
size: [512, 512] # 640에서 512로 감소
7. 학습 결과 활용
7.1 최고 성능 모델 사용
파일 위치: output/det_ke_model/best_accuracy.*
추론용 모델로 변환:
cd C:\Pyg\Tools\PaddleOCR
python tools/export_model.py \
-c C:\Pyg\Projects\semi\yuzyproject-aimodels\core\paddle_train\configs\det_ke_finetune.yml \
-o Global.checkpoints="C:/Pyg/Projects/semi/yuzyproject-aimodels/output/det_ke_model/best_accuracy" \
Global.save_inference_dir="C:/Pyg/Projects/semi/yuzyproject-aimodels/output/det_ke_inference"
결과: output/det_ke_inference/ 폴더에 추론용 모델 생성
7.2 성능 평가
현재 프로젝트 성능:
- Pretrained (시작): HMean 35.2%
- 현재 (Epoch 2): HMean 89.7%
- 개선율: 약 2.5배 향상
목표 달성 여부:
- 85% 이상: 우수
- 90% 이상: 매우 우수
- 현재 89.7%: 거의 목표 달성
8. 실전 팁
8.1 데이터 확인 팁
라벨 파일 통계 확인:
import json
label_file = "core/paddle_train/data/det/train_label.txt"
stats = {
'total_images': 0,
'total_annotations': 0,
'text_lengths': [],
'languages': {'ko': 0, 'en': 0, 'mixed': 0}
}
with open(label_file, 'r', encoding='utf-8') as f:
for line in f:
image_path, annotation_json = line.strip().split('\t', 1)
annotations = json.loads(annotation_json)
stats['total_images'] += 1
stats['total_annotations'] += len(annotations)
for ann in annotations:
text = ann['transcription']
stats['text_lengths'].append(len(text))
# 언어 판별 (간단한 예시)
has_korean = any('\uAC00' <= c <= '\uD7A3' for c in text)
has_english = any(c.isalpha() and ord(c) < 128 for c in text)
if has_korean and has_english:
stats['languages']['mixed'] += 1
elif has_korean:
stats['languages']['ko'] += 1
elif has_english:
stats['languages']['en'] += 1
print(f"총 이미지: {stats['total_images']:,}개")
print(f"총 텍스트 영역: {stats['total_annotations']:,}개")
print(f"평균 텍스트 길이: {sum(stats['text_lengths'])/len(stats['text_lengths']):.1f}자")
print(f"언어 분포: {stats['languages']}")
8.2 학습 중단/재개 베스트 프랙티스
안전한 중단 시점:
- Epoch 완료 직후 (체크포인트 저장됨)
- Eval 완료 직후 (성능 확인됨)
재개 전 확인:
- 체크포인트 파일 존재 확인
- 설정 파일 동일한지 확인
- 데이터 경로 올바른지 확인
8.3 성능 향상을 위한 팁
데이터 측면:
- 데이터 품질이 가장 중요
- 잘못된 라벨은 학습에 악영향
- 다양한 각도, 조명, 배경의 데이터 수집
하이퍼파라미터 조정:
- Learning rate: 너무 크면 불안정, 너무 작으면 느림
- Batch size: GPU 메모리에 맞게 최대한 크게
- Epoch 수: 성능이 수렴할 때까지
현재 프로젝트 권장 사항:
- 현재 설정은 잘 최적화됨
- 추가 조정보다는 학습 완료 대기 권장
9. 용어 사전
Backbone: 특징 추출 네트워크
Neck: 특징 피라미드 네트워크
Head: 최종 예측 출력 네트워크
Batch: 한 번에 학습하는 샘플 그룹
Epoch: 전체 데이터셋을 한 번 학습
Step: 한 번의 forward + backward + 업데이트
Loss: 모델의 예측 오차
Learning Rate: 가중치 업데이트 크기
Optimizer: 가중치를 업데이트하는 알고리즘 (Adam 등)
Checkpoint: 학습 중간 상태 저장 파일
Fine-tuning: 사전 학습된 모델을 특정 도메인에 맞게 추가 학습
Pretrained Model: 미리 학습된 모델
Precision: 검출한 것 중 정답 비율
Recall: 실제 텍스트 중 검출한 비율
HMean: Precision과 Recall의 조화 평균
Polygon: 여러 점으로 이루어진 다각형 (텍스트 영역)
Bounding Box: 텍스트를 감싸는 사각형
Data Augmentation: 데이터 변형을 통한 증강 (회전, 크기 조정 등)
10. 현재 프로젝트 상태 요약
학습 진행:
- Epoch: 2/20 (진행 중)
- Step: 약 16,000+
- Loss: 1.14 (초기 1.64에서 개선)
성능:
- HMean: 89.7% (초기 35.2%에서 약 2.5배 향상)
- Precision: 91.2%
- Recall: 88.3%
체크포인트:
- best_accuracy: 최신 (HMean 89.7%)
- iter_epoch_1: Epoch 1 완료
- latest: 최신 상태
예상 완료 시간:
- 현재 속도 기준: 약 18일
- Epoch당: 약 22시간
'3. 자습 & 메모(실전, 실습, 프로젝트) > 3-2 메모(실전, 프로젝트)' 카테고리의 다른 글
| [MEMO] 학습 데이터셋 정제 작업 메모 (0) | 2025.12.31 |
|---|---|
| [파인 튜닝] PaddleOCR 성능 분석 및 체크포인트 (0) | 2025.12.30 |
| PaddleOCR Detection 파인튜닝 실전 기록 (중간 점검) (0) | 2025.12.28 |
| [Memo] PaddleOCR + AIHub 데이터셋 (0) | 2025.12.26 |
| [LLM] '코딩 AI' 구축하기: 모델 선정부터 에러 해결 (0) | 2025.12.13 |