본문 바로가기
----------책----------/밑바닥부터 시작하는 딥러닝2

CHAPTER 1 - 신경망 복습

by 탶선 2020. 1. 13.
반응형

1.1 수학과 파이썬 복습

1.1.1 벡터, 행렬

벡터 - 크기와 방향을 가짐, 일렬로 늘어선 집합으로 표현 가능(파이썬 - 1차 배열 취급 가능)

행렬 - 2차원 형태(사각형 형상)

그림 1-1 3행 2열의 행렬, 3x2 행렬

numpy를 사용한 배열 생성

변수명 = np.array([1,2,3]) #[1,2,3] 의 행렬 생성

변수명 = np.array([1,2,3],[4,5,6]) #[[1,2,3],[4,5,6]] 의 행렬 생성

변수명.shape # 행렬의 형태 출력

변수명.ndim # 행렬의 차원 출력

import numpy as np
x = np.array([1,2,3])
x.shape

x.ndim

W = np.array([[1,2,3],[4,5,6]])
W.shape

W.ndim

 

 

1.1.2 행렬의 원소별 연산

 

서로 대응하는 원소끼리의 연산

import numpy as np

W = np.array(([1,2,3],[4,5,6]))
X = np.array(([0,1,2],[3,4,5]))

W + X

W * X

 

 

1.1.3 브로드캐스트(broadcast - 전파하다, 흩뿌리다)

2x2 행렬 A에 스칼라 값 10 곱

import numpy as np
A = np.array([[1,2,],[3,4]])
A * 10

브로드캐스트(broadcast) - 어떤 조건만 만족한다면 형태가 다른 배열끼리의 연산도 가능하게 하며
형태가 맞지 않는 부분을 확장하여 연산을 수행할 수 있도록 하는 기능

##형태가 다른 배열들 간의 연산이 어떤 조건을 만족할 때 연산이 가능해지도록 배열을 자동적으로 변환하는 기능

 

 

 

 

1.1.4 벡터의 내적과 행렬의 곱

벡터의 내적

벡터의 내적 - 두 벡터에서 대응하는 원소들의 곱을 모두 한한 것

                - 두 벡터가 얼마나 같은 방향을 향하고 있는가

                - 벡터의 길이가 1인 경우/ 같은 방향을 ㅡ향하는 두 벡터의 내적은 1

                - 반대 방향을 향하는 두 벡터의 내적은 -1

행렬의 곱셈 - (왼쪽 행렬의)행 벡터와 (오른쪽 행렬의 ) 열 벡터의 내적으로 계산

1,2 - 벡터의 내적 / 3 - 행렬곱

import numpy as np

a = np.array([1,2,3])
b = np.array([4,5,6])
np.dot(a,b)

A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
np.matmul(A,B)

 

1.1.5 행렬 형상 확인

행렬곱 등 행렬 계산 시 차원의 원소 수를 일치시켜야 하기에 shape확인은 중요하다

 

 

 

 

1.2 신경망의 추론

1.2.1 신경망 추론 전체 그림

2차원 데이터를 입력하여 3차원 데이터를 출력하는 함수

O - 뉴런

→  - 연결, 가중치와 뉴런의 값을 각각 곱해 그 합이 다음 뉴런의 입력으로 쓰이도록 연결

편향(bias) - 이전 뉴런의 값에 영향받지 않는 정수

 

신경망이 수행하는 계산 수식

h - 은닉층, x - 입력값, W - 가중치, b - 편향

h - 은닉층의 뉴런은 가중치의 합으로 계산

import numpy as np
W1 = np.random.randn(2,4)
b1 = np.random.randn(4)
x = np.random.randn(10m2)
h = np.matmul(x,W1) + b1

h.shape

h

완전 연결 계층에 의한 변환은 선형 변환

비선형 효과를 부여하기 위해 활성화 함수를 사용

시그모이드 함수(0~1사이의 실수 출력)

*ISLR을 참고 바람

sigmoid 함수 구현

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

import numpy as np

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

x = np.random.randn(10,2)
W1 = np.random.randn(2,4)
b1 = np.random.randn(4)
W2 = np.random.randn(4,3)
b2 = np.random.randn(3)

