| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- anaconda3
- 커널
- MongoDB
- 아나콘다3
- 아나콘다설치
- GCP
- 데이터분석부트캠프
- 데이터싸이언티스트
- nosql
- 데이터
- 데이터분석
- 데이터사시언티스트 #데이터 #모두의연구소
- 가상환경만들기
- 가상환경설정
- 데이터분석환경
- 아이펠톤
- jupyter
- 데이터사이언티스트
- 데이터사이언티스트 #데이터 #모두의연구소 #데이터분석부트캠프
- 모두의연구소
- python
- 데이터전처리
- Today
- Total
EH_dream
딥러닝 첫걸음 – MNIST 손글씨 분류 실습 정리_25.06.08 본문
이번 글에서는 내가 학습한 노드 중 하나인 "MNIST 손글씨 숫자 분류 실습"을 정리해보려 한다.
이 실습은 아주 기본적인 딥러닝 모델부터 시작해서 CNN(합성곱 신경망)을 사용한 이미지 분류까지
자연스럽게 배울 수 있게 구성되어 있어서 처음 딥러닝을 접하는 나도 이해하기 어렵지 않았다.
참고 CNN이란?
CNN은 이미지 인식, 영상 분석, 음성 인식, 자연어 처리 등 공간적인 구조를 가진 데이터를 분석하는 데 특화된 인공신경망이다.
기존의 완전연결신경망(Dense Layer)은 모든 입력값과 뉴런이 1:1로 연결되어 있어서
이미지처럼 크고 복잡한 데이터를 처리할 때 파라미터 수가 폭발적으로 많아지고 오버피팅 위험이 커진다.
CNN은 이런 문제를 해결하기 위해 지역성(locality)과 파라미터 공유(weight sharing)라는 개념을 도입한 구조다.
CNN의 장점으로는 적은 파라미터 수로도 이미지 처리가 가능하고 , 이미지 공간적 구조(형태, 위치)를 잘 보존한다.
필터가 가장으로 유용한 특징을 학습하기도한다. ( 에지, 곡선, 형태 등 )
- 출처 : ChatGPT
이번 노드 학습에서는 , Tensorflow와 Keras를 사용해서 직접 코드를 작성하고 모델을 학습시켜본다는 점이었다.
실습 중심의 학습이다 보니 처음엔 어렵게 느껴졌던 개념들도, 코드와 함께 경험하다 보면 훨씬 자연스럽게 익혀졌다.
MNIST 데이터 셋
우리가 다룬 첫 번째 데이터셋은 MNIST(Mixed National Institute of Standards and Technology)였다.
0부터 9까지의 손글씨 숫자를 담고 있는 이미지 데이터셋으로, 딥러닝 입문자에게는 일종의 ‘Hello World’ 같은 존재다.
- 총 70,000장의 28x28 크기 흑백 이미지
- 60,000장은 학습용, 10,000장은 테스트용
- 각 이미지에는 해당 숫자 레이블이 붙어 있음
이번 학습 노드에서는 이 데이터를 Tensorflow로 불러오고 간단히 출력해보는 것부터 시작했다.
처음엔 ‘이걸로 뭘 할 수 있을까’ 싶었지만, 뒤로 갈수록 이 간단한 데이터셋이 딥러닝 개념을 익히기에
얼마나 적합한지 실감하게 되었다.
전처리
다음으로는 딥러닝 모델에 맞는 데이터를 만드는 일을 해야하는데 이미지 데이터는
딥러닝 모델에 넣기 전에 01 사이의 실수값으로 정규화 해주는것이 일반적이였다.
또한 CNN을 사용하기 위해서는 채널 정보 (흑백은 1)를 포함한 형태로 redhape도 필요하다.
x_train = x_train.reshape(-1, 28, 28, 1).astype("float32") / 255.0
x_test = x_test.reshape(-1, 28, 28, 1).astype("float32") / 255.0
데이터 전처리 과정을 거치면서 딥러닝에서는 ‘데이터 준비’가 얼마나 중요한지 체감할 수 있었다.
모델을 아무리 잘 짜도 입력 데이터가 제대로 정리되어 있지 않으면 학습이 제대로 되지 않는다.
CNN Sequential Model을 사용해 구현하기
나는 MNIST 손글씨 숫자를 분류하기 위해 Sequential Model 사용하여 CNN 모델을 만들었다.
CNN은 이미지에서 특징을 추출하는 데 특화된 신경망 구조로 이미지 분류 문제에서 거의 필수적으로 쓰인다.
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D(2, 2),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D(2, 2),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
위 코드가 처음에는 잘 이해가 가지 않아 아래처럼 정리해 두었다.
## 수정한 코드
model = models.Sequential([
# 첫 번째 합성곱 계층: 입력 이미지에서 특징을 추출
# - 32개의 필터(filter)를 사용
# - 각 필터는 3x3 크기로 이미지의 국소 영역을 스캔
# - activation='relu'로 비선형성 부여
# - input_shape=(28, 28, 1): 입력 이미지의 크기 (28x28 흑백 이미지)
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
# 첫 번째 풀링 계층: 특징 맵의 크기를 줄이고, 주요 정보만 추출
# - 2x2 크기의 필터로 MaxPooling 수행 → 공간적 크기를 절반으로 줄임
layers.MaxPooling2D(2, 2),
# 두 번째 합성곱 계층: 더 많은(64개) 필터로 더 복잡한 특징 추출
# - 3x3 필터 크기, relu 활성화
layers.Conv2D(64, (3, 3), activation='relu'),
# 두 번째 풀링 계층: 다시 한번 특징 맵을 축소하여 연산량 감소
layers.MaxPooling2D(2, 2),
# Flatten 계층: 2차원 특징 맵을 1차원 벡터로 변환
# - Dense 계층과 연결하기 위해 필수
layers.Flatten(),
# 완전 연결(Dense) 계층: 앞에서 추출된 특징들을 바탕으로 학습
# - 64개의 뉴런을 사용
# - relu로 비선형성 부여
layers.Dense(64, activation='relu'),
# 출력층: 클래스 개수만큼 뉴런 사용 (MNIST는 0~9 → 10개)
# - softmax 함수로 각 클래스에 대한 확률값 출력
layers.Dense(10, activation='softmax')
])
모델 학습과 평가
모델을 학습시키기 전에는 compile 단계에서 손실 함수와 optimizer를 지정해줘야 한다.
나는 adam을 사용했고, 다중 클래스 분류에 적합한 sparse_categorical_crossentropy 손실 함수를 사용했다.
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, validation_split=0.2)
학습이 진행되면서 loss가 감소하고 accuracy가 상승하는 그래프를 보면서,
‘모델이 점점 학습되고 있다’는 걸 느낄 수 있었다. 학습 후에는 테스트 데이터셋으로 평가를 진행했다.
test_loss, test_acc = model.evaluate(x_test, y_test)
하이퍼파라미터 튜닝과 성능 개선
기본 모델의 성능이 나쁘진 않았지만, 더 나은 결과를 얻기 위해 하이퍼파라미터를 조정해보았다.
이번 학습 노드에서는 몇 가지 값을 바꿔보며 직접 실험해봤다.
# 바꿔 볼 수 있는 하이퍼파라미터들
n_channel_1 = 20
n_channel_2 = 45
n_dense = 40
n_train_epoch = 10
위와 같이 첫 번째 합성곱 계층의 필터 수를 20으로, 두 번째는 45로 조정하고
Dense 층의 뉴런 수를 줄인 뒤 학습 epoch을 늘려보았다. 결과적으로 얻은 테스트 정확도는 다음과 같았다.
결과 :
test_loss: 0.03314834460616112
test_accuracy: 0.9909999966621399
무려 99.1% 정확도를 달성했다. 이처럼 단순한 파라미터 조정만으로도 성능이 크게 향상될 수 있다는 점이 인상 깊었고
하이퍼파라미터의 중요성을 실감하게 된 실험이었다.
직접 예측해보기
모델이 실제로 예측하는 걸 확인하는 것도 재미있는 경험이었다. 아래처럼 테스트 데이터의 예측 결과를 확인할 수 있다.
predictions = model.predict(x_test)
np.argmax(predictions[0])
모델이 ‘이건 숫자 7이야!’라고 확신하는 걸 보는 건 재밌기도 했지만
틀린것을 보면서 과연 어떻게 해야 잘 맞출 수 있을까? 라는 생각을 하게되는 부분이였다.
이제 막 딥러닝을 시작한 입장에서 만들어 본 모델이 실제로 뭔가를 예측한다는 것 자체가 큰 동기부여가 되었다.
느낀 점
이번 실습은 실제로 모델이 학습되는 과정과 결과를 직접 확인할 수 있어서 훨씬 재미 있었다.
하이퍼파라미터를 직접 조정하면서 모델의 성능을 개선해본 경험은 딥러닝 학습에 있어 매우 중요한 부분이었다.
앞으로 더 복잡한 모델에서도 이런 방식으로 실험하고 튜닝하는 감각을 계속 키워야겠다는 생각이 들었다.
'딥러닝' 카테고리의 다른 글
| 딥러닝학습 : 단어빈도와 벡터화 25.06.16 (0) | 2025.06.18 |
|---|---|
| 딥러닝실습정리: Boston, Reuters, CIFAR_25.06.11 (1) | 2025.06.11 |
| 딥러닝 모델 성능 향상을 위한 실전 기법 정리_25.06.10 (0) | 2025.06.10 |
| 딥러닝_텐서 , 모델, 학습 흐름 정리_25.06.09 (0) | 2025.06.09 |
| 딥러닝_개념의 발전 학습 흐름 정리_25.06.09 (0) | 2025.06.09 |