59doit

신경망 알고리즘 본문

인공지능

신경망 알고리즘

yul_S2 2023. 1. 10. 15:35
반응형

신경망 알고리즘 벡터화하기

 

# 필요한 모듈 및 임포트 

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

 

 

# breast cancer 데이터 활용

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)
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)

 

# SingleLayer 신경망

class SingleLayer:
 
    def __init__(self, learning_rate=0.1, l1=0, l2=0):
        self.w = None  # 가중치
        self.b = None  # 절편
        self.losses = []  # 훈련 손실
        self.val_losses = []  # 검증 손실
        self.w_history = []  # 가중치 기록
        self.lr = learning_rate  # 학습률
        self.l1 = l1  # L1 손실 하이퍼파라미터
        self.l2 = l2  # L2 손실 하이퍼파라미터
 
    def forpass(self, x):
        z = np.dot(x, self.w) + self.b  # 선형 출력을 계산합니다.
        return z
 
    def backprop(self, x, err):
        m = len(x)
        w_grad = np.dot(x.T, err) / m  # 가중치에 대한 그래디언트를 계산합니다.
        b_grad = np.sum(err) / m  # 절편에 대한 그래디언트를 계산합니다.
        return w_grad, b_grad
 
    def activation(self, z):
        z = np.clip(z, -100, None)  # 안전한 np.exp() 계산을 위해
        a = 1 / (1 + np.exp(-z))  # 시그모이드 계산
        return a
 
    def fit(self, x, y, epochs=100, x_val=None, y_val=None):
        y = y.reshape(-1, 1)  # 타깃을  벡터로 바꿉니다.
        y_val = y_val.reshape(-1, 1)
        m = len(x)  # 샘플 개수를 저장합니다.
        self.w = np.ones((x.shape[1], 1))  # 가중치를 초기화합니다.
        self.b = 0  # 절편을 초기화합니다.
        self.w_history.append(self.w.copy())  # 가중치를 기록합니다.
        # epochs만큼 반복합니다.
        for i in range(epochs):
            z = self.forpass(x)  # 정방향 계산을 수행합니다.
            a = self.activation(z)  # 활성화 함수를 적용합니다.
            err = -(y - a)  # 오차를 계산합니다.
            # 오차를 역전파하여 그래디언트를 계산합니다.
            w_grad, b_grad = self.backprop(x, err)
            # 그래디언트에 페널티 항의 미분 값을 더합니다.
            w_grad += (self.l1 * np.sign(self.w) + self.l2 * self.w) / m
            # 가중치와 절편을 업데이트합니다.
            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 = np.sum(-(y * np.log(a) + (1 - y) * np.log(1 - a)))
            self.losses.append((loss + self.reg_loss()) / m)
            # 검증 세트에 대한 손실을 계산합니다.
            self.update_val_loss(x_val, y_val)
 
    def predict(self, x):
        z = self.forpass(x)  # 정방향 계산을 수행합니다.
        return z > 0  # 스텝 함수를 적용합니다.
 
    def score(self, x, y):
        # 예측과 타깃  벡터를 비교하여 True 비율을 반환합니다.
        return np.mean(self.predict(x) == y.reshape(-1, 1))
 
    def reg_loss(self):
        # 가중치에 규제를 적용합니다.
        return self.l1 * np.sum(np.abs(self.w)) + self.l2 / 2 * np.sum(self.w ** 2)
 
    def update_val_loss(self, x_val, y_val):
        z = self.forpass(x_val)  # 정방향 계산을 수행합니다.
        a = self.activation(z)  # 활성화 함수를 적용합니다.
        a = np.clip(a, 1e-10, 1 - 1e-10)  # 출력 값을 클리핑합니다.
        # 로그 손실과 규제 손실을 더하여 리스트에 추가합니다.
        val_loss = np.sum(-(y_val * np.log(a) + (1 - y_val) * np.log(1 - a)))
        self.val_losses.append((val_loss + self.reg_loss()) / len(y_val))

 

 

# scaler

from sklearn.preprocessing import StandardScaler
 
scaler = StandardScaler()
scaler.fit(x_train)
x_train_scaled = scaler.transform(x_train)
x_val_scaled = scaler.transform(x_val)

 

 

# 학습하기

single_layer = SingleLayer(l2=0.01)
single_layer.fit(x_train_scaled, y_train, x_val=x_val_scaled, y_val=y_val, epochs=10000)
single_layer.score(x_val_scaled, y_val)
# 0.978021978021978

 

 

# 시각화

 

# 시각화

 

 

 

# 시각화

w2 = []
w3 = []
for w in single_layer.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()

 

 

 

반응형

'인공지능' 카테고리의 다른 글

다층신경망(2) 미니배치  (7) 2023.01.11
다층신경망(1)  (3) 2023.01.11
규제적용하기  (1) 2023.01.10
전처리(3)  (6) 2023.01.09
전처리(2)  (0) 2023.01.08
Comments