無Optimizerの傾斜降下法による直線回帰


今回は最適化関数を用いず,直接符号化により実現する.

▶ Theoretical Overview



bはまず0と省略する.
  • H(x):与えられたx値を予測する方法
  • コスト(W):H(x)のyに対する予測がどれほど良いか
    Note that it is simplified, without the bias b added to H(x).
  • ▶ Imports

    # 시각화용 라이브러리
    import matplotlib.pyplot as plt
    
    import numpy as np
    import torch
    import torch.optim as optim
    
    # For reproducibility
    torch.manual_seed(1)
    matplotlib.pyplotビジュアル化用のライブラリ.

    ▶ Data

    x_train = torch.FloatTensor([[1], [2], [3]])
    y_train = torch.FloatTensor([[1], [2], [3]])
    
    # Data
    plt.scatter(x_train, y_train)
    # Best-fit line
    xs = np.linspace(1, 3, 1000)
    plt.plot(xs, xs)

    以前の実験と同様に,x trainとy trainが付与され,pltというライブラリ内の分散関数を用いて出力される.numpyの「線空間」(Linear Space)関数により、1から3までの1000等分操作を含み、2 D図を描くplot関数でx軸y軸をパラメータ値として設定します.

    ▶ Cost by W


    実際のコストの計算を直感的に理解するために、次のコードを作成しました.
    # -5 ~ 7 사이를 1000등분해서 w_l
    # list <= 순차적으로 데이터를 담는 추상자료형
    
    # w_list
    W_l = np.linspace(-5, 7, 1000)
    # cost list
    cost_l = []
    for W in W_l:
        hypothesis = W * x_train
        cost = torch.mean((hypothesis - y_train) ** 2)
    
        cost_l.append(cost.item())
        
        
    plt.plot(W_l, cost_l)
    plt.xlabel('$W$')
    plt.ylabel('Cost')
    plt.show()
    また,滴下はnumpyのリンク空間としてWlに5から7までの1000等分値を含む.次に、原価値を含む原価リストを宣言し、原価値を計算する重複文を続行します.これらのコストとW値を2 Dグラフィックを表すplot関数に設定し、x軸y軸に出力します.

    x軸とy軸のラベル、すなわち命名されたplt.正式な図面ではなく、内部でデータを回転させるにはshow()を行わなければなりません.

    ▶ Gradient Descent by Hand



    cost偏微分をWとし,これを勾配変数に代入してWを0に初期化し,上記式の実施を試みる.
    W = 0
    
    # 2/m은 생략 가능
    gradient = torch.sum((W * x_train - y_train) * x_train)
    print(gradient)

    出力時にはW単位の勾配値を求めることができる.
    私たちは今コスト値を知っているので、以下のW値を知ることができます.

    現在のW-lr*コストのWの偏微分値として更新するWをコード実装すると、
    lr = 0.1
    # w = w - lr*gradient
    W -= lr * gradient
    print(W)

    これにより,Wを0に更新したWは1.4となり,直接コードでGradient Descentを実現した.

    ▶ Training

    # 데이터
    x_train = torch.FloatTensor([[1], [2], [3]])
    y_train = torch.FloatTensor([[1], [2], [3]])
    # 모델 초기화
    W = torch.zeros(1)
    # learning rate 설정
    lr = 0.1
    
    nb_epochs = 10
    for epoch in range(nb_epochs + 1):
        
        # H(x) 계산
        hypothesis = x_train * W
        
        # cost gradient 계산
        cost = torch.mean((hypothesis - y_train) ** 2)
        gradient = torch.sum((W * x_train - y_train) * x_train)
    
        print('Epoch {:4d}/{} W: {:.3f}, Cost: {:.6f}'.format(
            epoch, nb_epochs, W.item(), cost.item()
        ))
    
        # cost gradient로 H(x) 개선
        W -= lr * gradient

    この直接実装されたGradient Descentアルゴリズムは、コストを削減し続け、Wを1に収束させることができる.