2022. 4. 23. 16:13ㆍ인공지능
안녕하세요.
아래와 같은 딥러닝(사실 딥러닝은 Hidden layer가 2개이상부터 이지만, 여기선 기초를 잡기위해 1개로 생각해보겠습니다) 네트워크를 딥러닝 패키지 없이 Numpy와 Matplotlib만 사용하여 Neural Network Gradient Descent를 설계해보도록 하겠습니다.
# Import Library
import numpy as np
from numpy import loadtxt
import matplotlib.pyplot as plt
## DATA SET
dataset = loadtxt('./training.txt')
training_data = dataset[:,0:2]
test_data = dataset[:,-1]
label = np.zeros((1000,2))
for i in range(1000):
if test_data[i]== 1.:
label[i,1]=1
if test_data[i]== 0.:
label[i,0]=1
데이터 셋은 아래와 같습니다.
총 1000개가 있고, input data는 2개의 열, label은 마지막 열(값이 0또는 1)입니다.
## Activate Fuction Sigmoid
def sigmoid(x):
return 1 / (1+np.exp(-x))
활성함수는 sigmoid함수로 하겠습니다.
## Basic Deep Learning Network
class BasicDeepLearning:
def __init__(self, input_nodes, hidden_nodes, output_nodes, learning_rate):
self.input_nodes = input_nodes
self.hidden_nodes = hidden_nodes
self.output_nodes = output_nodes
# hidden layer weight init
self.W2 = np.random.random((self.input_nodes, self.hidden_nodes))
# output layer weight init
self.W3 = np.random.random((self.hidden_nodes, self.output_nodes))
# output layer
self.Z3 = np.zeros([1,output_nodes])
self.A3 = np.zeros([1,output_nodes])
# hidden layer
self.Z2 = np.zeros([1,hidden_nodes])
self.A2 = np.zeros([1,hidden_nodes])
# input layer
self.Z1 = np.zeros([1,input_nodes])
self.A1 = np.zeros([1,input_nodes])
# learning rate
self.learning_rate = learning_rate
## Feed Forward
def feed_forward(self):
# input layer
self.Z1 = self.input_data
self.A1 = self.input_data
# hidden layer
self.Z2 = self.A1.dot( self.W2)
self.A2 = sigmoid(self.Z2)
# output layser
self.Z3 = self.A2.dot(self.W3)
self.A3 = sigmoid(self.Z3)
return self.A3
## loss
def loss_val(self):
loss = ((self.A3 - self.target_data)**2)
loss = np.mean(loss)
return loss
## Train(Backwoard, Weight Update)
def train(self, input_data, target_data):
self.target_data = target_data
self.input_data = input_data
#feedforward
self.feed_forward()
# stage1 (output → hidden weight update)
loss_3 = (self.A3 - self.target_data) * self.A3 * (1- self.A3)
self.W3 = self.W3 - self.learning_rate * np.dot(self.A2.T, loss_3)
# stage2 (hidden → input weight update)
loss_2 = np.dot(loss_3, self.W3.T) * self.A2 * (1-self.A2)
self.W2 = self.W2 - self.learning_rate * np.dot(self.A1.T, loss_2)
변수설명을 먼저 할게요!
Z는 W(Weight)와 계산(선형함)된 결과를 뜻하며, A는 Z에서 활성함수를 통과한 결과를 뜻합니다.
따라서 전체적인 네트워크 Feedforward Flow를 생각해보면 아래와 같습니다.
Z1/A1 → W2(Weight) → Z2 → 활성함수 → A2 → W3(Weight) → Z3 → 활성함수 → A3
또한, Backpropagation(Weight 없데이트) Flow를 생각해보면 아래와 같습니다.
output → hidden weight update(STEP1) → hidden → input weight update(STEP2)
여기서, Weight를 업데이트 할때, Loss가 최소화가 될때까지 업데이트를 해줍니다.
즉, 우리는 Loss가 최소화가 될때의 Weight값을 구하는 것입니다.
Loss Function은 다양하게 있지만, 가장 기본적으로는 MSE가 있는데 MSE는 Feedforward의 출력물과 결과물(label, 진짜값)의 차이의 거리를 뜻합니다. 즉, 우리가 계산한 출력값이 진짜값과 차이를 가장 최소화 하는 파라미터(Weight)를 찾습니다.)
수학적으로, Loss function의 최소화는 기울기가 0이 되는 것입니다. Loss function의 기울기를 Gradient라 하고 Gradient를 learning rate만큼 줄여나가며 0에 가까운 값(최소화)을 찾아나갑니다.
(여기서 중요한 체인룰(Chain Rule)기법이 나오는데, 이부분은 다음에 자세히 설명하기로 합니다.)
## Parameter Settinga
input_nodes = 2
hidden_nodes = 8
output_nodes = 1
learning_rate = 0.01
epochs=1000
네트워크 설계가 다 끝났으면, 파라미터 셋팅값을 넣어줍니다.
## Training for optimization
loss = []
bdl = BasicDeepLearning(input_nodes, hidden_nodes, output_nodes, learning_rate)
for i in range(epochs):
bdl.train( training_data, label )
loss.append(bdl.loss_val())
print(bdl.loss_val())
점점 줄어드는 loss를 볼 수 있습니다.
점점 줄어는 loss를 시각화해서 보도록 합니다.
뭔가 smooth하게 안정적으로 가진 않지만, loss가 줄어드는 것(0으로 수렴하는것)을 볼 수 있습니다.
'인공지능' 카테고리의 다른 글
딥러닝 Hidden Layer 개수 정해보기: Deep Learning With Only Numpy(패키지 없이 코딩하기) (1) | 2022.05.05 |
---|---|
직장인 인공지능 대학원 합격 후기 2탄(면접질문 및 준비과정) (2) | 2022.02.02 |
직장인 인공지능 대학원 합격 후기 1탄(자소서 항목 및 준비과정) (1) | 2022.01.31 |