[PyTorch] Lab03 - Deeper Look at GD


📌 学習目標

  • データ確認
  • Cost機能
  • について
  • Gradient Descrent理論
  • Gradient Descrent実施
  • データ定義


    サンプルデータを使用して、学習時間(x)のスコア(y)を指定します.
    簡単にinput=outputと定義します.
    これをtorch.tensorとして以下に示す.
    # Data
    x_train = torch.FloatTensor([[1], [2], [3]])
    y_train = torch.FloatTensor([[1], [2], [3]])
    最良のモデル(Hypothesis)はH(x)=xH(x)=xH(x)=xである.

    Cost機能について


    モデルの良し悪しを評価するために,コスト関数を用いた.
    リニア回帰なのでMSEを使います.
    現在のデータでは,W=1が最良のモデルであるため,W=1の場合cost関数は0である.

    Gradient Descent理論


    Gradient Descentはコスト関数の曲線に沿って下がっています.
    つまり、微斜度で移動します.
    これを下記のように数式で表します.
    cost(W)=1m∑i=1m(Wx(i)−y(i))2cost(W) =\frac{1}{m}\sum_{i=1}^{m}(Wx^{(i)}-y^{(i)})^2cost(W)=m1​∑i=1m​(Wx(i)−y(i))2
    ∇W=∂cost∂W=2m∑i=1m(Wx(i)−y(i))x(i)\nabla{W} =\frac{\partial{cost}}{\partial{W}} =\frac{2}{m}\sum_{i=1}^{m}(Wx^{(i)}-y^{(i)})x^{(i)}∇W=∂W∂cost​=m2​∑i=1m​(Wx(i)−y(i))x(i)
    W:=W−a∇WW := W - a\nabla{W}W:=W−a∇W

    Gradient Descent実装


    コード全体を以下に示します.
    import torch
    
    x_train = torch.FloatTensor([[1], [2], [3]])
    y_train = torch.FloatTensor([[1], [2], [3]])
    
    W = torch.zeros(1)
    
    epochs = 10
    lr = 0.1
    
    for epoch in range(1, epochs+1, 1):
        hypothesis = x_train*W
        
        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, epochs, W.item(), cost.item()
        ))
        
        W -= lr * gradient
    
    '''
    Epoch    1/10 W: 0.000, Cost: 4.666667
    Epoch    2/10 W: 1.400, Cost: 0.746666
    Epoch    3/10 W: 0.840, Cost: 0.119467
    Epoch    4/10 W: 1.064, Cost: 0.019115
    Epoch    5/10 W: 0.974, Cost: 0.003058
    Epoch    6/10 W: 1.010, Cost: 0.000489
    Epoch    7/10 W: 0.996, Cost: 0.000078
    Epoch    8/10 W: 1.002, Cost: 0.000013
    Epoch    9/10 W: 0.999, Cost: 0.000002
    Epoch   10/10 W: 1.000, Cost: 0.000000
    '''
    勾配を直接求めて更新することができるが、Torchはtorch.optimをサポートする.
    import torch
    
    x_train = torch.FloatTensor([[1], [2], [3]])
    y_train = torch.FloatTensor([[1], [2], [3]])
    
    W = torch.zeros(1, requires_grad=True)
    #optimizer 설정
    optimizer = torch.optim.SGD([W], lr=0.15 )
    
    epochs = 10
    
    for epoch in range(1, epochs+1, 1):
        hypothesis = x_train*W
        
        cost = torch.mean((hypothesis - y_train) ** 2)
        
        
        print('Epoch {:4d}/{} W: {:.3f}, Cost: {:.6f}'.format(
            epoch, epochs, W.item(), cost.item()
        ))
        
    		# 갱신 과정
        optimizer.zero_grad()
        cost.backward()
        optimizer.step()
    
    '''
    Epoch    1/10 W: 0.000, Cost: 4.666667
    Epoch    2/10 W: 1.400, Cost: 0.746667
    Epoch    3/10 W: 0.840, Cost: 0.119467
    Epoch    4/10 W: 1.064, Cost: 0.019115
    Epoch    5/10 W: 0.974, Cost: 0.003058
    Epoch    6/10 W: 1.010, Cost: 0.000489
    Epoch    7/10 W: 0.996, Cost: 0.000078
    Epoch    8/10 W: 1.002, Cost: 0.000013
    Epoch    9/10 W: 0.999, Cost: 0.000002
    Epoch   10/10 W: 1.000, Cost: 0.000000
    '''