P7-3.1 입력 구조는 프로젝트를 어떻게 바꾸는가¶
Section ID: P7-3.1 Version: v2026.07.22
입력이 표의 행(row)이 아니라 이미지 텐서(tensor)일 때 프로젝트 문서와 준비 코드가 어떻게 바뀌는지 확인합니다.
하지만 여기서도 먼저 분명히 해야 할 점이 있습니다.
이미지 분류 프로젝트의 핵심은 멋진 합성곱 신경망(CNN) 코드를 길게 쓰는 것이 아니라, 입력 모양(shape), 라벨(label), 예측 결과, 오류 사례를 함께 기록하는 데 있습니다.
목적은 딥러닝 성능 경쟁이 아니라, 이미지 분류 프로젝트에서 입력 구조가 바뀌면 준비 코드와 해석 기준도 함께 바뀐다는 점을 실제로 확인하는 데 있습니다.
이미지 입력이 바꾸는 기록¶
- 이미지 분류 프로젝트는 표 데이터 프로젝트와 무엇이 다른가?
- 이미지 패치를 분류 문제로 바꾸려면 무엇을 먼저 적어야 하는가?
- 딥러닝 프로젝트에서 입력 구조는 준비 코드와 해석 기준을 어떻게 바꾸는가?
핵심은 이미지 프로젝트에서 입력 모양 -> 라벨 -> 학습 -> 예측 -> 오류를 어떤 기록 구조로 남길지 먼저 고정하는 데 있습니다. 이미지 입력으로 바뀌면 준비 코드뿐 아니라 예측 결과와 오류 사례를 적는 방식도 함께 바뀐다는 점을 여기서 붙잡습니다.
이미지 입력으로 바뀌어도 프로젝트 메모의 기본 항목은 여기서 그대로 유지됩니다. 이미지 텐서, 라벨, 예측, 테스트 기록을 어떤 문서 항목으로 남길지 정리합니다.
판단 기준¶
- 이미지 분류 프로젝트를
입력 모양 -> 라벨 -> 학습 -> 예측 -> 오류흐름으로 설명할 수 있습니다. - 이미지도 결국 숫자 배열(array)이라는 점을 다시 확인할 수 있습니다.
- 실제 점검 장면에 가까운 이미지 패치 실습으로 train/test 예측 흐름을 직접 기록할 수 있습니다.
왜 이미지 프로젝트가 필요한가¶
독자는 이미지 분류를 들으면 곧바로 복잡한 모델 구조부터 떠올리기 쉽습니다. 하지만 프로젝트 문서에서 먼저 필요한 것은 다음입니다.
- 이미지 한 장은 어떤 숫자 배열인가?
- 분류 클래스(class)는 몇 개인가?
- 학습용 샘플과 평가용 샘플은 어떻게 구분되는가?
- 잘 맞춘 사례와 애매한 사례는 무엇인가?
즉, 이 이미지 프로젝트는 딥러닝 프레임워크 훈련법을 전부 배우는 자리가 아니라, 신경망의 기본 흐름을 실제 프로젝트 기록 형태로 바꾸는 자리입니다.
이미지 분류 프로젝트 입구에서 바로 확인해야 할 판단 기준을 표로 고정하면 다음과 같습니다.
| 질문 | 짧은 답 |
|---|---|
| 이 프로젝트에서 먼저 적을 것은 무엇인가? | 입력 모양, 클래스 라벨, train/test 분리 |
| 왜 실제 점검 패치에 가까운 예제로 시작하는가? | 픽셀 배열, 결함 위치, 예측 흐름이 함께 바뀌는 장면을 보기 위해 |
| 최소 산출물은 무엇인가? | 예측값, 정확도, 애매한 샘플 기록 |
여기에 한 가지를 더 붙이면 이미지 프로젝트의 입구부터 기록 구조가 더 분명해집니다. 입력 모양과 라벨만 적는 데서 끝내지 말고, 어떤 샘플을 추가 검토 대상으로 남길 것인가, 어떤 예측이 비교 기준선이 되는가, 어떤 오류 사례를 더 볼 것인가를 같이 적어 두는 것입니다.
| 입구에서 같이 남길 기록 | 왜 필요한가 |
|---|---|
| 입력 모양(shape) | 어떤 숫자 배열을 다루는지 고정하기 위해서입니다. |
| 클래스 라벨 | 예측 목표를 분명히 하기 위해서입니다. |
| 추가 검토 대상 샘플 기준 | 확신 차이(margin)가 낮거나 오분류된 샘플을 따로 보기 위해서입니다. |
| 다음 점검 질문 | 데이터, 표현, 모델 중 어디를 먼저 볼지 정하기 위해서입니다. |
예를 들어 평가 정확도 0.75와 약한 결함 오답 하나만 먼저 보면, 빠르게는 이미지 모델도 결국 정확도만 보면 된다고 적고 싶어질 수 있습니다. 하지만 더 안전한 다음 판단은 숫자 한 줄로 닫는 것이 아니라, 틀린 샘플이 어떤 위치 패턴을 놓쳤는가, 입력이 표의 한 행이 아니라 8x8 배열이라는 사실이 무엇을 바꾸는가, 그래서 어떤 샘플을 추가 검토 대상으로 남길 것인가를 먼저 적는 것입니다. 그렇게 읽어야 이미지 프로젝트가 표 데이터를 다른 모델에 넣은 문제가 아니라 공간 구조를 가진 입력을 어떻게 기록할 것인가의 문제로 다시 보입니다.
flowchart TD
A["문제 장면<br/>평가 정확도 0.75, 약한 결함 오답 1건"]
B["빠른 판단<br/>정확도만 보면 충분하다"]
C["오답 패턴 확인<br/>어느 위치 신호를 놓쳤는가"]
D["입력 구조 확인<br/>8x8 배열이 해석을 어떻게 바꾸는가"]
E["추가 검토 대상 고정<br/>어떤 샘플을 다시 볼 것인가"]
F["더 안전한 판단<br/>정확도와 입력 구조를 함께 기록"]
A --> B
A --> C --> D --> E --> F
프로젝트 질문 설정¶
8x8 grayscale 카메라 패치에서 정상 표면과 스크래치 경고를 구분할 수 있는가?라는 질문에서 시작합니다. 표 데이터와 달리 이미지에서는 한 행이 하나의 수치 레코드가 아니라 공간 구조를 가진 픽셀 묶음이라는 점이 중요합니다. 따라서 이 예제의 초점은 이미지도 숫자 배열이다에서 멈추지 않고, 어떤 위치의 변화가 예측과 오류 해석을 바꾸는가를 함께 보는 데 있습니다.
프로젝트 흐름¶
flowchart TD
A["이미지 텐서<br/>8x8 grayscale 패치"]
B["라벨<br/>정상 또는 스크래치 경고"]
C["기본 분류기 학습<br/>클래스별 점수 계산"]
D["평가 이미지 예측"]
E["오류 또는 애매한 사례 확인"]
A --> B --> C --> D --> E
이 도식은 이미지 분류 프로젝트를 복잡한 CNN 구현이 아니라 입력 배열과 예측 기록의 흐름으로 다시 보여 줍니다. 이미지도 결국 숫자 텐서이고, 프로젝트 문서에서는 그 텐서가 라벨과 예측으로 어떻게 이어지는지를 먼저 남겨야 합니다.
프로젝트 기록으로 남기면 순서는 다음과 같습니다.
| 단계 | 문서에 남길 것 |
|---|---|
| 입력 | 이미지 모양과 픽셀 예시 |
| 라벨 | 클래스 정의 |
| 학습 | 어떤 기본 분류기를 썼는가 |
| 결과 | train/test 예측과 정확도 |
| 오류 | 애매하거나 틀린 샘플 |
예제 데이터¶
생산 라인 표면 점검 카메라가 잘라 낸 8x8 grayscale ROI(region of interest) 패치를 사용합니다. 본문 설명에서는 대표 패치를 직접 보여 주되, Python 예제에서 읽는 전체 학습/평가 데이터는 p7-3-surface-patches.csv에 따로 둡니다.
- 클래스 0: 정상 표면
- 클래스 1: 스크래치 경고
예시 패치를 반올림해 글자로 보면 다음과 같습니다.
정상 표면(class 0)¶
스크래치 경고(class 1)¶
이 예제는 실제 사진 원본을 그대로 사용한 것은 아니지만, 조명 변화가 있는 정상 표면과 중앙 또는 약간 옆으로 치우친 세로 스크래치를 구분하는 점검 문제처럼 읽을 수 있도록 만든 자체 사례입니다. 핵심은 픽셀 값 하나가 아니라 어느 위치의 패턴이 꺼지는가가 라벨과 연결된다는 점입니다.
Python 예제¶
예제는 8x8 점검 패치를 펼쳐 64차원 입력으로 바꾸고, 매우 단순한 softmax 분류기를 학습해 평가 예측을 확인하는 것입니다. 이번에도 정확도만 보는 대신, 어떤 평가 이미지가 왜 흔들렸는지 바로 추적할 수 있도록 평가 샘플 이름, 패턴 이름, 확률 분포, 추가 검토 여부를 함께 남기겠습니다. 원시 패치 값은 코드 안에 직접 쓰지 않고 CSV 파일로 분리해, 본문 코드는 읽기 -> 배열 변환 -> 학습 -> 평가 기록 흐름에만 집중합니다.
- 문제 상황: 정상 표면과 스크래치 경고를 구분한다.
- 입력: 8x8 grayscale 패치 12장(학습), 4장(평가)
- 정답 라벨: 정상 표면 = 0, 스크래치 경고 = 1
- 확인할 개념:
- 이미지도 숫자 배열이다
- 분류기는 클래스 점수(score)를 비교해 예측을 만든다
- test 데이터에서 약한 결함 샘플이 틀릴 수 있다
- 오류 사례로 이어질 수 있게 샘플별 예측 기록을 남겨야 한다
입력 파일¶
- 파일 경로:
p7-3-surface-patches.csv - 한 행의 의미:
표면 점검 패치 하나 - 핵심 열:
split: 학습(train) / 평가(test) 구분sample: 샘플 식별자pattern_name: 정상, 약한 스크래치 같은 패턴 이름label: 정상 표면(0) / 스크래치 경고(1)pixel_00...pixel_77: 8x8 grayscale 픽셀 값
즉, 이 파일은 이미지 파일 경로 목록이 아니라 이미지를 바로 숫자 격자로 펼쳐 둔 학습 기록입니다. Python 예제는 이 숫자 열들을 다시 8x8 배열로 복원한 뒤 학습과 평가로 넘깁니다.
실행 기록 기준¶
이미지 분류 기록은 정확도 한 줄보다 입력 구조와 오류 샘플을 함께 남길 때 의미가 분명해집니다. 입력 파일의 한 행은 이미지 패치 하나이고, 결과 해석에는 원래 입력 모양, 펼친 입력 모양, 틀린 평가 샘플, 추가 검토 샘플이 같이 필요합니다.
기록은 다음 기준으로 나눕니다.
- CSV에서
split,sample,pattern_name,label,pixel_00...pixel_77열의 역할을 확인합니다. - 대표 정상 패치와 스크래치 경고 패치를 비교해, 어느 위치의 픽셀 값이 라벨 판단과 연결되는지 표시합니다.
- Python 예제를 실행한 뒤 원래 shape와 펼친 shape가 어떻게 다른지 적습니다.
- 평가 결과에서
오류 검토 필요가예인 샘플을 하나 골라, 왜 다음 분석 대상으로 남겨야 하는지 한 문장으로 씁니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
실행 결과 예시는 다음과 같습니다.
결과를 어떻게 읽는가¶
이 결과에서 읽어야 할 핵심은 세 가지입니다.
-
입력 모양
예제의 실행 요약에는 원래 모양(shape)(12, 8, 8)와 펼친 뒤 모양(12, 64)가 함께 남습니다. 즉, 이미지가 원래는 8x8 픽셀 묶음이었고, 학습 직전에는 64개 숫자 입력으로 바뀌었다는 점을 한 번에 확인할 수 있습니다. -
학습 데이터와 평가 데이터 분리
학습에서는 모두 맞았지만, 평가에서는평가-결함-약함을 틀렸습니다. 즉, 학습 성공과 일반화 성공은 같은 말이 아닙니다. -
약한 결함의 흔들림
세 번째 샘플은 실제 라벨이스크래치 경고인데도 예측은정상 표면으로 나왔습니다. 확률[0.73, 0.27]은 모델이 아주 무지한 것은 아니지만, 약한 결함을 정상 조명 변화와 분리하지 못했다는 신호입니다.오류 검토 필요 = 예를 함께 남겼기 때문에, 이 결과를 원인 확정으로 읽기보다 어떤 샘플을 우선 검토해야 하는지 바로 정할 수 있습니다.
이 결과는 다음 세 줄로 요약할 수 있습니다.
- 이미지는 결국 64개 숫자 입력으로 바뀌었다
- 학습에서는 맞아도 평가에서는 약한 결함 샘플이 틀릴 수 있다
- 샘플 ID와 불확실성 기록이 있어야 오류 분석 우선순위를 분명히 남길 수 있다
- 약한 결함 오분류는 오류 분석의 핵심 출발점이다
이 실습은 개념 설명과 프로젝트 기록을 연결합니다.
- 입력층(input layer), 출력층(output layer), 손실(loss), 학습(learning) 같은 개념은 여기서 실제 점검 기록 안의 항목으로 다시 나타납니다.
- 따라서 독자는 추상적인 구조 설명을 넘어서, 어떤 입력과 어떤 오류 사례가 그 개념을 실제 판단 기준으로 바꾸는지 함께 확인할 수 있습니다.
즉, CNN을 배웠다가 아니라 이미지 분류 프로젝트에서 입력 구조와 오류 기록을 어떤 구조로 남겨야 하는가를 익히는 자리입니다.
Part 7 전체 흐름에서 입력 표현이 표가 아니라 이미지가 되었을 때도 프로젝트 문서의 뼈대는 유지된다는 점을 보여 줍니다.
결과 해석 기준¶
실행 결과를 볼 때는 정확도보다 먼저 모양 변화와 샘플별 흔들림을 봅니다. 특히 (12, 8, 8)이 (12, 64)로 바뀌는 지점은 이미지의 공간 구조를 그대로 보존한 것이 아니라, 학습 입력으로 넣기 위해 펼친 상태라는 뜻입니다.
다음 세 가지를 구분해 적어야 합니다.
| 관찰할 것 | 기록할 질문 |
|---|---|
| 입력 모양 변화 | 이미지 패치가 어떤 shape에서 어떤 벡터로 바뀌었는가? |
| 평가 오답 | 어떤 샘플 ID가 어떤 라벨로 잘못 예측되었는가? |
| 추가 검토 필요 | 오답이 데이터 부족, 입력 표현, 모델 구조 중 어느 질문을 먼저 여는가? |
프로젝트 기록 예시¶
기록은 다음 형식으로 압축할 수 있습니다.
| 항목 | 기록 |
|---|---|
| 입력 단위 | 한 행은 8x8 grayscale ROI 패치 하나다. |
| shape 변화 | 원래 입력은 (12, 8, 8), 펼친 입력은 (12, 64)다. |
| 기준선 결과 | 학습 정확도는 1.0, 평가 정확도는 0.75다. |
| 오류 검토 샘플 | 평가-결함-약함을 우선 검토 대상으로 남긴다. |
| 다음 질문 | 약한 스크래치가 데이터 범위 부족인지, 공간 구조 손실인지 확인한다. |
이 코드에서 학습 루프 용어를 다시 읽기¶
Python 예제는 이미지 분류 입문 예제이지만, 동시에 학습 루프 용어를 실제 코드 위치에 다시 붙여 볼 수 있는 가장 짧은 사례이기도 합니다. 프레임워크 함수 이름이 아니라, 지금 눈앞의 코드가 forward -> loss에 해당하는 오차 신호 -> gradient -> update -> inference를 어떤 순서로 밟는지 확인하는 것이 중요합니다.
앞쪽의 입력 구조 설명은 무엇을 한 샘플로 넣는가를 고정합니다. 여기의 학습 루프 설명은 그 입력이 들어간 뒤 어느 줄에서 파라미터가 바뀌고, 어느 줄에서 예측만 하는가를 가르는 역할입니다.
| 학습 루프 용어 | 이 코드에서 대응되는 위치 | 코드에서 어떻게 읽으면 좋은가 |
|---|---|---|
| 입력 배치(batch) | X_train, y_train 전체 | 예제는 학습 샘플 12개를 한 번에 넣는 full-batch 학습이다 |
| step | for _ in range(num_steps) 안의 한 번의 갱신 | 한 번 logits를 만들고 gradient를 계산한 뒤 W, b를 움직이는 한 주기다 |
| epoch | 이 코드에서는 step과 사실상 같다 | full-batch라서 샘플 전체를 한 번 본 뒤 바로 한 번 update한다 |
| learning rate | learning_rate = 0.35 | gradient를 얼마나 크게 반영해 W, b를 움직일지 정하는 보폭이다 |
| optimizer update | W -= learning_rate * grad_W, b -= learning_rate * grad_b | gradient만 계산하는 데서 끝나지 않고 실제 파라미터가 바뀌는 지점이다 |
| inference | test_probs, test_pred 계산 | 학습이 끝난 현재 W, b를 고정한 채 평가 샘플에 예측만 수행하는 단계다 |
이 표가 중요한 이유는, 초심자가 실제 코드를 읽을 때 gradient를 계산했다와 파라미터를 실제로 바꿨다, 학습 중이다와 지금은 평가만 한다를 자주 섞기 때문입니다. 예제는 아주 작지만, 바로 그 경계를 다시 확인하기에는 충분합니다.
예제 학습 루프를 그림으로 다시 보면¶
flowchart TD
A["학습 배치 준비<br/>X_train, y_train 전체"]
B["forward 계산<br/>logits, probs"]
C["오차 신호 계산<br/>grad_W, grad_b"]
D["update 적용<br/>W, b 이동"]
E["같은 배치로 반복<br/>700 step"]
F["평가 단계<br/>X_test -> test_pred"]
A --> B --> C --> D --> E
E --> B
E --> F
이 도식은 학습 중 반복과 평가 단계를 일부러 분리해서 보여 줍니다. 학습 중에는 같은 train 배치를 여러 번 돌며 파라미터를 조금씩 바꾸고, 평가 단계에서는 더 이상 W, b를 바꾸지 않고 현재 상태로만 예측합니다.
같은 내용을 이 코드 기준으로 한 줄씩 다시 적으면 다음과 같습니다.
X_train @ W + b는 현재 파라미터로 예측 점수(logits)를 만드는 forward 계산입니다.probs - Y_train은 현재 예측과 정답 차이에서 나온 오차 신호입니다.grad_W,grad_b는 그 오차 신호를 파라미터 쪽으로 되돌려 계산한 gradient입니다.W -= ...,b -= ...는 gradient를 실제 update로 바꾸는 지점입니다.test_probs,test_pred는 학습이 끝난 뒤 현재 파라미터를 고정해 수행하는 inference입니다.
즉, 학습 루프 용어들은 이 프로젝트 코드 안에서도 실제로 어느 줄이 파라미터를 바꾸는가, 어느 줄은 예측만 하는가를 구분하는 읽기 기준으로 바로 쓰입니다.
같은 흐름을 최소 기록으로 줄이면 다음 표처럼 정리할 수 있습니다.
| 단계 | 다시 검토가 필요한 상태 | 다음 행동 |
|---|---|---|
| 입력 확인 | 입력 모양이 예상과 다르다 | 전처리 다시 확인 |
| 예측 확인 | 약한 결함 샘플이 정상으로 분류된다 | 구조 계열 비교 질문으로 넘김 |
| 평가 결과 | 오분류 샘플이 있다 | 데이터/모델/표현 확인 질문 기록 |
이 표가 있으면 이미지 분류 프로젝트 입구부터 입력 -> 비교 기준 -> 다시 볼 질문 구조가 보입니다.
직접 바꿔 보며 확인할 것¶
-
평가-결함-약함패치의 중앙 세로 줄 값을 조금 더 낮춰 봅니다. 관찰할 점: 약한 결함 신호를 더 또렷하게 만들면클래스별 확률과오류 검토 필요상태가 어떻게 달라지는가? -
평가-정상-그림자패치에 어두운 값 두세 칸을 더 넣어 봅니다. 관찰할 점: 조명 그림자가 늘어나면 모델이약한 결함과정상 그림자를 어디서 헷갈리기 시작하는가? -
학습 데이터에
약한 스크래치와 비슷한 패치 한 장을 더 추가했다고 가정해 봅니다. 관찰할 점: 지금 문제를입력 구조 이해문제로 봐야 하는가, 아니면학습 데이터 범위 부족문제로 봐야 하는가가 어떻게 달라지는가?
체크리스트¶
| 확인할 것 | 스스로 답할 질문 |
|---|---|
| 입력 모양 | 이미지가 어떤 shape에서 어떤 벡터 입력으로 바뀌는지 적었는가? |
| 라벨 | 클래스 라벨과 예측 목표를 먼저 고정했는가? |
| 학습/평가 분리 | 학습 정확도와 평가 정확도를 따로 읽었는가? |
| 오류 검토 | 애매하거나 틀린 샘플 ID를 다음 분석 대상으로 남겼는가? |
| 학습 루프 | 어느 줄이 파라미터를 바꾸고 어느 줄이 inference인지 구분했는가? |
이 다섯 칸이 비어 있으면 CNN이나 프레임워크 이름을 더 붙여도 프로젝트 기록은 선명해지지 않습니다. 이미지 프로젝트의 첫 문서는 입력 모양 -> 라벨 -> 학습/평가 -> 오류 검토 순서를 먼저 닫아야 합니다.
출처와 참고 자료¶
- NumPy Developers,
NumPy documentation, 확인 날짜: 2026-06-29. https://numpy.org/doc/stable/
이 절의 이미지 데이터는 프로젝트 실습을 위해 만든 자체 synthetic 점검 패치 데이터입니다.