深度學習之PyTorch學習_3.3 線性迴歸的簡潔實現

3.3 線性迴歸的簡潔實現

3.3.1 生成數據集

%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
num_inputs = 2
num_examples = 1000
true_w = [2,-3.4]
true_b = 4.2
features = torch.from_numpy(np.random.normal(0,1,(num_examples,num_inputs)))
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += torch.from_numpy(np.random.normal(0,0.01,size = labels.size()))

3.3.2 讀取數據

import torch.utils.data as Data

batch_size = 10
# 把訓練集的特徵與標籤進行組合
dataset = Data.TensorDataset(features, labels)
# 隨機讀取小批量數據
data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)

這裏的data_iter與上一節一樣,根據設定的batch_size讀取小批量數據

for x, y in data_iter:
    print(x, y)
    break
tensor([[ 0.4889,  0.8471],
        [ 1.0232,  1.2690],
        [ 0.0906, -0.6728],
        [-0.6681, -0.1366],
        [-0.4193,  0.0632],
        [ 0.9439, -0.0119],
        [ 1.0156, -0.0104],
        [-0.2202, -1.1330],
        [-0.0229,  0.8879],
        [ 1.2394, -0.2916]], dtype=torch.float64) tensor([2.2978, 1.9403, 6.6585, 3.3204, 3.1487, 6.1291, 6.2743, 7.6209, 1.1419,
        7.6899], dtype=torch.float64)

3.3.3 定義模型

  • torch.nn 模塊
import torch.nn as nn
class LinearNet(nn.Module):
    def __init__(self, n_feature):
        super(LinearNet, self).__init__()
        self.linear = nn.Linear(n_feature,1)
    def forward(self, x):
        y = self.linear(x)
        return y
net = LinearNet(num_inputs)
# 打印網絡結構
print(net)
LinearNet(
  (linear): Linear(in_features=2, out_features=1, bias=True)
)

也可以使用nn.Sequential來更加方便的搭建網絡,Sequential是一個有序的容器

# 方法一
net = nn.Sequential(nn.Linear(num_inputs,1))
print(net)
print(net[0])
# 方法二
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ...
print(net)
print(net[0])
#方法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([('linear', nn.Linear(num_inputs, 1))
                                #...
                                ]))
print(net)
print(net[0])
Sequential(
  (0): Linear(in_features=2, out_features=1, bias=True)
)
Linear(in_features=2, out_features=1, bias=True)
Sequential(
  (linear): Linear(in_features=2, out_features=1, bias=True)
)
Linear(in_features=2, out_features=1, bias=True)
Sequential(
  (linear): Linear(in_features=2, out_features=1, bias=True)
)
Linear(in_features=2, out_features=1, bias=True)

通過net.parameters()查看模型所有的可學習參數,返回一個生成器

for param in net.parameters():
    print(param)
#  返回的是權重 和 偏差
Parameter containing:
tensor([[-0.3807,  0.6131]], requires_grad=True)
Parameter containing:
tensor([0.4925], requires_grad=True)

3.3.4 初始化模型參數

在使用net 前需要初始化模型參數,即 權重和偏差。pytorch 在 init 模塊中提供了參數初始化方法。

from torch.nn import init

init.normal_(net[0].weight, mean = 0, std = 0.01)
init.constant_(net[0].bias, val = 0)
Parameter containing:
tensor([0.], requires_grad=True)

3.3.5 定義損失函數

loss = nn.MSELoss()

3.3.6 定義優化算法

  • torch.optim 模塊 提供常用的優化算法
    如 SGD Adam RMSProp等
import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr = 0.03)
print(optimizer)
SGD (
Parameter Group 0
    dampening: 0
    lr: 0.03
    momentum: 0
    nesterov: False
    weight_decay: 0
)

有時候需要爲子網絡設置不同的學習率

學習率(learning rate)是指導我們該如何通過損失函數的梯度調整網絡權重的超參數。學習率越低,損失函數的變化速度就越慢。雖然使用低學習率可以確保我們不會錯過任何局部極小值,但也意味着我們將花費更長的時間來進行收斂,特別是在被困在高原區域的情況下。

# optimizer = optim.SGD([
#         # 如果對某個參數不指定學習率,就使⽤最外層的默認學習率
#         {'params': net.subnet1.parameters()}, # lr=0.03
#         {'params': net.subnet2.parameters(), 'lr': 0.01}
#         ], lr=0.03)
# 如何調整學習率
# for param_group in optimizer.param_groups:
#     param_group['lr'] *= 0.1 # 學習率爲之前的0.1倍

3.3.7訓練模型

num_epochs = 3
for epoch in range(1, num_epochs + 1):
    for x, y in data_iter:
        x = torch.tensor(x, dtype=torch.float32)
        y = torch.tensor(y, dtype=torch.float32)
#         print(x.dtype)
        output = net(x)
        l = loss(output, y.view(-1,1))
        optimizer.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d, loss:%f'%(epoch, l.item()))
epoch 1, loss:0.000840
epoch 2, loss:0.000063
epoch 3, loss:0.000052
dense = net[0]
print(true_w, dense.weight)
print(true_b, dense.bias)
[2, -3.4] Parameter containing:
tensor([[ 2.0001, -3.3998]], requires_grad=True)
4.2 Parameter containing:
tensor([4.2004], requires_grad=True)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章