6장 2개의 층을 연결 – 다층

6-1 신경망 알고리즘을 벡터화하여 전체 샘플을 한 번에 사용

– 벡터화

벡터화된 연산을 사용하여 알고리즘의 성능을 향상시킬 수 있습니다.

– 벡터 및 행렬 연산


– SingleLayer 클래스에 배치 경사하강법 적용

1. Numpy 및 Matplotlib 가져오기

import numpy as np
import matplotlib.pyplot as plt

2. Wisconsin 유방암 데이터 세트를 교육, 검증 및 테스트 세트로 나눕니다.

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

3. 훈련 세트와 검증 세트의 크기 확인

print(x_train.shape, x_val.shape)


##출력: (364, 30) (91, 30)

4. 순방향 계산을 행렬 곱셈으로 표현



5. 그래디언트 계산 이해


6. forpass() 및 backprop() 메서드에 배치 경사 하강법 적용

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

7. fit() 메서드 수정

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)

8. 나머지 메서드 수정

def predict(self, x):
  z = self.forpass(x)      # 정방향 계산을 수행합니다.

return z > 0 # 스텝 함수를 적용합니다.

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

9. 훈련 데이터 정규화 전처리

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)

10. SingleLayer 클래스 개체에 데이터를 전달하여 일괄 경사 하강 적용

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

11. 검증 세트로 성능 측정, 곡선 비교

plt.ylim(0, 0.3)
plt.plot(single_layer.losses)
plt.plot(single_layer.val_losses)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(('train_loss', 'val_loss'))
plt.show()


12. 무게 변화의 그래픽 표현

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


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

※ 내용 Dies sind die Inhalte, die basierend auf den Inhalten der Einführung in Deep Learning> 배우고 조직하는 것.