Deep Learning day 2


ニューラルネットワーク学習

  • クロスエントロピー
  • from IPython.display import Image
    import numpy as np
    import matplotlib.pyplot as plt
    Image("e 4.2.png", width=200)
    def cross_entropy_error(y ,t ):
        delta = 1e-7
        return -np.sum(t* np.log(y + delta))
    t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
    y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
    
    cross_entropy_error(np.array(y), np.array(t))
    0.510825457099338
    t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
    y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
    
    cross_entropy_error(np.array(y), np.array(t))
    2.302584092994546
    Image("e 4.3.png", width=300)
    def cross_entropy_error(y ,t ):
        delta = 1e-7
        if y.ndim == 1:
            t = t.reshape(1, t.size)
            y = y.reshape(1, y.size)
        
        batch_size = y.shape[0]
        return -np.sum(t* np.log(y + delta))/ batch_size
    t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
    y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
    
    cross_entropy_error(np.array(y), np.array(t))
    0.510825457099338
  • 微粉
  • Image("e 4.5.png", width=200)
    def function_1(x):
        return 0.01*x**2 + 0.1*x
    x = np.arange(0.0, 20.0, 0.1)
    y = function_1(x)
    plt.xlabel("x")
    plt.ylabel("f(x)")
    plt.plot(x, y)
    [<matplotlib.lines.Line2D at 0x2ad385e8be0>]
  • 中央差分数値微分
  • def numerical_diff(f, x):
        h = 1e-4
        return (f(x+h) - f(x-h)) / (2*h)
    x = np.arange(0.0, 20.0, 0.1)
    y = function_1(x)
    
    a = numerical_diff(function_1, 5)
    b = function_1(5) - (a*5)
    y2 = (a * x) + b
    
    plt.xlabel("x")
    plt.ylabel("f(x)")
    plt.plot(x, y)
    plt.plot(x, y2)
    [<matplotlib.lines.Line2D at 0x2ad38af1940>]
  • グラデーション(偏微分ベクトル)
  • def numerical_graient(f, x):
        h = 1e-4
        grad = np.zeros_like(x)
        
        for idx in range(x.size):
            tmp_val = x[idx]
            x[idx] = tmp_val + h
            fxh1 = f(x)  #f(x+h)        
            
            x[idx] = tmp_val - h
            fxh2 = f(x)  #f(x-h)
            
            grad[idx] = (fxh1 - fxh2)/(2*h)
            x[idx] = tmp_val # 값 복원
        
        return grad
    Image("e 4.6.png", width=200)
    def function_2(x):
        return x[0]**2 + x[1]**2
    numerical_graient(function_2, np.array([3.0, 4.0]))
    array([6., 8.])
  • 傾斜降下法
  • Image("e 4.7.png", width=150)
    def gradient_descent(f, init_x, lr=0.01, step_num=100):
        x = init_x
        
        for i in range(step_num):
            grad = numerical_graient(f, x)
            x = x - (lr*grad)
            #print(x) 
        return x
    init_x = np.array([-3.0, 4.0])
    gradient_descent(function_2, init_x = init_x, lr=0.1, step_num =100)
    array([-6.11110793e-10,  8.14814391e-10])
  • ニューラルネットワークにおける傾斜
  • def numerical_gradient(f, x):
        h = 1e-4 # 0.0001
        grad = np.zeros_like(x)
        
        it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
        while not it.finished:
            idx = it.multi_index
            tmp_val = x[idx]
            x[idx] = float(tmp_val) + h
            fxh1 = f(x) # f(x+h)
            
            x[idx] = tmp_val - h 
            fxh2 = f(x) # f(x-h)
            grad[idx] = (fxh1 - fxh2) / (2*h)
            
            x[idx] = tmp_val # 값 복원
            it.iternext()   
            
        return grad
    def softmax(a):
        c = np.max(a)
        exp_a = np.exp(a-c)
        sum_exp_a = np.sum(exp_a)
        y  = exp_a / sum_exp_a
        
        return y
    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):
            z = self.predict(x)
            y = softmax(z)
            loss = cross_entropy_error(y, t)
            return loss
    x = np.array([0.6, 0.9])
    t = np.array([0, 0, 1])
    
    net = simpleNet()
    f = lambda w: net.loss(x, t)
    dw = numerical_gradient(f, net.W)
    net.W # 랜덤하게 임의로 설정한 가중치
    array([[-0.48115741,  0.54270006, -0.80327648],
           [-0.41143265, -0.67968633, -0.94115196]])
    dw # 기울기 벡터
    array([[ 0.20245512,  0.29394845, -0.49640358],
           [ 0.30368269,  0.44092268, -0.74460537]])