본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 2. · 13 Views
Keras Sequential API 완벽 가이드
딥러닝 입문자를 위한 Keras Sequential API 완벽 가이드입니다. TensorFlow와의 관계부터 모델 구축, 학습, 시각화까지 실무 예제와 함께 차근차근 배워봅니다.
목차
- Keras와 TensorFlow 관계
- Sequential 모델 구조
- Dense와 Activation 레이어
- 모델 컴파일 optimizer loss metrics
- model.fit으로 학습하기
- 학습 결과 시각화
1. Keras와 TensorFlow 관계
어느 날 김개발 씨가 딥러닝 공부를 시작하려고 인터넷을 검색했습니다. 그런데 어떤 글에서는 "Keras를 설치하세요"라고 하고, 다른 글에서는 "TensorFlow만 설치하면 됩니다"라고 합니다.
대체 Keras와 TensorFlow는 어떤 관계일까요?
Keras는 딥러닝 모델을 쉽게 만들 수 있게 해주는 고수준 API입니다. 마치 자동차의 핸들과 페달처럼, 복잡한 엔진 내부를 몰라도 운전할 수 있게 해주는 인터페이스와 같습니다.
TensorFlow 2.0부터 Keras는 TensorFlow 안에 완전히 통합되어, 별도 설치 없이 바로 사용할 수 있습니다.
다음 코드를 살펴봅시다.
# TensorFlow를 설치하면 Keras가 함께 포함됩니다
import tensorflow as tf
from tensorflow import keras
# 버전 확인
print(f"TensorFlow 버전: {tf.__version__}")
print(f"Keras 버전: {keras.__version__}")
# Keras는 tf.keras로 접근합니다
model = tf.keras.Sequential()
# 또는 간단히
model = keras.Sequential()
김개발 씨는 입사 3개월 차 주니어 개발자입니다. 회사에서 딥러닝 프로젝트에 투입되었는데, 선배가 건네준 코드에는 온통 Keras 코드가 가득했습니다.
그런데 막상 환경을 세팅하려고 보니 혼란스러웠습니다. "Keras를 따로 설치해야 하나요?" 김개발 씨가 물었습니다.
선배 개발자 박시니어 씨가 웃으며 대답했습니다. "아니요, TensorFlow만 설치하면 됩니다.
Keras는 이미 TensorFlow 안에 들어있거든요." 그렇다면 Keras와 TensorFlow의 관계는 정확히 무엇일까요? 쉽게 비유하자면, TensorFlow는 자동차의 엔진이고 Keras는 운전대와 페달입니다.
엔진이 아무리 강력해도 운전대 없이는 자동차를 몰 수 없습니다. 반대로 운전대만 있고 엔진이 없어도 자동차는 움직이지 않습니다.
이처럼 TensorFlow가 실제 연산을 처리하고, Keras는 그것을 쉽게 다룰 수 있는 인터페이스를 제공합니다. 원래 Keras는 독립적인 라이브러리였습니다.
2015년에 프랑수아 숄레라는 개발자가 만들었는데, "딥러닝을 더 쉽게 할 수 없을까?"라는 고민에서 시작되었습니다. 당시 딥러닝 코드는 복잡하고 어려웠거든요.
Keras의 철학은 단순했습니다. 사용자 친화적이고, 모듈화가 잘 되어 있으며, 확장이 쉬워야 한다는 것이었습니다.
이런 철학 덕분에 Keras는 빠르게 인기를 얻었습니다. 구글은 이런 Keras의 장점을 인정하고, TensorFlow 2.0부터 Keras를 공식 고수준 API로 채택했습니다.
이제 TensorFlow를 설치하면 tf.keras라는 이름으로 Keras를 바로 사용할 수 있습니다. 위의 코드를 살펴보면, import tensorflow as tf를 실행한 후 tf.keras로 Keras의 모든 기능에 접근할 수 있습니다.
from tensorflow import keras로 더 간결하게 불러올 수도 있습니다. 실제 현업에서는 어떻게 활용할까요?
대부분의 회사에서 딥러닝 프로젝트를 시작할 때 TensorFlow와 Keras 조합을 선택합니다. 프로토타입은 Keras로 빠르게 만들고, 성능 최적화가 필요한 부분만 TensorFlow 저수준 API를 사용하는 방식입니다.
주의할 점도 있습니다. 간혹 오래된 튜토리얼에서 keras를 별도로 설치하라고 하는 경우가 있는데, 이는 TensorFlow 1.x 시절의 방식입니다.
지금은 그냥 TensorFlow만 설치하면 됩니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 이해가 되었습니다. "그러니까 TensorFlow가 기반이고, Keras는 그걸 쉽게 쓰는 도구군요!" Keras와 TensorFlow의 관계를 이해하면 딥러닝 학습의 첫 발을 뗀 것입니다.
실전 팁
💡 - TensorFlow 2.x를 사용한다면 별도로 Keras를 설치할 필요가 없습니다
- import는 from tensorflow import keras 형태를 권장합니다
2. Sequential 모델 구조
김개발 씨가 첫 번째 딥러닝 모델을 만들려고 합니다. 그런데 코드를 보니 Sequential이라는 단어가 계속 나옵니다.
"Sequential이 뭐예요? 왜 이름이 Sequential인가요?" 박시니어 씨가 화이트보드에 그림을 그리기 시작했습니다.
Sequential 모델은 레이어를 순서대로 쌓아 올리는 가장 기본적인 신경망 구조입니다. 마치 레고 블록을 아래에서 위로 차곡차곡 쌓는 것처럼, 입력층부터 출력층까지 일렬로 연결됩니다.
간단하고 직관적이어서 딥러닝 입문자가 처음 배우기에 가장 좋은 모델 구조입니다.
다음 코드를 살펴봅시다.
from tensorflow import keras
from keras import layers
# Sequential 모델 생성 방법 1: 리스트로 레이어 전달
model = keras.Sequential([
layers.Dense(64, input_shape=(784,)), # 입력층
layers.Dense(32), # 은닉층
layers.Dense(10) # 출력층
])
# Sequential 모델 생성 방법 2: add() 메서드 사용
model = keras.Sequential()
model.add(layers.Dense(64, input_shape=(784,)))
model.add(layers.Dense(32))
model.add(layers.Dense(10))
# 모델 구조 확인
model.summary()
박시니어 씨가 화이트보드에 세 개의 상자를 세로로 그렸습니다. "Sequential이라는 이름은 '순차적'이라는 뜻이에요.
데이터가 이 상자들을 위에서 아래로, 순서대로 통과하거든요." 김개발 씨가 고개를 끄덕였습니다. "아, 그래서 Sequential이군요!" 그렇다면 Sequential 모델이란 정확히 무엇일까요?
쉽게 비유하자면, Sequential 모델은 공장의 조립 라인과 같습니다. 자동차 공장에서 철판이 들어가면 용접 공정, 도장 공정, 조립 공정을 차례로 거쳐 완성차가 나옵니다.
각 공정은 이전 공정의 결과물을 받아서 작업하고, 다음 공정으로 넘깁니다. Sequential 모델도 마찬가지로 데이터가 레이어를 차례로 통과하며 변환됩니다.
Keras에서 모델을 만드는 방법은 크게 세 가지가 있습니다. Sequential API, Functional API, 그리고 Model 서브클래싱입니다.
이 중 Sequential API가 가장 간단합니다. Sequential 모델을 만드는 방법은 두 가지입니다.
첫 번째는 리스트에 레이어들을 담아서 한 번에 전달하는 방법입니다. 두 번째는 빈 Sequential 객체를 만들고 add() 메서드로 레이어를 하나씩 추가하는 방법입니다.
결과는 동일하니 취향에 맞게 선택하면 됩니다. 위의 코드에서 첫 번째 방법을 보면, keras.Sequential()에 리스트를 전달하고 있습니다.
리스트 안에는 세 개의 Dense 레이어가 있습니다. 첫 번째 레이어에만 input_shape를 지정하는데, 이것은 입력 데이터의 형태를 알려주는 것입니다.
두 번째 방법은 먼저 빈 모델을 만들고, model.add()로 레이어를 추가합니다. 이 방법은 조건에 따라 레이어를 동적으로 추가할 때 유용합니다.
model.summary()를 호출하면 모델의 전체 구조를 확인할 수 있습니다. 각 레이어의 이름, 출력 형태, 파라미터 개수가 표 형태로 출력됩니다.
이것은 모델이 제대로 만들어졌는지 확인하는 좋은 습관입니다. 실제 현업에서 Sequential 모델은 간단한 분류 문제나 회귀 문제에 주로 사용됩니다.
이미지 분류, 숫자 인식, 스팸 메일 분류 같은 기본적인 작업에 적합합니다. 하지만 주의할 점도 있습니다.
Sequential 모델은 입력과 출력이 각각 하나씩만 있는 단순한 구조에만 사용할 수 있습니다. 여러 입력을 받거나 중간에 분기가 필요한 복잡한 모델은 Functional API를 사용해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. "그러니까 레고 블록처럼 쌓기만 하면 되는 거네요?" 박시니어 씨가 고개를 끄덕였습니다.
"맞아요. 처음엔 Sequential로 시작하고, 나중에 복잡한 모델이 필요하면 Functional API를 배우면 됩니다."
실전 팁
💡 - 첫 번째 레이어에는 반드시 input_shape를 지정해야 합니다
- model.summary()로 모델 구조를 항상 확인하는 습관을 들이세요
3. Dense와 Activation 레이어
김개발 씨가 코드를 따라 치다가 궁금증이 생겼습니다. "Dense가 뭐예요?
왜 이름이 Dense인가요? 그리고 activation은 또 뭐고요?" 박시니어 씨가 설명을 시작했습니다.
"Dense는 '밀집'이라는 뜻이에요. 모든 뉴런이 빽빽하게 연결되어 있거든요."
Dense 레이어는 완전 연결 레이어로, 이전 레이어의 모든 뉴런과 현재 레이어의 모든 뉴런이 연결됩니다. Activation은 활성화 함수로, 뉴런의 출력값을 변환하여 신경망에 비선형성을 부여합니다.
이 두 가지는 신경망의 가장 기본적인 구성 요소입니다.
다음 코드를 살펴봅시다.
from tensorflow import keras
from keras import layers
# Dense 레이어 기본 사용
model = keras.Sequential([
# 64개 뉴런, ReLU 활성화 함수
layers.Dense(64, activation='relu', input_shape=(784,)),
# 32개 뉴런, ReLU 활성화 함수
layers.Dense(32, activation='relu'),
# 10개 출력, Softmax로 확률 변환
layers.Dense(10, activation='softmax')
])
# 활성화 함수를 별도 레이어로 분리할 수도 있습니다
model = keras.Sequential([
layers.Dense(64, input_shape=(784,)),
layers.Activation('relu'),
layers.Dense(10),
layers.Activation('softmax')
])
박시니어 씨가 칠판에 두 개의 원 그룹을 그렸습니다. 왼쪽에 4개, 오른쪽에 3개의 원을 그리고, 모든 원을 선으로 연결했습니다.
"이게 Dense 레이어예요. 왼쪽의 모든 뉴런이 오른쪽의 모든 뉴런과 연결되어 있죠?
그래서 '밀집'이라는 뜻의 Dense라고 부릅니다." 그렇다면 Dense 레이어란 정확히 무엇일까요? 쉽게 비유하자면, Dense 레이어는 회사의 전체 회의와 같습니다.
마케팅팀의 모든 직원이 개발팀의 모든 직원과 의견을 나누는 상황입니다. 아이디어가 빽빽하게 교환되고, 종합적인 결론이 도출됩니다.
Dense 레이어도 마찬가지로 이전 층의 모든 정보를 종합하여 새로운 정보를 만들어냅니다. Dense 레이어의 첫 번째 인자는 뉴런의 개수입니다.
위 코드에서 Dense(64)는 64개의 뉴런을 가진 레이어를 만듭니다. 뉴런 개수가 많을수록 더 복잡한 패턴을 학습할 수 있지만, 그만큼 계산량도 늘어납니다.
그렇다면 Activation, 즉 활성화 함수는 왜 필요할까요? 만약 활성화 함수가 없다면, 아무리 레이어를 많이 쌓아도 결국 하나의 선형 변환과 같아집니다.
마치 직선으로만 곡선을 그리려는 것처럼, 복잡한 패턴을 표현할 수 없습니다. 활성화 함수가 비선형성을 부여해서 곡선도 그릴 수 있게 해줍니다.
가장 많이 쓰이는 활성화 함수는 ReLU입니다. 입력값이 0보다 작으면 0을 출력하고, 0보다 크면 그대로 출력합니다.
단순하지만 효과적이어서 은닉층에 주로 사용됩니다. 출력층에는 문제 유형에 따라 다른 활성화 함수를 사용합니다.
다중 분류 문제에는 softmax를 사용합니다. softmax는 출력값을 확률로 변환해서, 모든 출력의 합이 1이 되게 합니다.
이진 분류에는 sigmoid를, 회귀 문제에는 활성화 함수 없이 선형 출력을 사용합니다. 위의 코드를 보면, activation 파라미터로 활성화 함수를 지정할 수 있습니다.
또는 Activation 레이어를 별도로 추가할 수도 있는데, 결과는 동일합니다. 보통은 Dense 안에 activation을 지정하는 것이 더 간결합니다.
실제 현업에서는 은닉층에 ReLU, 출력층에 softmax나 sigmoid를 사용하는 것이 표준적인 패턴입니다. 처음에는 이 조합으로 시작하고, 필요에 따라 다른 활성화 함수를 실험해보면 됩니다.
주의할 점은 출력층의 활성화 함수와 손실 함수를 맞춰야 한다는 것입니다. softmax를 쓰면 categorical_crossentropy를, sigmoid를 쓰면 binary_crossentropy를 사용해야 합니다.
이 조합이 맞지 않으면 학습이 제대로 되지 않습니다.
실전 팁
💡 - 은닉층에는 ReLU, 출력층에는 문제에 맞는 활성화 함수를 사용하세요
- 뉴런 개수는 보통 입력 차원보다 작게 시작해서 점점 줄여나갑니다
4. 모델 컴파일 optimizer loss metrics
김개발 씨가 모델을 만들고 나서 학습을 시키려 했습니다. 그런데 에러가 발생했습니다.
"모델을 먼저 컴파일해야 합니다"라는 메시지였습니다. "컴파일이요?
C언어처럼 컴파일하는 건가요?" 박시니어 씨가 고개를 저었습니다. "조금 다른 의미예요."
**model.compile()**은 모델 학습에 필요한 설정을 지정하는 단계입니다. optimizer는 가중치를 어떻게 업데이트할지, loss는 예측이 얼마나 틀렸는지를 어떻게 계산할지, metrics는 어떤 지표로 성능을 측정할지를 결정합니다.
이 세 가지는 딥러닝 학습의 핵심 요소입니다.
다음 코드를 살펴봅시다.
from tensorflow import keras
from keras import layers
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(784,)),
layers.Dense(32, activation='relu'),
layers.Dense(10, activation='softmax')
])
# 모델 컴파일 - 학습 전에 반드시 필요
model.compile(
optimizer='adam', # 최적화 알고리즘
loss='sparse_categorical_crossentropy', # 손실 함수
metrics=['accuracy'] # 평가 지표
)
# 학습률을 직접 지정하고 싶다면
from keras import optimizers
model.compile(
optimizer=optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
박시니어 씨가 비유를 들었습니다. "요리를 한다고 생각해봐요.
레시피(모델)가 있어도, 어떤 불로 요리할지(optimizer), 간이 맞는지 어떻게 확인할지(loss), 완성도를 뭘로 평가할지(metrics)를 정해야 실제로 요리를 시작할 수 있잖아요." 김개발 씨가 눈을 빛냈습니다. "아, 요리 시작 전에 세팅하는 거군요!" 그렇다면 **compile()**의 각 요소는 정확히 무엇을 의미할까요?
먼저 **optimizer(최적화기)**는 학습의 방향을 정하는 나침반과 같습니다. 신경망은 가중치라는 수많은 숫자로 이루어져 있는데, 이 가중치를 어떻게 조금씩 바꿔가며 정답에 가까워질지를 결정합니다.
Adam이 가장 널리 쓰이는데, 학습 속도를 자동으로 조절해주는 똑똑한 최적화기입니다. 다음으로 **loss(손실 함수)**는 예측이 얼마나 틀렸는지를 숫자로 계산합니다.
마치 시험에서 오답 개수를 세는 것과 같습니다. 분류 문제에서는 crossentropy 계열을 사용하고, 회귀 문제에서는 **mse(평균 제곱 오차)**를 사용합니다.
손실 함수 선택은 출력층의 형태에 따라 달라집니다. 레이블이 정수 형태(0, 1, 2...)면 sparse_categorical_crossentropy를, 원핫 인코딩 형태([1,0,0], [0,1,0]...)면 categorical_crossentropy를 사용합니다.
마지막으로 **metrics(평가 지표)**는 사람이 이해하기 쉬운 성능 지표입니다. 손실 값은 0.3421 같은 숫자라 직관적이지 않지만, accuracy는 "92%의 정확도"처럼 바로 이해할 수 있습니다.
위의 코드를 보면, compile() 함수에 세 가지 인자를 전달하고 있습니다. optimizer='adam'은 Adam 최적화기를 사용하겠다는 것이고, loss는 정수 레이블용 크로스엔트로피를, metrics에는 정확도를 리스트로 전달했습니다.
학습률(learning_rate)을 직접 조절하고 싶다면 optimizer 객체를 직접 생성해서 전달합니다. 학습률은 한 번에 가중치를 얼마나 바꿀지를 결정하는데, 너무 크면 최적점을 지나치고, 너무 작으면 학습이 느려집니다.
실제 현업에서는 일단 기본 설정으로 시작하고, 학습이 잘 안 되면 학습률을 조절하는 방식으로 진행합니다. Adam optimizer와 0.001의 학습률은 대부분의 상황에서 잘 작동합니다.
주의할 점은 compile()을 호출한 후에 모델 구조를 변경하면 다시 compile()을 해야 한다는 것입니다. 또한 손실 함수와 출력층 활성화 함수의 조합을 잘못 맞추면 학습이 제대로 되지 않습니다.
실전 팁
💡 - 처음에는 optimizer='adam', 분류는 crossentropy, 회귀는 mse로 시작하세요
- 학습이 잘 안 되면 학습률을 0.0001로 낮춰보세요
5. model.fit으로 학습하기
드디어 김개발 씨가 모델을 학습시킬 차례입니다. 선배가 "fit()을 호출하면 돼요"라고 했는데, fit에 넣어야 할 파라미터가 너무 많아 보입니다.
epochs, batch_size, validation_split... 이것들은 다 뭘까요?
**model.fit()**은 실제로 모델을 학습시키는 함수입니다. 학습 데이터를 넣고, 몇 번 반복할지(epochs), 한 번에 얼마나 처리할지(batch_size), 검증 데이터를 어떻게 할지(validation_split)를 설정합니다.
fit()을 호출하면 지정한 만큼 반복하며 모델이 점점 똑똑해집니다.
다음 코드를 살펴봅시다.
import numpy as np
from tensorflow import keras
from keras import layers
# 예시 데이터 (실제로는 로드한 데이터 사용)
x_train = np.random.random((1000, 784))
y_train = np.random.randint(10, size=(1000,))
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(784,)),
layers.Dense(32, activation='relu'),
layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 모델 학습
history = model.fit(
x_train, y_train, # 학습 데이터
epochs=10, # 전체 데이터를 10번 반복 학습
batch_size=32, # 한 번에 32개씩 처리
validation_split=0.2 # 20%를 검증용으로 사용
)
박시니어 씨가 운동 비유를 들었습니다. "헬스장에서 운동한다고 생각해봐요.
스쿼트 100개를 한다면, 한 번에 다 하지 않고 10개씩 10세트로 나누잖아요. 10개가 batch_size고, 10세트가 epoch이에요." 김개발 씨가 이해했습니다.
"아, 한 번에 다 안 하고 나눠서 하는 거군요!" 그렇다면 fit() 함수의 각 파라미터는 정확히 무엇을 의미할까요? epochs는 전체 학습 데이터를 몇 번 반복해서 볼지를 의미합니다.
마치 교과서를 몇 번 읽을지와 같습니다. 한 번만 읽으면 내용을 잘 모르고, 여러 번 읽으면 점점 이해가 깊어집니다.
하지만 너무 많이 읽으면 교과서만 달달 외우고 응용을 못하는 과적합이 발생할 수 있습니다. batch_size는 한 번에 처리하는 데이터 개수입니다.
전체 1000개의 데이터를 batch_size=32로 설정하면, 한 번에 32개씩 처리하고 가중치를 업데이트합니다. batch_size가 작으면 업데이트가 자주 일어나지만 불안정하고, 크면 안정적이지만 메모리를 많이 사용합니다.
validation_split은 학습 데이터의 일부를 검증용으로 떼어놓는 비율입니다. 0.2로 설정하면 20%의 데이터는 학습에 사용하지 않고, 각 epoch이 끝날 때마다 성능을 확인하는 데 사용합니다.
이렇게 해야 모델이 새로운 데이터에도 잘 작동하는지 확인할 수 있습니다. fit() 함수는 History 객체를 반환합니다.
이 객체에는 각 epoch별 손실 값과 정확도가 기록되어 있습니다. 나중에 이것을 그래프로 그려서 학습이 잘 되고 있는지 확인할 수 있습니다.
위의 코드를 보면, fit()에 학습 데이터(x_train, y_train)를 전달하고, epochs=10으로 10번 반복, batch_size=32로 한 번에 32개 처리, validation_split=0.2로 20%를 검증용으로 사용하도록 설정했습니다. 실제 현업에서는 학습 시간과 성능의 균형을 맞추는 것이 중요합니다.
epochs가 너무 적으면 학습이 부족하고, 너무 많으면 과적합됩니다. batch_size는 GPU 메모리에 맞춰 조절합니다.
주의할 점은 validation_split을 사용하면 매번 같은 데이터가 검증용으로 사용되지 않을 수 있다는 것입니다. 재현성이 중요하다면 별도의 검증 데이터셋을 validation_data 파라미터로 전달하는 것이 좋습니다.
실전 팁
💡 - epochs는 10-100 사이에서 시작하고, 과적합이 보이면 줄이세요
- batch_size는 32나 64로 시작하는 것이 일반적입니다
6. 학습 결과 시각화
김개발 씨의 모델 학습이 끝났습니다. 화면에는 숫자들이 주르륵 지나갔는데, 이게 잘 된 건지 모르겠습니다.
"선배, 이게 잘 학습된 건가요?" 박시니어 씨가 대답했습니다. "그래프로 그려보면 바로 알 수 있어요."
학습 결과 시각화는 모델이 제대로 학습되고 있는지 확인하는 필수 과정입니다. history 객체에 저장된 손실 값과 정확도를 그래프로 그리면, 학습 추이와 과적합 여부를 한눈에 파악할 수 있습니다.
matplotlib 라이브러리를 사용하여 간단하게 시각화할 수 있습니다.
다음 코드를 살펴봅시다.
import matplotlib.pyplot as plt
# fit() 함수가 반환한 history 객체 활용
# history = model.fit(...) 의 결과
# 손실 그래프
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Val Loss')
plt.title('Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
# 정확도 그래프
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Train Acc')
plt.plot(history.history['val_accuracy'], label='Val Acc')
plt.title('Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout()
plt.savefig('training_history.png')
plt.show()
박시니어 씨가 화면에 그래프 두 개를 띄웠습니다. 왼쪽은 손실 그래프, 오른쪽은 정확도 그래프입니다.
"이 그래프만 봐도 모델 상태를 바로 알 수 있어요." 김개발 씨가 그래프를 유심히 봤습니다. "파란 선이랑 주황 선이 있네요?" "파란 선은 훈련 데이터, 주황 선은 검증 데이터예요.
이 두 선이 어떻게 움직이는지가 중요합니다." 그렇다면 그래프에서 무엇을 봐야 할까요? 먼저 손실 그래프입니다.
이상적인 경우, 두 선 모두 아래로 내려가야 합니다. 훈련 손실과 검증 손실이 함께 줄어들면 학습이 잘 되고 있는 것입니다.
만약 훈련 손실은 계속 줄어드는데 검증 손실이 어느 순간부터 올라간다면, 이것이 바로 **과적합(overfitting)**입니다. 모델이 훈련 데이터를 외워버려서 새로운 데이터에는 오히려 못하게 된 상황입니다.
정확도 그래프도 마찬가지입니다. 두 선이 함께 올라가면 좋고, 훈련 정확도만 올라가고 검증 정확도가 떨어지면 과적합입니다.
위의 코드를 보면, matplotlib의 subplot을 사용하여 두 개의 그래프를 나란히 그립니다. history.history는 딕셔너리로, 'loss', 'val_loss', 'accuracy', 'val_accuracy' 키로 각 값에 접근할 수 있습니다.
plt.savefig()로 그래프를 이미지 파일로 저장할 수 있습니다. 실험 결과를 기록하고 비교할 때 유용합니다.
실제 현업에서는 이 그래프를 보고 다음 단계를 결정합니다. 과적합이 보이면 Dropout을 추가하거나 데이터를 늘리고, 학습이 부족해 보이면 epochs를 늘리거나 모델을 복잡하게 만듭니다.
주의할 점은 검증 손실이 들쭉날쭉하다고 해서 무조건 문제가 있는 것은 아닙니다. 어느 정도의 변동은 정상입니다.
전체적인 추세를 봐야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
그래프를 본 김개발 씨가 말했습니다. "어, 제 모델은 검증 손실이 올라가기 시작하네요?" 박시니어 씨가 고개를 끄덕였습니다.
"네, epoch 7 이후부터 과적합이 시작됐네요. epochs=7로 다시 학습하거나, Dropout을 추가해보세요." 이렇게 시각화를 통해 모델의 상태를 진단하고, 개선 방향을 찾을 수 있습니다.
시각화는 딥러닝에서 가장 중요한 도구 중 하나입니다.
실전 팁
💡 - 훈련과 검증 그래프가 벌어지기 시작하면 과적합을 의심하세요
- 학습 곡선을 저장해두면 나중에 모델 비교할 때 유용합니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.