본문 바로가기

프로그래머스 데브 코스/TIL

[6기] 프로그래머스 인공지능 데브코스 53일차 TIL

1023

[9주차 - Day4] ML 기초 실습과제 2

규제화를 사용한 모델 학습

L2 regularization을 비용함수(compute_cost 내에)에 포함시키고 gradient 계산에(batch_gd 내에) 반영하세요.
def compute_cost(X, T, W, lambd):
    epsilon = 1e-5
    N = len(T)
    K = np.size(T, 1)
    cost = - (1/N) * np.ones((1,N)) @ (np.multiply(np.log(softmax(X, W) + epsilon), T)) @ np.ones((K,1)) + 1 / (2 * N) * lambd * np.sum(W ** 2)
    # L2 regularization으로 '1 / (2 * N) * lambd * np.sum(W ** 2)' 추가로 더해줌
    return cost


def batch_gd(X, T, W, learning_rate, iterations, batch_size, lambd):
    N = len(T)
    cost_history = np.zeros((iterations,1))
    shuffled_indices = np.random.permutation(N)
    X_shuffled = X[shuffled_indices]
    T_shuffled = T[shuffled_indices]

    for i in range(iterations):
        j = i % N
        X_batch = X_shuffled[j:j+batch_size]
        T_batch = T_shuffled[j:j+batch_size]
        # batch가 epoch 경계를 넘어가는 경우, 앞 부분으로 채워줌
        if X_batch.shape[0] < batch_size:
            X_batch = np.vstack((X_batch, X_shuffled[:(batch_size - X_batch.shape[0])]))
            T_batch = np.vstack((T_batch, T_shuffled[:(batch_size - T_batch.shape[0])]))
        W = W - (learning_rate/batch_size) * (X_batch.T @ (softmax(X_batch, W) - T_batch))
        cost_history[i] = compute_cost(X_batch, T_batch, W, lambd)
        # lambd 반영 
        if i % 1000 == 0:
            print(cost_history[i][0])

    return (cost_history, W)

 

 


 

 

Regularization을 위한 가중치 lambda를 튜닝해보세요. 이것을 위해서 학습데이터의 일부를 validation data로 따로 구분하고 이 validation data에 대한 accuracy를 최적화하는 lambda를 찾도록 하는 코드를 구현해보세요.
X = np.hstack((np.ones((np.size(X_train, 0),1)),X_train))
T = y_train

K = np.size(T, 1)
M = np.size(X, 1)
W = np.zeros((M,K))

X_ = np.hstack((np.ones((np.size(X_test, 0),1)),X_test))
T_ = y_test

iterations = 50000
learning_rate = 0.01

initial_cost = compute_cost(X, T, W, 0)

print("Initial Cost is: {} \n".format(initial_cost[0][0]))

# accuracy 최적화하는 lambda 찾기 위한 변수 선언
best_score = 0
best_lambda = 0

# 시도할 정규화 강도(λ) 값들
lambda_values = np.arange(0, 1, 0.05)

for lam in lambda_values:
    (cost_history, W_optimal) = batch_gd(X, T, W, learning_rate, iterations, 64, lam)

    y_pred = predict(X_, W_optimal)
    score = float(sum(y_pred == np.argmax(T_, axis=1)))/ float(len(y_test))
    print(f"Lambda: {lam}, Validation Accuracy: {score}")

    # 가장 높은 검증 정확도를 가진 λ 업데이트
    if score > best_score:
        best_score = score
        best_lambda = lam

print(f"Best Lambda: {best_lambda}, Best Validation Accuracy: {best_score}")

(cost_history, W_optimal) = batch_gd(X, T, W, learning_rate, iterations, 64, best_lambda)

 

 


 

 

다중클래스 분류모델의 결정경계 구하기

아래 웹페이지에서 두 가지의 모델이 학습됩니다. 그 중에서 'multinomial' logistic regression의 경우에, 결정경계를 나타내는 방정식들을 구하고 화면에 나타내보세요.

https://scikit-learn.org/stable/auto_examples/linear_model/plot_logistic_multinomial.html

# Authors: Tom Dupre la Tour <tom.dupre-la-tour@m4x.org>
# License: BSD 3 clause

import matplotlib.pyplot as plt
import numpy as np

from sklearn.datasets import make_blobs
from sklearn.inspection import DecisionBoundaryDisplay
from sklearn.linear_model import LogisticRegression

# make 3-class dataset for classification 
# 분류를 위한 3개의 클래스 데이터셋 만들기
centers = [[-5, 0], [0, 1.5], [5, -1]]
X, y = make_blobs(n_samples=1000, centers=centers, random_state=40)
transformation = [[0.4, 0.2], [-0.4, 1.2]]
X = np.dot(X, transformation)

clf = LogisticRegression(
    solver="sag", max_iter=100, random_state=42, multi_class="multinomial"
).fit(X, y)

# print the training scores
# 훈련 점수 출력
print("training score : %.3f (multinomial)" % (clf.score(X, y)))

# 배경 색상 그래프
_, ax = plt.subplots()
DecisionBoundaryDisplay.from_estimator(
    clf, X, response_method="predict", cmap=plt.cm.Paired, ax=ax
)
plt.title("Decision surface of LogisticRegression (multinomial)")
plt.axis("tight")

# Plot also the training points
# 트레이닝 포인트 플롯 (산점도)
colors = "bry"
for i, color in zip(clf.classes_, colors):
    idx = np.where(y == i)
    plt.scatter(
        X[idx, 0], X[idx, 1], c=color, cmap=plt.cm.Paired, edgecolor="black", s=20
    )

# Plot the three one-against-all classifiers
# 3개의 1:1 분류기 플롯 
xmin, xmax = plt.xlim()
ymin, ymax = plt.ylim()
coef = clf.coef_
intercept = clf.intercept_

# 세 개의 직선 그래프 부분 
def plot_hyperplane(c, color):
    def line(x0):
        return (-(x0 * coef[c, 0]) - intercept[c]) / coef[c, 1]

    plt.plot([xmin, xmax], [line(xmin), line(xmax)], ls="--", color=color)

for i, color in zip(clf.classes_, colors):
    plot_hyperplane(i, color)


for i in range(3):
    w = coef[i]
    b = intercept[i]
    # 그래프 좌측 위에 결정경계 방정식 프린트
    plt.text(2, 5.5-i*0.5, r'$y_{} = {:+.3f}x {:+.3f}$'.format(i+1, w[0]/w[1], b/w[1]), fontdict={'size': 10})
plt.show()