CycleSequenceMonitor
실시간 사이클 순서 모니터입니다. InferenceHandler 내부에서 자동으로 동작하며, 각 사이클을 하나씩 받아 기대 순서와 비교하고 이탈 시 알림을 생성합니다.
Note:
CycleResultVerifier(배치 검증 API)는 제거되었습니다. 순서 모니터링은InferenceHandler.get_cycles()내부에서 자동으로 수행됩니다.
개요
학습 시 훈련 데이터로부터 기대 클래스 순서(expected_class_sequence)가 자동 추출되어 체크포인트에 저장됩니다.
추론 시 InferenceHandler.build()에서 체크포인트를 로드하면 CycleSequenceMonitor가 자동으로 생성되며,
get_cycles() 호출 시 각 사이클에 아래 필드가 추가됩니다:
| 필드 | 타입 | 설명 |
|---|---|---|
sequence_status |
str \| None |
"ok" (정상) 또는 "duplicate" (중복) |
expected_class_index |
int \| None |
해당 시점에서 기대하던 class index |
sequence_missing |
list[int] \| None |
이 사이클 도착까지 건너뛴 class index 목록 (미검) |
동작 원리
expected_sequence = (1, 2, 6, 9, 7, 10, 8)
↑ cursor
입력: class_index=1 → ok (cursor → 2)
입력: class_index=6 → ok (cursor → 9, missing=[2])
입력: class_index=99 → duplicate (시퀀스에 없는 클래스)
판단 기준
| 케이스 | 상태 | 설명 |
|---|---|---|
| cursor 위치의 기대값과 일치 | ok |
정상 진행 |
| 기대 시퀀스의 이후 위치에 존재 | ok + missing |
건너뛴 클래스들이 missing으로 보고 |
| 기대 시퀀스에 없는 클래스 | duplicate |
중복 |
| 이미 지나간 위치의 클래스 | duplicate |
중복/중복 |
| 첫 번째 기대 클래스 재등장 | 새 super-cycle 시작 | 이전 cycle의 남은 expected → missing |
Super-cycle 순환
한 바퀴(super-cycle)가 끝나면 커서가 자동으로 처음으로 돌아갑니다. 첫 번째 기대 클래스가 중간에 다시 나타나면, 이전 super-cycle을 마무리하고 새 cycle을 시작합니다.
InferenceHandler에서의 사용
별도 설정 없이 자동으로 동작합니다.
on/off 제어
# 현재 상태 확인
error, message, enabled = handler.get_inference_option("sequence_monitor_enabled")
# 비활성화
handler.set_inference_option("sequence_monitor_enabled", False)
# 다시 활성화
handler.set_inference_option("sequence_monitor_enabled", True)
get_cycles() 결과 예시
error, message, cycles = handler.get_cycles()
for cycle in cycles:
for ci in cycle.get("cycle_info", []):
print(
f"class={ci['class_id']}, "
f"status={ci['sequence_status']}, "
f"expected={ci['expected_class_index']}, "
f"missing={ci['sequence_missing']}"
)
출력 예시:
class=1, status=ok, expected=1, missing=[]
class=6, status=ok, expected=2, missing=[2] # class 2 미검
class=99, status=duplicate, expected=9, missing=[] # 중복
class=9, status=ok, expected=9, missing=[]
모듈 단독 사용
InferenceHandler 없이 직접 사용할 수도 있습니다.
생성
from cycle_counter.modules.sequence_monitor.sequence_monitor import CycleSequenceMonitor
# 직접 생성
v = CycleSequenceMonitor(expected_sequence=(1, 2, 6, 9, 7, 10, 8))
# config dict에서 생성 (InferenceHandler 내부 방식)
v = CycleSequenceMonitor.build({"expected_class_sequence": [1, 2, 6, 9, 7, 10, 8]})
사이클 처리
result = v.process_cycle(class_index=1)
# {'status': 'ok', 'expected_class_index': 1, 'missing_class_indices': []}
result = v.process_cycle(class_index=6)
# {'status': 'ok', 'expected_class_index': 2, 'missing_class_indices': [2]}
finalize / reset
에러 코드
| 코드 | 에러 클래스 | 설명 |
|---|---|---|
| 350 | EmptyExpectedSequenceError |
빈 시퀀스로 생성 시도 |
| 351 | MissingExpectedSequenceConfigError |
config에 시퀀스 키가 없음 |
Demo
전체 예시는 demo/demo_cycle_sequence_monitor.py를 참고하세요.