주택 면적으로 가격을 예측하는 선형회귀 모델 f(x) = wx + b를 경사하강법으로 학습합니다.
import numpy as np
rng = np.random.default_rng(0)
x = rng.uniform(0.5, 3.5, 50) # 면적 (1000 feet²)
y = 100 * x + 50 + rng.normal(0, 20, 50) # 가격 ($1000)
compute_cost(x, y, w, b): J(w,b) = (1/2m) Σ (wx⁽ⁱ⁾ + b − y⁽ⁱ⁾)²gradient_descent(x, y, alpha, iters): w와 b를 동시 갱신합니다.import matplotlib.pyplot as plt
def compute_cost(x, y, w, b):
m = x.shape[0]
f = w * x + b # 예측값
return np.sum((f - y) ** 2) / (2 * m) # 제곱오차의 평균의 절반
def gradient_descent(x, y, alpha, iters, w=0.0, b=0.0):
m = x.shape[0]
J_hist = []
for _ in range(iters):
err = w * x + b - y
dj_dw = np.sum(err * x) / m # 이전 w, b로 두 기울기를 먼저 계산
dj_db = np.sum(err) / m
w, b = w - alpha * dj_dw, b - alpha * dj_db # 동시 갱신
J_hist.append(compute_cost(x, y, w, b))
return w, b, J_hist
w, b, J_hist = gradient_descent(x, y, alpha=0.1, iters=1000)
print(f"w = {w:.2f}, b = {b:.2f}")
print(f"1250 feet² 예측 가격: ${(w * 1.25 + b) * 1000:,.0f}")
plt.plot(J_hist)
plt.xlabel("iteration"); plt.ylabel("J(w, b)"); plt.title("learning curve")
plt.show()
실행 결과
w = 103.49, b = 43.40
1250 feet² 예측 가격: $172,766해설: 학습된 w ≈ 103, b ≈ 43은 데이터를 만든 값(100, 50)에 가깝습니다. 학습 곡선은 처음에 빠르게 내려간 뒤 평평해지며, 이는 경사하강법이 수렴했다는 뜻입니다.
8×8 손글씨 숫자 이미지(0~9)를 분류하는 신경망을 학습합니다.
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.losses import SparseCategoricalCrossentropy
X, y = load_digits(return_X_y=True) # 8×8 = 64 픽셀, 숫자 0~9
X = X / 16.0
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
SparseCategoricalCrossentropy(from_logits=True)와 Adam(learning_rate = 0.001)으로 30 epoch 학습합니다.tf.nn.softmax로 클래스별 확률과 예측한 숫자를 출력합니다.tf.keras.utils.set_random_seed(0) # 재현성
model = Sequential([
Dense(25, activation="relu"),
Dense(15, activation="relu"),
Dense(10, activation="linear"), # 출력은 logits
])
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
metrics=["accuracy"])
model.fit(X_train, y_train, epochs=30, verbose=0)
loss, acc = model.evaluate(X_test, y_test, verbose=0)
print(f"테스트 정확도: {acc:.3f}")
# 출력층은 logits(z)를 내므로, 확률은 softmax를 직접 적용해 얻는다
logits = model.predict(X_test[:1], verbose=0)
probs = tf.nn.softmax(logits).numpy()
print("확률:", np.round(probs, 3))
print("예측:", probs.argmax(), "정답:", y_test[0])
실행 결과 (TensorFlow 버전·환경에 따라 정확도가 조금 다를 수 있습니다)
테스트 정확도: 0.956
확률: [[0. 0. 0.999 0.001 0. 0. 0. 0. 0. 0. ]]
예측: 2 정답: 2해설: 출력층을 "linear"로 두고 from_logits=True를 쓰면, TensorFlow가 소프트맥스와 log를 손실 안에서 한 번에 계산해 수치 오차를 줄입니다. 그래서 모델 출력은 확률이 아닌 logits이며, 확률이 필요하면 tf.nn.softmax를 적용합니다.