본문 바로가기

밑바닥부터 시작하는 딥러닝

Neural Network example

공부를 하는 입장이기 때문에, 내용에 오류가 있을 수 있습니다. 오류가 있다면 적극적으로 알려주시면 감사합니다!

1. Three layer neural network

 3층 신경망을 통해 값을 추론하는 예제 코드이다. Neural_network.three_layer_neural_network.py 에서 확인 할 수 있다.

입력 데이터가 한개이므로 출력 값도 한 개다. 

배열들의 형상 추이

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def identity_function(x):
    return x

class NEURAL_NETWORK:

    def __init__(self, x):
        self.x = x
        self.network = {}
        self.network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])   # 2 x 3
        self.network['b1'] = np.array([0.1, 0.2, 0.3])                      # 1 x 3 
        self.network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]]) # 3 x 2
        self.network['b2'] = np.array([0.1, 0.2])                           # 1 x 2
        self.network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])             # 2 x 2
        self.network['b3'] = np.array([[0.1, 0.2]])                         # 1 x 2
    
    def forward(self):
        W1, W2, W3 = self.network['W1'], self.network['W2'], self.network['W3']
        b1, b2, b3 = self.network['b1'], self.network['b2'], self.network['b3']

        a1 = np.dot(self.x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        z2 = sigmoid(a2)
        a3 = np.dot(z2, W3) + b3
        y = identity_function(a3)

        return y
    
if __name__=='__main__':
    x = np.array([1.0, 0.5])
    nn = NEURAL_NETWORK(x)
    y = nn.forward()
    print(y)

 

2. Batch

 

 MNIST 데이터를 사용하여 저장된 가중치로 추론을 수행하고, 배치 처리 여부에 따른 시간 차이를 측정하는 코드이다. Neural_network.neural_mnist.py에서 확인 할 수 있다.

 

 파이썬 파일을 실행하면 해당 파일이 있는 폴더가 자동으로 모듈 검색 경로에 포함된다. 같은 계층의 폴더를 사용하려면 절대 경로를 통해 파일을 불러오는 방법이 가장 간단하지만, 이 방식은 확장성과 파일 관리의 유연성을 떨어뜨린다. 따라서 현재 파일이 있는 폴더보다 상위 폴더를 모듈 검색 경로에 추가해 같은 계층의 다른 폴더를 유연하게 사용할 수 있도록 했다.

import sys, os
# 내경로가 현재 폴더가 아닌 상위 폴더로 바꿈 # 부모 디렉터리의 파일을 가져올 수 있도록 설정
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))

 

 파이썬의 pickle 라이브러리 같은 경우는 지금 사용하고 있는 객체를 저장하고 불러올 수 있는 라이브러리이다. 이번 코드에서는 가중치가 담겨있는 객체를 불러와서 직접 사용할 수 있도록 했다. 

 

  dataset.mnist.py에서는 mnist데이터를 불러오는 코드가 담겨있는데, load_mnist라는 함수를 통해 데이터를 불러올수 있다. 총 3가지 normalize, flatten, one_hot_label 파라미터가 존재한다. normalize 같은 경우는 입력 이미지의 픽셀을 0~255에서 0.0~1.0의 크기로 정규화할지 정한다. flatten는 이미지를 1차원으로 바꿀지 아니면 1x28x28로 그대로 유지할지를 정하는 파라미터이다. 마지막으로 one_hot_encoding 같은 경우는 정답을 [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] 형태로 one-hot encoding 할지, 아니면 숫자 '3'과 같이 정답 레이블을 그대로 사용할지 설정한다.

 

실행 결과

 

 실행 결과, x의 개수는 총 10,000개인 것을 확인할 수 있다. 배치 없이 데이터를 하나씩 처리하면 10,000번의 반복문을 거쳐 추론이 이루어지고, 이때 0.18초가 소요된다. 그러나 batch_size를 100으로 설정하고 실행하면,  10000 / 100으로 총100번의 반복문만 실행된다. 이때 실행 시간은 0.02초로, 배치를 사용했을 때 시간이 확실히 더 빠른 것을 확인할 수 있다.

import sys, os
# 내경로가 현재 폴더가 아닌 상위 폴더로 바꿈 # 부모 디렉터리의 파일을 가져올 수 있도록 설정
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__)))) 
import numpy as np
from dataset.mnist import load_mnist
from Neural_network.sigmoid import sigmoid
from Neural_network.softmax import softmax
import pickle
import time

class NEURALNET_MNIST:

    def __init__(self):
        self.network = None
        self.W1 = self.W2 = self.W3 = None
        self.b1 = self.b2 = self.b3 = None
        self.init_network()

    def get_data(self):
        (x_train, t_train), (x_test, t_test) = \
            load_mnist(normalize=True, flatten=True, one_hot_label=False)
        return x_test, t_test
    
    def init_network(self):
        with open("Neural_network\\sample_weight.pkl", 'rb') as f:
            self.network = pickle.load(f)

    def predict(self, x):
        self.W1, self.W2, self.W3 = self.network['W1'], self.network['W2'], self.network['W3']
        self.b1, self.b2, self.b3 = self.network['b1'], self.network['b2'], self.network['b3']

        a1 = np.dot(x, self.W1) + self.b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, self.W2) + self.b2
        z2 = sigmoid(a2)
        a3 = np.dot(z2, self.W3) + self.b3
        y = softmax(a3)

        return y
    
if __name__=='__main__':

    neuralnet_mnist = NEURALNET_MNIST()
    x, t = neuralnet_mnist.get_data()

    batch_size = 100
    accuracy_cnt = 0
    accuracy_cnt2 = 0
    print(x.shape)
    cnt = 0
    time_start = time.time()
    for i in range(len(x)):
        y = neuralnet_mnist.predict(x[i])
        p = np.argmax(y)
        if p == t[i]:
            accuracy_cnt += 1
        cnt += 1
    during_time = time.time() - time_start
    print("cnt : ",cnt)
    print("time without batch : ", during_time)
    print("Accuracy:" ,str(float(accuracy_cnt) / len(x)))

    cnt = 0
    time_start = time.time()
    for i in range(0, len(x), batch_size):
        x_batch = x[i:i+batch_size]
        y_batch = neuralnet_mnist.predict(x_batch)
        p = np.argmax(y_batch, axis=1)
        accuracy_cnt2 += np.sum(p == t[i:i+batch_size])
        cnt += 1
    during_time = time.time() - time_start

    print("cnt : ",cnt)
    print("time with batch :    ", during_time)
    print("Accuracy with batch:" ,str(float(accuracy_cnt) / len(x)))

 

 

 

Study_with_book/DeepLearning-from-Scratch at main · dy0221/Study_with_book

Contribute to dy0221/Study_with_book development by creating an account on GitHub.

github.com

 

 

GitHub - WegraLee/deep-learning-from-scratch: 『밑바닥부터 시작하는 딥러닝』(한빛미디어, 2017)

『밑바닥부터 시작하는 딥러닝』(한빛미디어, 2017). Contribute to WegraLee/deep-learning-from-scratch development by creating an account on GitHub.

github.com

 

'밑바닥부터 시작하는 딥러닝' 카테고리의 다른 글

Backpropagation  (0) 2024.12.24
Neural Network Learning Example  (0) 2024.12.22
Neural Network Learning  (0) 2024.12.22
Neural Network  (0) 2024.12.19
밑바닥부터 시작하는 딥러닝  (0) 2024.12.18