[이 글은 "Do it 딥러닝 입문" 책을 보고 공부한 내용을 복습하고자 정리한 글입니다.]
목표 - 유방암 데이터 셋으로부터 모델을 만들고 테스트 후 정확도를 확인한다.
sklearn(Scikit-learn이란?
- 파이썬에 있는 머신러닝 라이브러리 중 하나로, 분류(classification), 회귀(regression), 군집화(clustering), 의사결정 트리(decision tree) 등의 다양한 알고리즘을 적용할 수 있는 다양한 함수들을 제공하는 라이브러리
[공부 중 궁금했던 것과 사용한 함수들을 정리]
1. from sklearn.dataset import load_breast_cancer
- 사이킷런에서 유방암 데이터를 로드
2. plt.boxplot(cancer.data)
- cancer.data에 있는 열(column)의 데이터를 상자와 수염을 이용해 그린 그래프
참고 링크 : https://rfriend.tistory.com/410
3. cancer.feature_names[[3,13,23]]
- 각 인덱스에 해당하는 열의 특성(이름)을 볼 수 있음.
4. np.unique(target, return_counts=)
- target안에 고유한 값의 개수를 센 다음 반환
5. from sklearn.model_selection import train_test_split
- 주어진 데이터 셋에서 훈련 데이터와 테스트 데이터로 나누기 위한 모듈
6. train_test_split(x, y, stratify=y, test_size, random_state=42)
- stratify : 훈련 데이터를 나눌 때 골고루 나눠져야 하는데 y로 주게 되면 y를 기준으로 균형 있게 나눠진다.
- test_size : default는 75 : 25지만 우리는 80 : 20으로 나누기 위해 0.2르 주었다.
- random_state : 무작위로 데이터 세트를 섞음 다음 나누는 함수
7. forpass(x):
- hypothesis를 구하는 함수 정방향 계산이라고도 불린다. x값과 w값을 곱하구 b를 더해 예측 값을 구한다.
8. backprop(x, err):
- err는 실제값과 예측값의 차이이다. w 값은 x * err, b 값은 1 * err을 준다. 그레이디언트를 계산하는 것이다.
9. np.random.permutation(np.arange(len(x)))
- x값의 길이 즉, 행의 인덱스를 섞어서 훈련을 랜덤 하게 되게(효율적으로)하는 용도로 사용한다.
10. np.clip(값, 범위, 범위)
- 값의 주어진 범위 밖으로 나가면 양 끝의 값으로 잘라낸다.
- 섞으므로서 우리는 확률적 경사 하강법에서부터 배치 경사 하강법을 구현할 수 있다.
11. 모델 생성의 메커니즘
w값과 b값을 랜덤으로 부여(여기선 None으로 줌)
-> w값과 x값을 forpass 해주기 위해 w값을 x의 열의 수로 맞춰준다.(행렬의 곱은 행열*열행이 충족돼야 하므로)
-> forpass로 예측 값 즉, z값을 구해준다.
-> z값을 activation함수에 넣어주어 0 ~ 1 사이의 값(a)으로 바꿔준다. (sigmoid)
-> 실제 값과 예측 값을 빼주어서 오차율을 구한다.(여기서 음수인 이유는 y_hat은 w와 b의 함수이기 때문이다.)
-> backprop을 이용해서 w와 b를 업데이트를 해준다.
-> 로지스틱 손실 함수를 구해준다.
-> epoch만큼 모델이 학습되면 x_test값과 y_test으로 모델의 정확도를 판단해준다.
#유방암 데이터 세트 준비
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
print(cancer.data.shape, cancer.target.shape)
cancer.data[:3]
cancer.target[:100]
import numpy as np
import matplotlib.pyplot as plt
plt.boxplot(cancer.data)
plt.show()
cancer.feature_names[[3,13,23]]
np.unique(cancer.target, return_counts=True)
#cancer.target에 있는 수를 카운트해서 반환
# 훈련 데이터 저장
x = cancer.data
y = cancer.target
# 하나의 데이터 셋에서 훈련데이터와 테스트데이터로 나눈다.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y, test_size=0.2, random_state=42)
np.unique(y_train, return_counts=True)
class SingleLayer():
def __init__(self):
self.w = None # 데이터 특성이 많기 때문에 가중치를 미리 초기화하지 않음.
self.b = None
self.losses = []
def forpass(self, x):
z = np.sum(x * self.w) + self.b # 직선의 방정식 즉 hypothesis #np.sum을 사용하면 1차원 넘파이배열에서 배열의 요소끼리 사칙연산을 할 수 있음.
return z
def backprop(self, x, err):
w_grad = x * err #가중치에 대한 그레이디언트 계산
b_grad = 1 * err #절편에 대한 그레이디언트 계산
return w_grad, b_grad
def fit(self, x, y, epochs=100):
self.w = np.ones(x.shape[1]) #가중치를 초기화하는데 x의 shape과 똑같고 1채움 즉 각 행값
self.b = 0
for i in range(epochs):
loss = 0
indexes = np.random.permutation(np.arange(len(x))) #인덱스를 섞음. 데이터가 섞여서 훈련될수록 손실 함수의 값이 효율적으로 줄어듬
for i in indexes:
z = self.forpass(x[i]) #정방향 계산
a = self.activation(z) #activation함수 적용
err = -(y[i] - a) #실제값과 예측값 오차계산
w_grad, b_grad = self.backprop(x[i], err) #역방향 계산
self.w -= w_grad #업데이트
self.b -= b_grad
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))
def activation(self, z):
a = 1 / (1 + np.exp(-z))
return a
def predict(self, x):
z = [self.forpass(x_i) for x_i in x] #hypothesis를 구해 반환
return np.array(z) > 0 #스텝 함수 적용
def score(self, x, y):
return np.mean(self.predict(x)==y)
layer = SingleLayer()
layer.fit(x_train,y_train)
layer.score(x_test,y_test)
plt.plot(layer.losses)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
'빅데이터 | 머신러닝 | 딥러닝 > 딥러닝' 카테고리의 다른 글
[딥러닝 기초] 다층 신경망 (MLPClassifier) (0) | 2020.05.08 |
---|---|
[딥러닝 기초] k-fold 교차 검증(cross validation) (0) | 2020.05.02 |
[딥러닝 기초] Neural Network (L1, L2 규제) (0) | 2020.04.25 |
[딥러닝 기초] Neural Network (훈련 노하우) (0) | 2020.04.24 |
[jupyter notebook] Neural Network (use mnist dataset) (0) | 2020.04.18 |