h = np.matmul(x,W1) + b1
a = sigmoid(h)
s = np.matmul(a,W2) + b2

s.shape

s

x의 형태 (10,2) - 2차원 데이터 10개를 미니 배치(다수의 샘플 데이터를 한 번에 처리)로 처리하여

s의 형태 (10,3) - 각 데이터가 3차원 데이터로 변환(각 클래스에 대응하는 점수로 분류 가능)

 

1.2.2 계층으로 클래스화 및 순전파 구현

순전파(forward propagation) - 입력층에서 출력층으로 향하는 전파

                                      - 신경망을 구성하는 각 계층이 입력으로부터 출력 방향으로 처리 결과를 차례로 전파

sigmoid함수를 클래스로 구현

import numpy as np

class Sigmoid:
	def __init__(self):
    	self.params = []
    def forward(self,x):
    	return 1/(1+np.exp(-x))
        
class Affine:
	def __init__(self,W,b):
    	self.params = [W,b]
    def forward(self,x):
    	W,b = self.params
        out = np.matmul(x,W) + b
        return out

Affine - 완전 연결 계층에 의한 변환

Affine계층 - 완전 연결 계층

예 - 입력 x가 Affine계층, sigmoid계층, Affine계층을 거쳐 점수(s)를 출력

import numpy as np


class Sigmoid:
    def __init__(self):
        self.params = []

    def forward(self, x):
        return 1 / (1 + np.exp(-x))


class Affine:
    def __init__(self, W, b):
        self.params = [W, b]

    def forward(self, x):
        W, b = self.params
        out = np.dot(x, W) + b
        return out


class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size):
        I, H, O = input_size, hidden_size, output_size

        # 가중치와 편향 초기화
        W1 = np.random.randn(I, H)
        b1 = np.random.randn(H)
        W2 = np.random.randn(H, O)
        b2 = np.random.randn(O)

        # 계층 생성
        self.layers = [
            Affine(W1, b1),
            Sigmoid(),
            Affine(W2, b2)
        ]

        # 모든 가중치를 리스트에 모은다.
        self.params = []
        for layer in self.layers:
            self.params += layer.params

    def predict(self, x):
        for layer in self.layers:
            x = layer.forward(x)
        return x


x = np.random.randn(10, 2)
model = TwoLayerNet(2, 4, 3)
s = model.predict(x)
print(s)

## github ch01/forward_net.py 

__init__  - 가중치 초기화, 3개의 계층 생성

params - 학습할 가중치 매개변수들을 저장할 리스트

 

1.3 신경망의 학습

- 최적의 매개변수 값을 찾는 작업

 

1.3.1 손실 함수(loss function)

- 신경망의 성능을 나타내는 척도

- 학습 데이터(정답 데이터)와 신경망이 예측한 결과를 비교하여 예측이 얼마나 나쁜가 산출한 단일 값(스칼라)

 

교차 엔트로피 오차(Cross Entropy Error)

x - 입력 데이터, t - 정답 레이블, L - 손실

softmax - 확률 출력

Cross Entropy Error - 확률, 정답 레이블 입력

softmax 함수 

출력이 총 n개일 때, k번째의 출력 $y_{k}$ 를 구하는 계산식

$y_{k}$ - k번째 클래스에 해당하는 소프트맥스 함수의 출력

소프트맥스 함수의 분자 - $s_{k}$의 지수 함수

소프트맥스 함수의 분모 - 모든 입력 신호의 지수 함수의 총합

Cross Entropy Error

$t_{k}$ - k번째 클래스에 해당하는 정답 레이블

log는 네이피어 상수(오일러의 수) e를 밑으로 하는 로그/ 정답 레이블은 t=[0,0,1]과 같이 one-hot 벡터로 표기

원핫 벡터(one-hot vector) - 하나의 원소만 1(정답), 나머지 모두 0인 벡터

미니배치 처리를 고려한 Cross Entropy Error 식

데이터는 N개, $t_{nk}$ - 정답 레이블 

[식 1.8] - 하나의 데이터에 대한 손실 함수를 나타낸 [식 1.7]의 확장

[식 1.8]을 N개로 나누어 평균 손실 함수를 구함

# 본 게시물은 밑바닥부터 시작하는 딥러닝 2를 읽어 작성되었습니다. 

 

 

