반응형
5-1 검증 세트를 나누고 전처리 과정 배우기
- 테스트 세트로 모델 튜닝
로지스틱 회귀로 모델 훈련하고 평가
1) cancer 데이터 세트를 읽어 들여 훈련 세트와 테스트 세트로 나눔
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
cancer = load_breast_cancer()
x = cancer.data
y = cancer.target
x_train_all, x_test, y_train_all, y_test = train_test_split(x, y, stratify = y, test_size=0.2, random_state=42)
2) SGDClassifier 클래스를 이용하여 로지스틱 회귀 모델 훈련
from sklearn.linear_model import SGDClassifier
sgd = SGDClassifier(loss = 'log', random_state=42)
sgd.fit(x_train_all, y_train_all)
sgd.score(x_test, y_test)
##출력: sgd.score(x_test, y_test)
※ 서포트 벡터 머신으로 모델 훈련하고 평가
from sklearn.linear_model import SGDClassifier
sgd = SGDClassifier(loss='hinge', random_state = 42)
sgd.fit(x_train_all, y_train_all)
sgd.score(x_test, y_test)
##출력: 0.9385964912280702
테스트 세트로 모델을 튜닝하면 '테스트 세트에 대해서만 좋은 성능을 보여주는 모델'이 되어 일반화 성능(generalization performance)이 왜곡된다.
- 검증 세트 준비
1. 데이터 세트 준비하기
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
cancer = load_breast_cancer()
x = cancer.data
y = cancer.target
x_train_all, x_test, y_train_all, y_test = train_test_split(x, y, stratify = y, test_size=0.2, random_state=42)
2. 검증 세트 분할하기
x_train, x_val, y_train, y_val = train_test_split(x_train_all, y_train_all, stratify=y_train_all, test_size = 0.2, random_state=42)
print(len(x_train), len(x_val))
##출력: 364 91
3. 검증 세트 사용해 모델 평가하기
sgd = SGDClassifier(loss='log', random_state=42)
sgd.fit(x_train, y_train)
sgd.score(x_val, y_val)
##출력: 0.6923076923076923
반응형
- 스케일을 조정하지 않고 모델 훈련
1. 훈련 데이터 준비하고 스케일 비교
import matplotlib.pyplot as plt
print(cancer.feature_names[[2,3]])
plt.boxplot(x_train[:, 2:4])
plt.xlabel('feature')
plt.ylabel('value')
plt.show()
2. 가중치를 기록할 변수와 학습률 파라미터 추가
def __init__(self, learning_rate=0.1):
self.w = None
self.b = None
self.losses = []
self.w_history = []
self.lr = learning_rate
3. 가중치 기록하고 업데이트 양 조절
import numpy as np
def fit(self, x, y, epochs=100, x_val=None, y_val=None):
self.w = np.ones(x.shape[1]) # 가중치를 초기화합니다.
self.b = 0 # 절편을 초기화합니다.
self.w_history.append(self.w.copy()) # 가중치를 기록합니다.
np.random.seed(42) # 랜덤 시드를 지정합니다.
for i in range(epochs): # epochs만큼 반복합니다.
loss = 0
# 인덱스를 섞습니다
indexes = np.random.permutation(np.arange(len(x)))
for i in indexes: # 모든 샘플에 대해 반복합니다
z = self.forpass(x[i]) # 정방향 계산
a = self.activation(z) # 활성화 함수 적용
err = -(y[i] - a) # 오차 계산
w_grad, b_grad = self.backprop(x[i], err) # 역방향 계산
# 그래디언트에서 페널티 항의 미분 값을 더합니다
w_grad += self.l1 * np.sign(self.w) + self.l2 * self.w
self.w -= self.lr * w_grad # 가중치 업데이트
self.b -= self.lr * b_grad # 절편 업데이트
# 가중치를 기록합니다.
self.w_history.append(self.w.copy())
# 안전한 로그 계산을 위해 클리핑한 후 손실을 누적합니다
a = np.clip(a, 1e-10, 1-1e-10)
loss += -(y[i]*np.log(a)+(1-y[i])*np.log(1-a))
# 에포크마다 평균 손실을 저장합니다
self.losses.append(loss/len(y) + self.reg_loss())
4. 모델 훈련하고 평가
layer1 = SingleLayer()
layer1.fit(x_train, y_train)
layer1.score(x_val, y_val)
##출력: 0.9120879120879121
5. 최종적으로 결정된 가중치 표시
w2 = []
w3 = []
for w in layer1.w_history:
w2.append(w[2])
w3.append(w[3])
plt.plot(w2, w3)
plt.plot(w2[-1], w3[-1], 'ro')
plt.xlabel('w[2]')
plt.ylabel('w[3]')
plt.show()
- 스케일을 조정해 모델 훈련
1. 넘파이로 표준화 구현하기
train_mean = np.mean(x_train, axis=0)
train_std = np.std(x_train, axis=0)
x_train_scaled = (x_train - train_mean) / train_std
2. 모델 훈련하기
layer2 = SingleLayer()
layer2.fit(x_train_scaled, y_train)
w2 = []
w3 = []
for w in layer2.w_history:
w2.append(w[2])
w3.append(w[3])
plt.plot(w2, w3)
plt.plot(w2[-1], w3[-1], 'ro')
plt.xlabel('w[2]')
plt.ylabel('w[3]')
plt.show()
3. 모델 성능 평가하기
layer2.score(x_val, y_val)
##출력: 0.37362637362637363
4. 표준화 전처리 적용
val_mean = np.mean(x_val, axis=0)
val_std = np.std(x_val, axis=0)
x_val_scaled = (x_val - val_mean) / val_std
layer2.score(x_val_scaled, y_val)
##출력: 0.967032967032967
- 스케일을 조정한 다음 실수하기 쉬운 함정
'훈련 세트와 검증 세트가 다른 비율로 스케일이 조정된 경우'
1. 원본 훈련 세트와 검증 세트로 산점도 그리기
plt.plot(x_train[:50, 0], x_train[:50, 1], 'bo')
plt.plot(x_val[:50, 0], x_val[:50, 1], 'ro')
plt.xlabel('feature 1')
plt.ylabel('feature 2')
plt.legend(['train set', 'val. set'])
plt.show()
2. 전처리한 훈련 세트와 검증 세트로 산점도 그리기
plt.plot(x_train_scaled[:50, 0], x_train_scaled[:50, 1], 'bo')
plt.plot(x_val_scaled[:50, 0], x_val_scaled[:50, 1], 'ro')
plt.xlabel('feature 1')
plt.ylabel('feature 2')
plt.legend(['train set', 'val. set'])
plt.show()
3. 올바르게 검증 세트 전처리하기
x_val_scaled = (x_val - train_mean) / train_std
plt.plot(x_train_scaled[:50, 0], x_train_scaled[:50, 1], 'bo')
plt.plot(x_val_scaled[:50, 0], x_val_scaled[:50, 1], 'ro')
plt.xlabel('feature 1')
plt.ylabel('feature 2')
plt.legend(['train set', 'val. set'])
plt.show()
4. 모델 평가하기
layer2.score(x_val_scaled, y_val)
##출력: 0.967032967032967
※ 해당 내용은 <Do it! 딥러닝 입문>의 내용을 토대로 학습하며 정리한 내용입니다.
반응형
'딥러닝 학습' 카테고리의 다른 글
5장 훈련 노하우 배우기 (3) (0) | 2023.03.08 |
---|---|
5장 훈련 노하우 배우기 (2) (0) | 2023.03.07 |
4장 분류하는 뉴런 만들기-이진분류 (3) (0) | 2023.03.05 |
4장 분류하는 뉴런 만들기-이진 분류 (2) (0) | 2023.03.04 |
4장 분류하는 뉴런 만들기-이진 분류 (1) (0) | 2023.03.03 |