線性迴歸
主要內容包括:
- 線性迴歸的基本要素
- 線性迴歸模型從零開始的實現
- 線性迴歸模型使用pytorch的簡潔實模型
模型爲預測房價 有兩個因素,即面積(平方米)和房齡(年)
我們的目標是爲了找到一個擬合函數與真實值逼近。
2、損失函數
在模型訓練中,我們需要衡量價格預測值與真實值之間的誤差。通常我們會選取一個非負數作爲誤差,且數值越小表示誤差越小。一個常用的選擇是平方函數。 它在評估索引爲 ii 的樣本誤差的表達式爲
優化函數 - 隨機梯度下降
在求數值解的優化算法中,小批量隨機梯度下降(mini-batch stochastic gradient descent)在深度學習中被廣泛使用。它的算法很簡單:先選取一組模型參數的初始值,如隨機選取;接下來對參數進行多次迭代,使每次迭代都可能降低損失函數的值。在每次迭代中,先隨機均勻採樣一個由固定數目訓練數據樣本所組成的小批量(mini-batch)BB,然後求小批量中數據樣本的平均損失有關模型參數的導數(梯度),最後用此結果與預先設定的一個正數的乘積作爲模型參數在本次迭代的減小量。
優化函數步驟爲
- (i)初始化模型參數,一般來說使用隨機初始化;
- (ii)我們在數據上迭代多次,通過在負梯度方向移動參數來更新每個參數。
線性迴歸模型使用pytorch的簡潔實現
In [16]:
import torch from torch import nn import numpy as np torch.manual_seed(1) print(torch.__version__) torch.set_default_tensor_type('torch.FloatTensor')
生成數據集
在這裏生成數據集跟從零開始的實現中是完全一樣的。
In [17]:
num_inputs = 2 num_examples = 1000 true_w = [2, -3.4] true_b = 4.2 features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float) labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)
讀取數據集
In [18]:
import torch.utils.data as Data batch_size = 10 # combine featues and labels of dataset dataset = Data.TensorDataset(features, labels) # put dataset into DataLoader data_iter = Data.DataLoader( dataset=dataset, # torch TensorDataset format batch_size=batch_size, # mini batch size shuffle=True, # whether shuffle the data or not num_workers=2, # read data in multithreading )
In [19]:
for X, y in data_iter: print(X, '\n', y) break
定義模型
In [20]:
class LinearNet(nn.Module): def __init__(self, n_feature): super(LinearNet, self).__init__() # call father function to init self.linear = nn.Linear(n_feature, 1) # function prototype: `torch.nn.Linear(in_features, out_features, bias=True)` def forward(self, x): y = self.linear(x) return y net = LinearNet(num_inputs) print(net)
In [21]:
# ways to init a multilayer network # method one net = nn.Sequential( nn.Linear(num_inputs, 1) # other layers can be added here ) # method two net = nn.Sequential() net.add_module('linear', nn.Linear(num_inputs, 1)) # net.add_module ...... # method three from collections import OrderedDict net = nn.Sequential(OrderedDict([ ('linear', nn.Linear(num_inputs, 1)) # ...... ])) print(net) print(net[0])
初始化模型參數
In [22]:
from torch.nn import init init.normal_(net[0].weight, mean=0.0, std=0.01) init.constant_(net[0].bias, val=0.0) # or you can use `net[0].bias.data.fill_(0)` to modify it directly
In [23]:
for param in net.parameters(): print(param)
定義損失函數
In [24]:
loss = nn.MSELoss() # nn built-in squared loss function # function prototype: `torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')`
定義優化函數
In [25]:
import torch.optim as optim optimizer = optim.SGD(net.parameters(), lr=0.03) # built-in random gradient descent function print(optimizer) # function prototype: `torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)`
訓練
In [26]:
num_epochs = 3 for epoch in range(1, num_epochs + 1): for X, y in data_iter: output = net(X) l = loss(output, y.view(-1, 1)) optimizer.zero_grad() # reset gradient, equal to net.zero_grad() l.backward() optimizer.step() print('epoch %d, loss: %f' % (epoch, l.item()))
In [27]:
# result comparision dense = net[0] print(true_w, dense.weight.data) print(true_b, dense.bias.data)