1.3.2 미분과 기울기

미분 - 조금의 변화를 극한까지 줄일 때 y값의 변화 정도

기울기(gradient) - 각 x에서의 변화의 정도/ 벡터의 각 원소에 대해 미분을 정리한 것

 

 

1.3.3 연쇄 법칙(chain rule)

오차 역전파(back-propagation) 

연쇄 법칙(chain rule) - 합성함수에 대한 미분의 법칙

(합성함수 - [정의] 함수의 합성의 도함수에 대한 공식

두 개 이상의 함수를 하나의 함수로 결합하여 만들어진 함수. 어떤 함수 속에 또 다른 함수가 들어있고,                      또 다른 함수 속에 여전히 다른 함수가 들어있는 함수

ex) y=f(x), z=g(y) 일 때 z = g(f(x)) 를 합성 합수라 한다.

- 각 함수의 국소적인 미분을 계산 가능할 때 그 값들을 곱해 전체의 미분을 구할 수 있다.

 

1.3.4 계산 그래프

계산 그래프 - 계산 과정을 시각적으로 보여주는 그래프

 

 

순전파의 계산 그래프

z = x + y라는 수식, L - 출력 값, 스칼라 값

L의 미분(기울기)을 각 변수에 대해 구한다.

역전파가 이루어지는 과정

z에 대한 미분 - ${\partial L \over \partial z}$

x에 대한 미분 - ${\partial L \over \partial x}$

y에 대한 미분 - ${\partial L \over \partial y}$

연쇄 법칙에 따라 ${\partial L \over \partial x} = {\partial L \over \partial z}{\partial z \over \partial x}$

${\partial L \over \partial y} = {\partial L \over \partial z}{\partial z \over \partial y}$

 

우항을 약분하면 - ${\partial z \over \partial x} {\partial z \over \partial y} 모두 1 $

 

곱셈 노드

z = x × y 계산 수행

${\partial z \over \partial x} = y와 {\partial z \over \partial y} = x$ 의 미분 결과를 구할 수 있다.

곱셈 노드의 역전파 - 출력 쪽에서 받은 기울기(이 예시에선 z)에 순전파의 입력을 서로 바꾼 값을 곱

입력이 x면 y를, 입력이 y면 x를 곱

 

 

분기 노드

분기 노드(복제 노드) - 단순히 선이 두 개로 나뉘도록 그린다 이때 같은 값이 복제되어 분기

 

Repeat 노드

분기 노드를 일반화한 N개의 분기 노드

 

import numpy as np
D,N = 8,7
x = np.random.randn(1,D)
y = np.repeat(x,N,axis=0)   #원소 복제, 순전파

dy = np.random.randn(N,D)
dx = np.sum(dy, axis = 0, keepdims = True) #keepdims 배열의 차원 유지 True - (1,N) False - (N,)

 

1.3.6 가중치 갱신

신경망 학습의 순서

  1. 미니 배치        - 훈련 데이터중 무작위로 데이터 선택
  2. 기울기 계산    - back propagation으로 가중치 매개변수에 대한 loss function의 gradient 구하기
  3. 매개변수 갱신 - gradient를 사용하여 가중치 매개변수 갱신
  4. 반복             - 1~3 반복

경사 하강법 - 함수의 기울기를 구하여 기울기가 낮은 쪽으로 계속 이동시켜 극값에 이를 때까지 반복하는 방법

매개변수 갱신 기법

- 확률적 경사 하강법(Stochastic Gradient Descent)

무작위로 선택된 데이터에 대한 기울기를 이용한다.

SGD의 수식

W - 갱신하는 가중치 매개변수

W에 대한 loss function의 기울기 ${\partial L \over \partial W} = y와 {\partial z \over \partial y} = x$

$n^{에타}$는 학습률(learning rate)을 나타낸다.

class SGD:
	def __init__(self,lr=0.01):
    	self.lr = lr
	
    def update(self, prams, grads):
    	for i in range(len(params)):
        	params[i] -= self.lr * grads[i]

 

 

### 본 게시물은 밑바닥부터 시작하는 딥러닝 2를 읽고 정리한 노트입니다. ###

반응형

댓글