NurseMate
간호사를 위한 AI 알약 인식과 간호 타이머 iOS, watchOS 앱. App Store 출시
간호사를 인터뷰하고 설문하며 문제를 정의했고, 북극성 지표를 설계해 사용자 활동을 분석했습니다. 이 지표를 개선하기 위해 51개의 실험을 돌려 181개의 모델을 학습시켰습니다. 학습한 모델은 Core ML로 iOS에 이식했고, 다양한 기기에서 RAM과 GPU 사용량을 분석하며 모델별로 연산 유닛(ANE, GPU, CPU)을 나눠 적재하는 메모리 최적화를 진행했습니다. 그 결과 저성능 기기에서도 사용자 경험을 보장하고, 기존 타 서비스 기준 평균 2분 이상 걸리던 알약 식별 시간을 1분 이내로 줄였습니다.
-
문제
알약 검색의 병목은 각인 하나였습니다.
- 앱 분석에서 사용자가 손으로 고치는 속성은 압도적으로 각인. 색, 모양, 제형 수정은 거의 0
- 앱에 각인 추출이 없어 사용자가 매번 직접 입력
- 각인 없이 검색하면 25,246종 중 정답의 중앙 순위가 1,248위, top-1 0%
- 각인은 잉크가 아니라 음각이라 표면과 같은 색이고 그림자로만 보임. 문서용 OCR은 정확도 0.7%
-
시도 1
상용 비전 언어 모델(Gemini)로 판독, 검색, 검증을 잇는 파이프라인을 만들고 실사진 69알약 138면으로 전수 측정했습니다.
- 판독만 붙여도 top-1 0%에서 53.6%. 후보 20개를 다시 보여 주는 검증 단계를 더해 58.0%
- 이득의 절반은 판독기 뒤에서 나왔습니다. API 호출 없이 랭커의 순위 감쇠와 속성 가중치만 조정해 top-20 +13.0%p
- 후보 목록을 함께 보여 주면 같은 모델의 판독 정확도가 59.4%에서 69.6%로 상승
- 앞뒤 두 면을 찍으면 한 면 대비 top-1 +17.4%p. 모델 교체보다 여섯 배 큰 레버
- 전처리 18종, 확대, 더 큰 모델, 곡선 정렬은 전부 효과 0. 사람도 블라인드로는 37.1%만 읽고 45.7%는 못 읽는 사진이라 판독기 자체는 한계
-
시도 2
온디바이스로 돌릴 자체 각인 판독기(CRNN + CTC)를 학습했습니다. 식약처 참조 사진 23,750알약 47,500면을 약포지 촬영 조건으로 열화시켜 학습 데이터로 썼습니다.
- 팀이 쓸 라벨링 도구를 직접 만들어 평가셋을 69알약에서 291알약(559면)으로 늘렸습니다. 이것만으로 "정밀도 100%"가 표본 탓이었음이 드러나 이전 결론 여러 개를 뒤집었습니다
- 지표를 고정 임계값 대신 "정밀도 90% 지점에서 통과하는 면 수"로 다시 설계. 선별은 1시드, 채택은 3시드 규칙
- 고확신 오답 4건 중 3건이 글자는 읽는데 회전 방향을 잘못 고른 경우. 증강이 ±20°만 덮은 탓이라, 뒤집힌 면에 빈 정답을 가르치는 학습으로 한때 12에서 41알약으로 올렸으나, 최종 구조(TPS, FRM)에서 다시 재니 손해라 닫았습니다
- 학습 없이 추론만 바꿔 확대 TTA와 후보 단위 시드 앙상블을 더하고, 학습량을 20에폭에서 60에폭으로 늘렸습니다. 앙상블은 모델이 셋이라 폰에 올릴 수 없어 측정만 하고, 최종 채택은 단일 시드 모델입니다
- 증강, 전처리, MIM 사전학습, 백본 교체, 학습률, 가중치 평균 등 24개 실험은 전부 기준 미달로 닫았습니다
정밀도 90% 지점 통과 수 (실사진 감사셋 331면, 192알약) 구성 면 알약 20에폭 단일 모델 188 124 20에폭, 확대 TTA, 3시드 합의 앙상블 206 130 40에폭, 3시드 합의 앙상블 210 128 60에폭 단일 모델 (앱 탑재) 240 150 60에폭, 확대 TTA, 3시드 합의 앙상블 (측정만, 미채택) 248 153 -
시도 3
남은 실패의 원인을 해부하고, 모델을 바꾸지 않고 후보를 좁혔습니다.
- 실패는 알약이 아니라 사진에 달렸습니다. 같은 알약을 두 번 이상 찍은 57건 중 22건이 사진에 따라 성공과 실패가 갈렸고, 해상도, 대비, 선명도와의 상관은 전부 |r| 0.13 이하
- 오라클 진단: 144개 후보 안에 정답이 있는 비율 84%. 선택 실패 12%, 인식 실패 16%
- 판독기 답을 "확신도 0.95를 넘는 글자 전부"로 바꾸고 부분 수열로 대조해, 학습 없이 후보 중앙값 1,248개에서 19개(정답 유지 93%)
- 이미지 임베딩은 각인 대체로는 실패(+1.5%p)했지만, 각인으로 좁힌 뒤의 순위에만 쓰고 특징을 마크 모델에서 뽑자 후보 안 1위 67.5%, 5위 안 88.7%. 마크 필터는 임베딩과 겹쳐 순손해라 껐고, 카탈로그 임베딩 72MB는 서버에 두어 기기는 12KB만 보냄
-
결과
- 각인 검색 top-1 0%에서 58.0%, top-3 0%에서 71.0% (69알약 138면)
- 자체 판독기 정밀도 90% 통과 188면에서 240면 (최종 채택 단일 모델). 3시드 앙상블은 248면으로 측정만 하고 채택하지 않음
- 마크(제조사 기호) 유무 모델은 일곱 번 실패한 뒤 원인이 앞뒤 면 배정임을 찾아 전용 ConvNeXt로 교체. 정답 해석 오류까지 바로잡자 AUC 0.82에서 0.99, 같은 정밀도에서 재현율 36%에서 80%
- fp16 ONNX 변환으로 마크 모델 111.7MB를 55.9MB로 줄이고 판정이 바뀐 면 0건을 확인. 전처리 한 줄 차이가 fp16보다 70배 크게 흔들려, 텐서 대조와 크롭 대조를 나누는 2단계 검증을 iOS 이식 절차로 정함
- Core ML로 실기기에 올리며 모델별 연산 장치를 재서 정했습니다. fp32는 Neural Engine에 못 올라가 마크 모델만 fp16으로 바꿔 추론 244ms에서 60ms, 각인은 GPU와 CPU 두 레인으로 나눠 iPhone 12 판독 1장 9.2초에서 5.4초
- App Store 출시, 출시 초기 사용자 3,600명
| 항목 | 전 | 후 | 어떻게 |
|---|---|---|---|
| 각인 검색 top-1 (69알약) | 0% | 58.0% | 판독, 검색, 검증 파이프라인과 랭커 조정 |
| 판독기 정밀도 90% 통과 면 (331면) | 188면 | 240면 | 60에폭 단일 모델, 확대 TTA. 3시드 앙상블(248면)은 측정만 |
| 후보 수 중앙값 (감사셋 347면) | 1,248개 | 19개 | 확신 글자 전부로 부분 수열 대조 |
| 좁힌 후보 안 1위 적중 (347면) | 45.6% | 67.5% | 마크 모델 특징으로 임베딩 재정렬 |
| 마크 유무 AUC (AI Hub 475면) | 0.82 | 0.99 | 전용 ConvNeXt와 정답 해석 교정 |
| 판독 1장 (iPhone 12, 알약 6개) | 9.2초 | 5.4초 | 각인 GPU·CPU 두 레인, 마크 fp16 Neural Engine |
App Storeapps.apple.com/kr/app/id6783877557 GitHubgithub.com/Two-Park-One-Bae/iOS 실험 기록각인 판독 실험 전체
iPhone
iPhone
Apple Watch