import numpy as np
def sum_squared_error(y, t):
return 0.5 * np.sum((y - t) ** 2)
신경망 학습
deep learning
- 훈련 데이터로 학습을 해서 매개변수의 최적값을 자동으로 휙득하는 방법
- 이때 기준은 손실 함수이다.
- 그냥 정확도를 기준으로 하면 연속된 값이 안나와서 최적화가 안됨.
손실함수
오차 제곱합
- \(E = \frac{1}{2} \sum_{i=1}^{n} (y_i - t_i)^2\)
- \(y_i\): 예측값
- \(t_i\): 정답값
- \(\frac{1}{2}\)는 미분을 쉽게 하기 위해서 곱해주는 상수
교차 엔트로피
- \(E = -\sum_{i=1}^{n} t_i \log(y_i)\)
- 일반적으로 정답값인 \(t_i\)는 0 또는 1이기 때문에(one hot encoding), \(t_i = 1\)인 경우에만 계산된다.
- \(y_i\)가 1에 가까울수록 손실이 작아진다.
def cross_entropy_error(y, t):
= 1e-7 # log(0) 방지
delta return -np.sum(t * np.log(y + delta))
미니배치 학습
- 모든 데이터를 한 번에 학습하는 것이 아니라, 일부 데이터만을 사용하여 학습하는 방법
import numpy as np
from dl_dataset.mnist import load_mnist
= load_mnist(normalize=True, one_hot_label=True) (x_train, t_train), (x_test, t_test)
= x_train.shape[0]
train_size = 10
batch_size = np.random.choice(train_size, batch_size)
batch_mask = x_train[batch_mask]
x_batch = t_train[batch_mask] t_batch
def cross_entropy_error(y, t):
if y.ndim == 1:
= t.reshape(1, t.size)
t = y.reshape(1, y.size)
y = y.shape[0]
batch_size return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size
def cross_entropy_error(y, t):
if y.ndim == 1:
= t.reshape(1, t.size)
t = y.reshape(1, y.size)
y = y.shape[0]
batch_size return -np.sum(t * np.log(y + 1e-7)) / batch_size
경사법
- 기울기가 가리키는 쪽은 각 장소에서 함수의 출력 값을 가장 크게 줄이는 방향
- 기울어진 방향이 반드시 최솟값은 아니지만, 그 방향으로 가야 함수의 값을 줄일 수 있다.
import numpy as np
def numerical_gradient(f, x):
= 1e-4
h = np.zeros_like(x)
grad
for idx in range(x.size):
= x[idx]
tmp_val = tmp_val + h
x[idx] = f(x)
fxh1
= tmp_val - h
x[idx] = f(x)
fxh2
= (fxh1 - fxh2) / (2 * h)
grad[idx] = tmp_val
x[idx]
return grad
def gradient_descent(f, init_x, lr=0.01, step_num=100):
= init_x.copy()
x
for _ in range(step_num):
= numerical_gradient(f, x)
grad -= lr * grad
x return x
from dl_common.functions import softmax, cross_entropy_error
from dl_common.gradient import numerical_gradient
class simpleNet:
def __init__(self):
self.W = np.random.randn(2, 3)
def predict(self, x):
return np.dot(x, self.W)
def loss(self, x, t):
= self.predict(x)
z = softmax(z)
y return cross_entropy_error(y, t)
= simpleNet()
net = np.array([0.6, 0.9])
x = net.predict(x)
p np.argmax(p)
0
= np.array([0, 0, 1])
t net.loss(x, t)
1.5687375483483121
= lambda w: net.loss(x, t)
f
= numerical_gradient(f, net.W)
dW print(dW)
[[ 0.39309067 0.08192436 -0.47501503]
[ 0.58963601 0.12288654 -0.71252255]]
학습 알고리즘 구현
from dl_common.functions import *
from dl_common.gradient import numerical_gradient
class TwoLayerNet:
def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
self.params = {}
self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
self.params['b1'] = np.zeros(hidden_size)
self.params['W2'] = np.random.randn(hidden_size, output_size)
self.params['b2'] = np.zeros(output_size)
def predict(self, x):
= self.params['W1'], self.params['b1']
W1, b1 = self.params['W2'], self.params['b2']
W2, b2 = np.dot(x, W1) + b1
a1 = sigmoid(a1)
z1 = np.dot(z1, W2) + b2
a2 = softmax(a2)
y return y
def loss(self, x, t):
= self.predict(x)
y return cross_entropy_error(y, t)
def accuracy(self, x, t):
= self.predict(x)
y if t.ndim != 1: # one-hot encoding
= np.argmax(t, axis=1)
t return np.sum(np.argmax(y, axis=1) == t) / float(x.shape[0])
def numerical_gradient(self, x, t):
= lambda w: self.loss(x, t)
loss_w = {}
grads 'W1'] = numerical_gradient(loss_w, self.params['W1'])
grads['b1'] = numerical_gradient(loss_w, self.params['b1'])
grads['W2'] = numerical_gradient(loss_w, self.params['W2'])
grads['b2'] = numerical_gradient(loss_w, self.params['b2'])
grads[return grads
from dl_dataset.mnist import load_mnist
= load_mnist(normalize=True, one_hot_label=True)
(x_train, t_train), (x_test, t_test)
= []
train_loss_list = []
train_acc_list = []
test_acc_list
= 10000
iters_num = x_train.shape[0]
train_size = 100
batch_size = 0.1
learning_rate = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
network = max(train_size / batch_size, 1)
iter_per_epoch
for i in range(iters_num):
= np.random.choice(train_size, batch_size)
batch_mask = x_train[batch_mask]
x_batch = t_train[batch_mask]
t_batch = network.numerical_gradient(x_batch, t_batch)
grads for key in ('W1', 'b1', 'W2', 'b2'):
-= learning_rate * grads[key]
network.params[key] = network.loss(x_batch, t_batch)
loss
train_loss_list.append(loss)
if i % iter_per_epoch == 0:
= network.accuracy(x_train, t_train)
train_acc = network.accuracy(x_test, t_test)
test_acc
train_acc_list.append(train_acc) test_acc_list.append(test_acc)