일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 역전파
- 자전거 여행
- 신경망
- 소수
- project euler
- 전처리
- A Neural Algorithm of Artistic Style
- Autoencoder
- 합성곱 신경망
- mnist
- bayesian
- 오토인코더
- CNN
- Python
- neural network
- 수달
- backpropagation
- 딥러닝
- 역전파법
- c#
- Convolutional Neural Network
- deep learning
- 냥코 센세
- SQL
- 히토요시
- 소인수분해
- 베이지안
- 비샤몬당
- Gram matrix
- 오일러 프로젝트
- Today
- Total
통계, IT, AI
딥러닝: 화풍을 모방하기 (6) - 연습: 다클래스 분류 문제 본문
1. 개요
- 입력이 4개이며 출력은 3가지 클래스를 갖는 경우를 생각해보자. 신경망은 그림 1과 같다.
그림 1. 3개 클래스의 출력을 갖는 단층 신경망
- 입력과 파라미터를 아래와 같이 정의한다.
$$\begin{eqnarray} x_n&=& \begin{bmatrix}x_{n1} & x_{n2} & x_{n3}& x_{n4} \end{bmatrix}, \quad w=\begin{bmatrix}w_{11} & w_{21} & w_{31} \\ w_{12} & w_{22} & w_{32} \\ w_{13} & w_{23} & w_{33} \\ w_{14} & w_{24} & w_{34} \end{bmatrix}, \quad b=\begin{bmatrix}b_{1} & b_{2} & b_{3} \end{bmatrix} \\ \\ u&=&\begin{bmatrix} u_1 & u_2 & u_3\end{bmatrix} = x_nw+b \\ \\&=& \begin{bmatrix} \sum_{i=1}^{4}w_{1i}x_{ni} + b_1 & \sum_{i=1}^{4}w_{2i}x_{ni} + b_2 & \sum_{i=1}^{4}w_{2i}x_{ni} + b_2\end{bmatrix} \end{eqnarray}$$
-출력의 활성화 함수로 softmax 함수를 사용한다.
$$\begin{eqnarray} z&=&\begin{bmatrix} z_1 & z_2 & z_3 \end{bmatrix} = f \left(\begin{bmatrix} u_1 & u_2 & u_3\end{bmatrix}\right) \\ \\ &=& \begin{bmatrix} \frac{exp(u_1)}{\sum_{k=1}^{K}exp(u_k)}& \frac{exp(u_2)}{\sum_{k=1}^{K}exp(u_k)}&\frac{exp(u_3)}{\sum_{k=1}^{K}exp(u_k)} \end{bmatrix}\end{eqnarray}$$
-오차함수로 교차엔트로피를 사용하자. \(n\)번째 자료에 대한 오차는 다음과 같다. 단, \(d_{nk}\)는 \(n\)번째 입력의 클래스가 \(k\)이면 1 그렇지 않으면 0의 값을 갖는다.
$$E_n(\boldsymbol{w})=-\sum_{k=1}^{K}d_{nk}log\left\{ y_k(x_n;\boldsymbol{w})\right\}$$
- \(w_{ji}\)에 대한 미분이 아래와 같다. 간결성을 위하여 \(y_k(x_n;\boldsymbol{w})\)는 \(y_k\)로 표기한다.
$$\begin{eqnarray}\frac{\partial E_n(\boldsymbol{w})}{\partial w_{ji}}&=&-\sum_{k=1}^{K}\frac{d_{nk}}{y_k}\frac{\partial y_k}{\partial w_{ji}} \\&=&-\frac{d_{nj}}{y_j}\frac{\partial y_j}{\partial w_{ji}}-\sum_{k\neq j}\frac{d_{nk}}{y_k}\frac{\partial y_k}{\partial w_{ji}} \\&=&-d_{nj}(1-y_j)x_{ni}+\sum_{k\neq j} d_{nk} y_jx_{ni} \\&=&(y_j-d_{nj})x_{ni} \end{eqnarray}$$
- 따라서 오차함수의 파라미터에 대한 미분을 다음과 같이 정의한다.
$$\begin{eqnarray} \frac{\partial E_n(\boldsymbol{w})}{\partial \boldsymbol{w}}&=& \left[ \frac{\partial E_n(\boldsymbol{w})}{\partial w_{ji}}\right]_{j,i} =\left[ (y_j-d_{nj})x_{ni}\right]_{j,i} \\ \frac{\partial E_n(\boldsymbol{w})}{\partial \boldsymbol{b}}&=& \left[ \frac{\partial E_n(\boldsymbol{w})}{\partial b_{j}}\right]_{j} =\left[ y_j-d_{nj}\right]_{j} \end{eqnarray}$$
- 데이터는 Iris dataset을 사용한다. Iris dataset은 피셔가 제시한 다변수자료로 독립변수는 꽃받침의 길이, 꽃받침의 너비, 꽃잎의 길이 그리고 꽃잎의 너비이다. 종속변수는 꽃의 종류로 총 3가지로 분류가 있다. 자료의 수는 150개이며 해당 자료를 첨부한다.iris.csv
- 미니배치의 크기는 30, 반복횟수는 20000 그리고 \(\epsilon=0.001\)으로 한다. 테스트 데이터는 임의로 30개를 선정한다. 최종 결과에서 클래스 결정을 위한 threshold로 0.5를 사용한다.
2. 구현
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import csv import datetime as dt """ GENERAL SETTING """ np.random.seed(0) enable_visualization = True """ DATA """ with open('iris.csv', 'r') as f: dat = [row for row in csv.reader(f.readlines())] print('COLUMN: ', dat.pop(0)) temp_x, temp_d = [], [] for row in dat: temp_d.append(row.pop()) temp_x.append(row) X = np.asmatrix(temp_x, dtype=float) N, p = X.shape levels = list(set(temp_d)) K = len(levels) d = np.zeros((N, K), dtype=float) for row_num, level in enumerate(temp_d): d[row_num,levels.index(level)] = 1.0 print('N: ', N, ', p: ', p, ', K: ', K) """ FUNCTION """ def activate(u_list): exp_u = np.exp(u_list) return np.diag((1/np.sum(exp_u, axis=1)).A1).dot(exp_u) def feedforward(X, w, b, activate_function=activate): X_ = np.column_stack((np.zeros(X.shape[0], dtype=float), X)) w_ = np.vstack((b, w)) return activate_function(X_.dot(w_)) def error(X, w, b, d, feedforward_function=feedforward): return -np.sum(np.multiply(d, np.log(feedforward_function(X, w, b)))) """ PARAMETER & OPTIMIZATION SETTING """ w = np.zeros((p, K), dtype=float) b = np.zeros((1, K), dtype=float) epsilon = 0.001 batch_size = 30 epoch_size = 20000 index_list = np.arange(N) np.random.shuffle(index_list) test_x = X[index_list[0:30],] test_d = d[index_list[0:30],] error_history = [error(test_x, w, b, test_d)] """ OPTIMIZATION """ for epoch in range(epoch_size): np.random.shuffle(index_list) if epoch % 5000 == 0: print('epoch: ', epoch, ', ', dt.datetime.now()) for i in range(N//batch_size): selected_index_list = index_list[(i*batch_size):((i+1)*batch_size)] training_x, training_d = X[selected_index_list,], d[selected_index_list,] # Caculate nabla E der_w = training_x.T.dot(feedforward(training_x, w, b) - training_d)/batch_size der_b = np.mean(feedforward(training_x, w, b), axis=0) w -= epsilon * der_w b -= epsilon * der_b error_history.append(error(test_x, w, b, test_d)) """ RESULT """ print('w: ', w) print('b: ', b) if enable_visualization: plt.plot(error_history) plt.show() result = np.asmatrix(feedforward(X, w, b) > 0.5, dtype=float) error_rate = np.sum(np.array(result != d, dtype=int))//2.0 / N print(error_rate)
3. 결과
- 전체 데이터에 대한 오분류율은 약 3%이며, 테스트 오차의 경향은 그림 2와 같다.
그림 2. 테스트 오차의 경향
- 속도에 대한 이슈가 있다. 총 연산에 약 16초가 걸리는데 생각보다 느리다. 텐서플로우 사용을 고려하자.
- 지금까지는 파라미터의 초기값으로 0을 주었다. 하지만 언젠가 이 부분에 이슈가 있을 것이다.
- 학습률 \(\epsilon\)에 대한 조정 및 여러가지 규제화 또한 실습할 기회를 만들어보자.
- http://neuralnetworksanddeeplearning.com/에서 다음과 같은 내용을 보았다. 즉, classification을 진행할 때 출력층의 노드의 수가 왜 class의 수와 같아야 하는 것이다. 위의 예에서, 구분하고자 하는 꽃의 종류는 3가지이므로 이진수의 두개의 노드로도 충분하다. 첫번째 꽃은 \((0,0)\), 두번째 꽃은 \((0,1)\) 그리고 세번째 꽃은 \((1,0)\)으로 말이다.
- 하지만 이 방법은 성과가 그다지 좋지 않다. 왜냐하면 출력층의 각 원소가 무엇을 의미하는지 확실하지 않기 때문이다. 다른 예를 들면, 0부터 9까지의 숫자의 이미지가 있을 때 이를 분류하는 문제를 생각해보자. 이 경우 \(9=(1,0,0,1)\)이므로 출력층의 노드의 수는 4개면 충분하다. 하지만 출력층의 노드의 각 원소가 의미하는 것은 무엇인가? 마지막 원소가 0이면 짝수, 1이면 홀수지만 그것과 이미지와는 아무런 연관성이 없다. 따라서 출력층의 노드의 수는 일반적으로 class의 수와 같게 하는 것이 좋다.
- 또한, 어째서 classfication의 에러 함수로 "오분류의 개수"로 하지 않는지에 대하여 보았다. 저자는 이에 대하여 신경망이 학습을 거듭해 가면서 개선되는 것을 연속형으로 나타내어 이전 학습과 비교하기 위함이라고 설명하였다.
'머신러닝' 카테고리의 다른 글
딥러닝: 화풍을 모방하기 (8) - 연습: 역전파법 (0) | 2017.03.01 |
---|---|
딥러닝: 화풍을 모방하기 (7) - 책 요약: 4. 역전파법 (0) | 2017.02.16 |
딥러닝: 화풍을 모방하기 (5) - 연습: 이진 분류 문제 (0) | 2017.02.01 |
딥러닝: 화풍을 모방하기 (4) - 연습: 회귀 문제 (0) | 2017.01.30 |
딥러닝: 화풍을 모방하기 (3) - 책 요약: 3. 확률적 경사 하강법 (1) | 2017.01.30 |