ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 3. 신경망 학습(7)
    AI 모델(딥러닝 기초)/3. 신경망 학습 2023. 1. 15. 11:45
    728x90

    ※ 미니배치 학습 구현

    신경망 학습(6)을 통해 구현해 둔 TwoLayerNet class를 사용하여 MNIST 데이터셋을 미니배치로 구현해 보자.

     

    import numpy as np
    from dataset.mnist import load_mnist
    from two_layer_net import TwoLayerNet
    import matplotlib.pylab as plt
    
    # 데이터 읽기
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
    
    network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
    
    # 하이퍼파라미터
    iters_num = 10000  # 반복 횟수를 적절히 설정한다.
    train_size = x_train.shape[0]
    batch_size = 100   # 미니배치 크기
    learning_rate = 0.1
    
    train_loss_list = []
    train_acc_list = []
    test_acc_list = []
    
    # 1에폭당 반복 수
    iter_per_epoch = max(train_size / batch_size, 1)
    
    for i in range(iters_num):
        # 미니배치 획득
        batch_mask = np.random.choice(train_size, batch_size)
        x_batch = x_train[batch_mask]
        t_batch = t_train[batch_mask]
        
        # 기울기 계산
        #grad = network.numerical_gradient(x_batch, t_batch)
        grad = network.gradient(x_batch, t_batch)
        
        # 매개변수 갱신
        for key in ('W1', 'b1', 'W2', 'b2'):
            network.params[key] -= learning_rate * grad[key]
        
        # 학습 경과 기록
        loss = network.loss(x_batch, t_batch)
        train_loss_list.append(loss)
        
    x = np.arange(len(train_loss_list))
    plt.plot(x, train_loss_list, label='train loss')
    plt.xlabel("iteration")
    plt.ylabel("loss")
    plt.show()

     

    반복횟수를 10000번 그리고 미니배치를 100, 학습률은 0.1로 설정하였다. 10000번을 반복하면서 미니배치를 획득 -> 기울기 계산 -> 매개변수 갱신 -> 학습 경과 기록을 반복적으로 수행하였다.

     

    train_loss_list에 구해진 loss 값을 담아 손실 함수의 반복 추이를 뽑아내보았다.

     

    이와 같은 10000번 동안의 손실함수 그래프가 그려지는 것을 확인할 수 있다. 이를 통해 학습 횟수가 늘어날 수록 손실 함수의 값은 줄어드는 것을 확인했다. 손실함수가 최솟값이 되는 것이 최적의 상태이므로 손실 함수가 줄어드는 것을 통해 학습이 잘 되고 있다는 것을 확인해 볼 수 있다. 또한, 신경망의 가중치 매개변수가 데이터에 서서히 적응해 나가고 있다는 것을 확인할 수 있다. 미니배치를 통한 경사하강법을 구현하여 MNIST 데이터셋이 서서히 우리가 구현한 신경망에 적응해 나가고 있는 것을 확인해 볼 수 있다.

     

     

     

    ※ 데이터 평가

    # 데이터 읽기
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
    
    network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
    
    # 하이퍼파라미터
    iters_num = 10000  # 반복 횟수를 적절히 설정한다.
    train_size = x_train.shape[0]
    batch_size = 100   # 미니배치 크기
    learning_rate = 0.1
    
    train_loss_list = []
    train_acc_list = []
    test_acc_list = []
    
    # 1에폭당 반복 수
    iter_per_epoch = max(train_size / batch_size, 1)
    
    for i in range(iters_num):
        # 미니배치 획득
        batch_mask = np.random.choice(train_size, batch_size)
        x_batch = x_train[batch_mask]
        t_batch = t_train[batch_mask]
        
        # 기울기 계산
        #grad = network.numerical_gradient(x_batch, t_batch)
        grad = network.gradient(x_batch, t_batch)
        
        # 매개변수 갱신
        for key in ('W1', 'b1', 'W2', 'b2'):
            network.params[key] -= learning_rate * grad[key]
        
        # 학습 경과 기록
        loss = network.loss(x_batch, t_batch)
        train_loss_list.append(loss)
    
        # 1에폭당 정확도 계산
        if i % iter_per_epoch == 0:
            train_acc = network.accuracy(x_train, t_train)
            test_acc = network.accuracy(x_test, t_test)
            train_acc_list.append(train_acc)
            test_acc_list.append(test_acc)
            print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))
    
    # 그래프 그리기
    markers = {'train': 'o', 'test': 's'}
    x = np.arange(len(train_acc_list))
    plt.plot(x, train_acc_list, label='train acc')
    plt.plot(x, test_acc_list, label='test acc', linestyle='--')
    plt.xlabel("epochs")
    plt.ylabel("accuracy")
    plt.ylim(0, 1.0)
    plt.legend(loc='lower right')
    plt.show()

     

    위의 코드를 살짝 개선하여 epoch 당 데이터를 평가해보았다.

    ■ 1epoch : 우리는 10000개의 데이터를 100개의 미니배치로 학습했으므로 1epoch은 100회가 된다. 확률적 경사 하강법을 100회 반복하여 모든 훈련 데이터를 소진한 셈이다.

    1epoch 당 정확도를 계산하고 train데이터와 test데이터를 기록하면서 정확도를 기록해 보았다. 1epoch 마다 구현시킴으로써 for문으로 할 반복작업을 줄여준 셈이다. epoch 작업이 없다면 신경망을 running 할 때 어마어마한 시간이 필요할지도 모른다.

     

    train acc, test acc | 0.09736666666666667, 0.0982
    train acc, test acc | 0.7849, 0.7908
    train acc, test acc | 0.87945, 0.8834
    train acc, test acc | 0.8987166666666667, 0.9017
    train acc, test acc | 0.9082833333333333, 0.9098
    train acc, test acc | 0.9144, 0.9168
    train acc, test acc | 0.91995, 0.9209
    train acc, test acc | 0.9242, 0.9247
    train acc, test acc | 0.9272666666666667, 0.9287
    train acc, test acc | 0.9313666666666667, 0.9316
    train acc, test acc | 0.9344166666666667, 0.934
    train acc, test acc | 0.9364833333333333, 0.9378
    train acc, test acc | 0.9395166666666667, 0.9387
    train acc, test acc | 0.9414166666666667, 0.9416
    train acc, test acc | 0.9431, 0.9436
    train acc, test acc | 0.9456333333333333, 0.9453
    train acc, test acc | 0.9474166666666667, 0.9459
    

     

    해당 그래프 처럼 정확도가 epoch이 지날수록 증가하는 것을 확인할 수 있다. 위에서 손실 함수값이 작아지는 것과 반대로 해당 그래프처럼 점점 정확도가 높아지는 것까지 확인된다면 해당 신경망 학습이 제대로 이루어졌다고 판단할 수 있다. 또한, train acc와 test acc가 겹쳐서 하나의 그래프 처럼 나타나는 위 상황이 오버피팅이 나타나지 않은 정상적으로 신경망이 제대로 구현 된 상태이다.

    훈련데이터 평가는 오버피팅을 일으키지 않는지를 확인하는 작업이다. 훈련 데이터에 포함된 이미지만 제대로 인식하고 그렇지 않은 이미지는 식별할 수 없다면 신경망 학습의 의미가 없다. 범용적인 능력을 익히고 훈련 데이터에 포함되지 않는 객관적인 데이터까지도 식별할 수 있도록 구현하는 것이 신경망 학습의 진정한 의미이다. 주기적인 평가 작업이 필요하다.

     

     

     

    728x90

    'AI 모델(딥러닝 기초) > 3. 신경망 학습' 카테고리의 다른 글

    3. 신경망 학습(6)  (0) 2023.01.15
    3. 신경망 학습(5)  (0) 2023.01.10
    3. 신경망 학습(4)  (0) 2023.01.09
    3. 신경망 학습(3)  (0) 2023.01.07
    3. 신경망 학습(2)  (0) 2023.01.07
Designed by Tistory.