深度学習開発フレームワークPyTorch(3)--Autograd

3235 ワード

PyTorchとPython,Numpyなどの最大の違いは,ニューラルネットワーク訓練中の勾配計算のために特別に設計された自動導出機構にある.PyTorchでは、Autogradはすべてのニューラルネットワークのコアコンテンツであり、Tensorのすべての操作に自動導出方法を提供する.Autogradメカニズムの強さを理解するために、次の例を適用します.
手動で線形回帰を実現
線形回帰は機械学習の入門知識であり,応用は非常に広範である.線形回帰は数理統計における回帰解析を適用して,y=wx+b+eの表現形式を持つ2つ以上の変数間の相互依存の定量的関係を決定し,誤差eは平均値0の正規分布に従う.ランダム勾配降下法を用いてパラメータwとbを更新して損失関数を最小化し,最終的にwとbの数値を学んだ.
import torch as t
import torch.optim as optim
import matplotlib.pyplot as plt

#########################################################
#        
#########################################################

def get_fake_data(batch_size=8):
    '''
          :  y=x*2+3 '''
    x = t.randn(batch_size, 1) * 20
    y = x * 2 + 3
    return x, y

#   x,y  
x, y = get_fake_data()

#      
# plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())
# plt.show()

#########################################################
#     
#########################################################

#        
w = t.rand(1, 1)
b = t.zeros(1, 1)
#    
lr = 0.001
#        
batch_size = 8

for i in range(1000):
    # forward  
    y_pred = x.mm(w) + b.expand_as(y)
    error = y_pred - y

    #          
    loss = error ** 2 / batch_size #     
    loss = loss.sum()
    print('loss is ', loss.numpy())

    if loss < 0.01:
        print(w.squeeze().numpy(), b.squeeze().numpy()) 
        break

    # backward  
    dw = x.t().mm(error) / batch_size
    db = error.sum()

#      
# plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())
# plt.plot(x.squeeze().numpy(), (w*x + b).squeeze().numpy())
# plt.show()

Autogradによる線形回帰
Autogradで実現される線形回帰の最大の違いは,Autogradを用いて勾配を手動で計算する必要がなく,自動的に微分できることである.パラメータを更新した後、勾配をゼロにすることを忘れないでください.
import torch as t
import torch.optim as optim
import matplotlib.pyplot as plt

#########################################################
#        
#########################################################

def get_fake_data(batch_size=8):
    '''
          :  y=x*2+3 '''
    x = t.randn(batch_size, 1) * 20
    y = x * 2 + 3
    return x, y

#   x,y  
x, y = get_fake_data()

#      
# plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())
# plt.show()

#########################################################
#     
#########################################################

#        
w = t.rand(1, 1, requires_grad=True)
b = t.zeros(1, 1, requires_grad=True)
#    
lr = 0.001
#        
batch_size = 8

for i in range(3000):
    # forward  
    y_pred = x.mm(w) + b.expand_as(y)
    error = y_pred - y

    #          
    loss = error ** 2 / batch_size #     
    loss = loss.sum()
    print('loss is ', loss.item())

    if loss.item() < 0.05:
        print(w.item(), b.item()) 
        break

    # backward  (      )
    loss.backward()

    #     
    w.requires_grad = False
    b.requires_grad = False
    w.sub_(lr * w.grad.data)
    b.sub_(lr * b.grad.data)
    w.requires_grad = True
    b.requires_grad = True

    #     
    w.grad.data.zero_()
    b.grad.data.zero_()

#      
# plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())
# plt.plot(x.squeeze().numpy(), (w.item()*x + b.item()).squeeze().numpy())
# plt.show()