1. 程式人生 > >[PyTorch小試牛刀]實戰一·使用PyTorch擬合曲線(對比PyTorch與TensorFlow實現的區別)

[PyTorch小試牛刀]實戰一·使用PyTorch擬合曲線(對比PyTorch與TensorFlow實現的區別)

[PyTorch小試牛刀]實戰一·使用PyTorch擬合曲線

深度學習入門的部落格中,我們用TensorFlow進行了擬合曲線,到達了不錯的效果。
我們現在使用PyTorch進行相同的曲線擬合,進而來比較一下TensorFlow與PyTorch的異同。
搭建神經網路進行訓練的步驟基本相同,我們現在開始用PyTorch來實現。

  • 問題描述
    擬合y= x*x -2x +3 + 0.1(-1到1的隨機值) 曲線
    給定x範圍(0,3)

  • 問題分析
    直線擬合部落格中,我們使用最簡單的y=wx+b的模型成功擬合了一條直線,現在我們在進一步進行曲線的擬合。簡單的y=wx+b模型已經無法滿足我們的需求,需要利用更多的神經元來解決問題了。

  • 生成資料

import numpy as np
import matplotlib.pyplot as plt
import torch as t
from torch.autograd import Variable as var

def get_data(x,w,b,d):
    c,r = x.shape
    y = (w * x * x + b*x + d)+ (0.1*(2*np.random.rand(c,r)-1))
    return(y)

xs = np.arange(0,3,0.01).reshape(-1,1)
ys = get_data(xs,
1,-2,3) xs = var(t.Tensor(xs)) ys = var(t.Tensor(ys))

生成的資料影象為:
在這裡插入圖片描述

  • 搭建網路結構
class Fit_model(t.nn.Module):
    def __init__(self):
        super(Fit_model,self).__init__()
        self.linear1 = t.nn.Linear(1,16)
        self.relu = t.nn.ReLU()
        self.linear2 = t.nn.Linear(16,1)

        self.
criterion = t.nn.MSELoss() self.opt = t.optim.SGD(self.parameters(),lr=0.01) def forward(self, input): y = self.linear1(input) y = self.relu(y) y = self.linear2(y) return y
  • 訓練網路引數
model = Fit_model()
for e in range(2000):
    y_pre = model(xs)

    loss = model.criterion(y_pre,ys)
    if(e%100==0):
        print(e,loss.data)
    
    # Zero gradients
    model.opt.zero_grad()
    # perform backward pass
    loss.backward()
    # update weights
    model.opt.step()
  • 顯示預測結果
ys_pre = model(xs)

plt.title("curve")
plt.plot(xs.data.numpy(),ys.data.numpy())
plt.plot(xs.data.numpy(),ys_pre.data.numpy())
plt.legend("ys","ys_pre")
plt.show()

  • 執行結果
    log:
0 tensor(15.7941)
200 tensor(0.3394)
400 tensor(0.2086)
600 tensor(0.1115)
800 tensor(0.0634)
1000 tensor(0.0422)
1200 tensor(0.0312)
1400 tensor(0.0244)
1600 tensor(0.0197)
1800 tensor(0.0165)
2000 tensor(0.0140)
2200 tensor(0.0122)
2400 tensor(0.0108)
2600 tensor(0.0097)
2800 tensor(0.0087)
3000 tensor(0.0080)
3200 tensor(0.0074)
3400 tensor(0.0069)
3600 tensor(0.0066)
3800 tensor(0.0063)
4000 tensor(0.0060)

執行結果圖
在這裡插入圖片描述

  • 完整程式碼
import numpy as np
import matplotlib.pyplot as plt
import torch as t
from torch.autograd import Variable as var


def get_data(x,w,b,d):
    c,r = x.shape
    y = (w * x * x + b*x + d)+ (0.1*(2*np.random.rand(c,r)-1))
    return(y)

xs = np.arange(0,3,0.01).reshape(-1,1)
ys = get_data(xs,1,-2,3)

xs = var(t.Tensor(xs))
ys = var(t.Tensor(ys))

class Fit_model(t.nn.Module):
    def __init__(self):
        super(Fit_model,self).__init__()
        self.linear1 = t.nn.Linear(1,16)
        self.relu = t.nn.ReLU()
        self.linear2 = t.nn.Linear(16,1)

        self.criterion = t.nn.MSELoss()
        self.opt = t.optim.SGD(self.parameters(),lr=0.01)
    def forward(self, input):
        y = self.linear1(input)
        y = self.relu(y)
        y = self.linear2(y)
        return y
        
model = Fit_model()
for e in range(4001):
    y_pre = model(xs)

    loss = model.criterion(y_pre,ys)
    if(e%200==0):
        print(e,loss.data)
    
    # Zero gradients
    model.opt.zero_grad()
    # perform backward pass
    loss.backward()
    # update weights
    model.opt.step()

ys_pre = model(xs)

plt.title("curve")
plt.plot(xs.data.numpy(),ys.data.numpy())
plt.plot(xs.data.numpy(),ys_pre.data.numpy())
plt.legend("ys","ys_pre")
plt.show()
  • 總結
    在簡單的問題上,採用相同數量網路引數,分別使用PyTorch與TensorFlow實現可以達到差不多的結果。
    解決問題時,網路結構都是相同的,區別在於兩種框架語法上的差異,PyTorch更接近Python原生程式設計,TensorFlow則採用更多新的概念,所以TensorFlow新手入門會慢一些。TensorFlow優勢可能就是教程多,社群支援好。選擇哪種框架還是看個人喜好,和你所處的環境了。