1. 程式人生 > 其它 >Pytorch基礎筆記 Ⅳ——單變數線性迴歸

Pytorch基礎筆記 Ⅳ——單變數線性迴歸

技術標籤:Pytorch基礎筆記pythonpytorch深度學習機器學習線性迴歸

文章目錄

前情函式

import torch

GPU相關語句

'''以下通過先判斷GPU是否存在,
   在通過對應的語句打印出GPU的資訊
'''

if torch.cuda.is_available():
    # 返回gpu數量
    GPU_num = torch.cuda.device_count()
    # 返回gpu名字,裝置索引預設從0開始
GPU_name = torch.cuda.get_device_name(0) # 返回當前裝置索引 GPU_index = torch.cuda.current_device() print(GPU_num, GPU_name, GPU_index) else: print('Use CPU for work')
1 GeForce GTX 960M 0

下面語句用於將模型放在GPU上訓練

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu"
) device
device(type='cuda', index=0)

torch.unsqueeze 與 torch.squeeze

torch.unsqueeze(input, dim) → Tensor

    返回插入指定位置尺寸為1的新張量

    返回的張量與此張量共享相同的基礎資料

    可以通過dim控制指定的軸向

這個函式主要是對資料維度進行擴充。給指定位置加上維數為1的維度

x0 = torch.tensor([1, 2, 3, 4])
print('x0 維度:', x0.size(),'\n', x0)

x1 = torch.unsqueeze(x0, 0)
print
('x1 維度:', x1.size(),'\n', x1) x2 = torch.unsqueeze(x0, 1) print('x2 維度:', x2.size(),'\n', x2)
x0 維度: torch.Size([4]) 
 tensor([1, 2, 3, 4])
x1 維度: torch.Size([1, 4]) 
 tensor([[1, 2, 3, 4]])
x2 維度: torch.Size([4, 1]) 
 tensor([[1],
        [2],
        [3],
        [4]])

torch.squeeze(input, dim=None, out=None) → Tensor

    移除輸入張量維度為1的軸

    例如輸入張量的shape為: ( A × 1 × B × C × 1 × D ) (A \times 1 \times B \times C \times 1 \times D) (A×1×B×C×1×D)輸出張量的shape則為: ( A × B × C × D ) (A \times B \times C \times D) (A×B×C×D)

    可以通過dim控制指定的軸向,例如輸入張量的shape為: ( A × 1 × B ) (A \times 1 \times B) (A×1×B),通過squeeze(input, 1),輸出張量的shape為: ( A × B ) (A \times B) (A×B)

這個函式主要對資料的維度進行壓縮,去掉維數為1的的維度

x0 = torch.zeros(2, 1, 2, 1, 2)
print('x0 維度:', x0.size())

x1 = torch.squeeze(x0)
print('x1 維度:', x1.size())

x2 = torch.squeeze(x0, 0)
print('x2 維度:', x2.size())

x3 = torch.squeeze(x0, 1)
print('x3 維度:', x3.size())
x0 維度: torch.Size([2, 1, 2, 1, 2])
x1 維度: torch.Size([2, 2, 2])
x2 維度: torch.Size([2, 1, 2, 1, 2])
x3 維度: torch.Size([2, 2, 1, 2])

正式開始

匯入必要模組

安裝pytorch時,不會安裝torchsummary,需要手動通過!pip install torchsummary安裝,如果不在jupyter中,則去掉感嘆號進行安裝

%matplotlib inline
import torch
from torchsummary import summary
import torch.nn.functional as F
import matplotlib.pyplot as plt
import pylab as pl
from IPython import display

torch.__version__
'1.6.0'

構建資料集

本案例中將以一個正弦函式 y = s i n ( x ) y=sin(x) y=sin(x)為例

如果使用多個GPU,應該使用torch.cuda.manual_seed_all()為所有的GPU設定種子。

if torch.cuda.is_available():
    torch.cuda.manual_seed(1) #為當前GPU設定隨機種子用於生成隨機數,以使得結果是確定的
    print('GPU is available')
else:
    torch.manual_seed(1)      #為CPU設定隨機種子用於生成隨機數,以使得結果是確定的
    print('Use CPU for work')
GPU is available

squeeze是刪除維度為1的軸,unsqueeze則是增加一個維度為1的軸,通過dim控制增加軸的方向,其中可以通過x.size()獲取x的維度為torch.Size([100, 1])

import math

PI = math.pi

x = torch.unsqueeze(torch.linspace(-PI, PI, 200), dim=1)

y = torch.sin(x) + 0.07 * torch.randn(x.size())
plt.plot(x, torch.sin(x).numpy(), color='r', label='GroundTruth')
plt.scatter(x.numpy(), y.numpy(), s=10, color='b', label='Dataset')
plt.legend()
plt.show()

1

模型定義

採用relu啟用函式,單隱層神經網路結構

class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x

開啟GPU模式並檢視網路摘要summary

net = Net(n_feature=1, n_hidden=10, n_output=1).to(device)

summary(net, input_size=(1,))
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Linear-1                   [-1, 10]              20
            Linear-2                    [-1, 1]              11
================================================================
Total params: 31
Trainable params: 31
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------

模型引數設定

優化器以及損失函式設定

optimizer = torch.optim.Adam(net.parameters(), lr=0.02)

loss_func = torch.nn.MSELoss()

將資料拷貝至GPU

x_data, y_data = x.to(device), y.to(device)

Pytorch引數重置,避免調參後重新執行for迴圈時,原始已訓練引數進行保留

def weight_reset(m):
    if isinstance(m, torch.nn.Conv2d) or isinstance(m, torch.nn.Linear):
        m.reset_parameters()
%%time

net.apply(weight_reset)

loss_value = []

for i in range(1000):
    prediction = net(x_data)
    
    loss = loss_func(prediction, y_data)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    loss_value.append(loss.cpu().detach().numpy())

    if i % 10 == 0:
        pl.axis([-4, 4, -2, 2]) 
        pl.clf()
        pl.scatter(x.numpy(), y.numpy(), s=5)
        pl.plot(x.numpy(), torch.sin(x).numpy(), 'g', lw=2, label='GroundTruth')
        pl.plot(x.numpy(), prediction.cpu().detach().numpy(), 'r-', lw=2, label='Prediction')
        pl.text(1.0, -1.0, 'Loss=%.4f' % loss.cpu().detach().numpy(), fontdict={'size': 15, 'color':  'red'})
        pl.legend()
        display.display(pl.gcf())
        display.clear_output(wait=True)
Wall time: 31.3 s

2

損失值視覺化

pl.plot([i for i in range(len(loss_value))], loss_value, label='model line', color='r')
pl.legend()
pl.show()

3