목차
메타 설명
인공신경망은 어떻게 데이터를 학습하고 정답을 예측할까요? TensorFlow와 Keras를 이용해 뉴런, 가중치, 편향, 활성화 함수, 손실 함수, 옵티마이저, 역전파, 에포크, 배치의 원리를 알아보고 손글씨 숫자 이미지 분류 모델을 직접 만들어 봅니다.
지난 시간에는 scikit-learn을 이용해 머신러닝 모델을 만들었습니다.
고객 정보를 입력받아 해지 가능성을 예측하고, 정확도와 재현율을 계산했으며, Pipeline과 교차검증까지 살펴보았습니다.
그런데 데이터가 더욱 복잡해지면 어떤 일이 벌어질까요?
사진 속 고양이와 강아지를 구분한다.
사람의 음성을 문자로 바꾼다.
긴 문장의 의미를 이해한다.
영상 속 움직이는 물체를 추적한다.
제품 사진의 불량 여부를 판단한다.이런 문제는 사람이 사용할 특징을 일일이 정하기 어렵습니다.
예를 들어 고양이 사진을 분류하기 위해 다음 규칙을 작성한다고 생각해 보겠습니다.
if 귀_모양 == "뾰족":
고양이_점수 += 1
if 수염_개수 >= 6:
고양이_점수 += 1
if 눈동자_모양 == "세로":
고양이_점수 += 1하지만 현실의 고양이는 규칙에 협조하지 않습니다.
귀가 사진 밖으로 잘린 고양이
이불 속에 숨어 있는 고양이
선글라스를 쓴 고양이
카메라를 등진 고양이
자신이 강아지라고 믿는 고양이조건문을 계속 추가하다 보면 프로그램은 고양이를 찾기도 전에 개발자의 체력을 먼저 분류합니다.
정상 체력
→ 주의 체력
→ 야근 위험
→ 모델 학습보다 개발자가 먼저 종료딥러닝은 사람이 모든 특징을 직접 지정하는 대신, 여러 층의 인공신경망이 데이터에서 중요한 특징을 스스로 찾아가도록 학습시키는 기술입니다.
이번 시간의 주인공은 딥러닝 계산 엔진 TensorFlow와 신경망을 편리하게 만드는 고수준 API Keras입니다. 🧠⚙️
1. TensorFlow란?
TensorFlow는 머신러닝과 딥러닝 모델을 만들고 학습하며 여러 환경에 배포할 수 있도록 지원하는 오픈소스 프레임워크입니다.
숫자 배열인 텐서를 처리하고, 자동 미분을 이용해 신경망의 가중치를 학습하며, CPU·GPU·TPU 같은 계산 장치를 활용할 수 있습니다. TensorFlow는 데스크톱, 서버, 모바일, 웹, 클라우드 등 다양한 환경을 대상으로 하는 머신러닝 생태계를 제공합니다.
2026년 7월 28일 기준 PyPI에 공개된 TensorFlow 최신 안정 배포판은 2.21.0입니다. 다만 운영체제와 Python 버전에 따라 설치 가능한 패키지가 달라질 수 있으므로 실제 프로젝트에서는 설치 전에 호환성을 확인해야 합니다.
TensorFlow가 담당하는 주요 작업은 다음과 같습니다.
텐서 계산
자동 미분
신경망 학습
GPU·TPU 연산
데이터 처리
모델 저장
모델 배포
분산 학습TensorFlow는 딥러닝 세계의 거대한 발전소와 비슷합니다.
전기를 직접 생산할 수 있지만, 처음 방문한 사람에게 발전소 제어판은 버튼이 너무 많아 보일 수 있습니다.
이때 등장하는 친절한 조종석이 Keras입니다.
2. Keras란?
Keras는 신경망 모델을 쉽고 일관된 코드로 만들 수 있도록 설계된 고수준 딥러닝 API입니다.
레이어를 연결하고, 손실 함수와 옵티마이저를 설정하고, `fit()`으로 모델을 학습하는 흐름을 제공합니다. Keras는 코드의 간결성, 유지보수성, 빠른 실험을 중요하게 설계되었습니다.
Keras를 사용하면 다음과 같은 신경망을 비교적 짧은 코드로 만들 수 있습니다.
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
keras.Input(shape=(10,)),
layers.Dense(
32,
activation="relu"
),
layers.Dense(
1,
activation="sigmoid"
)
])코드를 사람의 언어로 해석하면 다음과 같습니다.
숫자 10개를 입력받는다.
뉴런 32개가 특징을 학습한다.
마지막 뉴런 하나가 확률을 출력한다.Keras는 신경망을 쉽게 만들어 주지만 딥러닝의 원리를 없애 주는 것은 아닙니다.
자동차의 자동변속기가 운전을 편하게 해 주더라도 브레이크와 가속페달의 차이는 알아야 하는 것과 같습니다.
3. TensorFlow와 Keras의 관계
TensorFlow와 Keras를 처음 접하면 두 이름의 관계가 혼란스럽습니다.
TensorFlow와 Keras는 다른 것인가?
Keras를 별도로 설치해야 하는가?
tf.keras와 keras는 무엇이 다른가?핵심 관계는 다음과 같습니다.
TensorFlow
→ 텐서 계산과 자동 미분을 담당하는 프레임워크
Keras
→ 신경망 모델을 쉽게 구성하는 고수준 APITensorFlow 2.16부터 `pip install tensorflow`을 실행하면 Keras 3이 함께 설치되며, 기본적으로 `tf.keras` 역시 Keras 3을 가리킵니다.
이번 글에서는 TensorFlow를 백엔드로 사용하고 다음 방식으로 Keras를 불러옵니다.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layersKeras 3 자체는 TensorFlow뿐 아니라 JAX와 PyTorch 백엔드도 지원하는 멀티 프레임워크 API입니다. 그러나 이번 편에서는 개념을 단순하게 유지하기 위해 TensorFlow 백엔드에 집중합니다.
4. 머신러닝과 딥러닝의 차이
딥러닝은 머신러닝과 완전히 별개의 기술이 아닙니다.
인공지능
└─ 머신러닝
└─ 딥러닝딥러닝은 여러 층을 가진 인공신경망을 이용하는 머신러닝 방법입니다.
전통적인 머신러닝
전통적인 머신러닝에서는 사람이 유용한 특성을 어느 정도 선택합니다.
고객 이탈 예측:
가입 기간
월 이용요금
문의 횟수
계약 방식
로그인 횟수모델은 사람이 정리한 특성을 이용해 규칙을 학습합니다.
딥러닝
딥러닝에서는 원본 데이터에서 중요한 표현을 여러 층이 단계적으로 학습할 수 있습니다.
이미지 분류:
첫 번째 층
→ 선과 방향 감지
중간 층
→ 모서리와 작은 모양 감지
깊은 층
→ 눈, 귀, 얼굴 같은 복잡한 구조 감지
출력층
→ 고양이 또는 강아지 판단실제 신경망이 반드시 사람이 이해하기 쉬운 순서로 특징을 학습하는 것은 아니지만, 층이 깊어질수록 더 복잡한 표현을 구성할 수 있습니다.
비교
| 구분 | 전통적인 머신러닝 | 딥러닝 |
|---|---|---|
| 대표 도구 | scikit-learn | TensorFlow, Keras |
| 특성 설계 | 사람의 역할이 큰 편 | 모델이 표현 학습 가능 |
| 데이터 요구량 | 비교적 적을 수 있음 | 많은 데이터가 유리한 경우가 많음 |
| 계산량 | 비교적 적음 | 상대적으로 많음 |
| 표 데이터 | 매우 강함 | 문제에 따라 효과가 다름 |
| 이미지·음성 | 별도 특성 설계 필요 | 매우 강력하게 활용 가능 |
| 해석 | 비교적 쉬운 모델 존재 | 복잡해질수록 어려움 |
딥러닝이 항상 scikit-learn보다 좋은 것은 아닙니다.
작은 표 데이터에서는 선형 모델, 랜덤 포레스트, 그래디언트 부스팅이 더 빠르고 좋은 결과를 낼 수도 있습니다.
최신 기술
≠
모든 문제의 최선 기술5. 인공신경망이란?
인공신경망은 여러 개의 계산 단위를 층으로 연결한 모델입니다.
가장 기본적인 구조는 다음과 같습니다.
입력층
→ 은닉층
→ 출력층예를 들어 고객 이탈을 예측한다면 입력값은 다음과 같습니다.
나이
월요금
가입기간
문의횟수
로그인횟수은닉층은 입력값을 조합해 패턴을 학습합니다.
출력층은 최종 결과를 만듭니다.
해지 확률:
0.82신경망은 처음부터 똑똑하지 않습니다.
처음 생성된 모델의 가중치는 대부분 무작위 값에서 시작합니다.
첫 예측:
엉뚱함
손실 확인:
매우 큼
가중치 수정:
조금 나아짐
다시 예측:
여전히 수상함
수천 번 반복:
점점 쓸 만해짐신경망의 학습은 천재의 번뜩임보다 틀린 답을 끈질기게 수정하는 과정에 가깝습니다.
6. 뉴런의 구조
인공 뉴런 하나는 여러 입력값을 받아 계산한 뒤 결과를 출력합니다.
기본 계산은 다음과 같습니다.
출력 전 값
=
입력값 × 가중치의 합
+ 편향입력이 두 개라면 다음처럼 표현할 수 있습니다.
z = x₁w₁ + x₂w₂ + b각 기호의 의미는 다음과 같습니다.
x
→ 입력값
w
→ 가중치
b
→ 편향
z
→ 활성화 함수에 들어가기 전 값Python으로 단순화하면 다음과 같습니다.
def neuron(
x1: float,
x2: float,
w1: float,
w2: float,
bias: float
) -> float:
return (
x1 * w1
+ x2 * w2
+ bias
)예를 들어 다음 값을 넣어 보겠습니다.
result = neuron(
x1=2,
x2=3,
w1=0.5,
w2=-0.2,
bias=0.1
)
print(result)계산:
2 × 0.5
+ 3 × -0.2
+ 0.1
= 0.5이 계산 결과는 보통 활성화 함수를 통과한 뒤 다음 층으로 전달됩니다.
7. 가중치와 편향
가중치
가중치는 각 입력이 결과에 얼마나 큰 영향을 주는지 결정합니다.
큰 양수 가중치
→ 입력이 증가하면 출력도 증가하는 방향
큰 음수 가중치
→ 입력이 증가하면 출력은 감소하는 방향
0에 가까운 가중치
→ 영향이 상대적으로 작음고객 이탈 예측의 가상 예:
문의 횟수 가중치:
+1.2
가입 기간 가중치:
-0.8모델이 다음 관계를 학습했을 가능성을 생각할 수 있습니다.
문의가 많아질수록
해지 방향으로 이동
가입 기간이 길수록
유지 방향으로 이동다만 복잡한 신경망의 가중치 하나를 이처럼 직접 해석하기는 어렵습니다.
편향
편향은 모든 입력값이 0일 때도 뉴런이 일정한 기준값을 가질 수 있게 합니다.
가중치:
입력의 영향 조정
편향:
판단 기준선 이동가중치가 라디오의 볼륨 조절 장치라면 편향은 방송국을 맞추는 주파수 다이얼과 비슷합니다. 📻
8. 신경망의 층
입력층
모델에 데이터를 전달합니다.
입력 이미지:
28 × 28 픽셀
입력 특성:
784개은닉층
입력 데이터의 패턴을 학습하는 층입니다.
layers.Dense(
128,
activation="relu"
)`128`은 이 층에 뉴런이 128개 있다는 의미입니다.
출력층
문제의 최종 결과를 출력합니다.
회귀
layers.Dense(1)숫자 하나를 출력합니다.
이진 분류
layers.Dense(
1,
activation="sigmoid"
)0에서 1 사이의 확률 하나를 출력합니다.
10개 클래스 분류
layers.Dense(
10,
activation="softmax"
)10개 클래스의 확률을 출력합니다.
9. 순전파
순전파는 입력 데이터가 신경망의 각 층을 차례대로 통과해 예측값을 만드는 과정입니다.
입력
→ 첫 번째 은닉층
→ 두 번째 은닉층
→ 출력층
→ 예측예를 들어 숫자 이미지가 들어오면 다음 과정이 진행됩니다.
28 × 28 이미지
→ 784개 숫자로 펼치기
→ Dense 뉴런 계산
→ 활성화 함수
→ 출력 클래스 확률
→ 가장 높은 확률의 숫자 선택Keras에서는 모델을 호출하거나 `predict()`를 실행하면 순전파가 수행됩니다.
predictions = model.predict(
test_images
)순전파는 학생이 문제를 읽고 현재 실력으로 답을 제출하는 단계입니다.
답이 맞았는지는 아직 확인하지 않았습니다.
10. 활성화 함수
활성화 함수는 뉴런의 계산 결과를 변환해 신경망이 복잡한 관계를 학습할 수 있도록 합니다.
활성화 함수가 없다면 여러 Dense 층을 쌓아도 전체적으로는 단순한 선형 변환에 머물게 됩니다.
ReLU
ReLU(x) = max(0, x)음수
→ 0
양수
→ 그대로Keras:
layers.Dense(
128,
activation="relu"
)은닉층에서 가장 흔히 시작점으로 사용되는 활성화 함수입니다.
입력: -3
출력: 0
입력: 5
출력: 5ReLU는 음수에게 문을 닫고 양수에게는 통행증을 발급합니다.
Sigmoid
Sigmoid는 값을 0과 1 사이로 변환합니다.
layers.Dense(
1,
activation="sigmoid"
)이진 분류의 출력층에서 활용할 수 있습니다.
출력:
0.87
해석:
양성 클래스일 확률 약 87%Softmax
Softmax는 여러 클래스의 출력값을 확률 분포로 변환합니다.
layers.Dense(
3,
activation="softmax"
)결과 예:
고양이: 0.10
강아지: 0.80
토끼: 0.10모든 확률의 합은 1이 됩니다.
대표 활성화 함수
| 함수 | 주 사용 위치 | 특징 |
|---|---|---|
| ReLU | 은닉층 | 음수는 0, 양수는 유지 |
| Sigmoid | 이진 분류 출력층 | 0~1 확률 |
| Softmax | 다중 분류 출력층 | 클래스별 확률 |
| Tanh | 일부 은닉층·순환 모델 | -1~1 범위 |
| Linear | 회귀 출력층 | 값을 그대로 출력 |
Keras에서는 Dense 같은 레이어의 `activation` 인수나 별도의 Activation 레이어를 통해 활성화 함수를 지정할 수 있습니다.
11. 손실 함수
손실 함수는 모델의 예측이 실제 정답과 얼마나 다른지 숫자로 계산합니다.
정답:
7
예측:
2
→ 손실 큼정답:
7
예측:
6.9
→ 손실 작음신경망 학습의 목표는 손실을 줄이는 것입니다.
모델의 목표:
정확도를 직접 자랑하기 전에
손실부터 줄이기회귀
회귀에서는 평균제곱오차를 사용할 수 있습니다.
loss="mse"이진 분류
loss="binary_crossentropy"정답이 0 또는 1인 문제에 사용할 수 있습니다.
다중 분류
정답이 정수 클래스 번호라면 다음 손실을 사용할 수 있습니다.
loss="sparse_categorical_crossentropy"예:
정답:
0, 1, 2, 3, ... 9정답이 원-핫 인코딩되어 있다면 다음을 사용할 수 있습니다.
loss="categorical_crossentropy"Keras 공식 문서에서 `SparseCategoricalCrossentropy`는 두 개 이상의 클래스를 분류하면서 정답이 정수 레이블로 제공되는 경우에 사용하도록 설명합니다.
손실 함수 선택표
| 문제 | 출력층 | 대표 손실 |
|---|---|---|
| 회귀 | Dense(1) | MSE, MAE |
| 이진 분류 | Dense(1, sigmoid) | Binary Crossentropy |
| 정수 다중 분류 | Dense(K, softmax) | Sparse Categorical Crossentropy |
| 원-핫 다중 분류 | Dense(K, softmax) | Categorical Crossentropy |
출력층과 손실 함수의 조합이 맞지 않으면 모델은 열심히 공부하면서도 시험 과목을 잘못 선택할 수 있습니다.
12. 경사하강법과 옵티마이저
손실을 계산했다면 가중치를 어느 방향으로 수정해야 하는지 결정해야 합니다.
이 과정을 담당하는 것이 옵티마이저입니다.
경사하강법
산 위에 서 있지만 안개 때문에 전체 지형을 볼 수 없다고 가정해 보겠습니다.
가장 낮은 골짜기로 내려가려면 현재 위치에서 어느 방향이 아래쪽인지 확인한 뒤 조금 이동할 수 있습니다.
현재 위치에서 기울기 계산
→ 손실이 감소하는 방향 탐색
→ 가중치 조금 수정
→ 다시 손실 계산
→ 반복이 과정을 경사하강법이라고 합니다.
Adam
Keras에서 많이 사용하는 옵티마이저 중 하나가 Adam입니다.
optimizer="adam"직접 설정할 수도 있습니다.
optimizer = keras.optimizers.Adam(
learning_rate=0.001
)Adam은 각 매개변수의 업데이트에 적응적인 학습률 개념을 적용하는 확률적 경사하강법 계열 옵티마이저입니다. Keras의 기본 Adam 학습률은 `0.001`입니다.
옵티마이저는 신경망의 트레이너입니다.
“틀렸어!”
라고 말하는 것은 손실 함수이고,
“그럼 어느 근육을 얼마나 조정하지?”
를 결정하는 것이 옵티마이저입니다.13. 역전파
역전파는 출력에서 계산된 손실을 신경망 뒤쪽부터 앞쪽으로 전달하며 각 가중치가 손실에 얼마나 영향을 주었는지 계산하는 과정입니다.
입력
→ 은닉층 1
→ 은닉층 2
→ 출력
→ 손실 계산이후 반대 방향으로 진행합니다.
손실
→ 출력층 책임 계산
→ 은닉층 2 책임 계산
→ 은닉층 1 책임 계산
→ 가중치 수정역전파의 핵심에는 미분과 연쇄법칙이 있습니다.
하지만 Keras를 사용하는 입문 단계에서는 미분 공식을 직접 구현하지 않아도 됩니다.
TensorFlow의 자동 미분 기능이 각 가중치에 대한 기울기를 계산합니다.
전체 학습 과정
1. 데이터를 입력한다.
2. 순전파로 예측한다.
3. 손실을 계산한다.
4. 역전파로 기울기를 계산한다.
5. 옵티마이저가 가중치를 수정한다.
6. 다음 데이터를 학습한다.
7. 반복한다.신경망의 성장 비결은 실수를 숨기지 않는 것입니다.
틀린 답을 발견하면 책임 소재를 각 층에 공평하게 나눠 주고 다음 시험에 반영합니다. 📝
14. 에포크·배치·스텝
딥러닝 학습 로그를 보면 다음 단어들이 등장합니다.
epoch
batch
step에포크
전체 학습 데이터를 한 번 모두 사용한 것을 1에포크라고 합니다.
학습 데이터:
10,000개
모든 데이터를 한 번 학습:
1 epoch배치
전체 데이터를 한 번에 처리하지 않고 작은 묶음으로 나눕니다.
학습 데이터:
10,000개
batch_size:
100
→ 한 번에 100개씩 처리스텝
배치 하나를 처리하고 가중치를 한 번 수정하는 과정입니다.
데이터 10,000개
÷ 배치 크기 100
= 에포크당 100스텝코드
model.fit(
X_train,
y_train,
epochs=20,
batch_size=100
)의미:
전체 학습 데이터를
100개씩 나누어 학습하고
이 과정을 최대 20번 반복한다.에포크는 교과서 전체 회독 수이고, 배치는 한 번에 공부하는 페이지 묶음입니다.
책 500페이지를 한 번에 펼치면 책상도 모델도 힘들어집니다.
15. 학습률
학습률은 가중치를 한 번에 얼마나 크게 수정할지 결정합니다.
keras.optimizers.Adam(
learning_rate=0.001
)너무 큰 학습률
골짜기를 향해 내려가지만
한 번에 너무 멀리 점프
→ 최저점을 계속 지나침
→ 손실이 불안정너무 작은 학습률
한 걸음이 지나치게 작음
→ 학습이 매우 느림
→ 제한된 에포크 안에 도착하지 못함적절한 학습률
안정적으로 손실이 감소하면서
합리적인 시간 안에 수렴학습률은 모델의 보폭입니다.
보폭이 너무 크면 계단을 건너뛰고, 너무 작으면 점심시간이 끝날 때까지 첫 계단에 머뭅니다.
16. TensorFlow 설치하기
가상환경을 만든 뒤 설치하는 것이 좋습니다.
Windows
python -m venv venv
venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install tensorflow matplotlibmacOS 또는 Linux
python3 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
python -m pip install tensorflow matplotlibTensorFlow 2.16 이상을 설치하면 Keras 3이 함께 설치되므로 이번 예제에서는 Keras를 별도로 설치하지 않아도 됩니다.
설치 확인
import tensorflow as tf
print(
tf.__version__
)Keras 확인
from tensorflow import keras
print(
keras.__version__
)계산 장치 확인
import tensorflow as tf
print(
tf.config.list_physical_devices()
)CPU만 표시되어도 이번 글의 예제는 실행할 수 있습니다.
GPU 설정은 운영체제, GPU 종류, 드라이버와 TensorFlow 버전에 따라 달라지므로 실제 환경에서는 해당 버전의 공식 설치 안내를 확인해야 합니다.
17. 텐서란?
텐서는 다차원 숫자 배열입니다.
NumPy에서 배웠던 `ndarray`와 비슷하게 생각할 수 있습니다.
0차원 텐서
import tensorflow as tf
scalar = tf.constant(7)
print(scalar)
print(scalar.shape)1차원 텐서
vector = tf.constant([
10,
20,
30
])
print(vector)2차원 텐서
matrix = tf.constant([
[1, 2, 3],
[4, 5, 6]
])
print(matrix)3차원 텐서
tensor_3d = tf.constant([
[
[1, 2],
[3, 4]
],
[
[5, 6],
[7, 8]
]
])
print(tensor_3d.shape)결과:
(2, 2, 2)NumPy 변환
numpy_array = matrix.numpy()
print(numpy_array)TensorFlow 텐서로 변환
import numpy as np
import tensorflow as tf
array = np.array([
1,
2,
3
])
tensor = tf.convert_to_tensor(
array
)
print(tensor)텐서는 딥러닝 세계의 화물 상자입니다.
숫자, 이미지, 음성, 문장을 계산 가능한 형태로 담아 신경망 층 사이를 이동합니다. 📦
18. 첫 번째 신경망 만들기
먼저 매우 단순한 관계를 학습시켜 보겠습니다.
y = 3x + 5데이터 만들기
import numpy as np
X = np.arange(
-10,
11,
dtype=np.float32
).reshape(
-1,
1
)
y = (
3 * X
+ 5
)모델 만들기
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
keras.Input(
shape=(1,)
),
layers.Dense(1)
])모델 컴파일
model.compile(
optimizer=keras.optimizers.Adam(
learning_rate=0.05
),
loss="mse"
)모델 학습
history = model.fit(
X,
y,
epochs=300,
verbose=0
)새로운 값 예측
prediction = model.predict(
np.array([
[20.0]
]),
verbose=0
)
print(
f"x=20일 때 예측: "
f"{prediction[0, 0]:.2f}"
)실제 정답:
3 × 20 + 5
= 65학습이 안정적으로 진행되었다면 65에 가까운 값이 출력됩니다.
학습된 가중치 확인
weights, bias = (
model.layers[0]
.get_weights()
)
print(
f"학습된 가중치: "
f"{weights[0, 0]:.4f}"
)
print(
f"학습된 편향: "
f"{bias[0]:.4f}"
)기대값:
가중치:
약 3
편향:
약 5모델은 `y = 3x + 5`라는 공식을 직접 전달받지 않았습니다.
여러 입력과 정답을 보며 가중치와 편향을 조정해 관계를 근사했습니다.
19. Sequential 모델
Sequential은 레이어를 한 줄로 차례대로 쌓는 모델 방식입니다.
입력
→ 레이어 1
→ 레이어 2
→ 출력Keras 공식 문서는 각 층이 입력 하나와 출력 하나를 가지는 단순한 레이어 스택에 Sequential 모델이 적합하다고 설명합니다.
리스트 방식
model = keras.Sequential([
keras.Input(
shape=(20,)
),
layers.Dense(
64,
activation="relu"
),
layers.Dense(
32,
activation="relu"
),
layers.Dense(
1,
activation="sigmoid"
)
])add 방식
model = keras.Sequential()
model.add(
keras.Input(
shape=(20,)
)
)
model.add(
layers.Dense(
64,
activation="relu"
)
)
model.add(
layers.Dense(
1,
activation="sigmoid"
)
)모델 구조 확인
model.summary()출력에는 다음 정보가 표시됩니다.
레이어 이름
출력 형태
학습할 파라미터 개수
전체 파라미터 수파라미터 개수 계산
입력 특성이 20개이고 뉴런이 64개라면:
가중치:
20 × 64 = 1,280개
편향:
64개
전체:
1,344개뉴런 수를 늘리면 표현 능력뿐 아니라 학습할 파라미터와 계산량도 증가합니다.
20. compile·fit·evaluate·predict
Keras 모델의 기본 흐름은 네 단계로 정리할 수 있습니다.
compile
학습 방법을 설정합니다.
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=[
"accuracy"
]
)fit
학습 데이터를 이용해 모델을 학습합니다.
history = model.fit(
X_train,
y_train,
epochs=20,
batch_size=128,
validation_split=0.1
)evaluate
평가 데이터로 손실과 지표를 계산합니다.
test_loss, test_accuracy = (
model.evaluate(
X_test,
y_test
)
)predict
새로운 데이터의 출력값을 계산합니다.
predictions = model.predict(
X_new
)Keras의 기본 학습 API는 `fit()`, 평가 API는 `evaluate()`, 추론 API는 `predict()`를 중심으로 구성됩니다.
compile
→ 공부 방법 결정
fit
→ 실제 공부
evaluate
→ 모의고사
predict
→ 새로운 문제 풀기21. 학습·검증·평가 데이터
딥러닝에서는 데이터를 보통 세 부분으로 나눕니다.
학습 데이터
검증 데이터
평가 데이터학습 데이터
모델의 가중치를 직접 수정하는 데 사용합니다.
검증 데이터
학습 중 모델이 새로운 데이터에서도 잘 작동하는지 확인합니다.
model.fit(
X_train,
y_train,
validation_split=0.1
)학습 데이터의 10%를 검증에 사용합니다.
평가 데이터
모델 개발이 끝난 후 최종 성능을 확인합니다.
model.evaluate(
X_test,
y_test
)중요한 원칙
학습 데이터:
가중치 학습
검증 데이터:
모델 선택과 조기 종료
평가 데이터:
최종 성적 확인평가 결과를 확인하며 모델을 계속 수정하면 평가 데이터에도 간접적으로 과적합될 수 있습니다.
평가 데이터는 졸업시험입니다.
연습문제처럼 매일 펼쳐 보면 더 이상 공정한 시험지가 아닙니다.
22. 회귀·이진 분류·다중 분류 출력층
문제 유형에 따라 출력층과 손실 함수를 맞춰야 합니다.
회귀
주택 가격처럼 연속적인 숫자를 예측합니다.
model.add(
layers.Dense(1)
)
model.compile(
optimizer="adam",
loss="mse",
metrics=[
"mae"
]
)이진 분류
해지 또는 유지처럼 두 클래스를 분류합니다.
model.add(
layers.Dense(
1,
activation="sigmoid"
)
)
model.compile(
optimizer="adam",
loss="binary_crossentropy",
metrics=[
"accuracy"
]
)다중 분류
0부터 9까지 숫자를 분류합니다.
model.add(
layers.Dense(
10,
activation="softmax"
)
)
model.compile(
optimizer="adam",
loss=(
"sparse_categorical_crossentropy"
),
metrics=[
"accuracy"
]
)조합표
| 문제 | 출력 뉴런 | 활성화 | 손실 |
|---|---|---|---|
| 회귀 | 1 | 없음 또는 linear | MSE·MAE |
| 이진 분류 | 1 | sigmoid | binary crossentropy |
| 정수 다중 분류 | 클래스 수 | softmax | sparse categorical crossentropy |
| 원-핫 다중 분류 | 클래스 수 | softmax | categorical crossentropy |
출력층과 손실 함수는 한 팀입니다.
축구화를 신고 수영장에 들어가면 장비는 새것이어도 경기가 순조롭지 않습니다.
23. 과소적합과 과적합
과소적합
모델이 데이터의 패턴을 충분히 배우지 못한 상태입니다.
학습 정확도:
낮음
검증 정확도:
낮음원인 예:
모델이 지나치게 단순함
학습 시간이 짧음
특성이 부족함
학습률이 부적절함과적합
학습 데이터를 지나치게 외운 상태입니다.
학습 정확도:
계속 상승
검증 정확도:
정체 또는 하락
검증 손실:
다시 증가원인 예:
모델이 지나치게 복잡함
데이터가 적음
에포크가 너무 많음
규제가 부족함대응 방법
더 많은 데이터 확보
데이터 증강
모델 단순화
Dropout
가중치 규제
EarlyStopping
전이학습과소적합 모델은 교과서를 덜 읽었고, 과적합 모델은 답안지의 커피 얼룩 위치까지 암기했습니다.
24. Dropout
Dropout은 학습 중 일부 뉴런의 출력을 무작위로 0으로 만들어 특정 뉴런에 지나치게 의존하지 않도록 돕는 규제 기법입니다.
layers.Dropout(
0.2
)`0.2`는 학습 중 약 20%의 입력 단위를 무작위로 제외한다는 의미입니다.
model = keras.Sequential([
keras.Input(
shape=(784,)
),
layers.Dense(
128,
activation="relu"
),
layers.Dropout(
0.2
),
layers.Dense(
10,
activation="softmax"
)
])Dropout은 학습할 때 활성화되고 일반적인 예측 시에는 비활성화됩니다. Keras는 Dropout을 비롯한 여러 규제 레이어를 제공합니다.
Dropout은 회의 중 일부 팀원을 무작위로 휴가 보내는 방식과 비슷합니다.
남은 팀원들이 스스로 일하는 법을 배우게 되지만, 휴가 비율이 너무 높으면 프로젝트가 멈출 수도 있습니다. 🏖️
25. EarlyStopping과 ModelCheckpoint
EarlyStopping
검증 성능이 더 이상 좋아지지 않으면 학습을 중단합니다.
early_stopping = (
keras.callbacks.EarlyStopping(
monitor="val_loss",
patience=3,
restore_best_weights=True
)
)monitor="val_loss"
→ 검증 손실 감시
patience=3
→ 3에포크 동안 개선이 없어도 기다림
restore_best_weights=True
→ 가장 좋았던 가중치 복구EarlyStopping은 에포크가 끝날 때마다 지정한 지표의 개선 여부를 확인하고 조건을 만족하면 학습을 종료합니다.
ModelCheckpoint
학습 중 가장 좋은 모델을 파일로 저장합니다.
checkpoint = (
keras.callbacks.ModelCheckpoint(
filepath="best_model.keras",
monitor="val_loss",
save_best_only=True
)
)ModelCheckpoint는 `fit()` 학습 과정에서 모델이나 가중치를 지정한 조건에 따라 저장하는 Callback입니다.
함께 사용하기
history = model.fit(
X_train,
y_train,
validation_split=0.1,
epochs=50,
callbacks=[
early_stopping,
checkpoint
]
)Callback은 학습, 평가, 예측 과정의 특정 시점에 추가 동작을 연결하는 기능입니다.
EarlyStopping:
“더 공부해도 성적이 안 오르니 여기까지.”
ModelCheckpoint:
“가장 잘 본 시험지는 따로 보관했습니다.”26. 학습 기록 시각화
`model.fit()`은 History 객체를 반환합니다.
History에는 에포크별 손실과 평가 지표가 저장됩니다.
history = model.fit(
X_train,
y_train,
epochs=20,
validation_split=0.1
)저장된 항목 확인
print(
history.history.keys()
)결과 예:
dict_keys([
'accuracy',
'loss',
'val_accuracy',
'val_loss'
])손실 그래프
import matplotlib.pyplot as plt
plt.figure(
figsize=(10, 5)
)
plt.plot(
history.history["loss"],
label="Train loss"
)
plt.plot(
history.history["val_loss"],
label="Validation loss"
)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training and Validation Loss")
plt.legend()
plt.grid(alpha=0.3)
plt.show()정확도 그래프
plt.figure(
figsize=(10, 5)
)
plt.plot(
history.history["accuracy"],
label="Train accuracy"
)
plt.plot(
history.history["val_accuracy"],
label="Validation accuracy"
)
plt.xlabel("Epoch")
plt.ylabel("Accuracy")
plt.title(
"Training and Validation Accuracy"
)
plt.legend()
plt.grid(alpha=0.3)
plt.show()과적합 징후
학습 손실:
계속 감소
검증 손실:
어느 순간부터 증가이 시점 이후에는 모델이 새로운 패턴을 배우기보다 학습 데이터의 세부 특징을 외우고 있을 가능성이 있습니다.
27. 실전 프로젝트 준비
이번에는 손글씨 숫자 이미지를 분류하는 신경망을 만들겠습니다.
프로젝트 목표
MNIST 데이터 불러오기
이미지 형태 확인
픽셀값 정규화
Sequential 신경망 생성
모델 컴파일
EarlyStopping 적용
모델 학습
평가 데이터 정확도 확인
숫자 예측
혼동행렬 출력
오답 이미지 분석
모델 저장과 불러오기필요한 라이브러리:
python -m pip install tensorflow matplotlib28. MNIST 데이터셋
MNIST는 0부터 9까지 손글씨 숫자가 포함된 대표적인 이미지 분류 데이터셋입니다.
TensorFlow의 Keras 데이터셋 API는 28×28 크기의 회색조 학습 이미지 60,000장과 평가 이미지 10,000장을 제공합니다.
데이터 불러오기
from tensorflow import keras
(
train_images,
train_labels
), (
test_images,
test_labels
) = (
keras.datasets.mnist.load_data()
)형태 확인
print(
train_images.shape
)
print(
train_labels.shape
)
print(
test_images.shape
)
print(
test_labels.shape
)결과:
(60000, 28, 28)
(60000,)
(10000, 28, 28)
(10000,)의미:
학습 이미지:
60,000장
각 이미지:
28행 × 28열
학습 정답:
이미지마다 숫자 하나첫 번째 이미지 확인
import matplotlib.pyplot as plt
plt.imshow(
train_images[0],
cmap="gray"
)
plt.title(
f"Label: {train_labels[0]}"
)
plt.axis("off")
plt.show()컴퓨터에게 이미지는 그림이 아니라 숫자 표입니다.
0:
검은색
255:
흰색
중간값:
회색신경망은 “이 숫자는 5처럼 생겼다”라고 감상하지 않습니다.
784개의 픽셀값을 보고 통계적인 패턴을 계산합니다.
29. 이미지 정규화
MNIST 픽셀값은 0부터 255 사이입니다.
이를 0부터 1 사이로 변환하겠습니다.
train_images = (
train_images.astype(
"float32"
)
/ 255.0
)
test_images = (
test_images.astype(
"float32"
)
/ 255.0
)변환 전:
0 ~ 255변환 후:
0.0 ~ 1.0입력값 범위를 일정하게 조정하면 학습이 더 안정적으로 진행되는 경우가 많습니다.
정답은 변환하지 않는다
print(
train_labels[:10]
)결과 예:
[5 0 4 1 9 2 1 3 1 4]이번 모델에서는 `sparse_categorical_crossentropy`를 사용하므로 정답을 원-핫 인코딩하지 않고 정수 상태로 유지합니다.
30. 손글씨 숫자 분류 모델
모델 구조
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
keras.Input(
shape=(28, 28)
),
layers.Flatten(),
layers.Dense(
128,
activation="relu"
),
layers.Dropout(
0.2
),
layers.Dense(
10,
activation="softmax"
)
])레이어 해석
Input
keras.Input(
shape=(28, 28)
)28×28 이미지를 입력받습니다.
Flatten
layers.Flatten()2차원 이미지를 1차원으로 펼칩니다.
28 × 28
→ 784Dense 128
layers.Dense(
128,
activation="relu"
)128개의 뉴런이 픽셀 조합에서 패턴을 학습합니다.
Dropout
layers.Dropout(
0.2
)과적합을 줄이기 위해 학습 중 일부 뉴런을 무작위로 제외합니다.
출력층
layers.Dense(
10,
activation="softmax"
)0부터 9까지 10개 숫자의 확률을 출력합니다.
모델 구조 확인
model.summary()31. 모델 학습과 평가
컴파일
model.compile(
optimizer=keras.optimizers.Adam(
learning_rate=0.001
),
loss=(
keras.losses
.SparseCategoricalCrossentropy()
),
metrics=[
keras.metrics
.SparseCategoricalAccuracy(
name="accuracy"
)
]
)Callback 준비
callbacks = [
keras.callbacks.EarlyStopping(
monitor="val_loss",
patience=3,
restore_best_weights=True
),
keras.callbacks.ModelCheckpoint(
filepath=(
"best_mnist_model.keras"
),
monitor="val_loss",
save_best_only=True
)
]학습
history = model.fit(
train_images,
train_labels,
validation_split=0.1,
epochs=20,
batch_size=128,
callbacks=callbacks,
verbose=1
)`fit()`은 학습 데이터와 NumPy 배열뿐 아니라 다양한 데이터 입력 형식을 지원하며, 손실과 지표는 History 객체에 기록됩니다.
평가
test_loss, test_accuracy = (
model.evaluate(
test_images,
test_labels,
verbose=0
)
)
print(
f"평가 손실: "
f"{test_loss:.4f}"
)
print(
f"평가 정확도: "
f"{test_accuracy:.4%}"
)실행 환경과 무작위 초기값에 따라 결과는 달라질 수 있습니다.
높은 정확도가 나왔다고 모델이 사람처럼 숫자를 이해하는 것은 아닙니다.
학습 데이터에서 발견한 픽셀 패턴으로 숫자를 구분하는 능력을 얻은 것입니다.
32. 예측 결과 확인
전체 평가 이미지 예측
import numpy as np
probabilities = model.predict(
test_images,
verbose=0
)
predicted_labels = np.argmax(
probabilities,
axis=1
)`probabilities`의 형태:
(10000, 10)첫 번째 이미지에 대한 확률:
print(
probabilities[0]
)예:
[0.0001, 0.0000, 0.0004, ..., 0.9980, ...]가장 높은 확률의 위치가 예측 숫자가 됩니다.
print(
predicted_labels[0]
)
print(
test_labels[0]
)이미지와 예측 표시
index = 0
plt.imshow(
test_images[index],
cmap="gray"
)
plt.title(
"Actual: "
f"{test_labels[index]} / "
"Predicted: "
f"{predicted_labels[index]}"
)
plt.axis("off")
plt.show()예측 확률 확인
confidence = np.max(
probabilities[index]
)
print(
f"예측 확률: "
f"{confidence:.2%}"
)예측 확률이 높다고 반드시 예측이 맞는 것은 아닙니다.
모델도 자신 있게 틀릴 수 있습니다.
회의실에서 가장 큰 목소리가 항상 정답은 아닌 것과 같습니다.
33. 혼동행렬 만들기
혼동행렬을 이용하면 어떤 숫자를 어떤 숫자로 자주 혼동하는지 확인할 수 있습니다.
계산
confusion_matrix = (
tf.math.confusion_matrix(
test_labels,
predicted_labels,
num_classes=10
)
.numpy()
)
print(confusion_matrix)시각화
plt.figure(
figsize=(9, 8)
)
plt.imshow(
confusion_matrix,
cmap="Blues"
)
plt.title(
"MNIST Confusion Matrix"
)
plt.xlabel(
"Predicted label"
)
plt.ylabel(
"Actual label"
)
plt.xticks(
range(10)
)
plt.yticks(
range(10)
)
plt.colorbar()
for actual in range(10):
for predicted in range(10):
value = confusion_matrix[
actual,
predicted
]
if value > 0:
plt.text(
predicted,
actual,
str(value),
ha="center",
va="center"
)
plt.tight_layout()
plt.show()대각선은 올바른 예측입니다.
실제 3
→ 예측 3대각선 밖의 값은 오답입니다.
실제 4
→ 예측 9정확도 하나만 보면 어떤 종류의 실수가 발생하는지 알기 어렵습니다.
혼동행렬은 모델의 오답 노트를 펼쳐 보여 줍니다.
34. 틀린 예측 분석하기
오답 위치 찾기
wrong_indices = np.where(
predicted_labels
!= test_labels
)[0]
print(
f"오답 개수: "
f"{len(wrong_indices)}"
)오답 이미지 표시
plt.figure(
figsize=(12, 8)
)
for plot_index, data_index in enumerate(
wrong_indices[:12]
):
plt.subplot(
3,
4,
plot_index + 1
)
plt.imshow(
test_images[data_index],
cmap="gray"
)
confidence = np.max(
probabilities[data_index]
)
plt.title(
f"True: {test_labels[data_index]}\n"
f"Pred: {predicted_labels[data_index]}\n"
f"Conf: {confidence:.1%}"
)
plt.axis("off")
plt.tight_layout()
plt.show()오답 분석 질문
글씨가 지나치게 흐린가?
두 숫자의 모양이 비슷한가?
이미지가 한쪽으로 치우쳤는가?
사람도 구분하기 어려운가?
특정 숫자에서 오답이 집중되는가?모델 개선은 단순히 레이어를 더 쌓는 것에서 시작하지 않습니다.
모델이 틀린 데이터를 직접 살펴보는 과정에서 시작합니다.
모델:
“저건 9입니다.”
사람:
“아무리 봐도 4인데?”
이미지:
“사실 저도 제 정체성을 고민 중입니다.”35. 모델 저장과 불러오기
전체 모델 저장
model.save(
"mnist_classifier.keras"
)Keras 모델 저장 기능은 모델 구조, 가중치, 학습 설정 등을 저장하고 다시 불러오는 흐름을 제공합니다. 커스텀 레이어나 함수가 포함되면 별도의 직렬화 설정이 필요할 수 있습니다.
모델 불러오기
loaded_model = (
keras.models.load_model(
"mnist_classifier.keras"
)
)다시 평가
loss, accuracy = (
loaded_model.evaluate(
test_images,
test_labels,
verbose=0
)
)
print(
f"불러온 모델 정확도: "
f"{accuracy:.4%}"
)다시 예측
prediction = loaded_model.predict(
test_images[:1],
verbose=0
)
print(
np.argmax(
prediction[0]
)
)저장 시 함께 관리할 정보
TensorFlow 버전
Keras 버전
Python 버전
학습 데이터 버전
전처리 방법
클래스 이름
입력 크기
학습 날짜
평가 결과모델 파일만 저장하고 입력 규칙을 기록하지 않으면 미래의 개발자가 디지털 유적 발굴 작업을 시작하게 됩니다. 🏺
36. Functional API
Sequential은 한 줄로 이어지는 모델에 적합합니다.
하지만 다음 구조에서는 한계가 있습니다.
입력이 여러 개
출력이 여러 개
중간 레이어가 갈라짐
레이어를 공유함
건너뛰는 연결이 있음이럴 때 Functional API를 사용할 수 있습니다.
Keras Functional API는 Sequential보다 유연하며 비선형 구조, 공유 레이어, 다중 입력과 다중 출력을 구성할 수 있습니다.
기본 예제
inputs = keras.Input(
shape=(20,),
name="customer_features"
)
x = layers.Dense(
64,
activation="relu"
)(inputs)
x = layers.Dense(
32,
activation="relu"
)(x)
outputs = layers.Dense(
1,
activation="sigmoid",
name="churn_probability"
)(x)
model = keras.Model(
inputs=inputs,
outputs=outputs
)흐름
Input 객체 생성
→ 레이어를 함수처럼 호출
→ 입력과 출력을 연결
→ Model 생성Functional API에서는 데이터가 흐르는 경로를 코드로 직접 그리는 느낌을 받을 수 있습니다.
Sequential이 직선 지하철 노선이라면 Functional API는 환승역과 지선이 있는 도시철도망입니다. 🚇
37. 전이학습
전이학습은 이미 대규모 데이터로 학습된 모델의 지식을 새로운 문제에 활용하는 방법입니다.
예를 들어 ImageNet으로 학습된 이미지 모델은 다음과 같은 시각적 특징을 어느 정도 학습하고 있습니다.
선
모서리
질감
형태
복잡한 물체 구조새로운 고양이·강아지 분류 문제에서 처음부터 모든 특징을 학습하는 대신 기존 모델의 일부를 재사용할 수 있습니다.
기본 흐름
사전 학습 모델 불러오기
→ 기존 가중치 고정
→ 새로운 출력층 추가
→ 새 데이터로 출력층 학습
→ 필요하면 일부 층을 낮은 학습률로 미세조정Keras Applications는 사전 학습 가중치와 함께 사용할 수 있는 여러 딥러닝 모델을 제공합니다. 이러한 모델은 예측, 특징 추출, 미세조정에 활용할 수 있습니다.
TensorFlow 공식 가이드는 전이학습 후 필요에 따라 일부 또는 전체 층을 다시 학습하는 미세조정 단계를 설명하며, 미세조정 시에는 일반적으로 낮은 학습률을 사용합니다.
개념 예제
base_model = (
keras.applications.MobileNetV2(
weights="imagenet",
include_top=False,
input_shape=(
224,
224,
3
)
)
)
base_model.trainable = Falsebase_model:
기존에 학습된 시각 특징 추출기
새 출력층:
현재 문제에 맞는 분류기전이학습은 새 직원에게 알파벳부터 다시 가르치는 대신 경력자를 채용해 회사 업무만 추가로 교육하는 방식입니다.
38. GPU 확인하기
TensorFlow가 인식한 GPU를 확인할 수 있습니다.
import tensorflow as tf
gpus = tf.config.list_physical_devices(
"GPU"
)
print(
f"GPU 개수: {len(gpus)}"
)
for gpu in gpus:
print(gpu)GPU가 없으면 다음처럼 빈 목록이 출력될 수 있습니다.
[]이번 MNIST 모델은 CPU에서도 학습할 수 있습니다.
GPU는 이미지, 영상, 언어 모델처럼 계산량이 큰 신경망에서 학습 시간을 크게 줄이는 데 도움이 될 수 있습니다.
그러나 GPU가 있다고 모든 모델이 자동으로 빨라지는 것은 아닙니다.
모델이 매우 작음
데이터 전송 시간이 큼
입력 파이프라인이 느림
GPU 메모리가 부족함이런 경우 GPU 사용 효과가 제한될 수 있습니다.
39. 재현 가능한 실험 만들기
신경망은 가중치 초기화, 데이터 섞기, Dropout 등 여러 무작위 요소를 포함합니다.
Keras에서 무작위 시드를 설정할 수 있습니다.
from tensorflow import keras
keras.utils.set_random_seed(
2026
)NumPy도 함께 사용한다면 다음처럼 작성할 수 있습니다.
import numpy as np
np.random.seed(
2026
)실험 기록
Python 버전
TensorFlow 버전
Keras 버전
운영체제
하드웨어
무작위 시드
학습 데이터
전처리 방식
모델 구조
학습률
배치 크기
에포크
평가 결과동일한 시드를 지정해도 하드웨어와 연산 방식에 따라 결과가 완전히 동일하지 않을 수 있습니다.
따라서 재현성은 시드 하나가 아니라 실행 환경 전체를 기록하는 문제입니다.
무작위 시드는 실험 세계에 꽂아 두는 책갈피이지만, 책의 판본까지 달라지면 페이지 내용도 달라질 수 있습니다.
40. TensorFlow 사용 시 주의점
딥러닝부터 선택하지 않는다
표 데이터가 작다면 scikit-learn 모델을 먼저 기준 모델로 만들어 보는 것이 좋습니다.
선형회귀
로지스틱 회귀
랜덤 포레스트
그래디언트 부스팅더 복잡한 신경망이 기준 모델보다 실제로 좋은지 비교해야 합니다.
평가 데이터 누수를 막는다
이미지 정규화처럼 고정된 변환은 단순하지만, 데이터에서 평균이나 통계를 학습하는 전처리는 학습 데이터만 사용해야 합니다.
학습 데이터로 전처리 규칙 학습
→ 검증·평가 데이터에는 같은 규칙 적용정확도 하나만 보지 않는다
불균형 분류에서는 다음 지표를 함께 확인합니다.
정밀도
재현율
F1 점수
ROC AUC
PR AUC
혼동행렬검증 손실을 확인한다
학습 정확도만 계속 증가한다고 좋은 모델은 아닙니다.
학습 손실 감소
검증 손실 증가
→ 과적합 가능성입력 형태를 확인한다
print(
X_train.shape
)
print(
y_train.shape
)신경망 오류의 상당수는 철학보다 `shape`에서 발생합니다.
모델의 출력과 손실을 맞춘다
sigmoid
+ binary crossentropy
softmax
+ categorical 계열 손실
linear
+ 회귀 손실운영 환경 변화를 감시한다
학습 당시와 운영 시점의 데이터가 달라질 수 있습니다.
카메라 교체
조명 변화
고객 행동 변화
상품 정책 변화
새로운 클래스 등장모델의 자신감을 맹신하지 않는다
예측 확률 99%
≠
정답이 확실함학습 범위를 벗어난 입력에서도 모델이 높은 확률을 출력할 수 있습니다.
윤리와 개인정보를 확인한다
사람에게 영향을 주는 예측에서는 편향, 설명 가능성, 개인정보 보호, 오류 비용을 검토해야 합니다.
대출
채용
보험
교육
의료
보안신경망은 숫자를 최적화합니다.
그 숫자가 사회적으로 올바른 목표인지 결정하는 책임은 사람에게 있습니다.
41. 자주 발생하는 오류
오류 1. TensorFlow가 설치되지 않음
ModuleNotFoundError:
No module named 'tensorflow'해결:
python -m pip install tensorflow설치 확인:
python -m pip show tensorflow오류 2. Python 환경이 다름
TensorFlow를 설치한 Python과 코드를 실행하는 Python이 다를 수 있습니다.
python -c "import sys; print(sys.executable)"python -m pip show tensorflow가상환경이 활성화되어 있는지 확인합니다.
오류 3. 입력 형태가 맞지 않음
expected shape=(None, 28, 28)
found shape=(None, 784)모델의 입력 형태와 실제 데이터 형태를 비교합니다.
print(
model.input_shape
)
print(
train_images.shape
)오류 4. 출력 클래스 수가 맞지 않음
숫자 0부터 9까지 분류하는데 출력 뉴런을 9개만 만들면 안 됩니다.
# 잘못된 예
layers.Dense(
9,
activation="softmax"
)수정:
layers.Dense(
10,
activation="softmax"
)오류 5. 정답과 손실 함수가 맞지 않음
정답이 정수인 경우:
0, 1, 2, ..., 9사용:
loss=(
"sparse_categorical_crossentropy"
)정답이 원-핫 인코딩된 경우:
[0, 0, 1, 0, ...]사용:
loss="categorical_crossentropy"오류 6. loss가 NaN으로 변함
loss: nan확인할 내용:
입력 데이터에 NaN이나 무한대가 있는가?
학습률이 지나치게 큰가?
숫자 범위가 지나치게 큰가?
잘못된 수학 연산이 있는가?
손실 함수가 문제에 맞는가?확인 코드:
import numpy as np
print(
np.isnan(
train_images
).any()
)
print(
np.isinf(
train_images
).any()
)오류 7. 모델이 전혀 학습되지 않음
accuracy가 계속 비슷함
loss가 감소하지 않음확인할 내용:
정답 데이터가 올바른가?
입력과 정답 순서가 일치하는가?
출력층이 문제와 맞는가?
학습률이 적절한가?
입력값이 정규화되었는가?
모델 용량이 충분한가?오류 8. 학습 정확도만 높음
train accuracy:
99%
validation accuracy:
72%과적합 가능성이 있습니다.
대응:
EarlyStopping
Dropout
모델 단순화
데이터 추가
데이터 증강
규제 적용오류 9. GPU가 인식되지 않음
print(
tf.config.list_physical_devices(
"GPU"
)
)빈 목록이면 TensorFlow가 GPU를 사용하지 못하는 상태입니다.
운영체제, TensorFlow 버전, GPU 드라이버, 지원되는 가속 환경을 확인해야 합니다.
CPU만으로 실행 가능한 모델인지 먼저 판단하는 것도 중요합니다.
오류 10. 메모리가 부족함
ResourceExhaustedError대응:
batch_size 줄이기
이미지 크기 줄이기
모델 크기 줄이기
불필요한 텐서 제거
데이터를 배치 단위로 읽기history = model.fit(
train_images,
train_labels,
batch_size=32
)오류 11. 저장 모델을 불러오지 못함
커스텀 레이어나 커스텀 손실 함수가 포함되었다면 해당 객체 정보를 함께 제공해야 할 수 있습니다.
또한 TensorFlow와 Keras 버전 차이를 확인합니다.
import tensorflow as tf
from tensorflow import keras
print(
tf.__version__
)
print(
keras.__version__
)42. 연습 문제
문제 1
다음 관계를 학습하는 신경망을 만드세요.
y = 2x - 4학습 후 `x=10`의 값을 예측하세요.
문제 2
입력 특성이 5개이고 은닉층 뉴런이 16개인 Sequential 모델을 만드세요.
입력:
5개
은닉층:
16개, ReLU
출력:
1개문제 3
이진 분류 모델의 출력층과 손실 함수를 작성하세요.
힌트
layers.Dense(
1,
activation="sigmoid"
)문제 4
5개 클래스를 분류하는 모델의 출력층을 작성하세요.
layers.Dense(
5,
activation="softmax"
)문제 5
Adam 옵티마이저의 학습률을 `0.0005`로 설정하세요.
keras.optimizers.Adam(
learning_rate=0.0005
)문제 6
검증 손실이 4에포크 동안 개선되지 않으면 학습을 중단하도록 EarlyStopping을 설정하세요.
문제 7
가장 낮은 검증 손실을 가진 모델을 `best.keras`로 저장하도록 ModelCheckpoint를 설정하세요.
문제 8
MNIST 이미지 한 장의 28×28 형태를 784개의 숫자로 바꾸는 레이어를 작성하세요.
layers.Flatten()문제 9
MNIST 평가 데이터 중 잘못 예측한 이미지의 인덱스를 찾으세요.
wrong_indices = np.where(
predicted_labels
!= test_labels
)[0]문제 10
학습 손실과 검증 손실을 하나의 그래프에 출력하세요.
문제 11
다음 모델에서 학습 가능한 파라미터 개수를 직접 계산해 보세요.
model = keras.Sequential([
keras.Input(
shape=(10,)
),
layers.Dense(
8,
activation="relu"
),
layers.Dense(1)
])힌트
첫 번째 Dense:
10 × 8 + 8
두 번째 Dense:
8 × 1 + 1문제 12
Sequential 대신 Functional API로 다음 모델을 만들어 보세요.
입력 20개
→ Dense 64 ReLU
→ Dense 32 ReLU
→ Dense 1 Sigmoid문제 13
과적합이 발생했을 때 사용할 수 있는 방법을 세 가지 이상 설명하세요.
문제 14
다음 상황에 알맞은 모델을 선택해 보세요.
표 데이터 500건으로 가격 예측
100만 장의 이미지 분류
고객 이탈 표 데이터 10만 건
음성에서 문장 인식43. 핵심 요약
TensorFlow 불러오기
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers텐서 생성
tensor = tf.constant([
[1, 2],
[3, 4]
])Sequential 모델
model = keras.Sequential([
keras.Input(
shape=(10,)
),
layers.Dense(
32,
activation="relu"
),
layers.Dense(
1,
activation="sigmoid"
)
])모델 컴파일
model.compile(
optimizer="adam",
loss="binary_crossentropy",
metrics=[
"accuracy"
]
)모델 학습
history = model.fit(
X_train,
y_train,
validation_split=0.1,
epochs=20,
batch_size=128
)모델 평가
loss, accuracy = model.evaluate(
X_test,
y_test
)모델 예측
predictions = model.predict(
X_new
)이진 분류
layers.Dense(
1,
activation="sigmoid"
)loss="binary_crossentropy"다중 분류
layers.Dense(
class_count,
activation="softmax"
)loss=(
"sparse_categorical_crossentropy"
)Dropout
layers.Dropout(
0.2
)EarlyStopping
keras.callbacks.EarlyStopping(
monitor="val_loss",
patience=3,
restore_best_weights=True
)ModelCheckpoint
keras.callbacks.ModelCheckpoint(
"best_model.keras",
monitor="val_loss",
save_best_only=True
)모델 저장
model.save(
"model.keras"
)모델 불러오기
model = keras.models.load_model(
"model.keras"
)GPU 확인
tf.config.list_physical_devices(
"GPU"
)44. 마무리
이번 시간에는 TensorFlow와 Keras를 이용해 인공신경망이 데이터를 학습하는 과정을 살펴보았습니다.
신경망 학습은 다음 과정의 반복입니다.
데이터 입력
→ 순전파
→ 예측
→ 손실 계산
→ 역전파
→ 가중치 수정
→ 다시 예측핵심 개념도 정리해 보겠습니다.
뉴런
→ 입력값을 계산하는 단위
가중치
→ 입력의 영향력
편향
→ 판단 기준 조정
활성화 함수
→ 비선형 표현 생성
손실 함수
→ 예측이 얼마나 틀렸는지 계산
옵티마이저
→ 가중치 수정 방향 결정
에포크
→ 전체 데이터 학습 횟수
배치
→ 한 번에 처리하는 데이터 묶음
역전파
→ 손실의 책임을 각 가중치에 전달Keras 모델의 코드는 짧습니다.
model.compile(...)
model.fit(...)
model.evaluate(...)
model.predict(...)하지만 이 네 줄 뒤에서는 수많은 계산이 진행됩니다.
수천 개의 가중치
수만 번의 행렬 곱셈
손실 함수 계산
미분과 기울기 계산
가중치 업데이트
검증 성능 측정딥러닝 모델은 데이터를 넣으면 지혜가 자동으로 나오는 마법 상자가 아닙니다.
좋은 문제 정의
깨끗한 데이터
올바른 출력층
적절한 손실 함수
공정한 평가 데이터
오답 분석
운영 환경 감시이 모든 과정이 함께 갖춰져야 쓸 만한 모델이 만들어집니다.
인공신경망은 사람처럼 생각하지 않습니다.
하지만 수많은 예제에서 반복되는 숫자 패턴을 찾아내고, 자신의 실수를 조금씩 수정하는 데 매우 능숙합니다.
첫 번째 에포크:
“이게 7인가요?”
다섯 번째 에포크:
“7일 가능성이 높습니다.”
열 번째 에포크:
“이번에는 꽤 자신 있습니다.”
평가 데이터:
“자신감 말고 실력으로 증명하세요.”딥러닝에서 가장 중요한 습관은 모델이 맞힌 결과보다 틀린 결과를 살펴보는 것입니다.
오답에는 데이터의 문제, 모델의 한계, 새로운 개선 방향이 숨어 있기 때문입니다.
TensorFlow가 거대한 계산 발전소라면 Keras는 그 발전소를 사람이 조작할 수 있게 만든 조종석입니다.
이제 조종석의 기본 버튼을 익혔습니다.
다음부터 신경망 코드를 만나면 막연한 주문처럼 보지 말고 이렇게 해석해 보세요.
“무엇을 입력받고, 어떤 층을 지나며, 무엇을 줄이도록 학습하는가?”
이 세 가지를 찾을 수 있다면 복잡해 보이는 신경망도 하나씩 해체해서 이해할 수 있습니다. 🧠⚡
다음 편 예고
[Python 완전정복 시리즈 #30] PyTorch 완벽 이해하기 | 직접 제어하며 만드는 유연한 딥러닝 모델
다음 시간에는 연구와 실험 환경에서 널리 활용되는 PyTorch를 알아봅니다.
Tensor 생성, 자동 미분, Dataset과 DataLoader, 신경망 클래스, 학습 루프, GPU 이동, 모델 저장까지 Keras와는 또 다른 방식으로 딥러닝 모델을 직접 제어해 보겠습니다.
#Python #파이썬 #Python강좌 #파이썬기초 #TensorFlow #텐서플로 #Keras #케라스 #딥러닝 #DeepLearning #머신러닝 #인공지능 #인공신경망 #뉴런 #가중치 #활성화함수 #손실함수 #역전파 #경사하강법 #Adam #MNIST #이미지분류 #Sequential #FunctionalAPI #전이학습 #코딩공부 #프로그래밍
