Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- bioinformatics
- RNN
- HMM
- 딥러닝
- ncbi
- 자바
- 시그모이드
- Kaggle
- Java
- 블록체인
- AP Computer Science A
- SVM
- 생물정보학
- 이항분포
- 인공지능
- COVID
- 인공지능 수학
- AP
- MERS
- 캐글
- 파이썬
- BLaST
- 오류역전파
- 서열정렬
- 결정트리
- 바이오파이썬
- 생명정보학
- 인공신경망
- CNN
- 바이오인포매틱스
Archives
- Today
- Total
데이터 과학
CNN, MNIST 코드 분석 본문
Tensorflow 작동되는 코드 Conv-Pool- Conv-Pool-FC 동작을 기준으로 어떤 방법으로 학습이 되는지 분석하는 내용입니다.
활성화 함수와 손실함수에 대한 내용과 시행횟수 epoch등의 내용을 설명합니다.
MNIST의 경우 프로그램 내용과 소스가 많이 알려져 있어서 세분화 하게 이해만 하면 합성곱 신경망을 어렵지 않게 이해할 수 있습니다.
1) 데이터 & 전처리 (TF/Keras 기준)
- 데이터셋: tf.keras.datasets.mnist (Train 60,000 / Test 10,000, 흑백 28×28)
- 스케일링: x/255.0으로 [0,1] 정규화
- 표준화: ((x - 0.1307)/0.3081) — MNIST 평균/표준편차로 표준화해 수렴 안정화
- 텐서 모양: (H,W)→(H,W,1)로 채널 차원 추가
- 검증 분리: Train의 10%를 검증 세트로 분할
- tf.data 파이프라인:
- Dataset.from_tensor_slices → shuffle(10000) → map(증강) → batch(128) → prefetch(AUTOTUNE)
2) 모델 아키텍처 (Keras Functional, from_logits=True)
입력 (28,28,1) → Conv(32,3,same)+ReLU → MaxPool2D →
Conv(64,3,same)+ReLU → MaxPool2D → Flatten → Dropout(0.25) →
Dense(128)+ReLU → Dense(10)(logits, Softmax 미적용)
블록레이어출력 텐서 크기파라미터 수
| 입력 | — | (None, 28, 28, 1) | — |
| Conv1 | Conv2D(32, k=3, same) + ReLU | (None, 28, 28, 32) | 320 |
| Pool1 | MaxPool2D(2×2) | (None, 14, 14, 32) | 0 |
| Conv2 | Conv2D(64, k=3, same) + ReLU | (None, 14, 14, 64) | 18,496 |
| Pool2 | MaxPool2D(2×2) | (None, 7, 7, 64) | 0 |
| Flatten | — | (None, 3136) | 0 |
| Dropout | p=0.25 | (None, 3136) | 0 |
| FC1 | Dense(128) + ReLU | (None, 128) | 401,536 |
| FC2 | Dense(10) (logits) | (None, 10) | 1,290 |
- 총 파라미터: 320 + 18,496 + 401,536 + 1,290 = 421,642
- 손실함수: SparseCategoricalCrossentropy(from_logits=True)
→ 모델 출력은 Softmax 없이 logits. 수치적으로 안정적이며 CE = (LogSoftmax+NLL)의 결합과 동일한 효과. - 옵티마이저: Adam(learning_rate=1e-3)
3) 학습 설정 & 콜백
- 배치 크기: 128 (미니배치 SGD)
- 에포크: 5 (MNIST는 3~5 에포크로도 99% 전후 도달)
- 지표: Accuracy/Loss
- 콜백:
- ReduceLROnPlateau(monitor="val_accuracy", factor=0.5, patience=2)
- EarlyStopping(monitor="val_accuracy", patience=3, restore_best_weights=True)
- ModelCheckpoint("mnist_cnn_best.keras", save_best_only=True)
- 재현성 설정: tf.keras.utils.set_random_seed(42) + enable_op_determinism() (가능한 한 결정적 연산)
4) 결과 및 해석 (경향)
- 테스트 정확도: 보통 98.8~99.3% 범위
- 학습 곡선:
- 초기 1~2 에포크 급상승, 이후 완만
- Train/Val loss 동반 하락, Dropout 덕에 과적합 억제
- 클래스 혼동(정성):
- ‘5’ ↔ ‘6/8’, ‘4’ ↔ ‘9’ 등 획 굵기·연결/미연결에 따른 유사 패턴에서 드문 오분류
5) 오류 분석 (왜 틀리나?)
- 형태 유사성: 필기체/약한 대비로 경계가 뭉개지면 특징 추출이 애매
- 정렬 문제: 숫자가 구석에 치우치면 Pooling 이후 정보 손실 영향↑
- 과한 증강: 좌우 반전 등 의미를 바꾸는 변형은 혼동 유발
대응
RandomTranslation/RandomRotation(±10°) 수준의 가벼운 어핀 변환만 사용
입력을 중앙 정렬/패딩하는 미세 전처리(선택)
채널 수/모델 용량을 소폭 늘리거나 BatchNormalization 추가
6) 개선 실험(Ablation) (Keras로 손쉽게 바꿔보기)
설정기대 변화구현 힌트
| BatchNorm 추가 | 수렴 안정·성능 소폭↑ | 각 Conv 뒤에 BatchNormalization() |
| 데이터 증강 조정 | 일반화↑ | tf.keras.layers.RandomRotation(0.1), RandomTranslation(0.1,0.1) 등 (좌우 반전은 비권장) |
| 채널 수 확대 | 표현력↑(약간) | Conv(32→48/64), Conv(64→96/128) |
| FC 축소(128→64) | 파라미터↓, 성능≈ | Dense(64)로 경량화 |
| 스케줄러 | 학습 안정 | CosineDecay, ExponentialDecay 등 LR schedule |
| Label Smoothing | 일반화↑ | loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, label_smoothing=0.05) |
7) 왜 잘 되나? (직관)
- 숫자 스트로크는 지역적 패턴으로 잘 설명됨 → 합성곱+풀링이 강점
- 표준화·미니배치가 수렴 안정성과 일반화 균형 제공
- CE 손실은 **정답 로그 확률 최대화(음의 로그우도 최소화)**로 다중분류에 직접적
8) 재현 체크리스트 (TensorFlow 환경)
- set_random_seed(42)와 동일 전처리(mean=0.1307, std=0.3081) 적용
- 동일 배치/러닝레이트/에포크/콜백 유지
- from_logits=True 일관성(출력에 Softmax 미적용)
- 평가 시 model.evaluate 또는 training=False로 드롭아웃/BN 고정
- tf.data 파이프라인의 증강 유무/종류 동일하게 유지
'인공지능 > 딥러닝 -파이썬 인공지능' 카테고리의 다른 글
| RNN (0) | 2025.10.22 |
|---|---|
| 마르코프 모델과 벨만 방정식 (0) | 2025.10.22 |
| 패션 MNIST 소스 분석 (1) | 2025.09.10 |
| RNN(순환 신경망), LSTM 그리고 cs231n (1) | 2023.11.12 |
| GAN(Generative Adversarial Network) (0) | 2022.11.07 |