TensorFlow 기본 모델링
TensorFlow 기본 모델링
TensorFlow 기본 모델링
231016 학습한 내용 정리
TensorFlow 개요
정의
- TensorFlow: Google에서 개발한 오픈소스 머신러닝 프레임워크
- 딥러닝 모델 구축과 훈련을 위한 종합적인 플랫폼
- Tensor: 다차원 배열, Flow: 데이터 흐름 그래프
특징
- 유연성: 다양한 머신러닝 모델 구축 가능
- 확장성: CPU, GPU, TPU에서 실행 가능
- 생태계: 풍부한 라이브러리와 도구 제공
- 프로덕션: 실제 서비스 배포에 최적화
장점
- 성능: 높은 계산 성능
- 유연성: 다양한 모델 아키텍처 지원
- 커뮤니티: 활발한 커뮤니티와 문서
- 통합: Keras와의 완벽한 통합
TensorFlow 설치 및 기본 사용법
1. 설치
1
2
3
4
5
6
7
8
# CPU 버전
pip install tensorflow
# GPU 버전
pip install tensorflow-gpu
# 최신 버전
pip install tensorflow==2.12.0
2. 기본 사용법
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
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# TensorFlow 버전 확인
print(f"TensorFlow 버전: {tf.__version__}")
# 샘플 데이터 생성
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 데이터 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# TensorFlow 데이터셋 생성
train_dataset = tf.data.Dataset.from_tensor_slices((X_train_scaled, y_train))
test_dataset = tf.data.Dataset.from_tensor_slices((X_test_scaled, y_test))
# 배치 크기 설정
batch_size = 32
train_dataset = train_dataset.batch(batch_size)
test_dataset = test_dataset.batch(batch_size)
TensorFlow 모델 구축
1. Sequential API
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
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.metrics import Accuracy
# Sequential 모델 생성
model = Sequential([
Dense(64, activation='relu', input_shape=(20,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1, activation='sigmoid')
])
# 모델 컴파일
model.compile(
optimizer=Adam(learning_rate=0.001),
loss=BinaryCrossentropy(),
metrics=[Accuracy()]
)
# 모델 구조 확인
model.summary()
# 모델 학습
history = model.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
verbose=1
)
2. Functional API
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
from tensorflow.keras.layers import Input, Dense, Dropout
from tensorflow.keras.models import Model
# Functional API 모델 생성
inputs = Input(shape=(20,))
x = Dense(64, activation='relu')(inputs)
x = Dropout(0.2)(x)
x = Dense(32, activation='relu')(x)
x = Dropout(0.2)(x)
x = Dense(16, activation='relu')(x)
outputs = Dense(1, activation='sigmoid')(x)
model_functional = Model(inputs=inputs, outputs=outputs)
# 모델 컴파일
model_functional.compile(
optimizer=Adam(learning_rate=0.001),
loss=BinaryCrossentropy(),
metrics=[Accuracy()]
)
# 모델 학습
history_functional = model_functional.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
verbose=1
)
3. Subclassing API
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
from tensorflow.keras.layers import Layer
from tensorflow.keras.models import Model
# 커스텀 레이어 정의
class CustomDense(Layer):
def __init__(self, units, activation=None, **kwargs):
super(CustomDense, self).__init__(**kwargs)
self.units = units
self.activation = tf.keras.activations.get(activation)
def build(self, input_shape):
self.kernel = self.add_weight(
name='kernel',
shape=(input_shape[-1], self.units),
initializer='glorot_uniform',
trainable=True
)
self.bias = self.add_weight(
name='bias',
shape=(self.units,),
initializer='zeros',
trainable=True
)
super(CustomDense, self).build(input_shape)
def call(self, inputs):
output = tf.matmul(inputs, self.kernel) + self.bias
if self.activation is not None:
output = self.activation(output)
return output
# Subclassing 모델 정의
class CustomModel(Model):
def __init__(self):
super(CustomModel, self).__init__()
self.dense1 = CustomDense(64, activation='relu')
self.dropout1 = Dropout(0.2)
self.dense2 = CustomDense(32, activation='relu')
self.dropout2 = Dropout(0.2)
self.dense3 = CustomDense(16, activation='relu')
self.dense4 = CustomDense(1, activation='sigmoid')
def call(self, inputs, training=None):
x = self.dense1(inputs)
x = self.dropout1(x, training=training)
x = self.dense2(x)
x = self.dropout2(x, training=training)
x = self.dense3(x)
return self.dense4(x)
# 모델 생성
model_subclassing = CustomModel()
# 모델 컴파일
model_subclassing.compile(
optimizer=Adam(learning_rate=0.001),
loss=BinaryCrossentropy(),
metrics=[Accuracy()]
)
# 모델 학습
history_subclassing = model_subclassing.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
verbose=1
)
TensorFlow 고급 기능
1. 콜백 (Callbacks)
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
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
# 콜백 정의
callbacks = [
EarlyStopping(
monitor='val_loss',
patience=10,
restore_best_weights=True
),
ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=5,
min_lr=1e-7
),
ModelCheckpoint(
'best_model.h5',
monitor='val_loss',
save_best_only=True
)
]
# 콜백을 사용한 모델 학습
model_with_callbacks = Sequential([
Dense(64, activation='relu', input_shape=(20,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1, activation='sigmoid')
])
model_with_callbacks.compile(
optimizer=Adam(learning_rate=0.001),
loss=BinaryCrossentropy(),
metrics=[Accuracy()]
)
history_callbacks = model_with_callbacks.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
callbacks=callbacks,
verbose=1
)
2. 커스텀 손실 함수
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
# 커스텀 손실 함수 정의
def custom_loss(y_true, y_pred):
"""커스텀 손실 함수"""
# 기본 이진 교차 엔트로피
bce = tf.keras.losses.binary_crossentropy(y_true, y_pred)
# L2 정규화
l2_reg = tf.reduce_sum([tf.nn.l2_loss(w) for w in model.trainable_weights])
return bce + 0.01 * l2_reg
# 커스텀 손실 함수를 사용한 모델
model_custom_loss = Sequential([
Dense(64, activation='relu', input_shape=(20,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1, activation='sigmoid')
])
model_custom_loss.compile(
optimizer=Adam(learning_rate=0.001),
loss=custom_loss,
metrics=[Accuracy()]
)
history_custom_loss = model_custom_loss.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
verbose=1
)
3. 커스텀 메트릭
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
# 커스텀 메트릭 정의
class CustomAccuracy(tf.keras.metrics.Metric):
def __init__(self, name='custom_accuracy', **kwargs):
super(CustomAccuracy, self).__init__(name=name, **kwargs)
self.true_positives = self.add_weight(name='tp', initializer='zeros')
self.false_positives = self.add_weight(name='fp', initializer='zeros')
self.false_negatives = self.add_weight(name='fn', initializer='zeros')
self.true_negatives = self.add_weight(name='tn', initializer='zeros')
def update_state(self, y_true, y_pred, sample_weight=None):
y_pred = tf.cast(y_pred > 0.5, tf.float32)
y_true = tf.cast(y_true, tf.float32)
tp = tf.reduce_sum(y_true * y_pred)
fp = tf.reduce_sum((1 - y_true) * y_pred)
fn = tf.reduce_sum(y_true * (1 - y_pred))
tn = tf.reduce_sum((1 - y_true) * (1 - y_pred))
self.true_positives.assign_add(tp)
self.false_positives.assign_add(fp)
self.false_negatives.assign_add(fn)
self.true_negatives.assign_add(tn)
def result(self):
precision = self.true_positives / (self.true_positives + self.false_positives + 1e-8)
recall = self.true_positives / (self.true_positives + self.false_negatives + 1e-8)
f1 = 2 * precision * recall / (precision + recall + 1e-8)
return f1
def reset_state(self):
self.true_positives.assign(0)
self.false_positives.assign(0)
self.false_negatives.assign(0)
self.true_negatives.assign(0)
# 커스텀 메트릭을 사용한 모델
model_custom_metric = Sequential([
Dense(64, activation='relu', input_shape=(20,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1, activation='sigmoid')
])
model_custom_metric.compile(
optimizer=Adam(learning_rate=0.001),
loss=BinaryCrossentropy(),
metrics=[CustomAccuracy()]
)
history_custom_metric = model_custom_metric.fit(
train_dataset,
epochs=100,
validation_data=test_dataset,
verbose=1
)
TensorFlow 모델 평가 및 예측
1. 모델 평가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 모델 평가
test_loss, test_accuracy = model.evaluate(test_dataset, verbose=0)
print(f"테스트 손실: {test_loss:.4f}")
print(f"테스트 정확도: {test_accuracy:.4f}")
# 예측
predictions = model.predict(X_test_scaled)
predicted_classes = (predictions > 0.5).astype(int)
# 혼동 행렬
from sklearn.metrics import confusion_matrix, classification_report
cm = confusion_matrix(y_test, predicted_classes)
print("혼동 행렬:")
print(cm)
print("\n분류 보고서:")
print(classification_report(y_test, predicted_classes))
2. 학습 곡선 시각화
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
# 학습 곡선 시각화
plt.figure(figsize=(15, 5))
# 손실 곡선
plt.subplot(1, 3, 1)
plt.plot(history.history['loss'], label='훈련 손실')
plt.plot(history.history['val_loss'], label='검증 손실')
plt.title('모델 손실')
plt.xlabel('에포크')
plt.ylabel('손실')
plt.legend()
plt.grid(True)
# 정확도 곡선
plt.subplot(1, 3, 2)
plt.plot(history.history['accuracy'], label='훈련 정확도')
plt.plot(history.history['val_accuracy'], label='검증 정확도')
plt.title('모델 정확도')
plt.xlabel('에포크')
plt.ylabel('정확도')
plt.legend()
plt.grid(True)
# 예측 vs 실제
plt.subplot(1, 3, 3)
plt.scatter(y_test, predictions, alpha=0.7)
plt.plot([0, 1], [0, 1], 'r--', lw=2)
plt.title('예측 vs 실제')
plt.xlabel('실제 값')
plt.ylabel('예측 값')
plt.grid(True)
plt.tight_layout()
plt.show()
3. 모델 저장 및 로드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 모델 저장
model.save('my_model.h5')
# 모델 로드
loaded_model = tf.keras.models.load_model('my_model.h5')
# 가중치만 저장
model.save_weights('my_weights.h5')
# 가중치만 로드
model.load_weights('my_weights.h5')
# 모델 구조 저장
model_json = model.to_json()
with open('model.json', 'w') as json_file:
json_file.write(model_json)
# 모델 구조 로드
with open('model.json', 'r') as json_file:
loaded_model_json = json_file.read()
loaded_model = tf.keras.models.model_from_json(loaded_model_json)
TensorFlow 실무 적용 예시
1. 회귀 문제
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
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScaler
# 보스턴 주택 가격 데이터 로드
boston = load_boston()
X, y = boston.data, boston.target
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 데이터 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 회귀 모델 생성
regression_model = Sequential([
Dense(64, activation='relu', input_shape=(13,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(1)
])
# 모델 컴파일
regression_model.compile(
optimizer=Adam(learning_rate=0.001),
loss='mse',
metrics=['mae']
)
# 모델 학습
history_regression = regression_model.fit(
X_train_scaled, y_train,
epochs=100,
validation_data=(X_test_scaled, y_test),
verbose=1
)
# 예측
predictions_regression = regression_model.predict(X_test_scaled)
# 성능 평가
from sklearn.metrics import mean_squared_error, r2_score
mse = mean_squared_error(y_test, predictions_regression)
r2 = r2_score(y_test, predictions_regression)
print(f"평균제곱오차: {mse:.4f}")
print(f"결정계수: {r2:.4f}")
# 시각화
plt.figure(figsize=(10, 6))
plt.scatter(y_test, predictions_regression, alpha=0.7)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('실제 값')
plt.ylabel('예측 값')
plt.title('회귀 예측 결과')
plt.grid(True)
plt.show()
2. 다중 클래스 분류
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
from sklearn.datasets import load_iris
from tensorflow.keras.utils import to_categorical
# 아이리스 데이터 로드
iris = load_iris()
X, y = iris.data, iris.target
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 데이터 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 원-핫 인코딩
y_train_categorical = to_categorical(y_train, 3)
y_test_categorical = to_categorical(y_test, 3)
# 다중 클래스 분류 모델
multiclass_model = Sequential([
Dense(64, activation='relu', input_shape=(4,)),
Dropout(0.2),
Dense(32, activation='relu'),
Dropout(0.2),
Dense(16, activation='relu'),
Dense(3, activation='softmax')
])
# 모델 컴파일
multiclass_model.compile(
optimizer=Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 모델 학습
history_multiclass = multiclass_model.fit(
X_train_scaled, y_train_categorical,
epochs=100,
validation_data=(X_test_scaled, y_test_categorical),
verbose=1
)
# 예측
predictions_multiclass = multiclass_model.predict(X_test_scaled)
predicted_classes = np.argmax(predictions_multiclass, axis=1)
# 성능 평가
from sklearn.metrics import accuracy_score, classification_report
accuracy = accuracy_score(y_test, predicted_classes)
print(f"정확도: {accuracy:.4f}")
print("\n분류 보고서:")
print(classification_report(y_test, predicted_classes, target_names=iris.target_names))
3. 하이퍼파라미터 튜닝
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
import kerastuner as kt
# 하이퍼파라미터 튜닝 모델 정의
def build_model(hp):
model = Sequential()
# 입력 레이어
model.add(Dense(
units=hp.Int('units_1', min_value=32, max_value=128, step=32),
activation='relu',
input_shape=(20,)
))
# 드롭아웃 레이어
model.add(Dropout(
rate=hp.Float('dropout_1', min_value=0.1, max_value=0.5, step=0.1)
))
# 히든 레이어
for i in range(hp.Int('num_layers', 1, 3)):
model.add(Dense(
units=hp.Int(f'units_{i+2}', min_value=16, max_value=64, step=16),
activation='relu'
))
model.add(Dropout(
rate=hp.Float(f'dropout_{i+2}', min_value=0.1, max_value=0.5, step=0.1)
))
# 출력 레이어
model.add(Dense(1, activation='sigmoid'))
# 컴파일
model.compile(
optimizer=Adam(learning_rate=hp.Float('learning_rate', min_value=1e-4, max_value=1e-2, sampling='log')),
loss='binary_crossentropy',
metrics=['accuracy']
)
return model
# 하이퍼파라미터 튜너 생성
tuner = kt.Hyperband(
build_model,
objective='val_accuracy',
max_epochs=50,
factor=3,
directory='tuner_results',
project_name='tensorflow_tuning'
)
# 하이퍼파라미터 탐색
tuner.search(
X_train_scaled, y_train,
epochs=50,
validation_data=(X_test_scaled, y_test),
callbacks=[EarlyStopping(patience=5)]
)
# 최적 모델 가져오기
best_model = tuner.get_best_models(num_models=1)[0]
best_hyperparameters = tuner.get_best_hyperparameters(num_trials=1)[0]
print("최적 하이퍼파라미터:")
print(best_hyperparameters.values)
주의사항 및 모범 사례
1. 모델 설계
- 레이어 수: 과적합을 방지하기 위해 적절한 레이어 수 선택
- 뉴런 수: 데이터 복잡도에 맞는 뉴런 수 설정
- 활성화 함수: 문제 유형에 맞는 활성화 함수 선택
2. 학습 최적화
- 학습률: 적절한 학습률 설정
- 배치 크기: 메모리와 성능을 고려한 배치 크기 선택
- 에포크 수: 조기 종료를 통한 과적합 방지
3. 성능 모니터링
- 검증 데이터: 검증 데이터를 통한 성능 모니터링
- 콜백: 적절한 콜백을 통한 학습 제어
- 메트릭: 문제에 맞는 메트릭 선택
마무리
TensorFlow는 딥러닝 모델 구축과 훈련을 위한 강력한 프레임워크입니다. Sequential API, Functional API, Subclassing API 등 다양한 모델 구축 방법을 제공하며, 콜백, 커스텀 손실 함수, 커스텀 메트릭 등 고급 기능을 통해 실무에서 요구되는 복잡한 모델을 구축할 수 있습니다. 적절한 모델 설계와 학습 최적화를 통해 높은 성능의 딥러닝 모델을 개발할 수 있습니다.
This post is licensed under CC BY 4.0 by the author.