마키나락스
경력근거: 데이터 불균형 및 노이즈 문제를 해결하여 모델 성능을 극대화합니다
마키나락스 FDE본부는 실제 현장 데이터로 결함 탐지 문제를 정의하고, 적은 데이터와 불균형 상황을 다루는 일을 이 포지션에 맡깁니다. 현장 데이터는 검사자가 여럿이고 촬영 라인이 달라 같은 사진이 여러 번 들어오거나 라벨이 엇갈리는 일이 잦은데, 그 상태로 학습하면 성능 숫자 자체가 믿을 수 없게 됩니다. 이 도구는 그 전 단계를 봅니다. 공고 업무는 데이터 정의부터 모델 연구개발과 경량화까지 걸쳐 있는데 1주 범위에서 데이터 점검 축을 골랐습니다. 이 포트폴리오는 데이터 누수와 라벨 충돌을 규칙으로 찾아내는 기술을 보여줍니다. 이상탐지 모델 설계나 비전 논문 구현의 전문성은 주장하지 않습니다. 그 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
공고가 데이터 증강과 전후처리로 데이터 불균형과 노이즈 문제를 푸는 일을 업무로 듭니다. 어느 클래스가 얼마나 모자라고 어떤 라벨이 엇갈리는지를 먼저 세는 것이 그 작업의 앞단입니다.
실제 현장의 데이터로 풀어야 할 결함 탐지 문제를 정의하는 일이 첫 업무입니다. 정의는 데이터가 그 문제를 담고 있는지 확인한 뒤에야 성립합니다.
축적된 문제 해결 경험을 자산화하고 솔루션화하는 과정이 본부 소개에 적혀 있습니다. 점검 규칙을 파일로 남기면 다음 현장에서 같은 절차를 그대로 돌립니다.
현장에서 받은 결함 라벨 목록을 읽어, 학습과 평가에 같은 이미지가 섞였는지와 라벨이 서로 엇갈리는지를 나눠 보여주는 점검 CLI입니다. 클래스별 수량 쏠림도 함께 셉니다.
현장에서 결함 학습셋을 받아 오는 담당자입니다. 정확도가 안 나올 때 모델을 먼저 의심하게 되는데, 실제로는 같은 이미지가 학습과 평가에 같이 들어갔거나 검사자 두 명이 같은 사진을 다르게 라벨한 경우가 섞여 있습니다.
라벨 목록에 이미지 해시와 분할 구분이 같이 남아 있으면, 모델을 돌리기 전에 데이터가 성립하는지는 규칙으로 갈라집니다.
라벨 목록 파일을 인자로 받아 사유별 점검표와 클래스별 수량을 출력하고 점검 리포트를 떨구는 CLI입니다. 이미지 파일 자체는 열지 않고 메타데이터에 적힌 해시를 그대로 믿는 것을 전제로 시작합니다.
해시가 달라도 눈으로 같은 사진을 찾아내는 유사도 비교기입니다. 여기서부터 이미지 파일을 실제로 읽습니다.
클래스 사전과 임계값을 파일로 분리해 현장마다 다른 기준으로 같은 점검을 돌리는 구성입니다.
라벨 20건을 넣어 사유별 점검표와 클래스별 수량이 나오고 점검 리포트가 떨어지는 것을 시연합니다.
결측·중복·미등록 클래스 표기가 섞인 입력 30종을 넣어도 출력 형식이 깨지지 않고, 판정하지 못한 행은 사유가 붙어 남습니다.
클래스 표기가 사전에 없으면 정상으로 세지 않고 미매핑으로 따로 답니다. 모르는 것을 수량에 섞지 않습니다.
점검 결과와 손으로 만든 정답표를 맞춰 사유별로 어긋난 건을 셉니다. 단, 라벨과 정답을 모두 작성자가 만든 합성 기준이라 성능 측정이 아니라 데모 조건 동작입니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 더미데이터 자가채점이며, 실제 점검 정확도는 마키나락스가 현장에서 받는 실제 라벨과 실제 검사자 기준이 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 결측·중복·라벨 충돌·미등록 클래스를 더미에 일부러 섞어 쉬운 문제만 푸는 것을 피합니다.
라벨이 엇갈린다고 해서 한쪽이 틀렸다고 단정할 수 없습니다. 경계가 모호한 결함은 검사자마다 다르게 볼 수 있어, 이 도구는 충돌을 알리고 판단은 검사 담당자가 합니다.
1주차는 메타데이터에 적힌 해시를 그대로 믿습니다. 해시가 다르지만 눈으로 같은 사진인 경우는 2주차에야 잡히므로, 1주차 결과를 데이터가 깨끗하다는 근거로 쓰면 안 됩니다.
실제 도입하면 현장마다 클래스 이름과 촬영 조건이 다릅니다. 사전을 처음 채우는 일이 도입 단계의 실제 과제입니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
현장에서 받은 결함 라벨 목록입니다. 이미지 해시와 분할 구분, 검사자가 같이 적혀 있어 누수와 충돌을 대조할 수 있습니다. 결측과 중복, 미등록 클래스 표기를 일부러 섞었습니다.
| record_no | image_hash | class_raw | split | annotator | bbox_count | capture_line |
|---|---|---|---|---|---|---|
| L-001 | h0a1b2 | 스크래치 | train | 검사자A | 2 | LINE-1 |
| L-002 | h0a1b3 | 정상 | train | 검사자A | 0 | LINE-1 |
| L-003 | h0a1b4 | 찍힘 | train | 검사자B | 1 | LINE-2 |
| L-004 | h0a1b2 | 스크래치 | test | 검사자A | 2 | LINE-1 |
| L-005 | h0a1b5 | 정상 | train | 검사자B | 0 | LINE-2 |
아래 JSON Schema에 맞는 결함 라벨 행을 더 만들어 주세요. {"type":"object","properties":{"record_no":{"type":"string"},"image_hash":{"type":"string"},"class_raw":{"type":"string"},"split":{"type":"string","enum":["train","val","test"]},"annotator":{"type":"string"},"bbox_count":{"type":["integer","null"]},"capture_line":{"type":"string"}},"required":["record_no","image_hash","class_raw","split","annotator","bbox_count","capture_line"]} 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라. 첫째 결측으로 bbox_count가 null인 행, 둘째 중복으로 같은 image_hash가 같은 분할에 두 번 있는 행, 셋째 누수로 같은 image_hash가 train과 test에 나뉘어 있는 행 쌍, 넷째 라벨 충돌로 같은 image_hash에 검사자 두 명이 다른 class_id를 붙인 행 쌍, 다섯째 미매핑으로 class_raw가 사전에 없어 class_id가 null인 행, 여섯째 표기흔들림으로 같은 클래스를 스크래치·scratch·Scratch로 다르게 적은 행. 정상 클래스가 결함보다 훨씬 많게 해 실제 현장의 불균형을 재현해 주세요. 또한 형식 깨뜨리기 시도 3건을 별도 파일로 만들어 split에 enum 밖 값을 넣거나 required 필드를 빼서 스키마 검증이 걸러내는지 확인하게 해 주세요.{"type":"object","properties":{"record_no":{"type":"string"},"image_hash":{"type":"string"},"class_raw":{"type":"string"},"split":{"type":"string","enum":["train","val","test"]},"annotator":{"type":"string"},"bbox_count":{"type":["integer","null"]},"capture_line":{"type":"string"}},"required":["record_no","image_hash","class_raw","split","annotator","bbox_count","capture_line"]}현장 표기를 표준 클래스로 잇는 사전입니다. 라벨 목록의 class_raw가 이 사전에 없으면 미매핑으로 답니다. 사전에 일부러 이물 계열을 넣지 않아 미등록 상황을 재현했습니다.
| class_raw | class_id | is_defect | registered_line |
|---|---|---|---|
| 스크래치 | scratch | true | LINE-1 |
| scratch | scratch | true | LINE-1 |
| Scratch | scratch | true | LINE-2 |
| 찍힘 | dent | true | LINE-2 |
| dent | dent | true | LINE-2 |
아래 JSON Schema에 맞는 클래스 사전 행을 더 만들어 주세요. {"type":"object","properties":{"class_raw":{"type":"string"},"class_id":{"type":"string"},"is_defect":{"type":"boolean"},"registered_line":{"type":"string"}},"required":["class_raw","class_id","is_defect","registered_line"]} 쉬운 데이터만 만들지 말 것. 같은 class_id에 한글·영문·대소문자 표기를 여러 개 두어 표기흔들림을 재현하고, 라벨 목록에는 나오지만 사전에는 없는 클래스가 남도록 일부 결함 종류는 일부러 등록하지 말아 주세요. 또한 형식 깨뜨리기 시도 3건을 별도 파일로 만들어 is_defect에 문자열을 넣어 스키마 검증이 걸러내는지 확인하게 해 주세요.{"type":"object","properties":{"class_raw":{"type":"string"},"class_id":{"type":"string"},"is_defect":{"type":"boolean"},"registered_line":{"type":"string"}},"required":["class_raw","class_id","is_defect","registered_line"]}| Python | 라벨 목록을 읽어 점검 규칙을 돌리고 리포트를 만드는 본체입니다. |
| PyTorch | 2주차에 이미지 임베딩으로 유사 사진을 찾을 때 씁니다. 1주차에는 쓰지 않습니다. |
| 이상탐지 | 정상과 결함의 수량이 얼마나 기울어 있는지를 세어, 적은 쪽으로 학습이 쏠리지 않는지 미리 봅니다. |
| 데이터 증강 | 클래스별 수량 쏠림을 숫자로 내어 어느 클래스에 증강이 필요한지 정하는 근거로 씁니다. |
| 이미지 분류 | 라벨이 엇갈린 건을 찾을 때 같은 이미지에 붙은 서로 다른 클래스를 비교하는 기준입니다. |
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 이미지를 실제로 열어 해시가 달라도 같은 사진을 찾습니다.
✓ pass → 유사도 비교까지가 한 덩어리입니다. 더 키우려면 사전과 임계값을 현장별로 분리합니다.
라벨 한 건의 점검 결과입니다. 학습에 쓸 수 있는지, 안 되면 무엇 때문인지를 근거와 함께 담습니다.
{"type":"object","properties":{"record_no":{"type":"string"},"verdict":{"type":"string","enum":["ok","class_unmapped","split_leak","label_conflict","duplicate_record","bbox_missing"]},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"agg":{"type":["string","null"]},"value":{},"quote":{"type":["string","null"]}},"required":["field","value"]}},"next_action":{"type":"string"}},"required":["record_no","verdict","evidence","next_action"]}[
{
"record_no": "L-002",
"verdict": "ok",
"evidence": [
{
"field": "class_raw",
"value": "정상"
},
{
"field": "split",
"value": "train"
},
{
"field": "bbox_count",
"value": 0
}
],
"next_action": "학습에 그대로 씁니다."
},
{
"record_no": "L-003",
"verdict": "ok",
"evidence": [
{
"field": "class_raw",
"value": "찍힘"
},
{
"field": "split",
"value": "train"
},
{
"field": "bbox_count",
"value": 1
}
],
"next_action": "학습에 그대로 씁니다."
},
{
"record_no": "L-016",
"verdict": "ok",
"evidence": [
{
"field": "class_raw",
"value": "Scratch",
"quote": "Scratch"
},
{
"field": "class_raw",
"value": "Scratch"
}
],
"next_action": "표기가 대문자로 적혔지만 사전으로 정규화됐습니다. 학습에 그대로 씁니다."
},
{
"record_no": "L-004",
"verdict": "split_leak",
"evidence": [
{
"field": "image_hash",
"value": "h0a1b2"
},
{
"field": "split",
"value": "test"
},
{
"field": "image_hash",
"agg": "count",
"value": 2
}
],
"next_action": "같은 이미지가 학습에도 있습니다. 평가 결과가 부풀 수 있으니 test 쪽을 뺍니다."
},
{
"record_no": "L-011",
"verdict": "label_conflict",
"evidence": [
{
"field": "image_hash",
"value": "h0a1b3"
},
{
"field": "class_raw",
"value": "스크래치"
},
{
"field": "annotator",
"value": "검사자C"
}
],
"next_action": "같은 이미지를 검사자A는 정상, 검사자C는 스크래치로 봤습니다. 검사 기준을 맞춘 뒤 다시 라벨합니다."
},
{
"record_no": "L-007",
"verdict": "class_unmapped",
"evidence": [
{
"field": "class_raw",
"value": "이물",
"quote": "이물"
},
{
"field": "class_raw",
"value": "이물"
}
],
"next_action": "사전에 없는 클래스입니다. 새 클래스로 받을지 기존 클래스에 합칠지 정한 뒤 학습에 넣습니다."
},
{
"record_no": "L-009",
"verdict": "bbox_missing",
"evidence": [
{
"field": "class_raw",
"value": "찍힘"
},
{
"field": "bbox_count",
"value": null
}
],
"next_action": "결함인데 영역 수가 비어 있습니다. 라벨 파일이 덜 옮겨졌는지 확인합니다."
},
{
"record_no": "L-005",
"verdict": "ok",
"evidence": [
{
"field": "class_raw",
"value": "정상"
},
{
"field": "split",
"value": "train"
},
{
"field": "bbox_count",
"value": 0
}
],
"next_action": "학습에 그대로 씁니다."
}
][자동 검증 · 1주차] 1. verdict가 enum 여섯 값 안에 있는지 확인합니다. 2. record_no·verdict·evidence·next_action이 모두 있는지 확인합니다. 3. bbox_count가 0 이상인지 확인합니다. 4. class_id가 null이면 verdict가 class_unmapped인지 확인합니다. 5. evidence의 field가 입력 표의 컬럼에 실재하는지 확인합니다. 6. evidence의 quote가 그 행 class_raw의 일부인지 확인합니다. 7. next_action이 존댓말로 끝나는지 확인합니다. [판정 규칙] 1. 결함 분류 표기은 대소문자와 띄어쓰기, 구분자를 없애 소문자로 모은 뒤 defect_class_dictionary의 class_id와 맞춥니다. 맞는 것이 없으면 미매핑으로 남기고 그 행은 나머지 판정에서 뺍니다. [수동 검증] 1. 라벨이 엇갈린 건에서 어느 쪽이 맞는지 검사 담당자가 판단합니다. 2. L-006·L-016처럼 표기가 흔들렸지만 사전으로 정규화된 행은 사유를 달지 않는 것이 맞는지 확인합니다. [평가 러너 · 2주차] 1. 손으로 만든 정답표와 verdict를 맞춰 사유별로 어긋난 건을 셉니다. 2. 라벨과 정답을 작성자가 만든 합성 기준이라 이 수치는 성능 측정이 아니라 데모 조건 동작입니다.